CommandLine.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9#include "squid.h"
10
11#include "CommandLine.h"
12#include "sbuf/SBuf.h"
13
14static void
15ResetGetopt(const bool allowStderrWarnings)
16{
17 opterr = allowStderrWarnings;
18 // Resetting optind to zero instead of conventional '1' has an
19 // advantage, since it also resets getopt(3) global state.
20 // getopt(3) always skips argv[0], even if optind is zero
21 optind = 0;
22}
23
24CommandLine::CommandLine(int argC, char *argV[], const char *shortRules, const RawLongOption *longRules):
25 argv_(),
26 shortOptions_(shortRules ? xstrdup(shortRules) : ""),
27 longOptions_()
28{
29 assert(argC > 0); // C++ main() requirement that makes our arg0() safe
30 assert(shortRules);
31
32 /* copy argV items */
33 argv_.reserve(argC+1);
34 for (int i = 0; i < argC; ++i)
35 argv_.push_back(xstrdup(argV[i]));
36 argv_.push_back(nullptr); // POSIX argv "must be terminated by a null pointer"
37
38 /* copy grammar rules for the long options */
39 if (longRules) {
40 for (auto longOption = longRules; longOption->name; ++longOption)
41 longOptions_.emplace_back(*longOption);
42 longOptions_.emplace_back();
43 }
44}
45
47 CommandLine(them.argc(), them.argv(), them.shortOptions_, them.longOptions())
48{
49}
50
53{
54 // cannot just swap(*this, them): std::swap(T,T) may call this assignment op
55 CommandLine tmp(them);
56 std::swap(argv_, tmp.argv_);
57 std::swap(shortOptions_, tmp.shortOptions_);
58 std::swap(longOptions_, tmp.longOptions_);
59 return *this;
60}
61
63{
64 for (auto arg: argv_)
65 xfree(arg);
66
68}
69
70bool
71CommandLine::hasOption(const int optIdToFind, const char **optValue) const
72{
73 ResetGetopt(false); // avoid duped warnings; forEachOption() will complain
74 int optId = 0;
75 while (nextOption(optId)) {
76 if (optId == optIdToFind) {
77 if (optValue) {
78 // do not need to copy the optarg string because it is a pointer into the original
79 // argv array (https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html)
80 *optValue = optarg;
81 }
82 return true;
83 }
84 }
85 return false;
86}
87
88void
89CommandLine::forEachOption(Visitor visitor) const
90{
91 ResetGetopt(true);
92 int optId = 0;
93 while (nextOption(optId))
94 visitor(optId, optarg);
95}
96
100bool
101CommandLine::nextOption(int &optId) const
102{
103 optId = getopt_long(argc(), argv(), shortOptions_, longOptions(), nullptr);
104 if ((optId == ':' && shortOptions_[0] == ':') || optId == '?') {
105 assert(optind > 0 && static_cast<unsigned int>(optind) < argv_.size());
106 SBuf errMsg;
107 errMsg.Printf("'%s': %s", argv_[optind - 1], optId == '?' ?
108 "unrecognized option or missing required argument" : "missing required argument");
109 throw TexcHere(errMsg);
110 }
111 return optId != -1;
112}
113
114void
115CommandLine::resetArg0(const char *programName)
116{
117 assert(programName);
118 xfree(argv_[0]);
119 argv_[0] = xstrdup(programName);
120}
121
122void
123CommandLine::pushFrontOption(const char *name, const char *value)
124{
125 assert(name);
126 argv_.insert(argv_.begin() + 1, xstrdup(name));
127 if (value)
128 argv_.insert(argv_.begin() + 2, xstrdup(value));
129}
130
132 option({nullptr, 0, nullptr, 0})
133{
134}
135
137 option({nullptr, 0, nullptr, 0})
138{
139 copy(opt);
140}
141
143 LongOption(static_cast<const RawLongOption &>(opt))
144{
145}
146
148{
149 xfree(name);
150}
151
154{
155 if (this != &opt)
156 copy(static_cast<const RawLongOption &>(opt));
157 return *this;
158}
159
160void
162{
163 xfree(name);
164 name = opt.name ? xstrdup(opt.name) : nullptr;
165 has_arg = opt.has_arg;
166 flag = opt.flag;
167 val = opt.val;
168}
169
static void ResetGetopt(const bool allowStderrWarnings)
Definition: CommandLine.cc:15
#define TexcHere(msg)
legacy convenience macro; it is not difficult to type Here() now
Definition: TextException.h:63
#define assert(EX)
Definition: assert.h:17
Manages arguments passed to a program (i.e., main(argc, argv) parameters).
Definition: CommandLine.h:35
std::vector< char * > argv_
raw main() parameters, including argv[0] and a nil argv[argc]
Definition: CommandLine.h:77
int argc() const
Definition: CommandLine.h:61
bool hasOption(const int optId, const char **optValue=nullptr) const
Definition: CommandLine.cc:71
CommandLine & operator=(const CommandLine &)
Definition: CommandLine.cc:52
const RawLongOption * longOptions() const
Definition: CommandLine.h:73
void forEachOption(Visitor) const
calls Visitor for each of the configured command line option
Definition: CommandLine.cc:89
std::vector< LongOption > longOptions_
long –option rules
Definition: CommandLine.h:81
const char * shortOptions_
single-dash, single-letter (-x) option rules
Definition: CommandLine.h:80
void resetArg0(const char *programName)
replaces argv[0] with the new value
Definition: CommandLine.cc:115
CommandLine(int argc, char *argv[], const char *shortRules, const RawLongOption *longRules)
expects main() input plus getopt_long(3) grammar rules for parsing argv
Definition: CommandLine.cc:24
void pushFrontOption(const char *name, const char *value=nullptr)
inserts a (possibly duplicated) option at the beginning of options (just after argv[0])
Definition: CommandLine.cc:123
bool nextOption(int &optId) const
Definition: CommandLine.cc:101
char ** argv() const
Definition: CommandLine.h:64
A struct option C++ wrapper, helps with option::name copying/freeing.
Definition: CommandLine.h:21
void copy(const RawLongOption &)
Definition: CommandLine.cc:161
LongOption & operator=(const LongOption &)
Definition: CommandLine.cc:153
Definition: SBuf.h:94
SBuf & Printf(const char *fmt,...) PRINTF_FORMAT_ARG2
Definition: SBuf.cc:214
int optind
Definition: getopt.c:48
char * optarg
Definition: getopt.c:51
int opterr
Definition: getopt.c:47
#define xfree
#define xstrdup

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors