109
109
* them. Helpers below facilitate that.
110
110
*/
111
111
112
+ unsigned short number_of_regex = 0 ;
113
+ unsigned short number_of_db_regex = 0 ;
114
+
112
115
static const char *
113
116
__alloc_and_copy_literal (const char * src , size_t len , bool keep_bs )
114
117
{
@@ -397,6 +400,9 @@ typedef enum {
397
400
TOKEN_SEMICOLON ,
398
401
TOKEN_LITERAL ,
399
402
TOKEN_ARROW ,
403
+ TOKEN_TILDA ,
404
+ TOKEN_REGEX ,
405
+ TOKEN_REGEX_CI ,
400
406
_TOKEN_COUNT ,
401
407
} token_t ;
402
408
@@ -588,9 +594,12 @@ read_next_token(TfwCfgParserState *ps)
588
594
TOKEN_NEQSIGN );
589
595
TFSM_COND_MOVE_EXIT (ps -> c == '>' && ps -> prev_c == '-' ,
590
596
TOKEN_ARROW );
597
+ TFSM_COND_MOVE_EXIT (ps -> c == '*' && ps -> prev_c == '~' ,
598
+ TOKEN_REGEX_CI );
591
599
592
600
/* Special case to differ single equal sign from double one. */
593
601
TFSM_COND_MOVE (ps -> c == '=' , TS_EQSIGN );
602
+ TFSM_COND_MOVE (ps -> c == '~' , TS_TILDA );
594
603
595
604
/* Everything else is not a special character and therefore
596
605
* it starts a literal. */
@@ -619,6 +628,14 @@ read_next_token(TfwCfgParserState *ps)
619
628
TFSM_JMP_EXIT (TOKEN_EQSIGN );
620
629
}
621
630
631
+ FSM_STATE (TS_TILDA ) {
632
+ TFSM_COND_JMP_EXIT (!ps -> c , TOKEN_REGEX );
633
+
634
+ /* If this is double equal sign, eat second sign and exit. */
635
+ TFSM_COND_MOVE_EXIT (ps -> c == '*' , TOKEN_REGEX_CI );
636
+ TFSM_JMP_EXIT (TOKEN_REGEX );
637
+ }
638
+
622
639
FSM_STATE (TS_COMMENT ) {
623
640
TFSM_COND_JMP_EXIT (!ps -> c , TOKEN_NA );
624
641
@@ -732,7 +749,21 @@ entry_set_cond(TfwCfgEntry *e, token_t cond_type, const char *src, int len)
732
749
if (!(e -> name = alloc_and_copy_literal (name , name_len )))
733
750
return - ENOMEM ;
734
751
735
- rule -> inv = cond_type == TOKEN_DEQSIGN ? false : true;
752
+ switch (cond_type ) {
753
+ case TOKEN_REGEX :
754
+ rule -> regex = TFW_REGEX_REGULAR ;
755
+ rule -> inv = false;
756
+ break ;
757
+ case TOKEN_REGEX_CI :
758
+ rule -> regex = TFW_REGEX_CI ;
759
+ rule -> inv = false;
760
+ break ;
761
+ default :
762
+ rule -> regex = TFW_REGEX_NO ;
763
+ rule -> inv = cond_type == TOKEN_DEQSIGN ? false : true;
764
+ break ;
765
+ }
766
+
736
767
return 0 ;
737
768
}
738
769
@@ -806,8 +837,10 @@ parse_cfg_entry(TfwCfgParserState *ps)
806
837
807
838
FSM_STATE (PS_PLAIN_OR_RULE ) {
808
839
PFSM_COND_MOVE (ps -> t == TOKEN_DEQSIGN ||
809
- ps -> t == TOKEN_NEQSIGN ,
810
- PS_RULE_COND );
840
+ ps -> t == TOKEN_NEQSIGN ||
841
+ ps -> t == TOKEN_REGEX ||
842
+ ps -> t == TOKEN_REGEX_CI ,
843
+ PS_RULE_COND );
811
844
PFSM_COND_MOVE (ps -> t == TOKEN_LITERAL , PS_PLAIN_OR_LONG_RULE );
812
845
813
846
/* Jump to plain val/attr scheme to make remained checks
@@ -819,35 +852,41 @@ parse_cfg_entry(TfwCfgParserState *ps)
819
852
820
853
FSM_STATE (PS_PLAIN_OR_LONG_RULE ) {
821
854
FSM_COND_JMP (ps -> t == TOKEN_DEQSIGN ||
822
- ps -> t == TOKEN_NEQSIGN ,
823
- PS_LONG_RULE_COND );
855
+ ps -> t == TOKEN_NEQSIGN ||
856
+ ps -> t == TOKEN_REGEX ||
857
+ ps -> t == TOKEN_REGEX_CI ,
858
+ PS_LONG_RULE_COND );
824
859
825
860
/* This is not rule (simple or extended), so jump to
826
861
* plain val/attr scheme. */
827
862
ps -> err = entry_set_name (& ps -> e );
828
863
FSM_COND_JMP (ps -> err , PS_EXIT );
829
864
FSM_COND_JMP (ps -> t == TOKEN_EQSIGN , PS_STORE_ATTR_PREV );
830
865
FSM_COND_JMP (ps -> t == TOKEN_LITERAL ||
831
- ps -> t == TOKEN_SEMICOLON ||
832
- ps -> t == TOKEN_LBRACE ,
833
- PS_STORE_VAL_PREV );
866
+ ps -> t == TOKEN_SEMICOLON ||
867
+ ps -> t == TOKEN_LBRACE ,
868
+ PS_STORE_VAL_PREV );
834
869
835
870
ps -> err = - EINVAL ;
836
871
FSM_JMP (PS_EXIT );
837
872
}
838
873
839
874
FSM_STATE (PS_LONG_RULE_COND ) {
840
875
ps -> err = entry_add_rule_param (& ps -> e .rule .fst_ext ,
841
- ps -> prev_lit ,
842
- ps -> prev_lit_len );
876
+ ps -> prev_lit ,
877
+ ps -> prev_lit_len );
843
878
FSM_COND_JMP (ps -> err , PS_EXIT );
844
879
PFSM_MOVE (PS_RULE_COND );
845
880
}
846
881
847
882
FSM_STATE (PS_RULE_COND ) {
883
+ FSM_COND_JMP (ps -> prev_t == TOKEN_REGEX ||
884
+ ps -> prev_t == TOKEN_REGEX_CI ,
885
+ PS_STORE_VAL_PREV_REGEX );
886
+
848
887
PFSM_COND_JMP_EXIT_ERROR (ps -> t != TOKEN_LITERAL );
849
888
ps -> err = entry_set_cond (& ps -> e , ps -> prev_t , ps -> lit ,
850
- ps -> lit_len );
889
+ ps -> lit_len );
851
890
FSM_COND_JMP (ps -> err , PS_EXIT );
852
891
PFSM_MOVE (PS_RULE_COND_END );
853
892
}
@@ -866,7 +905,7 @@ parse_cfg_entry(TfwCfgParserState *ps)
866
905
FSM_STATE (PS_RULE_ACTION ) {
867
906
PFSM_COND_JMP_EXIT_ERROR (ps -> t != TOKEN_LITERAL );
868
907
ps -> err = entry_add_rule_param (& ps -> e .rule .act , ps -> lit ,
869
- ps -> lit_len );
908
+ ps -> lit_len );
870
909
FSM_COND_JMP (ps -> err , PS_EXIT );
871
910
PFSM_MOVE (PS_RULE_ACTION_VAL );
872
911
}
@@ -878,7 +917,7 @@ parse_cfg_entry(TfwCfgParserState *ps)
878
917
PFSM_COND_JMP_EXIT_ERROR (ps -> t != TOKEN_LITERAL );
879
918
880
919
ps -> err = entry_add_rule_param (& ps -> e .rule .val , ps -> lit ,
881
- ps -> lit_len );
920
+ ps -> lit_len );
882
921
FSM_COND_JMP (ps -> err , PS_EXIT );
883
922
884
923
read_next_token (ps );
@@ -914,6 +953,38 @@ parse_cfg_entry(TfwCfgParserState *ps)
914
953
FSM_JMP (PS_STORE_VAL_PREV );
915
954
}
916
955
956
+ FSM_STATE (PS_STORE_VAL_PREV_REGEX ) {
957
+ /* name val1 val2;
958
+ * ^
959
+ * We are here (but still need to store val1)
960
+ * and name or condition.
961
+ */
962
+ T_DBG3 ("add value: %.*s\n" , ps -> prev_lit_len , ps -> prev_lit );
963
+
964
+ if (ps -> e .ftoken && !strcmp (ps -> e .ftoken , "location" )) {
965
+ ps -> err = entry_set_name (& ps -> e );
966
+
967
+ if (!ps -> err ) {
968
+ if (ps -> prev_t == TOKEN_REGEX )
969
+ ps -> err = entry_add_val (& ps -> e , "regex" ,
970
+ sizeof ("regex" ));
971
+ if (ps -> prev_t == TOKEN_REGEX_CI )
972
+ ps -> err = entry_add_val (& ps -> e ,
973
+ "regex_ci" ,
974
+ sizeof ("regex_ci" ));
975
+ }
976
+ FSM_COND_JMP (ps -> err , PS_EXIT );
977
+ FSM_JMP (PS_VAL_OR_ATTR );
978
+ }
979
+
980
+ /*If it is not location*/
981
+ ps -> err = entry_set_cond (& ps -> e , ps -> prev_t ,
982
+ ps -> lit , ps -> lit_len );
983
+ FSM_COND_JMP (ps -> err , PS_EXIT );
984
+ PFSM_MOVE (PS_RULE_COND_END );
985
+
986
+ }
987
+
917
988
FSM_STATE (PS_STORE_VAL_PREV ) {
918
989
/* name val1 val2;
919
990
* ^
0 commit comments