@@ -2,12 +2,14 @@ use std::ffi::c_char;
22use std:: marker:: PhantomData ;
33use std:: str:: Utf8Error ;
44
5+ use crate :: lexer:: Capture ;
6+ use crate :: lexer:: Fragment ;
57use crate :: lexer:: Lexer ;
6- use crate :: lexer:: LogComponent ;
78use crate :: regex:: Regex ;
89use crate :: schema:: Schema ;
910
1011#[ repr( C ) ]
12+ #[ derive( Debug , Clone , Copy ) ]
1113pub struct CSlice < ' lifetime , T > {
1214 pointer : * const T ,
1315 length : usize ,
@@ -16,14 +18,14 @@ pub struct CSlice<'lifetime, T> {
1618
1719pub type CStringView < ' lifetime > = CSlice < ' lifetime , c_char > ;
1820
19- // #[unsafe(no_mangle )]
20- // unsafe extern "C" fn clp_log_mechanic_c_string_view<'unknown>(pointer: *const c_char) -> CSlice<'unknown, c_char > {
21- // CSlice {
22- // pointer ,
23- // length: unsafe { libc::strlen(pointer) } ,
24- // _lifetime: PhantomData ,
25- // }
26- // }
21+ # [ repr ( C ) ]
22+ pub struct CLogFragment < ' schema , ' input > {
23+ pub rule : usize ,
24+ pub start : * const u8 ,
25+ pub end : * const u8 ,
26+ pub captures : * const Capture < ' schema , ' input > ,
27+ pub captures_count : usize ,
28+ }
2729
2830#[ unsafe( no_mangle) ]
2931extern "C" fn clp_log_mechanic_schema_new ( ) -> Box < Schema > {
@@ -53,28 +55,35 @@ unsafe extern "C" fn clp_log_mechanic_schema_add_rule(
5355}
5456
5557#[ unsafe( no_mangle) ]
56- unsafe extern "C" fn clp_log_mechanic_lexer_new < ' schema > ( schema : & ' schema Schema ) -> Box < Lexer < ' schema > > {
57- let lexer: Lexer < ' _ > = Lexer :: new ( schema) . unwrap ( ) ;
58+ unsafe extern "C" fn clp_log_mechanic_lexer_new < ' schema , ' a > ( schema : & ' schema Schema ) -> Box < Lexer < ' schema , ' a > > {
59+ let lexer: Lexer < ' _ , ' _ > = Lexer :: new ( schema) . unwrap ( ) ;
5860 Box :: new ( lexer)
5961}
6062
6163#[ unsafe( no_mangle) ]
62- unsafe extern "C" fn clp_log_mechanic_lexer_delete ( lexer : Box < Lexer < ' _ > > ) {
64+ unsafe extern "C" fn clp_log_mechanic_lexer_delete < ' a > ( lexer : Box < Lexer < ' _ , ' a > > ) {
6365 std:: mem:: drop ( lexer) ;
6466}
6567
68+ /// Very unsafe!
69+ ///
70+ /// The returned [`CLogFragment`] includes a hidden exclusive borrow of `lexer`
71+ /// (it contains a pointer into an interal buffer of `lexer`),
72+ /// so it is nolonger valid/you must not use it after a subsequent exclusive borrow of `lexer`
73+ /// (i.e. this borrow has ended).
6674#[ unsafe( no_mangle) ]
67- unsafe extern "C" fn clp_log_mechanic_lexer_next_token < ' schema , ' lexer > (
68- lexer : & ' lexer mut Lexer < ' schema > ,
69- input : CStringView < ' _ > ,
75+ unsafe extern "C" fn clp_log_mechanic_lexer_next_fragment < ' schema , ' lexer , ' input > (
76+ lexer : & ' lexer mut Lexer < ' schema , ' input > ,
77+ input : CStringView < ' input > ,
7078 pos : & mut usize ,
71- log_component : & mut LogComponent < ' schema , ' lexer > ,
72- ) -> bool {
73- if let Some ( component) = lexer. next_token ( input. as_utf8 ( ) . unwrap ( ) , pos) {
74- * log_component = component;
75- true
76- } else {
77- false
79+ ) -> CLogFragment < ' schema , ' input > {
80+ let fragment: Fragment < ' _ , ' _ , ' _ > = lexer. next_fragment ( input. as_utf8 ( ) . unwrap ( ) , pos) ;
81+ CLogFragment {
82+ rule : fragment. rule ,
83+ start : fragment. lexeme . as_bytes ( ) . as_ptr_range ( ) . start ,
84+ end : fragment. lexeme . as_bytes ( ) . as_ptr_range ( ) . end ,
85+ captures : fragment. captures . as_ptr ( ) ,
86+ captures_count : fragment. captures . len ( ) ,
7887 }
7988}
8089
@@ -98,3 +107,45 @@ impl<'lifetime> CStringView<'lifetime> {
98107 str:: from_utf8 ( bytes)
99108 }
100109}
110+
111+ #[ cfg( test) ]
112+ mod test {
113+ use super :: * ;
114+ use crate :: regex:: Regex ;
115+
116+ #[ test]
117+ fn basic ( ) {
118+ let mut schema: Schema = Schema :: new ( ) ;
119+ schema. set_delimiters ( " " ) ;
120+ schema. add_rule ( "hello" , Regex :: from_pattern ( "hello world" ) . unwrap ( ) ) ;
121+ schema. add_rule ( "bye" , Regex :: from_pattern ( "goodbye" ) . unwrap ( ) ) ;
122+
123+ let mut lexer: Lexer < ' _ , ' _ > = Lexer :: new ( & schema) . unwrap ( ) ;
124+ let input: CStringView < ' _ > = CStringView :: from_utf8 ( "hello world goodbye hello world goodbye " ) ;
125+ let mut pos: usize = 0 ;
126+
127+ unsafe {
128+ assert_eq ! (
129+ clp_log_mechanic_lexer_next_fragment( & mut lexer, input, & mut pos) . rule,
130+ 1
131+ ) ;
132+ assert_eq ! (
133+ clp_log_mechanic_lexer_next_fragment( & mut lexer, input, & mut pos) . rule,
134+ 2
135+ ) ;
136+ assert_eq ! (
137+ clp_log_mechanic_lexer_next_fragment( & mut lexer, input, & mut pos) . rule,
138+ 1
139+ ) ;
140+ assert_eq ! (
141+ clp_log_mechanic_lexer_next_fragment( & mut lexer, input, & mut pos) . rule,
142+ 2
143+ ) ;
144+ assert_eq ! (
145+ clp_log_mechanic_lexer_next_fragment( & mut lexer, input, & mut pos) . rule,
146+ 0
147+ ) ;
148+ }
149+ assert_eq ! ( pos, input. length) ;
150+ }
151+ }
0 commit comments