More refactoring. This time breaking up svnlib.php
authorRobert Sesek <rsesek@bluestatic.org>
Fri, 13 Jan 2006 05:02:56 +0000 (05:02 +0000)
committerRobert Sesek <rsesek@bluestatic.org>
Fri, 13 Jan 2006 05:02:56 +0000 (05:02 +0000)
includes/svncommon.php [new file with mode: 0644]
includes/svnlib.php

diff --git a/includes/svncommon.php b/includes/svncommon.php
new file mode 100644 (file)
index 0000000..7ce63a0
--- /dev/null
@@ -0,0 +1,955 @@
+<?php
+/*=====================================================================*\
+|| ###################################################################
+|| # ViewSVN [#]version[#]
+|| # Copyright ©2002-[#]year[#] Iris Studios, Inc.
+|| #
+|| # This program is free software; you can redistribute it and/or modify
+|| # it under the terms of the GNU General Public License as published by
+|| # the Free Software Foundation; version [#]gpl[#] of the License.
+|| #
+|| # This program is distributed in the hope that it will be useful, but
+|| # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+|| # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+|| # more details.
+|| #
+|| # You should have received a copy of the GNU General Public License along
+|| # with this program; if not, write to the Free Software Foundation, Inc.,
+|| # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+|| ###################################################################
+\*=====================================================================*/
+
+/**
+* Common functions that aren't Xquery-related and advanced query systems
+*
+* @package     ViewSVN
+*/
+
+/**
+* Interacts with the command line subsystem to
+* access SVN information
+*
+* @package     ViewSVN
+* @version     $Id$
+*/
+class SVNLib
+{
+       /**
+       * Path to the SVN binary
+       * @var  string
+       */
+       var $svnpath;
+       
+       /**
+       * Common command system
+       * @var  object
+       */
+       var $common;
+       
+       /**
+       * Constructor: validate SVN path
+       *
+       * @param        string  Path to SVN binary
+       */
+       function SVNLib($svnpath)
+       {
+               global $viewsvn;
+               
+               $this->svnpath = $viewsvn->shell->cmd($svnpath);
+               
+               $this->common =& new SVNCommon();
+               
+               $access = $viewsvn->shell->exec($this->svnpath . ' --version');
+               
+               if (!$access)
+               {
+                       $viewsvn->trigger->error($viewsvn->lang->string('The SVN binary could not be located'));
+               }
+               
+               if (!preg_match('#^svn, version (.*?)\)$#i', trim($access[0])))
+               {
+                       $viewsvn->trigger->error($viewsvn->lang->string('The SVN binary does not appear to be valid (it failed our tests)'));
+               }
+       }
+       
+       /**
+       * Prepares data for output
+       *
+       * @access       public
+       *
+       * @param        string  Standard data
+       *
+       * @return       string  Output-ready data
+       */
+       function format($string)
+       {
+               // convert entities
+               $string = htmlspecialchars($string);
+               
+               // tabs to 5 spaces
+               $string = str_replace("\t", '     ', $string);
+               
+               // spaces to nbsp
+               if (true)
+               {
+                       $string = preg_replace('#( +)#e', '$this->format_spaces("\1")', $string);
+               }
+               // no word wrap
+               else
+               {
+                       $string = str_replace(' ', '&nbsp;', $string);
+               }
+               
+               // convert advanced diff
+               $string = str_replace(array('{@+' . '+}', '{@-' . '-}'), array('<span class="diff_add_bit">', '<span class="diff_del_bit">'), $string);
+               $string = str_replace(array('{/@+' . '+}', '{/@-' . '-}'), '</span>', $string);
+               
+               // nl2br
+               $string = nl2br($string);
+               
+               return $string;
+       }
+       
+       /**
+       * Formats a SVN log message
+       *
+       * @access       public
+       *
+       * @param        string  Unformatted log message
+       *
+       * @return       string  Output-ready log message
+       */
+       function format_log_message($message)
+       {
+               global $viewsvn;
+               
+               $message = $viewsvn->entity_encode($message);
+               
+               $message = preg_replace('#r([0-9]+)#e', '"<a href=\"" . $viewsvn->path . "/" . $viewsvn->paths->out("diff.php" . $viewsvn->paths->fetch_rev_str(true, "\1", 0), $viewsvn->paths->fetch_repos($viewsvn->paths->parse()) . "/") . "\">r\1</a>"', $message);
+               
+               $list = false;
+               $lines = explode("\n", $message);
+               $message = '';
+               foreach ($lines AS $line)
+               {
+                       if (preg_match('#^\s*?(\*|\-)\s?(.*)#', $line, $matches))
+                       {
+                               if ($list)
+                               {
+                                       $message .= '<li>' . $matches[2] . '</li>';
+                               }
+                               else
+                               {
+                                       $message .= '<ul class="list">';
+                                       $message .= '<li>' . $matches[2] . '</li>';
+                               }
+                               $list = true;
+                       }
+                       else
+                       {
+                               if ($list)
+                               {
+                                       $message .= '</ul>';
+                                       $message .= $line;
+                               }
+                               else
+                               {
+                                       $message .= $line;
+                                       $message .= '<br />';
+                               }
+                               $list = false;
+                       }
+                       
+                       $message .= "\n";
+               }
+               
+               if ($list)
+               {
+                       $message .= '</ul>';
+               }
+               
+               $message = preg_replace('#(<br />)*$#', '', $message);
+               
+               return $message;
+       }
+       
+       // ###################################################################
+       /**
+       * Parses a date from Xquery XML outut
+       *
+       * @access       public
+       *
+       * @param        string  Date string
+       *
+       * @return       string  Formatted and readable date string
+       */
+       function format_date_string($string)
+       {
+               // 2005-01-23T20:42:53.703057Z
+               return preg_replace('#(....)\-(..)\-(..)T(..):(..):(..).(.*)Z#e', 'gmdate("r", mktime(\4, \5, \6, \2, \3, \1))', $string);
+       }
+       
+       /**
+       * Counts the spaces and replaces two or more ones
+       *
+       * @access       private
+       *
+       * @param        string  Spaced string
+       *
+       * @return       string  &nbsp;'d string
+       */
+       function format_spaces($thestring)
+       {
+               if (strlen($thestring) >= 2)
+               {
+                       $thestring = str_replace(' ', '&nbsp;', $thestring);
+               }
+               
+               return $thestring;
+       }
+}
+
+/**
+* Commonly executed SVN commands that return data
+* used in many parts of the system
+*
+* @package     ViewSVN
+* @version     $Id$
+*/
+class SVNCommon
+{
+       /**
+       * Registry object
+       * @var  object
+       */
+       var $registry;
+       
+       /**
+       * List of revisions
+       * @var  array
+       */
+       var $revisions;
+       
+       /**
+       * List of logs
+       * @var  array
+       */
+       var $logs;
+       
+       /**
+       * Constructor: bind with registry
+       */
+       function SVNCommon()
+       {
+               global $viewsvn;
+               
+               $this->registry =& $viewsvn;
+       }
+       
+       /**
+       * Checks to see if the given universal path is
+       * a directory
+       *
+       * @access       public
+       *
+       * @param        string  Universal path
+       *
+       * @return       bool    Directory or not
+       */
+       function isdir($path)
+       {
+               $output = $this->registry->svn->std('info', $this->registry->paths->fetch_repos($path), $this->registry->paths->fetch_path($path), $this->registry->paths->revnum);
+               
+               foreach ($output AS $line)
+               {
+                       if (preg_match('#^Node Kind: (.*)#', $line, $matches))
+                       {
+                               if (trim(strtolower($matches[1])) == 'directory')
+                               {
+                                       return true;
+                               }
+                       }
+               }
+               
+               return false;
+       }
+       
+       /**
+       * Get a list of revisions for a path
+       *
+       * @access       public
+       *
+       * @param        string  Universal path
+       *
+       * @return       array   Key revisions
+       */
+       function fetch_revs($path)
+       {
+               if (!isset($this->revisions["$path"]))
+               {
+                       $log = $this->fetch_logs($path);
+                       
+                       $revs = array_keys($log);
+                       
+                       $this->revisions["$path"] = array(
+                               'HEAD'  => $revs[0],
+                               'START' => $revs[ count($revs) - 1 ],
+                               'revs'  => $revs
+                       );
+               }
+               
+               return $this->revisions["$path"];
+       }
+       
+       /**
+       * Gets the revision that is marked as HEAD
+       *
+       * @access       public
+       *
+       * @param        string  Universal path
+       *
+       * @return       integer Revision
+       */
+       function fetch_head_rev($path)
+       {
+               $output = $this->registry->shell->exec($this->registry->svn->svnpath . ' info ' . $this->registry->repos->fetch_path($this->registry->paths->fetch_repos($path), false) . $this->registry->paths->fetch_path($path));
+               
+               foreach ($output AS $line)
+               {
+                       if (preg_match('#^Last Changed Rev: (.*)#', $line, $matches))
+                       {
+                               return $matches[1];
+                       }
+               }
+               
+               $revs = $this->fetch_revs($path);
+               return $revs['HEAD'];
+       }
+       
+       /**
+       * Returns the previous revision to the one given
+       *
+       * @access       public
+       *
+       * @param        string  Universal path
+       * @param        integer Arbitrary revision
+       *
+       * @return       integer Previous revision (-1 if none)
+       */
+       function fetch_prev_rev($path, $current)
+       {
+               global $viewsvn;
+               
+               $revs = $this->fetch_revs($path);
+               
+               if ($current == 'HEAD')
+               {
+                       $current = $this->fetch_head_rev($path);
+               }
+               
+               $index = array_search($current, $revs['revs']);
+               if ($current === false)
+               {
+                       $message->trigger->error(sprintf($viewsvn->lang->string('Revision r%1$s is not in path %2$s'), $current, $path));
+               }
+               
+               if (isset($revs['revs'][ $index + 1 ]))
+               {
+                       return $revs['revs'][ $index + 1 ];
+               }
+               else
+               {
+                       return -1;
+               }
+       }
+       
+       /**
+       * Get a list of logs
+       *
+       * @access       public
+       *
+       * @param        string  Universal path
+       * @param        bool    Override the cache system?
+       *
+       * @return       array   Log data
+       */
+       function fetch_logs($path)
+       {
+               if (!isset($this->logs["$path"]))
+               {
+                       $log = new SVNLog($this->registry->paths->fetch_repos($path), $this->registry->paths->fetch_path($path), 0, $this->registry->paths->revnum);
+                       
+                       $this->logs["$path"] = $log->fetch();
+               }
+               
+               return $this->logs["$path"];
+       }
+       
+       /**
+       * Returns a given log entry for a path
+       * and revision
+       *
+       * @access       public
+       *
+       * @param        string  Universal path
+       * @param        integer Arbitrary revision
+       *
+       * @return       array   Log entry
+       */
+       function fetch_log($path, $rev)
+       {
+               $logs = $this->fetch_logs($path);
+               
+               $rev = $this->registry->svn->rev($rev);
+               if ($rev == 'HEAD')
+               {
+                       $rev = $this->fetch_head_rev($path);
+               }
+               
+               if (isset($logs["$rev"]))
+               {
+                       return $logs["$rev"];
+               }
+               else
+               {
+                       $keys = array_keys($logs);
+                       sort($keys);
+
+                       for ($i = 0; $i < count($keys); $i++)
+                       {
+                               if ($rev > $keys["$i"] AND $rev < $keys[ $i + 1 ])
+                               {
+                                       return $logs["$keys[$i]"];
+                               }
+                       }
+                       
+                       return null;
+               }
+       }
+       
+       /**
+       * Prints the file changed list
+       *
+       * @access       public
+       *
+       * @public       array   List of file changes
+       * @public       string  The repository
+       * @public       integer Current revision
+       *
+       * @return       string  Processed HTML
+       */
+       function construct_file_changes($changes, $repos, $revision)
+       {
+               global $viewsvn;
+               
+               $files = '';
+               
+               foreach ($changes AS $file)
+               {
+                       switch ($file['action'])
+                       {
+                               case 'A':
+                                       $class = 'file_add';
+                                       $tooltip = $viewsvn->lang->string('Added');
+                                       break;
+                               case 'D':
+                                       $class = 'file_delete';
+                                       $tooltip = $viewsvn->lang->string('Deleted');
+                                       break;
+                               case 'M':
+                                       $class = 'file_modify';
+                                       $tooltip = $viewsvn->lang->string('Modified');
+                                       break;
+                               case 'R':
+                                       $class = 'file_replace';
+                                       $tooltip = $viewsvn->lang->string('Replaced');
+                                       break;
+                       }
+                       
+                       $show['from'] = (bool)$file['from'];
+                       
+                       if ($file['from'])
+                       {
+                               $class = 'file_move';
+                               $tooltip = 'Moved/Copied';
+                               preg_match('#(.*):([0-9]+)#', $file['from'], $matches);
+                               $link['from'] = $viewsvn->paths->out('view.php' . $viewsvn->paths->fetch_rev_str(false, $matches[2]), $repos . $matches[1]);
+                       }
+                       
+                       $link['file'] = $viewsvn->paths->out('view.php' . $viewsvn->paths->fetch_rev_str(false, $revision), $repos . $file['file']);
+                       
+                       eval('$files .= "' . $viewsvn->template->fetch('file_change') . '";');
+               }
+               
+               return $files;
+       }
+}
+
+/**
+* Annotation/blame system; constructs an array
+* that is ready for output
+*
+* @package     ViewSVN
+* @version     $Id$
+*/
+class SVNBlame
+{
+       /**
+       * Array of blame information
+       * @var  array
+       */
+       var $blame = array();
+       
+       /**
+       * Raw "svn blame" output
+       * @var  array
+       */
+       var $rawoutput;
+       
+       /**
+       * Constructor: create blame and store data
+       *
+       * @param        string  Repository
+       * @param        string  Path
+       * @param        integer Revision
+       */
+       function SVNBlame($repos, $path, $revision)
+       {
+               global $viewsvn;
+               
+               $this->rawoutput = $viewsvn->svn->blame($repos, $path, $revision);
+               $this->process();
+       }
+       
+       /**
+       * Returns blame for display
+       *
+       * @access       public
+       *
+       * @return       array   Blame data
+       */
+       function fetch()
+       {
+               return $this->blame;
+       }
+       
+       /**
+       * Parses the blame data
+       *
+       * @access       private
+       */
+       function process()
+       {
+               $lineno = 1;
+               
+               foreach ($this->rawoutput AS $line)
+               {
+                       if (preg_match('#^\s+([0-9]+)\s+([\w\.\-_]+)\s(.*)$#', $line, $matches))
+                       {
+                               $this->blame[] = array(
+                                       'rev'           => $matches[1],
+                                       'author'        => $matches[2],
+                                       'line'          => $matches[3],
+                                       'lineno'        => $lineno++
+                               );
+                       }
+                       // a blank line
+                       else if (preg_match('#^\s+([0-9]+)\s+([\w\.\-_]+)$#', $line, $matches))
+                       {
+                               $this->blame[] = array(
+                                       'rev'           => $matches[1],
+                                       'author'        => $matches[2],
+                                       'line'          => '',
+                                       'lineno'        => $lineno++
+                               );
+                       }
+               }
+       }
+}
+
+/**
+* Log management system; creates a complex list
+* of SVN log information
+*
+* @package     ViewSVN
+* @version     $Id$
+*/
+class SVNLog
+{
+       /**
+       * Array of logs
+       * @var  array
+       */
+       var $logs = array();
+       
+       /**
+       * Raw "svn log" output
+       * @var  array
+       */
+       var $rawoutput;
+       
+       /**
+       * Constructor: create log store for the given file
+       *
+       * @param        string  Repository
+       * @param        string  Path
+       * @param        integer Lower revision
+       * @param        integer Higher revision
+       */
+       function SVNLog($repos, $path, $lorev, $hirev)
+       {
+               global $viewsvn;
+               
+               $this->rawoutput = $viewsvn->svn->log($repos, $path, $lorev, $hirev);
+               $this->process();
+       }
+       
+       /**
+       * Returns logs for display
+       *
+       * @access       public
+       *
+       * @return       array   Log data
+       */
+       function fetch()
+       {
+               return $this->logs;
+       }
+       
+       /**
+       * Splits up the raw output into a usable log
+       *
+       * @access       private
+       */
+       function process()
+       {
+               $lastrev = 0;
+               
+               for ($i = 1; $i <= count($this->rawoutput) - 1; $i++)
+               {
+                       $line = $this->rawoutput["$i"];
+                       
+                       if (preg_match('#^r([0-9]*) \| (.*?) \| (....-..-.. ..:..:..) ([0-9\-]*) \((.*?)\) \| ([0-9]*) lines?$#', $line, $matches))
+                       {
+                               if (isset($this->logs["$lastrev"]))
+                               {
+                                       $this->logs["$lastrev"]['message'] = $this->strip_last_line($this->logs["$lastrev"]['message']);
+                               }
+                               
+                               $this->logs["$matches[1]"] = array(
+                                       'rev'           => $matches[1],
+                                       'author'        => $matches[2],
+                                       'date'          => $matches[3],
+                                       'timezone'      => $matches[4],
+                                       'lines'         => $matches[6],
+                                       'message'       => ''
+                               );
+                               
+                               $lastrev = $matches[1];
+                       }
+                       else if (preg_match('#^\s+([ADMR])\s(.*)#', $line, $matches))
+                       {
+                               if (preg_match('#(.*) \(from (.*?)\)$#', $matches[2], $amatches))
+                               {
+                                       $matches[2] = $amatches[1];
+                               }
+                               
+                               $this->logs["$lastrev"]['files'][] = array(
+                                       'action'        => $matches[1],
+                                       'file'          => trim($matches[2]),
+                                       'from'          => (isset($amatches[2]) ? $amatches[2] : '')
+                               );
+                       }
+                       else
+                       {
+                               if (trim($line) != 'Changed paths:')
+                               {
+                                       $this->logs["$lastrev"]['message'] .= $line . "\n";
+                               }
+                       }
+               }
+               
+               if (isset($this->logs["$lastrev"]))
+               {
+                       $this->logs["$lastrev"]['message'] = $this->strip_last_line($this->logs["$lastrev"]['message']);
+               }
+       }
+       
+       /**
+       * Trims the last dash line off a message
+       *
+       * @access       private
+       *
+       * @param        string  Message with annoying-ass line
+       *
+       * @return       string  Clean string
+       */
+       function strip_last_line($string)
+       {
+               return trim(preg_replace("#\n(.*?)\n$#", '', $string));
+       }
+}
+
+/**
+* Diff system; constructs a diff array that
+* is ready for output
+*
+* @package     ViewSVN
+*/
+class SVNDiff
+{
+       /**
+       * Array of diff information
+       * @var  array
+       */
+       var $diff = array();
+       
+       /**
+       * Raw "svn diff" output
+       * @var  array
+       */
+       var $rawoutput;
+       
+       /**
+       * Constructor: create and store diff data
+       *
+       * @param        string  Repository
+       * @param        string  Path
+       * @param        integer Lower revision
+       * @param        integer Higher revision
+       */
+       function SVNDiff($repos, $path, $lorev, $hirev)
+       {
+               global $viewsvn;
+               
+               $this->rawoutput = $viewsvn->svn->diff($repos, $path, $lorev, $hirev);
+               $this->process();
+       }
+       
+       /**
+       * Returns diffs for display
+       *
+       * @access       public
+       *
+       * @return       array   Diff data
+       */
+       function fetch()
+       {
+               return $this->diff;
+       }
+       
+       /**
+       * Processes and prepares diff data
+       *
+       * @access       private
+       */
+       function process()
+       {
+               global $viewsvn;
+               
+               $chunk = 0;
+               $indexcounter = null;
+               $curprop = '';
+               
+               $delstack = array();
+               
+               foreach ($this->rawoutput AS $line)
+               {
+                       if (preg_match('#^@@ \-([0-9]*),([0-9]*) \+([0-9]*),([0-9]*) @@$#', $line, $bits))
+                       {
+                               $property = false;
+                               $delstack = array();
+                               $this->diff["$index"][ ++$chunk ]['hunk'] = array('old' => array('line' => $bits[1], 'count' => $bits[2]), 'new' => array('line' => $bits[3], 'count' => $bits[4]));
+                               $lines['old'] = $this->diff["$index"]["$chunk"]['hunk']['old']['line'] - 1;
+                               $lines['new'] = $this->diff["$index"]["$chunk"]['hunk']['new']['line'] - 1;
+                               continue;
+                       }
+                       else if (preg_match('#^Property changes on: (.*?)$#', $line, $bits))
+                       {
+                               $property = true;
+                               $index = $bits[1];
+                               $this->diff["$index"]['props'] = array();
+                               continue;
+                       }
+                       
+                       if ($indexcounter <= 3 AND $indexcounter !== null)
+                       {
+                               $indexcounter++;
+                               continue;
+                       }
+                       else if ($indexcounter == 3)
+                       {
+                               $indexcounter = null;
+                               continue;
+                       }
+                       
+                       if (preg_match('#^([\+\- ])(.*)#', $line, $matches) AND !$property)
+                       {
+                               $act = $matches[1];
+                               $content = $matches[2];
+                               
+                               if ($act == ' ')
+                               {
+                                       $this->diff["$index"]["$chunk"][] = array(
+                                               'line'          => $content,
+                                               'act'           => '',
+                                               'oldlineno'     => ++$lines['old'],
+                                               'newlineno'     => ++$lines['new']
+                                       );
+                                       
+                                       $delstack = array();
+                               }
+                               else if ($act == '+')
+                               {               
+                                       // potential line delta
+                                       if (count($delstack) > 0)
+                                       {
+                                               $lastline = array_shift($delstack);
+                                               
+                                               if ($delta = @$this->fetch_diff_extent($lastline['line'], $content))
+                                               {
+                                                       if (strlen($lastline['line']) > ($delta['start'] - $delta['end']))
+                                                       {
+                                                               $end = strlen($lastline['line']) + $delta['end'];
+                                                               $viewsvn->debug("RM delta- = " . $end);
+                                                               $change = '{@-' . '-}' . substr($lastline['line'], $delta['start'], $end - $delta['start']) . '{/@-' . '-}';
+                                                               $this->diff["$index"]["$chunk"]["$lastline[INDEX]"]['line'] = substr($lastline['line'], 0, $delta['start']) . $change . substr($lastline['line'], $end);
+                                                       }
+                                                       
+                                                       if (strlen($content) > $delta['start'] - $delta['end'])
+                                                       {
+                                                               $end = strlen($content) + $delta['end'];
+                                                               $viewsvn->debug("MK delta+ = " . $end);
+                                                               $change = '{@+' . '+}' . substr($content, $delta['start'], $end - $delta['start']) . '{/@+' . '+}';
+                                                               $content = substr($content, 0, $delta['start']) . $change . substr($content, $end);
+                                                       }
+                                               }
+                                       }
+                                       
+                                       $this->diff["$index"]["$chunk"][] = array(
+                                               'line'          => $content,
+                                               'act'           => '+',
+                                               'oldlineno'     => '',
+                                               'newlineno'     => ++$lines['new']
+                                       );
+                               }
+                               else if ($act == '-')
+                               {
+                                       $this->diff["$index"]["$chunk"][] = $thearray = array(
+                                               'line'          => $content,
+                                               'act'           => '-',
+                                               'oldlineno'     => ++$lines['old'],
+                                               'newlineno'     => ''
+                                       );
+                                       
+                                       $key = count($this->diff["$index"]["$chunk"]) - 2;
+                                       $thearray['INDEX'] = $key;
+                                       
+                                       array_push($delstack, $thearray);
+                               }
+                       }
+                       // whitespace lines
+                       else
+                       {
+                               if (preg_match('#^Index: (.*?)$#', $line, $matches))
+                               {
+                                       $index = $matches[1];
+                                       $indexcounter = 1;
+                                       $chunk = 0;
+                                       continue;
+                               }
+                               
+                               if ($property)
+                               {
+                                       if (preg_match('#^__*_$#', trim($line)))
+                                       {
+                                               $viewsvn->debug("skipping: $line");
+                                               continue;
+                                       }
+                                       
+                                       if (preg_match('#Name: (.*?)$#', $line, $matches))
+                                       {
+                                               $curprop = $matches[1];
+                                               $viewsvn->debug("prop: $curprop");
+                                               continue;
+                                       }
+                                       else
+                                       {
+                                               if (preg_match('#^\s+?\+(.*)#', $line, $matches))
+                                               {
+                                                       $mode = 'add';
+                                                       $this->diff["$index"]['props']["$curprop"]['add'] .= $matches[1];
+                                               }
+                                               else if (preg_match('#^\s+?\-(.*)#', $line, $matches))
+                                               {
+                                                       $mode = 'del';
+                                                       $this->diff["$index"]['props']["$curprop"]['del'] .= $matches[1];
+                                               }
+                                               else if (!preg_match('#^\s+[\+\- ](.*)#', $line) AND trim($line) != '')
+                                               {
+                                                       $this->diff["$index"]['props']["$curprop"]["$mode"] .= "\n" . $line;
+                                               }
+                                               continue;
+                                       }
+                               }
+                               
+                               $this->diff["$index"]["$chunk"][] = array(
+                                       'line'          => '',
+                                       'act'           => '',
+                                       'oldlineno'     => ++$lines['old'],
+                                       'newlineno'     => ++$lines['new']
+                               );
+                               
+                               $delstack = array();
+                       }
+               }
+       }
+       
+       /**
+       * Returns the amount of change that occured
+       * between two lines
+       *
+       * @access       private
+       *
+       * @param        string  Old line
+       * @param        string  New line
+       *
+       * @return       array   Difference of positions
+       */
+       function fetch_diff_extent($old, $new)
+       {
+               global $viewsvn;
+               
+               $start = 0;
+               $min = min(strlen($old), strlen($new));
+               
+               $viewsvn->debug("min1 = $min");
+               
+               while ($start < $min AND $old["$start"] == $new["$start"])
+               {
+                       $start++;
+               }
+               
+               $end = -1;
+               $min = $min - $start;
+               
+               $viewsvn->debug("min2 = $min");
+               
+               $viewsvn->debug("checking: " . $old[ strlen($old) + $end ] . ' ==  ' . $new[ strlen($new) + $end ]);
+               
+               while (-$end <= $min AND $old[ strlen($old) + $end ] == $new[ strlen($new) + $end ])
+               {
+                       $end--;
+               }
+               
+               return array('start' => $start, 'end' => $end + 1);
+       }
+}
+
+/*=====================================================================*\
+|| ###################################################################
+|| # $HeadURL$
+|| # $Id$
+|| ###################################################################
+\*=====================================================================*/
+?>
\ No newline at end of file
index 3fd86ca4aa3e65c8f7f1bccaa749307cfa9c4a59..c9790ee1f412d7b1bb85a559d25dab92798e2dc8 100644 (file)
@@ -41,173 +41,36 @@ class SVNLib
        var $svnpath;
        
        /**
-       * Common command system
+       * Controller
        * @var  object
+       * @access       private
        */
