Commit b159408a by seldaek

Fixed parsing of quoted keywords in if statements, like 'not' was parsed as !…

Fixed parsing of quoted keywords in if statements, like 'not' was parsed as ! because using {if not $foo} is valid, but it was impossible to use them even as string. Fixes #46. git-svn-id: http://svn.dwoo.org/trunk@329 0598d79b-80c4-4d41-97ba-ac86fbbd088b
parent 9364271e
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
count (just a helper that counts anything). It won't affect you unless count (just a helper that counts anything). It won't affect you unless
you built some plugin depending on isArray, in which case you should you built some plugin depending on isArray, in which case you should
check all works fine still check all works fine still
* Fixed parsing of quoted keywords in if statements, like 'not' was
parsed as ! because using {if not $foo} is valid, but it was impossible
to use them even as string.
[2009--] 1.1.1 [2009--] 1.1.1
+ Added {optional} plugin that just prints an optional var without any + Added {optional} plugin that just prints an optional var without any
......
...@@ -232,6 +232,17 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -232,6 +232,17 @@ class Dwoo_Compiler implements Dwoo_ICompiler
protected static $instance; protected static $instance;
/** /**
* token types
* @var int
*/
const T_UNQUOTED_STRING = 1;
const T_NUMERIC = 2;
const T_NULL = 4;
const T_BOOL = 8;
const T_MATH = 16;
const T_BREAKCHAR = 32;
/**
* constructor * constructor
* *
* saves the created instance so that child templates get the same one * saves the created instance so that child templates get the same one
...@@ -1210,6 +1221,22 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -1210,6 +1221,22 @@ class Dwoo_Compiler implements Dwoo_ICompiler
} }
/** /**
* returns the token of each parameter out of the given parameter array
*
* @param array $params parameter array
* @return array tokens
*/
public function getParamTokens(array $params)
{
foreach ($params as $k=>$p) {
if (is_array($p)) {
$params[$k] = isset($p[2]) ? $p[2] : 0;
}
}
return $params;
}
/**
* entry point of the parser, it redirects calls to other parse* functions * entry point of the parser, it redirects calls to other parse* functions
* *
* @param string $in the string within which we must parse something * @param string $in the string within which we must parse something
...@@ -1468,9 +1495,10 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -1468,9 +1495,10 @@ class Dwoo_Compiler implements Dwoo_ICompiler
} }
$parts = $this->mapParams($parts, array('Dwoo_Plugin_if', 'init'), 1); $parts = $this->mapParams($parts, array('Dwoo_Plugin_if', 'init'), 1);
$tokens = $this->getParamTokens($parts);
$parts = $this->getCompiledParams($parts); $parts = $this->getCompiledParams($parts);
$value = Dwoo_Plugin_if::replaceKeywords($parts['*'], $this); $value = Dwoo_Plugin_if::replaceKeywords($parts['*'], $tokens['*'], $this);
$echo = ''; $echo = '';
} else { } else {
$value = array(); $value = array();
...@@ -1581,7 +1609,8 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -1581,7 +1609,8 @@ class Dwoo_Compiler implements Dwoo_ICompiler
if ($curBlock === 'condition') { if ($curBlock === 'condition') {
// load if plugin // load if plugin
$this->getPluginType('if'); $this->getPluginType('if');
if (Dwoo_Plugin_if::replaceKeywords(array($func), $this) !== array($func)) {
if (Dwoo_Plugin_if::replaceKeywords(array($func), array(self::T_UNQUOTED_STRING), $this) !== array($func)) {
return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer); return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
} }
} }
...@@ -1738,8 +1767,10 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -1738,8 +1767,10 @@ class Dwoo_Compiler implements Dwoo_ICompiler
} }
// only keep php-syntax-safe values for non-block plugins // only keep php-syntax-safe values for non-block plugins
foreach ($params as &$p) { $tokens = array();
$p = $p[0]; foreach ($params as $k => $p) {
$tokens[$k] = isset($p[2]) ? $p[2] : 0;
$params[$k] = $p[0];
} }
if ($pluginType & Dwoo::NATIVE_PLUGIN) { if ($pluginType & Dwoo::NATIVE_PLUGIN) {
if ($func === 'do') { if ($func === 'do') {
...@@ -1769,6 +1800,9 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -1769,6 +1800,9 @@ class Dwoo_Compiler implements Dwoo_ICompiler
$funcCompiler = 'Dwoo_Plugin_'.$func.'_compile'; $funcCompiler = 'Dwoo_Plugin_'.$func.'_compile';
} }
array_unshift($params, $this); array_unshift($params, $this);
if ($func === 'tif') {
$params[] = $tokens;
}
$output = call_user_func_array($funcCompiler, $params); $output = call_user_func_array($funcCompiler, $params);
} else { } else {
array_unshift($params, '$this'); array_unshift($params, '$this');
...@@ -2498,35 +2532,41 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -2498,35 +2532,41 @@ class Dwoo_Compiler implements Dwoo_ICompiler
if (strtolower($substr) === 'false' || strtolower($substr) === 'no' || strtolower($substr) === 'off') { if (strtolower($substr) === 'false' || strtolower($substr) === 'no' || strtolower($substr) === 'off') {
if ($this->debug) echo 'BOOLEAN(FALSE) PARSED<br />'; if ($this->debug) echo 'BOOLEAN(FALSE) PARSED<br />';
$substr = 'false'; $substr = 'false';
$type = self::T_BOOL;
} elseif (strtolower($substr) === 'true' || strtolower($substr) === 'yes' || strtolower($substr) === 'on') { } elseif (strtolower($substr) === 'true' || strtolower($substr) === 'yes' || strtolower($substr) === 'on') {
if ($this->debug) echo 'BOOLEAN(TRUE) PARSED<br />'; if ($this->debug) echo 'BOOLEAN(TRUE) PARSED<br />';
$substr = 'true'; $substr = 'true';
$type = self::T_BOOL;
} elseif ($substr === 'null' || $substr === 'NULL') { } elseif ($substr === 'null' || $substr === 'NULL') {
if ($this->debug) echo 'NULL PARSED<br />'; if ($this->debug) echo 'NULL PARSED<br />';
$substr = 'null'; $substr = 'null';
$type = self::T_NULL;
} elseif (is_numeric($substr)) { } elseif (is_numeric($substr)) {
$substr = (float) $substr; $substr = (float) $substr;
if ((int) $substr == $substr) { if ((int) $substr == $substr) {
$substr = (int) $substr; $substr = (int) $substr;
} }
$type = self::T_NUMERIC;
if ($this->debug) echo 'NUMBER ('.$substr.') PARSED<br />'; if ($this->debug) echo 'NUMBER ('.$substr.') PARSED<br />';
} elseif (preg_match('{^-?(\d+|\d*(\.\d+))\s*([/*%+-]\s*-?(\d+|\d*(\.\d+)))+$}', $substr)) { } elseif (preg_match('{^-?(\d+|\d*(\.\d+))\s*([/*%+-]\s*-?(\d+|\d*(\.\d+)))+$}', $substr)) {
if ($this->debug) echo 'SIMPLE MATH PARSED<br />'; if ($this->debug) echo 'SIMPLE MATH PARSED<br />';
$type = self::T_MATH;
$substr = '('.$substr.')'; $substr = '('.$substr.')';
} elseif ($curBlock === 'condition' && array_search($substr, $breakChars, true) !== false) { } elseif ($curBlock === 'condition' && array_search($substr, $breakChars, true) !== false) {
if ($this->debug) echo 'BREAKCHAR ('.$substr.') PARSED<br />'; if ($this->debug) echo 'BREAKCHAR ('.$substr.') PARSED<br />';
$type = self::T_BREAKCHAR;
//$substr = '"'.$substr.'"'; //$substr = '"'.$substr.'"';
} else { } else {
$substr = $this->replaceStringVars('\''.str_replace('\'', '\\\'', $substr).'\'', '\'', $curBlock); $substr = $this->replaceStringVars('\''.str_replace('\'', '\\\'', $substr).'\'', '\'', $curBlock);
$type = self::T_UNQUOTED_STRING;
if ($this->debug) echo 'BLABBER ('.$substr.') CASTED AS STRING<br />'; if ($this->debug) echo 'BLABBER ('.$substr.') CASTED AS STRING<br />';
} }
if (is_array($parsingParams)) { if (is_array($parsingParams)) {
$parsingParams[] = array($substr, $src); $parsingParams[] = array($substr, $src, $type);
return $parsingParams; return $parsingParams;
} elseif ($curBlock === 'namedparam') { } elseif ($curBlock === 'namedparam') {
return array($substr, $src); return array($substr, $src, $type);
} elseif ($curBlock === 'expression') { } elseif ($curBlock === 'expression') {
return $substr; return $substr;
} else { } else {
...@@ -2988,12 +3028,14 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -2988,12 +3028,14 @@ class Dwoo_Compiler implements Dwoo_ICompiler
} }
$tmp = array(); $tmp = array();
$tmp2 = array(); $tmp2 = array();
$tmp3 = array();
foreach ($ps as $i=>$p) { foreach ($ps as $i=>$p) {
$tmp[$i] = $p[0]; $tmp[$i] = $p[0];
$tmp2[$i] = $p[1]; $tmp2[$i] = $p[1];
$tmp3[$i] = isset($p[2]) ? $p[2] : 0;
unset($ps[$i]); unset($ps[$i]);
} }
$paramlist[$v[0]] = array($tmp, $tmp2); $paramlist[$v[0]] = array($tmp, $tmp2, $tmp3);
unset($tmp, $tmp2, $i, $p); unset($tmp, $tmp2, $i, $p);
break; break;
} elseif (isset($ps[$v[0]])) { } elseif (isset($ps[$v[0]])) {
...@@ -3019,7 +3061,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -3019,7 +3061,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler
throw new Dwoo_Compilation_Exception($this, 'Argument '.$k.'/'.$v[0].' missing for '.str_replace(array('Dwoo_Plugin_', '_compile'), '', $name)); throw new Dwoo_Compilation_Exception($this, 'Argument '.$k.'/'.$v[0].' missing for '.str_replace(array('Dwoo_Plugin_', '_compile'), '', $name));
} elseif ($v[2]===null) { } elseif ($v[2]===null) {
// enforce lowercased null if default value is null (php outputs NULL with var export) // enforce lowercased null if default value is null (php outputs NULL with var export)
$paramlist[$v[0]] = array('null', null); $paramlist[$v[0]] = array('null', null, self::T_NULL);
} else { } else {
// outputs default value with var_export // outputs default value with var_export
$paramlist[$v[0]] = array(var_export($v[2], true), $v[2]); $paramlist[$v[0]] = array(var_export($v[2], true), $v[2]);
......
...@@ -44,9 +44,10 @@ class Dwoo_Plugin_elseif extends Dwoo_Plugin_if implements Dwoo_ICompilable_Bloc ...@@ -44,9 +44,10 @@ class Dwoo_Plugin_elseif extends Dwoo_Plugin_if implements Dwoo_ICompilable_Bloc
return ''; return '';
} }
$tokens = $compiler->getParamTokens($params);
$params = $compiler->getCompiledParams($params); $params = $compiler->getCompiledParams($params);
$pre = Dwoo_Compiler::PHP_OPEN."elseif (".implode(' ', self::replaceKeywords($params['*'], $compiler)).") {\n" . Dwoo_Compiler::PHP_CLOSE; $pre = Dwoo_Compiler::PHP_OPEN."elseif (".implode(' ', self::replaceKeywords($params['*'], $tokens['*'], $compiler)).") {\n" . Dwoo_Compiler::PHP_CLOSE;
$post = Dwoo_Compiler::PHP_OPEN."\n}".Dwoo_Compiler::PHP_CLOSE; $post = Dwoo_Compiler::PHP_OPEN."\n}".Dwoo_Compiler::PHP_CLOSE;
if (isset($params['hasElse'])) { if (isset($params['hasElse'])) {
......
...@@ -33,7 +33,7 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block ...@@ -33,7 +33,7 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
{ {
} }
public static function replaceKeywords(array $params, Dwoo_Compiler $compiler) public static function replaceKeywords(array $params, array $tokens, Dwoo_Compiler $compiler)
{ {
$p = array(); $p = array();
...@@ -48,53 +48,108 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block ...@@ -48,53 +48,108 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
switch($vmod) { switch($vmod) {
case 'and': case 'and':
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '&&'; $p[] = '&&';
} else {
$p[] = $v;
}
break; break;
case 'or': case 'or':
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '||'; $p[] = '||';
} else {
$p[] = $v;
}
break; break;
case '==':
case 'eq': case 'eq':
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '=='; $p[] = '==';
} else {
$p[] = $v;
}
break; break;
case '<>':
case '!=':
case 'ne': case 'ne':
case 'neq': case 'neq':
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '!='; $p[] = '!=';
} else {
$p[] = $v;
}
break; break;
case '>=':
case 'gte': case 'gte':
case 'ge': case 'ge':
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '>='; $p[] = '>=';
} else {
$p[] = $v;
}
break; break;
case '<=':
case 'lte': case 'lte':
case 'le': case 'le':
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '<='; $p[] = '<=';
} else {
$p[] = $v;
}
break; break;
case '>':
case 'gt': case 'gt':
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '>'; $p[] = '>';
} else {
$p[] = $v;
}
break; break;
case '<':
case 'lt': case 'lt':
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '<'; $p[] = '<';
} else {
$p[] = $v;
}
break; break;
case '===': case 'mod':
$p[] = '==='; if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '%';
} else {
$p[] = $v;
}
break; break;
case 'not':
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '!';
} else {
$p[] = $v;
}
break;
case '<>':
$p[] = '!=';
break;
case '==':
case '!=':
case '>=':
case '<=':
case '>':
case '<':
case '===':
case '!==': case '!==':
$p[] = '!=='; case '%':
case '!':
$p[] = $vmod;
break; break;
case 'is': case 'is':
if (isset($params[$k+1]) && strtolower(trim($params[$k+1], '"\'')) === 'not') { if ($tokens[$k] !== Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = $v;
break;
}
if (isset($params[$k+1]) && strtolower(trim($params[$k+1], '"\'')) === 'not' && $tokens[$k+1] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$negate = true; $negate = true;
next($params); next($params);
} else { } else {
$negate = false; $negate = false;
} }
$ptr = 1+(int)$negate; $ptr = 1+(int)$negate;
if ($tokens[$k+$ptr] !== Dwoo_Compiler::T_UNQUOTED_STRING) {
break;
}
if (!isset($params[$k+$ptr])) { if (!isset($params[$k+$ptr])) {
$params[$k+$ptr] = ''; $params[$k+$ptr] = '';
} else { } else {
...@@ -141,14 +196,6 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block ...@@ -141,14 +196,6 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
} }
break; break;
case '%':
case 'mod':
$p[] = '%';
break;
case '!':
case 'not':
$p[] = '!';
break;
default: default:
$p[] = $v; $p[] = $v;
...@@ -165,9 +212,9 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block ...@@ -165,9 +212,9 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
public static function postProcessing(Dwoo_Compiler $compiler, array $params, $prepend, $append, $content) public static function postProcessing(Dwoo_Compiler $compiler, array $params, $prepend, $append, $content)
{ {
$tokens = $compiler->getParamTokens($params);
$params = $compiler->getCompiledParams($params); $params = $compiler->getCompiledParams($params);
$pre = Dwoo_Compiler::PHP_OPEN.'if ('.implode(' ', self::replaceKeywords($params['*'], $tokens['*'], $compiler)).") {\n".Dwoo_Compiler::PHP_CLOSE;
$pre = Dwoo_Compiler::PHP_OPEN.'if ('.implode(' ', self::replaceKeywords($params['*'], $compiler)).") {\n".Dwoo_Compiler::PHP_CLOSE;
$post = Dwoo_Compiler::PHP_OPEN."\n}".Dwoo_Compiler::PHP_CLOSE; $post = Dwoo_Compiler::PHP_OPEN."\n}".Dwoo_Compiler::PHP_CLOSE;
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* @date 2008-10-23 * @date 2008-10-23
* @package Dwoo * @package Dwoo
*/ */
function Dwoo_Plugin_tif_compile(Dwoo_Compiler $compiler, array $rest) function Dwoo_Plugin_tif_compile(Dwoo_Compiler $compiler, array $rest, array $tokens)
{ {
// load if plugin // load if plugin
if (!class_exists('Dwoo_Plugin_if', false)) { if (!class_exists('Dwoo_Plugin_if', false)) {
...@@ -68,7 +68,7 @@ function Dwoo_Plugin_tif_compile(Dwoo_Compiler $compiler, array $rest) ...@@ -68,7 +68,7 @@ function Dwoo_Plugin_tif_compile(Dwoo_Compiler $compiler, array $rest)
} }
// parse condition // parse condition
$condition = Dwoo_Plugin_if::replaceKeywords($rest, $compiler); $condition = Dwoo_Plugin_if::replaceKeywords($rest, $tokens, $compiler);
return '(('.implode(' ', $condition).') ? '.($trueResult===true ? implode(' ', $condition) : $trueResult).' : '.$falseResult.')'; return '(('.implode(' ', $condition).') ? '.($trueResult===true ? implode(' ', $condition) : $trueResult).' : '.$falseResult.')';
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment