annotate src/c/urweb.c @ 307:52d4c60518d4

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