| [ Index ] |
PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008] |
[Summary view] [Print] [Text view]
1 <?php 2 ini_set('display_errors', "On"); 3 4 require_once 'PEAR.php'; 5 6 if(!function_exists('scandir')) 7 { 8 function scandir($dir, $sortorder = 0) 9 { 10 if(is_dir($dir)) 11 { 12 $dirlist = opendir($dir); 13 14 while( ($file = readdir($dirlist)) !== false) 15 { 16 if(!is_dir($file)) 17 { 18 $files[] = $file; 19 } 20 } 21 22 ($sortorder == 0) ? asort($files) : arsort($files); 23 24 return $files; 25 } 26 else 27 { 28 return FALSE; 29 break; 30 } 31 } 32 } 33 34 35 /** 36 * Command-line options parsing class. 37 * 38 * @author Andrei Zmievski <andrei@php.net> 39 * 40 */ 41 class Console_Getopt { 42 /** 43 * Parses the command-line options. 44 * 45 * The first parameter to this function should be the list of command-line 46 * arguments without the leading reference to the running program. 47 * 48 * The second parameter is a string of allowed short options. Each of the 49 * option letters can be followed by a colon ':' to specify that the option 50 * requires an argument, or a double colon '::' to specify that the option 51 * takes an optional argument. 52 * 53 * The third argument is an optional array of allowed long options. The 54 * leading '--' should not be included in the option name. Options that 55 * require an argument should be followed by '=', and options that take an 56 * option argument should be followed by '=='. 57 * 58 * The return value is an array of two elements: the list of parsed 59 * options and the list of non-option command-line arguments. Each entry in 60 * the list of parsed options is a pair of elements - the first one 61 * specifies the option, and the second one specifies the option argument, 62 * if there was one. 63 * 64 * Long and short options can be mixed. 65 * 66 * Most of the semantics of this function are based on GNU getopt_long(). 67 * 68 * @param array $args an array of command-line arguments 69 * @param string $short_options specifies the list of allowed short options 70 * @param array $long_options specifies the list of allowed long options 71 * 72 * @return array two-element array containing the list of parsed options and 73 * the non-option arguments 74 * 75 * @access public 76 * 77 */ 78 function getopt2($args, $short_options, $long_options = null) 79 { 80 return Console_Getopt::doGetopt(2, $args, $short_options, $long_options); 81 } 82 83 /** 84 * This function expects $args to start with the script name (POSIX-style). 85 * Preserved for backwards compatibility. 86 * @see getopt2() 87 */ 88 function getopt($args, $short_options, $long_options = null) 89 { 90 return Console_Getopt::doGetopt(1, $args, $short_options, $long_options); 91 } 92 93 /** 94 * The actual implementation of the argument parsing code. 95 */ 96 function doGetopt($version, $args, $short_options, $long_options = null) 97 { 98 // in case you pass directly readPHPArgv() as the first arg 99 if (PEAR::isError($args)) { 100 return $args; 101 } 102 if (empty($args)) { 103 return array(array(), array()); 104 } 105 $opts = array(); 106 $non_opts = array(); 107 108 settype($args, 'array'); 109 110 if ($long_options) { 111 sort($long_options); 112 } 113 114 /* 115 * Preserve backwards compatibility with callers that relied on 116 * erroneous POSIX fix. 117 */ 118 if ($version < 2) { 119 if (isset($args[0]{0}) && $args[0]{0} != '-') { 120 array_shift($args); 121 } 122 } 123 124 reset($args); 125 while (list($i, $arg) = each($args)) { 126 127 /* The special element '--' means explicit end of 128 options. Treat the rest of the arguments as non-options 129 and end the loop. */ 130 if ($arg == '--') { 131 $non_opts = array_merge($non_opts, array_slice($args, $i + 1)); 132 break; 133 } 134 135 if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) { 136 $non_opts = array_merge($non_opts, array_slice($args, $i)); 137 break; 138 } elseif (strlen($arg) > 1 && $arg{1} == '-') { 139 $error = Console_Getopt::_parseLongOption(substr($arg, 2), $long_options, $opts, $args); 140 if (PEAR::isError($error)) 141 return $error; 142 } else { 143 $error = Console_Getopt::_parseShortOption(substr($arg, 1), $short_options, $opts, $args); 144 if (PEAR::isError($error)) 145 return $error; 146 } 147 } 148 149 return array($opts, $non_opts); 150 } 151 152 /** 153 * @access private 154 * 155 */ 156 function _parseShortOption($arg, $short_options, &$opts, &$args) 157 { 158 for ($i = 0; $i < strlen($arg); $i++) { 159 $opt = $arg{$i}; 160 $opt_arg = null; 161 162 /* Try to find the short option in the specifier string. */ 163 if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') 164 { 165 return PEAR::raiseError("Console_Getopt: unrecognized option -- $opt"); 166 } 167 168 if (strlen($spec) > 1 && $spec{1} == ':') { 169 if (strlen($spec) > 2 && $spec{2} == ':') { 170 if ($i + 1 < strlen($arg)) { 171 /* Option takes an optional argument. Use the remainder of 172 the arg string if there is anything left. */ 173 $opts[] = array($opt, substr($arg, $i + 1)); 174 break; 175 } 176 } else { 177 /* Option requires an argument. Use the remainder of the arg 178 string if there is anything left. */ 179 if ($i + 1 < strlen($arg)) { 180 $opts[] = array($opt, substr($arg, $i + 1)); 181 break; 182 } else if (list(, $opt_arg) = each($args)) 183 /* Else use the next argument. */; 184 else 185 return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt"); 186 } 187 } 188 189 $opts[] = array($opt, $opt_arg); 190 } 191 } 192 193 /** 194 * @access private 195 * 196 */ 197 function _parseLongOption($arg, $long_options, &$opts, &$args) 198 { 199 @list($opt, $opt_arg) = explode('=', $arg); 200 $opt_len = strlen($opt); 201 202 for ($i = 0; $i < count($long_options); $i++) { 203 $long_opt = $long_options[$i]; 204 $opt_start = substr($long_opt, 0, $opt_len); 205 206 /* Option doesn't match. Go on to the next one. */ 207 if ($opt_start != $opt) 208 continue; 209 210 $opt_rest = substr($long_opt, $opt_len); 211 212 /* Check that the options uniquely matches one of the allowed 213 options. */ 214 if ($opt_rest != '' && $opt{0} != '=' && 215 $i + 1 < count($long_options) && 216 $opt == substr($long_options[$i+1], 0, $opt_len)) { 217 return PEAR::raiseError("Console_Getopt: option --$opt is ambiguous"); 218 } 219 220 if (substr($long_opt, -1) == '=') { 221 if (substr($long_opt, -2) != '==') { 222 /* Long option requires an argument. 223 Take the next argument if one wasn't specified. */; 224 if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) { 225 return PEAR::raiseError("Console_Getopt: option --$opt requires an argument"); 226 } 227 } 228 } else if ($opt_arg) { 229 return PEAR::raiseError("Console_Getopt: option --$opt doesn't allow an argument"); 230 } 231 232 $opts[] = array('--' . $opt, $opt_arg); 233 return; 234 } 235 236 return PEAR::raiseError("Console_Getopt: unrecognized option --$opt"); 237 } 238 239 /** 240 * Safely read the $argv PHP array across different PHP configurations. 241 * Will take care on register_globals and register_argc_argv ini directives 242 * 243 * @access public 244 * @return mixed the $argv PHP array or PEAR error if not registered 245 */ 246 function readPHPArgv() 247 { 248 global $argv; 249 if (!is_array($argv)) { 250 if (!@is_array($_SERVER['argv'])) { 251 if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) { 252 return PEAR::raiseError("Console_Getopt: Could not read cmd args (register_argc_argv=Off?)"); 253 } 254 return $GLOBALS['HTTP_SERVER_VARS']['argv']; 255 } 256 return $_SERVER['argv']; 257 } 258 return $argv; 259 } 260 261 } 262 263 264 /** 265 * Profiler adapted from Pear::APD's pprofp script. Not quite there yet, I need 266 * to get this to accept a similar list of arguments as the script does, 267 * and process them the same way. Also make sure that the file being loaded 268 * is the right one. Also support multiple pids used in one page load (up to 4 so far). 269 * Then output all this in a nicely formatted table. 270 */ 271 class Profiler 272 { 273 var $stimes; 274 var $utimes; 275 var $calls; 276 var $c_stimes; 277 var $c_utimes; 278 var $mem; 279 280 /** 281 * Concatenates all the pprof files generated by apd_set_pprof_trace() 282 * and returns the resulting string, which can then be processed by 283 * get_profiling(); 284 * It also deletes these files once finished, in order to limit 285 * cluttering of the filesystem. This can be switched off by 286 * providing "false" as the only argument to this function. 287 * 288 * WARNING: If you switch cleanup off, profiling data will 289 * accumulate from one pageload to the next. 290 * 291 * @param boolean $cleanup Whether to delete pprof files or not. 292 * @return String Profiling raw data 293 */ 294 function _get_pprofp($cleanup = true) 295 { 296 global $CFG, $USER; 297 // List all files under our temporary directory 298 $tempdir = $CFG->dataroot . '/temp/profile/' . $USER->id; 299 if ($files = scandir($tempdir)) { 300 // Concatenate the files 301 print_r($files); 302 } else { 303 print "Error: Profiler could not read the directory $tempdir."; 304 return false; 305 } 306 307 308 // Return a handle to the resulting file 309 310 311 if(($DATA = fopen($dataFile, "r")) == FALSE) { 312 return "Failed to open $dataFile for reading\n"; 313 } 314 return $handle; 315 } 316 317 318 /** 319 * Returns profiling information gathered using APD functions. 320 * Accepts a numerical array of command-line arguments. 321 * 322 * @usage Profiler::get_profiling($args) 323 * Sort options 324 * -a Sort by alphabetic names of subroutines. 325 * -l Sort by number of calls to subroutines 326 * -m Sort by memory used in a function call. 327 * -r Sort by real time spent in subroutines. 328 * -R Sort by real time spent in subroutines (inclusive of child calls). 329 * -s Sort by system time spent in subroutines. 330 * -S Sort by system time spent in subroutines (inclusive of child calls). 331 * -u Sort by user time spent in subroutines. 332 * -U Sort by user time spent in subroutines (inclusive of child calls). 333 * -v Sort by average amount of time spent in subroutines. 334 * -z Sort by user+system time spent in subroutines. (default) 335 * 336 * Display options 337 * -c Display Real time elapsed alongside call tree. 338 * -i Suppress reporting for php builtin functions 339 * -O <cnt> Specifies maximum number of subroutines to display. (default 15) 340 * -t Display compressed call tree. 341 * -T Display uncompressed call tree. 342 * 343 * Example array: array('-a', '-l'); 344 * 345 * @param Array $args 346 * @return String Profiling info 347 */ 348 function get_profiling($args) 349 { 350 $con = new Console_Getopt; 351 array_shift($args); 352 353 $shortoptions = 'acg:hiIlmMrRsStTuUO:vzZ'; 354 $retval = $con->getopt( $args, $shortoptions); 355 if(is_object($retval)) { 356 usage(); 357 } 358 359 $opt['O'] = 20; 360 foreach ($retval[0] as $kv_array) { 361 $opt[$kv_array[0]] = $kv_array[1]; 362 } 363 364 $DATA = Profiler::_get_pprofp(); 365 366 $cfg = array(); 367 $this->parse_info('HEADER', $DATA, $cfg); 368 369 $callstack = array(); 370 $calls = array(); 371 $indent_cur = 0; 372 $file_hash = array(); 373 $this->mem = array(); 374 $t_rtime = 0; 375 $t_stime = 0; 376 $t_utime = 0; 377 $c_rtimes = array(); 378 $this->c_stimes = array(); 379 $this->c_utimes = array(); 380 $rtimes = array(); 381 $this->stimes = array(); 382 $this->utimes = array(); 383 $rtotal = 0; 384 $stotal = 0; 385 $utotal = 0; 386 $last_memory = 0; 387 388 $symbol_hash = array(); 389 $symbol_type = array(); 390 391 while($line = fgets($DATA)) { 392 $line = rtrim($line); 393 if(preg_match("/^END_TRACE/", $line)){ 394 break; 395 } 396 list($token, $data) = preg_split("/ /",$line, 2); 397 if($token == '!') { 398 list ($index, $file) = preg_split("/ /", $data, 2); 399 $file_hash[$index] = $file; 400 continue; 401 } 402 if( $token == '&') { 403 list ($index, $name, $type) = preg_split("/ /", $data, 3); 404 $symbol_hash[$index] = $name; 405 $symbol_type[$index] = $type; 406 continue; 407 } 408 if( $token == '+') { 409 list($index, $file, $line) = preg_split("/ /",$data, 3); 410 if(array_key_exists('i',$opt) && $symbol_type[$index] == 1) { 411 continue; 412 } 413 $index_cur = $index; 414 $calls[$index_cur]++; 415 array_push($callstack, $index_cur); 416 if(array_key_exists('T', $opt)) { 417 if(array_key_exists('c', $opt)) { 418 $retstring .= sprintf("%2.02f ", $rtotal/1000000); 419 } 420 $retstring .= str_repeat(" ", $indent_cur).$symbol_hash[$index_cur]."\n"; 421 if(array_key_exists('m', $opt)) { 422 $retstring .= str_repeat(" ", $indent_cur)."C: $file_hash[$file]:$line M: $memory\n"; 423 } 424 } 425 elseif(array_key_exists('t', $opt)) { 426 if ( $indent_last == $indent_cur && $index_last == $index_cur ) { 427 $repcnt++; 428 } 429 else { 430 if ( $repcnt ) { 431 $repstr = ' ('.++$repcnt.'x)'; 432 } 433 if(array_key_exists('c', $opt)) { 434 $retstring .= sprintf("%2.02f ", $rtotal/1000000); 435 } 436 $retstring .= str_repeat(" ", $indent_last).$symbol_hash[$index_last].$repstr."\n"; 437 if(array_key_exists('m', $opt)) { 438 $retstring .= str_repeat(" ", $indent_cur)."C: $file_hash[$file_last]:$line_last M: $memory\n"; 439 } 440 $repstr = ''; 441 $repcnt = 0; 442 $index_last = $index_cur; 443 $indent_last = $indent_cur; 444 $file_last = $file; 445 $line_last = $line; 446 } 447 } 448 $indent_cur++; 449 continue; 450 } 451 if( $token == '@') { 452 list($file_no, $line_no, $ut, $st, $rt) = preg_split("/ /", $data); 453 $top = array_pop($callstack); 454 $this->utimes[$top] += $ut; 455 $utotal += $ut; 456 $this->stimes[$top] += $st; 457 $stotal += $st; 458 $rtimes[$top] += $rt; 459 $rtotal += $rt; 460 array_push($callstack, $top); 461 foreach ($callstack as $stack_element) { 462 $this->c_utimes[$stack_element] += $ut; 463 $this->c_stimes[$stack_element] += $st; 464 $c_rtimes[$stack_element] += $rt; 465 } 466 continue; 467 } 468 if ($token == '-') { 469 list ($index, $memory) = preg_split("/ /", $data, 2); 470 if(array_key_exists('i',$opt) && $symbol_type[$index] == 1) 471 { 472 continue; 473 } 474 $this->mem[$index] += ($memory - $last_memory); 475 $last_memory = $memory; 476 $indent_cur--; 477 $tmp = array_pop($callstack); 478 continue; 479 } 480 } 481 $this->parse_info('FOOTER', $DATA, $cfg); 482 $sort = 'by_time'; 483 if(array_key_exists('l', $opt)) { $sort = 'by_calls'; } 484 if(array_key_exists('m', $opt)) { $sort = 'by_mem'; } 485 if(array_key_exists('a', $opt)) { $sort = 'by_name'; } 486 if(array_key_exists('v', $opt)) { $sort = 'by_avgcpu'; } 487 if(array_key_exists('r', $opt)) { $sort = 'by_rtime'; } 488 if(array_key_exists('R', $opt)) { $sort = 'by_c_rtime'; } 489 if(array_key_exists('s', $opt)) { $sort = 'by_stime'; } 490 if(array_key_exists('S', $opt)) { $sort = 'by_c_stime'; } 491 if(array_key_exists('u', $opt)) { $sort = 'by_utime'; } 492 if(array_key_exists('U', $opt)) { $sort = 'by_c_utime'; } 493 if(array_key_exists('Z', $opt)) { $sort = 'by_c_time'; } 494 if( !count($symbol_hash)) { 495 continue; 496 } 497 498 $retstring .= sprintf(" 499 Trace for %s 500 Total Elapsed Time = %4.2f 501 Total System Time = %4.2f 502 Total User Time = %4.2f 503 ", $cfg['caller'], $rtotal/1000000, $stotal/1000000, $utotal/1000000); 504 505 $retstring .= "\n 506 Real User System secs/ cumm 507 %Time (excl/cumm) (excl/cumm) (excl/cumm) Calls call s/call Memory Usage Name 508 --------------------------------------------------------------------------------------\n"; 509 $l = 0; 510 $itotal = 0; 511 $percall = 0; 512 $cpercall = 0; 513 514 uksort($symbol_hash, $sort); 515 foreach (array_keys($symbol_hash) as $j) { 516 if(array_key_exists('i', $opt) && $symbol_type[$j] == 1) { 517 continue; 518 } 519 if ($l++ < $opt['O']) { 520 $pcnt = 100*($this->stimes[$j] + $this->utimes[$j])/($utotal + $stotal + $itotal); 521 $c_pcnt = 100* ($this->c_stimes[$j] + $this->c_utimes[$j])/($utotal + $stotal + $itotal); 522 $rsecs = $rtimes[$j]/1000000; 523 $ssecs = $this->stimes[$j]/1000000; 524 $usecs = $this->utimes[$j]/1000000; 525 $c_rsecs = $c_rtimes[$j]/1000000; 526 $c_ssecs = $this->c_stimes[$j]/1000000; 527 $c_usecs = $this->c_utimes[$j]/1000000; 528 $ncalls = $calls[$j]; 529 if(array_key_exists('z', $opt)) { 530 $percall = ($usecs + $ssecs)/$ncalls; 531 $cpercall = ($c_usecs + $c_ssecs)/$ncalls; 532 if($utotal + $stotal) { 533 $pcnt = 100*($this->stimes[$j] + $this->utimes[$j])/($utotal + $stotal); 534 } 535 else { 536 $pcnt = 100; 537 } 538 } 539 if(array_key_exists('Z', $opt)) { 540 $percall = ($usecs + $ssecs)/$ncalls; 541 $cpercall = ($c_usecs + $c_ssecs)/$ncalls; 542 if($utotal + $stotal) { 543 $pcnt = 100*($this->c_stimes[$j] + $this->c_utimes[$j])/($utotal + $stotal); 544 } 545 else { 546 $pcnt = 100; 547 } 548 } 549 if(array_key_exists('r', $opt)) { 550 $percall = ($rsecs)/$ncalls; 551 $cpercall = ($c_rsecs)/$ncalls; 552 if($rtotal) { 553 $pcnt = 100*$rtimes[$j]/$rtotal; 554 } 555 else { 556 $pcnt = 100; 557 } 558 } 559 if(array_key_exists('R', $opt)) { 560 $percall = ($rsecs)/$ncalls; 561 $cpercall = ($c_rsecs)/$ncalls; 562 if($rtotal) { 563 $pcnt = 100*$c_rtimes[$j]/$rtotal; 564 } 565 else { 566 $pcnt = 100; 567 } 568 } 569 if(array_key_exists('u', $opt)) { 570 $percall = ($usecs)/$ncalls; 571 $cpercall = ($c_usecs)/$ncalls; 572 if($utotal) { 573 $pcnt = 100*$this->utimes[$j]/$utotal; 574 } 575 else { 576 $pcnt = 100; 577 } 578 } 579 if(array_key_exists('U', $opt)) { 580 $percall = ($usecs)/$ncalls; 581 $cpercall = ($c_usecs)/$ncalls; 582 if($utotal) { 583 $pcnt = 100*$this->c_utimes[$j]/$utotal; 584 } 585 else { 586 $pcnt = 100; 587 } 588 } 589 if(array_key_exists('s', $opt)) { 590 $percall = ($ssecs)/$ncalls; 591 $cpercall = ($c_ssecs)/$ncalls; 592 if($stotal) { 593 $pcnt = 100*$this->stimes[$j]/$stotal; 594 } 595 else { 596 $pcnt = 100; 597 } 598 } 599 if(array_key_exists('S', $opt)) { 600 $percall = ($ssecs)/$ncalls; 601 $cpercall = ($c_ssecs)/$ncalls; 602 if($stotal) { 603 $pcnt = 100*$this->c_stimes[$j]/$stotal; 604 } 605 else { 606 $pcnt = 100; 607 } 608 } 609 // $cpercall = ($c_usecs + $c_ssecs)/$ncalls; 610 $mem_usage = $this->mem[$j]; 611 $name = $symbol_hash[$j]; 612 $retstring .= sprintf("%3.01f %2.02f %2.02f %2.02f %2.02f %2.02f %2.02f %4d %2.04f %2.04f %12d %s\n", 613 $pcnt, $rsecs, $c_rsecs, $usecs, $c_usecs, $ssecs, $c_ssecs, $ncalls, $percall, $cpercall, $mem_usage, $name); 614 return $retstring; 615 } 616 } 617 return $retstring; 618 } 619 620 function usage() { 621 return <<<EOD 622 Profiler::get_profiling(\$args) 623 Sort options 624 -a Sort by alphabetic names of subroutines. 625 -l Sort by number of calls to subroutines 626 -m Sort by memory used in a function call. 627 -r Sort by real time spent in subroutines. 628 -R Sort by real time spent in subroutines (inclusive of child calls). 629 -s Sort by system time spent in subroutines. 630 -S Sort by system time spent in subroutines (inclusive of child calls). 631 -u Sort by user time spent in subroutines. 632 -U Sort by user time spent in subroutines (inclusive of child calls). 633 -v Sort by average amount of time spent in subroutines. 634 -z Sort by user+system time spent in subroutines. (default) 635 636 Display options 637 -c Display Real time elapsed alongside call tree. 638 -i Suppress reporting for php builtin functions 639 -O <cnt> Specifies maximum number of subroutines to display. (default 15) 640 -t Display compressed call tree. 641 -T Display uncompressed call tree. 642 643 EOD; 644 exit(1); 645 } 646 647 function parse_info($tag, $datasource, &$cfg) { 648 while($line = fgets($datasource)) { 649 $line = rtrim($line); 650 if(preg_match("/^END_$tag$/", $line)) { 651 break; 652 } 653 if(preg_match("/(\w+)=(.*)/", $line, $matches)) { 654 $cfg[$matches[1]] = $matches[2]; 655 } 656 } 657 } 658 659 function num_cmp($a, $b) { 660 if (intval($a) > intval($b)) { return 1;} 661 elseif(intval($a) < intval($b)) { return -1;} 662 else {return 0;} 663 } 664 665 function by_time($a,$b) { 666 return $this->num_cmp(($this->stimes[$b] + $this->utimes[$b]),($this->stimes[$a] + $this->utimes[$a])); 667 } 668 669 function by_c_time($a,$b) { 670 return $this->num_cmp(($this->c_stimes[$b] + $this->c_utimes[$b]),($this->c_stimes[$a] + $this->c_utimes[$a])); 671 } 672 673 function by_avgcpu($a,$b) { 674 return $this->num_cmp(($this->stimes[$b] + $this->utimes[$b])/$this->calls[$b],($this->stimes[$a] + $this->utimes[$a])/$this->calls[$a]); 675 } 676 677 function by_calls($a, $b) { 678 return $this->num_cmp($this->calls[$b], $this->calls[$a]); 679 } 680 681 function by_rtime($a,$b) { 682 return $this->num_cmp($this->rtimes[$b], $this->rtimes[$a]); 683 } 684 685 function by_c_rtime($a,$b) { 686 return $this->num_cmp($this->c_rtimes[$b], $this->c_rtimes[$a]); 687 } 688 689 function by_stime($a,$b) { 690 return $this->num_cmp($this->stimes[$b], $this->stimes[$a]); 691 } 692 693 function by_c_stime($a,$b) { 694 return $this->num_cmp($this->c_stimes[$b], $this->c_stimes[$a]); 695 } 696 697 function by_utime($a,$b) { 698 return $this->num_cmp($this->utimes[$b], $this->utimes[$a]); 699 } 700 701 function by_c_utime($a,$b) { 702 return $this->num_cmp($this->c_utimes[$b], $this->c_utimes[$a]); 703 } 704 705 function by_mem($a, $b) { 706 return $this->num_cmp($this->mem[$b], $this->mem[$a]); 707 } 708 } 709 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Jan 14 11:33:29 2009 | Cross-referenced by PHPXref 0.7 |