* Get the correct column number in parsing exceptions
authorRobert Sesek <rsesek@bluestatic.org>
Tue, 26 Jul 2011 13:05:10 +0000 (09:05 -0400)
committerRobert Sesek <rsesek@bluestatic.org>
Tue, 26 Jul 2011 13:11:37 +0000 (09:11 -0400)
* Throw an exception when nesting two macros

testing/tests/views/template_test.php
views/template.php

index 0a64e186afb8599e6a4b05583ae6179ff4541824..62e684693a5091ed7c72ab5fcae18cdb5748262e 100644 (file)
@@ -45,7 +45,7 @@ class TemplateTest extends \PHPUnit_Framework_TestCase
 
   public function testRender2Vars()
   {
-    $template = Template::NewWithData('Hello, {% $name %}. Today is the {% $date->day %} of July.');
+    $template = Template::NewWithData('Hello, {% $name %}. Today is the {% $date->day | int %} of July.');
     $date = new \stdClass();
     $date->day = 26;
     $template->name = 'Robert';
@@ -65,4 +65,38 @@ class TemplateTest extends \PHPUnit_Framework_TestCase
     $template->user->logged_in = FALSE;
     $this->assertEquals('You are not logged in', $this->_Render($template));
   }
+
+  public function testExceptions()
+  {
+    try {
+      $catch = FALSE;
+      $template = Template::NewWithData('Hello %}');
+    } catch (\hoplite\views\TemplateException $e) {
+      $message = $e->GetMessage();
+      // Check that the column number is correct.
+      $this->assertTrue(strpos($message, '1:6') !== FALSE);
+      $catch = TRUE;
+    }
+    $this->assertTrue($catch);
+
+    try {
+      $catch = FALSE;
+      $template = Template::NewWithData("Salve\n{% {%");
+    } catch (\hoplite\views\TemplateException $e) {
+      $message = $e->GetMessage();
+      $this->assertTrue(strpos($message, '2:4') !== FALSE);
+      $catch = TRUE;
+    }
+    $this->assertTrue($catch);
+
+    try {
+      $catch = FALSE;
+      $template = Template::NewWithData("Salve\n\n{% \$name {!%");
+    } catch (\hoplite\views\TemplateException $e) {
+      $message = $e->GetMessage();
+      $this->assertTrue(strpos($message, '3:10') !== FALSE);
+      $catch = TRUE;
+    }
+    $this->assertTrue($catch);
+  }
 }
index f9cb5e60bd13fff6ecb19114360b312fb3b19899..ede5723de8007347d1322c8a3ebb5638a257a029 100644 (file)
@@ -119,7 +119,7 @@ class Template
     $i = 0;  // The current position of the iterator.
     $looking_for_end = FALSE;  // Whehter or not an end tag is expected.
     $line_number = 1;  // The current line number.
-    $column_number = 0;  // The current column number.
+    $i_last_line = 0;  // The value of |i| at the previous new line, used for column numbering.
 
     while ($i < $length) {
       // See how far the current position is from the end of the string.
@@ -128,14 +128,16 @@ class Template
       // When a new line is reached, update the counters.
       if ($data[$i] == "\n") {
         ++$line_number;
-        $column_number = 0;
+        $i_last_line = $i;
       }
 
       // Check for simple PHP short-tag expansion.
       if ($delta >= 3 && substr($data, $i, 3) == '{!%') {
         // If an expansion has already been opened, then it's an error to nest.
-        if ($looking_for_end)
-          throw new TemplateException("Unexpected start of expansion at line $line_number:$column_number");
+        if ($looking_for_end) {
+          $column = $i - $i_last_line;
+          throw new TemplateException("Unexpected start of expansion at line $line_number:$column");
+        }
 
         $looking_for_end = TRUE;
         $processed .= '<' . '?php';
@@ -148,8 +150,10 @@ class Template
         // Check for an end tag.
         if ($substr == '%}') {
           // If an end tag was encountered without an open tag, that's an error.
-          if (!$looking_for_end)
-            throw new TemplateException("Unexpected end of expansion at line $line_number:$column_number");
+          if (!$looking_for_end) {
+            $column = $i - $i_last_line;
+            throw new TemplateException("Unexpected end of expansion at line $line_number:$column");
+          }
 
           // If this is a macro, it's time to process it.
           if ($in_macro)
@@ -163,6 +167,12 @@ class Template
         }
         // Check for the beginning of a macro.
         else if ($substr == '{%') {
+          // If an expansion has already been opened, then it's an error to nest.
+          if ($looking_for_end) {
+            $column = $i - $i_last_line;
+            throw new TemplateException("Unexpected start of expansion at line $line_number:$column");
+          }
+
           $processed .= '<' . '?php echo ';
           $macro = '';
           $in_macro = TRUE;