LCOV - code coverage report
Current view: top level - src - loslib.c Hit Total Coverage
Test: Lua 5.1.5 Lines: 113 115 98.3 %
Date: 2014-12-13 17:49:16
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11