webmcp
diff framework/accelerator/webmcp_accelerator.c @ 0:9fdfb27f8e67
Version 1.0.0
author | jbe/bsw |
---|---|
date | Sun Oct 25 12:00:00 2009 +0100 (2009-10-25) |
parents | |
children | 3d43a5cf17c1 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/framework/accelerator/webmcp_accelerator.c Sun Oct 25 12:00:00 2009 +0100 1.3 @@ -0,0 +1,196 @@ 1.4 +#include <lua.h> 1.5 +#include <lauxlib.h> 1.6 +#include <stdlib.h> 1.7 +#include <string.h> 1.8 + 1.9 +static int webmcp_encode_html(lua_State *L) { 1.10 + const char *input; 1.11 + size_t input_len; 1.12 + size_t i; 1.13 + luaL_Buffer buf; 1.14 + input = luaL_checklstring(L, 1, &input_len); 1.15 + for (i=0; i<input_len; i++) { 1.16 + char c = input[i]; 1.17 + if ((c == '<') || (c == '>') || (c == '&') || (c == '"')) break; 1.18 + } 1.19 + if (i == input_len) { 1.20 + lua_settop(L, 1); 1.21 + return 1; 1.22 + } 1.23 + luaL_buffinit(L, &buf); 1.24 + for (i=0; i<input_len; i++) { 1.25 + char c; 1.26 + size_t j = i; 1.27 + do { 1.28 + c = input[j]; 1.29 + if ((c == '<') || (c == '>') || (c == '&') || (c == '"')) break; 1.30 + else j++; 1.31 + } while (j<input_len); 1.32 + if (j != i) { 1.33 + luaL_addlstring(&buf, input+i, j-i); 1.34 + i = j; 1.35 + } 1.36 + if (i<input_len) { 1.37 + if (c == '<') luaL_addstring(&buf, "<"); 1.38 + else if (c == '>') luaL_addstring(&buf, ">"); 1.39 + else if (c == '&') luaL_addstring(&buf, "&"); 1.40 + else if (c == '"') luaL_addstring(&buf, """); 1.41 + else abort(); // should not happen 1.42 + } 1.43 + } 1.44 + luaL_pushresult(&buf); 1.45 + return 1; 1.46 +} 1.47 + 1.48 +static int webmcp_slot_put_into(lua_State *L) { 1.49 + int argc; 1.50 + int i; 1.51 + int j; 1.52 + luaL_checkany(L, 1); 1.53 + argc = lua_gettop(L); 1.54 + lua_getglobal(L, "slot"); 1.55 + lua_getfield(L, -1, "_data"); 1.56 + lua_pushvalue(L, 1); 1.57 + lua_gettable(L, -2); // get table by reference passed as 1st argument 1.58 + lua_getfield(L, -1, "string_fragments"); 1.59 + j = lua_objlen(L, -1); 1.60 + for (i=2; i<=argc; i++) { 1.61 + lua_pushvalue(L, i); 1.62 + lua_rawseti(L, -2, ++j); 1.63 + } 1.64 + return 0; 1.65 +} 1.66 + 1.67 +static int webmcp_slot_put(lua_State *L) { 1.68 + int argc; 1.69 + int i; 1.70 + int j; 1.71 + argc = lua_gettop(L); 1.72 + lua_getglobal(L, "slot"); 1.73 + lua_getfield(L, -1, "_data"); 1.74 + lua_getfield(L, -2, "_active_slot"); 1.75 + lua_gettable(L, -2); 1.76 + lua_getfield(L, -1, "string_fragments"); 1.77 + j = lua_objlen(L, -1); 1.78 + for (i=1; i<=argc; i++) { 1.79 + lua_pushvalue(L, i); 1.80 + lua_rawseti(L, -2, ++j); 1.81 + } 1.82 + return 0; 1.83 +} 1.84 + 1.85 +static int webmcp_ui_tag(lua_State *L) { 1.86 + int tag_given = 0; 1.87 + int j; 1.88 + lua_settop(L, 1); 1.89 + luaL_checktype(L, 1, LUA_TTABLE); 1.90 + lua_getglobal(L, "slot"); // 2 1.91 + lua_getfield(L, 2, "_data"); // 3 1.92 + lua_getfield(L, 2, "_active_slot"); 1.93 + lua_gettable(L, 3); // 4 1.94 + lua_getfield(L, 4, "string_fragments"); // 5 1.95 + lua_getfield(L, 1, "tag"); // 6 1.96 + lua_getfield(L, 1, "attr"); // 7 1.97 + lua_getfield(L, 1, "content"); // 8 1.98 + if (lua_toboolean(L, 7) && !lua_istable(L, 7)) { 1.99 + return luaL_error(L, 1.100 + "\"attr\" argument for ui.tag{...} must be nil or a table." 1.101 + ); 1.102 + } 1.103 + if (lua_toboolean(L, 6)) { 1.104 + tag_given = 1; 1.105 + } else if (lua_toboolean(L, 7)) { 1.106 + lua_pushnil(L); 1.107 + if (lua_next(L, 7)) { 1.108 + lua_pop(L, 2); 1.109 + lua_pushliteral(L, "span"); 1.110 + lua_replace(L, 6); 1.111 + tag_given = 1; 1.112 + } 1.113 + } 1.114 + j = lua_objlen(L, 5); 1.115 + if (tag_given) { 1.116 + lua_pushliteral(L, "<"); 1.117 + lua_rawseti(L, 5, ++j); 1.118 + lua_pushvalue(L, 6); 1.119 + lua_rawseti(L, 5, ++j); 1.120 + if (lua_toboolean(L, 7)) { 1.121 + for (lua_pushnil(L); lua_next(L, 7); lua_pop(L, 1)) { 1.122 + // key at position 9 1.123 + // value at position 10 1.124 + lua_pushliteral(L, " "); 1.125 + lua_rawseti(L, 5, ++j); 1.126 + lua_pushvalue(L, 9); 1.127 + lua_rawseti(L, 5, ++j); 1.128 + lua_pushliteral(L, "=\""); 1.129 + lua_rawseti(L, 5, ++j); 1.130 + if (!strcmp(lua_tostring(L, 9), "class") && lua_istable(L, 10)) { // NOTE: lua_tostring(...) is destructive, will cause errors for numeric keys 1.131 + lua_getglobal(L, "table"); // 11 1.132 + lua_getfield(L, 11, "concat"); // 12 1.133 + lua_replace(L, 11); // 11 1.134 + lua_pushvalue(L, 10); // 12 1.135 + lua_pushliteral(L, " "); // 13 1.136 + lua_call(L, 2, 1); // 11 1.137 + lua_rawseti(L, 5, ++j); 1.138 + } else { 1.139 + lua_pushcfunction(L, webmcp_encode_html); 1.140 + lua_pushvalue(L, 10); 1.141 + lua_call(L, 1, 1); 1.142 + lua_rawseti(L, 5, ++j); 1.143 + } 1.144 + lua_pushliteral(L, "\""); 1.145 + lua_rawseti(L, 5, ++j); 1.146 + } 1.147 + } 1.148 + } 1.149 + if (lua_toboolean(L, 8)) { 1.150 + if (tag_given) { 1.151 + lua_pushliteral(L, ">"); 1.152 + lua_rawseti(L, 5, ++j); 1.153 + } 1.154 + if (lua_isfunction(L, 8)) { 1.155 + // content function should be on last stack position 8 1.156 + lua_call(L, 0, 0); 1.157 + // stack is now at position 7, but we don't care 1.158 + // we assume that the active slot hasn't been exchanged or resetted 1.159 + j = lua_objlen(L, 5); // but it may include more elements now 1.160 + } else { 1.161 + lua_pushcfunction(L, webmcp_encode_html); // 9 1.162 + lua_pushvalue(L, 8); // 10 1.163 + lua_call(L, 1, 1); // 9 1.164 + lua_rawseti(L, 5, ++j); 1.165 + } 1.166 + if (tag_given) { 1.167 + lua_pushliteral(L, "</"); 1.168 + lua_rawseti(L, 5, ++j); 1.169 + lua_pushvalue(L, 6); 1.170 + lua_rawseti(L, 5, ++j); 1.171 + lua_pushliteral(L, ">"); 1.172 + lua_rawseti(L, 5, ++j); 1.173 + } 1.174 + } else { 1.175 + if (tag_given) { 1.176 + lua_pushliteral(L, " />"); 1.177 + lua_rawseti(L, 5, ++j); 1.178 + } 1.179 + } 1.180 + return 0; 1.181 +} 1.182 + 1.183 +int luaopen_webmcp_accelerator(lua_State *L) { 1.184 + lua_settop(L, 0); 1.185 + lua_getglobal(L, "encode"); // 1 1.186 + lua_pushcfunction(L, webmcp_encode_html); 1.187 + lua_setfield(L, 1, "html"); 1.188 + lua_settop(L, 0); 1.189 + lua_getglobal(L, "slot"); // 1 1.190 + lua_pushcfunction(L, webmcp_slot_put_into); 1.191 + lua_setfield(L, 1, "put_into"); 1.192 + lua_pushcfunction(L, webmcp_slot_put); 1.193 + lua_setfield(L, 1, "put"); 1.194 + lua_settop(L, 0); 1.195 + lua_getglobal(L, "ui"); // 1 1.196 + lua_pushcfunction(L, webmcp_ui_tag); 1.197 + lua_setfield(L, 1, "tag"); 1.198 + return 0; 1.199 +}