1<?php
2/**
3 * Smarty Internal Plugin Configfilelexer
4 *
5 * This is the lexer to break the config file source into tokens
6 *
7 * @package    Smarty
8 * @subpackage Config
9 * @author     Uwe Tews
10 */
11
12/**
13 * Smarty_Internal_Configfilelexer
14 *
15 * This is the config file lexer.
16 * It is generated from the smarty_internal_configfilelexer.plex file
17 *
18 * @package    Smarty
19 * @subpackage Compiler
20 * @author     Uwe Tews
21 */
22class Smarty_Internal_Configfilelexer
23{
24    const START              = 1;
25    const VALUE              = 2;
26    const NAKED_STRING_VALUE = 3;
27    const COMMENT            = 4;
28    const SECTION            = 5;
29    const TRIPPLE            = 6;
30
31    /**
32     * Source
33     *
34     * @var string
35     */
36    public $data;
37
38    /**
39     * Source length
40     *
41     * @var int
42     */
43    public $dataLength = null;
44
45    /**
46     * byte counter
47     *
48     * @var int
49     */
50    public $counter;
51
52    /**
53     * token number
54     *
55     * @var int
56     */
57    public $token;
58
59    /**
60     * token value
61     *
62     * @var string
63     */
64    public $value;
65
66    /**
67     * current line
68     *
69     * @var int
70     */
71    public $line;
72
73    /**
74     * state number
75     *
76     * @var int
77     */
78    public $state = 1;
79
80    /**
81     * Smarty object
82     *
83     * @var Smarty
84     */
85    public $smarty = null;
86
87    /**
88     * trace file
89     *
90     * @var resource
91     */
92    public $yyTraceFILE;
93
94    /**
95     * trace prompt
96     *
97     * @var string
98     */
99    public $yyTracePrompt;
100
101    /**
102     * state names
103     *
104     * @var array
105     */
106    public $state_name = array(
107        1 => 'START', 2 => 'VALUE', 3 => 'NAKED_STRING_VALUE', 4 => 'COMMENT', 5 => 'SECTION', 6 => 'TRIPPLE'
108    );
109
110    /**
111     * token names
112     *
113     * @var array
114     */
115    public $smarty_token_names = array(        // Text for parser error messages
116    );
117
118    /**
119     * compiler object
120     *
121     * @var Smarty_Internal_Config_File_Compiler
122     */
123    private $compiler = null;
124
125    /**
126     * copy of config_booleanize
127     *
128     * @var bool
129     */
130    private $configBooleanize = false;
131
132    /**
133     * storage for assembled token patterns
134     *
135     * @var string
136     */
137    private $yy_global_pattern1 = null;
138
139    private $yy_global_pattern2 = null;
140
141    private $yy_global_pattern3 = null;
142
143    private $yy_global_pattern4 = null;
144
145    private $yy_global_pattern5 = null;
146
147    private $yy_global_pattern6 = null;
148
149    private $_yy_state          = 1;
150
151    private $_yy_stack          = array();
152
153    /**
154     * constructor
155     *
156     * @param   string                             $data template source
157     * @param Smarty_Internal_Config_File_Compiler $compiler
158     */
159    public function __construct($data, Smarty_Internal_Config_File_Compiler $compiler)
160    {
161        $this->data = $data . "\n"; //now all lines are \n-terminated
162        $this->dataLength = strlen($data);
163        $this->counter = 0;
164        if (preg_match('/^\xEF\xBB\xBF/', $this->data, $match)) {
165            $this->counter += strlen($match[ 0 ]);
166        }
167        $this->line = 1;
168        $this->compiler = $compiler;
169        $this->smarty = $compiler->smarty;
170        $this->configBooleanize = $this->smarty->config_booleanize;
171    }
172
173    public function replace($input)
174    {
175        return $input;
176    } // end function
177
178    public function PrintTrace()
179    {
180        $this->yyTraceFILE = fopen('php://output', 'w');
181        $this->yyTracePrompt = '<br>';
182    }
183
184    public function yylex()
185    {
186        return $this->{'yylex' . $this->_yy_state}();
187    }
188
189    public function yypushstate($state)
190    {
191        if ($this->yyTraceFILE) {
192            fprintf(
193                $this->yyTraceFILE,
194                "%sState push %s\n",
195                $this->yyTracePrompt,
196                isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state
197            );
198        }
199        array_push($this->_yy_stack, $this->_yy_state);
200        $this->_yy_state = $state;
201        if ($this->yyTraceFILE) {
202            fprintf(
203                $this->yyTraceFILE,
204                "%snew State %s\n",
205                $this->yyTracePrompt,
206                isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state
207            );
208        }
209    }
210
211    public function yypopstate()
212    {
213        if ($this->yyTraceFILE) {
214            fprintf(
215                $this->yyTraceFILE,
216                "%sState pop %s\n",
217                $this->yyTracePrompt,
218                isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state
219            );
220        }
221        $this->_yy_state = array_pop($this->_yy_stack);
222        if ($this->yyTraceFILE) {
223            fprintf(
224                $this->yyTraceFILE,
225                "%snew State %s\n",
226                $this->yyTracePrompt,
227                isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state
228            );
229        }
230    }
231
232    public function yybegin($state)
233    {
234        $this->_yy_state = $state;
235        if ($this->yyTraceFILE) {
236            fprintf(
237                $this->yyTraceFILE,
238                "%sState set %s\n",
239                $this->yyTracePrompt,
240                isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state
241            );
242        }
243    }
244
245    public function yylex1()
246    {
247        if (!isset($this->yy_global_pattern1)) {
248            $this->yy_global_pattern1 =
249                $this->replace("/\G(#|;)|\G(\\[)|\G(\\])|\G(=)|\G([ \t\r]+)|\G(\n)|\G([0-9]*[a-zA-Z_]\\w*)|\G([\S\s])/isS");
250        }
251        if (!isset($this->dataLength)) {
252            $this->dataLength = strlen($this->data);
253        }
254        if ($this->counter >= $this->dataLength) {
255            return false; // end of input
256        }
257        do {
258            if (preg_match($this->yy_global_pattern1, $this->data, $yymatches, 0, $this->counter)) {
259                if (!isset($yymatches[ 0 ][ 1 ])) {
260                    $yymatches = preg_grep("/(.|\s)+/", $yymatches);
261                } else {
262                    $yymatches = array_filter($yymatches);
263                }
264                if (empty($yymatches)) {
265                    throw new Exception('Error: lexing failed because a rule matched' .
266                                        ' an empty string.  Input "' . substr(
267                                            $this->data,
268                                            $this->counter,
269                                            5
270                                        ) . '... state START');
271                }
272                next($yymatches); // skip global match
273                $this->token = key($yymatches); // token number
274                $this->value = current($yymatches); // token value
275                $r = $this->{'yy_r1_' . $this->token}();
276                if ($r === null) {
277                    $this->counter += strlen($this->value);
278                    $this->line += substr_count($this->value, "\n");
279                    // accept this token
280                    return true;
281                } elseif ($r === true) {
282                    // we have changed state
283                    // process this token in the new state
284                    return $this->yylex();
285                } elseif ($r === false) {
286                    $this->counter += strlen($this->value);
287                    $this->line += substr_count($this->value, "\n");
288                    if ($this->counter >= $this->dataLength) {
289                        return false; // end of input
290                    }
291                    // skip this token
292                    continue;
293                }
294            } else {
295                throw new Exception('Unexpected input at line' . $this->line .
296                                    ': ' . $this->data[ $this->counter ]);
297            }
298            break;
299        } while (true);
300    }
301
302    public function yy_r1_1()
303    {
304        $this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART;
305        $this->yypushstate(self::COMMENT);
306    }
307
308    public function yy_r1_2()
309    {
310        $this->token = Smarty_Internal_Configfileparser::TPC_OPENB;
311        $this->yypushstate(self::SECTION);
312    }
313
314    public function yy_r1_3()
315    {
316        $this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB;
317    }
318
319    public function yy_r1_4()
320    {
321        $this->token = Smarty_Internal_Configfileparser::TPC_EQUAL;
322        $this->yypushstate(self::VALUE);
323    } // end function
324
325    public function yy_r1_5()
326    {
327        return false;
328    }
329
330    public function yy_r1_6()
331    {
332        $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
333    }
334
335    public function yy_r1_7()
336    {
337        $this->token = Smarty_Internal_Configfileparser::TPC_ID;
338    }
339
340    public function yy_r1_8()
341    {
342        $this->token = Smarty_Internal_Configfileparser::TPC_OTHER;
343    }
344
345    public function yylex2()
346    {
347        if (!isset($this->yy_global_pattern2)) {
348            $this->yy_global_pattern2 =
349                $this->replace("/\G([ \t\r]+)|\G(\\d+\\.\\d+(?=[ \t\r]*[\n#;]))|\G(\\d+(?=[ \t\r]*[\n#;]))|\G(\"\"\")|\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*'(?=[ \t\r]*[\n#;]))|\G(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"(?=[ \t\r]*[\n#;]))|\G([a-zA-Z]+(?=[ \t\r]*[\n#;]))|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/isS");
350        }
351        if (!isset($this->dataLength)) {
352            $this->dataLength = strlen($this->data);
353        }
354        if ($this->counter >= $this->dataLength) {
355            return false; // end of input
356        }
357        do {
358            if (preg_match($this->yy_global_pattern2, $this->data, $yymatches, 0, $this->counter)) {
359                if (!isset($yymatches[ 0 ][ 1 ])) {
360                    $yymatches = preg_grep("/(.|\s)+/", $yymatches);
361                } else {
362                    $yymatches = array_filter($yymatches);
363                }
364                if (empty($yymatches)) {
365                    throw new Exception('Error: lexing failed because a rule matched' .
366                                        ' an empty string.  Input "' . substr(
367                                            $this->data,
368                                            $this->counter,
369                                            5
370                                        ) . '... state VALUE');
371                }
372                next($yymatches); // skip global match
373                $this->token = key($yymatches); // token number
374                $this->value = current($yymatches); // token value
375                $r = $this->{'yy_r2_' . $this->token}();
376                if ($r === null) {
377                    $this->counter += strlen($this->value);
378                    $this->line += substr_count($this->value, "\n");
379                    // accept this token
380                    return true;
381                } elseif ($r === true) {
382                    // we have changed state
383                    // process this token in the new state
384                    return $this->yylex();
385                } elseif ($r === false) {
386                    $this->counter += strlen($this->value);
387                    $this->line += substr_count($this->value, "\n");
388                    if ($this->counter >= $this->dataLength) {
389                        return false; // end of input
390                    }
391                    // skip this token
392                    continue;
393                }
394            } else {
395                throw new Exception('Unexpected input at line' . $this->line .
396                                    ': ' . $this->data[ $this->counter ]);
397            }
398            break;
399        } while (true);
400    }
401
402    public function yy_r2_1()
403    {
404        return false;
405    }
406
407    public function yy_r2_2()
408    {
409        $this->token = Smarty_Internal_Configfileparser::TPC_FLOAT;
410        $this->yypopstate();
411    }
412
413    public function yy_r2_3()
414    {
415        $this->token = Smarty_Internal_Configfileparser::TPC_INT;
416        $this->yypopstate();
417    }
418
419    public function yy_r2_4()
420    {
421        $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES;
422        $this->yypushstate(self::TRIPPLE);
423    }
424
425    public function yy_r2_5()
426    {
427        $this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING;
428        $this->yypopstate();
429    }
430
431    public function yy_r2_6()
432    {
433        $this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING;
434        $this->yypopstate();
435    } // end function
436
437    public function yy_r2_7()
438    {
439        if (!$this->configBooleanize ||
440            !in_array(strtolower($this->value), array('true', 'false', 'on', 'off', 'yes', 'no'))) {
441            $this->yypopstate();
442            $this->yypushstate(self::NAKED_STRING_VALUE);
443            return true; //reprocess in new state
444        } else {
445            $this->token = Smarty_Internal_Configfileparser::TPC_BOOL;
446            $this->yypopstate();
447        }
448    }
449
450    public function yy_r2_8()
451    {
452        $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
453        $this->yypopstate();
454    }
455
456    public function yy_r2_9()
457    {
458        $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
459        $this->value = '';
460        $this->yypopstate();
461    } // end function
462
463    public function yylex3()
464    {
465        if (!isset($this->yy_global_pattern3)) {
466            $this->yy_global_pattern3 = $this->replace("/\G([^\n]+?(?=[ \t\r]*\n))/isS");
467        }
468        if (!isset($this->dataLength)) {
469            $this->dataLength = strlen($this->data);
470        }
471        if ($this->counter >= $this->dataLength) {
472            return false; // end of input
473        }
474        do {
475            if (preg_match($this->yy_global_pattern3, $this->data, $yymatches, 0, $this->counter)) {
476                if (!isset($yymatches[ 0 ][ 1 ])) {
477                    $yymatches = preg_grep("/(.|\s)+/", $yymatches);
478                } else {
479                    $yymatches = array_filter($yymatches);
480                }
481                if (empty($yymatches)) {
482                    throw new Exception('Error: lexing failed because a rule matched' .
483                                        ' an empty string.  Input "' . substr(
484                                            $this->data,
485                                            $this->counter,
486                                            5
487                                        ) . '... state NAKED_STRING_VALUE');
488                }
489                next($yymatches); // skip global match
490                $this->token = key($yymatches); // token number
491                $this->value = current($yymatches); // token value
492                $r = $this->{'yy_r3_' . $this->token}();
493                if ($r === null) {
494                    $this->counter += strlen($this->value);
495                    $this->line += substr_count($this->value, "\n");
496                    // accept this token
497                    return true;
498                } elseif ($r === true) {
499                    // we have changed state
500                    // process this token in the new state
501                    return $this->yylex();
502                } elseif ($r === false) {
503                    $this->counter += strlen($this->value);
504                    $this->line += substr_count($this->value, "\n");
505                    if ($this->counter >= $this->dataLength) {
506                        return false; // end of input
507                    }
508                    // skip this token
509                    continue;
510                }
511            } else {
512                throw new Exception('Unexpected input at line' . $this->line .
513                                    ': ' . $this->data[ $this->counter ]);
514            }
515            break;
516        } while (true);
517    }
518
519    public function yy_r3_1()
520    {
521        $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
522        $this->yypopstate();
523    }
524
525    public function yylex4()
526    {
527        if (!isset($this->yy_global_pattern4)) {
528            $this->yy_global_pattern4 = $this->replace("/\G([ \t\r]+)|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/isS");
529        }
530        if (!isset($this->dataLength)) {
531            $this->dataLength = strlen($this->data);
532        }
533        if ($this->counter >= $this->dataLength) {
534            return false; // end of input
535        }
536        do {
537            if (preg_match($this->yy_global_pattern4, $this->data, $yymatches, 0, $this->counter)) {
538                if (!isset($yymatches[ 0 ][ 1 ])) {
539                    $yymatches = preg_grep("/(.|\s)+/", $yymatches);
540                } else {
541                    $yymatches = array_filter($yymatches);
542                }
543                if (empty($yymatches)) {
544                    throw new Exception('Error: lexing failed because a rule matched' .
545                                        ' an empty string.  Input "' . substr(
546                                            $this->data,
547                                            $this->counter,
548                                            5
549                                        ) . '... state COMMENT');
550                }
551                next($yymatches); // skip global match
552                $this->token = key($yymatches); // token number
553                $this->value = current($yymatches); // token value
554                $r = $this->{'yy_r4_' . $this->token}();
555                if ($r === null) {
556                    $this->counter += strlen($this->value);
557                    $this->line += substr_count($this->value, "\n");
558                    // accept this token
559                    return true;
560                } elseif ($r === true) {
561                    // we have changed state
562                    // process this token in the new state
563                    return $this->yylex();
564                } elseif ($r === false) {
565                    $this->counter += strlen($this->value);
566                    $this->line += substr_count($this->value, "\n");
567                    if ($this->counter >= $this->dataLength) {
568                        return false; // end of input
569                    }
570                    // skip this token
571                    continue;
572                }
573            } else {
574                throw new Exception('Unexpected input at line' . $this->line .
575                                    ': ' . $this->data[ $this->counter ]);
576            }
577            break;
578        } while (true);
579    }
580
581    public function yy_r4_1()
582    {
583        return false;
584    }
585
586    public function yy_r4_2()
587    {
588        $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
589    } // end function
590
591    public function yy_r4_3()
592    {
593        $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
594        $this->yypopstate();
595    }
596
597    public function yylex5()
598    {
599        if (!isset($this->yy_global_pattern5)) {
600            $this->yy_global_pattern5 = $this->replace("/\G(\\.)|\G(.*?(?=[\.=[\]\r\n]))/isS");
601        }
602        if (!isset($this->dataLength)) {
603            $this->dataLength = strlen($this->data);
604        }
605        if ($this->counter >= $this->dataLength) {
606            return false; // end of input
607        }
608        do {
609            if (preg_match($this->yy_global_pattern5, $this->data, $yymatches, 0, $this->counter)) {
610                if (!isset($yymatches[ 0 ][ 1 ])) {
611                    $yymatches = preg_grep("/(.|\s)+/", $yymatches);
612                } else {
613                    $yymatches = array_filter($yymatches);
614                }
615                if (empty($yymatches)) {
616                    throw new Exception('Error: lexing failed because a rule matched' .
617                                        ' an empty string.  Input "' . substr(
618                                            $this->data,
619                                            $this->counter,
620                                            5
621                                        ) . '... state SECTION');
622                }
623                next($yymatches); // skip global match
624                $this->token = key($yymatches); // token number
625                $this->value = current($yymatches); // token value
626                $r = $this->{'yy_r5_' . $this->token}();
627                if ($r === null) {
628                    $this->counter += strlen($this->value);
629                    $this->line += substr_count($this->value, "\n");
630                    // accept this token
631                    return true;
632                } elseif ($r === true) {
633                    // we have changed state
634                    // process this token in the new state
635                    return $this->yylex();
636                } elseif ($r === false) {
637                    $this->counter += strlen($this->value);
638                    $this->line += substr_count($this->value, "\n");
639                    if ($this->counter >= $this->dataLength) {
640                        return false; // end of input
641                    }
642                    // skip this token
643                    continue;
644                }
645            } else {
646                throw new Exception('Unexpected input at line' . $this->line .
647                                    ': ' . $this->data[ $this->counter ]);
648            }
649            break;
650        } while (true);
651    }
652
653    public function yy_r5_1()
654    {
655        $this->token = Smarty_Internal_Configfileparser::TPC_DOT;
656    }
657
658    public function yy_r5_2()
659    {
660        $this->token = Smarty_Internal_Configfileparser::TPC_SECTION;
661        $this->yypopstate();
662    } // end function
663
664    public function yylex6()
665    {
666        if (!isset($this->yy_global_pattern6)) {
667            $this->yy_global_pattern6 = $this->replace("/\G(\"\"\"(?=[ \t\r]*[\n#;]))|\G([\S\s])/isS");
668        }
669        if (!isset($this->dataLength)) {
670            $this->dataLength = strlen($this->data);
671        }
672        if ($this->counter >= $this->dataLength) {
673            return false; // end of input
674        }
675        do {
676            if (preg_match($this->yy_global_pattern6, $this->data, $yymatches, 0, $this->counter)) {
677                if (!isset($yymatches[ 0 ][ 1 ])) {
678                    $yymatches = preg_grep("/(.|\s)+/", $yymatches);
679                } else {
680                    $yymatches = array_filter($yymatches);
681                }
682                if (empty($yymatches)) {
683                    throw new Exception('Error: lexing failed because a rule matched' .
684                                        ' an empty string.  Input "' . substr(
685                                            $this->data,
686                                            $this->counter,
687                                            5
688                                        ) . '... state TRIPPLE');
689                }
690                next($yymatches); // skip global match
691                $this->token = key($yymatches); // token number
692                $this->value = current($yymatches); // token value
693                $r = $this->{'yy_r6_' . $this->token}();
694                if ($r === null) {
695                    $this->counter += strlen($this->value);
696                    $this->line += substr_count($this->value, "\n");
697                    // accept this token
698                    return true;
699                } elseif ($r === true) {
700                    // we have changed state
701                    // process this token in the new state
702                    return $this->yylex();
703                } elseif ($r === false) {
704                    $this->counter += strlen($this->value);
705                    $this->line += substr_count($this->value, "\n");
706                    if ($this->counter >= $this->dataLength) {
707                        return false; // end of input
708                    }
709                    // skip this token
710                    continue;
711                }
712            } else {
713                throw new Exception('Unexpected input at line' . $this->line .
714                                    ': ' . $this->data[ $this->counter ]);
715            }
716            break;
717        } while (true);
718    }
719
720    public function yy_r6_1()
721    {
722        $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END;
723        $this->yypopstate();
724        $this->yypushstate(self::START);
725    }
726
727    public function yy_r6_2()
728    {
729        $to = strlen($this->data);
730        preg_match("/\"\"\"[ \t\r]*[\n#;]/", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
731        if (isset($match[ 0 ][ 1 ])) {
732            $to = $match[ 0 ][ 1 ];
733        } else {
734            $this->compiler->trigger_config_file_error('missing or misspelled literal closing tag');
735        }
736        $this->value = substr($this->data, $this->counter, $to - $this->counter);
737        $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT;
738    }
739}
740