/* ** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ #include #define lfunc_c #define LUA_CORE #include "lua.h" #include "lfunc.h" #include "lgc.h" #include "lmem.h" #include "lobject.h" #include "lstate.h" Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); luaC_link(L, obj2gco(c), LUA_TFUNCTION); c->c.isC = 1; c->c.env = e; c->c.nupvalues = cast_byte(nelems); return c; } Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); luaC_link(L, obj2gco(c), LUA_TFUNCTION); c->l.isC = 0; c->l.env = e; c->l.nupvalues = cast_byte(nelems); while (nelems--) c->l.upvals[nelems] = NULL; return c; } UpVal *luaF_newupval (lua_State *L) { UpVal *uv = luaM_new(L, UpVal); luaC_link(L, obj2gco(uv), LUA_TUPVAL); uv->v = &uv->u.value; setnilvalue(uv->v); return uv; } UpVal *luaF_findupval (lua_State *L, StkId level) { global_State *g = G(L); GCObject **pp = &L->openupval; UpVal *p; UpVal *uv; while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { lua_assert(p->v != &p->u.value); if (p->v == level) { /* found a corresponding upvalue? */ if (isdead(g, obj2gco(p))) /* is it dead? */ changewhite(obj2gco(p)); /* ressurect it */ return p; } pp = &p->next; } uv = luaM_new(L, UpVal); /* not found: create a new one */ uv->tt = LUA_TUPVAL; uv->marked = luaC_white(g); uv->v = level; /* current value lives in the stack */ uv->next = *pp; /* chain it in the proper position */ *pp = obj2gco(uv); uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ uv->u.l.next = g->uvhead.u.l.next; uv->u.l.next->u.l.prev = uv; g->uvhead.u.l.next = uv; lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); return uv; } static void unlinkupval (UpVal *uv) { lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ uv->u.l.prev->u.l.next = uv->u.l.next; } void luaF_freeupval (lua_State *L, UpVal *uv) { if (uv->v != &uv->u.value) /* is it open? */ unlinkupval(uv); /* remove from open list */ luaM_free(L, uv); /* free upvalue */ } void luaF_close (lua_State *L, StkId level) { UpVal *uv; global_State *g = G(L); while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { GCObject *o = obj2gco(uv); lua_assert(!isblack(o) && uv->v != &uv->u.value); L->openupval = uv->next; /* remove from `open' list */ if (isdead(g, o)) luaF_freeupval(L, uv); /* free upvalue */ else { unlinkupval(uv); setobj(L, &uv->u.value, uv->v); uv->v = &uv->u.value; /* now current value lives here */ luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ } } } Proto *luaF_newproto (lua_State *L) { Proto *f = luaM_new(L, Proto); luaC_link(L, obj2gco(f), LUA_TPROTO); f->k = NULL; f->sizek = 0; f->p = NULL; f->sizep = 0; f->code = NULL; f->sizecode = 0; f->sizelineinfo = 0; f->sizeupvalues = 0; f->nups = 0; f->upvalues = NULL; f->numparams = 0; f->is_vararg = 0; f->maxstacksize = 0; f->lineinfo = NULL; f->sizelocvars = 0; f->locvars = NULL; f->linedefined = 0; f->lastlinedefined = 0; f->source = NULL; return f; } void luaF_freeproto (lua_State *L, Proto *f) { luaM_freearray(L, f->code, f->sizecode, Instruction); luaM_freearray(L, f->p, f->sizep, Proto *); luaM_freearray(L, f->k, f->sizek, TValue); luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); luaM_free(L, f); } void luaF_freeclosure (lua_State *L, Closure *c) { int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : sizeLclosure(c->l.nupvalues); luaM_freemem(L, c, size); } /* ** Look for n-th local variable at line `line' in function `func'. ** Returns NULL if not found. */ const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { int i; for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { if (pc < f->locvars[i].endpc) { /* is variable active? */ local_number--; if (local_number == 0) return getstr(f->locvars[i].varname); } } return NULL; /* not found */ } f='#n48'>48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
/*
** $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);
}

#if CONFIG_RTC
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;
}
#endif


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) {