From 42f54ee9375e28e70caa673bc998d69ea301013d Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Fri, 10 Jun 2016 23:22:26 +0200
Subject: [PATCH] Minor improvements of PJL parser

---
 xcpt.c | 52 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 30 insertions(+), 22 deletions(-)

diff --git a/xcpt.c b/xcpt.c
index c1a8804..fad78da 100644
--- a/xcpt.c
+++ b/xcpt.c
@@ -12,6 +12,12 @@
 #define PRINTF(i,j) __attribute__((format(printf,i,j)))
 #define NONRET __attribute__((noreturn))
 
+#if 1
+#define DEBUG(...) debug(__VA_ARGS__)
+#else
+#define DEBUG(...) do { } while(0)
+#endif
+
 /*** Utility functions ***/
 
 static void PRINTF(1,2) NONRET bug(const char *fmt, ...)
@@ -19,7 +25,7 @@ static void PRINTF(1,2) NONRET bug(const char *fmt, ...)
   va_list args;
   va_start(args, fmt);
 
-  fprintf(stderr, "ERROR: ");
+  fprintf(stderr, "ERROR: XCPT: ");
   vfprintf(stderr, fmt, args);
   fputc('\n', stderr);
 
@@ -33,7 +39,7 @@ static void PRINTF(1,2) error(const char *fmt, ...)
   va_list args;
   va_start(args, fmt);
 
-  fprintf(stderr, "ERROR: ");
+  fprintf(stderr, "ERROR: XCPT: ");
   vfprintf(stderr, fmt, args);
   fputc('\n', stderr);
 
@@ -46,7 +52,7 @@ static void PRINTF(1,2) debug(const char *fmt, ...)
   va_list args;
   va_start(args, fmt);
 
-  fprintf(stderr, "DEBUG: ");
+  fprintf(stderr, "DEBUG: XCPT: ");
   vfprintf(stderr, fmt, args);
   fputc('\n', stderr);
 
@@ -91,13 +97,18 @@ static void set_option(char *key, char *val)
   for (int i=0; i<OPT_MAX; i++)
     if (!strcmp(opt_names[i], key))
       {
+	debug("Setting %s=<%s>\n", key, val);
 	opt[i] = xstrdup(val);
 	return;
       }
-  debug("SET: Unrecognized option <%s>\n", key);
+  debug("Unrecognized option <%s>\n", key);
 }
 
-/*** PJL parser ***/
+/**
+ *  This is our parser of PJL. A hacky one, indeed, but it is expected
+ *  to parse only PJL directives generated by our PPD or by CUPS itself,
+ *  so we need not pay attention to all obscure details of the language.
+ **/
 
 #define LINESIZE 256
 
@@ -137,7 +148,7 @@ static char *get_token(char **pp)
   else
     *tok++ = *p++;
   *tok++ = 0;
-  *pp = skip_spaces(p);
+  *pp = p;
   token_buf = tok;
   return token_start;
 }
@@ -163,19 +174,19 @@ static void parse_pjl(void)
 	  if (c == '\r')
 	    continue;
 	  if (c == '\n')
-	    {
-	      line[i] = 0;
 	      break;
-	    }
 	  if (i >= LINESIZE-1)
 	    bug("PJL error: Line too long");
 	  line[i++] = c;
 	}
+      while (i > 0 && (line[i] == ' ' || line[i] == '\t'))
+	i--;
+      line[i] = 0;
 
-      debug("PJL: %s", line);
+      DEBUG("PJL: %s", line);
       char *p = line+1;
       token_buf = tokens;
-      char *t;
+      char *t, *t2, *t3;
       if (!(t = get_token(&p)) || strcasecmp(t, "PJL"))
 	bug("PJL error: Malformed line");
       if (!(t = get_token(&p)))
@@ -183,26 +194,23 @@ static void parse_pjl(void)
 
       if (!strcasecmp(t, "ENTER"))
 	{
-	  char *t2 = get_token(&p);
-	  if (t2 && !strcasecmp(t2, "LANGUAGE"))
+	  if ((t2 = get_token(&p)) && !strcasecmp(t2, "LANGUAGE"))
 	    {
-	      char *t3 = get_token(&p);
-	      if (t3 && !strcasecmp(t3, "="))
+	      if ((t3 = get_token(&p)) && !strcasecmp(t3, "="))
 		{
-		  set_option("LANGUAGE", p);
-		  break;
+		  set_option("LANGUAGE", skip_spaces(p));
+		  return;
 		}
 	    }
 	}
 
       if (!strcasecmp(t, "SET"))
 	{
-	  char *t2 = get_token(&p);
-	  if (t2)
+	  if (t2 = get_token(&p))
 	    {
-	      char *t3 = get_token(&p);
-	      if (t3 && !strcasecmp(t3, "="))
+	      if ((t3 = get_token(&p)) && !strcasecmp(t3, "="))
 		{
+		  p = skip_spaces(p);
 		  if (*p == '"')
 		    {
 		      *p++ = 0;
@@ -232,7 +240,7 @@ int main(int argc, const char **argv)
   parse_pjl();
 
   for (int i=0; i<OPT_MAX; i++)
-    debug("Option %s=<%s>\n", opt_names[i], opt[i]);
+    DEBUG("Option %s=<%s>\n", opt_names[i], opt[i]);
 
   return 0;
 }
-- 
GitLab