diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-04-12 16:56:25 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-04-12 16:56:25 -0300 |
commit | 1ce6cb6032d1a25a91beb101d2b790d273670204 (patch) | |
tree | 6aab68863ad2212410785945c6a2d37e9a23aa77 | |
parent | 11c63bc3aff94a79137e45fd8a1883df465c68d5 (diff) | |
download | lua-1ce6cb6032d1a25a91beb101d2b790d273670204.tar.gz lua-1ce6cb6032d1a25a91beb101d2b790d273670204.tar.bz2 lua-1ce6cb6032d1a25a91beb101d2b790d273670204.zip |
no more option `*u' in read (too complex)
-rw-r--r-- | liolib.c | 91 |
1 files changed, 25 insertions, 66 deletions
@@ -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 | |||
194 | static 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 | |||
207 | static 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 | |||
239 | static int read_number (lua_State *L, FILE *f) { | 183 | static 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 | ||
201 | static 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 | |||
257 | static int read_chars (lua_State *L, FILE *f, size_t n) { | 223 | static 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 */ |