@@ -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// ===========================================================================
20932143static 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// ===========================================================================
21492199bool 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// ===========================================================================
22292279static 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// ===========================================================================
22502300bool 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// ===========================================================================
0 commit comments