1/* $RCSfile: util.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:29 $
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 * $Log:	util.c,v $
10 */
11
12#include "EXTERN.h"
13#include "a2p.h"
14#include "INTERN.h"
15#include "util.h"
16
17#include <stdarg.h>
18#define FLUSH
19
20static char nomem[] = "Out of memory!\n";
21
22/* paranoid version of malloc */
23
24
25Malloc_t
26safemalloc(MEM_SIZE size)
27{
28    Malloc_t ptr;
29
30    /* malloc(0) is NASTY on some systems */
31    ptr = malloc(size ? size : 1);
32#ifdef DEBUGGING
33    if (debug & 128)
34	fprintf(stderr,"0x%lx: (%05d) malloc %ld bytes\n",(unsigned long)ptr,
35    	    	an++,(long)size);
36#endif
37    if (ptr != Nullch)
38	return ptr;
39    else {
40	fputs(nomem,stdout) FLUSH;
41	exit(1);
42    }
43    /*NOTREACHED*/
44    return 0;
45}
46
47/* paranoid version of realloc */
48
49Malloc_t
50saferealloc(Malloc_t where, MEM_SIZE size)
51{
52    Malloc_t ptr;
53
54    /* realloc(0) is NASTY on some systems */
55    ptr = realloc(where, size ? size : 1);
56#ifdef DEBUGGING
57    if (debug & 128) {
58	fprintf(stderr,"0x%lx: (%05d) rfree\n",(unsigned long)where,an++);
59	fprintf(stderr,"0x%lx: (%05d) realloc %ld bytes\n",(unsigned long)ptr,an++,(long)size);
60    }
61#endif
62    if (ptr != Nullch)
63	return ptr;
64    else {
65	fputs(nomem,stdout) FLUSH;
66	exit(1);
67    }
68    /*NOTREACHED*/
69    return 0;
70}
71
72/* safe version of free */
73
74Free_t
75safefree(Malloc_t where)
76{
77#ifdef DEBUGGING
78    if (debug & 128)
79	fprintf(stderr,"0x%lx: (%05d) free\n",(unsigned long)where,an++);
80#endif
81    free(where);
82}
83
84/* safe version of string copy */
85
86char *
87safecpy(char *to, register char *from, register int len)
88{
89    register char *dest = to;
90
91    if (from != Nullch)
92	for (len--; len && (*dest++ = *from++); len--) ;
93    *dest = '\0';
94    return to;
95}
96
97/* copy a string up to some (non-backslashed) delimiter, if any */
98
99char *
100cpytill(register char *to, register char *from, register int delim)
101{
102    for (; *from; from++,to++) {
103	if (*from == '\\') {
104	    if (from[1] == delim)
105		from++;
106	    else if (from[1] == '\\')
107		*to++ = *from++;
108	}
109	else if (*from == delim)
110	    break;
111	*to = *from;
112    }
113    *to = '\0';
114    return from;
115}
116
117
118char *
119cpy2(register char *to, register char *from, register int delim)
120{
121    for (; *from; from++,to++) {
122	if (*from == '\\')
123	    *to++ = *from++;
124	else if (*from == '$')
125	    *to++ = '\\';
126	else if (*from == delim)
127	    break;
128	*to = *from;
129    }
130    *to = '\0';
131    return from;
132}
133
134/* return ptr to little string in big string, NULL if not found */
135
136char *
137instr(char *big, char *little)
138{
139    register char *t, *s, *x;
140
141    for (t = big; *t; t++) {
142	for (x=t,s=little; *s; x++,s++) {
143	    if (!*x)
144		return Nullch;
145	    if (*s != *x)
146		break;
147	}
148	if (!*s)
149	    return t;
150    }
151    return Nullch;
152}
153
154/* copy a string to a safe spot */
155
156char *
157savestr(char *str)
158{
159    register char *newaddr = (char *) safemalloc((MEM_SIZE)(strlen(str)+1));
160
161    (void)strcpy(newaddr,str);
162    return newaddr;
163}
164
165/* grow a static string to at least a certain length */
166
167void
168growstr(char **strptr, int *curlen, int newlen)
169{
170    if (newlen > *curlen) {		/* need more room? */
171	if (*curlen)
172	    *strptr = (char *) saferealloc(*strptr,(MEM_SIZE)newlen);
173	else
174	    *strptr = (char *) safemalloc((MEM_SIZE)newlen);
175	*curlen = newlen;
176    }
177}
178
179void
180croak(char *pat,...)
181{
182#if defined(HAS_VPRINTF)
183    va_list args;
184
185    va_start(args, pat);
186    vfprintf(stderr,pat,args);
187    va_end(args);
188#else
189    fprintf(stderr,pat,a1,a2,a3,a4);
190#endif
191    exit(1);
192}
193
194void
195fatal(char *pat,...)
196{
197#if defined(HAS_VPRINTF)
198    va_list args;
199
200    va_start(args, pat);
201    vfprintf(stderr,pat,args);
202    va_end(args);
203#else
204    fprintf(stderr,pat,a1,a2,a3,a4);
205#endif
206    exit(1);
207}
208
209#if defined(DARWIN)
210__private_extern__	/* warn() conflicts with libc */
211#endif
212void
213warn(char *pat,...)
214{
215#if defined(HAS_VPRINTF)
216    va_list args;
217
218    va_start(args, pat);
219    vfprintf(stderr,pat,args);
220    va_end(args);
221#else
222    fprintf(stderr,pat,a1,a2,a3,a4);
223#endif
224}
225
226