💾 Archived View for gemini.conman.org › extensions › port70 › handlers › blog › html.c captured on 2021-12-03 at 14:04:38.
View Raw
More Information
⬅️ Previous capture (2020-11-01)
➡️ Next capture (2021-12-17)
🚧 View Differences
-=-=-=-=-=-=-
/************************************************************************
- Copyright 2020 by Sean Conner. All Rights Reserved.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- Comments, questions and criticisms can be sent to: sean@conman.org
- ************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#include <limits.h>
#include <lua.h>
#include <lauxlib.h>
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 503
# error You need to compile against Lua 5.3 or higher
#endif
/**************************************************************************/
enum
{
UPV_ENTITY = 1,
UPV_UTF8 = 2,
};
struct _yycontext;
static int readchars (struct _yycontext *,char *,size_t);
static void push_string (struct _yycontext *,char const *,size_t);
static void tagi (struct _yycontext *,char const *);
static void tagb (struct _yycontext *,char const *);
static void endtag (struct _yycontext *);
static void setfield (struct _yycontext *,char const *);
static void deentifyn (struct _yycontext *,char const *,int);
static void deentify (struct _yycontext *,char const *);
#define YY_CTX_LOCAL
#define YY_PARSE(T) static T
#define YY_CTX_MEMBERS \
size_t len; \
char const *buffer; \
lua_State *L; \
luaL_Buffer buf; \
bool pre;
#define YY_INPUT(yy,buf,result,max) result = readchars(yy,buf,max)
#include "html.i"
/**************************************************************************/
static int readchars(yycontext *yy,char *dest,size_t dlen)
{
size_t xfer;
if (dlen > INT_MAX)
dlen = INT_MAX;
xfer = dlen < yy->len ? dlen : yy->len;
memcpy(dest,yy->buffer,xfer);
yy->len -= xfer;
yy->buffer += xfer;
return (int)xfer;
}
/**************************************************************************/
static void tagi(yycontext *yy,char const *tag)
{
lua_createtable(yy->L,0,0);
lua_pushstring(yy->L,tag);
lua_setfield(yy->L,-2,"tag");
lua_pushboolean(yy->L,true);
lua_setfield(yy->L,-2,"inline");
lua_createtable(yy->L,0,0);
lua_setfield(yy->L,-2,"attributes");
}
/**************************************************************************/
static void tagb(yycontext *yy,char const *tag)
{
lua_createtable(yy->L,0,0);
lua_pushstring(yy->L,tag);
lua_setfield(yy->L,-2,"tag");
lua_pushboolean(yy->L,true);
lua_setfield(yy->L,-2,"block");
lua_createtable(yy->L,0,0);
lua_setfield(yy->L,-2,"attributes");
}
/**************************************************************************/
static void endtag(yycontext *yy)
{
lua_pushinteger(yy->L,luaL_len(yy->L,-2) + 1);
lua_insert(yy->L,-2);
lua_settable(yy->L,-3);
}
/**************************************************************************/
static void setfield(yycontext *yy,char const *name)
{
lua_pushstring(yy->L,name);
lua_insert(yy->L,-2);
lua_getfield(yy->L,-3,"attributes");
lua_insert(yy->L,-3);
lua_settable(yy->L,-3);
lua_pop(yy->L,1);
}
/**************************************************************************/
static void deentifyn(yycontext *yy,char const *num,int base)
{
size_t len;
char const *s;
lua_Integer v = strtoul(num,NULL,base);
lua_getfield(yy->L,lua_upvalueindex(UPV_UTF8),"char");
lua_pushinteger(yy->L,v);
lua_call(yy->L,1,1);
luaL_addvalue(&yy->buf);
}
/**************************************************************************/
static void deentify(yycontext *yy,char const *label)
{
char const *entity;
size_t len;
lua_getfield(yy->L,lua_upvalueindex(UPV_ENTITY),label);
luaL_addvalue(&yy->buf);
}
/**************************************************************************/
static int parse(lua_State *L)
{
yycontext yyctx;
int rc;
lua_settop(L,1);
lua_createtable(L,0,0);
memset(&yyctx,0,sizeof(yyctx));
yyctx.buffer = luaL_checklstring(L,1,&yyctx.len);
yyctx.L = L;
rc = yyparse(&yyctx);
yyrelease(&yyctx);
if (rc == 0)
lua_pushnil(L);
return 1;
}
/**************************************************************************/
int luaopen_org_conman_app_port70_handlers_blog_html(lua_State *L)
{
lua_getglobal(L,"require");
lua_pushliteral(L,"org.conman.const.entity");
lua_call(L,1,1);
lua_getglobal(L,"require");
lua_pushliteral(L,"utf8");
lua_call(L,1,1);
lua_pushcclosure(L,parse,2);
return 1;
}