[php内核分析]php_getopt函数

10 篇文章 0 订阅

头文件:

#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);
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值