#include "lua/upb.h"
#include <float.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "lauxlib.h"
#include "upb/message/message.h"
static bool lua_isinteger(lua_State* L, int argn) {
LUPB_UNUSED(L);
LUPB_UNUSED(argn);
return false;
}
void lupb_checkstatus(lua_State* L, upb_Status* s) {
if (!upb_Status_IsOk(s)) {
lua_pushstring(L, upb_Status_ErrorMessage(s));
lua_error(L);
}
}
void* lupb_newuserdata(lua_State* L, size_t size, int n, const char* type) {
#if LUA_VERSION_NUM >= 504
void* ret = lua_newuserdatauv(L, size, n);
#else
void* ret = lua_newuserdata(L, size);
lua_createtable(L, 0, n);
lua_setuservalue(L, -2);
#endif
luaL_getmetatable(L, type);
assert(!lua_isnil(L, -1));
lua_setmetatable(L, -2);
return ret;
}
#if LUA_VERSION_NUM < 504
int lua_setiuservalue(lua_State* L, int index, int n) {
lua_getuservalue(L, index);
lua_insert(L, -2);
lua_rawseti(L, -2, n);
lua_pop(L, 1);
return 1;
}
int lua_getiuservalue(lua_State* L, int index, int n) {
lua_getuservalue(L, index);
lua_rawgeti(L, -1, n);
lua_replace(L, -2);
return 1;
}
#endif
int lupb_indexmm(lua_State* L) {
lua_pushvalue(L, 2);
lua_rawget(L, lua_upvalueindex(1));
if (!lua_isnil(L, -1)) {
return 1;
}
lua_pushvalue(L, lua_upvalueindex(2));
lua_pushvalue(L, 1);
lua_pushvalue(L, 2);
lua_call(L, 2, 1);
return 1;
}
void lupb_register_type(lua_State* L, const char* name, const luaL_Reg* m,
const luaL_Reg* mm) {
luaL_newmetatable(L, name);
if (mm) {
lupb_setfuncs(L, mm);
}
if (m) {
lua_createtable(L, 0, 0);
lupb_setfuncs(L, m);
lua_getfield(L, -2, "__index");
if (lua_isnil(L, -1)) {
lua_pop(L, 1);
} else {
lua_pushcclosure(L, &lupb_indexmm, 2);
}
lua_setfield(L, -2, "__index");
}
lua_pop(L, 1);
}
bool lupb_checkbool(lua_State* L, int narg) {
if (!lua_isboolean(L, narg)) {
luaL_error(L, "must be true or false");
}
return lua_toboolean(L, narg);
}
const char* lupb_checkstring(lua_State* L, int narg, size_t* len) {
if (lua_type(L, narg) != LUA_TSTRING) {
luaL_error(L, "Expected string");
}
return lua_tolstring(L, narg, len);
}
#define INTCHECK(type, ctype, min, max) \
ctype lupb_check##type(lua_State* L, int narg) { \
double n; \
if (lua_isinteger(L, narg)) { \
return lua_tointeger(L, narg); \
} \
\
\
luaL_checktype(L, narg, LUA_TNUMBER); \
n = lua_tonumber(L, narg); \
\
\
double i; \
double max_value = (((double)max / 2) * 2) + 1; \
if ((modf(n, &i) != 0.0) || n < min || n >= max_value) { \
luaL_error(L, "number %f was not an integer or out of range for " #type, \
n); \
} \
return (ctype)n; \
} \
void lupb_push##type(lua_State* L, ctype val) { \
\
\
\
lua_pushnumber(L, val); \
}
INTCHECK(int64, int64_t, INT64_MIN, INT64_MAX)
INTCHECK(int32, int32_t, INT32_MIN, INT32_MAX)
INTCHECK(uint64, uint64_t, 0, UINT64_MAX)
INTCHECK(uint32, uint32_t, 0, UINT32_MAX)
double lupb_checkdouble(lua_State* L, int narg) {
luaL_checktype(L, narg, LUA_TNUMBER);
return lua_tonumber(L, narg);
}
float lupb_checkfloat(lua_State* L, int narg) {
luaL_checktype(L, narg, LUA_TNUMBER);
return lua_tonumber(L, narg);
}
void lupb_pushdouble(lua_State* L, double d) { lua_pushnumber(L, d); }
void lupb_pushfloat(lua_State* L, float d) { lua_pushnumber(L, d); }
int luaopen_lupb(lua_State* L) {
#if LUA_VERSION_NUM == 501
const struct luaL_Reg funcs[] = {{NULL, NULL}};
luaL_register(L, "upb_c", funcs);
#else
lua_createtable(L, 0, 8);
#endif
lupb_def_registertypes(L);
lupb_msg_registertypes(L);
return 1;
}