CHDK_DE Vorschauversion  Trunk Rev. 6014
 Alle Datenstrukturen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
loslib.c-Dateireferenz
#include <errno.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <dirent.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
+ Include-Abhängigkeitsdiagramm für loslib.c:

gehe zum Quellcode dieser Datei

Datenstrukturen

struct  idir_udata_t
 

Makrodefinitionen

#define loslib_c
 
#define LUA_LIB
 
#define IDIR_META   "chdk_idir_meta"
 

Funktionen

static int os_pushresult (lua_State *L, int i, const char *filename)
 
static int os_remove (lua_State *L)
 
static int os_rename (lua_State *L)
 
static void setfield (lua_State *L, const char *key, int value)
 
static void setboolfield (lua_State *L, const char *key, int value)
 
static int getboolfield (lua_State *L, const char *key)
 
static int getfield (lua_State *L, const char *key, int d)
 
static int os_date (lua_State *L)
 
static int os_time (lua_State *L)
 
static int os_difftime (lua_State *L)
 
static int os_mkdir (lua_State *L)
 
static int get_table_optbool (lua_State *L, int narg, const char *fname, int d)
 
static int os_listdir (lua_State *L)
 
static int idir_iter (lua_State *L)
 
static int idir_gc (lua_State *L)
 
static int os_idir (lua_State *L)
 
static void idir_register (lua_State *L)
 
static int os_stat (lua_State *L)
 
static int os_utime (lua_State *L)
 
LUALIB_API int luaopen_os (lua_State *L)
 

Variablen

static const luaL_Reg idir_meta_methods []
 
static const luaL_Reg syslib []
 

Makro-Dokumentation

#define IDIR_META   "chdk_idir_meta"

Definiert in Zeile 312 der Datei loslib.c.

#define loslib_c

Definiert in Zeile 18 der Datei loslib.c.

#define LUA_LIB

Definiert in Zeile 19 der Datei loslib.c.

Dokumentation der Funktionen

static int get_table_optbool ( lua_State L,
int  narg,
const char *  fname,
int  d 
)
static

Definiert in Zeile 257 der Datei loslib.c.

258 {
259  int r;
260  lua_getfield(L, narg, fname);
261  // not set - use default
262  if(lua_isnil(L,-1)) {
263  r=d;
264  } else {// otherwise, treat as bool
265  r=lua_toboolean(L,-1);
266  }
267  lua_pop(L,1);
268  return r;
269 }
static int getboolfield ( lua_State L,
const char *  key 
)
static

Definiert in Zeile 111 der Datei loslib.c.

111  {
112  int res;
113  lua_getfield(L, -1, key);
114  res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
115  lua_pop(L, 1);
116  return res;
117 }
static int getfield ( lua_State L,
const char *  key,
int  d 
)
static

Definiert in Zeile 120 der Datei loslib.c.

120  {
121  int res;
122  lua_getfield(L, -1, key);
123  if (lua_isnumber(L, -1))
124  res = (int)lua_tointeger(L, -1);
125  else {
126  if (d < 0)
127  return luaL_error(L, "field " LUA_QS " missing in date table", key);
128  res = d;
129  }
130  lua_pop(L, 1);
131  return res;
132 }
static int idir_gc ( lua_State L)
static

Definiert in Zeile 350 der Datei loslib.c.

350  {
352  if(ud->dir) {
353  closedir(ud->dir);
354  }
355  return 0;
356 }
static int idir_iter ( lua_State L)
static

Definiert in Zeile 319 der Datei loslib.c.

319  {
320  struct dirent *de;
322  // dir may be on first call if opendir failed, or previous explicit close
323  if(!ud->dir) {
324  return 0;
325  }
326  // allow explicit close by calling iterator(ud,false)
327  // need to check type because first invocation is called with nil
328  if(lua_type(L, 2) == LUA_TBOOLEAN && lua_toboolean(L,2) == 0) {
329  closedir(ud->dir);
330  ud->dir=NULL;
331  return 0;
332  }
333  while((de = readdir(ud->dir))) {
334  // if not all, skip over ignored items
335  if(!ud->all && (de->d_name[0] == '\xE5' || (strcmp(de->d_name,".")==0) || (strcmp(de->d_name,"..")==0))) {
336  continue;
337  }
338  break;
339  }
340  if(de) {
341  lua_pushstring(L, de->d_name);
342  return 1;
343  } else { // on last, close immediately to avoid keeping the handle open until GC
344  closedir(ud->dir);
345  ud->dir=NULL;
346  return 0;
347  }
348 }
static void idir_register ( lua_State L)
static

