|
|
@ -1,5 +1,5 @@ |
|
|
|
/*
|
|
|
|
** $Id: loslib.c,v 1.56 2015/02/09 17:41:54 roberto Exp roberto $ |
|
|
|
** $Id: loslib.c,v 1.57 2015/04/10 17:41:04 roberto Exp roberto $ |
|
|
|
** Standard Operating System library |
|
|
|
** See Copyright Notice in lua.h |
|
|
|
*/ |
|
|
@ -54,7 +54,12 @@ |
|
|
|
*/ |
|
|
|
#define l_timet lua_Integer |
|
|
|
#define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) |
|
|
|
#define l_checktime(L,a) ((time_t)luaL_checkinteger(L,a)) |
|
|
|
|
|
|
|
static time_t l_checktime (lua_State *L, int arg) { |
|
|
|
lua_Integer t = luaL_checkinteger(L, arg); |
|
|
|
luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds"); |
|
|
|
return (time_t)t; |
|
|
|
} |
|
|
|
|
|
|
|
#endif /* } */ |
|
|
|
|
|
|
@ -198,17 +203,29 @@ static int getboolfield (lua_State *L, const char *key) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int getfield (lua_State *L, const char *key, int d) { |
|
|
|
int res, isnum; |
|
|
|
lua_getfield(L, -1, key); |
|
|
|
res = (int)lua_tointegerx(L, -1, &isnum); |
|
|
|
if (!isnum) { |
|
|
|
if (d < 0) |
|
|
|
/* maximum value for date fields (to avoid arithmetic overflows with 'int') */ |
|
|
|
#if !defined(L_MAXDATEFIELD) |
|
|
|
#define L_MAXDATEFIELD (INT_MAX / 2) |
|
|
|
#endif |
|
|
|
|
|
|
|
static int getfield (lua_State *L, const char *key, int d, int delta) { |
|
|
|
int isnum; |
|
|
|
int t = lua_getfield(L, -1, key); |
|
|
|
lua_Integer res = lua_tointegerx(L, -1, &isnum); |
|
|
|
if (!isnum) { /* field is not a number? */ |
|
|
|
if (t != LUA_TNIL) /* some other value? */ |
|
|
|
return luaL_error(L, "field '%s' not an integer", key); |
|
|
|
else if (d < 0) /* abssent field; no default? */ |
|
|
|
return luaL_error(L, "field '%s' missing in date table", key); |
|
|
|
res = d; |
|
|
|
} |
|
|
|
else { |
|
|
|
if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD)) |
|
|
|
return luaL_error(L, "field '%s' out-of-bounds", key); |
|
|
|
res -= delta; |
|
|
|
} |
|
|
|
lua_pop(L, 1); |
|
|
|
return res; |
|
|
|
return (int)res; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -247,8 +264,8 @@ static int os_date (lua_State *L) { |
|
|
|
else |
|
|
|
stm = l_localtime(&t, &tmr); |
|
|
|
if (stm == NULL) /* invalid date? */ |
|
|
|
lua_pushnil(L); |
|
|
|
else if (strcmp(s, "*t") == 0) { |
|
|
|
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 */ |
|
|
|
setfield(L, "sec", stm->tm_sec); |
|
|
|
setfield(L, "min", stm->tm_min); |
|
|
@ -290,21 +307,18 @@ static int os_time (lua_State *L) { |
|
|
|
struct tm ts; |
|
|
|
luaL_checktype(L, 1, LUA_TTABLE); |
|
|
|
lua_settop(L, 1); /* make sure table is at the top */ |
|
|
|
ts.tm_sec = getfield(L, "sec", 0); |
|
|
|
ts.tm_min = getfield(L, "min", 0); |
|
|
|
ts.tm_hour = getfield(L, "hour", 12); |
|
|
|
ts.tm_mday = getfield(L, "day", -1); |
|
|
|
ts.tm_mon = getfield(L, "month", -1) - 1; |
|
|
|
ts.tm_year = getfield(L, "year", -1) - 1900; |
|
|
|
ts.tm_sec = getfield(L, "sec", 0, 0); |
|
|
|
ts.tm_min = getfield(L, "min", 0, 0); |
|
|
|
ts.tm_hour = getfield(L, "hour", 12, 0); |
|
|
|
ts.tm_mday = getfield(L, "day", -1, 0); |
|
|
|
ts.tm_mon = getfield(L, "month", -1, 1); |
|
|
|
ts.tm_year = getfield(L, "year", -1, 1900); |
|
|
|
ts.tm_isdst = getboolfield(L, "isdst"); |
|
|
|
t = mktime(&ts); |
|
|
|
} |
|
|
|
if (t != (time_t)(l_timet)t) |
|
|
|
luaL_error(L, "time result cannot be represented in this Lua installation"); |
|
|
|
else if (t == (time_t)(-1)) |
|
|
|
lua_pushnil(L); |
|
|
|
else |
|
|
|
l_pushtime(L, t); |
|
|
|
if (t != (time_t)(l_timet)t || t == (time_t)(-1)) |
|
|
|
luaL_error(L, "time result cannot be represented in this installation"); |
|
|
|
l_pushtime(L, t); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|