annotate src/c/urweb.c @ 323:5030e909fbf3

Region memory allocation for query parameters
author Adam Chlipala <adamc@hcoop.net>
date Thu, 11 Sep 2008 12:40:40 -0400
parents cd4cabaf3e52
children b91480c9a729
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@167 5 #include <setjmp.h>
adamc@167 6 #include <stdarg.h>
adamc@102 7
adamc@102 8 #include "types.h"
adamc@102 9
adamc@311 10 uw_unit uw_unit_v = {};
adamc@102 11
adamc@167 12 #define ERROR_BUF_LEN 1024
adamc@167 13
adamc@323 14 typedef struct regions {
adamc@323 15 struct regions *next;
adamc@323 16 } regions;
adamc@323 17
adamc@311 18 struct uw_context {
adamc@117 19 char *page, *page_front, *page_back;
adamc@136 20 char *heap, *heap_front, *heap_back;
adamc@144 21 char **inputs;
adamc@167 22
adamc@272 23 void *db;
adamc@272 24
adamc@167 25 jmp_buf jmp_buf;
adamc@167 26
adamc@323 27 regions *regions;
adamc@323 28
adamc@167 29 char error_message[ERROR_BUF_LEN];
adamc@117 30 };
adamc@117 31
adamc@311 32 extern int uw_inputs_len;
adamc@144 33
adamc@311 34 uw_context uw_init(size_t page_len, size_t heap_len) {
adamc@311 35 uw_context ctx = malloc(sizeof(struct uw_context));
adamc@136 36
adamc@117 37 ctx->page_front = ctx->page = malloc(page_len);
adamc@117 38 ctx->page_back = ctx->page_front + page_len;
adamc@136 39
adamc@136 40 ctx->heap_front = ctx->heap = malloc(heap_len);
adamc@136 41 ctx->heap_back = ctx->heap_front + heap_len;
adamc@136 42
adamc@311 43 ctx->inputs = calloc(uw_inputs_len, sizeof(char *));
adamc@144 44
adamc@272 45 ctx->db = NULL;
adamc@272 46
adamc@323 47 ctx->regions = NULL;
adamc@323 48
adamc@167 49 ctx->error_message[0] = 0;
adamc@167 50
adamc@117 51 return ctx;
adamc@106 52 }
adamc@106 53
adamc@311 54 void uw_set_db(uw_context ctx, void *db) {
adamc@272 55 ctx->db = db;
adamc@272 56 }
adamc@272 57
adamc@311 58 void *uw_get_db(uw_context ctx) {
adamc@272 59 return ctx->db;
adamc@272 60 }
adamc@272 61
adamc@311 62 void uw_free(uw_context ctx) {
adamc@117 63 free(ctx->page);
adamc@136 64 free(ctx->heap);
adamc@144 65 free(ctx->inputs);
adamc@136 66 free(ctx);
adamc@136 67 }
adamc@136 68
adamc@311 69 void uw_reset_keep_request(uw_context ctx) {
adamc@138 70 ctx->page_front = ctx->page;
adamc@138 71 ctx->heap_front = ctx->heap;
adamc@323 72 ctx->regions = NULL;
adamc@167 73
adamc@167 74 ctx->error_message[0] = 0;
adamc@167 75 }
adamc@167 76
adamc@311 77 void uw_reset_keep_error_message(uw_context ctx) {
adamc@167 78 ctx->page_front = ctx->page;
adamc@167 79 ctx->heap_front = ctx->heap;
adamc@323 80 ctx->regions = NULL;
adamc@167 81 }
adamc@167 82
adamc@311 83 void uw_reset(uw_context ctx) {
adamc@311 84 uw_reset_keep_request(ctx);
adamc@311 85 memset(ctx->inputs, 0, uw_inputs_len * sizeof(char *));
adamc@144 86 }
adamc@144 87
adamc@311 88 void uw_db_init(uw_context);
adamc@311 89 void uw_handle(uw_context, char *);
adamc@167 90
adamc@311 91 failure_kind uw_begin_init(uw_context ctx) {
adamc@272 92 int r = setjmp(ctx->jmp_buf);
adamc@272 93
adamc@272 94 if (r == 0)
adamc@311 95 uw_db_init(ctx);
adamc@272 96
adamc@272 97 return r;
adamc@272 98 }
adamc@272 99
adamc@311 100 failure_kind uw_begin(uw_context ctx, char *path) {
adamc@190 101 int r = setjmp(ctx->jmp_buf);
adamc@190 102
adamc@190 103 if (r == 0)
adamc@311 104 uw_handle(ctx, path);
adamc@167 105
adamc@190 106 return r;
adamc@167 107 }
adamc@167 108
adamc@311 109 __attribute__((noreturn)) void uw_error(uw_context ctx, failure_kind fk, const char *fmt, ...) {
adamc@167 110 va_list ap;
adamc@167 111 va_start(ap, fmt);
adamc@167 112
adamc@167 113 vsnprintf(ctx->error_message, ERROR_BUF_LEN, fmt, ap);
adamc@167 114
adamc@190 115 longjmp(ctx->jmp_buf, fk);
adamc@167 116 }
adamc@167 117
adamc@311 118 char *uw_error_message(uw_context ctx) {
adamc@167 119 return ctx->error_message;
adamc@167 120 }
adamc@167 121
adamc@311 122 int uw_input_num(char*);
adamc@144 123
adamc@311 124 void uw_set_input(uw_context ctx, char *name, char *value) {
adamc@311 125 int n = uw_input_num(name);
adamc@144 126
adamc@169 127 if (n < 0)
adamc@311 128 uw_error(ctx, FATAL, "Bad input name %s", name);
adamc@144 129
adamc@311 130 if (n >= uw_inputs_len)
adamc@311 131 uw_error(ctx, FATAL, "For input name %s, index %d is out of range", name, n);
adamc@169 132
adamc@144 133 ctx->inputs[n] = value;
adamc@144 134
adamc@282 135 //printf("[%d] %s = %s\n", n, name, value);
adamc@144 136 }
adamc@144 137
adamc@311 138 char *uw_get_input(uw_context ctx, int n) {
adamc@169 139 if (n < 0)
adamc@311 140 uw_error(ctx, FATAL, "Negative input index %d", n);
adamc@311 141 if (n >= uw_inputs_len)
adamc@311 142 uw_error(ctx, FATAL, "Out-of-bounds input index %d", n);
adamc@282 143 //printf("[%d] = %s\n", n, ctx->inputs[n]);
adamc@144 144 return ctx->inputs[n];
adamc@138 145 }
adamc@138 146
adamc@311 147 char *uw_get_optional_input(uw_context ctx, int n) {
adamc@190 148 if (n < 0)
adamc@311 149 uw_error(ctx, FATAL, "Negative input index %d", n);
adamc@311 150 if (n >= uw_inputs_len)
adamc@311 151 uw_error(ctx, FATAL, "Out-of-bounds input index %d", n);
adamc@190 152 printf("[%d] = %s\n", n, ctx->inputs[n]);
adamc@190 153 return (ctx->inputs[n] == NULL ? "" : ctx->inputs[n]);
adamc@190 154 }
adamc@190 155
adamc@311 156 static void uw_check_heap(uw_context ctx, size_t extra) {
adamc@136 157 if (ctx->heap_back - ctx->heap_front < extra) {
adamc@321 158 size_t desired = ctx->heap_front - ctx->heap + extra, next;
adamc@136 159 char *new_heap;
adamc@136 160
adamc@317 161 next = ctx->heap_back - ctx->heap;
adamc@317 162 if (next == 0)
adamc@317 163 next = 1;
adamc@317 164 for (; next < desired; next *= 2);
adamc@136 165
adamc@136 166 new_heap = realloc(ctx->heap, next);
adamc@321 167 ctx->heap_front = new_heap + (ctx->heap_front - ctx->heap);
adamc@169 168 ctx->heap_back = new_heap + next;
adamc@136 169
adamc@136 170 if (new_heap != ctx->heap) {
adamc@136 171 ctx->heap = new_heap;
adamc@311 172 uw_error(ctx, UNLIMITED_RETRY, "Couldn't allocate new heap chunk contiguously");
adamc@136 173 }
adamc@136 174
adamc@169 175 ctx->heap = new_heap;
adamc@136 176 }
adamc@136 177 }
adamc@136 178
adamc@311 179 void *uw_malloc(uw_context ctx, size_t len) {
adamc@136 180 void *result;
adamc@136 181
adamc@311 182 uw_check_heap(ctx, len);
adamc@136 183
adamc@136 184 result = ctx->heap_front;
adamc@136 185 ctx->heap_front += len;
adamc@136 186 return result;
adamc@117 187 }
adamc@117 188
adamc@323 189 void uw_begin_region(uw_context ctx) {
adamc@323 190 regions *r = (regions *) ctx->heap_front;
adamc@323 191
adamc@323 192 uw_check_heap(ctx, sizeof(regions));
adamc@323 193
adamc@323 194 ctx->heap_front += sizeof(regions);
adamc@323 195
adamc@323 196 r->next = ctx->regions;
adamc@323 197 ctx->regions = r;
adamc@323 198 }
adamc@323 199
adamc@323 200 void uw_end_region(uw_context ctx) {
adamc@323 201 regions *r = ctx->regions;
adamc@323 202
adamc@323 203 if (r == NULL)
adamc@323 204 uw_error(ctx, FATAL, "Region stack underflow");
adamc@323 205
adamc@323 206 ctx->heap_front = (char *) r;
adamc@323 207 ctx->regions = r->next;
adamc@323 208 }
adamc@323 209
adamc@311 210 int uw_really_send(int sock, const void *buf, ssize_t len) {
adamc@117 211 while (len > 0) {
adamc@117 212 ssize_t n = send(sock, buf, len, 0);
adamc@117 213
adamc@117 214 if (n < 0)
adamc@117 215 return n;
adamc@117 216
adamc@117 217 buf += n;
adamc@117 218 len -= n;
adamc@117 219 }
adamc@117 220
adamc@117 221 return 0;
adamc@117 222 }
adamc@117 223
adamc@311 224 int uw_send(uw_context ctx, int sock) {
adamc@311 225 return uw_really_send(sock, ctx->page, ctx->page_front - ctx->page);
adamc@117 226 }
adamc@117 227
adamc@311 228 static void uw_check(uw_context ctx, size_t extra) {
adamc@321 229 size_t desired = ctx->page_front - ctx->page + extra, next;
adamc@117 230 char *new_page;
adamc@117 231
adamc@317 232 next = ctx->page_back - ctx->page;
adamc@317 233 if (next == 0)
adamc@317 234 next = 1;
adamc@317 235 for (; next < desired; next *= 2);
adamc@117 236
adamc@117 237 new_page = realloc(ctx->page, next);
adamc@117 238 ctx->page_front = new_page + (ctx->page_front - ctx->page);
adamc@317 239 ctx->page_back = new_page + next;
adamc@117 240 ctx->page = new_page;
adamc@117 241 }
adamc@117 242
adamc@311 243 static void uw_writec_unsafe(uw_context ctx, char c) {
adamc@117 244 *(ctx->page_front)++ = c;
adamc@117 245 }
adamc@117 246
adamc@311 247 void uw_writec(uw_context ctx, char c) {
adamc@311 248 uw_check(ctx, 1);
adamc@311 249 uw_writec_unsafe(ctx, c);
adamc@117 250 }
adamc@117 251
adamc@311 252 static void uw_write_unsafe(uw_context ctx, const char* s) {
adamc@117 253 int len = strlen(s);
adamc@117 254 memcpy(ctx->page_front, s, len);
adamc@117 255 ctx->page_front += len;
adamc@117 256 }
adamc@117 257
adamc@311 258 void uw_write(uw_context ctx, const char* s) {
adamc@311 259 uw_check(ctx, strlen(s) + 1);
adamc@311 260 uw_write_unsafe(ctx, s);
adamc@183 261 *ctx->page_front = 0;
adamc@102 262 }
adamc@106 263
adamc@135 264
adamc@311 265 char *uw_Basis_attrifyInt(uw_context ctx, uw_Basis_int n) {
adamc@136 266 char *result;
adamc@136 267 int len;
adamc@311 268 uw_check_heap(ctx, INTS_MAX);
adamc@136 269 result = ctx->heap_front;
adamc@276 270 sprintf(result, "%lld%n", n, &len);
adamc@137 271 ctx->heap_front += len+1;
adamc@136 272 return result;
adamc@106 273 }
adamc@106 274
adamc@311 275 char *uw_Basis_attrifyFloat(uw_context ctx, uw_Basis_float n) {
adamc@136 276 char *result;
adamc@136 277 int len;
adamc@311 278 uw_check_heap(ctx, FLOATS_MAX);
adamc@136 279 result = ctx->heap_front;
adamc@136 280 sprintf(result, "%g%n", n, &len);
adamc@137 281 ctx->heap_front += len+1;
adamc@136 282 return result;
adamc@106 283 }
adamc@106 284
adamc@311 285 char *uw_Basis_attrifyString(uw_context ctx, uw_Basis_string s) {
adamc@136 286 int len = strlen(s);
adamc@136 287 char *result, *p;
adamc@311 288 uw_check_heap(ctx, len * 6 + 1);
adamc@136 289
adamc@136 290 result = p = ctx->heap_front;
adamc@136 291
adamc@136 292 for (; *s; s++) {
adamc@136 293 char c = *s;
adamc@136 294
adamc@136 295 if (c == '"') {
adamc@136 296 strcpy(p, "&quot;");
adamc@136 297 p += 6;
adamc@136 298 } else if (c == '&') {
adamc@136 299 strcpy(p, "&amp;");
adamc@136 300 p += 5;
adamc@136 301 }
adamc@136 302 else if (isprint(c))
adamc@136 303 *p++ = c;
adamc@136 304 else {
adamc@136 305 int len2;
adamc@136 306 sprintf(p, "&#%d;%n", c, &len2);
adamc@136 307 p += len2;
adamc@136 308 }
adamc@136 309 }
adamc@136 310
adamc@137 311 *p++ = 0;
adamc@136 312 ctx->heap_front = p;
adamc@136 313 return result;
adamc@106 314 }
adamc@106 315
adamc@311 316 static void uw_Basis_attrifyInt_w_unsafe(uw_context ctx, uw_Basis_int n) {
adamc@117 317 int len;
adamc@117 318
adamc@276 319 sprintf(ctx->page_front, "%lld%n", n, &len);
adamc@117 320 ctx->page_front += len;
adamc@106 321 }
adamc@106 322
adamc@311 323 void uw_Basis_attrifyInt_w(uw_context ctx, uw_Basis_int n) {
adamc@311 324 uw_check(ctx, INTS_MAX);
adamc@311 325 uw_Basis_attrifyInt_w_unsafe(ctx, n);
adamc@106 326 }
adamc@106 327
adamc@311 328 void uw_Basis_attrifyFloat_w(uw_context ctx, uw_Basis_float n) {
adamc@117 329 int len;
adamc@117 330
adamc@311 331 uw_check(ctx, FLOATS_MAX);
adamc@117 332 sprintf(ctx->page_front, "%g%n", n, &len);
adamc@117 333 ctx->page_front += len;
adamc@117 334 }
adamc@117 335
adamc@311 336 void uw_Basis_attrifyString_w(uw_context ctx, uw_Basis_string s) {
adamc@311 337 uw_check(ctx, strlen(s) * 6);
adamc@117 338
adamc@106 339 for (; *s; s++) {
adamc@106 340 char c = *s;
adamc@106 341
adamc@106 342 if (c == '"')
adamc@311 343 uw_write_unsafe(ctx, "&quot;");
adamc@136 344 else if (c == '&')
adamc@311 345 uw_write_unsafe(ctx, "&amp;");
adamc@106 346 else if (isprint(c))
adamc@311 347 uw_writec_unsafe(ctx, c);
adamc@106 348 else {
adamc@311 349 uw_write_unsafe(ctx, "&#");
adamc@311 350 uw_Basis_attrifyInt_w_unsafe(ctx, c);
adamc@311 351 uw_writec_unsafe(ctx, ';');
adamc@106 352 }
adamc@106 353 }
adamc@106 354 }
adamc@120 355
adamc@120 356
adamc@311 357 char *uw_Basis_urlifyInt(uw_context ctx, uw_Basis_int n) {
adamc@137 358 int len;
adamc@137 359 char *r;
adamc@137 360
adamc@311 361 uw_check_heap(ctx, INTS_MAX);
adamc@137 362 r = ctx->heap_front;
adamc@276 363 sprintf(r, "%lld%n", n, &len);
adamc@137 364 ctx->heap_front += len+1;
adamc@137 365 return r;
adamc@120 366 }
adamc@120 367
adamc@311 368 char *uw_Basis_urlifyFloat(uw_context ctx, uw_Basis_float n) {
adamc@137 369 int len;
adamc@137 370 char *r;
adamc@137 371
adamc@311 372 uw_check_heap(ctx, FLOATS_MAX);
adamc@137 373 r = ctx->heap_front;
adamc@137 374 sprintf(r, "%g%n", n, &len);
adamc@137 375 ctx->heap_front += len+1;
adamc@137 376 return r;
adamc@120 377 }
adamc@120 378
adamc@311 379 char *uw_Basis_urlifyString(uw_context ctx, uw_Basis_string s) {
adamc@137 380 char *r, *p;
adamc@137 381
adamc@311 382 uw_check_heap(ctx, strlen(s) * 3 + 1);
adamc@137 383
adamc@137 384 for (r = p = ctx->heap_front; *s; s++) {
adamc@137 385 char c = *s;
adamc@137 386
adamc@137 387 if (c == ' ')
adamc@137 388 *p++ = '+';
adamc@137 389 else if (isalnum(c))
adamc@137 390 *p++ = c;
adamc@137 391 else {
adamc@137 392 sprintf(p, "%%%02X", c);
adamc@137 393 p += 3;
adamc@137 394 }
adamc@137 395 }
adamc@137 396
adamc@137 397 *p++ = 0;
adamc@137 398 ctx->heap_front = p;
adamc@137 399 return r;
adamc@120 400 }
adamc@120 401
adamc@311 402 char *uw_Basis_urlifyBool(uw_context ctx, uw_Basis_bool b) {
adamc@311 403 if (b == uw_Basis_False)
adamc@186 404 return "0";
adamc@186 405 else
adamc@186 406 return "1";
adamc@186 407 }
adamc@186 408
adamc@311 409 static void uw_Basis_urlifyInt_w_unsafe(uw_context ctx, uw_Basis_int n) {
adamc@120 410 int len;
adamc@120 411
adamc@276 412 sprintf(ctx->page_front, "%lld%n", n, &len);
adamc@120 413 ctx->page_front += len;
adamc@120 414 }
adamc@120 415
adamc@311 416 void uw_Basis_urlifyInt_w(uw_context ctx, uw_Basis_int n) {
adamc@311 417 uw_check(ctx, INTS_MAX);
adamc@311 418 uw_Basis_urlifyInt_w_unsafe(ctx, n);
adamc@120 419 }
adamc@120 420
adamc@311 421 void uw_Basis_urlifyFloat_w(uw_context ctx, uw_Basis_float n) {
adamc@120 422 int len;
adamc@120 423
adamc@311 424 uw_check(ctx, FLOATS_MAX);
adamc@120 425 sprintf(ctx->page_front, "%g%n", n, &len);
adamc@120 426 ctx->page_front += len;
adamc@120 427 }
adamc@120 428
adamc@311 429 void uw_Basis_urlifyString_w(uw_context ctx, uw_Basis_string s) {
adamc@311 430 uw_check(ctx, strlen(s) * 3);
adamc@120 431
adamc@120 432 for (; *s; s++) {
adamc@120 433 char c = *s;
adamc@120 434
adamc@120 435 if (c == ' ')
adamc@311 436 uw_writec_unsafe(ctx, '+');
adamc@120 437 else if (isalnum(c))
adamc@311 438 uw_writec_unsafe(ctx, c);
adamc@120 439 else {
adamc@120 440 sprintf(ctx->page_front, "%%%02X", c);
adamc@120 441 ctx->page_front += 3;
adamc@120 442 }
adamc@120 443 }
adamc@120 444 }
adamc@120 445
adamc@311 446 void uw_Basis_urlifyBool_w(uw_context ctx, uw_Basis_bool b) {
adamc@311 447 if (b == uw_Basis_False)
adamc@311 448 uw_writec(ctx, '0');
adamc@186 449 else
adamc@311 450 uw_writec(ctx, '1');
adamc@186 451 }
adamc@186 452
adamc@120 453
adamc@311 454 static char *uw_unurlify_advance(char *s) {
adamc@144 455 char *new_s = strchr(s, '/');
adamc@120 456
adamc@120 457 if (new_s)
adamc@120 458 *new_s++ = 0;
adamc@120 459 else
adamc@144 460 new_s = strchr(s, 0);
adamc@144 461
adamc@144 462 return new_s;
adamc@144 463 }
adamc@144 464
adamc@311 465 uw_Basis_int uw_Basis_unurlifyInt(uw_context ctx, char **s) {
adamc@311 466 char *new_s = uw_unurlify_advance(*s);
adamc@311 467 uw_Basis_int r;
adamc@120 468
adamc@276 469 r = atoll(*s);
adamc@120 470 *s = new_s;
adamc@120 471 return r;
adamc@120 472 }
adamc@120 473
adamc@311 474 uw_Basis_float uw_Basis_unurlifyFloat(uw_context ctx, char **s) {
adamc@311 475 char *new_s = uw_unurlify_advance(*s);
adamc@311 476 uw_Basis_float r;
adamc@120 477
adamc@120 478 r = atof(*s);
adamc@120 479 *s = new_s;
adamc@120 480 return r;
adamc@120 481 }
adamc@120 482
adamc@311 483 static uw_Basis_string uw_unurlifyString_to(uw_context ctx, char *r, char *s) {
adamc@144 484 char *s1, *s2;
adamc@144 485 int n;
adamc@136 486
adamc@144 487 for (s1 = r, s2 = s; *s2; ++s1, ++s2) {
adamc@136 488 char c = *s2;
adamc@136 489
adamc@136 490 switch (c) {
adamc@136 491 case '+':
adamc@136 492 *s1 = ' ';
adamc@136 493 break;
adamc@136 494 case '%':
adamc@169 495 if (s2[1] == 0)
adamc@311 496 uw_error(ctx, FATAL, "Missing first character of escaped URL byte");
adamc@169 497 if (s2[2] == 0)
adamc@311 498 uw_error(ctx, FATAL, "Missing second character of escaped URL byte");
adamc@169 499 if (sscanf(s2+1, "%02X", &n) != 1)
adamc@311 500 uw_error(ctx, FATAL, "Invalid escaped URL byte starting at: %s", s2);
adamc@136 501 *s1 = n;
adamc@136 502 s2 += 2;
adamc@136 503 break;
adamc@136 504 default:
adamc@136 505 *s1 = c;
adamc@136 506 }
adamc@136 507 }
adamc@136 508 *s1++ = 0;
adamc@144 509 return s1;
adamc@144 510 }
adamc@144 511
adamc@311 512 uw_Basis_bool uw_Basis_unurlifyBool(uw_context ctx, char **s) {
adamc@311 513 char *new_s = uw_unurlify_advance(*s);
adamc@311 514 uw_Basis_bool r;
adamc@186 515
adamc@186 516 if (*s[0] == 0 || !strcmp(*s, "0") || !strcmp(*s, "off"))
adamc@311 517 r = uw_Basis_False;
adamc@186 518 else
adamc@311 519 r = uw_Basis_True;
adamc@186 520
adamc@186 521 *s = new_s;
adamc@186 522 return r;
adamc@186 523 }
adamc@186 524
adamc@311 525 uw_Basis_string uw_Basis_unurlifyString(uw_context ctx, char **s) {
adamc@311 526 char *new_s = uw_unurlify_advance(*s);
adamc@144 527 char *r, *s1, *s2;
adamc@144 528 int len, n;
adamc@144 529
adamc@200 530 len = strlen(*s);
adamc@311 531 uw_check_heap(ctx, len + 1);
adamc@144 532
adamc@144 533 r = ctx->heap_front;
adamc@311 534 ctx->heap_front = uw_unurlifyString_to(ctx, ctx->heap_front, *s);
adamc@136 535 *s = new_s;
adamc@136 536 return r;
adamc@120 537 }
adamc@135 538
adamc@135 539
adamc@311 540 char *uw_Basis_htmlifyInt(uw_context ctx, uw_Basis_int n) {
adamc@286 541 int len;
adamc@286 542 char *r;
adamc@286 543
adamc@311 544 uw_check_heap(ctx, INTS_MAX);
adamc@286 545 r = ctx->heap_front;
adamc@286 546 sprintf(r, "%lld%n", n, &len);
adamc@286 547 ctx->heap_front += len+1;
adamc@286 548 return r;
adamc@286 549 }
adamc@286 550
adamc@311 551 void uw_Basis_htmlifyInt_w(uw_context ctx, uw_Basis_int n) {
adamc@286 552 int len;
adamc@286 553
adamc@311 554 uw_check(ctx, INTS_MAX);
adamc@286 555 sprintf(ctx->page_front, "%lld%n", n, &len);
adamc@286 556 ctx->page_front += len;
adamc@286 557 }
adamc@286 558
adamc@311 559 char *uw_Basis_htmlifyFloat(uw_context ctx, uw_Basis_float n) {
adamc@286 560 int len;
adamc@286 561 char *r;
adamc@286 562
adamc@311 563 uw_check_heap(ctx, FLOATS_MAX);
adamc@286 564 r = ctx->heap_front;
adamc@286 565 sprintf(r, "%g%n", n, &len);
adamc@286 566 ctx->heap_front += len+1;
adamc@286 567 return r;
adamc@286 568 }
adamc@286 569
adamc@311 570 void uw_Basis_htmlifyFloat_w(uw_context ctx, uw_Basis_float n) {
adamc@286 571 int len;
adamc@286 572
adamc@311 573 uw_check(ctx, FLOATS_MAX);
adamc@286 574 sprintf(ctx->page_front, "%g%n", n, &len);
adamc@286 575 ctx->page_front += len;
adamc@286 576 }
adamc@286 577
adamc@311 578 char *uw_Basis_htmlifyString(uw_context ctx, uw_Basis_string s) {
adamc@137 579 char *r, *s2;
adamc@137 580
adamc@311 581 uw_check_heap(ctx, strlen(s) * 5 + 1);
adamc@137 582
adamc@137 583 for (r = s2 = ctx->heap_front; *s; s++) {
adamc@137 584 char c = *s;
adamc@137 585
adamc@137 586 switch (c) {
adamc@137 587 case '<':
adamc@137 588 strcpy(s2, "&lt;");
adamc@137 589 s2 += 4;
adamc@137 590 break;
adamc@137 591 case '&':
adamc@137 592 strcpy(s2, "&amp;");
adamc@137 593 s2 += 5;
adamc@137 594 break;
adamc@137 595 default:
adamc@137 596 if (isprint(c))
adamc@137 597 *s2++ = c;
adamc@137 598 else {
adamc@137 599 int len2;
adamc@137 600 sprintf(s2, "&#%d;%n", c, &len2);
adamc@137 601 s2 += len2;
adamc@137 602 }
adamc@137 603 }
adamc@137 604 }
adamc@137 605
adamc@137 606 *s2++ = 0;
adamc@137 607 ctx->heap_front = s2;
adamc@137 608 return r;
adamc@135 609 }
adamc@135 610
adamc@311 611 void uw_Basis_htmlifyString_w(uw_context ctx, uw_Basis_string s) {
adamc@321 612 uw_check(ctx, strlen(s) * 6);
adamc@135 613
adamc@135 614 for (; *s; s++) {
adamc@135 615 char c = *s;
adamc@135 616
adamc@135 617 switch (c) {
adamc@135 618 case '<':
adamc@311 619 uw_write_unsafe(ctx, "&lt;");
adamc@135 620 break;
adamc@135 621 case '&':
adamc@311 622 uw_write_unsafe(ctx, "&amp;");
adamc@135 623 break;
adamc@135 624 default:
adamc@135 625 if (isprint(c))
adamc@311 626 uw_writec_unsafe(ctx, c);
adamc@135 627 else {
adamc@311 628 uw_write_unsafe(ctx, "&#");
adamc@311 629 uw_Basis_attrifyInt_w_unsafe(ctx, c);
adamc@311 630 uw_writec_unsafe(ctx, ';');
adamc@135 631 }
adamc@135 632 }
adamc@135 633 }
adamc@135 634 }
adamc@180 635
adamc@311 636 uw_Basis_string uw_Basis_htmlifyBool(uw_context ctx, uw_Basis_bool b) {
adamc@311 637 if (b == uw_Basis_False)
adamc@286 638 return "False";
adamc@286 639 else
adamc@286 640 return "True";
adamc@286 641 }
adamc@286 642
adamc@311 643 void uw_Basis_htmlifyBool_w(uw_context ctx, uw_Basis_bool b) {
adamc@311 644 if (b == uw_Basis_False) {
adamc@311 645 uw_check(ctx, 6);
adamc@286 646 strcpy(ctx->page_front, "False");
adamc@286 647 ctx->page_front += 5;
adamc@286 648 } else {
adamc@311 649 uw_check(ctx, 5);
adamc@286 650 strcpy(ctx->page_front, "True");
adamc@286 651 ctx->page_front += 4;
adamc@286 652 }
adamc@286 653 }
adamc@286 654
adamc@311 655 uw_Basis_string uw_Basis_strcat(uw_context ctx, uw_Basis_string s1, uw_Basis_string s2) {
adamc@180 656 int len = strlen(s1) + strlen(s2) + 1;
adamc@180 657 char *s;
adamc@180 658
adamc@311 659 uw_check_heap(ctx, len);
adamc@180 660
adamc@180 661 s = ctx->heap_front;
adamc@180 662
adamc@180 663 strcpy(s, s1);
adamc@180 664 strcat(s, s2);
adamc@180 665 ctx->heap_front += len;
adamc@180 666
adamc@180 667 return s;
adamc@180 668 }
adamc@278 669
adamc@311 670 uw_Basis_string uw_Basis_strdup(uw_context ctx, uw_Basis_string s1) {
adamc@278 671 int len = strlen(s1) + 1;
adamc@278 672 char *s;
adamc@278 673
adamc@311 674 uw_check_heap(ctx, len);
adamc@278 675
adamc@278 676 s = ctx->heap_front;
adamc@278 677
adamc@278 678 strcpy(s, s1);
adamc@278 679 ctx->heap_front += len;
adamc@278 680
adamc@278 681 return s;
adamc@278 682 }
adamc@280 683
adamc@280 684
adamc@311 685 char *uw_Basis_sqlifyInt(uw_context ctx, uw_Basis_int n) {
adamc@281 686 int len;
adamc@281 687 char *r;
adamc@281 688
adamc@311 689 uw_check_heap(ctx, INTS_MAX + 6);
adamc@281 690 r = ctx->heap_front;
adamc@281 691 sprintf(r, "%lld::int8%n", n, &len);
adamc@281 692 ctx->heap_front += len+1;
adamc@281 693 return r;
adamc@281 694 }
adamc@281 695
adamc@311 696 char *uw_Basis_sqlifyFloat(uw_context ctx, uw_Basis_float n) {
adamc@281 697 int len;
adamc@281 698 char *r;
adamc@281 699
adamc@311 700 uw_check_heap(ctx, FLOATS_MAX + 8);
adamc@281 701 r = ctx->heap_front;
adamc@281 702 sprintf(r, "%g::float8%n", n, &len);
adamc@281 703 ctx->heap_front += len+1;
adamc@281 704 return r;
adamc@281 705 }
adamc@281 706
adamc@281 707
adamc@311 708 uw_Basis_string uw_Basis_sqlifyString(uw_context ctx, uw_Basis_string s) {
adamc@280 709 char *r, *s2;
adamc@280 710
adamc@311 711 uw_check_heap(ctx, strlen(s) * 2 + 10);
adamc@280 712
adamc@280 713 r = s2 = ctx->heap_front;
adamc@280 714 *s2++ = 'E';
adamc@280 715 *s2++ = '\'';
adamc@280 716
adamc@280 717 for (; *s; s++) {
adamc@280 718 char c = *s;
adamc@280 719
adamc@280 720 switch (c) {
adamc@280 721 case '\'':
adamc@280 722 strcpy(s2, "\\'");
adamc@280 723 s2 += 2;
adamc@280 724 break;
adamc@280 725 case '\\':
adamc@280 726 strcpy(s2, "\\\\");
adamc@280 727 s2 += 2;
adamc@280 728 break;
adamc@280 729 default:
adamc@280 730 if (isprint(c))
adamc@280 731 *s2++ = c;
adamc@280 732 else {
adamc@280 733 sprintf(s2, "\\%3o", c);
adamc@280 734 s2 += 4;
adamc@280 735 }
adamc@280 736 }
adamc@280 737 }
adamc@280 738
adamc@281 739 strcpy(s2, "'::text");
adamc@281 740 ctx->heap_front = s2 + 8;
adamc@280 741 return r;
adamc@280 742 }
adamc@281 743
adamc@311 744 char *uw_Basis_sqlifyBool(uw_context ctx, uw_Basis_bool b) {
adamc@311 745 if (b == uw_Basis_False)
adamc@281 746 return "FALSE";
adamc@281 747 else
adamc@281 748 return "TRUE";
adamc@281 749 }
adamc@282 750
adamc@311 751 char *uw_Basis_ensqlBool(uw_Basis_bool b) {
adamc@311 752 static uw_Basis_int true = 1;
adamc@311 753 static uw_Basis_int false = 0;
adamc@282 754
adamc@311 755 if (b == uw_Basis_False)
adamc@282 756 return (char *)&false;
adamc@282 757 else
adamc@282 758 return (char *)&true;
adamc@282 759 }
adamc@284 760
adamc@311 761 uw_Basis_string uw_Basis_intToString(uw_context ctx, uw_Basis_int n) {
adamc@284 762 int len;
adamc@284 763 char *r;
adamc@284 764
adamc@311 765 uw_check_heap(ctx, INTS_MAX);
adamc@284 766 r = ctx->heap_front;
adamc@284 767 sprintf(r, "%lld%n", n, &len);
adamc@284 768 ctx->heap_front += len+1;
adamc@284 769 return r;
adamc@284 770 }
adamc@285 771
adamc@311 772 uw_Basis_string uw_Basis_floatToString(uw_context ctx, uw_Basis_float n) {
adamc@285 773 int len;
adamc@285 774 char *r;
adamc@285 775
adamc@311 776 uw_check_heap(ctx, FLOATS_MAX);
adamc@285 777 r = ctx->heap_front;
adamc@285 778 sprintf(r, "%g%n", n, &len);
adamc@285 779 ctx->heap_front += len+1;
adamc@285 780 return r;
adamc@285 781 }
adamc@285 782
adamc@311 783 uw_Basis_string uw_Basis_boolToString(uw_context ctx, uw_Basis_bool b) {
adamc@311 784 if (b == uw_Basis_False)
adamc@285 785 return "False";
adamc@285 786 else
adamc@285 787 return "True";
adamc@285 788 }
adamc@288 789
adamc@288 790
adamc@311 791 uw_Basis_int *uw_Basis_stringToInt(uw_context ctx, uw_Basis_string s) {
adamc@288 792 char *endptr;
adamc@311 793 uw_Basis_int n = strtoll(s, &endptr, 10);
adamc@288 794
adamc@288 795 if (*s != '\0' && *endptr == '\0') {
adamc@311 796 uw_Basis_int *r = uw_malloc(ctx, sizeof(uw_Basis_int));
adamc@288 797 *r = n;
adamc@288 798 return r;
adamc@288 799 } else
adamc@288 800 return NULL;
adamc@288 801 }
adamc@289 802
adamc@311 803 uw_Basis_float *uw_Basis_stringToFloat(uw_context ctx, uw_Basis_string s) {
adamc@289 804 char *endptr;
adamc@311 805 uw_Basis_float n = strtod(s, &endptr);
adamc@289 806
adamc@289 807 if (*s != '\0' && *endptr == '\0') {
adamc@311 808 uw_Basis_float *r = uw_malloc(ctx, sizeof(uw_Basis_float));
adamc@289 809 *r = n;
adamc@289 810 return r;
adamc@289 811 } else
adamc@289 812 return NULL;
adamc@289 813 }
adamc@289 814
adamc@311 815 uw_Basis_bool *uw_Basis_stringToBool(uw_context ctx, uw_Basis_string s) {
adamc@311 816 static uw_Basis_bool true = uw_Basis_True;
adamc@311 817 static uw_Basis_bool false = uw_Basis_False;
adamc@289 818
adamc@289 819 if (!strcasecmp (s, "True"))
adamc@289 820 return &true;
adamc@289 821 else if (!strcasecmp (s, "False"))
adamc@289 822 return &false;
adamc@289 823 else
adamc@289 824 return NULL;
adamc@289 825 }
adamc@292 826
adamc@311 827 uw_Basis_int uw_Basis_stringToInt_error(uw_context ctx, uw_Basis_string s) {
adamc@292 828 char *endptr;
adamc@311 829 uw_Basis_int n = strtoll(s, &endptr, 10);
adamc@292 830
adamc@292 831 if (*s != '\0' && *endptr == '\0')
adamc@292 832 return n;
adamc@292 833 else
adamc@311 834 uw_error(ctx, FATAL, "Can't parse int: %s", s);
adamc@292 835 }
adamc@293 836
adamc@311 837 uw_Basis_float uw_Basis_stringToFloat_error(uw_context ctx, uw_Basis_string s) {
adamc@293 838 char *endptr;
adamc@311 839 uw_Basis_float n = strtod(s, &endptr);
adamc@293 840
adamc@293 841 if (*s != '\0' && *endptr == '\0')
adamc@293 842 return n;
adamc@293 843 else
adamc@311 844 uw_error(ctx, FATAL, "Can't parse float: %s", s);
adamc@293 845 }
adamc@293 846
adamc@311 847 uw_Basis_bool uw_Basis_stringToBool_error(uw_context ctx, uw_Basis_string s) {
adamc@296 848 if (!strcasecmp(s, "T") || !strcasecmp (s, "True"))
adamc@311 849 return uw_Basis_True;
adamc@296 850 else if (!strcasecmp(s, "F") || !strcasecmp (s, "False"))
adamc@311 851 return uw_Basis_False;
adamc@293 852 else
adamc@311 853 uw_error(ctx, FATAL, "Can't parse bool: %s", s);
adamc@293 854 }