adamc@117
|
1 #include <stdlib.h>
|
adamc@102
|
2 #include <stdio.h>
|
adamc@117
|
3 #include <string.h>
|
adamc@106
|
4 #include <ctype.h>
|
adamc@136
|
5 #include <assert.h>
|
adamc@167
|
6 #include <setjmp.h>
|
adamc@167
|
7 #include <stdarg.h>
|
adamc@102
|
8
|
adamc@102
|
9 #include "types.h"
|
adamc@102
|
10
|
adamc@102
|
11 lw_unit lw_unit_v = {};
|
adamc@102
|
12
|
adamc@167
|
13 #define ERROR_BUF_LEN 1024
|
adamc@167
|
14
|
adamc@117
|
15 struct lw_context {
|
adamc@117
|
16 char *page, *page_front, *page_back;
|
adamc@136
|
17 char *heap, *heap_front, *heap_back;
|
adamc@144
|
18 char **inputs;
|
adamc@167
|
19
|
adamc@167
|
20 jmp_buf jmp_buf;
|
adamc@167
|
21
|
adamc@167
|
22 failure_kind failure_kind;
|
adamc@167
|
23 char error_message[ERROR_BUF_LEN];
|
adamc@117
|
24 };
|
adamc@117
|
25
|
adamc@144
|
26 extern int lw_inputs_len;
|
adamc@144
|
27
|
adamc@136
|
28 lw_context lw_init(size_t page_len, size_t heap_len) {
|
adamc@117
|
29 lw_context ctx = malloc(sizeof(struct lw_context));
|
adamc@136
|
30
|
adamc@117
|
31 ctx->page_front = ctx->page = malloc(page_len);
|
adamc@117
|
32 ctx->page_back = ctx->page_front + page_len;
|
adamc@136
|
33
|
adamc@136
|
34 ctx->heap_front = ctx->heap = malloc(heap_len);
|
adamc@136
|
35 ctx->heap_back = ctx->heap_front + heap_len;
|
adamc@136
|
36
|
adamc@144
|
37 ctx->inputs = calloc(lw_inputs_len, sizeof(char *));
|
adamc@144
|
38
|
adamc@167
|
39 ctx->failure_kind = SUCCESS;
|
adamc@167
|
40 ctx->error_message[0] = 0;
|
adamc@167
|
41
|
adamc@117
|
42 return ctx;
|
adamc@106
|
43 }
|
adamc@106
|
44
|
adamc@117
|
45 void lw_free(lw_context ctx) {
|
adamc@117
|
46 free(ctx->page);
|
adamc@136
|
47 free(ctx->heap);
|
adamc@144
|
48 free(ctx->inputs);
|
adamc@136
|
49 free(ctx);
|
adamc@136
|
50 }
|
adamc@136
|
51
|
adamc@167
|
52 void lw_reset_keep_request(lw_context ctx) {
|
adamc@138
|
53 ctx->page_front = ctx->page;
|
adamc@138
|
54 ctx->heap_front = ctx->heap;
|
adamc@167
|
55
|
adamc@167
|
56 ctx->failure_kind = SUCCESS;
|
adamc@167
|
57 ctx->error_message[0] = 0;
|
adamc@167
|
58 }
|
adamc@167
|
59
|
adamc@167
|
60 void lw_reset_keep_error_message(lw_context ctx) {
|
adamc@167
|
61 ctx->page_front = ctx->page;
|
adamc@167
|
62 ctx->heap_front = ctx->heap;
|
adamc@167
|
63
|
adamc@167
|
64 ctx->failure_kind = SUCCESS;
|
adamc@167
|
65 }
|
adamc@167
|
66
|
adamc@167
|
67 void lw_reset(lw_context ctx) {
|
adamc@167
|
68 lw_reset_keep_request(ctx);
|
adamc@144
|
69 memset(ctx->inputs, 0, lw_inputs_len * sizeof(char *));
|
adamc@144
|
70 }
|
adamc@144
|
71
|
adamc@167
|
72 void lw_handle(lw_context, char *);
|
adamc@167
|
73
|
adamc@167
|
74 failure_kind lw_begin(lw_context ctx, char *path) {
|
adamc@167
|
75 if (!setjmp(ctx->jmp_buf))
|
adamc@167
|
76 lw_handle(ctx, path);
|
adamc@167
|
77
|
adamc@167
|
78 return ctx->failure_kind;
|
adamc@167
|
79 }
|
adamc@167
|
80
|
adamc@167
|
81 void lw_error(lw_context ctx, failure_kind fk, const char *fmt, ...) {
|
adamc@167
|
82 va_list ap;
|
adamc@167
|
83 va_start(ap, fmt);
|
adamc@167
|
84
|
adamc@167
|
85 ctx->failure_kind = fk;
|
adamc@167
|
86 vsnprintf(ctx->error_message, ERROR_BUF_LEN, fmt, ap);
|
adamc@167
|
87
|
adamc@167
|
88 longjmp(ctx->jmp_buf, 1);
|
adamc@167
|
89 }
|
adamc@167
|
90
|
adamc@167
|
91 char *lw_error_message(lw_context ctx) {
|
adamc@167
|
92 return ctx->error_message;
|
adamc@167
|
93 }
|
adamc@167
|
94
|
adamc@144
|
95 int lw_input_num(char*);
|
adamc@144
|
96
|
adamc@144
|
97 void lw_set_input(lw_context ctx, char *name, char *value) {
|
adamc@144
|
98 int n = lw_input_num(name);
|
adamc@144
|
99
|
adamc@144
|
100 if (n < 0) {
|
adamc@144
|
101 printf("Bad input name");
|
adamc@144
|
102 exit(1);
|
adamc@144
|
103 }
|
adamc@144
|
104
|
adamc@144
|
105 assert(n < lw_inputs_len);
|
adamc@144
|
106 ctx->inputs[n] = value;
|
adamc@144
|
107
|
adamc@144
|
108 printf("[%d] %s = %s\n", n, name, value);
|
adamc@144
|
109 }
|
adamc@144
|
110
|
adamc@144
|
111 char *lw_get_input(lw_context ctx, int n) {
|
adamc@144
|
112 assert(n >= 0);
|
adamc@144
|
113 assert(n < lw_inputs_len);
|
adamc@144
|
114 printf("[%d] = %s\n", n, ctx->inputs[n]);
|
adamc@144
|
115 return ctx->inputs[n];
|
adamc@138
|
116 }
|
adamc@138
|
117
|
adamc@136
|
118 static void lw_check_heap(lw_context ctx, size_t extra) {
|
adamc@136
|
119 if (ctx->heap_back - ctx->heap_front < extra) {
|
adamc@136
|
120 size_t desired = ctx->heap_back - ctx->heap_front + extra, next;
|
adamc@136
|
121 char *new_heap;
|
adamc@136
|
122
|
adamc@136
|
123 for (next = ctx->heap_back - ctx->heap_front; next < desired; next *= 2);
|
adamc@136
|
124
|
adamc@136
|
125 new_heap = realloc(ctx->heap, next);
|
adamc@136
|
126
|
adamc@136
|
127 if (new_heap != ctx->heap) {
|
adamc@136
|
128 ctx->heap = new_heap;
|
adamc@136
|
129 puts("Couldn't get contiguous chunk");
|
adamc@136
|
130 exit(1);
|
adamc@136
|
131 }
|
adamc@136
|
132
|
adamc@136
|
133 ctx->heap_back = new_heap + next;
|
adamc@136
|
134 }
|
adamc@136
|
135 }
|
adamc@136
|
136
|
adamc@136
|
137 void *lw_malloc(lw_context ctx, size_t len) {
|
adamc@136
|
138 void *result;
|
adamc@136
|
139
|
adamc@136
|
140 lw_check_heap(ctx, len);
|
adamc@136
|
141
|
adamc@136
|
142 result = ctx->heap_front;
|
adamc@136
|
143 ctx->heap_front += len;
|
adamc@136
|
144 return result;
|
adamc@117
|
145 }
|
adamc@117
|
146
|
adamc@117
|
147 int lw_really_send(int sock, const void *buf, ssize_t len) {
|
adamc@117
|
148 while (len > 0) {
|
adamc@117
|
149 ssize_t n = send(sock, buf, len, 0);
|
adamc@117
|
150
|
adamc@117
|
151 if (n < 0)
|
adamc@117
|
152 return n;
|
adamc@117
|
153
|
adamc@117
|
154 buf += n;
|
adamc@117
|
155 len -= n;
|
adamc@117
|
156 }
|
adamc@117
|
157
|
adamc@117
|
158 return 0;
|
adamc@117
|
159 }
|
adamc@117
|
160
|
adamc@117
|
161 int lw_send(lw_context ctx, int sock) {
|
adamc@117
|
162 return lw_really_send(sock, ctx->page, ctx->page_front - ctx->page);
|
adamc@117
|
163 }
|
adamc@117
|
164
|
adamc@117
|
165 static void lw_check(lw_context ctx, size_t extra) {
|
adamc@117
|
166 size_t desired = ctx->page_back - ctx->page_front + extra, next;
|
adamc@117
|
167 char *new_page;
|
adamc@117
|
168
|
adamc@117
|
169 for (next = ctx->page_back - ctx->page_front; next < desired; next *= 2);
|
adamc@117
|
170
|
adamc@117
|
171 new_page = realloc(ctx->page, next);
|
adamc@117
|
172 ctx->page_front = new_page + (ctx->page_front - ctx->page);
|
adamc@117
|
173 ctx->page_back = new_page + (ctx->page_back - ctx->page);
|
adamc@117
|
174 ctx->page = new_page;
|
adamc@117
|
175 }
|
adamc@117
|
176
|
adamc@117
|
177 static void lw_writec_unsafe(lw_context ctx, char c) {
|
adamc@117
|
178 *(ctx->page_front)++ = c;
|
adamc@117
|
179 }
|
adamc@117
|
180
|
adamc@117
|
181 void lw_writec(lw_context ctx, char c) {
|
adamc@117
|
182 lw_check(ctx, 1);
|
adamc@117
|
183 lw_writec_unsafe(ctx, c);
|
adamc@117
|
184 }
|
adamc@117
|
185
|
adamc@117
|
186 static void lw_write_unsafe(lw_context ctx, const char* s) {
|
adamc@117
|
187 int len = strlen(s);
|
adamc@117
|
188 memcpy(ctx->page_front, s, len);
|
adamc@117
|
189 ctx->page_front += len;
|
adamc@117
|
190 }
|
adamc@117
|
191
|
adamc@117
|
192 void lw_write(lw_context ctx, const char* s) {
|
adamc@117
|
193 lw_check(ctx, strlen(s));
|
adamc@117
|
194 lw_write_unsafe(ctx, s);
|
adamc@102
|
195 }
|
adamc@106
|
196
|
adamc@135
|
197
|
adamc@136
|
198 #define INTS_MAX 50
|
adamc@136
|
199 #define FLOATS_MAX 100
|
adamc@136
|
200
|
adamc@136
|
201 char *lw_Basis_attrifyInt(lw_context ctx, lw_Basis_int n) {
|
adamc@136
|
202 char *result;
|
adamc@136
|
203 int len;
|
adamc@136
|
204 lw_check_heap(ctx, INTS_MAX);
|
adamc@136
|
205 result = ctx->heap_front;
|
adamc@136
|
206 sprintf(result, "%d%n", n, &len);
|
adamc@137
|
207 ctx->heap_front += len+1;
|
adamc@136
|
208 return result;
|
adamc@106
|
209 }
|
adamc@106
|
210
|
adamc@136
|
211 char *lw_Basis_attrifyFloat(lw_context ctx, lw_Basis_float n) {
|
adamc@136
|
212 char *result;
|
adamc@136
|
213 int len;
|
adamc@137
|
214 lw_check_heap(ctx, FLOATS_MAX);
|
adamc@136
|
215 result = ctx->heap_front;
|
adamc@136
|
216 sprintf(result, "%g%n", n, &len);
|
adamc@137
|
217 ctx->heap_front += len+1;
|
adamc@136
|
218 return result;
|
adamc@106
|
219 }
|
adamc@106
|
220
|
adamc@136
|
221 char *lw_Basis_attrifyString(lw_context ctx, lw_Basis_string s) {
|
adamc@136
|
222 int len = strlen(s);
|
adamc@136
|
223 char *result, *p;
|
adamc@137
|
224 lw_check_heap(ctx, len * 6 + 1);
|
adamc@136
|
225
|
adamc@136
|
226 result = p = ctx->heap_front;
|
adamc@136
|
227
|
adamc@136
|
228 for (; *s; s++) {
|
adamc@136
|
229 char c = *s;
|
adamc@136
|
230
|
adamc@136
|
231 if (c == '"') {
|
adamc@136
|
232 strcpy(p, """);
|
adamc@136
|
233 p += 6;
|
adamc@136
|
234 } else if (c == '&') {
|
adamc@136
|
235 strcpy(p, "&");
|
adamc@136
|
236 p += 5;
|
adamc@136
|
237 }
|
adamc@136
|
238 else if (isprint(c))
|
adamc@136
|
239 *p++ = c;
|
adamc@136
|
240 else {
|
adamc@136
|
241 int len2;
|
adamc@136
|
242 sprintf(p, "&#%d;%n", c, &len2);
|
adamc@136
|
243 p += len2;
|
adamc@136
|
244 }
|
adamc@136
|
245 }
|
adamc@136
|
246
|
adamc@137
|
247 *p++ = 0;
|
adamc@136
|
248 ctx->heap_front = p;
|
adamc@136
|
249 return result;
|
adamc@106
|
250 }
|
adamc@106
|
251
|
adamc@117
|
252 static void lw_Basis_attrifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) {
|
adamc@117
|
253 int len;
|
adamc@117
|
254
|
adamc@117
|
255 sprintf(ctx->page_front, "%d%n", n, &len);
|
adamc@117
|
256 ctx->page_front += len;
|
adamc@106
|
257 }
|
adamc@106
|
258
|
adamc@117
|
259 void lw_Basis_attrifyInt_w(lw_context ctx, lw_Basis_int n) {
|
adamc@117
|
260 lw_check(ctx, INTS_MAX);
|
adamc@117
|
261 lw_Basis_attrifyInt_w_unsafe(ctx, n);
|
adamc@106
|
262 }
|
adamc@106
|
263
|
adamc@117
|
264 void lw_Basis_attrifyFloat_w(lw_context ctx, lw_Basis_float n) {
|
adamc@117
|
265 int len;
|
adamc@117
|
266
|
adamc@117
|
267 lw_check(ctx, FLOATS_MAX);
|
adamc@117
|
268 sprintf(ctx->page_front, "%g%n", n, &len);
|
adamc@117
|
269 ctx->page_front += len;
|
adamc@117
|
270 }
|
adamc@117
|
271
|
adamc@117
|
272 void lw_Basis_attrifyString_w(lw_context ctx, lw_Basis_string s) {
|
adamc@117
|
273 lw_check(ctx, strlen(s) * 6);
|
adamc@117
|
274
|
adamc@106
|
275 for (; *s; s++) {
|
adamc@106
|
276 char c = *s;
|
adamc@106
|
277
|
adamc@106
|
278 if (c == '"')
|
adamc@117
|
279 lw_write_unsafe(ctx, """);
|
adamc@136
|
280 else if (c == '&')
|
adamc@136
|
281 lw_write_unsafe(ctx, "&");
|
adamc@106
|
282 else if (isprint(c))
|
adamc@117
|
283 lw_writec_unsafe(ctx, c);
|
adamc@106
|
284 else {
|
adamc@117
|
285 lw_write_unsafe(ctx, "&#");
|
adamc@117
|
286 lw_Basis_attrifyInt_w_unsafe(ctx, c);
|
adamc@117
|
287 lw_writec_unsafe(ctx, ';');
|
adamc@106
|
288 }
|
adamc@106
|
289 }
|
adamc@106
|
290 }
|
adamc@120
|
291
|
adamc@120
|
292
|
adamc@137
|
293 char *lw_Basis_urlifyInt(lw_context ctx, lw_Basis_int n) {
|
adamc@137
|
294 int len;
|
adamc@137
|
295 char *r;
|
adamc@137
|
296
|
adamc@137
|
297 lw_check_heap(ctx, INTS_MAX);
|
adamc@137
|
298 r = ctx->heap_front;
|
adamc@137
|
299 sprintf(r, "%d%n", n, &len);
|
adamc@137
|
300 ctx->heap_front += len+1;
|
adamc@137
|
301 return r;
|
adamc@120
|
302 }
|
adamc@120
|
303
|
adamc@137
|
304 char *lw_Basis_urlifyFloat(lw_context ctx, lw_Basis_float n) {
|
adamc@137
|
305 int len;
|
adamc@137
|
306 char *r;
|
adamc@137
|
307
|
adamc@137
|
308 lw_check_heap(ctx, FLOATS_MAX);
|
adamc@137
|
309 r = ctx->heap_front;
|
adamc@137
|
310 sprintf(r, "%g%n", n, &len);
|
adamc@137
|
311 ctx->heap_front += len+1;
|
adamc@137
|
312 return r;
|
adamc@120
|
313 }
|
adamc@120
|
314
|
adamc@137
|
315 char *lw_Basis_urlifyString(lw_context ctx, lw_Basis_string s) {
|
adamc@137
|
316 char *r, *p;
|
adamc@137
|
317
|
adamc@137
|
318 lw_check_heap(ctx, strlen(s) * 3 + 1);
|
adamc@137
|
319
|
adamc@137
|
320 for (r = p = ctx->heap_front; *s; s++) {
|
adamc@137
|
321 char c = *s;
|
adamc@137
|
322
|
adamc@137
|
323 if (c == ' ')
|
adamc@137
|
324 *p++ = '+';
|
adamc@137
|
325 else if (isalnum(c))
|
adamc@137
|
326 *p++ = c;
|
adamc@137
|
327 else {
|
adamc@137
|
328 sprintf(p, "%%%02X", c);
|
adamc@137
|
329 p += 3;
|
adamc@137
|
330 }
|
adamc@137
|
331 }
|
adamc@137
|
332
|
adamc@137
|
333 *p++ = 0;
|
adamc@137
|
334 ctx->heap_front = p;
|
adamc@137
|
335 return r;
|
adamc@120
|
336 }
|
adamc@120
|
337
|
adamc@120
|
338 static void lw_Basis_urlifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) {
|
adamc@120
|
339 int len;
|
adamc@120
|
340
|
adamc@120
|
341 sprintf(ctx->page_front, "%d%n", n, &len);
|
adamc@120
|
342 ctx->page_front += len;
|
adamc@120
|
343 }
|
adamc@120
|
344
|
adamc@120
|
345 void lw_Basis_urlifyInt_w(lw_context ctx, lw_Basis_int n) {
|
adamc@120
|
346 lw_check(ctx, INTS_MAX);
|
adamc@120
|
347 lw_Basis_urlifyInt_w_unsafe(ctx, n);
|
adamc@120
|
348 }
|
adamc@120
|
349
|
adamc@120
|
350 void lw_Basis_urlifyFloat_w(lw_context ctx, lw_Basis_float n) {
|
adamc@120
|
351 int len;
|
adamc@120
|
352
|
adamc@120
|
353 lw_check(ctx, FLOATS_MAX);
|
adamc@120
|
354 sprintf(ctx->page_front, "%g%n", n, &len);
|
adamc@120
|
355 ctx->page_front += len;
|
adamc@120
|
356 }
|
adamc@120
|
357
|
adamc@120
|
358 void lw_Basis_urlifyString_w(lw_context ctx, lw_Basis_string s) {
|
adamc@120
|
359 lw_check(ctx, strlen(s) * 3);
|
adamc@120
|
360
|
adamc@120
|
361 for (; *s; s++) {
|
adamc@120
|
362 char c = *s;
|
adamc@120
|
363
|
adamc@120
|
364 if (c == ' ')
|
adamc@120
|
365 lw_writec_unsafe(ctx, '+');
|
adamc@120
|
366 else if (isalnum(c))
|
adamc@120
|
367 lw_writec_unsafe(ctx, c);
|
adamc@120
|
368 else {
|
adamc@120
|
369 sprintf(ctx->page_front, "%%%02X", c);
|
adamc@120
|
370 ctx->page_front += 3;
|
adamc@120
|
371 }
|
adamc@120
|
372 }
|
adamc@120
|
373 }
|
adamc@120
|
374
|
adamc@120
|
375
|
adamc@144
|
376 static char *lw_unurlify_advance(char *s) {
|
adamc@144
|
377 char *new_s = strchr(s, '/');
|
adamc@120
|
378
|
adamc@120
|
379 if (new_s)
|
adamc@120
|
380 *new_s++ = 0;
|
adamc@120
|
381 else
|
adamc@144
|
382 new_s = strchr(s, 0);
|
adamc@144
|
383
|
adamc@144
|
384 return new_s;
|
adamc@144
|
385 }
|
adamc@144
|
386
|
adamc@144
|
387 lw_Basis_int lw_unurlifyInt(char **s) {
|
adamc@144
|
388 char *new_s = lw_unurlify_advance(*s);
|
adamc@144
|
389 int r;
|
adamc@120
|
390
|
adamc@120
|
391 r = atoi(*s);
|
adamc@120
|
392 *s = new_s;
|
adamc@120
|
393 return r;
|
adamc@120
|
394 }
|
adamc@120
|
395
|
adamc@120
|
396 lw_Basis_float lw_unurlifyFloat(char **s) {
|
adamc@144
|
397 char *new_s = lw_unurlify_advance(*s);
|
adamc@120
|
398 int r;
|
adamc@120
|
399
|
adamc@120
|
400 r = atof(*s);
|
adamc@120
|
401 *s = new_s;
|
adamc@120
|
402 return r;
|
adamc@120
|
403 }
|
adamc@120
|
404
|
adamc@144
|
405 static lw_Basis_string lw_unurlifyString_to(char *r, char *s) {
|
adamc@144
|
406 char *s1, *s2;
|
adamc@144
|
407 int n;
|
adamc@136
|
408
|
adamc@144
|
409 for (s1 = r, s2 = s; *s2; ++s1, ++s2) {
|
adamc@136
|
410 char c = *s2;
|
adamc@136
|
411
|
adamc@136
|
412 switch (c) {
|
adamc@136
|
413 case '+':
|
adamc@136
|
414 *s1 = ' ';
|
adamc@136
|
415 break;
|
adamc@136
|
416 case '%':
|
adamc@144
|
417 assert(s2[1] != 0 && s2[2] != 0);
|
adamc@136
|
418 sscanf(s2+1, "%02X", &n);
|
adamc@136
|
419 *s1 = n;
|
adamc@136
|
420 s2 += 2;
|
adamc@136
|
421 break;
|
adamc@136
|
422 default:
|
adamc@136
|
423 *s1 = c;
|
adamc@136
|
424 }
|
adamc@136
|
425 }
|
adamc@136
|
426 *s1++ = 0;
|
adamc@144
|
427 return s1;
|
adamc@144
|
428 }
|
adamc@144
|
429
|
adamc@144
|
430 lw_Basis_string lw_unurlifyString(lw_context ctx, char **s) {
|
adamc@144
|
431 char *new_s = lw_unurlify_advance(*s);
|
adamc@144
|
432 char *r, *s1, *s2;
|
adamc@144
|
433 int len, n;
|
adamc@144
|
434
|
adamc@144
|
435 len = strlen(*s);
|
adamc@144
|
436 lw_check_heap(ctx, len + 1);
|
adamc@144
|
437
|
adamc@144
|
438 r = ctx->heap_front;
|
adamc@144
|
439 ctx->heap_front = lw_unurlifyString_to(ctx->heap_front, *s);
|
adamc@136
|
440 *s = new_s;
|
adamc@136
|
441 return r;
|
adamc@120
|
442 }
|
adamc@135
|
443
|
adamc@135
|
444
|
adamc@136
|
445 char *lw_Basis_htmlifyString(lw_context ctx, lw_Basis_string s) {
|
adamc@137
|
446 char *r, *s2;
|
adamc@137
|
447
|
adamc@137
|
448 lw_check_heap(ctx, strlen(s) * 5 + 1);
|
adamc@137
|
449
|
adamc@137
|
450 for (r = s2 = ctx->heap_front; *s; s++) {
|
adamc@137
|
451 char c = *s;
|
adamc@137
|
452
|
adamc@137
|
453 switch (c) {
|
adamc@137
|
454 case '<':
|
adamc@137
|
455 strcpy(s2, "<");
|
adamc@137
|
456 s2 += 4;
|
adamc@137
|
457 break;
|
adamc@137
|
458 case '&':
|
adamc@137
|
459 strcpy(s2, "&");
|
adamc@137
|
460 s2 += 5;
|
adamc@137
|
461 break;
|
adamc@137
|
462 default:
|
adamc@137
|
463 if (isprint(c))
|
adamc@137
|
464 *s2++ = c;
|
adamc@137
|
465 else {
|
adamc@137
|
466 int len2;
|
adamc@137
|
467 sprintf(s2, "&#%d;%n", c, &len2);
|
adamc@137
|
468 s2 += len2;
|
adamc@137
|
469 }
|
adamc@137
|
470 }
|
adamc@137
|
471 }
|
adamc@137
|
472
|
adamc@137
|
473 *s2++ = 0;
|
adamc@137
|
474 ctx->heap_front = s2;
|
adamc@137
|
475 return r;
|
adamc@135
|
476 }
|
adamc@135
|
477
|
adamc@135
|
478 void lw_Basis_htmlifyString_w(lw_context ctx, lw_Basis_string s) {
|
adamc@135
|
479 lw_check(ctx, strlen(s) * 5);
|
adamc@135
|
480
|
adamc@135
|
481 for (; *s; s++) {
|
adamc@135
|
482 char c = *s;
|
adamc@135
|
483
|
adamc@135
|
484 switch (c) {
|
adamc@135
|
485 case '<':
|
adamc@135
|
486 lw_write_unsafe(ctx, "<");
|
adamc@135
|
487 break;
|
adamc@135
|
488 case '&':
|
adamc@135
|
489 lw_write_unsafe(ctx, "&");
|
adamc@135
|
490 break;
|
adamc@135
|
491 default:
|
adamc@135
|
492 if (isprint(c))
|
adamc@135
|
493 lw_writec_unsafe(ctx, c);
|
adamc@135
|
494 else {
|
adamc@135
|
495 lw_write_unsafe(ctx, "&#");
|
adamc@135
|
496 lw_Basis_attrifyInt_w_unsafe(ctx, c);
|
adamc@135
|
497 lw_writec_unsafe(ctx, ';');
|
adamc@135
|
498 }
|
adamc@135
|
499 }
|
adamc@135
|
500 }
|
adamc@135
|
501 }
|