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

libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen