1
0
Fork 0
forked from len0rd/rockbox

Lua: add support for os library

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21106 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Maurus Cuelenaere 2009-05-27 22:48:50 +00:00
parent 64595105b1
commit b2581e143d
7 changed files with 398 additions and 3 deletions

View file

@ -1,7 +1,9 @@
The following files are (with slight modifications for Rockbox) from dietlibc The following files are (with slight modifications for Rockbox) from dietlibc
version 0.31 which is licensed under the GPL version 2: version 0.31 which is licensed under the GPL version 2:
gmtime.c
strcspn.c strcspn.c
strftime.c
strncat.c strncat.c
strpbrk.c strpbrk.c
strtol.c strtol.c

View file

@ -11,6 +11,7 @@ llex.c
lmem.c lmem.c
lobject.c lobject.c
lopcodes.c lopcodes.c
loslib.c
lparser.c lparser.c
lstate.c lstate.c
lstring.c lstring.c
@ -24,7 +25,9 @@ lzio.c
rockaux.c rockaux.c
rocklib.c rocklib.c
rockmalloc.c rockmalloc.c
gmtime.c
strcspn.c strcspn.c
strftime.c
strncat.c strncat.c
strpbrk.c strpbrk.c
strtoul.c strtoul.c

58
apps/plugins/lua/gmtime.c Normal file
View file

@ -0,0 +1,58 @@
#include <time.h>
/* seconds per day */
#define SPD 24*60*60
/* days per month -- nonleap! */
const short __spm[13] =
{ 0,
(31),
(31+28),
(31+28+31),
(31+28+31+30),
(31+28+31+30+31),
(31+28+31+30+31+30),
(31+28+31+30+31+30+31),
(31+28+31+30+31+30+31+31),
(31+28+31+30+31+30+31+31+30),
(31+28+31+30+31+30+31+31+30+31),
(31+28+31+30+31+30+31+31+30+31+30),
(31+28+31+30+31+30+31+31+30+31+30+31),
};
int __isleap(int year) {
/* every fourth year is a leap year except for century years that are
* not divisible by 400. */
/* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */
return (!(year%4) && ((year%100) || !(year%400)));
}
struct tm *gmtime(const time_t *timep) {
static struct tm r;
time_t i;
register time_t work=*timep%(SPD);
r.tm_sec=work%60; work/=60;
r.tm_min=work%60; r.tm_hour=work/60;
work=*timep/(SPD);
r.tm_wday=(4+work)%7;
for (i=1970; ; ++i) {
register time_t k=__isleap(i)?366:365;
if (work>=k)
work-=k;
else
break;
}
r.tm_year=i-1900;
r.tm_yday=work;
r.tm_mday=1;
if (__isleap(i) && (work>58)) {
if (work==59) r.tm_mday=2; /* 29.2. */
work-=1;
}
for (i=11; i && (__spm[i]>work); --i) ;
r.tm_mon=i;
r.tm_mday+=work-__spm[i];
return &r;
}

199
apps/plugins/lua/loslib.c Normal file
View file

