webmcp

view framework/accelerator/webmcp_accelerator.c @ 79:3a6962b9121c

Anchor support for encode.url{...}, ui.link{...} and ui.paginate{...}
author jbe
date Wed Jun 27 18:57:53 2012 +0200 (2012-06-27)
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, "&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 #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 }

Impressum / About Us