]> mj.ucw.cz Git - paperjam.git/blobdiff - parse.cc
Measure bboxes by Ghostscripting
[paperjam.git] / parse.cc
index 827cb516f59ddf3236ddb35addc5c301148f53df..1869b3a76ef04345ffd4d0ead54f7bbe2314eba6 100644 (file)
--- a/parse.cc
+++ b/parse.cc
@@ -71,7 +71,8 @@ static token_type get_next_token()
     {
       while (*in_pos >= 'A' && *in_pos <= 'Z' ||
             *in_pos >= 'a' && *in_pos <= 'z' ||
-            *in_pos >= '0' && *in_pos <= '9')
+            *in_pos >= '0' && *in_pos <= '9' ||
+            *in_pos == '_')
        token += *in_pos++;
       return TOK_IDENT;
     }
@@ -154,22 +155,31 @@ static bool token_is_int()
 
 /*** Argument types ***/
 
+class arg_int : public arg_val {
+  int val;
+public:
+  arg_int(int x) { val = x; }
+  bool given() { return true; }
+  int as_int(int def UNUSED) { return val; }
+  string dump() { return "<int> " + to_string(val); }
+};
+
 class arg_double : public arg_val {
   double val;
 public:
-  bool given() { return true; }
-  explicit operator double () { return val; }
   arg_double(double x) { val = x; }
-  string dump() { return to_string(val); }
+  bool given() { return true; }
+  double as_double(double def UNUSED) { return val; }
+  string dump() { return "<double> " + to_string(val); }
 };
 
 class arg_string : public arg_val {
   string val;
 public:
-  bool given() { return true; }
-  explicit operator string () { return val; }
   arg_string(string x) { val = x; }
-  string dump() { return '"' + val + '"'; }
+  bool given() { return true; }
+  const string as_string(string def UNUSED) { return val; }
+  string dump() { return "<string> \"" + val + '"'; }
 };
 
 static arg_val null_arg;
@@ -222,23 +232,15 @@ static void parse_pipeline(cmd *c)
       pipeline_branch *pb = new pipeline_branch;
       pp->branches.push_back(pb);
 
+      token_type t;
       for (;;)
        {
-         token_type t = next_token();
-         if (t == TOK_CLOSE_BRACE || t == TOK_END)
-           parse_error("Premature end of pipeline");
-         if (t == TOK_COLON)
+         t = next_token();
+         if (t == TOK_END)
+           parse_error("Missing close brace");
+         if (t == TOK_CLOSE_BRACE || t == TOK_COLON || t == TOK_COMMA)
            break;
 
-         if (pb->selectors.size())
-           {
-             if (t != TOK_COMMA)
-               parse_error("Invalid pipeline selector");
-             t = next_token();
-             if (t == TOK_CLOSE_BRACE || t == TOK_END)
-               parse_error("Premature end of pipeline");
-           }
-
          pipeline_selector ps;
          if (t != TOK_NUMBER)
            parse_error("Pipeline selectors must start with a number");
@@ -261,7 +263,10 @@ static void parse_pipeline(cmd *c)
          pb->selectors.push_back(ps);
        }
 
-      parse_commands(pb->commands);
+      if (t == TOK_COLON)
+       parse_commands(pb->commands);
+      else
+       return_token();
     }
 
   c->pipe = pp;
@@ -326,6 +331,12 @@ static void parse_args(cmd *c)
            parse_error("Parameter %s must be a string", adef->name);
          val = new arg_string(token);
          break;
+       case AT_INT:
+         t = next_token();
+         if (t != TOK_NUMBER || !token_is_int())
+           parse_error("Parameter %s must be an integer", adef->name);
+         val = new arg_int((int) token_num);
+         break;
        case AT_DOUBLE:
          t = next_token();
          if (t != TOK_NUMBER)
@@ -448,3 +459,29 @@ void parse(const char *in, list<cmd *> &cmds)
   debug_cmds(cmds);
   instantiate(cmds);
 }
+
+void help()
+{
+  for (int i=0; cmd_table[i].name; i++)
+    {
+      const cmd_def *def = &cmd_table[i];
+      printf("%s\n", def->name);
+
+      const arg_def *arg = def->arg_defs;
+      static const char * const type_names[] = {
+       "string", "int", "double", "dimen"
+      };
+      while (arg->name)
+       {
+         printf("\t%s (%s)%s%s\n",
+           arg->name,
+           type_names[arg->type & AT_TYPE_MASK],
+           (arg->type & AT_MANDATORY) ? " [mandatory]" : "",
+           (arg->type & AT_POSITIONAL) ? " [positional]" : "");
+         arg++;
+       }
+
+       if (def->has_pipeline)
+         printf("\t{ pipeline }\n");
+    }
+}