aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--liolib.c91
1 files changed, 25 insertions, 66 deletions
diff --git a/liolib.c b/liolib.c
index 4260534d..c9abe78b 100644
--- a/liolib.c
+++ b/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 2.1 2002/04/04 20:24:56 roberto Exp roberto $ 2** $Id: liolib.c,v 2.2 2002/04/05 18:54:31 roberto Exp roberto $
3** Standard I/O (and system) library 3** Standard I/O (and system) library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -180,62 +180,6 @@ static int io_output (lua_State *L) {
180*/ 180*/
181 181
182 182
183#ifndef LUA_MAXUNTIL
184#define LUA_MAXUNTIL 100
185#endif
186
187
188/*
189** Knuth-Morris-Pratt algorithm for string searching
190** (based on `Algorithms in MODULA-3', Robert Sedgewick;
191** Addison-Wesley, 1993.)
192*/
193
194static void prep_read_until (int next[], const char *p, int pl) {
195 int i = 0;
196 int j = -1;
197 next[0] = -1;
198 while (i < pl) {
199 if (j == -1 || p[i] == p[j]) {
200 i++; j++; next[i] = j;
201 }
202 else j = next[j];
203 }
204}
205
206
207static int read_until (lua_State *L, FILE *f, const char *p, int pl) {
208 int c;
209 int j;
210 int next[LUA_MAXUNTIL+1];
211 luaL_Buffer b;
212 luaL_buffinit(L, &b);
213 prep_read_until(next, p, pl);
214 j = 0;
215 while ((c = getc(f)) != EOF) {
216 NoRead:
217 if (c == p[j]) {
218 j++; /* go to next char in pattern */
219 if (j == pl) { /* complete match? */
220 luaL_pushresult(&b); /* close buffer */
221 return 1; /* always success */
222 }
223 }
224 else if (j == 0)
225 luaL_putchar(&b, c);
226 else { /* match fail */
227 luaL_addlstring(&b, p, j - next[j]); /* put failed part on result */
228 j = next[j]; /* backtrack pattern index */
229 goto NoRead; /* repeat without reading next char */
230 }
231 }
232 /* end of file without a match */
233 luaL_addlstring(&b, p, j); /* put failed part on result */
234 luaL_pushresult(&b); /* close buffer */
235 return (lua_strlen(L, -1) > 0);
236}
237
238
239static int read_number (lua_State *L, FILE *f) { 183static int read_number (lua_State *L, FILE *f) {
240 lua_Number d; 184 lua_Number d;
241 if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { 185 if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
@@ -254,6 +198,28 @@ static int test_eof (lua_State *L, FILE *f) {
254} 198}
255 199
256 200
201static int read_line (lua_State *L, FILE *f) {
202 luaL_Buffer b;
203 luaL_buffinit(L, &b);
204 for (;;) {
205 size_t l;
206 char *p = luaL_prepbuffer(&b);
207 if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
208 luaL_pushresult(&b); /* close buffer */
209 return (lua_strlen(L, -1) > 0); /* check whether read something */
210 }
211 l = strlen(p);
212 if (p[l-1] != '\n')
213 luaL_addsize(&b, l);
214 else {
215 luaL_addsize(&b, l - 1); /* do not include `eol' */
216 luaL_pushresult(&b); /* close buffer */
217 return 1; /* read at least an `eol' */
218 }
219 }
220}
221
222
257static int read_chars (lua_State *L, FILE *f, size_t n) { 223static int read_chars (lua_State *L, FILE *f, size_t n) {
258 size_t rlen; /* how much to read */ 224 size_t rlen; /* how much to read */
259 size_t nr; /* number of chars actually read */ 225 size_t nr; /* number of chars actually read */
@@ -277,7 +243,7 @@ static int g_read (lua_State *L, FILE *f, int first) {
277 int success; 243 int success;
278 int n; 244 int n;
279 if (nargs == 0) { /* no arguments? */ 245 if (nargs == 0) { /* no arguments? */
280 success = read_until(L, f, "\n", 1); /* read until \n (a line) */ 246 success = read_line(L, f);
281 n = first+1; /* to return 1 result */ 247 n = first+1; /* to return 1 result */
282 } 248 }
283 else { /* ensure stack space for all results and for auxlib's buffer */ 249 else { /* ensure stack space for all results and for auxlib's buffer */
@@ -297,7 +263,7 @@ static int g_read (lua_State *L, FILE *f, int first) {
297 success = read_number(L, f); 263 success = read_number(L, f);
298 break; 264 break;
299 case 'l': /* line */ 265 case 'l': /* line */
300 success = read_until(L, f, "\n", 1); /* read until \n */ 266 success = read_line(L, f);
301 break; 267 break;
302 case 'a': /* file */ 268 case 'a': /* file */
303 read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ 269 read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
@@ -306,13 +272,6 @@ static int g_read (lua_State *L, FILE *f, int first) {
306 case 'w': /* word */ 272 case 'w': /* word */
307 lua_error(L, "obsolete option `*w'"); 273 lua_error(L, "obsolete option `*w'");
308 break; 274 break;
309 case 'u': { /* read until */
310 size_t pl = lua_strlen(L, n) - 2;
311 luaL_arg_check(L, 0 < pl && pl <= LUA_MAXUNTIL, n,
312 "invalid read-until length");
313 success = read_until(L, f, p+2, (int)(pl));
314 break;
315 }
316 default: 275 default:
317 luaL_argerror(L, n, "invalid format"); 276 luaL_argerror(L, n, "invalid format");
318 success = 0; /* to avoid warnings */ 277 success = 0; /* to avoid warnings */