php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
anb.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2021-2022 Alexander Borisov
3 *
4 * Author: Alexander Borisov <borisov@lexbor.com>
5 */
6
7#include "lexbor/core/conv.h"
9#include "lexbor/css/css.h"
10#include "lexbor/css/parser.h"
12
13
14static bool
15lxb_css_syntax_anb_state(lxb_css_parser_t *parser,
16 const lxb_css_syntax_token_t *token, void *ctx);
17
18static lxb_status_t
19lxb_css_syntax_anb_end(lxb_css_parser_t *parser,
20 const lxb_css_syntax_token_t *token,
21 void *ctx, bool failed);
22
24lxb_css_syntax_anb_fail(lxb_css_parser_t *parser,
25 const lxb_css_syntax_token_t *token);
26
27static lxb_status_t
28lxb_css_syntax_anb_state_ident(lxb_css_parser_t *parser,
29 const lxb_css_syntax_token_t *token,
31
32static lxb_status_t
33lxb_css_syntax_anb_state_ident_data(lxb_css_parser_t *parser,
35 const lxb_css_syntax_token_t *token,
36 const lxb_char_t *data,
37 const lxb_char_t *end);
38
39
40static const lxb_css_syntax_cb_pipe_t lxb_css_syntax_anb_pipe = {
41 .state = lxb_css_syntax_anb_state,
42 .block = NULL,
43 .failed = lxb_css_state_failed,
44 .end = lxb_css_syntax_anb_end
45};
46
47
50 const lxb_char_t *data, size_t length)
51{
55
56 memset(&anb, 0, sizeof(lxb_css_syntax_anb_t));
57
58 if (parser->stage != LXB_CSS_PARSER_CLEAN) {
59 if (parser->stage == LXB_CSS_PARSER_RUN) {
61 return anb;
62 }
63
65 }
66
67 lxb_css_parser_buffer_set(parser, data, length);
68
70 &lxb_css_syntax_anb_pipe, &anb,
72 if (rule == NULL) {
73 return anb;
74 }
75
76 parser->tkz->with_comment = false;
77 parser->stage = LXB_CSS_PARSER_RUN;
78
80 if (status != LXB_STATUS_OK) {
81 /* Destroy. */
82 }
83
84 parser->stage = LXB_CSS_PARSER_END;
85
86 return anb;
87}
88
89static bool
90lxb_css_syntax_anb_state(lxb_css_parser_t *parser,
91 const lxb_css_syntax_token_t *token, void *ctx)
92{
93 parser->status = lxb_css_syntax_anb_handler(parser, token, ctx);
94
95 token = lxb_css_syntax_parser_token(parser);
96 if (token == NULL) {
97 return lxb_css_parser_memory_fail(parser);
98 }
99
100 if (parser->status != LXB_STATUS_OK
101 || (token->type != LXB_CSS_SYNTAX_TOKEN__END))
102 {
103 (void) lxb_css_syntax_anb_fail(parser, token);
104 }
105
106 return lxb_css_parser_success(parser);
107}
108
109static lxb_status_t
110lxb_css_syntax_anb_end(lxb_css_parser_t *parser,
111 const lxb_css_syntax_token_t *token,
112 void *ctx, bool failed)
113{
114 return LXB_STATUS_OK;
115}
116
118lxb_css_syntax_anb_fail(lxb_css_parser_t *parser,
119 const lxb_css_syntax_token_t *token)
120{
122
123 static const char anb[] = "An+B";
124
125 return lxb_css_syntax_token_error(parser, token, anb);
126}
127
130 const lxb_css_syntax_token_t *token,
132{
133 const lxb_char_t *data, *end;
135
136again:
137
138 switch (token->type) {
140 if (lxb_css_syntax_token_dimension(token)->num.is_float) {
142 }
143
145
147
148 goto ident;
149
151 return lxb_css_syntax_anb_state_ident(parser, token, anb);
152
156 }
157
158 anb->a = 0;
160 break;
161
163 if (lxb_css_syntax_token_delim(token)->character != '+') {
165 }
166
168 lxb_css_parser_token_status_m(parser, token);
169
170 if (token->type != LXB_CSS_SYNTAX_TOKEN_IDENT) {
172 }
173
174 anb->a = 1;
175
176 ident = lxb_css_syntax_token_ident(token);
177
178 goto ident;
179
182 lxb_css_parser_token_status_m(parser, token);
183 goto again;
184
185 default:
187 }
188
190
191 return LXB_STATUS_OK;
192
193ident:
194
195 data = ident->data;
196 end = ident->data + ident->length;
197
198 if (*data != 'n' && *data != 'N') {
200 }
201
202 data++;
203
204 return lxb_css_syntax_anb_state_ident_data(parser, anb, token, data, end);
205}
206
207static lxb_status_t
208lxb_css_syntax_anb_state_ident(lxb_css_parser_t *parser,
209 const lxb_css_syntax_token_t *token,
211{
212 size_t length;
213 lxb_char_t c;
214 const lxb_char_t *data, *end;
216
217 static const lxb_char_t odd[] = "odd";
218 static const lxb_char_t even[] = "even";
219
220 ident = lxb_css_syntax_token_ident(token);
221
222 length = ident->length;
223 data = ident->data;
224 end = data + length;
225
226 c = *data++;
227
228 /* 'n' or '-n' */
229
230 if (c == 'n' || c == 'N') {
231 anb->a = 1;
232 }
233 else if (c == '-') {
234 if (data >= end) {
236 }
237
238 c = *data++;
239
240 if (c != 'n' && c != 'N') {
242 }
243
244 anb->a = -1;
245 }
246 else if (length == sizeof(odd) - 1
247 && lexbor_str_data_ncasecmp(ident->data, odd, sizeof(odd) - 1))
248 {
249 anb->a = 2;
250 anb->b = 1;
251
253 return LXB_STATUS_OK;
254 }
255 else if (length == sizeof(even) - 1
256 && lexbor_str_data_ncasecmp(ident->data, even, sizeof(even) - 1))
257 {
258 anb->a = 2;
259 anb->b = 0;
260
262 return LXB_STATUS_OK;
263 }
264 else {
266 }
267
268 return lxb_css_syntax_anb_state_ident_data(parser, anb, token, data, end);
269}
270
271static lxb_status_t
272lxb_css_syntax_anb_state_ident_data(lxb_css_parser_t *parser,
274 const lxb_css_syntax_token_t *token,
275 const lxb_char_t *data,
276 const lxb_char_t *end)
277{
278 unsigned sign;
279 lxb_char_t c;
280 const lxb_char_t *p;
281
282 sign = 0;
283
284 if (data >= end) {
287
288 switch (token->type) {
290 if (!lxb_css_syntax_token_number(token)->have_sign) {
291 anb->b = 0;
292 return LXB_STATUS_OK;
293 }
294
295 break;
296
298 c = lxb_css_syntax_token_delim(token)->character;
299
300 switch (c) {
301 case '-':
302 sign = 1;
303 break;
304
305 case '+':
306 sign = 2;
307 break;
308
309 default:
310 anb->b = 0;
311 return LXB_STATUS_OK;
312 }
313
316
317 break;
318
320 anb->b = 0;
321 return LXB_STATUS_OK;
322
323 default:
324 anb->b = 0;
325 return LXB_STATUS_OK;
326 }
327
328 goto number;
329 }
330
331 c = *data++;
332
333 if (c != '-') {
335 }
336
337 if (data < end) {
338 p = data;
340
341 if (anb->b > 0 || data == p || data < end) {
343 }
344
345 goto done;
346 }
347
348 sign = 1;
349
352
353number:
354
355 if (token->type != LXB_CSS_SYNTAX_TOKEN_NUMBER) {
357 }
358
360 || (sign > 0 && lxb_css_syntax_token_number(token)->have_sign))
361 {
363 }
364
366
367 if (sign == 1) {
368 anb->b = -anb->b;
369 }
370
371done:
372
374
375 return LXB_STATUS_OK;
376}
377
380 lexbor_serialize_cb_f cb, void *ctx)
381{
382 lxb_char_t buf[128];
383 lxb_char_t *p, *end;
384
385 if (anb == NULL) {
386 return LXB_STATUS_OK;
387 }
388
389 static const lxb_char_t odd[] = "odd";
390 static const lxb_char_t even[] = "even";
391
392 if (anb->a == 2) {
393 if (anb->b == 1) {
394 return cb(odd, sizeof(odd) - 1, ctx);
395 }
396
397 if (anb->b == 0) {
398 return cb(even, sizeof(even) - 1, ctx);
399 }
400 }
401
402 p = buf;
403 end = p + sizeof(buf);
404
405 if (anb->a == 1) {
406 *p = '+';
407 p++;
408 }
409 else if (anb->a == -1) {
410 *p = '-';
411 p++;
412 }
413 else {
414 p += lexbor_conv_float_to_data((double) anb->a, p, end - p);
415 if (p >= end) {
417 }
418 }
419
420 *p = 'n';
421 p++;
422
423 if (p >= end) {
424 return cb(buf, p - buf, ctx);
425 }
426
427 if (anb->b == 0) {
428 return cb(buf, p - buf, ctx);
429 }
430
431 if (anb->b > 0) {
432 *p = '+';
433 p++;
434
435 if (p >= end) {
437 }
438 }
439
440 p += lexbor_conv_float_to_data((double) anb->b, p, end - p);
441
442 return cb(buf, p - buf, ctx);
443}
444
447{
448 size_t length = 0;
450 lexbor_str_t str;
451
453 &length);
454 if (status != LXB_STATUS_OK) {
455 goto failed;
456 }
457
458 /* + 1 == '\0' */
459 str.data = lexbor_malloc(length + 1);
460 if (str.data == NULL) {
461 goto failed;
462 }
463
464 str.length = 0;
465
467 if (status != LXB_STATUS_OK) {
468 lexbor_free(str.data);
469 goto failed;
470 }
471
472 str.data[str.length] = '\0';
473
474 if (out_length != NULL) {
475 *out_length = str.length;
476 }
477
478 return str.data;
479
480failed:
481
482 if (out_length != NULL) {
483 *out_length = 0;
484 }
485
486 return NULL;
487}
lxb_status_t lxb_css_syntax_anb_handler(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, lxb_css_syntax_anb_t *anb)
Definition anb.c:129
lxb_css_syntax_anb_t lxb_css_syntax_anb_parse(lxb_css_parser_t *parser, const lxb_char_t *data, size_t length)
Definition anb.c:49
lxb_char_t * lxb_css_syntax_anb_serialize_char(lxb_css_syntax_anb_t *anb, size_t *out_length)
Definition anb.c:446
lxb_status_t lxb_css_syntax_anb_serialize(lxb_css_syntax_anb_t *anb, lexbor_serialize_cb_f cb, void *ctx)
Definition anb.c:379
char * cb
Definition assert.c:26
is_float(mixed $value)
sign
Definition bcmath.h:37
long lexbor_conv_data_to_long(const lxb_char_t **data, size_t length)
Definition conv.c:236
size_t lexbor_conv_float_to_data(double num, lxb_char_t *buf, size_t len)
Definition conv.c:16
lxb_inline long lexbor_conv_double_to_long(double number)
Definition conv.h:43
lxb_status_t(* lexbor_serialize_cb_f)(const lxb_char_t *data, size_t len, void *ctx)
Definition base.h:82
@ LXB_STATUS_ERROR_SMALL_BUFFER
Definition base.h:53
@ LXB_STATUS_ERROR_WRONG_ARGS
Definition base.h:58
@ LXB_STATUS_OK
Definition base.h:49
@ LXB_STATUS_ERROR_UNEXPECTED_DATA
Definition base.h:61
struct lxb_css_syntax_token lxb_css_syntax_token_t
Definition base.h:46
struct lxb_css_parser lxb_css_parser_t
Definition base.h:41
bool lxb_css_parser_success(lxb_css_parser_t *parser)
Definition parser.c:279
void lxb_css_parser_clean(lxb_css_parser_t *parser)
Definition parser.c:104
bool lxb_css_parser_memory_fail(lxb_css_parser_t *parser)
Definition parser.c:335
@ LXB_CSS_PARSER_CLEAN
Definition parser.h:124
@ LXB_CSS_PARSER_RUN
Definition parser.h:125
@ LXB_CSS_PARSER_END
Definition parser.h:127
#define lxb_css_parser_token_status_m(parser, token)
Definition parser.h:56
lxb_inline void lxb_css_parser_buffer_set(lxb_css_parser_t *parser, const lxb_char_t *data, size_t length)
Definition parser.h:338
#define lxb_css_parser_token_status_wo_ws_m(parser, token)
Definition parser.h:74
bool lxb_css_state_failed(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, void *ctx)
Definition state.c:32
lxb_css_syntax_rule_t * lxb_css_syntax_parser_pipe_push(lxb_css_parser_t *parser, lxb_css_parser_state_f state_back, const lxb_css_syntax_cb_pipe_t *pipe, void *ctx, lxb_css_syntax_token_type_t stop)
Definition parser.c:550
lxb_status_t lxb_css_syntax_parser_run(lxb_css_parser_t *parser)
Definition parser.c:116
const lxb_css_syntax_token_t * lxb_css_syntax_parser_token(lxb_css_parser_t *parser)
Definition parser.c:142
void lxb_css_syntax_parser_consume(lxb_css_parser_t *parser)
Definition parser.c:171
lxb_css_log_message_t * lxb_css_syntax_token_error(lxb_css_parser_t *parser, const lxb_css_syntax_token_t *token, const char *module_name)
Definition token.c:594
#define lxb_css_syntax_token_number(token)
Definition token.h:31
lxb_css_syntax_token_string_t lxb_css_syntax_token_ident_t
Definition token.h:145
#define lxb_css_syntax_token_ident(token)
Definition token.h:21
@ LXB_CSS_SYNTAX_TOKEN__EOF
Definition token.h:101
@ LXB_CSS_SYNTAX_TOKEN_NUMBER
Definition token.h:88
@ LXB_CSS_SYNTAX_TOKEN_DELIM
Definition token.h:87
@ LXB_CSS_SYNTAX_TOKEN_UNDEF
Definition token.h:69
@ LXB_CSS_SYNTAX_TOKEN_DIMENSION
Definition token.h:84
@ LXB_CSS_SYNTAX_TOKEN_IDENT
Definition token.h:72
@ LXB_CSS_SYNTAX_TOKEN_WHITESPACE
Definition token.h:81
@ LXB_CSS_SYNTAX_TOKEN__END
Definition token.h:103
#define lxb_css_syntax_token_dimension(token)
Definition token.h:33
#define lxb_css_syntax_token_delim(token)
Definition token.h:29
#define lxb_css_syntax_token_dimension_string(token)
Definition token.h:34
DNS_STATUS status
Definition dns_win32.c:49
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
#define NULL
Definition gdcache.h:45
LXB_API void * lexbor_free(void *dst)
Definition memory.c:33
LXB_API void * lexbor_malloc(size_t size)
Definition memory.c:15
unsigned const char * end
Definition php_ffi.h:51
zend_constant * data
lxb_status_t lexbor_serialize_length_cb(const lxb_char_t *data, size_t length, void *ctx)
Definition serialize.c:12
lxb_status_t lexbor_serialize_copy_cb(const lxb_char_t *data, size_t length, void *ctx)
Definition serialize.c:19
p
Definition session.c:1105
bool lexbor_str_data_ncasecmp(const lxb_char_t *first, const lxb_char_t *sec, size_t size)
Definition str.c:435
lxb_char_t * data
Definition str.h:47
size_t length
Definition str.h:48
lxb_status_t status
Definition parser.h:177
lxb_css_parser_stage_t stage
Definition parser.h:170
lxb_css_syntax_tokenizer_t * tkz
Definition parser.h:136
const lxb_char_t * data
Definition token.h:128
lxb_css_syntax_token_type_t type
Definition token.h:192
lxb_css_syntax_cb_base_t lxb_css_syntax_cb_pipe_t
Definition syntax.h:75
struct lxb_css_syntax_rule lxb_css_syntax_rule_t
Definition syntax.h:17
unsigned int lxb_status_t
Definition types.h:28
unsigned char lxb_char_t
Definition types.h:27
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)