webmcp

view framework/accelerator/webmcp_accelerator.c @ 334:ac44b171aa09

merge
author jbe
date Tue Mar 24 17:27:41 2015 +0100 (2015-03-24)
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, "&lt;");
35 else if (c == '>') luaL_addstring(&buf, "&gt;");
36 else if (c == '&') luaL_addstring(&buf, "&amp;");
37 else if (c == '"') luaL_addstring(&buf, "&quot;");
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 }

Impressum / About Us