@ -0,0 +1,199 @@
/*
** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define loslib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
static int os_pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
if (i) {
lua_pushboolean(L, 1);
return 1;
}
else {
lua_pushnil(L);
lua_pushfstring(L, "%s: %s", filename, strerror(en));
lua_pushinteger(L, en);
return 3;
}
}
static int os_remove (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
return os_pushresult(L, rb->remove(filename) == 0, filename);
}
static int os_rename (lua_State *L) {
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
return os_pushresult(L, rb->rename(fromname, toname) == 0, fromname);
}
/*
** {======================================================
** Time/Date operations
** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
** wday=%w+1, yday=%j, isdst=? }
** =======================================================
*/
static void setfield (lua_State *L, const char *key, int value) {
lua_pushinteger(L, value);
lua_setfield(L, -2, key);
}
static void setboolfield (lua_State *L, const char *key, int value) {
if (value < 0) /* undefined? */
return; /* does not set field */
lua_pushboolean(L, value);
lua_setfield(L, -2, key);
}
static int getboolfield (lua_State *L, const char *key) {
int res;
lua_getfield(L, -1, key);
res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}
static int getfield (lua_State *L, const char *key, int d) {
int res;
lua_getfield(L, -1, key);
if (lua_isnumber(L, -1))
res = (int)lua_tointeger(L, -1);
else {
if (d < 0)
return luaL_error(L, "field " LUA_QS " missing in date table", key);
res = d;
}
lua_pop(L, 1);
return res;
}
static int os_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, "%c");
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2,
#if CONFIG_RTC
rb->mktime(rb->get_time())
#else
0
#endif
);
struct tm *stm;
if (*s == '!') /* UTC? */ /* Rockbox doesn't support timezones */
s++; /* skip `!' */
stm = gmtime(&t);
if (stm == NULL) /* invalid date? */
lua_pushnil(L);
else 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);
setfield(L, "hour", stm->tm_hour);
setfield(L, "day", stm->tm_mday);
setfield(L, "month", stm->tm_mon+1);
setfield(L, "year", stm->tm_year+1900);
setfield(L, "wday", stm->tm_wday+1);
setfield(L, "yday", stm->tm_yday+1);
setboolfield(L, "isdst", stm->tm_isdst);
}
else {
char cc[3];
luaL_Buffer b;
cc[0] = '%'; cc[2] = '\0';
luaL_buffinit(L, &b);
for (; *s; s++) {
if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */
luaL_addchar(&b, *s);
else {
size_t reslen;
char buff[200]; /* should be big enough for any conversion result */
cc[1] = *(++s);
reslen = strftime(buff, sizeof(buff), cc, stm);
luaL_addlstring(&b, buff, reslen);
}
}
luaL_pushresult(&b);
}
return 1;
}
static int os_time (lua_State *L) {
time_t t = -1;
#if CONFIG_RTC
if (lua_isnoneornil(L, 1)) /* called without args? */
t = rb->mktime(rb->get_time()); /* get current time */
else {
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_isdst = getboolfield(L, "isdst");
t = rb->mktime(&ts);
}
#endif
if (t == (time_t)(-1))
lua_pushnil(L);
else
lua_pushnumber(L, (lua_Number)t);
return 1;
}
/* }====================================================== */
static int os_exit (lua_State *L) {
exit(luaL_optint(L, 1, EXIT_SUCCESS));
}
static const luaL_Reg syslib[] = {
//{"clock", os_clock},
{"date", os_date},
//{"difftime", os_difftime},
//{"execute", os_execute},
{"exit", os_exit},
//{"getenv", os_getenv},
{"remove", os_remove},
{"rename", os_rename},
//{"setlocale", os_setlocale},
{"time", os_time},
//{"tmpname", os_tmpname},
{NULL, NULL}
};
/* }====================================================== */
LUALIB_API int luaopen_os (lua_State *L) {
luaL_register(L, LUA_OSLIBNAME, syslib);
return 1;
}

View file

@ -43,8 +43,10 @@
extern char curpath[MAX_PATH]; extern char curpath[MAX_PATH];
void *dlrealloc(void *ptr, size_t size); void *dlrealloc(void *ptr, size_t size);
void dlfree(void *ptr); void dlfree(void *ptr);
struct tm *gmtime(const time_t *timep);
long strtol(const char *nptr, char **endptr, int base); long strtol(const char *nptr, char **endptr, int base);
unsigned long strtoul(const char *str, char **endptr, int base); unsigned long strtoul(const char *str, char **endptr, int base);
size_t strftime(char* dst, size_t max, const char* format, const struct tm* tm);
long floor(long x); long floor(long x);
long pow(long x, long y); long pow(long x, long y);

View file

@ -30,9 +30,10 @@
PLUGIN_HEADER PLUGIN_HEADER
static const luaL_Reg lualibs[] = { static const luaL_Reg lualibs[] = {
{"", luaopen_base}, {"", luaopen_base},
{LUA_TABLIBNAME, luaopen_table}, {LUA_TABLIBNAME, luaopen_table},
{LUA_STRLIBNAME, luaopen_string}, {LUA_STRLIBNAME, luaopen_string},
{LUA_OSLIBNAME, luaopen_os},
{LUA_ROCKLIBNAME, luaopen_rock}, {LUA_ROCKLIBNAME, luaopen_rock},
{NULL, NULL} {NULL, NULL}
}; };

130
apps/plugins/lua/strftime.c Normal file
View file