-       var $common;
+       var $controller;
        
        /**
        * Constructor: validate SVN path
        *
-       * @param        string  Path to SVN binary
+       * @param        object  Controller
        */
-       function SVNLib($svnpath)
+       function SVNLib(&$controller)
        {
-               global $viewsvn;
+               $this->controller =& $controller;
                
-               $this->svnpath = $viewsvn->shell->cmd($svnpath);
+               $this->svnpath = $this->controller->xquery->cmd($svnpath);
                
-               $this->common =& new SVNCommon();
-               
-               $access = $viewsvn->shell->exec($this->svnpath . ' --version');
+               $access = $this->controller->xquery->exec($this->svnpath . ' --version');
                
                if (!$access)
                {
-                       $viewsvn->trigger->error($viewsvn->lang->string('The SVN binary could not be located'));
+                       $this->controller->registry->trigger->error($this->controller->registry->lang->string('The SVN binary could not be located'));
                }
                
                if (!preg_match('#^svn, version (.*?)\)$#i', trim($access[0])))
                {
-                       $viewsvn->trigger->error($viewsvn->lang->string('The SVN binary does not appear to be valid (it failed our tests)'));
-               }
-       }
-       
-       /**
-       * Prepares data for output
-       *
-       * @access       public
-       *
-       * @param        string  Standard data
-       *
-       * @return       string  Output-ready data
-       */
-       function format($string)
-       {
-               // convert entities
-               $string = htmlspecialchars($string);
-               
-               // tabs to 5 spaces
-               $string = str_replace("\t", '     ', $string);
-               
-               // spaces to nbsp
-               if (true)
-               {
-                       $string = preg_replace('#( +)#e', '$this->format_spaces("\1")', $string);
-               }
-               // no word wrap
-               else
-               {
-                       $string = str_replace(' ', '&nbsp;', $string);
-               }
-               
-               // convert advanced diff
-               $string = str_replace(array('{@+' . '+}', '{@-' . '-}'), array('<span class="diff_add_bit">', '<span class="diff_del_bit">'), $string);
-               $string = str_replace(array('{/@+' . '+}', '{/@-' . '-}'), '</span>', $string);
-               
-               // nl2br
-               $string = nl2br($string);
-               
-               return $string;
-       }
-       
-       /**
-       * Formats a SVN log message
-       *
-       * @access       public
-       *
-       * @param        string  Unformatted log message
-       *
-       * @return       string  Output-ready log message
-       */
-       function format_log_message($message)
-       {
-               global $viewsvn;
-               
-               $message = $viewsvn->entity_encode($message);
-               
-               $message = preg_replace('#r([0-9]+)#e', '"<a href=\"" . $viewsvn->path . "/" . $viewsvn->paths->out("diff.php" . $viewsvn->paths->fetch_rev_str(true, "\1", 0), $viewsvn->paths->fetch_repos($viewsvn->paths->parse()) . "/") . "\">r\1</a>"', $message);
-               
-               $list = false;
-               $lines = explode("\n", $message);
-               $message = '';
-               foreach ($lines AS $line)
-               {
-                       if (preg_match('#^\s*?(\*|\-)\s?(.*)#', $line, $matches))
-                       {
-                               if ($list)
-                               {
-                                       $message .= '<li>' . $matches[2] . '</li>';
-                               }
-                               else
-                               {
-                                       $message .= '<ul class="list">';
-                                       $message .= '<li>' . $matches[2] . '</li>';
-                               }
-                               $list = true;
-                       }
-                       else
-                       {
-                               if ($list)
-                               {
-                                       $message .= '</ul>';
-                                       $message .= $line;
-                               }
-                               else
-                               {
-                                       $message .= $line;
-                                       $message .= '<br />';
-                               }
-                               $list = false;
-                       }
-                       
-                       $message .= "\n";
-               }
-               
-               if ($list)
-               {
-                       $message .= '</ul>';
+                       $this->controller->registry->trigger->error($this->controller->registry->lang->string('The SVN binary does not appear to be valid (it failed our tests)'));
                }
-               
-               $message = preg_replace('#(<br />)*$#', '', $message);
-               
-               return $message;
        }
