blob: a7def196f9938606d3fbe8f731d91a4da8b50b54 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "kcounter_cmdline.h"
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
constexpr char kShortOptions[] = "c:hltvw::";
constexpr struct option kLongOptions[] = {{"help", no_argument, nullptr, 'h'},
{"list", no_argument, nullptr, 'l'},
{"terse", no_argument, nullptr, 't'},
{"verbose", no_argument, nullptr, 'v'},
{"watch", optional_argument, nullptr, 'w'},
{"cpuid", required_argument, nullptr, 'c'},
{nullptr, 0, nullptr, 0}};
constexpr int default_period = 3;
void kcounter_usage(const char* myname, FILE* into) {
fprintf(into,
"\
Usage: %s [-hltvw] [--help] [--list] [--terse] [--verbose] [--watch[=period]] [PREFIX...]\n\
Prints one counter per line.\n\
With --help or -h, display this help and exit.\n\
With --list or -l, show names and types rather than values.\n\
With --terse or -t, show only values and no names.\n\
With --verbose or -v, show space-separated lists of per-CPU values.\n\
With --watch or -w, keep showing the values every [period] seconds, default is %d seconds.\n\
With --cpuid or -c, show only values for the chosen CPU ID.\n\
Otherwise values are aggregated summaries across all CPUs.\n\
If PREFIX arguments are given, only matching names are shown.\n\
Results are always sorted by name.\n\
",
myname, default_period);
}
bool kcounter_parse_cmdline(int argc, const char* const argv[], FILE* err,
KcounterCmdline* cmdline) {
memset(cmdline, 0, sizeof(*cmdline));
cmdline->cpuid = kNoCpuIdChosen;
optind = 0;
int opt;
while ((opt = getopt_long(argc, const_cast<char* const*>(argv), kShortOptions, kLongOptions,
nullptr)) != -1) {
switch (opt) {
case 'c':
cmdline->cpuid = atoi(optarg);
if (cmdline->cpuid < 0) {
fprintf(err, "CPU ID must be non-negative\n");
return false;
}
break;
case 'h':
cmdline->help = true;
break;
case 'l':
cmdline->list = true;
break;
case 't':
cmdline->terse = true;
break;
case 'v':
cmdline->verbose = true;
break;
case 'w':
// default to every 3 seconds.
cmdline->period = optarg ? atoi(optarg) : default_period;
if (cmdline->period < 1) {
fprintf(err, "watch period must be greater than 1\n");
return false;
}
break;
default:
return false;
}
}
if (cmdline->list + cmdline->terse + cmdline->verbose > 1) {
fprintf(err, "%s: --list, --terse, and --verbose are mutually exclusive\n", argv[0]);
kcounter_usage(argv[0], err);
return false;
}
if (cmdline->verbose && (cmdline->cpuid != kNoCpuIdChosen)) {
fprintf(err, "%s: --verbose and --cpuid mutually exclusive\n", argv[0]);
kcounter_usage(argv[0], err);
return false;
}
if (cmdline->list && cmdline->period > 0) {
fprintf(err, "%s: --list and --watch are mutually exclusive\n", argv[0]);
kcounter_usage(argv[0], err);
return false;
}
cmdline->unparsed_args_start = optind;
return true;
}