static const char *match (MatchState *ms, const char *s, const char *p) { init: /* using goto's to optimize tail recursion */ switch (*p) { case '(': { /* start capture */ if (*(p+1) == ')') /* position capture? */ return start_capture(ms, s, p+2, CAP_POSITION); else return start_capture(ms, s, p+1, CAP_UNFINISHED); } case ')': { /* end capture */ return end_capture(ms, s, p+1); } case L_ESC: { switch (*(p+1)) { case 'b': { /* balanced string? */ s = matchbalance(ms, s, p+2); if (s == NULL) return NULL; p+=4; goto init; /* else return match(ms, s, p+4); */ } case 'f': { /* frontier? */ const char *ep; char previous; p += 2; if (*p != '[') luaL_error(ms->L, "missing " LUA_QL("[") " after " LUA_QL("%%f") " in pattern"); ep = classend(ms, p); /* points to what is next */ previous = (s == ms->src_init) ? '\0' : *(s-1); if (matchbracketclass(uchar(previous), p, ep-1) || !matchbracketclass(uchar(*s), p, ep-1)) return NULL; p=ep; goto init; /* else return match(ms, s, ep); */ } default: { if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ s = match_capture(ms, s, uchar(*(p+1))); if (s == NULL) return NULL; p+=2; goto init; /* else return match(ms, s, p+2) */ } goto dflt; /* case default */ } } } case '\0': { /* end of pattern */ return s; /* match succeeded */ } case '$': { if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ return (s == ms->src_end) ? s : NULL; /* check end of string */ else goto dflt; } default: dflt: { /* it is a pattern item */ const char *ep = classend(ms, p); /* points to what is next */ int m = s<ms->src_end && singlematch(uchar(*s), p, ep); switch (*ep) { case '?': { /* optional */ const char *res; if (m && ((res=match(ms, s+1, ep+1)) != NULL)) return res; p=ep+1; goto init; /* else return match(ms, s, ep+1); */ } case '*': { /* 0 or more repetitions */ return max_expand(ms, s, p, ep); } case '+': { /* 1 or more repetitions */ return (m ? max_expand(ms, s+1, p, ep) : NULL); } case '-': { /* 0 or more repetitions (minimum) */ return min_expand(ms, s, p, ep); } default: { if (!m) return NULL; s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ } } } } }
static int str_format (lua_State *L) { int top = lua_gettop(L); int arg = 1; size_t sfl; const char *strfrmt = luaL_checklstring(L, arg, &sfl); const char *strfrmt_end = strfrmt+sfl; luaL_Buffer b; luaL_buffinit(L, &b); while (strfrmt < strfrmt_end) { if (*strfrmt != L_ESC) luaL_addchar(&b, *strfrmt++); else if (*++strfrmt == L_ESC) luaL_addchar(&b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format (`%...') */ char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ int nb = 0; /* number of bytes in added item */ if (++arg > top) luaL_argerror(L, arg, "no value"); strfrmt = scanformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { nb = sprintf(buff, form, luaL_checkint(L, arg)); break; } case 'd': case 'i': { lua_Number n = luaL_checknumber(L, arg); luaL_argcheck(L, (MIN_INTFRM - 1) < n && n < (MAX_INTFRM + 1), arg, "not a number in proper range"); addlenmod(form, LUA_INTFRMLEN); nb = sprintf(buff, form, (LUA_INTFRM_T)n); break; } case 'o': case 'u': case 'x': case 'X': { lua_Number n = luaL_checknumber(L, arg); luaL_argcheck(L, 0 <= n && n < (MAX_UINTFRM + 1), arg, "not a non-negative number in proper range"); addlenmod(form, LUA_INTFRMLEN); nb = sprintf(buff, form, (unsigned LUA_INTFRM_T)n); break; } case 'e': case 'E': case 'f': #if defined(LUA_USE_AFORMAT) case 'a': case 'A': #endif case 'g': case 'G': { addlenmod(form, LUA_FLTFRMLEN); nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg)); break; } case 'q': { addquoted(L, &b, arg); break; } case 's': { size_t l; const char *s = luaL_tolstring(L, arg, &l); if (!strchr(form, '.') && l >= 100) { /* no precision and string is too long to be formatted; keep original string */ luaL_addvalue(&b); break; } else { nb = sprintf(buff, form, s); lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ break; } } default: { /* also treat cases `pnLlh' */ return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " LUA_QL("format"), *(strfrmt - 1)); } } luaL_addsize(&b, nb); } } luaL_pushresult(&b); return 1; }
const char *luaX_token2str (LexState *ls, int token) { if (token < FIRST_RESERVED) { lua_assert(token == cast(unsigned char, token)); return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) : luaO_pushfstring(ls->L, "char(%d)", token); }
static int patch_set(lua_State *L) { return luaL_error(L, LUA_QL("patch_t") " struct cannot be edited by Lua."); }
static const char *match (MatchState *ms, const char *s, const char *p) { if (ms->matchdepth-- == 0) luaL_error(ms->L, "pattern too complex"); init: /* using goto's to optimize tail recursion */ if (p != ms->p_end) { /* end of pattern? */ switch (*p) { case '(': { /* start capture */ if (*(p + 1) == ')') /* position capture? */ s = start_capture(ms, s, p + 2, CAP_POSITION); else s = start_capture(ms, s, p + 1, CAP_UNFINISHED); break; } case ')': { /* end capture */ s = end_capture(ms, s, p + 1); break; } case '$': { if ((p + 1) != ms->p_end) /* is the `$' the last char in pattern? */ goto dflt; /* no; go to default */ s = (s == ms->src_end) ? s : NULL; /* check end of string */ break; } case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ switch (*(p + 1)) { case 'b': { /* balanced string? */ s = matchbalance(ms, s, p + 2); if (s != NULL) { p += 4; goto init; /* return match(ms, s, p + 4); */ } /* else fail (s == NULL) */ break; } case 'f': { /* frontier? */ const char *ep; char previous; p += 2; if (*p != '[') luaL_error(ms->L, "missing " LUA_QL("[") " after " LUA_QL("%%f") " in pattern"); ep = classend(ms, p); /* points to what is next */ previous = (s == ms->src_init) ? '\0' : *(s - 1); if (!matchbracketclass(uchar(previous), p, ep - 1) && matchbracketclass(uchar(*s), p, ep - 1)) { p = ep; goto init; /* return match(ms, s, ep); */ } s = NULL; /* match failed */ break; } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { /* capture results (%0-%9)? */ s = match_capture(ms, s, uchar(*(p + 1))); if (s != NULL) { p += 2; goto init; /* return match(ms, s, p + 2) */ } break; } default: goto dflt; } break; } default: dflt: { /* pattern class plus optional suffix */ const char *ep = classend(ms, p); /* points to optional suffix */ /* does not match at least once? */ if (!singlematch(ms, s, p, ep)) { if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ } else /* '+' or no suffix */ s = NULL; /* fail */ } else { /* matched once */ switch (*ep) { /* handle optional suffix */ case '?': { /* optional */ const char *res; if ((res = match(ms, s + 1, ep + 1)) != NULL) s = res; else { p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ } break; } case '+': /* 1 or more repetitions */ s++; /* 1 match already done */ /* go through */ case '*': /* 0 or more repetitions */ s = max_expand(ms, s, p, ep); break; case '-': /* 0 or more repetitions (minimum) */ s = min_expand(ms, s, p, ep); break; default: /* no suffix */ s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ } } break; } } } ms->matchdepth++; return s; }
static void laction (int i) { signal(i, SIG_DFL); /* if another SIGINT happens before lstop, terminate process (default action) */ lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); } static void print_usage (void) { #if defined(LUA_USE_STDIO) fprintf(stderr, #else luai_writestringerror( #endif "usage: %s [options] [script [args]].\n" "Available options are:\n" " -e stat execute string " LUA_QL("stat") "\n" " -l name require library " LUA_QL("name") "\n" " -m limit set memory limit. (units are in Kbytes)\n" " -i enter interactive mode after executing " LUA_QL("script") "\n" " -v show version information\n" " -- stop handling options\n" " - execute stdin and stop handling options\n" , progname); #if defined(LUA_USE_STDIO) fflush(stderr); #endif } void l_message (const char *pname, const char *msg) {
void LuaConsole::ExecOrContinue() { const std::string stmt = m_entryField->GetText(); int result; lua_State *L = Lua::manager->GetLuaState(); // If the statement is an expression, print its final value. result = luaL_loadbuffer(L, ("return " + stmt).c_str(), stmt.size()+7, CONSOLE_CHUNK_NAME); if (result == LUA_ERRSYNTAX) result = luaL_loadbuffer(L, stmt.c_str(), stmt.size(), CONSOLE_CHUNK_NAME); // check for an incomplete statement // (follows logic from the official Lua interpreter lua.c:incomplete()) if (result == LUA_ERRSYNTAX) { const char eofstring[] = LUA_QL("<eof>"); size_t msglen; const char *msg = lua_tolstring(L, -1, &msglen); if (msglen >= (sizeof(eofstring) - 1)) { const char *tail = msg + msglen - (sizeof(eofstring) - 1); if (strcmp(tail, eofstring) == 0) { // statement is incomplete -- allow the user to continue on the next line m_entryField->SetText(stmt + "\n"); m_entryField->ResizeRequest(); ResizeRequest(); lua_pop(L, 1); return; } } } if (result == LUA_ERRSYNTAX) { size_t msglen; const char *msg = lua_tolstring(L, -1, &msglen); AddOutput(std::string(msg, msglen)); lua_pop(L, 1); return; } if (result == LUA_ERRMEM) { // this will probably fail too, since we've apparently // just had a memory allocation failure... AddOutput("memory allocation failure"); return; } std::istringstream stmt_stream(stmt); std::string string_buffer; std::getline(stmt_stream, string_buffer); AddOutput("> " + string_buffer); while(!stmt_stream.eof()) { std::getline(stmt_stream, string_buffer); AddOutput(" " + string_buffer); } // perform a protected call int top = lua_gettop(L) - 1; // -1 for the chunk itself result = lua_pcall(L, 0, LUA_MULTRET, 0); if (result == LUA_ERRRUN) { size_t len; const char *s = lua_tolstring(L, -1, &len); AddOutput(std::string(s, len)); } else if (result == LUA_ERRERR) { size_t len; const char *s = lua_tolstring(L, -1, &len); AddOutput("error in error handler: " + std::string(s, len)); } else if (result == LUA_ERRMEM) { AddOutput("memory allocation failure"); } else { int nresults = lua_gettop(L) - top; if (nresults) { std::ostringstream ss; // call tostring() on each value and display it lua_getglobal(L, "tostring"); // i starts at 1 because Lua stack uses 1-based indexing for (int i = 1; i <= nresults; ++i) { ss.str(std::string()); if (nresults > 1) ss << "[" << i << "] "; // duplicate the tostring function for the call lua_pushvalue(L, -1); lua_pushvalue(L, top+i); result = lua_pcall(L, 1, 1, 0); size_t len = 0; const char *s = 0; if (result == 0) s = lua_tolstring(L, -1, &len); ss << s ? std::string(s, len) : "<internal error when converting result to string>"; // pop the result lua_pop(L, 1); AddOutput(ss.str()); } } } // pop all return values lua_settop(L, top); // update the history list if (! result) { // command succeeded... add it to the history unless it's just // an exact repeat of the immediate last command if (m_statementHistory.empty() || (stmt != m_statementHistory.back())) m_statementHistory.push_back(stmt); // clear the entry box m_entryField->SetText(""); ResizeRequest(); } // always forget the history position and clear the stashed command m_historyPosition = -1; m_stashedStatement.clear(); }
/** * @brief Handles the CLI input. * * @param wid Window receiving the input. * @param unused Unused. */ static void cli_input( unsigned int wid, char *unused ) { (void) unused; int status; char *str; lua_State *L; char buf[LINE_LENGTH]; /* Get the input. */ str = window_getInput( wid, "inpInput" ); /* Ignore useless stuff. */ if (str == NULL) return; /* Put the message in the console. */ snprintf( buf, LINE_LENGTH, "%s %s", cli_firstline ? "> " : ">>", str ); cli_addMessage( buf ); /* Set up state. */ L = cli_state; /* Set up for concat. */ if (!cli_firstline) /* o */ lua_pushliteral(L, "\n"); /* o \n */ /* Load the string. */ lua_pushstring( L, str ); /* s */ /* Concat. */ if (!cli_firstline) /* o \n s */ lua_concat(L, 3); /* s */ status = luaL_loadbuffer( L, lua_tostring(L,-1), lua_strlen(L,-1), "=cli" ); /* String isn't proper Lua yet. */ if (status == LUA_ERRSYNTAX) { size_t lmsg; const char *msg = lua_tolstring(L, -1, &lmsg); const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1); if (strstr(msg, LUA_QL("<eof>")) == tp) { /* Pop the loaded buffer. */ lua_pop(L, 1); cli_firstline = 0; } else { /* Real error, spew message and break. */ cli_addMessage( lua_tostring(L, -1) ); lua_settop(L, 0); cli_firstline = 1; } } /* Print results - all went well. */ else if (status == 0) { lua_remove(L,1); if (lua_pcall(L, 0, LUA_MULTRET, 0)) { cli_addMessage( lua_tostring(L, -1) ); lua_pop(L,1); } if (lua_gettop(L) > 0) { lua_getglobal(L, "print"); lua_insert(L, 1); if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) cli_addMessage( "Error printing results." ); } /* Clear stack. */ lua_settop(L, 0); cli_firstline = 1; } /* Clear the box now. */ window_setInput( wid, "inpInput", NULL ); }
/* * If the luac command line includes multiple files or has the -f option * then luac generates a main function to reference all sub-main prototypes. * This is one of two types: * Type 0 The standard luac combination main * Type 1 A lookup wrapper that facilitates indexing into the generated protos */ static const Proto* combine(lua_State* L, int n, int type) { if (n==1 && type == 0) return toproto(L,-1); else { int i; Instruction *pc; Proto* f=luaF_newproto(L); setptvalue2s(L,L->top,f); incr_top(L); f->source=luaS_newliteral(L,"=(" PROGNAME ")"); f->p=luaM_newvector(L,n,Proto*); f->sizep=n; for (i=0; i<n; i++) f->p[i]=toproto(L,i-n-1); pc=0; if (type == 0) { /* * Type 0 is as per the standard luac, which is just a main routine which * invokes all of the compiled functions sequentially. This is fine if * they are self registering modules, but useless otherwise. */ f->numparams = 0; f->maxstacksize = 1; f->sizecode = 2*n + 1 ; f->sizek = 0; f->code = luaM_newvector(L, f->sizecode , Instruction); f->k = luaM_newvector(L,f->sizek,TValue); for (i=0, pc = f->code; i<n; i++) { *pc++ = CREATE_ABx(OP_CLOSURE,0,i); *pc++ = CREATE_ABC(OP_CALL,0,1,1); } *pc++ = CREATE_ABC(OP_RETURN,0,1,0); } else { /* * The Type 1 main() is a lookup which takes a single argument, the name to * be resolved. If this matches root name of one of the compiled files then * a closure to this file main is returned. Otherwise the Unixtime of the * compile and the list of root names is returned. */ if (n > LFIELDS_PER_FLUSH) { #define NO_MOD_ERR_(n) ": Number of modules > " #n #define NO_MOD_ERR(n) NO_MOD_ERR_(n) usage(LUA_QL("-f") NO_MOD_ERR(LFIELDS_PER_FLUSH)); } f->numparams = 1; f->maxstacksize = n + 3; f->sizecode = 5*n + 5 ; f->sizek = n + 1; f->sizelocvars = 0; f->code = luaM_newvector(L, f->sizecode , Instruction); f->k = luaM_newvector(L,f->sizek,TValue); for (i=0, pc = f->code; i<n; i++) { /* if arg1 == FnameA then return function (...) -- funcA -- end end */ setsvalue2n(L,f->k+i,corename(L, f->p[i]->source)); *pc++ = CREATE_ABC(OP_EQ,0,0,RKASK(i)); *pc++ = CREATE_ABx(OP_JMP,0,MAXARG_sBx+2); *pc++ = CREATE_ABx(OP_CLOSURE,1,i); *pc++ = CREATE_ABC(OP_RETURN,1,2,0); } setnvalue(f->k+n, (lua_Number) time(NULL)); *pc++ = CREATE_ABx(OP_LOADK,1,n); *pc++ = CREATE_ABC(OP_NEWTABLE,2,luaO_int2fb(i),0); for (i=0; i<n; i++) *pc++ = CREATE_ABx(OP_LOADK,i+3,i); *pc++ = CREATE_ABC(OP_SETLIST,2,i,1); *pc++ = CREATE_ABC(OP_RETURN,1,3,0); *pc++ = CREATE_ABC(OP_RETURN,0,1,0); } lua_assert((pc-f->code) == f->sizecode); return f; } }
static int doargs(int argc, char* argv[]) { int i; int version=0; if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; for (i=1; i<argc; i++) { if (*argv[i]!='-') /* end of options; keep it */ break; else if (IS("--")) /* end of options; skip it */ { ++i; if (version) ++version; break; } else if (IS("-")) /* end of options; use stdin */ break; else if (IS("-l")) /* list */ ++listing; else if (IS("-o")) /* output file */ { output=argv[++i]; if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument"); if (IS("-")) output=NULL; } else if (IS("-p")) /* parse only */ dumping=0; else if (IS("-s")) /* strip debug information */ stripping=1; else if (IS("-v")) /* show version */ ++version; else if (IS("-cci")) /* target integer size */ { int s = target.sizeof_int = atoi(argv[++i])/8; if (!(s==1 || s==2 || s==4)) fatal(LUA_QL("-cci") " must be 8, 16 or 32"); } else if (IS("-ccn")) /* target lua_Number type and size */ { const char *type=argv[++i]; if (strcmp(type,"int")==0) target.lua_Number_integral=1; else if (strcmp(type,"float")==0) target.lua_Number_integral=0; else if (strcmp(type,"float_arm")==0) { target.lua_Number_integral=0; target.is_arm_fpa=1; } else fatal(LUA_QL("-ccn") " type must be " LUA_QL("int") " or " LUA_QL("float") " or " LUA_QL("float_arm")); int s = target.sizeof_lua_Number = atoi(argv[++i])/8; if (target.lua_Number_integral && !(s==1 || s==2 || s==4)) fatal(LUA_QL("-ccn") " size must be 8, 16, or 32 for int"); if (!target.lua_Number_integral && !(s==4 || s==8)) fatal(LUA_QL("-ccn") " size must be 32 or 64 for float"); } else if (IS("-cce")) /* target endianness */ { const char *val=argv[++i]; if (strcmp(val,"big")==0) target.little_endian=0; else if (strcmp(val,"little")==0) target.little_endian=1; else fatal(LUA_QL("-cce") " must be " LUA_QL("big") " or " LUA_QL("little")); } else /* unknown option */ usage(argv[i]); } if (i==argc && (listing || !dumping)) { dumping=0; argv[--i]=Output; } if (version) { printf("%s %s\n",LUA_RELEASE,LUA_COPYRIGHT); if (version==argc-1) exit(EXIT_SUCCESS); } return i; }
int LuaIOLib::io_open(lua_State *lua) { const char *filename = luaL_checkstring(lua, 1); const char *mode = luaL_optstring(lua, 2, "r"); int i = 0; /* check whether 'mode' matches '[rwa]%+?b?' */ auto file_mode = FileHandle::NONE; while (mode[i] != '\0') { auto m = mode[i++]; if (m == 'r') { file_mode |= FileHandle::READ; } else if (m == 'w') { file_mode |= FileHandle::WRITE; } else if (m == 'a') { file_mode |= FileHandle::APPEND; } else if (m == '+') { file_mode |= FileHandle::READ | FileHandle::WRITE; } else { return luaL_error(lua, "invalid mode " LUA_QS " (should match " LUA_QL("[rwa]%%+?b?") ")", mode); } } auto process = proc(lua); auto &info = process->info(); auto &vfs = info.vfs(); FileHandle *handle = nullptr; vfs.open(info.id(), filename, file_mode, handle); if (handle == nullptr) { if ((file_mode & (FileHandle::WRITE | FileHandle::APPEND)) > 0) { if (vfs.create_file(filename) != ReturnCode::SUCCESS) { return luaL_fileresult(lua, 0, filename); } vfs.open(info.id(), filename, file_mode, handle); if (handle == nullptr) { return luaL_fileresult(lua, 0, filename); } } else { return luaL_fileresult(lua, 0, filename); } } auto result = new LuaFile(); result->file(handle); wrap_object(lua, result); return 1; }
void QLuaApplication::Private::ttyInput(QByteArray ba) { // are we in a pause? if (ttyPauseReceived) { ttyPauseReceived = false; theEngine->resume(false); return; } // are we quitting? if (ttyEofReceived) { ttyEofReceived = false; if ((ba[0]=='y' || ba[0]=='Y')) { if (! theApp->close()) acceptInput(true); } else if (ba.size()==0 || ba[0]=='n' || ba[0]=='N') { ttyEofCount = 0; acceptInput(true); } else ttyEndOfFile(); return; } // append to the current input if (! luaInput.size()) { luaInput = ba; if (ba.size() > 0 && ba[0] == '=') luaInput = QByteArray("return ") + (ba.constData() + 1); } else { luaInput += '\n'; luaInput += ba; } // determine if line is complete QtLuaLocker lua(theEngine, 1000); struct lua_State *L = lua; const char *data = luaInput.constData(); int status = (L) ? 0 : 1; if (! status) { status = luaL_loadbuffer(L, data, luaInput.size(), "=stdin"); if (status == LUA_ERRSYNTAX) { size_t lmsg; const char *msg = lua_tolstring(L, -1, &lmsg); const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1); status = (strstr(msg, LUA_QL("<eof>")) == tp); } lua_pop(L, 1); } // action if (status) { theConsole->readLine(luaPrompt2.constData()); } else { QByteArray cmd = luaInput; luaInput.clear(); theConsole->addToHistory(cmd); if (cmd.simplified().isEmpty()) acceptInput(true); else runCommand(cmd, false); } }
static void nlua_thread(int pin, int pout, char *project, char *filename) { char cmd[4096]; int cmd_size; fprintf(stderr, "[err] Starting up Lua interpreter...\n"); fprintf(stdout, "[out] Starting up Lua interpreter...\n"); lua_State *L; L = lua_open(); if (!L) { cmd[0] = LC_ERROR; cmd_size = snprintf(cmd+1, sizeof(cmd)-2, "Unable to open lua") + 1; write(1, cmd, cmd_size); exit(0); } luaL_openlibs(L); lua_sethook(L, nlua_interpret_hook, LUA_MASKLINE, 0); /* If a filename was specified, load it in and run it */ if (project && *project) { char full_filename[2048]; if (filename && *filename) snprintf(full_filename, sizeof(full_filename)-1, "%s/%s/%s", PROJECT_DIR, project, filename); else snprintf(full_filename, sizeof(full_filename)-1, "%s/%s", PROJECT_DIR, project); if (luaL_dofile(L, full_filename)) { cmd[0] = LC_ERROR; cmd_size = snprintf(cmd+1, sizeof(cmd)-2, "Error: %s", lua_tostring(L, 1)) + 1; write(1, cmd, cmd_size); } } /* If no file was specified, enter REPL mode */ else { printf("Entering REPL mode...\n"); int status; while ((status = loadline(L)) != -1) { if (status == 0) status = docall(L, 0, 0); report(L, status); if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ lua_getglobal(L, "print"); lua_insert(L, 1); if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) l_message(progname, lua_pushfstring(L, "error calling " LUA_QL("print") " (%s)", lua_tostring(L, -1))); } } lua_settop(L, 0); fputs("\n", stdout); fflush(stdout); } lua_close(L); close(pin); close(pout); exit(0); return; }
static const char *match(LuaMatchState *ms, const char *s, const char *p) { init: // using goto's to optimize tail recursion if (p == ms->p_end) // end of pattern? return s; // match succeeded switch (*p) { case '(': { // start capture if (*(p+1) == ')') // position capture? return start_capture(ms, s, p+2, CAP_POSITION); else return start_capture(ms, s, p+1, CAP_UNFINISHED); } case ')': { // end capture return end_capture(ms, s, p+1); } case '$': { if ((p+1) == ms->p_end) // is the `$' the last char in pattern? return (s == ms->src_end) ? s : NULL; // check end of string else goto dflt; } case L_ESC: { // escaped sequences not in the format class[*+?-]? switch (*(p+1)) { case 'b': { // balanced string? s = matchbalance(ms, s, p+2); if (s == NULL) return NULL; p+=4; goto init; // else return match(ms, s, p+4); } case 'f': { // frontier? const char *ep; char previous; p += 2; if (*p != '['){ ms->error = "missing " LUA_QL("[") " after " LUA_QL("%%f") " in pattern"; return NULL; } if(!classend(ms, p, &ep)) return NULL; // points to what is next previous = (s == ms->src_init) ? '\0' : *(s-1); if (matchbracketclass(uchar(previous), p, ep-1) || !matchbracketclass(uchar(*s), p, ep-1)) return NULL; p=ep; goto init; // else return match(ms, s, ep); } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { // capture results (%0-%9)? s = match_capture(ms, s, uchar(*(p+1))); if (s == NULL) return NULL; p+=2; goto init; // else return match(ms, s, p+2) } default: goto dflt; } } default: dflt: { // pattern class plus optional suffix const char *ep; int m; if(!classend(ms, p, &ep)) return NULL; // points to what is next m = s < ms->src_end && singlematch(uchar(*s), p, ep); switch (*ep) { case '?': { // optional const char *res; if (m && ((res=match(ms, s+1, ep+1)) != NULL)) return res; p=ep+1; goto init; // else return match(ms, s, ep+1); } case '*': { // 0 or more repetitions return max_expand(ms, s, p, ep); } case '+': { // 1 or more repetitions return (m ? max_expand(ms, s+1, p, ep) : NULL); } case '-': { // 0 or more repetitions (minimum) return min_expand(ms, s, p, ep); } default: { if (!m) return NULL; s++; p=ep; goto init; // else return match(ms, s+1, ep); } } } } }
static int gfind_nodef (lua_State *L) { return luaL_error(L, LUA_QL("string.gfind") " was renamed to " LUA_QL("string.gmatch")); }
static int doargs(int argc, char* argv[]) { int i; int version=0; if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; for (i=1; i<argc; i++) { if (*argv[i]!='-') /* end of options; keep it */ break; else if (IS("--")) /* end of options; skip it */ { ++i; if (version) ++version; break; } else if (IS("-")) /* end of options; use stdin */ break; else if (IS("-e")) /* execute a lua source file file */ { execute=argv[++i]; if (execute ==NULL || *execute==0 || *execute=='-' ) usage(LUA_QL("-e") " needs argument"); } else if (IS("-f")) /* Flash image file */ { flash=lookup=1; } else if (IS("-a")) /* Absolue flash image file */ { flash=lookup=1; address=strtol(argv[++i],NULL,0); size_t offset = (unsigned) (address -IROM0_SEG); if (offset > IROM0_SEGMAX) usage(LUA_QL("-e") " absolute address must be valid flash address"); } else if (IS("-i")) /* lookup */ lookup = 1; else if (IS("-l")) /* list */ ++listing; else if (IS("-m")) /* specify a maximum image size */ { flash=lookup=1; maxSize=strtol(argv[++i],NULL,0); if (maxSize & 0xFFF) usage(LUA_QL("-e") " maximum size must be a multiple of 4,096"); } else if (IS("-o")) /* output file */ { output=argv[++i]; if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument"); if (IS("-")) output=NULL; } else if (IS("-p")) /* parse only */ dumping=0; else if (IS("-s")) /* strip debug information */ stripping=1; else if (IS("-v")) /* show version */ ++version; else /* unknown option */ usage(argv[i]); } if (i==argc && (listing || !dumping)) { dumping=0; argv[--i]=Output; } if (version) { printf("%s %s\n",LUA_RELEASE,LUA_COPYRIGHT); if (version==argc-1) exit(EXIT_SUCCESS); } return i; }
static int str_format (lua_State *L) { int arg = 1; size_t sfl; const char *strfrmt = luaL_checklstring(L, arg, &sfl); const char *strfrmt_end = strfrmt+sfl; luaL_Buffer b; luaL_buffinit(L, &b); while (strfrmt < strfrmt_end) { if (*strfrmt != L_ESC) luaL_addchar(&b, *strfrmt++); else if (*++strfrmt == L_ESC) luaL_addchar(&b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format (`%...') */ char buff[MAX_ITEM]; /* to store the formatted item */ arg++; strfrmt = scanformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { sprintf(buff, form, (int)luaL_checknumber(L, arg)); break; } case 'd': case 'i': { addintlen(form); sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); break; } case 'o': case 'u': case 'x': case 'X': { addintlen(form); sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); break; } case 'e': case 'E': case 'f': case 'g': case 'G': { sprintf(buff, form, (double)luaL_checknumber(L, arg)); break; } case 'q': { addquoted(L, &b, arg); continue; /* skip the 'addsize' at the end */ } case 's': { size_t l; const char *s = luaL_checklstring(L, arg, &l); if (!strchr(form, '.') && l >= 100) { /* no precision and string is too long to be formatted; keep original string */ lua_pushvalue(L, arg); luaL_addvalue(&b); continue; /* skip the `addsize' at the end */ } else { sprintf(buff, form, s); break; } } default: { /* also treat cases `pnLlh' */ return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " LUA_QL("format"), *(strfrmt - 1)); } } luaL_addlstring(&b, buff, strlen(buff)); } } luaL_pushresult(&b); return 1; }
static void simpleexp (LexState *ls, expdesc *v) { /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | constructor | FUNCTION body | primaryexp */ switch (ls->t.token) { case TK_NUMBER: { init_exp(v, VKNUM, 0); v->u.nval = ls->t.seminfo.r; break; } case TK_STRING: { codestring(ls, v, ls->t.seminfo.ts); break; } case TK_NIL: { init_exp(v, VNIL, 0); break; } case TK_TRUE: { init_exp(v, VTRUE, 0); break; } case TK_FALSE: { init_exp(v, VFALSE, 0); break; } case TK_DOTS: { /* vararg */ FuncState *fs = GetCurrentFuncState( ls ); check_condition(ls, fs->f->is_vararg, "cannot use " LUA_QL("...") " outside a vararg function"); fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); break; } case '{': { /* constructor */ constructor(ls, v); return; } case TK_FUNCTION: { luaX_next(ls); body(ls, v, 0, ls->linenumber); return; } default: { primaryexp(ls, v); return; } } luaX_next(ls); }