Mercurial > urweb
comparison src/c/lacweb.c @ 136:133fa2d51bb4
Dynamic arena allocation
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Thu, 17 Jul 2008 14:18:57 -0400 |
parents | b1cfe49ce692 |
children | 4ffdbf429e8d |
comparison
equal
deleted
inserted
replaced
135:b1cfe49ce692 | 136:133fa2d51bb4 |
---|---|
1 #include <stdlib.h> | 1 #include <stdlib.h> |
2 #include <stdio.h> | 2 #include <stdio.h> |
3 #include <string.h> | 3 #include <string.h> |
4 #include <ctype.h> | 4 #include <ctype.h> |
5 #include <assert.h> | |
5 | 6 |
6 #include "types.h" | 7 #include "types.h" |
7 | 8 |
8 lw_unit lw_unit_v = {}; | 9 lw_unit lw_unit_v = {}; |
9 | 10 |
10 struct lw_context { | 11 struct lw_context { |
11 char *page, *page_front, *page_back; | 12 char *page, *page_front, *page_back; |
13 char *heap, *heap_front, *heap_back; | |
12 }; | 14 }; |
13 | 15 |
14 lw_context lw_init(int page_len) { | 16 lw_context lw_init(size_t page_len, size_t heap_len) { |
15 lw_context ctx = malloc(sizeof(struct lw_context)); | 17 lw_context ctx = malloc(sizeof(struct lw_context)); |
18 | |
16 ctx->page_front = ctx->page = malloc(page_len); | 19 ctx->page_front = ctx->page = malloc(page_len); |
17 ctx->page_back = ctx->page_front + page_len; | 20 ctx->page_back = ctx->page_front + page_len; |
21 | |
22 ctx->heap_front = ctx->heap = malloc(heap_len); | |
23 ctx->heap_back = ctx->heap_front + heap_len; | |
24 | |
18 return ctx; | 25 return ctx; |
19 } | 26 } |
20 | 27 |
21 void lw_free(lw_context ctx) { | 28 void lw_free(lw_context ctx) { |
22 free(ctx->page); | 29 free(ctx->page); |
30 free(ctx->heap); | |
31 free(ctx); | |
32 } | |
33 | |
34 static void lw_check_heap(lw_context ctx, size_t extra) { | |
35 if (ctx->heap_back - ctx->heap_front < extra) { | |
36 size_t desired = ctx->heap_back - ctx->heap_front + extra, next; | |
37 char *new_heap; | |
38 | |
39 for (next = ctx->heap_back - ctx->heap_front; next < desired; next *= 2); | |
40 | |
41 new_heap = realloc(ctx->heap, next); | |
42 | |
43 if (new_heap != ctx->heap) { | |
44 ctx->heap = new_heap; | |
45 puts("Couldn't get contiguous chunk"); | |
46 exit(1); | |
47 } | |
48 | |
49 ctx->heap_back = new_heap + next; | |
50 } | |
51 } | |
52 | |
53 void *lw_malloc(lw_context ctx, size_t len) { | |
54 void *result; | |
55 | |
56 lw_check_heap(ctx, len); | |
57 | |
58 result = ctx->heap_front; | |
59 ctx->heap_front += len; | |
60 return result; | |
23 } | 61 } |
24 | 62 |
25 int lw_really_send(int sock, const void *buf, ssize_t len) { | 63 int lw_really_send(int sock, const void *buf, ssize_t len) { |
26 while (len > 0) { | 64 while (len > 0) { |
27 ssize_t n = send(sock, buf, len, 0); | 65 ssize_t n = send(sock, buf, len, 0); |
71 lw_check(ctx, strlen(s)); | 109 lw_check(ctx, strlen(s)); |
72 lw_write_unsafe(ctx, s); | 110 lw_write_unsafe(ctx, s); |
73 } | 111 } |
74 | 112 |
75 | 113 |
76 char *lw_Basis_attrifyInt(lw_Basis_int n) { | |
77 return "0"; | |
78 } | |
79 | |
80 char *lw_Basis_attrifyFloat(lw_Basis_float n) { | |
81 return "0.0"; | |
82 } | |
83 | |
84 char *lw_Basis_attrifyString(lw_Basis_string s) { | |
85 return ""; | |
86 } | |
87 | |
88 #define INTS_MAX 50 | 114 #define INTS_MAX 50 |
89 #define FLOATS_MAX 100 | 115 #define FLOATS_MAX 100 |
116 | |
117 char *lw_Basis_attrifyInt(lw_context ctx, lw_Basis_int n) { | |
118 char *result; | |
119 int len; | |
120 lw_check_heap(ctx, INTS_MAX); | |
121 result = ctx->heap_front; | |
122 sprintf(result, "%d%n", n, &len); | |
123 ctx->heap_front += len; | |
124 return result; | |
125 } | |
126 | |
127 char *lw_Basis_attrifyFloat(lw_context ctx, lw_Basis_float n) { | |
128 char *result; | |
129 int len; | |
130 lw_check_heap(ctx, INTS_MAX); | |
131 result = ctx->heap_front; | |
132 sprintf(result, "%g%n", n, &len); | |
133 ctx->heap_front += len; | |
134 return result; | |
135 } | |
136 | |
137 char *lw_Basis_attrifyString(lw_context ctx, lw_Basis_string s) { | |
138 int len = strlen(s); | |
139 char *result, *p; | |
140 lw_check_heap(ctx, len * 6); | |
141 | |
142 result = p = ctx->heap_front; | |
143 | |
144 for (; *s; s++) { | |
145 char c = *s; | |
146 | |
147 if (c == '"') { | |
148 strcpy(p, """); | |
149 p += 6; | |
150 } else if (c == '&') { | |
151 strcpy(p, "&"); | |
152 p += 5; | |
153 } | |
154 else if (isprint(c)) | |
155 *p++ = c; | |
156 else { | |
157 int len2; | |
158 sprintf(p, "&#%d;%n", c, &len2); | |
159 p += len2; | |
160 } | |
161 } | |
162 | |
163 ctx->heap_front = p; | |
164 return result; | |
165 } | |
90 | 166 |
91 static void lw_Basis_attrifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) { | 167 static void lw_Basis_attrifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) { |
92 int len; | 168 int len; |
93 | 169 |
94 sprintf(ctx->page_front, "%d%n", n, &len); | 170 sprintf(ctx->page_front, "%d%n", n, &len); |
114 for (; *s; s++) { | 190 for (; *s; s++) { |
115 char c = *s; | 191 char c = *s; |
116 | 192 |
117 if (c == '"') | 193 if (c == '"') |
118 lw_write_unsafe(ctx, """); | 194 lw_write_unsafe(ctx, """); |
195 else if (c == '&') | |
196 lw_write_unsafe(ctx, "&"); | |
119 else if (isprint(c)) | 197 else if (isprint(c)) |
120 lw_writec_unsafe(ctx, c); | 198 lw_writec_unsafe(ctx, c); |
121 else { | 199 else { |
122 lw_write_unsafe(ctx, "&#"); | 200 lw_write_unsafe(ctx, "&#"); |
123 lw_Basis_attrifyInt_w_unsafe(ctx, c); | 201 lw_Basis_attrifyInt_w_unsafe(ctx, c); |
203 r = atof(*s); | 281 r = atof(*s); |
204 *s = new_s; | 282 *s = new_s; |
205 return r; | 283 return r; |
206 } | 284 } |
207 | 285 |
208 lw_Basis_string lw_unurlifyString(char **s) { | 286 lw_Basis_string lw_unurlifyString(lw_context ctx, char **s) { |
209 return ""; | 287 char *new_s = strchr(*s, '/'); |
210 } | 288 char *r, *s1, *s2; |
211 | 289 int len, n; |
212 | 290 |
213 char *lw_Basis_htmlifyString(lw_Basis_string s) { | 291 if (new_s) |
292 *new_s++ = 0; | |
293 else | |
294 new_s = strchr(*s, 0); | |
295 | |
296 len = strlen(*s); | |
297 lw_check_heap(ctx, len + 1); | |
298 | |
299 r = ctx->heap_front; | |
300 for (s1 = r, s2 = *s; *s2; ++s1, ++s2) { | |
301 char c = *s2; | |
302 | |
303 switch (c) { | |
304 case '+': | |
305 *s1 = ' '; | |
306 break; | |
307 case '%': | |
308 assert(s2 + 2 < new_s); | |
309 sscanf(s2+1, "%02X", &n); | |
310 *s1 = n; | |
311 s2 += 2; | |
312 break; | |
313 default: | |
314 *s1 = c; | |
315 } | |
316 } | |
317 *s1++ = 0; | |
318 ctx->heap_front = s1; | |
319 *s = new_s; | |
320 return r; | |
321 } | |
322 | |
323 | |
324 char *lw_Basis_htmlifyString(lw_context ctx, lw_Basis_string s) { | |
214 return ""; | 325 return ""; |
215 } | 326 } |
216 | 327 |
217 void lw_Basis_htmlifyString_w(lw_context ctx, lw_Basis_string s) { | 328 void lw_Basis_htmlifyString_w(lw_context ctx, lw_Basis_string s) { |
218 lw_check(ctx, strlen(s) * 5); | 329 lw_check(ctx, strlen(s) * 5); |