perl 4.0.00: (no release announcement available)
[p5sagit/p5-mst-13.2.git] / x2p / util.c
1 /* $Header: util.c,v 4.0 91/03/20 01:58:25 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 4.0  91/03/20  01:58:25  lwall
10  * 4.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 /* copy a string up to some (non-backslashed) delimiter, if any */
107
108 char *
109 cpytill(to,from,delim)
110 register char *to, *from;
111 register int delim;
112 {
113     for (; *from; from++,to++) {
114         if (*from == '\\') {
115             if (from[1] == delim)
116                 from++;
117             else if (from[1] == '\\')
118                 *to++ = *from++;
119         }
120         else if (*from == delim)
121             break;
122         *to = *from;
123     }
124     *to = '\0';
125     return from;
126 }
127
128
129 char *
130 cpy2(to,from,delim)
131 register char *to, *from;
132 register int delim;
133 {
134     for (; *from; from++,to++) {
135         if (*from == '\\')
136             *to++ = *from++;
137         else if (*from == '$')
138             *to++ = '\\';
139         else if (*from == delim)
140             break;
141         *to = *from;
142     }
143     *to = '\0';
144     return from;
145 }
146
147 /* return ptr to little string in big string, NULL if not found */
148
149 char *
150 instr(big, little)
151 char *big, *little;
152
153 {
154     register char *t, *s, *x;
155
156     for (t = big; *t; t++) {
157         for (x=t,s=little; *s; x++,s++) {
158             if (!*x)
159                 return Nullch;
160             if (*s != *x)
161                 break;
162         }
163         if (!*s)
164             return t;
165     }
166     return Nullch;
167 }
168
169 /* copy a string to a safe spot */
170
171 char *
172 savestr(str)
173 char *str;
174 {
175     register char *newaddr = safemalloc((MEM_SIZE)(strlen(str)+1));
176
177     (void)strcpy(newaddr,str);
178     return newaddr;
179 }
180
181 /* grow a static string to at least a certain length */
182
183 void
184 growstr(strptr,curlen,newlen)
185 char **strptr;
186 int *curlen;
187 int newlen;
188 {
189     if (newlen > *curlen) {             /* need more room? */
190         if (*curlen)
191             *strptr = saferealloc(*strptr,(MEM_SIZE)newlen);
192         else
193             *strptr = safemalloc((MEM_SIZE)newlen);
194         *curlen = newlen;
195     }
196 }
197
198 /*VARARGS1*/
199 fatal(pat,a1,a2,a3,a4)
200 char *pat;
201 {
202     fprintf(stderr,pat,a1,a2,a3,a4);
203     exit(1);
204 }
205
206 /*VARARGS1*/
207 warn(pat,a1,a2,a3,a4)
208 char *pat;
209 {
210     fprintf(stderr,pat,a1,a2,a3,a4);
211 }
212
213 static bool firstsetenv = TRUE;
214 extern char **environ;
215
216 void
217 setenv(nam,val)
218 char *nam, *val;
219 {
220     register int i=envix(nam);          /* where does it go? */
221
222     if (!environ[i]) {                  /* does not exist yet */
223         if (firstsetenv) {              /* need we copy environment? */
224             int j;
225 #ifndef lint
226             char **tmpenv = (char**)    /* point our wand at memory */
227                 safemalloc((i+2) * sizeof(char*));
228 #else
229             char **tmpenv = Null(char **);
230 #endif /* lint */
231     
232             firstsetenv = FALSE;
233             for (j=0; j<i; j++)         /* copy environment */
234                 tmpenv[j] = environ[j];
235             environ = tmpenv;           /* tell exec where it is now */
236         }
237 #ifndef lint
238         else
239             environ = (char**) saferealloc((char*) environ,
240                 (i+2) * sizeof(char*));
241                                         /* just expand it a bit */
242 #endif /* lint */
243         environ[i+1] = Nullch;  /* make sure it's null terminated */
244     }
245     environ[i] = safemalloc(strlen(nam) + strlen(val) + 2);
246                                         /* this may or may not be in */
247                                         /* the old environ structure */
248     sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
249 }
250
251 int
252 envix(nam)
253 char *nam;
254 {
255     register int i, len = strlen(nam);
256
257     for (i = 0; environ[i]; i++) {
258         if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
259             break;                      /* strnEQ must come first to avoid */
260     }                                   /* potential SEGV's */
261     return i;
262 }