Mercurial > urweb
comparison src/c/lacweb.c @ 167:2be573fec9a6
Unurlifying a datatype; longjmp-based error signaling mechanism
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 29 Jul 2008 15:25:42 -0400 |
parents | f0d3402184d1 |
children | 2232ab355f66 |
comparison
equal
deleted
inserted
replaced
166:a991431b77eb | 167:2be573fec9a6 |
---|---|
1 #include <stdlib.h> | 1 #include <stdlib.h> |
2 #include <stdio.h> | 2 #include <stdio.h> |
3 #include <string.h> | 3 #include <string.h> |
4 #include <ctype.h> | 4 #include <ctype.h> |
5 #include <assert.h> | 5 #include <assert.h> |
6 #include <setjmp.h> | |
7 #include <stdarg.h> | |
6 | 8 |
7 #include "types.h" | 9 #include "types.h" |
8 | 10 |
9 lw_unit lw_unit_v = {}; | 11 lw_unit lw_unit_v = {}; |
12 | |
13 #define ERROR_BUF_LEN 1024 | |
10 | 14 |
11 struct lw_context { | 15 struct lw_context { |
12 char *page, *page_front, *page_back; | 16 char *page, *page_front, *page_back; |
13 char *heap, *heap_front, *heap_back; | 17 char *heap, *heap_front, *heap_back; |
14 char **inputs; | 18 char **inputs; |
19 | |
20 jmp_buf jmp_buf; | |
21 | |
22 failure_kind failure_kind; | |
23 char error_message[ERROR_BUF_LEN]; | |
15 }; | 24 }; |
16 | 25 |
17 extern int lw_inputs_len; | 26 extern int lw_inputs_len; |
18 | 27 |
19 lw_context lw_init(size_t page_len, size_t heap_len) { | 28 lw_context lw_init(size_t page_len, size_t heap_len) { |
24 | 33 |
25 ctx->heap_front = ctx->heap = malloc(heap_len); | 34 ctx->heap_front = ctx->heap = malloc(heap_len); |
26 ctx->heap_back = ctx->heap_front + heap_len; | 35 ctx->heap_back = ctx->heap_front + heap_len; |
27 | 36 |
28 ctx->inputs = calloc(lw_inputs_len, sizeof(char *)); | 37 ctx->inputs = calloc(lw_inputs_len, sizeof(char *)); |
38 | |
39 ctx->failure_kind = SUCCESS; | |
40 ctx->error_message[0] = 0; | |
29 | 41 |
30 return ctx; | 42 return ctx; |
31 } | 43 } |
32 | 44 |
33 void lw_free(lw_context ctx) { | 45 void lw_free(lw_context ctx) { |
35 free(ctx->heap); | 47 free(ctx->heap); |
36 free(ctx->inputs); | 48 free(ctx->inputs); |
37 free(ctx); | 49 free(ctx); |
38 } | 50 } |
39 | 51 |
40 void lw_reset(lw_context ctx) { | 52 void lw_reset_keep_request(lw_context ctx) { |
41 ctx->page_front = ctx->page; | 53 ctx->page_front = ctx->page; |
42 ctx->heap_front = ctx->heap; | 54 ctx->heap_front = ctx->heap; |
55 | |
56 ctx->failure_kind = SUCCESS; | |
57 ctx->error_message[0] = 0; | |
58 } | |
59 | |
60 void lw_reset_keep_error_message(lw_context ctx) { | |
61 ctx->page_front = ctx->page; | |
62 ctx->heap_front = ctx->heap; | |
63 | |
64 ctx->failure_kind = SUCCESS; | |
65 } | |
66 | |
67 void lw_reset(lw_context ctx) { | |
68 lw_reset_keep_request(ctx); | |
43 memset(ctx->inputs, 0, lw_inputs_len * sizeof(char *)); | 69 memset(ctx->inputs, 0, lw_inputs_len * sizeof(char *)); |
70 } | |
71 | |
72 void lw_handle(lw_context, char *); | |
73 | |
74 failure_kind lw_begin(lw_context ctx, char *path) { | |
75 if (!setjmp(ctx->jmp_buf)) | |
76 lw_handle(ctx, path); | |
77 | |
78 return ctx->failure_kind; | |
79 } | |
80 | |
81 void lw_error(lw_context ctx, failure_kind fk, const char *fmt, ...) { | |
82 va_list ap; | |
83 va_start(ap, fmt); | |
84 | |
85 ctx->failure_kind = fk; | |
86 vsnprintf(ctx->error_message, ERROR_BUF_LEN, fmt, ap); | |
87 | |
88 longjmp(ctx->jmp_buf, 1); | |
89 } | |
90 | |
91 char *lw_error_message(lw_context ctx) { | |
92 return ctx->error_message; | |
44 } | 93 } |
45 | 94 |
46 int lw_input_num(char*); | 95 int lw_input_num(char*); |
47 | 96 |
48 void lw_set_input(lw_context ctx, char *name, char *value) { | 97 void lw_set_input(lw_context ctx, char *name, char *value) { |