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