]> granicus.if.org Git - nethack/commitdiff
loadlua() simplification
authorPatR <rankin@nethack.org>
Fri, 31 Jan 2020 21:36:22 +0000 (13:36 -0800)
committerPatR <rankin@nethack.org>
Fri, 31 Jan 2020 21:36:22 +0000 (13:36 -0800)
nhl_loadlua() went from too simple to too complicated, now somewhere
in between.  Still doesn't assume that an entire file can be scooped
up with a single fread(), but no longer mucks about with the contents
of the file in order to insert a comment containing the file's name.
In order to have useful filename feedback in Lua error messages, just
use a different liblua routine to feed the file's contents to it.

src/nhlua.c

index b0f6a1eb6537e1f11bca86ae54b41be441622052..68c09dfd36369f10f14bb110b85a3215afec1cb8 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 nhlua.c $NHDT-Date: 1580427882 2020/01/30 23:44:42 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */
+/* NetHack 3.7 nhlua.c $NHDT-Date: 1580506559 2020/01/31 21:35:59 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ */
 /*      Copyright (c) 2018 by Pasi Kallinen */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -959,42 +959,40 @@ lua_State *L;
     return 1;
 }
 
-/* read lua code/data from a dlb module or an external file, insert the file
-   name as new first record so that we aren't at the mercy of whoever edits
-   it to maintain that, and since we're forced to muck with messy details,
-   replace full-line comments with empty lines so that Lua won't need to */
+/* read lua code/data from a dlb module or an external file
+   into a string buffer and feed that to lua */
 boolean
 nhl_loadlua(L, fname)
 lua_State *L;
 const char *fname;
 {
 #define LOADCHUNKSIZE (1L << 13) /* 8K */
-    boolean ret = TRUE, is_comment;
+    boolean ret = TRUE;
     dlb *fh;
-    char *buf = (char *) 0, *bufin, *bufout, *p, *nl;
-    long buflen, ct, cnt, fnamesiz;
-    int llret, first = 0, spanlines = 0;
-
+    char *buf = (char *) 0, *bufin, *bufout, *p, *nl, *altfname;
+    long buflen, ct, cnt;
+    int llret;
+
+    altfname = (char *) alloc(strlen(fname) + 3); /* 3: '('...')\0' */
+    /* don't know whether 'fname' is inside a dlb container;
+       if we did, we could choose between "nhdat(<fname>)" and "<fname>"
+       but since we don't, compromise */
+    Sprintf(altfname, "(%s)", fname);
     fh = dlb_fopen(fname, "r");
     if (!fh) {
-        impossible("nhl_loadlua: Error loading %s", fname);
+        impossible("nhl_loadlua: Error loading %s", altfname);
         ret = FALSE;
         goto give_up;
     }
 
-    fnamesiz = strlen(fname) + 7L; /* 7: "--{" + "}--\n" (no '\0') */
     dlb_fseek(fh, 0L, SEEK_END);
     buflen = dlb_ftell(fh);
     dlb_fseek(fh, 0L, SEEK_SET);
 
     /* extra +1: room to add final '\n' if missing */
-    buf = bufout = (char *) alloc(fnamesiz + buflen + 1 + 1);
-    /* insert file name as first record so nhl_error() can report it;
-       leading dashes make it be a comment, trailing ones are for
-       symmetry; delimit file name with braces instead of spaces to
-       avoid an undesireable line split during error feedback */
-    Sprintf(bufout, "--{%s}--\n", fname);
-    bufin = bufout = eos(buf);
+    buf = bufout = (char *) alloc(buflen + 1 + 1);
+    buf[0] = '\0';
+    bufin = bufout = buf;
 
     ct = 0L;
     while (buflen > 0 || ct) {
@@ -1025,41 +1023,14 @@ const char *fname;
             if ((nl = index(bufin, '\n')) != 0) {
                 /* normal case, newline is present */
                 ct = (long) (nl - bufin + 1L); /* +1: keep the newline */
-                for (p = bufin; *p == ' '; ++p)
-                    continue;
-                is_comment = (p[0] == '-' && p[1] == '-' && !spanlines);
-                if (spanlines && index("])}", *p))
-                    --spanlines;
-                if (!first++ && (*p == '\n' || is_comment)) {
-                    /* if first line is blank or a comment, omit it so that
-                       our "--{fname}--\n" line doesn't make the line count
-                       be out of sync; note: when first line is code, line
-                       number reported in error messages will be off by one */
-                    bufin = nl + 1;
-                } else if (is_comment) {
-                    /* discard comment to shorten the string Lua will deal
-                       with but keep the line to maintain Lua line counter */
-#if 0
-                    Strcpy(bufout, "--\n"), bufout += 3;
-#else
-                    Strcpy(bufout, "\n"), bufout += 1;
-#endif
-                    bufin += ct;
-                } else {
-                    /* normal case; some text terminated by newline */
-                    for (p = bufin; p <= nl; ++p)
-                        *bufout++ = *bufin++;
-                    for (p = &bufout[-2]; *p == ' '; --p) /* [-1] is '\n' */
-                        continue;
-                    if (index("[({", *p))
-                        ++spanlines;
-                }
+                for (p = bufin; p <= nl; ++p)
+                    *bufout++ = *bufin++;
                 if (*bufin == '\r')
                     ++bufin, ++ct;
                 /* update for next loop iteration */
                 cnt -= ct;
                 ct = 0;
-            } else {
+            } else if (strlen(bufin) < LOADCHUNKSIZE) {
                 /* no newline => partial record; move unprocessed chars
                    to front of input buffer (bufin portion of buf[]) */
                 ct = cnt = (long) (eos(bufin) - bufin);
@@ -1068,35 +1039,20 @@ const char *fname;
                 *p = '\0';
                 bufin = p; /* next fread() populates buf[] starting here */
                 /* cnt==0 so inner loop will terminate */
+            } else {
+                /* LOADCHUNKSIZE portion of buffer already completely full */
+                impossible("(%s) line too long", altfname);
+                goto give_up;
             }
         }
     }
     *bufout = '\0';
     (void) dlb_fclose(fh);
 
-#ifdef DEBUG
-    if (explicitdebug("loadlua")) {
-        FILE *fp;
-        char oname[QBUFSZ];
-
-        (void) strsubst(strcpy(oname, fname), ".lua", ".txt");
-        if ((fp = fopen(oname, "w")) != 0) {
-            for (buflen = strlen(buf), p = buf;
-                 buflen > 0;
-                 buflen -= cnt, p += cnt) {
-                cnt = min(buflen, LOADCHUNKSIZE);
-                if ((long) fwrite(p, 1, cnt, fp) < cnt)
-                    break;
-            }
-            (void) fclose(fp);
-        }
-    }
-#endif
-
-    llret = luaL_loadstring(L, buf);
+    llret = luaL_loadbuffer(L, buf, strlen(buf), altfname);
     if (llret != LUA_OK) {
-        impossible("luaL_loadstring: Error loading %s (errcode %i)",
-                   fname, llret);
+        impossible("luaL_loadbuffer: Error loading %s (errcode %i)",
+                   altfname, llret);
         ret = FALSE;
         goto give_up;
     } else {
@@ -1110,10 +1066,10 @@ const char *fname;
     }
 
  give_up:
-    if (buf) {
+    if (altfname)
+        free((genericptr_t) altfname);
+    if (buf)
         free((genericptr_t) buf);
-        buflen = 0;
-    }
     return ret;
 }