利用argp_parse制作工具
```c
#include <stdio.h>
#include <stdlib.h>
#include <argp.h>
const char *argp_program_version = "heljaolj";
struct argp_option options[] =
{
{ "dot", 'd', "NUM", OPTION_ARG_OPTIONAL, "Show some dots on the screen"},
{ 0 },
};
static int parse_opt (int key, char *arg, struct argp_state *state)
{
// int *arg_count = state->input;
switch (key)
{
case 'd':
{
unsigned int i;
unsigned int dots = 1;
if (arg != NULL) dots = atoi (arg);
printf("arg : %d\r\n",dots);
for (i = 0; i < dots; i++) printf (".");
printf("\n");
break;
}
/* case ARGP_KEY_ARG:
(*arg_count)--;
if (*arg_count >= 0) printf (" %s", arg);
break;
case ARGP_KEY_END:
printf ("\n");
if (*arg_count >= 4) argp_failure (state, 1, 0, "too few arguments");
else if (*arg_count < 0) argp_failure (state, 1, 0, "too many arguments");
break;
*/ }
return 0; //很关键,否则无信息提示了!!
}
struct argp argp = {options, parse_opt, "[param1 [param2 [param3 [param4]]]]" };
int main(int argc,char **argv){
// int arg_count = 4;
argp_parse (&argp, argc, argv, 0, 0, 0);
return 0;
}
执行结果:
//①解析函数 argp_parse
/*每当系统分析到参数时,就会回调parse_opt, 并传递key参数为ARGP_KEY_ARG,
当所有参数处理完时,传递ARGP_KEY_END key 参数
*/
argp_parse (&argp, argc, argv, 0, 0, 0);
argp_parse(const struct argp * _argp,//第一个参数:结构体指针
int _argc,char ** _argv, //第二个、第三个参数是c语言命令行参数选项
unsigned _flags,//第四项:flag
int * _arg_index,//第五项:index 会传递给回调函数的state->input
void * _input);//第六项:input
//②解析结构体 argp_option
struct argp_option options[] =
{
{ "dot", 'd', "NUM", OPTION_ARG_OPTIONAL, "Show some dots on the screen"},
{ 0 },
};
struct argp_option{
const char* name;//长选项名称
int key;//短选项,一个字符,各选项靠它区分
const char *arg;//参数提示信息,上例"NUM" 字符串会跟在长选项提示信息中
int flags;//OPTION_ARG_OPTIONAL 表示该参数是可选的(可以跟参数或不跟参数)
const char *doc;//帮助信息
int group;//分组数值
}
//③ 解析结构体
struct argp argp = {options, parse_opt, "[param1 [param2 [param3 [param4]]]]" };
struct argp{
const struct argp_option *options;//option指针显然指向定义的argp_option数组
argp_parser_t parser;//回调函数用来解析选项
const char *args_doc;//【Usage】中的参数
const char* doc;
const struct argp_child *children;
char *(*help_filter)(int,const char*,void *);
const char* argp_domain;
}
实例
#include <argp.h>
#include <stdbool.h>
#include <unistd.h>
#include "fan_tool.h"
const char *argp_program_version = ARGP_PROGRAM_VERSION;
const char *argp_program_bug_address = "SW Contact Hotline";
static char doc[] = DOC;
static char args_doc[] = "This is a tool about the FAN module.";
static uint8_t choice(struct arguments *arguments){
if((arguments->fan->index < 0) || (arguments->fan->index > 4)){
printf("Please enter the correct fan index.(1,2 or 3)\r\n");
return 0;
}
return 1;
}
static error_t parse_opt(int key, char *arg, struct argp_state *state)
{
long val = 0;
struct arguments *a = state->input;
switch (key) {
case ARGP_KEY_INIT:
a->bus = 0;
a->num = 0;
a->device = 0;
a->reg = 0;
a->reg_bw = 0;
a->argv = 0;
a->argv_len = 0;
a->oper = I2C_READ;
a->fan->index = 255;
a->fan->led_val = 255;
a->fan->speed_val =255;
break;
case 'e':
if(choice(a) == 1)
version_message(a->fan->index);
break;
case 'i':
{
val = strtol(arg,NULL,0);
if(val >= 1 && val < 4)
a->fan->index = val;
break;
}
case 'l':
{
val = strtol(arg,NULL,0);
if(val >= 0 && val < 5)
a->fan->led_val = val;
else
printf( "Please give correct LED value: 0,1,2,3 or 4! \r\n");
break;
}
case 's':
{
val = strtol(arg,NULL,0);
if(val >=0 && val <4)
a->fan->speed_val = val;
else
printf( "Please give correct fan value: 0,1 or 2! \r\n");
break;
}
case 'g':
{
if(choice(a) == 1)
speed_get(a->fan->index);
break;
}
case 'c':
{
if(choice(a) == 1)
fan_card_reset(a->fan->index);
break;
}
case 't':
{
if(choice(a) == 1)
get_fan_tempture(a->fan->index);
break;
}
case 'd':
{
if(choice(a) == 1)
watch_dog(a->fan->index);
break;
}
default: return ARGP_ERR_UNKNOWN;
}
return 0;
}
int main(int argc, char *argv[])
{
struct argp_option options[] = {
{"reg_edition",'e',0,0,"reg_edition"},
{"fan_index",'i',"index",0,"fan index:1,2,or 3."},
{"led_control",'l',"LED",0,"led control:0:off,1:red,2:green,3:red blnk,4:green blnk"},
{"speed_set",'s',"SPEED",0,"set fan speed:0:slow,1:medium,or 2:fast ! "},
{"speed_get",'g',0,0,"get fan speed"},
{"card_reset",'c',0,0,"fan card reset"},
{"tempture",'t',0,0,"get tempture"},
{"watch_dog",'d',0,0,"enable watch dog and feed dog"},
{0}
};
struct fan_mes fan = {0};
struct arguments arguments = {0,0,0,0,0,0," ",0,&fan};
struct argp argp = {options, parse_opt, 0, args_doc};
argp_parse(&argp, argc, argv, 0, 0, &arguments);
if(arguments.fan->index > 0 && arguments.fan->index < 4){
if(arguments.fan->led_val >= 0 && arguments.fan->led_val < 5){
led_control(arguments.fan->index,arguments.fan->led_val);
}else if(arguments.fan->speed_val >= 0 && arguments.fan->speed_val < 3){
speed_set(arguments.fan->index,arguments.fan->speed_val);
}
}
return 0;
}