| [ Index ] |
|
Code source de Horde 3.1.3 |
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 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |