]> mj.ucw.cz Git - paperjam.git/commitdiff
Allow bare identifiers as values of string arguments
authorMartin Mares <mj@ucw.cz>
Sat, 28 Apr 2018 16:31:46 +0000 (18:31 +0200)
committerMartin Mares <mj@ucw.cz>
Sat, 28 Apr 2018 16:31:46 +0000 (18:31 +0200)
parse.cc

index a7b38f6c34be4e31b3159327df7a11be427f1479..d1573c88e84561bca9540231218f2dc441e5440a 100644 (file)
--- 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: