libFAUDES

Sections

Index

luafaudes.cpp

Go to the documentation of this file.
00001 /** @file luafaudes.cpp Simple Lua stand-alone interpreter for lua/faudes
00002  
00003    This lua interpreter is almost a plain copy of the original lua.c 
00004    provided with the lua 5.1.3 distribution  and under an MIT license;
00005    see original lua.h or http://www.lua.org
00006 
00007    The Advanced-Readline patch has been applied, also with lua license,
00008    copyright see below. Lua swig based bindings and minor adjustments 
00009    (wellcome string, logging) have been added (and signed "luafaudes").
00010    Thomas Moor, 2008.
00011 
00012 
00013 @ingroup Tutorials
00014 
00015 
00016 */
00017 
00018 
00019 // luafaudes: skip doxygen
00020 #ifndef FAUDES_DOXYGEN
00021 
00022 /*
00023 ** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $
00024 ** Lua stand-alone interpreter
00025 ** See Copyright Notice in lua.h
00026 */
00027 
00028 
00029 // luafaudes: include c libs since we dont use lua.h
00030 #include <csignal>
00031 #include <cstdio>
00032 #include <cstdlib>
00033 #include <cstring>
00034 
00035 
00036 // luafaudes: use my include file
00037 #include "libluafaudes.h"
00038 
00039 // below this line: all from lua provided interpreter lua.cpp, except tagged "luafaudes"
00040 
00041 static lua_State *globalL = NULL;
00042 static const char *progname = LUA_PROGNAME;
00043 
00044 
00045 static void lstop (lua_State *L, lua_Debug *ar) {
00046   (void)ar;  /* unused arg. */
00047   lua_sethook(L, NULL, 0, 0);
00048   luaL_error(L, "interrupted!");
00049 }
00050 
00051 
00052 static void laction (int i) {
00053   signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
00054                               terminate process (default action) */
00055   lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
00056 }
00057 
00058 
00059 static void print_usage (void) {
00060   fprintf(stderr,
00061   "usage: %s [options] [script [args]].\n"
00062   "Available options are:\n"
00063   "  -e stat  execute string " LUA_QL("stat") "\n"
00064   "  -l name  require library " LUA_QL("name") "\n"
00065   "  -i       enter interactive mode after executing " LUA_QL("script") "\n"
00066   "  -v       show version information\n"
00067   "  -d       pass on libFAUDES messages to console\n"   /* luafaudes: d-option */
00068   "  --       stop handling options\n"
00069   "  -        execute stdin and stop handling options\n"
00070   ,
00071   progname);
00072   fflush(stderr);
00073 }
00074 
00075 
00076 static void l_message (const char *pname, const char *msg) {
00077   if (pname) fprintf(stderr, "%s: ", pname);
00078   fprintf(stderr, "%s\n", msg);
00079   fflush(stderr);
00080 }
00081 
00082 
00083 static int report (lua_State *L, int status) {
00084   if (status && !lua_isnil(L, -1)) {
00085     const char *msg = lua_tostring(L, -1);
00086     if (msg == NULL) msg = "(error object is not a string)";
00087     l_message(progname, msg);
00088     lua_pop(L, 1);
00089   }
00090   return status;
00091 }
00092 
00093 
00094 static int traceback (lua_State *L) {
00095   if (!lua_isstring(L, 1))  /* 'message' not a string? */
00096     return 1;  /* keep it intact */
00097   lua_getfield(L, LUA_GLOBALSINDEX, "debug");
00098   if (!lua_istable(L, -1)) {
00099     lua_pop(L, 1);
00100     return 1;
00101   }
00102   lua_getfield(L, -1, "traceback");
00103   if (!lua_isfunction(L, -1)) {
00104     lua_pop(L, 2);
00105     return 1;
00106   }
00107   lua_pushvalue(L, 1);  /* pass error message */
00108   lua_pushinteger(L, 2);  /* skip this function and traceback */
00109   lua_call(L, 2, 1);  /* call debug.traceback */
00110   return 1;
00111 }
00112 
00113 
00114 static int docall (lua_State *L, int narg, int clear) {
00115   int status;
00116   int base = lua_gettop(L) - narg;  /* function index */
00117   lua_pushcfunction(L, traceback);  /* push traceback function */
00118   lua_insert(L, base);  /* put it under chunk and args */
00119   signal(SIGINT, laction);
00120   status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
00121   signal(SIGINT, SIG_DFL);
00122   lua_remove(L, base);  /* remove traceback function */
00123   /* force a complete garbage collection in case of errors */
00124   if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
00125   return status;
00126 }
00127 
00128 
00129 // luafaudes: my print version
00130 static void print_version (void) {
00131   std::stringstream sstr;
00132   sstr 
00133     << "Welcome to luafaudes console." << std::endl
00134     << "Versions: " << faudes::FDVersionString() << " / " << faudes::FDPluginsString() 
00135           << " / " << LUA_VERSION << std::endl
00136     << "Credits: This libFAUDES interpreter is based on the projects Lua and SWIG." << std::endl
00137     << "Type 'faudes.Help()' for a list of faudes related types and functions." << std::endl;
00138   l_message(NULL, sstr.str().c_str());
00139 }
00140 
00141 
00142 static int getargs (lua_State *L, char **argv, int n) {
00143   int narg;
00144   int i;
00145   int argc = 0;
00146   while (argv[argc]) argc++;  /* count total number of arguments */
00147   narg = argc - (n + 1);  /* number of arguments to the script */
00148   luaL_checkstack(L, narg + 3, "too many arguments to script");
00149   for (i=n+1; i < argc; i++)
00150     lua_pushstring(L, argv[i]);
00151   lua_createtable(L, narg, n + 1);
00152   for (i=0; i < argc; i++) {
00153     lua_pushstring(L, argv[i]);
00154     lua_rawseti(L, -2, i - n);
00155   }
00156   return narg;
00157 }
00158 
00159 
00160 static int dofile (lua_State *L, const char *name) {
00161   int status = luaL_loadfile(L, name) || docall(L, 0, 1);
00162   return report(L, status);
00163 }
00164 
00165 
00166 static int dostring (lua_State *L, const char *s, const char *name) {
00167   int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
00168   return report(L, status);
00169 }
00170 
00171 
00172 static int dolibrary (lua_State *L, const char *name) {
00173   lua_getglobal(L, "require");
00174   lua_pushstring(L, name);
00175   return report(L, docall(L, 1, 1));
00176 }
00177 
00178 
00179 /* ------------------------------------------------------------------------ */
00180 
00181 #ifdef LUA_USE_READLINE
00182 /*
00183 ** Advanced readline support for the GNU readline and history libraries
00184 ** or compatible replacements.
00185 **
00186 ** Copyright (C) 2004-2006 Mike Pall. Same license as Lua. See lua.h.
00187 **
00188 ** Advanced features:
00189 ** - Completion of keywords and global variable names.
00190 ** - Recursive and metatable-aware completion of variable names.
00191 ** - Context sensitive delimiter completion.
00192 ** - Save/restore of the history to/from a file (LUA_HISTORY env variable).
00193 ** - Setting a limit for the size of the history (LUA_HISTSIZE env variable).
00194 ** - Setting the app name to allow for $if lua ... $endif in ~/.inputrc.
00195 **
00196 ** Start lua and try these (replace ~ with the TAB key):
00197 **
00198 ** ~~
00199 ** fu~foo() ret~fa~end<CR>
00200 ** io~~~s~~~o~~~w~"foo\n")<CR>
00201 **
00202 ** The ~~ are just for demonstration purposes (io~s~o~w~ suffices, of course).
00203 **
00204 ** If you are used to zsh/tcsh-style completion support, try adding
00205 ** 'TAB: menu-complete' and 'C-d: possible-completions' to your ~/.inputrc.
00206 **
00207 ** The patch has been successfully tested with:
00208 **
00209 ** GNU    readline 2.2.1  (1998-07-17)
00210 ** GNU    readline 4.0    (1999-02-18) [harmless compiler warning]
00211 ** GNU    readline 4.3    (2002-07-16)
00212 ** GNU    readline 5.0    (2004-07-27)
00213 ** GNU    readline 5.1    (2005-12-07)
00214 ** NETBSD libedit  2.6.5  (2002-03-25)
00215 ** NETBSD libedit  2.6.9  (2004-05-01)
00216 */
00217 
00218 #include <ctype.h>
00219 
00220 static char *lua_rl_hist;
00221 static int lua_rl_histsize;
00222 
00223 static lua_State *lua_rl_L;  /* User data is not passed to rl callbacks. */
00224 
00225 /* Reserved keywords. */
00226 static const char *const lua_rl_keywords[] = {
00227   "and", "break", "do", "else", "elseif", "end", "false",
00228   "for", "function", "if", "in", "local", "nil", "not", "or",
00229   "repeat", "return", "then", "true", "until", "while", NULL
00230 };
00231 
00232 static int valididentifier(const char *s)
00233 {
00234   if (!(isalpha(*s) || *s == '_')) return 0;
00235   for (s++; *s; s++) if (!(isalpha(*s) || isdigit(*s) || *s == '_')) return 0;
00236   return 1;
00237 }
00238 
00239 /* Dynamically resizable match list. */
00240 typedef struct {
00241   char **list;
00242   size_t idx, allocated, matchlen;
00243 } dmlist;
00244 
00245 /* Add prefix + string + suffix to list and compute common prefix. */
00246 static int lua_rl_dmadd(dmlist *ml, const char *p, size_t pn, const char *s,
00247       int suf)
00248 {
00249   char *t = NULL;
00250 
00251   if (ml->idx+1 >= ml->allocated &&
00252       !(ml->list = (char **) realloc(ml->list, sizeof(char *) * (ml->allocated += 32)))  )
00253     return -1;
00254 
00255   if (s) {
00256     size_t n = strlen(s);
00257     if (!(t = (char *)malloc(sizeof(char)*(pn+n+(suf?2:1))))) return 1;
00258     memcpy(t, p, pn);
00259     memcpy(t+pn, s, n);
00260     n += pn;
00261     t[n] = suf;
00262     if (suf) t[++n] = '\0';
00263 
00264     if (ml->idx == 0) {
00265       ml->matchlen = n;
00266     } else {
00267       size_t i;
00268       for (i = 0; i < ml->matchlen && i < n && ml->list[1][i] == t[i]; i++) ;
00269       ml->matchlen = i;  /* Set matchlen to common prefix. */
00270     }
00271   }
00272 
00273   ml->list[++ml->idx] = t;
00274   return 0;
00275 }
00276 
00277 /* Get __index field of metatable of object on top of stack. */
00278 static int lua_rl_getmetaindex(lua_State *L)
00279 {
00280   if (!lua_getmetatable(L, -1)) { lua_pop(L, 1); return 0; }
00281   lua_pushstring(L, "__index");
00282   lua_rawget(L, -2);
00283   lua_replace(L, -2);
00284   if (lua_isnil(L, -1) || lua_rawequal(L, -1, -2)) { lua_pop(L, 2); return 0; }
00285   lua_replace(L, -2);
00286   return 1;
00287 }  /* 1: obj -- val, 0: obj -- */
00288 
00289 /* Get field from object on top of stack. Avoid calling metamethods. */
00290 static int lua_rl_getfield(lua_State *L, const char *s, size_t n)
00291 {
00292   int i = 20;  /* Avoid infinite metatable loops. */
00293   do {
00294     if (lua_istable(L, -1)) {
00295       lua_pushlstring(L, s, n);
00296       lua_rawget(L, -2);
00297       if (!lua_isnil(L, -1)) { lua_replace(L, -2); return 1; }
00298       lua_pop(L, 1);
00299     }
00300   } while (--i > 0 && lua_rl_getmetaindex(L));
00301   lua_pop(L, 1);
00302   return 0;
00303 }  /* 1: obj -- val, 0: obj -- */
00304 
00305 /* Completion callback. */
00306 static char **lua_rl_complete(const char *text, int start, int end)
00307 {
00308   lua_State *L = lua_rl_L;
00309   dmlist ml;
00310   const char *s;
00311   size_t i, n, dot, loop;
00312   int savetop;
00313 
00314   if (!(text[0] == '\0' || isalpha(text[0]) || text[0] == '_')) return NULL;
00315 
00316   ml.list = NULL;
00317   ml.idx = ml.allocated = ml.matchlen = 0;
00318 
00319   savetop = lua_gettop(L);
00320   lua_pushvalue(L, LUA_GLOBALSINDEX);
00321   for (n = (size_t)(end-start), i = dot = 0; i < n; i++)
00322     if (text[i] == '.' || text[i] == ':') {
00323       if (!lua_rl_getfield(L, text+dot, i-dot))
00324   goto error;  /* Invalid prefix. */
00325       dot = i+1;  /* Points to first char after dot/colon. */
00326     }
00327 
00328   /* Add all matches against keywords if there is no dot/colon. */
00329   if (dot == 0)
00330     for (i = 0; (s = lua_rl_keywords[i]) != NULL; i++)
00331       if (!strncmp(s, text, n) && lua_rl_dmadd(&ml, NULL, 0, s, ' '))
00332   goto error;
00333 
00334   /* Add all valid matches from all tables/metatables. */
00335   loop = 0;  /* Avoid infinite metatable loops. */
00336   do {
00337     if (lua_istable(L, -1) &&
00338   (loop == 0 || !lua_rawequal(L, -1, LUA_GLOBALSINDEX)))
00339       for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1))
00340   if (lua_type(L, -2) == LUA_TSTRING) {
00341     s = lua_tostring(L, -2);
00342     /* Only match names starting with '_' if explicitly requested. */
00343     if (!strncmp(s, text+dot, n-dot) && valididentifier(s) &&
00344         (*s != '_' || text[dot] == '_')) {
00345       int suf = ' ';  /* Default suffix is a space. */
00346       switch (lua_type(L, -1)) {
00347       case LUA_TTABLE:  suf = '.'; break;  /* No way to guess ':'. */
00348       case LUA_TFUNCTION: suf = '('; break;
00349       case LUA_TUSERDATA:
00350         if (lua_getmetatable(L, -1)) { lua_pop(L, 1); suf = ':'; }
00351         break;
00352       }
00353       if (lua_rl_dmadd(&ml, text, dot, s, suf)) goto error;
00354     }
00355   }
00356   } while (++loop < 20 && lua_rl_getmetaindex(L));
00357 
00358   if (ml.idx > 1) {
00359     /* list[0] holds the common prefix of all matches (may be ""). */
00360     if (!(ml.list[0] = (char *)malloc(sizeof(char)*(ml.matchlen+1)))) {
00361 error:
00362       lua_settop(L, savetop);
00363       return NULL;
00364     }
00365     memcpy(ml.list[0], ml.list[1], ml.matchlen);
00366     ml.list[0][ml.matchlen] = '\0';
00367     /* Add the NULL list terminator. */
00368     if (lua_rl_dmadd(&ml, NULL, 0, NULL, 0)) goto error;
00369   } else if (ml.idx == 1) {
00370     ml.list[0] = ml.list[1];  /* Only return common prefix. */
00371     ml.list[1] = NULL;
00372   }
00373 
00374   lua_settop(L, savetop);
00375   return ml.list;
00376 }
00377 
00378 /* Initialize readline library. */
00379 static void lua_rl_init(lua_State *L)
00380 {
00381   char *s;
00382 
00383   lua_rl_L = L;
00384 
00385   /* This allows for $if lua ... $endif in ~/.inputrc. */
00386   rl_readline_name = "lua";
00387   /* Break words at every non-identifier character except '.' and ':'. */
00388   rl_completer_word_break_characters = (char *) 
00389     "\t\r\n !\"#$%&'()*+,-/;<=>?@[\\]^`{|}~"; // luafaudes: pragmatic avoidance of compiler warning
00390 
00391   rl_completer_quote_characters = "\"'";
00392   rl_completion_append_character = '\0';
00393   rl_attempted_completion_function = lua_rl_complete;
00394   rl_initialize();
00395 
00396   /* Start using history, optionally set history size and load history file. */
00397   using_history();
00398   if ((s = getenv("LUA_HISTSIZE")) &&
00399       (lua_rl_histsize = atoi(s))) stifle_history(lua_rl_histsize);
00400   if ((lua_rl_hist = getenv("LUA_HISTORY"))) read_history(lua_rl_hist);
00401 }
00402 
00403 /* Finalize readline library. */
00404 static void lua_rl_exit(lua_State *L)
00405 {
00406   /* Optionally save history file. */
00407   if (lua_rl_hist) write_history(lua_rl_hist);
00408 }
00409 #else
00410 #define lua_rl_init(L)    ((void)L)
00411 #define lua_rl_exit(L)    ((void)L)
00412 #endif
00413 
00414 /* ------------------------------------------------------------------------ */
00415 
00416 
00417 static const char *get_prompt (lua_State *L, int firstline) {
00418   const char *p;
00419   lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2");
00420   p = lua_tostring(L, -1);
00421   if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
00422   lua_pop(L, 1);  /* remove global */
00423   return p;
00424 }
00425 
00426 
00427 static int incomplete (lua_State *L, int status) {
00428   if (status == LUA_ERRSYNTAX) {
00429     size_t lmsg;
00430     const char *msg = lua_tolstring(L, -1, &lmsg);
00431     const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
00432     if (strstr(msg, LUA_QL("<eof>")) == tp) {
00433       lua_pop(L, 1);
00434       return 1;
00435     }
00436   }
00437   return 0;  /* else... */
00438 }
00439 
00440 
00441 static int pushline (lua_State *L, int firstline) {
00442   char buffer[LUA_MAXINPUT];
00443   char *b = buffer;
00444   size_t l;
00445   const char *prmt = get_prompt(L, firstline);
00446   if (lua_readline(L, b, prmt) == 0)
00447     return 0;  /* no input */
00448   l = strlen(b);
00449   luafaudes_lastline=b; // luafaudes: logging
00450   if (l > 0 && b[l-1] == '\n')  /* line ends with newline? */
00451     b[l-1] = '\0';  /* remove it */
00452   if (firstline && b[0] == '=')  /* first line starts with `=' ? */
00453     lua_pushfstring(L, "return %s", b+1);  /* change it to `return' */
00454   else
00455     lua_pushstring(L, b);
00456   lua_freeline(L, b);
00457   return 1;
00458 }
00459 
00460 
00461 static int loadline (lua_State *L) {
00462   int status;
00463   lua_settop(L, 0);
00464   if (!pushline(L, 1))
00465     return -1;  /* no input */
00466   for (;;) {  /* repeat until gets a complete line */
00467     status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
00468     if (!incomplete(L, status)) break;  /* cannot try to add lines? */
00469     if (!pushline(L, 0))  /* no more input? */
00470       return -1;
00471     lua_pushliteral(L, "\n");  /* add a new line... */
00472     lua_insert(L, -2);  /* ...between the two lines */
00473     lua_concat(L, 3);  /* join them */
00474   }
00475   lua_saveline(L, 1);
00476   lua_remove(L, 1);  /* remove line */
00477   return status;
00478 }
00479 
00480 
00481 static void dotty (lua_State *L) {
00482   int status;
00483   const char *oldprogname = progname;
00484   progname = NULL;
00485   lua_rl_init(L);
00486   while ((status = loadline(L)) != -1) {
00487     if (status == 0) status = docall(L, 0, 0);
00488     luafaudes_logwrite(luafaudes_lastline); // luafaudes: logging 
00489     report(L, status);
00490     if (status == 0 && lua_gettop(L) > 0) {  /* any result to print? */
00491       lua_getglobal(L, "print");
00492       lua_insert(L, 1);
00493       if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
00494         l_message(progname, lua_pushfstring(L,
00495                                "error calling " LUA_QL("print") " (%s)",
00496                                lua_tostring(L, -1)));
00497     }
00498   }
00499   lua_settop(L, 0);  /* clear stack */
00500   fputs("\n", stdout);
00501   fflush(stdout);
00502   lua_rl_exit(L);
00503   progname = oldprogname;
00504 }
00505 
00506 static int handle_script (lua_State *L, char **argv, int n) {
00507   int status;
00508   const char *fname;
00509   int narg = getargs(L, argv, n);  /* collect arguments */
00510   lua_setglobal(L, "arg");
00511   fname = argv[n];
00512   if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) 
00513     fname = NULL;  /* stdin */
00514   status = luaL_loadfile(L, fname);
00515   lua_insert(L, -(narg+1));
00516   if (status == 0)
00517     status = docall(L, narg, 0);
00518   else
00519     lua_pop(L, narg);      
00520   return report(L, status);
00521 }
00522 
00523 
00524 /* check that argument has no extra characters at the end */
00525 #define notail(x) {if ((x)[2] != '\0') return -1;}
00526 
00527 
00528 // luafudes: have extra option -d
00529 static int collectargs (char **argv, int *pi, int *pv, int *pe, int *pd) {
00530   int i;
00531   for (i = 1; argv[i] != NULL; i++) {
00532     if (argv[i][0] != '-')  /* not an option? */
00533         return i;
00534     switch (argv[i][1]) {  /* option */
00535       case '-':
00536         notail(argv[i]);
00537         return (argv[i+1] != NULL ? i+1 : 0);
00538       case '\0':
00539         return i;
00540       case 'i':
00541         notail(argv[i]);
00542         *pi = 1;  /* go through */
00543       case 'v':
00544         notail(argv[i]);
00545         *pv = 1;
00546         break;
00547       case 'e':
00548         *pe = 1;  /* go through */
00549       case 'l':
00550         if (argv[i][2] == '\0') {
00551           i++;
00552           if (argv[i] == NULL) return -1;
00553         }
00554         break;
00555       case 'd': // luafaudes: d-option
00556         notail(argv[i]);
00557         *pd = 1;
00558         break;
00559       default: return -1;  /* invalid option */
00560     }
00561   }
00562   return 0;
00563 }
00564 
00565 
00566 static int runargs (lua_State *L, char **argv, int n) {
00567   int i;
00568   for (i = 1; i < n; i++) {
00569     if (argv[i] == NULL) continue;
00570     lua_assert(argv[i][0] == '-');
00571     switch (argv[i][1]) {  /* option */
00572       case 'e': {
00573         const char *chunk = argv[i] + 2;
00574         if (*chunk == '\0') chunk = argv[++i];
00575         lua_assert(chunk != NULL);
00576         if (dostring(L, chunk, "=(command line)") != 0)
00577           return 1;
00578         break;
00579       }
00580       case 'l': {
00581         const char *filename = argv[i] + 2;
00582         if (*filename == '\0') filename = argv[++i];
00583         lua_assert(filename != NULL);
00584         if (dolibrary(L, filename))
00585           return 1;  /* stop if file fails */
00586         break;
00587       }
00588       default: break;
00589     }
00590   }
00591   return 0;
00592 }
00593 
00594 
00595 static int handle_luainit (lua_State *L) {
00596   const char *init = getenv(LUA_INIT);
00597   if (init == NULL) return 0;  /* status OK */
00598   else if (init[0] == '@')
00599     return dofile(L, init+1);
00600   else
00601     return dostring(L, init, "=" LUA_INIT);
00602 }
00603 
00604 
00605 struct Smain {
00606   int argc;
00607   char **argv;
00608   int status;
00609 };
00610 
00611 
00612 static int pmain (lua_State *L) {
00613   struct Smain *s = (struct Smain *)lua_touserdata(L, 1);
00614   char **argv = s->argv;
00615   int script;
00616   int has_i = 0, has_v = 0, has_e = 0, has_d=0; // luafaudes: d-option
00617   globalL = L;
00618   if (argv[0] && argv[0][0]) progname = argv[0];
00619   lua_gc(L, LUA_GCSTOP, 0);  /* stop collector during initialization */
00620   luaL_openlibs(L);  /* open libraries */
00621   luaopen_faudes_allplugins(L); // luafaudes: register
00622   lua_gc(L, LUA_GCRESTART, 0);
00623   s->status = handle_luainit(L);
00624   if (s->status != 0) return 0;
00625   script = collectargs(argv, &has_i, &has_v, &has_e, &has_d); // luafaudes: d-option
00626   if (script < 0) {  /* invalid args? */
00627     print_usage();
00628     s->status = 1;
00629     return 0;
00630   }
00631   if (has_v) print_version(); 
00632   if (!has_d) luafaudes_mute(true); // luafaudes_mute
00633   s->status = runargs(L, argv, (script > 0) ? script : s->argc);
00634   if (s->status != 0) return 0;
00635   if (script)
00636     s->status = handle_script(L, argv, script);
00637   if (s->status != 0) return 0;
00638   if (has_i)
00639     dotty(L);
00640   else if (script == 0 && !has_e && !has_v) {
00641     if (lua_stdin_is_tty()) {
00642       print_version(); 
00643       dotty(L);
00644     }
00645     else dofile(L, NULL);  /* executes stdin as a file */
00646   }
00647   return 0;
00648 }
00649 
00650 
00651 int main (int argc, char **argv) {
00652   int status;
00653   struct Smain s;
00654   lua_State *L = lua_open();  /* create state */
00655   if (L == NULL) {
00656     l_message(argv[0], "cannot create state: not enough memory");
00657     return EXIT_FAILURE;
00658   }
00659   s.argc = argc;
00660   s.argv = argv;
00661   status = lua_cpcall(L, &pmain, &s);
00662   report(L, status);
00663   lua_close(L);
00664   return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
00665 }
00666 
00667 
00668 // luafaudes: end skip doxygen
00669 #endif

libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3