diff options
| author | Ben Fuhrmannek | 2021-08-16 23:22:47 +0200 |
|---|---|---|
| committer | Ben Fuhrmannek | 2021-08-16 23:22:47 +0200 |
| commit | 333984c636ac3318f35efc78529186e63d3ce59e (patch) | |
| tree | eeb7e90d5005ab8a053b557ae9dcd08e414cae69 /src/sp_config_scanner.re | |
| parent | 5148ded7268b569fd5e720f90b44645c83ac3e9e (diff) | |
config supports variables now
Diffstat (limited to 'src/sp_config_scanner.re')
| -rw-r--r-- | src/sp_config_scanner.re | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/src/sp_config_scanner.re b/src/sp_config_scanner.re index 075c343..33362fc 100644 --- a/src/sp_config_scanner.re +++ b/src/sp_config_scanner.re | |||
| @@ -67,16 +67,25 @@ zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) { | |||
| 67 | return ret; | 67 | return ret; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | static void str_dtor(zval *zv) { | ||
| 71 | zend_string_release_ex(Z_STR_P(zv), 1); | ||
| 72 | } | ||
| 73 | |||
| 70 | zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_keyword*)) | 74 | zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_keyword*)) |
| 71 | { | 75 | { |
| 72 | const char *YYCURSOR = data; | 76 | const char *YYCURSOR = data; |
| 73 | const char *YYMARKER, *t1, *t2, *t3, *t4; | 77 | const char *YYMARKER, *t1, *t2, *t3, *t4; |
| 74 | /*!stags:re2c format = 'const char *@@;\n'; */ | 78 | /*!stags:re2c format = 'const char *@@;\n'; */ |
| 75 | 79 | ||
| 80 | int ret = FAILURE; | ||
| 81 | |||
| 76 | const int max_keywords = 16; | 82 | const int max_keywords = 16; |
| 77 | sp_parsed_keyword parsed_rule[max_keywords+1]; | 83 | sp_parsed_keyword parsed_rule[max_keywords+1]; |
| 78 | int kw_i = 0; | 84 | int kw_i = 0; |
| 79 | 85 | ||
| 86 | HashTable vars; | ||
| 87 | zend_hash_init(&vars, 10, NULL, str_dtor, 1); | ||
| 88 | |||
| 80 | int cond = yycinit; | 89 | int cond = yycinit; |
| 81 | long lineno = 1; | 90 | long lineno = 1; |
| 82 | 91 | ||
| @@ -92,31 +101,53 @@ zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_key | |||
| 92 | end = "\x00"; | 101 | end = "\x00"; |
| 93 | nl = "\r"?"\n"; | 102 | nl = "\r"?"\n"; |
| 94 | ws = [ \t]; | 103 | ws = [ \t]; |
| 104 | wsnl = [ \t\r\n]; | ||
| 95 | keyword = [a-zA-Z_][a-zA-Z0-9_]*; | 105 | keyword = [a-zA-Z_][a-zA-Z0-9_]*; |
| 96 | string = "\"" ("\\\"" | [^"\r\n])* "\""; | 106 | string = "\"" ("\\\"" | [^"\r\n])* "\""; |
| 97 | 107 | ||
| 98 | <init> * { cs_error_log("Parser error on line %d", lineno); return FAILURE; } | 108 | <init> * { cs_error_log("Parser error on line %d", lineno); goto out; } |
| 99 | <init> ws+ { goto yyc_init; } | 109 | <init> ws+ { goto yyc_init; } |
| 100 | <init> [;#] .* { goto yyc_init; } | 110 | <init> [;#] .* { goto yyc_init; } |
| 101 | <init> nl { lineno++; goto yyc_init; } | 111 | <init> nl { lineno++; goto yyc_init; } |
| 102 | <init> "sp" { kw_i = 0; goto yyc_rule; } | 112 | <init> "sp" { kw_i = 0; goto yyc_rule; } |
| 103 | <init> end { return SUCCESS; } | 113 | <init> end { ret = SUCCESS; goto out; } |
| 114 | <init> "set" wsnl+ @t1 keyword @t2 wsnl+ @t3 string @t4 ";"? { | ||
| 115 | char *key = (char*)t1; | ||
| 116 | int keylen = t2-t1; | ||
| 117 | zend_string *tmp = zend_hash_str_find_ptr(&vars, key, keylen); | ||
| 118 | if (tmp) { | ||
| 119 | zend_hash_str_del(&vars, key, keylen); | ||
| 120 | } | ||
| 121 | tmp = zend_string_init(t3+1, t4-t3-2, 1); | ||
| 122 | zend_hash_str_add_ptr(&vars, key, keylen, tmp); | ||
| 123 | goto yyc_init; | ||
| 124 | } | ||
| 125 | |||
| 104 | 126 | ||
| 105 | <rule> ws+ { goto yyc_rule; } | 127 | <rule> ws+ { goto yyc_rule; } |
| 106 | <rule> nl / ( nl | ws )* "." { lineno++; goto yyc_rule; } | 128 | <rule> nl / ( nl | ws )* "." { lineno++; goto yyc_rule; } |
| 107 | <rule> "." @t1 keyword @t2 ( "(" @t3 string? @t4 ")" )? { | 129 | <rule> "." @t1 keyword @t2 ( "(" @t3 ( string? | keyword ) @t4 ")" )? { |
| 108 | if (kw_i == max_keywords) { | 130 | if (kw_i == max_keywords) { |
| 109 | cs_error_log("Too many keywords in rule (more than %d) on line %d", max_keywords, lineno); | 131 | cs_error_log("Too many keywords in rule (more than %d) on line %d", max_keywords, lineno); |
| 110 | return FAILURE; | 132 | goto out; |
| 111 | } | 133 | } |
| 112 | sp_parsed_keyword kw = {.kw = (char*)t1, .kwlen = t2-t1, .arg = (char*)t3, .arglen = t4-t3, .argtype = SP_ARGTYPE_UNKNOWN, .lineno = lineno}; | 134 | sp_parsed_keyword kw = {.kw = (char*)t1, .kwlen = t2-t1, .arg = (char*)t3, .arglen = t4-t3, .argtype = SP_ARGTYPE_UNKNOWN, .lineno = lineno}; |
| 113 | if (t3 && t4) { | 135 | if (t3 && t4) { |
| 114 | if (t3 == t4) { | 136 | if (t3 == t4) { |
| 115 | kw.argtype = SP_ARGTYPE_EMPTY; | 137 | kw.argtype = SP_ARGTYPE_EMPTY; |
| 116 | } else if (t4-t2 >= 2) { | 138 | } else if (t4-t3 >= 2 && *t3 == '"') { |
| 117 | kw.arg = (char*)t3 + 1; | 139 | kw.arg = (char*)t3 + 1; |
| 118 | kw.arglen = t4 - t3 - 2; | 140 | kw.arglen = t4 - t3 - 2; |
| 119 | kw.argtype = SP_ARGTYPE_STR; | 141 | kw.argtype = SP_ARGTYPE_STR; |
| 142 | } else { | ||
| 143 | zend_string *tmp = zend_hash_str_find_ptr(&vars, t3, t4-t3); | ||
| 144 | if (!tmp) { | ||
| 145 | cs_error_log("unknown variable on line %d", lineno); | ||
| 146 | goto out; | ||
| 147 | } | ||
| 148 | kw.arg = ZSTR_VAL(tmp); | ||
| 149 | kw.arglen = ZSTR_LEN(tmp); | ||
| 150 | kw.argtype = SP_ARGTYPE_STR; | ||
| 120 | } | 151 | } |
| 121 | } else { | 152 | } else { |
| 122 | kw.argtype = SP_ARGTYPE_NONE; | 153 | kw.argtype = SP_ARGTYPE_NONE; |
| @@ -128,12 +159,14 @@ zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_key | |||
| 128 | end_of_rule: | 159 | end_of_rule: |
| 129 | parsed_rule[kw_i++] = (sp_parsed_keyword){0, 0, 0, 0, 0, 0}; | 160 | parsed_rule[kw_i++] = (sp_parsed_keyword){0, 0, 0, 0, 0, 0}; |
| 130 | if (process_rule && process_rule(parsed_rule) != SUCCESS) { | 161 | if (process_rule && process_rule(parsed_rule) != SUCCESS) { |
| 131 | return FAILURE; | 162 | goto out; |
| 132 | } | 163 | } |
| 133 | goto yyc_init; | 164 | goto yyc_init; |
| 134 | } | 165 | } |
| 135 | <rule> * { goto end_of_rule; } | 166 | <rule> * { goto end_of_rule; } |
| 136 | 167 | ||
| 137 | */ | 168 | */ |
| 138 | return FAILURE; | 169 | out: |
| 170 | zend_hash_destroy(&vars); | ||
| 171 | return ret; | ||
| 139 | } \ No newline at end of file | 172 | } \ No newline at end of file |
