diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/lua/README | 2 | ||||
-rw-r--r-- | apps/plugins/lua/SOURCES | 3 | ||||
-rw-r--r-- | apps/plugins/lua/gmtime.c | 58 | ||||
-rw-r--r-- | apps/plugins/lua/loslib.c | 199 | ||||
-rw-r--r-- | apps/plugins/lua/rockconf.h | 2 | ||||
-rw-r--r-- | apps/plugins/lua/rocklua.c | 7 | ||||
-rw-r--r-- | apps/plugins/lua/strftime.c | 130 |
7 files changed, 398 insertions, 3 deletions
diff --git a/apps/plugins/lua/README b/apps/plugins/lua/README index 593aad2ee7..db6933f517 100644 --- a/apps/plugins/lua/README +++ b/apps/plugins/lua/README | |||
@@ -1,7 +1,9 @@ | |||
1 | The following files are (with slight modifications for Rockbox) from dietlibc | 1 | The following files are (with slight modifications for Rockbox) from dietlibc |
2 | version 0.31 which is licensed under the GPL version 2: | 2 | version 0.31 which is licensed under the GPL version 2: |
3 | 3 | ||
4 | gmtime.c | ||
4 | strcspn.c | 5 | strcspn.c |
6 | strftime.c | ||
5 | strncat.c | 7 | strncat.c |
6 | strpbrk.c | 8 | strpbrk.c |
7 | strtol.c | 9 | strtol.c |
diff --git a/apps/plugins/lua/SOURCES b/apps/plugins/lua/SOURCES index 3b9f9348bd..058b991417 100644 --- a/apps/plugins/lua/SOURCES +++ b/apps/plugins/lua/SOURCES | |||
@@ -11,6 +11,7 @@ llex.c | |||
11 | lmem.c | 11 | lmem.c |
12 | lobject.c | 12 | lobject.c |
13 | lopcodes.c | 13 | lopcodes.c |
14 | loslib.c | ||
14 | lparser.c | 15 | lparser.c |
15 | lstate.c | 16 | lstate.c |
16 | lstring.c | 17 | lstring.c |
@@ -24,7 +25,9 @@ lzio.c | |||
24 | rockaux.c | 25 | rockaux.c |
25 | rocklib.c | 26 | rocklib.c |
26 | rockmalloc.c | 27 | rockmalloc.c |
28 | gmtime.c | ||
27 | strcspn.c | 29 | strcspn.c |
30 | strftime.c | ||
28 | strncat.c | 31 | strncat.c |
29 | strpbrk.c | 32 | strpbrk.c |
30 | strtoul.c | 33 | strtoul.c |
diff --git a/apps/plugins/lua/gmtime.c b/apps/plugins/lua/gmtime.c new file mode 100644 index 0000000000..f13c855de8 --- /dev/null +++ b/apps/plugins/lua/gmtime.c | |||
@@ -0,0 +1,58 @@ | |||
1 | #include <time.h> | ||
2 | |||
3 | /* seconds per day */ | ||
4 | #define SPD 24*60*60 | ||
5 | |||
6 | /* days per month -- nonleap! */ | ||
7 | const short __spm[13] = | ||
8 | { 0, | ||
9 | (31), | ||
10 | (31+28), | ||
11 | (31+28+31), | ||
12 | (31+28+31+30), | ||
13 | (31+28+31+30+31), | ||
14 | (31+28+31+30+31+30), | ||
15 | (31+28+31+30+31+30+31), | ||
16 | (31+28+31+30+31+30+31+31), | ||
17 | (31+28+31+30+31+30+31+31+30), | ||
18 | (31+28+31+30+31+30+31+31+30+31), | ||
19 | (31+28+31+30+31+30+31+31+30+31+30), | ||
20 | (31+28+31+30+31+30+31+31+30+31+30+31), | ||
21 | }; | ||
22 | |||
23 | int __isleap(int year) { | ||
24 | /* every fourth year is a leap year except for century years that are | ||
25 | * not divisible by 400. */ | ||
26 | /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */ | ||
27 | return (!(year%4) && ((year%100) || !(year%400))); | ||
28 | } | ||
29 | |||
30 | struct tm *gmtime(const time_t *timep) { | ||
31 | static struct tm r; | ||
32 | time_t i; | ||
33 | register time_t work=*timep%(SPD); | ||
34 | r.tm_sec=work%60; work/=60; | ||
35 | r.tm_min=work%60; r.tm_hour=work/60; | ||
36 | work=*timep/(SPD); | ||
37 | r.tm_wday=(4+work)%7; | ||
38 | for (i=1970; ; ++i) { | ||
39 | register time_t k=__isleap(i)?366:365; | ||
40 | if (work>=k) | ||
41 | work-=k; | ||
42 | else | ||
43 | break; | ||
44 | } | ||
45 | r.tm_year=i-1900; | ||
46 | r.tm_yday=work; | ||
47 | |||
48 | r.tm_mday=1; | ||
49 | if (__isleap(i) && (work>58)) { | ||
50 | if (work==59) r.tm_mday=2; /* 29.2. */ | ||
51 | work-=1; | ||
52 | } | ||
53 | |||
54 | for (i=11; i && (__spm[i]>work); --i) ; | ||
55 | r.tm_mon=i; | ||
56 | r.tm_mday+=work-__spm[i]; | ||
57 | return &r; | ||
58 | } | ||
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 | |||
diff --git a/apps/plugins/lua/rockconf.h b/apps/plugins/lua/rockconf.h index 7ae2245c3a..1b267c78e6 100644 --- a/apps/plugins/lua/rockconf.h +++ b/apps/plugins/lua/rockconf.h | |||
@@ -43,8 +43,10 @@ | |||
43 | extern char curpath[MAX_PATH]; | 43 | extern char curpath[MAX_PATH]; |
44 | void *dlrealloc(void *ptr, size_t size); | 44 | void *dlrealloc(void *ptr, size_t size); |
45 | void dlfree(void *ptr); | 45 | void dlfree(void *ptr); |
46 | struct tm *gmtime(const time_t *timep); | ||
46 | long strtol(const char *nptr, char **endptr, int base); | 47 | long strtol(const char *nptr, char **endptr, int base); |
47 | unsigned long strtoul(const char *str, char **endptr, int base); | 48 | unsigned long strtoul(const char *str, char **endptr, int base); |
49 | size_t strftime(char* dst, size_t max, const char* format, const struct tm* tm); | ||
48 | long floor(long x); | 50 | long floor(long x); |
49 | long pow(long x, long y); | 51 | long pow(long x, long y); |
50 | 52 | ||
diff --git a/apps/plugins/lua/rocklua.c b/apps/plugins/lua/rocklua.c index 5360090cab..1162c026d1 100644 --- a/apps/plugins/lua/rocklua.c +++ b/apps/plugins/lua/rocklua.c | |||
@@ -30,9 +30,10 @@ | |||
30 | PLUGIN_HEADER | 30 | PLUGIN_HEADER |
31 | 31 | ||
32 | static const luaL_Reg lualibs[] = { | 32 | static const luaL_Reg lualibs[] = { |
33 | {"", luaopen_base}, | 33 | {"", luaopen_base}, |
34 | {LUA_TABLIBNAME, luaopen_table}, | 34 | {LUA_TABLIBNAME, luaopen_table}, |
35 | {LUA_STRLIBNAME, luaopen_string}, | 35 | {LUA_STRLIBNAME, luaopen_string}, |
36 | {LUA_OSLIBNAME, luaopen_os}, | ||
36 | {LUA_ROCKLIBNAME, luaopen_rock}, | 37 | {LUA_ROCKLIBNAME, luaopen_rock}, |
37 | {NULL, NULL} | 38 | {NULL, NULL} |
38 | }; | 39 | }; |
diff --git a/apps/plugins/lua/strftime.c b/apps/plugins/lua/strftime.c new file mode 100644 index 0000000000..df230f7bd0 --- /dev/null +++ b/apps/plugins/lua/strftime.c | |||
@@ -0,0 +1,130 @@ | |||
1 | #include <sys/types.h> | ||
2 | #include <time.h> | ||
3 | #include "plugin.h" | ||
4 | |||
5 | static const char sweekdays [7] [4] = { | ||
6 | "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" | ||
7 | }; | ||
8 | static const char weekdays [7] [10] = { | ||
9 | "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" | ||
10 | }; | ||
11 | static const char smonths [12] [4] = { | ||
12 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", | ||
13 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" | ||
14 | }; | ||
15 | static const char* months [12] = { | ||
16 | "January", "February", "March", "April", smonths[5-1], "June", | ||
17 | "July", "August", "September", "October", "November", "December" | ||
18 | }; | ||
19 | static const char ampm [4] [3] = { | ||
20 | "am", "pm", | ||
21 | "AM", "PM" | ||
22 | }; | ||
23 | |||
24 | static void i2a ( char* dest,unsigned long x ) | ||
25 | { | ||
26 | int div = 10; | ||
27 | *dest++ = x/div + '0'; | ||
28 | *dest++ = x%div + '0'; | ||
29 | *dest++ = '\0'; | ||
30 | } | ||
31 | |||
32 | size_t strftime ( char* dst, size_t max, const char* format, const struct tm* tm ) | ||
33 | { | ||
34 | char* p = dst; | ||
35 | const char* src; | ||
36 | unsigned long no; | ||
37 | char buf [5]; | ||
38 | |||
39 | if (!max) return 0; | ||
40 | for ( ; *format != '\0'; format++ ) { | ||
41 | if (*format == '%') { | ||
42 | if (*++format == '%') { | ||
43 | *p++ = '%'; | ||
44 | } | ||
45 | else | ||
46 | again: | ||
47 | switch (*format) { | ||
48 | // case '%': *p++ = '%'; break; // reduce size of jump table | ||
49 | case 'n': *p++ = '\n'; break; | ||
50 | case 't': *p++ = '\t'; break; | ||
51 | case 'O': case 'E': ++format; goto again; | ||
52 | case 'c': src = "%b %a %d %k:%M:%S %Z %Y"; goto _strf; | ||
53 | case 'r': src = "%I:%M:%S %p"; goto _strf; | ||
54 | case 'R': src = "%H:%M"; goto _strf; | ||
55 | case 'x': src = "%b %a %d"; goto _strf; | ||
56 | case 'X': src = "%k:%M:%S"; goto _strf; | ||
57 | case 'D': src = "%m/%d/%y"; goto _strf; | ||
58 | case 'T': src = "%H:%M:%S"; | ||
59 | _strf: p += strftime (p, (size_t)(dst+max-p), src, tm); break; | ||
60 | case 'a': src = sweekdays [tm->tm_wday]; goto _str; | ||
61 | case 'A': src = weekdays [tm->tm_wday]; goto _str; | ||
62 | case 'h': | ||
63 | case 'b': src = smonths [tm->tm_mon]; goto _str; | ||
64 | case 'B': src = months [tm->tm_mon]; goto _str; | ||
65 | case 'p': src = ampm [tm->tm_hour > 12 ? 3 : 2]; goto _str; | ||
66 | case 'P': src = ampm [tm->tm_hour > 12 ? 1 : 0]; goto _str; | ||
67 | case 'C': no = tm->tm_year/100 + 19; goto _no; | ||
68 | case 'd': no = tm->tm_mday; goto _no; | ||
69 | case 'e': no = tm->tm_mday; goto _nos; | ||
70 | case 'H': no = tm->tm_hour; goto _no; | ||
71 | case 'I': no = tm->tm_hour % 12; goto _no; | ||
72 | case 'j': no = tm->tm_yday; goto _no; | ||
73 | case 'k': no = tm->tm_hour; goto _nos; | ||
74 | case 'l': no = tm->tm_hour % 12; goto _nos; | ||
75 | case 'm': no = tm->tm_mon + 1; goto _no; | ||
76 | case 'M': no = tm->tm_min; goto _no; | ||
77 | case 'S': no = tm->tm_sec; goto _no; | ||
78 | case 'u': no = tm->tm_wday ? tm->tm_wday : 7; goto _no; | ||
79 | case 'w': no = tm->tm_wday; goto _no; | ||
80 | case 'U': no = (tm->tm_yday - tm->tm_wday + 7) / 7; goto _no; | ||
81 | case 'W': no = (tm->tm_yday - (tm->tm_wday - 1 + 7) % 7 + 7) / 7; goto _no; | ||
82 | case 's': { | ||
83 | time_t t = rb->mktime((struct tm*)tm); | ||
84 | char buf[101]; | ||
85 | char* c; | ||
86 | buf[100]=0; | ||
87 | for (c=buf+99; c>buf; --c) { | ||
88 | *c=(t%10)+'0'; | ||
89 | t/=10; | ||
90 | if (!t) break; | ||
91 | } | ||
92 | src=c; | ||
93 | goto _str; | ||
94 | } | ||
95 | case 'Z': | ||
96 | #ifdef WANT_TZFILE_PARSER | ||
97 | tzset(); src = tzname[0]; | ||
98 | #else | ||
99 | src = "[unknown timezone]"; | ||
100 | #endif | ||
101 | goto _str; | ||
102 | case 'Y': i2a ( buf+0, (unsigned int)(tm->tm_year / 100 + 19) ); | ||
103 | i2a ( buf+2, (unsigned int)(tm->tm_year % 100) ); | ||
104 | src = buf; | ||
105 | goto _str; | ||
106 | case 'y': no = tm->tm_year % 100; goto _no; | ||
107 | _no: i2a ( buf, no ); /* append number 'no' */ | ||
108 | src = buf; | ||
109 | goto _str; | ||
110 | _nos: i2a ( buf, no ); /* the same, but '0'->' ' */ | ||
111 | if (buf[0] == '0') | ||
112 | buf[0] = ' '; | ||
113 | src = buf; | ||
114 | _str: while (*src && p < dst+max) /* append string */ | ||
115 | *p++ = *src++; | ||
116 | break; | ||
117 | }; | ||
118 | } else { | ||
119 | *p++ = *format; | ||
120 | } | ||
121 | |||
122 | if (p >= dst+max) | ||
123 | break; | ||
124 | } | ||
125 | |||
126 | *p = '\0'; | ||
127 | return p - dst; | ||
128 | } | ||
129 | |||
130 | |||