/*
** tek.lib.luahtml - Lua+HTML parser/decoding library
** Written by Timm S. Mueller
** This file is licensed under the terms of the free MIT license.
*/
#include "luahtml_parser.h"
#define luahtml_topfile(L) ((FILE **) luaL_checkudata(L, 1, LUA_FILEHANDLE))
static FILE *luahtml_tofile (lua_State *L)
{
FILE **f = luahtml_topfile(L);
if (*f == NULL)
luaL_error(L, "attempt to use a closed file");
return *f;
}
static int luahtml_readstring(struct luahtml_utf8reader *rd)
{
if (rd->srclen == 0)
return -1;
rd->srclen--;
return *rd->src++;
}
static int luahtml_readfile(struct luahtml_utf8reader *rd)
{
return fgetc(rd->file);
}
static int luahtml_load(lua_State *L)
{
struct luahtml_readdata rd;
const char *outfunc = luaL_checkstring(L, 2);
const char *chunkname = luaL_checkstring(L, 3);
int res;
if (lua_isuserdata(L, 1))
{
rd.utf8.file = luahtml_tofile(L);
rd.utf8.readchar = luahtml_readfile;
}
else
{
rd.utf8.src = (unsigned char *) lua_tolstring(L, 1, &rd.utf8.srclen);
rd.utf8.readchar = luahtml_readstring;
}
rd.utf8.accu = 0;
rd.utf8.numa = 0;
rd.utf8.bufc = -1;
rd.code_present = 0;
rd.state = PARSER_UNDEF;
strcpy((char *) rd.buf0, " ");
strcat((char *) rd.buf0, outfunc);
strcat((char *) rd.buf0, "(");
rd.buf = rd.buf0 + strlen((char *) rd.buf0);
#if LUA_VERSION_NUM < 502
res = lua_load(L, luahtml_readparsed, &rd, chunkname);
#else
res = lua_load(L, luahtml_readparsed, &rd, chunkname, NULL);
#endif
if (res == 0)
{
#if LUA_VERSION_NUM >= 502
lua_pushvalue(L, 4);
lua_setupvalue(L, -2, 1);
#endif
lua_pushboolean(L, rd.code_present);
return 2;
}
lua_pushnil(L);
lua_insert(L, -2);
/* nil, message on stack */
return 2;
}
static int luahtml_encode(lua_State *L)
{
struct luahtml_readdata rd;
char sbuf[16];
luaL_Buffer b;
int c;
if (lua_isuserdata(L, 1))
{
rd.utf8.file = luahtml_tofile(L);
rd.utf8.readchar = luahtml_readfile;
}
else
{
rd.utf8.src = (unsigned char *) lua_tolstring(L, 1, &rd.utf8.srclen);
rd.utf8.readchar = luahtml_readstring;
}
luaL_buffinit(L, &b);
rd.utf8.accu = 0;
rd.utf8.numa = 0;
rd.utf8.bufc = -1;
while ((c = luahtml_readutf8(&rd.utf8)) >= 0)
{
switch(c)
{
case 34:
luaL_addlstring(&b, """, 6);
break;
case 38:
luaL_addlstring(&b, "&", 5);
break;
case 60:
luaL_addlstring(&b, "<", 4);
break;
case 62:
luaL_addlstring(&b, ">", 4);
break;
default:
if (/*c == 91 || c == 93 ||*/ c > 126)
{
sprintf(sbuf, "%03d;", c);
luaL_addstring(&b, sbuf);
}
else
luaL_addchar(&b, c);
}
}
luaL_pushresult(&b);
return 1;
}
static const luaL_Reg luahtml_lib[] =
{
{ "load", luahtml_load },
{ "encode", luahtml_encode },
{ NULL, NULL }
};
int luaopen_tek_lib_luahtml(lua_State *L)
{
#if LUA_VERSION_NUM < 502
luaL_register(L, "tek.lib.luahtml", luahtml_lib);
#else
luaL_newlib(L, luahtml_lib);
#endif
return 1;
}