Comment polishing.
[open-adventure.git] / misc.c
diff --git a/misc.c b/misc.c
index 3b612d8c5c99cde0104fa5d51d30b1a43684d8c1..752bc8ee2cd3f483f5994abf0e5f750a24331ea6 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -21,14 +21,37 @@ void* xmalloc(size_t size)
   return(ptr);
 }
 
+char* xstrdup(const char* s)
+{
+  char* ptr = strdup(s);
+  if (ptr == NULL)
+    {
+      fprintf(stderr, "Out of memory!\n");
+      exit(EXIT_FAILURE);
+    }
+  return(ptr);
+}
+
 void packed_to_token(long packed, char token[6])
 {
+  // Unpack and map back to ASCII.
   for (int i = 0; i < 5; ++i)
     {
       char advent = (packed >> i * 6) & 63;
-      token[i] = advent_to_ascii[advent];
+      token[4 - i] = advent_to_ascii[advent];
     }
+
+  // Ensure the last character is \0.
   token[5] = '\0';
+
+  // Replace trailing whitespace with \0.
+  for (int i = 4; i >= 0; --i)
+    {
+      if (token[i] == ' ' || token[i] == '\t')
+       token[i] = '\0';
+      else
+       break;
+    }
 }
 
 /*  I/O routines (SPEAK, PSPEAK, RSPEAK, SETPRM, GETIN, YES) */
@@ -48,8 +71,7 @@ void newspeak(char* msg)
     printf("\n");
 
   // Create a copy of our string, so we can edit it.
-  char* copy = (char*) xmalloc(strlen(msg) + 1);
-  strncpy(copy, msg, strlen(msg) + 1);
+  char* copy = xstrdup(msg);
 
   // Staging area for stringified parameters.
   char parameters[5][100]; // FIXME: to be replaced with dynamic allocation
@@ -66,7 +88,7 @@ void newspeak(char* msg)
          if (msg[i + 1] == 'd')
            {
              copy[i + 1] = 's';
-             sprintf(parameters[pi], "%d", PARMS[pi]);
+             sprintf(parameters[pi], "%ld", PARMS[pi]);
            }
 
          // Unmodified string specifier.
@@ -116,7 +138,7 @@ void newspeak(char* msg)
 
   // Render the final string.
   char rendered[2000]; // FIXME: to be replaced with dynamic allocation
-  sprintf(&rendered, copy, parameters[1], parameters[2], parameters[3], parameters[4]); // FIXME: to be replaced with vsprintf()
+  sprintf(rendered, copy, parameters[1], parameters[2], parameters[3], parameters[4]); // FIXME: to be replaced with vsprintf()
 
   // Print the message.
   printf("%s\n", rendered);
@@ -124,109 +146,6 @@ void newspeak(char* msg)
   free(copy);
 }
 
-void SPEAK(vocab_t msg)
-/*  Print the message which starts at LINES[N].  Precede it with a blank line
- *  unless game.blklin is false. */
-{
-    long blank, casemake, i, nxt, neg, nparms, param, prmtyp, state;
-
-    if (msg == 0)
-       return;
-    blank=game.blklin;
-    nparms=1;
-    do {
-       nxt=labs(LINES[msg])-1;
-       ++msg;
-       LNLENG=0;
-       LNPOSN=1;
-       state=0;
-       for (i = msg; i <= nxt; i++) {
-           PUTTXT(LINES[i],&state,2);
-       }
-       LNPOSN=0;
-       ++LNPOSN;
-
-       while (LNPOSN <= LNLENG) { 
-           if (INLINE[LNPOSN] != ascii_to_advent['%']) {
-               ++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, 65-73 (1-9) =
-            *  number using that many characters. */
-           if (prmtyp == ascii_to_advent['!'])
-               return;
-           if (prmtyp == ascii_to_advent['S']) {
-               SHFTXT(LNPOSN+2,-1);
-               INLINE[LNPOSN] = ascii_to_advent['s'];
-               if (PARMS[nparms] == 1)
-                   SHFTXT(LNPOSN+1,-1);
-               ++nparms;
-               continue;
-           }
-           if (prmtyp == ascii_to_advent['W'] || prmtyp == ascii_to_advent['L'] || prmtyp == ascii_to_advent['U'] || prmtyp == ascii_to_advent['C']) {
-               SHFTXT(LNPOSN+2,-2);
-               state = 0;
-               casemake = -1;
-               if (prmtyp == ascii_to_advent['U'])
-                   casemake=1;
-               if (prmtyp == ascii_to_advent['W'])
-                   casemake=0;
-               i = LNPOSN;
-               PUTTXT(PARMS[nparms],&state,casemake);
-               PUTTXT(PARMS[nparms+1],&state,casemake);
-               if (prmtyp == ascii_to_advent['C'] && INLINE[i] >= ascii_to_advent['a'] && INLINE[i] <= ascii_to_advent['z'])
-                 {
-                   // Convert to uppercase.
-                   // Round-trip to ASCII and back so that this code doesn't break when the mapping changes.
-                   // This can be simplified when mapping goes away.
-                   char this = advent_to_ascii[INLINE[i]];
-                   char uc_this = toupper(this);
-                   INLINE[i] = ascii_to_advent[uc_this];
-                 }
-               nparms += 2;
-               continue;
-           }
-
-           prmtyp=prmtyp-64;
-           if (prmtyp < ascii_to_advent['!'] || prmtyp > ascii_to_advent['-']) {
-               ++LNPOSN;
-               continue;
-           }
-           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;
-               }
-               param=param/10;
-           }
-           LNPOSN += prmtyp;
-           ++nparms;
-           continue;
-       }
-
-       if (blank)
-           TYPE0();
-       blank=false;
-       TYPE();
-       msg = nxt + 1;
-    } while
-       (LINES[msg] >= 0);
-}
-
 void PSPEAK(vocab_t msg,int skip)
 /*  Find the skip+1st message from msg and print it.  msg should be
  *  the index of the inventory message for object.  (INVEN+N+1 message
@@ -721,10 +640,10 @@ bool MAPLIN(FILE *fp)
      *  and is not changed thereafter unless the routines on this page choose
      *  to do so. */
 
-    if (!oldstyle && !isatty(1))
-       fputs("> ", stdout);
     do {
-       if (oldstyle) {
+       if (!editline) {
+           if (prompt)
+               fputs("> ", stdout);
            IGNORE(fgets(rawbuf,sizeof(rawbuf)-1,fp));
            eof = (feof(fp));
        } else {
@@ -744,10 +663,17 @@ bool MAPLIN(FILE *fp)
            fclose(logfp);
        return false;
     } else {
+       FILE *efp = NULL;
        if (logfp && fp == stdin)
-           IGNORE(fputs(rawbuf, logfp));
+           efp = logfp;
        else if (!isatty(0))
-           IGNORE(fputs(rawbuf, stdout));
+           efp = stdout;
+       if (efp != NULL)
+       {
+           if (prompt)
+               fputs("> ", efp);
+           IGNORE(fputs(rawbuf, efp));
+       }
        strcpy(INLINE+1, rawbuf);
        LNLENG=0;
        for (i=1; i<=(long)sizeof(INLINE) && INLINE[i]!=0; i++) {
@@ -789,7 +715,4 @@ void DATIME(long* d, long* t)
     *t = (long) tv.tv_usec;
 }
 
-long MOD(long n, long m) 
-{
-    return(n%m);
-}
+/* end */