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