diff --git a/template.lime b/template.lime index 39b38e9..6b766f0 100644 --- a/template.lime +++ b/template.lime @@ -89,7 +89,7 @@ chunks = { $$ = ''; } | chunks chunk { - $$ = $1 . $2; + $$ = $1 . "# line ".$this->template->lexer->lineno."\n" . $2; } . chunk = literal { diff --git a/template.parser.php b/template.parser.php index a4b8d13..9010b30 100644 --- a/template.parser.php +++ b/template.parser.php @@ -4,7 +4,7 @@ * Homepage: http://yourcmc.ru/wiki/VMX::Template * License: GNU GPLv3 or later * Author: Vitaliy Filippov, 2006-2016 - * Version: V3 (LALR), 2016-10-31 + * Version: V3 (LALR), 2017-02-24 * * This file contains the implementation of VMX::Template compiler. * It is only used when a template is compiled in runtime. @@ -190,26 +190,38 @@ class VMXTemplateCompiler // Generate code for functions $code = ''; - $functions = array(); + $functions = []; + $smap = []; + $l = 9; foreach ($this->st->functions as $n => $f) { + $ms = []; + preg_match_all('/(?:^|\n)# line (\d+)|\n/', $f['body'], $ms, PREG_SET_ORDER); + foreach ($ms as $m) + { + $l++; + if (!empty($m[1])) + $smap[] = [ $l, $m[1] ]; + } $code .= $f['body']; $functions[$n] = $f['args']; } // Assemble the class code $functions = var_export($functions, true); + $smap = var_export($smap, true); $rfn = addcslashes($this->options->input_filename, '\\\''); $code = "options->input_filename} class Template_$func_ns extends VMXTemplate { static \$template_filename = '$rfn'; static \$version = ".VMXTemplate::CODE_VERSION."; -static \$functions = $functions; function __construct(\$t) { \$this->tpldata = &\$t->tpldata; \$this->parent = &\$t; } $code +static \$functions = $functions; +static \$smap = $smap; } "; @@ -3466,7 +3478,7 @@ class VMXTemplateParser extends lime_parser { // (2) chunks := chunks chunk $result = reset($tokens); - $result = $tokens[0] . $tokens[1]; + $result = $tokens[0] . "# line ".$this->template->lexer->lineno."\n" . $tokens[1]; } function reduce_3_chunk_1($tokens, &$result) { diff --git a/template.php b/template.php index 131f275..1b91fef 100644 --- a/template.php +++ b/template.php @@ -8,7 +8,7 @@ * Homepage: http://yourcmc.ru/wiki/VMX::Template * License: GNU GPLv3 or later * Author: Vitaliy Filippov, 2006-2016 - * Version: V3 (LALR), 2016-10-31 + * Version: V3 (LALR), 2017-02-24 * * The template engine is split into two parts: * (1) This file - always used when running templates @@ -349,6 +349,36 @@ class VMXTemplate return $t; } + /** + * Translate template file line number from stack frame $frame (taken from debug_backtrace()) + */ + public static function translateLine(&$frame) + { + if (!empty($frame['class']) && substr($frame['class'], 0, 9) == 'Template_') + { + $class = $frame['class']; + if (isset($class::$smap)) + { + $l = $frame['line']; + $s = 0; + $e = count($class::$smap); + while ($e > $s+1) + { + if ($l < $class::$smap[($e+$s)>>1][0]) + $e = ($e+$s)>>1; + else + $s = ($e+$s)>>1; + } + $frame['class'] = ''; + $frame['type'] = ''; + if (substr($frame['function'], 0, 3) == 'fn_') + $frame['function'] = substr($frame['function'], 3); + $frame['file'] = $class::$template_filename; + $frame['line'] = $s; + } + } + } + /** * Load file (with caching) *