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