Turn off debugging\!
[bascat] / bascat.c
index 2401892..218b749 100644 (file)
--- a/bascat.c
+++ b/bascat.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: bascat.c,v 1.1 1998/03/16 15:21:37 mdw Exp $
+ * $Id$
  *
  * Display BBC BASIC programs more or less anywhere
  *
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
  */
 
-/*----- Revision history --------------------------------------------------*
- *
- * $Log: bascat.c,v $
- * Revision 1.1  1998/03/16 15:21:37  mdw
- * Files placed under CVS control.
- *
- * Revision 1.1  1997/07/23 01:19:33  mdw
- * Initial revision
- *
- */
-
 /*----- Header files ------------------------------------------------------*/
 
 /* --- ANSI library headers --- */
@@ -61,7 +50,7 @@
 
 /*----- Version information -----------------------------------------------*/
 
-#ifndef NDEBUG
+#ifdef DEBUG
 #  define D(x) x
 #else
 #  define D(x)
@@ -73,7 +62,7 @@
  * carried out on an A440 with RISC OS 3.1
  */
 
-static const char *bcTok__base[] = {
+static const char *tok_base[] = {
   "OTHERWISE",
   "AND", "DIV", "EOR", "MOD", "OR", "ERROR", "LINE", "OFF",
   "STEP", "SPC", "TAB(", "ELSE", "THEN", "*", "OPENIN", "PTR",
@@ -93,18 +82,18 @@ static const char *bcTok__base[] = {
   "RETURN", "RUN", "STOP", "COLOUR", "TRACE", "UNTIL", "WIDTH", "OSCLI"
 };
 
-static const char *bcTok__c6[] = {
+static const char *tok_c6[] = {
   "SUM", "BEAT"
 };
 
-static const char *bcTok__c7[] = {
+static const char *tok_c7[] = {
   "APPEND", "AUTO",
   "CRUNCH", "DELETE", "EDIT", "HELP", "LIST", "LOAD", "LVAR", "NEW",
   "OLD", "RENUMBER", "SAVE", "TEXTLOAD", "TEXTSAVE", "TWIN", "TWINO",
     "INSTALL"
 };
 
-static const char *bcTok__c8[] = {
+static const char *tok_c8[] = {
   "CASE", "CIRCLE",
   "FILL", "ORIGIN", "POINT", "RECTANGLE", "SWAP", "WHILE", "WAIT", "MOUSE",
   "QUIT", "SYS", "INSTALL", "LIBRARY", "TINT", "ELLIPSE", "BEATS", "TEMPO",
@@ -121,10 +110,12 @@ enum {
   s_comment,                           /* In a command (or literal *cmd) */
   s_quote,                             /* Inside a quoted string */
   s_c6, s_c7, s_c8,                    /* Various shift states */
+  s_linex, s_liney, s_linez,           /* Line number states */
   s_dummy
 };
 
-static bc__state = s_normal;           /* Current detokenisation state */
+static int state = s_normal;           /* Current detokenisation state */
+static unsigned int lineno;            /* Line number */
 
 enum {
   f_highlight = 1,                     /* Highlight keywords and things */
@@ -134,13 +125,13 @@ enum {
   f_dummy
 };
 
-static int bc__flags;                  /* Various options flags */
+static int flags;                      /* Various options flags */
 
 #ifdef HAVE_LIBTERMCAP
-static char bc__termcap[2048];         /* Terminal capabilities buffer */
+static char termcap[2048];             /* Terminal capabilities buffer */
 #endif
 
-static char *bc__pager = 0;            /* Pointer to pager to use */
+static char *pager = 0;                        /* Pointer to pager to use */
 
 /*----- Main code ---------------------------------------------------------*/
 
@@ -159,7 +150,7 @@ static int die(const char *p)
   return (1);
 }
 
-/* --- @bc__keyword@ --- *
+/* --- @keyword@ --- *
  *
  * Arguments:   @char *s@ = pointer to keyword string
  *              @FILE *fp@ = stream to write onto
@@ -173,13 +164,13 @@ static int die(const char *p)
  *              characters.  What fun...
  */
 
-static void bc__keyword(const char *s, FILE *fp)
+static void keyword(const char *s, FILE *fp)
 {
 #ifdef HAVE_LIBTERMCAP
-  if ((~bc__flags & (f_less | f_highlight)) == 0) {
+  if ((~flags & (f_less | f_highlight)) == 0) {
     while (*s) {
       putc(*s, fp);
-      putc(8, fp);                     /* evil... */
+      putc('\b', fp);
       putc(*s, fp);
       s++;
     }
@@ -188,7 +179,7 @@ static void bc__keyword(const char *s, FILE *fp)
     static char *hs, *he, *p = buff;
 
     if (!hs) {
-      if (bc__flags & f_highlight) {
+      if (flags & f_highlight) {
        hs = tgetstr("md", &p);
        he = tgetstr("me", &p);
       } else
@@ -203,7 +194,7 @@ static void bc__keyword(const char *s, FILE *fp)
 #endif
 }
 
-/* --- @bc__mbtok@ --- *
+/* --- @mbtok@ --- *
  *
  * Arguments:   @int byte@ = the current byte
  *              @const char *t[]@ = pointer to token table
@@ -215,17 +206,17 @@ static void bc__keyword(const char *s, FILE *fp)
  * Use:         Decodes multibyte tokens.
  */
 
-static int bc__mbtok(int byte, const char *t[], int n, FILE * fp)
+static int mbtok(int byte, const char *t[], int n, FILE *fp)
 {
   byte -= 0x8E;
   if (byte >= n)
     return (die("Bad program: invalid multibyte token"));
-  bc__keyword(t[byte], fp);
-  bc__state = s_normal;
+  keyword(t[byte], fp);
+  state = s_normal;
   return (0);
 }
 
-/* --- @bc__decode@ --- *
+/* --- @decode@ --- *
  *
  * Arguments:   @int byte@ = byte to decode
  *              @FILE *fp@ = stream to write onto
@@ -235,68 +226,107 @@ static int bc__mbtok(int byte, const char *t[], int n, FILE * fp)
  * Use:         Decodes a byte, changing states as necessary.
  */
 
-static int bc__decode(int byte, FILE * fp)
+static int decode(int byte, FILE *fp)
 {
-  switch (bc__state) {
+  switch (state) {
+
+    /* --- Tokenised states --- */
+
     case s_keyword:
       if (byte == '*')
-       bc__state = s_comment;
+       state = s_comment;
       else
-       bc__state = s_normal;
+       state = s_normal;
       /* Fall through here */
+
     case s_normal:
       if (byte >= 0x7F) {
        switch (byte) {
          case 0xC6:
-           bc__state = s_c6;
+           state = s_c6;
            break;
          case 0xC7:
-           bc__state = s_c7;
+           state = s_c7;
            break;
          case 0xC8:
-           bc__state = s_c8;
+           state = s_c8;
+           break;
+         case 0x8D:
+           state = s_linex;
            break;
          case 0x8B:                    /* ELSE */
          case 0x8C:                    /* THEN */
          case 0xF5:                    /* REPEAT (a funny one) */
-           bc__state = s_keyword;
-           bc__keyword(bcTok__base[byte - 0x7F], fp);
+           state = s_keyword;
+           goto keyword;
            break;
          case 0xDC:                    /* DATA */
          case 0xF4:                    /* REM */
-           bc__state = s_comment;
+           state = s_comment;
            /* Fall through here */
          default:
-           bc__keyword(bcTok__base[byte - 0x7F], fp);
+         keyword:
+           keyword(tok_base[byte - 0x7F], fp);
            break;
        }
       } else {
        if (byte == '"')
-         bc__state = s_quote;
+         state = s_quote;
        fputc(byte, fp);
       }
       break;
+
+    /* --- Non-tokenised states --- */
+
     case s_quote:
       if (byte == '"')
-       bc__state = s_normal;
+       state = s_normal;
       /* Fall through here */
+
     case s_comment:
       fputc(byte, fp);
       break;
+
+    /* --- Double-byte token states --- */
+
     case s_c6:
-      return (bc__mbtok(byte, bcTok__c6, ITEMS(bcTok__c6), fp));
+      return (mbtok(byte, tok_c6, ITEMS(tok_c6), fp));
       break;
+
     case s_c7:
-      return (bc__mbtok(byte, bcTok__c7, ITEMS(bcTok__c7), fp));
+      return (mbtok(byte, tok_c7, ITEMS(tok_c7), fp));
       break;
+
     case s_c8:
-      return (bc__mbtok(byte, bcTok__c8, ITEMS(bcTok__c8), fp));
+      return (mbtok(byte, tok_c8, ITEMS(tok_c8), fp));
+      break;
+
+    /* --- Encoded line number states --- */
+
+    case s_linex:
+      byte ^= 0x54;
+      lineno = (((byte & 0x30) << 2) |
+               ((byte & 0x0c) << 12) |
+               ((byte & 0x03)  << 16));
+      state++;
+      break;
+
+    case s_liney:
+      lineno |= byte & 0x3f;
+      state++;
       break;
+
+    case s_linez:
+      lineno |= (byte & 0x3f) << 8;
+      fprintf(fp, "%u", lineno);
+      state = s_normal;
+      break;
+
   }
   return (0);
 }
 
-/* --- @bc__line@ --- *
+/* --- @line@ --- *
  *
  * Arguments:   @FILE *in@ = input stream to read
  *              @FILE *out@ = output stream to write
@@ -306,7 +336,7 @@ static int bc__decode(int byte, FILE * fp)
  * Use:         Decodes a BASIC line into stuff to be written.
  */
 
-static int bc__line(FILE *in, FILE *out)
+static int line(FILE *in, FILE *out)
 {
   /* --- Read the line number --- */
 
@@ -325,7 +355,7 @@ static int bc__line(FILE *in, FILE *out)
       if (b == EOF)
       goto eof;
 
-    if (bc__flags & f_linenumbers)
+    if (flags & f_linenumbers)
       fprintf(out, "%5i", (a << 8) + b);
   }
 
@@ -339,14 +369,14 @@ static int bc__line(FILE *in, FILE *out)
       goto eof;
     len -= 4;
 
-    bc__state = s_normal;
+    state = s_keyword;
     while (len) {
       byte = getc(in);
-      D( fprintf(stderr, "state == %i, byte == %i\n", \
-               bc__state, byte); )
+      D( fprintf(stderr, "state == %i, byte == %i\n",
+                state, byte); )
        if (byte == EOF)
        goto eof;
-      bc__decode(byte, out);
+      decode(byte, out);
       len--;
     }
     putc('\n', out);
@@ -365,7 +395,7 @@ eof:
   return (die("Bad program: unexpected end-of-file"));
 }
 
-/* --- @bc__file@ --- *
+/* --- @file@ --- *
  *
  * Arguments:   @FILE *in@ = the input stream
  *              @FILE *out@ = the output stream
@@ -375,7 +405,7 @@ eof:
  * Use:         Decodes an entire file.
  */
 
-static void bc__file(FILE *in, FILE *out)
+static void file(FILE *in, FILE *out)
 {
   int byte;
 
@@ -387,7 +417,7 @@ static void bc__file(FILE *in, FILE *out)
 
   /* --- Now read the lines in one by one --- */
 
-  while (!bc__line(in, out)) ;
+  while (!line(in, out)) ;
 
   /* --- Check that we're really at end-of-file --- */
 
@@ -396,7 +426,7 @@ static void bc__file(FILE *in, FILE *out)
     die("Found data after end of program");
 }
 
-/* --- @bc__sigPipe@ --- *
+/* --- @sig_pipe@ --- *
  *
  * Arguments:   @int s@ = signal number
  *
@@ -405,13 +435,13 @@ static void bc__file(FILE *in, FILE *out)
  * Use:         Handles SIGPIPE signals, and gracefully kills the program.
  */
 
-static void bc__sigPipe(int s)
+static void sig_pipe(int s)
 {
   (void) s;
   exit(0);                             /* Gracefully, oh yes */
 }
 
-/* --- @bc__options@ --- *
+/* --- @options@ --- *
  *
  * Arguments:   @int c@ = number of arguments
  *              @char *v[]@ = pointer to arguments
@@ -423,20 +453,20 @@ static void bc__sigPipe(int s)
  * Use:         Parses lots of arguments.
  */
 
-static void bc__options(int c, char *v[], const char *s,
+static void options(int c, char *v[], const char *s,
                        const struct option *o)
 {
   int i;
 
   for (;;) {
-    i = mdwopt(c, v, s, o, 0, 0, gFlag_negation | gFlag_envVar);
+    i = mdwopt(c, v, s, o, 0, 0, OPTF_NEGATION | OPTF_ENVVAR);
     if (i == -1)
       break;
 
     switch (i) {
       case 'v':
       case 'h':
-       printf("%s v. " VERSION " (" __DATE__ ")\n", optprog);
+       printf("%s version " VERSION "\n", optprog);
        if (i == 'v')
          exit(0);
        printf("\n"
@@ -461,19 +491,19 @@ static void bc__options(int c, char *v[], const char *s,
        exit(0);
        break;
       case 'n':
-       bc__flags |= f_linenumbers;
+       flags |= f_linenumbers;
        break;
-      case 'n' | gFlag_negated:
-       bc__flags &= ~f_linenumbers;
+      case 'n' | OPTF_NEGATED:
+       flags &= ~f_linenumbers;
        break;
       case 'l':
-       bc__flags |= f_highlight;
+       flags |= f_highlight;
        break;
-      case 'l' | gFlag_negated:
-       bc__flags &= ~f_highlight;
+      case 'l' | OPTF_NEGATED:
+       flags &= ~f_highlight;
        break;
       case 'p':
-       bc__pager = optarg;
+       pager = optarg;
        break;
     }
   }
@@ -492,18 +522,18 @@ static void bc__options(int c, char *v[], const char *s,
 int main(int argc, char *argv[])
 {
   static struct option opts[] = {
-    { "help", 0, 0, 'h' },
-    { "version", 0, 0, 'v' },
-    { "line-numbers", gFlag_negate, 0, 'n' },
-    { "highlight", gFlag_negate, 0, 'l' },
-    { "pager", gFlag_argReq, 0, 'p' },
-    { 0, 0, 0, 0 }
+    { "help",          0,              0,      'h' },
+    { "version",       0,              0,      'v' },
+    { "line-numbers",  OPTF_NEGATE,    0,      'n' },
+    { "highlight",     OPTF_NEGATE,    0,      'l' },
+    { "pager",         OPTF_ARGREQ,    0,      'p' },
+    { 0,               0,              0,      0 }
   };
   static char *shortopts = "hvn+l+p:";
 
   /* --- Parse the command line options --- */
 
-  bc__options(argc, argv, shortopts, opts);
+  options(argc, argv, shortopts, opts);
 
   /* --- Now do the job --- */
 
@@ -517,8 +547,8 @@ int main(int argc, char *argv[])
   }
 
 #ifdef HAVE_LIBTERMCAP
-  if (bc__flags & f_highlight)
-    tgetent(bc__termcap, getenv("TERM"));
+  if (flags & f_highlight)
+    tgetent(termcap, getenv("TERM"));
 #endif
 
   {
@@ -531,18 +561,18 @@ int main(int argc, char *argv[])
      */
 
     if (isatty(1)) {
-      if (!bc__pager)
-       bc__pager = getenv("PAGER");
-      if (!bc__pager)
-       bc__pager = PAGER;              /* Worth a try */
-      if (strstr(bc__pager, "less"))
-       bc__flags |= f_less;            /* HACK!!! */
-      out = popen(bc__pager, "w");
+      if (!pager)
+       pager = getenv("PAGER");
+      if (!pager)
+       pager = PAGER;                  /* Worth a try */
+      if (strstr(pager, "less"))
+       flags |= f_less;                /* HACK!!! */
+      out = popen(pager, "w");
       if (!out)
        out = stdout;
       else {
-       bc__flags |= f_tty;
-       signal(SIGPIPE, bc__sigPipe);
+       flags |= f_tty;
+       signal(SIGPIPE, sig_pipe);
       }
     } else
       out = stdout;
@@ -550,11 +580,11 @@ int main(int argc, char *argv[])
     /* --- Now go through all the files --- */
 
     if (optind == argc)
-      bc__file(stdin, out);
+      file(stdin, out);
     else
       while (optind < argc) {
        if (strcmp(argv[optind], "-") == 0)
-         bc__file(stdin, out);
+         file(stdin, out);
        else {
          in = fopen(argv[optind], "rb");
          if (!in) {
@@ -562,13 +592,13 @@ int main(int argc, char *argv[])
                    "%s: Couldn't open input file: %s\n",
                    optprog, strerror(errno));
          } else {
-           bc__file(in, out);
+           file(in, out);
            fclose(in);
          }
        }
        optind++;
       }
-    if (bc__flags & f_tty)
+    if (flags & f_tty)
       pclose(out);
   }