annotate src/c/lacweb.c @ 137:4ffdbf429e8d

Replaced allocation stubs
author Adam Chlipala <adamc@hcoop.net>
date Thu, 17 Jul 2008 14:32:49 -0400
parents 133fa2d51bb4
children d6d78055f001
rev   line source
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@102 6
adamc@102 7 #include "types.h"
adamc@102 8
adamc@102 9 lw_unit lw_unit_v = {};
adamc@102 10
adamc@117 11 struct lw_context {
adamc@117 12 char *page, *page_front, *page_back;
adamc@136 13 char *heap, *heap_front, *heap_back;
adamc@117 14 };
adamc@117 15
adamc@136 16 lw_context lw_init(size_t page_len, size_t heap_len) {
adamc@117 17 lw_context ctx = malloc(sizeof(struct lw_context));
adamc@136 18
adamc@117 19 ctx->page_front = ctx->page = malloc(page_len);
adamc@117 20 ctx->page_back = ctx->page_front + page_len;
adamc@136 21
adamc@136 22 ctx->heap_front = ctx->heap = malloc(heap_len);
adamc@136 23 ctx->heap_back = ctx->heap_front + heap_len;
adamc@136 24
adamc@117 25 return ctx;
adamc@106 26 }
adamc@106 27
adamc@117 28 void lw_free(lw_context ctx) {
adamc@117 29 free(ctx->page);
adamc@136 30 free(ctx->heap);
adamc@136 31 free(ctx);
adamc@136 32 }
adamc@136 33
adamc@136 34 static void lw_check_heap(lw_context ctx, size_t extra) {
adamc@136 35 if (ctx->heap_back - ctx->heap_front < extra) {
adamc@136 36 size_t desired = ctx->heap_back - ctx->heap_front + extra, next;
adamc@136 37 char *new_heap;
adamc@136 38
adamc@136 39 for (next = ctx->heap_back - ctx->heap_front; next < desired; next *= 2);
adamc@136 40
adamc@136 41 new_heap = realloc(ctx->heap, next);
adamc@136 42
adamc@136 43 if (new_heap != ctx->heap) {
adamc@136 44 ctx->heap = new_heap;
adamc@136 45 puts("Couldn't get contiguous chunk");
adamc@136 46 exit(1);
adamc@136 47 }
adamc@136 48
adamc@136 49 ctx->heap_back = new_heap + next;
adamc@136 50 }
adamc@136 51 }
adamc@136 52
adamc@136 53 void *lw_malloc(lw_context ctx, size_t len) {
adamc@136 54 void *result;
adamc@136 55
adamc@136 56 lw_check_heap(ctx, len);
adamc@136 57
adamc@136 58 result = ctx->heap_front;
adamc@136 59 ctx->heap_front += len;
adamc@136 60 return result;
adamc@117 61 }
adamc@117 62
adamc@117 63 int lw_really_send(int sock, const void *buf, ssize_t len) {
adamc@117 64 while (len > 0) {
adamc@117 65 ssize_t n = send(sock, buf, len, 0);
adamc@117 66
adamc@117 67 if (n < 0)
adamc@117 68 return n;
adamc@117 69
adamc@117 70 buf += n;
adamc@117 71 len -= n;
adamc@117 72 }
adamc@117 73
adamc@117 74 return 0;
adamc@117 75 }
adamc@117 76
adamc@117 77 int lw_send(lw_context ctx, int sock) {
adamc@117 78 return lw_really_send(sock, ctx->page, ctx->page_front - ctx->page);
adamc@117 79 }
adamc@117 80
adamc@117 81 static void lw_check(lw_context ctx, size_t extra) {
adamc@117 82 size_t desired = ctx->page_back - ctx->page_front + extra, next;
adamc@117 83 char *new_page;
adamc@117 84
adamc@117 85 for (next = ctx->page_back - ctx->page_front; next < desired; next *= 2);
adamc@117 86
adamc@117 87 new_page = realloc(ctx->page, next);
adamc@117 88 ctx->page_front = new_page + (ctx->page_front - ctx->page);
adamc@117 89 ctx->page_back = new_page + (ctx->page_back - ctx->page);
adamc@117 90 ctx->page = new_page;
adamc@117 91 }
adamc@117 92
adamc@117 93 static void lw_writec_unsafe(lw_context ctx, char c) {
adamc@117 94 *(ctx->page_front)++ = c;
adamc@117 95 }
adamc@117 96
adamc@117 97 void lw_writec(lw_context ctx, char c) {
adamc@117 98 lw_check(ctx, 1);
adamc@117 99 lw_writec_unsafe(ctx, c);
adamc@117 100 }
adamc@117 101
adamc@117 102 static void lw_write_unsafe(lw_context ctx, const char* s) {
adamc@117 103 int len = strlen(s);
adamc@117 104 memcpy(ctx->page_front, s, len);
adamc@117 105 ctx->page_front += len;
adamc@117 106 }
adamc@117 107
adamc@117 108 void lw_write(lw_context ctx, const char* s) {
adamc@117 109 lw_check(ctx, strlen(s));
adamc@117 110 lw_write_unsafe(ctx, s);
adamc@102 111 }
adamc@106 112
adamc@135 113
adamc@136 114 #define INTS_MAX 50
adamc@136 115 #define FLOATS_MAX 100
adamc@136 116
adamc@136 117 char *lw_Basis_attrifyInt(lw_context ctx, lw_Basis_int n) {
adamc@136 118 char *result;
adamc@136 119 int len;
adamc@136 120 lw_check_heap(ctx, INTS_MAX);
adamc@136 121 result = ctx->heap_front;
adamc@136 122 sprintf(result, "%d%n", n, &len);
adamc@137 123 ctx->heap_front += len+1;
adamc@136 124 return result;
adamc@106 125 }
adamc@106 126
adamc@136 127 char *lw_Basis_attrifyFloat(lw_context ctx, lw_Basis_float n) {
adamc@136 128 char *result;
adamc@136 129 int len;
adamc@137 130 lw_check_heap(ctx, FLOATS_MAX);
adamc@136 131 result = ctx->heap_front;
adamc@136 132 sprintf(result, "%g%n", n, &len);
adamc@137 133 ctx->heap_front += len+1;
adamc@136 134 return result;
adamc@106 135 }
adamc@106 136
adamc@136 137 char *lw_Basis_attrifyString(lw_context ctx, lw_Basis_string s) {
adamc@136 138 int len = strlen(s);
adamc@136 139 char *result, *p;
adamc@137 140 lw_check_heap(ctx, len * 6 + 1);
adamc@136 141
adamc@136 142 result = p = ctx->heap_front;
adamc@136 143
adamc@136 144 for (; *s; s++) {
adamc@136 145 char c = *s;
adamc@136 146
adamc@136 147 if (c == '"') {
adamc@136 148 strcpy(p, "&quot;");
adamc@136 149 p += 6;
adamc@136 150 } else if (c == '&') {
adamc@136 151 strcpy(p, "&amp;");
adamc@136 152 p += 5;
adamc@136 153 }
adamc@136 154 else if (isprint(c))
adamc@136 155 *p++ = c;
adamc@136 156 else {
adamc@136 157 int len2;
adamc@136 158 sprintf(p, "&#%d;%n", c, &len2);
adamc@136 159 p += len2;
adamc@136 160 }
adamc@136 161 }
adamc@136 162
adamc@137 163 *p++ = 0;
adamc@136 164 ctx->heap_front = p;
adamc@136 165 return result;
adamc@106 166 }
adamc@106 167
adamc@117 168 static void lw_Basis_attrifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) {
adamc@117 169 int len;
adamc@117 170
adamc@117 171 sprintf(ctx->page_front, "%d%n", n, &len);
adamc@117 172 ctx->page_front += len;
adamc@106 173 }
adamc@106 174
adamc@117 175 void lw_Basis_attrifyInt_w(lw_context ctx, lw_Basis_int n) {
adamc@117 176 lw_check(ctx, INTS_MAX);
adamc@117 177 lw_Basis_attrifyInt_w_unsafe(ctx, n);
adamc@106 178 }
adamc@106 179
adamc@117 180 void lw_Basis_attrifyFloat_w(lw_context ctx, lw_Basis_float n) {
adamc@117 181 int len;
adamc@117 182
adamc@117 183 lw_check(ctx, FLOATS_MAX);
adamc@117 184 sprintf(ctx->page_front, "%g%n", n, &len);
adamc@117 185 ctx->page_front += len;
adamc@117 186 }
adamc@117 187
adamc@117 188 void lw_Basis_attrifyString_w(lw_context ctx, lw_Basis_string s) {
adamc@117 189 lw_check(ctx, strlen(s) * 6);
adamc@117 190
adamc@106 191 for (; *s; s++) {
adamc@106 192 char c = *s;
adamc@106 193
adamc@106 194 if (c == '"')
adamc@117 195 lw_write_unsafe(ctx, "&quot;");
adamc@136 196 else if (c == '&')
adamc@136 197 lw_write_unsafe(ctx, "&amp;");
adamc@106 198 else if (isprint(c))
adamc@117 199 lw_writec_unsafe(ctx, c);
adamc@106 200 else {
adamc@117 201 lw_write_unsafe(ctx, "&#");
adamc@117 202 lw_Basis_attrifyInt_w_unsafe(ctx, c);
adamc@117 203 lw_writec_unsafe(ctx, ';');
adamc@106 204 }
adamc@106 205 }
adamc@106 206 }
adamc@120 207
adamc@120 208
adamc@137 209 char *lw_Basis_urlifyInt(lw_context ctx, lw_Basis_int n) {
adamc@137 210 int len;
adamc@137 211 char *r;
adamc@137 212
adamc@137 213 lw_check_heap(ctx, INTS_MAX);
adamc@137 214 r = ctx->heap_front;
adamc@137 215 sprintf(r, "%d%n", n, &len);
adamc@137 216 ctx->heap_front += len+1;
adamc@137 217 return r;
adamc@120 218 }
adamc@120 219
adamc@137 220 char *lw_Basis_urlifyFloat(lw_context ctx, lw_Basis_float n) {
adamc@137 221 int len;
adamc@137 222 char *r;
adamc@137 223
adamc@137 224 lw_check_heap(ctx, FLOATS_MAX);
adamc@137 225 r = ctx->heap_front;
adamc@137 226 sprintf(r, "%g%n", n, &len);
adamc@137 227 ctx->heap_front += len+1;
adamc@137 228 return r;
adamc@120 229 }
adamc@120 230
adamc@137 231 char *lw_Basis_urlifyString(lw_context ctx, lw_Basis_string s) {
adamc@137 232 char *r, *p;
adamc@137 233
adamc@137 234 lw_check_heap(ctx, strlen(s) * 3 + 1);
adamc@137 235
adamc@137 236 for (r = p = ctx->heap_front; *s; s++) {
adamc@137 237 char c = *s;
adamc@137 238
adamc@137 239 if (c == ' ')
adamc@137 240 *p++ = '+';
adamc@137 241 else if (isalnum(c))
adamc@137 242 *p++ = c;
adamc@137 243 else {
adamc@137 244 sprintf(p, "%%%02X", c);
adamc@137 245 p += 3;
adamc@137 246 }
adamc@137 247 }
adamc@137 248
adamc@137 249 *p++ = 0;
adamc@137 250 ctx->heap_front = p;
adamc@137 251 return r;
adamc@120 252 }
adamc@120 253
adamc@120 254 static void lw_Basis_urlifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) {
adamc@120 255 int len;
adamc@120 256
adamc@120 257 sprintf(ctx->page_front, "%d%n", n, &len);
adamc@120 258 ctx->page_front += len;
adamc@120 259 }
adamc@120 260
adamc@120 261 void lw_Basis_urlifyInt_w(lw_context ctx, lw_Basis_int n) {
adamc@120 262 lw_check(ctx, INTS_MAX);
adamc@120 263 lw_Basis_urlifyInt_w_unsafe(ctx, n);
adamc@120 264 }
adamc@120 265
adamc@120 266 void lw_Basis_urlifyFloat_w(lw_context ctx, lw_Basis_float n) {
adamc@120 267 int len;
adamc@120 268
adamc@120 269 lw_check(ctx, FLOATS_MAX);
adamc@120 270 sprintf(ctx->page_front, "%g%n", n, &len);
adamc@120 271 ctx->page_front += len;
adamc@120 272 }
adamc@120 273
adamc@120 274 void lw_Basis_urlifyString_w(lw_context ctx, lw_Basis_string s) {
adamc@120 275 lw_check(ctx, strlen(s) * 3);
adamc@120 276
adamc@120 277 for (; *s; s++) {
adamc@120 278 char c = *s;
adamc@120 279
adamc@120 280 if (c == ' ')
adamc@120 281 lw_writec_unsafe(ctx, '+');
adamc@120 282 else if (isalnum(c))
adamc@120 283 lw_writec_unsafe(ctx, c);
adamc@120 284 else {
adamc@120 285 sprintf(ctx->page_front, "%%%02X", c);
adamc@120 286 ctx->page_front += 3;
adamc@120 287 }
adamc@120 288 }
adamc@120 289 }
adamc@120 290
adamc@120 291
adamc@120 292 lw_Basis_int lw_unurlifyInt(char **s) {
adamc@120 293 char *new_s = strchr(*s, '/');
adamc@120 294 int r;
adamc@120 295
adamc@120 296 if (new_s)
adamc@120 297 *new_s++ = 0;
adamc@120 298 else
adamc@120 299 new_s = strchr(*s, 0);
adamc@120 300
adamc@120 301 r = atoi(*s);
adamc@120 302 *s = new_s;
adamc@120 303 return r;
adamc@120 304 }
adamc@120 305
adamc@120 306 lw_Basis_float lw_unurlifyFloat(char **s) {
adamc@120 307 char *new_s = strchr(*s, '/');
adamc@120 308 int r;
adamc@120 309
adamc@120 310 if (new_s)
adamc@120 311 *new_s++ = 0;
adamc@120 312 else
adamc@120 313 new_s = strchr(*s, 0);
adamc@120 314
adamc@120 315 r = atof(*s);
adamc@120 316 *s = new_s;
adamc@120 317 return r;
adamc@120 318 }
adamc@120 319
adamc@136 320 lw_Basis_string lw_unurlifyString(lw_context ctx, char **s) {
adamc@136 321 char *new_s = strchr(*s, '/');
adamc@136 322 char *r, *s1, *s2;
adamc@136 323 int len, n;
adamc@136 324
adamc@136 325 if (new_s)
adamc@136 326 *new_s++ = 0;
adamc@136 327 else
adamc@136 328 new_s = strchr(*s, 0);
adamc@136 329
adamc@136 330 len = strlen(*s);
adamc@136 331 lw_check_heap(ctx, len + 1);
adamc@136 332
adamc@136 333 r = ctx->heap_front;
adamc@136 334 for (s1 = r, s2 = *s; *s2; ++s1, ++s2) {
adamc@136 335 char c = *s2;
adamc@136 336
adamc@136 337 switch (c) {
adamc@136 338 case '+':
adamc@136 339 *s1 = ' ';
adamc@136 340 break;
adamc@136 341 case '%':
adamc@136 342 assert(s2 + 2 < new_s);
adamc@136 343 sscanf(s2+1, "%02X", &n);
adamc@136 344 *s1 = n;
adamc@136 345 s2 += 2;
adamc@136 346 break;
adamc@136 347 default:
adamc@136 348 *s1 = c;
adamc@136 349 }
adamc@136 350 }
adamc@136 351 *s1++ = 0;
adamc@136 352 ctx->heap_front = s1;
adamc@136 353 *s = new_s;
adamc@136 354 return r;
adamc@120 355 }
adamc@135 356
adamc@135 357
adamc@136 358 char *lw_Basis_htmlifyString(lw_context ctx, lw_Basis_string s) {
adamc@137 359 char *r, *s2;
adamc@137 360
adamc@137 361 lw_check_heap(ctx, strlen(s) * 5 + 1);
adamc@137 362
adamc@137 363 for (r = s2 = ctx->heap_front; *s; s++) {
adamc@137 364 char c = *s;
adamc@137 365
adamc@137 366 switch (c) {
adamc@137 367 case '<':
adamc@137 368 strcpy(s2, "&lt;");
adamc@137 369 s2 += 4;
adamc@137 370 break;
adamc@137 371 case '&':
adamc@137 372 strcpy(s2, "&amp;");
adamc@137 373 s2 += 5;
adamc@137 374 break;
adamc@137 375 default:
adamc@137 376 if (isprint(c))
adamc@137 377 *s2++ = c;
adamc@137 378 else {
adamc@137 379 int len2;
adamc@137 380 sprintf(s2, "&#%d;%n", c, &len2);
adamc@137 381 s2 += len2;
adamc@137 382 }
adamc@137 383 }
adamc@137 384 }
adamc@137 385
adamc@137 386 *s2++ = 0;
adamc@137 387 ctx->heap_front = s2;
adamc@137 388 return r;
adamc@135 389 }
adamc@135 390
adamc@135 391 void lw_Basis_htmlifyString_w(lw_context ctx, lw_Basis_string s) {
adamc@135 392 lw_check(ctx, strlen(s) * 5);
adamc@135 393
adamc@135 394 for (; *s; s++) {
adamc@135 395 char c = *s;
adamc@135 396
adamc@135 397 switch (c) {
adamc@135 398 case '<':
adamc@135 399 lw_write_unsafe(ctx, "&lt;");
adamc@135 400 break;
adamc@135 401 case '&':
adamc@135 402 lw_write_unsafe(ctx, "&amp;");
adamc@135 403 break;
adamc@135 404 default:
adamc@135 405 if (isprint(c))
adamc@135 406 lw_writec_unsafe(ctx, c);
adamc@135 407 else {
adamc@135 408 lw_write_unsafe(ctx, "&#");
adamc@135 409 lw_Basis_attrifyInt_w_unsafe(ctx, c);
adamc@135 410 lw_writec_unsafe(ctx, ';');
adamc@135 411 }
adamc@135 412 }
adamc@135 413 }
adamc@135 414 }