webmcp
view framework/accelerator/webmcp_accelerator.c @ 2:72860d232f32
Version 1.0.2
Fixed bug with explicit garbage collection (requests > 256kB caused an error)
Views prefixed with an underscore can't be called externally
ui.paginate now displays the last page, if the selected page number is too high.
Fixed bug with explicit garbage collection (requests > 256kB caused an error)
Views prefixed with an underscore can't be called externally
ui.paginate now displays the last page, if the selected page number is too high.
author | jbe/bsw |
---|---|
date | Thu Dec 10 12:00:00 2009 +0100 (2009-12-10) |
parents | 9fdfb27f8e67 |
children | 3d43a5cf17c1 |
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_objlen(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_objlen(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_objlen(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_objlen(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 }