123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- /* Read-only tables for Lua */
- #define LUAC_CROSS_FILE
- #include "lua.h"
- #include C_HEADER_STRING
- #include "lrotable.h"
- #include "lauxlib.h"
- #include "lstring.h"
- #include "lobject.h"
- #include "lapi.h"
- /* Local defines */
- #define LUAR_FINDFUNCTION 0
- #define LUAR_FINDVALUE 1
- /* Externally defined read-only table array */
- extern const luaR_table lua_rotable[];
- /* Find a global "read only table" in the constant lua_rotable array */
- void* luaR_findglobal(const char *name, unsigned len) {
- unsigned i;
- if (c_strlen(name) > LUA_MAX_ROTABLE_NAME)
- return NULL;
- for (i=0; lua_rotable[i].name; i ++)
- if (*lua_rotable[i].name != '\0' && c_strlen(lua_rotable[i].name) == len && !c_strncmp(lua_rotable[i].name, name, len)) {
- return (void*)(lua_rotable[i].pentries);
- }
- return NULL;
- }
- /* Find an entry in a rotable and return it */
- static const TValue* luaR_auxfind(const luaR_entry *pentry, const char *strkey, luaR_numkey numkey, unsigned *ppos) {
- const TValue *res = NULL;
- unsigned i = 0;
-
- if (pentry == NULL)
- return NULL;
- while(pentry->key.type != LUA_TNIL) {
- if ((strkey && (pentry->key.type == LUA_TSTRING) && (!c_strcmp(pentry->key.id.strkey, strkey))) ||
- (!strkey && (pentry->key.type == LUA_TNUMBER) && ((luaR_numkey)pentry->key.id.numkey == numkey))) {
- res = &pentry->value;
- break;
- }
- i ++; pentry ++;
- }
- if (res && ppos)
- *ppos = i;
- return res;
- }
- int luaR_findfunction(lua_State *L, const luaR_entry *ptable) {
- const TValue *res = NULL;
- const char *key = luaL_checkstring(L, 2);
-
- res = luaR_auxfind(ptable, key, 0, NULL);
- if (res && ttislightfunction(res)) {
- luaA_pushobject(L, res);
- return 1;
- }
- else
- return 0;
- }
- /* Find an entry in a rotable and return its type
- If "strkey" is not NULL, the function will look for a string key,
- otherwise it will look for a number key */
- const TValue* luaR_findentry(void *data, const char *strkey, luaR_numkey numkey, unsigned *ppos) {
- return luaR_auxfind((const luaR_entry*)data, strkey, numkey, ppos);
- }
- /* Find the metatable of a given table */
- void* luaR_getmeta(void *data) {
- #ifdef LUA_META_ROTABLES
- const TValue *res = luaR_auxfind((const luaR_entry*)data, "__metatable", 0, NULL);
- return res && ttisrotable(res) ? rvalue(res) : NULL;
- #else
- return NULL;
- #endif
- }
- static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos, TValue *key, TValue *val) {
- setnilvalue(key);
- setnilvalue(val);
- if (pentries[pos].key.type != LUA_TNIL) {
- /* Found an entry */
- if (pentries[pos].key.type == LUA_TSTRING)
- setsvalue(L, key, luaS_newro(L, pentries[pos].key.id.strkey))
- else
- setnvalue(key, (lua_Number)pentries[pos].key.id.numkey)
- setobj2s(L, val, &pentries[pos].value);
- }
- }
- /* next (used for iteration) */
- void luaR_next(lua_State *L, void *data, TValue *key, TValue *val) {
- const luaR_entry* pentries = (const luaR_entry*)data;
- char strkey[LUA_MAX_ROTABLE_NAME + 1], *pstrkey = NULL;
- luaR_numkey numkey = 0;
- unsigned keypos;
-
- /* Special case: if key is nil, return the first element of the rotable */
- if (ttisnil(key))
- luaR_next_helper(L, pentries, 0, key, val);
- else if (ttisstring(key) || ttisnumber(key)) {
- /* Find the previoud key again */
- if (ttisstring(key)) {
- luaR_getcstr(strkey, rawtsvalue(key), LUA_MAX_ROTABLE_NAME);
- pstrkey = strkey;
- } else
- numkey = (luaR_numkey)nvalue(key);
- luaR_findentry(data, pstrkey, numkey, &keypos);
- /* Advance to next key */
- keypos ++;
- luaR_next_helper(L, pentries, keypos, key, val);
- }
- }
- /* Convert a Lua string to a C string */
- void luaR_getcstr(char *dest, const TString *src, size_t maxsize) {
- if (src->tsv.len+1 > maxsize)
- dest[0] = '\0';
- else {
- c_memcpy(dest, getstr(src), src->tsv.len);
- dest[src->tsv.len] = '\0';
- }
- }
- /* Return 1 if the given pointer is a rotable */
- #ifdef LUA_META_ROTABLES
- #include "compiler.h"
- int luaR_isrotable(void *p) {
- return RODATA_START_ADDRESS <= (char*)p && (char*)p <= RODATA_END_ADDRESS;
- }
- #endif
|