| rev | line source | 
| jbe/bsw@0 | 1 #include <lua.h> | 
| jbe/bsw@0 | 2 #include <lauxlib.h> | 
| jbe/bsw@0 | 3 #include <stdlib.h> | 
| jbe/bsw@0 | 4 #include <string.h> | 
| jbe/bsw@0 | 5 | 
| jbe/bsw@0 | 6 static int webmcp_encode_html(lua_State *L) { | 
| jbe/bsw@0 | 7   const char *input; | 
| jbe/bsw@0 | 8   size_t input_len; | 
| jbe/bsw@0 | 9   size_t i; | 
| jbe/bsw@0 | 10   luaL_Buffer buf; | 
| jbe/bsw@0 | 11   input = luaL_checklstring(L, 1, &input_len); | 
| jbe/bsw@0 | 12   for (i=0; i<input_len; i++) { | 
| jbe/bsw@0 | 13     char c = input[i]; | 
| jbe/bsw@0 | 14     if ((c == '<') || (c == '>') || (c == '&') || (c == '"')) break; | 
| jbe/bsw@0 | 15   } | 
| jbe/bsw@0 | 16   if (i == input_len) { | 
| jbe/bsw@0 | 17     lua_settop(L, 1); | 
| jbe/bsw@0 | 18     return 1; | 
| jbe/bsw@0 | 19   } | 
| jbe/bsw@0 | 20   luaL_buffinit(L, &buf); | 
| jbe/bsw@0 | 21   for (i=0; i<input_len; i++) { | 
| jbe/bsw@0 | 22     char c; | 
| jbe/bsw@0 | 23     size_t j = i; | 
| jbe/bsw@0 | 24     do { | 
| jbe/bsw@0 | 25       c = input[j]; | 
| jbe/bsw@0 | 26       if ((c == '<') || (c == '>') || (c == '&') || (c == '"')) break; | 
| jbe/bsw@0 | 27       else j++; | 
| jbe/bsw@0 | 28     } while (j<input_len); | 
| jbe/bsw@0 | 29     if (j != i) { | 
| jbe/bsw@0 | 30       luaL_addlstring(&buf, input+i, j-i); | 
| jbe/bsw@0 | 31       i = j; | 
| jbe/bsw@0 | 32     } | 
| jbe/bsw@0 | 33     if (i<input_len) { | 
| jbe/bsw@0 | 34       if      (c == '<') luaL_addstring(&buf, "<"); | 
| jbe/bsw@0 | 35       else if (c == '>') luaL_addstring(&buf, ">"); | 
| jbe/bsw@0 | 36       else if (c == '&') luaL_addstring(&buf, "&"); | 
| jbe/bsw@0 | 37       else if (c == '"') luaL_addstring(&buf, """); | 
| jbe/bsw@0 | 38       else abort();  // should not happen | 
| jbe/bsw@0 | 39     } | 
| jbe/bsw@0 | 40   } | 
| jbe/bsw@0 | 41   luaL_pushresult(&buf); | 
| jbe/bsw@0 | 42   return 1; | 
| jbe/bsw@0 | 43 } | 
| jbe/bsw@0 | 44 | 
| jbe/bsw@0 | 45 static int webmcp_slot_put_into(lua_State *L) { | 
| jbe/bsw@0 | 46   int argc; | 
| jbe/bsw@0 | 47   int i; | 
| jbe/bsw@0 | 48   int j; | 
| jbe/bsw@0 | 49   luaL_checkany(L, 1); | 
| jbe/bsw@0 | 50   argc = lua_gettop(L); | 
| jbe/bsw@0 | 51   lua_getglobal(L, "slot"); | 
| jbe/bsw@0 | 52   lua_getfield(L, -1, "_data"); | 
| jbe/bsw@0 | 53   lua_pushvalue(L, 1); | 
| jbe/bsw@0 | 54   lua_gettable(L, -2);  // get table by reference passed as 1st argument | 
| jbe/bsw@0 | 55   lua_getfield(L, -1, "string_fragments"); | 
| jbe@66 | 56 #if LUA_VERSION_NUM >= 502 | 
| jbe@64 | 57   j = lua_rawlen(L, -1); | 
| jbe@64 | 58 #else | 
| jbe/bsw@0 | 59   j = lua_objlen(L, -1); | 
| jbe@64 | 60 #endif | 
| jbe/bsw@0 | 61   for (i=2; i<=argc; i++) { | 
| jbe/bsw@0 | 62     lua_pushvalue(L, i); | 
| jbe/bsw@0 | 63     lua_rawseti(L, -2, ++j); | 
| jbe/bsw@0 | 64   } | 
| jbe/bsw@0 | 65   return 0; | 
| jbe/bsw@0 | 66 } | 
| jbe/bsw@0 | 67 | 
| jbe/bsw@0 | 68 static int webmcp_slot_put(lua_State *L) { | 
| jbe/bsw@0 | 69   int argc; | 
| jbe/bsw@0 | 70   int i; | 
| jbe/bsw@0 | 71   int j; | 
| jbe/bsw@0 | 72   argc = lua_gettop(L); | 
| jbe/bsw@0 | 73   lua_getglobal(L, "slot"); | 
| jbe/bsw@0 | 74   lua_getfield(L, -1, "_data"); | 
| jbe/bsw@0 | 75   lua_getfield(L, -2, "_active_slot"); | 
| jbe/bsw@0 | 76   lua_gettable(L, -2); | 
| jbe/bsw@0 | 77   lua_getfield(L, -1, "string_fragments"); | 
| jbe@66 | 78 #if LUA_VERSION_NUM >= 502 | 
| jbe@64 | 79   j = lua_rawlen(L, -1); | 
| jbe@64 | 80 #else | 
| jbe/bsw@0 | 81   j = lua_objlen(L, -1); | 
| jbe@64 | 82 #endif | 
| jbe/bsw@0 | 83   for (i=1; i<=argc; i++) { | 
| jbe/bsw@0 | 84     lua_pushvalue(L, i); | 
| jbe/bsw@0 | 85     lua_rawseti(L, -2, ++j); | 
| jbe/bsw@0 | 86   } | 
| jbe/bsw@0 | 87   return 0; | 
| jbe/bsw@0 | 88 } | 
| jbe/bsw@0 | 89 | 
| jbe/bsw@0 | 90 static int webmcp_ui_tag(lua_State *L) { | 
| jbe/bsw@0 | 91   int tag_given = 0; | 
| jbe/bsw@0 | 92   int j; | 
| jbe/bsw@0 | 93   lua_settop(L, 1); | 
| jbe/bsw@0 | 94   luaL_checktype(L, 1, LUA_TTABLE); | 
| jbe/bsw@0 | 95   lua_getglobal(L, "slot");       // 2 | 
| jbe/bsw@0 | 96   lua_getfield(L, 2, "_data");    // 3 | 
| jbe/bsw@0 | 97   lua_getfield(L, 2, "_active_slot"); | 
| jbe/bsw@0 | 98   lua_gettable(L, 3);             // 4 | 
| jbe/bsw@0 | 99   lua_getfield(L, 4, "string_fragments");  // 5 | 
| jbe/bsw@0 | 100   lua_getfield(L, 1, "tag");      // 6 | 
| jbe/bsw@0 | 101   lua_getfield(L, 1, "attr");     // 7 | 
| jbe/bsw@0 | 102   lua_getfield(L, 1, "content");  // 8 | 
| jbe/bsw@0 | 103   if (lua_toboolean(L, 7) && !lua_istable(L, 7)) { | 
| jbe/bsw@0 | 104     return luaL_error(L, | 
| jbe/bsw@0 | 105       "\"attr\" argument for ui.tag{...} must be nil or a table." | 
| jbe/bsw@0 | 106     ); | 
| jbe/bsw@0 | 107   } | 
| jbe/bsw@0 | 108   if (lua_toboolean(L, 6)) { | 
| jbe/bsw@0 | 109     tag_given = 1; | 
| jbe/bsw@0 | 110   } else if (lua_toboolean(L, 7)) { | 
| jbe/bsw@0 | 111     lua_pushnil(L); | 
| jbe/bsw@0 | 112     if (lua_next(L, 7)) { | 
| jbe/bsw@0 | 113       lua_pop(L, 2); | 
| jbe/bsw@0 | 114       lua_pushliteral(L, "span"); | 
| jbe/bsw@0 | 115       lua_replace(L, 6); | 
| jbe/bsw@0 | 116       tag_given = 1; | 
| jbe/bsw@0 | 117     } | 
| jbe/bsw@0 | 118   } | 
| jbe@66 | 119 #if LUA_VERSION_NUM >= 502 | 
| jbe@64 | 120   j = lua_rawlen(L, 5); | 
| jbe@64 | 121 #else | 
| jbe/bsw@0 | 122   j = lua_objlen(L, 5); | 
| jbe@64 | 123 #endif | 
| jbe/bsw@0 | 124   if (tag_given) { | 
| jbe/bsw@0 | 125     lua_pushliteral(L, "<"); | 
| jbe/bsw@0 | 126     lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 127     lua_pushvalue(L, 6); | 
| jbe/bsw@0 | 128     lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 129     if (lua_toboolean(L, 7)) { | 
| jbe/bsw@0 | 130       for (lua_pushnil(L); lua_next(L, 7); lua_pop(L, 1)) { | 
| jbe/bsw@0 | 131         // key at position 9 | 
| jbe/bsw@0 | 132         // value at position 10 | 
| jbe/bsw@0 | 133         lua_pushliteral(L, " "); | 
| jbe/bsw@0 | 134         lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 135         lua_pushvalue(L, 9); | 
| jbe/bsw@0 | 136         lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 137         lua_pushliteral(L, "=\""); | 
| jbe/bsw@0 | 138         lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 139         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 | 140           lua_getglobal(L, "table");  // 11 | 
| jbe/bsw@0 | 141           lua_getfield(L, 11, "concat");  // 12 | 
| jbe/bsw@0 | 142           lua_replace(L, 11);  // 11 | 
| jbe/bsw@0 | 143           lua_pushvalue(L, 10);  // 12 | 
| jbe/bsw@0 | 144           lua_pushliteral(L, " ");  // 13 | 
| jbe/bsw@0 | 145           lua_call(L, 2, 1);  // 11 | 
| jbe/bsw@0 | 146           lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 147         } else { | 
| jbe/bsw@0 | 148           lua_pushcfunction(L, webmcp_encode_html); | 
| jbe/bsw@0 | 149           lua_pushvalue(L, 10); | 
| jbe/bsw@0 | 150           lua_call(L, 1, 1); | 
| jbe/bsw@0 | 151           lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 152         } | 
| jbe/bsw@0 | 153         lua_pushliteral(L, "\""); | 
| jbe/bsw@0 | 154         lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 155       } | 
| jbe/bsw@0 | 156     } | 
| jbe/bsw@0 | 157   } | 
| jbe/bsw@0 | 158   if (lua_toboolean(L, 8)) { | 
| jbe/bsw@0 | 159     if (tag_given) { | 
| jbe/bsw@0 | 160       lua_pushliteral(L, ">"); | 
| jbe/bsw@0 | 161       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 162     } | 
| jbe/bsw@0 | 163     if (lua_isfunction(L, 8)) { | 
| jbe/bsw@0 | 164       // content function should be on last stack position 8 | 
| jbe/bsw@0 | 165       lua_call(L, 0, 0); | 
| jbe/bsw@0 | 166       // stack is now at position 7, but we don't care | 
| jbe/bsw@0 | 167       // we assume that the active slot hasn't been exchanged or resetted | 
| jbe@66 | 168 #if LUA_VERSION_NUM >= 502 | 
| jbe@64 | 169       j = lua_rawlen(L, 5);  // but it may include more elements now | 
| jbe@64 | 170 #else | 
| jbe/bsw@0 | 171       j = lua_objlen(L, 5);  // but it may include more elements now | 
| jbe@64 | 172 #endif | 
| jbe/bsw@0 | 173     } else { | 
| jbe/bsw@0 | 174       lua_pushcfunction(L, webmcp_encode_html);  // 9 | 
| jbe/bsw@0 | 175       lua_pushvalue(L, 8);  // 10 | 
| jbe/bsw@0 | 176       lua_call(L, 1, 1);  // 9 | 
| jbe/bsw@0 | 177       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 178     } | 
| jbe/bsw@0 | 179     if (tag_given) { | 
| jbe/bsw@0 | 180       lua_pushliteral(L, "</"); | 
| jbe/bsw@0 | 181       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 182       lua_pushvalue(L, 6); | 
| jbe/bsw@0 | 183       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 184       lua_pushliteral(L, ">"); | 
| jbe/bsw@0 | 185       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 186     } | 
| jbe/bsw@0 | 187   } else { | 
| jbe/bsw@0 | 188     if (tag_given) { | 
| jbe/bsw@0 | 189       lua_pushliteral(L, " />"); | 
| jbe/bsw@0 | 190       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 191     } | 
| jbe/bsw@0 | 192   } | 
| jbe/bsw@0 | 193   return 0; | 
| jbe/bsw@0 | 194 } | 
| jbe/bsw@0 | 195 | 
| jbe/bsw@0 | 196 int luaopen_webmcp_accelerator(lua_State *L) { | 
| jbe/bsw@0 | 197   lua_settop(L, 0); | 
| jbe/bsw@0 | 198   lua_getglobal(L, "encode");  // 1 | 
| jbe/bsw@0 | 199   lua_pushcfunction(L, webmcp_encode_html); | 
| jbe/bsw@0 | 200   lua_setfield(L, 1, "html"); | 
| jbe/bsw@0 | 201   lua_settop(L, 0); | 
| jbe/bsw@0 | 202   lua_getglobal(L, "slot");  // 1 | 
| jbe/bsw@0 | 203   lua_pushcfunction(L, webmcp_slot_put_into); | 
| jbe/bsw@0 | 204   lua_setfield(L, 1, "put_into"); | 
| jbe/bsw@0 | 205   lua_pushcfunction(L, webmcp_slot_put); | 
| jbe/bsw@0 | 206   lua_setfield(L, 1, "put"); | 
| jbe/bsw@0 | 207   lua_settop(L, 0); | 
| jbe/bsw@0 | 208   lua_getglobal(L, "ui");  // 1 | 
| jbe/bsw@0 | 209   lua_pushcfunction(L, webmcp_ui_tag); | 
| jbe/bsw@0 | 210   lua_setfield(L, 1, "tag"); | 
| jbe/bsw@0 | 211   return 0; | 
| jbe/bsw@0 | 212 } |