--- /dev/null
+<?php\r
+\r
+/**\r
+ * Parser Exception\r
+ *\r
+ * @package Less\r
+ * @subpackage exception\r
+ */\r
+class Less_Exception_Parser extends Exception{\r
+\r
+ /**\r
+ * The current file\r
+ *\r
+ * @var Less_ImportedFile\r
+ */\r
+ public $currentFile;\r
+\r
+ /**\r
+ * The current parser index\r
+ *\r
+ * @var integer\r
+ */\r
+ public $index;\r
+\r
+ protected $input;\r
+\r
+ protected $details = array();\r
+\r
+\r
+ /**\r
+ * Constructor\r
+ *\r
+ * @param string $message\r
+ * @param Exception $previous Previous exception\r
+ * @param integer $index The current parser index\r
+ * @param Less_FileInfo|string $currentFile The file\r
+ * @param integer $code The exception code\r
+ */\r
+ public function __construct($message = null, Exception $previous = null, $index = null, $currentFile = null, $code = 0){\r
+\r
+ if (PHP_VERSION_ID < 50300) {\r
+ $this->previous = $previous;\r
+ parent::__construct($message, $code);\r
+ } else {\r
+ parent::__construct($message, $code, $previous);\r
+ }\r
+\r
+ $this->currentFile = $currentFile;\r
+ $this->index = $index;\r
+\r
+ $this->genMessage();\r
+ }\r
+\r
+\r
+ protected function getInput(){\r
+\r
+ if( !$this->input && $this->currentFile && $this->currentFile['filename'] && file_exists($this->currentFile['filename']) ){\r
+ $this->input = file_get_contents( $this->currentFile['filename'] );\r
+ }\r
+ }\r
+\r
+\r
+\r
+ /**\r
+ * Converts the exception to string\r
+ *\r
+ * @return string\r
+ */\r
+ public function genMessage(){\r
+\r
+ if( $this->currentFile && $this->currentFile['filename'] ){\r
+ $this->message .= ' in '.basename($this->currentFile['filename']);\r
+ }\r
+\r
+ if( $this->index !== null ){\r
+ $this->getInput();\r
+ if( $this->input ){\r
+ $line = self::getLineNumber();\r
+ $this->message .= ' on line '.$line.', column '.self::getColumn();\r
+\r
+ $lines = explode("\n",$this->input);\r
+\r
+ $count = count($lines);\r
+ $start_line = max(0, $line-3);\r
+ $last_line = min($count, $start_line+6);\r
+ $num_len = strlen($last_line);\r
+ for( $i = $start_line; $i < $last_line; $i++ ){\r
+ $this->message .= "\n".str_pad($i+1,$num_len,'0',STR_PAD_LEFT).'| '.$lines[$i];\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Returns the line number the error was encountered\r
+ *\r
+ * @return integer\r
+ */\r
+ public function getLineNumber(){\r
+ if( $this->index ){\r
+ // https://bugs.php.net/bug.php?id=49790\r
+ if (ini_get("mbstring.func_overload")) {\r
+ return substr_count(substr($this->input, 0, $this->index), "\n") + 1;\r
+ } else {\r
+ return substr_count($this->input, "\n", 0, $this->index) + 1;\r
+ }\r
+ }\r
+ return 1;\r
+ }\r
+\r
+\r
+ /**\r
+ * Returns the column the error was encountered\r
+ *\r
+ * @return integer\r
+ */\r
+ public function getColumn(){\r
+\r
+ $part = substr($this->input, 0, $this->index);\r
+ $pos = strrpos($part,"\n");\r
+ return $this->index - $pos;\r
+ }\r
+\r
+}\r