[ Index ]
 

Code source de Horde 3.1.3

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/Horde/ -> VC.php (source)

   1  <?php
   2  /**
   3   * Sorting options
   4   */
   5  define('VC_SORT_NONE', 0);        // don't sort
   6  define('VC_SORT_AGE', 1);         // sort by age
   7  define('VC_SORT_NAME', 2);        // sort by filename
   8  define('VC_SORT_REV', 3);         // sort by revision number
   9  define('VC_SORT_AUTHOR', 4);      // sort by author name
  10  
  11  define('VC_SORT_ASCENDING', 0);   // ascending order
  12  define('VC_SORT_DESCENDING', 1);  // descending order
  13  
  14  define('VC_WINDOWS', substr(PHP_OS, 0, 3) == 'WIN');
  15  
  16  /**
  17   * Version Control generalized library.
  18   *
  19   * $Horde: framework/VC/VC.php,v 1.12.8.12 2006/05/31 17:06:37 selsky Exp $
  20   *
  21   * @package VC
  22   */
  23  class VC {
  24  
  25      /**
  26       * The source root of the repository.
  27       *
  28       * @access protected
  29       * @var string
  30       */
  31      var $_sourceroot;
  32  
  33      /**
  34       * Hash with the locations of all necessary binaries.
  35       * @var array
  36       */
  37      var $_paths = array();
  38  
  39      /**
  40       * Hash caching the parsed users file.
  41       * @var array
  42       */
  43      var $_users;
  44  
  45      /**
  46       * Return the source root for this repository, with no trailing /
  47       *
  48       * @return string  Source root for this repository.
  49       */
  50      function sourceroot()
  51      {
  52          return $this->_sourceroot;
  53      }
  54  
  55      /**
  56       * Returns the location of the specified binary.
  57       *
  58       * @param string $binary  An external program name.
  59       *
  60       * @return boolean|string  The location of the external program or false if
  61       *                         it wasn't specified.
  62       */
  63      function getPath($binary)
  64      {
  65          if (isset($this->_paths[$binary])) {
  66              if (VC_WINDOWS) {
  67                  return $this->_paths[$binary];
  68              } else {
  69                  return is_executable($this->_paths[$binary]) ? $this->_paths[$binary] : false;
  70              }
  71          }
  72  
  73          return false;
  74      }
  75  
  76      /**
  77       * Parse the users file, if present in the source root, and return
  78       * a hash containing the requisite information, keyed on the
  79       * username, and with the 'desc','name', and 'mail' values inside.
  80       *
  81       * @return boolean|array  False if the file is not present, otherwise
  82       *                        $this->_users populated with the data
  83       */
  84      function getUsers($usersfile)
  85      {
  86          /* Check that we haven't already parsed users. */
  87          if (isset($this->_users) && is_array($this->_users)) {
  88              return $this->_users;
  89          }
  90  
  91          if (!@is_file($usersfile) || !($fl = @fopen($usersfile, VC_WINDOWS ? 'rb' : 'r'))) {
  92              return false;
  93          }
  94  
  95          $this->_users = array();
  96  
  97          /* Discard the first line, since it'll be the header info. */
  98          fgets($fl, 4096);
  99  
 100          /* Parse the rest of the lines into a hash, keyed on
 101           * username. */
 102          while ($line = fgets($fl, 4096)) {
 103              if (preg_match('/^\s*$/', $line)) {
 104                  continue;
 105              }
 106              if (!preg_match('/^(\w+)\s+(.+)\s+([\w\.\-\_]+@[\w\.\-\_]+)\s+(.*)$/', $line, $regs)) {
 107                  continue;
 108              }
 109  
 110              $this->_users[$regs[1]]['name'] = trim($regs[2]);
 111              $this->_users[$regs[1]]['mail'] = trim($regs[3]);
 112              $this->_users[$regs[1]]['desc'] = trim($regs[4]);
 113          }
 114  
 115          return $this->_users;
 116      }
 117  
 118      /**
 119       * Attempts to return a concrete VC instance based on $driver.
 120       *
 121       * @param mixed $driver  The type of concrete VC subclass to return.
 122       *                       The code is dynamically included.
 123       * @param array $params  A hash containing any additional configuration
 124       *                       or  parameters a subclass might need.
 125       *
 126       * @return VC  The newly created concrete VC instance, or PEAR_Error on
 127       *             failure.
 128       */
 129      function &factory($driver, $params = array())
 130      {
 131          include_once 'VC/' . $driver . '.php';
 132          $class = 'VC_' . $driver;
 133          if (class_exists($class)) {
 134              $vc = new $class($params);
 135          } else {
 136              $vc = PEAR::raiseError($class . ' not found.');
 137          }
 138  
 139          return $vc;
 140      }
 141  
 142      /**
 143       * Attempts to return a reference to a concrete VC instance based
 144       * on $driver. It will only create a new instance if no VC
 145       * instance with the same parameters currently exists.
 146       *
 147       * This should be used if multiple types of file backends (and,
 148       * thus, multiple VC instances) are required.
 149       *
 150       * This method must be invoked as: $var = &VC::singleton()
 151       *
 152       * @param mixed $driver  The type of concrete VC subclass to return.
 153       *                       The code is dynamically included.
 154       * @param array $params  A hash containing any additional configuration
 155       *                       or parameters a subclass might need.
 156       *
 157       * @return VC  The concrete VC reference, or PEAR_Error on failure.
 158       */
 159      function &singleton($driver, $params = array())
 160      {
 161          static $instances;
 162          if (!isset($instances)) {
 163              $instances = array();
 164          }
 165  
 166          $signature = serialize(array($driver, $params));
 167          if (!isset($instances[$signature])) {
 168              $instances[$signature] = VC::factory($driver, $params);
 169          }
 170  
 171          return $instances[$signature];
 172      }
 173  
 174  }
 175  
 176  /**
 177   * @package VC
 178   */
 179  class VC_Diff {
 180  
 181      /**
 182       * Obtain a tree containing information about the changes between
 183       * two revisions.
 184       *
 185       * @param array $raw  An array of lines of the raw unified diff,
 186       *                    normally obtained through VC_Diff::get().
 187       *
 188       * @return array
 189       *
 190       * @todo document this thoroughly, as the format is a bit complex.
 191       */
 192      function humanReadable($raw)
 193      {
 194          $ret = array();
 195  
 196          /* Hold the left and right columns of lines for change
 197           * blocks. */
 198          $cols = array(array(), array());
 199          $state = 'empty';
 200  
 201          /* Iterate through every line of the diff. */
 202          foreach ($raw as $line) {
 203              /* Look for a header which indicates the start of a diff
 204               * chunk. */
 205              if (preg_match('/^@@ \-([0-9]+).*\+([0-9]+).*@@(.*)/', $line, $regs)) {
 206                  /* Push any previous header information to the return
 207                   * stack. */
 208                  if (isset($data)) {
 209                      $ret[] = $data;
 210                  }
 211                  $data = array('type' => 'header', 'oldline' => $regs[1],
 212                                'newline' => $regs[2], 'contents'> array());
 213                  $data['function'] = isset($regs[3]) ? $regs[3] : '';
 214                  $state = 'dump';
 215              } elseif ($state != 'empty') {
 216                  /* We are in a chunk, so split out the action (+/-)
 217                   * and the line. */
 218                  preg_match('/^([\+\- ])(.*)/', $line, $regs);
 219                  if (count($regs) > 2) {
 220                      $action = $regs[1];
 221                      $content = $regs[2];
 222                  } else {
 223                      $action = ' ';
 224                      $content = '';
 225                  }
 226  
 227                  if ($action == '+') {
 228                      /* This is just an addition line. */
 229                      if ($state == 'dump' || $state == 'add') {
 230                          /* Start adding to the addition stack. */
 231                          $cols[0][] = $content;
 232                          $state = 'add';
 233                      } else {
 234                          /* This is inside a change block, so start
 235                           * accumulating lines. */
 236                          $state = 'change';
 237                          $cols[1][] = $content;
 238                      }
 239                  } elseif ($action == '-') {
 240                      /* This is a removal line. */
 241                      $state = 'remove';
 242                      $cols[0][] = $content;
 243                  } else {
 244                      /* An empty block with no action. */
 245                      switch ($state) {
 246                      case 'add':
 247                          $data['contents'][] = array('type' => 'add', 'lines' => $cols[0]);
 248                          break;
 249  
 250                      case 'remove':
 251                          /* We have some removal lines pending in our
 252                           * stack, so flush them. */
 253                          $data['contents'][] = array('type' => 'remove', 'lines' => $cols[0]);
 254                          break;
 255  
 256                      case 'change':
 257                          /* We have both remove and addition lines, so
 258                           * this is a change block. */
 259                          $data['contents'][] = array('type' => 'change', 'old' => $cols[0], 'new' => $cols[1]);
 260                          break;
 261                      }
 262                      $cols = array(array(), array());
 263                      $data['contents'][] = array('type' => 'empty', 'line' => $content);
 264                      $state = 'dump';
 265                  }
 266              }
 267          }
 268  
 269          /* Just flush any remaining entries in the columns stack. */
 270          switch ($state) {
 271          case 'add':
 272              $data['contents'][] = array('type' => 'add', 'lines' => $cols[0]);
 273              break;
 274  
 275          case 'remove':
 276              /* We have some removal lines pending in our stack, so
 277               * flush them. */
 278              $data['contents'][] = array('type' => 'remove', 'lines' => $cols[0]);
 279              break;
 280  
 281          case 'change':
 282              /* We have both remove and addition lines, so this is a
 283               * change block. */
 284              $data['contents'][] = array('type' => 'change', 'old' => $cols[0], 'new' => $cols[1]);
 285              break;
 286          }
 287  
 288          if (isset($data)) {
 289              $ret[] = $data;
 290          }
 291  
 292          return $ret;
 293      }
 294  
 295  }
 296  
 297  /**
 298   * @package VC
 299   */
 300  class VC_File {
 301  
 302      var $rep;
 303      var $dir;
 304      var $name;
 305      var $logs;
 306      var $revs;
 307      var $head;
 308      var $quicklog;
 309      var $symrev;
 310      var $revsym;
 311      var $branches;
 312  
 313      function setRepository($rep)
 314      {
 315          $this->rep = $rep;
 316      }
 317  
 318  }
 319  
 320  /**
 321   * VC patchset class.
 322   *
 323   * @package VC
 324   */
 325  class VC_Patchset {
 326  
 327      var $_rep;
 328      var $_patchsets = array();
 329  
 330      function setRepository($rep)
 331      {
 332          $this->_rep = $rep;
 333      }
 334  
 335  }
 336  
 337  /**
 338   * VC revisions class.
 339   *
 340   * Copyright Anil Madhavapeddy, <anil@recoil.org>
 341   *
 342   * @author  Anil Madhavapeddy <anil@recoil.org>
 343   * @package VC
 344   */
 345  class VC_Revision {
 346  
 347      /**
 348       * Validation function to ensure that a revision number is of the
 349       * right form.
 350       *
 351       * @param string $val  Value to check.
 352       *
 353       * @return boolean  True if it is a revision number
 354       */
 355      function valid($val)
 356      {
 357          return $val && preg_match('/^[\d\.]+$/', $val);
 358      }
 359  
 360      /**
 361       * Given a revision number, remove a given number of portions from
 362       * it. For example, if we remove 2 portions of 1.2.3.4, we are
 363       * left with 1.2.
 364       *
 365       * @param string $val      Input revision
 366       * @param integer $amount  Number of portions to strip
 367       *
 368       * @return string  Stripped revision number
 369       */
 370      function strip($val, $amount)
 371      {
 372          if (!VC_Revision::valid($val)) {
 373              return false;
 374          }
 375          $pos = 0;
 376          while ($amount-- > 0 && ($pos = strrpos($val, '.')) !== false) {
 377              $val = substr($val, 0, $pos);
 378          }
 379          return $pos !== false ? $val : false;
 380      }
 381  
 382      /**
 383       * The size of a revision number is the number of portions it has.
 384       * For example, 1,2.3.4 is of size 4.
 385       *
 386       * @param string $val  Revision number to determine size of
 387       *
 388       * @return integer  Size of revision number
 389       */
 390      function sizeof($val)
 391      {
 392          if (!VC_Revision::valid($val)) {
 393              return false;
 394          }
 395  
 396          return (substr_count($val, '.') + 1);
 397      }
 398  
 399      /**
 400       * Given a valid revision number, this will return the revision
 401       * number from which it branched. If it cannot be determined, then
 402       * false is returned.
 403       *
 404       * @param string $val  Revision number.
 405       *
 406       * @return string|boolean  Branch point revision, or false.
 407       */
 408      function branchPoint($val)
 409      {
 410          /* Check if we have a valid revision number */
 411          if (!VC_Revision::valid($val)) {
 412              return false;
 413          }
 414  
 415          /* If its on the trunk, or is an odd size, ret false */
 416          if (VC_Revision::sizeof($val) < 3 || (VC_Revision::sizeof($val) % 2)) {
 417              return false;
 418          }
 419  
 420          /* Strip off two revision portions, and return it */
 421          return VC_Revision::strip($val, 2);
 422      }
 423  
 424      /**
 425       * Given two SVN revision numbers, this figures out which one is
 426       * greater than the other by stepping along the decimal points
 427       * until a difference is found, at which point a sign comparison
 428       * of the two is returned.
 429       *
 430       * @param string $rev1  Period delimited revision number
 431       * @param string $rev2  Second period delimited revision number
 432       *
 433       * @return integer  1 if the first is greater, -1 if the second if greater,
 434       *                  and 0 if they are equal
 435       */
 436      function cmp($rev1, $rev2)
 437      {
 438          return version_compare($rev1, $rev2);
 439      }
 440  
 441      /**
 442       * Return the logical revision before this one. Normally, this
 443       * will be the revision minus one, but in the case of a new
 444       * branch, we strip off the last two decimal places to return the
 445       * original branch point.
 446       *
 447       * @param string $rev  Revision number to decrement.
 448       *
 449       * @return string|boolean  Revision number, or false if none could be
 450       *                         determined.
 451       */
 452      function prev($rev)
 453      {
 454          $last_dot = strrpos($rev, '.');
 455          $val = substr($rev, ++$last_dot);
 456  
 457          if (--$val > 0) {
 458              return substr($rev, 0, $last_dot) . $val;
 459          } else {
 460              $last_dot--;
 461              while (--$last_dot) {
 462                  if ($rev[$last_dot] == '.') {
 463                      return  substr($rev, 0, $last_dot);
 464                  } elseif ($rev[$last_dot] == null) {
 465                      return false;
 466                  }
 467              }
 468          }
 469      }
 470  
 471      /**
 472       * Given a revision number of the form x.y.0.z, this remaps it
 473       * into the appropriate branch number, which is x.y.z
 474       *
 475       * @param string $rev  Even-digit revision number of a branch
 476       *
 477       * @return string  Odd-digit Branch number
 478       */
 479      function toBranch($rev)
 480      {
 481          /* Check if we have a valid revision number */
 482          if (!VC_Revision::valid($rev)) {
 483              return false;
 484          }
 485  
 486          if (($end = strrpos($rev, '.')) === false) {
 487              return false;
 488          }
 489  
 490          $rev[$end] = 0;
 491          if (($end2 = strrpos($rev, '.')) === false) {
 492              return substr($rev, ++$end);
 493          }
 494  
 495          return substr_replace($rev, '.', $end2, ($end-$end2+1));
 496      }
 497  
 498  }


Généré le : Sun Feb 25 18:01:28 2007 par Balluche grâce à PHPXref 0.7