aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-06-02 18:20:54 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1998-06-02 18:20:54 -0300
commitbdb1db4d373b1379d48e60666a00106d50213d6a (patch)
treec8de3548b857f27df888fae5781b4aa76d4e130c
parent02a6891939895129bc968364a5beda73331005e7 (diff)
downloadlua-bdb1db4d373b1379d48e60666a00106d50213d6a.tar.gz
lua-bdb1db4d373b1379d48e60666a00106d50213d6a.tar.bz2
lua-bdb1db4d373b1379d48e60666a00106d50213d6a.zip
"read" more efficient when reading lines and whole files ('.*')
-rw-r--r--liolib.c121
1 files changed, 71 insertions, 50 deletions
diff --git a/liolib.c b/liolib.c
index e963073f..51f24444 100644
--- a/liolib.c
+++ b/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 1.17 1998/03/24 20:14:25 roberto Exp roberto $ 2** $Id: liolib.c,v 1.18 1998/05/20 22:21:35 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,60 +180,81 @@ static void io_appendto (void)
180 180
181#define NEED_OTHER (EOF-1) /* just some flag different from EOF */ 181#define NEED_OTHER (EOF-1) /* just some flag different from EOF */
182 182
183static void io_read (void) 183
184{ 184static void read_until (FILE *f, int lim) {
185 int l = 0;
186 int c;
187 for (c = getc(f); c != EOF && c != lim; c = getc(f)) {
188 luaL_addchar(c);
189 l++;
190 }
191 if (l > 0 || c == lim) /* read anything? */
192 lua_pushlstring(luaL_buffer(), l);
193}
194
195static void io_read (void) {
185 int arg = FIRSTARG; 196 int arg = FIRSTARG;
186 FILE *f = getfileparam(FINPUT, &arg); 197 FILE *f = getfileparam(FINPUT, &arg);
187 int l; 198 char *p = luaL_opt_string(arg, NULL);
188 char *p = luaL_opt_string(arg, "[^\n]*{\n}");
189 int inskip = 0; /* to control {skips} */
190 int c = NEED_OTHER;
191 luaL_resetbuffer(); 199 luaL_resetbuffer();
192 while (*p) { 200 if (p == NULL) /* default: read a line */
193 if (*p == '{') { 201 read_until(f, '\n');
194 inskip++; 202 else if (p[0] == '.' && p[1] == '*' && p[2] == 0) /* p = ".*" */
195 p++; 203 read_until(f, EOF);
196 } 204 else {
197 else if (*p == '}') { 205 int l = 0; /* number of chars read in buffer */
198 if (inskip == 0) 206 int inskip = 0; /* to control {skips} */
199 lua_error("unbalanced braces in read pattern"); 207 int c = NEED_OTHER;
200 inskip--; 208 while (*p) {
201 p++; 209 switch (*p) {
202 } 210 case '{':
203 else { 211 inskip++;
204 char *ep; /* get what is next */ 212 p++;
205 int m; /* match result */ 213 continue;
206 if (c == NEED_OTHER) c = getc(f); 214 case '}':
207 if (c == EOF) { 215 if (inskip == 0)
208 luaI_singlematch(0, p, &ep); /* to set "ep" */ 216 lua_error("unbalanced braces in read pattern");
209 m = 0; 217 inskip--;
210 } 218 p++;
211 else { 219 continue;
212 m = luaI_singlematch(c, p, &ep); 220 default: {
213 if (m) { 221 char *ep; /* get what is next */
214 if (inskip == 0) luaL_addchar(c); 222 int m; /* match result */
215 c = NEED_OTHER; 223 if (c == NEED_OTHER) c = getc(f);
224 if (c == EOF) {
225 luaI_singlematch(0, p, &ep); /* to set "ep" */
226 m = 0;
227 }
228 else {
229 m = luaI_singlematch(c, p, &ep);
230 if (m) {
231 if (inskip == 0) {
232 luaL_addchar(c);
233 l++;
234 }
235 c = NEED_OTHER;
236 }
237 }
238 switch (*ep) {
239 case '*': /* repetition */
240 if (!m) p = ep+1; /* else stay in (repeat) the same item */
241 continue;
242 case '?': /* optional */
243 p = ep+1; /* continues reading the pattern */
244 continue;
245 default:
246 if (m) p = ep; /* continues reading the pattern */
247 else
248 goto break_while; /* pattern fails */
249 }
216 } 250 }
217 } 251 }
218 switch (*ep) { 252 } break_while:
219 case '*': /* repetition */ 253 if (c >= 0) /* not EOF nor NEED_OTHER? */
220 if (!m) p = ep+1; /* else stay in (repeat) the same item */ 254 ungetc(c, f);
221 break; 255 if (l > 0 || *p == 0) /* read something or did not fail? */
222 case '?': /* optional */ 256 lua_pushlstring(luaL_buffer(), l);
223 p = ep+1; /* continues reading the pattern */ 257 }
224 break;
225 default:
226 if (m) p = ep; /* continues reading the pattern */
227 else
228 goto break_while; /* pattern fails */
229 }
230 }
231 } break_while:
232 if (c >= 0) /* not EOF nor NEED_OTHER? */
233 ungetc(c, f);
234 l = luaL_getsize();
235 if (l > 0 || *p == 0) /* read something or did not fail? */
236 lua_pushlstring(luaL_buffer(), l);
237} 258}
238 259
239 260