summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/loslib.c
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2009-05-27 22:48:50 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2009-05-27 22:48:50 +0000
commitb2581e143d7c9a564026fbe3bf4f471b2260fd0f (patch)
treef6a25e4d6626fa986da215db75f781b1d85bc2cc /apps/plugins/lua/loslib.c
parent64595105b1e63eedcd0c47290cf6c0d5e7e4cd46 (diff)
downloadrockbox-b2581e143d7c9a564026fbe3bf4f471b2260fd0f.tar.gz
rockbox-b2581e143d7c9a564026fbe3bf4f471b2260fd0f.zip
Lua: add support for os library
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21106 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/lua/loslib.c')
-rw-r--r--apps/plugins/lua/loslib.c199
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
22static 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
37static 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
43static 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
58static void setfield (lua_State *L, const char *key, int value) {
59 lua_pushinteger(L, value);
60 lua_setfield(L, -2, key);
61}
62
63static 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
70static 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
79static 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
94static 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
142static 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
172static int os_exit (lua_State *L) {
173 exit(luaL_optint(L, 1, EXIT_SUCCESS));
174}
175
176static 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
195LUALIB_API int luaopen_os (lua_State *L) {
196 luaL_register(L, LUA_OSLIBNAME, syslib);
197 return 1;
198}
199