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