annotate src/c/urweb.c @ 283:c0e4ac23522d

'error' function
author Adam Chlipala <adamc@hcoop.net>
date Sun, 07 Sep 2008 10:02:27 -0400
parents 0236d9412ad2
children 77a28e7430bf
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@283 108 __attribute__((noreturn)) void lw_Basis_error(lw_context ctx, const char *s) {
adamc@283 109 lw_error(ctx, FATAL, s);
adamc@283 110 }
adamc@283 111
adamc@167 112 char *lw_error_message(lw_context ctx) {
adamc@167 113 return ctx->error_message;
adamc@167 114 }
adamc@167 115
adamc@144 116 int lw_input_num(char*);
adamc@144 117
adamc@144 118 void lw_set_input(lw_context ctx, char *name, char *value) {
adamc@144 119 int n = lw_input_num(name);
adamc@144 120
adamc@169 121 if (n < 0)
adamc@169 122 lw_error(ctx, FATAL, "Bad input name %s", name);
adamc@144 123
adamc@169 124 if (n >= lw_inputs_len)
adamc@169 125 lw_error(ctx, FATAL, "For input name %s, index %d is out of range", name, n);
adamc@169 126
adamc@144 127 ctx->inputs[n] = value;
adamc@144 128
adamc@282 129 //printf("[%d] %s = %s\n", n, name, value);
adamc@144 130 }
adamc@144 131
adamc@144 132 char *lw_get_input(lw_context ctx, int n) {
adamc@169 133 if (n < 0)
adamc@169 134 lw_error(ctx, FATAL, "Negative input index %d", n);
adamc@169 135 if (n >= lw_inputs_len)
adamc@169 136 lw_error(ctx, FATAL, "Out-of-bounds input index %d", n);
adamc@282 137 //printf("[%d] = %s\n", n, ctx->inputs[n]);
adamc@144 138 return ctx->inputs[n];
adamc@138 139 }
adamc@138 140
adamc@190 141 char *lw_get_optional_input(lw_context ctx, int n) {
adamc@190 142 if (n < 0)
adamc@190 143 lw_error(ctx, FATAL, "Negative input index %d", n);
adamc@190 144 if (n >= lw_inputs_len)
adamc@190 145 lw_error(ctx, FATAL, "Out-of-bounds input index %d", n);
adamc@190 146 printf("[%d] = %s\n", n, ctx->inputs[n]);
adamc@190 147 return (ctx->inputs[n] == NULL ? "" : ctx->inputs[n]);
adamc@190 148 }
adamc@190 149
adamc@136 150 static void lw_check_heap(lw_context ctx, size_t extra) {
adamc@136 151 if (ctx->heap_back - ctx->heap_front < extra) {
adamc@136 152 size_t desired = ctx->heap_back - ctx->heap_front + extra, next;
adamc@136 153 char *new_heap;
adamc@136 154
adamc@136 155 for (next = ctx->heap_back - ctx->heap_front; next < desired; next *= 2);
adamc@136 156
adamc@136 157 new_heap = realloc(ctx->heap, next);
adamc@169 158 ctx->heap_front = new_heap;
adamc@169 159 ctx->heap_back = new_heap + next;
adamc@136 160
adamc@136 161 if (new_heap != ctx->heap) {
adamc@136 162 ctx->heap = new_heap;
adamc@169 163 lw_error(ctx, UNLIMITED_RETRY, "Couldn't allocate new heap chunk contiguously");
adamc@136 164 }
adamc@136 165
adamc@169 166 ctx->heap = new_heap;
adamc@136 167 }
adamc@136 168 }
adamc@136 169
adamc@136 170 void *lw_malloc(lw_context ctx, size_t len) {
adamc@136 171 void *result;
adamc@136 172
adamc@136 173 lw_check_heap(ctx, len);
adamc@136 174
adamc@136 175 result = ctx->heap_front;
adamc@136 176 ctx->heap_front += len;
adamc@136 177 return result;
adamc@117 178 }
adamc@117 179
adamc@117 180 int lw_really_send(int sock, const void *buf, ssize_t len) {
adamc@117 181 while (len > 0) {
adamc@117 182 ssize_t n = send(sock, buf, len, 0);
adamc@117 183
adamc@117 184 if (n < 0)
adamc@117 185 return n;
adamc@117 186
adamc@117 187 buf += n;
adamc@117 188 len -= n;
adamc@117 189 }
adamc@117 190
adamc@117 191 return 0;
adamc@117 192 }
adamc@117 193
adamc@117 194 int lw_send(lw_context ctx, int sock) {
adamc@117 195 return lw_really_send(sock, ctx->page, ctx->page_front - ctx->page);
adamc@117 196 }
adamc@117 197
adamc@117 198 static void lw_check(lw_context ctx, size_t extra) {
adamc@117 199 size_t desired = ctx->page_back - ctx->page_front + extra, next;
adamc@117 200 char *new_page;
adamc@117 201
adamc@117 202 for (next = ctx->page_back - ctx->page_front; next < desired; next *= 2);
adamc@117 203
adamc@117 204 new_page = realloc(ctx->page, next);
adamc@117 205 ctx->page_front = new_page + (ctx->page_front - ctx->page);
adamc@117 206 ctx->page_back = new_page + (ctx->page_back - ctx->page);
adamc@117 207 ctx->page = new_page;
adamc@117 208 }
adamc@117 209
adamc@117 210 static void lw_writec_unsafe(lw_context ctx, char c) {
adamc@117 211 *(ctx->page_front)++ = c;
adamc@117 212 }
adamc@117 213
adamc@117 214 void lw_writec(lw_context ctx, char c) {
adamc@117 215 lw_check(ctx, 1);
adamc@117 216 lw_writec_unsafe(ctx, c);
adamc@117 217 }
adamc@117 218
adamc@117 219 static void lw_write_unsafe(lw_context ctx, const char* s) {
adamc@117 220 int len = strlen(s);
adamc@117 221 memcpy(ctx->page_front, s, len);
adamc@117 222 ctx->page_front += len;
adamc@117 223 }
adamc@117 224
adamc@117 225 void lw_write(lw_context ctx, const char* s) {
adamc@183 226 lw_check(ctx, strlen(s) + 1);
adamc@117 227 lw_write_unsafe(ctx, s);
adamc@183 228 *ctx->page_front = 0;
adamc@102 229 }
adamc@106 230
adamc@135 231
adamc@136 232 #define INTS_MAX 50
adamc@136 233 #define FLOATS_MAX 100
adamc@136 234
adamc@136 235 char *lw_Basis_attrifyInt(lw_context ctx, lw_Basis_int n) {
adamc@136 236 char *result;
adamc@136 237 int len;
adamc@136 238 lw_check_heap(ctx, INTS_MAX);
adamc@136 239 result = ctx->heap_front;
adamc@276 240 sprintf(result, "%lld%n", n, &len);
adamc@137 241 ctx->heap_front += len+1;
adamc@136 242 return result;
adamc@106 243 }
adamc@106 244
adamc@136 245 char *lw_Basis_attrifyFloat(lw_context ctx, lw_Basis_float n) {
adamc@136 246 char *result;
adamc@136 247 int len;
adamc@137 248 lw_check_heap(ctx, FLOATS_MAX);
adamc@136 249 result = ctx->heap_front;
adamc@136 250 sprintf(result, "%g%n", n, &len);
adamc@137 251 ctx->heap_front += len+1;
adamc@136 252 return result;
adamc@106 253 }
adamc@106 254
adamc@136 255 char *lw_Basis_attrifyString(lw_context ctx, lw_Basis_string s) {
adamc@136 256 int len = strlen(s);
adamc@136 257 char *result, *p;
adamc@137 258 lw_check_heap(ctx, len * 6 + 1);
adamc@136 259
adamc@136 260 result = p = ctx->heap_front;
adamc@136 261
adamc@136 262 for (; *s; s++) {
adamc@136 263 char c = *s;
adamc@136 264
adamc@136 265 if (c == '"') {
adamc@136 266 strcpy(p, "&quot;");
adamc@136 267 p += 6;
adamc@136 268 } else if (c == '&') {
adamc@136 269 strcpy(p, "&amp;");
adamc@136 270 p += 5;
adamc@136 271 }
adamc@136 272 else if (isprint(c))
adamc@136 273 *p++ = c;
adamc@136 274 else {
adamc@136 275 int len2;
adamc@136 276 sprintf(p, "&#%d;%n", c, &len2);
adamc@136 277 p += len2;
adamc@136 278 }
adamc@136 279 }
adamc@136 280
adamc@137 281 *p++ = 0;
adamc@136 282 ctx->heap_front = p;
adamc@136 283 return result;
adamc@106 284 }
adamc@106 285
adamc@117 286 static void lw_Basis_attrifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) {
adamc@117 287 int len;
adamc@117 288
adamc@276 289 sprintf(ctx->page_front, "%lld%n", n, &len);
adamc@117 290 ctx->page_front += len;
adamc@106 291 }
adamc@106 292
adamc@117 293 void lw_Basis_attrifyInt_w(lw_context ctx, lw_Basis_int n) {
adamc@117 294 lw_check(ctx, INTS_MAX);
adamc@117 295 lw_Basis_attrifyInt_w_unsafe(ctx, n);
adamc@106 296 }
adamc@106 297
adamc@117 298 void lw_Basis_attrifyFloat_w(lw_context ctx, lw_Basis_float n) {
adamc@117 299 int len;
adamc@117 300
adamc@117 301 lw_check(ctx, FLOATS_MAX);
adamc@117 302 sprintf(ctx->page_front, "%g%n", n, &len);
adamc@117 303 ctx->page_front += len;
adamc@117 304 }
adamc@117 305
adamc@117 306 void lw_Basis_attrifyString_w(lw_context ctx, lw_Basis_string s) {
adamc@117 307 lw_check(ctx, strlen(s) * 6);
adamc@117 308
adamc@106 309 for (; *s; s++) {
adamc@106 310 char c = *s;
adamc@106 311
adamc@106 312 if (c == '"')
adamc@117 313 lw_write_unsafe(ctx, "&quot;");
adamc@136 314 else if (c == '&')
adamc@136 315 lw_write_unsafe(ctx, "&amp;");
adamc@106 316 else if (isprint(c))
adamc@117 317 lw_writec_unsafe(ctx, c);
adamc@106 318 else {
adamc@117 319 lw_write_unsafe(ctx, "&#");
adamc@117 320 lw_Basis_attrifyInt_w_unsafe(ctx, c);
adamc@117 321 lw_writec_unsafe(ctx, ';');
adamc@106 322 }
adamc@106 323 }
adamc@106 324 }
adamc@120 325
adamc@120 326
adamc@137 327 char *lw_Basis_urlifyInt(lw_context ctx, lw_Basis_int n) {
adamc@137 328 int len;
adamc@137 329 char *r;
adamc@137 330
adamc@137 331 lw_check_heap(ctx, INTS_MAX);
adamc@137 332 r = ctx->heap_front;
adamc@276 333 sprintf(r, "%lld%n", n, &len);
adamc@137 334 ctx->heap_front += len+1;
adamc@137 335 return r;
adamc@120 336 }
adamc@120 337
adamc@137 338 char *lw_Basis_urlifyFloat(lw_context ctx, lw_Basis_float n) {
adamc@137 339 int len;
adamc@137 340 char *r;
adamc@137 341
adamc@137 342 lw_check_heap(ctx, FLOATS_MAX);
adamc@137 343 r = ctx->heap_front;
adamc@137 344 sprintf(r, "%g%n", n, &len);
adamc@137 345 ctx->heap_front += len+1;
adamc@137 346 return r;
adamc@120 347 }
adamc@120 348
adamc@137 349 char *lw_Basis_urlifyString(lw_context ctx, lw_Basis_string s) {
adamc@137 350 char *r, *p;
adamc@137 351
adamc@137 352 lw_check_heap(ctx, strlen(s) * 3 + 1);
adamc@137 353
adamc@137 354 for (r = p = ctx->heap_front; *s; s++) {
adamc@137 355 char c = *s;
adamc@137 356
adamc@137 357 if (c == ' ')
adamc@137 358 *p++ = '+';
adamc@137 359 else if (isalnum(c))
adamc@137 360 *p++ = c;
adamc@137 361 else {
adamc@137 362 sprintf(p, "%%%02X", c);
adamc@137 363 p += 3;
adamc@137 364 }
adamc@137 365 }
adamc@137 366
adamc@137 367 *p++ = 0;
adamc@137 368 ctx->heap_front = p;
adamc@137 369 return r;
adamc@120 370 }
adamc@120 371
adamc@186 372 char *lw_Basis_urlifyBool(lw_context ctx, lw_Basis_bool b) {
adamc@189 373 if (b == lw_Basis_False)
adamc@186 374 return "0";
adamc@186 375 else
adamc@186 376 return "1";
adamc@186 377 }
adamc@186 378
adamc@120 379 static void lw_Basis_urlifyInt_w_unsafe(lw_context ctx, lw_Basis_int n) {
adamc@120 380 int len;
adamc@120 381
adamc@276 382 sprintf(ctx->page_front, "%lld%n", n, &len);
adamc@120 383 ctx->page_front += len;
adamc@120 384 }
adamc@120 385
adamc@120 386 void lw_Basis_urlifyInt_w(lw_context ctx, lw_Basis_int n) {
adamc@120 387 lw_check(ctx, INTS_MAX);
adamc@120 388 lw_Basis_urlifyInt_w_unsafe(ctx, n);
adamc@120 389 }
adamc@120 390
adamc@120 391 void lw_Basis_urlifyFloat_w(lw_context ctx, lw_Basis_float n) {
adamc@120 392 int len;
adamc@120 393
adamc@120 394 lw_check(ctx, FLOATS_MAX);
adamc@120 395 sprintf(ctx->page_front, "%g%n", n, &len);
adamc@120 396 ctx->page_front += len;
adamc@120 397 }
adamc@120 398
adamc@120 399 void lw_Basis_urlifyString_w(lw_context ctx, lw_Basis_string s) {
adamc@120 400 lw_check(ctx, strlen(s) * 3);
adamc@120 401
adamc@120 402 for (; *s; s++) {
adamc@120 403 char c = *s;
adamc@120 404
adamc@120 405 if (c == ' ')
adamc@120 406 lw_writec_unsafe(ctx, '+');
adamc@120 407 else if (isalnum(c))
adamc@120 408 lw_writec_unsafe(ctx, c);
adamc@120 409 else {
adamc@120 410 sprintf(ctx->page_front, "%%%02X", c);
adamc@120 411 ctx->page_front += 3;
adamc@120 412 }
adamc@120 413 }
adamc@120 414 }
adamc@120 415
adamc@186 416 void lw_Basis_urlifyBool_w(lw_context ctx, lw_Basis_bool b) {
adamc@189 417 if (b == lw_Basis_False)
adamc@186 418 lw_writec(ctx, '0');
adamc@186 419 else
adamc@186 420 lw_writec(ctx, '1');
adamc@186 421 }
adamc@186 422
adamc@120 423
adamc@144 424 static char *lw_unurlify_advance(char *s) {
adamc@144 425 char *new_s = strchr(s, '/');
adamc@120 426
adamc@120 427 if (new_s)
adamc@120 428 *new_s++ = 0;
adamc@120 429 else
adamc@144 430 new_s = strchr(s, 0);
adamc@144 431
adamc@144 432 return new_s;
adamc@144 433 }
adamc@144 434
adamc@186 435 lw_Basis_int lw_Basis_unurlifyInt(lw_context ctx, char **s) {
adamc@144 436 char *new_s = lw_unurlify_advance(*s);
adamc@276 437 lw_Basis_int r;
adamc@120 438
adamc@276 439 r = atoll(*s);
adamc@120 440 *s = new_s;
adamc@120 441 return r;
adamc@120 442 }
adamc@120 443
adamc@186 444 lw_Basis_float lw_Basis_unurlifyFloat(lw_context ctx, char **s) {
adamc@144 445 char *new_s = lw_unurlify_advance(*s);
adamc@276 446 lw_Basis_float r;
adamc@120 447
adamc@120 448 r = atof(*s);
adamc@120 449 *s = new_s;
adamc@120 450 return r;
adamc@120 451 }
adamc@120 452
adamc@169 453 static lw_Basis_string lw_unurlifyString_to(lw_context ctx, char *r, char *s) {
adamc@144 454 char *s1, *s2;
adamc@144 455 int n;
adamc@136 456
adamc@144 457 for (s1 = r, s2 = s; *s2; ++s1, ++s2) {
adamc@136 458 char c = *s2;
adamc@136 459
adamc@136 460 switch (c) {
adamc@136 461 case '+':
adamc@136 462 *s1 = ' ';
adamc@136 463 break;
adamc@136 464 case '%':
adamc@169 465 if (s2[1] == 0)
adamc@169 466 lw_error(ctx, FATAL, "Missing first character of escaped URL byte");
adamc@169 467 if (s2[2] == 0)
adamc@169 468 lw_error(ctx, FATAL, "Missing second character of escaped URL byte");
adamc@169 469 if (sscanf(s2+1, "%02X", &n) != 1)
adamc@169 470 lw_error(ctx, FATAL, "Invalid escaped URL byte starting at: %s", s2);
adamc@136 471 *s1 = n;
adamc@136 472 s2 += 2;
adamc@136 473 break;
adamc@136 474 default:
adamc@136 475 *s1 = c;
adamc@136 476 }
adamc@136 477 }
adamc@136 478 *s1++ = 0;
adamc@144 479 return s1;
adamc@144 480 }
adamc@144 481
adamc@186 482 lw_Basis_bool lw_Basis_unurlifyBool(lw_context ctx, char **s) {
adamc@186 483 char *new_s = lw_unurlify_advance(*s);
adamc@186 484 lw_Basis_bool r;
adamc@186 485
adamc@186 486 if (*s[0] == 0 || !strcmp(*s, "0") || !strcmp(*s, "off"))
adamc@189 487 r = lw_Basis_False;
adamc@186 488 else
adamc@189 489 r = lw_Basis_True;
adamc@186 490
adamc@186 491 *s = new_s;
adamc@186 492 return r;
adamc@186 493 }
adamc@186 494
adamc@186 495 lw_Basis_string lw_Basis_unurlifyString(lw_context ctx, char **s) {
adamc@144 496 char *new_s = lw_unurlify_advance(*s);
adamc@144 497 char *r, *s1, *s2;
adamc@144 498 int len, n;
adamc@144 499
adamc@200 500 len = strlen(*s);
adamc@144 501 lw_check_heap(ctx, len + 1);
adamc@144 502
adamc@144 503 r = ctx->heap_front;
adamc@200 504 ctx->heap_front = lw_unurlifyString_to(ctx, ctx->heap_front, *s);
adamc@136 505 *s = new_s;
adamc@136 506 return r;
adamc@120 507 }
adamc@135 508
adamc@135 509
adamc@136 510 char *lw_Basis_htmlifyString(lw_context ctx, lw_Basis_string s) {
adamc@137 511 char *r, *s2;
adamc@137 512
adamc@137 513 lw_check_heap(ctx, strlen(s) * 5 + 1);
adamc@137 514
adamc@137 515 for (r = s2 = ctx->heap_front; *s; s++) {
adamc@137 516 char c = *s;
adamc@137 517
adamc@137 518 switch (c) {
adamc@137 519 case '<':
adamc@137 520 strcpy(s2, "&lt;");
adamc@137 521 s2 += 4;
adamc@137 522 break;
adamc@137 523 case '&':
adamc@137 524 strcpy(s2, "&amp;");
adamc@137 525 s2 += 5;
adamc@137 526 break;
adamc@137 527 default:
adamc@137 528 if (isprint(c))
adamc@137 529 *s2++ = c;
adamc@137 530 else {
adamc@137 531 int len2;
adamc@137 532 sprintf(s2, "&#%d;%n", c, &len2);
adamc@137 533 s2 += len2;
adamc@137 534 }
adamc@137 535 }
adamc@137 536 }
adamc@137 537
adamc@137 538 *s2++ = 0;
adamc@137 539 ctx->heap_front = s2;
adamc@137 540 return r;
adamc@135 541 }
adamc@135 542
adamc@135 543 void lw_Basis_htmlifyString_w(lw_context ctx, lw_Basis_string s) {
adamc@135 544 lw_check(ctx, strlen(s) * 5);
adamc@135 545
adamc@135 546 for (; *s; s++) {
adamc@135 547 char c = *s;
adamc@135 548
adamc@135 549 switch (c) {
adamc@135 550 case '<':
adamc@135 551 lw_write_unsafe(ctx, "&lt;");
adamc@135 552 break;
adamc@135 553 case '&':
adamc@135 554 lw_write_unsafe(ctx, "&amp;");
adamc@135 555 break;
adamc@135 556 default:
adamc@135 557 if (isprint(c))
adamc@135 558 lw_writec_unsafe(ctx, c);
adamc@135 559 else {
adamc@135 560 lw_write_unsafe(ctx, "&#");
adamc@135 561 lw_Basis_attrifyInt_w_unsafe(ctx, c);
adamc@135 562 lw_writec_unsafe(ctx, ';');
adamc@135 563 }
adamc@135 564 }
adamc@135 565 }
adamc@135 566 }
adamc@180 567
adamc@180 568 lw_Basis_string lw_Basis_strcat(lw_context ctx, lw_Basis_string s1, lw_Basis_string s2) {
adamc@180 569 int len = strlen(s1) + strlen(s2) + 1;
adamc@180 570 char *s;
adamc@180 571
adamc@183 572 lw_check_heap(ctx, len);
adamc@180 573
adamc@180 574 s = ctx->heap_front;
adamc@180 575
adamc@180 576 strcpy(s, s1);
adamc@180 577 strcat(s, s2);
adamc@180 578 ctx->heap_front += len;
adamc@180 579
adamc@180 580 return s;
adamc@180 581 }
adamc@278 582
adamc@278 583 lw_Basis_string lw_Basis_strdup(lw_context ctx, lw_Basis_string s1) {
adamc@278 584 int len = strlen(s1) + 1;
adamc@278 585 char *s;
adamc@278 586
adamc@278 587 lw_check_heap(ctx, len);
adamc@278 588
adamc@278 589 s = ctx->heap_front;
adamc@278 590
adamc@278 591 strcpy(s, s1);
adamc@278 592 ctx->heap_front += len;
adamc@278 593
adamc@278 594 return s;
adamc@278 595 }
adamc@280 596
adamc@280 597
adamc@281 598 char *lw_Basis_sqlifyInt(lw_context ctx, lw_Basis_int n) {
adamc@281 599 int len;
adamc@281 600 char *r;
adamc@281 601
adamc@281 602 lw_check_heap(ctx, INTS_MAX + 6);
adamc@281 603 r = ctx->heap_front;
adamc@281 604 sprintf(r, "%lld::int8%n", n, &len);
adamc@281 605 ctx->heap_front += len+1;
adamc@281 606 return r;
adamc@281 607 }
adamc@281 608
adamc@281 609 char *lw_Basis_sqlifyFloat(lw_context ctx, lw_Basis_float n) {
adamc@281 610 int len;
adamc@281 611 char *r;
adamc@281 612
adamc@281 613 lw_check_heap(ctx, FLOATS_MAX + 8);
adamc@281 614 r = ctx->heap_front;
adamc@281 615 sprintf(r, "%g::float8%n", n, &len);
adamc@281 616 ctx->heap_front += len+1;
adamc@281 617 return r;
adamc@281 618 }
adamc@281 619
adamc@281 620
adamc@280 621 lw_Basis_string lw_Basis_sqlifyString(lw_context ctx, lw_Basis_string s) {
adamc@280 622 char *r, *s2;
adamc@280 623
adamc@281 624 lw_check_heap(ctx, strlen(s) * 2 + 10);
adamc@280 625
adamc@280 626 r = s2 = ctx->heap_front;
adamc@280 627 *s2++ = 'E';
adamc@280 628 *s2++ = '\'';
adamc@280 629
adamc@280 630 for (; *s; s++) {
adamc@280 631 char c = *s;
adamc@280 632
adamc@280 633 switch (c) {
adamc@280 634 case '\'':
adamc@280 635 strcpy(s2, "\\'");
adamc@280 636 s2 += 2;
adamc@280 637 break;
adamc@280 638 case '\\':
adamc@280 639 strcpy(s2, "\\\\");
adamc@280 640 s2 += 2;
adamc@280 641 break;
adamc@280 642 default:
adamc@280 643 if (isprint(c))
adamc@280 644 *s2++ = c;
adamc@280 645 else {
adamc@280 646 sprintf(s2, "\\%3o", c);
adamc@280 647 s2 += 4;
adamc@280 648 }
adamc@280 649 }
adamc@280 650 }
adamc@280 651
adamc@281 652 strcpy(s2, "'::text");
adamc@281 653 ctx->heap_front = s2 + 8;
adamc@280 654 return r;
adamc@280 655 }
adamc@281 656
adamc@281 657 char *lw_Basis_sqlifyBool(lw_context ctx, lw_Basis_bool b) {
adamc@281 658 if (b == lw_Basis_False)
adamc@281 659 return "FALSE";
adamc@281 660 else
adamc@281 661 return "TRUE";
adamc@281 662 }
adamc@282 663
adamc@282 664 char *lw_Basis_ensqlBool(lw_Basis_bool b) {
adamc@282 665 static lw_Basis_int true = 1;
adamc@282 666 static lw_Basis_int false = 0;
adamc@282 667
adamc@282 668 if (b == lw_Basis_False)
adamc@282 669 return (char *)&false;
adamc@282 670 else
adamc@282 671 return (char *)&true;
adamc@282 672 }