mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-24 02:35:41 +00:00
Acked-by: Mike Rapoport <rppt@linux.ibm.com> Signed-off-by: Adrian Reber <areber@redhat.com>
168 lines
3.2 KiB
C
168 lines
3.2 KiB
C
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include "zdtmtst.h"
|
|
|
|
static struct long_opt *opt_head;
|
|
|
|
static int help;
|
|
TEST_OPTION(help, bool, "print help message and exit", 0);
|
|
|
|
void __push_opt(struct long_opt *opt)
|
|
{
|
|
opt->next = opt_head;
|
|
/* FIXME: barrier ? */
|
|
opt_head = opt;
|
|
}
|
|
|
|
int parse_opt_bool(char *param, void *arg)
|
|
{
|
|
if (param == NULL || !strcmp(param, "on") || !strcmp(param, "yes") || !strcmp(param, "true")) {
|
|
*(int *)arg = 1;
|
|
return 0;
|
|
}
|
|
if (!strcmp(param, "off") || !strcmp(param, "no") || !strcmp(param, "false")) {
|
|
*(int *)arg = 0;
|
|
return 0;
|
|
}
|
|
return -EINVAL;
|
|
}
|
|
|
|
int parse_opt_int(char *param, void *arg)
|
|
{
|
|
char *tail;
|
|
if (param == NULL || param[0] == '\0')
|
|
return -EINVAL;
|
|
*(int *)arg = strtol(param, &tail, 0);
|
|
if (tail[0] != '\0')
|
|
return -EINVAL;
|
|
return 0;
|
|
}
|
|
|
|
int parse_opt_uint(char *param, void *arg)
|
|
{
|
|
char *tail;
|
|
if (param == NULL || param[0] == '\0')
|
|
return -EINVAL;
|
|
*(unsigned int *)arg = strtoul(param, &tail, 0);
|
|
if (tail[0] != '\0')
|
|
return -EINVAL;
|
|
return 0;
|
|
}
|
|
|
|
int parse_opt_long(char *param, void *arg)
|
|
{
|
|
char *tail;
|
|
if (param == NULL || param[0] == '\0')
|
|
return -EINVAL;
|
|
*(long *)arg = strtol(param, &tail, 0);
|
|
if (tail[0] != '\0')
|
|
return -EINVAL;
|
|
return 0;
|
|
}
|
|
|
|
int parse_opt_ulong(char *param, void *arg)
|
|
{
|
|
char *tail;
|
|
if (param == NULL || param[0] == '\0')
|
|
return -EINVAL;
|
|
*(unsigned long *)arg = strtoul(param, &tail, 0);
|
|
if (tail[0] != '\0')
|
|
return -EINVAL;
|
|
return 0;
|
|
}
|
|
|
|
int parse_opt_string(char *param, void *arg)
|
|
{
|
|
if (param == NULL || param[0] == '\0')
|
|
return -EINVAL;
|
|
*(char **)arg = param;
|
|
return 0;
|
|
}
|
|
|
|
static void printopt(const struct long_opt *opt)
|
|
{
|
|
const char *obracket = "", *cbracket = "";
|
|
|
|
if (!opt->is_required) {
|
|
obracket = "[";
|
|
cbracket = "]";
|
|
}
|
|
|
|
fprintf(stderr, " %s--%s=%s%s\t%s\n", obracket, opt->name, opt->type, cbracket, opt->doc);
|
|
}
|
|
|
|
static void helpexit(void)
|
|
{
|
|
struct long_opt *opt;
|
|
|
|
fputs("Usage:\n", stderr);
|
|
|
|
for (opt = opt_head; opt; opt = opt->next)
|
|
printopt(opt);
|
|
|
|
exit(1);
|
|
}
|
|
|
|
const char __attribute__((weak)) * test_doc;
|
|
const char __attribute__((weak)) * test_author;
|
|
|
|
static void prdoc(void)
|
|
{
|
|
if (test_doc)
|
|
fprintf(stderr, "%s\n", test_doc);
|
|
if (test_author)
|
|
fprintf(stderr, "Author: %s\n", test_author);
|
|
}
|
|
|
|
void parseargs(int argc, char **argv)
|
|
{
|
|
int i;
|
|
struct long_opt *opt;
|
|
|
|
for (i = 1; i < argc; i++) {
|
|
char *name, *value;
|
|
|
|
if (strlen(argv[i]) < 2 || strncmp(argv[i], "--", 2)) {
|
|
fprintf(stderr, "%s: options should start with --\n", argv[i]);
|
|
helpexit();
|
|
}
|
|
|
|
name = argv[i] + 2;
|
|
|
|
value = strchr(name, '=');
|
|
if (value)
|
|
value++;
|
|
|
|
for (opt = opt_head; opt; opt = opt->next)
|
|
if (!strncmp(name, opt->name, value - name - 1)) {
|
|
if (opt->parse_opt(value, opt->value)) {
|
|
fprintf(stderr, "%s: failed to parse\n", argv[i]);
|
|
helpexit();
|
|
} else
|
|
/* -1 marks fulfilled requirement */
|
|
opt->is_required = -opt->is_required;
|
|
|
|
break;
|
|
}
|
|
|
|
if (!opt) {
|
|
fprintf(stderr, "%s: unknown option\n", argv[i]);
|
|
helpexit();
|
|
}
|
|
}
|
|
|
|
if (help) {
|
|
prdoc();
|
|
helpexit();
|
|
}
|
|
|
|
for (opt = opt_head; opt; opt = opt->next)
|
|
if (opt->is_required > 0) {
|
|
fprintf(stderr, "mandatory flag --%s not given\n", opt->name);
|
|
helpexit();
|
|
}
|
|
}
|