]> granicus.if.org Git - php/commitdiff
Added NOWDOC
authorDmitry Stogov <dmitry@php.net>
Tue, 12 Feb 2008 09:28:30 +0000 (09:28 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 12 Feb 2008 09:28:30 +0000 (09:28 +0000)
32 files changed:
Zend/tests/heredoc_001.phpt [new file with mode: 0644]
Zend/tests/heredoc_002.phpt [new file with mode: 0644]
Zend/tests/heredoc_003.phpt [new file with mode: 0644]
Zend/tests/heredoc_004.phpt [new file with mode: 0644]
Zend/tests/heredoc_005.phpt [new file with mode: 0644]
Zend/tests/heredoc_006.phpt [new file with mode: 0644]
Zend/tests/heredoc_007.phpt [new file with mode: 0644]
Zend/tests/heredoc_008.phpt [new file with mode: 0644]
Zend/tests/heredoc_009.phpt [new file with mode: 0644]
Zend/tests/heredoc_010.phpt [new file with mode: 0644]
Zend/tests/heredoc_011.phpt [new file with mode: 0644]
Zend/tests/nowdoc.inc [new file with mode: 0644]
Zend/tests/nowdoc_001.phpt [new file with mode: 0644]
Zend/tests/nowdoc_002.phpt [new file with mode: 0644]
Zend/tests/nowdoc_003.phpt [new file with mode: 0644]
Zend/tests/nowdoc_004.phpt [new file with mode: 0644]
Zend/tests/nowdoc_005.phpt [new file with mode: 0644]
Zend/tests/nowdoc_006.phpt [new file with mode: 0644]
Zend/tests/nowdoc_007.phpt [new file with mode: 0644]
Zend/tests/nowdoc_008.phpt [new file with mode: 0644]
Zend/tests/nowdoc_009.phpt [new file with mode: 0644]
Zend/tests/nowdoc_010.phpt [new file with mode: 0644]
Zend/tests/nowdoc_011.phpt [new file with mode: 0644]
Zend/tests/nowdoc_012.phpt [new file with mode: 0644]
Zend/tests/nowdoc_013.phpt [new file with mode: 0644]
Zend/tests/nowdoc_014.phpt [new file with mode: 0644]
Zend/tests/nowdoc_015.phpt [new file with mode: 0644]
Zend/zend_compile.c
Zend/zend_highlight.c
Zend/zend_language_parser.y
Zend/zend_language_scanner.l
ext/tokenizer/tokenizer.c

diff --git a/Zend/tests/heredoc_001.phpt b/Zend/tests/heredoc_001.phpt
new file mode 100644 (file)
index 0000000..d42b3df
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+basic heredoc syntax
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<ENDOFHEREDOC
+This is a heredoc test.
+
+ENDOFHEREDOC;
+
+$x = <<<ENDOFHEREDOC
+This is another heredoc test.
+
+ENDOFHEREDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is a heredoc test.
+This is another heredoc test.
diff --git a/Zend/tests/heredoc_002.phpt b/Zend/tests/heredoc_002.phpt
new file mode 100644 (file)
index 0000000..481ada9
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+basic binary heredoc syntax
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print b<<<ENDOFHEREDOC
+This is a heredoc test.
+
+ENDOFHEREDOC;
+
+$x = b<<<ENDOFHEREDOC
+This is another heredoc test.
+
+ENDOFHEREDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is a heredoc test.
+This is another heredoc test.
diff --git a/Zend/tests/heredoc_003.phpt b/Zend/tests/heredoc_003.phpt
new file mode 100644 (file)
index 0000000..fb34f51
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+simple variable replacement test (heredoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<ENDOFHEREDOC
+This is heredoc test #$a.
+
+ENDOFHEREDOC;
+
+$x = <<<ENDOFHEREDOC
+This is heredoc test #$b.
+
+ENDOFHEREDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is heredoc test #1.
+This is heredoc test #2.
diff --git a/Zend/tests/heredoc_004.phpt b/Zend/tests/heredoc_004.phpt
new file mode 100644 (file)
index 0000000..29334b8
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+braces variable replacement test (heredoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<ENDOFHEREDOC
+This is heredoc test #{$a}.
+
+ENDOFHEREDOC;
+
+$x = <<<ENDOFHEREDOC
+This is heredoc test #{$b}.
+
+ENDOFHEREDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is heredoc test #1.
+This is heredoc test #2.
diff --git a/Zend/tests/heredoc_005.phpt b/Zend/tests/heredoc_005.phpt
new file mode 100644 (file)
index 0000000..8ab3a65
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+unbraced complex variable replacement test (heredoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<ENDOFHEREDOC
+This is heredoc test #s $a, $b, $c['c'], and $d->d.
+
+ENDOFHEREDOC;
+
+$x = <<<ENDOFHEREDOC
+This is heredoc test #s $a, $b, $c['c'], and $d->d.
+
+ENDOFHEREDOC;
+
+print "{$x}";
+
+?>
+--EXPECTF--
+Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in %sheredoc_005.php on line 6
diff --git a/Zend/tests/heredoc_006.phpt b/Zend/tests/heredoc_006.phpt
new file mode 100644 (file)
index 0000000..d40ae1e
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+braced complex variable replacement test (heredoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<ENDOFHEREDOC
+This is heredoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.
+
+ENDOFHEREDOC;
+
+$x = <<<ENDOFHEREDOC
+This is heredoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.
+
+ENDOFHEREDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is heredoc test #s 1, 2, 3, and 4.
+This is heredoc test #s 1, 2, 3, and 4.
diff --git a/Zend/tests/heredoc_007.phpt b/Zend/tests/heredoc_007.phpt
new file mode 100644 (file)
index 0000000..b823b55
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+braced and unbraced complex variable replacement test (heredoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<ENDOFHEREDOC
+This is heredoc test #s $a, {$b}, {$c['c']}, and {$d->d}.
+
+ENDOFHEREDOC;
+
+$x = <<<ENDOFHEREDOC
+This is heredoc test #s $a, {$b}, {$c['c']}, and {$d->d}.
+
+ENDOFHEREDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is heredoc test #s 1, 2, 3, and 4.
+This is heredoc test #s 1, 2, 3, and 4.
diff --git a/Zend/tests/heredoc_008.phpt b/Zend/tests/heredoc_008.phpt
new file mode 100644 (file)
index 0000000..8feda03
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+empty doc test (heredoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<ENDOFHEREDOC
+ENDOFHEREDOC;
+
+$x = <<<ENDOFHEREDOC
+ENDOFHEREDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
diff --git a/Zend/tests/heredoc_009.phpt b/Zend/tests/heredoc_009.phpt
new file mode 100644 (file)
index 0000000..38f5d28
--- /dev/null
@@ -0,0 +1,42 @@
+--TEST--
+Torture the T_END_HEREDOC rules (heredoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<ENDOFHEREDOC
+ENDOFHEREDOC    ;
+    ENDOFHEREDOC;
+ENDOFHEREDOC    
+    ENDOFHEREDOC
+$ENDOFHEREDOC;
+
+ENDOFHEREDOC;
+
+$x = <<<ENDOFHEREDOC
+ENDOFHEREDOC    ;
+    ENDOFHEREDOC;
+ENDOFHEREDOC    
+    ENDOFHEREDOC
+$ENDOFHEREDOC;
+
+ENDOFHEREDOC;
+
+print "{$x}";
+
+?>
+--EXPECTF--
+Notice: Undefined variable: ENDOFHEREDOC in %s on line %d
+ENDOFHEREDOC    ;
+    ENDOFHEREDOC;
+ENDOFHEREDOC    
+    ENDOFHEREDOC
+;
+
+Notice: Undefined variable: ENDOFHEREDOC in %s on line %d
+ENDOFHEREDOC    ;
+    ENDOFHEREDOC;
+ENDOFHEREDOC    
+    ENDOFHEREDOC
+;
diff --git a/Zend/tests/heredoc_010.phpt b/Zend/tests/heredoc_010.phpt
new file mode 100644 (file)
index 0000000..5aa0433
--- /dev/null
@@ -0,0 +1,32 @@
+--TEST--
+Torture the T_END_HEREDOC rules with variable expansions (heredoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+$fooledYou = '';
+
+print <<<ENDOFHEREDOC
+{$fooledYou}ENDOFHEREDOC{$fooledYou}
+ENDOFHEREDOC{$fooledYou}
+{$fooledYou}ENDOFHEREDOC
+
+ENDOFHEREDOC;
+
+$x = <<<ENDOFHEREDOC
+{$fooledYou}ENDOFHEREDOC{$fooledYou}
+ENDOFHEREDOC{$fooledYou}
+{$fooledYou}ENDOFHEREDOC
+
+ENDOFHEREDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+ENDOFHEREDOC
+ENDOFHEREDOC
+ENDOFHEREDOC
+ENDOFHEREDOC
+ENDOFHEREDOC
+ENDOFHEREDOC
diff --git a/Zend/tests/heredoc_011.phpt b/Zend/tests/heredoc_011.phpt
new file mode 100644 (file)
index 0000000..6a1d5a0
--- /dev/null
@@ -0,0 +1,20 @@
+--TEST--
+Heredocs can NOT be used as static scalars.
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+class e {
+    
+    const E = <<<THISMUSTERROR
+If you see this, something's wrong.
+THISMUSTERROR;
+
+};
+
+print e::E . "\n";
+
+?>
+--EXPECTF--
+Parse error: syntax error, unexpected T_START_HEREDOC in %sheredoc_011.php on line 8
diff --git a/Zend/tests/nowdoc.inc b/Zend/tests/nowdoc.inc
new file mode 100644 (file)
index 0000000..98f9fba
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+
+// Common definitions for heredoc/nowdoc tests.
+$a = 1;
+$b = 2;
+$c = array( 'c' => 3, );
+class d { public function __construct() { $this->d = 4; } };
+$d = new d;
+
+?>
+
diff --git a/Zend/tests/nowdoc_001.phpt b/Zend/tests/nowdoc_001.phpt
new file mode 100644 (file)
index 0000000..3b9e3ef
--- /dev/null
@@ -0,0 +1,24 @@
+--TEST--
+basic nowdoc syntax
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<'ENDOFNOWDOC'
+This is a nowdoc test.
+
+ENDOFNOWDOC;
+
+$x = <<<'ENDOFNOWDOC'
+This is another nowdoc test.
+With another line in it.
+ENDOFNOWDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is a nowdoc test.
+This is another nowdoc test.
+With another line in it.
diff --git a/Zend/tests/nowdoc_002.phpt b/Zend/tests/nowdoc_002.phpt
new file mode 100644 (file)
index 0000000..3b17da8
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+basic binary nowdoc syntax
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print b<<<'ENDOFNOWDOC'
+This is a nowdoc test.
+
+ENDOFNOWDOC;
+
+$x = b<<<'ENDOFNOWDOC'
+This is another nowdoc test.
+
+ENDOFNOWDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is a nowdoc test.
+This is another nowdoc test.
diff --git a/Zend/tests/nowdoc_003.phpt b/Zend/tests/nowdoc_003.phpt
new file mode 100644 (file)
index 0000000..4282ab9
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+simple variable replacement test (nowdoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<'ENDOFNOWDOC'
+This is nowdoc test #$a.
+
+ENDOFNOWDOC;
+
+$x = <<<'ENDOFNOWDOC'
+This is nowdoc test #$b.
+
+ENDOFNOWDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is nowdoc test #$a.
+This is nowdoc test #$b.
diff --git a/Zend/tests/nowdoc_004.phpt b/Zend/tests/nowdoc_004.phpt
new file mode 100644 (file)
index 0000000..0e5b927
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+braces variable replacement test (nowdoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<'ENDOFNOWDOC'
+This is nowdoc test #{$a}.
+
+ENDOFNOWDOC;
+
+$x = <<<'ENDOFNOWDOC'
+This is nowdoc test #{$b}.
+
+ENDOFNOWDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is nowdoc test #{$a}.
+This is nowdoc test #{$b}.
diff --git a/Zend/tests/nowdoc_005.phpt b/Zend/tests/nowdoc_005.phpt
new file mode 100644 (file)
index 0000000..65e33d7
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+unbraced complex variable replacement test (nowdoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<'ENDOFNOWDOC'
+This is nowdoc test #s $a, $b, $c['c'], and $d->d.
+
+ENDOFNOWDOC;
+
+$x = <<<'ENDOFNOWDOC'
+This is nowdoc test #s $a, $b, $c['c'], and $d->d.
+
+ENDOFNOWDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is nowdoc test #s $a, $b, $c['c'], and $d->d.
+This is nowdoc test #s $a, $b, $c['c'], and $d->d.
diff --git a/Zend/tests/nowdoc_006.phpt b/Zend/tests/nowdoc_006.phpt
new file mode 100644 (file)
index 0000000..9d99973
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+braced complex variable replacement test (nowdoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<'ENDOFNOWDOC'
+This is nowdoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.
+
+ENDOFNOWDOC;
+
+$x = <<<'ENDOFNOWDOC'
+This is nowdoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.
+
+ENDOFNOWDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is nowdoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.
+This is nowdoc test #s {$a}, {$b}, {$c['c']}, and {$d->d}.
diff --git a/Zend/tests/nowdoc_007.phpt b/Zend/tests/nowdoc_007.phpt
new file mode 100644 (file)
index 0000000..d9e9411
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+braced and unbraced complex variable replacement test (nowdoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+                     
+print <<<'ENDOFNOWDOC'
+This is nowdoc test #s $a, {$b}, {$c['c']}, and {$d->d}.
+
+ENDOFNOWDOC;
+
+$x = <<<'ENDOFNOWDOC'
+This is nowdoc test #s $a, {$b}, {$c['c']}, and {$d->d}.
+
+ENDOFNOWDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+This is nowdoc test #s $a, {$b}, {$c['c']}, and {$d->d}.
+This is nowdoc test #s $a, {$b}, {$c['c']}, and {$d->d}.
diff --git a/Zend/tests/nowdoc_008.phpt b/Zend/tests/nowdoc_008.phpt
new file mode 100644 (file)
index 0000000..486f002
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+empty doc test (nowdoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<'ENDOFNOWDOC'
+ENDOFNOWDOC;
+
+$x = <<<'ENDOFNOWDOC'
+ENDOFNOWDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
diff --git a/Zend/tests/nowdoc_009.phpt b/Zend/tests/nowdoc_009.phpt
new file mode 100644 (file)
index 0000000..ec8b78f
--- /dev/null
@@ -0,0 +1,40 @@
+--TEST--
+Torture the T_END_NOWDOC rules (nowdoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+print <<<'ENDOFNOWDOC'
+ENDOFNOWDOC    ;
+    ENDOFNOWDOC;
+ENDOFNOWDOC    
+    ENDOFNOWDOC
+$ENDOFNOWDOC;
+
+ENDOFNOWDOC;
+
+$x = <<<'ENDOFNOWDOC'
+ENDOFNOWDOC    ;
+    ENDOFNOWDOC;
+ENDOFNOWDOC    
+    ENDOFNOWDOC
+$ENDOFNOWDOC;
+
+ENDOFNOWDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+ENDOFNOWDOC    ;
+    ENDOFNOWDOC;
+ENDOFNOWDOC    
+    ENDOFNOWDOC
+$ENDOFNOWDOC;
+ENDOFNOWDOC    ;
+    ENDOFNOWDOC;
+ENDOFNOWDOC    
+    ENDOFNOWDOC
+$ENDOFNOWDOC;
+
diff --git a/Zend/tests/nowdoc_010.phpt b/Zend/tests/nowdoc_010.phpt
new file mode 100644 (file)
index 0000000..6f28815
--- /dev/null
@@ -0,0 +1,33 @@
+--TEST--
+Torture the T_END_NOWDOC rules with variable expansions (nowdoc)
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+$fooledYou = '';
+
+print <<<'ENDOFNOWDOC'
+{$fooledYou}ENDOFNOWDOC{$fooledYou}
+ENDOFNOWDOC{$fooledYou}
+{$fooledYou}ENDOFNOWDOC
+
+ENDOFNOWDOC;
+
+$x = <<<'ENDOFNOWDOC'
+{$fooledYou}ENDOFNOWDOC{$fooledYou}
+ENDOFNOWDOC{$fooledYou}
+{$fooledYou}ENDOFNOWDOC
+
+ENDOFNOWDOC;
+
+print "{$x}";
+
+?>
+--EXPECT--
+{$fooledYou}ENDOFNOWDOC{$fooledYou}
+ENDOFNOWDOC{$fooledYou}
+{$fooledYou}ENDOFNOWDOC
+{$fooledYou}ENDOFNOWDOC{$fooledYou}
+ENDOFNOWDOC{$fooledYou}
+{$fooledYou}ENDOFNOWDOC
+
diff --git a/Zend/tests/nowdoc_011.phpt b/Zend/tests/nowdoc_011.phpt
new file mode 100644 (file)
index 0000000..84bcdb6
--- /dev/null
@@ -0,0 +1,20 @@
+--TEST--
+Nowdocs CAN be used as static scalars.
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+class e {
+    
+    const E = <<<'THISMUSTNOTERROR'
+If you DON'T see this, something's wrong.
+THISMUSTNOTERROR;
+
+};
+
+print e::E . "\n";
+
+?>
+--EXPECTF--
+If you DON'T see this, something's wrong.
diff --git a/Zend/tests/nowdoc_012.phpt b/Zend/tests/nowdoc_012.phpt
new file mode 100644 (file)
index 0000000..0bcb92e
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+Test false labels
+--FILE--
+<?php
+
+require_once 'nowdoc.inc';
+
+$x = <<<'ENDOFNOWDOC'
+This is a nowdoc test.
+NOTREALLYEND;
+Another line
+NOTENDEITHER;
+ENDOFNOWDOCWILLBESOON
+Now let's finish it
+ENDOFNOWDOC;
+print "{$x}\n";
+
+?>
+--EXPECT--
+This is a nowdoc test.
+NOTREALLYEND;
+Another line
+NOTENDEITHER;
+ENDOFNOWDOCWILLBESOON
+Now let's finish it
diff --git a/Zend/tests/nowdoc_013.phpt b/Zend/tests/nowdoc_013.phpt
new file mode 100644 (file)
index 0000000..574d3d2
--- /dev/null
@@ -0,0 +1,26 @@
+--TEST--
+Test whitespace following end of nowdoc
+--INI--
+highlight.string  = #DD0000
+highlight.comment = #FF8000
+highlight.keyword = #007700
+highlight.bg      = #FFFFFF
+highlight.default = #0000BB
+highlight.html    = #000000
+--FILE--
+<?php
+$code = <<<'EOF'
+<?php
+  $x = <<<'EOT'
+some string    
+EOT
+  $y = 2;
+?>
+EOF;
+highlight_string($code);
+?>
+--EXPECT--
+<code><span style="color: #000000">
+<span style="color: #0000BB">&lt;?php<br />&nbsp;&nbsp;$x&nbsp;</span><span style="color: #007700">=&nbsp;&lt;&lt;&lt;'EOT'<br /></span><span style="color: #0000BB">some&nbsp;string&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #007700">EOT<br />&nbsp;&nbsp;</span><span style="color: #0000BB">$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span>
+</span>
+</code>
diff --git a/Zend/tests/nowdoc_014.phpt b/Zend/tests/nowdoc_014.phpt
new file mode 100644 (file)
index 0000000..120a96f
--- /dev/null
@@ -0,0 +1,25 @@
+--TEST--
+Highliting empty nowdoc
+--INI--
+highlight.string  = #DD0000
+highlight.comment = #FF8000
+highlight.keyword = #007700
+highlight.bg      = #FFFFFF
+highlight.default = #0000BB
+highlight.html    = #000000
+--FILE--
+<?php
+$code = <<<'EOF'
+<?php
+  $x = <<<'EOT'
+EOT
+  $y = 2;
+?>
+EOF;
+highlight_string($code);
+?>
+--EXPECT--
+<code><span style="color: #000000">
+<span style="color: #0000BB">&lt;?php<br />&nbsp;&nbsp;$x&nbsp;</span><span style="color: #007700">=&nbsp;&lt;&lt;&lt;'EOT'<br /></span><span style="color: #0000BB"></span><span style="color: #007700">EOT<br />&nbsp;&nbsp;</span><span style="color: #0000BB">$y&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span>
+</span>
+</code>
diff --git a/Zend/tests/nowdoc_015.phpt b/Zend/tests/nowdoc_015.phpt
new file mode 100644 (file)
index 0000000..cafa076
--- /dev/null
@@ -0,0 +1,99 @@
+--TEST--
+Test nowdoc and line numbering
+--FILE--
+<?php
+function error_handler($num, $msg, $file, $line, $vars) {
+       echo $line,"\n";
+}
+set_error_handler('error_handler');
+trigger_error("line", E_USER_ERROR);
+$x = <<<EOF
+EOF;
+var_dump($x);
+trigger_error("line", E_USER_ERROR);
+$x = <<<'EOF'
+EOF;
+var_dump($x);
+trigger_error("line", E_USER_ERROR);
+$x = <<<EOF
+test
+EOF;
+var_dump($x);
+trigger_error("line", E_USER_ERROR);
+$x = <<<'EOF'
+test
+EOF;
+var_dump($x);
+trigger_error("line", E_USER_ERROR);
+$x = <<<EOF
+test1
+test2
+
+test3
+
+
+EOF;
+var_dump($x);
+trigger_error("line", E_USER_ERROR);
+$x = <<<'EOF'
+test1
+test2
+
+test3
+
+
+EOF;
+var_dump($x);
+trigger_error("line", E_USER_ERROR);
+echo "ok\n";
+?>
+--EXPECT--
+6
+string(0) ""
+10
+string(0) ""
+14
+string(4) "test"
+19
+string(4) "test"
+24
+string(20) "test1
+test2
+
+test3
+
+"
+34
+string(20) "test1
+test2
+
+test3
+
+"
+44
+ok
+--UEXPECT--
+6
+unicode(0) ""
+10
+unicode(0) ""
+14
+unicode(4) "test"
+19
+unicode(4) "test"
+24
+unicode(20) "test1
+test2
+
+test3
+
+"
+34
+unicode(20) "test1
+test2
+
+test3
+
+"
+44
+ok
index 49145461f1d3785f5f01730ffc6f6455cbcb8da3..625f28dcb8e0026e75602268c367c4a6abb940c7 100644 (file)
@@ -5011,6 +5011,7 @@ again:
                        retval = T_ECHO;
                        break;
                case T_END_HEREDOC:
+               case T_END_NOWDOC:
                        efree(Z_STRVAL(zendlval->u.constant));
                        break;
        }
index 05116098ea8ee9871c1376b256ec140b0bd2e9b1..3a546f291e5a4c0320fe35d418f3dfb34e9b0078 100644 (file)
@@ -134,6 +134,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
                }
                switch (token_type) {
                        case T_END_HEREDOC:
+                       case T_END_NOWDOC:
                                zend_html_puts(Z_STRVAL(token), Z_STRLEN(token) TSRMLS_CC);
                                break;
                        default:
@@ -155,7 +156,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
                                        efree(Z_UNIVAL(token).v);
                                        break;
                        }
-               } else if (token_type == T_END_HEREDOC) {
+               } else if (token_type == T_END_HEREDOC || token_type == T_END_NOWDOC) {
                        efree(Z_UNIVAL(token).v);
                }
                Z_TYPE(token) = 0;
@@ -207,6 +208,7 @@ ZEND_API void zend_strip(TSRMLS_D) /* {{{ */
                                return;
 
                        case T_END_HEREDOC:
+                       case T_END_NOWDOC:
                                zend_write(LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
                                efree(Z_STRVAL(token));
                                /* read the following character, either newline or ; */
index c0a79179245858082ceccd9ac611e8a22a513fc6..959797c2b1cfa3ea2ba406d610b5f412722823e6 100644 (file)
 %token T_NAMESPACE
 %token T_NS_C
 %token T_DIR
+%token T_START_NOWDOC
+%token T_END_NOWDOC
 
 %% /* Rules */
 
@@ -727,6 +729,7 @@ common_scalar:
        |       T_METHOD_C                                      { $$ = $1; }
        |       T_FUNC_C                                        { $$ = $1; }
        |       T_NS_C                                          { $$ = $1; }
+       |       T_START_NOWDOC T_ENCAPSED_AND_WHITESPACE T_END_NOWDOC   { $$ = $2; }
 ;
 
 
index 12b152740a9b7326e250cb427fbbda8e24058955..179127a4959fdd0334667b8988ae3a96f016e0e4 100644 (file)
@@ -39,6 +39,9 @@
 %x ST_HEREDOC
 %x ST_START_HEREDOC
 %x ST_END_HEREDOC
+%x ST_NOWDOC
+%x ST_START_NOWDOC
+%x ST_END_NOWDOC
 %x ST_LOOKING_FOR_PROPERTY
 %x ST_LOOKING_FOR_VARNAME
 %x ST_VAR_OFFSET
@@ -1411,6 +1414,8 @@ DOUBLE_QUOTES_CHARS ("{"*([^$"\\{]|("\\"{ANY_CHAR}))|{DOUBLE_QUOTES_LITERAL_DOLL
 BACKQUOTE_CHARS     ("{"*([^$`\\{]|("\\"{ANY_CHAR}))|{BACKQUOTE_LITERAL_DOLLAR})
 HEREDOC_CHARS       ("{"*([^$\n\r\\{]|("\\"[^\n\r]))|{HEREDOC_LITERAL_DOLLAR}|({HEREDOC_NEWLINE}+({HEREDOC_NON_LABEL}|{HEREDOC_LABEL_NO_NEWLINE})))
 
+NOWDOC_CHARS           ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_\x7f-\xff;\n\r][^\n\r]*)|({LABEL}[;][^\n\r]+)))
+
 %option noyylineno
 %option noyywrap
 %%
@@ -2589,6 +2594,109 @@ HEREDOC_CHARS       ("{"*([^$\n\r\\{]|("\\"[^\n\r]))|{HEREDOC_LITERAL_DOLLAR}|({
 }
 
 
+%{
+/* BEGIN nowdoc */
+%}
+<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}[']{LABEL}[']{NEWLINE} {
+       int bprefix = (yytext[0] != '<') ? 1 : 0;
+       char *s;
+       CG(zend_lineno)++;
+       /* 3 is <<<, 2 is quotes, 1 is newline */
+       CG(heredoc_len) = yyleng-bprefix-3-2-1-(yytext[yyleng-2]=='\r'?1:0);
+       s = yytext+bprefix+3;
+       while ((*s == ' ') || (*s == '\t')) {
+               s++;
+               CG(heredoc_len)--;
+       }
+       s++; /* first quote */
+       CG(heredoc) = estrndup(s, CG(heredoc_len));
+
+       CG(literal_type) = bprefix?IS_STRING:ZEND_STR_TYPE;
+       BEGIN(ST_START_NOWDOC);
+       return T_START_NOWDOC;
+}
+
+<ST_START_NOWDOC>{ANY_CHAR} {
+       yyless(0);
+       BEGIN(ST_NOWDOC);
+}
+
+<ST_START_NOWDOC>{LABEL}";"?[\r\n] {
+       int label_len = yyleng - 1;
+
+       if (yytext[label_len-1]==';') {
+               label_len--;
+       }
+
+       if (label_len==CG(heredoc_len) && !memcmp(yytext, CG(heredoc), label_len)) {
+               yyless(label_len-1);
+               yyleng = 0;
+               BEGIN(ST_END_NOWDOC);
+               if (CG(literal_type) == IS_UNICODE) {
+                       ZVAL_EMPTY_UNICODE(zendlval);
+               } else {
+                       ZVAL_EMPTY_STRING(zendlval);
+               }
+               return T_ENCAPSED_AND_WHITESPACE;
+       } else {
+               yyless(label_len);
+               yymore();
+               BEGIN(ST_NOWDOC);
+       }
+}
+
+<ST_NOWDOC>{NOWDOC_CHARS}*{NEWLINE}+{LABEL}";"?[\n\r] {
+       char *end = yytext + yyleng - 1;
+
+       if (end[-1] == ';') {
+               end--;
+               yyleng--;
+       }
+
+       if (yyleng > CG(heredoc_len) && !memcmp(end - CG(heredoc_len), CG(heredoc), CG(heredoc_len))) {
+               int len = yyleng - CG(heredoc_len) - 2; /* 2 for newline before and after label */
+
+               if (len > 0 && yytext[len - 1] == '\r' && yytext[len] == '\n') {
+                       len--;
+               }
+
+               /* Go back before last label char, to match in ST_END_HEREDOC state */
+               yyless(yyleng - 2);
+
+               /* Subtract the remaining label length. yyleng must include newline
+                * before label, for zend_highlight/strip, tokenizer, etc. */
+               yyleng -= CG(heredoc_len) - 1;
+
+               CG(increment_lineno) = 1; /* For newline before label */
+               BEGIN(ST_END_NOWDOC);
+
+               HANDLE_NEWLINES(yytext, len);
+               if (!zend_copy_scanner_string(zendlval, yytext, len, CG(literal_type), SCNG(output_conv) TSRMLS_CC)) {
+                       return 0;
+               }
+               return T_ENCAPSED_AND_WHITESPACE;
+       } else {
+               /* Go back to end of label, so the next match works correctly in case of
+                * a variable or another label at the beginning of the next line */
+               yyless(yyleng - 1);
+               yymore();
+       }
+}
+
+<ST_END_NOWDOC>{ANY_CHAR} {
+       Z_STRVAL_P(zendlval) = CG(heredoc);
+       Z_STRLEN_P(zendlval) = CG(heredoc_len);
+       yytext = CG(heredoc);
+       yyleng = CG(heredoc_len);
+       CG(heredoc) = NULL;
+       CG(heredoc_len) = 0;
+       BEGIN(ST_IN_SCRIPTING);
+       return T_END_NOWDOC;
+}
+%{
+/* END nowdoc */
+%}
+
 <ST_DOUBLE_QUOTES>["] {
        BEGIN(ST_IN_SCRIPTING);
        return '"';
index 22aec51fb914fc1b80fddb65a6a79e645ed2fb94..082619b275508f5ed20713f74358dbe181f996be 100644 (file)
@@ -180,7 +180,7 @@ static void tokenize(zval *return_value TSRMLS_DC)
                        MAKE_STD_ZVAL(keyword);
                        array_init(keyword);
                        add_next_index_long(keyword, token_type);
-                       if (token_type == T_END_HEREDOC) {
+                       if (token_type == T_END_HEREDOC || token_type == T_END_NOWDOC) {
                                if (CG(increment_lineno)) {
                                        token_line = ++CG(zend_lineno);
                                        CG(increment_lineno) = 0;