头文件:
#include "php_getopt.h"
源代码:
PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg,
int *optind, int show_err, int arg_start){
static int optchr = 0;
static int dash = 0; /* have already seen the - */
static char **prev_optarg = NULL;
php_optidx = -1;//全局变量,在成功匹配后外部程序可以知道匹配到哪个参数类型
if(prev_optarg && prev_optarg != optarg) {
/* reset the state */
optchr = 0;
dash = 0;
}
prev_optarg = optarg;
if(*optind >= argc){
return (EOF);
}
if(!dash){//上一个或当前参数没有以-开头
if((argv[*optind][0] != '-')){//一个或一对参数必须是以-开头的
return (EOF);
}else{
if(!argv[*optind][1]){//参数就一个-
return (EOF);
}
}
}
if((argv[*optind][0]=='-') && (argv[*optind][1] == '-')){//参数以--开头
char *pos;
int arg_end = strlen(argv[*optind])-1;
if(argv[*optind][2] == '\0'){//空有两个-,则进行下一个区配
(*optind)++;
return (EOF);
}
arg_start = 2;//查找'='从第2个字符开始
if((pos = php_memnstr(&argv[*optind][arg_start], "=", 1, argv[*optind]+arg_end)) != NULL){
arg_end = pos - &argv[*optind][arg_start];//第一个参数的结束位置索引
arg_start++;
}else{
arg_end--;//没找着=号
}
while(1){
php_optidx++;//遍历opts,直到找到与opt_name相同的一项
if(opts[php_optidx].opt_char == '-'){//-是最后一项,表示没找着
(*optind)++;
return (php_opt_error(argc, argv, *optind - 1, optchr, OPTERRARG, show_err));
}else if(opts[php_optidx].opt_name && !strncmp(&argv[*optind][2], opts[php_optidx].opt_name, arg_end)
&& arg_end == strlen(opts[php_optidx].opt_name)){
break;
}
}
}else{
if(!dash){
dash = 1;//可以确定参数第一个字符是-
optchr = 1;//参数的有效字符是索引为1
}
if(argv[*optind][optchr] == ':'){//以-:开头的参数无效
dash = 0;
(*optind)++;
return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
}
arg_start = 1 + optchr;//参数的值的位置,因为参数只有一个字符,所以+1即可
}
if(php_optidx < 0){
while(1){
php_optidx++;
if(opts[php_optidx].opt_char == '-'){
int errind = *optind;
int errchr = optchr;
if(!argv[*optind][optchr+1]){
dash = 0;
(*optind)++;
}else{
optchr++;
arg_start++;
}
return (php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
}else if(argv[*optind][optchr] == opt[php_optidx].opt_char){
break;
}
}
}
//到此说明已经找到匹配的opts[php_optidx].opt_char
if(opts[php_optidx].need_param){//需要参数
dash = 0;
if(!argv[*optind][arg_start]){//针对-<arg> <val>模式
(*optind)++;
if(*optind == argc){
if(opts[php_optidx].need_param == 1){
return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
}
}else if(opts[php_optidx].need_param == 1){
*optarg = argv[(*optind)++];//本指针指向value部分
}
}else if(argv[*optind][arg_start] == '='){//针对-<arg>=<varl>模式
arg_start++;
*optarg = &argv[*optind][arg_start];
(*optind)++;
}else{//针对 -<arg><val>模式
*optarg = &argv[*optind][arg_start];
(*optind)++;
}
return opts[php_optidx].opt_char;
}else{
if(arg_start >=2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))){//本参数不需要值
if(!argv[*optind][optchr+1]){
dash = 0;
(*optind)++;
}else{
optchr++;
}
}
return opts[php_optidx].opt_char;
}
assert(0);
return (0);
}