@ -0,0 +1,130 @@
#include <sys/types.h>
#include <time.h>
#include "plugin.h"
static const char sweekdays [7] [4] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static const char weekdays [7] [10] = {
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
};
static const char smonths [12] [4] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static const char* months [12] = {
"January", "February", "March", "April", smonths[5-1], "June",
"July", "August", "September", "October", "November", "December"
};
static const char ampm [4] [3] = {
"am", "pm",
"AM", "PM"
};
static void i2a ( char* dest,unsigned long x )
{
int div = 10;
*dest++ = x/div + '0';
*dest++ = x%div + '0';
*dest++ = '\0';
}
size_t strftime ( char* dst, size_t max, const char* format, const struct tm* tm )
{
char* p = dst;
const char* src;
unsigned long no;
char buf [5];
if (!max) return 0;
for ( ; *format != '\0'; format++ ) {
if (*format == '%') {
if (*++format == '%') {
*p++ = '%';
}
else
again:
switch (*format) {
// case '%': *p++ = '%'; break; // reduce size of jump table
case 'n': *p++ = '\n'; break;
case 't': *p++ = '\t'; break;
case 'O': case 'E': ++format; goto again;
case 'c': src = "%b %a %d %k:%M:%S %Z %Y"; goto _strf;
case 'r': src = "%I:%M:%S %p"; goto _strf;
case 'R': src = "%H:%M"; goto _strf;
case 'x': src = "%b %a %d"; goto _strf;
case 'X': src = "%k:%M:%S"; goto _strf;
case 'D': src = "%m/%d/%y"; goto _strf;
case 'T': src = "%H:%M:%S";
_strf: p += strftime (p, (size_t)(dst+max-p), src, tm); break;
case 'a': src = sweekdays [tm->tm_wday]; goto _str;
case 'A': src = weekdays [tm->tm_wday]; goto _str;
case 'h':
case 'b': src = smonths [tm->tm_mon]; goto _str;
case 'B': src = months [tm->tm_mon]; goto _str;
case 'p': src = ampm [tm->tm_hour > 12 ? 3 : 2]; goto _str;
case 'P': src = ampm [tm->tm_hour > 12 ? 1 : 0]; goto _str;
case 'C': no = tm->tm_year/100 + 19; goto _no;
case 'd': no = tm->tm_mday; goto _no;
case 'e': no = tm->tm_mday; goto _nos;
case 'H': no = tm->tm_hour; goto _no;
case 'I': no = tm->tm_hour % 12; goto _no;
case 'j': no = tm->tm_yday; goto _no;
case 'k': no = tm->tm_hour; goto _nos;
case 'l': no = tm->tm_hour % 12; goto _nos;
case 'm': no = tm->tm_mon + 1; goto _no;
case 'M': no = tm->tm_min; goto _no;
case 'S': no = tm->tm_sec; goto _no;
case 'u': no = tm->tm_wday ? tm->tm_wday : 7; goto _no;
case 'w': no = tm->tm_wday; goto _no;
case 'U': no = (tm->tm_yday - tm->tm_wday + 7) / 7; goto _no;
case 'W': no = (tm->tm_yday - (tm->tm_wday - 1 + 7) % 7 + 7) / 7; goto _no;
case 's': {
time_t t = rb->mktime((struct tm*)tm);
char buf[101];
char* c;
buf[100]=0;
for (c=buf+99; c>buf; --c) {
*c=(t%10)+'0';
t/=10;
if (!t) break;
}
src=c;
goto _str;
}
case 'Z':
#ifdef WANT_TZFILE_PARSER
tzset(); src = tzname[0];
#else
src = "[unknown timezone]";
#endif
goto _str;
case 'Y': i2a ( buf+0, (unsigned int)(tm->tm_year / 100 + 19) );
i2a ( buf+2, (unsigned int)(tm->tm_year % 100) );
src = buf;
goto _str;
case 'y': no = tm->tm_year % 100; goto _no;
_no: i2a ( buf, no ); /* append number 'no' */
src = buf;
goto _str;
_nos: i2a ( buf, no ); /* the same, but '0'->' ' */
if (buf[0] == '0')
buf[0] = ' ';
src = buf;
_str: while (*src && p < dst+max) /* append string */
*p++ = *src++;
break;
};
} else {
*p++ = *format;
}
if (p >= dst+max)
break;
}
*p = '\0';
return p - dst;
}