Change the magic number used to introduce a trie file, so that instead
[sgt/agedu] / alloc.c
1 /*
2 * alloc.c: implementation of alloc.h
3 */
4
5 #include "agedu.h"
6 #include "alloc.h"
7
8 extern void fatal(const char *, ...);
9
10 void *smalloc(size_t size) {
11 void *p;
12 p = malloc(size);
13 if (!p) {
14 fatal("out of memory");
15 }
16 return p;
17 }
18
19 void sfree(void *p) {
20 if (p) {
21 free(p);
22 }
23 }
24
25 void *srealloc(void *p, size_t size) {
26 void *q;
27 if (p) {
28 q = realloc(p, size);
29 } else {
30 q = malloc(size);
31 }
32 if (!q)
33 fatal("out of memory");
34 return q;
35 }
36
37 char *dupstr(const char *s) {
38 char *r = smalloc(1+strlen(s));
39 strcpy(r,s);
40 return r;
41 }
42
43 char *dupfmt(const char *fmt, ...)
44 {
45 int pass;
46 int totallen;
47 char *ret = NULL, *rp = NULL;
48 char datebuf[80];
49 va_list ap;
50 time_t t;
51 struct tm tm;
52 int got_time = 0;
53
54 datebuf[0] = '\0';
55 totallen = 0;
56
57 for (pass = 0; pass < 2; pass++) {
58 const char *p = fmt;
59
60 va_start(ap, fmt);
61
62 while (*p) {
63 const char *data = NULL;
64 int datalen = 0, stuffcr = 0, htmlesc = 0;
65
66 if (*p == '%') {
67 p++;
68 if (*p == 'D') {
69 if (!datebuf[0]) {
70 if (!got_time) {
71 t = time(NULL);
72 tm = *gmtime(&t);
73 got_time = 1;
74 }
75 strftime(datebuf, lenof(datebuf),
76 "%a, %d %b %Y %H:%M:%S GMT", &tm);
77 }
78 data = datebuf;
79 datalen = strlen(data);
80 } else if (*p == 'd') {
81 int i = va_arg(ap, int);
82 sprintf(datebuf, "%d", i);
83 data = datebuf;
84 datalen = strlen(data);
85 } else if (*p == 's') {
86 data = va_arg(ap, const char *);
87 datalen = strlen(data);
88 } else if (*p == 'h') {
89 htmlesc = 1;
90 data = va_arg(ap, const char *);
91 datalen = strlen(data);
92 } else if (assert(*p == 'S'), 1) {
93 stuffcr = va_arg(ap, int);
94 data = va_arg(ap, const char *);
95 datalen = strlen(data);
96 }
97 p++;
98 } else {
99 data = p;
100 while (*p && *p != '%') p++;
101 datalen = p - data;
102 }
103
104 if (pass == 0) {
105 while (datalen > 0) {
106 totallen++;
107 if (stuffcr && *data == '\n')
108 totallen++;
109 if (htmlesc &&
110 (*data == '<' || *data == '>' || *data == '&'))
111 totallen += 4; /* max(len("gt;"),len("amp;")) */
112 data++, datalen--;
113 }
114 } else {
115 while (datalen > 0) {
116 if (htmlesc && (*data < 32 || *data >= 127))
117 *rp++ = '?'; /* *shrug* */
118 else if (htmlesc && *data == '<')
119 rp += sprintf(rp, "&lt;");
120 else if (htmlesc && *data == '>')
121 rp += sprintf(rp, "&gt;");
122 else if (htmlesc && *data == '&')
123 rp += sprintf(rp, "&amp;");
124 else if (stuffcr && *data == '\n')
125 *rp++ = '\r', *rp++ = '\n';
126 else
127 *rp++ = *data;
128 data++, datalen--;
129 }
130 }
131 }
132
133 va_end(ap);
134
135 if (pass == 0) {
136 rp = ret = snewn(totallen+1, char);
137 } else {
138 assert(rp - ret == totallen);
139 *rp = '\0';
140 }
141 }
142
143 return ret;
144 }