re-write CLI argument parsing for testability
This commit is contained in:
1 parent
8cb8d4bf69
commit
5ab17ec375
7 files changed
+552
-39
No files matched your search
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* pvxs is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include "cliutil.h"
|
||||
|
||||
namespace pvxs {
|
||||
|
||||
bool operator==(const ArgVal& rhs, const ArgVal& lhs) {
|
||||
return rhs.defined==lhs.defined && rhs.value==lhs.value;
|
||||
}
|
||||
|
||||
GetOpt::GetOpt(int argc, char *argv[], const char *spec)
|
||||
:argv0("<program name>")
|
||||
{
|
||||
if(argc>=1)
|
||||
argv0 = argv[0];
|
||||
|
||||
bool allpos = false; // after "--", treat all remaining as positional
|
||||
for(int i=1; i<argc; i++) {
|
||||
const char * arg = argv[i];
|
||||
if(!allpos && arg[0]=='-') {
|
||||
arg++;
|
||||
|
||||
if(arg[0]=='-') {
|
||||
if(arg[1]=='\0') { // "--"
|
||||
allpos = true;
|
||||
continue;
|
||||
}
|
||||
// "--..." not supported
|
||||
arguments.emplace_back(-1, argv[i]);
|
||||
continue;
|
||||
}
|
||||
// process as short args
|
||||
|
||||
for(; *arg; arg++) {
|
||||
for(auto s=spec; *s; s++) {
|
||||
if(*s==*arg) { // match
|
||||
if(s[1]==':') { // need arg value
|
||||
if(arg[1]=='\0') { // "-a", "value"
|
||||
if(i+1==argc) {
|
||||
// oops. no value
|
||||
arguments.emplace_back('?', nullptr);
|
||||
return;
|
||||
}
|
||||
arguments.emplace_back(*arg, argv[i+1]);
|
||||
i++;
|
||||
|
||||
} else {
|
||||
// "-avalue"
|
||||
arguments.emplace_back(*arg, &arg[1]);
|
||||
}
|
||||
goto nextarg;
|
||||
|
||||
} else { // flag
|
||||
arguments.emplace_back(*s, nullptr);
|
||||
// continue scanning for more flags. eg. "-vv"
|
||||
goto nextchar;
|
||||
}
|
||||
} else {
|
||||
if(s[1]==':')
|
||||
s++;
|
||||
}
|
||||
}
|
||||
// unrecognized
|
||||
arguments.emplace_back(-1, nullptr);
|
||||
break;
|
||||
nextchar:
|
||||
(void)0; // need a statement after label...
|
||||
}
|
||||
nextarg:
|
||||
(void)0;
|
||||
|
||||
} else {
|
||||
positional.push_back(arg);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pvxs
|
||||
Reference in new issue
Block a user