libFAUDES
Sections
Index
|
luafaudes.cppGo 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