This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pod/perlipc.pod patch
[perl5.git] / util.c
CommitLineData
a0d0e21e 1/* util.c
a687059c 2 *
a0d0e21e 3 * Copyright (c) 1991-1994, Larry Wall
a687059c 4 *
d48672a2
LW
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 *
8d063cd8 8 */
a0d0e21e
LW
9
10/*
11 * "Very useful, no doubt, that was to Saruman; yet it seems that he was
12 * not content." --Gandalf
13 */
8d063cd8 14
8d063cd8 15#include "EXTERN.h"
8d063cd8 16#include "perl.h"
62b28dd9 17
6eb13c3b 18#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
a687059c 19#include <signal.h>
62b28dd9 20#endif
a687059c 21
36477c24 22#ifndef SIG_ERR
23# define SIG_ERR ((Sighandler_t) -1)
24#endif
25
bd4080b3 26/* XXX If this causes problems, set i_unistd=undef in the hint file. */
85e6fe83 27#ifdef I_UNISTD
8990e307
LW
28# include <unistd.h>
29#endif
30
a687059c
LW
31#ifdef I_VFORK
32# include <vfork.h>
33#endif
34
94b6baf5
AD
35/* Put this after #includes because fork and vfork prototypes may
36 conflict.
37*/
38#ifndef HAS_VFORK
39# define vfork fork
40#endif
41
fe14fcc3
LW
42#ifdef I_FCNTL
43# include <fcntl.h>
44#endif
45#ifdef I_SYS_FILE
46# include <sys/file.h>
47#endif
48
ff68c719 49#ifdef I_SYS_WAIT
50# include <sys/wait.h>
51#endif
52
8d063cd8 53#define FLUSH
8d063cd8 54
a0d0e21e
LW
55#ifdef LEAKTEST
56static void xstat _((void));
57#endif
58
55497cff 59#ifndef MYMALLOC
de3bb511 60
8d063cd8
LW
61/* paranoid version of malloc */
62
a687059c
LW
63/* NOTE: Do not call the next three routines directly. Use the macros
64 * in handy.h, so that we can easily redefine everything to do tracking of
65 * allocated hunks back to the original New to track down any memory leaks.
20cec16a 66 * XXX This advice seems to be widely ignored :-( --AD August 1996.
a687059c
LW
67 */
68
bd4080b3 69Malloc_t
8d063cd8
LW
70safemalloc(size)
71MEM_SIZE size;
72{
bd4080b3 73 Malloc_t ptr;
55497cff 74#ifdef HAS_64K_LIMIT
62b28dd9 75 if (size > 0xffff) {
760ac839 76 PerlIO_printf(PerlIO_stderr(), "Allocation too large: %lx\n", size) FLUSH;
79072805 77 my_exit(1);
62b28dd9 78 }
55497cff 79#endif /* HAS_64K_LIMIT */
34de22dd
LW
80#ifdef DEBUGGING
81 if ((long)size < 0)
463ee0b2 82 croak("panic: malloc");
34de22dd 83#endif
8d063cd8 84 ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */
79072805 85#if !(defined(I286) || defined(atarist))
760ac839 86 DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%x: (%05d) malloc %ld bytes\n",ptr,an++,(long)size));
79072805 87#else
760ac839 88 DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) malloc %ld bytes\n",ptr,an++,(long)size));
8d063cd8
LW
89#endif
90 if (ptr != Nullch)
91 return ptr;
7c0587c8
LW
92 else if (nomemok)
93 return Nullch;
8d063cd8 94 else {
760ac839 95 PerlIO_puts(PerlIO_stderr(),no_mem) FLUSH;
79072805 96 my_exit(1);
8d063cd8
LW
97 }
98 /*NOTREACHED*/
99}
100
101/* paranoid version of realloc */
102
bd4080b3 103Malloc_t
8d063cd8 104saferealloc(where,size)
bd4080b3 105Malloc_t where;
8d063cd8
LW
106MEM_SIZE size;
107{
bd4080b3 108 Malloc_t ptr;
ecfc5424 109#if !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE)
bd4080b3 110 Malloc_t realloc();
ecfc5424 111#endif /* !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE) */
8d063cd8 112
55497cff 113#ifdef HAS_64K_LIMIT
62b28dd9 114 if (size > 0xffff) {
760ac839 115 PerlIO_printf(PerlIO_stderr(), "Reallocation too large: %lx\n", size) FLUSH;
79072805 116 my_exit(1);
62b28dd9 117 }
55497cff 118#endif /* HAS_64K_LIMIT */
378cc40b 119 if (!where)
463ee0b2 120 croak("Null realloc");
34de22dd
LW
121#ifdef DEBUGGING
122 if ((long)size < 0)
463ee0b2 123 croak("panic: realloc");
34de22dd 124#endif
8d063cd8 125 ptr = realloc(where,size?size:1); /* realloc(0) is NASTY on our system */
79072805
LW
126
127#if !(defined(I286) || defined(atarist))
128 DEBUG_m( {
760ac839
LW
129 PerlIO_printf(Perl_debug_log, "0x%x: (%05d) rfree\n",where,an++);
130 PerlIO_printf(Perl_debug_log, "0x%x: (%05d) realloc %ld bytes\n",ptr,an++,(long)size);
79072805
LW
131 } )
132#else
133 DEBUG_m( {
760ac839
LW
134 PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) rfree\n",where,an++);
135 PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) realloc %ld bytes\n",ptr,an++,(long)size);
79072805 136 } )
8d063cd8 137#endif
79072805 138
8d063cd8
LW
139 if (ptr != Nullch)
140 return ptr;
7c0587c8
LW
141 else if (nomemok)
142 return Nullch;
8d063cd8 143 else {
760ac839 144 PerlIO_puts(PerlIO_stderr(),no_mem) FLUSH;
79072805 145 my_exit(1);
8d063cd8
LW
146 }
147 /*NOTREACHED*/
148}
149
150/* safe version of free */
151
a687059c 152void
8d063cd8 153safefree(where)
bd4080b3 154Malloc_t where;
8d063cd8 155{
79072805 156#if !(defined(I286) || defined(atarist))
760ac839 157 DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%x: (%05d) free\n",where,an++));
79072805 158#else
760ac839 159 DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) free\n",where,an++));
8d063cd8 160#endif
378cc40b 161 if (where) {
de3bb511 162 /*SUPPRESS 701*/
378cc40b
LW
163 free(where);
164 }
8d063cd8
LW
165}
166
1050c9ca 167/* safe version of calloc */
168
bd4080b3 169Malloc_t
1050c9ca 170safecalloc(count, size)
171MEM_SIZE count;
172MEM_SIZE size;
173{
bd4080b3 174 Malloc_t ptr;
1050c9ca 175
55497cff 176#ifdef HAS_64K_LIMIT
1050c9ca 177 if (size * count > 0xffff) {
760ac839 178 PerlIO_printf(PerlIO_stderr(), "Allocation too large: %lx\n", size * count) FLUSH;
1050c9ca 179 my_exit(1);
180 }
55497cff 181#endif /* HAS_64K_LIMIT */
1050c9ca 182#ifdef DEBUGGING
183 if ((long)size < 0 || (long)count < 0)
184 croak("panic: calloc");
185#endif
186#if !(defined(I286) || defined(atarist))
760ac839 187 DEBUG_m(PerlIO_printf(PerlIO_stderr(), "0x%x: (%05d) calloc %ld x %ld bytes\n",ptr,an++,(long)count,(long)size));
1050c9ca 188#else
760ac839 189 DEBUG_m(PerlIO_printf(PerlIO_stderr(), "0x%lx: (%05d) calloc %ld x %ld bytes\n",ptr,an++,(long)count,(long)size));
1050c9ca 190#endif
191 size *= count;
192 ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */
193 if (ptr != Nullch) {
194 memset((void*)ptr, 0, size);
195 return ptr;
196 }
197 else if (nomemok)
198 return Nullch;
199 else {
760ac839 200 PerlIO_puts(PerlIO_stderr(),no_mem) FLUSH;
1050c9ca 201 my_exit(1);
202 }
203 /*NOTREACHED*/
204}
205
55497cff 206#endif /* !MYMALLOC */
de3bb511 207
a687059c
LW
208#ifdef LEAKTEST
209
210#define ALIGN sizeof(long)
8d063cd8 211
bd4080b3 212Malloc_t
a687059c 213safexmalloc(x,size)
79072805 214I32 x;
a687059c 215MEM_SIZE size;
8d063cd8 216{
bd4080b3 217 register Malloc_t where;
8d063cd8 218
a687059c
LW
219 where = safemalloc(size + ALIGN);
220 xcount[x]++;
221 where[0] = x % 100;
222 where[1] = x / 100;
223 return where + ALIGN;
8d063cd8 224}
8d063cd8 225
bd4080b3 226Malloc_t
a687059c 227safexrealloc(where,size)
bd4080b3 228Malloc_t where;
a687059c
LW
229MEM_SIZE size;
230{
bd4080b3 231 register Malloc_t new = saferealloc(where - ALIGN, size + ALIGN);
a0d0e21e 232 return new + ALIGN;
a687059c
LW
233}
234
235void
236safexfree(where)
bd4080b3 237Malloc_t where;
a687059c 238{
79072805 239 I32 x;
a687059c
LW
240
241 if (!where)
242 return;
243 where -= ALIGN;
244 x = where[0] + 100 * where[1];
245 xcount[x]--;
246 safefree(where);
247}
248
bd4080b3 249Malloc_t
1050c9ca 250safexcalloc(x,count,size)
251I32 x;
252MEM_SIZE count;
253MEM_SIZE size;
254{
bd4080b3 255 register Malloc_t where;
1050c9ca 256
257 where = safexmalloc(x, size * count + ALIGN);
258 xcount[x]++;
259 memset((void*)where + ALIGN, 0, size * count);
260 where[0] = x % 100;
261 where[1] = x / 100;
262 return where + ALIGN;
263}
264
7c0587c8 265static void
a687059c 266xstat()
8d063cd8 267{
79072805 268 register I32 i;
8d063cd8 269
a687059c 270 for (i = 0; i < MAXXCOUNT; i++) {
de3bb511 271 if (xcount[i] > lastxcount[i]) {
760ac839 272 PerlIO_printf(PerlIO_stderr(),"%2d %2d\t%ld\n", i / 100, i % 100, xcount[i]);
a687059c 273 lastxcount[i] = xcount[i];
8d063cd8
LW
274 }
275 }
8d063cd8 276}
a687059c
LW
277
278#endif /* LEAKTEST */
8d063cd8
LW
279
280/* copy a string up to some (non-backslashed) delimiter, if any */
281
282char *
a687059c 283cpytill(to,from,fromend,delim,retlen)
62b28dd9
LW
284register char *to;
285register char *from;
a687059c 286register char *fromend;
a0d0e21e 287register int delim;
79072805 288I32 *retlen;
8d063cd8 289{
a687059c
LW
290 char *origto = to;
291
292 for (; from < fromend; from++,to++) {
378cc40b
LW
293 if (*from == '\\') {
294 if (from[1] == delim)
295 from++;
296 else if (from[1] == '\\')
297 *to++ = *from++;
298 }
8d063cd8
LW
299 else if (*from == delim)
300 break;
301 *to = *from;
302 }
303 *to = '\0';
a687059c 304 *retlen = to - origto;
8d063cd8
LW
305 return from;
306}
307
308/* return ptr to little string in big string, NULL if not found */
378cc40b 309/* This routine was donated by Corey Satten. */
8d063cd8
LW
310
311char *
312instr(big, little)
378cc40b
LW
313register char *big;
314register char *little;
315{
316 register char *s, *x;
79072805 317 register I32 first;
378cc40b 318
a687059c
LW
319 if (!little)
320 return big;
321 first = *little++;
378cc40b
LW
322 if (!first)
323 return big;
324 while (*big) {
325 if (*big++ != first)
326 continue;
327 for (x=big,s=little; *s; /**/ ) {
328 if (!*x)
329 return Nullch;
330 if (*s++ != *x++) {
331 s--;
332 break;
333 }
334 }
335 if (!*s)
336 return big-1;
337 }
338 return Nullch;
339}
8d063cd8 340
a687059c
LW
341/* same as instr but allow embedded nulls */
342
343char *
344ninstr(big, bigend, little, lend)
345register char *big;
346register char *bigend;
347char *little;
348char *lend;
8d063cd8 349{
a687059c 350 register char *s, *x;
79072805 351 register I32 first = *little;
a687059c 352 register char *littleend = lend;
378cc40b 353
a0d0e21e 354 if (!first && little >= littleend)
a687059c 355 return big;
de3bb511
LW
356 if (bigend - big < littleend - little)
357 return Nullch;
a687059c
LW
358 bigend -= littleend - little++;
359 while (big <= bigend) {
360 if (*big++ != first)
361 continue;
362 for (x=big,s=little; s < littleend; /**/ ) {
363 if (*s++ != *x++) {
364 s--;
365 break;
366 }
367 }
368 if (s >= littleend)
369 return big-1;
378cc40b 370 }
a687059c
LW
371 return Nullch;
372}
373
374/* reverse of the above--find last substring */
375
376char *
377rninstr(big, bigend, little, lend)
378register char *big;
379char *bigend;
380char *little;
381char *lend;
382{
383 register char *bigbeg;
384 register char *s, *x;
79072805 385 register I32 first = *little;
a687059c
LW
386 register char *littleend = lend;
387
a0d0e21e 388 if (!first && little >= littleend)
a687059c
LW
389 return bigend;
390 bigbeg = big;
391 big = bigend - (littleend - little++);
392 while (big >= bigbeg) {
393 if (*big-- != first)
394 continue;
395 for (x=big+2,s=little; s < littleend; /**/ ) {
396 if (*s++ != *x++) {
397 s--;
398 break;
399 }
400 }
401 if (s >= littleend)
402 return big+1;
378cc40b 403 }
a687059c 404 return Nullch;
378cc40b 405}
a687059c 406
bbce6d69 407/*
408 * Set up for a new ctype locale.
409 */
55497cff 410void
bbce6d69 411perl_new_ctype(newctype)
412 char *newctype;
ef7eada9 413{
36477c24 414#ifdef USE_LOCALE_CTYPE
415
bbce6d69 416 int i;
ef7eada9 417
bbce6d69 418 for (i = 0; i < 256; i++) {
419 if (isUPPER_LC(i))
420 fold_locale[i] = toLOWER_LC(i);
421 else if (isLOWER_LC(i))
422 fold_locale[i] = toUPPER_LC(i);
423 else
424 fold_locale[i] = i;
425 }
bbce6d69 426
36477c24 427#endif /* USE_LOCALE_CTYPE */
428}
bbce6d69 429
430/*
431 * Set up for a new collation locale.
432 */
433void
434perl_new_collate(newcoll)
435 char *newcoll;
436{
36477c24 437#ifdef USE_LOCALE_COLLATE
438
bbce6d69 439 if (! newcoll) {
440 if (collation_name) {
441 ++collation_ix;
442 Safefree(collation_name);
443 collation_name = NULL;
444 collation_standard = TRUE;
bbce6d69 445 collxfrm_base = 0;
446 collxfrm_mult = 2;
bbce6d69 447 }
448 return;
449 }
450
451 if (! collation_name || strNE(collation_name, newcoll)) {
452 ++collation_ix;
453 Safefree(collation_name);
454 collation_name = savepv(newcoll);
ff68c719 455 collation_standard = (strEQ(newcoll, "C") || strEQ(newcoll, "POSIX"));
bbce6d69 456
bbce6d69 457 {
458 /* 2: at most so many chars ('a', 'b'). */
459 /* 50: surely no system expands a char more. */
460#define XFRMBUFSIZE (2 * 50)
461 char xbuf[XFRMBUFSIZE];
462 Size_t fa = strxfrm(xbuf, "a", XFRMBUFSIZE);
463 Size_t fb = strxfrm(xbuf, "ab", XFRMBUFSIZE);
464 SSize_t mult = fb - fa;
465 if (mult < 1)
466 croak("strxfrm() gets absurd");
467 collxfrm_base = (fa > mult) ? (fa - mult) : 0;
468 collxfrm_mult = mult;
469 }
bbce6d69 470 }
bbce6d69 471
36477c24 472#endif /* USE_LOCALE_COLLATE */
473}
bbce6d69 474
475/*
476 * Set up for a new numeric locale.
477 */
478void
479perl_new_numeric(newnum)
480 char *newnum;
481{
36477c24 482#ifdef USE_LOCALE_NUMERIC
483
bbce6d69 484 if (! newnum) {
485 if (numeric_name) {
486 Safefree(numeric_name);
487 numeric_name = NULL;
488 numeric_standard = TRUE;
489 numeric_local = TRUE;
490 }
491 return;
492 }
493
494 if (! numeric_name || strNE(numeric_name, newnum)) {
495 Safefree(numeric_name);
496 numeric_name = savepv(newnum);
ff68c719 497 numeric_standard = (strEQ(newnum, "C") || strEQ(newnum, "POSIX"));
bbce6d69 498 numeric_local = TRUE;
499 }
36477c24 500
501#endif /* USE_LOCALE_NUMERIC */
bbce6d69 502}
503
36477c24 504#ifdef USE_LOCALE_NUMERIC
505
bbce6d69 506void
36477c24 507perl_set_numeric_standard()
bbce6d69 508{
509 if (! numeric_standard) {
510 setlocale(LC_NUMERIC, "C");
511 numeric_standard = TRUE;
512 numeric_local = FALSE;
513 }
514}
515
516void
36477c24 517perl_set_numeric_local()
bbce6d69 518{
519 if (! numeric_local) {
520 setlocale(LC_NUMERIC, numeric_name);
521 numeric_standard = FALSE;
522 numeric_local = TRUE;
523 }
524}
525
36477c24 526#endif /* USE_LOCALE_NUMERIC */
527
bbce6d69 528
36477c24 529/*
530 * Initialize locale awareness.
531 */
f0c5b223 532int
1050c9ca 533perl_init_i18nl10n(printwarn)
f0c5b223
TB
534 int printwarn;
535{
536 int ok = 1;
537 /* returns
538 * 1 = set ok or not applicable,
539 * 0 = fallback to C locale,
540 * -1 = fallback to C locale failed
541 */
bbce6d69 542
36477c24 543#ifdef USE_LOCALE
bbce6d69 544
545 char *lc_all = getenv("LC_ALL");
546 char *lang = getenv("LANG");
36477c24 547#ifdef USE_LOCALE_CTYPE
bbce6d69 548 char *lc_ctype = getenv("LC_CTYPE");
549 char *curctype = NULL;
36477c24 550#endif /* USE_LOCALE_CTYPE */
551#ifdef USE_LOCALE_COLLATE
bbce6d69 552 char *lc_collate = getenv("LC_COLLATE");
553 char *curcoll = NULL;
36477c24 554#endif /* USE_LOCALE_COLLATE */
555#ifdef USE_LOCALE_NUMERIC
bbce6d69 556 char *lc_numeric = getenv("LC_NUMERIC");
557 char *curnum = NULL;
36477c24 558#endif /* USE_LOCALE_NUMERIC */
bbce6d69 559 bool setlocale_failure = FALSE;
560 char *subloc;
f0c5b223 561
bbce6d69 562#ifdef LC_ALL
563 subloc = NULL;
564 if (! setlocale(LC_ALL, ""))
565 setlocale_failure = TRUE;
566#else
567 subloc = "";
568#endif /* LC_ALL */
569
36477c24 570#ifdef USE_LOCALE_CTYPE
bbce6d69 571 if (! (curctype = setlocale(LC_CTYPE, subloc)))
572 setlocale_failure = TRUE;
36477c24 573#endif /* USE_LOCALE_CTYPE */
574#ifdef USE_LOCALE_COLLATE
bbce6d69 575 if (! (curcoll = setlocale(LC_COLLATE, subloc)))
576 setlocale_failure = TRUE;
36477c24 577#endif /* USE_LOCALE_COLLATE */
578#ifdef USE_LOCALE_NUMERIC
bbce6d69 579 if (! (curnum = setlocale(LC_NUMERIC, subloc)))
580 setlocale_failure = TRUE;
36477c24 581#endif /* USE_LOCALE_NUMERIC */
bbce6d69 582
ef7eada9
JH
583 if (setlocale_failure && (lc_all || lang)) {
584 char *perl_badlang;
20cec16a 585
586 if (printwarn > 1 ||
ef7eada9
JH
587 printwarn &&
588 (!(perl_badlang = getenv("PERL_BADLANG")) || atoi(perl_badlang))) {
589
ef7eada9 590 PerlIO_printf(PerlIO_stderr(),
bbce6d69 591 "perl: warning: Setting locale failed for the categories:\n\t");
36477c24 592#ifdef USE_LOCALE_CTYPE
bbce6d69 593 if (! curctype)
36477c24 594 PerlIO_printf(PerlIO_stderr(), "USE_LOCALE_CTYPE ");
595#endif /* USE_LOCALE_CTYPE */
596#ifdef USE_LOCALE_COLLATE
bbce6d69 597 if (! curcoll)
36477c24 598 PerlIO_printf(PerlIO_stderr(), "USE_LOCALE_COLLATE ");
599#endif /* USE_LOCALE_COLLATE */
600#ifdef USE_LOCALE_NUMERIC
bbce6d69 601 if (! curnum)
36477c24 602 PerlIO_printf(PerlIO_stderr(), "USE_LOCALE_NUMERIC ");
603#endif /* USE_LOCALE_NUMERIC */
bbce6d69 604 PerlIO_printf(PerlIO_stderr(), "\n");
605
760ac839 606 PerlIO_printf(PerlIO_stderr(),
bbce6d69 607 "perl: warning: Please check that your locale settings:\n");
ef7eada9
JH
608
609 PerlIO_printf(PerlIO_stderr(),
bbce6d69 610 "\tLC_ALL = %c%s%c,\n",
611 lc_all ? '"' : '(',
612 lc_all ? lc_all : "unset",
613 lc_all ? '"' : ')');
36477c24 614#ifdef USE_LOCALE_CTYPE
bbce6d69 615 if (! curctype)
616 PerlIO_printf(PerlIO_stderr(),
617 "\tLC_CTYPE = %c%s%c,\n",
618 lc_ctype ? '"' : '(',
619 lc_ctype ? lc_ctype : "unset",
620 lc_ctype ? '"' : ')');
36477c24 621#endif /* USE_LOCALE_CTYPE */
622#ifdef USE_LOCALE_COLLATE
bbce6d69 623 if (! curcoll)
624 PerlIO_printf(PerlIO_stderr(),
625 "\tLC_COLLATE = %c%s%c,\n",
626 lc_collate ? '"' : '(',
627 lc_collate ? lc_collate : "unset",
628 lc_collate ? '"' : ')');
36477c24 629#endif /* USE_LOCALE_COLLATE */
630#ifdef USE_LOCALE_NUMERIC
631 if (! curnum)
bbce6d69 632 PerlIO_printf(PerlIO_stderr(),
633 "\tLC_NUMERIC = %c%s%c,\n",
634 lc_numeric ? '"' : '(',
635 lc_numeric ? lc_numeric : "unset",
636 lc_numeric ? '"' : ')');
36477c24 637#endif /* USE_LOCALE_NUMERIC */
ef7eada9 638 PerlIO_printf(PerlIO_stderr(),
bbce6d69 639 "\tLANG = %c%s%c\n",
640 lang ? '"' : ')',
641 lang ? lang : "unset",
642 lang ? '"' : ')');
ef7eada9 643
bbce6d69 644 PerlIO_printf(PerlIO_stderr(),
645 " are supported and installed on your system.\n");
ef7eada9 646
bbce6d69 647 ok = 0;
ef7eada9 648 }
bbce6d69 649
ef7eada9
JH
650#ifdef LC_ALL
651 if (setlocale_failure) {
ef7eada9 652 PerlIO_printf(PerlIO_stderr(),
bbce6d69 653 "perl: warning: Falling back to the \"C\" locale.\n");
654 if (setlocale(LC_ALL, "C")) {
36477c24 655#ifdef USE_LOCALE_CTYPE
bbce6d69 656 curctype = "C";
36477c24 657#endif /* USE_LOCALE_CTYPE */
658#ifdef USE_LOCALE_COLLATE
bbce6d69 659 curcoll = "C";
36477c24 660#endif /* USE_LOCALE_COLLATE */
661#ifdef USE_LOCALE_NUMERIC
bbce6d69 662 curnum = "C";
36477c24 663#endif /* USE_LOCALE_NUMERIC */
bbce6d69 664 }
665 else {
666 PerlIO_printf(PerlIO_stderr(),
667 "perl: warning: Failed to fall back to the \"C\" locale.\n");
668 ok = -1;
669 }
670 }
671#else /* ! LC_ALL */
ef7eada9 672 PerlIO_printf(PerlIO_stderr(),
bbce6d69 673 "perl: warning: Cannot fall back to the \"C\" locale.\n");
674#endif /* ! LC_ALL */
ef7eada9
JH
675 }
676
36477c24 677#ifdef USE_LOCALE_CTYPE
bbce6d69 678 perl_new_ctype(curctype);
36477c24 679#endif /* USE_LOCALE_CTYPE */
bbce6d69 680
36477c24 681#ifdef USE_LOCALE_COLLATE
bbce6d69 682 perl_new_collate(curcoll);
36477c24 683#endif /* USE_LOCALE_COLLATE */
bbce6d69 684
36477c24 685#ifdef USE_LOCALE_NUMERIC
bbce6d69 686 perl_new_numeric(curnum);
36477c24 687#endif /* USE_LOCALE_NUMERIC */
ef7eada9 688
36477c24 689#endif /* USE_LOCALE */
ef7eada9 690
f0c5b223
TB
691 return ok;
692}
693
bbce6d69 694/* Backwards compatibility. */
695int
696perl_init_i18nl14n(printwarn)
697 int printwarn;
698{
699 perl_init_i18nl10n(printwarn);
700}
ef7eada9 701
36477c24 702#ifdef USE_LOCALE_COLLATE
ef7eada9 703
bbce6d69 704/*
705 * mem_collxfrm() is a bit like strxfrm() but with two important
706 * differences. First, it handles embedded NULs. Second, it allocates
707 * a bit more memory than needed for the transformed data itself.
708 * The real transformed data begins at offset sizeof(collationix).
709 * Please see sv_collxfrm() to see how this is used.
710 */
711char *
712mem_collxfrm(s, len, xlen)
713 const char *s;
714 STRLEN len;
715 STRLEN *xlen;
716{
717 char *xbuf;
718 STRLEN xalloc, xin, xout;
719
720 /* the first sizeof(collationix) bytes are used by sv_collxfrm(). */
721 /* the +1 is for the terminating NUL. */
722
723 xalloc = sizeof(collation_ix) + collxfrm_base + (collxfrm_mult * len) + 1;
724 New(171, xbuf, xalloc, char);
725 if (! xbuf)
726 goto bad;
727
728 *(U32*)xbuf = collation_ix;
729 xout = sizeof(collation_ix);
730 for (xin = 0; xin < len; ) {
731 SSize_t xused;
732
733 for (;;) {
734 xused = strxfrm(xbuf + xout, s + xin, xalloc - xout);
735 if (xused == -1)
736 goto bad;
737 if (xused < xalloc - xout)
738 break;
739 xalloc = (2 * xalloc) + 1;
740 Renew(xbuf, xalloc, char);
741 if (! xbuf)
742 goto bad;
743 }
ef7eada9 744
bbce6d69 745 xin += strlen(s + xin) + 1;
746 xout += xused;
747
748 /* Embedded NULs are understood but silently skipped
749 * because they make no sense in locale collation. */
750 }
ef7eada9 751
bbce6d69 752 xbuf[xout] = '\0';
753 *xlen = xout - sizeof(collation_ix);
754 return xbuf;
755
756 bad:
757 Safefree(xbuf);
758 *xlen = 0;
759 return NULL;
ef7eada9
JH
760}
761
36477c24 762#endif /* USE_LOCALE_COLLATE */
bbce6d69 763
378cc40b 764void
bbce6d69 765fbm_compile(sv)
79072805 766SV *sv;
378cc40b 767{
a687059c
LW
768 register unsigned char *s;
769 register unsigned char *table;
79072805
LW
770 register U32 i;
771 register U32 len = SvCUR(sv);
772 I32 rarest = 0;
773 U32 frequency = 256;
774
748a9306
LW
775 if (len > 255)
776 return; /* can't have offsets that big */
79072805 777 Sv_Grow(sv,len+258);
463ee0b2 778 table = (unsigned char*)(SvPVX(sv) + len + 1);
a687059c
LW
779 s = table - 2;
780 for (i = 0; i < 256; i++) {
378cc40b
LW
781 table[i] = len;
782 }
783 i = 0;
463ee0b2 784 while (s >= (unsigned char*)(SvPVX(sv)))
a687059c 785 {
bbce6d69 786 if (table[*s] == len)
787 table[*s] = i;
378cc40b
LW
788 s--,i++;
789 }
79072805 790 sv_upgrade(sv, SVt_PVBM);
bbce6d69 791 sv_magic(sv, Nullsv, 'B', Nullch, 0); /* deep magic */
79072805 792 SvVALID_on(sv);
378cc40b 793
463ee0b2 794 s = (unsigned char*)(SvPVX(sv)); /* deeper magic */
bbce6d69 795 for (i = 0; i < len; i++) {
796 if (freq[s[i]] < frequency) {
797 rarest = i;
798 frequency = freq[s[i]];
378cc40b
LW
799 }
800 }
79072805
LW
801 BmRARE(sv) = s[rarest];
802 BmPREVIOUS(sv) = rarest;
760ac839 803 DEBUG_r(PerlIO_printf(Perl_debug_log, "rarest char %c at %d\n",BmRARE(sv),BmPREVIOUS(sv)));
378cc40b
LW
804}
805
378cc40b 806char *
79072805 807fbm_instr(big, bigend, littlestr)
a687059c
LW
808unsigned char *big;
809register unsigned char *bigend;
79072805 810SV *littlestr;
378cc40b 811{
a687059c 812 register unsigned char *s;
79072805
LW
813 register I32 tmp;
814 register I32 littlelen;
a687059c
LW
815 register unsigned char *little;
816 register unsigned char *table;
817 register unsigned char *olds;
818 register unsigned char *oldlittle;
378cc40b 819
79072805 820 if (SvTYPE(littlestr) != SVt_PVBM || !SvVALID(littlestr)) {
a0d0e21e
LW
821 STRLEN len;
822 char *l = SvPV(littlestr,len);
823 if (!len)
d48672a2 824 return (char*)big;
a0d0e21e 825 return ninstr((char*)big,(char*)bigend, l, l + len);
d48672a2 826 }
378cc40b 827
79072805
LW
828 littlelen = SvCUR(littlestr);
829 if (SvTAIL(littlestr) && !multiline) { /* tail anchored? */
0f85fab0
LW
830 if (littlelen > bigend - big)
831 return Nullch;
463ee0b2 832 little = (unsigned char*)SvPVX(littlestr);
bbce6d69 833 s = bigend - littlelen;
36477c24 834 if (*s == *little && memEQ((char*)s,(char*)little,littlelen))
bbce6d69 835 return (char*)s; /* how sweet it is */
836 else if (bigend[-1] == '\n' && little[littlelen-1] != '\n'
837 && s > big) {
838 s--;
36477c24 839 if (*s == *little && memEQ((char*)s,(char*)little,littlelen))
bbce6d69 840 return (char*)s;
a687059c 841 }
bbce6d69 842 return Nullch;
a687059c 843 }
463ee0b2 844 table = (unsigned char*)(SvPVX(littlestr) + littlelen + 1);
62b28dd9
LW
845 if (--littlelen >= bigend - big)
846 return Nullch;
847 s = big + littlelen;
a687059c 848 oldlittle = little = table - 2;
bbce6d69 849 if (s < bigend) {
850 top2:
851 /*SUPPRESS 560*/
852 if (tmp = table[*s]) {
62b28dd9 853#ifdef POINTERRIGOR
bbce6d69 854 if (bigend - s > tmp) {
855 s += tmp;
856 goto top2;
857 }
62b28dd9 858#else
bbce6d69 859 if ((s += tmp) < bigend)
860 goto top2;
62b28dd9 861#endif
bbce6d69 862 return Nullch;
a687059c 863 }
bbce6d69 864 else {
865 tmp = littlelen; /* less expensive than calling strncmp() */
866 olds = s;
867 while (tmp--) {
868 if (*--s == *--little)
869 continue;
870 s = olds + 1; /* here we pay the price for failure */
871 little = oldlittle;
872 if (s < bigend) /* fake up continue to outer loop */
62b28dd9 873 goto top2;
62b28dd9 874 return Nullch;
a687059c 875 }
bbce6d69 876 return (char *)s;
378cc40b
LW
877 }
878 }
879 return Nullch;
880}
881
882char *
883screaminstr(bigstr, littlestr)
79072805
LW
884SV *bigstr;
885SV *littlestr;
378cc40b 886{
a687059c
LW
887 register unsigned char *s, *x;
888 register unsigned char *big;
79072805
LW
889 register I32 pos;
890 register I32 previous;
891 register I32 first;
a687059c
LW
892 register unsigned char *little;
893 register unsigned char *bigend;
894 register unsigned char *littleend;
378cc40b 895
79072805 896 if ((pos = screamfirst[BmRARE(littlestr)]) < 0)
378cc40b 897 return Nullch;
463ee0b2 898 little = (unsigned char *)(SvPVX(littlestr));
79072805 899 littleend = little + SvCUR(littlestr);
378cc40b 900 first = *little++;
79072805 901 previous = BmPREVIOUS(littlestr);
463ee0b2 902 big = (unsigned char *)(SvPVX(bigstr));
79072805 903 bigend = big + SvCUR(bigstr);
378cc40b
LW
904 while (pos < previous) {
905 if (!(pos += screamnext[pos]))
906 return Nullch;
907 }
de3bb511 908#ifdef POINTERRIGOR
bbce6d69 909 do {
910 if (big[pos-previous] != first)
911 continue;
912 for (x=big+pos+1-previous,s=little; s < littleend; /**/ ) {
913 if (x >= bigend)
914 return Nullch;
915 if (*s++ != *x++) {
916 s--;
917 break;
de3bb511 918 }
bbce6d69 919 }
920 if (s == littleend)
921 return (char *)(big+pos-previous);
922 } while ( pos += screamnext[pos] );
de3bb511
LW
923#else /* !POINTERRIGOR */
924 big -= previous;
bbce6d69 925 do {
926 if (big[pos] != first)
927 continue;
928 for (x=big+pos+1,s=little; s < littleend; /**/ ) {
929 if (x >= bigend)
930 return Nullch;
931 if (*s++ != *x++) {
932 s--;
933 break;
378cc40b 934 }
bbce6d69 935 }
936 if (s == littleend)
937 return (char *)(big+pos);
938 } while ( pos += screamnext[pos] );
de3bb511 939#endif /* POINTERRIGOR */
8d063cd8
LW
940 return Nullch;
941}
942
79072805 943I32
bbce6d69 944ibcmp(s1, s2, len)
945char *s1, *s2;
79072805
LW
946register I32 len;
947{
bbce6d69 948 register U8 *a = (U8 *)s1;
949 register U8 *b = (U8 *)s2;
79072805 950 while (len--) {
bbce6d69 951 if (*a != *b && *a != fold[*b])
952 return 1;
953 a++,b++;
954 }
955 return 0;
956}
957
958I32
959ibcmp_locale(s1, s2, len)
960char *s1, *s2;
961register I32 len;
962{
963 register U8 *a = (U8 *)s1;
964 register U8 *b = (U8 *)s2;
965 while (len--) {
966 if (*a != *b && *a != fold_locale[*b])
967 return 1;
968 a++,b++;
79072805
LW
969 }
970 return 0;
971}
972
8d063cd8
LW
973/* copy a string to a safe spot */
974
975char *
a0d0e21e 976savepv(sv)
79072805 977char *sv;
8d063cd8 978{
a687059c 979 register char *newaddr;
8d063cd8 980
79072805
LW
981 New(902,newaddr,strlen(sv)+1,char);
982 (void)strcpy(newaddr,sv);
8d063cd8
LW
983 return newaddr;
984}
985
a687059c
LW
986/* same thing but with a known length */
987
988char *
a0d0e21e 989savepvn(sv, len)
79072805
LW
990char *sv;
991register I32 len;
a687059c
LW
992{
993 register char *newaddr;
994
995 New(903,newaddr,len+1,char);
79072805 996 Copy(sv,newaddr,len,char); /* might not be null terminated */
a687059c
LW
997 newaddr[len] = '\0'; /* is now */
998 return newaddr;
999}
1000
a0d0e21e 1001#ifdef I_STDARG
8990e307 1002char *
2304df62 1003mess(char *pat, va_list *args)
a687059c
LW
1004#else
1005/*VARARGS0*/
de3bb511 1006char *
8990e307 1007mess(pat, args)
a687059c 1008 char *pat;
2304df62 1009 va_list *args;
8990e307
LW
1010#endif
1011{
a687059c 1012 char *s;
f0c5b223 1013 char *s_start;
79072805
LW
1014 SV *tmpstr;
1015 I32 usermess;
d48672a2 1016#ifndef HAS_VPRINTF
85e6fe83 1017#ifdef USE_CHAR_VSPRINTF
a687059c
LW
1018 char *vsprintf();
1019#else
79072805 1020 I32 vsprintf();
a687059c 1021#endif
d48672a2 1022#endif
a687059c 1023
f0c5b223 1024 s = s_start = buf;
de3bb511
LW
1025 usermess = strEQ(pat, "%s");
1026 if (usermess) {
8990e307 1027 tmpstr = sv_newmortal();
2304df62 1028 sv_setpv(tmpstr, va_arg(*args, char *));
463ee0b2 1029 *s++ = SvPVX(tmpstr)[SvCUR(tmpstr)-1];
de3bb511
LW
1030 }
1031 else {
2304df62 1032 (void) vsprintf(s,pat,*args);
de3bb511
LW
1033 s += strlen(s);
1034 }
2304df62 1035 va_end(*args);
a687059c 1036
a687059c 1037 if (s[-1] != '\n') {
2304df62
AD
1038 if (dirty)
1039 strcpy(s, " during global destruction.\n");
1040 else {
1041 if (curcop->cop_line) {
1042 (void)sprintf(s," at %s line %ld",
1043 SvPVX(GvSV(curcop->cop_filegv)), (long)curcop->cop_line);
1044 s += strlen(s);
1045 }
c07a80fd 1046 if (GvIO(last_in_gv) && IoLINES(GvIOp(last_in_gv))) {
1047 bool line_mode = (RsSIMPLE(rs) &&
1048 SvLEN(rs) == 1 && *SvPVX(rs) == '\n');
2304df62
AD
1049 (void)sprintf(s,", <%s> %s %ld",
1050 last_in_gv == argvgv ? "" : GvNAME(last_in_gv),
c07a80fd 1051 line_mode ? "line" : "chunk",
a0d0e21e 1052 (long)IoLINES(GvIOp(last_in_gv)));
2304df62
AD
1053 s += strlen(s);
1054 }
1055 (void)strcpy(s,".\n");
f0c5b223 1056 s += 2;
a687059c 1057 }
de3bb511 1058 if (usermess)
79072805 1059 sv_catpv(tmpstr,buf+1);
a687059c 1060 }
de3bb511 1061
f0c5b223
TB
1062 if (s - s_start >= sizeof(buf)) { /* Ooops! */
1063 if (usermess)
760ac839 1064 PerlIO_puts(PerlIO_stderr(), SvPVX(tmpstr));
f0c5b223 1065 else
760ac839
LW
1066 PerlIO_puts(PerlIO_stderr(), buf);
1067 PerlIO_puts(PerlIO_stderr(), "panic: message overflow - memory corrupted!\n");
f0c5b223
TB
1068 my_exit(1);
1069 }
de3bb511 1070 if (usermess)
463ee0b2 1071 return SvPVX(tmpstr);
de3bb511
LW
1072 else
1073 return buf;
a687059c
LW
1074}
1075
ecfc5424 1076#ifdef I_STDARG
36477c24 1077OP *
1078die(char* pat, ...)
1079#else
1080/*VARARGS0*/
1081OP *
1082die(pat, va_alist)
1083 char *pat;
1084 va_dcl
1085#endif
1086{
1087 va_list args;
1088 char *message;
1089 int oldrunlevel = runlevel;
1090 int was_in_eval = in_eval;
1091 HV *stash;
1092 GV *gv;
1093 CV *cv;
1094
1095 /* We have to switch back to mainstack or die_where may try to pop
1096 * the eval block from the wrong stack if die is being called from a
1097 * signal handler. - dkindred@cs.cmu.edu */
1098 if (curstack != mainstack) {
1099 dSP;
1100 SWITCHSTACK(curstack, mainstack);
1101 }
1102
1103#ifdef I_STDARG
1104 va_start(args, pat);
1105#else
1106 va_start(args);
1107#endif
1108 message = mess(pat, &args);
1109 va_end(args);
1110
1111 if (diehook && (cv = sv_2cv(diehook, &stash, &gv, 0)) && !CvDEPTH(cv)) {
1112 dSP;
1113 SV *msg = sv_2mortal(newSVpv(message, 0));
1114
1115 PUSHMARK(sp);
1116 EXTEND(sp, 1);
1117 PUSHs(msg);
1118 PUTBACK;
1119 perl_call_sv((SV*)cv, G_DISCARD);
1120
1121 /* It's okay for the __DIE__ hook to modify the message. */
1122 message = SvPV(msg, na);
1123 }
1124
1125 restartop = die_where(message);
1126 if ((!restartop && was_in_eval) || oldrunlevel > 1)
1127 Siglongjmp(top_env, 3);
1128 return restartop;
1129}
1130
1131#ifdef I_STDARG
79072805 1132void
8990e307 1133croak(char* pat, ...)
463ee0b2 1134#else
8990e307
LW
1135/*VARARGS0*/
1136void
1137croak(pat, va_alist)
1138 char *pat;
1139 va_dcl
463ee0b2 1140#endif
a687059c
LW
1141{
1142 va_list args;
de3bb511 1143 char *message;
748a9306
LW
1144 HV *stash;
1145 GV *gv;
1146 CV *cv;
a687059c 1147
a0d0e21e 1148#ifdef I_STDARG
8990e307
LW
1149 va_start(args, pat);
1150#else
a687059c 1151 va_start(args);
8990e307 1152#endif
2304df62 1153 message = mess(pat, &args);
a687059c 1154 va_end(args);
20cec16a 1155 if (diehook) {
1156 SV *olddiehook = diehook;
1157 diehook = Nullsv; /* sv_2cv might call croak() */
1158 cv = sv_2cv(olddiehook, &stash, &gv, 0);
1159 diehook = olddiehook;
1160 if (cv && !CvDEPTH(cv)) {
1161 dSP;
36477c24 1162 SV *msg = sv_2mortal(newSVpv(message, 0));
20cec16a 1163
1164 PUSHMARK(sp);
1165 EXTEND(sp, 1);
36477c24 1166 PUSHs(msg);
20cec16a 1167 PUTBACK;
1168 perl_call_sv((SV*)cv, G_DISCARD);
36477c24 1169
1170 /* It's okay for the __DIE__ hook to modify the message. */
1171 message = SvPV(msg, na);
20cec16a 1172 }
748a9306 1173 }
a0d0e21e
LW
1174 if (in_eval) {
1175 restartop = die_where(message);
a5f75d66 1176 Siglongjmp(top_env, 3);
a0d0e21e 1177 }
760ac839
LW
1178 PerlIO_puts(PerlIO_stderr(),message);
1179 (void)PerlIO_flush(PerlIO_stderr());
38cd9116 1180 if (e_tmpname) {
1181 if (e_fp) {
760ac839 1182 PerlIO_close(e_fp);
38cd9116 1183 e_fp = Nullfp;
1184 }
a687059c 1185 (void)UNLINK(e_tmpname);
38cd9116 1186 Safefree(e_tmpname);
1187 e_tmpname = Nullch;
f0c5b223 1188 }
748a9306
LW
1189 statusvalue = SHIFTSTATUS(statusvalue);
1190#ifdef VMS
1191 my_exit((U32)(vaxc$errno?vaxc$errno:(statusvalue?statusvalue:44)));
1192#else
1193 my_exit((U32)((errno&255)?errno:((statusvalue&255)?statusvalue:255)));
1194#endif
a687059c
LW
1195}
1196
8990e307 1197void
ecfc5424 1198#ifdef I_STDARG
8990e307 1199warn(char* pat,...)
463ee0b2 1200#else
8990e307
LW
1201/*VARARGS0*/
1202warn(pat,va_alist)
1203 char *pat;
1204 va_dcl
463ee0b2 1205#endif
a687059c
LW
1206{
1207 va_list args;
de3bb511 1208 char *message;
748a9306
LW
1209 HV *stash;
1210 GV *gv;
1211 CV *cv;
a687059c 1212
a0d0e21e 1213#ifdef I_STDARG
8990e307
LW
1214 va_start(args, pat);
1215#else
a687059c 1216 va_start(args);
8990e307 1217#endif
2304df62 1218 message = mess(pat, &args);
a687059c
LW
1219 va_end(args);
1220
20cec16a 1221 if (warnhook) {
1222 SV *oldwarnhook = warnhook;
1223 warnhook = Nullsv; /* sv_2cv might end up calling warn() */
1224 cv = sv_2cv(oldwarnhook, &stash, &gv, 0);
1225 warnhook = oldwarnhook;
1226 if (cv && !CvDEPTH(cv)) {
1227 dSP;
1228
1229 PUSHMARK(sp);
1230 EXTEND(sp, 1);
1231 PUSHs(sv_2mortal(newSVpv(message,0)));
1232 PUTBACK;
1233 perl_call_sv((SV*)cv, G_DISCARD);
1234 return;
1235 }
748a9306 1236 }
20cec16a 1237 PerlIO_puts(PerlIO_stderr(),message);
a687059c 1238#ifdef LEAKTEST
20cec16a 1239 DEBUG_L(xstat());
a687059c 1240#endif
20cec16a 1241 (void)PerlIO_flush(PerlIO_stderr());
a687059c 1242}
8d063cd8 1243
a0d0e21e 1244#ifndef VMS /* VMS' my_setenv() is in VMS.c */
8d063cd8 1245void
7c0587c8 1246my_setenv(nam,val)
8d063cd8
LW
1247char *nam, *val;
1248{
79072805 1249 register I32 i=setenv_getix(nam); /* where does it go? */
8d063cd8 1250
fe14fcc3 1251 if (environ == origenviron) { /* need we copy environment? */
79072805
LW
1252 I32 j;
1253 I32 max;
fe14fcc3
LW
1254 char **tmpenv;
1255
de3bb511 1256 /*SUPPRESS 530*/
fe14fcc3
LW
1257 for (max = i; environ[max]; max++) ;
1258 New(901,tmpenv, max+2, char*);
1259 for (j=0; j<max; j++) /* copy environment */
a0d0e21e 1260 tmpenv[j] = savepv(environ[j]);
fe14fcc3
LW
1261 tmpenv[max] = Nullch;
1262 environ = tmpenv; /* tell exec where it is now */
1263 }
a687059c
LW
1264 if (!val) {
1265 while (environ[i]) {
1266 environ[i] = environ[i+1];
1267 i++;
1268 }
1269 return;
1270 }
8d063cd8 1271 if (!environ[i]) { /* does not exist yet */
fe14fcc3 1272 Renew(environ, i+2, char*); /* just expand it a bit */
8d063cd8
LW
1273 environ[i+1] = Nullch; /* make sure it's null terminated */
1274 }
fe14fcc3
LW
1275 else
1276 Safefree(environ[i]);
a687059c 1277 New(904, environ[i], strlen(nam) + strlen(val) + 2, char);
62b28dd9 1278#ifndef MSDOS
a687059c 1279 (void)sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
62b28dd9
LW
1280#else
1281 /* MS-DOS requires environment variable names to be in uppercase */
fe14fcc3
LW
1282 /* [Tom Dinger, 27 August 1990: Well, it doesn't _require_ it, but
1283 * some utilities and applications may break because they only look
1284 * for upper case strings. (Fixed strupr() bug here.)]
1285 */
1286 strcpy(environ[i],nam); strupr(environ[i]);
62b28dd9
LW
1287 (void)sprintf(environ[i] + strlen(nam),"=%s",val);
1288#endif /* MSDOS */
8d063cd8
LW
1289}
1290
79072805
LW
1291I32
1292setenv_getix(nam)
8d063cd8
LW
1293char *nam;
1294{
79072805 1295 register I32 i, len = strlen(nam);
8d063cd8
LW
1296
1297 for (i = 0; environ[i]; i++) {
1298 if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
1299 break; /* strnEQ must come first to avoid */
1300 } /* potential SEGV's */
1301 return i;
1302}
a0d0e21e 1303#endif /* !VMS */
378cc40b 1304
16d20bd9 1305#ifdef UNLINK_ALL_VERSIONS
79072805 1306I32
378cc40b
LW
1307unlnk(f) /* unlink all versions of a file */
1308char *f;
1309{
79072805 1310 I32 i;
378cc40b
LW
1311
1312 for (i = 0; unlink(f) >= 0; i++) ;
1313 return i ? 0 : -1;
1314}
1315#endif
1316
85e6fe83 1317#if !defined(HAS_BCOPY) || !defined(HAS_SAFE_BCOPY)
378cc40b 1318char *
7c0587c8 1319my_bcopy(from,to,len)
378cc40b
LW
1320register char *from;
1321register char *to;
79072805 1322register I32 len;
378cc40b
LW
1323{
1324 char *retval = to;
1325
7c0587c8
LW
1326 if (from - to >= 0) {
1327 while (len--)
1328 *to++ = *from++;
1329 }
1330 else {
1331 to += len;
1332 from += len;
1333 while (len--)
faf8582f 1334 *(--to) = *(--from);
7c0587c8 1335 }
378cc40b
LW
1336 return retval;
1337}
ffed7fef 1338#endif
378cc40b 1339
7c0587c8 1340#if !defined(HAS_BZERO) && !defined(HAS_MEMSET)
378cc40b 1341char *
7c0587c8 1342my_bzero(loc,len)
378cc40b 1343register char *loc;
79072805 1344register I32 len;
378cc40b
LW
1345{
1346 char *retval = loc;
1347
1348 while (len--)
1349 *loc++ = 0;
1350 return retval;
1351}
1352#endif
7c0587c8 1353
36477c24 1354#if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP)
79072805 1355I32
7c0587c8 1356my_memcmp(s1,s2,len)
36477c24 1357char *s1;
1358char *s2;
79072805 1359register I32 len;
7c0587c8 1360{
36477c24 1361 register U8 *a = (U8 *)s1;
1362 register U8 *b = (U8 *)s2;
79072805 1363 register I32 tmp;
7c0587c8
LW
1364
1365 while (len--) {
36477c24 1366 if (tmp = *a++ - *b++)
7c0587c8
LW
1367 return tmp;
1368 }
1369 return 0;
1370}
36477c24 1371#endif /* !HAS_MEMCMP || !HAS_SANE_MEMCMP */
a687059c 1372
4633a7c4 1373#if defined(I_STDARG) || defined(I_VARARGS)
fe14fcc3 1374#ifndef HAS_VPRINTF
a687059c 1375
85e6fe83 1376#ifdef USE_CHAR_VSPRINTF
a687059c
LW
1377char *
1378#else
1379int
1380#endif
1381vsprintf(dest, pat, args)
1382char *dest, *pat, *args;
1383{
1384 FILE fakebuf;
1385
1386 fakebuf._ptr = dest;
1387 fakebuf._cnt = 32767;
35c8bce7
LW
1388#ifndef _IOSTRG
1389#define _IOSTRG 0
1390#endif
a687059c
LW
1391 fakebuf._flag = _IOWRT|_IOSTRG;
1392 _doprnt(pat, args, &fakebuf); /* what a kludge */
1393 (void)putc('\0', &fakebuf);
85e6fe83 1394#ifdef USE_CHAR_VSPRINTF
a687059c
LW
1395 return(dest);
1396#else
1397 return 0; /* perl doesn't use return value */
1398#endif
1399}
1400
fe14fcc3 1401#endif /* HAS_VPRINTF */
4633a7c4 1402#endif /* I_VARARGS || I_STDARGS */
a687059c
LW
1403
1404#ifdef MYSWAP
ffed7fef 1405#if BYTEORDER != 0x4321
a687059c 1406short
748a9306 1407#ifndef CAN_PROTOTYPE
a687059c
LW
1408my_swap(s)
1409short s;
748a9306
LW
1410#else
1411my_swap(short s)
1412#endif
a687059c
LW
1413{
1414#if (BYTEORDER & 1) == 0
1415 short result;
1416
1417 result = ((s & 255) << 8) + ((s >> 8) & 255);
1418 return result;
1419#else
1420 return s;
1421#endif
1422}
1423
1424long
748a9306
LW
1425#ifndef CAN_PROTOTYPE
1426my_htonl(l)
a687059c 1427register long l;
748a9306
LW
1428#else
1429my_htonl(long l)
1430#endif
a687059c
LW
1431{
1432 union {
1433 long result;
ffed7fef 1434 char c[sizeof(long)];
a687059c
LW
1435 } u;
1436
ffed7fef 1437#if BYTEORDER == 0x1234
a687059c
LW
1438 u.c[0] = (l >> 24) & 255;
1439 u.c[1] = (l >> 16) & 255;
1440 u.c[2] = (l >> 8) & 255;
1441 u.c[3] = l & 255;
1442 return u.result;
1443#else
ffed7fef 1444#if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
463ee0b2 1445 croak("Unknown BYTEORDER\n");
a687059c 1446#else
79072805
LW
1447 register I32 o;
1448 register I32 s;
a687059c 1449
ffed7fef
LW
1450 for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
1451 u.c[o & 0xf] = (l >> s) & 255;
a687059c
LW
1452 }
1453 return u.result;
1454#endif
1455#endif
1456}
1457
1458long
748a9306
LW
1459#ifndef CAN_PROTOTYPE
1460my_ntohl(l)
a687059c 1461register long l;
748a9306
LW
1462#else
1463my_ntohl(long l)
1464#endif
a687059c
LW
1465{
1466 union {
1467 long l;
ffed7fef 1468 char c[sizeof(long)];
a687059c
LW
1469 } u;
1470
ffed7fef 1471#if BYTEORDER == 0x1234
a687059c
LW
1472 u.c[0] = (l >> 24) & 255;
1473 u.c[1] = (l >> 16) & 255;
1474 u.c[2] = (l >> 8) & 255;
1475 u.c[3] = l & 255;
1476 return u.l;
1477#else
ffed7fef 1478#if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
463ee0b2 1479 croak("Unknown BYTEORDER\n");
a687059c 1480#else
79072805
LW
1481 register I32 o;
1482 register I32 s;
a687059c
LW
1483
1484 u.l = l;
1485 l = 0;
ffed7fef
LW
1486 for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
1487 l |= (u.c[o & 0xf] & 255) << s;
a687059c
LW
1488 }
1489 return l;
1490#endif
1491#endif
1492}
1493
ffed7fef 1494#endif /* BYTEORDER != 0x4321 */
988174c1
LW
1495#endif /* MYSWAP */
1496
1497/*
1498 * Little-endian byte order functions - 'v' for 'VAX', or 'reVerse'.
1499 * If these functions are defined,
1500 * the BYTEORDER is neither 0x1234 nor 0x4321.
1501 * However, this is not assumed.
1502 * -DWS
1503 */
1504
1505#define HTOV(name,type) \
1506 type \
1507 name (n) \
1508 register type n; \
1509 { \
1510 union { \
1511 type value; \
1512 char c[sizeof(type)]; \
1513 } u; \
79072805
LW
1514 register I32 i; \
1515 register I32 s; \
988174c1
LW
1516 for (i = 0, s = 0; i < sizeof(u.c); i++, s += 8) { \
1517 u.c[i] = (n >> s) & 0xFF; \
1518 } \
1519 return u.value; \
1520 }
1521
1522#define VTOH(name,type) \
1523 type \
1524 name (n) \
1525 register type n; \
1526 { \
1527 union { \
1528 type value; \
1529 char c[sizeof(type)]; \
1530 } u; \
79072805
LW
1531 register I32 i; \
1532 register I32 s; \
988174c1
LW
1533 u.value = n; \
1534 n = 0; \
1535 for (i = 0, s = 0; i < sizeof(u.c); i++, s += 8) { \
1536 n += (u.c[i] & 0xFF) << s; \
1537 } \
1538 return n; \
1539 }
1540
1541#if defined(HAS_HTOVS) && !defined(htovs)
1542HTOV(htovs,short)
1543#endif
1544#if defined(HAS_HTOVL) && !defined(htovl)
1545HTOV(htovl,long)
1546#endif
1547#if defined(HAS_VTOHS) && !defined(vtohs)
1548VTOH(vtohs,short)
1549#endif
1550#if defined(HAS_VTOHL) && !defined(vtohl)
1551VTOH(vtohl,long)
1552#endif
a687059c 1553
55497cff 1554#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) \
1555 && !defined(VMS) /* VMS' my_popen() is in VMS.c, same with OS/2. */
760ac839 1556PerlIO *
79072805 1557my_popen(cmd,mode)
a687059c
LW
1558char *cmd;
1559char *mode;
1560{
1561 int p[2];
79072805
LW
1562 register I32 this, that;
1563 register I32 pid;
1564 SV *sv;
55497cff 1565 I32 doexec =
1566#ifdef AMIGAOS
1567 1;
1568#else
1569 strNE(cmd,"-");
1570#endif
a687059c 1571
ddcf38b7
IZ
1572#ifdef OS2
1573 if (doexec) {
1574 return my_syspopen(cmd,mode);
1575 }
1576#endif
a687059c
LW
1577 if (pipe(p) < 0)
1578 return Nullfp;
1579 this = (*mode == 'w');
1580 that = !this;
bbce6d69 1581 if (doexec && tainting) {
1582 taint_env();
1583 taint_proper("Insecure %s%s", "EXEC");
d48672a2 1584 }
a687059c
LW
1585 while ((pid = (doexec?vfork():fork())) < 0) {
1586 if (errno != EAGAIN) {
1587 close(p[this]);
1588 if (!doexec)
463ee0b2 1589 croak("Can't fork");
a687059c
LW
1590 return Nullfp;
1591 }
1592 sleep(5);
1593 }
1594 if (pid == 0) {
79072805
LW
1595 GV* tmpgv;
1596
a687059c
LW
1597#define THIS that
1598#define THAT this
1599 close(p[THAT]);
1600 if (p[THIS] != (*mode == 'r')) {
1601 dup2(p[THIS], *mode == 'r');
1602 close(p[THIS]);
1603 }
1604 if (doexec) {
a0d0e21e 1605#if !defined(HAS_FCNTL) || !defined(F_SETFD)
ae986130
LW
1606 int fd;
1607
1608#ifndef NOFILE
1609#define NOFILE 20
1610#endif
d48672a2 1611 for (fd = maxsysfd + 1; fd < NOFILE; fd++)
ae986130
LW
1612 close(fd);
1613#endif
a687059c
LW
1614 do_exec(cmd); /* may or may not use the shell */
1615 _exit(1);
1616 }
de3bb511 1617 /*SUPPRESS 560*/
85e6fe83 1618 if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
79072805 1619 sv_setiv(GvSV(tmpgv),(I32)getpid());
9f68db38 1620 forkprocess = 0;
463ee0b2 1621 hv_clear(pidstatus); /* we have no children */
a687059c
LW
1622 return Nullfp;
1623#undef THIS
1624#undef THAT
1625 }
62b28dd9 1626 do_execfree(); /* free any memory malloced by child on vfork */
a687059c 1627 close(p[that]);
62b28dd9
LW
1628 if (p[that] < p[this]) {
1629 dup2(p[this], p[that]);
1630 close(p[this]);
1631 p[this] = p[that];
1632 }
79072805 1633 sv = *av_fetch(fdpid,p[this],TRUE);
a0d0e21e 1634 (void)SvUPGRADE(sv,SVt_IV);
463ee0b2 1635 SvIVX(sv) = pid;
a687059c 1636 forkprocess = pid;
760ac839 1637 return PerlIO_fdopen(p[this], mode);
a687059c 1638}
7c0587c8 1639#else
55497cff 1640#if defined(atarist) || defined(DJGPP)
7c0587c8 1641FILE *popen();
760ac839 1642PerlIO *
79072805 1643my_popen(cmd,mode)
7c0587c8
LW
1644char *cmd;
1645char *mode;
1646{
760ac839 1647 /* Needs work for PerlIO ! */
55497cff 1648 /* used 0 for 2nd parameter to PerlIO-exportFILE; apparently not used */
1649 return popen(PerlIO_exportFILE(cmd, 0), mode);
7c0587c8
LW
1650}
1651#endif
1652
1653#endif /* !DOSISH */
a687059c 1654
748a9306 1655#ifdef DUMP_FDS
79072805 1656dump_fds(s)
ae986130
LW
1657char *s;
1658{
1659 int fd;
1660 struct stat tmpstatbuf;
1661
760ac839 1662 PerlIO_printf(PerlIO_stderr(),"%s", s);
ae986130 1663 for (fd = 0; fd < 32; fd++) {
a0d0e21e 1664 if (Fstat(fd,&tmpstatbuf) >= 0)
760ac839 1665 PerlIO_printf(PerlIO_stderr()," %d",fd);
ae986130 1666 }
760ac839 1667 PerlIO_printf(PerlIO_stderr(),"\n");
ae986130
LW
1668}
1669#endif
1670
fe14fcc3 1671#ifndef HAS_DUP2
fec02dd3 1672int
a687059c
LW
1673dup2(oldfd,newfd)
1674int oldfd;
1675int newfd;
1676{
a0d0e21e 1677#if defined(HAS_FCNTL) && defined(F_DUPFD)
fec02dd3
AD
1678 if (oldfd == newfd)
1679 return oldfd;
62b28dd9 1680 close(newfd);
fec02dd3 1681 return fcntl(oldfd, F_DUPFD, newfd);
62b28dd9 1682#else
d48672a2 1683 int fdtmp[256];
79072805 1684 I32 fdx = 0;
ae986130
LW
1685 int fd;
1686
fe14fcc3 1687 if (oldfd == newfd)
fec02dd3 1688 return oldfd;
a687059c 1689 close(newfd);
fec02dd3 1690 while ((fd = dup(oldfd)) != newfd && fd >= 0) /* good enough for low fd's */
ae986130
LW
1691 fdtmp[fdx++] = fd;
1692 while (fdx > 0)
1693 close(fdtmp[--fdx]);
fec02dd3 1694 return fd;
62b28dd9 1695#endif
a687059c
LW
1696}
1697#endif
1698
ff68c719 1699
1700#ifdef HAS_SIGACTION
1701
1702Sighandler_t
1703rsignal(signo, handler)
1704int signo;
1705Sighandler_t handler;
1706{
1707 struct sigaction act, oact;
1708
1709 act.sa_handler = handler;
1710 sigemptyset(&act.sa_mask);
1711 act.sa_flags = 0;
1712#ifdef SA_RESTART
1713 act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
1714#endif
1715 if (sigaction(signo, &act, &oact) == -1)
36477c24 1716 return SIG_ERR;
ff68c719 1717 else
36477c24 1718 return oact.sa_handler;
ff68c719 1719}
1720
1721Sighandler_t
1722rsignal_state(signo)
1723int signo;
1724{
1725 struct sigaction oact;
1726
1727 if (sigaction(signo, (struct sigaction *)NULL, &oact) == -1)
1728 return SIG_ERR;
1729 else
1730 return oact.sa_handler;
1731}
1732
1733int
1734rsignal_save(signo, handler, save)
1735int signo;
1736Sighandler_t handler;
1737Sigsave_t *save;
1738{
1739 struct sigaction act;
1740
1741 act.sa_handler = handler;
1742 sigemptyset(&act.sa_mask);
1743 act.sa_flags = 0;
1744#ifdef SA_RESTART
1745 act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
1746#endif
1747 return sigaction(signo, &act, save);
1748}
1749
1750int
1751rsignal_restore(signo, save)
1752int signo;
1753Sigsave_t *save;
1754{
1755 return sigaction(signo, save, (struct sigaction *)NULL);
1756}
1757
1758#else /* !HAS_SIGACTION */
1759
1760Sighandler_t
1761rsignal(signo, handler)
1762int signo;
1763Sighandler_t handler;
1764{
1765 return signal(signo, handler);
1766}
1767
1768static int sig_trapped;
1769
1770static
1771Signal_t
1772sig_trap(signo)
1773int signo;
1774{
1775 sig_trapped++;
1776}
1777
1778Sighandler_t
1779rsignal_state(signo)
1780int signo;
1781{
1782 Sighandler_t oldsig;
1783
1784 sig_trapped = 0;
1785 oldsig = signal(signo, sig_trap);
1786 signal(signo, oldsig);
1787 if (sig_trapped)
1788 kill(getpid(), signo);
1789 return oldsig;
1790}
1791
1792int
1793rsignal_save(signo, handler, save)
1794int signo;
1795Sighandler_t handler;
1796Sigsave_t *save;
1797{
1798 *save = signal(signo, handler);
1799 return (*save == SIG_ERR) ? -1 : 0;
1800}
1801
1802int
36477c24 1803rsignal_restore(signo, save)
ff68c719 1804int signo;
1805Sigsave_t *save;
1806{
1807 return (signal(signo, *save) == SIG_ERR) ? -1 : 0;
1808}
1809
1810#endif /* !HAS_SIGACTION */
1811
1812
55497cff 1813#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) \
1814 && !defined(VMS) /* VMS' my_popen() is in VMS.c */
79072805
LW
1815I32
1816my_pclose(ptr)
760ac839 1817PerlIO *ptr;
a687059c 1818{
ff68c719 1819 Sigsave_t hstat, istat, qstat;
a687059c 1820 int status;
a0d0e21e 1821 SV **svp;
20188a90 1822 int pid;
a687059c 1823
760ac839 1824 svp = av_fetch(fdpid,PerlIO_fileno(ptr),TRUE);
748a9306 1825 pid = (int)SvIVX(*svp);
a0d0e21e
LW
1826 SvREFCNT_dec(*svp);
1827 *svp = &sv_undef;
ddcf38b7
IZ
1828#ifdef OS2
1829 if (pid == -1) { /* Opened by popen. */
1830 return my_syspclose(ptr);
1831 }
1832#endif
760ac839 1833 PerlIO_close(ptr);
7c0587c8
LW
1834#ifdef UTS
1835 if(kill(pid, 0) < 0) { return(pid); } /* HOM 12/23/91 */
1836#endif
ff68c719 1837 rsignal_save(SIGHUP, SIG_IGN, &hstat);
1838 rsignal_save(SIGINT, SIG_IGN, &istat);
1839 rsignal_save(SIGQUIT, SIG_IGN, &qstat);
748a9306
LW
1840 do {
1841 pid = wait4pid(pid, &status, 0);
1842 } while (pid == -1 && errno == EINTR);
ff68c719 1843 rsignal_restore(SIGHUP, &hstat);
1844 rsignal_restore(SIGINT, &istat);
1845 rsignal_restore(SIGQUIT, &qstat);
20188a90
LW
1846 return(pid < 0 ? pid : status);
1847}
4633a7c4
LW
1848#endif /* !DOSISH */
1849
1850#if !defined(DOSISH) || defined(OS2)
79072805 1851I32
20188a90
LW
1852wait4pid(pid,statusp,flags)
1853int pid;
1854int *statusp;
1855int flags;
1856{
79072805
LW
1857 SV *sv;
1858 SV** svp;
20188a90
LW
1859 char spid[16];
1860
1861 if (!pid)
1862 return -1;
20188a90
LW
1863 if (pid > 0) {
1864 sprintf(spid, "%d", pid);
79072805
LW
1865 svp = hv_fetch(pidstatus,spid,strlen(spid),FALSE);
1866 if (svp && *svp != &sv_undef) {
463ee0b2 1867 *statusp = SvIVX(*svp);
748a9306 1868 (void)hv_delete(pidstatus,spid,strlen(spid),G_DISCARD);
20188a90
LW
1869 return pid;
1870 }
1871 }
1872 else {
79072805 1873 HE *entry;
20188a90 1874
79072805
LW
1875 hv_iterinit(pidstatus);
1876 if (entry = hv_iternext(pidstatus)) {
a0d0e21e 1877 pid = atoi(hv_iterkey(entry,(I32*)statusp));
79072805 1878 sv = hv_iterval(pidstatus,entry);
463ee0b2 1879 *statusp = SvIVX(sv);
20188a90 1880 sprintf(spid, "%d", pid);
748a9306 1881 (void)hv_delete(pidstatus,spid,strlen(spid),G_DISCARD);
20188a90
LW
1882 return pid;
1883 }
1884 }
79072805
LW
1885#ifdef HAS_WAITPID
1886 return waitpid(pid,statusp,flags);
1887#else
a0d0e21e
LW
1888#ifdef HAS_WAIT4
1889 return wait4((pid==-1)?0:pid,statusp,flags,Null(struct rusage *));
1890#else
1891 {
1892 I32 result;
1893 if (flags)
1894 croak("Can't do waitpid with flags");
1895 else {
1896 while ((result = wait(statusp)) != pid && pid > 0 && result >= 0)
1897 pidgone(result,*statusp);
1898 if (result < 0)
1899 *statusp = -1;
1900 }
1901 return result;
a687059c
LW
1902 }
1903#endif
20188a90 1904#endif
a687059c 1905}
7c0587c8 1906#endif /* !DOSISH */
a687059c 1907
7c0587c8 1908void
de3bb511 1909/*SUPPRESS 590*/
a687059c
LW
1910pidgone(pid,status)
1911int pid;
1912int status;
1913{
79072805 1914 register SV *sv;
20188a90 1915 char spid[16];
a687059c 1916
20188a90 1917 sprintf(spid, "%d", pid);
79072805 1918 sv = *hv_fetch(pidstatus,spid,strlen(spid),TRUE);
a0d0e21e 1919 (void)SvUPGRADE(sv,SVt_IV);
463ee0b2 1920 SvIVX(sv) = status;
20188a90 1921 return;
a687059c
LW
1922}
1923
55497cff 1924#if defined(atarist) || defined(OS2) || defined(DJGPP)
7c0587c8 1925int pclose();
ddcf38b7
IZ
1926#ifdef HAS_FORK
1927int /* Cannot prototype with I32
1928 in os2ish.h. */
1929my_syspclose(ptr)
1930#else
79072805
LW
1931I32
1932my_pclose(ptr)
ddcf38b7 1933#endif
760ac839 1934PerlIO *ptr;
a687059c 1935{
760ac839
LW
1936 /* Needs work for PerlIO ! */
1937 FILE *f = PerlIO_findFILE(ptr);
1938 I32 result = pclose(f);
1939 PerlIO_releaseFILE(ptr,f);
1940 return result;
a687059c 1941}
7c0587c8 1942#endif
9f68db38
LW
1943
1944void
1945repeatcpy(to,from,len,count)
1946register char *to;
1947register char *from;
79072805
LW
1948I32 len;
1949register I32 count;
9f68db38 1950{
79072805 1951 register I32 todo;
9f68db38
LW
1952 register char *frombase = from;
1953
1954 if (len == 1) {
1955 todo = *from;
1956 while (count-- > 0)
1957 *to++ = todo;
1958 return;
1959 }
1960 while (count-- > 0) {
1961 for (todo = len; todo > 0; todo--) {
1962 *to++ = *from++;
1963 }
1964 from = frombase;
1965 }
1966}
0f85fab0
LW
1967
1968#ifndef CASTNEGFLOAT
463ee0b2 1969U32
79072805 1970cast_ulong(f)
0f85fab0
LW
1971double f;
1972{
1973 long along;
1974
27e2fb84 1975#if CASTFLAGS & 2
34de22dd
LW
1976# define BIGDOUBLE 2147483648.0
1977 if (f >= BIGDOUBLE)
1978 return (unsigned long)(f-(long)(f/BIGDOUBLE)*BIGDOUBLE)|0x80000000;
1979#endif
0f85fab0
LW
1980 if (f >= 0.0)
1981 return (unsigned long)f;
1982 along = (long)f;
1983 return (unsigned long)along;
1984}
ed6116ce
LW
1985# undef BIGDOUBLE
1986#endif
1987
1988#ifndef CASTI32
5d94fbed 1989
5d94fbed
AD
1990/* Unfortunately, on some systems the cast_uv() function doesn't
1991 work with the system-supplied definition of ULONG_MAX. The
1992 comparison (f >= ULONG_MAX) always comes out true. It must be a
1993 problem with the compiler constant folding.
1994
1995 In any case, this workaround should be fine on any two's complement
1996 system. If it's not, supply a '-DMY_ULONG_MAX=whatever' in your
1997 ccflags.
1998 --Andy Dougherty <doughera@lafcol.lafayette.edu>
1999*/
1eb770ff 2000
2001/* Code modified to prefer proper named type ranges, I32, IV, or UV, instead
2002 of LONG_(MIN/MAX).
2003 -- Kenneth Albanowski <kjahds@kjahds.com>
2004*/
2005
20cec16a 2006#ifndef MY_UV_MAX
2007# define MY_UV_MAX ((UV)IV_MAX * (UV)2 + (UV)1)
5d94fbed
AD
2008#endif
2009
ed6116ce
LW
2010I32
2011cast_i32(f)
2012double f;
2013{
20cec16a 2014 if (f >= I32_MAX)
2015 return (I32) I32_MAX;
2016 if (f <= I32_MIN)
2017 return (I32) I32_MIN;
ed6116ce
LW
2018 return (I32) f;
2019}
a0d0e21e
LW
2020
2021IV
2022cast_iv(f)
2023double f;
2024{
20cec16a 2025 if (f >= IV_MAX)
2026 return (IV) IV_MAX;
2027 if (f <= IV_MIN)
2028 return (IV) IV_MIN;
a0d0e21e
LW
2029 return (IV) f;
2030}
5d94fbed
AD
2031
2032UV
2033cast_uv(f)
2034double f;
2035{
20cec16a 2036 if (f >= MY_UV_MAX)
2037 return (UV) MY_UV_MAX;
5d94fbed
AD
2038 return (UV) f;
2039}
2040
0f85fab0 2041#endif
62b28dd9 2042
fe14fcc3 2043#ifndef HAS_RENAME
79072805 2044I32
62b28dd9
LW
2045same_dirent(a,b)
2046char *a;
2047char *b;
2048{
93a17b20
LW
2049 char *fa = strrchr(a,'/');
2050 char *fb = strrchr(b,'/');
62b28dd9
LW
2051 struct stat tmpstatbuf1;
2052 struct stat tmpstatbuf2;
2053#ifndef MAXPATHLEN
2054#define MAXPATHLEN 1024
2055#endif
2056 char tmpbuf[MAXPATHLEN+1];
2057
2058 if (fa)
2059 fa++;
2060 else
2061 fa = a;
2062 if (fb)
2063 fb++;
2064 else
2065 fb = b;
2066 if (strNE(a,b))
2067 return FALSE;
2068 if (fa == a)
6eb13c3b 2069 strcpy(tmpbuf,".");
62b28dd9
LW
2070 else
2071 strncpy(tmpbuf, a, fa - a);
a0d0e21e 2072 if (Stat(tmpbuf, &tmpstatbuf1) < 0)
62b28dd9
LW
2073 return FALSE;
2074 if (fb == b)
6eb13c3b 2075 strcpy(tmpbuf,".");
62b28dd9
LW
2076 else
2077 strncpy(tmpbuf, b, fb - b);
a0d0e21e 2078 if (Stat(tmpbuf, &tmpstatbuf2) < 0)
62b28dd9
LW
2079 return FALSE;
2080 return tmpstatbuf1.st_dev == tmpstatbuf2.st_dev &&
2081 tmpstatbuf1.st_ino == tmpstatbuf2.st_ino;
2082}
fe14fcc3
LW
2083#endif /* !HAS_RENAME */
2084
55497cff 2085UV
79072805 2086scan_oct(start, len, retlen)
fe14fcc3 2087char *start;
79072805
LW
2088I32 len;
2089I32 *retlen;
fe14fcc3
LW
2090{
2091 register char *s = start;
55497cff 2092 register UV retval = 0;
2093 bool overflowed = FALSE;
fe14fcc3 2094
748a9306 2095 while (len && *s >= '0' && *s <= '7') {
55497cff 2096 register UV n = retval << 3;
2097 if (!overflowed && (n >> 3) != retval) {
2098 warn("Integer overflow in octal number");
2099 overflowed = TRUE;
2100 }
2101 retval = n | (*s++ - '0');
748a9306 2102 len--;
fe14fcc3 2103 }
748a9306
LW
2104 if (dowarn && len && (*s == '8' || *s == '9'))
2105 warn("Illegal octal digit ignored");
fe14fcc3
LW
2106 *retlen = s - start;
2107 return retval;
2108}
2109
2110unsigned long
79072805 2111scan_hex(start, len, retlen)
fe14fcc3 2112char *start;
79072805
LW
2113I32 len;
2114I32 *retlen;
fe14fcc3
LW
2115{
2116 register char *s = start;
55497cff 2117 register UV retval = 0;
2118 bool overflowed = FALSE;
fe14fcc3
LW
2119 char *tmp;
2120
93a17b20 2121 while (len-- && *s && (tmp = strchr(hexdigit, *s))) {
55497cff 2122 register UV n = retval << 4;
2123 if (!overflowed && (n >> 4) != retval) {
2124 warn("Integer overflow in hex number");
2125 overflowed = TRUE;
2126 }
2127 retval = n | (tmp - hexdigit) & 15;
fe14fcc3
LW
2128 s++;
2129 }
2130 *retlen = s - start;
2131 return retval;
2132}
760ac839
LW
2133
2134
2135#ifdef HUGE_VAL
2136/*
2137 * This hack is to force load of "huge" support from libm.a
2138 * So it is in perl for (say) POSIX to use.
2139 * Needed for SunOS with Sun's 'acc' for example.
2140 */
2141double
2142Perl_huge()
2143{
2144 return HUGE_VAL;
2145}
2146#endif