| 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 }
 |