| 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@64 | 56   j = lua_rawlen(L, -1); | 
| jbe/bsw@0 | 57   for (i=2; i<=argc; i++) { | 
| jbe/bsw@0 | 58     lua_pushvalue(L, i); | 
| jbe/bsw@0 | 59     lua_rawseti(L, -2, ++j); | 
| jbe/bsw@0 | 60   } | 
| jbe/bsw@0 | 61   return 0; | 
| jbe/bsw@0 | 62 } | 
| jbe/bsw@0 | 63 | 
| jbe/bsw@0 | 64 static int webmcp_slot_put(lua_State *L) { | 
| jbe/bsw@0 | 65   int argc; | 
| jbe/bsw@0 | 66   int i; | 
| jbe/bsw@0 | 67   int j; | 
| jbe/bsw@0 | 68   argc = lua_gettop(L); | 
| jbe/bsw@0 | 69   lua_getglobal(L, "slot"); | 
| jbe/bsw@0 | 70   lua_getfield(L, -1, "_data"); | 
| jbe/bsw@0 | 71   lua_getfield(L, -2, "_active_slot"); | 
| jbe/bsw@0 | 72   lua_gettable(L, -2); | 
| jbe/bsw@0 | 73   lua_getfield(L, -1, "string_fragments"); | 
| jbe@64 | 74   j = lua_rawlen(L, -1); | 
| jbe/bsw@0 | 75   for (i=1; i<=argc; i++) { | 
| jbe/bsw@0 | 76     lua_pushvalue(L, i); | 
| jbe/bsw@0 | 77     lua_rawseti(L, -2, ++j); | 
| jbe/bsw@0 | 78   } | 
| jbe/bsw@0 | 79   return 0; | 
| jbe/bsw@0 | 80 } | 
| jbe/bsw@0 | 81 | 
| jbe/bsw@0 | 82 static int webmcp_ui_tag(lua_State *L) { | 
| jbe/bsw@0 | 83   int tag_given = 0; | 
| jbe/bsw@0 | 84   int j; | 
| jbe/bsw@0 | 85   lua_settop(L, 1); | 
| jbe/bsw@0 | 86   luaL_checktype(L, 1, LUA_TTABLE); | 
| jbe/bsw@0 | 87   lua_getglobal(L, "slot");       // 2 | 
| jbe/bsw@0 | 88   lua_getfield(L, 2, "_data");    // 3 | 
| jbe/bsw@0 | 89   lua_getfield(L, 2, "_active_slot"); | 
| jbe/bsw@0 | 90   lua_gettable(L, 3);             // 4 | 
| jbe/bsw@0 | 91   lua_getfield(L, 4, "string_fragments");  // 5 | 
| jbe/bsw@0 | 92   lua_getfield(L, 1, "tag");      // 6 | 
| jbe/bsw@0 | 93   lua_getfield(L, 1, "attr");     // 7 | 
| jbe/bsw@0 | 94   lua_getfield(L, 1, "content");  // 8 | 
| jbe/bsw@0 | 95   if (lua_toboolean(L, 7) && !lua_istable(L, 7)) { | 
| jbe/bsw@0 | 96     return luaL_error(L, | 
| jbe/bsw@0 | 97       "\"attr\" argument for ui.tag{...} must be nil or a table." | 
| jbe/bsw@0 | 98     ); | 
| jbe/bsw@0 | 99   } | 
| jbe/bsw@0 | 100   if (lua_toboolean(L, 6)) { | 
| jbe/bsw@0 | 101     tag_given = 1; | 
| jbe/bsw@0 | 102   } else if (lua_toboolean(L, 7)) { | 
| jbe/bsw@0 | 103     lua_pushnil(L); | 
| jbe/bsw@0 | 104     if (lua_next(L, 7)) { | 
| jbe/bsw@0 | 105       lua_pop(L, 2); | 
| jbe/bsw@0 | 106       lua_pushliteral(L, "span"); | 
| jbe/bsw@0 | 107       lua_replace(L, 6); | 
| jbe/bsw@0 | 108       tag_given = 1; | 
| jbe/bsw@0 | 109     } | 
| jbe/bsw@0 | 110   } | 
| jbe@64 | 111   j = lua_rawlen(L, 5); | 
| jbe/bsw@0 | 112   if (tag_given) { | 
| jbe/bsw@0 | 113     lua_pushliteral(L, "<"); | 
| jbe/bsw@0 | 114     lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 115     lua_pushvalue(L, 6); | 
| jbe/bsw@0 | 116     lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 117     if (lua_toboolean(L, 7)) { | 
| jbe/bsw@0 | 118       for (lua_pushnil(L); lua_next(L, 7); lua_pop(L, 1)) { | 
| jbe/bsw@0 | 119         // key at position 9 | 
| jbe/bsw@0 | 120         // value at position 10 | 
| jbe/bsw@0 | 121         lua_pushliteral(L, " "); | 
| jbe/bsw@0 | 122         lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 123         lua_pushvalue(L, 9); | 
| jbe/bsw@0 | 124         lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 125         lua_pushliteral(L, "=\""); | 
| jbe/bsw@0 | 126         lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 127         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 | 128           lua_getglobal(L, "table");  // 11 | 
| jbe/bsw@0 | 129           lua_getfield(L, 11, "concat");  // 12 | 
| jbe/bsw@0 | 130           lua_replace(L, 11);  // 11 | 
| jbe/bsw@0 | 131           lua_pushvalue(L, 10);  // 12 | 
| jbe/bsw@0 | 132           lua_pushliteral(L, " ");  // 13 | 
| jbe/bsw@0 | 133           lua_call(L, 2, 1);  // 11 | 
| jbe/bsw@0 | 134           lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 135         } else { | 
| jbe/bsw@0 | 136           lua_pushcfunction(L, webmcp_encode_html); | 
| jbe/bsw@0 | 137           lua_pushvalue(L, 10); | 
| jbe/bsw@0 | 138           lua_call(L, 1, 1); | 
| jbe/bsw@0 | 139           lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 140         } | 
| jbe/bsw@0 | 141         lua_pushliteral(L, "\""); | 
| jbe/bsw@0 | 142         lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 143       } | 
| jbe/bsw@0 | 144     } | 
| jbe/bsw@0 | 145   } | 
| jbe/bsw@0 | 146   if (lua_toboolean(L, 8)) { | 
| jbe/bsw@0 | 147     if (tag_given) { | 
| jbe/bsw@0 | 148       lua_pushliteral(L, ">"); | 
| jbe/bsw@0 | 149       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 150     } | 
| jbe/bsw@0 | 151     if (lua_isfunction(L, 8)) { | 
| jbe/bsw@0 | 152       // content function should be on last stack position 8 | 
| jbe/bsw@0 | 153       lua_call(L, 0, 0); | 
| jbe/bsw@0 | 154       // stack is now at position 7, but we don't care | 
| jbe/bsw@0 | 155       // we assume that the active slot hasn't been exchanged or resetted | 
| jbe@64 | 156       j = lua_rawlen(L, 5);  // but it may include more elements now | 
| jbe/bsw@0 | 157     } else { | 
| jbe/bsw@0 | 158       lua_pushcfunction(L, webmcp_encode_html);  // 9 | 
| jbe/bsw@0 | 159       lua_pushvalue(L, 8);  // 10 | 
| jbe/bsw@0 | 160       lua_call(L, 1, 1);  // 9 | 
| jbe/bsw@0 | 161       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 162     } | 
| jbe/bsw@0 | 163     if (tag_given) { | 
| jbe/bsw@0 | 164       lua_pushliteral(L, "</"); | 
| jbe/bsw@0 | 165       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 166       lua_pushvalue(L, 6); | 
| jbe/bsw@0 | 167       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 168       lua_pushliteral(L, ">"); | 
| jbe/bsw@0 | 169       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 170     } | 
| jbe/bsw@0 | 171   } else { | 
| jbe/bsw@0 | 172     if (tag_given) { | 
| jbe/bsw@0 | 173       lua_pushliteral(L, " />"); | 
| jbe/bsw@0 | 174       lua_rawseti(L, 5, ++j); | 
| jbe/bsw@0 | 175     } | 
| jbe/bsw@0 | 176   } | 
| jbe/bsw@0 | 177   return 0; | 
| jbe/bsw@0 | 178 } | 
| jbe/bsw@0 | 179 | 
| jbe/bsw@0 | 180 int luaopen_webmcp_accelerator(lua_State *L) { | 
| jbe/bsw@0 | 181   lua_settop(L, 0); | 
| jbe/bsw@0 | 182   lua_getglobal(L, "encode");  // 1 | 
| jbe/bsw@0 | 183   lua_pushcfunction(L, webmcp_encode_html); | 
| jbe/bsw@0 | 184   lua_setfield(L, 1, "html"); | 
| jbe/bsw@0 | 185   lua_settop(L, 0); | 
| jbe/bsw@0 | 186   lua_getglobal(L, "slot");  // 1 | 
| jbe/bsw@0 | 187   lua_pushcfunction(L, webmcp_slot_put_into); | 
| jbe/bsw@0 | 188   lua_setfield(L, 1, "put_into"); | 
| jbe/bsw@0 | 189   lua_pushcfunction(L, webmcp_slot_put); | 
| jbe/bsw@0 | 190   lua_setfield(L, 1, "put"); | 
| jbe/bsw@0 | 191   lua_settop(L, 0); | 
| jbe/bsw@0 | 192   lua_getglobal(L, "ui");  // 1 | 
| jbe/bsw@0 | 193   lua_pushcfunction(L, webmcp_ui_tag); | 
| jbe/bsw@0 | 194   lua_setfield(L, 1, "tag"); | 
| jbe/bsw@0 | 195   return 0; | 
| jbe/bsw@0 | 196 } |