annotate src/c/urweb.c @ 289:0cc956a3216f

Parsing strings for floats and bools
author Adam Chlipala <adamc@hcoop.net>
date Sun, 07 Sep 2008 11:41:04 -0400
parents 4260ad920c36
children 6e665c7c96f6
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@286 510 char *lw_Basis_htmlifyInt(lw_context ctx, lw_Basis_int n) {
adamc@286 511 int len;
adamc@286 512 char *r;
adamc@286 513
adamc@286 514 lw_check_heap(ctx, INTS_MAX);
adamc@286 515 r = ctx->heap_front;
adamc@286 516 sprintf(r, "%lld%n", n, &len);
adamc@286 517 ctx->heap_front += len+1;
adamc@286 518 return r;
adamc@286 519 }
adamc@286 520
adamc@286 521 void lw_Basis_htmlifyInt_w(lw_context ctx, lw_Basis_int n) {
adamc@286 522 int len;
adamc@286 523
adamc@286 524 lw_check(ctx, INTS_MAX);
adamc@286 525 sprintf(ctx->page_front, "%lld%n", n, &len);
adamc@286 526 ctx->page_front += len;
adamc@286 527 }
adamc@286 528
adamc@286 529 char *lw_Basis_htmlifyFloat(lw_context ctx, lw_Basis_float n) {
adamc@286 530 int len;
adamc@286 531 char *r;
adamc@286 532
adamc@286 533 lw_check_heap(ctx, FLOATS_MAX);
adamc@286 534 r = ctx->heap_front;
adamc@286 535 sprintf(r, "%g%n", n, &len);
adamc@286 536 ctx->heap_front += len+1;
adamc@286 537 return r;
adamc@286 538 }
adamc@286 539
adamc@286 540 void lw_Basis_htmlifyFloat_w(lw_context ctx, lw_Basis_float n) {
adamc@286 541 int len;
adamc@286 542
adamc@286 543 lw_check(ctx, FLOATS_MAX);
adamc@286 544 sprintf(ctx->page_front, "%g%n", n, &len);
adamc@286 545 ctx->page_front += len;
adamc@286 546 }
adamc@286 547
adamc@136 548 char *lw_Basis_htmlifyString(lw_context ctx, lw_Basis_string s) {
adamc@137 549 char *r, *s2;
adamc@137 550
adamc@137 551 lw_check_heap(ctx, strlen(s) * 5 + 1);
adamc@137 552
adamc@137 553 for (r = s2 = ctx->heap_front; *s; s++) {
adamc@137 554 char c = *s;
adamc@137 555
adamc@137 556 switch (c) {
adamc@137 557 case '<':
adamc@137 558 strcpy(s2, "&lt;");
adamc@137 559 s2 += 4;
adamc@137 560 break;
adamc@137 561 case '&':
adamc@137 562 strcpy(s2, "&amp;");
adamc@137 563 s2 += 5;
adamc@137 564 break;
adamc@137 565 default:
adamc@137 566 if (isprint(c))
adamc@137 567 *s2++ = c;
adamc@137 568 else {
adamc@137 569 int len2;
adamc@137 570 sprintf(s2, "&#%d;%n", c, &len2);
adamc@137 571 s2 += len2;
adamc@137 572 }
adamc@137 573 }
adamc@137 574 }
adamc@137 575
adamc@137 576 *s2++ = 0;
adamc@137 577 ctx->heap_front = s2;
adamc@137 578 return r;
adamc@135 579 }
adamc@135 580
adamc@135 581 void lw_Basis_htmlifyString_w(lw_context ctx, lw_Basis_string s) {
adamc@135 582 lw_check(ctx, strlen(s) * 5);
adamc@135 583
adamc@135 584 for (; *s; s++) {
adamc@135 585 char c = *s;
adamc@135 586
adamc@135 587 switch (c) {
adamc@135 588 case '<':
adamc@135 589 lw_write_unsafe(ctx, "&lt;");
adamc@135 590 break;
adamc@135 591 case '&':
adamc@135 592 lw_write_unsafe(ctx, "&amp;");
adamc@135 593 break;
adamc@135 594 default:
adamc@135 595 if (isprint(c))
adamc@135 596 lw_writec_unsafe(ctx, c);
adamc@135 597 else {
adamc@135 598 lw_write_unsafe(ctx, "&#");
adamc@135 599 lw_Basis_attrifyInt_w_unsafe(ctx, c);
adamc@135 600 lw_writec_unsafe(ctx, ';');
adamc@135 601 }
adamc@135 602 }
adamc@135 603 }
adamc@135 604 }
adamc@180 605
adamc@286 606 lw_Basis_string lw_Basis_htmlifyBool(lw_context ctx, lw_Basis_bool b) {
adamc@286 607 if (b == lw_Basis_False)
adamc@286 608 return "False";
adamc@286 609 else
adamc@286 610 return "True";
adamc@286 611 }
adamc@286 612
adamc@286 613 void lw_Basis_htmlifyBool_w(lw_context ctx, lw_Basis_bool b) {
adamc@286 614 if (b == lw_Basis_False) {
adamc@286 615 lw_check(ctx, 6);
adamc@286 616 strcpy(ctx->page_front, "False");
adamc@286 617 ctx->page_front += 5;
adamc@286 618 } else {
adamc@286 619 lw_check(ctx, 5);
adamc@286 620 strcpy(ctx->page_front, "True");
adamc@286 621 ctx->page_front += 4;
adamc@286 622 }
adamc@286 623 }
adamc@286 624
adamc@180 625 lw_Basis_string lw_Basis_strcat(lw_context ctx, lw_Basis_string s1, lw_Basis_string s2) {
adamc@180 626 int len = strlen(s1) + strlen(s2) + 1;
adamc@180 627 char *s;
adamc@180 628
adamc@183 629 lw_check_heap(ctx, len);
adamc@180 630
adamc@180 631 s = ctx->heap_front;
adamc@180 632
adamc@180 633 strcpy(s, s1);
adamc@180 634 strcat(s, s2);
adamc@180 635 ctx->heap_front += len;
adamc@180 636
adamc@180 637 return s;
adamc@180 638 }
adamc@278 639
adamc@278 640 lw_Basis_string lw_Basis_strdup(lw_context ctx, lw_Basis_string s1) {
adamc@278 641 int len = strlen(s1) + 1;
adamc@278 642 char *s;
adamc@278 643
adamc@278 644 lw_check_heap(ctx, len);
adamc@278 645
adamc@278 646 s = ctx->heap_front;
adamc@278 647
adamc@278 648 strcpy(s, s1);
adamc@278 649 ctx->heap_front += len;
adamc@278 650
adamc@278 651 return s;
adamc@278 652 }
adamc@280 653
adamc@280 654
adamc@281 655 char *lw_Basis_sqlifyInt(lw_context ctx, lw_Basis_int n) {
adamc@281 656 int len;
adamc@281 657 char *r;
adamc@281 658
adamc@281 659 lw_check_heap(ctx, INTS_MAX + 6);
adamc@281 660 r = ctx->heap_front;
adamc@281 661 sprintf(r, "%lld::int8%n", n, &len);
adamc@281 662 ctx->heap_front += len+1;
adamc@281 663 return r;
adamc@281 664 }
adamc@281 665
adamc@281 666 char *lw_Basis_sqlifyFloat(lw_context ctx, lw_Basis_float n) {
adamc@281 667 int len;
adamc@281 668 char *r;
adamc@281 669
adamc@281 670 lw_check_heap(ctx, FLOATS_MAX + 8);
adamc@281 671 r = ctx->heap_front;
adamc@281 672 sprintf(r, "%g::float8%n", n, &len);
adamc@281 673 ctx->heap_front += len+1;
adamc@281 674 return r;
adamc@281 675 }
adamc@281 676
adamc@281 677
adamc@280 678 lw_Basis_string lw_Basis_sqlifyString(lw_context ctx, lw_Basis_string s) {
adamc@280 679 char *r, *s2;
adamc@280 680
adamc@281 681 lw_check_heap(ctx, strlen(s) * 2 + 10);
adamc@280 682
adamc@280 683 r = s2 = ctx->heap_front;
adamc@280 684 *s2++ = 'E';
adamc@280 685 *s2++ = '\'';
adamc@280 686
adamc@280 687 for (; *s; s++) {
adamc@280 688 char c = *s;
adamc@280 689
adamc@280 690 switch (c) {
adamc@280 691 case '\'':
adamc@280 692 strcpy(s2, "\\'");
adamc@280 693 s2 += 2;
adamc@280 694 break;
adamc@280 695 case '\\':
adamc@280 696 strcpy(s2, "\\\\");
adamc@280 697 s2 += 2;
adamc@280 698 break;
adamc@280 699 default:
adamc@280 700 if (isprint(c))
adamc@280 701 *s2++ = c;
adamc@280 702 else {
adamc@280 703 sprintf(s2, "\\%3o", c);
adamc@280 704 s2 += 4;
adamc@280 705 }
adamc@280 706 }
adamc@280 707 }
adamc@280 708
adamc@281 709 strcpy(s2, "'::text");
adamc@281 710 ctx->heap_front = s2 + 8;
adamc@280 711 return r;
adamc@280 712 }
adamc@281 713
adamc@281 714 char *lw_Basis_sqlifyBool(lw_context ctx, lw_Basis_bool b) {
adamc@281 715 if (b == lw_Basis_False)
adamc@281 716 return "FALSE";
adamc@281 717 else
adamc@281 718 return "TRUE";
adamc@281 719 }
adamc@282 720
adamc@282 721 char *lw_Basis_ensqlBool(lw_Basis_bool b) {
adamc@282 722 static lw_Basis_int true = 1;
adamc@282 723 static lw_Basis_int false = 0;
adamc@282 724
adamc@282 725 if (b == lw_Basis_False)
adamc@282 726 return (char *)&false;
adamc@282 727 else
adamc@282 728 return (char *)&true;
adamc@282 729 }
adamc@284 730
adamc@284 731 lw_Basis_string lw_Basis_intToString(lw_context ctx, lw_Basis_int n) {
adamc@284 732 int len;
adamc@284 733 char *r;
adamc@284 734
adamc@284 735 lw_check_heap(ctx, INTS_MAX);
adamc@284 736 r = ctx->heap_front;
adamc@284 737 sprintf(r, "%lld%n", n, &len);
adamc@284 738 ctx->heap_front += len+1;
adamc@284 739 return r;
adamc@284 740 }
adamc@285 741
adamc@285 742 lw_Basis_string lw_Basis_floatToString(lw_context ctx, lw_Basis_float n) {
adamc@285 743 int len;
adamc@285 744 char *r;
adamc@285 745
adamc@285 746 lw_check_heap(ctx, FLOATS_MAX);
adamc@285 747 r = ctx->heap_front;
adamc@285 748 sprintf(r, "%g%n", n, &len);
adamc@285 749 ctx->heap_front += len+1;
adamc@285 750 return r;
adamc@285 751 }
adamc@285 752
adamc@285 753 lw_Basis_string lw_Basis_boolToString(lw_context ctx, lw_Basis_bool b) {
adamc@285 754 if (b == lw_Basis_False)
adamc@285 755 return "False";
adamc@285 756 else
adamc@285 757 return "True";
adamc@285 758 }
adamc@288 759
adamc@288 760
adamc@288 761 lw_Basis_int *lw_Basis_stringToInt(lw_context ctx, lw_Basis_string s) {
adamc@288 762 char *endptr;
adamc@288 763 lw_Basis_int n = strtoll(s, &endptr, 10);
adamc@288 764
adamc@288 765 if (*s != '\0' && *endptr == '\0') {
adamc@288 766 lw_Basis_int *r = lw_malloc(ctx, sizeof(lw_Basis_int));
adamc@288 767 *r = n;
adamc@288 768 return r;
adamc@288 769 } else
adamc@288 770 return NULL;
adamc@288 771 }
adamc@289 772
adamc@289 773 lw_Basis_float *lw_Basis_stringToFloat(lw_context ctx, lw_Basis_string s) {
adamc@289 774 char *endptr;
adamc@289 775 lw_Basis_float n = strtod(s, &endptr);
adamc@289 776
adamc@289 777 if (*s != '\0' && *endptr == '\0') {
adamc@289 778 lw_Basis_float *r = lw_malloc(ctx, sizeof(lw_Basis_float));
adamc@289 779 *r = n;
adamc@289 780 return r;
adamc@289 781 } else
adamc@289 782 return NULL;
adamc@289 783 }
adamc@289 784
adamc@289 785 lw_Basis_bool *lw_Basis_stringToBool(lw_context ctx, lw_Basis_string s) {
adamc@289 786 static lw_Basis_bool true = lw_Basis_True;
adamc@289 787 static lw_Basis_bool false = lw_Basis_False;
adamc@289 788
adamc@289 789 if (!strcasecmp (s, "True"))
adamc@289 790 return &true;
adamc@289 791 else if (!strcasecmp (s, "False"))
adamc@289 792 return &false;
adamc@289 793 else
adamc@289 794 return NULL;
adamc@289 795 }