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_global.h"
22 #include "mycss/tokenizer_resource.h"
23 #include "mycore/utils/resources.h"
24
25 /////////////////////////////////////////////////////////
26 //// Global back
27 ////
28 /////////////////////////////////////////////////////////
mycss_tokenizer_global_back(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)29 size_t mycss_tokenizer_global_back(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
30 {
31 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
32
33 entry->state = MyCSS_TOKENIZER_STATE_DATA;
34 return css_offset;
35 }
36
37 /////////////////////////////////////////////////////////
38 //// Consume a numeric
39 ////
40 /////////////////////////////////////////////////////////
mycss_tokenizer_global_state_numeric(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)41 size_t mycss_tokenizer_global_state_numeric(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
42 {
43 if(css[css_offset] == '%')
44 {
45 css_offset++;
46
47 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
48 token->type = MyCSS_TOKEN_TYPE_PERCENTAGE;
49
50 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
51
52 entry->state = MyCSS_TOKENIZER_STATE_DATA;
53 return css_offset;
54 }
55 else if(css[css_offset] == '-') {
56 css_offset++;
57
58 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC_MINUS;
59 }
60 else if(css[css_offset] == '\\') {
61 css_offset++;
62
63 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC_RSOLIDUS;
64 }
65 else if(mycss_begin_chars_state_map[ (const unsigned char)(css[css_offset]) ] == MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT) {
66 css_offset++;
67
68 token->type = MyCSS_TOKEN_TYPE_DIMENSION;
69
70 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
71 entry->state_back = MyCSS_TOKENIZER_GLOBAL_BACK;
72 }
73 else
74 {
75 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
76 token->type = MyCSS_TOKEN_TYPE_NUMBER;
77
78 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
79
80 entry->state = MyCSS_TOKENIZER_STATE_DATA;
81 }
82
83 return css_offset;
84 }
85
mycss_tokenizer_global_state_numeric_minus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)86 size_t mycss_tokenizer_global_state_numeric_minus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
87 {
88 if(mycss_begin_chars_state_map[ (const unsigned char)(css[css_offset]) ] == MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT) {
89 css_offset++;
90
91 token->type = MyCSS_TOKEN_TYPE_DIMENSION;
92
93 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
94 entry->state_back = MyCSS_TOKENIZER_GLOBAL_BACK;
95 }
96 else if(css[css_offset] == '\\') {
97 css_offset++;
98
99 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMERIC_MINUS_RSOLIDUS;
100 }
101 else {
102 token->length = ((entry->current_buffer->offset + css_offset) - token->begin) - 1;
103 token->type = MyCSS_TOKEN_TYPE_NUMBER;
104
105 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
106
107 entry->state = MyCSS_TOKENIZER_STATE_DATA;
108 css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
109 }
110
111 return css_offset;
112 }
113
mycss_tokenizer_global_state_numeric_minus_rsolidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)114 size_t mycss_tokenizer_global_state_numeric_minus_rsolidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
115 {
116 if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
117 token->length = ((entry->current_buffer->offset + css_offset) - token->begin) - 2;
118 token->type = MyCSS_TOKEN_TYPE_NUMBER;
119
120 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
121
122 entry->state = MyCSS_TOKENIZER_STATE_DATA;
123 css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 2);
124 }
125 else {
126 css_offset++;
127
128 token->type = MyCSS_TOKEN_TYPE_DIMENSION;
129
130 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
131 entry->state_back = MyCSS_TOKENIZER_GLOBAL_BACK;
132 }
133
134 return css_offset;
135 }
136
mycss_tokenizer_global_state_numeric_rsolidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)137 size_t mycss_tokenizer_global_state_numeric_rsolidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
138 {
139 if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
140 token->length = ((entry->current_buffer->offset + css_offset) - token->begin) - 1;
141 token->type = MyCSS_TOKEN_TYPE_NUMBER;
142
143 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
144
145 entry->state = MyCSS_TOKENIZER_STATE_DATA;
146 css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
147 }
148 else {
149 css_offset++;
150
151 token->type = MyCSS_TOKEN_TYPE_DIMENSION;
152
153 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
154 entry->state_back = MyCSS_TOKENIZER_GLOBAL_BACK;
155 }
156
157 return css_offset;
158 }
159
160 /////////////////////////////////////////////////////////
161 //// Consume a number
162 ////
163 /////////////////////////////////////////////////////////
mycss_tokenizer_global_state_number_digit(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)164 size_t mycss_tokenizer_global_state_number_digit(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
165 {
166 while(css_offset < css_size)
167 {
168 if(css[css_offset] < '0' || css[css_offset] > '9')
169 {
170 if(css[css_offset] == '.') {
171 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DOT;
172
173 css_offset++;
174 break;
175 }
176 else if(css[css_offset] == 'E' || css[css_offset] == 'e') {
177 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_E;
178
179 css_offset++;
180 break;
181 }
182 else {
183 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
184
185 entry->state = entry->state_back;
186 break;
187 }
188 }
189
190 css_offset++;
191 }
192
193 return css_offset;
194 }
195
mycss_tokenizer_global_state_number_dot(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)196 size_t mycss_tokenizer_global_state_number_dot(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
197 {
198 if(css[css_offset] >= '0' && css[css_offset] <= '9') {
199 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_DECIMAL;
200 css_offset++;
201 }
202 else {
203 token->length = ((entry->current_buffer->offset + css_offset) - token->begin) - 1;
204 entry->state = entry->state_back;
205 }
206
207 return css_offset;
208 }
209
mycss_tokenizer_global_state_number_decimal(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)210 size_t mycss_tokenizer_global_state_number_decimal(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
211 {
212 while(css_offset < css_size)
213 {
214 if(css[css_offset] < '0' || css[css_offset] > '9')
215 {
216 if(css[css_offset] == 'E' || css[css_offset] == 'e') {
217 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_E;
218
219 css_offset++;
220 break;
221 }
222 else {
223 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
224 entry->state = entry->state_back;
225 break;
226 }
227 }
228
229 css_offset++;
230 }
231
232 return css_offset;
233 }
234
mycss_tokenizer_global_state_number_e(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)235 size_t mycss_tokenizer_global_state_number_e(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
236 {
237 if(css[css_offset] == '+' || css[css_offset] == '-') {
238 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_E_PLUS_MINUS;
239 css_offset++;
240 }
241 else if(css[css_offset] >= '0' && css[css_offset] <= '9') {
242 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_E_DECIMAL;
243 css_offset++;
244 }
245 else {
246 token->length = ((entry->current_buffer->offset + css_offset) - token->begin) - 1;
247 entry->state = entry->state_back;
248 }
249
250 return css_offset;
251 }
252
mycss_tokenizer_global_state_number_e_plus_minus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)253 size_t mycss_tokenizer_global_state_number_e_plus_minus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
254 {
255 if(css[css_offset] >= '0' && css[css_offset] <= '9') {
256 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NUMBER_E_DECIMAL;
257 css_offset++;
258 }
259 else {
260 token->length = ((entry->current_buffer->offset + css_offset) - token->begin) - 2;
261 entry->state = entry->state_back;
262 }
263
264 return css_offset;
265 }
266
mycss_tokenizer_global_state_number_e_decimal(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)267 size_t mycss_tokenizer_global_state_number_e_decimal(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
268 {
269 while(css_offset < css_size)
270 {
271 if(css[css_offset] < '0' || css[css_offset] > '9')
272 {
273 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
274 entry->state = entry->state_back;
275 break;
276 }
277
278 css_offset++;
279 }
280
281 return css_offset;
282 }
283
284 /////////////////////////////////////////////////////////
285 //// Consume a url token
286 ////
287 /////////////////////////////////////////////////////////
mycss_tokenizer_global_state_url(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)288 size_t mycss_tokenizer_global_state_url(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
289 {
290 while(css_offset < css_size)
291 {
292 if(css[css_offset] != '\r' && css[css_offset] != 0x0C &&
293 css[css_offset] != '\n' && css[css_offset] != '\t' && css[css_offset] != ' ')
294 {
295 if(css[css_offset] == '"') {
296 css_offset++;
297
298 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED;
299 entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_URL_STRING_BACK;
300
301 token->begin = entry->current_buffer->offset + css_offset;
302 break;
303 }
304 else if(css[css_offset] == '\'') {
305 css_offset++;
306
307 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED;
308 entry->state_back = MyCSS_TOKENIZER_GLOBAL_STATE_URL_STRING_BACK;
309
310 token->begin = entry->current_buffer->offset + css_offset;
311 break;
312 }
313
314 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_URL_AFTER;
315
316 token->begin = entry->current_buffer->offset + css_offset;
317 break;
318 }
319
320 ++css_offset;
321 }
322
323 return css_offset;
324 }
325
mycss_tokenizer_global_state_url_string_back(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)326 size_t mycss_tokenizer_global_state_url_string_back(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
327 {
328 if(token->type == MyCSS_TOKEN_TYPE_BAD_STRING)
329 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_BAD_URL;
330 else
331 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_URL_AFTER_WHITESPACE;
332
333 return css_offset;
334 }
335
mycss_tokenizer_global_state_url_after(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)336 size_t mycss_tokenizer_global_state_url_after(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
337 {
338 const unsigned char *u_css = (const unsigned char*)css;
339
340 while(css_offset < css_size)
341 {
342 if(css[css_offset] == ')') {
343 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
344 token->type = MyCSS_TOKEN_TYPE_URL;
345
346 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
347
348 entry->state = MyCSS_TOKENIZER_STATE_DATA;
349
350 css_offset++;
351 break;
352 }
353 else if(css[css_offset] == '\r' || css[css_offset] == 0x0C ||
354 css[css_offset] == '\n' || css[css_offset] == '\t' || css[css_offset] == ' ')
355 {
356 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_URL_AFTER_WHITESPACE;
357
358 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
359
360 css_offset++;
361 break;
362 }
363 else if(css[css_offset] == '"' || css[css_offset] == '\'' || css[css_offset] == '(' ||
364 // non-printable code point
365 u_css[css_offset] == 0x00 || u_css[css_offset] == 0x08 || u_css[css_offset] == 0x0B ||
366 u_css[css_offset] == 0x7F || (u_css[css_offset] >= 0x0E && u_css[css_offset] <= 0x1F))
367 {
368 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_BAD_URL;
369
370 css_offset++;
371 break;
372 }
373 else if(css[css_offset] == '\\') {
374 css_offset++;
375
376 break;
377 }
378
379 ++css_offset;
380 }
381
382 return css_offset;
383 }
384
mycss_tokenizer_global_state_url_after_whitespace(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)385 size_t mycss_tokenizer_global_state_url_after_whitespace(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
386 {
387 while(css_offset < css_size)
388 {
389 if(css[css_offset] != '\r' && css[css_offset] != 0x0C &&
390 css[css_offset] != '\n' && css[css_offset] != '\t' && css[css_offset] != ' ')
391 {
392 if(css[css_offset] == ')') {
393 token->type = MyCSS_TOKEN_TYPE_URL;
394
395 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
396
397 entry->state = MyCSS_TOKENIZER_STATE_DATA;
398
399 css_offset++;
400 break;
401 }
402
403 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_BAD_URL;
404 break;
405 }
406
407 ++css_offset;
408 }
409
410 return css_offset;
411 }
412
mycss_tokenizer_global_state_url_rsolidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)413 size_t mycss_tokenizer_global_state_url_rsolidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
414 {
415 if(css[css_offset] != '\n' && css[css_offset] != '\r' && css[css_offset] != 0x0C) {
416 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_URL_AFTER;
417 return (css_offset + 1);
418 }
419
420 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_BAD_URL;
421
422 return css_offset;
423 }
424
mycss_tokenizer_global_state_bad_url(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)425 size_t mycss_tokenizer_global_state_bad_url(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
426 {
427 while(css_offset < css_size)
428 {
429 if(css[css_offset] == ')') {
430 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
431 token->type = MyCSS_TOKEN_TYPE_BAD_URL;
432
433 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
434
435 entry->state = MyCSS_TOKENIZER_STATE_DATA;
436
437 css_offset++;
438 break;
439 }
440 // else if(css[css_offset] == '\\') {
441 // css_offset++;
442 // break;
443 // }
444
445 ++css_offset;
446 }
447
448 return css_offset;
449 }
450
451 /////////////////////////////////////////////////////////
452 //// Consume a string token
453 ////
454 /////////////////////////////////////////////////////////
mycss_tokenizer_global_state_string_double_quoted(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)455 size_t mycss_tokenizer_global_state_string_double_quoted(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
456 {
457 while(css_offset < css_size)
458 {
459 if(css[css_offset] == '"')
460 {
461 token->type = MyCSS_TOKEN_TYPE_STRING;
462 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
463
464 // skip QUOTATION MARK (")
465 ++css_offset;
466 entry->state = entry->state_back;
467 break;
468 }
469 else if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
470 token->type = MyCSS_TOKEN_TYPE_BAD_STRING;
471 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
472
473 entry->state = entry->state_back;
474 break;
475 }
476 else if(css[css_offset] == '\\') {
477 css_offset++;
478
479 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED_RSOLIDUS;
480 break;
481 }
482
483 ++css_offset;
484 }
485
486 return css_offset;
487 }
488
mycss_tokenizer_global_state_string_double_quoted_rsolidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)489 size_t mycss_tokenizer_global_state_string_double_quoted_rsolidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
490 {
491 if(css[css_offset] == '\r')
492 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED_RSOLIDUS_R;
493 else
494 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED;
495
496 css_offset++;
497 return css_offset;
498 }
499
mycss_tokenizer_global_state_string_double_quoted_rsolidus_r(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)500 size_t mycss_tokenizer_global_state_string_double_quoted_rsolidus_r(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
501 {
502 if(css[css_offset] == '\n')
503 css_offset++;
504
505 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_DOUBLE_QUOTED;
506
507 return css_offset;
508 }
509
mycss_tokenizer_global_state_string_single_quoted(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)510 size_t mycss_tokenizer_global_state_string_single_quoted(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
511 {
512 while(css_offset < css_size)
513 {
514 if(css[css_offset] == '\'')
515 {
516 token->type = MyCSS_TOKEN_TYPE_STRING;
517 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
518
519 // skip APOSTROPHE (')
520 ++css_offset;
521
522 entry->state = entry->state_back;
523 break;
524 }
525 else if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
526 token->type = MyCSS_TOKEN_TYPE_BAD_STRING;
527 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
528
529 entry->state = entry->state_back;
530 break;
531 }
532 else if(css[css_offset] == '\\') {
533 css_offset++;
534
535 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED_RSOLIDUS;
536 break;
537 }
538
539 ++css_offset;
540 }
541
542 return css_offset;
543 }
544
mycss_tokenizer_global_state_string_single_quoted_rsolidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)545 size_t mycss_tokenizer_global_state_string_single_quoted_rsolidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
546 {
547 if(css[css_offset] == '\r')
548 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED_RSOLIDUS_R;
549 else
550 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED;
551
552 css_offset++;
553 return css_offset;
554 }
555
mycss_tokenizer_global_state_string_single_quoted_rsolidus_r(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)556 size_t mycss_tokenizer_global_state_string_single_quoted_rsolidus_r(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
557 {
558 if(css[css_offset] == '\n')
559 css_offset++;
560
561 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_STRING_SINGLE_QUOTED;
562
563 return css_offset;
564 }
565
566 /////////////////////////////////////////////////////////
567 //// Consume an ident-like token
568 ////
569 /////////////////////////////////////////////////////////
mycss_tokenizer_global_state_ident(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)570 size_t mycss_tokenizer_global_state_ident(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
571 {
572 if(css[css_offset] == '(')
573 {
574 if(mycss_tokenizer_token_strcasecmp(entry, token, "url", 3) == 0) {
575 css_offset++;
576
577 token->begin = css_offset;
578 token->type = MyCSS_TOKEN_TYPE_URL;
579 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_URL;
580 }
581 else {
582 css_offset++;
583
584 token->type = MyCSS_TOKEN_TYPE_FUNCTION;
585
586 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
587
588 entry->state = MyCSS_TOKENIZER_STATE_DATA;
589 }
590 }
591 else {
592 token->type = MyCSS_TOKEN_TYPE_IDENT;
593
594 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
595
596 entry->state = MyCSS_TOKENIZER_STATE_DATA;
597 }
598
599 return css_offset;
600 }
601
602 /////////////////////////////////////////////////////////
603 //// Consume a name
604 ////
605 /////////////////////////////////////////////////////////
mycss_tokenizer_global_state_name(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)606 size_t mycss_tokenizer_global_state_name(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
607 {
608 const unsigned char *u_css = (const unsigned char*)css;
609
610 while(css_offset < css_size)
611 {
612 if(mycss_chars_name_code_point_map[ u_css[css_offset] ] == 0xff)
613 {
614 if(css[css_offset] == '\\') {
615 ++css_offset;
616
617 if(css_offset >= css_size) {
618 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME_RSOLIDUS;
619 break;
620 }
621
622 if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
623 --css_offset;
624
625 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
626 entry->state = entry->state_back;
627
628 break;
629 }
630 }
631 else {
632 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
633 entry->state = entry->state_back;
634
635 break;
636 }
637 }
638
639 css_offset++;
640 }
641
642 return css_offset;
643 }
644
mycss_tokenizer_global_state_name_rsolidus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)645 size_t mycss_tokenizer_global_state_name_rsolidus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
646 {
647 if(css[css_offset] == '\n' || css[css_offset] == '\r' || css[css_offset] == 0x0C) {
648 token->length = ((entry->current_buffer->offset + css_offset) - token->begin) - 1;
649 entry->state = entry->state_back;
650
651 return mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
652 }
653 else {
654 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_NAME;
655 css_offset++;
656 }
657
658 return css_offset;
659 }
660
661 /////////////////////////////////////////////////////////
662 //// Consume a unicode-range token
663 ////
664 /////////////////////////////////////////////////////////
mycss_tokenizer_global_state_unicode_range_before(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)665 size_t mycss_tokenizer_global_state_unicode_range_before(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
666 {
667 entry->help_counter = 0;
668 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE;
669
670 return css_offset;
671 }
672
mycss_tokenizer_global_state_unicode_range(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)673 size_t mycss_tokenizer_global_state_unicode_range(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
674 {
675 const unsigned char *u_css = (const unsigned char*)css;
676
677 while(css_offset < css_size)
678 {
679 if(mycore_string_chars_hex_map[ u_css[css_offset] ] != 0xff)
680 {
681 entry->help_counter++;
682
683 if(entry->help_counter == 6) {
684 css_offset++;
685
686 entry->help_counter = 0;
687 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_MINUS;
688
689 break;
690 }
691 }
692 else if(css[css_offset] == '?') {
693 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_QUESTION;
694 break;
695 }
696 else if(css[css_offset] == '-') {
697 css_offset++;
698
699 entry->help_counter = 0;
700 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_MINUS;
701 break;
702 }
703 else {
704 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
705 token->type = MyCSS_TOKEN_TYPE_UNICODE_RANGE;
706
707 // TODO
708 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
709
710 entry->state = MyCSS_TOKENIZER_STATE_DATA;
711 break;
712 }
713
714 css_offset++;
715 }
716
717 return css_offset;
718 }
719
mycss_tokenizer_global_state_unicode_range_question(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)720 size_t mycss_tokenizer_global_state_unicode_range_question(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
721 {
722 while(css_offset < css_size)
723 {
724 if(css[css_offset] == '?') {
725 entry->help_counter++;
726
727 if(entry->help_counter == 6) {
728 css_offset++;
729
730 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
731 token->type = MyCSS_TOKEN_TYPE_UNICODE_RANGE;
732
733 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
734
735 entry->state = MyCSS_TOKENIZER_STATE_DATA;
736 break;
737 }
738 }
739 else {
740 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
741 token->type = MyCSS_TOKEN_TYPE_UNICODE_RANGE;
742
743 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
744
745 entry->state = MyCSS_TOKENIZER_STATE_DATA;
746 break;
747 }
748
749 css_offset++;
750 }
751
752 return css_offset;
753 }
754
mycss_tokenizer_global_state_unicode_range_minus(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)755 size_t mycss_tokenizer_global_state_unicode_range_minus(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
756 {
757 const unsigned char *u_css = (const unsigned char*)css;
758
759 while(css_offset < css_size)
760 {
761 if(mycore_string_chars_hex_map[ u_css[css_offset] ] != 0xff)
762 {
763 entry->help_counter++;
764
765 if(entry->help_counter == 6) {
766 css_offset++;
767
768 entry->state = MyCSS_TOKENIZER_GLOBAL_STATE_UNICODE_RANGE_MINUS;
769 break;
770 }
771 }
772 else {
773 if(entry->help_counter == 0) {
774 token->length = ((entry->current_buffer->offset + css_offset) - token->begin) - 1;
775 css_offset = mycss_tokenizer_state_set_current_buffer_for_continue(entry, css_offset, 1);
776 }
777 else {
778 token->length = (entry->current_buffer->offset + css_offset) - token->begin;
779 }
780
781 token->type = MyCSS_TOKEN_TYPE_UNICODE_RANGE;
782
783 MyCSS_TOKEN_READY_CALLBACK_FUNCTION(entry, token);
784
785 entry->state = MyCSS_TOKENIZER_STATE_DATA;
786 break;
787 }
788
789 css_offset++;
790 }
791
792 return css_offset;
793 }
794
795
796
797