This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 2.0 patch 1: removed redundant debugging code in regexp.c
[perl5.git] / util.c
CommitLineData
378cc40b 1/* $Header: util.c,v 2.0 88/06/05 00:15:11 root Exp $
8d063cd8
LW
2 *
3 * $Log: util.c,v $
378cc40b
LW
4 * Revision 2.0 88/06/05 00:15:11 root
5 * Baseline version 2.0.
8d063cd8
LW
6 *
7 */
8
8d063cd8 9#include "EXTERN.h"
8d063cd8 10#include "perl.h"
8d063cd8
LW
11
12#define FLUSH
8d063cd8
LW
13
14static char nomem[] = "Out of memory!\n";
15
16/* paranoid version of malloc */
17
378cc40b 18#ifdef DEBUGGING
8d063cd8 19static int an = 0;
378cc40b 20#endif
8d063cd8
LW
21
22char *
23safemalloc(size)
24MEM_SIZE size;
25{
26 char *ptr;
27 char *malloc();
28
29 ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */
30#ifdef DEBUGGING
31 if (debug & 128)
32 fprintf(stderr,"0x%x: (%05d) malloc %d bytes\n",ptr,an++,size);
33#endif
34 if (ptr != Nullch)
35 return ptr;
36 else {
37 fputs(nomem,stdout) FLUSH;
38 exit(1);
39 }
40 /*NOTREACHED*/
41}
42
43/* paranoid version of realloc */
44
45char *
46saferealloc(where,size)
47char *where;
48MEM_SIZE size;
49{
50 char *ptr;
51 char *realloc();
52
378cc40b
LW
53 if (!where)
54 fatal("Null realloc");
8d063cd8
LW
55 ptr = realloc(where,size?size:1); /* realloc(0) is NASTY on our system */
56#ifdef DEBUGGING
57 if (debug & 128) {
58 fprintf(stderr,"0x%x: (%05d) rfree\n",where,an++);
59 fprintf(stderr,"0x%x: (%05d) realloc %d bytes\n",ptr,an++,size);
60 }
61#endif
62 if (ptr != Nullch)
63 return ptr;
64 else {
65 fputs(nomem,stdout) FLUSH;
66 exit(1);
67 }
68 /*NOTREACHED*/
69}
70
71/* safe version of free */
72
73safefree(where)
74char *where;
75{
76#ifdef DEBUGGING
77 if (debug & 128)
78 fprintf(stderr,"0x%x: (%05d) free\n",where,an++);
79#endif
378cc40b
LW
80 if (where) {
81 free(where);
82 }
8d063cd8
LW
83}
84
378cc40b 85#ifdef NOTDEF
8d063cd8
LW
86/* safe version of string copy */
87
88char *
89safecpy(to,from,len)
90char *to;
91register char *from;
92register int len;
93{
94 register char *dest = to;
95
96 if (from != Nullch)
97 for (len--; len && (*dest++ = *from++); len--) ;
98 *dest = '\0';
99 return to;
100}
378cc40b 101#endif /*NOTDEF*/
8d063cd8
LW
102
103#ifdef undef
104/* safe version of string concatenate, with \n deletion and space padding */
105
106char *
107safecat(to,from,len)
108char *to;
109register char *from;
110register int len;
111{
112 register char *dest = to;
113
114 len--; /* leave room for null */
115 if (*dest) {
116 while (len && *dest++) len--;
117 if (len) {
118 len--;
119 *(dest-1) = ' ';
120 }
121 }
122 if (from != Nullch)
123 while (len && (*dest++ = *from++)) len--;
124 if (len)
125 dest--;
126 if (*(dest-1) == '\n')
127 dest--;
128 *dest = '\0';
129 return to;
130}
131#endif
132
133/* copy a string up to some (non-backslashed) delimiter, if any */
134
135char *
136cpytill(to,from,delim)
137register char *to, *from;
138register int delim;
139{
140 for (; *from; from++,to++) {
378cc40b
LW
141 if (*from == '\\') {
142 if (from[1] == delim)
143 from++;
144 else if (from[1] == '\\')
145 *to++ = *from++;
146 }
8d063cd8
LW
147 else if (*from == delim)
148 break;
149 *to = *from;
150 }
151 *to = '\0';
152 return from;
153}
154
155/* return ptr to little string in big string, NULL if not found */
378cc40b 156/* This routine was donated by Corey Satten. */
8d063cd8
LW
157
158char *
159instr(big, little)
378cc40b
LW
160register char *big;
161register char *little;
162{
163 register char *s, *x;
164 register int first = *little++;
165
166 if (!first)
167 return big;
168 while (*big) {
169 if (*big++ != first)
170 continue;
171 for (x=big,s=little; *s; /**/ ) {
172 if (!*x)
173 return Nullch;
174 if (*s++ != *x++) {
175 s--;
176 break;
177 }
178 }
179 if (!*s)
180 return big-1;
181 }
182 return Nullch;
183}
8d063cd8 184
378cc40b
LW
185#ifdef NOTDEF
186void
187bmcompile(str)
188STR *str;
8d063cd8 189{
378cc40b
LW
190 register char *s;
191 register char *table;
192 register int i;
193 register int len = str->str_cur;
194
195 str_grow(str,len+128);
196 s = str->str_ptr;
197 table = s + len;
198 for (i = 1; i < 128; i++) {
199 table[i] = len;
200 }
201 i = 0;
202 while (*s) {
203 if (!isascii(*s))
204 return;
205 if (table[*s] == len)
206 table[*s] = i;
207 s++,i++;
208 }
209 str->str_pok |= 2; /* deep magic */
210}
211#endif /* NOTDEF */
212
213static unsigned char freq[] = {
214 1, 2, 84, 151, 154, 155, 156, 157,
215 165, 246, 250, 3, 158, 7, 18, 29,
216 40, 51, 62, 73, 85, 96, 107, 118,
217 129, 140, 147, 148, 149, 150, 152, 153,
218 255, 182, 224, 205, 174, 176, 180, 217,
219 233, 232, 236, 187, 235, 228, 234, 226,
220 222, 219, 211, 195, 188, 193, 185, 184,
221 191, 183, 201, 229, 181, 220, 194, 162,
222 163, 208, 186, 202, 200, 218, 198, 179,
223 178, 214, 166, 170, 207, 199, 209, 206,
224 204, 160, 212, 216, 215, 192, 175, 173,
225 243, 172, 161, 190, 203, 189, 164, 230,
226 167, 248, 227, 244, 242, 255, 241, 231,
227 240, 253, 169, 210, 245, 237, 249, 247,
228 239, 168, 252, 251, 254, 238, 223, 221,
229 213, 225, 177, 197, 171, 196, 159, 4,
230 5, 6, 8, 9, 10, 11, 12, 13,
231 14, 15, 16, 17, 19, 20, 21, 22,
232 23, 24, 25, 26, 27, 28, 30, 31,
233 32, 33, 34, 35, 36, 37, 38, 39,
234 41, 42, 43, 44, 45, 46, 47, 48,
235 49, 50, 52, 53, 54, 55, 56, 57,
236 58, 59, 60, 61, 63, 64, 65, 66,
237 67, 68, 69, 70, 71, 72, 74, 75,
238 76, 77, 78, 79, 80, 81, 82, 83,
239 86, 87, 88, 89, 90, 91, 92, 93,
240 94, 95, 97, 98, 99, 100, 101, 102,
241 103, 104, 105, 106, 108, 109, 110, 111,
242 112, 113, 114, 115, 116, 117, 119, 120,
243 121, 122, 123, 124, 125, 126, 127, 128,
244 130, 131, 132, 133, 134, 135, 136, 137,
245 138, 139, 141, 142, 143, 144, 145, 146
246};
8d063cd8 247
378cc40b
LW
248void
249fbmcompile(str)
250STR *str;
251{
252 register char *s;
253 register char *table;
254 register int i;
255 register int len = str->str_cur;
256 int rarest = 0;
257 int frequency = 256;
258
259 str_grow(str,len+128);
260 table = str->str_ptr + len; /* actually points at final '\0' */
261 s = table - 1;
262 for (i = 1; i < 128; i++) {
263 table[i] = len;
264 }
265 i = 0;
266 while (s >= str->str_ptr) {
267 if (!isascii(*s))
268 return;
269 if (table[*s] == len)
270 table[*s] = i;
271 s--,i++;
272 }
273 str->str_pok |= 2; /* deep magic */
274
275 s = str->str_ptr; /* deeper magic */
276 for (i = 0; i < len; i++) {
277 if (freq[s[i]] < frequency) {
278 rarest = i;
279 frequency = freq[s[i]];
280 }
281 }
282 str->str_rare = s[rarest];
283 str->str_prev = rarest;
284#ifdef DEBUGGING
285 if (debug & 512)
286 fprintf(stderr,"rarest char %c at %d\n",str->str_rare, str->str_prev);
287#endif
288}
289
290#ifdef NOTDEF
291char *
292bminstr(big, biglen, littlestr)
293register char *big;
294int biglen;
295STR *littlestr;
296{
297 register char *s;
298 register int tmp;
299 register char *little = littlestr->str_ptr;
300 int littlelen = littlestr->str_cur;
301 register char *table = little + littlelen;
302
303 s = big + biglen - littlelen;
304 while (s >= big) {
305 if (tmp = table[*s]) {
306 s -= tmp;
307 }
308 else {
309 if (strnEQ(s,little,littlelen))
310 return s;
311 s--;
312 }
313 }
314 return Nullch;
315}
316#endif /* NOTDEF */
317
318char *
319fbminstr(big, bigend, littlestr)
320char *big;
321register char *bigend;
322STR *littlestr;
323{
324 register char *s;
325 register int tmp;
326 register int littlelen;
327 register char *little;
328 register char *table;
329 register char *olds;
330 register char *oldlittle;
331 register int min;
332 char *screaminstr();
333
334 if (littlestr->str_pok != 3)
335 return instr(big,littlestr->str_ptr);
336
337 littlelen = littlestr->str_cur;
338 table = littlestr->str_ptr + littlelen;
339 s = big + --littlelen;
340 oldlittle = little = table - 1;
341 while (s < bigend) {
342 top:
343 if (tmp = table[*s]) {
344 s += tmp;
345 }
346 else {
347 tmp = littlelen; /* less expensive than calling strncmp() */
348 olds = s;
349 while (tmp--) {
350 if (*--s == *--little)
351 continue;
352 s = olds + 1; /* here we pay the price for failure */
353 little = oldlittle;
354 if (s < bigend) /* fake up continue to outer loop */
355 goto top;
356 return Nullch;
357 }
358 return s;
359 }
360 }
361 return Nullch;
362}
363
364char *
365screaminstr(bigstr, littlestr)
366STR *bigstr;
367STR *littlestr;
368{
369 register char *s, *x;
370 register char *big = bigstr->str_ptr;
371 register int pos;
372 register int previous;
373 register int first;
374 register char *little;
375
376 if ((pos = screamfirst[littlestr->str_rare]) < 0)
377 return Nullch;
378 little = littlestr->str_ptr;
379 first = *little++;
380 previous = littlestr->str_prev;
381 big -= previous;
382 while (pos < previous) {
383 if (!(pos += screamnext[pos]))
384 return Nullch;
385 }
386 do {
387 if (big[pos] != first)
388 continue;
389 for (x=big+pos+1,s=little; *s; /**/ ) {
8d063cd8
LW
390 if (!*x)
391 return Nullch;
378cc40b
LW
392 if (*s++ != *x++) {
393 s--;
8d063cd8 394 break;
378cc40b 395 }
8d063cd8
LW
396 }
397 if (!*s)
378cc40b
LW
398 return big+pos;
399 } while (pos += screamnext[pos]);
8d063cd8
LW
400 return Nullch;
401}
402
403/* copy a string to a safe spot */
404
405char *
406savestr(str)
407char *str;
408{
409 register char *newaddr = safemalloc((MEM_SIZE)(strlen(str)+1));
410
411 (void)strcpy(newaddr,str);
412 return newaddr;
413}
414
415/* grow a static string to at least a certain length */
416
417void
418growstr(strptr,curlen,newlen)
419char **strptr;
420int *curlen;
421int newlen;
422{
423 if (newlen > *curlen) { /* need more room? */
424 if (*curlen)
425 *strptr = saferealloc(*strptr,(MEM_SIZE)newlen);
426 else
427 *strptr = safemalloc((MEM_SIZE)newlen);
428 *curlen = newlen;
429 }
430}
431
378cc40b
LW
432extern int errno;
433
434/*VARARGS1*/
435mess(pat,a1,a2,a3,a4)
436char *pat;
437{
438 char *s;
439
440 s = tokenbuf;
441 sprintf(s,pat,a1,a2,a3,a4);
442 s += strlen(s);
443 if (s[-1] != '\n') {
444 if (line) {
445 sprintf(s," at %s line %ld",
446 in_eval?filename:origfilename, (long)line);
447 s += strlen(s);
448 }
449 if (last_in_stab &&
450 last_in_stab->stab_io &&
451 last_in_stab->stab_io->lines ) {
452 sprintf(s,", <%s> line %ld",
453 last_in_stab == argvstab ? "" : last_in_stab->stab_name,
454 (long)last_in_stab->stab_io->lines);
455 s += strlen(s);
456 }
457 strcpy(s,".\n");
458 }
459}
460
8d063cd8
LW
461/*VARARGS1*/
462fatal(pat,a1,a2,a3,a4)
463char *pat;
464{
465 extern FILE *e_fp;
466 extern char *e_tmpname;
467
378cc40b 468 mess(pat,a1,a2,a3,a4);
a559c259 469 if (in_eval) {
a559c259
LW
470 str_set(stabent("@",TRUE)->stab_val,tokenbuf);
471 longjmp(eval_env,1);
472 }
378cc40b
LW
473 fputs(tokenbuf,stderr);
474 fflush(stderr);
8d063cd8
LW
475 if (e_fp)
476 UNLINK(e_tmpname);
378cc40b
LW
477 statusvalue >>= 8;
478 exit(errno?errno:(statusvalue?statusvalue:255));
479}
480
481/*VARARGS1*/
482warn(pat,a1,a2,a3,a4)
483char *pat;
484{
485 mess(pat,a1,a2,a3,a4);
486 fputs(tokenbuf,stderr);
487 fflush(stderr);
8d063cd8
LW
488}
489
490static bool firstsetenv = TRUE;
491extern char **environ;
492
493void
494setenv(nam,val)
495char *nam, *val;
496{
497 register int i=envix(nam); /* where does it go? */
498
499 if (!environ[i]) { /* does not exist yet */
500 if (firstsetenv) { /* need we copy environment? */
501 int j;
502#ifndef lint
503 char **tmpenv = (char**) /* point our wand at memory */
504 safemalloc((i+2) * sizeof(char*));
505#else
506 char **tmpenv = Null(char **);
507#endif /* lint */
508
509 firstsetenv = FALSE;
510 for (j=0; j<i; j++) /* copy environment */
511 tmpenv[j] = environ[j];
512 environ = tmpenv; /* tell exec where it is now */
513 }
514#ifndef lint
515 else
516 environ = (char**) saferealloc((char*) environ,
517 (i+2) * sizeof(char*));
518 /* just expand it a bit */
519#endif /* lint */
520 environ[i+1] = Nullch; /* make sure it's null terminated */
521 }
378cc40b 522 environ[i] = safemalloc((MEM_SIZE)(strlen(nam) + strlen(val) + 2));
8d063cd8
LW
523 /* this may or may not be in */
524 /* the old environ structure */
525 sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
526}
527
528int
529envix(nam)
530char *nam;
531{
532 register int i, len = strlen(nam);
533
534 for (i = 0; environ[i]; i++) {
535 if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
536 break; /* strnEQ must come first to avoid */
537 } /* potential SEGV's */
538 return i;
539}
378cc40b
LW
540
541#ifdef EUNICE
542unlnk(f) /* unlink all versions of a file */
543char *f;
544{
545 int i;
546
547 for (i = 0; unlink(f) >= 0; i++) ;
548 return i ? 0 : -1;
549}
550#endif
551
552#ifndef BCOPY
553#ifndef MEMCPY
554char *
555bcopy(from,to,len)
556register char *from;
557register char *to;
558register int len;
559{
560 char *retval = to;
561
562 while (len--)
563 *to++ = *from++;
564 return retval;
565}
566
567char *
568bzero(loc,len)
569register char *loc;
570register int len;
571{
572 char *retval = loc;
573
574 while (len--)
575 *loc++ = 0;
576 return retval;
577}
578#endif
579#endif