[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: /usr/bin/env and the Lua bytecode format
- From: "Jay Carlson" <nop@...>
- Date: Thu, 2 Aug 2001 16:54:26 -0400
From: "Jay Carlson" <nop@place.org>
> --- ldo.c~ Mon Oct 30 07:38:50 2000
> +++ ldo.c Thu Aug 2 10:37:15 2001
> @@ -266,6 +266,21 @@
> if (f == NULL) return LUA_ERRFILE; /* unable to open file */
> c = fgetc(f);
> ungetc(c, f);
> +
> + if (c == '#') {
> + /* Eat until EOL */
> + while (1) {
> + c = fgetc(f);
> + if (c == EOF || c == '\n') {
> + break;
> + }
> + }
> + if (c != EOF) {
> + c = fgetc(f);
> + ungetc(c, f);
> + }
> + }
> +
> bin = (c == ID_CHUNK);
> if (bin && f != stdin) {
> f = freopen(filename, "rb", f); /* set binary mode */
Uh, I'm an idiot; freopen will rewind the file. The natural thing to do at
this point is to grab the file position with ftell and reseek after the
fopen, but I believe it is not guaranteed to seek to the same point on a
stream in a different ascii/binary mode; consider what happens with wchars.
So really the right thing to do appears to be to eat the chars in ascii
mode, determine the type, then eat them again in binary mode. Strictly
speaking, this code could potentially lose on bizarre character encodings,
but anybody trying to put UCS-2 in a #! line has problems I can't solve.
--- ldo.c.orig Thu Aug 2 16:21:19 2001
+++ ldo.c Thu Aug 2 16:20:15 2001
@@ -256,20 +256,50 @@
return status;
}
+static void skip_first_line_if_hash(FILE *f) {
+ int c = fgetc(f);
+
+ if (c != '#') {
+ if (c != EOF) ungetc(c, f);
+ return;
+ }
+
+ while (1) {
+ c = fgetc(f);
+ switch (c) {
+ case EOF:
+ return;
+ break;
+ case '\n':
+ return;
+ break;
+ case '\r':
+ c = fgetc(f);
+ if (c != '\n' && c != EOF)
+ ungetc(c, f);
+ return;
+ }
+ }
+}
+
+
static int parse_file (lua_State *L, const char *filename) {
ZIO z;
int status;
int bin; /* flag for file mode */
int c; /* look ahead char */
+
FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
if (f == NULL) return LUA_ERRFILE; /* unable to open file */
+ skip_first_line_if_hash(f);
c = fgetc(f);
ungetc(c, f);
bin = (c == ID_CHUNK);
if (bin && f != stdin) {
f = freopen(filename, "rb", f); /* set binary mode */
if (f == NULL) return LUA_ERRFILE; /* unable to reopen file */
+ skip_first_line_if_hash(f);
}
lua_pushstring(L, "@");
lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename);