예제 #1
0
abstract class CommandLine extends Enum
{
    public static $WINDOWS, $UNIX;
    static function __static()
    {
        self::$WINDOWS = new class(0, 'WINDOWS') extends CommandLine
        {
            static function __static()
            {
            }
            public function parse($cmd)
            {
                static $triple = '"""';
                $parts = [];
                $r = '';
                for ($i = 0, $s = strlen($cmd); $i < $s; $i++) {
                    if (' ' === $cmd[$i]) {
                        $parts[] = $r;
                        $r = '';
                    } else {
                        if ('"' === $cmd[$i]) {
                            $q = $i + 1;
                            do {
                                if (false === ($p = strpos($cmd, '"', $q))) {
                                    $q = $s;
                                    break;
                                }
                                $q = $p;
                                if ($triple === substr($cmd, $q, 3)) {
                                    if (false === ($p = strpos($cmd, $triple, $q + 3))) {
                                        $q = $q + 3;
                                        continue;
                                    }
                                    $q = $p + 3;
                                    continue;
                                }
                                break;
                            } while ($q < $s);
                            $r .= str_replace($triple, '"', substr($cmd, $i + 1, $q - $i - 1));
                            $i = $q;
                        } else {
                            $r .= $cmd[$i];
                        }
                    }
                }
                $parts[] = $r;
                return $parts;
            }
            protected static function quote($arg)
            {
                $l = strlen($arg);
                if ($l && strcspn($arg, '" ') >= $l) {
                    return $arg;
                }
                return '"' . str_replace('"', '"""', $arg) . '"';
            }
            public function compose($command, $arguments = [])
            {
                $cmd = self::quote($command);
                foreach ($arguments as $arg) {
                    $cmd .= " " . self::quote($arg);
                }
                return $cmd;
            }
        };
        self::$UNIX = new class(1, 'UNIX') extends CommandLine
        {
            static function __static()
            {
            }
            public function parse($cmd)
            {
                $parts = [];
                $o = 0;
                $l = strlen($cmd);
                while ($o < $l) {
                    $p = strcspn($cmd, ' ', $o);
                    $option = substr($cmd, $o, $p);
                    if (1 === substr_count($option, '"')) {
                        $ql = $o + $p;
                        $qp = strpos($cmd, '"', $ql) + 1;
                        $option .= substr($cmd, $ql, $qp - $ql);
                        $o = $qp + 1;
                    } else {
                        if (1 === substr_count($option, "'")) {
                            $ql = $o + $p;
                            $qp = strpos($cmd, "'", $ql) + 1;
                            $option .= substr($cmd, $ql, $qp - $ql);
                            $o = $qp + 1;
                        } else {
                            $o += $p + 1;
                        }
                    }
                    if ('"' === $option[0] || "'" === $option[0]) {
                        $option = substr($option, 1, -1);
                    }
                    $parts[] = $option;
                }
                return $parts;
            }
            protected static function quote($arg)
            {
                $l = strlen($arg);
                if ($l && strcspn($arg, "&;`\\'\"|*?~<>^()[]{}\$ ") >= $l) {
                    return $arg;
                }
                return "'" . str_replace("'", "'\\''", $arg) . "'";
            }
            public function compose($command, $arguments = [])
            {
                $cmd = self::quote($command);
                foreach ($arguments as $arg) {
                    $cmd .= ' ' . self::quote($arg);
                }
                return $cmd;
            }
        };
    }
    /**
     * Returns the command line implementation for the given operating 
     * system.
     *
     * @param   string os operating system name, e.g. PHP_OS
     * @return  lang.CommandLine
     */
    public static function forName(string $os) : self
    {
        if (0 === strncasecmp($os, 'Win', 3)) {
            return self::$WINDOWS;
        } else {
            return self::$UNIX;
        }
    }
    /**
     * Parse command line
     *
     * @param   string cmd
     * @return  string[] parts
     */
    public abstract function parse($cmd);
    /**
     * Build command line from a command and - optionally - arguments
     *
     * @param   string command
     * @param   string[] arguments default []
     * @return  string
     */
    public abstract function compose($command, $arguments = []);
}
예제 #2
0
 static function __static()
 {
     self::$WINDOWS = newinstance(__CLASS__, [0, 'WINDOWS'], '{
   static function __static() { }
   public function parse($cmd) {
     static $triple= "\\"\\"\\"";
     $parts= [];
     $r= "";
     for ($i= 0, $s= strlen($cmd); $i < $s; $i++) {
       if (" " === $cmd{$i}) {
         $parts[]= $r;
         $r= "";
       } else if ("\\"" === $cmd{$i}) {
         $q= $i+ 1;
         do {
           if (FALSE === ($p= strpos($cmd, "\\"", $q))) {
             $q= $s;
             break;
           }
           $q= $p;
           if ($triple === substr($cmd, $q, 3)) {
             if (FALSE === ($p= strpos($cmd, $triple, $q+ 3))) {
               $q= $q+ 3;
               continue;
             }
             $q= $p+ 3;
             continue;
           }
           break;
         } while ($q < $s);
         $r.= str_replace($triple, "\\"", substr($cmd, $i+ 1, $q- $i- 1));
         $i= $q;
       } else {
         $r.= $cmd{$i};
       }
     }
     $parts[]= $r;
     return $parts;
   }
   
   protected static function quote($arg) {
     $l= strlen($arg);
     if ($l && strcspn($arg, "\\" ") >= $l) return $arg;
     return \'"\'.str_replace(\'"\', \'"""\', $arg).\'"\';
   }
   
   public function compose($command, $arguments= []) {
     $cmd= self::quote($command);
     foreach ($arguments as $arg) {
       $cmd.= " ".self::quote($arg);
     }
     return $cmd;
   }
 }');
     self::$UNIX = newinstance(__CLASS__, [1, 'UNIX'], '{
   static function __static() { }
   public function parse($cmd) {
     $parts= [];
     $o= 0;
     $l= strlen($cmd);
     while ($o < $l) {
       $p= strcspn($cmd, " ", $o);
       $option= substr($cmd, $o, $p);
       if (1 === substr_count($option, \'"\')) {
         $ql= $o+ $p;
         $qp= strpos($cmd, \'"\', $ql)+ 1;
         $option.= substr($cmd, $ql, $qp- $ql);
         $o= $qp+ 1;
       } else if (1 === substr_count($option, "\'")) {
         $ql= $o+ $p;
         $qp= strpos($cmd, "\'", $ql)+ 1;
         $option.= substr($cmd, $ql, $qp- $ql);
         $o= $qp+ 1;
       } else {
         $o+= $p+ 1;
       }
       if (\'"\' === $option{0} || "\'" === $option{0}) $option= substr($option, 1, -1);
       $parts[]= $option;
     }
     return $parts;
   }
   
   protected static function quote($arg) {
     $l= strlen($arg);
     if ($l && strcspn($arg, "&;`\'\\"|*?~<>^()[]{}\\$ ") >= $l) return $arg;
     return "\'".str_replace("\'", "\'\\\'\'", $arg)."\'";
   }
   
   public function compose($command, $arguments= []) {
     $cmd= self::quote($command);
     foreach ($arguments as $arg) {
       $cmd.= " ".self::quote($arg);
     }
     return $cmd;
   }
 }');
 }