loadlua() simplification

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.
This commit is contained in:
PatR
2020-01-31 13:36:22 -08:00
parent 625a9a7b79
commit c03ed894de
+29 -73
View 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 */ /* Copyright (c) 2018 by Pasi Kallinen */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -959,42 +959,40 @@ lua_State *L;
return 1; return 1;
} }
/* read lua code/data from a dlb module or an external file, insert the file /* read lua code/data from a dlb module or an external file
name as new first record so that we aren't at the mercy of whoever edits into a string buffer and feed that to lua */
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 */
boolean boolean
nhl_loadlua(L, fname) nhl_loadlua(L, fname)
lua_State *L; lua_State *L;
const char *fname; const char *fname;
{ {
#define LOADCHUNKSIZE (1L << 13) /* 8K */ #define LOADCHUNKSIZE (1L << 13) /* 8K */
boolean ret = TRUE, is_comment; boolean ret = TRUE;
dlb *fh; dlb *fh;
char *buf = (char *) 0, *bufin, *bufout, *p, *nl; char *buf = (char *) 0, *bufin, *bufout, *p, *nl, *altfname;
long buflen, ct, cnt, fnamesiz; long buflen, ct, cnt;
int llret, first = 0, spanlines = 0; 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"); fh = dlb_fopen(fname, "r");
if (!fh) { if (!fh) {
impossible("nhl_loadlua: Error loading %s", fname); impossible("nhl_loadlua: Error loading %s", altfname);
ret = FALSE; ret = FALSE;
goto give_up; goto give_up;
} }
fnamesiz = strlen(fname) + 7L; /* 7: "--{" + "}--\n" (no '\0') */
dlb_fseek(fh, 0L, SEEK_END); dlb_fseek(fh, 0L, SEEK_END);
buflen = dlb_ftell(fh); buflen = dlb_ftell(fh);
dlb_fseek(fh, 0L, SEEK_SET); dlb_fseek(fh, 0L, SEEK_SET);
/* extra +1: room to add final '\n' if missing */ /* extra +1: room to add final '\n' if missing */
buf = bufout = (char *) alloc(fnamesiz + buflen + 1 + 1); buf = bufout = (char *) alloc(buflen + 1 + 1);
/* insert file name as first record so nhl_error() can report it; buf[0] = '\0';
leading dashes make it be a comment, trailing ones are for bufin = bufout = buf;
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);
ct = 0L; ct = 0L;
while (buflen > 0 || ct) { while (buflen > 0 || ct) {
@@ -1025,41 +1023,14 @@ const char *fname;
if ((nl = index(bufin, '\n')) != 0) { if ((nl = index(bufin, '\n')) != 0) {
/* normal case, newline is present */ /* normal case, newline is present */
ct = (long) (nl - bufin + 1L); /* +1: keep the newline */ ct = (long) (nl - bufin + 1L); /* +1: keep the newline */
for (p = bufin; *p == ' '; ++p) for (p = bufin; p <= nl; ++p)
continue; *bufout++ = *bufin++;
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;
}
if (*bufin == '\r') if (*bufin == '\r')
++bufin, ++ct; ++bufin, ++ct;
/* update for next loop iteration */ /* update for next loop iteration */
cnt -= ct; cnt -= ct;
ct = 0; ct = 0;
} else { } else if (strlen(bufin) < LOADCHUNKSIZE) {
/* no newline => partial record; move unprocessed chars /* no newline => partial record; move unprocessed chars
to front of input buffer (bufin portion of buf[]) */ to front of input buffer (bufin portion of buf[]) */
ct = cnt = (long) (eos(bufin) - bufin); ct = cnt = (long) (eos(bufin) - bufin);
@@ -1068,35 +1039,20 @@ const char *fname;
*p = '\0'; *p = '\0';
bufin = p; /* next fread() populates buf[] starting here */ bufin = p; /* next fread() populates buf[] starting here */
/* cnt==0 so inner loop will terminate */ /* 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'; *bufout = '\0';
(void) dlb_fclose(fh); (void) dlb_fclose(fh);
#ifdef DEBUG llret = luaL_loadbuffer(L, buf, strlen(buf), altfname);
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);
if (llret != LUA_OK) { if (llret != LUA_OK) {
impossible("luaL_loadstring: Error loading %s (errcode %i)", impossible("luaL_loadbuffer: Error loading %s (errcode %i)",
fname, llret); altfname, llret);
ret = FALSE; ret = FALSE;
goto give_up; goto give_up;
} else { } else {
@@ -1110,10 +1066,10 @@ const char *fname;
} }
give_up: give_up:
if (buf) { if (altfname)
free((genericptr_t) altfname);
if (buf)
free((genericptr_t) buf); free((genericptr_t) buf);
buflen = 0;
}
return ret; return ret;
} }