jbe/bsw@0: #include jbe/bsw@0: #include jbe/bsw@0: #include jbe/bsw@0: #include jbe/bsw@0: jbe/bsw@0: static int webmcp_encode_html(lua_State *L) { jbe/bsw@0: const char *input; jbe/bsw@0: size_t input_len; jbe/bsw@0: size_t i; jbe/bsw@0: luaL_Buffer buf; jbe/bsw@0: input = luaL_checklstring(L, 1, &input_len); jbe/bsw@0: for (i=0; i') || (c == '&') || (c == '"')) break; jbe/bsw@0: } jbe/bsw@0: if (i == input_len) { jbe/bsw@0: lua_settop(L, 1); jbe/bsw@0: return 1; jbe/bsw@0: } jbe/bsw@0: luaL_buffinit(L, &buf); jbe/bsw@0: for (i=0; i') || (c == '&') || (c == '"')) break; jbe/bsw@0: else j++; jbe/bsw@0: } while (j') luaL_addstring(&buf, ">"); jbe/bsw@0: else if (c == '&') luaL_addstring(&buf, "&"); jbe/bsw@0: else if (c == '"') luaL_addstring(&buf, """); jbe/bsw@0: else abort(); // should not happen jbe/bsw@0: } jbe/bsw@0: } jbe/bsw@0: luaL_pushresult(&buf); jbe/bsw@0: return 1; jbe/bsw@0: } jbe/bsw@0: jbe/bsw@0: static int webmcp_slot_put_into(lua_State *L) { jbe/bsw@0: int argc; jbe/bsw@0: int i; jbe/bsw@0: int j; jbe/bsw@0: luaL_checkany(L, 1); jbe/bsw@0: argc = lua_gettop(L); jbe/bsw@0: lua_getglobal(L, "slot"); jbe/bsw@0: lua_getfield(L, -1, "_data"); jbe/bsw@0: lua_pushvalue(L, 1); jbe/bsw@0: lua_gettable(L, -2); // get table by reference passed as 1st argument jbe/bsw@0: lua_getfield(L, -1, "string_fragments"); jbe@64: j = lua_rawlen(L, -1); jbe/bsw@0: for (i=2; i<=argc; i++) { jbe/bsw@0: lua_pushvalue(L, i); jbe/bsw@0: lua_rawseti(L, -2, ++j); jbe/bsw@0: } jbe/bsw@0: return 0; jbe/bsw@0: } jbe/bsw@0: jbe/bsw@0: static int webmcp_slot_put(lua_State *L) { jbe/bsw@0: int argc; jbe/bsw@0: int i; jbe/bsw@0: int j; jbe/bsw@0: argc = lua_gettop(L); jbe/bsw@0: lua_getglobal(L, "slot"); jbe/bsw@0: lua_getfield(L, -1, "_data"); jbe/bsw@0: lua_getfield(L, -2, "_active_slot"); jbe/bsw@0: lua_gettable(L, -2); jbe/bsw@0: lua_getfield(L, -1, "string_fragments"); jbe@64: j = lua_rawlen(L, -1); jbe/bsw@0: for (i=1; i<=argc; i++) { jbe/bsw@0: lua_pushvalue(L, i); jbe/bsw@0: lua_rawseti(L, -2, ++j); jbe/bsw@0: } jbe/bsw@0: return 0; jbe/bsw@0: } jbe/bsw@0: jbe/bsw@0: static int webmcp_ui_tag(lua_State *L) { jbe/bsw@0: int tag_given = 0; jbe/bsw@0: int j; jbe/bsw@0: lua_settop(L, 1); jbe/bsw@0: luaL_checktype(L, 1, LUA_TTABLE); jbe/bsw@0: lua_getglobal(L, "slot"); // 2 jbe/bsw@0: lua_getfield(L, 2, "_data"); // 3 jbe/bsw@0: lua_getfield(L, 2, "_active_slot"); jbe/bsw@0: lua_gettable(L, 3); // 4 jbe/bsw@0: lua_getfield(L, 4, "string_fragments"); // 5 jbe/bsw@0: lua_getfield(L, 1, "tag"); // 6 jbe/bsw@0: lua_getfield(L, 1, "attr"); // 7 jbe/bsw@0: lua_getfield(L, 1, "content"); // 8 jbe/bsw@0: if (lua_toboolean(L, 7) && !lua_istable(L, 7)) { jbe/bsw@0: return luaL_error(L, jbe/bsw@0: "\"attr\" argument for ui.tag{...} must be nil or a table." jbe/bsw@0: ); jbe/bsw@0: } jbe/bsw@0: if (lua_toboolean(L, 6)) { jbe/bsw@0: tag_given = 1; jbe/bsw@0: } else if (lua_toboolean(L, 7)) { jbe/bsw@0: lua_pushnil(L); jbe/bsw@0: if (lua_next(L, 7)) { jbe/bsw@0: lua_pop(L, 2); jbe/bsw@0: lua_pushliteral(L, "span"); jbe/bsw@0: lua_replace(L, 6); jbe/bsw@0: tag_given = 1; jbe/bsw@0: } jbe/bsw@0: } jbe@64: j = lua_rawlen(L, 5); jbe/bsw@0: if (tag_given) { jbe/bsw@0: lua_pushliteral(L, "<"); jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: lua_pushvalue(L, 6); jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: if (lua_toboolean(L, 7)) { jbe/bsw@0: for (lua_pushnil(L); lua_next(L, 7); lua_pop(L, 1)) { jbe/bsw@0: // key at position 9 jbe/bsw@0: // value at position 10 jbe/bsw@0: lua_pushliteral(L, " "); jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: lua_pushvalue(L, 9); jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: lua_pushliteral(L, "=\""); jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: if (!strcmp(lua_tostring(L, 9), "class") && lua_istable(L, 10)) { // NOTE: lua_tostring(...) is destructive, will cause errors for numeric keys jbe/bsw@0: lua_getglobal(L, "table"); // 11 jbe/bsw@0: lua_getfield(L, 11, "concat"); // 12 jbe/bsw@0: lua_replace(L, 11); // 11 jbe/bsw@0: lua_pushvalue(L, 10); // 12 jbe/bsw@0: lua_pushliteral(L, " "); // 13 jbe/bsw@0: lua_call(L, 2, 1); // 11 jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: } else { jbe/bsw@0: lua_pushcfunction(L, webmcp_encode_html); jbe/bsw@0: lua_pushvalue(L, 10); jbe/bsw@0: lua_call(L, 1, 1); jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: } jbe/bsw@0: lua_pushliteral(L, "\""); jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: } jbe/bsw@0: } jbe/bsw@0: } jbe/bsw@0: if (lua_toboolean(L, 8)) { jbe/bsw@0: if (tag_given) { jbe/bsw@0: lua_pushliteral(L, ">"); jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: } jbe/bsw@0: if (lua_isfunction(L, 8)) { jbe/bsw@0: // content function should be on last stack position 8 jbe/bsw@0: lua_call(L, 0, 0); jbe/bsw@0: // stack is now at position 7, but we don't care jbe/bsw@0: // we assume that the active slot hasn't been exchanged or resetted jbe@64: j = lua_rawlen(L, 5); // but it may include more elements now jbe/bsw@0: } else { jbe/bsw@0: lua_pushcfunction(L, webmcp_encode_html); // 9 jbe/bsw@0: lua_pushvalue(L, 8); // 10 jbe/bsw@0: lua_call(L, 1, 1); // 9 jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: } jbe/bsw@0: if (tag_given) { jbe/bsw@0: lua_pushliteral(L, ""); jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: } jbe/bsw@0: } else { jbe/bsw@0: if (tag_given) { jbe/bsw@0: lua_pushliteral(L, " />"); jbe/bsw@0: lua_rawseti(L, 5, ++j); jbe/bsw@0: } jbe/bsw@0: } jbe/bsw@0: return 0; jbe/bsw@0: } jbe/bsw@0: jbe/bsw@0: int luaopen_webmcp_accelerator(lua_State *L) { jbe/bsw@0: lua_settop(L, 0); jbe/bsw@0: lua_getglobal(L, "encode"); // 1 jbe/bsw@0: lua_pushcfunction(L, webmcp_encode_html); jbe/bsw@0: lua_setfield(L, 1, "html"); jbe/bsw@0: lua_settop(L, 0); jbe/bsw@0: lua_getglobal(L, "slot"); // 1 jbe/bsw@0: lua_pushcfunction(L, webmcp_slot_put_into); jbe/bsw@0: lua_setfield(L, 1, "put_into"); jbe/bsw@0: lua_pushcfunction(L, webmcp_slot_put); jbe/bsw@0: lua_setfield(L, 1, "put"); jbe/bsw@0: lua_settop(L, 0); jbe/bsw@0: lua_getglobal(L, "ui"); // 1 jbe/bsw@0: lua_pushcfunction(L, webmcp_ui_tag); jbe/bsw@0: lua_setfield(L, 1, "tag"); jbe/bsw@0: return 0; jbe/bsw@0: }