library/smarty/lexer/smarty_internal_configfileparser.y
changeset 46 f11c31f7fa3e
parent 45 a56e7f9a0463
child 47 03388ec805b4
equal deleted inserted replaced
45:a56e7f9a0463 46:f11c31f7fa3e
     1 /**
       
     2 * Smarty Internal Plugin Configfileparser
       
     3 *
       
     4 * This is the config file parser
       
     5 * 
       
     6 * 
       
     7 * @package Smarty
       
     8 * @subpackage Config
       
     9 * @author Uwe Tews
       
    10 */
       
    11 %name TPC_
       
    12 %declare_class {
       
    13 /**
       
    14 * Smarty Internal Plugin Configfileparse
       
    15 *
       
    16 * This is the config file parser.
       
    17 * It is generated from the smarty_internal_configfileparser.y file
       
    18 * @package Smarty
       
    19 * @subpackage Compiler
       
    20 * @author Uwe Tews
       
    21 */
       
    22 class Smarty_Internal_Configfileparser
       
    23 }
       
    24 %include_class
       
    25 {
       
    26     /**
       
    27      * result status
       
    28      *
       
    29      * @var bool
       
    30      */
       
    31     public $successful = true;
       
    32     /**
       
    33      * return value
       
    34      *
       
    35      * @var mixed
       
    36      */
       
    37     public $retvalue = 0;
       
    38     /**
       
    39      * @var
       
    40      */
       
    41     public $yymajor;
       
    42     /**
       
    43      * lexer object
       
    44      *
       
    45      * @var Smarty_Internal_Configfilelexer
       
    46      */
       
    47     private $lex;
       
    48     /**
       
    49      * internal error flag
       
    50      *
       
    51      * @var bool
       
    52      */
       
    53     private $internalError = false;
       
    54     /**
       
    55      * compiler object
       
    56      *
       
    57      * @var Smarty_Internal_Config_File_Compiler
       
    58      */
       
    59     public $compiler = null;
       
    60     /**
       
    61      * smarty object
       
    62      *
       
    63      * @var Smarty
       
    64      */
       
    65     public $smarty = null;
       
    66     /**
       
    67      * copy of config_overwrite property
       
    68      *
       
    69      * @var bool
       
    70      */
       
    71     private $configOverwrite = false;
       
    72     /**
       
    73      * copy of config_read_hidden property
       
    74      *
       
    75      * @var bool
       
    76      */
       
    77     private $configReadHidden = false;
       
    78     /**
       
    79      * helper map
       
    80      *
       
    81      * @var array
       
    82      */
       
    83     private static $escapes_single = Array('\\' => '\\',
       
    84                                            '\'' => '\'');
       
    85 
       
    86     /**
       
    87      * constructor
       
    88      *
       
    89      * @param Smarty_Internal_Configfilelexer      $lex
       
    90      * @param Smarty_Internal_Config_File_Compiler $compiler
       
    91      */
       
    92     function __construct(Smarty_Internal_Configfilelexer $lex, Smarty_Internal_Config_File_Compiler $compiler)
       
    93     {
       
    94         // set instance object
       
    95         self::instance($this);
       
    96         $this->lex = $lex;
       
    97         $this->smarty = $compiler->smarty;
       
    98         $this->compiler = $compiler;
       
    99         $this->configOverwrite = $this->smarty->config_overwrite;
       
   100         $this->configReadHidden = $this->smarty->config_read_hidden;
       
   101     }
       
   102 
       
   103     /**
       
   104      * @param null $new_instance
       
   105      *
       
   106      * @return null
       
   107      */
       
   108     public static function &instance($new_instance = null)
       
   109     {
       
   110         static $instance = null;
       
   111         if (isset($new_instance) && is_object($new_instance)) {
       
   112             $instance = $new_instance;
       
   113         }
       
   114         return $instance;
       
   115     }
       
   116 
       
   117     /**
       
   118      * parse optional boolean keywords
       
   119      *
       
   120      * @param string $str
       
   121      *
       
   122      * @return bool
       
   123      */
       
   124     private function parse_bool($str)
       
   125     {
       
   126         $str = strtolower($str);
       
   127         if (in_array($str, array('on', 'yes', 'true'))) {
       
   128             $res = true;
       
   129         } else {
       
   130             $res = false;
       
   131         }
       
   132         return $res;
       
   133     }
       
   134 
       
   135     /**
       
   136      * parse single quoted string
       
   137      *  remove outer quotes
       
   138      *  unescape inner quotes
       
   139      *
       
   140      * @param string $qstr
       
   141      *
       
   142      * @return string
       
   143      */
       
   144     private static function parse_single_quoted_string($qstr)
       
   145     {
       
   146         $escaped_string = substr($qstr, 1, strlen($qstr) - 2); //remove outer quotes
       
   147 
       
   148         $ss = preg_split('/(\\\\.)/', $escaped_string, - 1, PREG_SPLIT_DELIM_CAPTURE);
       
   149 
       
   150         $str = "";
       
   151         foreach ($ss as $s) {
       
   152             if (strlen($s) === 2 && $s[0] === '\\') {
       
   153                 if (isset(self::$escapes_single[$s[1]])) {
       
   154                     $s = self::$escapes_single[$s[1]];
       
   155                 }
       
   156             }
       
   157             $str .= $s;
       
   158         }
       
   159         return $str;
       
   160     }
       
   161 
       
   162     /**
       
   163      * parse double quoted string
       
   164      *
       
   165      * @param string $qstr
       
   166      *
       
   167      * @return string
       
   168      */
       
   169     private static function parse_double_quoted_string($qstr)
       
   170     {
       
   171         $inner_str = substr($qstr, 1, strlen($qstr) - 2);
       
   172         return stripcslashes($inner_str);
       
   173     }
       
   174 
       
   175     /**
       
   176      * parse triple quoted string
       
   177      *
       
   178      * @param string $qstr
       
   179      *
       
   180      * @return string
       
   181      */
       
   182     private static function parse_tripple_double_quoted_string($qstr)
       
   183     {
       
   184         return stripcslashes($qstr);
       
   185     }
       
   186 
       
   187     /**
       
   188      * set a config variable in target array
       
   189      *
       
   190      * @param array $var
       
   191      * @param array $target_array
       
   192      */
       
   193     private function set_var(Array $var, Array &$target_array)
       
   194     {
       
   195         $key = $var["key"];
       
   196         $value = $var["value"];
       
   197 
       
   198         if ($this->configOverwrite || !isset($target_array['vars'][$key])) {
       
   199             $target_array['vars'][$key] = $value;
       
   200         } else {
       
   201             settype($target_array['vars'][$key], 'array');
       
   202             $target_array['vars'][$key][] = $value;
       
   203         }
       
   204     }
       
   205 
       
   206     /**
       
   207      * add config variable to global vars
       
   208      *
       
   209      * @param array $vars
       
   210      */
       
   211     private function add_global_vars(Array $vars)
       
   212     {
       
   213         if (!isset($this->compiler->config_data['vars'])) {
       
   214             $this->compiler->config_data['vars'] = Array();
       
   215         }
       
   216         foreach ($vars as $var) {
       
   217             $this->set_var($var, $this->compiler->config_data);
       
   218         }
       
   219     }
       
   220 
       
   221     /**
       
   222      * add config variable to section
       
   223      *
       
   224      * @param string $section_name
       
   225      * @param array  $vars
       
   226      */
       
   227     private function add_section_vars($section_name, Array $vars)
       
   228     {
       
   229         if (!isset($this->compiler->config_data['sections'][$section_name]['vars'])) {
       
   230             $this->compiler->config_data['sections'][$section_name]['vars'] = Array();
       
   231         }
       
   232         foreach ($vars as $var) {
       
   233             $this->set_var($var, $this->compiler->config_data['sections'][$section_name]);
       
   234         }
       
   235     }
       
   236 }
       
   237 
       
   238 %token_prefix TPC_
       
   239 
       
   240 %parse_accept
       
   241 {
       
   242     $this->successful = !$this->internalError;
       
   243     $this->internalError = false;
       
   244     $this->retvalue = $this->_retvalue;
       
   245 }
       
   246 
       
   247 %syntax_error
       
   248 {
       
   249     $this->internalError = true;
       
   250     $this->yymajor = $yymajor;
       
   251     $this->compiler->trigger_config_file_error();
       
   252 }
       
   253 
       
   254 %stack_overflow
       
   255 {
       
   256     $this->internalError = true;
       
   257     $this->compiler->trigger_config_file_error("Stack overflow in configfile parser");
       
   258 }
       
   259 
       
   260 // Complete config file
       
   261 start(res) ::= global_vars sections. {
       
   262     res = null;
       
   263 }
       
   264 
       
   265 // Global vars
       
   266 global_vars(res) ::= var_list(vl). {
       
   267     $this->add_global_vars(vl);
       
   268     res = null;
       
   269 }
       
   270 
       
   271 // Sections
       
   272 sections(res) ::= sections section. {
       
   273     res = null;
       
   274 }
       
   275 
       
   276 sections(res) ::= . {
       
   277     res = null;
       
   278 }
       
   279 
       
   280 section(res) ::= OPENB SECTION(i) CLOSEB newline var_list(vars). {
       
   281     $this->add_section_vars(i, vars);
       
   282     res = null;
       
   283 }
       
   284 
       
   285 section(res) ::= OPENB DOT SECTION(i) CLOSEB newline var_list(vars). {
       
   286     if ($this->configReadHidden) {
       
   287         $this->add_section_vars(i, vars);
       
   288     }
       
   289     res = null;
       
   290 }
       
   291 
       
   292 // Var list
       
   293 var_list(res) ::= var_list(vl) newline. {
       
   294     res = vl;
       
   295 }
       
   296 
       
   297 var_list(res) ::= var_list(vl) var(v). {
       
   298     res = array_merge(vl, Array(v));
       
   299 }
       
   300 
       
   301 var_list(res) ::= . {
       
   302     res = Array();
       
   303 }
       
   304 
       
   305 
       
   306 // Var
       
   307 var(res) ::= ID(id) EQUAL value(v). {
       
   308     res = Array("key" => id, "value" => v);
       
   309 }
       
   310 
       
   311 
       
   312 value(res) ::= FLOAT(i). {
       
   313     res = (float) i;
       
   314 }
       
   315 
       
   316 value(res) ::= INT(i). {
       
   317     res = (int) i;
       
   318 }
       
   319 
       
   320 value(res) ::= BOOL(i). {
       
   321     res = $this->parse_bool(i);
       
   322 }
       
   323 
       
   324 value(res) ::= SINGLE_QUOTED_STRING(i). {
       
   325     res = self::parse_single_quoted_string(i);
       
   326 }
       
   327 
       
   328 value(res) ::= DOUBLE_QUOTED_STRING(i). {
       
   329     res = self::parse_double_quoted_string(i);
       
   330 }
       
   331 
       
   332 value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_TEXT(c) TRIPPLE_QUOTES_END(ii). {
       
   333     res = self::parse_tripple_double_quoted_string(c);
       
   334 }
       
   335 
       
   336 value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_QUOTES_END(ii). {
       
   337     res = '';
       
   338 }
       
   339 
       
   340 value(res) ::= NAKED_STRING(i). {
       
   341     res = i;
       
   342 }
       
   343 
       
   344 // NOTE: this is not a valid rule
       
   345 // It is added hier to produce a usefull error message on a missing '=';
       
   346 value(res) ::= OTHER(i). {
       
   347     res = i;
       
   348 }
       
   349 
       
   350 
       
   351 // Newline and comments
       
   352 newline(res) ::= NEWLINE. {
       
   353     res = null;
       
   354 }
       
   355 
       
   356 newline(res) ::= COMMENTSTART NEWLINE. {
       
   357     res = null;
       
   358 }
       
   359 
       
   360 newline(res) ::= COMMENTSTART NAKED_STRING NEWLINE. {
       
   361     res = null;
       
   362 }