1 /*    util.c
2  *
3  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999,
4  *    2000, 2001, by Larry Wall and others
5  *
6  *    You may distribute under the terms of either the GNU General Public
7  *    License or the Artistic License, as specified in the README file.
8  */
9 
10 #include "EXTERN.h"
11 #include "a2p.h"
12 #include "INTERN.h"
13 #include "util.h"
14 
15 #include <stdarg.h>
16 #define FLUSH
17 
18 static const char nomem[] = "Out of memory!\n";
19 
20 /* paranoid version of malloc */
21 
22 
23 Malloc_t
safemalloc(MEM_SIZE size)24 safemalloc(MEM_SIZE size)
25 {
26     Malloc_t ptr;
27 
28     /* malloc(0) is NASTY on some systems */
29     ptr = malloc(size ? size : 1);
30 #ifdef DEBUGGING
31     if (debug & 128)
32 	fprintf(stderr,"0x%lx: (%05d) malloc %ld bytes\n",(unsigned long)ptr,
33     	    	an++,(long)size);
34 #endif
35     if (ptr != Nullch)
36 	return ptr;
37     else {
38 	fputs(nomem,stdout) FLUSH;
39 	exit(1);
40     }
41     /*NOTREACHED*/
42     return 0;
43 }
44 
45 /* paranoid version of realloc */
46 
47 Malloc_t
saferealloc(Malloc_t where,MEM_SIZE size)48 saferealloc(Malloc_t where, MEM_SIZE size)
49 {
50     Malloc_t ptr;
51 
52     /* realloc(0) is NASTY on some systems */
53     ptr = realloc(where, size ? size : 1);
54 #ifdef DEBUGGING
55     if (debug & 128) {
56 	fprintf(stderr,"0x%lx: (%05d) rfree\n",(unsigned long)where,an++);
57 	fprintf(stderr,"0x%lx: (%05d) realloc %ld bytes\n",(unsigned long)ptr,an++,(long)size);
58     }
59 #endif
60     if (ptr != Nullch)
61 	return ptr;
62     else {
63 	fputs(nomem,stdout) FLUSH;
64 	exit(1);
65     }
66     /*NOTREACHED*/
67     return 0;
68 }
69 
70 /* safe version of free */
71 
72 Free_t
safefree(Malloc_t where)73 safefree(Malloc_t where)
74 {
75 #ifdef DEBUGGING
76     if (debug & 128)
77 	fprintf(stderr,"0x%lx: (%05d) free\n",(unsigned long)where,an++);
78 #endif
79     free(where);
80 }
81 
82 /* copy a string up to some (non-backslashed) delimiter, if any */
83 
84 char *
cpytill(register char * to,register char * from,register int delim)85 cpytill(register char *to, register char *from, register int delim)
86 {
87     for (; *from; from++,to++) {
88 	if (*from == '\\') {
89 	    if (from[1] == delim)
90 		from++;
91 	    else if (from[1] == '\\')
92 		*to++ = *from++;
93 	}
94 	else if (*from == delim)
95 	    break;
96 	*to = *from;
97     }
98     *to = '\0';
99     return from;
100 }
101 
102 
103 char *
cpy2(register char * to,register char * from,register int delim)104 cpy2(register char *to, register char *from, register int delim)
105 {
106     for (; *from; from++,to++) {
107 	if (*from == '\\')
108 	    *to++ = *from++;
109 	else if (*from == '$')
110 	    *to++ = '\\';
111 	else if (*from == delim)
112 	    break;
113 	*to = *from;
114     }
115     *to = '\0';
116     return from;
117 }
118 
119 /* return ptr to little string in big string, NULL if not found */
120 
121 char *
instr(char * big,char * little)122 instr(char *big, char *little)
123 {
124     register char *t, *s, *x;
125 
126     for (t = big; *t; t++) {
127 	for (x=t,s=little; *s; x++,s++) {
128 	    if (!*x)
129 		return Nullch;
130 	    if (*s != *x)
131 		break;
132 	}
133 	if (!*s)
134 	    return t;
135     }
136     return Nullch;
137 }
138 
139 /* copy a string to a safe spot */
140 
141 char *
savestr(char * str)142 savestr(char *str)
143 {
144     register char * const newaddr = (char *) safemalloc((MEM_SIZE)(strlen(str)+1));
145 
146     (void)strcpy(newaddr,str);
147     return newaddr;
148 }
149 
150 /* grow a static string to at least a certain length */
151 
152 void
growstr(char ** strptr,int * curlen,int newlen)153 growstr(char **strptr, int *curlen, int newlen)
154 {
155     if (newlen > *curlen) {		/* need more room? */
156 	if (*curlen)
157 	    *strptr = (char *) saferealloc(*strptr,(MEM_SIZE)newlen);
158 	else
159 	    *strptr = (char *) safemalloc((MEM_SIZE)newlen);
160 	*curlen = newlen;
161     }
162 }
163 
164 void
fatal(const char * pat,...)165 fatal(const char *pat,...)
166 {
167 #if defined(HAS_VPRINTF)
168     va_list args;
169 
170     va_start(args, pat);
171     vfprintf(stderr,pat,args);
172     va_end(args);
173 #else
174     fprintf(stderr,pat,a1,a2,a3,a4);
175 #endif
176     exit(1);
177 }
178 
179 #if defined(DARWIN)
180 __private_extern__	/* warn() conflicts with libc */
181 #endif
182 void
warn(const char * pat,...)183 warn(const char *pat,...)
184 {
185 #if defined(HAS_VPRINTF)
186     va_list args;
187 
188     va_start(args, pat);
189     vfprintf(stderr,pat,args);
190     va_end(args);
191 #else
192     fprintf(stderr,pat,a1,a2,a3,a4);
193 #endif
194 }
195 
196