static int loadline (lua_State *L) { int status; lua_settop(L, 0); if (!pushline(L, 1)) return -1; /* no input */ for (;;) { /* repeat until gets a complete line */ status = terra_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "stdin"); if (!incomplete(L, status)) break; /* cannot try to add lines? */ if (!pushline(L, 0)) /* no more input? */ return -1; lua_pushliteral(L, "\n"); /* add a new line... */ lua_insert(L, -2); /* ...between the two lines */ lua_concat(L, 3); /* join them */ } lua_saveline(L, 1); lua_remove(L, 1); /* remove line */ return status; }
/* ====================================================================== */ static int lzlib_crc32(lua_State *L) { if (lua_gettop(L) == 0) { /* crc32 initial value */ lua_pushnumber(L, crc32(0L, Z_NULL, 0)); } else { /* update crc32 checksum */ int crc = luaL_checkint(L, 1); const unsigned char* buf = (unsigned char*)luaL_checkstring(L, 2); int len = lua_strlen(L, 2); lua_pushnumber(L, crc32(crc, buf, len)); } return 1; }
static int l_usb_interrupt_write(lua_State *L) { struct usb_dev_handle * dev_handle = lua_touserdata(L, 1); int ep = lua_tonumber(L, 2); const char *bytes = lua_tostring (L, 3); int size = lua_strlen (L, 3); int timeout = lua_tonumber (L, 4); int ret = usb_interrupt_write(dev_handle, ep, (char*)bytes, size, timeout); if( ret < 0 ) { lua_pushnil (L); lua_pushnumber (L, ret); return 2; /* number of results */ } else{ lua_pushnumber (L, ret); return 1; /* number of results */ } }
bool ConfigManager::getGlobalBoolean(lua_State* L, const char* identifier, const bool defaultValue) { lua_getglobal(L, identifier); if (!lua_isboolean(L, -1)) { if (!lua_isstring(L, -1)) { return defaultValue; } size_t len = lua_strlen(L, -1); std::string ret(lua_tostring(L, -1), len); lua_pop(L, 1); return booleanString(ret); } int val = lua_toboolean(L, -1); lua_pop(L, 1); return val != 0; }
/* Based on lua.c */ static void _rpmluaInteractive(lua_State *L) /*@globals fileSystem @*/ /*@modifies L, fileSystem @*/ { (void) fputs("\n", stdout); printf("RPM Interactive %s Interpreter\n", LUA_VERSION); for (;;) { int rc = 0; if (rpmluaReadline(L, "> ") == 0) break; if (lua_tostring(L, -1)[0] == '=') { /*@-evalorder@*/ (void) lua_pushfstring(L, "print(%s)", lua_tostring(L, -1)+1); /*@=evalorder@*/ lua_remove(L, -2); } for (;;) { /*@-evalorder@*/ rc = luaL_loadbuffer(L, lua_tostring(L, -1), lua_strlen(L, -1), "<lua>"); /*@=evalorder@*/ if (rc == LUA_ERRSYNTAX && strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) { if (rpmluaReadline(L, ">> ") == 0) /*@innerbreak@*/ break; lua_remove(L, -2); /* Remove error */ lua_concat(L, 2); /*@innercontinue@*/ continue; } /*@innerbreak@*/ break; } if (rc == 0) rc = lua_pcall(L, 0, 0, 0); if (rc != 0) { /*@-evalorderuncon@*/ fprintf(stderr, "%s\n", lua_tostring(L, -1)); /*@=evalorderuncon@*/ lua_pop(L, 1); } lua_pop(L, 1); /* Remove line */ } (void) fputs("\n", stdout); }
static int read_chars(lua_State *L, FILE *f, size_t n) { size_t rlen; size_t nr; luaL_Buffer b; luaL_buffinit(L, &b); rlen = LUAL_BUFFERSIZE; do { char *p = luaL_prepbuffer(&b); if (rlen > n) rlen = n; nr = fread(p, sizeof(char), rlen, f); luaL_addsize(&b, nr); n -= nr; } while (n > 0 && nr == rlen); luaL_pushresult(&b); return (n == 0 || lua_strlen(L, -1) > 0); }
int LuaFonts::GetTextHeight(lua_State* L) { CglFont* font = tofont(L, 1); const int args = lua_gettop(L); // number of arguments if ((args < 2) || !lua_isstring(L, 2)) { luaL_error(L, "Incorrect arguments to font:GetTextHeight(\"text\")"); } const string text(lua_tostring(L, 2),lua_strlen(L, 2)); float descender; int lines; const float height = font->GetTextHeight(text,&descender,&lines); lua_pushnumber(L, height); lua_pushnumber(L, descender); lua_pushnumber(L, lines); return 3; }
int LuaFonts::Print(lua_State* L) { CheckDrawingEnabled(L, __FUNCTION__); const int args = lua_gettop(L); // number of arguments CglFont* font = tofont(L, 1); const string text(luaL_checkstring(L, 2),lua_strlen(L, 2)); const float x = luaL_checkfloat(L, 3); const float y = luaL_checkfloat(L, 4); const float size = luaL_optfloat(L, 5, font->GetSize()); int options = FONT_NEAREST; if ((args >= 6) && lua_isstring(L, 6)) { const char* c = lua_tostring(L, 6); while (*c != 0) { switch (*c) { case 'c': { options |= FONT_CENTER; break; } case 'r': { options |= FONT_RIGHT; break; } case 'a': { options |= FONT_ASCENDER; break; } case 't': { options |= FONT_TOP; break; } case 'v': { options |= FONT_VCENTER; break; } case 'x': { options |= FONT_BASELINE; break; } case 'b': { options |= FONT_BOTTOM; break; } case 'd': { options |= FONT_DESCENDER; break; } case 's': { options |= FONT_SHADOW; break; } case 'o': case 'O': { options |= FONT_OUTLINE; break; } case 'n': { options ^= FONT_NEAREST; break; } } c++; } } font->glPrint(x, y, size, options, text); return 0; }
int if2_lua_scanner::verify_received_data(lua_State *L) { if2_lua_scanner *o=get_this(L); const char *client_address; const char *url; const char *data; int data_len; data = lua_tostring(L,-1); data_len = lua_strlen(L,-1); lua_pop(L,1); url = lua_tostring(L,-1); lua_pop(L,1); client_address = lua_tostring(L,-1); lua_pop(L,1); int r=o->k.verify_received_data(client_address,url,data,data_len); jdk_lua_push(L,r); return 1; }
static int luaB_tostring (lua_State *L) { luaL_checkany(L, 1); if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ return 1; /* use its value */ switch (lua_type(L, 1)) { case LUA_TNUMBER: lua_pushstring(L, lua_tostring(L, 1)); break; case LUA_TSTRING: lua_pushvalue(L, 1); break; case LUA_TWSTRING: { luaL_Buffer b; size_t l; size_t i; const lua_WChar *s = lua_towstring(L, 1); l = lua_strlen(L, 1); if (l == 0) { lua_pushstring(L, ""); } else { luaL_buffinit(L, &b); for (i=0; i<l; i++) luaL_putchar(&b, (unsigned char)(s[i])); luaL_pushresult(&b); } return 1; } case LUA_TBOOLEAN: lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); break; case LUA_TNIL: lua_pushliteral(L, "nil"); break; default: lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); break; } return 1; }
static int digest_fdigest(lua_State *L) { const char *type_name = luaL_checkstring(L, 2); const EVP_MD *type = EVP_get_digestbyname(type_name); const char *s = luaL_checkstring(L, 3); unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int written = 0; EVP_MD_CTX *c; if (type == NULL) { luaL_argerror(L, 1, "invalid digest type"); return 0; } c = EVP_MD_CTX_create(); if (!EVP_DigestInit_ex(c, type, NULL)) { EVP_MD_CTX_destroy(c); return crypto_error(L); } if (!EVP_DigestUpdate(c, s, lua_strlen(L, 3))) { EVP_MD_CTX_destroy(c); return crypto_error(L); } if (!EVP_DigestFinal_ex(c, digest, &written)) { EVP_MD_CTX_destroy(c); return crypto_error(L); } EVP_MD_CTX_destroy(c); if (lua_toboolean(L, 4)) lua_pushlstring(L, (char *)digest, written); else { char *hex = (char*)calloc(sizeof(char), written*2 + 1); unsigned int i; for (i = 0; i < written; i++) sprintf(hex + 2*i, "%02x", digest[i]); lua_pushlstring(L, hex, written*2); free(hex); } return 1; }
static int read_line (lua_State *L, FILE *f) { luaL_Buffer b; luaL_buffinit(L, &b); for (;;) { size_t l; char *p = luaL_prepbuffer(&b); if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ luaL_pushresult(&b); /* close buffer */ return (lua_strlen(L, -1) > 0); /* check whether read something */ } l = strlen(p); if (l == 0 || p[l-1] != '\n') luaL_addsize(&b, l); else { luaL_addsize(&b, l - 1); /* do not include `eol' */ luaL_pushresult(&b); /* close buffer */ return 1; /* read at least an `eol' */ } } }
int LuaFonts::WrapText(lua_State* L) { CglFont* font = tofont(L, 1); const int args = lua_gettop(L); // number of arguments if ((args < 3) || !lua_isstring(L, 2) || !lua_isnumber(L, 3)) { luaL_error(L, "Incorrect arguments to font:WrapText(\"text\", maxWidth, [maxHeight], [size])"); } string text(lua_tostring(L, 2),lua_strlen(L, 2)); const float maxWidth = lua_tonumber(L, 3); const float maxHeight = luaL_optfloat(L, 4, 1e9); const float size = luaL_optfloat(L, 5, font->GetSize()); const int lines = font->WrapInPlace(text,size,maxWidth,maxHeight); lua_pushlstring(L, text.c_str(), text.length()); lua_pushnumber(L, lines); return 2; }
static int read_chars (lua_State *L, ZZIP_FILE *f, size_t n) { size_t rlen; /* how much to read */ size_t nr; /* number of chars actually read */ luaL_Buffer b; luaL_buffinit(L, &b); rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ do { char *p = luaL_prepbuffer(&b); if (rlen > n) rlen = n; /* cannot read more than asked */ nr = zzip_fread(p, sizeof(char), rlen, f); luaL_addsize(&b, nr); n -= nr; /* still have to read `n' chars */ } while (n > 0 && nr == rlen); /* until end of count or eof */ luaL_pushresult(&b); /* close buffer */ #if LUA_VERSION_NUM < 501 return (n == 0 || lua_strlen(L, -1) > 0); #else return (n == 0 || lua_rawlen(L, -1) > 0); #endif }
static int load_string (void) { int status; lua_settop(L, 0); if (lua_readline(L, get_prompt(1)) == 0) /* no input? */ return -1; if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */ lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */ lua_remove(L, -2); /* remove original line */ } for (;;) { /* repeat until gets a complete line */ status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); if (!incomplete(status)) break; /* cannot try to add lines? */ if (lua_readline(L, get_prompt(0)) == 0) /* no more input? */ return -1; lua_concat(L, lua_gettop(L)); /* join lines */ } lua_saveline(L, lua_tostring(L, 1)); lua_remove(L, 1); /* remove line */ return status; }
static void func_callback_wrapper(int which, sqlite3_context * ctx, int num_args, sqlite3_value ** values) { CB_Data * cb_data = sqlite3_user_data(ctx); DB * db = cb_data->db; lua_State * L = db->L; switch(which) { case 0: push_callback(L, db, KEY_XFUNC(cb_data)); break; case 1: push_callback(L, db, KEY_XSTEP(cb_data)); break; case 2: push_callback(L, db, KEY_XFINAL(cb_data)); break; } if (lua_isnil(L, -1)) { lua_pop(L, 1); fprintf(stderr, "libluasqlite3: func_callback_wrapper: Warning: function is null\n"); return; } lua_pushlightuserdata(L, ctx); if (values) { lua_pushnumber(L, num_args); lua_pushlightuserdata(L, values); } if (lua_pcall(L, values ? 3 : 1, 0, 0)) { fprintf(stderr, "libluasqlite3: func_callback_wrapper: Warning: user function error: %s\n", lua_tostring(L, -1)); sqlite3_result_error(ctx, lua_tostring(L, -1), lua_strlen(L, -1)); lua_pop(L, 1); } }
static PyObject *LuaConvert(lua_State *L, int n) { PyObject *ret = NULL; lua_Object lobj = lua_getparam(L, n); if (lua_isnil(L, lobj)) { Py_INCREF(Py_None); ret = Py_None; } else if (lua_isnumber(L, lobj)) { double num = lua_getnumber(L, lobj); if (rintf((float) num) == num) { // is int? ret = PyInt_FromLong((long) num); } else { ret = PyFloat_FromDouble(num); } } else if (lua_isstring(L, lobj)) { const char *s = lua_getstring(L, lobj); int len = lua_strlen(L, lobj); ret = PyString_FromStringAndSize(s, len); if (!ret) { ret = PyUnicode_FromStringAndSize(s, len); } } else if (lua_istable(L, lobj)) { if (get_base_tag(L) == lua_tag(L, lobj)) { py_object *pobj = get_py_object(L, n); ret = pobj->o; free(pobj); } else { lua_error(L, "param not supported"); } } else if (lua_isboolean(L, lobj)) { if (lua_getboolean(L, lobj)) { Py_INCREF(Py_True); ret = Py_True; } else { Py_INCREF(Py_False); ret = Py_False; } } return ret; }
int create_class::stage1(lua_State *L) { #ifndef LUABIND_NO_ERROR_CHECKING if(lua_gettop(L) != 1 || lua_type(L, 1) != LUA_TSTRING || lua_isnumber(L, 1)) { lua_pushstring(L, "invalid construct, expected class name"); lua_error(L); } if(std::strlen(lua_tostring(L, 1)) != lua_strlen(L, 1)) { lua_pushstring(L, "luabind does not support class names with extra nulls"); lua_error(L); } #endif const char *name = lua_tostring(L, 1); void *c = lua_newuserdata(L, sizeof(class_rep)); new(c) class_rep(L, name); // make the class globally available lua_pushvalue(L, -1); lua_setglobal(L, name); // also add it to the closure as return value lua_pushcclosure(L, &stage2, 1); return 1; }
/* Get block to process: - top of stack gets */ static const char* lzstream_fetch_block(lua_State *L, lz_stream *s, int hint) { if (s->i_buffer_pos >= s->i_buffer_len) { luaL_unref(L, LUA_REGISTRYINDEX, s->i_buffer_ref); s->i_buffer_ref = LUA_NOREF; s->i_buffer = NULL; lua_rawgeti(L, LUA_REGISTRYINDEX, s->io_cb); if (!lua_isnil(L, -1)) { if (lua_isfunction(L, -1)) { lua_pushinteger(L, hint); lua_call(L, 1, 1); } else { lua_getfield(L, -1, (s->peek ? "peek" : "read")); lua_insert(L, -2); lua_pushinteger(L, hint); lua_call(L, 2, 1); } if (lua_isstring(L, -1)) { s->i_buffer_pos = 0; s->i_buffer_len = lua_strlen(L, -1); if (s->i_buffer_len > 0) { s->i_buffer = lua_tostring(L, -1); s->i_buffer_ref = luaL_ref(L, LUA_REGISTRYINDEX); } else { lua_pop(L, 1); } } else if (lua_isnil(L, -1)) { lua_pop(L, 1); } else { lua_pushliteral(L, "deflate callback must return string or nil"); lua_error(L); } } else { lua_pop(L, 1); } } return s->i_buffer; }
int f_memcache_get_long(lua_State * L) { char *r; int n = lua_gettop(L); struct memcache *mc; if (!lua_islightuserdata(L, lua_upvalueindex(1))) { lua_pushstring(L, "where is my userdata ?"); lua_error(L); } mc = lua_touserdata(L, lua_upvalueindex(1)); if (n != 1) { lua_pushstring(L, "expected one argument"); lua_error(L); } if (!lua_isstring(L, 1)) { lua_pushstring(L, "argument has to be a string"); lua_error(L); } if (NULL == (r = mc_aget(mc, lua_tostring(L, 1), lua_strlen(L, 1)))) { lua_pushnil(L); return 1; } lua_pushnumber(L, strtol(r, NULL, 10)); free(r); return 1; }
static int lua_socket_write(lua_State *l) { char *buf; long len; lua_socket *ls; int ret; buf = (char *)lua_tostring(l, 2); if(!lua_islong(l, 1) || !buf) { lua_pushint(l, -1); return 1; } len = lua_strlen(l, 2); ls = socketbyidentifier(lua_tolong(l, 1)); if(!ls || (ls->state != SOCKET_CONNECTED)) { lua_pushint(l, -1); return 1; } ret = write(ls->fd, buf, len); if(ret == -1 && (errno == EAGAIN)) { deregisterhandler(ls->fd, 0); registerhandler(ls->fd, POLLIN | POLLOUT | POLLERR | POLLHUP, lua_socket_poll_event); lua_pushint(l, 0); return 1; } if(ret == -1) lua_socket_call_close(ls); if(ret < len) { deregisterhandler(ls->fd, 0); registerhandler(ls->fd, POLLIN | POLLOUT | POLLERR | POLLHUP, lua_socket_poll_event); } lua_pushint(l, ret); return 1; }
static int digest_final(lua_State *L) { EVP_MD_CTX *c = (EVP_MD_CTX*)luaL_checkudata(L, 1, LUACRYPTO_DIGESTNAME); EVP_MD_CTX *d = NULL; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int written = 0; unsigned int i; char *hex; if (lua_isstring(L, 2)) { const char *s = luaL_checkstring(L, 2); if(!EVP_DigestUpdate(c, s, lua_strlen(L, 2))) { return crypto_error(L); } } d = EVP_MD_CTX_create(); if (!EVP_MD_CTX_copy_ex(d, c)) { return crypto_error(L); } if (!EVP_DigestFinal_ex(d, digest, &written)) { return crypto_error(L); } EVP_MD_CTX_destroy(d); if (lua_toboolean(L, 3)) lua_pushlstring(L, (char *)digest, written); else { hex = (char*)calloc(sizeof(char), written*2 + 1); for (i = 0; i < written; i++) sprintf(hex + 2*i, "%02x", digest[i]); lua_pushlstring(L, hex, written*2); free(hex); } return 1; }
static lz_stream *lzstream_new(lua_State *L, int src) { lz_stream *s = (lz_stream*)lua_newuserdata(L, sizeof(lz_stream)); luaL_getmetatable(L, ZSTREAMMETA); lua_setmetatable(L, -2); /* set metatable */ s->state = LZ_NONE; s->error = Z_OK; s->eos = 0; s->io_cb = LUA_REFNIL; s->i_buffer = NULL; s->i_buffer_ref = LUA_REFNIL; s->i_buffer_pos = 0; s->i_buffer_len = 0; s->peek = 0; s->o_buffer_len = 0; s->o_buffer_max = sizeof(s->o_buffer) / sizeof(s->o_buffer[0]); s->zstream.zalloc = Z_NULL; s->zstream.zfree = Z_NULL; /* prepare source */ if (lua_isstring(L, src)) { lua_pushvalue(L, src); s->i_buffer_ref = luaL_ref(L, LUA_REGISTRYINDEX); s->i_buffer = lua_tostring(L, src); s->i_buffer_len = lua_strlen(L, src); } else { /* table | function | userdata */ lua_pushvalue(L, src); s->io_cb = luaL_ref(L, LUA_REGISTRYINDEX); } return s; }
static int luaClientPrint(lua_State *L) { // No output client set? => Discard if (!output_client || !CLIENT_USED(output_client)) return 0; int n=lua_gettop(L); for (int i=1; i <= n; i++) { if (i > 1) server_writeto(output_client, "\t", 1); if (lua_isstring(L,i)) server_writeto(output_client, lua_tostring(L,i), lua_strlen(L, i)); else if (lua_isnil(L,i)) server_writeto(output_client, "nil", 3); else if (lua_isboolean(L,i)) lua_toboolean(L,i) ? server_writeto(output_client, "true", 4): server_writeto(output_client, "false", 5); else { char buffer[128]; snprintf(buffer, sizeof(buffer), "%s:%p", lua_typename(L,lua_type(L,i)), lua_topointer(L,i)); server_writeto(output_client, buffer, strlen(buffer)); } } server_writeto(output_client, "\r\n", 2); return 0; }
static void print_string_var(lua_State *state, int si, int depth) { ldb_output( "\"" ); const char * val = lua_tostring(state, si); int vallen = lua_strlen(state, si); int i; const char spchar[] = "\"\t\n\r"; for(i = 0; i < vallen; ) { if(val[i] == 0) { ldb_output("\\000"); ++i; } else if (val[i] == '"') { ldb_output("\\\""); ++i; } else if(val[i] == '\\') { ldb_output("\\\\"); ++i; } else if(val[i] == '\t') { ldb_output("\\t"); ++i; } else if(val[i] == '\n') { ldb_output("\\n"); ++i; } else if(val[i] == '\r') { ldb_output("\\r"); ++i; } else { int splen = strcspn(val + i, spchar); ldb_output("%.*s", splen, val+i); i += splen; } } ldb_output("\""); }
static int gfind_aux (lua_State *L) { MatchState ms; const lua_WChar *s = lua_towstring(L, lua_upvalueindex(1)); size_t ls = lua_strlen(L, lua_upvalueindex(1)); const lua_WChar *p = lua_towstring(L, lua_upvalueindex(2)); const lua_WChar *src; ms.L = L; ms.src_init = s; ms.src_end = s+ls; for (src = s + (size_t)lua_tonumber(L, lua_upvalueindex(3)); src <= ms.src_end; src++) { const lua_WChar *e; ms.level = 0; if ((e = match(&ms, src, p)) != NULL) { int newstart = e-s; if (e == src) newstart++; /* empty match? go at least one position */ lua_pushnumber(L, newstart); lua_replace(L, lua_upvalueindex(3)); return push_captures(&ms, src, e); } } return 0; /* not found */ }
/* Based on lua.c */ static void _rpmluaInteractive(lua_State *L) { (void) fputs("\n", stdout); printf("RPM Interactive %s Interpreter\n", LUA_VERSION); for (;;) { int rc = 0; if (rpmluaReadline(L, "> ") == 0) break; if (lua_tostring(L, -1)[0] == '=') { (void) lua_pushfstring(L, "print(%s)", lua_tostring(L, -1)+1); lua_remove(L, -2); } for (;;) { rc = luaL_loadbuffer(L, lua_tostring(L, -1), lua_strlen(L, -1), "<lua>"); if (rc == LUA_ERRSYNTAX && strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) { if (rpmluaReadline(L, ">> ") == 0) break; lua_remove(L, -2); /* Remove error */ lua_concat(L, 2); continue; } break; } if (rc == 0) rc = lua_pcall(L, 0, 0, 0); if (rc != 0) { fprintf(stderr, "%s\n", lua_tostring(L, -1)); lua_pop(L, 1); } lua_pop(L, 1); /* Remove line */ } (void) fputs("\n", stdout); }
LUA_API void lua_safetostring(lua_State *L,int index,char* buffer) { const char* tmp; tmp=lua_tostring(L,index); memcpy(buffer,tmp,lua_strlen(L,index)+1); }
void luaReplyToRedisReply(redisClient *c, lua_State *lua) { int t = lua_type(lua,-1); switch(t) { case LUA_TSTRING: addReplyBulkCBuffer(c,(char*)lua_tostring(lua,-1),lua_strlen(lua,-1)); break; case LUA_TBOOLEAN: addReply(c,lua_toboolean(lua,-1) ? shared.cone : shared.nullbulk); break; case LUA_TNUMBER: addReplyLongLong(c,(long long)lua_tonumber(lua,-1)); break; case LUA_TTABLE: /* We need to check if it is an array, an error, or a status reply. * Error are returned as a single element table with 'err' field. * Status replies are returned as single element table with 'ok' field */ lua_pushstring(lua,"err"); lua_gettable(lua,-2); t = lua_type(lua,-1); if (t == LUA_TSTRING) { sds err = sdsnew(lua_tostring(lua,-1)); sdsmapchars(err,"\r\n"," ",2); addReplySds(c,sdscatprintf(sdsempty(),"-%s\r\n",err)); sdsfree(err); lua_pop(lua,2); return; } lua_pop(lua,1); lua_pushstring(lua,"ok"); lua_gettable(lua,-2); t = lua_type(lua,-1); if (t == LUA_TSTRING) { sds ok = sdsnew(lua_tostring(lua,-1)); sdsmapchars(ok,"\r\n"," ",2); addReplySds(c,sdscatprintf(sdsempty(),"+%s\r\n",ok)); sdsfree(ok); lua_pop(lua,1); } else { void *replylen = addDeferredMultiBulkLength(c); int j = 1, mbulklen = 0; lua_pop(lua,1); /* Discard the 'ok' field value we popped */ while(1) { lua_pushnumber(lua,j++); lua_gettable(lua,-2); t = lua_type(lua,-1); if (t == LUA_TNIL) { lua_pop(lua,1); break; } luaReplyToRedisReply(c, lua); mbulklen++; } setDeferredMultiBulkLength(c,replylen,mbulklen); } break; default: addReply(c,shared.nullbulk); } lua_pop(lua,1); }
int luaRedisGenericCommand(lua_State *lua, int raise_error) { int j, argc = lua_gettop(lua); struct redisCommand *cmd; robj **argv; redisClient *c = server.lua_client; sds reply; /* Require at least one argument */ if (argc == 0) { luaPushError(lua, "Please specify at least one argument for redis.call()"); return 1; } /* Build the arguments vector */ argv = zmalloc(sizeof(robj*)*argc); for (j = 0; j < argc; j++) { if (!lua_isstring(lua,j+1)) break; argv[j] = createStringObject((char*)lua_tostring(lua,j+1), lua_strlen(lua,j+1)); } /* Check if one of the arguments passed by the Lua script * is not a string or an integer (lua_isstring() return true for * integers as well). */ if (j != argc) { j--; while (j >= 0) { decrRefCount(argv[j]); j--; } zfree(argv); luaPushError(lua, "Lua redis() command arguments must be strings or integers"); return 1; } /* Setup our fake client for command execution */ c->argv = argv; c->argc = argc; /* Command lookup */ cmd = lookupCommand(argv[0]->ptr); if (!cmd || ((cmd->arity > 0 && cmd->arity != argc) || (argc < -cmd->arity))) { if (cmd) luaPushError(lua, "Wrong number of args calling Redis command From Lua script"); else luaPushError(lua,"Unknown Redis command called from Lua script"); goto cleanup; } /* There are commands that are not allowed inside scripts. */ if (cmd->flags & REDIS_CMD_NOSCRIPT) { luaPushError(lua, "This Redis command is not allowed from scripts"); goto cleanup; } /* Write commands are forbidden against read-only slaves, or if a * command marked as non-deterministic was already called in the context * of this script. */ if (cmd->flags & REDIS_CMD_WRITE) { if (server.lua_random_dirty) { luaPushError(lua, "Write commands not allowed after non deterministic commands"); goto cleanup; } else if (server.masterhost && server.repl_slave_ro && !server.loading && !(server.lua_caller->flags & REDIS_MASTER)) { luaPushError(lua, shared.roslaveerr->ptr); goto cleanup; } else if (server.stop_writes_on_bgsave_err && server.saveparamslen > 0 && server.lastbgsave_status == REDIS_ERR) { luaPushError(lua, shared.bgsaveerr->ptr); goto cleanup; } } /* If we reached the memory limit configured via maxmemory, commands that * could enlarge the memory usage are not allowed, but only if this is the * first write in the context of this script, otherwise we can't stop * in the middle. */ if (server.maxmemory && server.lua_write_dirty == 0 && (cmd->flags & REDIS_CMD_DENYOOM)) { if (freeMemoryIfNeeded() == REDIS_ERR) { luaPushError(lua, shared.oomerr->ptr); goto cleanup; } } if (cmd->flags & REDIS_CMD_RANDOM) server.lua_random_dirty = 1; if (cmd->flags & REDIS_CMD_WRITE) server.lua_write_dirty = 1; /* Run the command */ c->cmd = cmd; call(c,REDIS_CALL_SLOWLOG | REDIS_CALL_STATS); /* Convert the result of the Redis command into a suitable Lua type. * The first thing we need is to create a single string from the client * output buffers. */ reply = sdsempty(); if (c->bufpos) { reply = sdscatlen(reply,c->buf,c->bufpos); c->bufpos = 0; } while(listLength(c->reply)) { robj *o = listNodeValue(listFirst(c->reply)); reply = sdscatlen(reply,o->ptr,sdslen(o->ptr)); listDelNode(c->reply,listFirst(c->reply)); } if (raise_error && reply[0] != '-') raise_error = 0; redisProtocolToLuaType(lua,reply); /* Sort the output array if needed, assuming it is a non-null multi bulk * reply as expected. */ if ((cmd->flags & REDIS_CMD_SORT_FOR_SCRIPT) && (reply[0] == '*' && reply[1] != '-')) { luaSortArray(lua); } sdsfree(reply); c->reply_bytes = 0; cleanup: /* Clean up. Command code may have changed argv/argc so we use the * argv/argc of the client instead of the local variables. */ for (j = 0; j < c->argc; j++) decrRefCount(c->argv[j]); zfree(c->argv); if (raise_error) { /* If we are here we should have an error in the stack, in the * form of a table with an "err" field. Extract the string to * return the plain error. */ lua_pushstring(lua,"err"); lua_gettable(lua,-2); return lua_error(lua); } return 1; }