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