diff options
| -rw-r--r-- | liolib.c | 266 |
1 files changed, 147 insertions, 119 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 1.25 1998/09/07 18:59:59 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 1.26 1998/11/20 15:41:43 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 | */ |
| @@ -20,6 +20,7 @@ | |||
| 20 | #ifndef OLD_ANSI | 20 | #ifndef OLD_ANSI |
| 21 | #include <locale.h> | 21 | #include <locale.h> |
| 22 | #else | 22 | #else |
| 23 | /* no support for locale and for strerror: fake them */ | ||
| 23 | #define setlocale(a,b) 0 | 24 | #define setlocale(a,b) 0 |
| 24 | #define LC_ALL 0 | 25 | #define LC_ALL 0 |
| 25 | #define LC_COLLATE 0 | 26 | #define LC_COLLATE 0 |
| @@ -44,19 +45,19 @@ | |||
| 44 | FILE *popen(); | 45 | FILE *popen(); |
| 45 | int pclose(); | 46 | int pclose(); |
| 46 | #else | 47 | #else |
| 48 | /* no support for popen */ | ||
| 47 | #define popen(x,y) NULL /* that is, popen always fails */ | 49 | #define popen(x,y) NULL /* that is, popen always fails */ |
| 48 | #define pclose(x) (-1) | 50 | #define pclose(x) (-1) |
| 49 | #endif | 51 | #endif |
| 50 | 52 | ||
| 51 | 53 | ||
| 52 | static int gettag (int i) | 54 | |
| 53 | { | 55 | static int gettag (int i) { |
| 54 | return lua_getnumber(lua_getparam(i)); | 56 | return (int)lua_getnumber(lua_getparam(i)); |
| 55 | } | 57 | } |
| 56 | 58 | ||
| 57 | 59 | ||
| 58 | static void pushresult (int i) | 60 | static void pushresult (int i) { |
| 59 | { | ||
| 60 | if (i) | 61 | if (i) |
| 61 | lua_pushuserdata(NULL); | 62 | lua_pushuserdata(NULL); |
| 62 | else { | 63 | else { |
| @@ -67,8 +68,7 @@ static void pushresult (int i) | |||
| 67 | } | 68 | } |
| 68 | 69 | ||
| 69 | 70 | ||
| 70 | static int ishandler (lua_Object f) | 71 | static int ishandler (lua_Object f) { |
| 71 | { | ||
| 72 | if (lua_isuserdata(f)) { | 72 | if (lua_isuserdata(f)) { |
| 73 | if (lua_tag(f) == gettag(CLOSEDTAG)) | 73 | if (lua_tag(f) == gettag(CLOSEDTAG)) |
| 74 | lua_error("cannot access a closed file"); | 74 | lua_error("cannot access a closed file"); |
| @@ -77,8 +77,7 @@ static int ishandler (lua_Object f) | |||
| 77 | else return 0; | 77 | else return 0; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static FILE *getfilebyname (char *name) | 80 | static FILE *getfilebyname (char *name) { |
| 81 | { | ||
| 82 | lua_Object f = lua_getglobal(name); | 81 | lua_Object f = lua_getglobal(name); |
| 83 | if (!ishandler(f)) | 82 | if (!ishandler(f)) |
| 84 | luaL_verror("global variable `%.50s' is not a file handle", name); | 83 | luaL_verror("global variable `%.50s' is not a file handle", name); |
| @@ -112,8 +111,7 @@ static char *getmode (char mode) { | |||
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | 113 | ||
| 115 | static void closefile (char *name) | 114 | static void closefile (char *name) { |
| 116 | { | ||
| 117 | FILE *f = getfilebyname(name); | 115 | FILE *f = getfilebyname(name); |
| 118 | if (f == stdin || f == stdout) return; | 116 | if (f == stdin || f == stdout) return; |
| 119 | if (pclose(f) == -1) | 117 | if (pclose(f) == -1) |
| @@ -123,23 +121,20 @@ static void closefile (char *name) | |||
| 123 | } | 121 | } |
| 124 | 122 | ||
| 125 | 123 | ||
| 126 | static void setfile (FILE *f, char *name, int tag) | 124 | static void setfile (FILE *f, char *name, int tag) { |
| 127 | { | ||
| 128 | lua_pushusertag(f, tag); | 125 | lua_pushusertag(f, tag); |
| 129 | lua_setglobal(name); | 126 | lua_setglobal(name); |
| 130 | } | 127 | } |
| 131 | 128 | ||
| 132 | 129 | ||
| 133 | static void setreturn (FILE *f, char *name) | 130 | static void setreturn (FILE *f, char *name) { |
| 134 | { | ||
| 135 | int tag = gettag(IOTAG); | 131 | int tag = gettag(IOTAG); |
| 136 | setfile(f, name, tag); | 132 | setfile(f, name, tag); |
| 137 | lua_pushusertag(f, tag); | 133 | lua_pushusertag(f, tag); |
| 138 | } | 134 | } |
| 139 | 135 | ||
| 140 | 136 | ||
| 141 | static void io_readfrom (void) | 137 | static void io_readfrom (void) { |
| 142 | { | ||
| 143 | FILE *current; | 138 | FILE *current; |
| 144 | lua_Object f = lua_getparam(FIRSTARG); | 139 | lua_Object f = lua_getparam(FIRSTARG); |
| 145 | if (f == LUA_NOOBJECT) { | 140 | if (f == LUA_NOOBJECT) { |
| @@ -160,8 +155,7 @@ static void io_readfrom (void) | |||
| 160 | } | 155 | } |
| 161 | 156 | ||
| 162 | 157 | ||
| 163 | static void io_writeto (void) | 158 | static void io_writeto (void) { |
| 164 | { | ||
| 165 | FILE *current; | 159 | FILE *current; |
| 166 | lua_Object f = lua_getparam(FIRSTARG); | 160 | lua_Object f = lua_getparam(FIRSTARG); |
| 167 | if (f == LUA_NOOBJECT) { | 161 | if (f == LUA_NOOBJECT) { |
| @@ -182,8 +176,7 @@ static void io_writeto (void) | |||
| 182 | } | 176 | } |
| 183 | 177 | ||
| 184 | 178 | ||
| 185 | static void io_appendto (void) | 179 | static void io_appendto (void) { |
| 186 | { | ||
| 187 | char *s = luaL_check_string(FIRSTARG); | 180 | char *s = luaL_check_string(FIRSTARG); |
| 188 | FILE *fp = fopen (s, getmode('a')); | 181 | FILE *fp = fopen (s, getmode('a')); |
| 189 | if (fp != NULL) | 182 | if (fp != NULL) |
| @@ -193,90 +186,133 @@ static void io_appendto (void) | |||
| 193 | } | 186 | } |
| 194 | 187 | ||
| 195 | 188 | ||
| 196 | #define NEED_OTHER (EOF-1) /* just some flag different from EOF */ | ||
| 197 | 189 | ||
| 190 | /*==================================================== | ||
| 191 | ** READ | ||
| 192 | **===================================================*/ | ||
| 193 | |||
| 194 | static int read_pattern (FILE *f, char *p) { | ||
| 195 | int inskip = 0; /* {skip} level */ | ||
| 196 | int c = getc(f); | ||
| 197 | while (*p != '\0') { | ||
| 198 | switch (*p) { | ||
| 199 | case '{': | ||
| 200 | inskip++; | ||
| 201 | p++; | ||
| 202 | continue; | ||
| 203 | case '}': | ||
| 204 | if (!inskip) lua_error("unbalanced braces in read pattern"); | ||
| 205 | inskip--; | ||
| 206 | p++; | ||
| 207 | continue; | ||
| 208 | default: { | ||
| 209 | char *ep; /* get what is next */ | ||
| 210 | int m; /* match result */ | ||
| 211 | if (c != EOF) | ||
| 212 | m = luaI_singlematch(c, p, &ep); | ||
| 213 | else { | ||
| 214 | luaI_singlematch(0, p, &ep); /* to set "ep" */ | ||
| 215 | m = 0; /* EOF matches no pattern */ | ||
| 216 | } | ||
| 217 | if (m) { | ||
| 218 | if (!inskip) luaL_addchar(c); | ||
| 219 | c = getc(f); | ||
| 220 | } | ||
| 221 | switch (*ep) { | ||
| 222 | case '*': /* repetition */ | ||
| 223 | if (!m) p = ep+1; /* else stay in (repeat) the same item */ | ||
| 224 | continue; | ||
| 225 | case '?': /* optional */ | ||
| 226 | p = ep+1; /* continues reading the pattern */ | ||
| 227 | continue; | ||
| 228 | default: | ||
| 229 | if (!m) { /* pattern fails? */ | ||
| 230 | ungetc(c, f); | ||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | p = ep; /* continues reading the pattern */ | ||
| 234 | } | ||
| 235 | } | ||
| 236 | } | ||
| 237 | } | ||
| 238 | ungetc(c, f); | ||
| 239 | return 1; | ||
| 240 | } | ||
| 198 | 241 | ||
| 199 | static void read_until (FILE *f, int lim) { | 242 | |
| 200 | int l = 0; | 243 | static int read_number (FILE *f) { |
| 201 | int c; | 244 | double d; |
| 202 | for (c = getc(f); c != EOF && c != lim; c = getc(f)) { | 245 | if (fscanf(f, "%lf", &d) == 1) { |
| 203 | luaL_addchar(c); | 246 | lua_pushnumber(d); |
| 204 | l++; | 247 | return 1; |
| 205 | } | 248 | } |
| 206 | if (l > 0 || c == lim) /* read anything? */ | 249 | else return 0; /* read fails */ |
| 207 | lua_pushlstring(luaL_buffer(), l); | ||
| 208 | else | ||
| 209 | lua_pushnil(); | ||
| 210 | } | 250 | } |
| 211 | 251 | ||
| 252 | |||
| 253 | #define HUNK_LINE 1024 | ||
| 254 | #define HUNK_FILE BUFSIZ | ||
| 255 | |||
| 256 | static int read_line (FILE *f) { | ||
| 257 | /* equivalent to: return read_pattern(f, "[^\n]*{\n}"); */ | ||
| 258 | int n; | ||
| 259 | char *b; | ||
| 260 | do { | ||
| 261 | b = luaL_openspace(HUNK_LINE); | ||
| 262 | if (!fgets(b, HUNK_LINE, f)) return 0; /* read fails */ | ||
| 263 | n = strlen(b); | ||
| 264 | luaL_addsize(n); | ||
| 265 | } while (b[n-1] != '\n'); | ||
| 266 | luaL_addsize(-1); /* remove '\n' */ | ||
| 267 | return 1; | ||
| 268 | } | ||
| 269 | |||
| 270 | |||
| 271 | static void read_file (FILE *f) { | ||
| 272 | /* equivalent to: return read_pattern(f, ".*"); */ | ||
| 273 | int n; | ||
| 274 | do { | ||
| 275 | char *b = luaL_openspace(HUNK_FILE); | ||
| 276 | n = fread(b, sizeof(char), HUNK_FILE, f); | ||
| 277 | luaL_addsize(n); | ||
| 278 | } while (n==HUNK_FILE); | ||
| 279 | } | ||
| 280 | |||
| 281 | |||
| 212 | static void io_read (void) { | 282 | static void io_read (void) { |
| 283 | static char *options[] = {"*n", "*l", "*a", ".*", "*w", NULL}; | ||
| 213 | int arg = FIRSTARG; | 284 | int arg = FIRSTARG; |
| 214 | FILE *f = getfileparam(FINPUT, &arg); | 285 | FILE *f = getfileparam(FINPUT, &arg); |
| 215 | char *p = luaL_opt_string(arg, NULL); | 286 | char *p = luaL_opt_string(arg++, "*l"); |
| 216 | luaL_resetbuffer(); | 287 | do { /* repeat for each part */ |
| 217 | if (p == NULL) /* default: read a line */ | 288 | long l; |
| 218 | read_until(f, '\n'); | 289 | int success; |
| 219 | else if (strcmp(p, ".*") == 0) | 290 | luaL_resetbuffer(); |
| 220 | read_until(f, EOF); | 291 | switch (luaL_findstring(p, options)) { |
| 221 | else { | 292 | case 0: /* number */ |
| 222 | int l = 0; /* number of chars read in buffer */ | 293 | if (!read_number(f)) return; /* read fails */ |
| 223 | int inskip = 0; /* to control {skips} */ | 294 | continue; /* number is already pushed; avoid the "pushstring" */ |
| 224 | int c = NEED_OTHER; | 295 | case 1: /* line */ |
| 225 | while (*p) { | 296 | success = read_line(f); |
| 226 | switch (*p) { | 297 | break; |
| 227 | case '{': | 298 | case 2: case 3: /* file */ |
| 228 | inskip++; | 299 | read_file(f); |
| 229 | p++; | 300 | success = 1; /* always success */ |
| 230 | continue; | 301 | break; |
| 231 | case '}': | 302 | case 4: /* word */ |
| 232 | if (inskip == 0) | 303 | success = read_pattern(f, "{%s*}%S%S*"); |
| 233 | lua_error("unbalanced braces in read pattern"); | 304 | break; |
| 234 | inskip--; | 305 | default: |
| 235 | p++; | 306 | success = read_pattern(f, p); |
| 236 | continue; | 307 | } |
| 237 | default: { | 308 | l = luaL_getsize(); |
| 238 | char *ep; /* get what is next */ | 309 | if (!success && l==0) return; /* read fails */ |
| 239 | int m; /* match result */ | 310 | lua_pushlstring(luaL_buffer(), l); |
| 240 | if (c == NEED_OTHER) c = getc(f); | 311 | } while ((p = luaL_opt_string(arg++, NULL))); |
| 241 | if (c == EOF) { | ||
| 242 | luaI_singlematch(0, p, &ep); /* to set "ep" */ | ||
| 243 | m = 0; | ||
| 244 | } | ||
| 245 | else { | ||
| 246 | m = luaI_singlematch(c, p, &ep); | ||
| 247 | if (m) { | ||
| 248 | if (inskip == 0) { | ||
| 249 | luaL_addchar(c); | ||
| 250 | l++; | ||
| 251 | } | ||
| 252 | c = NEED_OTHER; | ||
| 253 | } | ||
| 254 | } | ||
| 255 | switch (*ep) { | ||
| 256 | case '*': /* repetition */ | ||
| 257 | if (!m) p = ep+1; /* else stay in (repeat) the same item */ | ||
| 258 | continue; | ||
| 259 | case '?': /* optional */ | ||
| 260 | p = ep+1; /* continues reading the pattern */ | ||
| 261 | continue; | ||
| 262 | default: | ||
| 263 | if (m) p = ep; /* continues reading the pattern */ | ||
| 264 | else | ||
| 265 | goto break_while; /* pattern fails */ | ||
| 266 | } | ||
| 267 | } | ||
| 268 | } | ||
| 269 | } break_while: | ||
| 270 | if (c >= 0) /* not EOF nor NEED_OTHER? */ | ||
| 271 | ungetc(c, f); | ||
| 272 | if (l > 0 || *p == 0) /* read something or did not fail? */ | ||
| 273 | lua_pushlstring(luaL_buffer(), l); | ||
| 274 | } | ||
| 275 | } | 312 | } |
| 276 | 313 | ||
| 277 | 314 | ||
| 278 | static void io_write (void) | 315 | static void io_write (void) { |
| 279 | { | ||
| 280 | int arg = FIRSTARG; | 316 | int arg = FIRSTARG; |
| 281 | FILE *f = getfileparam(FOUTPUT, &arg); | 317 | FILE *f = getfileparam(FOUTPUT, &arg); |
| 282 | int status = 1; | 318 | int status = 1; |
| @@ -312,34 +348,29 @@ static void io_flush (void) { | |||
| 312 | } | 348 | } |
| 313 | 349 | ||
| 314 | 350 | ||
| 315 | static void io_execute (void) | 351 | static void io_execute (void) { |
| 316 | { | ||
| 317 | lua_pushnumber(system(luaL_check_string(1))); | 352 | lua_pushnumber(system(luaL_check_string(1))); |
| 318 | } | 353 | } |
| 319 | 354 | ||
| 320 | 355 | ||
| 321 | static void io_remove (void) | 356 | static void io_remove (void) { |
| 322 | { | ||
| 323 | pushresult(remove(luaL_check_string(1)) == 0); | 357 | pushresult(remove(luaL_check_string(1)) == 0); |
| 324 | } | 358 | } |
| 325 | 359 | ||
| 326 | 360 | ||
| 327 | static void io_rename (void) | 361 | static void io_rename (void) { |
| 328 | { | ||
| 329 | pushresult(rename(luaL_check_string(1), | 362 | pushresult(rename(luaL_check_string(1), |
| 330 | luaL_check_string(2)) == 0); | 363 | luaL_check_string(2)) == 0); |
| 331 | } | 364 | } |
| 332 | 365 | ||
| 333 | 366 | ||
| 334 | static void io_tmpname (void) | 367 | static void io_tmpname (void) { |
| 335 | { | ||
| 336 | lua_pushstring(tmpnam(NULL)); | 368 | lua_pushstring(tmpnam(NULL)); |
| 337 | } | 369 | } |
| 338 | 370 | ||
| 339 | 371 | ||
| 340 | 372 | ||
| 341 | static void io_getenv (void) | 373 | static void io_getenv (void) { |
| 342 | { | ||
| 343 | lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */ | 374 | lua_pushstring(getenv(luaL_check_string(1))); /* if NULL push nil */ |
| 344 | } | 375 | } |
| 345 | 376 | ||
| @@ -349,12 +380,11 @@ static void io_clock (void) { | |||
| 349 | } | 380 | } |
| 350 | 381 | ||
| 351 | 382 | ||
| 352 | static void io_date (void) | 383 | static void io_date (void) { |
| 353 | { | 384 | char b[256]; |
| 354 | time_t t; | ||
| 355 | struct tm *tm; | ||
| 356 | char *s = luaL_opt_string(1, "%c"); | 385 | char *s = luaL_opt_string(1, "%c"); |
| 357 | char b[BUFSIZ]; | 386 | struct tm *tm; |
| 387 | time_t t; | ||
| 358 | time(&t); tm = localtime(&t); | 388 | time(&t); tm = localtime(&t); |
| 359 | if (strftime(b,sizeof(b),s,tm)) | 389 | if (strftime(b,sizeof(b),s,tm)) |
| 360 | lua_pushstring(b); | 390 | lua_pushstring(b); |
| @@ -363,8 +393,7 @@ static void io_date (void) | |||
| 363 | } | 393 | } |
| 364 | 394 | ||
| 365 | 395 | ||
| 366 | static void setloc (void) | 396 | static void setloc (void) { |
| 367 | { | ||
| 368 | static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, | 397 | static int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, |
| 369 | LC_TIME}; | 398 | LC_TIME}; |
| 370 | static char *catnames[] = {"all", "collate", "ctype", "monetary", | 399 | static char *catnames[] = {"all", "collate", "ctype", "monetary", |
| @@ -375,16 +404,14 @@ static void setloc (void) | |||
| 375 | } | 404 | } |
| 376 | 405 | ||
| 377 | 406 | ||
| 378 | static void io_exit (void) | 407 | static void io_exit (void) { |
| 379 | { | ||
| 380 | lua_Object o = lua_getparam(1); | 408 | lua_Object o = lua_getparam(1); |
| 381 | exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1); | 409 | exit(lua_isnumber(o) ? (int)lua_getnumber(o) : 1); |
| 382 | } | 410 | } |
| 383 | 411 | ||
| 384 | 412 | ||
| 385 | static void io_debug (void) | 413 | static void io_debug (void) { |
| 386 | { | 414 | for (;;) { |
| 387 | while (1) { | ||
| 388 | char buffer[250]; | 415 | char buffer[250]; |
| 389 | fprintf(stderr, "lua_debug> "); | 416 | fprintf(stderr, "lua_debug> "); |
| 390 | if (fgets(buffer, sizeof(buffer), stdin) == 0) return; | 417 | if (fgets(buffer, sizeof(buffer), stdin) == 0) return; |
| @@ -394,6 +421,7 @@ static void io_debug (void) | |||
| 394 | } | 421 | } |
| 395 | 422 | ||
| 396 | 423 | ||
| 424 | |||
| 397 | #define MESSAGESIZE 150 | 425 | #define MESSAGESIZE 150 |
| 398 | #define MAXMESSAGE (MESSAGESIZE*10) | 426 | #define MAXMESSAGE (MESSAGESIZE*10) |
| 399 | 427 | ||
| @@ -467,8 +495,7 @@ static struct luaL_reg iolibtag[] = { | |||
| 467 | {"write", io_write} | 495 | {"write", io_write} |
| 468 | }; | 496 | }; |
| 469 | 497 | ||
| 470 | static void openwithtags (void) | 498 | static void openwithtags (void) { |
| 471 | { | ||
| 472 | int iotag = lua_newtag(); | 499 | int iotag = lua_newtag(); |
| 473 | int closedtag = lua_newtag(); | 500 | int closedtag = lua_newtag(); |
| 474 | int i; | 501 | int i; |
| @@ -490,3 +517,4 @@ void lua_iolibopen (void) { | |||
| 490 | luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); | 517 | luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); |
| 491 | openwithtags(); | 518 | openwithtags(); |
| 492 | } | 519 | } |
| 520 | |||
