De-gotoize throw().
[open-adventure.git] / misc.c
diff --git a/misc.c b/misc.c
index 0d33cfd13a46cf22ed8045d9aa1b0ab784c1c65d..6b9e761d1b0ecd9375a66390c2214e92f68e1654 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -3,13 +3,16 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/time.h>
+
 #include "advent.h"
-#include "funcs.h"
 #include "database.h"
+#include "linenoise/linenoise.h"
 
 /* hack to ignore GCC Unused Result */
 #define IGNORE(r) do{if (r){}}while(0)
 
+#define PERCENT        63      /* partly hide the packed encoding */
+
 /*  I/O routines (SPEAK, PSPEAK, RSPEAK, SETPRM, GETIN, YES) */
 
 void SPEAK(vocab_t msg)
@@ -32,104 +35,100 @@ void SPEAK(vocab_t msg)
            PUTTXT(LINES[i],state,2);
        }
        LNPOSN=0;
-L30:
        ++LNPOSN;
-L32:
-       if (LNPOSN > LNLENG) 
-           goto L40;
-       if (INLINE[LNPOSN] != 63) 
-           goto L30;
-       prmtyp=INLINE[LNPOSN+1];
-       /*  63 is a "%"; the next character determine the type of
-        *  parameter: 1 (!) = suppress message completely, 29 (S) = NULL
-        *  If PARAM=1, else 'S' (optional plural ending), 33 (W) = word
-        *  (two 30-bit values) with trailing spaces suppressed, 22 (L) or
-        *  31 (U) = word but map to lower/upper case, 13 (C) = word in
-        *  lower case with first letter capitalised, 30 (T) = text ending
-        *  with a word of -1, 65-73 (1-9) = number using that many
-        *  characters, 12 (B) = variable number of blanks. */
-       if (prmtyp == 1)
-           return;
-       if (prmtyp == 29)
-           goto L320;
-       if (prmtyp == 30)
-           goto L340;
-       if (prmtyp == 12)
-           goto L360;
-       if (prmtyp == 33 || prmtyp == 22 || prmtyp == 31 || prmtyp == 13)
-           goto L380;
-       prmtyp=prmtyp-64;
-       if (prmtyp < 1 || prmtyp > 9)
-           goto L30;
-       SHFTXT(LNPOSN+2,prmtyp-2);
-       LNPOSN += prmtyp;
-       param=labs(PARMS[nparms]);
-       neg=0;
-       if (PARMS[nparms] < 0)
-           neg=9;
-       for (i=1; i <= prmtyp; i++) {
-           --LNPOSN;
-           INLINE[LNPOSN]=MOD(param,10)+64;
-           if (i != 1 && param == 0) {
-               INLINE[LNPOSN]=neg;
-               neg=0;
+
+       while (LNPOSN <= LNLENG) { 
+           if (INLINE[LNPOSN] != PERCENT) {
+               ++LNPOSN;
+               continue;
+           }
+           prmtyp = INLINE[LNPOSN+1];
+           /*  A "%"; the next character determine the type of
+            *  parameter: 1 (!) = suppress message completely, 29 (S) = NULL
+            *  If PARAM=1, else 'S' (optional plural ending), 33 (W) = word
+            *  (two 30-bit values) with trailing spaces suppressed, 22 (L) or
+            *  31 (U) = word but map to lower/upper case, 13 (C) = word in
+            *  lower case with first letter capitalised, 30 (T) = text ending
+            *  with a word of -1, 65-73 (1-9) = number using that many
+            *  characters, 12 (B) = variable number of blanks. */
+           if (prmtyp == 1)
+               return;
+           if (prmtyp == 29) {
+               SHFTXT(LNPOSN+2,-1);
+               INLINE[LNPOSN] = 55;
+               if (PARMS[nparms] == 1)
+                   SHFTXT(LNPOSN+1,-1);
+               ++nparms;
+               continue;
+           }
+           if (prmtyp == 30) {
+               SHFTXT(LNPOSN+2,-2);
+               state=0;
+               casemake=2;
+
+               while (PARMS[nparms] > 0) {
+                   if (PARMS[nparms+1] < 0)
+                       casemake=0;
+                   PUTTXT(PARMS[nparms],state,casemake);
+                   nparms=nparms+1;
+               }
+               ++nparms;
+               continue;
+           }
+           if (prmtyp == 12) {
+               prmtyp=PARMS[nparms];
+               SHFTXT(LNPOSN+2,prmtyp-2);
+               if (prmtyp != 0) {
+                   for (i=1; i<=prmtyp; i++) {
+                       INLINE[LNPOSN]=0;
+                       ++LNPOSN;
+                   }
+               }
+               ++nparms;
+               continue;
+           }
+           if (prmtyp == 33 || prmtyp == 22 || prmtyp == 31 || prmtyp == 13) {
+               SHFTXT(LNPOSN+2,-2);
+               state = 0;
+               casemake = -1;
+               if (prmtyp == 31)
+                   casemake=1;
+               if (prmtyp == 33)
+                   casemake=0;
+               i = LNPOSN;
+               PUTTXT(PARMS[nparms],state,casemake);
+               PUTTXT(PARMS[nparms+1],state,casemake);
+               if (prmtyp == 13 && INLINE[i] >= 37 && INLINE[i] <= 62)
+                   INLINE[i] -= 26;
+               nparms += 2;
+               continue;
            }
-           param=param/10;
-       }
-       LNPOSN=LNPOSN+prmtyp;
-L395:
-       ++nparms;
-       goto L32;
-
-L320:
-       SHFTXT(LNPOSN+2,-1);
-       INLINE[LNPOSN]=55;
-       if (PARMS[nparms] == 1)
-           SHFTXT(LNPOSN+1,-1);
-       goto L395;
-
-L340:
-       SHFTXT(LNPOSN+2,-2);
-       state=0;
-       casemake=2;
 
-       for (;;) {
+           prmtyp=prmtyp-64;
+           if (prmtyp < 1 || prmtyp > 9) {
+               ++LNPOSN;
+               continue;
+           }
+           SHFTXT(LNPOSN+2,prmtyp-2);
+           LNPOSN += prmtyp;
+           param=labs(PARMS[nparms]);
+           neg=0;
            if (PARMS[nparms] < 0)
-               goto L395;
-           if (PARMS[nparms+1] < 0)
-               casemake=0;
-           PUTTXT(PARMS[nparms],state,casemake);
-           nparms=nparms+1;
-       }
-
-L360:
-       prmtyp=PARMS[nparms];
-       SHFTXT(LNPOSN+2,prmtyp-2);
-       if (prmtyp != 0) {
-           for (i=1; i<=prmtyp; i++) {
-               INLINE[LNPOSN]=0;
-               LNPOSN=LNPOSN+1;
+               neg=9;
+           for (i=1; i <= prmtyp; i++) {
+               --LNPOSN;
+               INLINE[LNPOSN]=MOD(param,10)+64;
+               if (i != 1 && param == 0) {
+                   INLINE[LNPOSN]=neg;
+                   neg=0;
+               }
+               param=param/10;
            }
+           LNPOSN += prmtyp;
+           ++nparms;
+           continue;
        }
-       goto L395;
-
-L380:
-       SHFTXT(LNPOSN+2,-2);
-       state = 0;
-       casemake = -1;
-       if (prmtyp == 31)
-           casemake=1;
-       if (prmtyp == 33)
-           casemake=0;
-       i = LNPOSN;
-       PUTTXT(PARMS[nparms],state,casemake);
-       PUTTXT(PARMS[nparms+1],state,casemake);
-       if (prmtyp == 13 && INLINE[i] >= 37 && INLINE[i] <= 62)
-           INLINE[i] -= 26;
-       nparms = nparms+2;
-       goto L32;
-
-L40:
+
        if (blank)
            TYPE0();
        blank=false;
@@ -264,7 +263,7 @@ long GETTXT(bool skip, bool onewrd, bool upper)
        if (LNPOSN > LNLENG || (onewrd && INLINE[LNPOSN] == 0))
            continue;
        char current=INLINE[LNPOSN];
-       if (current < 63) {
+       if (current < PERCENT) {
            splitting = -1;
            if (upper && current >= 37)
                current=current-26;
@@ -273,12 +272,12 @@ long GETTXT(bool skip, bool onewrd, bool upper)
            continue;
        }
        if (splitting != LNPOSN) {
-           text=text+63;
+           text=text+PERCENT;
            splitting = LNPOSN;
            continue;
        }
 
-       text=text+current-63;
+       text=text+current-PERCENT;
        splitting = -1;
        LNPOSN=LNPOSN+1;
     }
@@ -335,8 +334,8 @@ void fPUTTXT(token_t word, long *state, long casemake)
            return;
        byte=w/div;
        w=(w-byte*div)*64;
-       if (!(*state != 0 || byte != 63)) {
-           *state=63;
+       if (!(*state != 0 || byte != PERCENT)) {
+           *state=PERCENT;
            continue;
        }
        SHFTXT(LNPOSN,1);
@@ -821,8 +820,8 @@ void fSAVEIO(long op, long in, long arr[])
  *  automatically.  Finishing reading can be a no-op as long as a subsequent
  *  SAVEIO(0,false,X) will still work.) */
 {
-    static FILE *fp = NULL; 
-    char name[50];
+    static FILE *fp = NULL;
+    char* name;
 
     switch (op < 0 ? -1 : (op > 0 ? 1 : 0)) 
     { 
@@ -831,12 +830,12 @@ void fSAVEIO(long op, long in, long arr[])
        break;
     case 0:
        while (fp == NULL) {
-           printf("\nFile name: ");
-           IGNORE(fgets(name, sizeof(name), stdin));
+           name = linenoise("File name: ");
            fp = fopen(name,(in ? READ_MODE : WRITE_MODE));
            if (fp == NULL)
                printf("Can't open file %s, try again.\n", name); 
        }
+       linenoiseFree(name);
        break;
     case 1: 
        if (in)