= count($args)){ return false; } else { $num += 1; return $args[$num]; } }; // all types & subtypes $types_subtypes = ['S' => 'stcr', 'V' => 'smar', 'O' => 'smar', 'A' => 'sr']; // output $Ores = []; $Oerr = []; $Oags = []; // parsed options $short = []; $long = []; $type = []; // parse options foreach($params AS $opt => $names){ if(is_string($names)){ $names = preg_split('/ +/', $names); } if(!is_array($names) || count($names) < 2){ trigger_error('Invalid type/name(s) to param "'.$opt.'"', E_USER_ERROR); } $ty = array_shift($names); if(!is_string($ty) || mb_strlen($ty) < 1 || mb_strlen($ty) > 2){ trigger_error('Invalid type to param "'.$opt.'"', E_USER_ERROR); } $ty0 = $ty[0]; if(!isset($types_subtypes[$ty0])){ trigger_error('Invalid type to param "'.$opt.'"', E_USER_ERROR); } if(mb_strlen($ty) == 1){ $ty1 = $types_subtypes[$ty0][0]; }else{ $ty1 = $ty[1]; if(mb_strpos($types_subtypes[$ty0], $ty1) === false){ trigger_error('Invalid type to param "'.$opt.'"', E_USER_ERROR); } } $type[$opt] = $ty0.$ty1; foreach($names AS $name){ if(!is_string($name)){ trigger_error('Invalid names to param "'.$opt.'"', E_USER_ERROR); } if(!preg_match('!^(-)?([0-9a-zA-Z]+)$!', $name, $r)){ trigger_error('Invalid name to param "'.$opt.'"', E_USER_ERROR); } if($r[1] == '-' || mb_strlen($r[2]) > 1){ if(isset($long[$r[2]])){ trigger_error('Duplicate option name "'.$r[2].'"', E_USER_ERROR); } $long[$r[2]] = $opt; }else{ if(isset($short[$r[2]])){ trigger_error('Duplicate option name "'.$r[2].'"', E_USER_ERROR); } $short[$r[2]] = $opt; } } $Ores[$opt] = []; } // parse arguments for($num=0; $num skip continue; }else if($arg[0] != '-'){ // not an option -> copy to args $Oags[] = $arg; continue; } // this arg is an option! if($arg[1] == '-'){ // long option $p = mb_strpos($arg, '='); if($p !== false){ $next = $mb_substr($arg, $p+1); $arg = mb_substr($arg, 2, $p-2); }else{ $next = true; $arg = mb_substr($arg, 2); } if(!isset($long[$arg])){ $Oerr[] = 'Unknown option "--'.$arg.'"'; }else{ $opt = $long[$arg]; $Earg = '--'.$arg; switch($type[$opt][0]){ case 'S': $Ores[$opt][] = $next; break; case 'V': if(($val = $get_arg($next,$args,$num)) === false){ $Oerr[] = 'Missing artument to option "'.$Earg.'"'; }else{ $Ores[$opt][] = $val; } break; case 'O': $Ores[$opt][] = $next; break; case 'A': if(($val = $get_arg($next,$args,$num)) === false){ $Oerr[] = 'Missing artument to option "'.$Earg.'"'; }else{ $p = mb_strpos($val, '='); if($p === false){ $Oerr[] = 'Malformed artument to option "'.$Earg.'" (a "=" is missing)'; }else if(isset($Ores[$opt][mb_substr($val, 0, $p)])){ $Oerr[] = 'Duplicate key "'.mb_substr($val, 0, $p).'" to option "'.$Earg.'"'; }else{ $Ores[$opt][mb_substr($val, 0, $p)] = $mb_substr($val, $p+1); } } break; } } }else{ // short option(s) for($i=1; $i &$r){ switch($type[$opt]){ case 'Ss': $r = count($r) > 0; break; case 'St': $r = (count($r) & 1) == 1; break; case 'Sc': $r = count($r); break; case 'Vs': if(count($r) == 0){ // no option $r = false; }else{ // pick last entry $r = array_pop($r); } break; case 'Os': if(count($r) == 0){ // no option $r = false; }else{ // pick last entry; if possible last used (non true) entry do{ $rr = array_pop($r); }while($rr === true && count($r) > 0); $r = $rr; } break; case 'Vm': case 'Om': if(count($r) == 0){ // no option $r = false; }else{ // as array // (already done) } break; case 'Va': case 'Oa': // false if none, direct (string) if only one, array otherwise if(count($r) == 0){ // no option $r = false; }else if(count($r) == 1){ // a single option $r = array_pop($r); }else{ // as array // (already done) } break; case 'As': // as array // (already done) break; } } } // errors? if(count($Oerr) == 0){ $Oerr = false; } // result return [$Oerr, $Ores, $Oags]; } ?>