函数实现原型:
uint32_t
getopt32(char **argv, const char *applet_opts, ...)
参数说明:
applet_opts
:命令行选项必须声明为类似const char *applet_opts的字符串形式,如果其中一个选项被找到了, 就有一个标志值(unsigned long类型)中的某一位被置为1,
最终这个标志值被作为返回值返回,标志值在哪一个位由字符在applet_opts种的位置决定
。
最新代码链接:https://git.busybox.net/busybox/tree/libbb/getopt32.c
注:本文所用的代码是https://git.busybox.net/busybox/snapshot/busybox-1_8_2.tar.gz
例如:
uint32_t
flags = getopt32(argv, "rnug");
applet_opts
= "rnug
"
applet_opts[0]
=
"r"将添加1 (0比特位) 1<0
applet_opts
[1] = "n"将添加2 (1比特位) 1<1
applet_opts
[2] = "u"将添加4 (2比特位) 1<2
applet_opts
[3] = "g"讲添加8 (3比特位) 1<3
等等, 你也可以通过位域方式查看返回值,每个选项就是其中一位.
一旦退出, 全局变量optind就被设置,因此如果你做argc -= optind; argv+= optind; argc就会等于剩下的非选项的参数个数,
第一个放在argv[0],下一个放在argv[1]等等(选项和它们的参数在argv[optind]之前都会被移到argv[]中).
applet_opts格式的说明(特殊字符代表不同的意思):
":" 如果一个选项需要一个参数, 那就在applet_opts字符后面添加":"然后提供指向参数的指针. 例如:
char *pointer_to_arg_for_a;
char *pointer_to_arg_for_b;
char *pointer_to_arg_for_c;
char *pointer_to_arg_for_d;
flags = getopt32(argv, "a:b:c:d:",
&pointer_to_arg_for_a, &pointer_to_arg_for_b,
&pointer_to_arg_for_c, &pointer_to_arg_for_d);
applet_opts
= "a:b:c:d:"
;
代码块1
...........
while (*s) {
if (c >= 32) break;// sizeof(uint32_t)=4B=32b
on_off->opt = *s;
on_off->switch_on = (1 << c);//c是字符出现的位置也就是index
if (*++s == ':') {//c: c->arg = va_arg 当一个字符后面加:此时会给这个选项加一个返回值,也就是pointer_to_arg_for_a
等等
on_off->optarg = va_arg(p, void **);
while (*++s == ':') /* skip */;
}
on_off++;
c++;
}
............
指针类型(char* 或 llist_t *)可以由"::"特殊分隔符控制,该分隔符由外部字符串opt_complementary设置(详细信息请看下面)
"::" 如果选项有一个可选参数, 那就在applet_opts字符后面添加一个"::"并提供一个存储参数的指针. 注意可选参数必需紧跟着选项: -oparam而不是-o param.
"+" 如果applet_opts字符串第一个字符是加号, 那就argv数组中一旦遇上非选项字符就马上停止选项处理. 对于像env那样的applet就不会处理参数为子程序了: env -i ls -d /
这里我们希望env仅仅处理'-i'不是'-d'.
函数内部实现(代码截取)
uint32_t
getopt32(char **argv, const char *applet_opts, ...)
代码部分基本可以分成四个处理块:
1.applet_opts
代码块,这个可以看上面关于参数的说明
2.applet_long_options
代码块处理
const char *applet_long_options
该结构体允许你定义长选项:
static const char applet_longopts[] ALIGN1 =
//"name" has_arg val
"verbose" No_argument "v";
applet_long_options = applet_longopts;
结构体的最后一个成员(val)通常在applet_opts里面设置用来匹配短选项. 如果在applet_opts里面没有匹配到, 如是:
– 短选项的下一个位置的比特数
– 如果has_arg不是"No_argument", 也可以使用ptr作为参数
– opt_complementary也可以影响到它.
注意: 一个好的applet可以让长参数可配置,通过配置处理而不是必需的特征. 当前标准命名配置选项为CONFIG_FEATURE_