-       
-       // ###################################################################
-       /**
-       * Parses a date from Xquery XML outut
-       *
-       * @access       public
-       *
-       * @param        string  Date string
-       *
-       * @return       string  Formatted and readable date string
-       */
-       function format_date_string($string)
-       {
-               // 2005-01-23T20:42:53.703057Z
-               return preg_replace('#(....)\-(..)\-(..)T(..):(..):(..).(.*)Z#e', 'gmdate("r", mktime(\4, \5, \6, \2, \3, \1))', $string);
-       }
-       
-       /**
-       * Counts the spaces and replaces two or more ones
-       *
-       * @access       private
-       *
-       * @param        string  Spaced string
-       *
-       * @return       string  &nbsp;'d string
-       */
-       function format_spaces($thestring)
-       {
-               if (strlen($thestring) >= 2)
-               {
-                       $thestring = str_replace(' ', '&nbsp;', $thestring);
-               }
-               
-               return $thestring;
-       }
-       
+
        /**
        * Executes the SVN binary
        *
@@ -219,9 +82,7 @@ class SVNLib
        */
        function svn($command)
        {
-               global $viewsvn;
-               
-               $output = $viewsvn->shell->exec($this->svnpath . ' ' . $command . ' 2>&1');
+               $output = $this->controller->xquery->exec($this->svnpath . ' ' . $command . ' 2>&1');
                
                // make sure that we keep escaped chars
                //$output = str_replace(array('\t', '\n', '\r'), array('\\\t', '\\\n', '\\\r'), $output);
@@ -231,7 +92,7 @@ class SVNLib
                $temp = implode("\n", $output);
                if (strpos($temp, '(apr' . '_err=') !== false)
                {
-                       $viewsvn->trigger->error(nl2br($temp));
+                       $this->controller->registry->trigger->error(nl2br($temp));
                }
                return $output;
        }
