浏览代码

no more option `*u' in read (too complex)

Roberto Ierusalimschy 23 年之前
父节点
当前提交
1ce6cb6032
共有 1 个文件被更改,包括 25 次插入66 次删除
  1. 25 66
      liolib.c

+ 25 - 66
liolib.c

@@ -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 */