Fix decoding of line numbers.
[bascat] / bascat.c
index d3d6a75..48e032e 100644 (file)
--- a/bascat.c
+++ b/bascat.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: bascat.c,v 1.2 1998/06/26 11:29:28 mdw Exp $
+ * $Id: bascat.c,v 1.5 1999/11/25 01:08:57 mdw Exp $
  *
  * Display BBC BASIC programs more or less anywhere
  *
 /*----- Revision history --------------------------------------------------*
  *
  * $Log: bascat.c,v $
+ * Revision 1.5  1999/11/25 01:08:57  mdw
+ * Fix decoding of line numbers.
+ *
+ * Revision 1.4  1999/10/28 10:42:23  mdw
+ * More minor twiddling.
+ *
+ * Revision 1.3  1999/10/28 10:18:17  mdw
+ * Minor name changes for new coding standards.
+ *
  * Revision 1.2  1998/06/26 11:29:28  mdw
  * Added support for line-numbers.
  *
@@ -76,7 +85,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",
@@ -96,18 +105,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",
@@ -128,8 +137,8 @@ enum {
   s_dummy
 };
 
-static int bc__state = s_normal;       /* Current detokenisation state */
-static unsigned int bc__lineno;                /* Line number */
+static int state = s_normal;           /* Current detokenisation state */
+static unsigned int lineno;            /* Line number */
 
 enum {
   f_highlight = 1,                     /* Highlight keywords and things */
@@ -139,13 +148,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 ---------------------------------------------------------*/
 
@@ -164,7 +173,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
@@ -178,13 +187,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++;
     }
@@ -193,7 +202,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
@@ -208,7 +217,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
@@ -220,17 +229,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
@@ -240,52 +249,52 @@ 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:
-           bc__state = s_linex;
+           state = s_linex;
            break;
          case 0x8B:                    /* ELSE */
          case 0x8C:                    /* THEN */
          case 0xF5:                    /* REPEAT (a funny one) */
-           bc__state = s_keyword;
+           state = s_keyword;
            goto keyword;
            break;
          case 0xDC:                    /* DATA */
          case 0xF4:                    /* REM */
-           bc__state = s_comment;
+           state = s_comment;
            /* Fall through here */
          default:
          keyword:
-           bc__keyword(bcTok__base[byte - 0x7F], fp);
+           keyword(tok_base[byte - 0x7F], fp);
            break;
        }
       } else {
        if (byte == '"')
-         bc__state = s_quote;
+         state = s_quote;
        fputc(byte, fp);
       }
       break;
@@ -294,7 +303,7 @@ static int bc__decode(int byte, FILE * fp)
 
     case s_quote:
       if (byte == '"')
-       bc__state = s_normal;
+       state = s_normal;
       /* Fall through here */
 
     case s_comment:
@@ -304,40 +313,43 @@ static int bc__decode(int byte, FILE * fp)
     /* --- 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:
-      bc__lineno = ((((byte << 2) | (byte << 12)) & 0xc0c0u) ^ 0x4040u);
-      bc__state++;
+      byte ^= 0x54;
+      lineno = (((byte & 0x30) << 2) |
+               ((byte & 0x0c) << 12) |
+               ((byte & 0x03)  << 16));
+      state++;
       break;
 
     case s_liney:
-      bc__lineno |= byte & 0x3fu;
-      bc__state++;
+      lineno |= byte & 0x3f;
+      state++;
       break;
 
     case s_linez:
-      bc__lineno |= (byte << 8) & 0x3fu;
-      fprintf(fp, "%u", bc__lineno);
-      bc__state = s_normal;
+      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
@@ -347,7 +359,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 --- */
 
@@ -366,7 +378,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);
   }
 
@@ -380,14 +392,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); )
+                state, byte); )
        if (byte == EOF)
        goto eof;
-      bc__decode(byte, out);
+      decode(byte, out);
       len--;
     }
     putc('\n', out);
@@ -406,7 +418,7 @@ eof:
   return (die("Bad program: unexpected end-of-file"));
 }
 
-/* --- @bc__file@ --- *
+/* --- @file@ --- *
  *
  * Arguments:   @FILE *in@ = the input stream
  *              @FILE *out@ = the output stream
@@ -416,7 +428,7 @@ eof:
  * Use:         Decodes an entire file.
  */
 
-static void bc__file(FILE *in, FILE *out)
+static void file(FILE *in, FILE *out)
 {
   int byte;
 
@@ -428,7 +440,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 --- */
 
@@ -437,7 +449,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
  *
@@ -446,13 +458,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
@@ -464,20 +476,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"
@@ -502,19 +514,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;
     }
   }
@@ -533,18 +545,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 --- */
 
@@ -558,8 +570,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
 
   {
@@ -572,18 +584,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;
@@ -591,11 +603,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) {
@@ -603,13 +615,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);
   }