XXX impossible() should be swappable with pline/nothing/panic via flag */ read lua code/data from a dlb module or an external file into a string buffer and feed that to lua */
| 2181 | /* read lua code/data from a dlb module or an external file |
| 2182 | into a string buffer and feed that to lua */ |
| 2183 | boolean |
| 2184 | nhl_loadlua(lua_State *L, const char *fname) |
| 2185 | { |
| 2186 | #define LOADCHUNKSIZE (1L << 13) /* 8K */ |
| 2187 | boolean ret = TRUE; |
| 2188 | dlb *fh; |
| 2189 | char *buf = (char *) 0, *bufin, *bufout, *p, *nl, *altfname; |
| 2190 | long buflen, ct, cnt; |
| 2191 | int llret; |
| 2192 | |
| 2193 | altfname = (char *) alloc(Strlen(fname) + 3); /* 3: '('...')\0' */ |
| 2194 | /* don't know whether 'fname' is inside a dlb container; |
| 2195 | if we did, we could choose between "nhdat(<fname>)" and "<fname>" |
| 2196 | but since we don't, compromise */ |
| 2197 | Sprintf(altfname, "(%s)", fname); |
| 2198 | fh = dlb_fopen(fname, RDBMODE); |
| 2199 | if (!fh) { |
| 2200 | impossible("nhl_loadlua: Error opening %s", altfname); |
| 2201 | ret = FALSE; |
| 2202 | goto give_up; |
| 2203 | } |
| 2204 | |
| 2205 | dlb_fseek(fh, 0L, SEEK_END); |
| 2206 | buflen = dlb_ftell(fh); |
| 2207 | dlb_fseek(fh, 0L, SEEK_SET); |
| 2208 | |
| 2209 | /* extra +1: room to add final '\n' if missing */ |
| 2210 | buf = bufout = (char *) alloc(FITSint(buflen + 1 + 1)); |
| 2211 | buf[0] = '\0'; |
| 2212 | bufin = bufout = buf; |
| 2213 | |
| 2214 | ct = 0L; |
| 2215 | while (buflen > 0 || ct) { |
| 2216 | /* |
| 2217 | * Semi-arbitrarily limit reads to 8K at a time. That's big |
| 2218 | * enough to cover the majority of our Lua files in one bite |
| 2219 | * but small enough to fully exercise the partial record |
| 2220 | * handling (when processing the castle's level description). |
| 2221 | * |
| 2222 | * [For an external file (non-DLB), VMS may only be able to |
| 2223 | * read at most 32K-1 at a time depending on the file format |
| 2224 | * in use, and fseek(SEEK_END) only yields an upper bound on |
| 2225 | * the actual amount of data in that situation.] |
| 2226 | */ |
| 2227 | if ((cnt = dlb_fread(bufin, 1, min((int) buflen, LOADCHUNKSIZE), fh)) |
| 2228 | < 0L) |
| 2229 | break; |
| 2230 | buflen -= cnt; /* set up for next iteration, if any */ |
| 2231 | if (cnt == 0L) { |
| 2232 | *bufin = '\n'; /* very last line is unterminated? */ |
| 2233 | cnt = 1; |
| 2234 | } |
| 2235 | bufin[cnt] = '\0'; /* fread() doesn't do this */ |
| 2236 | |
| 2237 | /* in case partial line was leftover from previous fread */ |
| 2238 | bufin -= ct, cnt += ct, ct = 0; |
| 2239 | |
| 2240 | while (cnt > 0) { |
no test coverage detected