Definiert in Zeile 419 der Datei loslib.c.

419  {
422 }
LUALIB_API int luaopen_os ( lua_State L)

Definiert in Zeile 545 der Datei loslib.c.

545  {
546  idir_register(L);
548  return 1;
549 }
static int os_date ( lua_State L)
static

Definiert in Zeile 135 der Datei loslib.c.

135  {
136  const char *s = luaL_optstring(L, 1, "%c");
138  struct tm *stm;
139  if (*s == '!') { /* UTC? */
140  #if 0
141  // reyalp - we have no idea about timezones, so just eat the !
142  // and use local time
143  // TODO some cams may be timezone/dst aware ?
144  stm = gmtime(&t);
145  #endif
146  stm = localtime(&t);
147  s++; /* skip `!' */
148  }
149  else
150  stm = localtime(&t);
151  if (stm == NULL) /* invalid date? */
152  lua_pushnil(L);
153  else if (strcmp(s, "*t") == 0) {
154  lua_createtable(L, 0, 9); /* 9 = number of fields */
155  setfield(L, "sec", stm->tm_sec);
156  setfield(L, "min", stm->tm_min);
157  setfield(L, "hour", stm->tm_hour);
158  setfield(L, "day", stm->tm_mday);
159  setfield(L, "month", stm->tm_mon+1);
160  setfield(L, "year", stm->tm_year+1900);
161  setfield(L, "wday", stm->tm_wday+1);
162  setfield(L, "yday", stm->tm_yday+1);
163  setboolfield(L, "isdst", stm->tm_isdst);
164  }
165  else {
166  char cc[3];
167  luaL_Buffer b;
168  cc[0] = '%'; cc[2] = '\0';
169  luaL_buffinit(L, &b);
170  for (; *s; s++) {
171  if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */
172  luaL_addchar(&b, *s);
173  else {
174  size_t reslen;
175  char buff[200]; /* should be big enough for any conversion result */
176  cc[1] = *(++s);
177  reslen = strftime(buff, sizeof(buff), cc, stm);
178  luaL_addlstring(&b, buff, reslen);
179  }
180  }
181  luaL_pushresult(&b);
182  }
183  return 1;
184 }
static int os_difftime ( lua_State L)
static

Definiert in Zeile 219 der Datei loslib.c.

219  {
220  lua_pushnumber(L, (time_t)(luaL_checknumber(L, 1) - (time_t)(luaL_optnumber(L, 2, 0))));
221  return 1;
222 }
static int os_idir ( lua_State L)
static

Definiert in Zeile 387 der Datei loslib.c.

387  {
388 #ifdef HOST_LUA
389  // TODO: Not implemented for 'hostlua'
390  (void)L;
391  return 0;
392 #else
393  const char *dirname = luaL_checkstring(L, 1);
394  int all=0,od_flags=OPENDIR_FL_CHDK_LFN;
395  if(lua_istable(L,2)) {
396  all=get_table_optbool(L,2,"showall",0);
397  od_flags=(get_table_optbool(L,2,"chdklfn",1))?OPENDIR_FL_CHDK_LFN:OPENDIR_FL_NONE;
398  } else {
399  all=lua_toboolean(L, 2);
400  }
401 
403 
404  idir_udata_t *ud = lua_newuserdata(L,sizeof(idir_udata_t));
405  ud->dir = opendir_chdk(dirname,od_flags); // may be null, in which case iterator will stop on first iteration
406  // no obvious way to return error status
407  ud->all = all;
408 
410  lua_setmetatable(L, -2);
411  return 2;
412 #endif
413 }
static int os_listdir ( lua_State L)
static

Definiert in Zeile 278 der Datei loslib.c.

