mirror of
git://sourceware.org/git/lvm2.git
synced 2025-10-16 23:33:16 +03:00
Compare commits
1 Commits
dev-dct-cm
...
dev-dct-cm
Author | SHA1 | Date | |
---|---|---|---|
|
9d326f4ffb |
@@ -89,8 +89,8 @@ struct cmd_context {
|
||||
*/
|
||||
const char *cmd_line;
|
||||
struct command *command;
|
||||
char **pos_arg_values;
|
||||
struct arg_values *opt_arg_values;
|
||||
char **argv;
|
||||
struct arg_values *arg_values;
|
||||
struct dm_list arg_value_groups;
|
||||
|
||||
/*
|
||||
|
@@ -1,12 +1,3 @@
|
||||
#
|
||||
# When this file is changed, tools/command-lines.h
|
||||
# and tools/command-lines-count.h must be regenerated
|
||||
# with:
|
||||
#
|
||||
# scripts/create-commands --output count scripts/command-lines.in > tools/command-lines-count.h
|
||||
# scripts/create-commands --output struct scripts/command-lines.in > tools/command-lines.h
|
||||
#
|
||||
|
||||
#
|
||||
# A new command has a unique combination of:
|
||||
# command name, required option args and required
|
||||
@@ -37,7 +28,7 @@
|
||||
# --foo is accepted by the command. (This is uncommon.)
|
||||
#
|
||||
# Possible option arg types that can follow --opt are:
|
||||
# Bool, Number, String, PV, VG, LV, Tag.
|
||||
# Bool, Number, String, PV, VG, LV, Tag, Select.
|
||||
#
|
||||
# Option args outside the list of types are treated as literal
|
||||
# (non-variable) strings or numbers.
|
||||
|
@@ -78,52 +78,6 @@ static struct opt_name opt_names[ARG_COUNT + 1] = {
|
||||
|
||||
#include "command.h"
|
||||
|
||||
#define ARG_DEF_TYPES 16
|
||||
struct arg_def_type {
|
||||
const char *name;
|
||||
int flag;
|
||||
};
|
||||
|
||||
/* The names used for arg_def types in command-lines.in */
|
||||
static struct arg_def_type arg_def_types[ARG_DEF_TYPES] = {
|
||||
{ "None", ARG_DEF_TYPE_NONE},
|
||||
{ "Bool", ARG_DEF_TYPE_BOOL},
|
||||
{ "Number", ARG_DEF_TYPE_NUM_ANY},
|
||||
{ "String", ARG_DEF_TYPE_STR_ANY},
|
||||
{ "Name", ARG_DEF_TYPE_NAME_ANY},
|
||||
{ "PV", ARG_DEF_TYPE_NAME_PV},
|
||||
{ "VG", ARG_DEF_TYPE_NAME_VG},
|
||||
{ "LV", ARG_DEF_TYPE_NAME_LV},
|
||||
{ "Tag", ARG_DEF_TYPE_TAG},
|
||||
{ "Select", ARG_DEF_TYPE_SELECT},
|
||||
};
|
||||
|
||||
#define ARG_DEF_LVS 64
|
||||
struct arg_def_lv {
|
||||
const char *name;
|
||||
int flag;
|
||||
};
|
||||
|
||||
/* The names used for arg_def lv_types in command-lines.in */
|
||||
static struct arg_def_lv arg_def_lvs[ARG_DEF_LVS] = {
|
||||
{ "LV", ARG_DEF_LV_ANY},
|
||||
{ "LV_linear", ARG_DEF_LV_LINEAR},
|
||||
{ "LV_striped", ARG_DEF_LV_STRIPED},
|
||||
{ "LV_snapshot", ARG_DEF_LV_SNAPSHOT},
|
||||
{ "LV_mirror", ARG_DEF_LV_MIRROR},
|
||||
{ "LV_raid", ARG_DEF_LV_RAID},
|
||||
{ "LV_raid0", ARG_DEF_LV_RAID0},
|
||||
{ "LV_raid1", ARG_DEF_LV_RAID1},
|
||||
{ "LV_raid4", ARG_DEF_LV_RAID4},
|
||||
{ "LV_raid5", ARG_DEF_LV_RAID5},
|
||||
{ "LV_raid6", ARG_DEF_LV_RAID6},
|
||||
{ "LV_raid10", ARG_DEF_LV_RAID10},
|
||||
{ "LV_thin", ARG_DEF_LV_THIN},
|
||||
{ "LV_thinpool", ARG_DEF_LV_THINPOOL},
|
||||
{ "LV_cache", ARG_DEF_LV_CACHE},
|
||||
{ "LV_cachepool", ARG_DEF_LV_CACHEPOOL},
|
||||
};
|
||||
|
||||
#define MAX_CMD_NAMES 128
|
||||
struct cmd_name {
|
||||
const char *name;
|
||||
@@ -890,33 +844,23 @@ static void print_def(struct arg_def *def)
|
||||
printf(" ...");
|
||||
}
|
||||
|
||||
void print_expanded(void)
|
||||
void print_data_expanded(void)
|
||||
{
|
||||
struct command *cmd;
|
||||
int onereq;
|
||||
int i, ro, rp, oo, op;
|
||||
|
||||
for (i = 0; i < cmd_count; i++) {
|
||||
cmd = &cmd_array[i];
|
||||
printf("%s", cmd->name);
|
||||
|
||||
onereq = (cmd->cmd_flags & CMD_FLAG_ONE_REQUIRED_OPT) ? 1 : 0;
|
||||
|
||||
if (cmd->ro_count) {
|
||||
if (onereq)
|
||||
printf(" (");
|
||||
|
||||
for (ro = 0; ro < cmd->ro_count; ro++) {
|
||||
if (ro && onereq)
|
||||
printf(",");
|
||||
printf(" %s", opt_names[cmd->required_opt_args[ro].opt].long_opt);
|
||||
if (cmd->required_opt_args[ro].def.types) {
|
||||
printf(" ");
|
||||
print_def(&cmd->required_opt_args[ro].def);
|
||||
}
|
||||
}
|
||||
if (onereq)
|
||||
printf(" )");
|
||||
}
|
||||
|
||||
if (cmd->rp_count) {
|
||||
@@ -1159,8 +1103,6 @@ static char *flags_to_str(int flags)
|
||||
|
||||
void print_define_command_count(void)
|
||||
{
|
||||
printf("/* Do not edit. This file is generated by scripts/create-commands */\n");
|
||||
printf("/* using command definitions from scripts/command-lines.in */\n");
|
||||
printf("#define COMMAND_COUNT %d\n", cmd_count);
|
||||
}
|
||||
|
||||
@@ -1203,7 +1145,7 @@ void print_usage(struct command *cmd)
|
||||
goto op_count;
|
||||
|
||||
printf("\n");
|
||||
printf("\" [");
|
||||
printf("\"[");
|
||||
|
||||
if (cmd->oo_count) {
|
||||
for (oo = 0; oo < cmd->oo_count; oo++) {
|
||||
@@ -1224,7 +1166,7 @@ void print_usage(struct command *cmd)
|
||||
goto done;
|
||||
|
||||
printf("\n");
|
||||
printf("\" [");
|
||||
printf("\"[");
|
||||
|
||||
if (cmd->op_count) {
|
||||
for (op = 0; op < cmd->op_count; op++) {
|
||||
@@ -1241,33 +1183,21 @@ void print_usage(struct command *cmd)
|
||||
printf(";\n");
|
||||
}
|
||||
|
||||
void print_command_struct(int only_usage)
|
||||
void print_command_count(void)
|
||||
{
|
||||
printf("#define COMMAND_COUNT %d\n", cmd_count);
|
||||
}
|
||||
|
||||
void print_command_structs(void)
|
||||
{
|
||||
struct command *cmd;
|
||||
int i, j, ro, rp, oo, op;
|
||||
|
||||
printf("/* Do not edit. This file is generated by scripts/create-commands */\n");
|
||||
printf("/* using command definitions from scripts/command-lines.in */\n");
|
||||
|
||||
for (i = 0; i < cmd_count; i++) {
|
||||
cmd = &cmd_array[i];
|
||||
|
||||
if (only_usage) {
|
||||
print_usage(cmd);
|
||||
printf("\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("commands[%d].name = \"%s\";\n", i, cmd->name);
|
||||
printf("commands[%d].fn = %s;\n", i, cmd->name);
|
||||
printf("commands[%d].ro_count = %d;\n", i, cmd->ro_count);
|
||||
printf("commands[%d].rp_count = %d;\n", i, cmd->rp_count);
|
||||
printf("commands[%d].oo_count = %d;\n", i, cmd->oo_count);
|
||||
printf("commands[%d].op_count = %d;\n", i, cmd->op_count);
|
||||
|
||||
if (cmd->cmd_flags & CMD_FLAG_ONE_REQUIRED_OPT)
|
||||
printf("commands[%d].cmd_flags = CMD_FLAG_ONE_REQUIRED_OPT;\n", i);
|
||||
|
||||
printf("commands[%d].desc = \"%s\";\n", i, cmd->desc ?: "");
|
||||
printf("commands[%d].usage = ", i);
|
||||
print_usage(cmd);
|
||||
@@ -1426,20 +1356,18 @@ void print_option_list(void)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARG_COUNT; i++)
|
||||
printf("%d %s %s %c (%d)\n",
|
||||
printf("%d %s %s %c\n",
|
||||
opt_names[i].enum_val, opt_names[i].enum_name,
|
||||
opt_names[i].long_opt, opt_names[i].short_opt ?: ' ',
|
||||
opt_names[i].short_opt ? opt_names[i].short_opt : 0);
|
||||
opt_names[i].long_opt, opt_names[i].short_opt ?: ' ');
|
||||
}
|
||||
|
||||
static void print_help(int argc, char *argv[])
|
||||
{
|
||||
printf("%s --output struct|count|usage|expanded <filename>\n", argv[0]);
|
||||
printf("%s --output struct|count|expand <filename>\n", argv[0]);
|
||||
printf("\n");
|
||||
printf("struct: print C structures.\n");
|
||||
printf("usage: print usage format.\n");
|
||||
printf("expanded: print expanded input format.\n");
|
||||
printf("count: print #define COMMAND_COUNT <Number>\n");
|
||||
printf("struct: print C structures for command definitions.\n");
|
||||
printf("expand: print expanded input format.\n");
|
||||
printf("count: print #define COMMAND_COUNT <Number>\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@@ -1463,12 +1391,6 @@ int main(int argc, char *argv[])
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "debug")) {
|
||||
print_command_list();
|
||||
print_option_list();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{"output", required_argument, 0, 'o' },
|
||||
@@ -1543,7 +1465,7 @@ int main(int argc, char *argv[])
|
||||
char *desc = strdup(strstr(line_orig, ":") + 2);
|
||||
if (cmd->desc) {
|
||||
cmd->desc = realloc((char *)cmd->desc, strlen(cmd->desc) + strlen(desc) + 2);
|
||||
strcat((char *)cmd->desc, " ");
|
||||
strcat((char *)cmd->desc, "\n");
|
||||
strcat((char *)cmd->desc, desc);
|
||||
free(desc);
|
||||
} else
|
||||
@@ -1599,15 +1521,13 @@ int main(int argc, char *argv[])
|
||||
fclose(file);
|
||||
|
||||
if (!outputformat)
|
||||
print_command_struct(1);
|
||||
print_data_expanded();
|
||||
else if (!strcmp(outputformat, "struct"))
|
||||
print_command_struct(0);
|
||||
print_command_structs();
|
||||
else if (!strcmp(outputformat, "count"))
|
||||
print_define_command_count();
|
||||
else if (!strcmp(outputformat, "usage"))
|
||||
print_command_struct(1);
|
||||
else if (!strcmp(outputformat, "expanded"))
|
||||
print_expanded();
|
||||
print_command_count();
|
||||
else if (!strcmp(outputformat, "expand"))
|
||||
print_data_expanded();
|
||||
else
|
||||
print_help(argc, argv);
|
||||
}
|
||||
|
@@ -1,3 +0,0 @@
|
||||
/* Do not edit. This file is generated by scripts/create-commands */
|
||||
/* using command definitions from scripts/command-lines.in */
|
||||
#define COMMAND_COUNT 144
|
File diff suppressed because it is too large
Load Diff
@@ -47,7 +47,7 @@ enum {
|
||||
ARG_DEF_TYPE_STR_ANY = 1 << 2,
|
||||
ARG_DEF_TYPE_NUM_CONST = 1 << 3,
|
||||
ARG_DEF_TYPE_STR_CONST = 1 << 4,
|
||||
ARG_DEF_TYPE_STR_SET = 1 << 5,
|
||||
ARG_DEF_TYPE_STR_SET = 1 << 5, /* a set of specific accepted string values */
|
||||
ARG_DEF_TYPE_NAME_ANY = 1 << 6,
|
||||
ARG_DEF_TYPE_NAME_PV = 1 << 7,
|
||||
ARG_DEF_TYPE_NAME_VG = 1 << 8,
|
||||
@@ -56,6 +56,26 @@ enum {
|
||||
ARG_DEF_TYPE_SELECT = 1 << 11,
|
||||
};
|
||||
|
||||
#define ARG_DEF_TYPES 16
|
||||
struct arg_def_type {
|
||||
const char *name;
|
||||
int flag;
|
||||
};
|
||||
|
||||
/* The names used for arg_def types in command-lines.in */
|
||||
static struct arg_def_type arg_def_types[ARG_DEF_TYPES] = {
|
||||
{ "None", ARG_DEF_TYPE_NONE},
|
||||
{ "Bool", ARG_DEF_TYPE_BOOL},
|
||||
{ "Number", ARG_DEF_TYPE_NUM_ANY},
|
||||
{ "String", ARG_DEF_TYPE_STR_ANY},
|
||||
{ "Name", ARG_DEF_TYPE_NAME_ANY},
|
||||
{ "PV", ARG_DEF_TYPE_NAME_PV},
|
||||
{ "VG", ARG_DEF_TYPE_NAME_VG},
|
||||
{ "LV", ARG_DEF_TYPE_NAME_LV},
|
||||
{ "Tag", ARG_DEF_TYPE_TAG},
|
||||
{ "Select", ARG_DEF_TYPE_SELECT},
|
||||
};
|
||||
|
||||
/* arg_def lv_types, can be multiple */
|
||||
enum {
|
||||
ARG_DEF_LV_ANY = 0,
|
||||
@@ -76,6 +96,32 @@ enum {
|
||||
ARG_DEF_LV_CACHEPOOL = 1 << 14,
|
||||
};
|
||||
|
||||
#define ARG_DEF_LVS 64
|
||||
struct arg_def_lv {
|
||||
const char *name;
|
||||
int flag;
|
||||
};
|
||||
|
||||
/* The names used for arg_def lv_types in command-lines.in */
|
||||
static struct arg_def_lv arg_def_lvs[ARG_DEF_LVS] = {
|
||||
{ "LV", ARG_DEF_LV_ANY},
|
||||
{ "LV_linear", ARG_DEF_LV_LINEAR},
|
||||
{ "LV_striped", ARG_DEF_LV_STRIPED},
|
||||
{ "LV_snapshot", ARG_DEF_LV_SNAPSHOT},
|
||||
{ "LV_mirror", ARG_DEF_LV_MIRROR},
|
||||
{ "LV_raid", ARG_DEF_LV_RAID},
|
||||
{ "LV_raid0", ARG_DEF_LV_RAID0},
|
||||
{ "LV_raid1", ARG_DEF_LV_RAID1},
|
||||
{ "LV_raid4", ARG_DEF_LV_RAID4},
|
||||
{ "LV_raid5", ARG_DEF_LV_RAID5},
|
||||
{ "LV_raid6", ARG_DEF_LV_RAID6},
|
||||
{ "LV_raid10", ARG_DEF_LV_RAID10},
|
||||
{ "LV_thin", ARG_DEF_LV_THIN},
|
||||
{ "LV_thinpool", ARG_DEF_LV_THINPOOL},
|
||||
{ "LV_cache", ARG_DEF_LV_CACHE},
|
||||
{ "LV_cachepool", ARG_DEF_LV_CACHEPOOL},
|
||||
};
|
||||
|
||||
/* Description a value that follows an option or exists in a position. */
|
||||
|
||||
struct arg_def {
|
||||
@@ -106,8 +152,8 @@ struct pos_arg {
|
||||
* of which one is required after which the rest are
|
||||
* optional.
|
||||
*/
|
||||
#define CMD_RO_ARGS 64 /* required opt args */
|
||||
#define CMD_OO_ARGS 150 /* optional opt args */
|
||||
#define CMD_RO_ARGS 32 /* required opt args */
|
||||
#define CMD_OO_ARGS ARG_COUNT /* optional opt args */
|
||||
#define CMD_RP_ARGS 8 /* required positional args */
|
||||
#define CMD_OP_ARGS 8 /* optional positional args */
|
||||
|
||||
|
@@ -55,11 +55,10 @@ static char *_list_cmds(const char *text, int state)
|
||||
/* List matching arguments */
|
||||
static char *_list_args(const char *text, int state)
|
||||
{
|
||||
#if 0 /* FIXME: just go through args.h */
|
||||
|
||||
static int match_no = 0;
|
||||
static size_t len = 0;
|
||||
static struct command *com;
|
||||
|
||||
/* Initialise if this is a new completion attempt */
|
||||
if (!state) {
|
||||
char *s = rl_line_buffer;
|
||||
@@ -119,7 +118,7 @@ static char *_list_args(const char *text, int state)
|
||||
if (*(l + 2) && !strncmp(text, l, len))
|
||||
return strdup(l);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,7 @@ struct cmdline_context {
|
||||
struct arg_props *arg_props;
|
||||
struct command *commands;
|
||||
int num_commands;
|
||||
int commands_size;
|
||||
};
|
||||
|
||||
int lvm2_main(int argc, char **argv);
|
||||
|
@@ -49,13 +49,16 @@ extern char *optarg;
|
||||
# define OPTIND_INIT 1
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include "command-lines-count.h" /* #define COMMAND_COUNT, generated from command-lines.in */
|
||||
#endif
|
||||
#define COMMAND_COUNT 128
|
||||
|
||||
/*
|
||||
* Table of valid switches
|
||||
*/
|
||||
static struct arg_props _arg_props[ARG_COUNT + 1] = {
|
||||
#define arg(a, b, c, d, e, f) {a, b, "", "--" c, d, e, f},
|
||||
#define arg(a, b, c, d, e, f) {b, "", "--" c, d, e, f},
|
||||
#include "args.h"
|
||||
#undef arg
|
||||
};
|
||||
@@ -71,10 +74,10 @@ struct command_name {
|
||||
};
|
||||
|
||||
struct command_name command_names[MAX_COMMAND_NAMES] = {
|
||||
#define xx(a, b, c...) { # a, b, c },
|
||||
#define xx(a, b, c...) { # a, b, c }
|
||||
#include "commands.h"
|
||||
#undef xx
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Table of valid command lines
|
||||
@@ -731,7 +734,7 @@ int metadatacopies_arg(struct cmd_context *cmd, struct arg_values *av)
|
||||
return int_arg(cmd, av);
|
||||
}
|
||||
|
||||
static struct command_name *_find_command_name(const char *name)
|
||||
static struct command_name *_find_command_name(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -744,7 +747,7 @@ static struct command_name *_find_command_name(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _define_commands(void)
|
||||
void _define_commands(void)
|
||||
{
|
||||
/* command-lines.h defines command[] structs, generated from command-lines.in */
|
||||
#include "command-lines.h" /* generated from command-lines.in */
|
||||
@@ -755,11 +758,9 @@ void lvm_register_commands(void)
|
||||
struct command_name *cname;
|
||||
int i;
|
||||
|
||||
memset(&commands, 0, sizeof(commands));
|
||||
|
||||
_define_commands();
|
||||
|
||||
_cmdline.commands = commands;
|
||||
_cmdline.commands = &commands;
|
||||
_cmdline.num_commands = COMMAND_COUNT;
|
||||
|
||||
for (i = 0; i < COMMAND_COUNT; i++) {
|
||||
@@ -793,37 +794,37 @@ void lvm_register_commands(void)
|
||||
|
||||
static int _opt_equivalent_is_set(struct cmd_context *cmd, int opt)
|
||||
{
|
||||
if ((opt == mirrorlog_ARG) && arg_is_set(cmd, corelog_ARG))
|
||||
if ((opt == mirrorlog_ARG) && arg_is_set(cmd, corelog_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == resizeable_ARG) && arg_is_set(cmd, resizable_ARG))
|
||||
if ((opt == resizeable_ARG) && arg_is_set(cmd, resizable_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == allocatable_ARG) && arg_is_set(cmd, allocation_ARG))
|
||||
if ((opt == allocatable_ARG) && arg_is_set(cmd, allocation_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == resizeable_ARG) && arg_is_set(cmd, allocation_ARG))
|
||||
if ((opt == resizeable_ARG) && arg_is_set(cmd, allocation_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == activate_ARG) && arg_is_set(cmd, available_ARG))
|
||||
if ((opt == activate_ARG) && arg_is_set(cmd, available_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == rebuild_ARG) && arg_is_set(cmd, raidrebuild_ARG))
|
||||
if ((opt == rebuild_ARG) && arg_is_set(cmd, raidrebuild_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == syncaction_ARG) && arg_is_set(cmd, raidsyncaction_ARG))
|
||||
if ((opt == syncaction_ARG) && arg_is_set(cmd, raidsyncaction_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == writemostly_ARG) && arg_is_set(cmd, raidwritemostly_ARG))
|
||||
if ((opt == writemostly_ARG) && arg_is_set(cmd, raidwritemostly_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == minrecoveryrate_ARG) && arg_is_set(cmd, raidminrecoveryrate_ARG))
|
||||
if ((opt == minrecoveryrate_ARG) && arg_is_set(cmd, raidminrecoveryrate_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == maxrecoveryrate_ARG) && arg_is_set(cmd, raidmaxrecoveryrate_ARG))
|
||||
if ((opt == maxrecoveryrate_ARG) && arg_is_set(cmd, raidmaxrecoveryrate_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == writebehind_ARG) && arg_is_set(cmd, raidwritebehind_ARG))
|
||||
if ((opt == writebehind_ARG) && arg_is_set(cmd, raidwritebehind_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@@ -831,18 +832,18 @@ static int _opt_equivalent_is_set(struct cmd_context *cmd, int opt)
|
||||
|
||||
static int _command_required_opt_matches(struct cmd_context *cmd, int ci, int ro)
|
||||
{
|
||||
if (arg_is_set(cmd, commands[ci].required_opt_args[ro].opt))
|
||||
if (arg_is_set(cmd, commands[ci].required_opt_args[ro].opt, NULL))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* For some commands, --size and --extents are interchanable,
|
||||
* but command[] definitions use only --size.
|
||||
*/
|
||||
if ((commands[ci].required_opt_args[ro].opt == size_ARG) && arg_is_set(cmd, extents_ARG)) {
|
||||
if (!strcmp(commands[ci].name, "lvcreate") ||
|
||||
!strcmp(commands[ci].name, "lvresize") ||
|
||||
!strcmp(commands[ci].name, "lvextend") ||
|
||||
!strcmp(commands[ci].name, "lvreduce"))
|
||||
if ((commands[ci].required_opt_args[ro].opt == size_ARG) && arg_is_set(cmd, extents_ARG, NULL)) {
|
||||
if (!strcmp(commands[i].name, "lvcreate") ||
|
||||
!strcmp(commands[i].name, "lvresize")
|
||||
!strcmp(commands[i].name, "lvextend")
|
||||
!strcmp(commands[i].name, "lvreduce"))
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -850,8 +851,6 @@ static int _command_required_opt_matches(struct cmd_context *cmd, int ci, int ro
|
||||
|
||||
if (_opt_equivalent_is_set(cmd, commands[ci].required_opt_args[ro].opt))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _command_required_pos_matches(struct cmd_context *cmd, int ci, int rp)
|
||||
@@ -867,7 +866,7 @@ static int _command_required_pos_matches(struct cmd_context *cmd, int ci, int rp
|
||||
* empty if --select is used.
|
||||
*/
|
||||
if ((commands[ci].required_pos_args[rp].def.types & ARG_DEF_TYPE_SELECT) &&
|
||||
arg_is_set(cmd, select_ARG))
|
||||
arg_is_set(cmd, select_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@@ -876,11 +875,8 @@ static int _command_required_pos_matches(struct cmd_context *cmd, int ci, int rp
|
||||
static struct command *_find_command(struct cmd_context *cmd, const char *path)
|
||||
{
|
||||
const char *name;
|
||||
int match_count, mismatch_count;
|
||||
int best_match_i = 0, best_match_count = 0;
|
||||
int closest_i = 0, closest_count = 0;
|
||||
int ro_matches;
|
||||
int ro, rp;
|
||||
int found = 0;
|
||||
int i;
|
||||
|
||||
name = last_path_component(path);
|
||||
@@ -889,60 +885,39 @@ static struct command *_find_command(struct cmd_context *cmd, const char *path)
|
||||
if (strcmp(name, commands[i].name))
|
||||
continue;
|
||||
|
||||
match_count = 0;
|
||||
match_count = 1; /* for command name matching */
|
||||
mismatch_count = 0;
|
||||
ro_matches = 0;
|
||||
|
||||
/* if the command name alone is enough, then that's a match */
|
||||
|
||||
if (!commands[i].ro_count && !commands[i].rp_count) {
|
||||
/* log_warn("match %d command name %s", i, name); */
|
||||
match_count = 1;
|
||||
}
|
||||
|
||||
/* match required_opt_args */
|
||||
|
||||
for (ro = 0; ro < commands[i].ro_count; ro++) {
|
||||
if (_command_required_opt_matches(cmd, i, ro)) {
|
||||
/* log_warn("match %d ro opt %d", i, commands[i].required_opt_args[ro].opt); */
|
||||
if (_command_required_opt_matches(cmd, i, ro))
|
||||
match_count++;
|
||||
ro_matches++;
|
||||
} else {
|
||||
/* cmd is missing a required opt arg */
|
||||
/* log_warn("mismatch %d ro opt %d", i, commands[i].required_opt_args[ro].opt); */
|
||||
else
|
||||
mismatch_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Special case where missing required_opt_arg's does not matter
|
||||
* if one required_opt_arg did match.
|
||||
* One item in required_opt_args must be set for
|
||||
* a match, and the rest are optional (don't count
|
||||
* as mismatches).
|
||||
*/
|
||||
if (commands[i].cmd_flags & CMD_FLAG_ONE_REQUIRED_OPT) {
|
||||
if (ro_matches) {
|
||||
/* one or more of the required_opt_args is used */
|
||||
if (cmd->cmd_flags & CMD_FLAG_ONE_REQUIRED_OPT) {
|
||||
if (match_count >= 2) {
|
||||
match_count = 2;
|
||||
mismatch_count = 0;
|
||||
} else {
|
||||
/* not even one of the required_opt_args is used */
|
||||
mismatch_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* match required_pos_args */
|
||||
|
||||
for (rp = 0; rp < commands[i].rp_count; rp++) {
|
||||
if (_command_required_pos_matches(cmd, i, rp)) {
|
||||
/* log_warn("match %d rp %d", i, commands[i].required_pos_args[rp].pos); */
|
||||
if (_command_required_pos_matches(cmd, i, rp))
|
||||
match_count++;
|
||||
} else {
|
||||
/* cmd is missing a required pos arg */
|
||||
/* log_warn("mismatch %d rp %d", i, commands[i].required_pos_args[rp].pos); */
|
||||
else
|
||||
mismatch_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* if cmd is missing any required opt/pos args, it can't be this command. */
|
||||
|
||||
if (mismatch_count) {
|
||||
/* save i/match_count for "closest" command that doesn't match */
|
||||
if (!closest_count || (match_count > closest_count)) {
|
||||
@@ -952,21 +927,18 @@ static struct command *_find_command(struct cmd_context *cmd, const char *path)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* use command that has the most matching required opt/pos */
|
||||
|
||||
if (!best_match_count || (match_count > best_match_count)) {
|
||||
/* log_warn("match best i %d count %d", i, match_count); */
|
||||
best_match_i = i;
|
||||
best_match_count = match_count;
|
||||
}
|
||||
}
|
||||
|
||||
if (!best_match_count) {
|
||||
/* cmd did not have all the required opt/pos args of any command */
|
||||
/* nothing matches */
|
||||
/* TODO: report closest matching command and report missing required opt/pos args for that? */
|
||||
log_error("Failed to find a matching command definition.");
|
||||
if (closest_count) {
|
||||
log_warn("Closest command usage is:");
|
||||
/* FIXME: _print_usage_required(commands[closest_i].usage); with new lines, aligned, etc */
|
||||
log_warn("%s", commands[closest_i].usage);
|
||||
}
|
||||
return NULL;
|
||||
@@ -980,7 +952,7 @@ static struct command *_find_command(struct cmd_context *cmd, const char *path)
|
||||
* Same for pos args.
|
||||
*/
|
||||
|
||||
/* log_warn("command matched: %.256s ...", commands[best_match_i].usage); */
|
||||
log_debug("matched command usage: %.80s ...", commands[best_match_i].usage);
|
||||
|
||||
return &commands[best_match_i];
|
||||
}
|
||||
@@ -1006,83 +978,53 @@ static int _usage(const char *name)
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets up the arguments to pass to getopt_long().
|
||||
*
|
||||
* getopt_long() takes a string of short option characters
|
||||
* where the char is followed by ":" if the option takes an arg,
|
||||
* e.g. "abc:d:" This string is created in optstrp.
|
||||
*
|
||||
* getopt_long() also takes an array of struct option which
|
||||
* has the name of the long option, if it takes an arg, etc,
|
||||
* e.g.
|
||||
*
|
||||
* option long_options[] = {
|
||||
* { "foo", required_argument, 0, 0 },
|
||||
* { "bar", no_argument, 0, 'b' }
|
||||
* };
|
||||
*
|
||||
* this array is created in longoptsp.
|
||||
*
|
||||
* Original comment:
|
||||
* Sets up the short and long argument. If there
|
||||
* is no short argument then the index of the
|
||||
* argument in the the_args array is set as the
|
||||
* long opt value. Yuck. Of course this means we
|
||||
* can't have more than 'a' long arguments.
|
||||
*/
|
||||
|
||||
static void _add_getopt_arg(int arg_enum, char **optstrp, struct option **longoptsp)
|
||||
static void _add_getopt_arg(int arg, char **ptr, struct option **o)
|
||||
{
|
||||
struct arg_props *a = _cmdline.arg_props + arg_enum;
|
||||
struct arg_props *a = _cmdline.arg_props + arg;
|
||||
|
||||
if (a->short_arg) {
|
||||
*(*optstrp)++ = a->short_arg;
|
||||
*(*ptr)++ = a->short_arg;
|
||||
|
||||
if (a->fn)
|
||||
*(*optstrp)++ = ':';
|
||||
*(*ptr)++ = ':';
|
||||
}
|
||||
#ifdef HAVE_GETOPTLONG
|
||||
/* long_arg is "--foo", so +2 is the offset of the name after "--" */
|
||||
|
||||
if (*(a->long_arg + 2)) {
|
||||
(*longoptsp)->name = a->long_arg + 2;
|
||||
(*longoptsp)->has_arg = a->fn ? 1 : 0;
|
||||
(*longoptsp)->flag = NULL;
|
||||
|
||||
/*
|
||||
* When getopt_long() sees an option that has an associated
|
||||
* single letter, it returns the ascii value of that letter.
|
||||
* e.g. getopt_long() returns 100 for '-d' or '--debug'
|
||||
* (100 is the ascii value of 'd').
|
||||
*
|
||||
* When getopt_long() sees an option that does not have an
|
||||
* associated single letter, it returns the value of the
|
||||
* the enum for that long option name plus 128.
|
||||
* e.g. getopt_long() returns 139 for --cachepool
|
||||
* (11 is the enum value for --cachepool, so 11+128)
|
||||
*/
|
||||
|
||||
(*o)->name = a->long_arg + 2;
|
||||
(*o)->has_arg = a->fn ? 1 : 0;
|
||||
(*o)->flag = NULL;
|
||||
if (a->short_arg)
|
||||
(*longoptsp)->val = a->short_arg;
|
||||
(*o)->val = a->short_arg;
|
||||
else
|
||||
(*longoptsp)->val = arg_enum + 128;
|
||||
(*longoptsp)++;
|
||||
(*o)->val = arg + 128;
|
||||
(*o)++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int _find_arg(int goval)
|
||||
static int _find_arg(struct command *com, int opt)
|
||||
{
|
||||
int i;
|
||||
struct arg_props *a;
|
||||
int i, arg;
|
||||
|
||||
for (i = 0; i < ARG_COUNT; i++) {
|
||||
/* the value returned by getopt matches the ascii value of single letter option */
|
||||
if (_cmdline.arg_props[i].short_arg && (goval == _cmdline.arg_props[i].short_arg))
|
||||
return _cmdline.arg_props[i].enum_val;
|
||||
for (i = 0; i < com->num_args; i++) {
|
||||
arg = com->valid_args[i];
|
||||
a = _cmdline.arg_props + arg;
|
||||
|
||||
/* the value returned by getopt matches the enum value plus 128 */
|
||||
if (!_cmdline.arg_props[i].short_arg && (goval == _cmdline.arg_props[i].enum_val + 128))
|
||||
return _cmdline.arg_props[i].enum_val;
|
||||
/*
|
||||
* opt should equal either the
|
||||
* short arg, or the index into
|
||||
* the_args.
|
||||
*/
|
||||
if ((a->short_arg && (opt == a->short_arg)) ||
|
||||
(!a->short_arg && (opt == (arg + 128))))
|
||||
return arg;
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -1091,27 +1033,21 @@ static int _find_arg(int goval)
|
||||
static int _process_command_line(struct cmd_context *cmd, int *argc,
|
||||
char ***argv)
|
||||
{
|
||||
int i, opt, arg;
|
||||
char str[((ARG_COUNT + 1) * 2) + 1], *ptr = str;
|
||||
struct option opts[ARG_COUNT + 1], *o = opts;
|
||||
struct arg_props *a;
|
||||
struct arg_values *av;
|
||||
struct arg_value_group_list *current_group = NULL;
|
||||
int arg_enum; /* e.g. foo_ARG */
|
||||
int goval; /* the number returned from getopt_long identifying what it found */
|
||||
int i;
|
||||
|
||||
if (!(cmd->opt_arg_values = dm_pool_zalloc(cmd->mem, sizeof(*cmd->opt_arg_values) * ARG_COUNT))) {
|
||||
log_fatal("Unable to allocate memory for command line arguments.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* create the short-form character array (str) and the long-form option
|
||||
* array (opts) to pass to the getopt_long() function. IOW we generate
|
||||
* the arguments to pass to getopt_long() from the args.h/arg_props data.
|
||||
*/
|
||||
for (i = 0; i < ARG_COUNT; i++)
|
||||
_add_getopt_arg(_cmdline.arg_props[i].enum_val, &ptr, &o);
|
||||
/* fill in the short and long opts */
|
||||
for (i = 0; i < cmd->command->num_args; i++)
|
||||
_add_getopt_arg(cmd->command->valid_args[i], &ptr, &o);
|
||||
|
||||
*ptr = '\0';
|
||||
memset(o, 0, sizeof(*o));
|
||||
@@ -1119,23 +1055,19 @@ static int _process_command_line(struct cmd_context *cmd, int *argc,
|
||||
/* initialise getopt_long & scan for command line switches */
|
||||
optarg = 0;
|
||||
optind = OPTIND_INIT;
|
||||
while ((goval = GETOPTLONG_FN(*argc, *argv, str, opts, NULL)) >= 0) {
|
||||
while ((opt = GETOPTLONG_FN(*argc, *argv, str, opts, NULL)) >= 0) {
|
||||
|
||||
if (goval == '?')
|
||||
if (opt == '?')
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* translate the option value used by getopt into the enum
|
||||
* value (e.g. foo_ARG) from the args array....
|
||||
*/
|
||||
if ((arg_enum = _find_arg(goval)) < 0) {
|
||||
if ((arg = _find_arg(cmd->command, opt)) < 0) {
|
||||
log_fatal("Unrecognised option.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
a = _cmdline.arg_props + arg_enum;
|
||||
a = _cmdline.arg_props + arg;
|
||||
|
||||
av = &cmd->opt_arg_values[arg_enum];
|
||||
av = &cmd->opt_arg_values[arg];
|
||||
|
||||
if (a->flags & ARG_GROUPABLE) {
|
||||
/*
|
||||
@@ -1145,7 +1077,7 @@ static int _process_command_line(struct cmd_context *cmd, int *argc,
|
||||
* - or if argument has higher priority than current group.
|
||||
*/
|
||||
if (!current_group ||
|
||||
(current_group->arg_values[arg_enum].count && !(a->flags & ARG_COUNTABLE)) ||
|
||||
(current_group->arg_values[arg].count && !(a->flags & ARG_COUNTABLE)) ||
|
||||
(current_group->prio < a->prio)) {
|
||||
/* FIXME Reduce size including only groupable args */
|
||||
if (!(current_group = dm_pool_zalloc(cmd->mem, sizeof(struct arg_value_group_list) + sizeof(*cmd->opt_arg_values) * ARG_COUNT))) {
|
||||
@@ -1158,7 +1090,7 @@ static int _process_command_line(struct cmd_context *cmd, int *argc,
|
||||
}
|
||||
/* Maintain total argument count as well as count within each group */
|
||||
av->count++;
|
||||
av = ¤t_group->arg_values[arg_enum];
|
||||
av = ¤t_group->arg_values[arg];
|
||||
}
|
||||
|
||||
if (av->count && !(a->flags & ARG_COUNTABLE)) {
|
||||
@@ -1720,7 +1652,6 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||
{
|
||||
struct dm_config_tree *config_string_cft, *config_profile_command_cft, *config_profile_metadata_cft;
|
||||
const char *reason = NULL;
|
||||
const char *cmd_name;
|
||||
int ret = 0;
|
||||
int locking_type;
|
||||
int monitoring;
|
||||
@@ -1734,8 +1665,6 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||
/* each command should start out with sigint flag cleared */
|
||||
sigint_clear();
|
||||
|
||||
cmd_name = strdup(argv[0]);
|
||||
|
||||
/* eliminate '-' from all options starting with -- */
|
||||
for (i = 1; i < argc; i++) {
|
||||
|
||||
@@ -1779,10 +1708,10 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||
return EINVALID_CMD_LINE;
|
||||
}
|
||||
|
||||
if (!(cmd->command = _find_command(cmd, cmd_name)))
|
||||
if (!(cmd->command = _find_command(cmd, argv[0])))
|
||||
return ENO_SUCH_CMD;
|
||||
|
||||
set_cmd_name(cmd_name);
|
||||
set_cmd_name(cmd->command->name);
|
||||
|
||||
if (arg_is_set(cmd, backgroundfork_ARG)) {
|
||||
if (!become_daemon(cmd, 1)) {
|
||||
|
@@ -81,7 +81,6 @@ struct arg_values {
|
||||
|
||||
/* a global table of possible arguments */
|
||||
struct arg_props {
|
||||
int enum_val;
|
||||
const char short_arg;
|
||||
char _padding[7];
|
||||
const char *long_arg;
|
||||
|
Reference in New Issue
Block a user