diff options
Diffstat (limited to 'qa/src/getoptions.c')
-rw-r--r-- | qa/src/getoptions.c | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/qa/src/getoptions.c b/qa/src/getoptions.c new file mode 100644 index 0000000..d3eaee9 --- /dev/null +++ b/qa/src/getoptions.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2014 Red Hat. + * + * Exercise the pmGetOptions() series of PMAPI interfaces + */ + +#include <pcp/pmapi.h> + +int +getversion(void) +{ + int version = 0; + char *value; + + if ((value = getenv("PMAPI_VERSION")) != NULL) + version = atoi(value); + return version; +} + +int +getflags(void) +{ + int flags = 0; + + if (getenv("PM_OPTFLAG_MULTI") != NULL) + flags |= PM_OPTFLAG_MULTI; + if (getenv("PM_OPTFLAG_POSIX") != NULL) + flags |= PM_OPTFLAG_POSIX; + if (getenv("PM_OPTFLAG_MIXED") != NULL) + flags |= PM_OPTFLAG_MIXED; + if (getenv("PM_OPTFLAG_ENV_ONLY") != NULL) + flags |= PM_OPTFLAG_ENV_ONLY; + if (getenv("PM_OPTFLAG_LONG_ONLY") != NULL) + flags |= PM_OPTFLAG_LONG_ONLY; + if (getenv("PM_OPTFLAG_BOUNDARIES") != NULL) + flags |= PM_OPTFLAG_BOUNDARIES; + if (getenv("PM_OPTFLAG_STDOUT_TZ") != NULL) + flags |= PM_OPTFLAG_STDOUT_TZ; + return flags; +} + +char * +flagsstr(pmOptions *opts) +{ + static char flags[128]; + + if (opts->flags & PM_OPTFLAG_INIT) + strcat(flags, ",init"); + if (opts->flags & PM_OPTFLAG_DONE) + strcat(flags, ",done"); + if (opts->flags & PM_OPTFLAG_MULTI) + strcat(flags, ",multi"); + if (opts->flags & PM_OPTFLAG_USAGE_ERR) + strcat(flags, ",usage_err"); + if (opts->flags & PM_OPTFLAG_RUNTIME_ERR) + strcat(flags, ",runtime_err"); + if (opts->flags & PM_OPTFLAG_EXIT) + strcat(flags, ",exit"); + if (opts->flags & PM_OPTFLAG_POSIX) + strcat(flags, ",posix"); + if (opts->flags & PM_OPTFLAG_MIXED) + strcat(flags, ",mixed"); + if (opts->flags & PM_OPTFLAG_ENV_ONLY) + strcat(flags, ",env_only"); + if (opts->flags & PM_OPTFLAG_LONG_ONLY) + strcat(flags, ",long_only"); + if (opts->flags & PM_OPTFLAG_BOUNDARIES) + strcat(flags, ",boundaries"); + if (opts->flags & PM_OPTFLAG_STDOUT_TZ) + strcat(flags, ",stdout_tz"); + + if (flags[0] == '\0') /* no flags */ + flags[1] = '-'; + return &flags[1]; +} + +char * +contextstr(pmOptions *opts) +{ + if (opts->context == PM_CONTEXT_HOST) + return "host"; + if (opts->context == PM_CONTEXT_ARCHIVE) + return "archive"; + if (opts->context == PM_CONTEXT_LOCAL) + return "local"; + return "-"; +} + +char * +timevalstr(struct timeval *tp) +{ + struct tm tmp; + time_t then; + int msecs = tp->tv_usec / 1000; + int len; + static char tv[128]; + + if (tp->tv_sec == 0) + return "-"; + memset(tv, 0, sizeof(tv)); + then = (time_t)tp->tv_sec; + pmLocaltime(&then, &tmp); + len = sprintf(tv, "%s", asctime(&tmp)); + sprintf(&tv[len-1], " [msec=%d]", msecs); + return tv; +} + +char * +intervalstr(struct timeval *tp) +{ + struct tm tmp; + time_t then; + int msecs = tp->tv_usec / 1000; + static char it[128]; + + if (tp->tv_sec == 0) + return "-"; + memset(it, 0, sizeof(it)); + then = (time_t)tp->tv_sec; + pmLocaltime(&then, &tmp); + sprintf(it, "%02d:%02d.%03d", tmp.tm_min, tmp.tm_sec, msecs); + return it; +} + +char * +isempty(char *string) +{ + if (string == NULL) + return "-"; + return string; +} + +void +dumpall(pmOptions *opts) +{ + int i; + + printf("Options structure dump:\n"); + printf(" version: %d\n", opts->version); + printf(" flags: 0x%x (%s)\n", opts->flags, flagsstr(opts)); + printf(" errors: %d\n", opts->errors); + printf(" context: 0x%x (%s)\n", opts->context, contextstr(opts)); + printf(" nhosts: %d\n", opts->nhosts); + if (opts->nhosts > 0) { + printf(" hosts: %s", opts->hosts[0]); + for (i = 1; i < opts->nhosts; i++) + printf(",%s", opts->hosts[i]); + printf("\n"); + } + printf(" narchives: %d\n", opts->narchives); + if (opts->narchives > 0) { + printf(" archives: %s", opts->archives[0]); + for (i = 1; i < opts->narchives; i++) + printf(",%s", opts->archives[i]); + printf("\n"); + } + printf(" start: %s\n", timevalstr(&opts->start)); + printf(" finish: %s\n", timevalstr(&opts->finish)); + printf(" origin: %s\n", timevalstr(&opts->finish)); + printf(" interval: %s\n", intervalstr(&opts->interval)); + printf(" align_optarg: %s\n", isempty(opts->align_optarg)); + printf(" start_optarg: %s\n", isempty(opts->start_optarg)); + printf(" finish_optarg: %s\n", isempty(opts->finish_optarg)); + printf(" origin_optarg: %s\n", isempty(opts->origin_optarg)); + printf(" guiport_optarg: %s\n", isempty(opts->guiport_optarg)); + printf(" timezone: %s\n", isempty(opts->timezone)); + printf(" samples: %d\n", opts->samples); + printf(" guiport: %d\n", opts->guiport); + printf(" guiflag: %d\n", opts->guiflag); + printf(" tzflag: %d\n", opts->tzflag); + printf(" Lflag: %d\n", opts->Lflag); +} + +int +main(int argc, char *argv[]) +{ + pmLongOptions longopts[] = { + PMAPI_GENERAL_OPTIONS, + PMAPI_OPTIONS_HEADER("Context options"), + PMOPT_SPECLOCAL, + PMOPT_LOCALPMDA, + PMOPT_HOSTSFILE, + PMOPT_HOST_LIST, + PMOPT_ARCHIVE_LIST, + PMOPT_ARCHIVE_FOLIO, + PMAPI_OPTIONS_HEADER("Testing options"), + { "extra", 0, 'x', 0, "an extra option, for testing" }, + { "eXtra", 1, 'X', "ARG", "an extra option with an argument" }, + { "", 0, 'y', 0, "a short-option-only without argument" }, + { "", 1, 'Y', "N", "a short-option-only with an argument" }, + { "fubar", 0, 0, 0, "a long-option-only without argument" }, + { "foobar", 1, 0, "N", "a long-option-only with an argument" }, + PMAPI_OPTIONS_END + }; + pmOptions opts = { + .short_options = PMAPI_OPTIONS "H:K:L" "XxYy", + .long_options = longopts, + }; + char *tz; + int c; + + opts.version = getversion(); + opts.flags = getflags(); + while ((c = pmGetOptions(argc, argv, &opts)) != EOF) { + printf("Got option: %c index=%d [errors=%d]\n", c? c: '-', opts.index, opts.errors); + switch(c) { + case 'x': + printf(" -> x option has no argument\n"); + break; + case 'X': + printf(" -> X option argument was: '%s'\n", opts.optarg); + break; + case 'y': + printf(" -> y option has no argument\n"); + break; + case 'Y': + printf(" -> Y option argument was: '%s'\n", opts.optarg); + break; + case 0: /* long-only options */ + printf(" -> long-only option index=%d\n", opts.index); + break; + default: + printf(" -> unexpected option: '%c'\n", c); + pmUsageMessage(&opts); + exit(1); + } + } + printf("End of option processing\n"); + + if (opts.flags & PM_OPTFLAG_USAGE_ERR) + fprintf(stderr, "Warning: usage error detected\n"); + if (opts.flags & PM_OPTFLAG_RUNTIME_ERR) + fprintf(stderr, "Warning: runtime error detected\n"); + if (opts.padding != 0) + fprintf(stderr, "Warning: non-zero padding\n"); + if (opts.zeroes != 0) + fprintf(stderr, "Warning: unexpected non-zeroes\n"); + + if (opts.flags & PM_OPTFLAG_USAGE_ERR) + pmUsageMessage(&opts); + if (opts.flags & PM_OPTFLAG_RUNTIME_ERR) + pmflush(); + + if (opts.timezone) /* ensure we have deterministic output */ + tz = opts.timezone; + else + tz = "UTC"; + + if ((c = pmNewZone(tz)) < 0) + fprintf(stderr, "Warning: TZ failure - %s: %s\n", + opts.timezone, pmErrStr(c)); + + dumpall(&opts); + + pmFreeOptions(&opts); + exit(0); +} |