webmcp

diff framework/accelerator/webmcp_accelerator.c @ 0:9fdfb27f8e67

Version 1.0.0
author jbe/bsw
date Sun Oct 25 12:00:00 2009 +0100 (2009-10-25)
parents
children 3d43a5cf17c1
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/framework/accelerator/webmcp_accelerator.c	Sun Oct 25 12:00:00 2009 +0100
     1.3 @@ -0,0 +1,196 @@
     1.4 +#include <lua.h>
     1.5 +#include <lauxlib.h>
     1.6 +#include <stdlib.h>
     1.7 +#include <string.h>
     1.8 +
     1.9 +static int webmcp_encode_html(lua_State *L) {
    1.10 +  const char *input;
    1.11 +  size_t input_len;
    1.12 +  size_t i;
    1.13 +  luaL_Buffer buf;
    1.14 +  input = luaL_checklstring(L, 1, &input_len);
    1.15 +  for (i=0; i<input_len; i++) {
    1.16 +    char c = input[i];
    1.17 +    if ((c == '<') || (c == '>') || (c == '&') || (c == '"')) break;
    1.18 +  }
    1.19 +  if (i == input_len) {
    1.20 +    lua_settop(L, 1);
    1.21 +    return 1;
    1.22 +  }
    1.23 +  luaL_buffinit(L, &buf);
    1.24 +  for (i=0; i<input_len; i++) {
    1.25 +    char c;
    1.26 +    size_t j = i;
    1.27 +    do {
    1.28 +      c = input[j];
    1.29 +      if ((c == '<') || (c == '>') || (c == '&') || (c == '"')) break;
    1.30 +      else j++;
    1.31 +    } while (j<input_len);
    1.32 +    if (j != i) {
    1.33 +      luaL_addlstring(&buf, input+i, j-i);
    1.34 +      i = j;
    1.35 +    }
    1.36 +    if (i<input_len) {
    1.37 +      if      (c == '<') luaL_addstring(&buf, "&lt;");
    1.38 +      else if (c == '>') luaL_addstring(&buf, "&gt;");
    1.39 +      else if (c == '&') luaL_addstring(&buf, "&amp;");
    1.40 +      else if (c == '"') luaL_addstring(&buf, "&quot;");
    1.41 +      else abort();  // should not happen
    1.42 +    }
    1.43 +  }
    1.44 +  luaL_pushresult(&buf);
    1.45 +  return 1;
    1.46 +}
    1.47 +
    1.48 +static int webmcp_slot_put_into(lua_State *L) {
    1.49 +  int argc;
    1.50 +  int i;
    1.51 +  int j;
    1.52 +  luaL_checkany(L, 1);
    1.53 +  argc = lua_gettop(L);
    1.54 +  lua_getglobal(L, "slot");
    1.55 +  lua_getfield(L, -1, "_data");
    1.56 +  lua_pushvalue(L, 1);
    1.57 +  lua_gettable(L, -2);  // get table by reference passed as 1st argument
    1.58 +  lua_getfield(L, -1, "string_fragments");
    1.59 +  j = lua_objlen(L, -1);
    1.60 +  for (i=2; i<=argc; i++) {
    1.61 +    lua_pushvalue(L, i);
    1.62 +    lua_rawseti(L, -2, ++j);
    1.63 +  }
    1.64 +  return 0;
    1.65 +}
    1.66 +
    1.67 +static int webmcp_slot_put(lua_State *L) {
    1.68 +  int argc;
    1.69 +  int i;
    1.70 +  int j;
    1.71 +  argc = lua_gettop(L);
    1.72 +  lua_getglobal(L, "slot");
    1.73 +  lua_getfield(L, -1, "_data");
    1.74 +  lua_getfield(L, -2, "_active_slot");
    1.75 +  lua_gettable(L, -2);
    1.76 +  lua_getfield(L, -1, "string_fragments");
    1.77 +  j = lua_objlen(L, -1);
    1.78 +  for (i=1; i<=argc; i++) {
    1.79 +    lua_pushvalue(L, i);
    1.80 +    lua_rawseti(L, -2, ++j);
    1.81 +  }
    1.82 +  return 0;
    1.83 +}
    1.84 +
    1.85 +static int webmcp_ui_tag(lua_State *L) {
    1.86 +  int tag_given = 0;
    1.87 +  int j;
    1.88 +  lua_settop(L, 1);
    1.89 +  luaL_checktype(L, 1, LUA_TTABLE);
    1.90 +  lua_getglobal(L, "slot");       // 2
    1.91 +  lua_getfield(L, 2, "_data");    // 3
    1.92 +  lua_getfield(L, 2, "_active_slot");
    1.93 +  lua_gettable(L, 3);             // 4
    1.94 +  lua_getfield(L, 4, "string_fragments");  // 5
    1.95 +  lua_getfield(L, 1, "tag");      // 6
    1.96 +  lua_getfield(L, 1, "attr");     // 7
    1.97 +  lua_getfield(L, 1, "content");  // 8
    1.98 +  if (lua_toboolean(L, 7) && !lua_istable(L, 7)) {
    1.99 +    return luaL_error(L,
   1.100 +      "\"attr\" argument for ui.tag{...} must be nil or a table."
   1.101 +    );
   1.102 +  }
   1.103 +  if (lua_toboolean(L, 6)) {
   1.104 +    tag_given = 1;
   1.105 +  } else if (lua_toboolean(L, 7)) {
   1.106 +    lua_pushnil(L);
   1.107 +    if (lua_next(L, 7)) {
   1.108 +      lua_pop(L, 2);
   1.109 +      lua_pushliteral(L, "span");
   1.110 +      lua_replace(L, 6);
   1.111 +      tag_given = 1;
   1.112 +    }
   1.113 +  }
   1.114 +  j = lua_objlen(L, 5);
   1.115 +  if (tag_given) {
   1.116 +    lua_pushliteral(L, "<");
   1.117 +    lua_rawseti(L, 5, ++j);
   1.118 +    lua_pushvalue(L, 6);
   1.119 +    lua_rawseti(L, 5, ++j);
   1.120 +    if (lua_toboolean(L, 7)) {
   1.121 +      for (lua_pushnil(L); lua_next(L, 7); lua_pop(L, 1)) {
   1.122 +        // key at position 9
   1.123 +        // value at position 10
   1.124 +        lua_pushliteral(L, " ");
   1.125 +        lua_rawseti(L, 5, ++j);
   1.126 +        lua_pushvalue(L, 9);
   1.127 +        lua_rawseti(L, 5, ++j);
   1.128 +        lua_pushliteral(L, "=\"");
   1.129 +        lua_rawseti(L, 5, ++j);
   1.130 +        if (!strcmp(lua_tostring(L, 9), "class") && lua_istable(L, 10)) {  // NOTE: lua_tostring(...) is destructive, will cause errors for numeric keys
   1.131 +          lua_getglobal(L, "table");  // 11
   1.132 +          lua_getfield(L, 11, "concat");  // 12
   1.133 +          lua_replace(L, 11);  // 11
   1.134 +          lua_pushvalue(L, 10);  // 12
   1.135 +          lua_pushliteral(L, " ");  // 13
   1.136 +          lua_call(L, 2, 1);  // 11
   1.137 +          lua_rawseti(L, 5, ++j);
   1.138 +        } else {
   1.139 +          lua_pushcfunction(L, webmcp_encode_html);
   1.140 +          lua_pushvalue(L, 10);
   1.141 +          lua_call(L, 1, 1);
   1.142 +          lua_rawseti(L, 5, ++j);
   1.143 +        }
   1.144 +        lua_pushliteral(L, "\"");
   1.145 +        lua_rawseti(L, 5, ++j);
   1.146 +      }
   1.147 +    }
   1.148 +  }
   1.149 +  if (lua_toboolean(L, 8)) {
   1.150 +    if (tag_given) {
   1.151 +      lua_pushliteral(L, ">");
   1.152 +      lua_rawseti(L, 5, ++j);
   1.153 +    }
   1.154 +    if (lua_isfunction(L, 8)) {
   1.155 +      // content function should be on last stack position 8
   1.156 +      lua_call(L, 0, 0);
   1.157 +      // stack is now at position 7, but we don't care
   1.158 +      // we assume that the active slot hasn't been exchanged or resetted
   1.159 +      j = lua_objlen(L, 5);  // but it may include more elements now
   1.160 +    } else {
   1.161 +      lua_pushcfunction(L, webmcp_encode_html);  // 9
   1.162 +      lua_pushvalue(L, 8);  // 10
   1.163 +      lua_call(L, 1, 1);  // 9
   1.164 +      lua_rawseti(L, 5, ++j);
   1.165 +    }
   1.166 +    if (tag_given) {
   1.167 +      lua_pushliteral(L, "</");
   1.168 +      lua_rawseti(L, 5, ++j);
   1.169 +      lua_pushvalue(L, 6);
   1.170 +      lua_rawseti(L, 5, ++j);
   1.171 +      lua_pushliteral(L, ">");
   1.172 +      lua_rawseti(L, 5, ++j);
   1.173 +    }
   1.174 +  } else {
   1.175 +    if (tag_given) {
   1.176 +      lua_pushliteral(L, " />");
   1.177 +      lua_rawseti(L, 5, ++j);
   1.178 +    }
   1.179 +  }
   1.180 +  return 0;
   1.181 +}
   1.182 +
   1.183 +int luaopen_webmcp_accelerator(lua_State *L) {
   1.184 +  lua_settop(L, 0);
   1.185 +  lua_getglobal(L, "encode");  // 1
   1.186 +  lua_pushcfunction(L, webmcp_encode_html);
   1.187 +  lua_setfield(L, 1, "html");
   1.188 +  lua_settop(L, 0);
   1.189 +  lua_getglobal(L, "slot");  // 1
   1.190 +  lua_pushcfunction(L, webmcp_slot_put_into);
   1.191 +  lua_setfield(L, 1, "put_into");
   1.192 +  lua_pushcfunction(L, webmcp_slot_put);
   1.193 +  lua_setfield(L, 1, "put");
   1.194 +  lua_settop(L, 0);
   1.195 +  lua_getglobal(L, "ui");  // 1
   1.196 +  lua_pushcfunction(L, webmcp_ui_tag);
   1.197 +  lua_setfield(L, 1, "tag");
   1.198 +  return 0;
   1.199 +}

Impressum / About Us