annotate src/c/urweb.c @ 311:9ad92047a499

Rename 'lw' prefixes to 'uw'
author Adam Chlipala <adamc@hcoop.net>
date Sun, 07 Sep 2008 15:40:42 -0400
parents 5dc11235129d
children 6a4e365db60c
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@311 14 struct uw_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@311 26 extern int uw_inputs_len;
adamc@144 27
adamc@311 28 uw_context uw_init(size_t page_len, size_t heap_len) {
adamc@311 29 uw_context ctx = malloc(sizeof(struct uw_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@311 37 ctx->inputs = calloc(uw_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@311 46 void uw_set_db(uw_context ctx, void *db) {
adamc@272 47 ctx->db = db;
adamc@272 48 }
adamc@272 49
adamc@311 50 void *uw_get_db(uw_context ctx) {
adamc@272 51 return ctx->db;
adamc@272 52 }
adamc@272 53
adamc@311 54 void uw_free(uw_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@311 61 void uw_reset_keep_request(uw_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@311 68 void uw_reset_keep_error_message(uw_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@311 73 void uw_reset(uw_context ctx) {
adamc@311 74 uw_reset_keep_request(ctx);
adamc@311 75 memset(ctx->inputs, 0, uw_inputs_len * sizeof(char *));
adamc@144 76 }
adamc@144 77
adamc@311 78 void uw_db_init(uw_context);
adamc@311 79 void uw_handle(uw_context, char *);
adamc@167 80
adamc@311 81 failure_kind uw_begin_init(uw_context ctx) {
adamc@272 82 int r = setjmp(ctx->jmp_buf);
adamc@272 83
adamc@272 84 if (r == 0)
adamc@311 85 uw_db_init(ctx);
adamc@272 86
adamc@272 87 return r;
adamc@272 88 }
adamc@272 89
adamc@311 90 failure_kind uw_begin(uw_context ctx, char *path) {
adamc@190 91 int r = setjmp(ctx->jmp_buf);
adamc@190 92
adamc@190 93 if (r == 0)
adamc@311 94 uw_handle(ctx, path);
adamc@167 95
adamc@190 96 return r;
adamc@167 97 }
adamc@167 98
adamc@311 99 __attribute__((noreturn)) void uw_error(uw_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@311 108 char *uw_error_message(uw_context ctx) {
adamc@167 109 return ctx->error_message;
adamc@167 110 }
adamc@167 111
adamc@311 112 int uw_input_num(char*);
adamc@144 113
adamc@311 114 void uw_set_input(uw_context ctx, char *name, char *value) {
adamc@311 115 int n = uw_input_num(name);
adamc@144 116
adamc@169 117 if (n < 0)
adamc@311 118 uw_error(ctx, FATAL, "Bad input name %s", name);
adamc@144 119
adamc@311 120 if (n >= uw_inputs_len)
adamc@311 121 uw_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@311 128 char *uw_get_input(uw_context ctx, int n) {
adamc@169 129 if (n < 0)
adamc@311 130 uw_error(ctx, FATAL, "Negative input index %d", n);
adamc@311 131 if (n >= uw_inputs_len)
adamc@311 132 uw_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@311 137 char *uw_get_optional_input(uw_context ctx, int n) {
adamc@190 138 if (n < 0)
adamc@311 139 uw_error(ctx, FATAL, "Negative input index %d", n);
adamc@311 140 if (n >= uw_inputs_len)
adamc@311 141 uw_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@311 146 static void uw_check_heap(uw_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@311 159 uw_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@311 166 void *uw_malloc(uw_context ctx, size_t len) {
adamc@136 167 void *result;
adamc@136 168
adamc@311 169 uw_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@311 176 int uw_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@311 190 int uw_send(uw_context ctx, int sock) {
adamc@311 191 return uw_really_send(sock, ctx->page, ctx->page_front - ctx->page);
adamc@117 192 }
adamc@117 193
adamc@311 194 static void uw_check(uw_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@311 206 static void uw_writec_unsafe(uw_context ctx, char c) {
adamc@117 207 *(ctx->page_front)++ = c;
adamc@117 208 }
adamc@117 209
adamc@311 210 void uw_writec(uw_context ctx, char c) {
adamc@311 211 uw_check(ctx, 1);
adamc@311 212 uw_writec_unsafe(ctx, c);
adamc@117 213 }
adamc@117 214
adamc@311 215 static void uw_write_unsafe(uw_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@311 221 void uw_write(uw_context ctx, const char* s) {
adamc@311 222 uw_check(ctx, strlen(s) + 1);
adamc@311 223 uw_write_unsafe(ctx, s);
adamc@183 224 *ctx->page_front = 0;
adamc@102 225 }
adamc@106 226
adamc@135 227
adamc@311 228 char *uw_Basis_attrifyInt(uw_context ctx, uw_Basis_int n) {
adamc@136 229 char *result;
adamc@136 230 int len;
adamc@311 231 uw_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@311 238 char *uw_Basis_attrifyFloat(uw_context ctx, uw_Basis_float n) {
adamc@136 239 char *result;
adamc@136 240 int len;
adamc@311 241 uw_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@311 248 char *uw_Basis_attrifyString(uw_context ctx, uw_Basis_string s) {
adamc@136 249 int len = strlen(s);
adamc@136 250 char *result, *p;
adamc@311 251 uw_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@311 279 static void uw_Basis_attrifyInt_w_unsafe(uw_context ctx, uw_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@311 286 void uw_Basis_attrifyInt_w(uw_context ctx, uw_Basis_int n) {
adamc@311 287 uw_check(ctx, INTS_MAX);
adamc@311 288 uw_Basis_attrifyInt_w_unsafe(ctx, n);
adamc@106 289 }
adamc@106 290
adamc@311 291 void uw_Basis_attrifyFloat_w(uw_context ctx, uw_Basis_float n) {
adamc@117 292 int len;
adamc@117 293
adamc@311 294 uw_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@311 299 void uw_Basis_attrifyString_w(uw_context ctx, uw_Basis_string s) {
adamc@311 300 uw_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@311 306 uw_write_unsafe(ctx, "&quot;");
adamc@136 307 else if (c == '&')
adamc@311 308 uw_write_unsafe(ctx, "&amp;");
adamc@106 309 else if (isprint(c))
adamc@311 310 uw_writec_unsafe(ctx, c);
adamc@106 311 else {
adamc@311 312 uw_write_unsafe(ctx, "&#");
adamc@311 313 uw_Basis_attrifyInt_w_unsafe(ctx, c);
adamc@311 314 uw_writec_unsafe(ctx, ';');
adamc@106 315 }
adamc@106 316 }
adamc@106 317 }
adamc@120 318
adamc@120 319
adamc@311 320 char *uw_Basis_urlifyInt(uw_context ctx, uw_Basis_int n) {
adamc@137 321 int len;
adamc@137 322 char *r;
adamc@137 323
adamc@311 324 uw_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@311 331 char *uw_Basis_urlifyFloat(uw_context ctx, uw_Basis_float n) {
adamc@137 332 int len;
adamc@137 333 char *r;
adamc@137 334
adamc@311 335 uw_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@311 342 char *uw_Basis_urlifyString(uw_context ctx, uw_Basis_string s) {
adamc@137 343 char *r, *p;
adamc@137 344
adamc@311 345 uw_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@311 365 char *uw_Basis_urlifyBool(uw_context ctx, uw_Basis_bool b) {
adamc@311 366 if (b == uw_Basis_False)
adamc@186 367 return "0";
adamc@186 368 else
adamc@186 369 return "1";
adamc@186 370 }
adamc@186 371
adamc@311 372 static void uw_Basis_urlifyInt_w_unsafe(uw_context ctx, uw_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@311 379 void uw_Basis_urlifyInt_w(uw_context ctx, uw_Basis_int n) {
adamc@311 380 uw_check(ctx, INTS_MAX);
adamc@311 381 uw_Basis_urlifyInt_w_unsafe(ctx, n);
adamc@120 382 }
adamc@120 383
adamc@311 384 void uw_Basis_urlifyFloat_w(uw_context ctx, uw_Basis_float n) {
adamc@120 385 int len;
adamc@120 386
adamc@311 387 uw_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@311 392 void uw_Basis_urlifyString_w(uw_context ctx, uw_Basis_string s) {
adamc@311 393 uw_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@311 399 uw_writec_unsafe(ctx, '+');
adamc@120 400 else if (isalnum(c))
adamc@311 401 uw_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@311 409 void uw_Basis_urlifyBool_w(uw_context ctx, uw_Basis_bool b) {
adamc@311 410 if (b == uw_Basis_False)
adamc@311 411 uw_writec(ctx, '0');
adamc@186 412 else
adamc@311 413 uw_writec(ctx, '1');
adamc@186 414 }
adamc@186 415
adamc@120 416
adamc@311 417 static char *uw_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@311 428 uw_Basis_int uw_Basis_unurlifyInt(uw_context ctx, char **s) {
adamc@311 429 char *new_s = uw_unurlify_advance(*s);
adamc@311 430 uw_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@311 437 uw_Basis_float uw_Basis_unurlifyFloat(uw_context ctx, char **s) {
adamc@311 438 char *new_s = uw_unurlify_advance(*s);
adamc@311 439 uw_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@311 446 static uw_Basis_string uw_unurlifyString_to(uw_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@311 459 uw_error(ctx, FATAL, "Missing first character of escaped URL byte");
adamc@169 460 if (s2[2] == 0)
adamc@311 461 uw_error(ctx, FATAL, "Missing second character of escaped URL byte");
adamc@169 462 if (sscanf(s2+1, "%02X", &n) != 1)
adamc@311 463 uw_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@311 475 uw_Basis_bool uw_Basis_unurlifyBool(uw_context ctx, char **s) {
adamc@311 476 char *new_s = uw_unurlify_advance(*s);
adamc@311 477 uw_Basis_bool r;
adamc@186 478
adamc@186 479 if (*s[0] == 0 || !strcmp(*s, "0") || !strcmp(*s, "off"))
adamc@311 480 r = uw_Basis_False;
adamc@186 481 else
adamc@311 482 r = uw_Basis_True;
adamc@186 483
adamc@186 484 *s = new_s;
adamc@186 485 return r;
adamc@186 486 }
adamc@186 487
adamc@311 488 uw_Basis_string uw_Basis_unurlifyString(uw_context ctx, char **s) {
adamc@311 489 char *new_s = uw_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@311 494 uw_check_heap(ctx, len + 1);
adamc@144 495
adamc@144 496 r = ctx->heap_front;
adamc@311 497 ctx->heap_front = uw_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@311 503 char *uw_Basis_htmlifyInt(uw_context ctx, uw_Basis_int n) {
adamc@286 504 int len;
adamc@286 505 char *r;
adamc@286 506
adamc@311 507 uw_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@311 514 void uw_Basis_htmlifyInt_w(uw_context ctx, uw_Basis_int n) {
adamc@286 515 int len;
adamc@286 516
adamc@311 517 uw_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@311 522 char *uw_Basis_htmlifyFloat(uw_context ctx, uw_Basis_float n) {
adamc@286 523 int len;
adamc@286 524 char *r;
adamc@286 525
adamc@311 526 uw_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@311 533 void uw_Basis_htmlifyFloat_w(uw_context ctx, uw_Basis_float n) {
adamc@286 534 int len;
adamc@286 535
adamc@311 536 uw_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@311 541 char *uw_Basis_htmlifyString(uw_context ctx, uw_Basis_string s) {
adamc@137 542 char *r, *s2;
adamc@137 543
adamc@311 544 uw_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@311 574 void uw_Basis_htmlifyString_w(uw_context ctx, uw_Basis_string s) {
adamc@311 575 uw_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@311 582 uw_write_unsafe(ctx, "&lt;");
adamc@135 583 break;
adamc@135 584 case '&':
adamc@311 585 uw_write_unsafe(ctx, "&amp;");
adamc@135 586 break;
adamc@135 587 default:
adamc@135 588 if (isprint(c))
adamc@311 589 uw_writec_unsafe(ctx, c);
adamc@135 590 else {
adamc@311 591 uw_write_unsafe(ctx, "&#");
adamc@311 592 uw_Basis_attrifyInt_w_unsafe(ctx, c);
adamc@311 593 uw_writec_unsafe(ctx, ';');
adamc@135 594 }
adamc@135 595 }
adamc@135 596 }
adamc@135 597 }
adamc@180 598
adamc@311 599 uw_Basis_string uw_Basis_htmlifyBool(uw_context ctx, uw_Basis_bool b) {
adamc@311 600 if (b == uw_Basis_False)
adamc@286 601 return "False";
adamc@286 602 else
adamc@286 603 return "True";
adamc@286 604 }
adamc@286 605
adamc@311 606 void uw_Basis_htmlifyBool_w(uw_context ctx, uw_Basis_bool b) {
adamc@311 607 if (b == uw_Basis_False) {
adamc@311 608 uw_check(ctx, 6);
adamc@286 609 strcpy(ctx->page_front, "False");
adamc@286 610 ctx->page_front += 5;
adamc@286 611 } else {
adamc@311 612 uw_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@311 618 uw_Basis_string uw_Basis_strcat(uw_context ctx, uw_Basis_string s1, uw_Basis_string s2) {
adamc@180 619 int len = strlen(s1) + strlen(s2) + 1;
adamc@180 620 char *s;
adamc@180 621
adamc@311 622 uw_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@311 633 uw_Basis_string uw_Basis_strdup(uw_context ctx, uw_Basis_string s1) {
adamc@278 634 int len = strlen(s1) + 1;
adamc@278 635 char *s;
adamc@278 636
adamc@311 637 uw_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@311 648 char *uw_Basis_sqlifyInt(uw_context ctx, uw_Basis_int n) {
adamc@281 649 int len;
adamc@281 650 char *r;
adamc@281 651
adamc@311 652 uw_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@311 659 char *uw_Basis_sqlifyFloat(uw_context ctx, uw_Basis_float n) {
adamc@281 660 int len;
adamc@281 661 char *r;
adamc@281 662
adamc@311 663 uw_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@311 671 uw_Basis_string uw_Basis_sqlifyString(uw_context ctx, uw_Basis_string s) {
adamc@280 672 char *r, *s2;
adamc@280 673
adamc@311 674 uw_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@311 707 char *uw_Basis_sqlifyBool(uw_context ctx, uw_Basis_bool b) {
adamc@311 708 if (b == uw_Basis_False)
adamc@281 709 return "FALSE";
adamc@281 710 else
adamc@281 711 return "TRUE";
adamc@281 712 }
adamc@282 713
adamc@311 714 char *uw_Basis_ensqlBool(uw_Basis_bool b) {
adamc@311 715 static uw_Basis_int true = 1;
adamc@311 716 static uw_Basis_int false = 0;
adamc@282 717
adamc@311 718 if (b == uw_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@311 724 uw_Basis_string uw_Basis_intToString(uw_context ctx, uw_Basis_int n) {
adamc@284 725 int len;
adamc@284 726 char *r;
adamc@284 727
adamc@311 728 uw_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@311 735 uw_Basis_string uw_Basis_floatToString(uw_context ctx, uw_Basis_float n) {
adamc@285 736 int len;
adamc@285 737 char *r;
adamc@285 738
adamc@311 739 uw_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@311 746 uw_Basis_string uw_Basis_boolToString(uw_context ctx, uw_Basis_bool b) {
adamc@311 747 if (b == uw_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@311 754 uw_Basis_int *uw_Basis_stringToInt(uw_context ctx, uw_Basis_string s) {
adamc@288 755 char *endptr;
adamc@311 756 uw_Basis_int n = strtoll(s, &endptr, 10);
adamc@288 757
adamc@288 758 if (*s != '\0' && *endptr == '\0') {
adamc@311 759 uw_Basis_int *r = uw_malloc(ctx, sizeof(uw_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@311 766 uw_Basis_float *uw_Basis_stringToFloat(uw_context ctx, uw_Basis_string s) {
adamc@289 767 char *endptr;
adamc@311 768 uw_Basis_float n = strtod(s, &endptr);
adamc@289 769
adamc@289 770 if (*s != '\0' && *endptr == '\0') {
adamc@311 771 uw_Basis_float *r = uw_malloc(ctx, sizeof(uw_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@311 778 uw_Basis_bool *uw_Basis_stringToBool(uw_context ctx, uw_Basis_string s) {
adamc@311 779 static uw_Basis_bool true = uw_Basis_True;
adamc@311 780 static uw_Basis_bool false = uw_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@311 790 uw_Basis_int uw_Basis_stringToInt_error(uw_context ctx, uw_Basis_string s) {
adamc@292 791 char *endptr;
adamc@311 792 uw_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@311 797 uw_error(ctx, FATAL, "Can't parse int: %s", s);
adamc@292 798 }
adamc@293 799
adamc@311 800 uw_Basis_float uw_Basis_stringToFloat_error(uw_context ctx, uw_Basis_string s) {
adamc@293 801 char *endptr;
adamc@311 802 uw_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@311 807 uw_error(ctx, FATAL, "Can't parse float: %s", s);
adamc@293 808 }
adamc@293 809
adamc@311 810 uw_Basis_bool uw_Basis_stringToBool_error(uw_context ctx, uw_Basis_string s) {
adamc@296 811 if (!strcasecmp(s, "T") || !strcasecmp (s, "True"))
adamc@311 812 return uw_Basis_True;
adamc@296 813 else if (!strcasecmp(s, "F") || !strcasecmp (s, "False"))
adamc@311 814 return uw_Basis_False;
adamc@293 815 else
adamc@311 816 uw_error(ctx, FATAL, "Can't parse bool: %s", s);
adamc@293 817 }