perl 3.0: (no announcement message available)
[p5sagit/p5-mst-13.2.git] / x2p / util.c
1 /* $Header: util.c,v 3.0 89/10/18 15:35:35 lwall Locked $
2  *
3  *    Copyright (c) 1989, Larry Wall
4  *
5  *    You may distribute under the terms of the GNU General Public License
6  *    as specified in the README file that comes with the perl 3.0 kit.
7  *
8  * $Log:        util.c,v $
9  * Revision 3.0  89/10/18  15:35:35  lwall
10  * 3.0 baseline
11  * 
12  */
13
14 #include <stdio.h>
15
16 #include "handy.h"
17 #include "EXTERN.h"
18 #include "a2p.h"
19 #include "INTERN.h"
20 #include "util.h"
21
22 #define FLUSH
23 #define MEM_SIZE unsigned int
24
25 static char nomem[] = "Out of memory!\n";
26
27 /* paranoid version of malloc */
28
29 static int an = 0;
30
31 char *
32 safemalloc(size)
33 MEM_SIZE size;
34 {
35     char *ptr;
36     char *malloc();
37
38     ptr = malloc(size?size:1);  /* malloc(0) is NASTY on our system */
39 #ifdef DEBUGGING
40     if (debug & 128)
41         fprintf(stderr,"0x%x: (%05d) malloc %d bytes\n",ptr,an++,size);
42 #endif
43     if (ptr != Nullch)
44         return ptr;
45     else {
46         fputs(nomem,stdout) FLUSH;
47         exit(1);
48     }
49     /*NOTREACHED*/
50 }
51
52 /* paranoid version of realloc */
53
54 char *
55 saferealloc(where,size)
56 char *where;
57 MEM_SIZE size;
58 {
59     char *ptr;
60     char *realloc();
61
62     ptr = realloc(where,size?size:1);   /* realloc(0) is NASTY on our system */
63 #ifdef DEBUGGING
64     if (debug & 128) {
65         fprintf(stderr,"0x%x: (%05d) rfree\n",where,an++);
66         fprintf(stderr,"0x%x: (%05d) realloc %d bytes\n",ptr,an++,size);
67     }
68 #endif
69     if (ptr != Nullch)
70         return ptr;
71     else {
72         fputs(nomem,stdout) FLUSH;
73         exit(1);
74     }
75     /*NOTREACHED*/
76 }
77
78 /* safe version of free */
79
80 safefree(where)
81 char *where;
82 {
83 #ifdef DEBUGGING
84     if (debug & 128)
85         fprintf(stderr,"0x%x: (%05d) free\n",where,an++);
86 #endif
87     free(where);
88 }
89
90 /* safe version of string copy */
91
92 char *
93 safecpy(to,from,len)
94 char *to;
95 register char *from;
96 register int len;
97 {
98     register char *dest = to;
99
100     if (from != Nullch) 
101         for (len--; len && (*dest++ = *from++); len--) ;
102     *dest = '\0';
103     return to;
104 }
105
106 #ifdef undef
107 /* safe version of string concatenate, with \n deletion and space padding */
108
109 char *
110 safecat(to,from,len)
111 char *to;
112 register char *from;
113 register int len;
114 {
115     register char *dest = to;
116
117     len--;                              /* leave room for null */
118     if (*dest) {
119         while (len && *dest++) len--;
120         if (len) {
121             len--;
122             *(dest-1) = ' ';
123         }
124     }
125     if (from != Nullch)
126         while (len && (*dest++ = *from++)) len--;
127     if (len)
128         dest--;
129     if (*(dest-1) == '\n')
130         dest--;
131     *dest = '\0';
132     return to;
133 }
134 #endif
135
136 /* copy a string up to some (non-backslashed) delimiter, if any */
137
138 char *
139 cpytill(to,from,delim)
140 register char *to, *from;
141 register int delim;
142 {
143     for (; *from; from++,to++) {
144         if (*from == '\\') {
145             if (from[1] == delim)
146                 from++;
147             else if (from[1] == '\\')
148                 *to++ = *from++;
149         }
150         else if (*from == delim)
151             break;
152         *to = *from;
153     }
154     *to = '\0';
155     return from;
156 }
157
158
159 char *
160 cpy2(to,from,delim)
161 register char *to, *from;
162 register int delim;
163 {
164     for (; *from; from++,to++) {
165         if (*from == '\\')
166             *to++ = *from++;
167         else if (*from == '$')
168             *to++ = '\\';
169         else if (*from == delim)
170             break;
171         *to = *from;
172     }
173     *to = '\0';
174     return from;
175 }
176
177 /* return ptr to little string in big string, NULL if not found */
178
179 char *
180 instr(big, little)
181 char *big, *little;
182
183 {
184     register char *t, *s, *x;
185
186     for (t = big; *t; t++) {
187         for (x=t,s=little; *s; x++,s++) {
188             if (!*x)
189                 return Nullch;
190             if (*s != *x)
191                 break;
192         }
193         if (!*s)
194             return t;
195     }
196     return Nullch;
197 }
198
199 /* copy a string to a safe spot */
200
201 char *
202 savestr(str)
203 char *str;
204 {
205     register char *newaddr = safemalloc((MEM_SIZE)(strlen(str)+1));
206
207     (void)strcpy(newaddr,str);
208     return newaddr;
209 }
210
211 /* grow a static string to at least a certain length */
212
213 void
214 growstr(strptr,curlen,newlen)
215 char **strptr;
216 int *curlen;
217 int newlen;
218 {
219     if (newlen > *curlen) {             /* need more room? */
220         if (*curlen)
221             *strptr = saferealloc(*strptr,(MEM_SIZE)newlen);
222         else
223             *strptr = safemalloc((MEM_SIZE)newlen);
224         *curlen = newlen;
225     }
226 }
227
228 /*VARARGS1*/
229 fatal(pat,a1,a2,a3,a4)
230 char *pat;
231 {
232     fprintf(stderr,pat,a1,a2,a3,a4);
233     exit(1);
234 }
235
236 /*VARARGS1*/
237 warn(pat,a1,a2,a3,a4)
238 char *pat;
239 {
240     fprintf(stderr,pat,a1,a2,a3,a4);
241 }
242
243 static bool firstsetenv = TRUE;
244 extern char **environ;
245
246 void
247 setenv(nam,val)
248 char *nam, *val;
249 {
250     register int i=envix(nam);          /* where does it go? */
251
252     if (!environ[i]) {                  /* does not exist yet */
253         if (firstsetenv) {              /* need we copy environment? */
254             int j;
255 #ifndef lint
256             char **tmpenv = (char**)    /* point our wand at memory */
257                 safemalloc((i+2) * sizeof(char*));
258 #else
259             char **tmpenv = Null(char **);
260 #endif /* lint */
261     
262             firstsetenv = FALSE;
263             for (j=0; j<i; j++)         /* copy environment */
264                 tmpenv[j] = environ[j];
265             environ = tmpenv;           /* tell exec where it is now */
266         }
267 #ifndef lint
268         else
269             environ = (char**) saferealloc((char*) environ,
270                 (i+2) * sizeof(char*));
271                                         /* just expand it a bit */
272 #endif /* lint */
273         environ[i+1] = Nullch;  /* make sure it's null terminated */
274     }
275     environ[i] = safemalloc(strlen(nam) + strlen(val) + 2);
276                                         /* this may or may not be in */
277                                         /* the old environ structure */
278     sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
279 }
280
281 int
282 envix(nam)
283 char *nam;
284 {
285     register int i, len = strlen(nam);
286
287     for (i = 0; environ[i]; i++) {
288         if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
289             break;                      /* strnEQ must come first to avoid */
290     }                                   /* potential SEGV's */
291     return i;
292 }