278  {
279 #ifdef HOST_LUA
280  // TODO: Not implemented for 'hostlua'
281  (void)L;
282  return 0;
283 #else
284  DIR *dir;
285  struct dirent *de;
286  const char *dirname = luaL_checkstring(L, 1);
287  int all=0,od_flags=OPENDIR_FL_CHDK_LFN;
288  if(lua_istable(L,2)) {
289  all=get_table_optbool(L,2,"showall",0);
290  od_flags=(get_table_optbool(L,2,"chdklfn",1))?OPENDIR_FL_CHDK_LFN:OPENDIR_FL_NONE;
291  } else {
292  all=lua_toboolean(L, 2);
293  }
294  int i=1;
295  dir = opendir_chdk(dirname,od_flags);
296  if(!dir)
297  return os_pushresult(L, 0 , dirname);
298  lua_newtable(L);
299  while((de = readdir(dir))) {
300  if(!all && (de->d_name[0] == '\xE5' || (strcmp(de->d_name,".")==0) || (strcmp(de->d_name,"..")==0)))
301  continue;
302  lua_pushinteger(L, i);
303  lua_pushstring(L, de->d_name);
304  lua_settable(L,-3);
305  ++i;
306  }
307  closedir(dir);
308  return 1;
309 #endif
310 }
static int os_mkdir ( lua_State L)
static

Definiert in Zeile 247 der Datei loslib.c.

247  {
248  const char *dirname = luaL_checkstring(L, 1);
249 #if defined(HOST_LUA) && !defined(_WIN32)
250  return os_pushresult(L, mkdir(dirname,0777) == 0, dirname);
251 #else
252  return os_pushresult(L, mkdir(dirname) == 0, dirname);
253 #endif
254 }
static int os_pushresult ( lua_State L,
int  i,
const char *  filename 
)
static

Definiert in Zeile 27 der Datei loslib.c.

27  {
28  int en = errno; /* calls to Lua API may change this value */
29  if (i) {
30  lua_pushboolean(L, 1);
31  return 1;
32  }
33  else {
34  lua_pushnil(L);
35  lua_pushfstring(L, "%s: %s", filename, strerror(en));
36  lua_pushinteger(L, en);
37  return 3;
38  }
39 }
static int os_remove ( lua_State L)
static

Definiert in Zeile 50 der Datei loslib.c.

50  {
51  const char *filename = luaL_checkstring(L, 1);
52  return os_pushresult(L, remove(filename) == 0, filename);
53 }
static int os_rename ( lua_State L)
static

Definiert in Zeile 56 der Datei loslib.c.

56  {
57  const char *fromname = luaL_checkstring(L, 1);
58  const char *toname = luaL_checkstring(L, 2);
59  return os_pushresult(L, rename(fromname, toname) == 0, fromname);
60 }
static int os_stat ( lua_State L)
static

Definiert in Zeile 426 der Datei loslib.c.

426  {
427  struct stat st;
428  const char *name = luaL_checkstring(L, 1);
429  int result = stat(name,&st);
430  if (result==0) {
431  lua_createtable(L, 0, 6); /* = number of fields */
432  // don't expose the fields that aren't useful
433  // but leave them commented out for reference
434 //#ifndef CAM_DRYOS_2_3_R39
435 // setfield(L,"dev",st.st_dev); /* device ID number */
436 // setfield(L,"ino",st.st_ino); /* no inodes in fat, always -1 */
437 // setfield(L,"mode",st.st_mode); /* file mode (see below) */
438 //#endif
439 // setfield(L,"nlink",st.st_nlink); /* dryos 0, vxworks 1 */
440 // setfield(L,"uid",st.st_uid); /* no users or groups on fat */
441 // setfield(L,"gid",st.st_gid); /* " */
442 //#if !CAM_DRYOS
443 // doesn't appear useful, I wasn't able to stat any special files
444 // setfield(L,"rdev",st.st_rdev); /* device ID, only if special file */
445 //#endif
446  setfield(L,"size",st.st_size); /* size of file, in bytes */
447 //#ifndef CAM_DRYOS_2_3_R39
448 // setfield(L,"atime",st.st_atime); /* time of last access */
449 //#endif
450  setfield(L,"mtime",st.st_mtime); /* time of last modification */
451  setfield(L,"ctime",st.st_ctime); /* time of last change of file status */
452 #ifdef HOST_LUA
453 // fill in some sane values if we aren't running on the camera
454 // from chdk stdlib
455 #define DOS_ATTR_DIRECTORY 0x10 /* entry is a sub-directory */
456 #ifndef CAM_DRYOS_2_3_R39
457  setfield(L,"blksize",512);
458  setfield(L,"blocks",(st.st_size/512) + (st.st_size%512)?1:0);
459 #endif
460  if ( S_ISDIR(st.st_mode) ) {
461  setfield(L,"attrib",DOS_ATTR_DIRECTORY);
462  setboolfield(L,"is_dir",1);
463  setboolfield(L,"is_file",0);
464  }
465  else {
466  setboolfield(L,"is_dir",0);
467  setfield(L,"attrib",0);
468  if S_ISREG(st.st_mode) {
469  setboolfield(L,"is_file",1);
470  }
471  }
472 #else
473 //#ifndef CAM_DRYOS_2_3_R39
474 // setfield(L,"blksize",st.st_blksize); /* This is NOT the dos sector size. Appears to be 512 on all I've tested! */
475 // setfield(L,"blocks",st.st_blocks); /* number of blocks required to store file. May not be the same as size on disk, per above*/
476 //#endif
477  setfield(L,"attrib",st.st_attrib); /* file attribute byte (dosFs only) */
478  // for convenience
479  // note volume labels are neither file nor directory
480  setboolfield(L,"is_dir",st.st_attrib & DOS_ATTR_DIRECTORY);
481  setboolfield(L,"is_file",!(st.st_attrib & (DOS_ATTR_DIRECTORY | DOS_ATTR_VOL_LABEL)));
482 #endif
483 #if 0
484  setfield(L,"reserved1",st.reserved1);
485  setfield(L,"reserved2",st.reserved2);
486  setfield(L,"reserved3",st.reserved3);
487  setfield(L,"reserved4",st.reserved4);
488  setfield(L,"reserved5",st.reserved5);
489  setfield(L,"reserved6",st.reserved6);
490 #endif
491  return 1;
492  }
493  else {
494  int en = errno;
495  lua_pushnil(L);
496  lua_pushfstring(L, "%s: %s", name, strerror(en));
497  lua_pushinteger(L, en);
498  return 3;
499  }
500 }
static int os_time ( lua_State L)
static

