我正在尝试实现类似于 FFmpeg 的选项处理。具体来说,我想支持两种类型的调色板选项:
直接调色板规格:
-p "255,0,0 0,255,0"
配置文件调色板:
-p:c blackwhite
与 FFmpeg 处理编解码器选项的方式类似:
ffmpeg -i input.mp4 -c:v libx264 -c:a copy output.mp4
目前,我的代码使用 getopt:
static struct option long_options[] = {
{"palette", required_argument, 0, 'p'},
// other options...
};
int main(int argc, char** argv) {
while ((c = getopt_long(argc, argv, "p:h", long_options, &option_index)) != -1) {
switch (c) {
case 'p':
if (optarg[0] == 'c' && optarg[1] == ':') {
// This doesn't work as intended - optarg becomes ":c"
load_palette_from_config(optarg + 2);
} else {
parse_numeric_palette(optarg);
}
break;
}
}
}
问题在于,当使用
-p:c blackwhite
时,getopt将:c
视为-p
的参数,导致调色板加载失败。
有没有办法使用 getopt 实现这种类似 FFmpeg 的选项处理?
getopt 旨在解析简单的单字符命令行选项。 如果您检查使用更复杂选项的二进制文件的代码,例如 ffmpeg,您将看到它们在不使用 getopt 的情况下传递命令行。
您仍然可以使用 getopt 作为您的案例示例。 当您使用“p:h”时,您必须预期“cmd -p:c foobar”将导致“:c”作为 optarg 返回。 在这种情况下,您必须通过检查 argv[optind] 并在下一次迭代之前增加 opting 来从 arglist 中剥离下一个值。 你的“如果”部分应该看起来像......
if (optarg[0] == ':' && optarg[1] == 'c') {
if (!(optind < argc )) panic(BAD_ARGV);
if (! valid_color(argv[optind])) panic(BAD_ARGV);
load_palette_from_config(argv[optind]);
optind++;
} else { ...