MFp4:
- Print proper error message when argument is specified twice. Before the change it was detected properly, because of how G_OPT_DONE() macro worked. - Use err(3) functions where appropriate. - Add some assertions. - Bump version number, because G_TYPE_BOOL addition breaks API and ABI. Changes: 98721,98722,98723,101360,106985
This commit is contained in:
parent
59b61d5e58
commit
0160abf37e
@ -75,7 +75,7 @@ struct g_command std_commands[] = {
|
||||
},
|
||||
{ "status", 0, std_status,
|
||||
{
|
||||
{ 's', "script", NULL, G_TYPE_NONE },
|
||||
{ 's', "script", NULL, G_TYPE_BOOL },
|
||||
G_OPT_SENTINEL
|
||||
},
|
||||
"[-s] [name ...]"
|
||||
@ -102,14 +102,14 @@ usage_command(struct g_command *cmd, const char *prefix)
|
||||
opt = &cmd->gc_options[i];
|
||||
if (opt->go_name == NULL)
|
||||
break;
|
||||
if (opt->go_val != NULL || opt->go_type == G_TYPE_NONE)
|
||||
if (opt->go_val != NULL || G_OPT_TYPE(opt) == G_TYPE_BOOL)
|
||||
fprintf(stderr, " [");
|
||||
else
|
||||
fprintf(stderr, " ");
|
||||
fprintf(stderr, "-%c", opt->go_char);
|
||||
if (opt->go_type != G_TYPE_NONE)
|
||||
if (G_OPT_TYPE(opt) != G_TYPE_BOOL)
|
||||
fprintf(stderr, " %s", opt->go_name);
|
||||
if (opt->go_val != NULL || opt->go_type == G_TYPE_NONE)
|
||||
if (opt->go_val != NULL || G_OPT_TYPE(opt) == G_TYPE_BOOL)
|
||||
fprintf(stderr, "]");
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
@ -218,7 +218,7 @@ static void
|
||||
set_option(struct gctl_req *req, struct g_option *opt, const char *val)
|
||||
{
|
||||
|
||||
if (opt->go_type == G_TYPE_NUMBER) {
|
||||
if (G_OPT_TYPE(opt) == G_TYPE_NUMBER) {
|
||||
intmax_t number;
|
||||
|
||||
errno = 0;
|
||||
@ -233,9 +233,9 @@ set_option(struct gctl_req *req, struct g_option *opt, const char *val)
|
||||
*(intmax_t *)opt->go_val = number;
|
||||
|
||||
gctl_ro_param(req, opt->go_name, sizeof(intmax_t), opt->go_val);
|
||||
} else if (opt->go_type == G_TYPE_STRING) {
|
||||
} else if (G_OPT_TYPE(opt) == G_TYPE_STRING) {
|
||||
gctl_ro_param(req, opt->go_name, -1, optarg);
|
||||
} else /* if (opt->go_type == G_TYPE_NONE) */ {
|
||||
} else if (G_OPT_TYPE(opt) == G_TYPE_BOOL) {
|
||||
opt->go_val = malloc(sizeof(int));
|
||||
if (opt->go_val == NULL)
|
||||
errx(EXIT_FAILURE, "No memory.");
|
||||
@ -243,6 +243,8 @@ set_option(struct gctl_req *req, struct g_option *opt, const char *val)
|
||||
|
||||
gctl_ro_param(req, opt->go_name, sizeof(int),
|
||||
opt->go_val);
|
||||
} else {
|
||||
assert(!"Invalid type");
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,8 +269,10 @@ parse_arguments(struct g_command *cmd, struct gctl_req *req, int *argc,
|
||||
opt = &cmd->gc_options[i];
|
||||
if (opt->go_name == NULL)
|
||||
break;
|
||||
assert(G_OPT_TYPE(opt) != 0);
|
||||
assert((opt->go_type & ~G_TYPE_MASK) == 0);
|
||||
strlcatf(opts, sizeof(opts), "%c", opt->go_char);
|
||||
if (opt->go_type != G_TYPE_NONE)
|
||||
if (G_OPT_TYPE(opt) != G_TYPE_BOOL)
|
||||
strlcat(opts, ":", sizeof(opts));
|
||||
}
|
||||
|
||||
@ -287,13 +291,12 @@ parse_arguments(struct g_command *cmd, struct gctl_req *req, int *argc,
|
||||
if (opt == NULL)
|
||||
usage();
|
||||
if (G_OPT_ISDONE(opt)) {
|
||||
fprintf(stderr, "Flag '%c' specified twice.\n",
|
||||
opt->go_char);
|
||||
warnx("Option '%c' specified twice.", opt->go_char);
|
||||
usage();
|
||||
}
|
||||
G_OPT_DONE(opt);
|
||||
|
||||
if (opt->go_type == G_TYPE_NONE)
|
||||
if (G_OPT_TYPE(opt) == G_TYPE_BOOL)
|
||||
set_option(req, opt, "1");
|
||||
else
|
||||
set_option(req, opt, optarg);
|
||||
@ -311,21 +314,23 @@ parse_arguments(struct g_command *cmd, struct gctl_req *req, int *argc,
|
||||
if (G_OPT_ISDONE(opt))
|
||||
continue;
|
||||
|
||||
if (opt->go_type == G_TYPE_NONE) {
|
||||
if (G_OPT_TYPE(opt) == G_TYPE_BOOL) {
|
||||
assert(opt->go_val == NULL);
|
||||
set_option(req, opt, "0");
|
||||
} else {
|
||||
if (opt->go_val == NULL) {
|
||||
fprintf(stderr, "Flag '%c' not specified.\n",
|
||||
warnx("Option '%c' not specified.",
|
||||
opt->go_char);
|
||||
usage();
|
||||
} else {
|
||||
if (opt->go_type == G_TYPE_NUMBER) {
|
||||
if (G_OPT_TYPE(opt) == G_TYPE_NUMBER) {
|
||||
gctl_ro_param(req, opt->go_name,
|
||||
sizeof(intmax_t), opt->go_val);
|
||||
} else /* if (opt->go_type == G_TYPE_STRING)*/ {
|
||||
} else if (G_OPT_TYPE(opt) == G_TYPE_STRING) {
|
||||
gctl_ro_param(req, opt->go_name, -1,
|
||||
opt->go_val);
|
||||
} else {
|
||||
assert(!"Invalid type");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -406,12 +411,11 @@ run_command(int argc, char *argv[])
|
||||
/* Now, try to find a standard command. */
|
||||
cmd = find_command(argv[0], GEOM_STD_CMDS);
|
||||
if (cmd == NULL) {
|
||||
fprintf(stderr, "Unknown command: %s\n", argv[0]);
|
||||
warnx("Unknown command: %s.", argv[0]);
|
||||
usage();
|
||||
}
|
||||
if (!std_available(cmd->gc_name)) {
|
||||
fprintf(stderr, "Command '%s' not available.\n",
|
||||
argv[0]);
|
||||
warnx("Command '%s' not available.", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@ -437,7 +441,7 @@ run_command(int argc, char *argv[])
|
||||
errstr = gctl_issue(req);
|
||||
}
|
||||
if (errstr != NULL && errstr[0] != '\0') {
|
||||
fprintf(stderr, "%s\n", errstr);
|
||||
warnx("%s", errstr);
|
||||
if (strncmp(errstr, "warning: ", strlen("warning: ")) != 0) {
|
||||
gctl_free(req);
|
||||
exit(EXIT_FAILURE);
|
||||
@ -486,8 +490,7 @@ load_library(void)
|
||||
errx(EXIT_FAILURE, "Cannot open library: %s.", dlerror());
|
||||
lib_version = dlsym(dlh, "lib_version");
|
||||
if (lib_version == NULL) {
|
||||
fprintf(stderr, "Cannot find symbol %s: %s.\n", "lib_version",
|
||||
dlerror());
|
||||
warnx("Cannot find symbol %s: %s.", "lib_version", dlerror());
|
||||
dlclose(dlh);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -498,15 +501,14 @@ load_library(void)
|
||||
}
|
||||
version = dlsym(dlh, "version");
|
||||
if (version == NULL) {
|
||||
fprintf(stderr, "Cannot find symbol %s: %s.\n", "version",
|
||||
dlerror());
|
||||
warnx("Cannot find symbol %s: %s.", "version", dlerror());
|
||||
dlclose(dlh);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
class_commands = dlsym(dlh, "class_commands");
|
||||
if (class_commands == NULL) {
|
||||
fprintf(stderr, "Cannot find symbol %s: %s.\n",
|
||||
"class_commands", dlerror());
|
||||
warnx("Cannot find symbol %s: %s.", "class_commands",
|
||||
dlerror());
|
||||
dlclose(dlh);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -688,10 +690,8 @@ std_list_available(void)
|
||||
int error;
|
||||
|
||||
error = geom_gettree(&mesh);
|
||||
if (error != 0) {
|
||||
fprintf(stderr, "Cannot get GEOM tree: %s.\n", strerror(error));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (error != 0)
|
||||
errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
|
||||
classp = find_class(&mesh, gclass_name);
|
||||
geom_deletetree(&mesh);
|
||||
if (classp != NULL)
|
||||
@ -709,14 +709,12 @@ std_list(struct gctl_req *req, unsigned flags __unused)
|
||||
int error, i, nargs;
|
||||
|
||||
error = geom_gettree(&mesh);
|
||||
if (error != 0) {
|
||||
fprintf(stderr, "Cannot get GEOM tree: %s.\n", strerror(error));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (error != 0)
|
||||
errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
|
||||
classp = find_class(&mesh, gclass_name);
|
||||
if (classp == NULL) {
|
||||
geom_deletetree(&mesh);
|
||||
fprintf(stderr, "Class %s not found.\n", gclass_name);
|
||||
warnx("Class %s not found.", gclass_name);
|
||||
return;
|
||||
}
|
||||
nargs = gctl_get_int(req, "nargs");
|
||||
@ -727,7 +725,7 @@ std_list(struct gctl_req *req, unsigned flags __unused)
|
||||
if (gp != NULL)
|
||||
list_one_geom(gp);
|
||||
else
|
||||
fprintf(stderr, "No such geom: %s.\n", name);
|
||||
warnx("No such geom: %s.", name);
|
||||
}
|
||||
} else {
|
||||
LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
|
||||
@ -847,13 +845,11 @@ std_status(struct gctl_req *req, unsigned flags __unused)
|
||||
int error, i, n, nargs, script;
|
||||
|
||||
error = geom_gettree(&mesh);
|
||||
if (error != 0) {
|
||||
fprintf(stderr, "Cannot get GEOM tree: %s.\n", strerror(error));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (error != 0)
|
||||
errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
|
||||
classp = find_class(&mesh, gclass_name);
|
||||
if (classp == NULL) {
|
||||
fprintf(stderr, "Class %s not found.\n", gclass_name);
|
||||
warnx("Class %s not found.", gclass_name);
|
||||
goto end;
|
||||
}
|
||||
nargs = gctl_get_int(req, "nargs");
|
||||
@ -865,7 +861,7 @@ std_status(struct gctl_req *req, unsigned flags __unused)
|
||||
name = gctl_get_ascii(req, "arg%d", i);
|
||||
gp = find_geom(classp, name);
|
||||
if (gp == NULL)
|
||||
fprintf(stderr, "No such geom: %s.\n", name);
|
||||
warnx("No such geom: %s.", name);
|
||||
else {
|
||||
status_update_len(gp, &name_len, &status_len);
|
||||
n++;
|
||||
|
@ -28,19 +28,23 @@
|
||||
|
||||
#ifndef _GEOM_H_
|
||||
#define _GEOM_H_
|
||||
#define G_LIB_VERSION 1
|
||||
#define G_LIB_VERSION 2
|
||||
|
||||
#define G_FLAG_NONE 0x0000
|
||||
#define G_FLAG_VERBOSE 0x0001
|
||||
#define G_FLAG_LOADKLD 0x0002
|
||||
|
||||
#define G_TYPE_NONE 0
|
||||
#define G_TYPE_STRING 1
|
||||
#define G_TYPE_NUMBER 2
|
||||
#define G_TYPE_NONE 0x00
|
||||
#define G_TYPE_BOOL 0x01
|
||||
#define G_TYPE_STRING 0x02
|
||||
#define G_TYPE_NUMBER 0x03
|
||||
#define G_TYPE_MASK 0x03
|
||||
#define G_TYPE_DONE 0x10
|
||||
|
||||
#define G_OPT_MAX 16
|
||||
#define G_OPT_DONE(opt) (opt)->go_char = '\0'
|
||||
#define G_OPT_ISDONE(opt) ((opt)->go_char == '\0')
|
||||
#define G_OPT_DONE(opt) do { (opt)->go_type |= G_TYPE_DONE; } while (0)
|
||||
#define G_OPT_ISDONE(opt) ((opt)->go_type & G_TYPE_DONE)
|
||||
#define G_OPT_TYPE(opt) ((opt)->go_type & G_TYPE_MASK)
|
||||
|
||||
#define G_OPT_SENTINEL { '\0', NULL, NULL, G_TYPE_NONE }
|
||||
#define G_NULL_OPTS { G_OPT_SENTINEL }
|
||||
|
Loading…
x
Reference in New Issue
Block a user