tcpp/
ffi.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use std::convert::TryFrom;
use std::ffi::{CStr, CString, NulError};
use std::ptr::null_mut;

extern "C" {

    fn error_type_to_string(error: libc::c_uint) -> *const libc::c_char;

    fn create_input_stream(str: *const libc::c_char) -> *mut libc::c_void;

}

/// Struct representing an input stream of bytes or string
#[repr(C)]
pub struct IInputStream {
    pub(crate) handler : *mut libc::c_void
}

impl Default for IInputStream{
    /// synonym to [`IInputStream::null`]
    fn default() -> Self {
        Self::null()
    }
}

impl IInputStream {
    /// Creates a null stream, stands for no input at all
    pub fn null() -> Self {
        IInputStream {
            handler: null_mut()
        }
    }
}

impl TryFrom<String> for IInputStream {

    type Error = NulError;
    /// Construct an input stream from a single string
    fn try_from(value: String) -> Result<Self, Self::Error> {
        let cstring = CString::new(value)?;
        let stream = IInputStream {
            handler: unsafe {
                create_input_stream(cstring.as_ptr())
            }
        };
        Ok(stream)
    }

}

/// Struct representing a common error within preprocessor
#[repr(C)]
pub struct TErrorInfo {
    m_type: libc::c_uint,
    m_line: libc::size_t
}

impl TErrorInfo {
    /// Get the line number of this error
    pub fn get_line(&self) -> usize {
        self.m_line
    }

    /// Get the lint message of this error, returns None if an encoding error occurs
    pub fn get_message(&self) -> Option<String> {
        println!("{}", self.m_type);
        Some(unsafe {
            let msg = error_type_to_string(self.m_type);
            CStr::from_ptr(msg).to_str().ok()?.to_owned()
        })
    }

}