1 /*
2  Copyright (C) 2016-2017 Alexander Borisov
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 
18  Author: lex.borisov@gmail.com (Alexander Borisov)
19 */
20 
21 #include "mycss/selectors/state.h"
22 
mycss_selectors_state_end(mycss_entry_t * entry)23 void mycss_selectors_state_end(mycss_entry_t* entry)
24 {
25     mycss_selectors_entry_t* selector = entry->selectors->entry_last;
26 
27     if(selector == NULL)
28         return;
29 
30     if(selector->type == MyCSS_SELECTORS_TYPE_ATTRIBUTE ||
31        selector->type == MyCSS_SELECTORS_TYPE_PSEUDO_CLASS_FUNCTION ||
32        (selector->key == NULL && selector->value == NULL))
33     {
34         mycss_selectors_entry_clean(selector);
35     }
36     else {
37         mycss_selectors_parser_selector_end(entry, NULL);
38     }
39 }
40 
41 /* for unknown functions */
mycss_selectors_state_function_skip_all(mycss_entry_t * entry,mycss_token_t * token,bool last_response)42 bool mycss_selectors_state_function_skip_all(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
43 {
44 //    if(token->type == MyCSS_TOKEN_TYPE_RIGHT_PARENTHESIS)
45 //        return entry->parser_switch(entry, token);
46 
47     return true;
48 }
49 
50 /* <drop> */
mycss_selectors_state_drop(mycss_entry_t * entry,mycss_token_t * token,bool last_response)51 bool mycss_selectors_state_drop(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
52 {
53     switch (token->type) {
54         case MyCSS_TOKEN_TYPE_WHITESPACE:
55             break;
56 
57         case MyCSS_TOKEN_TYPE_LEFT_CURLY_BRACKET: {
58             if(mycss_entry_parser_list_length(entry) == 0) {
59                 entry->parser = mycss_selectors_state_drop_component_value;
60             }
61             else if(mycss_entry_parser_list_length(entry) <= 1) {
62                 mycss_entry_parser_list_pop(entry);
63 
64             }
65             return false;
66         }
67         default:
68             if(entry->selectors->list_last)
69                 entry->selectors->list_last->flags |= MyCSS_SELECTORS_FLAGS_SELECTOR_BAD;
70 
71             entry->parser = mycss_selectors_state_drop_component_value;
72             return false;
73     }
74 
75     return true;
76 }
77 
mycss_selectors_state_drop_component_value(mycss_entry_t * entry,mycss_token_t * token,bool last_response)78 bool mycss_selectors_state_drop_component_value(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
79 {
80     if(token->type == entry->selectors->ending_token) {
81         if(mycss_entry_parser_list_current_is_local(entry) == false) {
82             mycss_entry_parser_list_pop(entry);
83             return true;
84         }
85     }
86 
87     switch (token->type) {
88         case MyCSS_TOKEN_TYPE_WHITESPACE:
89             break;
90 
91         case MyCSS_TOKEN_TYPE_FUNCTION: {
92             mycss_entry_parser_list_push(entry, mycss_selectors_state_drop_component_value, NULL, entry->parser_ending_token, true);
93             entry->parser_ending_token = MyCSS_TOKEN_TYPE_RIGHT_PARENTHESIS;
94 
95             break;
96         }
97         case MyCSS_TOKEN_TYPE_LEFT_CURLY_BRACKET: {
98             mycss_entry_parser_list_push(entry, mycss_selectors_state_drop_component_value, NULL, entry->parser_ending_token, true);
99             entry->parser_ending_token = MyCSS_TOKEN_TYPE_RIGHT_CURLY_BRACKET;
100 
101             break;
102         }
103         case MyCSS_TOKEN_TYPE_LEFT_SQUARE_BRACKET: {
104             mycss_entry_parser_list_push(entry, mycss_selectors_state_drop_component_value, NULL, entry->parser_ending_token, true);
105             entry->parser_ending_token = MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET;
106 
107             break;
108         }
109         case MyCSS_TOKEN_TYPE_LEFT_PARENTHESIS: {
110             mycss_entry_parser_list_push(entry, mycss_selectors_state_drop_component_value, NULL, entry->parser_ending_token, true);
111             entry->parser_ending_token = MyCSS_TOKEN_TYPE_RIGHT_PARENTHESIS;
112 
113             break;
114         }
115         default: {
116             if(mycss_entry_parser_list_current_is_local(entry) &&
117                token->type == entry->parser_ending_token)
118             {
119                 mycss_entry_parser_list_pop(entry);
120             }
121 
122             break;
123         }
124     }
125 
126     return true;
127 }
128 
129 /* <combinator> */
mycss_selectors_state_combinator(mycss_entry_t * entry,mycss_token_t * token,bool last_response)130 bool mycss_selectors_state_combinator(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
131 {
132     switch (token->type) {
133         case MyCSS_TOKEN_TYPE_COLUMN: {
134             *entry->selectors->combinator = MyCSS_SELECTORS_COMBINATOR_COLUMN;
135             MyCORE_DEBUG("mycss_selectors_state_combinator_column");
136             entry->parser = entry->parser_switch;
137             break;
138         }
139         case MyCSS_TOKEN_TYPE_DELIM: {
140             if(*token->data == '+') {
141                 *entry->selectors->combinator = MyCSS_SELECTORS_COMBINATOR_NEXT_SIBLING;
142                 MyCORE_DEBUG("mycss_selectors_state_combinator_plus");
143                 entry->parser = entry->parser_switch;
144             }
145             else if(*token->data == '>') {
146                 *entry->selectors->combinator = MyCSS_SELECTORS_COMBINATOR_CHILD;
147                 MyCORE_DEBUG("mycss_selectors_state_combinator_greater_than");
148                 entry->parser = mycss_selectors_state_combinator_greater_than;
149             }
150             else if(*token->data == '~') {
151                 *entry->selectors->combinator = MyCSS_SELECTORS_COMBINATOR_FOLLOWING_SIBLING;
152                 MyCORE_DEBUG("mycss_selectors_state_combinator_tilde");
153                 entry->parser = entry->parser_switch;
154             }
155             else {
156                 *entry->selectors->combinator = MyCSS_SELECTORS_COMBINATOR_UNDEF;
157                 entry->parser = entry->parser_switch;
158                 return false;
159             }
160 
161             break;
162         }
163         default: {
164             *entry->selectors->combinator = MyCSS_SELECTORS_COMBINATOR_UNDEF;
165             entry->parser = entry->parser_switch;
166             return false;
167         }
168     }
169 
170     return true;
171 }
172 
mycss_selectors_state_combinator_greater_than(mycss_entry_t * entry,mycss_token_t * token,bool last_response)173 bool mycss_selectors_state_combinator_greater_than(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
174 {
175     if(token->type == MyCSS_TOKEN_TYPE_DELIM) {
176         if(*token->data == '>') {
177             *entry->selectors->combinator = MyCSS_SELECTORS_COMBINATOR_DESCENDANT;
178             MyCORE_DEBUG("mycss_selectors_state_combinator_greater_than_greater_than");
179             entry->parser = entry->parser_switch;
180         }
181         else {
182             entry->parser = entry->parser_switch;
183             return false;
184         }
185     }
186     else {
187         entry->parser = entry->parser_switch;
188         return false;
189     }
190 
191     return true;
192 }
193 
194 /* <complex-selector-list> */
mycss_selectors_state_complex_selector_list(mycss_entry_t * entry,mycss_token_t * token,bool last_response)195 bool mycss_selectors_state_complex_selector_list(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
196 {
197     mycss_selectors_t *selectors = entry->selectors;
198 
199     mycss_selectors_list_t *sel_list = mycss_selectors_list_create(entry->selectors);
200     mycss_selectors_list_append_to_current(entry->selectors, sel_list);
201 
202     mycss_selectors_list_append_selector(selectors, sel_list, NULL);
203     selectors->entry = &sel_list->entries_list[0].entry;
204     selectors->entry_last = NULL;
205 
206     entry->parser = mycss_selectors_state_complex_selector_list_need_selector;
207     return false;
208 }
209 
mycss_selectors_state_complex_selector_list_need_selector(mycss_entry_t * entry,mycss_token_t * token,bool last_response)210 bool mycss_selectors_state_complex_selector_list_need_selector(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
211 {
212     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE) {
213         return true;
214     }
215     else if(token->type == entry->selectors->ending_token) {
216         if(entry->selectors->list_last)
217             entry->selectors->list_last->flags |= MyCSS_SELECTORS_FLAGS_SELECTOR_BAD;
218 
219         mycss_entry_parser_list_pop(entry);
220         return false;
221     }
222 
223     entry->parser_switch = mycss_selectors_state_complex_selector_list_need_combinator_or_selector;
224 
225     if(entry->selectors->entry_last && entry->selectors->entry_last->key == NULL) {
226         if(mycss_selectors_state_simple_selector(entry, token, true))
227             return true;
228     }
229     else {
230         if(mycss_selectors_state_simple_selector_begin(entry, token, true))
231             return true;
232     }
233 
234     entry->parser = mycss_selectors_state_drop;
235 
236     return false;
237 }
238 
mycss_selectors_state_complex_selector_list_need_combinator_or_selector(mycss_entry_t * entry,mycss_token_t * token,bool last_response)239 bool mycss_selectors_state_complex_selector_list_need_combinator_or_selector(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
240 {
241     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE) {
242         entry->parser = mycss_selectors_state_complex_selector_list_need_combinator_or_selector_ws;
243         return true;
244     }
245     else if(token->type == MyCSS_TOKEN_TYPE_COMMA) {
246         mycss_selectors_t *selectors = entry->selectors;
247 
248         mycss_selectors_list_append_selector(selectors, selectors->list_last, NULL);
249 
250         selectors->entry = &selectors->list_last->entries_list[ (selectors->list_last->entries_list_length - 1) ].entry;
251         selectors->entry_last = NULL;
252 
253         entry->parser = mycss_selectors_state_complex_selector_list_need_selector;
254         return true;
255     }
256     else if(token->type == entry->selectors->ending_token) {
257         mycss_entry_parser_list_pop(entry);
258         return false;
259     }
260 
261     entry->parser_switch = mycss_selectors_state_complex_selector_list_need_combinator_or_selector;
262 
263     if(mycss_selectors_state_simple_selector_begin(entry, token, true))
264         return true;
265 
266     entry->parser = mycss_selectors_state_drop;
267 
268     return false;
269 }
270 
mycss_selectors_state_complex_selector_list_need_combinator_or_selector_ws(mycss_entry_t * entry,mycss_token_t * token,bool last_response)271 bool mycss_selectors_state_complex_selector_list_need_combinator_or_selector_ws(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
272 {
273     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE) {
274         return true;
275     }
276     else if(token->type == MyCSS_TOKEN_TYPE_COMMA) {
277         mycss_selectors_t *selectors = entry->selectors;
278 
279         mycss_selectors_list_append_selector(selectors, selectors->list_last, NULL);
280 
281         selectors->entry = &selectors->list_last->entries_list[ (selectors->list_last->entries_list_length - 1) ].entry;
282         selectors->entry_last = NULL;
283 
284         entry->parser = mycss_selectors_state_complex_selector_list_need_selector;
285         return true;
286     }
287     else if(token->type == entry->selectors->ending_token) {
288         mycss_entry_parser_list_pop(entry);
289         return false;
290     }
291 
292     entry->parser_switch = mycss_selectors_state_complex_selector_list_need_combinator_or_selector;
293 
294     if(mycss_selectors_state_simple_selector_begin(entry, token, true)) {
295         entry->selectors->entry_last->combinator = MyCSS_SELECTORS_COMBINATOR_DESCENDANT;
296         return true;
297     }
298 
299     entry->parser_switch = mycss_selectors_state_complex_selector_list_need_selector;
300     entry->selectors->combinator = &entry->selectors->entry_last->combinator;
301 
302     if(mycss_selectors_state_combinator(entry, token, true))
303         return true;
304 
305     entry->parser = mycss_selectors_state_drop;
306 
307     return false;
308 }
309 
310 /* <compound-selector-list> */
mycss_selectors_state_compound_selector_list(mycss_entry_t * entry,mycss_token_t * token,bool last_response)311 bool mycss_selectors_state_compound_selector_list(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
312 {
313     mycss_selectors_t *selectors = entry->selectors;
314 
315     mycss_selectors_list_t *sel_list = mycss_selectors_list_create(entry->selectors);
316     mycss_selectors_list_append_to_current(entry->selectors, sel_list);
317 
318     mycss_selectors_list_append_selector(selectors, sel_list, NULL);
319     selectors->entry = &sel_list->entries_list[0].entry;
320     selectors->entry_last = NULL;
321 
322     entry->parser = mycss_selectors_state_compound_selector_list_comma_ws;
323     return false;
324 }
325 
mycss_selectors_state_compound_selector_list_need_selector(mycss_entry_t * entry,mycss_token_t * token,bool last_response)326 bool mycss_selectors_state_compound_selector_list_need_selector(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
327 {
328     if(token->type == entry->selectors->ending_token) {
329         if(entry->selectors->list_last)
330             entry->selectors->list_last->flags |= MyCSS_SELECTORS_FLAGS_SELECTOR_BAD;
331 
332         mycss_entry_parser_list_pop(entry);
333         return false;
334     }
335 
336     entry->parser_switch = mycss_selectors_state_compound_selector_list_need_selector_or_comma;
337 
338     if(mycss_selectors_state_simple_selector_begin(entry, token, true))
339         return true;
340 
341     entry->parser = mycss_selectors_state_drop;
342 
343     return false;
344 }
345 
mycss_selectors_state_compound_selector_list_need_selector_or_comma(mycss_entry_t * entry,mycss_token_t * token,bool last_response)346 bool mycss_selectors_state_compound_selector_list_need_selector_or_comma(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
347 {
348     if(token->type == MyCSS_TOKEN_TYPE_COMMA) {
349         mycss_selectors_t *selectors = entry->selectors;
350 
351         mycss_selectors_list_append_selector(selectors, selectors->list_last, NULL);
352 
353         selectors->entry = &selectors->list_last->entries_list[ (selectors->list_last->entries_list_length - 1) ].entry;
354         selectors->entry_last = NULL;
355 
356         entry->parser = mycss_selectors_state_compound_selector_list_comma_ws;
357         return true;
358     }
359     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE) {
360         entry->parser = mycss_selectors_state_compound_selector_list_need_ending_or_comma;
361         return true;
362     }
363     else if(token->type == entry->selectors->ending_token) {
364         mycss_entry_parser_list_pop(entry);
365         return false;
366     }
367 
368     if(mycss_selectors_state_simple_selector_begin(entry, token, true))
369         return true;
370 
371     entry->parser = mycss_selectors_state_drop;
372 
373     return false;
374 }
375 
mycss_selectors_state_compound_selector_list_comma_ws(mycss_entry_t * entry,mycss_token_t * token,bool last_response)376 bool mycss_selectors_state_compound_selector_list_comma_ws(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
377 {
378     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE)
379         return true;
380 
381     entry->parser = mycss_selectors_state_compound_selector_list_need_selector;
382 
383     return false;
384 }
385 
mycss_selectors_state_compound_selector_list_need_ending_or_comma(mycss_entry_t * entry,mycss_token_t * token,bool last_response)386 bool mycss_selectors_state_compound_selector_list_need_ending_or_comma(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
387 {
388     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE) {
389         return true;
390     }
391     if(token->type == MyCSS_TOKEN_TYPE_COMMA) {
392         mycss_selectors_t *selectors = entry->selectors;
393 
394         mycss_selectors_list_append_selector(selectors, selectors->list_last, NULL);
395 
396         selectors->entry = &selectors->list_last->entries_list[ (selectors->list_last->entries_list_length - 1) ].entry;
397         selectors->entry_last = NULL;
398 
399         entry->parser = mycss_selectors_state_compound_selector_list_comma_ws;
400         return true;
401     }
402     else if(token->type == entry->selectors->ending_token) {
403         mycss_entry_parser_list_pop(entry);
404         return false;
405     }
406 
407     entry->parser = mycss_selectors_state_drop;
408 
409     return false;
410 }
411 
412 /* <relative-selector-list> */
mycss_selectors_state_relative_selector_list(mycss_entry_t * entry,mycss_token_t * token,bool last_response)413 bool mycss_selectors_state_relative_selector_list(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
414 {
415     mycss_selectors_t *selectors = entry->selectors;
416 
417     mycss_selectors_list_t *sel_list = mycss_selectors_list_create(entry->selectors);
418     mycss_selectors_list_append_to_current(entry->selectors, sel_list);
419 
420     mycss_selectors_list_append_selector(selectors, sel_list, NULL);
421     selectors->entry = &sel_list->entries_list[0].entry;
422     selectors->entry_last = NULL;
423 
424     entry->parser = mycss_selectors_state_relative_selector_list_need_combinator_or_selector_begin;
425     return false;
426 }
427 
mycss_selectors_state_relative_selector_list_need_selector(mycss_entry_t * entry,mycss_token_t * token,bool last_response)428 bool mycss_selectors_state_relative_selector_list_need_selector(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
429 {
430     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE) {
431         return true;
432     }
433     if(token->type == entry->selectors->ending_token) {
434         if(entry->selectors->list_last)
435             entry->selectors->list_last->flags |= MyCSS_SELECTORS_FLAGS_SELECTOR_BAD;
436 
437         mycss_entry_parser_list_pop(entry);
438         return false;
439     }
440 
441     entry->parser_switch = mycss_selectors_state_relative_selector_list_need_combinator_or_selector;
442 
443     if(entry->selectors->entry_last && entry->selectors->entry_last->key == NULL) {
444         if(mycss_selectors_state_simple_selector(entry, token, true))
445             return true;
446     }
447     else {
448         if(mycss_selectors_state_simple_selector_begin(entry, token, true))
449             return true;
450     }
451 
452     entry->parser = mycss_selectors_state_drop;
453 
454     return false;
455 }
456 
mycss_selectors_state_relative_selector_list_need_combinator_or_selector_begin(mycss_entry_t * entry,mycss_token_t * token,bool last_response)457 bool mycss_selectors_state_relative_selector_list_need_combinator_or_selector_begin(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
458 {
459     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE) {
460         return true;
461     }
462     else if(token->type == entry->selectors->ending_token) {
463         if(entry->selectors->list_last)
464             entry->selectors->list_last->flags |= MyCSS_SELECTORS_FLAGS_SELECTOR_BAD;
465 
466         mycss_entry_parser_list_pop(entry);
467         return false;
468     }
469 
470     entry->parser_switch = mycss_selectors_state_relative_selector_list_need_combinator_or_selector;
471 
472     if(mycss_selectors_state_simple_selector_begin(entry, token, true))
473         return true;
474 
475     entry->parser_switch = mycss_selectors_state_relative_selector_list_need_selector;
476     entry->selectors->combinator = &entry->selectors->entry_last->combinator;
477 
478     if(mycss_selectors_state_combinator(entry, token, true))
479         return true;
480 
481     entry->parser = mycss_selectors_state_drop;
482 
483     return false;
484 }
485 
486 
mycss_selectors_state_relative_selector_list_need_combinator_or_selector(mycss_entry_t * entry,mycss_token_t * token,bool last_response)487 bool mycss_selectors_state_relative_selector_list_need_combinator_or_selector(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
488 {
489     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE) {
490         entry->parser = mycss_selectors_state_relative_selector_list_need_combinator_or_selector_ws;
491         return true;
492     }
493     else if(token->type == MyCSS_TOKEN_TYPE_COMMA) {
494         mycss_selectors_t *selectors = entry->selectors;
495 
496         mycss_selectors_list_append_selector(selectors, selectors->list_last, NULL);
497 
498         selectors->entry = &selectors->list_last->entries_list[ (selectors->list_last->entries_list_length - 1) ].entry;
499         selectors->entry_last = NULL;
500 
501         entry->parser = mycss_selectors_state_relative_selector_list_need_combinator_or_selector_begin;
502         return true;
503     }
504     else if(token->type == entry->selectors->ending_token) {
505         mycss_entry_parser_list_pop(entry);
506         return false;
507     }
508 
509     entry->parser_switch = mycss_selectors_state_relative_selector_list_need_combinator_or_selector;
510 
511     if(mycss_selectors_state_simple_selector_begin(entry, token, true))
512         return true;
513 
514     entry->parser_switch = mycss_selectors_state_relative_selector_list_need_selector;
515     entry->selectors->combinator = &entry->selectors->entry_last->combinator;
516 
517     if(mycss_selectors_state_combinator(entry, token, true))
518         return true;
519 
520     entry->parser = mycss_selectors_state_drop;
521 
522     return false;
523 }
524 
mycss_selectors_state_relative_selector_list_need_combinator_or_selector_ws(mycss_entry_t * entry,mycss_token_t * token,bool last_response)525 bool mycss_selectors_state_relative_selector_list_need_combinator_or_selector_ws(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
526 {
527     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE) {
528         return true;
529     }
530     else if(token->type == MyCSS_TOKEN_TYPE_COMMA) {
531         mycss_selectors_t *selectors = entry->selectors;
532 
533         mycss_selectors_list_append_selector(selectors, selectors->list_last, NULL);
534 
535         selectors->entry = &selectors->list_last->entries_list[ (selectors->list_last->entries_list_length - 1) ].entry;
536         selectors->entry_last = NULL;
537 
538         entry->parser = mycss_selectors_state_relative_selector_list_need_combinator_or_selector_begin;
539         return true;
540     }
541     else if(token->type == entry->selectors->ending_token) {
542         mycss_entry_parser_list_pop(entry);
543         return false;
544     }
545 
546     entry->parser_switch = mycss_selectors_state_relative_selector_list_need_combinator_or_selector;
547 
548     if(mycss_selectors_state_simple_selector_begin(entry, token, true)) {
549         entry->selectors->entry_last->combinator = MyCSS_SELECTORS_COMBINATOR_DESCENDANT;
550         return true;
551     }
552 
553     entry->parser_switch = mycss_selectors_state_relative_selector_list_need_selector;
554     entry->selectors->combinator = &entry->selectors->entry_last->combinator;
555 
556     if(mycss_selectors_state_combinator(entry, token, true))
557         return true;
558 
559     entry->parser = mycss_selectors_state_drop;
560 
561     return false;
562 }
563 
564 /* <simple-selector> */
mycss_selectors_state_simple_selector_begin(mycss_entry_t * entry,mycss_token_t * token,bool last_response)565 bool mycss_selectors_state_simple_selector_begin(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
566 {
567     mycss_selectors_parser_selector_begin(entry, token);
568     return mycss_selectors_state_simple_selector(entry, token, last_response);
569 }
570 
mycss_selectors_state_simple_selector(mycss_entry_t * entry,mycss_token_t * token,bool last_response)571 bool mycss_selectors_state_simple_selector(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
572 {
573     switch (token->type) {
574         case MyCSS_TOKEN_TYPE_IDENT: {
575             mycss_selectors_parser_selector_ident_type(entry, token);
576             MyCORE_DEBUG("mycss_selectors_state_simple_selector_ident");
577 
578             entry->parser = mycss_selectors_state_simple_selector_ident;
579             break;
580         }
581         case MyCSS_TOKEN_TYPE_DELIM: {
582             // HAND_EDIT_BEGIN
583             if(*token->data == '*') {
584                 mycss_selectors_parser_selector_ident_type(entry, token);
585                 MyCORE_DEBUG("mycss_selectors_state_simple_selector_asterisk");
586 
587                 entry->parser = mycss_selectors_state_simple_selector_ident;
588             }
589             // HAND_EDIT_END
590             else if(*token->data == '.') {
591                 entry->parser = mycss_selectors_state_simple_selector_full_stop;
592             }
593             else if(*token->data == '|') {
594                 // HAND_EDIT_BEGIN
595                 mycss_selectors_parser_selector_namespace_ident(entry, token);
596                 // HAND_EDIT_END
597                 entry->parser = mycss_selectors_state_simple_selector_vertical_bar;
598             }
599             else {
600                 entry->parser = entry->parser_switch;
601                 return false;
602             }
603 
604             break;
605         }
606         case MyCSS_TOKEN_TYPE_COLON: {
607             entry->parser = mycss_selectors_state_simple_selector_colon;
608             break;
609         }
610         case MyCSS_TOKEN_TYPE_LEFT_SQUARE_BRACKET: {
611             entry->parser = mycss_selectors_state_simple_selector_left_bracket;
612             break;
613         }
614         case MyCSS_TOKEN_TYPE_HASH: {
615             mycss_selectors_parser_selector_id(entry, token);
616             MyCORE_DEBUG("mycss_selectors_state_simple_selector_hash");
617             entry->parser = entry->parser_switch;
618             break;
619         }
620         default: {
621             entry->parser = entry->parser_switch;
622             return false;
623         }
624     }
625 
626     return true;
627 }
628 
mycss_selectors_state_simple_selector_left_bracket(mycss_entry_t * entry,mycss_token_t * token,bool last_response)629 bool mycss_selectors_state_simple_selector_left_bracket(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
630 {
631     switch (token->type) {
632         case MyCSS_TOKEN_TYPE_WHITESPACE: {
633             break;
634         }
635         case MyCSS_TOKEN_TYPE_IDENT: {
636             mycss_selectors_parser_selector_ident_attr(entry, token);
637             entry->parser = mycss_selectors_state_simple_selector_left_bracket_ident;
638 
639             break;
640         }
641         case MyCSS_TOKEN_TYPE_DELIM: {
642             if(*token->data == '*') {
643                 // HAND_EDIT_BEGIN
644                 mycss_selectors_parser_selector_ident_attr(entry, token);
645                 // HAND_EDIT_END
646                 entry->parser = mycss_selectors_state_simple_selector_left_bracket_ident;
647             }
648             else if(*token->data == '|') {
649                 // HAND_EDIT_BEGIN
650                 mycss_selectors_parser_selector_namespace_attr(entry, token);
651                 // HAND_EDIT_END
652                 entry->parser = mycss_selectors_state_simple_selector_left_bracket_vertical_bar;
653             }
654             else {
655                 mycss_selectors_parser_expectations_error(entry, token);
656 
657                 mycss_entry_parser_list_push(entry, entry->parser_switch, NULL, entry->selectors->ending_token, false);
658                 entry->selectors->ending_token = MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET;
659 
660                 entry->parser = mycss_selectors_state_drop;
661                 return false;
662             }
663 
664             break;
665         }
666         default: {
667             mycss_selectors_parser_expectations_error(entry, token);
668 
669             mycss_entry_parser_list_push(entry, entry->parser_switch, NULL, entry->selectors->ending_token, false);
670             entry->selectors->ending_token = MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET;
671 
672             entry->parser = mycss_selectors_state_drop;
673             return false;
674         }
675     }
676 
677     return true;
678 }
679 
mycss_selectors_state_simple_selector_left_bracket_vertical_bar(mycss_entry_t * entry,mycss_token_t * token,bool last_response)680 bool mycss_selectors_state_simple_selector_left_bracket_vertical_bar(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
681 {
682     if(token->type == MyCSS_TOKEN_TYPE_IDENT) {
683         mycss_selectors_parser_selector_after_namespace(entry, token);
684         entry->parser = mycss_selectors_state_left_bracket_after_wq_name_attr;
685     }
686     else {
687         mycss_selectors_parser_expectations_error(entry, token);
688 
689         mycss_entry_parser_list_push(entry, entry->parser_switch, NULL, entry->selectors->ending_token, false);
690         entry->selectors->ending_token = MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET;
691 
692         entry->parser = mycss_selectors_state_drop;
693         return false;
694     }
695 
696     return true;
697 }
698 
mycss_selectors_state_simple_selector_left_bracket_ident(mycss_entry_t * entry,mycss_token_t * token,bool last_response)699 bool mycss_selectors_state_simple_selector_left_bracket_ident(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
700 {
701     mycss_selectors_entry_t *selector = entry->selectors->entry_last;
702 
703     switch (token->type) {
704         case MyCSS_TOKEN_TYPE_WHITESPACE: {
705             entry->parser = mycss_selectors_state_left_bracket_after_wq_name_attr;
706             break;
707         }
708         case MyCSS_TOKEN_TYPE_INCLUDE_MATCH: {
709             if(selector->value == NULL)
710                 selector->value = mycss_selectors_value_attribute_create(entry, true);
711 
712             mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_INCLUDE;
713             entry->parser = mycss_selectors_state_shared_after_attr_matcher;
714             break;
715         }
716         case MyCSS_TOKEN_TYPE_DASH_MATCH: {
717             if(selector->value == NULL)
718                 selector->value = mycss_selectors_value_attribute_create(entry, true);
719 
720             mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_DASH;
721             entry->parser = mycss_selectors_state_shared_after_attr_matcher;
722             break;
723         }
724         case MyCSS_TOKEN_TYPE_PREFIX_MATCH: {
725             if(selector->value == NULL)
726                 selector->value = mycss_selectors_value_attribute_create(entry, true);
727 
728             mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_PREFIX;
729             entry->parser = mycss_selectors_state_shared_after_attr_matcher;
730             break;
731         }
732         case MyCSS_TOKEN_TYPE_SUFFIX_MATCH: {
733             if(selector->value == NULL)
734                 selector->value = mycss_selectors_value_attribute_create(entry, true);
735 
736             mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_SUFFIX;
737             entry->parser = mycss_selectors_state_shared_after_attr_matcher;
738             break;
739         }
740         case MyCSS_TOKEN_TYPE_SUBSTRING_MATCH: {
741             if(selector->value == NULL)
742                 selector->value = mycss_selectors_value_attribute_create(entry, true);
743 
744             mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_SUBSTRING;
745             entry->parser = mycss_selectors_state_shared_after_attr_matcher;
746             break;
747         }
748         case MyCSS_TOKEN_TYPE_DELIM: {
749             if(*token->data == '=') {
750                 if(selector->value == NULL)
751                     selector->value = mycss_selectors_value_attribute_create(entry, true);
752 
753                 mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_EQUAL;
754                 entry->parser = mycss_selectors_state_shared_after_attr_matcher;
755             }
756             else if(*token->data == '|') {
757                 // HAND_EDIT_BEGIN
758                 mycss_selectors_parser_selector_namespace_attr(entry, token);
759                 // HAND_EDIT_END
760                 entry->parser = mycss_selectors_state_simple_selector_left_bracket_ident_vertical_bar;
761             }
762             else {
763                 mycss_selectors_parser_expectations_error(entry, token);
764 
765                 mycss_entry_parser_list_push(entry, entry->parser_switch, NULL, entry->selectors->ending_token, false);
766                 entry->selectors->ending_token = MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET;
767 
768                 entry->parser = mycss_selectors_state_drop;
769                 return false;
770             }
771             break;
772         }
773         case MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET: {
774             mycss_selectors_parser_selector_end(entry, token);
775             MyCORE_DEBUG("mycss_selectors_state_simple_selector_left_bracket_ident_right_bracket");
776             entry->parser = entry->parser_switch;
777             break;
778         }
779         default: {
780             mycss_selectors_parser_expectations_error(entry, token);
781 
782             mycss_entry_parser_list_push(entry, entry->parser_switch, NULL, entry->selectors->ending_token, false);
783             entry->selectors->ending_token = MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET;
784 
785             entry->parser = mycss_selectors_state_drop;
786             return false;
787         }
788     }
789 
790     return true;
791 }
792 
mycss_selectors_state_simple_selector_left_bracket_ident_vertical_bar(mycss_entry_t * entry,mycss_token_t * token,bool last_response)793 bool mycss_selectors_state_simple_selector_left_bracket_ident_vertical_bar(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
794 {
795     if(token->type == MyCSS_TOKEN_TYPE_IDENT) {
796         mycss_selectors_parser_selector_after_namespace(entry, token);
797         entry->parser = mycss_selectors_state_left_bracket_after_wq_name_attr;
798     }
799     else {
800         mycss_selectors_parser_expectations_error(entry, token);
801 
802         mycss_entry_parser_list_push(entry, entry->parser_switch, NULL, entry->selectors->ending_token, false);
803         entry->selectors->ending_token = MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET;
804 
805         entry->parser = mycss_selectors_state_drop;
806         return false;
807     }
808 
809     return true;
810 }
811 
812 // HAND_EDIT_BEGIN
mycss_selectors_state_simple_selector_colon(mycss_entry_t * entry,mycss_token_t * token,bool last_response)813 bool mycss_selectors_state_simple_selector_colon(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
814 {
815     switch (token->type) {
816         case MyCSS_TOKEN_TYPE_IDENT: {
817             mycss_selectors_parser_selector_pseudo_class(entry, token);
818             MyCORE_DEBUG("mycss_selectors_state_simple_selector_colon_ident");
819             entry->parser = entry->parser_switch;
820             break;
821         }
822         case MyCSS_TOKEN_TYPE_COLON: {
823             entry->parser = mycss_selectors_state_simple_selector_colon_colon;
824             break;
825         }
826         case MyCSS_TOKEN_TYPE_FUNCTION: {
827             mycss_selectors_parser_selector_pseudo_class_function(entry, token);
828             break;
829         }
830         default: {
831             mycss_selectors_parser_expectations_error(entry, token);
832             entry->parser = entry->parser_switch;
833             return false;
834         }
835     }
836 
837     return true;
838 }
839 
mycss_selectors_state_simple_selector_colon_colon(mycss_entry_t * entry,mycss_token_t * token,bool last_response)840 bool mycss_selectors_state_simple_selector_colon_colon(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
841 {
842     if(token->type == MyCSS_TOKEN_TYPE_IDENT) {
843         mycss_selectors_parser_selector_pseudo_element(entry, token);
844         MyCORE_DEBUG("mycss_selectors_state_simple_selector_colon_colon_ident");
845         entry->parser = entry->parser_switch;
846     }
847     else if(token->type == MyCSS_TOKEN_TYPE_FUNCTION) {
848         mycss_selectors_parser_selector_pseudo_element_function(entry, token);
849     }
850     else {
851         mycss_selectors_parser_expectations_error(entry, token);
852         entry->parser = entry->parser_switch;
853         return false;
854     }
855 
856     return true;
857 }
858 
mycss_selectors_state_simple_selector_colon_colon_function(mycss_entry_t * entry,mycss_token_t * token,bool last_response)859 bool mycss_selectors_state_simple_selector_colon_colon_function(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
860 {
861     if(token->type == MyCSS_TOKEN_TYPE_RIGHT_PARENTHESIS) {
862         mycss_selectors_parser_selector_pseudo_element_function_end(entry, token);
863         MyCORE_DEBUG("mycss_selectors_state_simple_selector_colon_colon_function_right_parenthesis");
864         entry->parser = entry->parser_switch;
865     }
866     else {
867         mycss_selectors_parser_expectations_error(entry, token);
868         entry->parser = entry->parser_switch;
869         return false;
870     }
871 
872     return true;
873 }
874 
mycss_selectors_state_simple_selector_colon_function(mycss_entry_t * entry,mycss_token_t * token,bool last_response)875 bool mycss_selectors_state_simple_selector_colon_function(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
876 {
877     if(token->type == MyCSS_TOKEN_TYPE_RIGHT_PARENTHESIS) {
878         mycss_selectors_parser_selector_pseudo_class_function_end(entry, token);
879         MyCORE_DEBUG("mycss_selectors_state_simple_selector_colon_function_right_parenthesis");
880         entry->parser = entry->parser_switch;
881     }
882     else {
883         mycss_selectors_parser_expectations_error(entry, token);
884         entry->parser = entry->parser_switch;
885         return false;
886     }
887 
888     return true;
889 }
890 // HAND_EDIT_END
891 
mycss_selectors_state_simple_selector_full_stop(mycss_entry_t * entry,mycss_token_t * token,bool last_response)892 bool mycss_selectors_state_simple_selector_full_stop(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
893 {
894     if(token->type == MyCSS_TOKEN_TYPE_IDENT) {
895         mycss_selectors_parser_selector_class(entry, token);
896         MyCORE_DEBUG("mycss_selectors_state_simple_selector_full_stop_ident");
897         entry->parser = entry->parser_switch;
898     }
899     else {
900         mycss_selectors_parser_expectations_error(entry, token);
901         entry->parser = entry->parser_switch;
902         return false;
903     }
904 
905     return true;
906 }
907 
mycss_selectors_state_simple_selector_vertical_bar(mycss_entry_t * entry,mycss_token_t * token,bool last_response)908 bool mycss_selectors_state_simple_selector_vertical_bar(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
909 {
910     if(token->type == MyCSS_TOKEN_TYPE_IDENT) {
911         mycss_selectors_parser_selector_after_namespace(entry, token);
912         mycss_selectors_parser_selector_end(entry, token);
913         MyCORE_DEBUG("mycss_selectors_state_simple_selector_vertical_bar_ident");
914         entry->parser = entry->parser_switch;
915     }
916     else if(token->type == MyCSS_TOKEN_TYPE_DELIM) {
917         if(*token->data == '*') {
918             mycss_selectors_parser_selector_after_namespace(entry, token);
919             mycss_selectors_parser_selector_end(entry, token);
920             MyCORE_DEBUG("mycss_selectors_state_simple_selector_vertical_bar_asterisk");
921             entry->parser = entry->parser_switch;
922         }
923         else {
924             mycss_selectors_parser_expectations_error(entry, token);
925             entry->parser = entry->parser_switch;
926             return false;
927         }
928     }
929     else {
930         mycss_selectors_parser_expectations_error(entry, token);
931         entry->parser = entry->parser_switch;
932         return false;
933     }
934 
935     return true;
936 }
937 
mycss_selectors_state_simple_selector_ident(mycss_entry_t * entry,mycss_token_t * token,bool last_response)938 bool mycss_selectors_state_simple_selector_ident(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
939 {
940     if(token->type == MyCSS_TOKEN_TYPE_DELIM) {
941         if(*token->data == '|') {
942             // HAND_EDIT_BEGIN
943             mycss_selectors_parser_selector_namespace_ident(entry, token);
944             // HAND_EDIT_END
945             entry->parser = mycss_selectors_state_simple_selector_ident_vertical_bar;
946         }
947         else {
948             mycss_selectors_parser_selector_end(entry, token);
949             entry->parser = entry->parser_switch;
950             return false;
951         }
952     }
953     else {
954         mycss_selectors_parser_selector_end(entry, token);
955         entry->parser = entry->parser_switch;
956         return false;
957     }
958 
959     return true;
960 }
961 
mycss_selectors_state_simple_selector_ident_vertical_bar(mycss_entry_t * entry,mycss_token_t * token,bool last_response)962 bool mycss_selectors_state_simple_selector_ident_vertical_bar(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
963 {
964     if(token->type == MyCSS_TOKEN_TYPE_IDENT) {
965         mycss_selectors_parser_selector_after_namespace(entry, token);
966         mycss_selectors_parser_selector_end(entry, token);
967         MyCORE_DEBUG("mycss_selectors_state_simple_selector_ident_vertical_bar_ident");
968         entry->parser = entry->parser_switch;
969     }
970     else if(token->type == MyCSS_TOKEN_TYPE_DELIM) {
971         if(*token->data == '*') {
972             mycss_selectors_parser_selector_after_namespace(entry, token);
973             mycss_selectors_parser_selector_end(entry, token);
974             MyCORE_DEBUG("mycss_selectors_state_simple_selector_ident_vertical_bar_asterisk");
975             entry->parser = entry->parser_switch;
976         }
977         else {
978             mycss_selectors_parser_expectations_error(entry, token);
979             entry->parser = entry->parser_switch;
980             return false;
981         }
982     }
983     else {
984         mycss_selectors_parser_expectations_error(entry, token);
985         entry->parser = entry->parser_switch;
986         return false;
987     }
988 
989     return true;
990 }
991 
mycss_selectors_state_left_bracket_after_wq_name_attr(mycss_entry_t * entry,mycss_token_t * token,bool last_response)992 bool mycss_selectors_state_left_bracket_after_wq_name_attr(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
993 {
994     mycss_selectors_entry_t *selector = entry->selectors->entry_last;
995 
996     switch (token->type) {
997         case MyCSS_TOKEN_TYPE_WHITESPACE: {
998             break;
999         }
1000         case MyCSS_TOKEN_TYPE_INCLUDE_MATCH: {
1001             if(selector->value == NULL)
1002                 selector->value = mycss_selectors_value_attribute_create(entry, true);
1003 
1004             mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_INCLUDE;
1005             entry->parser = mycss_selectors_state_shared_after_attr_matcher;
1006 
1007             break;
1008         }
1009         case MyCSS_TOKEN_TYPE_DASH_MATCH: {
1010             if(selector->value == NULL)
1011                 selector->value = mycss_selectors_value_attribute_create(entry, true);
1012 
1013             mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_DASH;
1014             entry->parser = mycss_selectors_state_shared_after_attr_matcher;
1015 
1016             break;
1017         }
1018         case MyCSS_TOKEN_TYPE_PREFIX_MATCH: {
1019             if(selector->value == NULL)
1020                 selector->value = mycss_selectors_value_attribute_create(entry, true);
1021 
1022             mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_PREFIX;
1023             entry->parser = mycss_selectors_state_shared_after_attr_matcher;
1024 
1025             break;
1026         }
1027         case MyCSS_TOKEN_TYPE_SUFFIX_MATCH: {
1028             if(selector->value == NULL)
1029                 selector->value = mycss_selectors_value_attribute_create(entry, true);
1030 
1031             mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_SUFFIX;
1032             entry->parser = mycss_selectors_state_shared_after_attr_matcher;
1033 
1034             break;
1035         }
1036         case MyCSS_TOKEN_TYPE_SUBSTRING_MATCH: {
1037             if(selector->value == NULL)
1038                 selector->value = mycss_selectors_value_attribute_create(entry, true);
1039 
1040             mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_SUBSTRING;
1041 
1042             entry->parser = mycss_selectors_state_shared_after_attr_matcher;
1043 
1044             break;
1045         }
1046         case MyCSS_TOKEN_TYPE_DELIM: {
1047             if(*token->data == '=') {
1048                 if(selector->value == NULL)
1049                     selector->value = mycss_selectors_value_attribute_create(entry, true);
1050 
1051                 mycss_selector_value_attribute(selector->value)->match = MyCSS_SELECTORS_MATCH_EQUAL;
1052                 entry->parser = mycss_selectors_state_shared_after_attr_matcher;
1053             }
1054             else {
1055                 mycss_selectors_parser_expectations_error(entry, token);
1056 
1057                 mycss_entry_parser_list_push(entry, entry->parser_switch, NULL, entry->selectors->ending_token, false);
1058                 entry->selectors->ending_token = MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET;
1059 
1060                 entry->parser = mycss_selectors_state_drop;
1061                 return false;
1062             }
1063             break;
1064         }
1065         case MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET: {
1066             mycss_selectors_parser_selector_end(entry, token);
1067             MyCORE_DEBUG("mycss_selectors_state_shared_after_wq_name_attr_right_bracket");
1068             entry->parser = entry->parser_switch;
1069             break;
1070         }
1071         default: {
1072             mycss_selectors_parser_expectations_error(entry, token);
1073 
1074             mycss_entry_parser_list_push(entry, entry->parser_switch, NULL, entry->selectors->ending_token, false);
1075             entry->selectors->ending_token = MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET;
1076 
1077             entry->parser = mycss_selectors_state_drop;
1078             return false;
1079         }
1080     }
1081 
1082     return true;
1083 }
1084 
mycss_selectors_state_shared_after_attr_modifier(mycss_entry_t * entry,mycss_token_t * token,bool last_response)1085 bool mycss_selectors_state_shared_after_attr_modifier(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
1086 {
1087     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE)
1088         return true;
1089 
1090     if(token->type == MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET) {
1091         mycss_selectors_parser_selector_end(entry, token);
1092         MyCORE_DEBUG("mycss_selectors_state_shared_after_attr_modifier_right_bracket");
1093         entry->parser = entry->parser_switch;
1094     }
1095     else {
1096         mycss_selectors_parser_expectations_error(entry, token);
1097         entry->parser = entry->parser_switch;
1098         return false;
1099     }
1100 
1101     return true;
1102 }
1103 
mycss_selectors_state_shared_after_attribute_value(mycss_entry_t * entry,mycss_token_t * token,bool last_response)1104 bool mycss_selectors_state_shared_after_attribute_value(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
1105 {
1106     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE)
1107         return true;
1108 
1109     if(token->type == MyCSS_TOKEN_TYPE_IDENT) {
1110         if(*token->data == 'i') {
1111             mycss_selectors_parser_selector_modifier(entry, token);
1112             entry->parser = mycss_selectors_state_shared_after_attr_modifier;
1113         }
1114         else {
1115             mycss_selectors_parser_expectations_error(entry, token);
1116             entry->parser = entry->parser_switch;
1117             return false;
1118         }
1119     }
1120     else if(token->type == MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET) {
1121         mycss_selectors_parser_selector_end(entry, token);
1122         MyCORE_DEBUG("mycss_selectors_state_shared_after_attribute_value_right_bracket");
1123         entry->parser = entry->parser_switch;
1124     }
1125     else {
1126         mycss_selectors_parser_expectations_error(entry, token);
1127         entry->parser = entry->parser_switch;
1128         return false;
1129     }
1130 
1131     return true;
1132 }
1133 
mycss_selectors_state_shared_after_attr_matcher(mycss_entry_t * entry,mycss_token_t * token,bool last_response)1134 bool mycss_selectors_state_shared_after_attr_matcher(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
1135 {
1136     if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE)
1137         return true;
1138 
1139     if(token->type == MyCSS_TOKEN_TYPE_IDENT) {
1140         mycss_selectors_parser_selector_value(entry, token);
1141         entry->parser = mycss_selectors_state_shared_after_attribute_value;
1142     }
1143     else if(token->type == MyCSS_TOKEN_TYPE_STRING) {
1144         mycss_selectors_parser_selector_value(entry, token);
1145         entry->parser = mycss_selectors_state_shared_after_attribute_value;
1146     }
1147     else {
1148         mycss_selectors_parser_expectations_error(entry, token);
1149         entry->parser = entry->parser_switch;
1150         return false;
1151     }
1152 
1153     return true;
1154 }
1155 
1156 
1157