@@ -405,747 +266,10 @@ class SVNLib
        }
 }
 
-/**
-* Commonly executed SVN commands that return data
-* used in many parts of the system
-*
-* @package     ViewSVN
-* @version     $Id$
-*/
-class SVNCommon
-{
-       /**
-       * Registry object
-       * @var  object
-       */
-       var $registry;
-       
-       /**
-       * List of revisions
-       * @var  array
-       */
-       var $revisions;
-       
-       /**
-       * List of logs
-       * @var  array
-       */
-       var $logs;
-       
-       /**
-       * Constructor: bind with registry
-       */
-       function SVNCommon()
-       {
-               global $viewsvn;
-               
-               $this->registry =& $viewsvn;
-       }
-       
-       /**
-       * Checks to see if the given universal path is
-       * a directory
-       *
-       * @access       public
-       *
-       * @param        string  Universal path
-       *
-       * @return       bool    Directory or not
-       */
-       function isdir($path)
-       {
-               $output = $this->registry->svn->std('info', $this->registry->paths->fetch_repos($path), $this->registry->paths->fetch_path($path), $this->registry->paths->revnum);
-               
-               foreach ($output AS $line)
-               {
-                       if (preg_match('#^Node Kind: (.*)#', $line, $matches))
-                       {
-                               if (trim(strtolower($matches[1])) == 'directory')
-                               {
-                                       return true;
-                               }
-                       }
-               }
-               
-               return false;
-       }
-       
-       /**
-       * Get a list of revisions for a path
-       *
-       * @access       public
-       *
-       * @param        string  Universal path
-       *
-       * @return       array   Key revisions
-       */
-       function fetch_revs($path)
-       {
-               if (!isset($this->revisions["$path"]))
-               {
-                       $log = $this->fetch_logs($path);
-                       
-                       $revs = array_keys($log);
-                       
-                       $this->revisions["$path"] = array(
-                               'HEAD'  => $revs[0],
-                               'START' => $revs[ count($revs) - 1 ],
-                               'revs'  => $revs
-                       );
-               }
-               
-               return $this->revisions["$path"];
-       }
-       
-       /**
-       * Gets the revision that is marked as HEAD
-       *
-       * @access       public
-       *
-       * @param        string  Universal path
-       *
-       * @return       integer Revision
-       */
-       function fetch_head_rev($path)
-       {
-               $output = $this->registry->shell->exec($this->registry->svn->svnpath . ' info ' . $this->registry->repos->fetch_path($this->registry->paths->fetch_repos($path), false) . $this->registry->paths->fetch_path($path));
-               
-               foreach ($output AS $line)
-               {
-                       if (preg_match('#^Last Changed Rev: (.*)#', $line, $matches))
-                       {
-                               return $matches[1];
-                       }
-               }
-               
-               $revs = $this->fetch_revs($path);
-               return $revs['HEAD'];
-       }
-       
-       /**
-       * Returns the previous revision to the one given
-       *
-       * @access       public
-       *
-       * @param        string  Universal path
-       * @param        integer Arbitrary revision
-       *
-       * @return       integer Previous revision (-1 if none)
-       */
-       function fetch_prev_rev($path, $current)
-       {
-               global $viewsvn;
-               
-               $revs = $this->fetch_revs($path);
-               
-               if ($current == 'HEAD')
-               {
-                       $current = $this->fetch_head_rev($path);
-               }
-               
-               $index = array_search($current, $revs['revs']);
-               if ($current === false)
-               {
-                       $message->trigger->error(sprintf($viewsvn->lang->string('Revision r%1$s is not in path %2$s'), $current, $path));
-               }
-               
-               if (isset($revs['revs'][ $index + 1 ]))
-               {
-                       return $revs['revs'][ $index + 1 ];
-               }
-               else
-               {
-                       return -1;
-               }
-       }
-       
-       /**
-       * Get a list of logs
-       *
-       * @access       public
-       *
-       * @param        string  Universal path
-       * @param        bool    Override the cache system?
-       *
-       * @return       array   Log data
-       */
-       function fetch_logs($path)
-       {
-               if (!isset($this->logs["$path"]))
-               {
-                       $log = new SVNLog($this->registry->paths->fetch_repos($path), $this->registry->paths->fetch_path($path), 0, $this->registry->paths->revnum);
-                       
-                       $this->logs["$path"] = $log->fetch();
-               }
-               
-               return $this->logs["$path"];
-       }
-       
-       /**
-       * Returns a given log entry for a path
-       * and revision
-       *
-       * @access       public
-       *
-       * @param        string  Universal path
-       * @param        integer Arbitrary revision
-       *
-       * @return       array   Log entry
-       */
-       function fetch_log($path, $rev)
-       {
-               $logs = $this->fetch_logs($path);
-               
-               $rev = $this->registry->svn->rev($rev);
-               if ($rev == 'HEAD')
-               {
-                       $rev = $this->fetch_head_rev($path);
-               }
-               
-               if (isset($logs["$rev"]))
-               {
-                       return $logs["$rev"];
-               }
-               else
-               {
-                       $keys = array_keys($logs);
-                       sort($keys);
-
-                       for ($i = 0; $i < count($keys); $i++)
-                       {
-                               if ($rev > $keys["$i"] AND $rev < $keys[ $i + 1 ])
-                               {
-                                       return $logs["$keys[$i]"];
-                               }
-                       }
-                       
-                       return null;
-               }
-       }
-       
-       /**
-       * Prints the file changed list
-       *
-       * @access       public
-       *
-       * @public       array   List of file changes
-       * @public       string  The repository
-       * @public       integer Current revision
-       *
-       * @return       string  Processed HTML
-       */
-       function construct_file_changes($changes, $repos, $revision)
-       {
-               global $viewsvn;
-               
-               $files = '';
-               
-               foreach ($changes AS $file)
-               {
-                       switch ($file['action'])
-                       {
-                               case 'A':
-                                       $class = 'file_add';
-                                       $tooltip = $viewsvn->lang->string('Added');
-                                       break;
-                               case 'D':
-                                       $class = 'file_delete';
-                                       $tooltip = $viewsvn->lang->string('Deleted');
-                                       break;
-                               case 'M':
-                                       $class = 'file_modify';
-                                       $tooltip = $viewsvn->lang->string('Modified');
-                                       break;
-                               case 'R':
-                                       $class = 'file_replace';
-                                       $tooltip = $viewsvn->lang->string('Replaced');
-                                       break;
-                       }
-                       
-                       $show['from'] = (bool)$file['from'];
-                       
-                       if ($file['from'])
-                       {
-                               $class = 'file_move';
-                               $tooltip = 'Moved/Copied';
-                               preg_match('#(.*):([0-9]+)#', $file['from'], $matches);
-                               $link['from'] = $viewsvn->paths->out('view.php' . $viewsvn->paths->fetch_rev_str(false, $matches[2]), $repos . $matches[1]);
-                       }
-                       
-                       $link['file'] = $viewsvn->paths->out('view.php' . $viewsvn->paths->fetch_rev_str(false, $revision), $repos . $file['file']);
-                       
-                       eval('$files .= "' . $viewsvn->template->fetch('file_change') . '";');
-               }
-               
-               return $files;
-       }
-}
-
-/**
-* Annotation/blame system; constructs an array
-* that is ready for output
-*
-* @package     ViewSVN
-* @version     $Id$
-*/
-class SVNBlame
-{
-       /**
-       * Array of blame information
-       * @var  array
-       */
-       var $blame = array();
-       
-       /**
-       * Raw "svn blame" output
-       * @var  array
-       */
-       var $rawoutput;
-       
-       /**
-       * Constructor: create blame and store data
-       *
-       * @param        string  Repository
-       * @param        string  Path
-       * @param        integer Revision
-       */
-       function SVNBlame($repos, $path, $revision)
-       {
-               global $viewsvn;
-               
-               $this->rawoutput = $viewsvn->svn->blame($repos, $path, $revision);
-               $this->process();
-       }
-       
-       /**
-       * Returns blame for display
-       *
-       * @access       public
-       *
-       * @return       array   Blame data
-       */
-       function fetch()
-       {
-               return $this->blame;
-       }
-       
-       /**
-       * Parses the blame data
-       *
-       * @access       private
-       */
-       function process()
-       {
-               $lineno = 1;
-               
-               foreach ($this->rawoutput AS $line)
-               {
-                       if (preg_match('#^\s+([0-9]+)\s+([\w\.\-_]+)\s(.*)$#', $line, $matches))
-                       {
-                               $this->blame[] = array(
-                                       'rev'           => $matches[1],
-                                       'author'        => $matches[2],
-                                       'line'          => $matches[3],
-                                       'lineno'        => $lineno++
-                               );
-                       }
-                       // a blank line
-                       else if (preg_match('#^\s+([0-9]+)\s+([\w\.\-_]+)$#', $line, $matches))
-                       {
-                               $this->blame[] = array(
-                                       'rev'           => $matches[1],
-                                       'author'        => $matches[2],
-                                       'line'          => '',
-                                       'lineno'        => $lineno++
-                               );
-                       }
-               }
-       }
-}
-
-/**
-* Log management system; creates a complex list
-* of SVN log information
-*
-* @package     ViewSVN
-* @version     $Id$
-*/
-class SVNLog
-{
-       /**
-       * Array of logs
-       * @var  array
-       */
-       var $logs = array();
-       
-       /**
-       * Raw "svn log" output
-       * @var  array
-       */
-       var $rawoutput;
-       
-       /**
-       * Constructor: create log store for the given file
-       *
-       * @param        string  Repository
-       * @param        string  Path
-       * @param        integer Lower revision
-       * @param        integer Higher revision
-       */
-       function SVNLog($repos, $path, $lorev, $hirev)
-       {
-               global $viewsvn;
-               
-               $this->rawoutput = $viewsvn->svn->log($repos, $path, $lorev, $hirev);
-               $this->process();
-       }
-       
-       /**
-       * Returns logs for display
-       *
-       * @access       public
-       *
-       * @return       array   Log data
-       */
-       function fetch()
-       {
-               return $this->logs;
-       }
-       
-       /**
-       * Splits up the raw output into a usable log
-       *
-       * @access       private
-       */
-       function process()
-       {
-               $lastrev = 0;
-               
-               for ($i = 1; $i <= count($this->rawoutput) - 1; $i++)
-               {
-                       $line = $this->rawoutput["$i"];
-                       
-                       if (preg_match('#^r([0-9]*) \| (.*?) \| (....-..-.. ..:..:..) ([0-9\-]*) \((.*?)\) \| ([0-9]*) lines?$#', $line, $matches))
-                       {
-                               if (isset($this->logs["$lastrev"]))
-                               {
-                                       $this->logs["$lastrev"]['message'] = $this->strip_last_line($this->logs["$lastrev"]['message']);
-                               }
-                               
-                               $this->logs["$matches[1]"] = array(
-                                       'rev'           => $matches[1],
-                                       'author'        => $matches[2],
-                                       'date'          => $matches[3],
-                                       'timezone'      => $matches[4],
-                                       'lines'         => $matches[6],
-                                       'message'       => ''
-                               );
-                               
-                               $lastrev = $matches[1];
-                       }
-                       else if (preg_match('#^\s+([ADMR])\s(.*)#', $line, $matches))
-                       {
-                               if (preg_match('#(.*) \(from (.*?)\)$#', $matches[2], $amatches))
-                               {
-                                       $matches[2] = $amatches[1];
-                               }
-                               
-                               $this->logs["$lastrev"]['files'][] = array(
-                                       'action'        => $matches[1],
-                                       'file'          => trim($matches[2]),
-                                       'from'          => (isset($amatches[2]) ? $amatches[2] : '')
-                               );
-                       }
-                       else
-                       {
-                               if (trim($line) != 'Changed paths:')
-                               {
-                                       $this->logs["$lastrev"]['message'] .= $line . "\n";
-                               }
-                       }
-               }
-               
-               if (isset($this->logs["$lastrev"]))
-               {
-                       $this->logs["$lastrev"]['message'] = $this->strip_last_line($this->logs["$lastrev"]['message']);
-               }
-       }
-       
-       /**
-       * Trims the last dash line off a message
-       *
-       * @access       private
-       *
-       * @param        string  Message with annoying-ass line
-       *
-       * @return       string  Clean string
-       */
-       function strip_last_line($string)
-       {
-               return trim(preg_replace("#\n(.*?)\n$#", '', $string));
-       }
-}
-
-/**
-* Diff system; constructs a diff array that
-* is ready for output
-*
-* @package     ViewSVN
-*/
-class SVNDiff
-{
-       /**
-       * Array of diff information
-       * @var  array
-       */
-       var $diff = array();
-       
-       /**
-       * Raw "svn diff" output
-       * @var  array
-       */
-       var $rawoutput;
-       
-       /**
-       * Constructor: create and store diff data
-       *
-       * @param        string  Repository
-       * @param        string  Path
-       * @param        integer Lower revision
-       * @param        integer Higher revision
-       */
-       function SVNDiff($repos, $path, $lorev, $hirev)
-       {
-               global $viewsvn;
-               
-               $this->rawoutput = $viewsvn->svn->diff($repos, $path, $lorev, $hirev);
-               $this->process();
-       }
-       
-       /**
-       * Returns diffs for display
-       *
-       * @access       public
-       *
-       * @return       array   Diff data
-       */
-       function fetch()
-       {
-               return $this->diff;
-       }
-       
-       /**
-       * Processes and prepares diff data
-       *
-       * @access       private
-       */
-       function process()
-       {
-               global $viewsvn;
-               
-               $chunk = 0;
-               $indexcounter = null;
-               $curprop = '';
-               
-               $delstack = array();
-               
-               foreach ($this->rawoutput AS $line)
-               {
-                       if (preg_match('#^@@ \-([0-9]*),([0-9]*) \+([0-9]*),([0-9]*) @@$#', $line, $bits))
-                       {
-                               $property = false;
-                               $delstack = array();
-                               $this->diff["$index"][ ++$chunk ]['hunk'] = array('old' => array('line' => $bits[1], 'count' => $bits[2]), 'new' => array('line' => $bits[3], 'count' => $bits[4]));
-                               $lines['old'] = $this->diff["$index"]["$chunk"]['hunk']['old']['line'] - 1;
-                               $lines['new'] = $this->diff["$index"]["$chunk"]['hunk']['new']['line'] - 1;
-                               continue;
-                       }
-                       else if (preg_match('#^Property changes on: (.*?)$#', $line, $bits))
-                       {
-                               $property = true;
-                               $index = $bits[1];
-                               $this->diff["$index"]['props'] = array();
-                               continue;
-                       }
-                       
-                       if ($indexcounter <= 3 AND $indexcounter !== null)
-                       {
-                               $indexcounter++;
-                               continue;
-                       }
-                       else if ($indexcounter == 3)
-                       {
-                               $indexcounter = null;
-                               continue;
-                       }
-                       
-                       if (preg_match('#^([\+\- ])(.*)#', $line, $matches) AND !$property)
-                       {
-                               $act = $matches[1];
-                               $content = $matches[2];
-                               
-                               if ($act == ' ')
-                               {
-                                       $this->diff["$index"]["$chunk"][] = array(
-                                               'line'          => $content,
-                                               'act'           => '',
-                                               'oldlineno'     => ++$lines['old'],
-                                               'newlineno'     => ++$lines['new']
-                                       );
-                                       
-                                       $delstack = array();
-                               }
-                               else if ($act == '+')
-                               {               
-                                       // potential line delta
-                                       if (count($delstack) > 0)
-                                       {
-                                               $lastline = array_shift($delstack);
-                                               
-                                               if ($delta = @$this->fetch_diff_extent($lastline['line'], $content))
-                                               {
-                                                       if (strlen($lastline['line']) > ($delta['start'] - $delta['end']))
-                                                       {
-                                                               $end = strlen($lastline['line']) + $delta['end'];
-                                                               $viewsvn->debug("RM delta- = " . $end);
-                                                               $change = '{@-' . '-}' . substr($lastline['line'], $delta['start'], $end - $delta['start']) . '{/@-' . '-}';
-                                                               $this->diff["$index"]["$chunk"]["$lastline[INDEX]"]['line'] = substr($lastline['line'], 0, $delta['start']) . $change . substr($lastline['line'], $end);
-                                                       }
-                                                       
-                                                       if (strlen($content) > $delta['start'] - $delta['end'])
-                                                       {
-                                                               $end = strlen($content) + $delta['end'];
-                                                               $viewsvn->debug("MK delta+ = " . $end);
-                                                               $change = '{@+' . '+}' . substr($content, $delta['start'], $end - $delta['start']) . '{/@+' . '+}';
-                                                               $content = substr($content, 0, $delta['start']) . $change . substr($content, $end);
-                                                       }
-                                               }
-                                       }
-                                       
-                                       $this->diff["$index"]["$chunk"][] = array(
-                                               'line'          => $content,
-                                               'act'           => '+',
-                                               'oldlineno'     => '',
-                                               'newlineno'     => ++$lines['new']
-                                       );
-                               }
-                               else if ($act == '-')
-                               {
-                                       $this->diff["$index"]["$chunk"][] = $thearray = array(
-                                               'line'          => $content,
-                                               'act'           => '-',
-                                               'oldlineno'     => ++$lines['old'],
-                                               'newlineno'     => ''
-                                       );
-                                       
-                                       $key = count($this->diff["$index"]["$chunk"]) - 2;
-                                       $thearray['INDEX'] = $key;
-                                       
-                                       array_push($delstack, $thearray);
-                               }
-                       }
-                       // whitespace lines
-                       else
-                       {
-                               if (preg_match('#^Index: (.*?)$#', $line, $matches))
-                               {
-                                       $index = $matches[1];
-                                       $indexcounter = 1;
-                                       $chunk = 0;
-                                       continue;
-                               }
-                               
-                               if ($property)
-                               {
-                                       if (preg_match('#^__*_$#', trim($line)))
-                                       {
-                                               $viewsvn->debug("skipping: $line");
-                                               continue;
-                                       }
-                                       
-                                       if (preg_match('#Name: (.*?)$#', $line, $matches))
-                                       {
-                                               $curprop = $matches[1];
-                                               $viewsvn->debug("prop: $curprop");
-                                               continue;
-                                       }
-                                       else
-                                       {
-                                               if (preg_match('#^\s+?\+(.*)#', $line, $matches))
-                                               {
-                                                       $mode = 'add';
-                                                       $this->diff["$index"]['props']["$curprop"]['add'] .= $matches[1];
-                                               }
-                                               else if (preg_match('#^\s+?\-(.*)#', $line, $matches))
-                                               {
-                                                       $mode = 'del';
-                                                       $this->diff["$index"]['props']["$curprop"]['del'] .= $matches[1];
-                                               }
-                                               else if (!preg_match('#^\s+[\+\- ](.*)#', $line) AND trim($line) != '')
-                                               {
-                                                       $this->diff["$index"]['props']["$curprop"]["$mode"] .= "\n" . $line;
-                                               }
-                                               continue;
-                                       }
-                               }
-                               
-                               $this->diff["$index"]["$chunk"][] = array(
-                                       'line'          => '',
-                                       'act'           => '',
-                                       'oldlineno'     => ++$lines['old'],
-                                       'newlineno'     => ++$lines['new']
-                               );
-                               
-                               $delstack = array();
-                       }
-               }
-       }
-       
-       /**
-       * Returns the amount of change that occured
-       * between two lines
-       *
-       * @access       private
-       *
-       * @param        string  Old line
-       * @param        string  New line
-       *
-       * @return       array   Difference of positions
-       */
-       function fetch_diff_extent($old, $new)
-       {
-               global $viewsvn;
-               
-               $start = 0;
-               $min = min(strlen($old), strlen($new));
-               
-               $viewsvn->debug("min1 = $min");
-               
-               while ($start < $min AND $old["$start"] == $new["$start"])
-               {
-                       $start++;
-               }
-               
-               $end = -1;
-               $min = $min - $start;
-               
-               $viewsvn->debug("min2 = $min");
-               
-               $viewsvn->debug("checking: " . $old[ strlen($old) + $end ] . ' ==  ' . $new[ strlen($new) + $end ]);
-               
-               while (-$end <= $min AND $old[ strlen($old) + $end ] == $new[ strlen($new) + $end ])
-               {
-                       $end--;
-               }
-               
-               return array('start' => $start, 'end' => $end + 1);
-       }
-}
-
 /*=====================================================================*\
 || ###################################################################
 || # $HeadURL$
 || # $Id$
 || ###################################################################
 \*=====================================================================*/
-?>
+?>
\ No newline at end of file