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