Definiert in Zeile 187 der Datei loslib.c.

187  {
188  time_t t;
189  if (lua_isnoneornil(L, 1)) /* called without args? */
190  t = time(NULL); /* get current time */
191  else {
192  struct tm ts;
193  luaL_checktype(L, 1, LUA_TTABLE);
194  lua_settop(L, 1); /* make sure table is at the top */
195  ts.tm_sec = getfield(L, "sec", 0);
196  ts.tm_min = getfield(L, "min", 0);
197  ts.tm_hour = getfield(L, "hour", 12);
198  ts.tm_mday = getfield(L, "day", -1);
199  ts.tm_mon = getfield(L, "month", -1) - 1;
200  ts.tm_year = getfield(L, "year", -1) - 1900;
201  ts.tm_isdst = getboolfield(L, "isdst");
202  t = mktime(&ts);
203  }
204  if (t == (time_t)(-1))
205  lua_pushnil(L);
206  else
207  lua_pushnumber(L, (lua_Number)t);
208  return 1;
209 }
static int os_utime ( lua_State L)
static

Definiert in Zeile 505 der Datei loslib.c.

505  {
506  const char *name = luaL_checkstring(L, 1);
507  struct utimbuf t;
508  t.modtime = luaL_optnumber(L, 2, time(NULL));
509  t.actime = luaL_optnumber(L, 3, time(NULL));
510  return os_pushresult(L, utime(name,&t) == 0, name);
511 }
static void setboolfield ( lua_State L,
const char *  key,
int  value 
)
static

Definiert in Zeile 104 der Datei loslib.c.

104  {
105  if (value < 0) /* undefined? */
106  return; /* does not set field */
107  lua_pushboolean(L, value);
108  lua_setfield(L, -2, key);
109 }
static void setfield ( lua_State L,
const char *  key,
int  value 
)
static

Definiert in Zeile 99 der Datei loslib.c.

99  {
100  lua_pushinteger(L, value);
101  lua_setfield(L, -2, key);
102 }

Variablen-Dokumentation

const luaL_Reg idir_meta_methods[]
static
Initialisierung:
= {
{"__gc", idir_gc},
}

Definiert in Zeile 415 der Datei loslib.c.

const luaL_Reg syslib[]
static
Initialisierung:
= {
{"date", os_date},
{"difftime", os_difftime},
{"mkdir", os_mkdir},
{"listdir", os_listdir},
{"idir", os_idir},
{"stat", os_stat},
{"utime", os_utime},
{"remove", os_remove},
{"rename", os_rename},
{"time", os_time},
}

Definiert in Zeile 513 der Datei loslib.c.