diff options
Diffstat (limited to 'apps/plugins/lua/loslib.c')
-rw-r--r-- | apps/plugins/lua/loslib.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/apps/plugins/lua/loslib.c b/apps/plugins/lua/loslib.c new file mode 100644 index 0000000000..9d29e905e1 --- /dev/null +++ b/apps/plugins/lua/loslib.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | ** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ | ||
3 | ** Standard Operating System library | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <errno.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <string.h> | ||
11 | #include <time.h> | ||
12 | |||
13 | #define loslib_c | ||
14 | #define LUA_LIB | ||
15 | |||
16 | #include "lua.h" | ||
17 | |||
18 | #include "lauxlib.h" | ||
19 | #include "lualib.h" | ||
20 | |||
21 | |||
22 | static int os_pushresult (lua_State *L, int i, const char *filename) { | ||
23 | int en = errno; /* calls to Lua API may change this value */ | ||
24 | if (i) { | ||
25 | lua_pushboolean(L, 1); | ||
26 | return 1; | ||
27 | } | ||
28 | else { | ||
29 | lua_pushnil(L); | ||
30 | lua_pushfstring(L, "%s: %s", filename, strerror(en)); | ||
31 | lua_pushinteger(L, en); | ||
32 | return 3; | ||
33 | } | ||
34 | } | ||
35 | |||
36 | |||
37 | static int os_remove (lua_State *L) { | ||
38 | const char *filename = luaL_checkstring(L, 1); | ||
39 | return os_pushresult(L, rb->remove(filename) == 0, filename); | ||
40 | } | ||
41 | |||
42 | |||
43 | static int os_rename (lua_State *L) { | ||
44 | const char *fromname = luaL_checkstring(L, 1); | ||
45 | const char *toname = luaL_checkstring(L, 2); | ||
46 | return os_pushresult(L, rb->rename(fromname, toname) == 0, fromname); | ||
47 | } | ||
48 | |||
49 | |||
50 | /* | ||
51 | ** {====================================================== | ||
52 | ** Time/Date operations | ||
53 | ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, | ||
54 | ** wday=%w+1, yday=%j, isdst=? } | ||
55 | ** ======================================================= | ||
56 | */ | ||
57 | |||
58 | static void setfield (lua_State *L, const char *key, int value) { | ||
59 | lua_pushinteger(L, value); | ||
60 | lua_setfield(L, -2, key); | ||
61 | } | ||
62 | |||
63 | static void setboolfield (lua_State *L, const char *key, int value) { | ||
64 | if (value < 0) /* undefined? */ | ||
65 | return; /* does not set field */ | ||
66 | lua_pushboolean(L, value); | ||
67 | lua_setfield(L, -2, key); | ||
68 | } | ||
69 | |||
70 | static int getboolfield (lua_State *L, const char *key) { | ||
71 | int res; | ||
72 | lua_getfield(L, -1, key); | ||
73 | res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); | ||
74 | lua_pop(L, 1); | ||
75 | return res; | ||
76 | } | ||
77 | |||
78 | |||
79 | static int getfield (lua_State *L, const char *key, int d) { | ||
80 | int res; | ||
81 | lua_getfield(L, -1, key); | ||
82 | if (lua_isnumber(L, -1)) | ||
83 | res = (int)lua_tointeger(L, -1); | ||
84 | else { | ||
85 | if (d < 0) | ||
86 | return luaL_error(L, "field " LUA_QS " missing in date table", key); | ||
87 | res = d; | ||
88 | } | ||
89 | lua_pop(L, 1); | ||
90 | return res; | ||
91 | } | ||
92 | |||
93 | |||
94 | static int os_date (lua_State *L) { | ||
95 | const char *s = luaL_optstring(L, 1, "%c"); | ||
96 | time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, | ||
97 | #if CONFIG_RTC | ||
98 | rb->mktime(rb->get_time()) | ||
99 | #else | ||
100 | 0 | ||
101 | #endif | ||
102 | ); | ||
103 | struct tm *stm; | ||
104 | if (*s == '!') /* UTC? */ /* Rockbox doesn't support timezones */ | ||
105 | s++; /* skip `!' */ | ||
106 | stm = gmtime(&t); | ||
107 | if (stm == NULL) /* invalid date? */ | ||
108 | lua_pushnil(L); | ||
109 | else if (strcmp(s, "*t") == 0) { | ||
110 | lua_createtable(L, 0, 9); /* 9 = number of fields */ | ||
111 | setfield(L, "sec", stm->tm_sec); | ||
112 | setfield(L, "min", stm->tm_min); | ||
113 | setfield(L, "hour", stm->tm_hour); | ||
114 | setfield(L, "day", stm->tm_mday); | ||
115 | setfield(L, "month", stm->tm_mon+1); | ||
116 | setfield(L, "year", stm->tm_year+1900); | ||
117 | setfield(L, "wday", stm->tm_wday+1); | ||
118 | setfield(L, "yday", stm->tm_yday+1); | ||
119 | setboolfield(L, "isdst", stm->tm_isdst); | ||
120 | } | ||
121 | else { | ||
122 | char cc[3]; | ||
123 | luaL_Buffer b; | ||
124 | cc[0] = '%'; cc[2] = '\0'; | ||
125 | luaL_buffinit(L, &b); | ||
126 | for (; *s; s++) { | ||
127 | if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ | ||
128 | luaL_addchar(&b, *s); | ||
129 | else { | ||
130 | size_t reslen; | ||
131 | char buff[200]; /* should be big enough for any conversion result */ | ||
132 | cc[1] = *(++s); | ||
133 | reslen = strftime(buff, sizeof(buff), cc, stm); | ||
134 | luaL_addlstring(&b, buff, reslen); | ||
135 | } | ||
136 | } | ||
137 | luaL_pushresult(&b); | ||
138 | } | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | static int os_time (lua_State *L) { | ||
143 | time_t t = -1; | ||
144 | #if CONFIG_RTC | ||
145 | if (lua_isnoneornil(L, 1)) /* called without args? */ | ||
146 | t = rb->mktime(rb->get_time()); /* get current time */ | ||
147 | else { | ||
148 | struct tm ts; | ||
149 | luaL_checktype(L, 1, LUA_TTABLE); | ||
150 | lua_settop(L, 1); /* make sure table is at the top */ | ||
151 | ts.tm_sec = getfield(L, "sec", 0); | ||
152 | ts.tm_min = getfield(L, "min", 0); | ||
153 | ts.tm_hour = getfield(L, "hour", 12); | ||
154 | ts.tm_mday = getfield(L, "day", -1); | ||
155 | ts.tm_mon = getfield(L, "month", -1) - 1; | ||
156 | ts.tm_year = getfield(L, "year", -1) - 1900; | ||
157 | ts.tm_isdst = getboolfield(L, "isdst"); | ||
158 | t = rb->mktime(&ts); | ||
159 | } | ||
160 | #endif | ||
161 | if (t == (time_t)(-1)) | ||
162 | lua_pushnil(L); | ||
163 | else | ||
164 | lua_pushnumber(L, (lua_Number)t); | ||
165 | return 1; | ||
166 | } | ||
167 | |||
168 | |||
169 | /* }====================================================== */ | ||
170 | |||
171 | |||
172 | static int os_exit (lua_State *L) { | ||
173 | exit(luaL_optint(L, 1, EXIT_SUCCESS)); | ||
174 | } | ||
175 | |||
176 | static const luaL_Reg syslib[] = { | ||
177 | //{"clock", os_clock}, | ||
178 | {"date", os_date}, | ||
179 | //{"difftime", os_difftime}, | ||
180 | //{"execute", os_execute}, | ||
181 | {"exit", os_exit}, | ||
182 | //{"getenv", os_getenv}, | ||
183 | {"remove", os_remove}, | ||
184 | {"rename", os_rename}, | ||
185 | //{"setlocale", os_setlocale}, | ||
186 | {"time", os_time}, | ||
187 | //{"tmpname", os_tmpname}, | ||
188 | {NULL, NULL} | ||
189 | }; | ||
190 | |||
191 | /* }====================================================== */ | ||
192 | |||
193 | |||
194 | |||
195 | LUALIB_API int luaopen_os (lua_State *L) { | ||
196 | luaL_register(L, LUA_OSLIBNAME, syslib); | ||
197 | return 1; | ||
198 | } | ||
199 | |||