rlm@1: /* rlm@1: ** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ rlm@1: ** Auxiliary functions for building Lua libraries rlm@1: ** See Copyright Notice in lua.h rlm@1: */ rlm@1: rlm@1: rlm@1: #include rlm@1: #include rlm@1: #include rlm@1: #include rlm@1: #include rlm@1: #include rlm@1: rlm@1: rlm@1: /* This file uses only the official API of Lua. rlm@1: ** Any function declared here could be written as an application function. rlm@1: */ rlm@1: rlm@1: #define lauxlib_c rlm@1: #define LUA_LIB rlm@1: rlm@1: #include "lua.h" rlm@1: rlm@1: #include "lauxlib.h" rlm@1: rlm@1: rlm@1: #define FREELIST_REF 0 /* free list of references */ rlm@1: rlm@1: rlm@1: /* convert a stack index to positive */ rlm@1: #define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ rlm@1: lua_gettop(L) + (i) + 1) rlm@1: rlm@1: rlm@1: /* rlm@1: ** {====================================================== rlm@1: ** Error-report functions rlm@1: ** ======================================================= rlm@1: */ rlm@1: rlm@1: rlm@1: LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { rlm@1: lua_Debug ar; rlm@1: if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ rlm@1: return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); rlm@1: lua_getinfo(L, "n", &ar); rlm@1: if (strcmp(ar.namewhat, "method") == 0) { rlm@1: narg--; /* do not count `self' */ rlm@1: if (narg == 0) /* error is in the self argument itself? */ rlm@1: return luaL_error(L, "calling " LUA_QS " on bad self (%s)", rlm@1: ar.name, extramsg); rlm@1: } rlm@1: if (ar.name == NULL) rlm@1: ar.name = "?"; rlm@1: return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", rlm@1: narg, ar.name, extramsg); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { rlm@1: const char *msg = lua_pushfstring(L, "%s expected, got %s", rlm@1: tname, luaL_typename(L, narg)); rlm@1: return luaL_argerror(L, narg, msg); rlm@1: } rlm@1: rlm@1: rlm@1: static void tag_error (lua_State *L, int narg, int tag) { rlm@1: luaL_typerror(L, narg, lua_typename(L, tag)); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaL_where (lua_State *L, int level) { rlm@1: lua_Debug ar; rlm@1: if (lua_getstack(L, level, &ar)) { /* check function at level */ rlm@1: lua_getinfo(L, "Sl", &ar); /* get info about it */ rlm@1: if (ar.currentline > 0) { /* is there info? */ rlm@1: lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); rlm@1: return; rlm@1: } rlm@1: } rlm@1: lua_pushliteral(L, ""); /* else, no information available... */ rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { rlm@1: va_list argp; rlm@1: va_start(argp, fmt); rlm@1: luaL_where(L, 1); rlm@1: lua_pushvfstring(L, fmt, argp); rlm@1: va_end(argp); rlm@1: lua_concat(L, 2); rlm@1: return lua_error(L); rlm@1: } rlm@1: rlm@1: /* }====================================================== */ rlm@1: rlm@1: rlm@1: LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, rlm@1: const char *const lst[]) { rlm@1: const char *name = (def) ? luaL_optstring(L, narg, def) : rlm@1: luaL_checkstring(L, narg); rlm@1: int i; rlm@1: for (i=0; lst[i]; i++) rlm@1: if (strcmp(lst[i], name) == 0) rlm@1: return i; rlm@1: return luaL_argerror(L, narg, rlm@1: lua_pushfstring(L, "invalid option " LUA_QS, name)); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { rlm@1: lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ rlm@1: if (!lua_isnil(L, -1)) /* name already in use? */ rlm@1: return 0; /* leave previous value on top, but return 0 */ rlm@1: lua_pop(L, 1); rlm@1: lua_newtable(L); /* create metatable */ rlm@1: lua_pushvalue(L, -1); rlm@1: lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ rlm@1: return 1; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { rlm@1: void *p = lua_touserdata(L, ud); rlm@1: if (p != NULL) { /* value is a userdata? */ rlm@1: if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ rlm@1: lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ rlm@1: if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ rlm@1: lua_pop(L, 2); /* remove both metatables */ rlm@1: return p; rlm@1: } rlm@1: } rlm@1: } rlm@1: luaL_typerror(L, ud, tname); /* else error */ rlm@1: return NULL; /* to avoid warnings */ rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { rlm@1: if (!lua_checkstack(L, space)) rlm@1: luaL_error(L, "stack overflow (%s)", mes); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { rlm@1: if (lua_type(L, narg) != t) rlm@1: tag_error(L, narg, t); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaL_checkany (lua_State *L, int narg) { rlm@1: if (lua_type(L, narg) == LUA_TNONE) rlm@1: luaL_argerror(L, narg, "value expected"); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { rlm@1: const char *s = lua_tolstring(L, narg, len); rlm@1: if (!s) tag_error(L, narg, LUA_TSTRING); rlm@1: return s; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, rlm@1: const char *def, size_t *len) { rlm@1: if (lua_isnoneornil(L, narg)) { rlm@1: if (len) rlm@1: *len = (def ? strlen(def) : 0); rlm@1: return def; rlm@1: } rlm@1: else return luaL_checklstring(L, narg, len); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { rlm@1: lua_Number d = lua_tonumber(L, narg); rlm@1: if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ rlm@1: tag_error(L, narg, LUA_TNUMBER); rlm@1: return d; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { rlm@1: return luaL_opt(L, luaL_checknumber, narg, def); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { rlm@1: lua_Integer d = lua_tointeger(L, narg); rlm@1: if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ rlm@1: tag_error(L, narg, LUA_TNUMBER); rlm@1: return d; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, rlm@1: lua_Integer def) { rlm@1: return luaL_opt(L, luaL_checkinteger, narg, def); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { rlm@1: if (!lua_getmetatable(L, obj)) /* no metatable? */ rlm@1: return 0; rlm@1: lua_pushstring(L, event); rlm@1: lua_rawget(L, -2); rlm@1: if (lua_isnil(L, -1)) { rlm@1: lua_pop(L, 2); /* remove metatable and metafield */ rlm@1: return 0; rlm@1: } rlm@1: else { rlm@1: lua_remove(L, -2); /* remove only metatable */ rlm@1: return 1; rlm@1: } rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { rlm@1: obj = abs_index(L, obj); rlm@1: if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ rlm@1: return 0; rlm@1: lua_pushvalue(L, obj); rlm@1: lua_call(L, 1, 1); rlm@1: return 1; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void (luaL_register) (lua_State *L, const char *libname, rlm@1: const luaL_Reg *l) { rlm@1: luaI_openlib(L, libname, l, 0); rlm@1: } rlm@1: rlm@1: rlm@1: static int libsize (const luaL_Reg *l) { rlm@1: int size = 0; rlm@1: for (; l->name; l++) size++; rlm@1: return size; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaI_openlib (lua_State *L, const char *libname, rlm@1: const luaL_Reg *l, int nup) { rlm@1: if (libname) { rlm@1: int size = libsize(l); rlm@1: /* check whether lib already exists */ rlm@1: luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); rlm@1: lua_getfield(L, -1, libname); /* get _LOADED[libname] */ rlm@1: if (!lua_istable(L, -1)) { /* not found? */ rlm@1: lua_pop(L, 1); /* remove previous result */ rlm@1: /* try global variable (and create one if it does not exist) */ rlm@1: if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) rlm@1: luaL_error(L, "name conflict for module " LUA_QS, libname); rlm@1: lua_pushvalue(L, -1); rlm@1: lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ rlm@1: } rlm@1: lua_remove(L, -2); /* remove _LOADED table */ rlm@1: lua_insert(L, -(nup+1)); /* move library table to below upvalues */ rlm@1: } rlm@1: for (; l->name; l++) { rlm@1: int i; rlm@1: for (i=0; ifunc, nup); rlm@1: lua_setfield(L, -(nup+2), l->name); rlm@1: } rlm@1: lua_pop(L, nup); /* remove upvalues */ rlm@1: } rlm@1: rlm@1: rlm@1: rlm@1: /* rlm@1: ** {====================================================== rlm@1: ** getn-setn: size for arrays rlm@1: ** ======================================================= rlm@1: */ rlm@1: rlm@1: #if defined(LUA_COMPAT_GETN) rlm@1: rlm@1: static int checkint (lua_State *L, int topop) { rlm@1: int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; rlm@1: lua_pop(L, topop); rlm@1: return n; rlm@1: } rlm@1: rlm@1: rlm@1: static void getsizes (lua_State *L) { rlm@1: lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); rlm@1: if (lua_isnil(L, -1)) { /* no `size' table? */ rlm@1: lua_pop(L, 1); /* remove nil */ rlm@1: lua_newtable(L); /* create it */ rlm@1: lua_pushvalue(L, -1); /* `size' will be its own metatable */ rlm@1: lua_setmetatable(L, -2); rlm@1: lua_pushliteral(L, "kv"); rlm@1: lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ rlm@1: lua_pushvalue(L, -1); rlm@1: lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ rlm@1: } rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaL_setn (lua_State *L, int t, int n) { rlm@1: t = abs_index(L, t); rlm@1: lua_pushliteral(L, "n"); rlm@1: lua_rawget(L, t); rlm@1: if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ rlm@1: lua_pushliteral(L, "n"); /* use it */ rlm@1: lua_pushinteger(L, n); rlm@1: lua_rawset(L, t); rlm@1: } rlm@1: else { /* use `sizes' */ rlm@1: getsizes(L); rlm@1: lua_pushvalue(L, t); rlm@1: lua_pushinteger(L, n); rlm@1: lua_rawset(L, -3); /* sizes[t] = n */ rlm@1: lua_pop(L, 1); /* remove `sizes' */ rlm@1: } rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API int luaL_getn (lua_State *L, int t) { rlm@1: int n; rlm@1: t = abs_index(L, t); rlm@1: lua_pushliteral(L, "n"); /* try t.n */ rlm@1: lua_rawget(L, t); rlm@1: if ((n = checkint(L, 1)) >= 0) return n; rlm@1: getsizes(L); /* else try sizes[t] */ rlm@1: lua_pushvalue(L, t); rlm@1: lua_rawget(L, -2); rlm@1: if ((n = checkint(L, 2)) >= 0) return n; rlm@1: return (int)lua_objlen(L, t); rlm@1: } rlm@1: rlm@1: #endif rlm@1: rlm@1: /* }====================================================== */ rlm@1: rlm@1: rlm@1: rlm@1: LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, rlm@1: const char *r) { rlm@1: const char *wild; rlm@1: size_t l = strlen(p); rlm@1: luaL_Buffer b; rlm@1: luaL_buffinit(L, &b); rlm@1: while ((wild = strstr(s, p)) != NULL) { rlm@1: luaL_addlstring(&b, s, wild - s); /* push prefix */ rlm@1: luaL_addstring(&b, r); /* push replacement in place of pattern */ rlm@1: s = wild + l; /* continue after `p' */ rlm@1: } rlm@1: luaL_addstring(&b, s); /* push last suffix */ rlm@1: luaL_pushresult(&b); rlm@1: return lua_tostring(L, -1); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API const char *luaL_findtable (lua_State *L, int idx, rlm@1: const char *fname, int szhint) { rlm@1: const char *e; rlm@1: lua_pushvalue(L, idx); rlm@1: do { rlm@1: e = strchr(fname, '.'); rlm@1: if (e == NULL) e = fname + strlen(fname); rlm@1: lua_pushlstring(L, fname, e - fname); rlm@1: lua_rawget(L, -2); rlm@1: if (lua_isnil(L, -1)) { /* no such field? */ rlm@1: lua_pop(L, 1); /* remove this nil */ rlm@1: lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ rlm@1: lua_pushlstring(L, fname, e - fname); rlm@1: lua_pushvalue(L, -2); rlm@1: lua_settable(L, -4); /* set new table into field */ rlm@1: } rlm@1: else if (!lua_istable(L, -1)) { /* field has a non-table value? */ rlm@1: lua_pop(L, 2); /* remove table and value */ rlm@1: return fname; /* return problematic part of the name */ rlm@1: } rlm@1: lua_remove(L, -2); /* remove previous table */ rlm@1: fname = e + 1; rlm@1: } while (*e == '.'); rlm@1: return NULL; rlm@1: } rlm@1: rlm@1: rlm@1: rlm@1: /* rlm@1: ** {====================================================== rlm@1: ** Generic Buffer manipulation rlm@1: ** ======================================================= rlm@1: */ rlm@1: rlm@1: rlm@1: #define bufflen(B) ((B)->p - (B)->buffer) rlm@1: #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) rlm@1: rlm@1: #define LIMIT (LUA_MINSTACK/2) rlm@1: rlm@1: rlm@1: static int emptybuffer (luaL_Buffer *B) { rlm@1: size_t l = bufflen(B); rlm@1: if (l == 0) return 0; /* put nothing on stack */ rlm@1: else { rlm@1: lua_pushlstring(B->L, B->buffer, l); rlm@1: B->p = B->buffer; rlm@1: B->lvl++; rlm@1: return 1; rlm@1: } rlm@1: } rlm@1: rlm@1: rlm@1: static void adjuststack (luaL_Buffer *B) { rlm@1: if (B->lvl > 1) { rlm@1: lua_State *L = B->L; rlm@1: int toget = 1; /* number of levels to concat */ rlm@1: size_t toplen = lua_strlen(L, -1); rlm@1: do { rlm@1: size_t l = lua_strlen(L, -(toget+1)); rlm@1: if (B->lvl - toget + 1 >= LIMIT || toplen > l) { rlm@1: toplen += l; rlm@1: toget++; rlm@1: } rlm@1: else break; rlm@1: } while (toget < B->lvl); rlm@1: lua_concat(L, toget); rlm@1: B->lvl = B->lvl - toget + 1; rlm@1: } rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { rlm@1: if (emptybuffer(B)) rlm@1: adjuststack(B); rlm@1: return B->buffer; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { rlm@1: while (l--) rlm@1: luaL_addchar(B, *s++); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { rlm@1: luaL_addlstring(B, s, strlen(s)); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaL_pushresult (luaL_Buffer *B) { rlm@1: emptybuffer(B); rlm@1: lua_concat(B->L, B->lvl); rlm@1: B->lvl = 1; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaL_addvalue (luaL_Buffer *B) { rlm@1: lua_State *L = B->L; rlm@1: size_t vl; rlm@1: const char *s = lua_tolstring(L, -1, &vl); rlm@1: if (vl <= bufffree(B)) { /* fit into buffer? */ rlm@1: memcpy(B->p, s, vl); /* put it there */ rlm@1: B->p += vl; rlm@1: lua_pop(L, 1); /* remove from stack */ rlm@1: } rlm@1: else { rlm@1: if (emptybuffer(B)) rlm@1: lua_insert(L, -2); /* put buffer before new value */ rlm@1: B->lvl++; /* add new value into B stack */ rlm@1: adjuststack(B); rlm@1: } rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { rlm@1: B->L = L; rlm@1: B->p = B->buffer; rlm@1: B->lvl = 0; rlm@1: } rlm@1: rlm@1: /* }====================================================== */ rlm@1: rlm@1: rlm@1: LUALIB_API int luaL_ref (lua_State *L, int t) { rlm@1: int ref; rlm@1: t = abs_index(L, t); rlm@1: if (lua_isnil(L, -1)) { rlm@1: lua_pop(L, 1); /* remove from stack */ rlm@1: return LUA_REFNIL; /* `nil' has a unique fixed reference */ rlm@1: } rlm@1: lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ rlm@1: ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ rlm@1: lua_pop(L, 1); /* remove it from stack */ rlm@1: if (ref != 0) { /* any free element? */ rlm@1: lua_rawgeti(L, t, ref); /* remove it from list */ rlm@1: lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ rlm@1: } rlm@1: else { /* no free elements */ rlm@1: ref = (int)lua_objlen(L, t); rlm@1: ref++; /* create new reference */ rlm@1: } rlm@1: lua_rawseti(L, t, ref); rlm@1: return ref; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { rlm@1: if (ref >= 0) { rlm@1: t = abs_index(L, t); rlm@1: lua_rawgeti(L, t, FREELIST_REF); rlm@1: lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ rlm@1: lua_pushinteger(L, ref); rlm@1: lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ rlm@1: } rlm@1: } rlm@1: rlm@1: rlm@1: rlm@1: /* rlm@1: ** {====================================================== rlm@1: ** Load functions rlm@1: ** ======================================================= rlm@1: */ rlm@1: rlm@1: typedef struct LoadF { rlm@1: int extraline; rlm@1: FILE *f; rlm@1: char buff[LUAL_BUFFERSIZE]; rlm@1: } LoadF; rlm@1: rlm@1: rlm@1: static const char *getF (lua_State *L, void *ud, size_t *size) { rlm@1: LoadF *lf = (LoadF *)ud; rlm@1: (void)L; rlm@1: if (lf->extraline) { rlm@1: lf->extraline = 0; rlm@1: *size = 1; rlm@1: return "\n"; rlm@1: } rlm@1: if (feof(lf->f)) return NULL; rlm@1: *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); rlm@1: return (*size > 0) ? lf->buff : NULL; rlm@1: } rlm@1: rlm@1: rlm@1: static int errfile (lua_State *L, const char *what, int fnameindex) { rlm@1: const char *serr = strerror(errno); rlm@1: const char *filename = lua_tostring(L, fnameindex) + 1; rlm@1: lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); rlm@1: lua_remove(L, fnameindex); rlm@1: return LUA_ERRFILE; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { rlm@1: LoadF lf; rlm@1: int status, readstatus; rlm@1: int c; rlm@1: int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ rlm@1: lf.extraline = 0; rlm@1: if (filename == NULL) { rlm@1: lua_pushliteral(L, "=stdin"); rlm@1: lf.f = stdin; rlm@1: } rlm@1: else { rlm@1: lua_pushfstring(L, "@%s", filename); rlm@1: lf.f = fopen(filename, "r"); rlm@1: if (lf.f == NULL) return errfile(L, "open", fnameindex); rlm@1: } rlm@1: c = getc(lf.f); rlm@1: if (c == '#') { /* Unix exec. file? */ rlm@1: lf.extraline = 1; rlm@1: while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ rlm@1: if (c == '\n') c = getc(lf.f); rlm@1: } rlm@1: if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ rlm@1: lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ rlm@1: if (lf.f == NULL) return errfile(L, "reopen", fnameindex); rlm@1: /* skip eventual `#!...' */ rlm@1: while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; rlm@1: lf.extraline = 0; rlm@1: } rlm@1: ungetc(c, lf.f); rlm@1: status = lua_load(L, getF, &lf, lua_tostring(L, -1)); rlm@1: readstatus = ferror(lf.f); rlm@1: if (filename) fclose(lf.f); /* close file (even in case of errors) */ rlm@1: if (readstatus) { rlm@1: lua_settop(L, fnameindex); /* ignore results from `lua_load' */ rlm@1: return errfile(L, "read", fnameindex); rlm@1: } rlm@1: lua_remove(L, fnameindex); rlm@1: return status; rlm@1: } rlm@1: rlm@1: rlm@1: typedef struct LoadS { rlm@1: const char *s; rlm@1: size_t size; rlm@1: } LoadS; rlm@1: rlm@1: rlm@1: static const char *getS (lua_State *L, void *ud, size_t *size) { rlm@1: LoadS *ls = (LoadS *)ud; rlm@1: (void)L; rlm@1: if (ls->size == 0) return NULL; rlm@1: *size = ls->size; rlm@1: ls->size = 0; rlm@1: return ls->s; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, rlm@1: const char *name) { rlm@1: LoadS ls; rlm@1: ls.s = buff; rlm@1: ls.size = size; rlm@1: return lua_load(L, getS, &ls, name); rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { rlm@1: return luaL_loadbuffer(L, s, strlen(s), s); rlm@1: } rlm@1: rlm@1: rlm@1: rlm@1: /* }====================================================== */ rlm@1: rlm@1: rlm@1: static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { rlm@1: (void)ud; rlm@1: (void)osize; rlm@1: if (nsize == 0) { rlm@1: free(ptr); rlm@1: return NULL; rlm@1: } rlm@1: else rlm@1: return realloc(ptr, nsize); rlm@1: } rlm@1: rlm@1: rlm@1: static int panic (lua_State *L) { rlm@1: (void)L; /* to avoid warnings */ rlm@1: fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", rlm@1: lua_tostring(L, -1)); rlm@1: return 0; rlm@1: } rlm@1: rlm@1: rlm@1: LUALIB_API lua_State *luaL_newstate (void) { rlm@1: lua_State *L = lua_newstate(l_alloc, NULL); rlm@1: if (L) lua_atpanic(L, &panic); rlm@1: return L; rlm@1: } rlm@1: