Browse Source

new options; no more _ALERT; no more getargs

Roberto Ierusalimschy 23 years ago
parent
commit
a960e62c3e
1 changed files with 120 additions and 144 deletions
  1. 120 144
      lua.c

+ 120 - 144
lua.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.c,v 1.93 2002/06/20 20:40:09 roberto Exp roberto $
+** $Id: lua.c,v 1.94 2002/06/26 16:37:39 roberto Exp roberto $
 ** Lua stand-alone interpreter
 ** See Copyright Notice in lua.h
 */
@@ -45,42 +45,62 @@ static lua_State *L = NULL;
 static const char *progname;
 
 
-static lua_Hook old_linehook = NULL;
-static lua_Hook old_callhook = NULL;
+static lua_Hook old_hook = NULL;
+static int old_mask = 0;
 
 
-static void lstop (void) {
-  lua_setlinehook(L, old_linehook);
-  lua_setcallhook(L, old_callhook);
-  luaL_error(L, "interrupted!");
+static void lstop (lua_State *l, lua_Debug *ar) {
+  (void)ar;  /* unused arg. */
+  lua_sethook(l, old_hook, old_mask);
+  luaL_error(l, "interrupted!");
 }
 
 
 static void laction (int i) {
   signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
                               terminate process (default action) */
-  old_linehook = lua_setlinehook(L, (lua_Hook)lstop);
-  old_callhook = lua_setcallhook(L, (lua_Hook)lstop);
+  old_hook = lua_gethook(L);
+  old_mask = lua_gethookmask(L);
+  lua_sethook(L, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT(1));
 }
 
 
-static void report (int status) {
+static void print_usage (void) {
+  fprintf(stderr,
+  "usage: %s [options] [prog [args]].\n"
+  "Available options are:\n"
+  "  -        execute stdin as a file\n"
+  "  -e stat  execute string `stat'\n"
+  "  -i       enter interactive mode after executing `prog'\n"
+  "  -l name  execute file `name'\n"
+  "  -v       print version information\n"
+  "  --       stop handling arguments\n" ,
+  progname);
+}
+
+
+static void l_message (const char *pname, const char *msg) {
+  if (pname) fprintf(stderr, "%s: ", pname);
+  fprintf(stderr, "%s\n", msg);
+}
+
+
+static void report (int status, int traceback) {
+  const char *msg;
   if (status) {
     if (status == LUA_ERRRUN) {
-      if (lua_isstring(L, -2) && lua_isstring(L, -1))
-        lua_concat(L, 2);  /* concat error message and traceback */
-      else
-        lua_remove(L, -2);  /* lease only traceback on stack */
-    }
-    lua_getglobal(L, "_ALERT");
-    if (lua_isfunction(L, -1)) {
-      lua_pushvalue(L, -2);
-      lua_pcall(L, 1, 0);
-    }
-    else {
-      lua_pop(L, 1);
-      fprintf(stderr, "%s", lua_tostring(L, -1));
+      if (!traceback) lua_pop(L, 1);  /* remove traceback */
+      else {
+        if (lua_isstring(L, -2) && lua_isstring(L, -1))
+          lua_concat(L, 2);  /* concat error message and traceback */
+        else
+          lua_remove(L, -2);  /* leave only traceback on stack */
+      }
     }
+    msg = lua_tostring(L, -1);
+    if (msg == NULL) msg = "(no message)";
+    l_message(progname, msg);
+    lua_pop(L, 1);
   }
 }
 
@@ -97,74 +117,36 @@ static int lcall (int clear) {
 }
 
 
-static void print_usage (void) {
-  fprintf(stderr,
-  "usage: %s [options].  Available options are:\n"
-  "  -        execute stdin as a file\n"
-  "  -c       close Lua when exiting\n"
-  "  -e stat  execute string `stat'\n"
-  "  -f name  execute file `name' with remaining arguments in table `arg'\n"
-  "  -i       enter interactive mode\n"
-  "  -v       print version information\n"
-  "  a=b      set global `a' to string `b'\n"
-  "  name     execute file `name'\n",
-  progname);
-}
-
-
 static int l_panic (lua_State *l) {
   (void)l;
-  fputs("unable to recover; exiting\n", stderr);
+  l_message(progname, "unable to recover; exiting");
   return 0;
 }
 
 
 static void print_version (void) {
-  printf("%.80s  %.80s\n", LUA_VERSION, LUA_COPYRIGHT);
+  l_message(NULL, LUA_VERSION "  " LUA_COPYRIGHT);
 }
 
 
-static void assign (const char *arg) {
-  char *eq = strchr(arg, '=');  /* arg is `name=value'; find the `=' */
-  lua_pushlstring(L, arg, eq-arg);  /* push name */
-  lua_pushstring(L, eq+1);  /* push value */
-  lua_settable(L, LUA_GLOBALSINDEX);  /* _G.name = value */
-}
-
-
-static void getargs (char *argv[]) {
+static void getargs (char *argv[], int n) {
   int i;
   lua_newtable(L);
   for (i=0; argv[i]; i++) {
-    /* arg[i] = argv[i] */
-    lua_pushnumber(L, i);
+    lua_pushnumber(L, i - n);
     lua_pushstring(L, argv[i]);
     lua_rawset(L, -3);
   }
   /* arg.n = maximum index in table `arg' */
   lua_pushliteral(L, "n");
-  lua_pushnumber(L, i-1);
+  lua_pushnumber(L, i-n-1);
   lua_rawset(L, -3);
 }
 
 
-static int l_alert (lua_State *l) {
-  if (progname) fprintf(stderr, "%s: ", progname);
-  fprintf(stderr, "%s\n", luaL_check_string(l, 1));
-  return 0;
-}
-
-
-static int l_getargs (lua_State *l) {
-  char **argv = (char **)lua_touserdata(l, lua_upvalueindex(1));
-  getargs(argv);
-  return 1;
-}
-
-
 static int docall (int status) {
   if (status == 0) status = lcall(1);
-  report(status);
+  report(status, 1);
   return status;
 }
 
@@ -258,20 +240,20 @@ static void manual_input (int version) {
   if (version) print_version();
   while ((status = load_string()) != -1) {
     if (status == 0) status = lcall(0);
-    report(status);
+    report(status, 0);
     if (status == 0 && lua_gettop(L) > 0) {  /* any result to print? */
       lua_getglobal(L, "print");
       lua_insert(L, 1);
       lua_pcall(L, lua_gettop(L)-1, 0);
     }
   }
-  printf("\n");
+  fputs("\n", stdout);
   progname = oldprogname;
 }
 
 
-static int handle_argv (char *argv[], int *toclose) {
-  if (*argv == NULL) {  /* no more arguments? */
+static int handle_argv (char *argv[], int *interactive) {
+  if (argv[1] == NULL) {  /* no more arguments? */
     if (isatty(0)) {
       manual_input(1);
     }
@@ -280,85 +262,80 @@ static int handle_argv (char *argv[], int *toclose) {
   }
   else {  /* other arguments; loop over them */
     int i;
-    for (i = 0; argv[i] != NULL; i++) {
-      if (argv[i][0] != '-') {  /* not an option? */
-        if (strchr(argv[i], '='))
-          assign(argv[i]);
-        else
-          if (file_input(argv[i]))
-            return EXIT_FAILURE;  /* stop if file fails */
+    for (i = 1; argv[i] != NULL; i++) {
+      if (argv[i][0] != '-') break;  /* not an option? */
+      switch (argv[i][1]) {  /* option */
+        case '-': {  /* `--' */
+          i++;  /* skip this argument */
+          goto endloop;  /* stop handling arguments */
         }
-        else switch (argv[i][1]) {  /* option */
-          case '\0': {
-            file_input(NULL);  /* executes stdin as a file */
-            break;
-          }
-          case 'i': {
-            manual_input(0);
-            break;
-          }
-          case 'c': {
-            *toclose = 1;
-            break;
-          }
-          case 'v': {
-            print_version();
-            break;
-          }
-          case 'e': {
-            const char *chunk = argv[i] + 2;
-            if (*chunk == '\0') chunk = argv[++i];
-            if (chunk == NULL) {
-              print_usage();
-              return EXIT_FAILURE;
-            }
-            if (dostring(chunk, "=command line") != 0)
-              return EXIT_FAILURE;
-            break;
-          }
-          case 'f': {
-            const char *filename = argv[i] + 2;
-            if (*filename == '\0') filename = argv[++i];
-            if (filename == NULL) {
-              print_usage();
-              return EXIT_FAILURE;
-            }
-            getargs(argv+i);  /* collect remaining arguments */
-            lua_setglobal(L, "arg");
-            return file_input(filename);  /* stop scanning arguments */
-          }
-          case 's': {
-            fprintf(stderr,
-                    "%s: option `-s' is deprecated (dynamic stack now)\n",
-                    progname);
-            break;
+        case '\0': {
+          file_input(NULL);  /* executes stdin as a file */
+          break;
+        }
+        case 'i': {
+          *interactive = 1;
+          break;
+        }
+        case 'v': {
+          print_version();
+          break;
+        }
+        case 'e': {
+          const char *chunk = argv[i] + 2;
+          if (*chunk == '\0') chunk = argv[++i];
+          if (chunk == NULL) {
+            print_usage();
+            return EXIT_FAILURE;
           }
-          default: {
+          if (dostring(chunk, "=<command line>") != 0)
+            return EXIT_FAILURE;
+          break;
+        }
+        case 'l': {
+          const char *filename = argv[i] + 2;
+          if (*filename == '\0') filename = argv[++i];
+          if (filename == NULL) {
             print_usage();
             return EXIT_FAILURE;
           }
+          if (file_input(filename))
+            return EXIT_FAILURE;  /* stop if file fails */
+          break;
+        }
+        case 'c': {
+          l_message(progname, "option `-c' is deprecated");
+          break;
+        }
+        case 's': {
+          l_message(progname, "option `-s' is deprecated");
+          break;
+        }
+        default: {
+          print_usage();
+          return EXIT_FAILURE;
         }
+      }
+    } endloop:
+    if (argv[i] != NULL) {
+      const char *filename = argv[i];
+      getargs(argv, i);  /* collect remaining arguments */
+      lua_setglobal(L, "arg");
+      return file_input(filename);  /* stop scanning arguments */
     }
   }
   return EXIT_SUCCESS;
 }
 
 
-static void register_own (char *argv[]) {
-  lua_pushudataval(L, argv);
-  lua_pushcclosure(L, l_getargs, 1);
-  lua_setglobal(L, "getargs");
-  lua_register(L, "_ALERT", l_alert);
-}
-
-
-static void openstdlibs (lua_State *l) {
-  lua_baselibopen(l);
-  lua_tablibopen(l);
-  lua_iolibopen(l);
-  lua_strlibopen(l);
-  lua_mathlibopen(l);
-  lua_dblibopen(l);
+static int openstdlibs (lua_State *l) {
+  return lua_baselibopen(l) +
+         lua_tablibopen(l) +
+         lua_iolibopen(l) +
+         lua_strlibopen(l) +
+         lua_mathlibopen(l) +
+         lua_dblibopen(l) +
+         0;
 }
 
 
@@ -374,18 +351,17 @@ static int handle_luainit (void) {
 
 int main (int argc, char *argv[]) {
   int status;
-  int toclose = 0;
+  int interactive = 0;
   (void)argc;  /* to avoid warnings */
   progname = argv[0];
   L = lua_open();  /* create state */
   lua_atpanic(L, l_panic);
-  LUA_USERINIT(L);  /* open libraries */
-  register_own(argv);  /* create own function */
+  lua_pop(L, LUA_USERINIT(L));  /* open libraries, dischard any results */
   status = handle_luainit();
   if (status != 0) return status;
-  status = handle_argv(argv+1, &toclose);
-  if (toclose)
-    lua_close(L);
+  status = handle_argv(argv, &interactive);
+  if (status == 0 && interactive) manual_input(0);
+  lua_close(L);
   return status;
 }