diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-07-09 12:47:48 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-07-09 12:47:48 -0300 |
| commit | 85f1d70e68efca3fba475e4a477457a54b7cedcc (patch) | |
| tree | 8651d0c3570901bb12fc79c572ae936ce169f23e | |
| parent | 31f6540fba010b941b44b2bd21672786d2e63e7f (diff) | |
| download | lua-85f1d70e68efca3fba475e4a477457a54b7cedcc.tar.gz lua-85f1d70e68efca3fba475e4a477457a54b7cedcc.tar.bz2 lua-85f1d70e68efca3fba475e4a477457a54b7cedcc.zip | |
OS lib (finally separated from io lib)
| -rw-r--r-- | loslib.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/loslib.c b/loslib.c new file mode 100644 index 00000000..d65a0b53 --- /dev/null +++ b/loslib.c | |||
| @@ -0,0 +1,241 @@ | |||
| 1 | /* | ||
| 2 | ** $Id: loslib.c,v $ | ||
| 3 | ** Standard Operating System library | ||
| 4 | ** See Copyright Notice in lua.h | ||
| 5 | */ | ||
| 6 | |||
| 7 | |||
| 8 | #include <errno.h> | ||
| 9 | #include <locale.h> | ||
| 10 | #include <stdlib.h> | ||
| 11 | #include <string.h> | ||
| 12 | #include <time.h> | ||
| 13 | |||
| 14 | #define loslib_c | ||
| 15 | #define LUA_LIB | ||
| 16 | |||
| 17 | #include "lua.h" | ||
| 18 | |||
| 19 | #include "lauxlib.h" | ||
| 20 | #include "lualib.h" | ||
| 21 | |||
| 22 | |||
| 23 | static int pushresult (lua_State *L, int i, const char *filename) { | ||
| 24 | if (i) { | ||
| 25 | lua_pushboolean(L, 1); | ||
| 26 | return 1; | ||
| 27 | } | ||
| 28 | else { | ||
| 29 | lua_pushnil(L); | ||
| 30 | if (filename) | ||
| 31 | lua_pushfstring(L, "%s: %s", filename, strerror(errno)); | ||
| 32 | else | ||
| 33 | lua_pushfstring(L, "%s", strerror(errno)); | ||
| 34 | lua_pushinteger(L, errno); | ||
| 35 | return 3; | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | |||
| 40 | static int io_execute (lua_State *L) { | ||
| 41 | lua_pushinteger(L, system(luaL_checkstring(L, 1))); | ||
| 42 | return 1; | ||
| 43 | } | ||
| 44 | |||
| 45 | |||
| 46 | static int io_remove (lua_State *L) { | ||
| 47 | const char *filename = luaL_checkstring(L, 1); | ||
| 48 | return pushresult(L, remove(filename) == 0, filename); | ||
| 49 | } | ||
| 50 | |||
| 51 | |||
| 52 | static int io_rename (lua_State *L) { | ||
| 53 | const char *fromname = luaL_checkstring(L, 1); | ||
| 54 | const char *toname = luaL_checkstring(L, 2); | ||
| 55 | return pushresult(L, rename(fromname, toname) == 0, fromname); | ||
| 56 | } | ||
| 57 | |||
| 58 | |||
| 59 | static int io_tmpname (lua_State *L) { | ||
| 60 | #if !USE_TMPNAME | ||
| 61 | luaL_error(L, "`tmpname' not supported"); | ||
| 62 | return 0; | ||
| 63 | #else | ||
| 64 | char buff[L_tmpnam]; | ||
| 65 | if (tmpnam(buff) != buff) | ||
| 66 | return luaL_error(L, "unable to generate a unique filename in `tmpname'"); | ||
| 67 | lua_pushstring(L, buff); | ||
| 68 | return 1; | ||
| 69 | #endif | ||
| 70 | } | ||
| 71 | |||
| 72 | |||
| 73 | static int io_getenv (lua_State *L) { | ||
| 74 | lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ | ||
| 75 | return 1; | ||
| 76 | } | ||
| 77 | |||
| 78 | |||
| 79 | static int io_clock (lua_State *L) { | ||
| 80 | lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); | ||
| 81 | return 1; | ||
| 82 | } | ||
| 83 | |||
| 84 | |||
| 85 | /* | ||
| 86 | ** {====================================================== | ||
| 87 | ** Time/Date operations | ||
| 88 | ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, | ||
| 89 | ** wday=%w+1, yday=%j, isdst=? } | ||
| 90 | ** ======================================================= | ||
| 91 | */ | ||
| 92 | |||
| 93 | static void setfield (lua_State *L, const char *key, int value) { | ||
| 94 | lua_pushstring(L, key); | ||
| 95 | lua_pushinteger(L, value); | ||
| 96 | lua_rawset(L, -3); | ||
| 97 | } | ||
| 98 | |||
| 99 | static void setboolfield (lua_State *L, const char *key, int value) { | ||
| 100 | lua_pushstring(L, key); | ||
| 101 | lua_pushboolean(L, value); | ||
| 102 | lua_rawset(L, -3); | ||
| 103 | } | ||
| 104 | |||
| 105 | static int getboolfield (lua_State *L, const char *key) { | ||
| 106 | int res; | ||
| 107 | lua_getfield(L, -1, key); | ||
| 108 | res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); | ||
| 109 | lua_pop(L, 1); | ||
| 110 | return res; | ||
| 111 | } | ||
| 112 | |||
| 113 | |||
| 114 | static int getfield (lua_State *L, const char *key, int d) { | ||
| 115 | int res; | ||
| 116 | lua_getfield(L, -1, key); | ||
| 117 | if (lua_isnumber(L, -1)) | ||
| 118 | res = (int)lua_tointeger(L, -1); | ||
| 119 | else { | ||
| 120 | if (d < 0) | ||
| 121 | return luaL_error(L, "field `%s' missing in date table", key); | ||
| 122 | res = d; | ||
| 123 | } | ||
| 124 | lua_pop(L, 1); | ||
| 125 | return res; | ||
| 126 | } | ||
| 127 | |||
| 128 | |||
| 129 | static int io_date (lua_State *L) { | ||
| 130 | const char *s = luaL_optstring(L, 1, "%c"); | ||
| 131 | lua_Number n = luaL_optnumber(L, 2, -1); | ||
| 132 | time_t t = (n == -1) ? time(NULL) : (time_t)n; | ||
| 133 | struct tm *stm; | ||
| 134 | if (*s == '!') { /* UTC? */ | ||
| 135 | stm = gmtime(&t); | ||
| 136 | s++; /* skip `!' */ | ||
| 137 | } | ||
| 138 | else | ||
| 139 | stm = localtime(&t); | ||
| 140 | if (stm == NULL) /* invalid date? */ | ||
| 141 | lua_pushnil(L); | ||
| 142 | else if (strcmp(s, "*t") == 0) { | ||
| 143 | lua_createtable(L, 0, 9); /* 9 = number of fields */ | ||
| 144 | setfield(L, "sec", stm->tm_sec); | ||
| 145 | setfield(L, "min", stm->tm_min); | ||
| 146 | setfield(L, "hour", stm->tm_hour); | ||
| 147 | setfield(L, "day", stm->tm_mday); | ||
| 148 | setfield(L, "month", stm->tm_mon+1); | ||
| 149 | setfield(L, "year", stm->tm_year+1900); | ||
| 150 | setfield(L, "wday", stm->tm_wday+1); | ||
| 151 | setfield(L, "yday", stm->tm_yday+1); | ||
| 152 | setboolfield(L, "isdst", stm->tm_isdst); | ||
| 153 | } | ||
| 154 | else { | ||
| 155 | char b[256]; | ||
| 156 | if (strftime(b, sizeof(b), s, stm)) | ||
| 157 | lua_pushstring(L, b); | ||
| 158 | else | ||
| 159 | return luaL_error(L, "`date' format too long"); | ||
| 160 | } | ||
| 161 | return 1; | ||
| 162 | } | ||
| 163 | |||
| 164 | |||
| 165 | static int io_time (lua_State *L) { | ||
| 166 | if (lua_isnoneornil(L, 1)) /* called without args? */ | ||
| 167 | lua_pushnumber(L, time(NULL)); /* return current time */ | ||
| 168 | else { | ||
| 169 | time_t t; | ||
| 170 | struct tm ts; | ||
| 171 | luaL_checktype(L, 1, LUA_TTABLE); | ||
| 172 | lua_settop(L, 1); /* make sure table is at the top */ | ||
| 173 | ts.tm_sec = getfield(L, "sec", 0); | ||
| 174 | ts.tm_min = getfield(L, "min", 0); | ||
| 175 | ts.tm_hour = getfield(L, "hour", 12); | ||
| 176 | ts.tm_mday = getfield(L, "day", -1); | ||
| 177 | ts.tm_mon = getfield(L, "month", -1) - 1; | ||
| 178 | ts.tm_year = getfield(L, "year", -1) - 1900; | ||
| 179 | ts.tm_isdst = getboolfield(L, "isdst"); | ||
| 180 | t = mktime(&ts); | ||
| 181 | if (t == (time_t)(-1)) | ||
| 182 | lua_pushnil(L); | ||
| 183 | else | ||
| 184 | lua_pushnumber(L, t); | ||
| 185 | } | ||
| 186 | return 1; | ||
| 187 | } | ||
| 188 | |||
| 189 | |||
| 190 | static int io_difftime (lua_State *L) { | ||
| 191 | lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), | ||
| 192 | (time_t)(luaL_optnumber(L, 2, 0)))); | ||
| 193 | return 1; | ||
| 194 | } | ||
| 195 | |||
| 196 | /* }====================================================== */ | ||
| 197 | |||
| 198 | |||
| 199 | static int io_setloc (lua_State *L) { | ||
| 200 | static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, | ||
| 201 | LC_NUMERIC, LC_TIME}; | ||
| 202 | static const char *const catnames[] = {"all", "collate", "ctype", "monetary", | ||
| 203 | "numeric", "time", NULL}; | ||
| 204 | const char *l = lua_tostring(L, 1); | ||
| 205 | int op = luaL_findstring(luaL_optstring(L, 2, "all"), catnames); | ||
| 206 | luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected"); | ||
| 207 | luaL_argcheck(L, op != -1, 2, "invalid option"); | ||
| 208 | lua_pushstring(L, setlocale(cat[op], l)); | ||
| 209 | return 1; | ||
| 210 | } | ||
| 211 | |||
| 212 | |||
| 213 | static int io_exit (lua_State *L) { | ||
| 214 | exit(luaL_optint(L, 1, EXIT_SUCCESS)); | ||
| 215 | return 0; /* to avoid warnings */ | ||
| 216 | } | ||
| 217 | |||
| 218 | static const luaL_reg syslib[] = { | ||
| 219 | {"clock", io_clock}, | ||
| 220 | {"date", io_date}, | ||
| 221 | {"difftime", io_difftime}, | ||
| 222 | {"execute", io_execute}, | ||
| 223 | {"exit", io_exit}, | ||
| 224 | {"getenv", io_getenv}, | ||
| 225 | {"remove", io_remove}, | ||
| 226 | {"rename", io_rename}, | ||
| 227 | {"setlocale", io_setloc}, | ||
| 228 | {"time", io_time}, | ||
| 229 | {"tmpname", io_tmpname}, | ||
| 230 | {NULL, NULL} | ||
| 231 | }; | ||
| 232 | |||
| 233 | /* }====================================================== */ | ||
| 234 | |||
| 235 | |||
| 236 | |||
| 237 | LUALIB_API int luaopen_os (lua_State *L) { | ||
| 238 | luaL_openlib(L, LUA_OSLIBNAME, syslib, 0); | ||
| 239 | return 1; | ||
| 240 | } | ||
| 241 | |||
