src/ets.php
function parse($ptype, &$i, &$line, $ncontent, $content)
	{
		$elts = array();
		$mode = _ETS_DATA;
		$ntext = $nname = $nvalue = $nspace = 0;
		$ctext = $cname = $cvalue = '';
		$nametype = NULL;
		$nspecial = 0;
		$saveline = $line;
		for ( ; $i < $ncontent; ++$i) {
			// skip parsing when error
			if ($this->skip) {
				return array();
			}
			// current character and following
			$c0 = $content{$i};
			$c1 = $content{$i + 1};
			$is_space0 = $this->is_space($c0);
			$a0 = ord($c0);
			// line count
			if ($a0 == 10 || ($a0 == 13 && ord($c1) != 10)) {
				++$line;
			}
			// data acquisition
			if ($mode == _ETS_DATA) {
				// tag?
				if ($c0 == '{') {
					$c2 = $content{$i + 2};
					$c3 = $content{$i + 3};
					$c4 = $content{$i + 4};
					$c5 = $content{$i + 5};
					$c6 = $content{$i + 6};
					$c7 = $content{$i + 7};
					// {* (comment)
					if ($c1 == '*') {
						if ($ptype & _ETS_CODEs) {
							$this->error(0, 1, 'comment', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_COMMENT;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						++$i;
						++$nspecial;
						$saveline = $line;
					// {# (cdata)
					} elseif ($c1 == '#') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 2, 'cdata', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_CDATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						++$i;
						++$nspecial;
						$saveline = $line;
					// {loop:   (formerly "{mask:")
					} elseif ($c1 == 'l' && $c2 == 'o' && $c3 == 'o' && $c4 == 'p' && $c5 == ':') {
						if ($ptype & _ETS_GROUP2) {
							$this->error(0, 3, 'template element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_TEMPLATE;
						$i += 5;
					// {mask:
					} elseif ($c1 == 'm' && $c2 == 'a' && $c3 == 's' && $c4 == 'k' && $c5 == ':') {
						if ($ptype & _ETS_GROUP2) {
							$this->error(0, 3, 'template element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_TEMPLATE;
						$i += 5;
					// {call:
					} elseif ($c1 == 'c' && $c2 == 'a' && $c3 == 'l' && $c4 == 'l' && $c5 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 4, 'call element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 6;
						$index = _ETS_CALL . ':' . $i;
						$elts[$index]['template'] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						$elts[$index]['args'] = $this->parse(_ETS_CALL, $i, $line, $ncontent, $content);
					// {const:
					} elseif ($c1 == 'c' && $c2 == 'o' && $c3 == 'n' && $c4 == 's' && $c5 == 't' && $c6 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 5, 'constant element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 7;
						$elts[_ETS_CONST . ':' . $i] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						--$i;
					// {set:
					} elseif ($c1 == 's' && $c2 == 'e' && $c3 == 't' && $c4 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 6, 'set element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_SET;
						$i += 4;
					// {mis:
					} elseif ($c1 == 'm' && $c2 == 'i' && $c3 == 's' && $c4 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 7, 'missing element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_MIS;
						$i += 4;
					// {choose:
					} elseif ($c1 == 'c' && $c2 == 'h' && $c3 == 'o' && $c4 == 'o' && $c5 == 's' && $c6 == 'e' && $c7 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 8, 'choose element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_CHOOSEVAR;
						$i += 7;
					// {arg:
					} elseif ($c1 == 'a' && $c2 == 'r' && $c3 == 'g' && $c4 == ':') {
						if ($ptype == _ETS_CALL) {
							$mode = _ETS_NAME;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = _ETS_ARG;
							$i += 4;
						} else {
							$this->error(0, 9, 'argument element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {reduce:
					} elseif ($c1 == 'r' && $c2 == 'e' && $c3 == 'd' && $c4 == 'u' && $c5 == 'c' && $c6 == 'e' && $c7 == ':') {
						if ($ptype == _ETS_ROOT) {
							if (!isset($elts['0reduce']) || $elts['0reduce'] == _ETS_REDUCE_NULL) {
								$mode = _ETS_NAME;
								$ntext = $nname = $nvalue = $nspace = 0;
								$ctext = $cname = $cvalue = '';
								$nametype = _ETS_REDUCE;
								$i += 7;
							} else {
								$this->error(7, 10, 'reduce element already used', $line);
							}
						} else {
							$this->error(0, 11, 'reduce element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {include:
					} elseif ($c1 == 'i' && $c2 == 'n' && $c3 == 'c' && $c4 == 'l' && $c5 == 'u' && $c6 == 'd' && $c7 == 'e' && $content{$i + 8} == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 15, 'include element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 9;
						$elts[_ETS_INCLUDE . ':' . $i] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						--$i;
					// {insert:
					} elseif ($c1 == 'i' && $c2 == 'n' && $c3 == 's' && $c4 == 'e' && $c5 == 'r' && $c6 == 't' && $c7 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 14, 'insert element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 8;
						$elts[_ETS_INSERT . ':' . $i] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						--$i;
					// {eval:
					} elseif ($c1 == 'e' && $c2 == 'v' && $c3 == 'a' && $c4 == 'l' && $c5 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 15, 'eval element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 6;
						$elts[_ETS_EVAL . ':' . $i] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						--$i;
					// {safe:
					} elseif ($c1 == 's' && $c2 == 'a' && $c3 == 'f' && $c4 == 'e' && $c5 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 16, 'safe eval element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 6;
						$elts[_ETS_SAFE . ':' . $i] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						--$i;
					// {when:
					} elseif ($c1 == 'w' && $c2 == 'h' && $c3 == 'e' && $c4 == 'n' && $c5 == ':') {
						// of of whentest
						if ($ptype == _ETS_CHOOSE) {
							$mode = _ETS_DATA;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 6;
							$index = _ETS_WHENTEST . ':' . $i;
							$elts['when'][$index]['test'] = $this->parse(_ETS_CODE,     $i, $line, $ncontent, $content);
							$elts['when'][$index]['true'] = $this->parse(_ETS_WHENTEST, $i, $line, $ncontent, $content);
						}
						// of whenval
						elseif ($ptype == _ETS_CHOOSEVAR) {
							$mode = _ETS_VALUE;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = _ETS_WHENVAL;
							switch ($c6) {
								case '\'':	$quotetype = 1; $i += 6; break;
								case '"':	$quotetype = 2; $i += 6; break;
								default:	$quotetype = 0; $i += 5; break;
							}
						} else {
							$this->error(0, 17, 'when element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {if:
					} elseif ($c1 == 'i' && $c2 == 'f' && $c3 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 18, 'if element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 4;
						$index = _ETS_IF . ':' . $i;
						$elts[$index]['test'] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						$elts[$index]['true'] = $this->parse(_ETS_IF, $i, $line, $ncontent, $content);
					// {repeat:
					} elseif ($c1 == 'r' && $c2 == 'e' && $c3 == 'p' && $c4 == 'e' && $c5 == 'a' && $c6 == 't' && $c7 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 19, 'repeat element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 8;
						$index = _ETS_REPEAT . ':' . $i;
						$elts[$index]['loops'] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						$elts[$index]['repeated'] = $this->parse(_ETS_REPEAT, $i, $line, $ncontent, $content);
					// {rss:
					} elseif ($c1 =='r' && $c2 =='s' && $c3=='s' && $c4==':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 19, 'rss element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_RSS;
						$i += 4;
					// simple tag with absolute path
					} elseif ($c1 == '/' && $c2 == '/') {
						if ($ptype & _ETS_GROUP3) {
							$this->error(0, 20, 'simple tag element with absolute path', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cvalue = '';
						$cname = '//';
						$nametype = _ETS_TAG;
						$i += 2;
					// other simple tag
					} elseif ($c1 != '/' && !$this->is_space($c1)) {
						// {else
						if ($c1 == 'e' && $c2 == 'l' && $c3 == 's' && $c4 == 'e' && ($this->is_space($c5) || $c5 == '}' )) {
							if ($ptype & _ETS_CHOOSEs) {
								$mode = _ETS_NAME;
								$ntext = $nvalue = $nspace = 0;
								$nname = 1;
								$ctext = $cvalue = '';
								$cname = 'else';
								$nametype = _ETS_TAG;
								$i += 4;
							} else {
								$this->error(0, 21, 'else element', $line, $ptype);
								$this->skip = TRUE;
								return array();
							}
						} elseif ($ptype & _ETS_GROUP3) {
							$this->error(0, 22, 'simple tag element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						// other
						} else {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_NAME;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = _ETS_TAG;
						}
					// {/loop     (formerly "{/mask")
					} elseif ($c1 == '/' && $c2 == 'l' && $c3 == 'o' && $c4 == 'o' && $c5 == 'p') {
						if ($ptype == _ETS_TEMPLATE) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						} else {
							$this->error(1, 23, 'loop', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/mask
					} elseif ($c1 == '/' && $c2 == 'm' && $c3 == 'a' && $c4 == 's' && $c5 == 'k') {
						if ($ptype == _ETS_TEMPLATE) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						} else {
							$this->error(1, 23, 'mask', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/set
					} elseif ($c1 == '/' && $c2 == 's' && $c3 == 'e' && $c4 == 't') {
						if ($ptype & _ETS_SETs) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 4;
						} else {
							$this->error(1, 24, 'set', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/mis
					} elseif ($c1 == '/' && $c2 == 'm' && $c3 == 'i' && $c4 == 's') {
						if ($ptype & _ETS_MISs) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 4;
						} else {
							$this->error(1, 25, 'mis', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/php
					} elseif ($c1 == '/' && $c2 == 'p' && $c3 == 'h' && $c4 == 'p') {
						if ($ptype == _ETS_PHP) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 4;
						} else {
							$this->error(1, 26, 'PHP', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/if
					} elseif ($c1 == '/' && $c2 == 'i' && $c3 == 'f') {
						if ($ptype == _ETS_IF) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 3;
						} else {
							$this->error(1, 27, 'if', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/choose
					} elseif ($c1 == '/' && $c2 == 'c' && $c3 == 'h' && $c4 == 'o' && $c5 == 'o' && $c6 == 's' && $c7 == 'e') {
						if ($ptype & _ETS_CHOOSEs) {
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 7;
						} else {
							$this->error(1, 28, 'choose', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/call
					} elseif ($c1 == '/' && $c2 == 'c' && $c3 == 'a' && $c4 == 'l' && $c5 == 'l') {
						if ($ptype == _ETS_CALL) {
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						} else {
							$this->error(1, 29, 'call', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/arg
					} elseif ($c1 == '/' && $c2 == 'a' && $c3 == 'r' && $c4 == 'g') {
						if ($ptype == _ETS_ARG) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 4;
						} else {
							$this->error(1, 30, 'arg', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/when
					} elseif ($c1 == '/' && $c2 == 'w' && $c3 == 'h' && $c4 == 'e' && $c5 == 'n') {
						// of when val
						if ($ptype == _ETS_WHENVAL) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						// of when test
						} elseif ($ptype == _ETS_WHENTEST) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						} else {
							$this->error(1, 31, 'when', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/else
					} elseif ($c1 == '/' && $c2 == 'e' && $c3 == 'l' && $c4 == 's' && $c5 == 'e') {
						if ($ptype == _ETS_ELSE) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						} else {
							$this->error(1, 32, 'else', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/repeat
					} elseif ($c1 == '/' && $c2 == 'r' && $c3 == 'e' && $c4 == 'p' && $c5 == 'e' && $c6 == 'a' && $c7 == 't') {
						if ($ptype == _ETS_REPEAT) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 7;
						} else {
							$this->error(1, 33, 'repeat', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/rss
					} elseif ($c1 == '/' && $c2 =='r' && $c3 == 's' && $c4 == 's') {
						if ($ptype == _ETS_RSS) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 4;
						} else {
							$this->error(1, 35, 'rss', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/ (simplified closing tag)
					} elseif ($c1 == '/' && ($c2 == '}' || $this->is_space($c2))) {
						if ($ptype != _ETS_ROOT) {
							if (!($ptype & _ETS_GROUP4)) {
								$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							}
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							++$i;
						} else {
							$this->error(1, 34, '', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// text
					} elseif (!($ptype & _ETS_GROUP3)) {
						$ctext .= $c0;
						$ntext = 1;
					}
				// end of code element
				} elseif ($c0 == '}' && $ptype == _ETS_CODE) {
					$this->store_text($elts, $i, $ptype, $ntext, $ctext);
					++$i;
					return $elts;
				// escape } with \} in code acquisition
				} elseif ($c0 == '\\' && $c1 == '}' && $ptype == _ETS_CODE) {
					$ctext .= '}';
					$ntext = 1;
					++$i;
				// no text in choosevar element
				} elseif ($ptype == _ETS_CHOOSE && !$is_space0) {
					$this->error(2, 35, "unexpected character '$c0' in choose element", $line);
					$this->skip = TRUE;
					return array();
				// no text in choose element
				} elseif ($ptype == _ETS_CHOOSEVAR && !$is_space0) {
					$this->error(2, 36, "unexpected character '$c0' in choose-variable element", $line);
					$this->skip = TRUE;
					return array();
				// no text in call element
				} elseif ($ptype == _ETS_CALL && !$is_space0) {
					$this->error(2, 37, "unexpected character '$c0' in call element", $line);
					$this->skip = TRUE;
					return array();
				// text
				} elseif ($ptype != _ETS_ROOT) {
					$ctext .= $c0;
					$ntext = 1;
				}
			// name acquisition
			} elseif ($mode == _ETS_NAME) {
				// end of name acquisition
				if ($c0 == '}' && $nname == 1) {
					// reduce
					if ($nametype == _ETS_REDUCE) {
						if (!isset($elts['0reduce']) || $elts['0reduce'] == _ETS_REDUCE_NULL) {
							if (!$this->store_reduce($elts, $cname)) {
								$this->error(7, 38, "invalid value $cname for reduce element", $line);
							}
						}
					// template
					} elseif ($nametype == _ETS_TEMPLATE) {
						++$i;
						if ($ptype != _ETS_ROOT) {
							$this->store_node($elts, _ETS_TEMPLATE, $i, $line, $cname, NULL, $ncontent, $content);
						} elseif (isset($elts[$cname])) {
							$this->error(2, 39, "template $cname already defined", $line);
							$this->skip = TRUE;
							return $elts; //array();
						} else {
							$elts[$cname] = $this->parse(_ETS_TEMPLATE, $i, $line, $ncontent, $content);
						}
					// set
					} elseif ($nametype == _ETS_SET) {
						++$i;
						$this->store_node($elts, _ETS_SET, $i, $line, $cname, NULL, $ncontent, $content);
					// mis
					} elseif ($nametype == _ETS_MIS) {
						++$i;
						$this->store_node($elts, _ETS_MIS, $i, $line, $cname, NULL, $ncontent, $content);
					// tag?
					} elseif ($nametype == _ETS_TAG) {
						// php
						if ($cname == 'php') {
							++$i;
							$elts[_ETS_PHP . ':' . $i] = $this->parse(_ETS_PHP, $i, $line, $ncontent, $content);
						// choose
						} elseif ($cname == 'choose') {
							++$i;
							$elts[_ETS_CHOOSE . ':' . $i] = $this->parse(_ETS_CHOOSE, $i, $line, $ncontent, $content);
						// else
						} elseif (($ptype == _ETS_CHOOSE || $ptype == _ETS_CHOOSEVAR) && $cname == 'else') {
							if (isset($elts['else'])) {
								$this->error(2, 40, 'else element already exists in ' . $this->elt_label($ptype), $line);
								$this->skip = TRUE;
								return array();
							} else {
								++$i;
								$elts['else'] = $this->parse(_ETS_ELSE, $i, $line, $ncontent, $content);
							}
						// tag!
						} else {
							$this->store_leaf($elts, _ETS_TAG, $i, $cname);
						}
					// choose var
					} elseif ($nametype == _ETS_CHOOSEVAR) {
						++$i;
						$this->store_node($elts, _ETS_CHOOSEVAR, $i, $line, $cname, NULL, $ncontent, $content);
					// arg
					} elseif ($nametype == _ETS_ARG) {
						++$i;
						$this->store_node($elts, _ETS_ARG, $i, $line, $cname, NULL, $ncontent, $content);
					}
					$mode = _ETS_DATA;
				// space in name acquisition
				} elseif ($is_space0) {
					if ($nname == 1) {
						$nspace = 1;
					} else {
						$this->error(2, 41, "unexpected space before name", $line);
						$this->skip = TRUE;
						return array();
					}
				// start of value acquisition
				} elseif ($c0 == ':' && $nname == 1 && ($nametype == _ETS_SET || $nametype == _ETS_MIS)) {
					$cvalue = '';
					$nvalue = 0;
					$nspace = 0;
					$mode = _ETS_VALUE;
					switch ($c1) {
						case '\'':	$quotetype = 1; ++$i; break;
						case '"':	$quotetype = 2; ++$i; break;
						default:	$quotetype = 0;       break;
					}
				// start of second name acquisition
				} elseif ($c0 == ':' && $nametype == _ETS_TAG && $nname == 1 && $nvalue == 0) {
					++$i;
					$this->store_node($elts, _ETS_ALT_TAG, $i, $line, $cname, $cvalue, $ncontent, $content, TRUE);
					--$i;
					$mode = _ETS_DATA;
					$ntext = $nname = $nvalue = $nspace = 0;
					$ctext = $cname = $cvalue = '';
					$nametype = NULL;
				// data after trailing spaces
				} elseif ($nspace == 1) {
					$this->error(2, 42, "unexpected character '$c0' after spaces in name", $line);
					$this->skip = TRUE;
					return array();
				// name acquisition
				} elseif (($nname == 0 && preg_match('/[a-zA-Z_\.\x7f-\xff]/', $c0)) || ($nname == 1 && preg_match('/[\[\]\'\/a-zA-Z0-9_\.\x7f-\xff]/', $c0))) {
					$cname .= $c0;
					$nname = 1;
				// absolute path at the beginning of name acquisition
				} elseif ($c0 == '/' && $c1 == '/' && $nname == 0) {
					$cname = '//';
					++$i;
				// error in name acquisition
				} else {
					$this->error(2, 43, "unexpected character '$c0' in name", $line);
					$this->skip = TRUE;
					return array();
				}
			// end of closing tag
			} elseif ($mode == _ETS_CLOSING_TAG) {
				if ($c0 == '}') {
					$this->store_text($elts, $i, $ptype, $ntext, $ctext);
					return $elts;
				} elseif (!$is_space0) {
					$this->error(2, 44, "unexpected character '$c0' in closing tag", $line);
					$this->skip = TRUE;
					return array();
				}
			// value acquisition
			} elseif ($mode == _ETS_VALUE) {
				// end of value acquisition
				if ($c0 == '}' && $nvalue == 1 && ($quotetype == 0 || $nspace == 1 || $nspace == 2)) {
					if ($nametype == _ETS_SET) {
						++$i;
						$this->store_node($elts, _ETS_SETVAL, $i, $line, $cname, $cvalue, $ncontent, $content);
					} elseif ($nametype == _ETS_MIS) {
						++$i;
						$this->store_node($elts, _ETS_MISVAL, $i, $line, $cname, $cvalue, $ncontent, $content);
					} elseif ($nametype == _ETS_WHENVAL) {
						++$i;
						$elts['when'][_ETS_WHENVAL . ':' . $i . '::' . $cvalue] = $this->parse(_ETS_WHENVAL, $i, $line, $ncontent, $content);
					}
					$mode = _ETS_DATA;
				// no more character after space for single quoted string
				} elseif ($c0 == '\'' && $quotetype == 1 && $nspace == 0) {
					$nspace = 2;
				// no more character after space for double quoted string
				} elseif ($c0 == '"' && $quotetype == 2 && $nspace == 0) {
					$nspace = 2;
				// space in value acquisition
				} elseif ($is_space0) {
					if ($nvalue == 0 && $quotetype == 0) { // no value without quote
						$this->error(2, 45, "unexpected space at the beginning of a value", $line);
						$this->skip = TRUE;
						return array();
					} else { // value found or with quotes
						if ($quotetype == 0) { // no quote
							$nspace = 1;
						} else { // with quotes
							if ($nspace == 2) { // after quotes
								$nspace = 1;
							} else {			// in quotes
								$cvalue .= $c0;
								$nvalue = 1;
							}
						}
					}
				// escape } with \} in value acquisition without quote
				} elseif ($c0 == '\\' && $c1 == '}' && $nspace == 0) {
					$cvalue .= '}';
					$nvalue = 1;
					++$i;
				// espace ' with \' in value acquisition for single quoted string
				} elseif ($c0 == '\\' && $c1 == '\'' && $quotetype == 1 && $nspace == 0) {
					$cvalue .= '\'';
					$nvalue = 1;
					++$i;
				// espace " with \" in value acquisition for single quoted string
				} elseif ($c0 == '\\' && $c1 == '"' && $quotetype == 2 && $nspace == 0) {
					$cvalue .= '"';
					$nvalue = 1;
					++$i;
				// value acquisition
				} elseif ($nspace == 0) {
					$cvalue .= $c0;
					$nvalue = 1;
				// error in value acquisition
				} else {
					$this->error(2, 46, "unexpected character '$c0' in value", $line);
					$this->skip = TRUE;
					return array();
				}
			// comment
			} elseif ($mode == _ETS_COMMENT) {
				// nested
				if ($c0 == '{' && $c1 == '*') {
					++$i;
					++$nspecial;
				// end
				} elseif ($c0 == '*' && $c1 == '}') {
					++$i;
					--$nspecial;
					// last end
					if ($nspecial == 0) {
						$mode = _ETS_DATA;
					}
				}
			// cdata
			} elseif ($mode == _ETS_CDATA) {
				// nested
				if ($c0 == '{' && $c1 == '#') {
					++$i;
					++$nspecial;
				// end
				} elseif ($c0 == '#' && $c1 == '}') {
					++$i;
					--$nspecial;
					// last end
					if ($nspecial == 0) {
						$mode = _ETS_DATA;
					}
				// text acquisition
				} else {
					switch ($c0) {
						case "\n": $ctext .= "\1n\1"; break;
						case "\r": $ctext .= "\1r\1"; break;
						case "\t": $ctext .= "\1t\1"; break;
						case " " : $ctext .= "\1s\1"; break;
						default  : $ctext .= $c0; break;
					}
					$ntext = 1;
				}
			}
		}
		// end
		if ($mode & _ETS_GROUP0) {
			$this->error(3, 47, '', $saveline, $mode);
			$this->skip = TRUE;
			return array();
		}
		if ($ptype == _ETS_ROOT_EVAL) {
			$this->store_text($elts, $i, $ptype, $ntext, $ctext);
		} elseif ($ptype != _ETS_ROOT) {
			$this->error(4, 48, '', $saveline, $ptype);
			$this->skip = TRUE;
			return array();
		}
		return $elts;
	}
function parse($ptype, &$i, &$line, $ncontent, $content)
	{
		$elts = array();
		$mode = _ETS_DATA;
		$ntext = $nname = $nvalue = $nspace = 0;
		$ctext = $cname = $cvalue = '';
		$nametype = NULL;
		$nspecial = 0;
		$saveline = $line;
		for ( ; $i < $ncontent; ++$i) {
			// skip parsing when error
			if ($this->skip) {
				return array();
			}
			// current character and following
			$c0 = $content{$i};
			$c1 = $content{$i + 1};
			$is_space0 = $this->is_space($c0);
			$a0 = ord($c0);
			// line count
			if ($a0 == 10 || ($a0 == 13 && ord($c1) != 10)) {
				++$line;
			}
			// data acquisition
			if ($mode == _ETS_DATA) {
				// tag?
				if ($c0 == '{') {
					$c2 = $content{$i + 2};
					$c3 = $content{$i + 3};
					$c4 = $content{$i + 4};
					$c5 = $content{$i + 5};
					$c6 = $content{$i + 6};
					$c7 = $content{$i + 7};
					// {* (comment)
					if ($c1 == '*') {
						if ($ptype & _ETS_CODEs) {
							$this->error(0, 1, 'comment', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_COMMENT;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						++$i;
						++$nspecial;
						$saveline = $line;
					// {# (cdata)
					} elseif ($c1 == '#') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 2, 'cdata', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_CDATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						++$i;
						++$nspecial;
						$saveline = $line;
					// {loop:   (formerly "{mask:")
					} elseif ($c1 == 'l' && $c2 == 'o' && $c3 == 'o' && $c4 == 'p' && $c5 == ':') {
						if ($ptype & _ETS_GROUP2) {
							$this->error(0, 3, 'template element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_TEMPLATE;
						$i += 5;
					// {mask:
					} elseif ($c1 == 'm' && $c2 == 'a' && $c3 == 's' && $c4 == 'k' && $c5 == ':') {
						if ($ptype & _ETS_GROUP2) {
							$this->error(0, 3, 'template element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_TEMPLATE;
						$i += 5;
					// {call:
					} elseif ($c1 == 'c' && $c2 == 'a' && $c3 == 'l' && $c4 == 'l' && $c5 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 4, 'call element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 6;
						$index = _ETS_CALL . ':' . $i;
						$elts[$index]['template'] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						$elts[$index]['args'] = $this->parse(_ETS_CALL, $i, $line, $ncontent, $content);
					// {const:
					} elseif ($c1 == 'c' && $c2 == 'o' && $c3 == 'n' && $c4 == 's' && $c5 == 't' && $c6 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 5, 'constant element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 7;
						$elts[_ETS_CONST . ':' . $i] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						--$i;
					// {set:
					} elseif ($c1 == 's' && $c2 == 'e' && $c3 == 't' && $c4 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 6, 'set element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_SET;
						$i += 4;
					// {mis:
					} elseif ($c1 == 'm' && $c2 == 'i' && $c3 == 's' && $c4 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 7, 'missing element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_MIS;
						$i += 4;
					// {choose:
					} elseif ($c1 == 'c' && $c2 == 'h' && $c3 == 'o' && $c4 == 'o' && $c5 == 's' && $c6 == 'e' && $c7 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 8, 'choose element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_CHOOSEVAR;
						$i += 7;
					// {arg:
					} elseif ($c1 == 'a' && $c2 == 'r' && $c3 == 'g' && $c4 == ':') {
						if ($ptype == _ETS_CALL) {
							$mode = _ETS_NAME;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = _ETS_ARG;
							$i += 4;
						} else {
							$this->error(0, 9, 'argument element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {reduce:
					} elseif ($c1 == 'r' && $c2 == 'e' && $c3 == 'd' && $c4 == 'u' && $c5 == 'c' && $c6 == 'e' && $c7 == ':') {
						if ($ptype == _ETS_ROOT) {
							if (!isset($elts['0reduce']) || $elts['0reduce'] == _ETS_REDUCE_NULL) {
								$mode = _ETS_NAME;
								$ntext = $nname = $nvalue = $nspace = 0;
								$ctext = $cname = $cvalue = '';
								$nametype = _ETS_REDUCE;
								$i += 7;
							} else {
								$this->error(7, 10, 'reduce element already used', $line);
							}
						} else {
							$this->error(0, 11, 'reduce element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {include:
					} elseif ($c1 == 'i' && $c2 == 'n' && $c3 == 'c' && $c4 == 'l' && $c5 == 'u' && $c6 == 'd' && $c7 == 'e' && $content{$i + 8} == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 15, 'include element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 9;
						$elts[_ETS_INCLUDE . ':' . $i] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						--$i;
					// {insert:
					} elseif ($c1 == 'i' && $c2 == 'n' && $c3 == 's' && $c4 == 'e' && $c5 == 'r' && $c6 == 't' && $c7 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 14, 'insert element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 8;
						$elts[_ETS_INSERT . ':' . $i] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						--$i;
					// {eval:
					} elseif ($c1 == 'e' && $c2 == 'v' && $c3 == 'a' && $c4 == 'l' && $c5 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 15, 'eval element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 6;
						$elts[_ETS_EVAL . ':' . $i] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						--$i;
					// {safe:
					} elseif ($c1 == 's' && $c2 == 'a' && $c3 == 'f' && $c4 == 'e' && $c5 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 16, 'safe eval element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 6;
						$elts[_ETS_SAFE . ':' . $i] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						--$i;
					// {when:
					} elseif ($c1 == 'w' && $c2 == 'h' && $c3 == 'e' && $c4 == 'n' && $c5 == ':') {
						// of of whentest
						if ($ptype == _ETS_CHOOSE) {
							$mode = _ETS_DATA;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 6;
							$index = _ETS_WHENTEST . ':' . $i;
							$elts['when'][$index]['test'] = $this->parse(_ETS_CODE,     $i, $line, $ncontent, $content);
							$elts['when'][$index]['true'] = $this->parse(_ETS_WHENTEST, $i, $line, $ncontent, $content);
						}
						// of whenval
						elseif ($ptype == _ETS_CHOOSEVAR) {
							$mode = _ETS_VALUE;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = _ETS_WHENVAL;
							switch ($c6) {
								case '\'':	$quotetype = 1; $i += 6; break;
								case '"':	$quotetype = 2; $i += 6; break;
								default:	$quotetype = 0; $i += 5; break;
							}
						} else {
							$this->error(0, 17, 'when element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {if:
					} elseif ($c1 == 'i' && $c2 == 'f' && $c3 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 18, 'if element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 4;
						$index = _ETS_IF . ':' . $i;
						$elts[$index]['test'] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						$elts[$index]['true'] = $this->parse(_ETS_IF, $i, $line, $ncontent, $content);
					// {repeat:
					} elseif ($c1 == 'r' && $c2 == 'e' && $c3 == 'p' && $c4 == 'e' && $c5 == 'a' && $c6 == 't' && $c7 == ':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 19, 'repeat element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_DATA;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = NULL;
						$i += 8;
						$index = _ETS_REPEAT . ':' . $i;
						$elts[$index]['loops'] = $this->parse(_ETS_CODE, $i, $line, $ncontent, $content);
						$elts[$index]['repeated'] = $this->parse(_ETS_REPEAT, $i, $line, $ncontent, $content);
					// {rss:
					} elseif ($c1 =='r' && $c2 =='s' && $c3=='s' && $c4==':') {
						if ($ptype & _ETS_GROUP1) {
							$this->error(0, 19, 'rss element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cname = $cvalue = '';
						$nametype = _ETS_RSS;
						$i += 4;
					// simple tag with absolute path
					} elseif ($c1 == '/' && $c2 == '/') {
						if ($ptype & _ETS_GROUP3) {
							$this->error(0, 20, 'simple tag element with absolute path', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
						$this->store_text($elts, $i, $ptype, $ntext, $ctext);
						$mode = _ETS_NAME;
						$ntext = $nname = $nvalue = $nspace = 0;
						$ctext = $cvalue = '';
						$cname = '//';
						$nametype = _ETS_TAG;
						$i += 2;
					// other simple tag
					} elseif ($c1 != '/' && !$this->is_space($c1)) {
						// {else
						if ($c1 == 'e' && $c2 == 'l' && $c3 == 's' && $c4 == 'e' && ($this->is_space($c5) || $c5 == '}' )) {
							if ($ptype & _ETS_CHOOSEs) {
								$mode = _ETS_NAME;
								$ntext = $nvalue = $nspace = 0;
								$nname = 1;
								$ctext = $cvalue = '';
								$cname = 'else';
								$nametype = _ETS_TAG;
								$i += 4;
							} else {
								$this->error(0, 21, 'else element', $line, $ptype);
								$this->skip = TRUE;
								return array();
							}
						} elseif ($ptype & _ETS_GROUP3) {
							$this->error(0, 22, 'simple tag element', $line, $ptype);
							$this->skip = TRUE;
							return array();
						// other
						} else {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_NAME;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = _ETS_TAG;
						}
					// {/loop     (formerly "{/mask")
					} elseif ($c1 == '/' && $c2 == 'l' && $c3 == 'o' && $c4 == 'o' && $c5 == 'p') {
						if ($ptype == _ETS_TEMPLATE) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						} else {
							$this->error(1, 23, 'loop', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/mask
					} elseif ($c1 == '/' && $c2 == 'm' && $c3 == 'a' && $c4 == 's' && $c5 == 'k') {
						if ($ptype == _ETS_TEMPLATE) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						} else {
							$this->error(1, 23, 'mask', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/set
					} elseif ($c1 == '/' && $c2 == 's' && $c3 == 'e' && $c4 == 't') {
						if ($ptype & _ETS_SETs) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 4;
						} else {
							$this->error(1, 24, 'set', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/mis
					} elseif ($c1 == '/' && $c2 == 'm' && $c3 == 'i' && $c4 == 's') {
						if ($ptype & _ETS_MISs) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 4;
						} else {
							$this->error(1, 25, 'mis', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/php
					} elseif ($c1 == '/' && $c2 == 'p' && $c3 == 'h' && $c4 == 'p') {
						if ($ptype == _ETS_PHP) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 4;
						} else {
							$this->error(1, 26, 'PHP', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/if
					} elseif ($c1 == '/' && $c2 == 'i' && $c3 == 'f') {
						if ($ptype == _ETS_IF) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 3;
						} else {
							$this->error(1, 27, 'if', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/choose
					} elseif ($c1 == '/' && $c2 == 'c' && $c3 == 'h' && $c4 == 'o' && $c5 == 'o' && $c6 == 's' && $c7 == 'e') {
						if ($ptype & _ETS_CHOOSEs) {
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 7;
						} else {
							$this->error(1, 28, 'choose', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/call
					} elseif ($c1 == '/' && $c2 == 'c' && $c3 == 'a' && $c4 == 'l' && $c5 == 'l') {
						if ($ptype == _ETS_CALL) {
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						} else {
							$this->error(1, 29, 'call', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/arg
					} elseif ($c1 == '/' && $c2 == 'a' && $c3 == 'r' && $c4 == 'g') {
						if ($ptype == _ETS_ARG) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 4;
						} else {
							$this->error(1, 30, 'arg', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/when
					} elseif ($c1 == '/' && $c2 == 'w' && $c3 == 'h' && $c4 == 'e' && $c5 == 'n') {
						// of when val
						if ($ptype == _ETS_WHENVAL) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						// of when test
						} elseif ($ptype == _ETS_WHENTEST) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						} else {
							$this->error(1, 31, 'when', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/else
					} elseif ($c1 == '/' && $c2 == 'e' && $c3 == 'l' && $c4 == 's' && $c5 == 'e') {
						if ($ptype == _ETS_ELSE) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 5;
						} else {
							$this->error(1, 32, 'else', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/repeat
					} elseif ($c1 == '/' && $c2 == 'r' && $c3 == 'e' && $c4 == 'p' && $c5 == 'e' && $c6 == 'a' && $c7 == 't') {
						if ($ptype == _ETS_REPEAT) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 7;
						} else {
							$this->error(1, 33, 'repeat', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/rss
					} elseif ($c1 == '/' && $c2 =='r' && $c3 == 's' && $c4 == 's') {
						if ($ptype == _ETS_RSS) {
							$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							$i += 4;
						} else {
							$this->error(1, 35, 'rss', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// {/ (simplified closing tag)
					} elseif ($c1 == '/' && ($c2 == '}' || $this->is_space($c2))) {
						if ($ptype != _ETS_ROOT) {
							if (!($ptype & _ETS_GROUP4)) {
								$this->store_text($elts, $i, $ptype, $ntext, $ctext);
							}
							$mode = _ETS_CLOSING_TAG;
							$ntext = $nname = $nvalue = $nspace = 0;
							$ctext = $cname = $cvalue = '';
							$nametype = NULL;
							++$i;
						} else {
							$this->error(1, 34, '', $line, $ptype);
							$this->skip = TRUE;
							return array();
						}
					// text
					} elseif (!($ptype & _ETS_GROUP3)) {
						$ctext .= $c0;
						$ntext = 1;
					}
				// end of code element
				} elseif ($c0 == '}' && $ptype == _ETS_CODE) {
					$this->store_text($elts, $i, $ptype, $ntext, $ctext);
					++$i;
					return $elts;
				// escape } with \} in code acquisition
				} elseif ($c0 == '\\' && $c1 == '}' && $ptype == _ETS_CODE) {
					$ctext .= '}';
					$ntext = 1;
					++$i;
				// no text in choosevar element
				} elseif ($ptype == _ETS_CHOOSE && !$is_space0) {
					$this->error(2, 35, "unexpected character '$c0' in choose element", $line);
					$this->skip = TRUE;
					return array();
				// no text in choose element
				} elseif ($ptype == _ETS_CHOOSEVAR && !$is_space0) {
					$this->error(2, 36, "unexpected character '$c0' in choose-variable element", $line);
					$this->skip = TRUE;
					return array();
				// no text in call element
				} elseif ($ptype == _ETS_CALL && !$is_space0) {
					$this->error(2, 37, "unexpected character '$c0' in call element", $line);
					$this->skip = TRUE;
					return array();
				// text
				} elseif ($ptype != _ETS_ROOT) {
					$ctext .= $c0;
					$ntext = 1;
				}
			// name acquisition
			} elseif ($mode == _ETS_NAME) {
				// end of name acquisition
				if ($c0 == '}' && $nname == 1) {
					// reduce
					if ($nametype == _ETS_REDUCE) {
						if (!isset($elts['0reduce']) || $elts['0reduce'] == _ETS_REDUCE_NULL) {
							if (!$this->store_reduce($elts, $cname)) {
								$this->error(7, 38, "invalid value $cname for reduce element", $line);
							}
						}
					// template
					} elseif ($nametype == _ETS_TEMPLATE) {
						++$i;
						if ($ptype != _ETS_ROOT) {
							$this->store_node($elts, _ETS_TEMPLATE, $i, $line, $cname, NULL, $ncontent, $content);
						} elseif (isset($elts[$cname])) {
							$this->error(2, 39, "template $cname already defined", $line);
							$this->skip = TRUE;
							return $elts; //array();
						} else {
							$elts[$cname] = $this->parse(_ETS_TEMPLATE, $i, $line, $ncontent, $content);
						}
					// set
					} elseif ($nametype == _ETS_SET) {
						++$i;
						$this->store_node($elts, _ETS_SET, $i, $line, $cname, NULL, $ncontent, $content);
					// mis
					} elseif ($nametype == _ETS_MIS) {
						++$i;
						$this->store_node($elts, _ETS_MIS, $i, $line, $cname, NULL, $ncontent, $content);
					// tag?
					} elseif ($nametype == _ETS_TAG) {
						// php
						if ($cname == 'php') {
							++$i;
							$elts[_ETS_PHP . ':' . $i] = $this->parse(_ETS_PHP, $i, $line, $ncontent, $content);
						// choose
						} elseif ($cname == 'choose') {
							++$i;
							$elts[_ETS_CHOOSE . ':' . $i] = $this->parse(_ETS_CHOOSE, $i, $line, $ncontent, $content);
						// else
						} elseif (($ptype == _ETS_CHOOSE || $ptype == _ETS_CHOOSEVAR) && $cname == 'else') {
							if (isset($elts['else'])) {
								$this->error(2, 40, 'else element already exists in ' . $this->elt_label($ptype), $line);
								$this->skip = TRUE;
								return array();
							} else {
								++$i;
								$elts['else'] = $this->parse(_ETS_ELSE, $i, $line, $ncontent, $content);
							}
						// tag!
						} else {
							$this->store_leaf($elts, _ETS_TAG, $i, $cname);
						}
					// choose var
					} elseif ($nametype == _ETS_CHOOSEVAR) {
						++$i;
						$this->store_node($elts, _ETS_CHOOSEVAR, $i, $line, $cname, NULL, $ncontent, $content);
					// arg
					} elseif ($nametype == _ETS_ARG) {
						++$i;
						$this->store_node($elts, _ETS_ARG, $i, $line, $cname, NULL, $ncontent, $content);
					}
					$mode = _ETS_DATA;
				// space in name acquisition
				} elseif ($is_space0) {
					if ($nname == 1) {
						$nspace = 1;
					} else {
						$this->error(2, 41, "unexpected space before name", $line);
						$this->skip = TRUE;
						return array();
					}
				// start of value acquisition
				} elseif ($c0 == ':' && $nname == 1 && ($nametype == _ETS_SET || $nametype == _ETS_MIS)) {
					$cvalue = '';
					$nvalue = 0;
					$nspace = 0;
					$mode = _ETS_VALUE;
					switch ($c1) {
						case '\'':	$quotetype = 1; ++$i; break;
						case '"':	$quotetype = 2; ++$i; break;
						default:	$quotetype = 0;       break;
					}
				// start of second name acquisition
				} elseif ($c0 == ':' && $nametype == _ETS_TAG && $nname == 1 && $nvalue == 0) {
					++$i;
					$this->store_node($elts, _ETS_ALT_TAG, $i, $line, $cname, $cvalue, $ncontent, $content, TRUE);
					--$i;
					$mode = _ETS_DATA;
					$ntext = $nname = $nvalue = $nspace = 0;
					$ctext = $cname = $cvalue = '';
					$nametype = NULL;
				// data after trailing spaces
				} elseif ($nspace == 1) {
					$this->error(2, 42, "unexpected character '$c0' after spaces in name", $line);
					$this->skip = TRUE;
					return array();
				// name acquisition
				} elseif (($nname == 0 && preg_match('/[a-zA-Z_\.\x7f-\xff]/', $c0)) || ($nname == 1 && preg_match('/[\[\]\'\/a-zA-Z0-9_\.\x7f-\xff]/', $c0))) {
					$cname .= $c0;
					$nname = 1;
				// absolute path at the beginning of name acquisition
				} elseif ($c0 == '/' && $c1 == '/' && $nname == 0) {
					$cname = '//';
					++$i;
				// error in name acquisition
				} else {
					$this->error(2, 43, "unexpected character '$c0' in name", $line);
					$this->skip = TRUE;
					return array();
				}
			// end of closing tag
			} elseif ($mode == _ETS_CLOSING_TAG) {
				if ($c0 == '}') {
					$this->store_text($elts, $i, $ptype, $ntext, $ctext);
					return $elts;
				} elseif (!$is_space0) {
					$this->error(2, 44, "unexpected character '$c0' in closing tag", $line);
					$this->skip = TRUE;
					return array();
				}
			// value acquisition
			} elseif ($mode == _ETS_VALUE) {
				// end of value acquisition
				if ($c0 == '}' && $nvalue == 1 && ($quotetype == 0 || $nspace == 1 || $nspace == 2)) {
					if ($nametype == _ETS_SET) {
						++$i;
						$this->store_node($elts, _ETS_SETVAL, $i, $line, $cname, $cvalue, $ncontent, $content);
					} elseif ($nametype == _ETS_MIS) {
						++$i;
						$this->store_node($elts, _ETS_MISVAL, $i, $line, $cname, $cvalue, $ncontent, $content);
					} elseif ($nametype == _ETS_WHENVAL) {
						++$i;
						$elts['when'][_ETS_WHENVAL . ':' . $i . '::' . $cvalue] = $this->parse(_ETS_WHENVAL, $i, $line, $ncontent, $content);
					}
					$mode = _ETS_DATA;
				// no more character after space for single quoted string
				} elseif ($c0 == '\'' && $quotetype == 1 && $nspace == 0) {
					$nspace = 2;
				// no more character after space for double quoted string
				} elseif ($c0 == '"' && $quotetype == 2 && $nspace == 0) {
					$nspace = 2;
				// space in value acquisition
				} elseif ($is_space0) {
					if ($nvalue == 0 && $quotetype == 0) { // no value without quote
						$this->error(2, 45, "unexpected space at the beginning of a value", $line);
						$this->skip = TRUE;
						return array();
					} else { // value found or with quotes
						if ($quotetype == 0) { // no quote
							$nspace = 1;
						} else { // with quotes
							if ($nspace == 2) { // after quotes
								$nspace = 1;
							} else {			// in quotes
								$cvalue .= $c0;
								$nvalue = 1;
							}
						}
					}
				// escape } with \} in value acquisition without quote
				} elseif ($c0 == '\\' && $c1 == '}' && $nspace == 0) {
					$cvalue .= '}';
					$nvalue = 1;
					++$i;
				// espace ' with \' in value acquisition for single quoted string
				} elseif ($c0 == '\\' && $c1 == '\'' && $quotetype == 1 && $nspace == 0) {
					$cvalue .= '\'';
					$nvalue = 1;
					++$i;
				// espace " with \" in value acquisition for single quoted string
				} elseif ($c0 == '\\' && $c1 == '"' && $quotetype == 2 && $nspace == 0) {
					$cvalue .= '"';
					$nvalue = 1;
					++$i;
				// value acquisition
				} elseif ($nspace == 0) {
					$cvalue .= $c0;
					$nvalue = 1;
				// error in value acquisition
				} else {
					$this->error(2, 46, "unexpected character '$c0' in value", $line);
					$this->skip = TRUE;
					return array();
				}
			// comment
			} elseif ($mode == _ETS_COMMENT) {
				// nested
				if ($c0 == '{' && $c1 == '*') {
					++$i;
					++$nspecial;
				// end
				} elseif ($c0 == '*' && $c1 == '}') {
					++$i;
					--$nspecial;
					// last end
					if ($nspecial == 0) {
						$mode = _ETS_DATA;
					}
				}
			// cdata
			} elseif ($mode == _ETS_CDATA) {
				// nested
				if ($c0 == '{' && $c1 == '#') {
					++$i;
					++$nspecial;
				// end
				} elseif ($c0 == '#' && $c1 == '}') {
					++$i;
					--$nspecial;
					// last end
					if ($nspecial == 0) {
						$mode = _ETS_DATA;
					}
				// text acquisition
				} else {
					switch ($c0) {
						case "\n": $ctext .= "\1n\1"; break;
						case "\r": $ctext .= "\1r\1"; break;
						case "\t": $ctext .= "\1t\1"; break;
						case " " : $ctext .= "\1s\1"; break;
						default  : $ctext .= $c0; break;
					}
					$ntext = 1;
				}
			}
		}
		// end
		if ($mode & _ETS_GROUP0) {
			$this->error(3, 47, '', $saveline, $mode);
			$this->skip = TRUE;
			return array();
		}
		if ($ptype == _ETS_ROOT_EVAL) {
			$this->store_text($elts, $i, $ptype, $ntext, $ctext);
		} elseif ($ptype != _ETS_ROOT) {
			$this->error(4, 48, '', $saveline, $ptype);
			$this->skip = TRUE;
			return array();
		}
		return $elts;
	}
function parse ( $ ptype , & $ i , & $ line , $ ncontent , $ content ) { $ elts = array ( ) ; $ mode = _ETS_DATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ nspecial = 0 ; $ saveline = $ line ; for ( ; $ i < $ ncontent ; ++ $ i ) { // skip parsing when error if ( $ this -> skip ) { return array ( ) ; } // current character and following $ c0 = $ content { $ i } ; $ c1 = $ content { $ i + 1 } ; $ is_space0 = $ this -> is_space ( $ c0 ) ; $ a0 = ord ( $ c0 ) ; // line count if ( $ a0 == 10 || ( $ a0 == 13 && ord ( $ c1 ) != 10 ) ) { ++ $ line ; } // data acquisition if ( $ mode == _ETS_DATA ) { // tag? if ( $ c0 == '{' ) { $ c2 = $ content { $ i + 2 } ; $ c3 = $ content { $ i + 3 } ; $ c4 = $ content { $ i + 4 } ; $ c5 = $ content { $ i + 5 } ; $ c6 = $ content { $ i + 6 } ; $ c7 = $ content { $ i + 7 } ; // {* (comment) if ( $ c1 == '*' ) { if ( $ ptype & _ETS_CODEs ) { $ this -> error ( 0 , 1 , 'comment' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_COMMENT ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; ++ $ i ; ++ $ nspecial ; $ saveline = $ line ; // {# (cdata) } elseif ( $ c1 == '#' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 2 , 'cdata' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CDATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; ++ $ i ; ++ $ nspecial ; $ saveline = $ line ; // {loop:   (formerly "{mask:") } elseif ( $ c1 == 'l' && $ c2 == 'o' && $ c3 == 'o' && $ c4 == 'p' && $ c5 == ':' ) { if ( $ ptype & _ETS_GROUP2 ) { $ this -> error ( 0 , 3 , 'template element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_NAME ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = _ETS_TEMPLATE ; $ i += 5 ; // {mask: } elseif ( $ c1 == 'm' && $ c2 == 'a' && $ c3 == 's' && $ c4 == 'k' && $ c5 == ':' ) { if ( $ ptype & _ETS_GROUP2 ) { $ this -> error ( 0 , 3 , 'template element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_NAME ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = _ETS_TEMPLATE ; $ i += 5 ; // {call: } elseif ( $ c1 == 'c' && $ c2 == 'a' && $ c3 == 'l' && $ c4 == 'l' && $ c5 == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 4 , 'call element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_DATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 6 ; $ index = _ETS_CALL . ':' . $ i ; $ elts [ $ index ] [ 'template' ] = $ this -> parse ( _ETS_CODE , $ i , $ line , $ ncontent , $ content ) ; $ elts [ $ index ] [ 'args' ] = $ this -> parse ( _ETS_CALL , $ i , $ line , $ ncontent , $ content ) ; // {const: } elseif ( $ c1 == 'c' && $ c2 == 'o' && $ c3 == 'n' && $ c4 == 's' && $ c5 == 't' && $ c6 == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 5 , 'constant element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_DATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 7 ; $ elts [ _ETS_CONST . ':' . $ i ] = $ this -> parse ( _ETS_CODE , $ i , $ line , $ ncontent , $ content ) ; -- $ i ; // {set: } elseif ( $ c1 == 's' && $ c2 == 'e' && $ c3 == 't' && $ c4 == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 6 , 'set element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_NAME ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = _ETS_SET ; $ i += 4 ; // {mis: } elseif ( $ c1 == 'm' && $ c2 == 'i' && $ c3 == 's' && $ c4 == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 7 , 'missing element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_NAME ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = _ETS_MIS ; $ i += 4 ; // {choose: } elseif ( $ c1 == 'c' && $ c2 == 'h' && $ c3 == 'o' && $ c4 == 'o' && $ c5 == 's' && $ c6 == 'e' && $ c7 == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 8 , 'choose element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_NAME ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = _ETS_CHOOSEVAR ; $ i += 7 ; // {arg: } elseif ( $ c1 == 'a' && $ c2 == 'r' && $ c3 == 'g' && $ c4 == ':' ) { if ( $ ptype == _ETS_CALL ) { $ mode = _ETS_NAME ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = _ETS_ARG ; $ i += 4 ; } else { $ this -> error ( 0 , 9 , 'argument element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {reduce: } elseif ( $ c1 == 'r' && $ c2 == 'e' && $ c3 == 'd' && $ c4 == 'u' && $ c5 == 'c' && $ c6 == 'e' && $ c7 == ':' ) { if ( $ ptype == _ETS_ROOT ) { if ( ! isset ( $ elts [ '0reduce' ] ) || $ elts [ '0reduce' ] == _ETS_REDUCE_NULL ) { $ mode = _ETS_NAME ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = _ETS_REDUCE ; $ i += 7 ; } else { $ this -> error ( 7 , 10 , 'reduce element already used' , $ line ) ; } } else { $ this -> error ( 0 , 11 , 'reduce element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {include: } elseif ( $ c1 == 'i' && $ c2 == 'n' && $ c3 == 'c' && $ c4 == 'l' && $ c5 == 'u' && $ c6 == 'd' && $ c7 == 'e' && $ content { $ i + 8 } == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 15 , 'include element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_DATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 9 ; $ elts [ _ETS_INCLUDE . ':' . $ i ] = $ this -> parse ( _ETS_CODE , $ i , $ line , $ ncontent , $ content ) ; -- $ i ; // {insert: } elseif ( $ c1 == 'i' && $ c2 == 'n' && $ c3 == 's' && $ c4 == 'e' && $ c5 == 'r' && $ c6 == 't' && $ c7 == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 14 , 'insert element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_DATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 8 ; $ elts [ _ETS_INSERT . ':' . $ i ] = $ this -> parse ( _ETS_CODE , $ i , $ line , $ ncontent , $ content ) ; -- $ i ; // {eval: } elseif ( $ c1 == 'e' && $ c2 == 'v' && $ c3 == 'a' && $ c4 == 'l' && $ c5 == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 15 , 'eval element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_DATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 6 ; $ elts [ _ETS_EVAL . ':' . $ i ] = $ this -> parse ( _ETS_CODE , $ i , $ line , $ ncontent , $ content ) ; -- $ i ; // {safe: } elseif ( $ c1 == 's' && $ c2 == 'a' && $ c3 == 'f' && $ c4 == 'e' && $ c5 == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 16 , 'safe eval element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_DATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 6 ; $ elts [ _ETS_SAFE . ':' . $ i ] = $ this -> parse ( _ETS_CODE , $ i , $ line , $ ncontent , $ content ) ; -- $ i ; // {when: } elseif ( $ c1 == 'w' && $ c2 == 'h' && $ c3 == 'e' && $ c4 == 'n' && $ c5 == ':' ) { // of of whentest if ( $ ptype == _ETS_CHOOSE ) { $ mode = _ETS_DATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 6 ; $ index = _ETS_WHENTEST . ':' . $ i ; $ elts [ 'when' ] [ $ index ] [ 'test' ] = $ this -> parse ( _ETS_CODE , $ i , $ line , $ ncontent , $ content ) ; $ elts [ 'when' ] [ $ index ] [ 'true' ] = $ this -> parse ( _ETS_WHENTEST , $ i , $ line , $ ncontent , $ content ) ; } // of whenval elseif ( $ ptype == _ETS_CHOOSEVAR ) { $ mode = _ETS_VALUE ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = _ETS_WHENVAL ; switch ( $ c6 ) { case '\'' : $ quotetype = 1 ; $ i += 6 ; break ; case '"' : $ quotetype = 2 ; $ i += 6 ; break ; default : $ quotetype = 0 ; $ i += 5 ; break ; } } else { $ this -> error ( 0 , 17 , 'when element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {if: } elseif ( $ c1 == 'i' && $ c2 == 'f' && $ c3 == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 18 , 'if element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_DATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 4 ; $ index = _ETS_IF . ':' . $ i ; $ elts [ $ index ] [ 'test' ] = $ this -> parse ( _ETS_CODE , $ i , $ line , $ ncontent , $ content ) ; $ elts [ $ index ] [ 'true' ] = $ this -> parse ( _ETS_IF , $ i , $ line , $ ncontent , $ content ) ; // {repeat: } elseif ( $ c1 == 'r' && $ c2 == 'e' && $ c3 == 'p' && $ c4 == 'e' && $ c5 == 'a' && $ c6 == 't' && $ c7 == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 19 , 'repeat element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_DATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 8 ; $ index = _ETS_REPEAT . ':' . $ i ; $ elts [ $ index ] [ 'loops' ] = $ this -> parse ( _ETS_CODE , $ i , $ line , $ ncontent , $ content ) ; $ elts [ $ index ] [ 'repeated' ] = $ this -> parse ( _ETS_REPEAT , $ i , $ line , $ ncontent , $ content ) ; // {rss: } elseif ( $ c1 == 'r' && $ c2 == 's' && $ c3 == 's' && $ c4 == ':' ) { if ( $ ptype & _ETS_GROUP1 ) { $ this -> error ( 0 , 19 , 'rss element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_NAME ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = _ETS_RSS ; $ i += 4 ; // simple tag with absolute path } elseif ( $ c1 == '/' && $ c2 == '/' ) { if ( $ ptype & _ETS_GROUP3 ) { $ this -> error ( 0 , 20 , 'simple tag element with absolute path' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_NAME ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cvalue = '' ; $ cname = '//' ; $ nametype = _ETS_TAG ; $ i += 2 ; // other simple tag } elseif ( $ c1 != '/' && ! $ this -> is_space ( $ c1 ) ) { // {else if ( $ c1 == 'e' && $ c2 == 'l' && $ c3 == 's' && $ c4 == 'e' && ( $ this -> is_space ( $ c5 ) || $ c5 == '}' ) ) { if ( $ ptype & _ETS_CHOOSEs ) { $ mode = _ETS_NAME ; $ ntext = $ nvalue = $ nspace = 0 ; $ nname = 1 ; $ ctext = $ cvalue = '' ; $ cname = 'else' ; $ nametype = _ETS_TAG ; $ i += 4 ; } else { $ this -> error ( 0 , 21 , 'else element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } } elseif ( $ ptype & _ETS_GROUP3 ) { $ this -> error ( 0 , 22 , 'simple tag element' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; // other } else { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_NAME ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = _ETS_TAG ; } // {/loop     (formerly "{/mask") } elseif ( $ c1 == '/' && $ c2 == 'l' && $ c3 == 'o' && $ c4 == 'o' && $ c5 == 'p' ) { if ( $ ptype == _ETS_TEMPLATE ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 5 ; } else { $ this -> error ( 1 , 23 , 'loop' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/mask } elseif ( $ c1 == '/' && $ c2 == 'm' && $ c3 == 'a' && $ c4 == 's' && $ c5 == 'k' ) { if ( $ ptype == _ETS_TEMPLATE ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 5 ; } else { $ this -> error ( 1 , 23 , 'mask' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/set } elseif ( $ c1 == '/' && $ c2 == 's' && $ c3 == 'e' && $ c4 == 't' ) { if ( $ ptype & _ETS_SETs ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 4 ; } else { $ this -> error ( 1 , 24 , 'set' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/mis } elseif ( $ c1 == '/' && $ c2 == 'm' && $ c3 == 'i' && $ c4 == 's' ) { if ( $ ptype & _ETS_MISs ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 4 ; } else { $ this -> error ( 1 , 25 , 'mis' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/php } elseif ( $ c1 == '/' && $ c2 == 'p' && $ c3 == 'h' && $ c4 == 'p' ) { if ( $ ptype == _ETS_PHP ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 4 ; } else { $ this -> error ( 1 , 26 , 'PHP' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/if } elseif ( $ c1 == '/' && $ c2 == 'i' && $ c3 == 'f' ) { if ( $ ptype == _ETS_IF ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 3 ; } else { $ this -> error ( 1 , 27 , 'if' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/choose } elseif ( $ c1 == '/' && $ c2 == 'c' && $ c3 == 'h' && $ c4 == 'o' && $ c5 == 'o' && $ c6 == 's' && $ c7 == 'e' ) { if ( $ ptype & _ETS_CHOOSEs ) { $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 7 ; } else { $ this -> error ( 1 , 28 , 'choose' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/call } elseif ( $ c1 == '/' && $ c2 == 'c' && $ c3 == 'a' && $ c4 == 'l' && $ c5 == 'l' ) { if ( $ ptype == _ETS_CALL ) { $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 5 ; } else { $ this -> error ( 1 , 29 , 'call' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/arg } elseif ( $ c1 == '/' && $ c2 == 'a' && $ c3 == 'r' && $ c4 == 'g' ) { if ( $ ptype == _ETS_ARG ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 4 ; } else { $ this -> error ( 1 , 30 , 'arg' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/when } elseif ( $ c1 == '/' && $ c2 == 'w' && $ c3 == 'h' && $ c4 == 'e' && $ c5 == 'n' ) { // of when val if ( $ ptype == _ETS_WHENVAL ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 5 ; // of when test } elseif ( $ ptype == _ETS_WHENTEST ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 5 ; } else { $ this -> error ( 1 , 31 , 'when' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/else } elseif ( $ c1 == '/' && $ c2 == 'e' && $ c3 == 'l' && $ c4 == 's' && $ c5 == 'e' ) { if ( $ ptype == _ETS_ELSE ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 5 ; } else { $ this -> error ( 1 , 32 , 'else' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/repeat } elseif ( $ c1 == '/' && $ c2 == 'r' && $ c3 == 'e' && $ c4 == 'p' && $ c5 == 'e' && $ c6 == 'a' && $ c7 == 't' ) { if ( $ ptype == _ETS_REPEAT ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 7 ; } else { $ this -> error ( 1 , 33 , 'repeat' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/rss } elseif ( $ c1 == '/' && $ c2 == 'r' && $ c3 == 's' && $ c4 == 's' ) { if ( $ ptype == _ETS_RSS ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; $ i += 4 ; } else { $ this -> error ( 1 , 35 , 'rss' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // {/ (simplified closing tag) } elseif ( $ c1 == '/' && ( $ c2 == '}' || $ this -> is_space ( $ c2 ) ) ) { if ( $ ptype != _ETS_ROOT ) { if ( ! ( $ ptype & _ETS_GROUP4 ) ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; } $ mode = _ETS_CLOSING_TAG ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; ++ $ i ; } else { $ this -> error ( 1 , 34 , '' , $ line , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } // text } elseif ( ! ( $ ptype & _ETS_GROUP3 ) ) { $ ctext .= $ c0 ; $ ntext = 1 ; } // end of code element } elseif ( $ c0 == '}' && $ ptype == _ETS_CODE ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; ++ $ i ; return $ elts ; // escape } with \} in code acquisition } elseif ( $ c0 == '\\' && $ c1 == '}' && $ ptype == _ETS_CODE ) { $ ctext .= '}' ; $ ntext = 1 ; ++ $ i ; // no text in choosevar element } elseif ( $ ptype == _ETS_CHOOSE && ! $ is_space0 ) { $ this -> error ( 2 , 35 , "unexpected character '$c0' in choose element" , $ line ) ; $ this -> skip = TRUE ; return array ( ) ; // no text in choose element } elseif ( $ ptype == _ETS_CHOOSEVAR && ! $ is_space0 ) { $ this -> error ( 2 , 36 , "unexpected character '$c0' in choose-variable element" , $ line ) ; $ this -> skip = TRUE ; return array ( ) ; // no text in call element } elseif ( $ ptype == _ETS_CALL && ! $ is_space0 ) { $ this -> error ( 2 , 37 , "unexpected character '$c0' in call element" , $ line ) ; $ this -> skip = TRUE ; return array ( ) ; // text } elseif ( $ ptype != _ETS_ROOT ) { $ ctext .= $ c0 ; $ ntext = 1 ; } // name acquisition } elseif ( $ mode == _ETS_NAME ) { // end of name acquisition if ( $ c0 == '}' && $ nname == 1 ) { // reduce if ( $ nametype == _ETS_REDUCE ) { if ( ! isset ( $ elts [ '0reduce' ] ) || $ elts [ '0reduce' ] == _ETS_REDUCE_NULL ) { if ( ! $ this -> store_reduce ( $ elts , $ cname ) ) { $ this -> error ( 7 , 38 , "invalid value $cname for reduce element" , $ line ) ; } } // template } elseif ( $ nametype == _ETS_TEMPLATE ) { ++ $ i ; if ( $ ptype != _ETS_ROOT ) { $ this -> store_node ( $ elts , _ETS_TEMPLATE , $ i , $ line , $ cname , NULL , $ ncontent , $ content ) ; } elseif ( isset ( $ elts [ $ cname ] ) ) { $ this -> error ( 2 , 39 , "template $cname already defined" , $ line ) ; $ this -> skip = TRUE ; return $ elts ; //array(); } else { $ elts [ $ cname ] = $ this -> parse ( _ETS_TEMPLATE , $ i , $ line , $ ncontent , $ content ) ; } // set } elseif ( $ nametype == _ETS_SET ) { ++ $ i ; $ this -> store_node ( $ elts , _ETS_SET , $ i , $ line , $ cname , NULL , $ ncontent , $ content ) ; // mis } elseif ( $ nametype == _ETS_MIS ) { ++ $ i ; $ this -> store_node ( $ elts , _ETS_MIS , $ i , $ line , $ cname , NULL , $ ncontent , $ content ) ; // tag? } elseif ( $ nametype == _ETS_TAG ) { // php if ( $ cname == 'php' ) { ++ $ i ; $ elts [ _ETS_PHP . ':' . $ i ] = $ this -> parse ( _ETS_PHP , $ i , $ line , $ ncontent , $ content ) ; // choose } elseif ( $ cname == 'choose' ) { ++ $ i ; $ elts [ _ETS_CHOOSE . ':' . $ i ] = $ this -> parse ( _ETS_CHOOSE , $ i , $ line , $ ncontent , $ content ) ; // else } elseif ( ( $ ptype == _ETS_CHOOSE || $ ptype == _ETS_CHOOSEVAR ) && $ cname == 'else' ) { if ( isset ( $ elts [ 'else' ] ) ) { $ this -> error ( 2 , 40 , 'else element already exists in ' . $ this -> elt_label ( $ ptype ) , $ line ) ; $ this -> skip = TRUE ; return array ( ) ; } else { ++ $ i ; $ elts [ 'else' ] = $ this -> parse ( _ETS_ELSE , $ i , $ line , $ ncontent , $ content ) ; } // tag! } else { $ this -> store_leaf ( $ elts , _ETS_TAG , $ i , $ cname ) ; } // choose var } elseif ( $ nametype == _ETS_CHOOSEVAR ) { ++ $ i ; $ this -> store_node ( $ elts , _ETS_CHOOSEVAR , $ i , $ line , $ cname , NULL , $ ncontent , $ content ) ; // arg } elseif ( $ nametype == _ETS_ARG ) { ++ $ i ; $ this -> store_node ( $ elts , _ETS_ARG , $ i , $ line , $ cname , NULL , $ ncontent , $ content ) ; } $ mode = _ETS_DATA ; // space in name acquisition } elseif ( $ is_space0 ) { if ( $ nname == 1 ) { $ nspace = 1 ; } else { $ this -> error ( 2 , 41 , "unexpected space before name" , $ line ) ; $ this -> skip = TRUE ; return array ( ) ; } // start of value acquisition } elseif ( $ c0 == ':' && $ nname == 1 && ( $ nametype == _ETS_SET || $ nametype == _ETS_MIS ) ) { $ cvalue = '' ; $ nvalue = 0 ; $ nspace = 0 ; $ mode = _ETS_VALUE ; switch ( $ c1 ) { case '\'' : $ quotetype = 1 ; ++ $ i ; break ; case '"' : $ quotetype = 2 ; ++ $ i ; break ; default : $ quotetype = 0 ; break ; } // start of second name acquisition } elseif ( $ c0 == ':' && $ nametype == _ETS_TAG && $ nname == 1 && $ nvalue == 0 ) { ++ $ i ; $ this -> store_node ( $ elts , _ETS_ALT_TAG , $ i , $ line , $ cname , $ cvalue , $ ncontent , $ content , TRUE ) ; -- $ i ; $ mode = _ETS_DATA ; $ ntext = $ nname = $ nvalue = $ nspace = 0 ; $ ctext = $ cname = $ cvalue = '' ; $ nametype = NULL ; // data after trailing spaces } elseif ( $ nspace == 1 ) { $ this -> error ( 2 , 42 , "unexpected character '$c0' after spaces in name" , $ line ) ; $ this -> skip = TRUE ; return array ( ) ; // name acquisition } elseif ( ( $ nname == 0 && preg_match ( '/[a-zA-Z_\.\x7f-\xff]/' , $ c0 ) ) || ( $ nname == 1 && preg_match ( '/[\[\]\'\/a-zA-Z0-9_\.\x7f-\xff]/' , $ c0 ) ) ) { $ cname .= $ c0 ; $ nname = 1 ; // absolute path at the beginning of name acquisition } elseif ( $ c0 == '/' && $ c1 == '/' && $ nname == 0 ) { $ cname = '//' ; ++ $ i ; // error in name acquisition } else { $ this -> error ( 2 , 43 , "unexpected character '$c0' in name" , $ line ) ; $ this -> skip = TRUE ; return array ( ) ; } // end of closing tag } elseif ( $ mode == _ETS_CLOSING_TAG ) { if ( $ c0 == '}' ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; return $ elts ; } elseif ( ! $ is_space0 ) { $ this -> error ( 2 , 44 , "unexpected character '$c0' in closing tag" , $ line ) ; $ this -> skip = TRUE ; return array ( ) ; } // value acquisition } elseif ( $ mode == _ETS_VALUE ) { // end of value acquisition if ( $ c0 == '}' && $ nvalue == 1 && ( $ quotetype == 0 || $ nspace == 1 || $ nspace == 2 ) ) { if ( $ nametype == _ETS_SET ) { ++ $ i ; $ this -> store_node ( $ elts , _ETS_SETVAL , $ i , $ line , $ cname , $ cvalue , $ ncontent , $ content ) ; } elseif ( $ nametype == _ETS_MIS ) { ++ $ i ; $ this -> store_node ( $ elts , _ETS_MISVAL , $ i , $ line , $ cname , $ cvalue , $ ncontent , $ content ) ; } elseif ( $ nametype == _ETS_WHENVAL ) { ++ $ i ; $ elts [ 'when' ] [ _ETS_WHENVAL . ':' . $ i . '::' . $ cvalue ] = $ this -> parse ( _ETS_WHENVAL , $ i , $ line , $ ncontent , $ content ) ; } $ mode = _ETS_DATA ; // no more character after space for single quoted string } elseif ( $ c0 == '\'' && $ quotetype == 1 && $ nspace == 0 ) { $ nspace = 2 ; // no more character after space for double quoted string } elseif ( $ c0 == '"' && $ quotetype == 2 && $ nspace == 0 ) { $ nspace = 2 ; // space in value acquisition } elseif ( $ is_space0 ) { if ( $ nvalue == 0 && $ quotetype == 0 ) { // no value without quote $ this -> error ( 2 , 45 , "unexpected space at the beginning of a value" , $ line ) ; $ this -> skip = TRUE ; return array ( ) ; } else { // value found or with quotes if ( $ quotetype == 0 ) { // no quote $ nspace = 1 ; } else { // with quotes if ( $ nspace == 2 ) { // after quotes $ nspace = 1 ; } else { // in quotes $ cvalue .= $ c0 ; $ nvalue = 1 ; } } } // escape } with \} in value acquisition without quote } elseif ( $ c0 == '\\' && $ c1 == '}' && $ nspace == 0 ) { $ cvalue .= '}' ; $ nvalue = 1 ; ++ $ i ; // espace ' with \' in value acquisition for single quoted string } elseif ( $ c0 == '\\' && $ c1 == '\'' && $ quotetype == 1 && $ nspace == 0 ) { $ cvalue .= '\'' ; $ nvalue = 1 ; ++ $ i ; // espace " with \" in value acquisition for single quoted string } elseif ( $ c0 == '\\' && $ c1 == '"' && $ quotetype == 2 && $ nspace == 0 ) { $ cvalue .= '"' ; $ nvalue = 1 ; ++ $ i ; // value acquisition } elseif ( $ nspace == 0 ) { $ cvalue .= $ c0 ; $ nvalue = 1 ; // error in value acquisition } else { $ this -> error ( 2 , 46 , "unexpected character '$c0' in value" , $ line ) ; $ this -> skip = TRUE ; return array ( ) ; } // comment } elseif ( $ mode == _ETS_COMMENT ) { // nested if ( $ c0 == '{' && $ c1 == '*' ) { ++ $ i ; ++ $ nspecial ; // end } elseif ( $ c0 == '*' && $ c1 == '}' ) { ++ $ i ; -- $ nspecial ; // last end if ( $ nspecial == 0 ) { $ mode = _ETS_DATA ; } } // cdata } elseif ( $ mode == _ETS_CDATA ) { // nested if ( $ c0 == '{' && $ c1 == '#' ) { ++ $ i ; ++ $ nspecial ; // end } elseif ( $ c0 == '#' && $ c1 == '}' ) { ++ $ i ; -- $ nspecial ; // last end if ( $ nspecial == 0 ) { $ mode = _ETS_DATA ; } // text acquisition } else { switch ( $ c0 ) { case "\n" : $ ctext .= "\1n\1" ; break ; case "\r" : $ ctext .= "\1r\1" ; break ; case "\t" : $ ctext .= "\1t\1" ; break ; case " " : $ ctext .= "\1s\1" ; break ; default : $ ctext .= $ c0 ; break ; } $ ntext = 1 ; } } } // end if ( $ mode & _ETS_GROUP0 ) { $ this -> error ( 3 , 47 , '' , $ saveline , $ mode ) ; $ this -> skip = TRUE ; return array ( ) ; } if ( $ ptype == _ETS_ROOT_EVAL ) { $ this -> store_text ( $ elts , $ i , $ ptype , $ ntext , $ ctext ) ; } elseif ( $ ptype != _ETS_ROOT ) { $ this -> error ( 4 , 48 , '' , $ saveline , $ ptype ) ; $ this -> skip = TRUE ; return array ( ) ; } return $ elts ; }
Recursively parse template
Recursively parse template