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