static int str_gsub (lua_State *L) { size_t srcl, lp; const char *src = luaL_checklstring(L, 1, &srcl); const char *p = luaL_checklstring(L, 2, &lp); int tr = lua_type(L, 3); size_t max_s = luaL_optinteger(L, 4, srcl+1); int anchor = (*p == '^'); size_t n = 0; MatchState ms; luaL_Buffer b; luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, "string/function/table expected"); luaL_buffinit(L, &b); if (anchor) { p++; lp--; /* skip anchor character */ } ms.L = L; ms.src_init = src; ms.src_end = src+srcl; ms.p_end = p + lp; while (n < max_s) { const char *e; ms.level = 0; e = match(&ms, src, p); if (e) { n++; add_value(&ms, &b, src, e, tr); } if (e && e>src) /* non empty match? */ src = e; /* skip it */ else if (src < ms.src_end) luaL_addchar(&b, *src++); else break; if (anchor) break; } luaL_addlstring(&b, src, ms.src_end-src); luaL_pushresult(&b); lua_pushinteger(L, n); /* number of substitutions */ return 2; }
/*-------------------------------------------------------------------------*\ * Incrementaly breaks a string into lines. The string can have CRLF breaks. * A, n = wrp(l, B, length) * A is a copy of B, broken into lines of at most 'length' bytes. * 'l' is how many bytes are left for the first line of B. * 'n' is the number of bytes left in the last line of A. \*-------------------------------------------------------------------------*/ static int mime_global_wrp(lua_State *L) { size_t size = 0; int left = (int) luaL_checknumber(L, 1); const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size); const UC *last = input + size; int length = (int) luaL_optnumber(L, 3, 76); luaL_Buffer buffer; /* end of input black-hole */ if (!input) { /* if last line has not been terminated, add a line break */ if (left < length) lua_pushstring(L, CRLF); /* otherwise, we are done */ else lua_pushnil(L); lua_pushnumber(L, length); return 2; } luaL_buffinit(L, &buffer); while (input < last) { switch (*input) { case '\r': break; case '\n': luaL_addstring(&buffer, CRLF); left = length; break; default: if (left <= 0) { left = length; luaL_addstring(&buffer, CRLF); } luaL_addchar(&buffer, *input); left--; break; } input++; } luaL_pushresult(&buffer); lua_pushnumber(L, left); return 2; }
static int GLua_BitStream_ReadString(lua_State *L) { GLua_Bitstream_t *stream = GLua_CheckBitStream(L, 1); luaL_Buffer B; char ch; if (!stream->reading) { luaL_error(L, "Attempted to read from a write-only bitstream"); return 0; } luaL_buffinit(L, &B); while (1) { ch = BitStream_ReadChar(&stream->stream); if (!ch) { break; } luaL_addchar(&B, ch); } luaL_pushresult(&B); return 1; }
static void protocol_command_handler(char * token, Channel * c, void * client_data) { struct channel_extra *ce = (struct channel_extra *)c->client_data; struct luaref *refp = (struct luaref *)client_data; lua_State *L = ce->L; InputStream * inp = &c->inp; luaL_Buffer msg; int ch; lua_rawgeti(L, LUA_REGISTRYINDEX, refp->ref); lua_pushstring(L, token); luaL_buffinit(L, &msg); while((ch = read_stream(inp)) >= 0) { luaL_addchar(&msg, ch); } luaL_pushresult(&msg); trace(LOG_LUA, "lua_protocol_command %d %s", refp->ref, lua_tostring(L, -1)); if(lua_pcall(L, 2, 0, 0) != 0) { fprintf(stderr, "%s\n", lua_tostring(L,1)); exit(1); } }
static int os_date (lua_State *L) { size_t slen; const char *s = luaL_optlstring(L, 1, "%c", &slen); time_t t = luaL_opt(L, l_checktime, 2, time(NULL)); const char *se = s + slen; /* 's' end */ struct tm tmr, *stm; if (*s == '!') { /* UTC? */ stm = l_gmtime(&t, &tmr); s++; /* skip '!' */ } else stm = l_localtime(&t, &tmr); if (stm == NULL) /* invalid date? */ return luaL_error(L, "time result cannot be represented in this installation"); if (strcmp(s, "*t") == 0) { lua_createtable(L, 0, 9); /* 9 = number of fields */ setallfields(L, stm); } else { char cc[4]; /* buffer for individual conversion specifiers */ luaL_Buffer b; cc[0] = '%'; luaL_buffinit(L, &b); while (s < se) { if (*s != '%') /* not a conversion specifier? */ luaL_addchar(&b, *s++); else { size_t reslen; char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); s++; /* skip '%' */ s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */ reslen = strftime(buff, SIZETIMEFMT, cc, stm); luaL_addsize(&b, reslen); } } luaL_pushresult(&b); } return 1; }
static int str_gsub (lua_State *L) { size_t srcl; const char *src = luaL_checklstring(L, 1, &srcl); const char *p = luaL_checkstring(L, 2); int tr = lua_type(L, 3); int max_s = luaL_optint(L, 4, srcl+1); int anchor = (*p == '^') ? (p++, 1) : 0; int n = 0; MatchState ms; luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC); if(!b) luaL_error(L, "str_gsub: cannot allocate memory"); luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, "string/function/table expected"); luaL_buffinit(L, b); ms.L = L; ms.src_init = src; ms.src_end = src+srcl; while (n < max_s) { const char *e; ms.level = 0; e = match(&ms, src, p); if (e) { n++; add_value(&ms, b, src, e); } if (e && e>src) /* non empty match? */ src = e; /* skip it */ else if (src < ms.src_end) luaL_addchar(b, *src++); else break; if (anchor) break; } luaL_addlstring(b, src, ms.src_end-src); luaL_pushresult(b); lua_pushinteger(L, n); /* number of substitutions */ kfree(b); return 2; }
static int read_line (lua_State *L, FILE *f, int chop) { luaL_Buffer b; int c = '\0'; luaL_buffinit(L, &b); while (c != EOF && c != '\n') { /* repeat until end of line */ char *buff = luaL_prepbuffer(&b); /* preallocate buffer */ int i = 0; l_lockfile(f); /* no memory errors can happen inside the lock */ #ifdef U8W_H if (f == stdin) { char *pb = u8fgets(buff, LUAL_BUFFERSIZE, f); if (pb != NULL) { char *pbn = strchr(buff, '\n'); if (pbn != NULL) { *pbn = '\0'; c = '\n'; } i = (int)strlen(pb); } else { c = EOF; } } else { #endif while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n') buff[i++] = c; #ifdef U8W_H } #endif l_unlockfile(f); luaL_addsize(&b, i); } if (!chop && c == '\n') /* want a newline and have one? */ luaL_addchar(&b, c); /* add ending newline to result */ luaL_pushresult(&b); /* close buffer */ /* return ok if read something (either a newline or something else) */ return (c == '\n' || lua_rawlen(L, -1) > 0); }
/* ** Fails with error message from ODBC ** Inputs: ** type: type of handle used in operation ** handle: handle used in operation */ static int fail(lua_State *L, const SQLSMALLINT type, const SQLHANDLE handle) { SQLCHAR State[6]; SQLINTEGER NativeError; SQLSMALLINT MsgSize, i; SQLRETURN ret; SQLCHAR Msg[SQL_MAX_MESSAGE_LENGTH]; luaL_Buffer b; lua_pushnil(L); luaL_buffinit(L, &b); i = 1; while (1) { ret = SQLGetDiagRec(type, handle, i, State, &NativeError, Msg, sizeof(Msg), &MsgSize); if (ret == SQL_NO_DATA) break; luaL_addlstring(&b, (char*)Msg, MsgSize); luaL_addchar(&b, '\n'); i++; } luaL_pushresult(&b); return 2; }
/* | Converts a relative directory path to an absolute. | | Params on Lua stack: | 1: a relative path to directory | | Returns on Lua stack: | The absolute path of directory */ static int l_realdir( lua_State *L ) { luaL_Buffer b; const char *rdir = luaL_checkstring(L, 1); char *adir = get_realpath(rdir); if (!adir) { printlogf(L, "Error", "failure getting absolute path of [%s]", rdir); return 0; } { // makes sure its a directory struct stat st; if (stat(adir, &st)) { printlogf(L, "Error", "cannot get absolute path of dir '%s': %s", rdir, strerror(errno)); free(adir); return 0; } if (!S_ISDIR(st.st_mode)) { printlogf(L, "Error", "cannot get absolute path of dir '%s': is not a directory", rdir); free(adir); return 0; } } // returns absolute path with a concated '/' luaL_buffinit(L, &b); luaL_addstring(&b, adir); luaL_addchar(&b, '/'); luaL_pushresult(&b); free(adir); return 1; }
static void Xml_pushDecode(lua_State* L, const char* s, size_t s_size) { luaL_Buffer b; const char* found = strstr(s, "&#"); size_t start=0, pos, i; if(!s_size) s_size=strlen(s); luaL_buffinit(L, &b); found = strstr(s, "&#"); pos = found ? found-s : s_size; while(found) { char ch = 0; size_t i=0; for(found += 2; i<3; ++i, ++found) if(isdigit(*found)) ch = ch * 10 + (*found - 48); else break; if(*found == ';') { if(pos>start) luaL_addlstring(&b, s+start, pos-start); luaL_addchar(&b, ch); start = pos + 3 + i; } found = strstr(found+1, "&#"); pos = found ? found-s : s_size; } if(pos>start) luaL_addlstring(&b,s+start, pos-start); luaL_pushresult(&b); for(i=sv_code_size-1; i<sv_code_size; i-=2) { luaL_gsub(L, lua_tostring(L,-1), sv_code[i], sv_code[i-1]); lua_remove(L,-2); } }
LB_API int lbind_pushmask(lua_State *L, int evalue, lbind_Enum *et) { luaL_Buffer b; lbind_EnumItem *items; int first = 1; unsigned value = lbind_checkmask(L, 2, et); if (et->items == NULL) { lua_pushliteral(L, ""); return 0; } luaL_buffinit(L, &b); for (items = et->items; items->name != NULL; ++items) { if ((items->value & value) == value) { if (first) first = 0; else luaL_addchar(&b, ' '); luaL_addstring(&b, items->name); value &= ~items->value; } } luaL_pushresult(&b); return 1; }
static int llog_print(lua_State *L, logging::level lv) { logging::logger* lg = logging::get(L); if (!lg) { return 0; } int n = lua_gettop(L); luaL_Buffer b; luaL_buffinit(L, &b); for (int i = 1; i <= n; i++) { size_t l; const char* s = lua_tolstring(L, i, &l); if (s == NULL) return luaL_error(L, "'tostring' must return a string to 'print'"); if (i>1) luaL_addchar(&b, '\t'); luaL_addlstring(&b, s, l); } luaL_pushresult(&b); size_t l; const char *s = lua_tolstring(L, -1, &l); LOGGING_STREAM(*lg, lv) << std::string(s, l); return 0; }
static int str_gsub (lua_State *L) { size_t srcl, lp; const char *src = luaL_checklstring(L, 1, &srcl); /* subject */ const char *p = luaL_checklstring(L, 2, &lp); /* pattern */ const char *lastmatch = NULL; /* end of last match */ int tr = lua_type(L, 3); /* replacement type */ lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */ int anchor = (*p == '^'); lua_Integer n = 0; /* replacement count */ MatchState ms; luaL_Buffer b; luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, "string/function/table expected"); luaL_buffinit(L, &b); if (anchor) { p++; lp--; /* skip anchor character */ } prepstate(&ms, L, src, srcl, p, lp); while (n < max_s) { const char *e; reprepstate(&ms); /* (re)prepare state for new match */ if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */ n++; add_value(&ms, &b, src, e, tr); /* add replacement to buffer */ src = lastmatch = e; } else if (src < ms.src_end) /* otherwise, skip one character */ luaL_addchar(&b, *src++); else break; /* end of subject */ if (anchor) break; } luaL_addlstring(&b, src, ms.src_end-src); luaL_pushresult(&b); lua_pushinteger(L, n); /* number of substitutions */ return 2; }
static void l_json_encode_string(lua_State *L, int pos, luaL_Buffer *B) { size_t len; const char *str = lua_tolstring(L, pos, &len); unsigned int i; for (i=0; i<len; i++) { switch (str[i]) { case '"': luaL_addstring(B, "\\\""); break; case '\\': luaL_addstring(B, "\\\\"); break; case '/': luaL_addstring(B, "\\/"); break; case '\b': luaL_addstring(B, "\\b"); break; case '\f': luaL_addstring(B, "\\f"); break; case '\n': luaL_addstring(B, "\\n"); break; case '\r': luaL_addstring(B, "\\r"); break; case '\t': luaL_addstring(B, "\\t"); break; default: luaL_addchar(B, str[i]); } } }
/* EXT - mostly copied from 'str_gsub' */ static int str_gsub_aux (lua_State *L, int table) { size_t srcl, lp; const char *src = luaL_checklstring(L, 1, &srcl); const char *p = luaL_checklstring(L, 2, &lp); int tr = lua_type(L, 3); lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); int anchor = (*p == '^'); lua_Integer n = 0; MatchState ms; luaL_Buffer b; luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, "string/function/table expected"); luaL_buffinit(L, &b); prepstate(&ms, L, src, srcl, p, lp); /* EXT - moved before anchor check */ if (anchor) p++; /* skip anchor character */ /* EXT */ while (n < max_s) { const char *e; reprepstate(&ms); if ((e = match(&ms, src, p)) != NULL) { n++; add_value(&ms, &b, src, e, tr, table); /* EXT - new 'table' argument */ } if (e && e>src) /* non empty match? */ src = e; /* skip it */ else if (src < ms.src_end) luaL_addchar(&b, *src++); else break; if (anchor) break; } luaL_addlstring(&b, src, ms.src_end-src); luaL_pushresult(&b); lua_pushinteger(L, n); /* number of substitutions */ return 2; }
static void Xml_pushDecode(lua_State* L, const char* s, size_t s_size) { size_t start=0, pos; if(!s_size) s_size=strlen(s); luaL_Buffer b; luaL_buffinit(L, &b); const char* found = strstr(s, "&#"); if(!found) pos = s_size; else pos = found-s; while(found&&(pos+5<s_size)&&(*(found+5)==';')&&isdigit(*(found+2))&&isdigit(*(found+3))&&isdigit(*(found+4)) ) { if(pos>start) luaL_addlstring(&b,s+start, pos-start); luaL_addchar(&b, 100*(s[pos+2]-48)+10*(s[pos+3]-48)+(s[pos+4]-48)); start=pos+6; found = strstr(found+6, "&#"); if(!found) pos = s_size; else pos = found-s; } if(pos>start) luaL_addlstring(&b,s+start, pos-start); luaL_pushresult(&b); size_t i; for(i=sv_code_size-1; i<sv_code_size; i-=2) { luaL_gsub(L, lua_tostring(L,-1), sv_code[i], sv_code[i-1]); lua_remove(L,-2); } }
static int lerror(lua_State *L) { struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1)); int n = lua_gettop(L); if (n <= 1) { lua_settop(L, 1); const char * s = luaL_tolstring(L, 1, NULL); skynet_error(context, "%s", s); return 0; } luaL_Buffer b; luaL_buffinit(L, &b); int i; for (i=1; i<=n; i++) { luaL_tolstring(L, i, NULL); luaL_addvalue(&b); if (i<n) { luaL_addchar(&b, ' '); } } luaL_pushresult(&b); skynet_error(context, "%s", lua_tostring(L, -1)); return 0; }
// Lua: read = i2c.txrx(addr, size) static v7_val_t i2c_txrx(struct v7 *v7) { const char* pdata; size_t datalen; int numdata; int argn; int i; luaL_Buffer b; vm_dcl_i2c_control_write_and_read_t param; char wbuf[8]; char rbuf[8]; int wbuf_index = 0; size_t size = luaL_checkinteger(L, -1); int top = lua_gettop(L); if(size <= 0) { return 0; } else if(size > 8) { return luaL_error(L, "read data length must not exceed 8"); } if(lua_gettop(L) < 2) return luaL_error(L, "invalid number of arguments"); for(argn = 1; argn < top; argn++) { // lua_isnumber() would silently convert a string of digits to an integer // whereas here strings are handled separately. if(lua_type(L, argn) == LUA_TNUMBER) { numdata = (int)luaL_checkinteger(L, argn); if(numdata < 0 || numdata > 255) return luaL_error(L, "numeric data must be from 0 to 255"); if(wbuf_index > 8) { return luaL_error(L, "write data length must not exceed 8"); } wbuf[wbuf_index] = numdata; wbuf_index++; } else if(lua_istable(L, argn)) { datalen = lua_objlen(L, argn); for(i = 0; i < datalen; i++) { lua_rawgeti(L, argn, i + 1); numdata = (int)luaL_checkinteger(L, -1); lua_pop(L, 1); if(numdata < 0 || numdata > 255) return luaL_error(L, "numeric data must be from 0 to 255"); if(wbuf_index > 8) { return luaL_error(L, "write data length must not exceed 8"); } wbuf[wbuf_index] = numdata; wbuf_index++; } } else { pdata = luaL_checklstring(L, argn, &datalen); for(i = 0; i < datalen; i++) { if(wbuf_index > 8) { return luaL_error(L, "write data length must not exceed 8"); } wbuf[wbuf_index] = numdata; wbuf_index++; } } } param.out_data_length = wbuf_index; param.out_data_ptr = wbuf; param.in_data_length = size; param.in_data_ptr = rbuf; if(vm_dcl_control(g_i2c_handle, VM_DCL_I2C_CMD_WRITE_AND_READ, ¶m) != VM_DCL_STATUS_OK) { return 0; } luaL_buffinit(L, &b); for(i = 0; i < size; i++) luaL_addchar(&b, rbuf[i]); luaL_pushresult(&b); return 1; }
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); LUA_INTFRM_T ni = (LUA_INTFRM_T)n; lua_Number diff = n - (lua_Number)ni; luaL_argcheck(L, -1 < diff && diff < 1, arg, "not a number in proper range"); addlenmod(form, LUA_INTFRMLEN); nb = sprintf(buff, form, ni); break; } case 'o': case 'u': case 'x': case 'X': { lua_Number n = luaL_checknumber(L, arg); unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n; lua_Number diff = n - (lua_Number)ni; luaL_argcheck(L, -1 < diff && diff < 1, arg, "not a non-negative number in proper range"); addlenmod(form, LUA_INTFRMLEN); nb = sprintf(buff, form, ni); 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; }
static int str_pack (lua_State *L) { luaL_Buffer b; Header h; const char *fmt = luaL_checkstring(L, 1); /* format string */ int arg = 1; /* current argument to pack */ size_t totalsize = 0; /* accumulate total size of result */ initheader(L, &h); lua_pushnil(L); /* mark to separate arguments from string buffer */ luaL_buffinit(L, &b); while (*fmt != '\0') { int size, ntoalign; KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign); totalsize += ntoalign + size; while (ntoalign-- > 0) luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */ arg++; switch (opt) { case Kint: { /* signed integers */ lua_Integer n = luaL_checkinteger(L, arg); if (size < SZINT) { /* need overflow check? */ lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1); luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow"); } packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0)); break; } case Kuint: { /* unsigned integers */ lua_Integer n = luaL_checkinteger(L, arg); if (size < SZINT) /* need overflow check? */ luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)), arg, "unsigned overflow"); packint(&b, (lua_Unsigned)n, h.islittle, size, 0); break; } case Kfloat: { /* floating-point options */ volatile Ftypes u; char *buff = luaL_prepbuffsize(&b, size); lua_Number n = luaL_checknumber(L, arg); /* get argument */ if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ else if (size == sizeof(u.d)) u.d = (double)n; else u.n = n; /* move 'u' to final result, correcting endianness if needed */ copywithendian(buff, u.buff, size, h.islittle); luaL_addsize(&b, size); break; } case Kchar: { /* fixed-size string */ size_t len; const char *s = luaL_checklstring(L, arg, &len); luaL_argcheck(L, len <= (size_t)size, arg, "string longer than given size"); luaL_addlstring(&b, s, len); /* add string */ while (len++ < (size_t)size) /* pad extra space */ luaL_addchar(&b, LUAL_PACKPADBYTE); break; } case Kstring: { /* strings with length count */ size_t len; const char *s = luaL_checklstring(L, arg, &len); luaL_argcheck(L, size >= (int)sizeof(size_t) || len < ((size_t)1 << (size * NB)), arg, "string length does not fit in given size"); packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */ luaL_addlstring(&b, s, len); totalsize += len; break; } case Kzstr: { /* zero-terminated string */ size_t len; const char *s = luaL_checklstring(L, arg, &len); luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros"); luaL_addlstring(&b, s, len); luaL_addchar(&b, '\0'); /* add zero at the end */ totalsize += len + 1; break; } case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */ case Kpaddalign: case Knop: arg--; /* undo increment */ break; } } luaL_pushresult(&b); return 1; }
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 = l_sprintf(buff, MAX_ITEM, form, (int)luaL_checkinteger(L, arg)); break; } case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': { lua_Integer n = luaL_checkinteger(L, arg); addlenmod(form, LUA_INTEGER_FRMLEN); nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACINT)n); break; } case 'a': case 'A': addlenmod(form, LUA_NUMBER_FRMLEN); nb = lua_number2strx(L, buff, MAX_ITEM, form, luaL_checknumber(L, arg)); break; case 'e': case 'E': case 'f': case 'g': case 'G': { lua_Number n = luaL_checknumber(L, arg); addlenmod(form, LUA_NUMBER_FRMLEN); nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n); break; } case 'q': { addliteral(L, &b, arg); break; } case 's': { size_t l; const char *s = luaL_tolstring(L, arg, &l); if (form[2] == '\0') /* no modifiers? */ luaL_addvalue(&b); /* keep entire string */ else { luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); if (!strchr(form, '.') && l >= 100) { /* no precision and string is too long to be formatted */ luaL_addvalue(&b); /* keep entire string */ } else { /* format the string into 'buff' */ nb = l_sprintf(buff, MAX_ITEM, form, s); lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ } } break; } default: { /* also treat cases 'pnLlh' */ return luaL_error(L, "invalid option '%%%c' to 'format'", *(strfrmt - 1)); } } lua_assert(nb < MAX_ITEM); luaL_addsize(&b, nb); } } luaL_pushresult(&b); return 1; }
static void addunquote (lua_State *L, luaL_Buffer *b, int arg) { size_t l, ol; const char *s = luaL_checklstring(L, arg, &l); ol = l-1; char prevChar = ' '; while (l--) { if((l == ol || l == 0) && *s == '"') { // ignore leading and trailing quotation mark } else if(prevChar == '\\') { // previous character was an escape marker switch(*s) { case 'n': { luaL_addchar(b, '\n'); break; } case 'r': { luaL_addchar(b, '\r'); break; } case '"': { luaL_addchar(b, '"'); break; } case '\\': { luaL_addchar(b, '\\'); break; } case 'b': { luaL_addchar(b, '\b'); break; } case 'f': { luaL_addchar(b, '\f'); break; } case 't': { luaL_addchar(b, '\t'); break; } case 'a': { luaL_addchar(b, '\a'); break; } case 'v': { luaL_addchar(b, '\v'); break; } case '?': { luaL_addchar(b, '\?'); break; } case '\'': { luaL_addchar(b, '\''); break; } case 'u': { int ch; sscanf(s, "u%04x", &ch); luaL_addchar(b, ch); s += 4; l -= 4; break; } } } else { if(*s != '\\') luaL_addchar(b, *s); } prevChar = *s; s++; } }
//-------------------------------------------------------------------- static void https_send_read_request_rsp_cb(VMUINT16 request_id, VMUINT8 result, VMUINT16 status, VMINT32 cause, VMUINT8 protocol, VMUINT32 content_length, VMBOOL more, VMUINT8* content_type, VMUINT8 content_type_len, VMUINT8* new_url, VMUINT32 new_url_len, VMUINT8* reply_header, VMUINT32 reply_header_len, VMUINT8* reply_segment, VMUINT32 reply_segment_len) { int ret = -1; if(result != 0) { vm_https_cancel(request_id); vm_https_unset_channel(g_channel_id); } else { g_request_id = request_id; if (g_https_header_cb_ref != LUA_NOREF) { int i; luaL_Buffer b; lua_rawgeti(L, LUA_REGISTRYINDEX, g_https_header_cb_ref); if ((lua_type(L, -1) != LUA_TFUNCTION) && (lua_type(L, -1) != LUA_TLIGHTFUNCTION)) { // * BAD CB function reference lua_remove(L, -1); } else { luaL_buffinit(L, &b); for(i = 0; i < reply_header_len; i++) { luaL_addchar(&b, reply_header[i]); } luaL_pushresult(&b); lua_call(L, 1, 0); } } else { fputs("\n--- Header: ---\n", stdout); for(int i = 0; i < reply_header_len; i++) { fputc(reply_header[i], stdout); } fputs("\n---------------\n", stdout); fflush(stdout); } if (g_https_response_cb_ref != LUA_NOREF) { int i; luaL_Buffer b; lua_rawgeti(L, LUA_REGISTRYINDEX, g_https_response_cb_ref); if ((lua_type(L, -1) != LUA_TFUNCTION) && (lua_type(L, -1) != LUA_TLIGHTFUNCTION)) { // * BAD CB function reference lua_remove(L, -1); } else { luaL_buffinit(L, &b); for(i = 0; i < reply_segment_len; i++) { luaL_addchar(&b, reply_segment[i]); } luaL_pushresult(&b); lua_pushinteger(L, more); lua_call(L, 2, 0); } } else { for(int i = 0; i < reply_segment_len; i++) { fputc(reply_segment[i], stdout); } fflush(stdout); } if(more) { ret = vm_https_read_content(request_id, ++g_read_seg_num, 128); if(ret != 0) { vm_https_cancel(request_id); vm_https_unset_channel(g_channel_id); } } } }
static void write_char (char c, void *v) { luaL_Buffer *b = (luaL_Buffer *) v; luaL_addchar(b, c); }
static void make_report(lua_State* L, lua_State* dL) { int size = 0; int i = 0; luaL_Buffer b; lua_newtable(L); lua_pushnil(dL); while (lua_next(dL, ROOT_TABLE) != 0) { lua_getfield(dL, -1, "name"); if (lua_isnil(dL, -1)) { lua_pop(dL, 2); continue; } else { lua_pop(dL, 1); } lua_newtable(L); size = 0; lua_pushnil(dL); while (lua_next(dL, -2) != 0) { if (LUA_TLIGHTUSERDATA == lua_type(dL, -2)) { size += (int)lua_tointeger(dL, -1); } lua_pop(dL, 1); } lua_pushnumber(L, size); lua_setfield(L, -2, "size"); lua_pushfstring(L, "%p", lua_touserdata(dL, -2)); lua_setfield(L, -2, "pointer"); lua_getfield(dL, -1, "name"); lua_pushstring(L, lua_tostring(dL, -1)); lua_pop(dL, 1); lua_setfield(L, -2, "name"); lua_getfield(dL, -1, "type"); lua_pushnumber(L, lua_tonumber(dL, -1)); lua_pop(dL, 1); lua_setfield(L, -2, "type"); lua_getfield(dL, -1, "used_in"); luaL_buffinit(L, &b); lua_pushnil(dL); while (lua_next(dL, -2) != 0) { lua_pop(dL, 1); luaL_addstring(&b, lua_tostring(dL, -1)); luaL_addchar(&b, ';'); } luaL_pushresult(&b); lua_pop(dL, 1); lua_setfield(L, -2, "used_in"); ++i; lua_rawseti(L, -2, i); lua_pop(dL, 1); } }
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { while (l--) luaL_addchar(B, *s++); }
void elua_uip_appcall() { volatile struct elua_uip_state *s; elua_net_size temp; int sockno; // If uIP is not yet configured (DHCP response not received), do nothing if( !elua_uip_configured ) return; s = ( struct elua_uip_state* )&( uip_conn->appstate ); // Need to find the actual socket location, since UIP doesn't provide this ... for( temp = 0; temp < UIP_CONNS; temp ++ ) if( uip_conns + temp == uip_conn ) break; sockno = ( int )temp; if( uip_connected() ) { #ifdef BUILD_CON_TCP if( uip_conn->lport == HTONS( ELUA_NET_TELNET_PORT ) ) // special case: telnet server { if( elua_uip_telnet_socket != -1 ) { uip_close(); return; } else elua_uip_telnet_socket = sockno; } else #endif if( elua_uip_accept_request ) { elua_uip_accept_sock = sockno; elua_uip_accept_remote.ipwords[ 0 ] = uip_conn->ripaddr[ 0 ]; elua_uip_accept_remote.ipwords[ 1 ] = uip_conn->ripaddr[ 1 ]; elua_uip_accept_request = 0; } else if( s->state == ELUA_UIP_STATE_CONNECT ) s->state = ELUA_UIP_STATE_IDLE; uip_stop(); return; } if( s->state == ELUA_UIP_STATE_IDLE ) return; // Do we need to read? if( s->state == ELUA_UIP_STATE_RECV ) { // Re-enable data transfer on the socket and change state s->state = ELUA_UIP_STATE_RECV_2; uip_restart(); return; } if( uip_aborted() || uip_timedout() || uip_closed() ) { // Signal this error s->res = uip_aborted() ? ELUA_NET_ERR_ABORTED : ( uip_timedout() ? ELUA_NET_ERR_TIMEDOUT : ELUA_NET_ERR_CLOSED ); #ifdef BUILD_CON_TCP if( sockno == elua_uip_telnet_socket ) elua_uip_telnet_socket = -1; #endif s->state = ELUA_UIP_STATE_IDLE; return; } // Handle data send if( ( uip_acked() || uip_rexmit() || uip_poll() ) && ( s->state == ELUA_UIP_STATE_SEND ) ) { // Special translation for TELNET: prepend all '\n' with '\r' // We write directly in UIP's buffer if( uip_acked() ) { elua_net_size minlen = UMIN( s->len, uip_mss() ); s->len -= minlen; s->ptr += minlen; if( s->len == 0 ) s->state = ELUA_UIP_STATE_IDLE; } if( s->len > 0 ) // need to (re)transmit? { #ifdef BUILD_CON_TCP if( sockno == elua_uip_telnet_socket ) { temp = elua_uip_telnet_prep_send( s->ptr, s->len ); uip_send( uip_sappdata, temp ); } else #endif uip_send( s->ptr, UMIN( s->len, uip_mss() ) ); } return; } // Handle close if( s->state == ELUA_UIP_STATE_CLOSE ) { uip_close(); s->state = ELUA_UIP_STATE_IDLE; return; } // Handle data receive if( uip_newdata() ) { if( s->state == ELUA_UIP_STATE_RECV_2 ) { #ifdef BUILD_CON_TCP if( sockno == elua_uip_telnet_socket ) { elua_uip_telnet_handle_input( s ); return; } #endif int lastfound = 0; // Check end of transmission if( uip_datalen() < UIP_RECEIVE_WINDOW ) lastfound = 1; // Check overflow if( s->len < uip_datalen() ) { s->res = ELUA_NET_ERR_OVERFLOW; temp = s->len; } else temp = uip_datalen(); if( s->readto != ELUA_NET_NO_LASTCHAR ) { char *tptr = ( char* )uip_appdata; char *last = ( char* )uip_appdata + temp - 1; luaL_Buffer *pbuf = ( luaL_Buffer* )s->ptr; char* dest = ( char* )s->ptr; while( tptr <= last ) { if( *tptr == s->readto ) { lastfound = 1; break; } if( *tptr != '\r' ) { if( s->res ) luaL_addchar( pbuf, *tptr ); else *dest ++ = *tptr; s->len --; } tptr ++; } } else { if( s->res ) luaL_addlstring( ( luaL_Buffer* )s->ptr, ( const char* )uip_appdata, temp ); else memcpy( ( char* )s->ptr, ( const char* )uip_appdata, temp ); s->len -= temp; } // Do we need to read another packet? if( s->len == 0 || lastfound ) { uip_stop(); s->res = ELUA_NET_ERR_OK; s->state = ELUA_UIP_STATE_IDLE; } } else uip_stop(); } }
static int binread(lua_State *L) { int n; FILE *f; FILE **fp; const char *fmt; const char *fmt_save; char buf[256]; luaL_Buffer lbuf; n = lua_gettop(L); if (n != 2) return luaL_error(L, "expected 2 arguments for binread function (got %d)", n); fp = luaL_checkudata(L, 1, LUA_FILEHANDLE); f = *fp; fmt = luaL_checkstring(L, 2); fmt_save = fmt; DEBUG(3, "binread(\"%s\", ...)\n", fmt); luaL_buffinit(L, &lbuf); for (; *fmt; fmt++) { switch (*fmt) { case '?': case 'b': case 'B': case 'c': luaL_addchar(&lbuf, GETCHAR); break; case 'h': case 'H': READ(2); break; case 'f': case 'i': case 'I': READ(4); break; case 'l': case 'L': READ(8); break; case 's': { int len = GETCHAR; luaL_addchar(&lbuf, len); READ(len); } break; case 'S': { unsigned short len; if (fread(&len, 2, 1, f) < 1) return luaL_error(L, "unexpected EOF"); luaL_addlstring(&lbuf, (char *) &len, 2); READ(len); } break; case 't': { unsigned int len; if (fread(&len, 4, 1, f) < 1) return luaL_error(L, "unexpected EOF"); luaL_addlstring(&lbuf, (char *) &len, 4); READ(len); } break; case 'v': READ(12); break; case 'z': { int c; while ((c = GETCHAR)) { if (c < 0) return luaL_error(L, "unexpected EOF"); luaL_addchar(&lbuf, c); } } break; default: return luaL_error(L, "invalid format string"); } } lua_settop(L, 0); lua_pushcfunction(L, unpack); lua_pushstring(L, fmt_save); luaL_pushresult(&lbuf); lua_call(L, 2, LUA_MULTRET); return lua_gettop(L); }
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 addquoted (lua_State *L, luaL_Buffer *b, int arg) { size_t l; const char *s = luaL_checklstring(L, arg, &l); luaL_addchar(b, '"'); while (l--) { switch(*s) { case '\n': { luaL_addchar(b, '\\'); luaL_addchar(b, 'n'); break; } case '\r': { luaL_addchar(b, '\\'); luaL_addchar(b, 'r'); break; } case '"': { luaL_addchar(b, '\\'); luaL_addchar(b, '"'); break; } case '\\': { luaL_addchar(b, '\\'); luaL_addchar(b, '\\'); break; } case '/': { luaL_addchar(b, '\\'); luaL_addchar(b, '/'); break; } case '\b': { luaL_addchar(b, '\\'); luaL_addchar(b, 'b'); break; } case '\f': { luaL_addchar(b, '\\'); luaL_addchar(b, 'f'); break; } case '\t': { luaL_addchar(b, '\\'); luaL_addchar(b, 't'); break; } default: { if (*s == '\0' || iscntrl(uchar(*s))) { char buff[10]; sprintf(buff, "\\u%04x", (int)uchar(*s)); luaL_addstring(b, buff); } else luaL_addchar(b, *s); } } s++; } luaL_addchar(b, '"'); }