Skip to content

Commit

Permalink
parseConfig and parseArgs now use the same parse
Browse files Browse the repository at this point in the history
  • Loading branch information
burner committed May 17, 2017
1 parent 4eff3de commit a4e8192
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
57 changes: 40 additions & 17 deletions source/args.d
Expand Up @@ -110,15 +110,17 @@ enum ArgsMatch {
complete complete
} }


ArgsMatch argsMatches(alias Args, string name, string Long, string Short)(string prefix, string opt) { ArgsMatch argsMatches(alias Args, string name, string Long, string Short)(
string prefix, string opt)
{
import stringbuffer; import stringbuffer;
import std.format : formattedWrite; import std.format : formattedWrite;
import std.algorithm.searching : startsWith, canFind; import std.algorithm.searching : startsWith, canFind;


StringBuffer buf; StringBuffer buf;
formattedWrite!"%s%s%s"(buf.writer(), Long, prefix, name); formattedWrite!"%s%s%s"(buf.writer(), Long, prefix, name);


//writeln(buf.getData(), "' '", prefix, "' '", name, "' '", opt, "'"); //writeln("argsMatches ", buf.getData(), "' '", prefix, "' '", opt, "'");
if(opt.startsWith(buf.getData())) { if(opt.startsWith(buf.getData())) {
return opt == buf.getData() ? ArgsMatch.complete : return opt == buf.getData() ? ArgsMatch.complete :
ArgsMatch.mustBeStruct; ArgsMatch.mustBeStruct;
Expand All @@ -140,7 +142,6 @@ bool parseArgsImpl(string mem, string Long, string Short, Opt, Args)(ref Opt opt
ref Args args) ref Args args)
{ {
import std.traits : hasUDA, getUDAs, isArray; import std.traits : hasUDA, getUDAs, isArray;
import std.algorithm.mutation : remove;
import std.algorithm.searching : canFind; import std.algorithm.searching : canFind;
import std.algorithm.iteration : splitter, map; import std.algorithm.iteration : splitter, map;
import std.array : array; import std.array : array;
Expand All @@ -159,7 +160,9 @@ bool parseArgsImpl(string mem, string Long, string Short, Opt, Args)(ref Opt opt
(prefix, arg); (prefix, arg);
if(matchType == ArgsMatch.mustBeStruct) { if(matchType == ArgsMatch.mustBeStruct) {
static if(is(typeof(__traits(getMember, opt, mem)) == struct)) { static if(is(typeof(__traits(getMember, opt, mem)) == struct)) {
parseArgs(__traits(getMember, opt, mem), mem ~ ".", args); parseArgs!(Long, Short)(__traits(getMember, opt, mem),
prefix ~ mem ~ ".", args
);
return false; return false;
} else { } else {
throw new Exception("Argument '" ~ arg ~ "' was prefix but" throw new Exception("Argument '" ~ arg ~ "' was prefix but"
Expand Down Expand Up @@ -216,10 +219,18 @@ bool parseArgsImpl(string mem, string Long, string Short, Opt, Args)(ref Opt opt
return false; return false;
} }


private ref Array!T remove(T)(return ref Array!T arr, size_t idx) { private ref T remove(T)(return ref T arr, size_t idx) {
auto r = arr[idx .. idx + 1]; import std.traits : isArray;
arr.linearRemove(r);
return arr; static if(isArray!T) {
import std.algorithm.mutation : remove;
arr = remove(arr, idx);
return arr;
} else {
auto r = arr[idx .. idx + 1];
arr.linearRemove(r);
return arr;
}
} }


unittest { unittest {
Expand All @@ -235,9 +246,11 @@ Array!string parseArgsConfigFile(string filename) {
import std.file : readText; import std.file : readText;
import std.algorithm.iteration : splitter; import std.algorithm.iteration : splitter;
import std.algorithm.searching : startsWith; import std.algorithm.searching : startsWith;
import std.string : indexOf, strip; import std.algorithm.mutation : strip;
import std.string : indexOf;


Array!string ret; Array!string ret;
ret.insertBack("dummyBecauseTheFirstArgumentIsTheFileName");


auto file = readText(filename); auto file = readText(filename);
foreach(line; file.splitter('\n')) { foreach(line; file.splitter('\n')) {
Expand All @@ -250,8 +263,8 @@ Array!string parseArgsConfigFile(string filename) {
continue; continue;
} }


ret.insertBack(line[0 .. eq].strip()); ret.insertBack(line[0 .. eq].strip(' ').strip('"'));
ret.insertBack(line[eq+1 .. $].strip()); ret.insertBack(line[eq+1 .. $].strip(' ').strip('"'));
} }


return ret; return ret;
Expand Down Expand Up @@ -330,17 +343,22 @@ unittest {


bool parseArgs(Opt,Args)(ref Opt opt, ref Args args) bool parseArgs(Opt,Args)(ref Opt opt, ref Args args)
{ {
return parseArgs(opt, "", args); return parseArgs!("--", "-")(opt, "", args);
} }


private bool parseArgs(Opt,Args)(ref Opt opt, string prefix, ref Args args) void parseConfigFile(Opt,Args)(ref Opt opt, ref Args args) {
parseArgs!("", "")(opt, "", args);
}

private bool parseArgs(string Long, string Short, Opt, Args)(ref Opt opt,
string prefix, ref Args args)
{ {
checkUnique!Opt(); checkUnique!Opt();


bool helpWanted = false; bool helpWanted = false;


foreach(optMem; __traits(allMembers, Opt)) { foreach(optMem; __traits(allMembers, Opt)) {
helpWanted |= parseArgsImpl!(optMem, "--", "-")(opt, prefix, args); helpWanted |= parseArgsImpl!(optMem, Long, Short)(opt, prefix, args);
} }
return helpWanted; return helpWanted;
} }
Expand Down Expand Up @@ -495,6 +513,8 @@ unittest {


unittest { unittest {
import std.exception : assertThrown; import std.exception : assertThrown;
import std.format : format;
import std.conv : to;


enum Enum { enum Enum {
yes, yes,
Expand All @@ -518,10 +538,13 @@ unittest {


Options opt; Options opt;
auto data = parseArgsConfigFile("testfile.argsd"); auto data = parseArgsConfigFile("testfile.argsd");
parseArgs(opt, data); writefln("%(%s %)", data[]);
parseConfigFile(opt, data);


assert(opt.someValue == 100); assert(opt.someValue == 100, format("%d %(%s %)",
assert(opt.en.en2.z == Enum.no); opt.someValue, data[]));
assert(opt.en.en2.engage == Enum.no, format("%s %(%s %)",
opt.en.en2.engage, data[]));
} }


unittest { unittest {
Expand Down
2 changes: 1 addition & 1 deletion testfile.argsd
Expand Up @@ -2,4 +2,4 @@
someValue = 100 someValue = 100


# another comment after a blank line # another comment after a blank line
en.en2.z = no en.en2.engage = no

0 comments on commit a4e8192

Please sign in to comment.