rev |
line source |
jbe/bsw@0
|
1 #include <lua.h>
|
jbe/bsw@0
|
2 #include <lauxlib.h>
|
jbe/bsw@0
|
3 #include <stdlib.h>
|
jbe/bsw@0
|
4 #include <string.h>
|
jbe/bsw@0
|
5
|
jbe/bsw@0
|
6 static int webmcp_encode_html(lua_State *L) {
|
jbe/bsw@0
|
7 const char *input;
|
jbe/bsw@0
|
8 size_t input_len;
|
jbe/bsw@0
|
9 size_t i;
|
jbe/bsw@0
|
10 luaL_Buffer buf;
|
jbe/bsw@0
|
11 input = luaL_checklstring(L, 1, &input_len);
|
jbe/bsw@0
|
12 for (i=0; i<input_len; i++) {
|
jbe/bsw@0
|
13 char c = input[i];
|
jbe/bsw@0
|
14 if ((c == '<') || (c == '>') || (c == '&') || (c == '"')) break;
|
jbe/bsw@0
|
15 }
|
jbe/bsw@0
|
16 if (i == input_len) {
|
jbe/bsw@0
|
17 lua_settop(L, 1);
|
jbe/bsw@0
|
18 return 1;
|
jbe/bsw@0
|
19 }
|
jbe/bsw@0
|
20 luaL_buffinit(L, &buf);
|
jbe/bsw@0
|
21 for (i=0; i<input_len; i++) {
|
jbe/bsw@0
|
22 char c;
|
jbe/bsw@0
|
23 size_t j = i;
|
jbe/bsw@0
|
24 do {
|
jbe/bsw@0
|
25 c = input[j];
|
jbe/bsw@0
|
26 if ((c == '<') || (c == '>') || (c == '&') || (c == '"')) break;
|
jbe/bsw@0
|
27 else j++;
|
jbe/bsw@0
|
28 } while (j<input_len);
|
jbe/bsw@0
|
29 if (j != i) {
|
jbe/bsw@0
|
30 luaL_addlstring(&buf, input+i, j-i);
|
jbe/bsw@0
|
31 i = j;
|
jbe/bsw@0
|
32 }
|
jbe/bsw@0
|
33 if (i<input_len) {
|
jbe/bsw@0
|
34 if (c == '<') luaL_addstring(&buf, "<");
|
jbe/bsw@0
|
35 else if (c == '>') luaL_addstring(&buf, ">");
|
jbe/bsw@0
|
36 else if (c == '&') luaL_addstring(&buf, "&");
|
jbe/bsw@0
|
37 else if (c == '"') luaL_addstring(&buf, """);
|
jbe/bsw@0
|
38 else abort(); // should not happen
|
jbe/bsw@0
|
39 }
|
jbe/bsw@0
|
40 }
|
jbe/bsw@0
|
41 luaL_pushresult(&buf);
|
jbe/bsw@0
|
42 return 1;
|
jbe/bsw@0
|
43 }
|
jbe/bsw@0
|
44
|
jbe/bsw@0
|
45 static int webmcp_slot_put_into(lua_State *L) {
|
jbe/bsw@0
|
46 int argc;
|
jbe/bsw@0
|
47 int i;
|
jbe/bsw@0
|
48 int j;
|
jbe/bsw@0
|
49 luaL_checkany(L, 1);
|
jbe/bsw@0
|
50 argc = lua_gettop(L);
|
jbe/bsw@0
|
51 lua_getglobal(L, "slot");
|
jbe/bsw@0
|
52 lua_getfield(L, -1, "_data");
|
jbe/bsw@0
|
53 lua_pushvalue(L, 1);
|
jbe/bsw@0
|
54 lua_gettable(L, -2); // get table by reference passed as 1st argument
|
jbe/bsw@0
|
55 lua_getfield(L, -1, "string_fragments");
|
jbe@64
|
56 j = lua_rawlen(L, -1);
|
jbe/bsw@0
|
57 for (i=2; i<=argc; i++) {
|
jbe/bsw@0
|
58 lua_pushvalue(L, i);
|
jbe/bsw@0
|
59 lua_rawseti(L, -2, ++j);
|
jbe/bsw@0
|
60 }
|
jbe/bsw@0
|
61 return 0;
|
jbe/bsw@0
|
62 }
|
jbe/bsw@0
|
63
|
jbe/bsw@0
|
64 static int webmcp_slot_put(lua_State *L) {
|
jbe/bsw@0
|
65 int argc;
|
jbe/bsw@0
|
66 int i;
|
jbe/bsw@0
|
67 int j;
|
jbe/bsw@0
|
68 argc = lua_gettop(L);
|
jbe/bsw@0
|
69 lua_getglobal(L, "slot");
|
jbe/bsw@0
|
70 lua_getfield(L, -1, "_data");
|
jbe/bsw@0
|
71 lua_getfield(L, -2, "_active_slot");
|
jbe/bsw@0
|
72 lua_gettable(L, -2);
|
jbe/bsw@0
|
73 lua_getfield(L, -1, "string_fragments");
|
jbe@64
|
74 j = lua_rawlen(L, -1);
|
jbe/bsw@0
|
75 for (i=1; i<=argc; i++) {
|
jbe/bsw@0
|
76 lua_pushvalue(L, i);
|
jbe/bsw@0
|
77 lua_rawseti(L, -2, ++j);
|
jbe/bsw@0
|
78 }
|
jbe/bsw@0
|
79 return 0;
|
jbe/bsw@0
|
80 }
|
jbe/bsw@0
|
81
|
jbe/bsw@0
|
82 static int webmcp_ui_tag(lua_State *L) {
|
jbe/bsw@0
|
83 int tag_given = 0;
|
jbe/bsw@0
|
84 int j;
|
jbe/bsw@0
|
85 lua_settop(L, 1);
|
jbe/bsw@0
|
86 luaL_checktype(L, 1, LUA_TTABLE);
|
jbe/bsw@0
|
87 lua_getglobal(L, "slot"); // 2
|
jbe/bsw@0
|
88 lua_getfield(L, 2, "_data"); // 3
|
jbe/bsw@0
|
89 lua_getfield(L, 2, "_active_slot");
|
jbe/bsw@0
|
90 lua_gettable(L, 3); // 4
|
jbe/bsw@0
|
91 lua_getfield(L, 4, "string_fragments"); // 5
|
jbe/bsw@0
|
92 lua_getfield(L, 1, "tag"); // 6
|
jbe/bsw@0
|
93 lua_getfield(L, 1, "attr"); // 7
|
jbe/bsw@0
|
94 lua_getfield(L, 1, "content"); // 8
|
jbe/bsw@0
|
95 if (lua_toboolean(L, 7) && !lua_istable(L, 7)) {
|
jbe/bsw@0
|
96 return luaL_error(L,
|
jbe/bsw@0
|
97 "\"attr\" argument for ui.tag{...} must be nil or a table."
|
jbe/bsw@0
|
98 );
|
jbe/bsw@0
|
99 }
|
jbe/bsw@0
|
100 if (lua_toboolean(L, 6)) {
|
jbe/bsw@0
|
101 tag_given = 1;
|
jbe/bsw@0
|
102 } else if (lua_toboolean(L, 7)) {
|
jbe/bsw@0
|
103 lua_pushnil(L);
|
jbe/bsw@0
|
104 if (lua_next(L, 7)) {
|
jbe/bsw@0
|
105 lua_pop(L, 2);
|
jbe/bsw@0
|
106 lua_pushliteral(L, "span");
|
jbe/bsw@0
|
107 lua_replace(L, 6);
|
jbe/bsw@0
|
108 tag_given = 1;
|
jbe/bsw@0
|
109 }
|
jbe/bsw@0
|
110 }
|
jbe@64
|
111 j = lua_rawlen(L, 5);
|
jbe/bsw@0
|
112 if (tag_given) {
|
jbe/bsw@0
|
113 lua_pushliteral(L, "<");
|
jbe/bsw@0
|
114 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
115 lua_pushvalue(L, 6);
|
jbe/bsw@0
|
116 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
117 if (lua_toboolean(L, 7)) {
|
jbe/bsw@0
|
118 for (lua_pushnil(L); lua_next(L, 7); lua_pop(L, 1)) {
|
jbe/bsw@0
|
119 // key at position 9
|
jbe/bsw@0
|
120 // value at position 10
|
jbe/bsw@0
|
121 lua_pushliteral(L, " ");
|
jbe/bsw@0
|
122 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
123 lua_pushvalue(L, 9);
|
jbe/bsw@0
|
124 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
125 lua_pushliteral(L, "=\"");
|
jbe/bsw@0
|
126 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
127 if (!strcmp(lua_tostring(L, 9), "class") && lua_istable(L, 10)) { // NOTE: lua_tostring(...) is destructive, will cause errors for numeric keys
|
jbe/bsw@0
|
128 lua_getglobal(L, "table"); // 11
|
jbe/bsw@0
|
129 lua_getfield(L, 11, "concat"); // 12
|
jbe/bsw@0
|
130 lua_replace(L, 11); // 11
|
jbe/bsw@0
|
131 lua_pushvalue(L, 10); // 12
|
jbe/bsw@0
|
132 lua_pushliteral(L, " "); // 13
|
jbe/bsw@0
|
133 lua_call(L, 2, 1); // 11
|
jbe/bsw@0
|
134 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
135 } else {
|
jbe/bsw@0
|
136 lua_pushcfunction(L, webmcp_encode_html);
|
jbe/bsw@0
|
137 lua_pushvalue(L, 10);
|
jbe/bsw@0
|
138 lua_call(L, 1, 1);
|
jbe/bsw@0
|
139 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
140 }
|
jbe/bsw@0
|
141 lua_pushliteral(L, "\"");
|
jbe/bsw@0
|
142 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
143 }
|
jbe/bsw@0
|
144 }
|
jbe/bsw@0
|
145 }
|
jbe/bsw@0
|
146 if (lua_toboolean(L, 8)) {
|
jbe/bsw@0
|
147 if (tag_given) {
|
jbe/bsw@0
|
148 lua_pushliteral(L, ">");
|
jbe/bsw@0
|
149 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
150 }
|
jbe/bsw@0
|
151 if (lua_isfunction(L, 8)) {
|
jbe/bsw@0
|
152 // content function should be on last stack position 8
|
jbe/bsw@0
|
153 lua_call(L, 0, 0);
|
jbe/bsw@0
|
154 // stack is now at position 7, but we don't care
|
jbe/bsw@0
|
155 // we assume that the active slot hasn't been exchanged or resetted
|
jbe@64
|
156 j = lua_rawlen(L, 5); // but it may include more elements now
|
jbe/bsw@0
|
157 } else {
|
jbe/bsw@0
|
158 lua_pushcfunction(L, webmcp_encode_html); // 9
|
jbe/bsw@0
|
159 lua_pushvalue(L, 8); // 10
|
jbe/bsw@0
|
160 lua_call(L, 1, 1); // 9
|
jbe/bsw@0
|
161 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
162 }
|
jbe/bsw@0
|
163 if (tag_given) {
|
jbe/bsw@0
|
164 lua_pushliteral(L, "</");
|
jbe/bsw@0
|
165 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
166 lua_pushvalue(L, 6);
|
jbe/bsw@0
|
167 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
168 lua_pushliteral(L, ">");
|
jbe/bsw@0
|
169 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
170 }
|
jbe/bsw@0
|
171 } else {
|
jbe/bsw@0
|
172 if (tag_given) {
|
jbe/bsw@0
|
173 lua_pushliteral(L, " />");
|
jbe/bsw@0
|
174 lua_rawseti(L, 5, ++j);
|
jbe/bsw@0
|
175 }
|
jbe/bsw@0
|
176 }
|
jbe/bsw@0
|
177 return 0;
|
jbe/bsw@0
|
178 }
|
jbe/bsw@0
|
179
|
jbe/bsw@0
|
180 int luaopen_webmcp_accelerator(lua_State *L) {
|
jbe/bsw@0
|
181 lua_settop(L, 0);
|
jbe/bsw@0
|
182 lua_getglobal(L, "encode"); // 1
|
jbe/bsw@0
|
183 lua_pushcfunction(L, webmcp_encode_html);
|
jbe/bsw@0
|
184 lua_setfield(L, 1, "html");
|
jbe/bsw@0
|
185 lua_settop(L, 0);
|
jbe/bsw@0
|
186 lua_getglobal(L, "slot"); // 1
|
jbe/bsw@0
|
187 lua_pushcfunction(L, webmcp_slot_put_into);
|
jbe/bsw@0
|
188 lua_setfield(L, 1, "put_into");
|
jbe/bsw@0
|
189 lua_pushcfunction(L, webmcp_slot_put);
|
jbe/bsw@0
|
190 lua_setfield(L, 1, "put");
|
jbe/bsw@0
|
191 lua_settop(L, 0);
|
jbe/bsw@0
|
192 lua_getglobal(L, "ui"); // 1
|
jbe/bsw@0
|
193 lua_pushcfunction(L, webmcp_ui_tag);
|
jbe/bsw@0
|
194 lua_setfield(L, 1, "tag");
|
jbe/bsw@0
|
195 return 0;
|
jbe/bsw@0
|
196 }
|