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