|
|
|
@ -33,21 +33,29 @@
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include "option.h"
|
|
|
|
|
#include "perf_list.h"
|
|
|
|
|
|
|
|
|
|
/// @brief 解析命令行参数,并根据参数的类型将其值赋给相应的变量。
|
|
|
|
|
/// @param argv
|
|
|
|
|
/// @param index
|
|
|
|
|
/// @param opts
|
|
|
|
|
/// @return
|
|
|
|
|
static int ParseOption(char **argv, int *index, PerfOption *opts)
|
|
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
const char *str = NULL;
|
|
|
|
|
|
|
|
|
|
// 使用while循环遍历 opts 结构体数组,直到遇到一个空指针。
|
|
|
|
|
while ((opts->name != NULL) && (*opts->name != 0)) {
|
|
|
|
|
if (strcmp(argv[*index], opts->name) == 0) {
|
|
|
|
|
switch (opts->type) {
|
|
|
|
|
//如果选项类型是 OPTION_TYPE_UINT,则将命令行参数转换为无符号整数,并存储到当前选项的值中。
|
|
|
|
|
case OPTION_TYPE_UINT:
|
|
|
|
|
*opts->value = strtoul(argv[++(*index)], NULL, 0);
|
|
|
|
|
break;
|
|
|
|
|
//如果选项类型是 OPTION_TYPE_STRING,则将命令行参数赋值给当前选项的字符串值。
|
|
|
|
|
case OPTION_TYPE_STRING:
|
|
|
|
|
*opts->str = argv[++(*index)];
|
|
|
|
|
break;
|
|
|
|
|
// 如果选项类型是 OPTION_TYPE_CALLBACK,则调用当前选项的回调函数,并将命令行参数作为参数传递给回调函数。
|
|
|
|
|
//如果回调函数返回值不为0,则打印解析错误信息,并将 ret 设置为-1。
|
|
|
|
|
case OPTION_TYPE_CALLBACK:
|
|
|
|
|
str = argv[++(*index)];
|
|
|
|
|
if ((*opts->cb)(str) != 0) {
|
|
|
|
@ -55,6 +63,7 @@ static int ParseOption(char **argv, int *index, PerfOption *opts)
|
|
|
|
|
ret = -1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
//如果在while循环中没有找到匹配的选项,则打印无效选项信息,并将 ret 设置为-1。
|
|
|
|
|
default:
|
|
|
|
|
printf("invalid option\n");
|
|
|
|
|
ret = -1;
|
|
|
|
@ -67,19 +76,27 @@ static int ParseOption(char **argv, int *index, PerfOption *opts)
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief 这段代码是一个命令行参数解析函数,它的目的是从命令行参数中提取选项和子命令,并将它们存储在opts cmd中
|
|
|
|
|
/// @param argc
|
|
|
|
|
/// @param argv
|
|
|
|
|
/// @param opts
|
|
|
|
|
/// @param cmd
|
|
|
|
|
/// @return
|
|
|
|
|
int ParseOptions(int argc, char **argv, PerfOption *opts, SubCmd *cmd)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
// 定义一个变量 index,初始值为0,用于表示当前正在处理的命令行参数的索引。
|
|
|
|
|
int index = 0;
|
|
|
|
|
|
|
|
|
|
//使用while循环遍历命令行参数,直到索引超出范围或者遇到非选项参数。
|
|
|
|
|
//在循环中,调用 ParseOption 函数解析当前选项,并将解析结果存储在 opts 结构体中。如果解析失败,则返回-1。
|
|
|
|
|
while ((index < argc) && (argv[index] != NULL) && (*argv[index] == '-')) {
|
|
|
|
|
if (ParseOption(argv, &index, opts) != 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//如果在while循环结束后还有剩余的命令行参数,则将第一个参数赋值给 cmd 结构体的 path 成员,
|
|
|
|
|
//并将其余参数存储在 cmd 结构体的 params 数组中。如果缺少子命令参数,则打印错误信息并返回-1。
|
|
|
|
|
if ((index < argc) && (argv[index] != NULL)) {
|
|
|
|
|
cmd->path = argv[index];
|
|
|
|
|
cmd->params[0] = argv[index];
|
|
|
|
@ -88,7 +105,7 @@ int ParseOptions(int argc, char **argv, PerfOption *opts, SubCmd *cmd)
|
|
|
|
|
printf("no subcmd to execute\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 使用for循环遍历剩余的命令行参数,并将它们存储在 cmd 结构体的 params 数组中。循环会一直执行直到达到最大参数数量或者索引超出范围
|
|
|
|
|
for (i = 1; (index < argc) && (i < CMD_MAX_PARAMS); index++, i++) {
|
|
|
|
|
cmd->params[i] = argv[index];
|
|
|
|
|
}
|
|
|
|
@ -128,7 +145,10 @@ EXIT:
|
|
|
|
|
free(list);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief 这段代码是一个C语言函数,其功能是将一个字符串转换为对应的PerfEvent结构体指针。
|
|
|
|
|
///这个函数对于输入的字符串,在全局的g_events数组中进行查找,并返回匹配的PerfEvent结构体指针。
|
|
|
|
|
/// @param str
|
|
|
|
|
/// @return
|
|
|
|
|
static inline const PerfEvent *StrToEvent(const char *str)
|
|
|
|
|
{
|
|
|
|
|
const PerfEvent *evt = &g_events[0];
|
|
|
|
@ -140,7 +160,11 @@ static inline const PerfEvent *StrToEvent(const char *str)
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @brief 这段代码定义了一个名为 ParseEvents 的函数,其目的是解析一个以逗号分隔的字符串,并将其转换为 PerfEventConfig 结构体中的事件配置。
|
|
|
|
|
/// @param argv
|
|
|
|
|
/// @param eventsCfg
|
|
|
|
|
/// @param len
|
|
|
|
|
/// @return
|
|
|
|
|
int ParseEvents(const char *argv, PerfEventConfig *eventsCfg, unsigned int *len)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|