Add an error check for correct formatting in Deflate uncompressed
[sgt/halibut] / malloc.c
1 /*
2 * malloc.c: safe wrappers around malloc, realloc, free, strdup
3 */
4
5 #include <stdlib.h>
6 #include <stdarg.h>
7 #include "halibut.h"
8
9 #ifdef LOGALLOC
10 #define LOGPARAMS char *file, int line,
11 static FILE *logallocfp = NULL;
12 static int logline = 2; /* off by 1: `null pointer is' */
13 static void loginc(void) { }
14 static void logallocinit(void) {
15 if (!logallocfp) {
16 logallocfp = fopen("malloc.log", "w");
17 if (!logallocfp) {
18 fprintf(stderr, "panic: unable to open malloc.log\n");
19 exit(10);
20 }
21 setvbuf (logallocfp, NULL, _IOLBF, BUFSIZ);
22 fprintf(logallocfp, "null pointer is %p\n", NULL);
23 }
24 }
25 static void logprintf(char *fmt, ...) {
26 va_list ap;
27 va_start(ap, fmt);
28 vfprintf(logallocfp, fmt, ap);
29 va_end(ap);
30 }
31 #define LOGPRINT(x) ( logallocinit(), logprintf x )
32 #define LOGINC do { loginc(); logline++; } while (0)
33 #else
34 #define LOGPARAMS
35 #define LOGPRINT(x)
36 #define LOGINC ((void)0)
37 #endif
38
39 /*
40 * smalloc should guarantee to return a useful pointer - Halibut
41 * can do nothing except die when it's out of memory anyway.
42 */
43 void *(smalloc)(LOGPARAMS int size) {
44 void *p;
45 LOGINC;
46 LOGPRINT(("%s %d malloc(%ld)",
47 file, line, (long)size));
48 p = malloc(size);
49 if (!p)
50 fatal(err_nomemory);
51 LOGPRINT((" returns %p\n", p));
52 return p;
53 }
54
55 /*
56 * sfree should guaranteeably deal gracefully with freeing NULL
57 */
58 void (sfree)(LOGPARAMS void *p) {
59 if (p) {
60 LOGINC;
61 LOGPRINT(("%s %d free(%p)\n",
62 file, line, p));
63 free(p);
64 }
65 }
66
67 /*
68 * srealloc should guaranteeably be able to realloc NULL
69 */
70 void *(srealloc)(LOGPARAMS void *p, int size) {
71 void *q;
72 if (p) {
73 LOGINC;
74 LOGPRINT(("%s %d realloc(%p,%ld)",
75 file, line, p, (long)size));
76 q = realloc(p, size);
77 LOGPRINT((" returns %p\n", q));
78 } else {
79 LOGINC;
80 LOGPRINT(("%s %d malloc(%ld)",
81 file, line, (long)size));
82 q = malloc(size);
83 LOGPRINT((" returns %p\n", q));
84 }
85 if (!q)
86 fatal(err_nomemory);
87 return q;
88 }
89
90 /*
91 * dupstr is like strdup, but with the never-return-NULL property
92 * of smalloc (and also reliably defined in all environments :-)
93 */
94 char *dupstr(char const *s) {
95 char *r = smalloc(1+strlen(s));
96 strcpy(r,s);
97 return r;
98 }
99
100 /*
101 * Duplicate a linked list of words
102 */
103 word *dup_word_list(word *w) {
104 word *head = NULL, **eptr = &head;
105
106 while (w) {
107 word *newwd = snew(word);
108 *newwd = *w; /* structure copy */
109 newwd->text = ustrdup(w->text);
110 if (w->alt)
111 newwd->alt = dup_word_list(w->alt);
112 *eptr = newwd;
113 newwd->next = NULL;
114 eptr = &newwd->next;
115
116 w = w->next;
117 }
118
119 return head;
120 }
121
122 /*
123 * Free a linked list of words
124 */
125 void free_word_list(word *w) {
126 word *t;
127 while (w) {
128 t = w;
129 w = w->next;
130 sfree(t->text);
131 if (t->alt)
132 free_word_list(t->alt);
133 sfree(t);
134 }
135 }
136
137 /*
138 * Free a linked list of paragraphs
139 */
140 void free_para_list(paragraph *p) {
141 paragraph *t;
142 while (p) {
143 t = p;
144 p = p->next;
145 sfree(t->keyword);
146 free_word_list(t->words);
147 sfree(t);
148 }
149 }