1 2/* 3 +------------------------------------------------------------------------+ 4 | Phalcon Framework | 5 +------------------------------------------------------------------------+ 6 | Copyright (c) 2011-present Phalcon Team (http://www.phalconphp.com) | 7 +------------------------------------------------------------------------+ 8 | This source file is subject to the New BSD License that is bundled | 9 | with this package in the file docs/LICENSE.txt. | 10 | | 11 | If you did not receive a copy of the license and are unable to | 12 | obtain it through the world-wide-web, please send an email | 13 | to license@phalconphp.com so we can send you a copy immediately. | 14 +------------------------------------------------------------------------+ 15 | Authors: Andres Gutierrez <andres@phalconphp.com> | 16 | Eduar Carvajal <eduar@phalconphp.com> | 17 +------------------------------------------------------------------------+ 18*/ 19 20#include "php_phalcon.h" 21#include "scanner.h" 22 23#define YYCTYPE unsigned char 24#define YYCURSOR (s->start) 25#define YYLIMIT (s->end) 26#define YYMARKER q 27 28void phvolt_rtrim(phvolt_scanner_token *token) { 29 30 char *cursor, *removed_str; 31 int i; 32 char ch; 33 34 if (token->len > 0) { 35 36 cursor = token->value; 37 cursor += (token->len - 1); 38 for (i = token->len; i > 0; i--) { 39 ch = (*cursor); 40 if (ch == '\t' || ch == '\n' || ch == '\r' || ch == ' ' || ch == '\v') { 41 cursor--; 42 continue; 43 } 44 break; 45 } 46 47 if (i >= 0) { 48 removed_str = emalloc(i + 1); 49 memcpy(removed_str, token->value, i); 50 removed_str[i] = '\0'; 51 52 efree(token->value); 53 token->value = removed_str; 54 token->len = i; 55 } 56 } 57 58} 59 60void phvolt_ltrim(phvolt_scanner_token *token) { 61 62 char *cursor, *removed_str; 63 int i; 64 65 if (token->len > 0) { 66 67 cursor = token->value; 68 for (i = 0; i < token->len; i++) { 69 char ch = (*cursor); 70 if (ch == '\t' || ch == '\n' || ch == '\r' || ch == ' ' || ch == '\v') { 71 cursor++; 72 continue; 73 } 74 break; 75 } 76 77 if (i >= 0) { 78 removed_str = emalloc(token->len - i + 1); 79 memcpy(removed_str, token->value + i, token->len - i); 80 removed_str[token->len - i] = '\0'; 81 82 efree(token->value); 83 token->value = removed_str; 84 token->len = token->len - i; 85 } 86 } 87 88} 89 90int phvolt_get_token(phvolt_scanner_state *s, phvolt_scanner_token *token) { 91 92 unsigned char next, double_next; 93 char *q = YYCURSOR, *start = YYCURSOR; 94 int status = PHVOLT_SCANNER_RETCODE_IMPOSSIBLE; 95 96 while (PHVOLT_SCANNER_RETCODE_IMPOSSIBLE == status) { 97 98 if (s->mode == PHVOLT_MODE_RAW || s->mode == PHVOLT_MODE_COMMENT) { 99 100 next = '\0'; 101 double_next = '\0'; 102 103 if (*YYCURSOR == '\n') { 104 s->active_line++; 105 } 106 107 if (*YYCURSOR != '\0') { 108 next = *(YYCURSOR + 1); 109 if (next != '\0') { 110 double_next = *(YYCURSOR + 2); 111 } 112 } 113 114 if (*YYCURSOR == '\0' || (*YYCURSOR == '{' && (next == '%' || next == '{' || next == '#'))) { 115 116 if (next != '#') { 117 118 s->mode = PHVOLT_MODE_CODE; 119 120 if (s->raw_buffer_cursor > 0) { 121 122 token->opcode = PHVOLT_T_RAW_FRAGMENT; 123 token->value = emalloc(sizeof(char) * s->raw_buffer_cursor + 1); 124 memcpy(token->value, s->raw_buffer, s->raw_buffer_cursor); 125 token->value[s->raw_buffer_cursor] = 0; 126 token->len = s->raw_buffer_cursor; 127 128 if (s->whitespace_control == 1) { 129 phvolt_ltrim(token); 130 s->whitespace_control = 0; 131 } 132 133 if (double_next == '-') { 134 phvolt_rtrim(token); 135 } 136 137 s->raw_buffer_cursor = 0; 138 q = YYCURSOR; 139 } else { 140 token->opcode = PHVOLT_T_IGNORE; 141 } 142 143 } else { 144 145 while ((next = *(++YYCURSOR))) { 146 if (next == '#' && *(YYCURSOR + 1) == '}') { 147 YYCURSOR += 2; 148 token->opcode = PHVOLT_T_IGNORE; 149 return 0; 150 } else { 151 if (next == '\n') { 152 s->active_line++; 153 } 154 } 155 } 156 157 return PHVOLT_SCANNER_RETCODE_EOF; 158 } 159 160 return 0; 161 162 } else { 163 164 if (s->raw_buffer_cursor == s->raw_buffer_size) { 165 s->raw_buffer_size += PHVOLT_RAW_BUFFER_SIZE; 166 s->raw_buffer = erealloc(s->raw_buffer, s->raw_buffer_size); 167 } 168 169 memcpy(s->raw_buffer+s->raw_buffer_cursor, YYCURSOR, 1); 170 s->raw_buffer_cursor++; 171 172 ++YYCURSOR; 173 } 174 175 } else { 176 177 /*!re2c 178 re2c:indent:top = 2; 179 re2c:yyfill:enable = 0; 180 181 INTEGER = [0-9]+; 182 INTEGER { 183 token->opcode = PHVOLT_T_INTEGER; 184 token->value = estrndup(start, YYCURSOR - start); 185 token->len = YYCURSOR - start; 186 q = YYCURSOR; 187 return 0; 188 } 189 190 DOUBLE = ([0-9]+[\.][0-9]+); 191 DOUBLE { 192 token->opcode = PHVOLT_T_DOUBLE; 193 token->value = estrndup(start, YYCURSOR - start); 194 token->len = YYCURSOR - start; 195 q = YYCURSOR; 196 return 0; 197 } 198 199 'if' { 200 s->statement_position++; 201 token->opcode = PHVOLT_T_IF; 202 return 0; 203 } 204 205 'else' { 206 token->opcode = PHVOLT_T_ELSE; 207 return 0; 208 } 209 210 'elsefor' { 211 token->opcode = PHVOLT_T_ELSEFOR; 212 return 0; 213 } 214 215 'elseif' { 216 token->opcode = PHVOLT_T_ELSEIF; 217 return 0; 218 } 219 220 'endif' { 221 token->opcode = PHVOLT_T_ENDIF; 222 return 0; 223 } 224 225 'for' { 226 s->statement_position++; 227 token->opcode = PHVOLT_T_FOR; 228 return 0; 229 } 230 231 'endfor' { 232 token->opcode = PHVOLT_T_ENDFOR; 233 return 0; 234 } 235 236 'switch' { 237 s->statement_position++; 238 token->opcode = PHVOLT_T_SWITCH; 239 return 0; 240 } 241 242 'case' { 243 token->opcode = PHVOLT_T_CASE; 244 return 0; 245 } 246 247 'default' { 248 token->opcode = PHVOLT_T_DEFAULT; 249 250 // TODO: Make this better. 251 // Issue: https://github.com/phalcon/cphalcon/issues/13242 252 // Introduced: https://github.com/phalcon/cphalcon/pull/13130 253 token->value = estrndup(start, YYCURSOR - start); 254 token->len = YYCURSOR - start; 255 q = YYCURSOR; 256 257 return 0; 258 } 259 260 'endswitch' { 261 token->opcode = PHVOLT_T_ENDSWITCH; 262 return 0; 263 } 264 265 'in' { 266 token->opcode = PHVOLT_T_IN; 267 return 0; 268 } 269 270 'set' { 271 token->opcode = PHVOLT_T_SET; 272 return 0; 273 } 274 275 'null' { 276 token->opcode = PHVOLT_T_NULL; 277 return 0; 278 } 279 280 'false' { 281 token->opcode = PHVOLT_T_FALSE; 282 return 0; 283 } 284 285 'true' { 286 token->opcode = PHVOLT_T_TRUE; 287 return 0; 288 } 289 290 'and' { 291 token->opcode = PHVOLT_T_AND; 292 return 0; 293 } 294 295 'or' { 296 token->opcode = PHVOLT_T_OR; 297 return 0; 298 } 299 300 'block' { 301 s->statement_position++; 302 token->opcode = PHVOLT_T_BLOCK; 303 return 0; 304 } 305 306 'endblock' { 307 token->opcode = PHVOLT_T_ENDBLOCK; 308 return 0; 309 } 310 311 'macro' { 312 s->statement_position++; 313 token->opcode = PHVOLT_T_MACRO; 314 return 0; 315 } 316 317 'endmacro' { 318 token->opcode = PHVOLT_T_ENDMACRO; 319 return 0; 320 } 321 322 'call' { 323 s->statement_position++; 324 token->opcode = PHVOLT_T_CALL; 325 return 0; 326 } 327 328 'endcall' { 329 token->opcode = PHVOLT_T_ENDCALL; 330 return 0; 331 } 332 333 'with' { 334 token->opcode = PHVOLT_T_WITH; 335 return 0; 336 } 337 338 'return' { 339 token->opcode = PHVOLT_T_RETURN; 340 return 0; 341 } 342 343 'extends' { 344 s->statement_position++; 345 token->opcode = PHVOLT_T_EXTENDS; 346 return 0; 347 } 348 349 'is not' { 350 s->statement_position++; 351 token->opcode = PHVOLT_T_NOTEQUALS; 352 return 0; 353 } 354 355 [i][s][ ]+[n][o][t] { 356 s->statement_position++; 357 token->opcode = PHVOLT_T_NOTEQUALS; 358 return 0; 359 } 360 361 'is' { 362 s->statement_position++; 363 token->opcode = PHVOLT_T_IS; 364 return 0; 365 } 366 367 'not' { 368 s->statement_position++; 369 token->opcode = PHVOLT_T_NOT; 370 return 0; 371 } 372 373 'defined' { 374 s->statement_position++; 375 token->opcode = PHVOLT_T_DEFINED; 376 return 0; 377 } 378 379 'include' { 380 s->statement_position++; 381 token->opcode = PHVOLT_T_INCLUDE; 382 return 0; 383 } 384 385 'empty' { 386 s->statement_position++; 387 token->opcode = PHVOLT_T_EMPTY; 388 return 0; 389 } 390 391 'even' { 392 s->statement_position++; 393 token->opcode = PHVOLT_T_EVEN; 394 return 0; 395 } 396 397 'odd' { 398 s->statement_position++; 399 token->opcode = PHVOLT_T_ODD; 400 return 0; 401 } 402 403 'numeric' { 404 s->statement_position++; 405 token->opcode = PHVOLT_T_NUMERIC; 406 return 0; 407 } 408 409 'scalar' { 410 s->statement_position++; 411 token->opcode = PHVOLT_T_SCALAR; 412 return 0; 413 } 414 415 'iterable' { 416 s->statement_position++; 417 token->opcode = PHVOLT_T_ITERABLE; 418 return 0; 419 } 420 421 'cache' { 422 s->statement_position++; 423 token->opcode = PHVOLT_T_CACHE; 424 return 0; 425 } 426 427 'endcache' { 428 token->opcode = PHVOLT_T_ENDCACHE; 429 return 0; 430 } 431 432 'do' { 433 s->statement_position++; 434 token->opcode = PHVOLT_T_DO; 435 return 0; 436 } 437 438 'autoescape' { 439 s->statement_position++; 440 token->opcode = PHVOLT_T_AUTOESCAPE; 441 return 0; 442 } 443 444 'endautoescape' { 445 s->statement_position++; 446 token->opcode = PHVOLT_T_ENDAUTOESCAPE; 447 return 0; 448 } 449 450 'continue' { 451 s->statement_position++; 452 token->opcode = PHVOLT_T_CONTINUE; 453 return 0; 454 } 455 456 'break' { 457 s->statement_position++; 458 token->opcode = PHVOLT_T_BREAK; 459 return 0; 460 } 461 462 'raw' { 463 s->statement_position++; 464 token->opcode = PHVOLT_T_RAW; 465 return 0; 466 } 467 468 'endraw' { 469 s->statement_position++; 470 token->opcode = PHVOLT_T_ENDRAW; 471 return 0; 472 } 473 474 "{%" { 475 s->whitespace_control = 0; 476 token->opcode = PHVOLT_T_OPEN_DELIMITER; 477 return 0; 478 } 479 480 "%}" { 481 s->mode = PHVOLT_MODE_RAW; 482 token->opcode = PHVOLT_T_CLOSE_DELIMITER; 483 return 0; 484 } 485 486 "{%-" { 487 s->whitespace_control = 0; 488 token->opcode = PHVOLT_T_OPEN_DELIMITER; 489 return 0; 490 } 491 492 "-%}" { 493 s->mode = PHVOLT_MODE_RAW; 494 s->whitespace_control = 1; 495 token->opcode = PHVOLT_T_CLOSE_DELIMITER; 496 return 0; 497 } 498 499 "{{" { 500 s->whitespace_control = 0; 501 s->statement_position++; 502 token->opcode = PHVOLT_T_OPEN_EDELIMITER; 503 return 0; 504 } 505 506 "}}" { 507 s->mode = PHVOLT_MODE_RAW; 508 token->opcode = PHVOLT_T_CLOSE_EDELIMITER; 509 return 0; 510 } 511 512 "{{-" { 513 s->whitespace_control = 0; 514 s->statement_position++; 515 token->opcode = PHVOLT_T_OPEN_EDELIMITER; 516 return 0; 517 } 518 519 "-}}" { 520 s->mode = PHVOLT_MODE_RAW; 521 s->whitespace_control = 1; 522 token->opcode = PHVOLT_T_CLOSE_EDELIMITER; 523 return 0; 524 } 525 526 STRING = (["] ([\\]["]|[\\].|[\001-\377]\[\\"])* ["])|(['] ([\\][']|[\\].|[\001-\377]\[\\'])* [']); 527 STRING { 528 token->opcode = PHVOLT_T_STRING; 529 token->value = estrndup(q, YYCURSOR - q - 1); 530 token->len = YYCURSOR - q - 1; 531 q = YYCURSOR; 532 return 0; 533 } 534 535 IDENTIFIER = [\\]?[a-zA-Z\_][a-zA-Z0-9\_\\]*; 536 IDENTIFIER { 537 token->opcode = PHVOLT_T_IDENTIFIER; 538 token->value = estrndup(start, YYCURSOR - start); 539 token->len = YYCURSOR - start; 540 q = YYCURSOR; 541 return 0; 542 } 543 544 "+" { 545 token->opcode = PHVOLT_T_ADD; 546 return 0; 547 } 548 549 "-" { 550 token->opcode = PHVOLT_T_SUB; 551 return 0; 552 } 553 554 "*" { 555 token->opcode = PHVOLT_T_MUL; 556 return 0; 557 } 558 559 "/" { 560 token->opcode = PHVOLT_T_DIV; 561 return 0; 562 } 563 564 "%" { 565 token->opcode = PHVOLT_T_MOD; 566 return 0; 567 } 568 569 "++" { 570 token->opcode = PHVOLT_T_INCR; 571 return 0; 572 } 573 574 "--" { 575 token->opcode = PHVOLT_T_DECR; 576 return 0; 577 } 578 579 "~" { 580 token->opcode = PHVOLT_T_CONCAT; 581 return 0; 582 } 583 584 ".." { 585 token->opcode = PHVOLT_T_RANGE; 586 return 0; 587 } 588 589 "." { 590 token->opcode = PHVOLT_T_DOT; 591 return 0; 592 } 593 594 "," { 595 token->opcode = PHVOLT_T_COMMA; 596 return 0; 597 } 598 599 "(" { 600 token->opcode = PHVOLT_T_PARENTHESES_OPEN; 601 return 0; 602 } 603 604 ")" { 605 token->opcode = PHVOLT_T_PARENTHESES_CLOSE; 606 return 0; 607 } 608 609 "[" { 610 token->opcode = PHVOLT_T_SBRACKET_OPEN; 611 return 0; 612 } 613 614 "]" { 615 token->opcode = PHVOLT_T_SBRACKET_CLOSE; 616 return 0; 617 } 618 619 "{" { 620 token->opcode = PHVOLT_T_CBRACKET_OPEN; 621 return 0; 622 } 623 624 "}" { 625 token->opcode = PHVOLT_T_CBRACKET_CLOSE; 626 return 0; 627 } 628 629 "<=" { 630 token->opcode = PHVOLT_T_LESSEQUAL; 631 return 0; 632 } 633 634 "=" { 635 token->opcode = PHVOLT_T_ASSIGN; 636 return 0; 637 } 638 639 "+=" { 640 token->opcode = PHVOLT_T_ADD_ASSIGN; 641 return 0; 642 } 643 644 "-=" { 645 token->opcode = PHVOLT_T_SUB_ASSIGN; 646 return 0; 647 } 648 649 "*=" { 650 token->opcode = PHVOLT_T_MUL_ASSIGN; 651 return 0; 652 } 653 654 "/=" { 655 token->opcode = PHVOLT_T_DIV_ASSIGN; 656 return 0; 657 } 658 659 ">=" { 660 token->opcode = PHVOLT_T_GREATEREQUAL; 661 return 0; 662 } 663 664 "==" { 665 token->opcode = PHVOLT_T_EQUALS; 666 return 0; 667 } 668 669 "!=" { 670 token->opcode = PHVOLT_T_NOTEQUALS; 671 return 0; 672 } 673 674 "<>" { 675 token->opcode = PHVOLT_T_NOTEQUALS; 676 return 0; 677 } 678 679 "===" { 680 token->opcode = PHVOLT_T_IDENTICAL; 681 return 0; 682 } 683 684 "!==" { 685 token->opcode = PHVOLT_T_NOTIDENTICAL; 686 return 0; 687 } 688 689 "!" { 690 token->opcode = PHVOLT_T_NOT; 691 return 0; 692 } 693 694 "<" { 695 token->opcode = PHVOLT_T_LESS; 696 return 0; 697 } 698 699 ">" { 700 token->opcode = PHVOLT_T_GREATER; 701 return 0; 702 } 703 704 "|" { 705 token->opcode = PHVOLT_T_PIPE; 706 return 0; 707 } 708 709 ":" { 710 token->opcode = PHVOLT_T_COLON; 711 return 0; 712 } 713 714 "?" { 715 token->opcode = PHVOLT_T_QUESTION; 716 return 0; 717 } 718 719 [ \t\r]+ { 720 token->opcode = PHVOLT_T_IGNORE; 721 return 0; 722 } 723 724 [\n] { 725 s->active_line++; 726 token->opcode = PHVOLT_T_IGNORE; 727 return 0; 728 } 729 730 "\000" { 731 status = PHVOLT_SCANNER_RETCODE_EOF; 732 break; 733 } 734 735 [^] { 736 status = PHVOLT_SCANNER_RETCODE_ERR; 737 break; 738 } 739 740 */ 741 742 } 743 } 744 745 return status; 746} 747