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