summaryrefslogtreecommitdiff
path: root/src/sp_var_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sp_var_parser.c')
-rw-r--r--src/sp_var_parser.c102
1 files changed, 53 insertions, 49 deletions
diff --git a/src/sp_var_parser.c b/src/sp_var_parser.c
index 3f3dcdc..55cbfc2 100644
--- a/src/sp_var_parser.c
+++ b/src/sp_var_parser.c
@@ -1,7 +1,7 @@
1#include "php_snuffleupagus.h" 1#include "php_snuffleupagus.h"
2 2
3static int parse_str_tokens(const char *str, const sp_conf_token token, 3static int parse_str_tokens(const char *str, const sp_conf_token token,
4 sp_list_node *tokens_list) { 4 sp_list_node *tokens_list) {
5 const char *cur_str = str; 5 const char *cur_str = str;
6 6
7 while ((cur_str = strchr(cur_str, token.text_repr[0]))) { 7 while ((cur_str = strchr(cur_str, token.text_repr[0]))) {
@@ -30,23 +30,24 @@ static bool is_var_name_valid(const char *name) {
30 } 30 }
31 if (NULL == regexp_var || NULL == regexp_const) { 31 if (NULL == regexp_var || NULL == regexp_const) {
32 regexp_var = sp_pcre_compile(REGEXP_VAR, PCRE_CASELESS, &pcre_error, 32 regexp_var = sp_pcre_compile(REGEXP_VAR, PCRE_CASELESS, &pcre_error,
33 &pcre_error_offset, NULL); 33 &pcre_error_offset, NULL);
34 regexp_const = sp_pcre_compile(REGEXP_CONST, PCRE_CASELESS, &pcre_error, 34 regexp_const = sp_pcre_compile(REGEXP_CONST, PCRE_CASELESS, &pcre_error,
35 &pcre_error_offset, NULL); 35 &pcre_error_offset, NULL);
36 } 36 }
37 if (NULL == regexp_var || NULL == regexp_const) { 37 if (NULL == regexp_var || NULL == regexp_const) {
38 sp_log_err("config", "Could not compile regexp."); 38 sp_log_err("config", "Could not compile regexp.");
39 return false; 39 return false;
40 } 40 }
41 if (0 > sp_pcre_exec(regexp_var, NULL, name, strlen(name), 0, 0, NULL, 0) 41 if (0 > sp_pcre_exec(regexp_var, NULL, name, strlen(name), 0, 0, NULL, 0) &&
42 && 0 > sp_pcre_exec(regexp_const, NULL, name, strlen(name), 0, 0, NULL, 0)) { 42 0 > sp_pcre_exec(regexp_const, NULL, name, strlen(name), 0, 0, NULL, 0)) {
43 return false; 43 return false;
44 } 44 }
45 return true; 45 return true;
46} 46}
47 47
48static int create_var(sp_tree *tree, const char *restrict value, 48static int create_var(sp_tree *tree, const char *restrict value,
49 size_t value_len, elem_type _type, const char *restrict idx) { 49 size_t value_len, elem_type _type,
50 const char *restrict idx) {
50 sp_tree *var_node = NULL; 51 sp_tree *var_node = NULL;
51 52
52 if (!tree) { 53 if (!tree) {
@@ -72,7 +73,8 @@ static int create_var(sp_tree *tree, const char *restrict value,
72 sp_log_err("config", "Can't allocate a strndup"); 73 sp_log_err("config", "Can't allocate a strndup");
73 return -1; 74 return -1;
74 } 75 }
75 if (var_node->type != INTERPRETED_STRING && !is_var_name_valid(var_node->value)) { 76 if (var_node->type != INTERPRETED_STRING &&
77 !is_var_name_valid(var_node->value)) {
76 sp_log_err("config", "Invalid var name: %s.", var_node->value); 78 sp_log_err("config", "Invalid var name: %s.", var_node->value);
77 return -1; 79 return -1;
78 } 80 }
@@ -88,22 +90,23 @@ static int create_var(sp_tree *tree, const char *restrict value,
88} 90}
89 91
90int cmp_tokens(sp_list_node *list1, sp_list_node *list2) { 92int cmp_tokens(sp_list_node *list1, sp_list_node *list2) {
91 return (((sp_conf_token *)list1->data)->pos 93 return (((sp_conf_token *)list1->data)->pos -
92 - ((sp_conf_token *)list2->data)->pos); 94 ((sp_conf_token *)list2->data)->pos);
93} 95}
94 96
95static int is_next_token_empty(sp_conf_token *token, sp_conf_token *token_next, 97static int is_next_token_empty(sp_conf_token *token, sp_conf_token *token_next,
96 const char * restrict str) { 98 const char *restrict str) {
97 if ((token_next && token_next->pos == token->pos + strlen(token->text_repr)) 99 if ((token_next &&
98 || (!token_next && token->pos == strlen(str) - strlen(token->text_repr))) { 100 token_next->pos == token->pos + strlen(token->text_repr)) ||
101 (!token_next && token->pos == strlen(str) - strlen(token->text_repr))) {
99 return -1; 102 return -1;
100 } 103 }
101 return 0; 104 return 0;
102} 105}
103 106
104static int is_token_valid(sp_list_node *tokens_list, elem_type quote, 107static int is_token_valid(sp_list_node *tokens_list, elem_type quote,
105 int array_count, const char * restrict str, 108 int array_count, const char *restrict str,
106 size_t pos) { 109 size_t pos) {
107 sp_conf_token *token = (sp_conf_token *)tokens_list->data; 110 sp_conf_token *token = (sp_conf_token *)tokens_list->data;
108 sp_conf_token *token_next = NULL; 111 sp_conf_token *token_next = NULL;
109 112
@@ -114,40 +117,40 @@ static int is_token_valid(sp_list_node *tokens_list, elem_type quote,
114 case LITERAL_STRING: 117 case LITERAL_STRING:
115 case INTERPRETED_STRING: 118 case INTERPRETED_STRING:
116 if (quote == token->type) { 119 if (quote == token->type) {
117 if (token_next) { 120 if (token_next) {
118 if (token_next->pos != token->pos + 1) { 121 if (token_next->pos != token->pos + 1) {
119 return -1; 122 return -1;
120 } 123 }
121 } else if (token->pos != strlen(str) - 1) { 124 } else if (token->pos != strlen(str) - 1) {
122 return -1; 125 return -1;
123 } 126 }
124 } 127 }
125 break; 128 break;
126 case ARRAY_END: 129 case ARRAY_END:
127 if (!quote) { 130 if (!quote) {
128 if (array_count < 1) { 131 if (array_count < 1) {
129 return -1; 132 return -1;
130 } else if (token_next) { 133 } else if (token_next) {
131 if (token_next->type == INTERPRETED_STRING 134 if (token_next->type == INTERPRETED_STRING ||
132 || token_next->type == LITERAL_STRING) { 135 token_next->type == LITERAL_STRING) {
133 return -1; 136 return -1;
134 } 137 }
135 } else if (token->pos != strlen(str) - strlen(token->text_repr)) { 138 } else if (token->pos != strlen(str) - strlen(token->text_repr)) {
136 return -1; 139 return -1;
137 } 140 }
138 } 141 }
139 break; 142 break;
140 case OBJECT: 143 case OBJECT:
141 if (!quote && -1 == is_next_token_empty(token, token_next, str)) { 144 if (!quote && -1 == is_next_token_empty(token, token_next, str)) {
142 return -1; 145 return -1;
143 } 146 }
144 if (pos == 0 && *str != VARIABLE_TOKEN) { 147 if (pos == 0 && *str != VARIABLE_TOKEN) {
145 return -1; 148 return -1;
146 } 149 }
147 break; 150 break;
148 case CLASS: 151 case CLASS:
149 if (!quote && -1 == is_next_token_empty(token, token_next, str)) { 152 if (!quote && -1 == is_next_token_empty(token, token_next, str)) {
150 return -1; 153 return -1;
151 } 154 }
152 break; 155 break;
153 default: 156 default:
@@ -156,8 +159,8 @@ static int is_token_valid(sp_list_node *tokens_list, elem_type quote,
156 return 0; 159 return 0;
157} 160}
158 161
159static sp_tree *parse_tokens(const char * restrict str, 162static sp_tree *parse_tokens(const char *restrict str,
160 sp_list_node *tokens_list) { 163 sp_list_node *tokens_list) {
161 size_t pos = 0; 164 size_t pos = 0;
162 int array_count = 0, pos_idx_start = -1; 165 int array_count = 0, pos_idx_start = -1;
163 elem_type quote = 0; 166 elem_type quote = 0;
@@ -179,7 +182,9 @@ static sp_tree *parse_tokens(const char * restrict str,
179 } 182 }
180 if (quote == 0) { 183 if (quote == 0) {
181 if (token->type == ARRAY) { 184 if (token->type == ARRAY) {
182 pos_idx_start = (array_count) ? pos_idx_start : (int)(token->pos + strlen(token->text_repr)); 185 pos_idx_start = (array_count)
186 ? pos_idx_start
187 : (int)(token->pos + strlen(token->text_repr));
183 array_count++; 188 array_count++;
184 } else if (token->type == ARRAY_END) { 189 } else if (token->type == ARRAY_END) {
185 array_count--; 190 array_count--;
@@ -210,12 +215,12 @@ static sp_tree *parse_tokens(const char * restrict str,
210 } 215 }
211 if (quote != 0) { 216 if (quote != 0) {
212 sp_log_err("config", "Missing a closing quote."); 217 sp_log_err("config", "Missing a closing quote.");
213error: 218 error:
214 sp_tree_free(tree); 219 sp_tree_free(tree);
215 return NULL; 220 return NULL;
216 } 221 }
217 if (pos != strlen(str) 222 if (pos != strlen(str) &&
218 && create_var(tree, &str[pos], strlen(str) - pos, CONSTANT, NULL)) { 223 create_var(tree, &str[pos], strlen(str) - pos, CONSTANT, NULL)) {
219 goto error; 224 goto error;
220 } 225 }
221 return tree; 226 return tree;
@@ -225,20 +230,19 @@ sp_tree *parse_var(const char *line) {
225 sp_list_node *tokens_list = NULL; 230 sp_list_node *tokens_list = NULL;
226 sp_tree *tree = NULL; 231 sp_tree *tree = NULL;
227 const sp_conf_token delimiter_list[] = { 232 const sp_conf_token delimiter_list[] = {
228 {.type=OBJECT, .text_repr=OBJECT_TOKEN}, 233 {.type = OBJECT, .text_repr = OBJECT_TOKEN},
229 {.type=ARRAY, .text_repr=ARRAY_TOKEN}, 234 {.type = ARRAY, .text_repr = ARRAY_TOKEN},
230 {.type=ARRAY_END, .text_repr=ARRAY_END_TOKEN}, 235 {.type = ARRAY_END, .text_repr = ARRAY_END_TOKEN},
231 {.type=INTERPRETED_STRING, .text_repr=STRING_TOKEN}, 236 {.type = INTERPRETED_STRING, .text_repr = STRING_TOKEN},
232 {.type=LITERAL_STRING, .text_repr=ESC_STRING_TOKEN}, 237 {.type = LITERAL_STRING, .text_repr = ESC_STRING_TOKEN},
233 {.type=CLASS, .text_repr=CLASS_TOKEN} 238 {.type = CLASS, .text_repr = CLASS_TOKEN}};
234 };
235
236 239
237 if (!line) { 240 if (!line) {
238 return NULL; 241 return NULL;
239 } 242 }
240 tokens_list = sp_list_new(); 243 tokens_list = sp_list_new();
241 for (unsigned int i = 0; i < sizeof(delimiter_list) / sizeof(sp_conf_token); i++) { 244 for (unsigned int i = 0; i < sizeof(delimiter_list) / sizeof(sp_conf_token);
245 i++) {
242 parse_str_tokens(line, delimiter_list[i], tokens_list); 246 parse_str_tokens(line, delimiter_list[i], tokens_list);
243 } 247 }
244 tokens_list = sp_list_sort(tokens_list, cmp_tokens); 248 tokens_list = sp_list_sort(tokens_list, cmp_tokens);