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, "&quot;");
149 p += 6;
150 } else if (c == '&') {
151 strcpy(p, "&amp;");
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, "&quot;"); 194 lw_write_unsafe(ctx, "&quot;");
195 else if (c == '&')
196 lw_write_unsafe(ctx, "&amp;");
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);