Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ceguilua/src/lua/loslib.c @ 1809

Last change on this file since 1809 was 1806, checked in by rgrieder, 16 years ago

added single 5.1.3 directory for lua since CEGUILua 0.5 can also build against lua 5.1

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
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 <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
23static int os_pushresult (lua_State *L, int i, const char *filename) {
24  int en = errno;  /* calls to Lua API may change this value */
25  if (i) {
26    lua_pushboolean(L, 1);
27    return 1;
28  }
29  else {
30    lua_pushnil(L);
31    lua_pushfstring(L, "%s: %s", filename, strerror(en));
32    lua_pushinteger(L, en);
33    return 3;
34  }
35}
36
37
38static int os_execute (lua_State *L) {
39  lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
40  return 1;
41}
42
43
44static int os_remove (lua_State *L) {
45  const char *filename = luaL_checkstring(L, 1);
46  return os_pushresult(L, remove(filename) == 0, filename);
47}
48
49
50static int os_rename (lua_State *L) {
51  const char *fromname = luaL_checkstring(L, 1);
52  const char *toname = luaL_checkstring(L, 2);
53  return os_pushresult(L, rename(fromname, toname) == 0, fromname);
54}
55
56
57static int os_tmpname (lua_State *L) {
58  char buff[LUA_TMPNAMBUFSIZE];
59  int err;
60  lua_tmpnam(buff, err);
61  if (err)
62    return luaL_error(L, "unable to generate a unique filename");
63  lua_pushstring(L, buff);
64  return 1;
65}
66
67
68static int os_getenv (lua_State *L) {
69  lua_pushstring(L, getenv(luaL_checkstring(L, 1)));  /* if NULL push nil */
70  return 1;
71}
72
73
74static int os_clock (lua_State *L) {
75  lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
76  return 1;
77}
78
79
80/*
81** {======================================================
82** Time/Date operations
83** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
84**   wday=%w+1, yday=%j, isdst=? }
85** =======================================================
86*/
87
88static void setfield (lua_State *L, const char *key, int value) {
89  lua_pushinteger(L, value);
90  lua_setfield(L, -2, key);
91}
92
93static void setboolfield (lua_State *L, const char *key, int value) {
94  if (value < 0)  /* undefined? */
95    return;  /* does not set field */
96  lua_pushboolean(L, value);
97  lua_setfield(L, -2, key);
98}
99
100static int getboolfield (lua_State *L, const char *key) {
101  int res;
102  lua_getfield(L, -1, key);
103  res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
104  lua_pop(L, 1);
105  return res;
106}
107
108
109static int getfield (lua_State *L, const char *key, int d) {
110  int res;
111  lua_getfield(L, -1, key);
112  if (lua_isnumber(L, -1))
113    res = (int)lua_tointeger(L, -1);
114  else {
115    if (d < 0)
116      return luaL_error(L, "field " LUA_QS " missing in date table", key);
117    res = d;
118  }
119  lua_pop(L, 1);
120  return res;
121}
122
123
124static int os_date (lua_State *L) {
125  const char *s = luaL_optstring(L, 1, "%c");
126  time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
127  struct tm *stm;
128  if (*s == '!') {  /* UTC? */
129    stm = gmtime(&t);
130    s++;  /* skip `!' */
131  }
132  else
133    stm = localtime(&t);
134  if (stm == NULL)  /* invalid date? */
135    lua_pushnil(L);
136  else if (strcmp(s, "*t") == 0) {
137    lua_createtable(L, 0, 9);  /* 9 = number of fields */
138    setfield(L, "sec", stm->tm_sec);
139    setfield(L, "min", stm->tm_min);
140    setfield(L, "hour", stm->tm_hour);
141    setfield(L, "day", stm->tm_mday);
142    setfield(L, "month", stm->tm_mon+1);
143    setfield(L, "year", stm->tm_year+1900);
144    setfield(L, "wday", stm->tm_wday+1);
145    setfield(L, "yday", stm->tm_yday+1);
146    setboolfield(L, "isdst", stm->tm_isdst);
147  }
148  else {
149    char cc[3];
150    luaL_Buffer b;
151    cc[0] = '%'; cc[2] = '\0';
152    luaL_buffinit(L, &b);
153    for (; *s; s++) {
154      if (*s != '%' || *(s + 1) == '\0')  /* no conversion specifier? */
155        luaL_addchar(&b, *s);
156      else {
157        size_t reslen;
158        char buff[200];  /* should be big enough for any conversion result */
159        cc[1] = *(++s);
160        reslen = strftime(buff, sizeof(buff), cc, stm);
161        luaL_addlstring(&b, buff, reslen);
162      }
163    }
164    luaL_pushresult(&b);
165  }
166  return 1;
167}
168
169
170static int os_time (lua_State *L) {
171  time_t t;
172  if (lua_isnoneornil(L, 1))  /* called without args? */
173    t = time(NULL);  /* get current time */
174  else {
175    struct tm ts;
176    luaL_checktype(L, 1, LUA_TTABLE);
177    lua_settop(L, 1);  /* make sure table is at the top */
178    ts.tm_sec = getfield(L, "sec", 0);
179    ts.tm_min = getfield(L, "min", 0);
180    ts.tm_hour = getfield(L, "hour", 12);
181    ts.tm_mday = getfield(L, "day", -1);
182    ts.tm_mon = getfield(L, "month", -1) - 1;
183    ts.tm_year = getfield(L, "year", -1) - 1900;
184    ts.tm_isdst = getboolfield(L, "isdst");
185    t = mktime(&ts);
186  }
187  if (t == (time_t)(-1))
188    lua_pushnil(L);
189  else
190    lua_pushnumber(L, (lua_Number)t);
191  return 1;
192}
193
194
195static int os_difftime (lua_State *L) {
196  lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
197                             (time_t)(luaL_optnumber(L, 2, 0))));
198  return 1;
199}
200
201/* }====================================================== */
202
203
204static int os_setlocale (lua_State *L) {
205  static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
206                      LC_NUMERIC, LC_TIME};
207  static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
208     "numeric", "time", NULL};
209  const char *l = luaL_optstring(L, 1, NULL);
210  int op = luaL_checkoption(L, 2, "all", catnames);
211  lua_pushstring(L, setlocale(cat[op], l));
212  return 1;
213}
214
215
216static int os_exit (lua_State *L) {
217  exit(luaL_optint(L, 1, EXIT_SUCCESS));
218}
219
220static const luaL_Reg syslib[] = {
221  {"clock",     os_clock},
222  {"date",      os_date},
223  {"difftime",  os_difftime},
224  {"execute",   os_execute},
225  {"exit",      os_exit},
226  {"getenv",    os_getenv},
227  {"remove",    os_remove},
228  {"rename",    os_rename},
229  {"setlocale", os_setlocale},
230  {"time",      os_time},
231  {"tmpname",   os_tmpname},
232  {NULL, NULL}
233};
234
235/* }====================================================== */
236
237
238
239LUALIB_API int luaopen_os (lua_State *L) {
240  luaL_register(L, LUA_OSLIBNAME, syslib);
241  return 1;
242}
243
Note: See TracBrowser for help on using the repository browser.