From: Martin Mares Date: Sat, 28 Apr 2018 16:31:46 +0000 (+0200) Subject: Allow bare identifiers as values of string arguments X-Git-Tag: v1.0~6 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=ab39b9756aa4c34811cd0d2a33298596951921ed;p=paperjam.git Allow bare identifiers as values of string arguments --- diff --git a/parse.cc b/parse.cc index a7b38f6..d1573c8 100644 --- a/parse.cc +++ b/parse.cc @@ -297,35 +297,49 @@ static void parse_args(cmd *c) t = next_token(); if (t == TOK_CLOSE_PAREN) break; + + while (next_pos < num_args && !(adefs[next_pos].type & AT_POSITIONAL)) + next_pos++; + uint argi = 0; bool has_value = false; + if (t == TOK_IDENT) { while (adefs[argi].name && token != adefs[argi].name) argi++; - if (!adefs[argi].name) - err("Command %s has no argument %s", cdef->name, token.c_str()); - if (c->args.count(token)) - err("Argument %s given multiple times", token.c_str()); - t = next_token(); - if (t == TOK_EQUAL) - has_value = true; + if (adefs[argi].name) + { + if (c->args.count(token)) + err("Argument %s given multiple times", token.c_str()); + t = next_token(); + if (t == TOK_EQUAL) + has_value = true; + else + return_token(); + saw_named = true; + } + else if (next_pos < num_args && (adefs[next_pos].type & AT_TYPE_MASK) == AT_STRING) + { + // Shortcut syntax: positional arguments of string type can be specified + // as bare identifiers if they do not collide with names or other arguments. + return_token(); + argi = next_pos++; + has_value = true; + } else - return_token(); - saw_named = true; + err("Command %s has no argument %s", cdef->name, token.c_str()); } else if (saw_named) err("Positional arguments must precede named ones"); - else + else if (next_pos < num_args) { return_token(); - while (next_pos < num_args && !(adefs[next_pos].type & AT_POSITIONAL)) - next_pos++; - if (next_pos >= num_args) - err("Too many positional arguments for command %s", cdef->name); argi = next_pos++; has_value = true; } + else + err("Too many positional arguments for command %s", cdef->name); const arg_def *adef = &adefs[argi]; uint type = adef->type & AT_TYPE_MASK; @@ -336,8 +350,8 @@ static void parse_args(cmd *c) { case AT_STRING: t = next_token(); - if (t != TOK_STRING) - err("Argument %s must be a string", adef->name); + if (t != TOK_STRING && t != TOK_IDENT) + err("Argument %s must be a string or identifier", adef->name); val = new arg_string(token); break; case AT_INT: