214 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			214 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| 	class Cli {
 | |
| 		
 | |
| 		private function __construct() {}
 | |
| 		
 | |
| 		/**
 | |
| 		 * Parses command line arguments
 | |
| 		 *
 | |
| 		 * @param  array $args
 | |
| 		 * @return array
 | |
| 		 */
 | |
| 		public static function parseArgs(array $args, CliSwitchCollection $switches) {
 | |
| 			$parsed = array(
 | |
| 				'switches' => array(),
 | |
| 				'args'     => array()
 | |
| 			);
 | |
| 			
 | |
| 			$last = null;
 | |
| 			foreach ($args as $arg) {
 | |
| 				if (strpos($arg, '-') === 0) {
 | |
| 					$last = (substr($arg, 0, 2) === '--') ? substr($arg, 2) : substr($arg, 1);
 | |
| 					$switch = $switches->getSwitch($last);
 | |
| 					if ($switch !== null) {
 | |
| 						$parsed['switches'][$switch->longName] = true;
 | |
| 					}
 | |
| 				} else if ($switch !== null) {
 | |
| 					if ($switch->value !== null) {
 | |
| 						$parsed['switches'][$switch->longName] = $arg;
 | |
| 					} else {
 | |
| 						$parsed['args'][] = $arg;
 | |
| 					}
 | |
| 					
 | |
| 					$switch = null;
 | |
| 				} else {
 | |
| 					$parsed['args'][] = $arg;
 | |
| 				}
 | |
| 			}
 | |
| 			
 | |
| 			return $parsed;
 | |
| 		}
 | |
| 		
 | |
| 	}
 | |
| 	
 | |
