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/tokenizer.h"
22 #include "mycss/tokenizer_resource.h"
23 #include "mycore/utils/resources.h"
24 
mycss_tokenizer_chunk(mycss_entry_t * entry,const char * css,size_t css_length)25 mystatus_t mycss_tokenizer_chunk(mycss_entry_t* entry, const char* css, size_t css_length)
26 {
27     entry->current_buffer = mycore_incoming_buffer_add(entry->current_buffer, entry->mcobject_incoming_buffer,
28                                                        css, css_length);
29 
30     if(entry->current_buffer == NULL)
31         return MyCSS_STATUS_ERROR_TOKENIZER_INCOMING_BUFFER_ADD;
32 
33     // first init
34     if(entry->first_buffer == NULL)
35         entry->first_buffer = entry->current_buffer;
36 
37     if(entry->token == NULL) {
38         entry->token = (mycss_token_t*)mycore_calloc(1, sizeof(mycss_token_t));
39 
40         if(entry->token == NULL)
41             return MyCSS_STATUS_ERROR_TOKENIZER_TOKEN_ALLOCATION;
42     }
43 
44     return mycss_tokenizer_process(entry, css, css_length);
45 }
46 
mycss_tokenizer_process(mycss_entry_t * entry,const char * css,size_t css_length)47 mystatus_t mycss_tokenizer_process(mycss_entry_t* entry, const char* css, size_t css_length)
48 {
49     /*
50      Why use utf-8 when the declaration says utf-16?
51      The bytes of the encoding declaration spell out “@charset "…";” in ASCII,
52      but UTF-16 is not ASCII-compatible. Either you’ve typed in complete gibberish (like 䁣桡牳整•utf-16be∻)
53      to get the right bytes in the document, which we don’t want to encourage,
54      or your document is actually in an ASCII-compatible encoding and your encoding declaration is lying.
55 
56      Either way, defaulting to UTF-8 is a decent answer.
57 
58      As well, this mimics the behavior of HTML’s <meta charset> attribute.
59      */
60     if(entry->encoding == MyENCODING_UTF_16LE || entry->encoding == MyENCODING_UTF_16BE)
61         entry->encoding = MyENCODING_UTF_8;
62 
63     mycss_t* mycss = entry->mycss;
64     mycss_tokenizer_state_f* state_f = mycss->parse_state_func;
65 
66     mycore_incoming_buffer_t *current = entry->current_buffer;
67 
68     do {
69         mycore_incoming_buffer_t *mt = entry->current_buffer;
70         mt->length = 0;
71 
72         while (mt->length < mt->size) {
73             mt->length = state_f[entry->state](entry, entry->token, mt->data, mt->length, mt->size);
74         }
75 
76         entry->current_buffer = mt->next;
77     }
78     while(entry->current_buffer);
79 
80     entry->current_buffer = current;
81 
82     return MyCSS_STATUS_OK;
83 }
84 
mycss_tokenizer_end(mycss_entry_t * entry)85 mystatus_t mycss_tokenizer_end(mycss_entry_t* entry)
86 {
87     mycss_t* mycss = entry->mycss;
88     mycss_tokenizer_state_f* state_f = mycss->parse_state_func;
89 
90     if(entry->state != MyCSS_TOKENIZER_STATE_DATA)
91     {
92         mycore_incoming_buffer_t *mt = entry->current_buffer;
93         size_t end_state = (MyCSS_TOKENIZER_STATE_LAST_ENTRY + entry->state);
94 
95         mt->length = state_f[end_state](entry, entry->token, mt->data, mt->length, mt->size);
96     }
97 
98     entry->type |= MyCSS_ENTRY_TYPE_END;
99 
100     return MyCSS_STATUS_OK;
101 }
102 
mycss_tokenizer_run_state_single(mycss_entry_t * entry,mycss_tokenizer_state_t state,const char * css,size_t css_offset,size_t css_size)103 size_t mycss_tokenizer_run_state_single(mycss_entry_t* entry, mycss_tokenizer_state_t state, const char* css, size_t css_offset, size_t css_size)
104 {
105     mycss_t* mycss = entry->mycss;
106     mycss_tokenizer_state_f* state_f = mycss->parse_state_func;
107 
108     return state_f[state](entry, entry->token, css, css_offset, css_size);
109 }
110 
mycss_tokenizer_state_set_current_buffer_for_continue(mycss_entry_t * entry,size_t css_offset,size_t css_minus_offset)111 size_t mycss_tokenizer_state_set_current_buffer_for_continue(mycss_entry_t* entry, size_t css_offset, size_t css_minus_offset)
112 {
113     if(css_minus_offset == 0)
114         return css_offset;
115 
116     if(css_offset >= css_minus_offset)
117         return css_offset;
118 
119     mycore_incoming_buffer_t *buffer = entry->current_buffer;
120 
121     size_t need = (css_minus_offset - css_offset);
122     size_t position = buffer->offset - need;
123 
124     while(buffer && buffer->offset > position)
125         buffer = buffer->prev;
126 
127     if(buffer == NULL)
128         return 0;
129 
130     entry->current_buffer = buffer;
131 
132     return (position - buffer->offset);
133 }
134 
mycss_tokenizer_token_strcasecmp(mycss_entry_t * entry,mycss_token_t * token,const char * to,size_t to_length)135 size_t mycss_tokenizer_token_strcasecmp(mycss_entry_t* entry, mycss_token_t* token, const char* to, size_t to_length)
136 {
137     mycore_incoming_buffer_t *buffer = mycore_incoming_buffer_find_by_position(entry->current_buffer, token->begin);
138 
139     size_t token_offset = token->begin - buffer->offset;
140 
141     return mycore_incoming_buffer_escaped_case_cmp(&buffer, to, to_length, &token_offset);
142 }
143 
144 //////////////////////
145 // Begin All State
146 //
mycss_tokenizer_state_data(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)147 size_t mycss_tokenizer_state_data(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
148 {
149     token->begin = entry->current_buffer->offset + css_offset;
150     token->data  = &css[css_offset];
151 
152     entry->state = mycss_begin_chars_state_map[ (const unsigned char)css[css_offset] ];
153 
154     css_offset++;
155     return css_offset;
156 }
157 
158 /////////////////////////////////////////////////////////
159 //// whitespace
160 ////
161 /////////////////////////////////////////////////////////
mycss_tokenizer_state_whitespace(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)162 size_t mycss_tokenizer_state_whitespace(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
163 {
164     const unsigned char *u_css = (const unsigned char*)css;
165 
166     while(css_offset < css_size)
167     {
168         if(mycss_begin_chars_state_map[ u_css[css_offset] ] != MyCSS_TOKENIZER_STATE_WHITESPACE)
169         {
170             token->length = (entry->current_buffer->offset + css_offset) - token->begin;
171             token->type   = MyCSS_TOKEN_TYPE_WHITESPACE;
172 
173             MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
174 
175             entry->state = MyCSS_TOKENIZER_STATE_DATA;
176             break;
177         }
178 
179         css_offset++;
180     }
181 
182     return css_offset;
183 }
184 
185 /////////////////////////////////////////////////////////
186 //// U+0022 QUOTATION MARK (")
187 ////
188 /////////////////////////////////////////////////////////
mycss_tokenizer_state_quotation_mark(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)189 size_t mycss_tokenizer_state_quotation_mark(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
190 {
191     // skip QUOTATION MARK (")
192     token->begin += 1;
193 
194     entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED;
195     entry->state_back = MyCSS_TOKENIZER_STATE_QUOTATION_MARK_BACK;
196 
197     return css_offset;
198 }
199 
mycss_tokenizer_state_quotation_mark_back(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)200 size_t mycss_tokenizer_state_quotation_mark_back(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
201 {
202     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
203 
204     entry->state = MyCSS_TOKENIZER_STATE_DATA;
205     return css_offset;
206 }
207 
208 /////////////////////////////////////////////////////////
209 //// U+0023 NUMBER SIGN (#)
210 ////
211 /////////////////////////////////////////////////////////
mycss_tokenizer_state_number_sign(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)212 size_t mycss_tokenizer_state_number_sign(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
213 {
214     const unsigned char *u_css = (const unsigned char*)css;
215 
216     if(mycss_chars_name_code_point_map[ u_css[css_offset] ] != 0xff)
217     {
218         token->begin++;
219         css_offset++;
220 
221         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
222         entry->state_back = MyCSS_TOKENIZER_STATE_NUMBER_SIGN_NAME_BACK;
223     }
224     else if(css[css_offset] == '\\') {
225         css_offset++;
226 
227         if(css_offset >= css_size) {
228             entry->state = MyCSS_TOKENIZER_STATE_NUMBER_SIGN_NAME_RSOLIDUS;
229             return css_offset;
230         }
231 
232         if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
233             css_offset--;
234 
235             token->length = 1;
236             token->type   = MyCSS_TOKEN_TYPE_DELIM;
237 
238             MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
239 
240             entry->state = MyCSS_TOKENIZER_STATE_DATA;
241         }
242         else {
243             token->begin++;
244             css_offset++;
245 
246             entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
247             entry->state_back = MyCSS_TOKENIZER_STATE_NUMBER_SIGN_NAME_BACK;
248         }
249     }
250     else {
251         token->length = 1;
252         token->type   = MyCSS_TOKEN_TYPE_DELIM;
253 
254         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
255 
256         entry->state = MyCSS_TOKENIZER_STATE_DATA;
257     }
258 
259     return css_offset;
260 }
261 
mycss_tokenizer_state_number_sign_name_back(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)262 size_t mycss_tokenizer_state_number_sign_name_back(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
263 {
264     token->type = MyCSS_TOKEN_TYPE_HASH;
265 
266     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
267 
268     entry->state = MyCSS_TOKENIZER_STATE_DATA;
269     return css_offset;
270 }
271 
mycss_tokenizer_state_number_sign_name_rsolidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)272 size_t mycss_tokenizer_state_number_sign_name_rsolidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
273 {
274     if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
275         token->length = 1;
276         token->type   = MyCSS_TOKEN_TYPE_DELIM;
277 
278         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
279 
280         entry->state = MyCSS_TOKENIZER_STATE_DATA;
281         return mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
282     }
283 
284     entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
285     entry->state_back = MyCSS_TOKENIZER_STATE_NUMBER_SIGN_NAME_BACK;
286 
287     token->begin++;
288     css_offset++;
289 
290     return css_offset;
291 }
292 
293 /////////////////////////////////////////////////////////
294 //// U+0024 DOLLAR SIGN ($)
295 ////
296 /////////////////////////////////////////////////////////
mycss_tokenizer_state_dollar_sign(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)297 size_t mycss_tokenizer_state_dollar_sign(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
298 {
299     if(css[css_offset] == '=') {
300         css_offset++;
301 
302         token->length = 2;
303         token->type = MyCSS_TOKEN_TYPE_SUFFIX_MATCH;
304     }
305     else {
306         token->length = 1;
307         token->type = MyCSS_TOKEN_TYPE_DELIM;
308     }
309 
310     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
311 
312     entry->state = MyCSS_TOKENIZER_STATE_DATA;
313     return css_offset;
314 }
315 
316 /////////////////////////////////////////////////////////
317 //// U+0027 APOSTROPHE (')
318 ////
319 /////////////////////////////////////////////////////////
mycss_tokenizer_state_apostrophe(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)320 size_t mycss_tokenizer_state_apostrophe(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
321 {
322     // skip APOSTROPHE (')
323     token->begin += 1;
324 
325     entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED;
326     entry->state_back = MyCSS_TOKENIZER_STATE_QUOTATION_MARK_BACK;
327 
328     return css_offset;
329 }
330 
mycss_tokenizer_state_apostrophe_back(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)331 size_t mycss_tokenizer_state_apostrophe_back(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
332 {
333     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
334 
335     entry->state = MyCSS_TOKENIZER_STATE_DATA;
336     return css_offset;
337 }
338 
339 /////////////////////////////////////////////////////////
340 //// U+0028 LEFT PARENTHESIS (()
341 ////
342 /////////////////////////////////////////////////////////
mycss_tokenizer_state_left_parenthesis(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)343 size_t mycss_tokenizer_state_left_parenthesis(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
344 {
345     token->length = 1;
346     token->type   = MyCSS_TOKEN_TYPE_LEFT_PARENTHESIS;
347 
348     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
349 
350     entry->state = MyCSS_TOKENIZER_STATE_DATA;
351     return css_offset;
352 }
353 
354 /////////////////////////////////////////////////////////
355 //// U+0029 RIGHT PARENTHESIS ())
356 ////
357 /////////////////////////////////////////////////////////
mycss_tokenizer_state_right_parenthesis(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)358 size_t mycss_tokenizer_state_right_parenthesis(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
359 {
360     token->length = 1;
361     token->type   = MyCSS_TOKEN_TYPE_RIGHT_PARENTHESIS;
362 
363     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
364 
365     entry->state = MyCSS_TOKENIZER_STATE_DATA;
366     return css_offset;
367 }
368 
369 /////////////////////////////////////////////////////////
370 //// U+002A ASTERISK (*)
371 ////
372 /////////////////////////////////////////////////////////
mycss_tokenizer_state_asterisk(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)373 size_t mycss_tokenizer_state_asterisk(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
374 {
375     if(css[css_offset] == '=') {
376         css_offset++;
377 
378         token->length = 2;
379         token->type = MyCSS_TOKEN_TYPE_SUBSTRING_MATCH;
380     }
381     else {
382         token->length = 1;
383         token->type = MyCSS_TOKEN_TYPE_DELIM;
384     }
385 
386     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
387 
388     entry->state = MyCSS_TOKENIZER_STATE_DATA;
389     return css_offset;
390 }
391 
392 /////////////////////////////////////////////////////////
393 //// U+002B PLUS SIGN (+)
394 ////
395 /////////////////////////////////////////////////////////
mycss_tokenizer_state_plus_sign(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)396 size_t mycss_tokenizer_state_plus_sign(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
397 {
398     if(css[css_offset] >= '0' && css[css_offset] <= '9') {
399         css_offset++;
400 
401         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DIGIT;
402         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC;
403     }
404     else if(css[css_offset] == '.') {
405         css_offset++;
406 
407         entry->state = MyCSS_TOKENIZER_STATE_PLUS_SIGN_FULL_STOP;
408     }
409     else {
410         token->length = 1;
411         token->type = MyCSS_TOKEN_TYPE_DELIM;
412 
413         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
414 
415         entry->state = MyCSS_TOKENIZER_STATE_DATA;
416     }
417 
418     return css_offset;
419 }
420 
mycss_tokenizer_state_plus_sign_full_stop(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)421 size_t mycss_tokenizer_state_plus_sign_full_stop(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
422 {
423     if(css[css_offset] >= '0' && css[css_offset] <= '9') {
424         css_offset++;
425 
426         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DECIMAL;
427         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC;
428     }
429     else {
430         token->length = 1;
431         token->type = MyCSS_TOKEN_TYPE_DELIM;
432 
433         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
434 
435         entry->state = MyCSS_TOKENIZER_STATE_DATA;
436         return mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
437     }
438 
439     return css_offset;
440 }
441 
442 /////////////////////////////////////////////////////////
443 //// U+002C COMMA (,)
444 ////
445 /////////////////////////////////////////////////////////
mycss_tokenizer_state_comma(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)446 size_t mycss_tokenizer_state_comma(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
447 {
448     token->length = 1;
449     token->type   = MyCSS_TOKEN_TYPE_COMMA;
450 
451     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
452 
453     entry->state = MyCSS_TOKENIZER_STATE_DATA;
454     return css_offset;
455 }
456 
457 /////////////////////////////////////////////////////////
458 //// U+002D HYPHEN-MINUS (-)
459 ////
460 /////////////////////////////////////////////////////////
mycss_tokenizer_state_hyphen_minus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)461 size_t mycss_tokenizer_state_hyphen_minus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
462 {
463     const unsigned char *u_css = (const unsigned char*)css;
464 
465     // If the input stream starts with a number, reconsume the current input code point,
466     // consume a numeric token, and return it.
467     if(css[css_offset] >= '0' && css[css_offset] <= '9') {
468         css_offset++;
469 
470         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DIGIT;
471         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC;
472     }
473     else if(css[css_offset] == '.') {
474         css_offset++;
475 
476         entry->state = MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_FULL_STOP;
477     }
478 
479     // Otherwise, if the input stream starts with an identifier,
480     // reconsume the current input code point, consume an ident-like token, and return it.
481     // and check
482     // Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS
483     // U+003E GREATER-THAN SIGN (->), consume them and return a <CDC-token>.
484     else if(css[css_offset] == '-') {
485         css_offset++;
486 
487         entry->state = MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_MINUS;
488     }
489 
490     // Otherwise, if the input stream starts with an identifier,
491     // reconsume the current input code point, consume an ident-like token, and return it.
492     else if(mycss_begin_chars_state_map[ u_css[css_offset] ] == MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT) {
493         css_offset++;
494 
495         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
496         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_IDENT;
497     }
498     else if(css[css_offset] == '\\') {
499         css_offset++;
500 
501         entry->state = MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_RSOLIDUS;
502     }
503 
504     // Otherwise, return a <delim-token> with its value set to the current input code point.
505     else {
506         token->length = 1;
507         token->type   = MyCSS_TOKEN_TYPE_DELIM;
508 
509         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
510 
511         entry->state = MyCSS_TOKENIZER_STATE_DATA;
512     }
513 
514     return css_offset;
515 }
516 
mycss_tokenizer_state_hyphen_minus_full_stop(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)517 size_t mycss_tokenizer_state_hyphen_minus_full_stop(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
518 {
519     if(css[css_offset] >= '0' && css[css_offset] <= '9') {
520         css_offset++;
521 
522         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DECIMAL;
523         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC;
524     }
525     else {
526         token->length = 1;
527         token->type = MyCSS_TOKEN_TYPE_DELIM;
528 
529         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
530 
531         entry->state = MyCSS_TOKENIZER_STATE_DATA;
532         return mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
533     }
534 
535     return css_offset;
536 }
537 
mycss_tokenizer_state_hyphen_minus_minus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)538 size_t mycss_tokenizer_state_hyphen_minus_minus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
539 {
540     if(css[css_offset] == '>') {
541         css_offset++;
542 
543         token->length = 3;
544         token->type   = MyCSS_TOKEN_TYPE_CDC;
545 
546         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
547 
548         entry->state = MyCSS_TOKENIZER_STATE_DATA;
549     }
550     else if(mycss_begin_chars_state_map[ ((const unsigned char *)css)[css_offset] ] == MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT) {
551         css_offset++;
552 
553         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
554         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_IDENT;
555     }
556     else if(css[css_offset] == '\\') {
557         css_offset++;
558 
559         entry->state = MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_MINUS_RSOLIDUS;
560     }
561     else {
562         token->length = 1; // only '-'
563         token->type   = MyCSS_TOKEN_TYPE_DELIM;
564 
565         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
566 
567         entry->state = MyCSS_TOKENIZER_STATE_DATA;
568         css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
569     }
570 
571     return css_offset;
572 }
573 
mycss_tokenizer_state_hyphen_minus_minus_rsolidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)574 size_t mycss_tokenizer_state_hyphen_minus_minus_rsolidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
575 {
576     if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
577         token->length = 1;
578         token->type   = MyCSS_TOKEN_TYPE_DELIM;
579 
580         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
581 
582         entry->state = MyCSS_TOKENIZER_STATE_DATA;
583         css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 2);
584     }
585     else {
586         css_offset++;
587 
588         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
589         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_IDENT;
590     }
591 
592     return css_offset;
593 }
594 
mycss_tokenizer_state_hyphen_minus_rsolidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)595 size_t mycss_tokenizer_state_hyphen_minus_rsolidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
596 {
597     if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
598         token->length = 1; // only '-'
599         token->type   = MyCSS_TOKEN_TYPE_DELIM;
600 
601         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
602 
603         entry->state = MyCSS_TOKENIZER_STATE_DATA;
604         css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
605     }
606     else {
607         css_offset++;
608 
609         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
610         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_IDENT;
611     }
612 
613     return css_offset;
614 }
615 
616 /////////////////////////////////////////////////////////
617 //// U+002E FULL STOP (.)
618 ////
619 /////////////////////////////////////////////////////////
mycss_tokenizer_state_full_stop(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)620 size_t mycss_tokenizer_state_full_stop(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
621 {
622     if(css[css_offset] >= '0' && css[css_offset] <= '9') {
623         css_offset++;
624 
625         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DECIMAL;
626         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC;
627     }
628     else {
629         token->length = 1;
630         token->type = MyCSS_TOKEN_TYPE_DELIM;
631 
632         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
633 
634         entry->state = MyCSS_TOKENIZER_STATE_DATA;
635     }
636 
637     return css_offset;
638 }
639 
640 /////////////////////////////////////////////////////////
641 //// U+002F SOLIDUS (/)
642 ////
643 /////////////////////////////////////////////////////////
mycss_tokenizer_state_solidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)644 size_t mycss_tokenizer_state_solidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
645 {
646     if(css[css_offset] == '*') {
647         css_offset++;
648 
649         entry->state = MyCSS_TOKENIZER_STATE_SOLIDUS_COMMENT_END;
650     }
651     else {
652         token->length = 1;
653         token->type = MyCSS_TOKEN_TYPE_DELIM;
654 
655         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
656 
657         entry->state = MyCSS_TOKENIZER_STATE_DATA;
658     }
659 
660 
661     return css_offset;
662 }
663 
mycss_tokenizer_state_solidus_comment_end(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)664 size_t mycss_tokenizer_state_solidus_comment_end(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
665 {
666     while(css_offset < css_size)
667     {
668         if(css[css_offset] == '/') {
669             if(css_offset == 0)
670             {
671                 mycore_incoming_buffer_t *buffer = entry->current_buffer->prev;
672 
673                 while(buffer && buffer->size == 0)
674                     buffer = buffer->prev;
675 
676                 if(buffer == NULL) {
677                     // panic!, this in not normal, something is very wrong
678                     entry->state = MyCSS_TOKENIZER_STATE_SOLIDUS;
679                     break;
680                 }
681 
682                 if(buffer->data[ (buffer->size - 1) ] == '*') {
683                     css_offset++;
684 
685                     token->length = (entry->current_buffer->offset + css_offset) - token->begin;
686                     token->type = MyCSS_TOKEN_TYPE_COMMENT;
687 
688                     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
689 
690                     entry->state = MyCSS_TOKENIZER_STATE_DATA;
691                     break;
692                 }
693             }
694             else if(css[ (css_offset - 1) ] == '*') {
695                 css_offset++;
696 
697                 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
698                 token->type = MyCSS_TOKEN_TYPE_COMMENT;
699 
700                 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
701 
702                 entry->state = MyCSS_TOKENIZER_STATE_DATA;
703                 break;
704             }
705         }
706 
707         ++css_offset;
708     }
709 
710     return css_offset;
711 }
712 
713 /////////////////////////////////////////////////////////
714 //// U+003A COLON (:)
715 ////
716 /////////////////////////////////////////////////////////
mycss_tokenizer_state_colon(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)717 size_t mycss_tokenizer_state_colon(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
718 {
719     token->length = 1;
720     token->type = MyCSS_TOKEN_TYPE_COLON;
721 
722     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
723 
724     entry->state = MyCSS_TOKENIZER_STATE_DATA;
725     return css_offset;
726 }
727 
728 /////////////////////////////////////////////////////////
729 //// U+003B SEMICOLON (;)
730 ////
731 /////////////////////////////////////////////////////////
mycss_tokenizer_state_semicolon(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)732 size_t mycss_tokenizer_state_semicolon(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
733 {
734     token->length = 1;
735     token->type = MyCSS_TOKEN_TYPE_SEMICOLON;
736 
737     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
738 
739     entry->state = MyCSS_TOKENIZER_STATE_DATA;
740     return css_offset;
741 }
742 
743 /////////////////////////////////////////////////////////
744 //// U+003C LESS-THAN SIGN (<)
745 ////
746 /////////////////////////////////////////////////////////
mycss_tokenizer_state_less_than_sign(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)747 size_t mycss_tokenizer_state_less_than_sign(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
748 {
749     if(css[css_offset] == '!') {
750         css_offset++;
751 
752         entry->state = MyCSS_TOKENIZER_STATE_LESS_THAN_SIGN_MINUS;
753     }
754     else {
755         token->length = 1;
756         token->type   = MyCSS_TOKEN_TYPE_DELIM;
757 
758         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
759 
760         entry->state = MyCSS_TOKENIZER_STATE_DATA;
761     }
762 
763     return css_offset;
764 }
765 
mycss_tokenizer_state_less_than_sign_minus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)766 size_t mycss_tokenizer_state_less_than_sign_minus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
767 {
768     if(css[css_offset] == '-') {
769         css_offset++;
770         entry->state = MyCSS_TOKENIZER_STATE_LESS_THAN_SIGN_MINUS_MINUS;
771     }
772     else {
773         token->length = 1;
774         token->type   = MyCSS_TOKEN_TYPE_DELIM;
775 
776         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
777 
778         entry->state = MyCSS_TOKENIZER_STATE_DATA;
779         css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
780     }
781 
782     return css_offset;
783 }
784 
mycss_tokenizer_state_less_than_sign_minus_minus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)785 size_t mycss_tokenizer_state_less_than_sign_minus_minus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
786 {
787     if(css[css_offset] == '-') {
788         css_offset++;
789 
790         token->length = 3;
791         token->type   = MyCSS_TOKEN_TYPE_CDO;
792 
793         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
794 
795         entry->state = MyCSS_TOKENIZER_STATE_DATA;
796     }
797     else {
798         token->length = 1;
799         token->type   = MyCSS_TOKEN_TYPE_DELIM;
800 
801         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
802 
803         entry->state = MyCSS_TOKENIZER_STATE_DATA;
804         css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 2);
805     }
806 
807     return css_offset;
808 }
809 
810 /////////////////////////////////////////////////////////
811 //// U+0040 COMMERCIAL AT (@)
812 ////
813 /////////////////////////////////////////////////////////
mycss_tokenizer_state_commercial_at(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)814 size_t mycss_tokenizer_state_commercial_at(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
815 {
816     if(css[css_offset] == '-') {
817         css_offset++;
818 
819         entry->state = MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_MINUS;
820     }
821     else if(css[css_offset] == '\\') {
822         css_offset++;
823 
824         entry->state = MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_RSOLIDUS;
825     }
826     else if(mycss_begin_chars_state_map[ ((const unsigned char *)css)[css_offset] ] == MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT) {
827         css_offset++;
828 
829         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
830         entry->state_back = MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_BACK;
831     }
832     else {
833         token->length = 1;
834         token->type   = MyCSS_TOKEN_TYPE_DELIM;
835 
836         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
837 
838         entry->state = MyCSS_TOKENIZER_STATE_DATA;
839     }
840 
841     return css_offset;
842 }
843 
mycss_tokenizer_state_commercial_at_minus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)844 size_t mycss_tokenizer_state_commercial_at_minus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
845 {
846     if(mycss_begin_chars_state_map[ ((const unsigned char *)css)[css_offset] ] == MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT) {
847         css_offset++;
848 
849         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
850         entry->state_back = MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_BACK;
851     }
852     else if(css[css_offset] == '\\') {
853         css_offset++;
854 
855         entry->state = MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_MINUS_RSOLIDUS;
856     }
857     else {
858         token->length = ((entry->current_buffer->offset + css_offset) - token->begin) - 1;
859         token->type   = MyCSS_TOKEN_TYPE_DELIM;
860 
861         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
862 
863         entry->state = MyCSS_TOKENIZER_STATE_DATA;
864         css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
865     }
866 
867     return css_offset;
868 }
869 
mycss_tokenizer_state_commercial_at_minus_rsolidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)870 size_t mycss_tokenizer_state_commercial_at_minus_rsolidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
871 {
872     if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
873         token->length = ((entry->current_buffer->offset + css_offset) - token->begin) - 2;
874         token->type   = MyCSS_TOKEN_TYPE_DELIM;
875 
876         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
877 
878         entry->state = MyCSS_TOKENIZER_STATE_DATA;
879         css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 2);
880     }
881     else {
882         css_offset++;
883 
884         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
885         entry->state_back = MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_BACK;
886     }
887 
888     return css_offset;
889 }
890 
mycss_tokenizer_state_commercial_at_rsolidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)891 size_t mycss_tokenizer_state_commercial_at_rsolidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
892 {
893     if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
894         token->length = ((entry->current_buffer->offset + css_offset) - token->begin) - 1;
895         token->type   = MyCSS_TOKEN_TYPE_DELIM;
896 
897         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
898 
899         entry->state = MyCSS_TOKENIZER_STATE_DATA;
900         css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
901     }
902     else {
903         css_offset++;
904 
905         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
906         entry->state_back = MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_BACK;
907     }
908 
909     return css_offset;
910 }
911 
mycss_tokenizer_state_commercial_at_back(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)912 size_t mycss_tokenizer_state_commercial_at_back(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
913 {
914     token->type    = MyCSS_TOKEN_TYPE_AT_KEYWORD;
915     token->begin  += 1;
916     token->length -= 1;
917 
918     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
919 
920     entry->state = MyCSS_TOKENIZER_STATE_DATA;
921     return css_offset;
922 }
923 
924 /////////////////////////////////////////////////////////
925 //// U+005B LEFT SQUARE BRACKET ([)
926 ////
927 /////////////////////////////////////////////////////////
mycss_tokenizer_state_left_square_bracket(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)928 size_t mycss_tokenizer_state_left_square_bracket(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
929 {
930     token->length = 1;
931     token->type   = MyCSS_TOKEN_TYPE_LEFT_SQUARE_BRACKET;
932 
933     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
934 
935     entry->state = MyCSS_TOKENIZER_STATE_DATA;
936     return css_offset;
937 }
938 
939 /////////////////////////////////////////////////////////
940 //// U+005C REVERSE SOLIDUS (\)
941 ////
942 /////////////////////////////////////////////////////////
mycss_tokenizer_state_reverse_solidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)943 size_t mycss_tokenizer_state_reverse_solidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
944 {
945     if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
946         token->length = 1;
947         token->type   = MyCSS_TOKEN_TYPE_DELIM;
948 
949         MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
950 
951         entry->state = MyCSS_TOKENIZER_STATE_DATA;
952     }
953     else {
954         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
955         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_IDENT;
956     }
957 
958     return css_offset;
959 }
960 
961 /////////////////////////////////////////////////////////
962 //// U+005D RIGHT SQUARE BRACKET (])
963 ////
964 /////////////////////////////////////////////////////////
mycss_tokenizer_state_right_square_bracket(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)965 size_t mycss_tokenizer_state_right_square_bracket(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
966 {
967     token->length = 1;
968     token->type   = MyCSS_TOKEN_TYPE_RIGHT_SQUARE_BRACKET;
969 
970     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
971 
972     entry->state = MyCSS_TOKENIZER_STATE_DATA;
973     return css_offset;
974 }
975 
976 /////////////////////////////////////////////////////////
977 //// U+005E CIRCUMFLEX ACCENT (^)
978 ////
979 /////////////////////////////////////////////////////////
mycss_tokenizer_state_circumflex_accent(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)980 size_t mycss_tokenizer_state_circumflex_accent(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
981 {
982     if(css[css_offset] == '=') {
983         css_offset++;
984 
985         token->length = 2;
986         token->type = MyCSS_TOKEN_TYPE_PREFIX_MATCH;
987     }
988     else {
989         token->length = 1;
990         token->type = MyCSS_TOKEN_TYPE_DELIM;
991     }
992 
993     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
994 
995     entry->state = MyCSS_TOKENIZER_STATE_DATA;
996     return css_offset;
997 }
998 
999 /////////////////////////////////////////////////////////
1000 //// U+007B LEFT CURLY BRACKET ({)
1001 ////
1002 /////////////////////////////////////////////////////////
mycss_tokenizer_state_left_curly_bracket(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)1003 size_t mycss_tokenizer_state_left_curly_bracket(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
1004 {
1005     token->length = 1;
1006     token->type   = MyCSS_TOKEN_TYPE_LEFT_CURLY_BRACKET;
1007 
1008     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
1009 
1010     entry->state = MyCSS_TOKENIZER_STATE_DATA;
1011     return css_offset;
1012 }
1013 
1014 /////////////////////////////////////////////////////////
1015 //// U+007D RIGHT CURLY BRACKET (})
1016 ////
1017 /////////////////////////////////////////////////////////
mycss_tokenizer_state_right_curly_bracket(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)1018 size_t mycss_tokenizer_state_right_curly_bracket(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
1019 {
1020     token->length = 1;
1021     token->type   = MyCSS_TOKEN_TYPE_RIGHT_CURLY_BRACKET;
1022 
1023     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
1024 
1025     entry->state = MyCSS_TOKENIZER_STATE_DATA;
1026     return css_offset;
1027 }
1028 
1029 /////////////////////////////////////////////////////////
1030 //// Digit
1031 ////
1032 /////////////////////////////////////////////////////////
mycss_tokenizer_state_digit(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)1033 size_t mycss_tokenizer_state_digit(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
1034 {
1035     entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DIGIT;
1036     entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC;
1037 
1038     return css_offset;
1039 }
1040 
1041 /////////////////////////////////////////////////////////
1042 //// U+0055 LATIN CAPITAL LETTER U (U) || U+0075 LATIN SMALL LETTER U (u)
1043 ////
1044 /////////////////////////////////////////////////////////
mycss_tokenizer_state_letter_u(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)1045 size_t mycss_tokenizer_state_letter_u(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
1046 {
1047     if(css[css_offset] == '+') {
1048         ++css_offset;
1049 
1050         if(css_offset >= css_size) {
1051             entry->state = MyCSS_TOKENIZER_STATE_LETTER_U_NEXT;
1052             return css_offset;
1053         }
1054 
1055         if(mycore_string_chars_hex_map[ (const unsigned char)(css[css_offset]) ] != 0xff ||
1056            css[css_offset] == '?')
1057         {
1058             token->begin += 2;
1059 
1060             ++css_offset;
1061             entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_BEFORE;
1062         }
1063         else {
1064             entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
1065             entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_IDENT;
1066         }
1067     }
1068     else {
1069         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
1070         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_IDENT;
1071     }
1072 
1073     return css_offset;
1074 }
1075 
mycss_tokenizer_state_letter_u_next(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)1076 size_t mycss_tokenizer_state_letter_u_next(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
1077 {
1078     if(mycore_string_chars_hex_map[ (const unsigned char)(css[css_offset]) ] != 0xff ||
1079        css[css_offset] == '?')
1080     {
1081         token->begin += 2;
1082 
1083         ++css_offset;
1084         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_BEFORE;
1085     }
1086     else {
1087         entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
1088         entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_IDENT;
1089     }
1090 
1091     return css_offset;
1092 }
1093 
1094 /////////////////////////////////////////////////////////
1095 //// name-start code point
1096 ////
1097 /////////////////////////////////////////////////////////
mycss_tokenizer_state_name_start_code_point(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)1098 size_t mycss_tokenizer_state_name_start_code_point(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
1099 {
1100     entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
1101     entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_IDENT;
1102 
1103     return css_offset;
1104 }
1105 
1106 /////////////////////////////////////////////////////////
1107 //// U+007C VERTICAL LINE (|)
1108 ////
1109 /////////////////////////////////////////////////////////
mycss_tokenizer_state_vertical_line(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)1110 size_t mycss_tokenizer_state_vertical_line(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
1111 {
1112     if(css[css_offset] == '=') {
1113         css_offset++;
1114 
1115         token->length = 2;
1116         token->type   = MyCSS_TOKEN_TYPE_DASH_MATCH;
1117     }
1118     else if(css[css_offset] == '|') {
1119         css_offset++;
1120 
1121         token->length = 2;
1122         token->type   = MyCSS_TOKEN_TYPE_COLUMN;
1123     }
1124     else {
1125         token->length = 1;
1126         token->type   = MyCSS_TOKEN_TYPE_DELIM;
1127     }
1128 
1129     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
1130 
1131     entry->state = MyCSS_TOKENIZER_STATE_DATA;
1132     return css_offset;
1133 }
1134 
1135 /////////////////////////////////////////////////////////
1136 //// U+007E TILDE (~)
1137 ////
1138 /////////////////////////////////////////////////////////
mycss_tokenizer_state_tilde(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)1139 size_t mycss_tokenizer_state_tilde(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
1140 {
1141     if(css[css_offset] == '=') {
1142         css_offset++;
1143 
1144         token->length = 2;
1145         token->type   = MyCSS_TOKEN_TYPE_INCLUDE_MATCH;
1146     }
1147     else {
1148         token->length = 1;
1149         token->type   = MyCSS_TOKEN_TYPE_DELIM;
1150     }
1151 
1152     MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
1153 
1154     entry->state = MyCSS_TOKENIZER_STATE_DATA;
1155     return css_offset;
1156 }
1157 
1158 /////////////////////////////////////////////////////////
1159 //// anything else
1160 ////
1161 /////////////////////////////////////////////////////////
mycss_tokenizer_state_delim_single_code_point(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)1162 size_t mycss_tokenizer_state_delim_single_code_point(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
1163 {
1164     const unsigned char *u_css = (const unsigned char*)css;
1165 
1166     while (css_offset < css_size)
1167     {
1168         if(u_css[css_offset] < 128)
1169         {
1170             token->length = (entry->current_buffer->offset + css_offset) - token->begin;
1171             token->type   = MyCSS_TOKEN_TYPE_DELIM;
1172 
1173             MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
1174 
1175             entry->state = MyCSS_TOKENIZER_STATE_DATA;
1176             break;
1177         }
1178 
1179         css_offset++;
1180     }
1181 
1182     return css_offset;
1183 }
1184 
1185 /////////////////////////////////////////////////////////
1186 //// init tokenizer
1187 ////
1188 /////////////////////////////////////////////////////////
mycss_tokenizer_state_init(mycss_t * mycss)1189 mystatus_t mycss_tokenizer_state_init(mycss_t* mycss)
1190 {
1191     mycss->parse_state_func = (mycss_tokenizer_state_f*)mycore_calloc((MyCSS_TOKENIZER_STATE_LAST_ENTRY * 2), sizeof(mycss_tokenizer_state_f));
1192 
1193     if(mycss->parse_state_func == NULL)
1194         return MyCSS_STATUS_ERROR_TOKENIZER_STATE_ALLOCATION;
1195 
1196     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_DATA] = mycss_tokenizer_state_data;
1197 
1198     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_WHITESPACE] = mycss_tokenizer_state_whitespace;
1199     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_QUOTATION_MARK] = mycss_tokenizer_state_quotation_mark;
1200     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_QUOTATION_MARK_BACK] = mycss_tokenizer_state_quotation_mark_back;
1201     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_NUMBER_SIGN] = mycss_tokenizer_state_number_sign;
1202     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_NUMBER_SIGN_NAME_BACK] = mycss_tokenizer_state_number_sign_name_back;
1203     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_NUMBER_SIGN_NAME_RSOLIDUS] = mycss_tokenizer_state_number_sign_name_rsolidus;
1204     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_DOLLAR_SIGN] = mycss_tokenizer_state_dollar_sign;
1205     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_APOSTROPHE] = mycss_tokenizer_state_apostrophe;
1206     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_APOSTROPHE_BACK] = mycss_tokenizer_state_apostrophe_back;
1207     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LEFT_PARENTHESIS] = mycss_tokenizer_state_left_parenthesis;
1208     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_RIGHT_PARENTHESIS] = mycss_tokenizer_state_right_parenthesis;
1209     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_ASTERISK] = mycss_tokenizer_state_asterisk;
1210     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_PLUS_SIGN] = mycss_tokenizer_state_plus_sign;
1211     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_PLUS_SIGN_FULL_STOP] = mycss_tokenizer_state_plus_sign_full_stop;
1212     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_COMMA] = mycss_tokenizer_state_comma;
1213     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_HYPHEN_MINUS] = mycss_tokenizer_state_hyphen_minus;
1214     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_FULL_STOP] = mycss_tokenizer_state_hyphen_minus_full_stop;
1215     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_MINUS] = mycss_tokenizer_state_hyphen_minus_minus;
1216     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_MINUS_RSOLIDUS] = mycss_tokenizer_state_hyphen_minus_minus_rsolidus;
1217     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_RSOLIDUS] = mycss_tokenizer_state_hyphen_minus_rsolidus;
1218     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_FULL_STOP] = mycss_tokenizer_state_full_stop;
1219     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_SOLIDUS] = mycss_tokenizer_state_solidus;
1220     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_SOLIDUS_COMMENT_END] = mycss_tokenizer_state_solidus_comment_end;
1221     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_COLON] = mycss_tokenizer_state_colon;
1222     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_SEMICOLON] = mycss_tokenizer_state_semicolon;
1223     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LESS_THAN_SIGN] = mycss_tokenizer_state_less_than_sign;
1224     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LESS_THAN_SIGN_MINUS] = mycss_tokenizer_state_less_than_sign_minus;
1225     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LESS_THAN_SIGN_MINUS_MINUS] = mycss_tokenizer_state_less_than_sign_minus_minus;
1226     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_COMMERCIAL_AT] = mycss_tokenizer_state_commercial_at;
1227     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_MINUS] = mycss_tokenizer_state_commercial_at_minus;
1228     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_MINUS_RSOLIDUS] = mycss_tokenizer_state_commercial_at_minus_rsolidus;
1229     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_RSOLIDUS] = mycss_tokenizer_state_commercial_at_rsolidus;
1230     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_BACK] = mycss_tokenizer_state_commercial_at_back;
1231     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LEFT_SQUARE_BRACKET] = mycss_tokenizer_state_left_square_bracket;
1232     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_REVERSE_SOLIDUS] = mycss_tokenizer_state_reverse_solidus;
1233     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_RIGHT_SQUARE_BRACKET] = mycss_tokenizer_state_right_square_bracket;
1234     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_CIRCUMFLEX_ACCENT] = mycss_tokenizer_state_circumflex_accent;
1235     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LEFT_CURLY_BRACKET] = mycss_tokenizer_state_left_curly_bracket;
1236     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_RIGHT_CURLY_BRACKET] = mycss_tokenizer_state_right_curly_bracket;
1237     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_DIGIT] = mycss_tokenizer_state_digit;
1238     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LETTER_U] = mycss_tokenizer_state_letter_u;
1239     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LETTER_U_NEXT] = mycss_tokenizer_state_letter_u_next;
1240     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT] = mycss_tokenizer_state_name_start_code_point;
1241     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_VERTICAL_LINE] = mycss_tokenizer_state_vertical_line;
1242     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_TILDE] = mycss_tokenizer_state_tilde;
1243     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_DELIM_SINGLE_CODE_POINT] = mycss_tokenizer_state_delim_single_code_point;
1244 
1245     // global
1246     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_BACK] = mycss_tokenizer_global_back;
1247     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC] = mycss_tokenizer_global_state_numeric;
1248     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC_MINUS] = mycss_tokenizer_global_state_numeric_minus;
1249     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC_MINUS_RSOLIDUS] = mycss_tokenizer_global_state_numeric_minus_rsolidus;
1250     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC_RSOLIDUS] = mycss_tokenizer_global_state_numeric_rsolidus;
1251     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DIGIT] = mycss_tokenizer_global_state_number_digit;
1252     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DOT] = mycss_tokenizer_global_state_number_dot;
1253     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DECIMAL] = mycss_tokenizer_global_state_number_decimal;
1254     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_E] = mycss_tokenizer_global_state_number_e;
1255     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_E_PLUS_MINUS] = mycss_tokenizer_global_state_number_e_plus_minus;
1256     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_E_DECIMAL] = mycss_tokenizer_global_state_number_e_decimal;
1257     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_IDENT] = mycss_tokenizer_global_state_ident;
1258     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_URL] = mycss_tokenizer_global_state_url;
1259     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_URL_STRING_BACK] = mycss_tokenizer_global_state_url_string_back;
1260     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_URL_AFTER] = mycss_tokenizer_global_state_url_after;
1261     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_URL_AFTER_WHITESPACE] = mycss_tokenizer_global_state_url_after_whitespace;
1262     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_URL_RSOLIDUS] = mycss_tokenizer_global_state_url_rsolidus;
1263     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_BAD_URL] = mycss_tokenizer_global_state_bad_url;
1264     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NAME] = mycss_tokenizer_global_state_name;
1265     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_NAME_RSOLIDUS] = mycss_tokenizer_global_state_name_rsolidus;
1266     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED] = mycss_tokenizer_global_state_string_double_quoted;
1267     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED_RSOLIDUS] = mycss_tokenizer_global_state_string_double_quoted_rsolidus;
1268     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED_RSOLIDUS_R] = mycss_tokenizer_global_state_string_double_quoted_rsolidus_r;
1269     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED] = mycss_tokenizer_global_state_string_single_quoted;
1270     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED_RSOLIDUS] = mycss_tokenizer_global_state_string_single_quoted_rsolidus;
1271     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED_RSOLIDUS_R] = mycss_tokenizer_global_state_string_single_quoted_rsolidus_r;
1272     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_BEFORE] = mycss_tokenizer_global_state_unicode_range_before;
1273     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE] = mycss_tokenizer_global_state_unicode_range;
1274     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_QUESTION] = mycss_tokenizer_global_state_unicode_range_question;
1275     mycss->parse_state_func[MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_MINUS] = mycss_tokenizer_global_state_unicode_range_minus;
1276 
1277     // end
1278     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_WHITESPACE] = mycss_tokenizer_end_state_whitespace;
1279     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_QUOTATION_MARK] = mycss_tokenizer_end_state_quotation_mark;
1280     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_QUOTATION_MARK_BACK] = mycss_tokenizer_end_state_quotation_mark_back;
1281     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_NUMBER_SIGN] = mycss_tokenizer_end_state_number_sign;
1282     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_NUMBER_SIGN_NAME_BACK] = mycss_tokenizer_end_state_number_sign_name_back;
1283     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_NUMBER_SIGN_NAME_RSOLIDUS] = mycss_tokenizer_end_state_number_sign_name_rsolidus;
1284     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_DOLLAR_SIGN] = mycss_tokenizer_end_state_dollar_sign;
1285     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_APOSTROPHE] = mycss_tokenizer_end_state_apostrophe;
1286     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_APOSTROPHE_BACK] = mycss_tokenizer_end_state_apostrophe_back;
1287     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_LEFT_PARENTHESIS] = mycss_tokenizer_end_state_left_parenthesis;
1288     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_RIGHT_PARENTHESIS] = mycss_tokenizer_end_state_right_parenthesis;
1289     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_ASTERISK] = mycss_tokenizer_end_state_asterisk;
1290     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_PLUS_SIGN] = mycss_tokenizer_end_state_plus_sign;
1291     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_PLUS_SIGN_FULL_STOP] = mycss_tokenizer_end_state_plus_sign_full_stop;
1292     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_COMMA] = mycss_tokenizer_end_state_comma;
1293     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_HYPHEN_MINUS] = mycss_tokenizer_end_state_hyphen_minus;
1294     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_FULL_STOP] = mycss_tokenizer_end_state_hyphen_minus_full_stop;
1295     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_MINUS] = mycss_tokenizer_end_state_hyphen_minus_minus;
1296     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_MINUS_RSOLIDUS] = mycss_tokenizer_end_state_hyphen_minus_minus_rsolidus;
1297     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_HYPHEN_MINUS_RSOLIDUS] = mycss_tokenizer_end_state_hyphen_minus_rsolidus;
1298     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_FULL_STOP] = mycss_tokenizer_end_state_full_stop;
1299     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_SOLIDUS] = mycss_tokenizer_end_state_solidus;
1300     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_SOLIDUS_COMMENT_END] = mycss_tokenizer_end_state_solidus_comment_end;
1301     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_COLON] = mycss_tokenizer_end_state_colon;
1302     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_SEMICOLON] = mycss_tokenizer_end_state_semicolon;
1303     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_LESS_THAN_SIGN] = mycss_tokenizer_end_state_less_than_sign;
1304     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_LESS_THAN_SIGN_MINUS] = mycss_tokenizer_end_state_less_than_sign_minus;
1305     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_LESS_THAN_SIGN_MINUS_MINUS] = mycss_tokenizer_end_state_less_than_sign_minus_minus;
1306     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_COMMERCIAL_AT] = mycss_tokenizer_end_state_commercial_at;
1307     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_MINUS] = mycss_tokenizer_end_state_commercial_at_minus;
1308     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_MINUS_RSOLIDUS] = mycss_tokenizer_end_state_commercial_at_minus_rsolidus;
1309     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_RSOLIDUS] = mycss_tokenizer_end_state_commercial_at_rsolidus;
1310     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_COMMERCIAL_AT_BACK] = mycss_tokenizer_end_state_commercial_at_back;
1311     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_LEFT_SQUARE_BRACKET] = mycss_tokenizer_end_state_left_square_bracket;
1312     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_REVERSE_SOLIDUS] = mycss_tokenizer_end_state_reverse_solidus;
1313     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_RIGHT_SQUARE_BRACKET] = mycss_tokenizer_end_state_right_square_bracket;
1314     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_CIRCUMFLEX_ACCENT] = mycss_tokenizer_end_state_circumflex_accent;
1315     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_LEFT_CURLY_BRACKET] = mycss_tokenizer_end_state_left_curly_bracket;
1316     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_RIGHT_CURLY_BRACKET] = mycss_tokenizer_end_state_right_curly_bracket;
1317     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_DIGIT] = mycss_tokenizer_end_state_digit;
1318     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_LETTER_U] = mycss_tokenizer_end_state_letter_u;
1319     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_LETTER_U_NEXT] = mycss_tokenizer_end_state_letter_u_next;
1320     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT] = mycss_tokenizer_end_state_name_start_code_point;
1321     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_VERTICAL_LINE] = mycss_tokenizer_end_state_vertical_line;
1322     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_TILDE] = mycss_tokenizer_end_state_tilde;
1323     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_STATE_DELIM_SINGLE_CODE_POINT] = mycss_tokenizer_end_state_delim_single_code_point;
1324 
1325     // global end
1326     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_BACK] = mycss_tokenizer_end_global_back;
1327     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC] = mycss_tokenizer_end_global_state_numeric;
1328     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC_MINUS] = mycss_tokenizer_end_global_state_numeric_minus;
1329     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC_MINUS_RSOLIDUS] = mycss_tokenizer_end_global_state_numeric_minus_rsolidus;
1330     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC_RSOLIDUS] = mycss_tokenizer_end_global_state_numeric_rsolidus;
1331     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DIGIT] = mycss_tokenizer_end_global_state_number_digit;
1332     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DOT] = mycss_tokenizer_end_global_state_number_dot;
1333     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DECIMAL] = mycss_tokenizer_end_global_state_number_decimal;
1334     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_E] = mycss_tokenizer_end_global_state_number_e;
1335     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_E_PLUS_MINUS] = mycss_tokenizer_end_global_state_number_e_plus_minus;
1336     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_E_DECIMAL] = mycss_tokenizer_end_global_state_number_e_decimal;
1337     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_IDENT] = mycss_tokenizer_end_global_state_ident;
1338     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_URL] = mycss_tokenizer_end_global_state_url;
1339     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_URL_STRING_BACK] = mycss_tokenizer_end_global_state_url_string_back;
1340     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_URL_AFTER] = mycss_tokenizer_end_global_state_url_after;
1341     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_URL_AFTER_WHITESPACE] = mycss_tokenizer_end_global_state_url_after_whitespace;
1342     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_URL_RSOLIDUS] = mycss_tokenizer_end_global_state_url_rsolidus;
1343     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_BAD_URL] = mycss_tokenizer_end_global_state_bad_url;
1344     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NAME] = mycss_tokenizer_end_global_state_name;
1345     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_NAME_RSOLIDUS] = mycss_tokenizer_end_global_state_name_rsolidus;
1346     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED] = mycss_tokenizer_end_global_state_string_double_quoted;
1347     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED_RSOLIDUS] = mycss_tokenizer_end_global_state_string_double_quoted_rsolidus;
1348     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED_RSOLIDUS_R] = mycss_tokenizer_end_global_state_string_double_quoted_rsolidus;
1349     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED] = mycss_tokenizer_end_global_state_string_single_quoted;
1350     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED_RSOLIDUS] = mycss_tokenizer_end_global_state_string_single_quoted_rsolidus;
1351     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED_RSOLIDUS_R] = mycss_tokenizer_end_global_state_string_single_quoted_rsolidus;
1352     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_BEFORE] = mycss_tokenizer_end_global_state_unicode_range_before;
1353     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE] = mycss_tokenizer_end_global_state_unicode_range;
1354     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_QUESTION] = mycss_tokenizer_end_global_state_unicode_range_question;
1355     mycss->parse_state_func[MyCSS_TOKENIZER_STATE_LAST_ENTRY + MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_MINUS] = mycss_tokenizer_end_global_state_unicode_range_minus;
1356 
1357 
1358     return MyCSS_STATUS_OK;
1359 }
1360 
mycss_tokenizer_state_destroy(mycss_t * mycss)1361 void mycss_tokenizer_state_destroy(mycss_t* mycss)
1362 {
1363     if(mycss->parse_state_func) {
1364         mycore_free(mycss->parse_state_func);
1365         mycss->parse_state_func = NULL;
1366     }
1367 }
1368 
1369 
1370