|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
-** $Id: liolib.c,v 2.1 2002/04/04 20:24:56 roberto Exp roberto $
|
|
|
+** $Id: liolib.c,v 2.2 2002/04/05 18:54:31 roberto Exp roberto $
|
|
|
** Standard I/O (and system) library
|
|
|
** See Copyright Notice in lua.h
|
|
|
*/
|
|
@@ -180,62 +180,6 @@ static int io_output (lua_State *L) {
|
|
|
*/
|
|
|
|
|
|
|
|
|
-#ifndef LUA_MAXUNTIL
|
|
|
-#define LUA_MAXUNTIL 100
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
-** Knuth-Morris-Pratt algorithm for string searching
|
|
|
-** (based on `Algorithms in MODULA-3', Robert Sedgewick;
|
|
|
-** Addison-Wesley, 1993.)
|
|
|
-*/
|
|
|
-
|
|
|
-static void prep_read_until (int next[], const char *p, int pl) {
|
|
|
- int i = 0;
|
|
|
- int j = -1;
|
|
|
- next[0] = -1;
|
|
|
- while (i < pl) {
|
|
|
- if (j == -1 || p[i] == p[j]) {
|
|
|
- i++; j++; next[i] = j;
|
|
|
- }
|
|
|
- else j = next[j];
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static int read_until (lua_State *L, FILE *f, const char *p, int pl) {
|
|
|
- int c;
|
|
|
- int j;
|
|
|
- int next[LUA_MAXUNTIL+1];
|
|
|
- luaL_Buffer b;
|
|
|
- luaL_buffinit(L, &b);
|
|
|
- prep_read_until(next, p, pl);
|
|
|
- j = 0;
|
|
|
- while ((c = getc(f)) != EOF) {
|
|
|
- NoRead:
|
|
|
- if (c == p[j]) {
|
|
|
- j++; /* go to next char in pattern */
|
|
|
- if (j == pl) { /* complete match? */
|
|
|
- luaL_pushresult(&b); /* close buffer */
|
|
|
- return 1; /* always success */
|
|
|
- }
|
|
|
- }
|
|
|
- else if (j == 0)
|
|
|
- luaL_putchar(&b, c);
|
|
|
- else { /* match fail */
|
|
|
- luaL_addlstring(&b, p, j - next[j]); /* put failed part on result */
|
|
|
- j = next[j]; /* backtrack pattern index */
|
|
|
- goto NoRead; /* repeat without reading next char */
|
|
|
- }
|
|
|
- }
|
|
|
- /* end of file without a match */
|
|
|
- luaL_addlstring(&b, p, j); /* put failed part on result */
|
|
|
- luaL_pushresult(&b); /* close buffer */
|
|
|
- return (lua_strlen(L, -1) > 0);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
static int read_number (lua_State *L, FILE *f) {
|
|
|
lua_Number d;
|
|
|
if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
|
|
@@ -254,6 +198,28 @@ static int test_eof (lua_State *L, FILE *f) {
|
|
|
}
|
|
|
|
|
|
|
|
|
+static int read_line (lua_State *L, FILE *f) {
|
|
|
+ luaL_Buffer b;
|
|
|
+ luaL_buffinit(L, &b);
|
|
|
+ for (;;) {
|
|
|
+ size_t l;
|
|
|
+ char *p = luaL_prepbuffer(&b);
|
|
|
+ if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
|
|
|
+ luaL_pushresult(&b); /* close buffer */
|
|
|
+ return (lua_strlen(L, -1) > 0); /* check whether read something */
|
|
|
+ }
|
|
|
+ l = strlen(p);
|
|
|
+ if (p[l-1] != '\n')
|
|
|
+ luaL_addsize(&b, l);
|
|
|
+ else {
|
|
|
+ luaL_addsize(&b, l - 1); /* do not include `eol' */
|
|
|
+ luaL_pushresult(&b); /* close buffer */
|
|
|
+ return 1; /* read at least an `eol' */
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static int read_chars (lua_State *L, FILE *f, size_t n) {
|
|
|
size_t rlen; /* how much to read */
|
|
|
size_t nr; /* number of chars actually read */
|
|
@@ -277,7 +243,7 @@ static int g_read (lua_State *L, FILE *f, int first) {
|
|
|
int success;
|
|
|
int n;
|
|
|
if (nargs == 0) { /* no arguments? */
|
|
|
- success = read_until(L, f, "\n", 1); /* read until \n (a line) */
|
|
|
+ success = read_line(L, f);
|
|
|
n = first+1; /* to return 1 result */
|
|
|
}
|
|
|
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) {
|
|
|
success = read_number(L, f);
|
|
|
break;
|
|
|
case 'l': /* line */
|
|
|
- success = read_until(L, f, "\n", 1); /* read until \n */
|
|
|
+ success = read_line(L, f);
|
|
|
break;
|
|
|
case 'a': /* file */
|
|
|
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) {
|
|
|
case 'w': /* word */
|
|
|
lua_error(L, "obsolete option `*w'");
|
|
|
break;
|
|
|
- case 'u': { /* read until */
|
|
|
- size_t pl = lua_strlen(L, n) - 2;
|
|
|
- luaL_arg_check(L, 0 < pl && pl <= LUA_MAXUNTIL, n,
|
|
|
- "invalid read-until length");
|
|
|
- success = read_until(L, f, p+2, (int)(pl));
|
|
|
- break;
|
|
|
- }
|
|
|
default:
|
|
|
luaL_argerror(L, n, "invalid format");
|
|
|
success = 0; /* to avoid warnings */
|