summaryrefslogtreecommitdiff
path: root/qa/src/getoptions.c
diff options
context:
space:
mode:
Diffstat (limited to 'qa/src/getoptions.c')
-rw-r--r--qa/src/getoptions.c257
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);
+}