💾 Archived View for gemini.conman.org › extensions › mod_blog › tumbler.c captured on 2023-07-10 at 13:45:21.

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-

/***************************************************************************


#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#include <lua.h>
#include <lauxlib.h>

#include "wbtum.h"

#if LUA_VERSION_NUM < 503
#  error Need Lua 5.3 or higher
#endif

/***********************************************************************/

char const *const m_units[] =
{
  "year",
  "month",
  "day",
  "part",
  NULL
};

/***********************************************************************/

static void tumL_pushbtm(lua_State *L,struct btm const *when)
{
  lua_createtable(L,0,4);
  lua_pushinteger(L,when->year);
  lua_setfield(L,-2,"year");
  lua_pushinteger(L,when->month);
  lua_setfield(L,-2,"month");
  lua_pushinteger(L,when->day);
  lua_setfield(L,-2,"day");
  lua_pushinteger(L,when->part);
  lua_setfield(L,-2,"part");
}

/***********************************************************************/

static void tumL_tobtm(lua_State *L,int idx,struct btm *when)
{
  idx = lua_absindex(L,idx);
  lua_getfield(L,idx,"year");
  when->year = lua_tointeger(L,-1);
  lua_getfield(L,idx,"month");
  when->month = lua_tointeger(L,-1);
  lua_getfield(L,idx,"day");
  when->day = lua_tointeger(L,-1);
  lua_getfield(L,idx,"part");
  when->part = lua_tointeger(L,-1);
  lua_pop(L,4);
}

/***********************************************************************/

static int tumlua_new(lua_State *L)
{
  tumbler__s tumbler;
  struct btm first;
  struct btm last;
  
  tumL_tobtm(L,2,&first);
  tumL_tobtm(L,3,&last);
  if (!tumbler_new(&tumbler,luaL_checkstring(L,1),&first,&last))
  {
    lua_pushnil(L);
    return 1;
  }
  
  lua_createtable(L,0,0);
  tumL_pushbtm(L,&tumbler.start);
  lua_setfield(L,-2,"start");
  tumL_pushbtm(L,&tumbler.stop);
  lua_setfield(L,-2,"stop");
  lua_pushstring(L,m_units[tumbler.ustart]);
  lua_setfield(L,-2,"ustart");
  lua_pushstring(L,m_units[tumbler.ustop]);
  lua_setfield(L,-2,"ustop");
  lua_pushboolean(L,tumbler.file);
  lua_setfield(L,-2,"file");
  lua_pushboolean(L,tumbler.redirect);
  lua_setfield(L,-2,"redirect");
  lua_pushboolean(L,tumbler.range);
  lua_setfield(L,-2,"range");
  if (tumbler.file)
  {
    lua_pushstring(L,tumbler.filename);
    lua_setfield(L,-2,"filename");
  }
  
  return 1;
}

/***********************************************************************/

static int tumlua_canonical(lua_State *L)
{
  tumbler__s  tumbler;
  char       *canonical;
  
  luaL_checktype(L,1,LUA_TTABLE);
  lua_getfield(L,1,"start");
  tumL_tobtm(L,-1,&tumbler.start);
  lua_getfield(L,1,"stop");
  tumL_tobtm(L,-1,&tumbler.stop);
  lua_getfield(L,1,"ustart");
  tumbler.ustart = luaL_checkoption(L,-1,NULL,m_units);
  lua_getfield(L,1,"ustop");
  tumbler.ustop = luaL_checkoption(L,-1,NULL,m_units);
  lua_getfield(L,1,"file");
  tumbler.file = lua_toboolean(L,-1);
  lua_getfield(L,1,"redirect");
  tumbler.redirect = lua_toboolean(L,-1);
  lua_getfield(L,1,"range");
  tumbler.range = lua_toboolean(L,-1);
  
  if (lua_getfield(L,1,"filename") == LUA_TSTRING)
  {
    size_t      fnlen;
    char const *filename = lua_tolstring(L,-1,&fnlen);
    
    if (fnlen >= sizeof(tumbler.filename))
      fnlen = sizeof(tumbler.filename) - 1;
    memcpy(tumbler.filename,filename,fnlen);
    tumbler.filename[fnlen+1] = '\0';
  }
  
  canonical = tumbler_canonical(&tumbler);
  if (canonical != NULL)
  {
    lua_pushstring(L,canonical);
    free(canonical);
  }
  else
    lua_pushnil(L);
    
  return 1;
}

/***********************************************************************/

int luaopen_org_conman_app_mod_blog_tumbler(lua_State *L)
{
  static luaL_Reg const m_tumbler_reg[] =
  {
    { "new"       , tumlua_new       } ,
    { "canonical" , tumlua_canonical } ,
    { NULL        , NULL             }
  };
  
  luaL_newlib(L,m_tumbler_reg);
  return 1;
}

/***********************************************************************/