Skip to content

Commit c8f2c8a

Browse files
committed
Add parseValue(PlanValue&) method to replace version taking all PlanValue members as separate arguments.
1 parent 762f7b1 commit c8f2c8a

2 files changed

Lines changed: 88 additions & 99 deletions

File tree

libs/dimcli/cli.cpp

Lines changed: 87 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ struct ParseState {
163163
unordered_map<Cli::OptBase *, int> optMatches;
164164
};
165165

166-
struct RawValue {
166+
struct PlanValue {
167167
enum Type { kOperand, kOption, kCommand } type;
168168
Cli::OptBase * opt;
169169
string name;
@@ -229,6 +229,8 @@ struct Cli::Config {
229229
);
230230
static const GroupConfig & findGrpOrDie(const Cli & cli);
231231

232+
static bool parseValue(Cli & cli, const PlanValue & val);
233+
232234
Config();
233235
void updateWidth(size_t width);
234236
};
@@ -284,8 +286,8 @@ struct Cli::OptIndex {
284286
//-----------------------------------------------------------------------
285287
// Parsing
286288
// Will completely rebuild index for new command if one is found.
287-
bool parseToRawValues(
288-
vector<RawValue> * out,
289+
bool parseToPlanValues(
290+
vector<PlanValue> * out,
289291
const vector<Cli::Arg> & args,
290292
Cli & cli
291293
);
@@ -314,13 +316,13 @@ struct Cli::OptIndex {
314316
);
315317

316318
bool parseOperandValue(
317-
vector<RawValue> * out,
319+
vector<PlanValue> * out,
318320
ParseState & st,
319321
Cli & cli,
320322
const vector<Cli::Arg> & args
321323
);
322324
bool parseOptionValue(
323-
vector<RawValue> * out,
325+
vector<PlanValue> * out,
324326
ParseState & st,
325327
Cli & cli,
326328
const vector<Cli::Arg> & args
@@ -740,6 +742,54 @@ void Cli::Config::updateWidth(size_t width) {
740742
/ width;
741743
}
742744

745+
//===========================================================================
746+
// static
747+
bool Cli::Config::parseValue(Cli & cli, const PlanValue & val) {
748+
auto & cfg = Cli::Config::get(cli);
749+
auto & opt = *val.opt;
750+
ArgMatch match;
751+
match.name = val.name;
752+
match.pos = (int) val.pos;
753+
match.src = val.src;
754+
if (!opt.match(match)) {
755+
string prefix = "Too many '" + val.name + "' values";
756+
string detail = "The maximum number of values is "
757+
+ intToString(opt, opt.maxSize()) + ".";
758+
cli.badUsage(prefix, val.ptr, detail);
759+
return false;
760+
}
761+
if (val.ptr) {
762+
cfg.originalValue = val.ptr;
763+
cfg.newValue = val.ptr;
764+
cfg.curOpt = &opt;
765+
opt.doTransforms(cli);
766+
cfg.curOpt = {};
767+
if (!cli.parseAborted()) {
768+
if (opt.m_bool) {
769+
bool bval = false;
770+
if (!parseBool(bval, cli.newValue())) {
771+
cli.badUsage(opt);
772+
return false;
773+
}
774+
if (val.nameFlags & fNameInvert)
775+
bval = !bval;
776+
cfg.newValue = bval ? "1" : "0";
777+
}
778+
opt.doParse(cli);
779+
}
780+
if (!cli.parseAborted())
781+
opt.doChecks(cli);
782+
} else {
783+
cfg.originalValue.clear();
784+
cfg.newValue.clear();
785+
opt.assignImplicit();
786+
opt.doChecks(cli);
787+
}
788+
cfg.originalValue.clear();
789+
cfg.newValue.clear();
790+
return !cli.parseAborted();
791+
}
792+
743793

744794
/****************************************************************************
745795
*
@@ -2091,8 +2141,8 @@ static int numMatches(
20912141

20922142
//===========================================================================
20932143
static bool matchOperands(
2094-
RawValue * rawValues,
2095-
size_t numRawValues,
2144+
PlanValue * planValues,
2145+
size_t numPlanValues,
20962146
Cli & cli,
20972147
const Cli::OptIndex & ndx,
20982148
int numOprs
@@ -2112,9 +2162,9 @@ static bool matchOperands(
21122162
}
21132163

21142164
if (usedOprs < numOprs) {
2115-
auto val = rawValues;
2165+
auto val = planValues;
21162166
for (int ipos = -1;; ++val) {
2117-
if (val->type == RawValue::kOperand && ++ipos >= usedOprs)
2167+
if (val->type == PlanValue::kOperand && ++ipos >= usedOprs)
21182168
break;
21192169
}
21202170
cli.badUsage("Unexpected argument", val->ptr);
@@ -2125,8 +2175,8 @@ static bool matchOperands(
21252175

21262176
int ipos = 0; // Operand being matched.
21272177
int imatch = 0; // Values already been matched to this opt.
2128-
for (auto val = rawValues; val < rawValues + numRawValues; ++val) {
2129-
if (val->opt || val->type != RawValue::kOperand)
2178+
for (auto val = planValues; val < planValues + numPlanValues; ++val) {
2179+
if (val->opt || val->type != PlanValue::kOperand)
21302180
continue;
21312181
if (matched[ipos] <= imatch) {
21322182
imatch = 0;
@@ -2147,7 +2197,7 @@ static bool matchOperands(
21472197

21482198
//===========================================================================
21492199
bool Cli::OptIndex::parseOperandValue(
2150-
vector<RawValue> * out,
2200+
vector<PlanValue> * out,
21512201
ParseState & st,
21522202
Cli & cli,
21532203
const vector<Cli::Arg> & args
@@ -2173,7 +2223,7 @@ bool Cli::OptIndex::parseOperandValue(
21732223

21742224
// Add command raw value and prepare for new set of opt rules
21752225
// that are defined by the command.
2176-
out->push_back({ RawValue::kCommand, nullptr, cmd });
2226+
out->push_back({ PlanValue::kCommand, nullptr, cmd });
21772227
st.precmdValues = out->size();
21782228
st.numOprs = 0;
21792229

@@ -2213,7 +2263,7 @@ bool Cli::OptIndex::parseOperandValue(
22132263
// Record operand, it will be assigned and named later by assignOperands().
22142264
st.numOprs += 1;
22152265
out->push_back({
2216-
RawValue::kOperand,
2266+
PlanValue::kOperand,
22172267
nullptr, // opt
22182268
string{}, // opt name
22192269
0, // opt name flags
@@ -2227,7 +2277,7 @@ bool Cli::OptIndex::parseOperandValue(
22272277

22282278
//===========================================================================
22292279
static void addOptionMatch(
2230-
vector<RawValue> * out,
2280+
vector<PlanValue> * out,
22312281
ParseState & st,
22322282
const char * ptr,
22332283
const vector<Cli::Arg> & args
@@ -2236,7 +2286,7 @@ static void addOptionMatch(
22362286
Cli::ArgSrc src;
22372287
src.type = Cli::ArgSrc::kNone;
22382288
out->push_back({
2239-
RawValue::kOption,
2289+
PlanValue::kOption,
22402290
st.optName.opt,
22412291
st.name,
22422292
st.optName.flags,
@@ -2248,7 +2298,7 @@ static void addOptionMatch(
22482298

22492299
//===========================================================================
22502300
bool Cli::OptIndex::parseOptionValue(
2251-
vector<RawValue> * out,
2301+
vector<PlanValue> * out,
22522302
ParseState & st,
22532303
Cli & cli,
22542304
const vector<Cli::Arg> & args
@@ -2306,8 +2356,8 @@ static bool commandRequired(const Cli::Config & cfg) {
23062356
}
23072357

23082358
//===========================================================================
2309-
bool Cli::OptIndex::parseToRawValues(
2310-
vector<RawValue> * out,
2359+
bool Cli::OptIndex::parseToPlanValues(
2360+
vector<PlanValue> * out,
23112361
const vector<Cli::Arg> & args,
23122362
Cli & cli
23132363
) {
@@ -2540,31 +2590,22 @@ static bool parse(Cli & cli, vector<string> & rawArgs) {
25402590
}
25412591

25422592
// Extract raw values and match them to opts.
2543-
vector<RawValue> rawValues;
2544-
if (!ndx.parseToRawValues(&rawValues, args, cli))
2593+
vector<PlanValue> planValues;
2594+
if (!ndx.parseToPlanValues(&planValues, args, cli))
25452595
return false;
25462596

25472597
// Parse values and copy them to defined opts.
25482598
cfg.command.clear();
2549-
for (auto && val : rawValues) {
2599+
for (auto && val : planValues) {
25502600
switch (val.type) {
2551-
case RawValue::kCommand:
2601+
case PlanValue::kCommand:
25522602
cfg.command = val.name;
25532603
continue;
25542604
default:
25552605
break;
25562606
}
2557-
if (!cli.parseValue(
2558-
*val.opt,
2559-
val.name,
2560-
val.nameFlags,
2561-
val.pos,
2562-
val.src.type,
2563-
val.src.name,
2564-
val.ptr
2565-
)) {
2607+
if (!Cli::Config::parseValue(cli, val))
25662608
return false;
2567-
}
25682609
}
25692610

25702611
// Report operands and options with too few values.
@@ -2736,7 +2777,13 @@ bool Cli::parseValue(
27362777
size_t pos,
27372778
const char ptr[]
27382779
) {
2739-
return parseValue(opt, name, 0, pos, ArgSrc::kArgv, {}, ptr);
2780+
PlanValue val = { PlanValue::kOperand };
2781+
val.opt = &opt;
2782+
val.name = name;
2783+
val.pos = pos;
2784+
val.src = { ArgSrc::kArgv, {} };
2785+
val.ptr = ptr;
2786+
return Config::parseValue(*this, val);
27402787
}
27412788

27422789
//===========================================================================
@@ -2746,61 +2793,12 @@ bool Cli::parseValue(
27462793
const std::string & srcName, // use {} if unsure
27472794
const char ptr[]
27482795
) {
2749-
return parseValue(opt, opt.defaultFrom(), 0, 0, srcType, srcName, ptr);
2750-
}
2751-
2752-
//===========================================================================
2753-
bool Cli::parseValue(
2754-
OptBase & opt,
2755-
const string & name,
2756-
unsigned nameFlags,
2757-
size_t pos,
2758-
ArgSrc::Type srcType,
2759-
const string & srcName,
2760-
const char ptr[]
2761-
) {
2762-
ArgMatch match;
2763-
match.name = name;
2764-
match.pos = (int) pos;
2765-
match.src.type = srcType;
2766-
match.src.name = srcName;
2767-
if (!opt.match(match)) {
2768-
string prefix = "Too many '" + name + "' values";
2769-
string detail = "The maximum number of values is "
2770-
+ intToString(opt, opt.maxSize()) + ".";
2771-
badUsage(prefix, ptr, detail);
2772-
return false;
2773-
}
2774-
if (ptr) {
2775-
m_cfg->originalValue = ptr;
2776-
m_cfg->newValue = ptr;
2777-
m_cfg->curOpt = &opt;
2778-
opt.doTransforms(*this);
2779-
m_cfg->curOpt = {};
2780-
if (!parseAborted()) {
2781-
if (opt.m_bool) {
2782-
bool val = false;
2783-
if (!parseBool(val, newValue())) {
2784-
badUsage(opt);
2785-
return false;
2786-
}
2787-
if (nameFlags & fNameInvert)
2788-
val = !val;
2789-
m_cfg->newValue = val ? "1" : "0";
2790-
}
2791-
opt.doParse(*this);
2792-
}
2793-
if (!parseAborted())
2794-
opt.doChecks(*this);
2795-
} else {
2796-
m_cfg->originalValue.clear();
2797-
m_cfg->newValue.clear();
2798-
opt.assignImplicit();
2799-
opt.doChecks(*this);
2800-
}
2801-
m_cfg->originalValue.clear();
2802-
m_cfg->newValue.clear();
2803-
return !parseAborted();
2796+
PlanValue val = { PlanValue::kOperand };
2797+
val.opt = &opt;
2798+
val.name = opt.defaultFrom();
2799+
val.src = { srcType, srcName };
2800+
val.ptr = ptr;
2801+
return Config::parseValue(*this, val);
28042802
}
28052803

28062804
//===========================================================================

libs/dimcli/cli.h

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -689,15 +689,6 @@ class DIMCLI_LIB_DECL Cli {
689689
const std::string & srcName, // use {} if unsure
690690
const char val[]
691691
);
692-
[[nodiscard]] bool parseValue(
693-
OptBase & out,
694-
const std::string & name, // use opt.defaultFrom() if unsure
695-
unsigned nameFlags, // use 0 if unsure
696-
size_t pos, // use 0 if unsure
697-
ArgSrc::Type srcType, // use kArgv if unsure (not kNone!)
698-
const std::string & srcName, // use {} if unsure
699-
const char val[]
700-
);
701692

702693
// Prompt sends a prompt message to cout and read a response from cin
703694
// (unless cli.iostreams() changed the streams to use), the response is
@@ -1999,7 +1990,7 @@ class Cli::OptShim : public OptBase {
19991990
// number of transform actions can be added.
20001991
//
20011992
// The function should:
2002-
// - Inspect, and/or change the val string via cli.newValue().
1993+
// - Inspect, then optionally change the val string via cli.newValue().
20031994
// - Call cli.badUsage() with an error message if there's a problem.
20041995
// - Call cli.parseExit() if the program should stop without an error.
20051996
// This could be due to an early out like "--version" and "--help".

0 commit comments

Comments
 (0)