| 	class CliSwitch {
 | |
| 		public $longName;
 | |
| 		public $shortName;
 | |
| 		public $required;
 | |
| 		public $value;
 | |
| 		public $description;
 | |
| 		
 | |
| 		public function __construct($longName, $shortName = '', $required = true, $value = null, $description = '') {
 | |
| 			$this->longName = $longName;
 | |
| 			$this->shortName = $shortName;
 | |
| 			$this->required = $required;
 | |
| 			$this->value = $value;
 | |
| 			$this->description = $description;
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	class CliSwitchCollection implements IteratorAggregate {
 | |
| 		
 | |
| 		private $switches;
 | |
| 		
 | |
| 		public function __construct() {
 | |
| 			$this->switches = array();
 | |
| 		}
 | |
| 		
 | |
| 		public function addSwitch(CliSwitch $switch) {
 | |
| 			$this->switches[] = $switch;
 | |
| 			return $this;
 | |
| 		}
 | |
| 		
 | |
| 		public function getSwitch($longOrShortName) {
 | |
| 			foreach ($this->switches as $switch) {
 | |
| 				if ($switch->longName == $longOrShortName || $switch->shortName == $longOrShortName) {
 | |
| 					return $switch;
 | |
| 				}
 | |
| 			}
 | |
| 			
 | |
| 			return null;
 | |
| 		}
 | |
| 		
 | |
| 		public function segregateSwitches() {
 | |
| 			$switches = array(
 | |
| 				'required' => array(),
 | |
| 				'optional' => array()
 | |
| 			);
 | |
| 			foreach ($this->switches as $switch) {
 | |
| 				if ($switch->required) {
 | |
| 					$switches['required'][] = $switch;
 | |
| 				} else {
 | |
| 					$switches['optional'][] = $switch;
 | |
| 				}
 | |
| 			}
 | |
| 			
 | |
| 			return $switches;
 | |
| 		}
 | |
| 		
 | |
| 		public function getIterator() {
 | |
| 			return new ArrayIterator($this->switches);
 | |
| 		}
 | |
| 		
 | |
| 	}
 | |
| 
 | |
| 	class Usage {
 | |
| 		
 | |
| 		private $switches;
 | |
| 		private $name;
 | |
| 		private $script;
 | |
| 		private $description;
 | |
| 		private $copyright;
 | |
| 		private $maxSwitchLength;
 | |
| 		
 | |
| 		const LINE_LENGTH = 80;
 | |
| 		
 | |
| 		public function __construct($name, $script, $description, $author = null, $date = null) {
 | |
| 			$this->switches = array(array(), array());
 | |
| 			$this->maxSwitchLength = 0;
 | |
| 			$this->script = $script;
 | |
| 			$this->name = $name;
 | |
| 			$this->description = $description;
 | |
| 			$this->copyright = 
 | |
| 				($date !== null)
 | |
| 				? 'Copyright (c) ' . $date . (($author !== null) ? " $author" : '')
 | |
| 				: (($author !== null) ? "by $author" : '');
 | |
| 		}
 | |
| 		
 | |
| 		public function __get($key) {
 | |
| 			if ($key === 'switches') {
 | |
| 				return $this->switches;
 | |
| 			}
 | |
| 			
 | |
| 			throw new InvalidArgumentException('Invalid property');
 | |
| 		}
 | |
| 		
 | |
| 		public function setSwitches(CliSwitchCollection $switches) {
 | |
| 			$this->switches = $switches;
 | |
| 			
 | |
| 			$this->maxSwitchLength = 0;
 | |
| 			foreach ($switches->getIterator() as $switch) {
 | |
| 				// + 2 for left padding
 | |
| 				// + 2 for double-hyphen
 | |
| 				$length = 2 + strlen($switch->longName) + 2;
 | |
| 				
 | |
| 				// + 1 for left padding
 | |
| 				// + 1 for hyphen
 | |
| 				// + 1 for openening parenthesis
 | |
| 				// + 1 for closing parenthesis
 | |
| 				$length += (strlen($switch->shortName) > 0) ? 1 + 1 + 1 + strlen($switch->shortName) + 1 : 0;
 | |
| 				//echo $length . "\n";
 | |
| 				$this->maxSwitchLength = max($this->maxSwitchLength, $length);
 | |
| 			}
 | |
| 			
 | |
| 			//echo $this->maxSwitchLength; exit;
 | |
| 		}
 | |
| 		
 | |
| 		public function __toString() {
 | |
| 			$this->maxSwitchLength += 2;
 | |
| 			$usage  = $this->name . "\n";
 | |
| 			$usage .= (!empty($this->copyright)) ? '  ' . $this->copyright . "\n" : '';
 | |
| 			$usage .= "\n";
 | |
| 			
 | |
| 			$usage .= "USAGE\n";
 | |
| 			$usageData = '  php ' . $this->script;
 | |
| 			
 | |
| 			$switchData = "REQUIRED\n";
 | |
| 			
 | |
| 			$switches = $this->switches->segregateSwitches();
 | |
| 			
 | |
| 			foreach ($switches['required'] as $switch) {
 | |
| 				$usageData .= ' --' . $switch->longName;
 | |
| 				if ($switch->value !== null) {
 | |
| 					$usageData .= ' ' . $switch->value;
 | |
| 				}
 | |
| 				
 | |
| 				$x = '  --' . $switch->longName;
 | |
| 				if (!empty($switch->shortName)) {
 | |
| 					$x .= str_repeat(' ', $this->maxSwitchLength - 5 - strlen($x)) . '(-' . $switch->shortName . ')';
 | |
| 				}
 | |
| 				
 | |
| 				$x .= str_repeat(' ' , $this->maxSwitchLength - strlen($x));
 | |
| 				$x .= wordwrap($switch->description, self::LINE_LENGTH - strlen($x), "\n" . str_repeat(' ', strlen($x))) . "\n";
 | |
| 				$switchData .= $x;
 | |
| 			}
 | |
| 			
 | |
| 			$switchData .= "\nOPTIONAL\n";
 | |
| 			foreach ($switches['optional'] as $switch) {
 | |
| 				$usageData .= ' [--' . $switch->longName;
 | |
| 				if ($switch->value !== null) {
 | |
| 					$usageData .= ' ' . $switch->value;
 | |
| 				}
 | |
| 				$usageData .= ']';
 | |
| 				
 | |
| 				$x = '  --' . $switch->longName;
 | |
| 				if (!empty($switch->shortName)) {
 | |
| 					$x .= str_repeat(' ', $this->maxSwitchLength - 5 - strlen($x)) . '(-' . $switch->shortName . ')';
 | |
| 				}
 | |
| 				
 | |
| 				$x .= str_repeat(' ' , $this->maxSwitchLength - strlen($x));
 | |
| 				$x .= wordwrap($switch->description, self::LINE_LENGTH - strlen($x), "\n" . str_repeat(' ', strlen($x))) . "\n";
 | |
| 				$switchData .= $x;
 | |
| 			}
 | |
| 			
 | |
| 			$usage .= wordwrap($usageData, self::LINE_LENGTH - 2, "\n  ");
 | |
| 			
 | |
| 			$usage .= "\n\n" . $switchData . "\n";
 | |
| 			
 | |
| 			return $usage;
 | |
| 		}
 | |
| 		
 | |
| 	}
 | |
| 	
 | |
| ?>
 |