X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=util.c;h=c9960814408840e5e166161539095ee6c590b5dd;hb=8803afc236dca2c2990fc3236c7c43e710a099fb;hp=9da5b7b152902e60e776df99594cfb25ea6aaef2;hpb=7c06b590c066c6b354b0347a68bd9817268651b8;p=p5sagit%2Fp5-mst-13.2.git diff --git a/util.c b/util.c index 9da5b7b..c996081 100644 --- a/util.c +++ b/util.c @@ -14,6 +14,7 @@ #include "EXTERN.h" #include "perl.h" +#include "perlmem.h" #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX) #include @@ -53,12 +54,14 @@ #define FLUSH #ifdef LEAKTEST -static void xstat _((void)); -#endif -#ifdef USE_THREADS -static U32 threadnum = 0; -#endif /* USE_THREADS */ +static void xstat _((int)); +long xcount[MAXXCOUNT]; +long lastxcount[MAXXCOUNT]; +long xycount[MAXXCOUNT][MAXYCOUNT]; +long lastxycount[MAXXCOUNT][MAXYCOUNT]; + +#endif #ifndef MYMALLOC @@ -71,8 +74,7 @@ static U32 threadnum = 0; */ Malloc_t -safemalloc(size) -MEM_SIZE size; +safemalloc(MEM_SIZE size) { Malloc_t ptr; #ifdef HAS_64K_LIMIT @@ -85,7 +87,7 @@ MEM_SIZE size; if ((long)size < 0) croak("panic: malloc"); #endif - ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */ + ptr = PerlMem_malloc(size?size:1); /* malloc(0) is NASTY on our system */ #if !(defined(I286) || defined(atarist)) DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%x: (%05d) malloc %ld bytes\n",ptr,an++,(long)size)); #else @@ -98,6 +100,7 @@ MEM_SIZE size; else { PerlIO_puts(PerlIO_stderr(),no_mem) FLUSH; my_exit(1); + return Nullch; } /*NOTREACHED*/ } @@ -105,13 +108,11 @@ MEM_SIZE size; /* paranoid version of realloc */ Malloc_t -saferealloc(where,size) -Malloc_t where; -MEM_SIZE size; +saferealloc(Malloc_t where,MEM_SIZE size) { Malloc_t ptr; #if !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE) - Malloc_t realloc(); + Malloc_t PerlMem_realloc(); #endif /* !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE) */ #ifdef HAS_64K_LIMIT @@ -127,7 +128,7 @@ MEM_SIZE size; if ((long)size < 0) croak("panic: realloc"); #endif - ptr = realloc(where,size?size:1); /* realloc(0) is NASTY on our system */ + ptr = PerlMem_realloc(where,size?size:1); /* realloc(0) is NASTY on our system */ #if !(defined(I286) || defined(atarist)) DEBUG_m( { @@ -148,6 +149,7 @@ MEM_SIZE size; else { PerlIO_puts(PerlIO_stderr(),no_mem) FLUSH; my_exit(1); + return Nullch; } /*NOTREACHED*/ } @@ -155,26 +157,23 @@ MEM_SIZE size; /* safe version of free */ Free_t -safefree(where) -Malloc_t where; +safefree(Malloc_t where) { #if !(defined(I286) || defined(atarist)) - DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%x: (%05d) free\n",where,an++)); + DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%x: (%05d) free\n",(char *) where,an++)); #else - DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) free\n",where,an++)); + DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) free\n",(char *) where,an++)); #endif if (where) { /*SUPPRESS 701*/ - free(where); + PerlMem_free(where); } } /* safe version of calloc */ Malloc_t -safecalloc(count, size) -MEM_SIZE count; -MEM_SIZE size; +safecalloc(MEM_SIZE count, MEM_SIZE size) { Malloc_t ptr; @@ -190,7 +189,7 @@ MEM_SIZE size; croak("panic: calloc"); #endif size *= count; - ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */ + ptr = PerlMem_malloc(size?size:1); /* malloc(0) is NASTY on our system */ #if !(defined(I286) || defined(atarist)) DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%x: (%05d) calloc %ld x %ld bytes\n",ptr,an++,(long)count,(long)size)); #else @@ -205,6 +204,7 @@ MEM_SIZE size; else { PerlIO_puts(PerlIO_stderr(),no_mem) FLUSH; my_exit(1); + return Nullch; } /*NOTREACHED*/ } @@ -213,71 +213,141 @@ MEM_SIZE size; #ifdef LEAKTEST -#define ALIGN sizeof(long) +struct mem_test_strut { + union { + long type; + char c[2]; + } u; + long size; +}; + +# define ALIGN sizeof(struct mem_test_strut) + +# define sizeof_chunk(ch) (((struct mem_test_strut*) (ch))->size) +# define typeof_chunk(ch) \ + (((struct mem_test_strut*) (ch))->u.c[0] + ((struct mem_test_strut*) (ch))->u.c[1]*100) +# define set_typeof_chunk(ch,t) \ + (((struct mem_test_strut*) (ch))->u.c[0] = t % 100, ((struct mem_test_strut*) (ch))->u.c[1] = t / 100) +#define SIZE_TO_Y(size) ( (size) > MAXY_SIZE \ + ? MAXYCOUNT - 1 \ + : ( (size) > 40 \ + ? ((size) - 1)/8 + 5 \ + : ((size) - 1)/4)) Malloc_t -safexmalloc(x,size) -I32 x; -MEM_SIZE size; +safexmalloc(I32 x, MEM_SIZE size) { - register Malloc_t where; + register char* where = (char*)safemalloc(size + ALIGN); - where = safemalloc(size + ALIGN); - xcount[x]++; - where[0] = x % 100; - where[1] = x / 100; - return where + ALIGN; + xcount[x] += size; + xycount[x][SIZE_TO_Y(size)]++; + set_typeof_chunk(where, x); + sizeof_chunk(where) = size; + return (Malloc_t)(where + ALIGN); } Malloc_t -safexrealloc(where,size) -Malloc_t where; -MEM_SIZE size; +safexrealloc(Malloc_t wh, MEM_SIZE size) { - register Malloc_t new = saferealloc(where - ALIGN, size + ALIGN); - return new + ALIGN; + char *where = (char*)wh; + + if (!wh) + return safexmalloc(0,size); + + { + MEM_SIZE old = sizeof_chunk(where - ALIGN); + int t = typeof_chunk(where - ALIGN); + register char* new = (char*)saferealloc(where - ALIGN, size + ALIGN); + + xycount[t][SIZE_TO_Y(old)]--; + xycount[t][SIZE_TO_Y(size)]++; + xcount[t] += size - old; + sizeof_chunk(new) = size; + return (Malloc_t)(new + ALIGN); + } } void -safexfree(where) -Malloc_t where; +safexfree(Malloc_t wh) { I32 x; - + char *where = (char*)wh; + MEM_SIZE size; + if (!where) return; where -= ALIGN; + size = sizeof_chunk(where); x = where[0] + 100 * where[1]; - xcount[x]--; + xcount[x] -= size; + xycount[x][SIZE_TO_Y(size)]--; safefree(where); } Malloc_t -safexcalloc(x,count,size) -I32 x; -MEM_SIZE count; -MEM_SIZE size; +safexcalloc(I32 x,MEM_SIZE count, MEM_SIZE size) { - register Malloc_t where; - - where = safexmalloc(x, size * count + ALIGN); - xcount[x]++; - memset((void*)where + ALIGN, 0, size * count); - where[0] = x % 100; - where[1] = x / 100; - return where + ALIGN; + register char * where = (char*)safexmalloc(x, size * count + ALIGN); + xcount[x] += size; + xycount[x][SIZE_TO_Y(size)]++; + memset((void*)(where + ALIGN), 0, size * count); + set_typeof_chunk(where, x); + sizeof_chunk(where) = size; + return (Malloc_t)(where + ALIGN); } static void -xstat() +xstat(int flag) { - register I32 i; + register I32 i, j, total = 0; + I32 subtot[MAXYCOUNT]; + for (j = 0; j < MAXYCOUNT; j++) { + subtot[j] = 0; + } + + PerlIO_printf(PerlIO_stderr(), " Id subtot 4 8 12 16 20 24 28 32 36 40 48 56 64 72 80 80+\n", total); for (i = 0; i < MAXXCOUNT; i++) { - if (xcount[i] > lastxcount[i]) { - PerlIO_printf(PerlIO_stderr(),"%2d %2d\t%ld\n", i / 100, i % 100, xcount[i]); + total += xcount[i]; + for (j = 0; j < MAXYCOUNT; j++) { + subtot[j] += xycount[i][j]; + } + if (flag == 0 + ? xcount[i] /* Have something */ + : (flag == 2 + ? xcount[i] != lastxcount[i] /* Changed */ + : xcount[i] > lastxcount[i])) { /* Growed */ + PerlIO_printf(PerlIO_stderr(),"%2d %02d %7ld ", i / 100, i % 100, + flag == 2 ? xcount[i] - lastxcount[i] : xcount[i]); lastxcount[i] = xcount[i]; + for (j = 0; j < MAXYCOUNT; j++) { + if ( flag == 0 + ? xycount[i][j] /* Have something */ + : (flag == 2 + ? xycount[i][j] != lastxycount[i][j] /* Changed */ + : xycount[i][j] > lastxycount[i][j])) { /* Growed */ + PerlIO_printf(PerlIO_stderr(),"%3ld ", + flag == 2 + ? xycount[i][j] - lastxycount[i][j] + : xycount[i][j]); + lastxycount[i][j] = xycount[i][j]; + } else { + PerlIO_printf(PerlIO_stderr(), " . ", xycount[i][j]); + } + } + PerlIO_printf(PerlIO_stderr(), "\n"); + } + } + if (flag != 2) { + PerlIO_printf(PerlIO_stderr(), "Total %7ld ", total); + for (j = 0; j < MAXYCOUNT; j++) { + if (subtot[j]) { + PerlIO_printf(PerlIO_stderr(), "%3ld ", subtot[j]); + } else { + PerlIO_printf(PerlIO_stderr(), " . "); + } } + PerlIO_printf(PerlIO_stderr(), "\n"); } } @@ -286,13 +356,7 @@ xstat() /* copy a string up to some (non-backslashed) delimiter, if any */ char * -delimcpy(to, toend, from, fromend, delim, retlen) -register char *to; -register char *toend; -register char *from; -register char *fromend; -register int delim; -I32 *retlen; +delimcpy(register char *to, register char *toend, register char *from, register char *fromend, register int delim, I32 *retlen) { register I32 tolen; for (tolen = 0; from < fromend; from++, tolen++) { @@ -321,9 +385,7 @@ I32 *retlen; /* This routine was donated by Corey Satten. */ char * -instr(big, little) -register char *big; -register char *little; +instr(register char *big, register char *little) { register char *s, *x; register I32 first; @@ -353,11 +415,7 @@ register char *little; /* same as instr but allow embedded nulls */ char * -ninstr(big, bigend, little, lend) -register char *big; -register char *bigend; -char *little; -char *lend; +ninstr(register char *big, register char *bigend, char *little, char *lend) { register char *s, *x; register I32 first = *little; @@ -386,11 +444,7 @@ char *lend; /* reverse of the above--find last substring */ char * -rninstr(big, bigend, little, lend) -register char *big; -char *bigend; -char *little; -char *lend; +rninstr(register char *big, char *bigend, char *little, char *lend) { register char *bigbeg; register char *s, *x; @@ -420,8 +474,7 @@ char *lend; * Set up for a new ctype locale. */ void -perl_new_ctype(newctype) - char *newctype; +perl_new_ctype(char *newctype) { #ifdef USE_LOCALE_CTYPE @@ -443,8 +496,7 @@ perl_new_ctype(newctype) * Set up for a new collation locale. */ void -perl_new_collate(newcoll) - char *newcoll; +perl_new_collate(char *newcoll) { #ifdef USE_LOCALE_COLLATE @@ -488,8 +540,7 @@ perl_new_collate(newcoll) * Set up for a new numeric locale. */ void -perl_new_numeric(newnum) - char *newnum; +perl_new_numeric(char *newnum) { #ifdef USE_LOCALE_NUMERIC @@ -514,7 +565,7 @@ perl_new_numeric(newnum) } void -perl_set_numeric_standard() +perl_set_numeric_standard(void) { #ifdef USE_LOCALE_NUMERIC @@ -528,7 +579,7 @@ perl_set_numeric_standard() } void -perl_set_numeric_local() +perl_set_numeric_local(void) { #ifdef USE_LOCALE_NUMERIC @@ -546,8 +597,7 @@ perl_set_numeric_local() * Initialize locale awareness. */ int -perl_init_i18nl10n(printwarn) - int printwarn; +perl_init_i18nl10n(int printwarn) { int ok = 1; /* returns @@ -567,8 +617,8 @@ perl_init_i18nl10n(printwarn) #ifdef USE_LOCALE_NUMERIC char *curnum = NULL; #endif /* USE_LOCALE_NUMERIC */ - char *lc_all = getenv("LC_ALL"); - char *lang = getenv("LANG"); + char *lc_all = PerlEnv_getenv("LC_ALL"); + char *lang = PerlEnv_getenv("LANG"); bool setlocale_failure = FALSE; #ifdef LOCALE_ENVIRON_REQUIRED @@ -592,19 +642,19 @@ perl_init_i18nl10n(printwarn) { #ifdef USE_LOCALE_CTYPE if (! (curctype = setlocale(LC_CTYPE, - (!done && (lang || getenv("LC_CTYPE"))) + (!done && (lang || PerlEnv_getenv("LC_CTYPE"))) ? "" : Nullch))) setlocale_failure = TRUE; #endif /* USE_LOCALE_CTYPE */ #ifdef USE_LOCALE_COLLATE if (! (curcoll = setlocale(LC_COLLATE, - (!done && (lang || getenv("LC_COLLATE"))) + (!done && (lang || PerlEnv_getenv("LC_COLLATE"))) ? "" : Nullch))) setlocale_failure = TRUE; #endif /* USE_LOCALE_COLLATE */ #ifdef USE_LOCALE_NUMERIC if (! (curnum = setlocale(LC_NUMERIC, - (!done && (lang || getenv("LC_NUMERIC"))) + (!done && (lang || PerlEnv_getenv("LC_NUMERIC"))) ? "" : Nullch))) setlocale_failure = TRUE; #endif /* USE_LOCALE_NUMERIC */ @@ -651,7 +701,7 @@ perl_init_i18nl10n(printwarn) char *p; bool locwarn = (printwarn > 1 || printwarn && - (!(p = getenv("PERL_BADLANG")) || atoi(p))); + (!(p = PerlEnv_getenv("PERL_BADLANG")) || atoi(p))); if (locwarn) { #ifdef LC_ALL @@ -776,8 +826,7 @@ perl_init_i18nl10n(printwarn) /* Backwards compatibility. */ int -perl_init_i18nl14n(printwarn) - int printwarn; +perl_init_i18nl14n(int printwarn) { return perl_init_i18nl10n(printwarn); } @@ -792,10 +841,7 @@ perl_init_i18nl14n(printwarn) * Please see sv_collxfrm() to see how this is used. */ char * -mem_collxfrm(s, len, xlen) - const char *s; - STRLEN len; - STRLEN *xlen; +mem_collxfrm(const char *s, STRLEN len, STRLEN *xlen) { char *xbuf; STRLEN xalloc, xin, xout; @@ -845,8 +891,7 @@ mem_collxfrm(s, len, xlen) #endif /* USE_LOCALE_COLLATE */ void -fbm_compile(sv) -SV *sv; +fbm_compile(SV *sv, U32 flags /* not used yet */) { register unsigned char *s; register unsigned char *table; @@ -855,22 +900,24 @@ SV *sv; I32 rarest = 0; U32 frequency = 256; - if (len > 255) + sv_upgrade(sv, SVt_PVBM); + if (len > 255 || len == 0) /* TAIL might be on on a zero-length string. */ return; /* can't have offsets that big */ - Sv_Grow(sv,len+258); - table = (unsigned char*)(SvPVX(sv) + len + 1); - s = table - 2; - for (i = 0; i < 256; i++) { - table[i] = len; - } - i = 0; - while (s >= (unsigned char*)(SvPVX(sv))) - { - if (table[*s] == len) - table[*s] = i; - s--,i++; + if (len > 2) { + Sv_Grow(sv,len + 258); + table = (unsigned char*)(SvPVX(sv) + len + 1); + s = table - 2; + for (i = 0; i < 256; i++) { + table[i] = len; + } + i = 0; + while (s >= (unsigned char*)(SvPVX(sv))) + { + if (table[*s] == len) + table[*s] = i; + s--,i++; + } } - sv_upgrade(sv, SVt_PVBM); sv_magic(sv, Nullsv, 'B', Nullch, 0); /* deep magic */ SvVALID_on(sv); @@ -887,10 +934,7 @@ SV *sv; } char * -fbm_instr(big, bigend, littlestr) -unsigned char *big; -register unsigned char *bigend; -SV *littlestr; +fbm_instr(unsigned char *big, register unsigned char *bigend, SV *littlestr) { register unsigned char *s; register I32 tmp; @@ -903,8 +947,23 @@ SV *littlestr; if (SvTYPE(littlestr) != SVt_PVBM || !SvVALID(littlestr)) { STRLEN len; char *l = SvPV(littlestr,len); - if (!len) + if (!len) { + if (SvTAIL(littlestr)) { /* Can be only 0-len constant + substr => we can ignore SvVALID */ + if (multiline) { + char *t = "\n"; + if ((s = (unsigned char*)ninstr((char*)big, (char*)bigend, + t, t + len))) { + return (char*)s; + } + } + if (bigend > big && bigend[-1] == '\n') + return (char *)(bigend - 1); + else + return (char *) bigend; + } return (char*)big; + } return ninstr((char*)big,(char*)bigend, l, l + len); } @@ -914,13 +973,32 @@ SV *littlestr; return Nullch; little = (unsigned char*)SvPVX(littlestr); s = bigend - littlelen; - if (*s == *little && memEQ((char*)s,(char*)little,littlelen)) + if (s > big + && bigend[-1] == '\n' + && s[-1] == *little && memEQ((char*)s - 1,(char*)little,littlelen)) + return (char*)s - 1; /* how sweet it is */ + else if (*s == *little && memEQ((char*)s,(char*)little,littlelen)) return (char*)s; /* how sweet it is */ - else if (bigend[-1] == '\n' && little[littlelen-1] != '\n' - && s > big) { - s--; - if (*s == *little && memEQ((char*)s,(char*)little,littlelen)) + return Nullch; + } + if (littlelen <= 2) { + unsigned char c1 = (unsigned char)SvPVX(littlestr)[0]; + unsigned char c2 = (unsigned char)SvPVX(littlestr)[1]; + /* This may do extra comparisons if littlelen == 2, but this + should be hidden in the noise since we do less indirection. */ + + s = big; + bigend -= littlelen; + while (s <= bigend) { + if (s[0] == c1 + && (littlelen == 1 || s[1] == c2) + && (!SvTAIL(littlestr) + || s == bigend + || s[littlelen] == '\n')) /* Automatically multiline */ + { return (char*)s; + } + s++; } return Nullch; } @@ -950,22 +1028,35 @@ SV *littlestr; while (tmp--) { if (*--s == *--little) continue; + differ: s = olds + 1; /* here we pay the price for failure */ little = oldlittle; if (s < bigend) /* fake up continue to outer loop */ goto top2; return Nullch; } + if (SvTAIL(littlestr) /* automatically multiline */ + && olds + 1 != bigend + && olds[1] != '\n') + goto differ; return (char *)s; } } return Nullch; } +/* start_shift, end_shift are positive quantities which give offsets + of ends of some substring of bigstr. + If `last' we want the last occurence. + old_posp is the way of communication between consequent calls if + the next call needs to find the . + The initial *old_posp should be -1. + Note that we do not take into account SvTAIL, so it may give wrong + positives if _ALL flag is set. + */ + char * -screaminstr(bigstr, littlestr) -SV *bigstr; -SV *littlestr; +screaminstr(SV *bigstr, SV *littlestr, I32 start_shift, I32 end_shift, I32 *old_posp, I32 last) { register unsigned char *s, *x; register unsigned char *big; @@ -973,60 +1064,69 @@ SV *littlestr; register I32 previous; register I32 first; register unsigned char *little; - register unsigned char *bigend; + register I32 stop_pos; register unsigned char *littleend; + I32 found = 0; - if ((pos = screamfirst[BmRARE(littlestr)]) < 0) + if (*old_posp == -1 + ? (pos = screamfirst[BmRARE(littlestr)]) < 0 + : (((pos = *old_posp), pos += screamnext[pos]) == 0)) return Nullch; little = (unsigned char *)(SvPVX(littlestr)); littleend = little + SvCUR(littlestr); first = *little++; + /* The value of pos we can start at: */ previous = BmPREVIOUS(littlestr); big = (unsigned char *)(SvPVX(bigstr)); - bigend = big + SvCUR(bigstr); - while (pos < previous) { + /* The value of pos we can stop at: */ + stop_pos = SvCUR(bigstr) - end_shift - (SvCUR(littlestr) - 1 - previous); + if (previous + start_shift > stop_pos) return Nullch; + while (pos < previous + start_shift) { if (!(pos += screamnext[pos])) return Nullch; } #ifdef POINTERRIGOR do { + if (pos >= stop_pos) return Nullch; if (big[pos-previous] != first) continue; for (x=big+pos+1-previous,s=little; s < littleend; /**/ ) { - if (x >= bigend) - return Nullch; if (*s++ != *x++) { s--; break; } } - if (s == littleend) - return (char *)(big+pos-previous); + if (s == littleend) { + *old_posp = pos; + if (!last) return (char *)(big+pos-previous); + found = 1; + } } while ( pos += screamnext[pos] ); + return (last && found) ? (char *)(big+(*old_posp)-previous) : Nullch; #else /* !POINTERRIGOR */ big -= previous; do { + if (pos >= stop_pos) return Nullch; if (big[pos] != first) continue; for (x=big+pos+1,s=little; s < littleend; /**/ ) { - if (x >= bigend) - return Nullch; if (*s++ != *x++) { s--; break; } } - if (s == littleend) - return (char *)(big+pos); + if (s == littleend) { + *old_posp = pos; + if (!last) return (char *)(big+pos); + found = 1; + } } while ( pos += screamnext[pos] ); + return (last && found) ? (char *)(big+(*old_posp)) : Nullch; #endif /* POINTERRIGOR */ - return Nullch; } I32 -ibcmp(s1, s2, len) -char *s1, *s2; -register I32 len; +ibcmp(char *s1, char *s2, register I32 len) { register U8 *a = (U8 *)s1; register U8 *b = (U8 *)s2; @@ -1039,9 +1139,7 @@ register I32 len; } I32 -ibcmp_locale(s1, s2, len) -char *s1, *s2; -register I32 len; +ibcmp_locale(char *s1, char *s2, register I32 len) { register U8 *a = (U8 *)s1; register U8 *b = (U8 *)s2; @@ -1056,8 +1154,7 @@ register I32 len; /* copy a string to a safe spot */ char * -savepv(sv) -char *sv; +savepv(char *sv) { register char *newaddr; @@ -1069,9 +1166,7 @@ char *sv; /* same thing but with a known length */ char * -savepvn(sv, len) -char *sv; -register I32 len; +savepvn(char *sv, register I32 len) { register char *newaddr; @@ -1084,7 +1179,7 @@ register I32 len; /* the SV for form() and mess() is not kept in an arena */ static SV * -mess_alloc() +mess_alloc(void) { SV *sv; XPVMG *any; @@ -1123,9 +1218,7 @@ form(pat, va_alist) } char * -mess(pat, args) - const char *pat; - va_list *args; +mess(const char *pat, va_list *args) { SV *sv; static char dgd[] = " during global destruction.\n"; @@ -1180,13 +1273,6 @@ die(pat, va_alist) "%p: die: curstack = %p, mainstack = %p\n", thr, curstack, mainstack)); #endif /* USE_THREADS */ - /* We have to switch back to mainstack or die_where may try to pop - * the eval block from the wrong stack if die is being called from a - * signal handler. - dkindred@cs.cmu.edu */ - if (curstack != mainstack) { - dSP; - SWITCHSTACK(curstack, mainstack); - } #ifdef I_STDARG va_start(args, pat); @@ -1218,7 +1304,7 @@ die(pat, va_alist) SvREADONLY_on(msg); SAVEFREESV(msg); - PUSHMARK(sp); + PUSHMARK(SP); XPUSHs(msg); PUTBACK; perl_call_sv((SV*)cv, G_DISCARD); @@ -1283,7 +1369,7 @@ croak(pat, va_alist) SvREADONLY_on(msg); SAVEFREESV(msg); - PUSHMARK(sp); + PUSHMARK(SP); XPUSHs(msg); PUTBACK; perl_call_sv((SV*)cv, G_DISCARD); @@ -1342,7 +1428,7 @@ warn(pat,va_alist) SvREADONLY_on(msg); SAVEFREESV(msg); - PUSHMARK(sp); + PUSHMARK(SP); XPUSHs(msg); PUTBACK; perl_call_sv((SV*)cv, G_DISCARD); @@ -1353,7 +1439,12 @@ warn(pat,va_alist) } PerlIO_puts(PerlIO_stderr(),message); #ifdef LEAKTEST - DEBUG_L(xstat()); + DEBUG_L(*message == '!' + ? (xstat(message[1]=='!' + ? (message[2]=='!' ? 2 : 1) + : 0) + , 0) + : 0); #endif (void)PerlIO_flush(PerlIO_stderr()); } @@ -1361,8 +1452,7 @@ warn(pat,va_alist) #ifndef VMS /* VMS' my_setenv() is in VMS.c */ #ifndef WIN32 void -my_setenv(nam,val) -char *nam, *val; +my_setenv(char *nam, char *val) { register I32 i=setenv_getix(nam); /* where does it go? */ @@ -1410,8 +1500,7 @@ char *nam, *val; #else /* if WIN32 */ void -my_setenv(nam,val) -char *nam, *val; +my_setenv(char *nam,char *val) { #ifdef USE_WIN32_RTL_ENV @@ -1445,7 +1534,7 @@ char *nam, *val; vallen = strlen(val); New(904, envstr, namlen + vallen + 3, char); (void)sprintf(envstr,"%s=%s",nam,val); - (void)putenv(envstr); + (void)PerlEnv_putenv(envstr); if (oldstr) Safefree(oldstr); #ifdef _MSC_VER @@ -1476,8 +1565,7 @@ char *nam, *val; #endif /* WIN32 */ I32 -setenv_getix(nam) -char *nam; +setenv_getix(char *nam) { register I32 i, len = strlen(nam); @@ -1503,17 +1591,14 @@ char *f; { I32 i; - for (i = 0; unlink(f) >= 0; i++) ; + for (i = 0; PerlLIO_unlink(f) >= 0; i++) ; return i ? 0 : -1; } #endif #if !defined(HAS_BCOPY) || !defined(HAS_SAFE_BCOPY) char * -my_bcopy(from,to,len) -register char *from; -register char *to; -register I32 len; +my_bcopy(register char *from,register char *to,register I32 len) { char *retval = to; @@ -1615,12 +1700,7 @@ char *args; #ifdef MYSWAP #if BYTEORDER != 0x4321 short -#ifndef CAN_PROTOTYPE -my_swap(s) -short s; -#else my_swap(short s) -#endif { #if (BYTEORDER & 1) == 0 short result; @@ -1633,12 +1713,7 @@ my_swap(short s) } long -#ifndef CAN_PROTOTYPE -my_htonl(l) -register long l; -#else my_htonl(long l) -#endif { union { long result; @@ -1667,12 +1742,7 @@ my_htonl(long l) } long -#ifndef CAN_PROTOTYPE -my_ntohl(l) -register long l; -#else my_ntohl(long l) -#endif { union { long l; @@ -1765,12 +1835,10 @@ VTOH(vtohl,long) /* VMS' my_popen() is in VMS.c, same with OS/2. */ #if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) PerlIO * -my_popen(cmd,mode) -char *cmd; -char *mode; +my_popen(char *cmd, char *mode) { int p[2]; - register I32 this, that; + register I32 This, that; register I32 pid; SV *sv; I32 doexec = strNE(cmd,"-"); @@ -1780,17 +1848,17 @@ char *mode; return my_syspopen(cmd,mode); } #endif - if (pipe(p) < 0) - return Nullfp; - this = (*mode == 'w'); - that = !this; + This = (*mode == 'w'); + that = !This; if (doexec && tainting) { taint_env(); taint_proper("Insecure %s%s", "EXEC"); } + if (PerlProc_pipe(p) < 0) + return Nullfp; while ((pid = (doexec?vfork():fork())) < 0) { if (errno != EAGAIN) { - close(p[this]); + PerlLIO_close(p[This]); if (!doexec) croak("Can't fork"); return Nullfp; @@ -1801,11 +1869,11 @@ char *mode; GV* tmpgv; #define THIS that -#define THAT this - close(p[THAT]); +#define THAT This + PerlLIO_close(p[THAT]); if (p[THIS] != (*mode == 'r')) { - dup2(p[THIS], *mode == 'r'); - close(p[THIS]); + PerlLIO_dup2(p[THIS], *mode == 'r'); + PerlLIO_close(p[THIS]); } if (doexec) { #if !defined(HAS_FCNTL) || !defined(F_SETFD) @@ -1815,10 +1883,10 @@ char *mode; #define NOFILE 20 #endif for (fd = maxsysfd + 1; fd < NOFILE; fd++) - close(fd); + PerlLIO_close(fd); #endif do_exec(cmd); /* may or may not use the shell */ - _exit(1); + PerlProc__exit(1); } /*SUPPRESS 560*/ if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV)) @@ -1830,17 +1898,17 @@ char *mode; #undef THAT } do_execfree(); /* free any memory malloced by child on vfork */ - close(p[that]); - if (p[that] < p[this]) { - dup2(p[this], p[that]); - close(p[this]); - p[this] = p[that]; + PerlLIO_close(p[that]); + if (p[that] < p[This]) { + PerlLIO_dup2(p[This], p[that]); + PerlLIO_close(p[This]); + p[This] = p[that]; } - sv = *av_fetch(fdpid,p[this],TRUE); + sv = *av_fetch(fdpid,p[This],TRUE); (void)SvUPGRADE(sv,SVt_IV); SvIVX(sv) = pid; forkprocess = pid; - return PerlIO_fdopen(p[this], mode); + return PerlIO_fdopen(p[This], mode); } #else #if defined(atarist) || defined(DJGPP) @@ -1867,7 +1935,7 @@ char *s; PerlIO_printf(PerlIO_stderr(),"%s", s); for (fd = 0; fd < 32; fd++) { - if (Fstat(fd,&tmpstatbuf) >= 0) + if (PerlLIO_fstat(fd,&tmpstatbuf) >= 0) PerlIO_printf(PerlIO_stderr()," %d",fd); } PerlIO_printf(PerlIO_stderr(),"\n"); @@ -1883,7 +1951,7 @@ int newfd; #if defined(HAS_FCNTL) && defined(F_DUPFD) if (oldfd == newfd) return oldfd; - close(newfd); + PerlLIO_close(newfd); return fcntl(oldfd, F_DUPFD, newfd); #else #define DUP2_MAX_FDS 256 @@ -1893,18 +1961,18 @@ int newfd; if (oldfd == newfd) return oldfd; - close(newfd); + PerlLIO_close(newfd); /* good enough for low fd's... */ - while ((fd = dup(oldfd)) != newfd && fd >= 0) { + while ((fd = PerlLIO_dup(oldfd)) != newfd && fd >= 0) { if (fdx >= DUP2_MAX_FDS) { - close(fd); + PerlLIO_close(fd); fd = -1; break; } fdtmp[fdx++] = fd; } while (fdx > 0) - close(fdtmp[--fdx]); + PerlLIO_close(fdtmp[--fdx]); return fd; #endif } @@ -1914,9 +1982,7 @@ int newfd; #ifdef HAS_SIGACTION Sighandler_t -rsignal(signo, handler) -int signo; -Sighandler_t handler; +rsignal(int signo, Sighandler_t handler) { struct sigaction act, oact; @@ -1933,8 +1999,7 @@ Sighandler_t handler; } Sighandler_t -rsignal_state(signo) -int signo; +rsignal_state(int signo) { struct sigaction oact; @@ -1945,10 +2010,7 @@ int signo; } int -rsignal_save(signo, handler, save) -int signo; -Sighandler_t handler; -Sigsave_t *save; +rsignal_save(int signo, Sighandler_t handler, Sigsave_t *save) { struct sigaction act; @@ -1962,9 +2024,7 @@ Sigsave_t *save; } int -rsignal_restore(signo, save) -int signo; -Sigsave_t *save; +rsignal_restore(int signo, Sigsave_t *save) { return sigaction(signo, save, (struct sigaction *)NULL); } @@ -1972,53 +2032,44 @@ Sigsave_t *save; #else /* !HAS_SIGACTION */ Sighandler_t -rsignal(signo, handler) -int signo; -Sighandler_t handler; +rsignal(int signo, Sighandler_t handler) { - return signal(signo, handler); + return PerlProc_signal(signo, handler); } static int sig_trapped; static Signal_t -sig_trap(signo) -int signo; +sig_trap(int signo) { sig_trapped++; } Sighandler_t -rsignal_state(signo) -int signo; +rsignal_state(int signo) { Sighandler_t oldsig; sig_trapped = 0; - oldsig = signal(signo, sig_trap); - signal(signo, oldsig); + oldsig = PerlProc_signal(signo, sig_trap); + PerlProc_signal(signo, oldsig); if (sig_trapped) - kill(getpid(), signo); + PerlProc_kill(getpid(), signo); return oldsig; } int -rsignal_save(signo, handler, save) -int signo; -Sighandler_t handler; -Sigsave_t *save; +rsignal_save(int signo, Sighandler_t handler, Sigsave_t *save) { - *save = signal(signo, handler); + *save = PerlProc_signal(signo, handler); return (*save == SIG_ERR) ? -1 : 0; } int -rsignal_restore(signo, save) -int signo; -Sigsave_t *save; +rsignal_restore(int signo, Sigsave_t *save) { - return (signal(signo, *save) == SIG_ERR) ? -1 : 0; + return (PerlProc_signal(signo, *save) == SIG_ERR) ? -1 : 0; } #endif /* !HAS_SIGACTION */ @@ -2026,8 +2077,7 @@ Sigsave_t *save; /* VMS' my_pclose() is in VMS.c; same with OS/2 */ #if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) I32 -my_pclose(ptr) -PerlIO *ptr; +my_pclose(PerlIO *ptr) { Sigsave_t hstat, istat, qstat; int status; @@ -2038,6 +2088,9 @@ PerlIO *ptr; #ifdef VMS int saved_vaxc_errno; #endif +#ifdef WIN32 + int saved_win32_errno; +#endif svp = av_fetch(fdpid,PerlIO_fileno(ptr),TRUE); pid = (int)SvIVX(*svp); @@ -2053,9 +2106,12 @@ PerlIO *ptr; #ifdef VMS saved_vaxc_errno = vaxc$errno; #endif +#ifdef WIN32 + saved_win32_errno = GetLastError(); +#endif } #ifdef UTS - if(kill(pid, 0) < 0) { return(pid); } /* HOM 12/23/91 */ + if(PerlProc_kill(pid, 0) < 0) { return(pid); } /* HOM 12/23/91 */ #endif rsignal_save(SIGHUP, SIG_IGN, &hstat); rsignal_save(SIGINT, SIG_IGN, &istat); @@ -2074,12 +2130,9 @@ PerlIO *ptr; } #endif /* !DOSISH */ -#if !defined(DOSISH) || defined(OS2) +#if !defined(DOSISH) || defined(OS2) || defined(WIN32) I32 -wait4pid(pid,statusp,flags) -int pid; -int *statusp; -int flags; +wait4pid(int pid, int *statusp, int flags) { SV *sv; SV** svp; @@ -2135,13 +2188,11 @@ int flags; } #endif } -#endif /* !DOSISH */ +#endif /* !DOSISH || OS2 || WIN32 */ void /*SUPPRESS 590*/ -pidgone(pid,status) -int pid; -int status; +pidgone(int pid, int status) { register SV *sv; char spid[TYPE_CHARS(int)]; @@ -2174,11 +2225,7 @@ PerlIO *ptr; #endif void -repeatcpy(to,from,len,count) -register char *to; -register char *from; -I32 len; -register I32 count; +repeatcpy(register char *to, register char *from, I32 len, register I32 count) { register I32 todo; register char *frombase = from; @@ -2298,13 +2345,13 @@ char *b; sv_setpv(tmpsv, "."); else sv_setpvn(tmpsv, a, fa - a); - if (Stat(SvPVX(tmpsv), &tmpstatbuf1) < 0) + if (PerlLIO_stat(SvPVX(tmpsv), &tmpstatbuf1) < 0) return FALSE; if (fb == b) sv_setpv(tmpsv, "."); else sv_setpvn(tmpsv, b, fb - b); - if (Stat(SvPVX(tmpsv), &tmpstatbuf2) < 0) + if (PerlLIO_stat(SvPVX(tmpsv), &tmpstatbuf2) < 0) return FALSE; return tmpstatbuf1.st_dev == tmpstatbuf2.st_dev && tmpstatbuf1.st_ino == tmpstatbuf2.st_ino; @@ -2312,10 +2359,7 @@ char *b; #endif /* !HAS_RENAME */ UV -scan_oct(start, len, retlen) -char *start; -I32 len; -I32 *retlen; +scan_oct(char *start, I32 len, I32 *retlen) { register char *s = start; register UV retval = 0; @@ -2337,23 +2381,20 @@ I32 *retlen; } UV -scan_hex(start, len, retlen) -char *start; -I32 len; -I32 *retlen; +scan_hex(char *start, I32 len, I32 *retlen) { register char *s = start; register UV retval = 0; bool overflowed = FALSE; char *tmp; - while (len-- && *s && (tmp = strchr(hexdigit, *s))) { + while (len-- && *s && (tmp = strchr((char *) hexdigit, *s))) { register UV n = retval << 4; if (!overflowed && (n >> 4) != retval) { warn("Integer overflow in hex number"); overflowed = TRUE; } - retval = n | (tmp - hexdigit) & 15; + retval = n | ((tmp - hexdigit) & 15); s++; } *retlen = s - start; @@ -2380,7 +2421,7 @@ void perl_cond_signal(cp) perl_cond *cp; { - perl_thread t; + perl_os_thread t; perl_cond cond = *cp; if (!cond) @@ -2401,7 +2442,7 @@ void perl_cond_broadcast(cp) perl_cond *cp; { - perl_thread t; + perl_os_thread t; perl_cond cond, cond_next; for (cond = *cp; cond; cond = cond_next) { @@ -2440,20 +2481,19 @@ perl_cond *cp; #endif /* FAKE_THREADS */ #ifdef OLD_PTHREADS_API -struct thread * +struct perl_thread * getTHR _((void)) { pthread_addr_t t; if (pthread_getspecific(thr_key, &t)) croak("panic: pthread_getspecific"); - return (struct thread *) t; + return (struct perl_thread *) t; } #endif /* OLD_PTHREADS_API */ MAGIC * -condpair_magic(sv) -SV *sv; +condpair_magic(SV *sv) { MAGIC *mg; @@ -2467,11 +2507,11 @@ SV *sv; COND_INIT(&cp->owner_cond); COND_INIT(&cp->cond); cp->owner = 0; - MUTEX_LOCK(&sv_mutex); + LOCK_SV_MUTEX; mg = mg_find(sv, 'm'); if (mg) { /* someone else beat us to initialising it */ - MUTEX_UNLOCK(&sv_mutex); + UNLOCK_SV_MUTEX; MUTEX_DESTROY(&cp->mutex); COND_DESTROY(&cp->owner_cond); COND_DESTROY(&cp->cond); @@ -2482,7 +2522,7 @@ SV *sv; mg = SvMAGIC(sv); mg->mg_ptr = (char *)cp; mg->mg_len = sizeof(cp); - MUTEX_UNLOCK(&sv_mutex); + UNLOCK_SV_MUTEX; DEBUG_L(WITH_THR(PerlIO_printf(PerlIO_stderr(), "%p: condpair_magic %p\n", thr, sv));) } @@ -2497,21 +2537,20 @@ SV *sv; * called. The use by ext/Thread/Thread.xs in core perl (where t is the * thread calling new_struct_thread) clearly satisfies this constraint. */ -struct thread * -new_struct_thread(t) -struct thread *t; +struct perl_thread * +new_struct_thread(struct perl_thread *t) { - struct thread *thr; + struct perl_thread *thr; SV *sv; SV **svp; I32 i; sv = newSVpv("", 0); - SvGROW(sv, sizeof(struct thread) + 1); - SvCUR_set(sv, sizeof(struct thread)); + SvGROW(sv, sizeof(struct perl_thread) + 1); + SvCUR_set(sv, sizeof(struct perl_thread)); thr = (Thread) SvPVX(sv); /* debug */ - memset(thr, 0xab, sizeof(struct thread)); + memset(thr, 0xab, sizeof(struct perl_thread)); markstack = 0; scopestack = 0; savestack = 0; @@ -2525,8 +2564,10 @@ struct thread *t; curcop = &compiling; thr->cvcache = newHV(); - thr->magicals = newAV(); + thr->threadsv = newAV(); thr->specific = newAV(); + thr->errsv = newSVpv("", 0); + thr->errhv = newHV(); thr->flags = THRf_R_JOINABLE; MUTEX_INIT(&thr->mutex); @@ -2564,18 +2605,18 @@ struct thread *t; bodytarget = newSVsv(t->Tbodytarget); toptarget = newSVsv(t->Ttoptarget); - /* Initialise all per-thread magicals that the template thread used */ - svp = AvARRAY(t->magicals); - for (i = 0; i <= AvFILL(t->magicals); i++, svp++) { + /* Initialise all per-thread SVs that the template thread used */ + svp = AvARRAY(t->threadsv); + for (i = 0; i <= AvFILLp(t->threadsv); i++, svp++) { if (*svp && *svp != &sv_undef) { SV *sv = newSVsv(*svp); - av_store(thr->magicals, i, sv); - sv_magic(sv, 0, 0, &per_thread_magicals[i], 1); + av_store(thr->threadsv, i, sv); + sv_magic(sv, 0, 0, &threadsv_names[i], 1); DEBUG_L(PerlIO_printf(PerlIO_stderr(), - "new_struct_thread: copied magical %d %p->%p\n",i, - t, thr)); + "new_struct_thread: copied threadsv %d %p->%p\n",i, t, thr)); } } + thr->threadsvp = AvARRAY(thr->threadsv); MUTEX_LOCK(&threads_mutex); nthreads++; @@ -2586,20 +2627,9 @@ struct thread *t; thr->next->prev = thr; MUTEX_UNLOCK(&threads_mutex); -/* - * This is highly suspect - new_struct_thread is executed - * by creating thread so pthread_self() or equivalent - * is parent thread not the child. - * In particular this should _NOT_ change dTHR value of calling thread. - * - * But a good place to have a 'hook' for filling in port-private - * fields of thr. - */ -#ifdef INIT_THREAD_INTERN - INIT_THREAD_INTERN(thr); -#else - thr->self = pthread_self(); -#endif /* INIT_THREAD_INTERN */ +#ifdef HAVE_THREAD_INTERN + init_thread_intern(thr); +#endif /* HAVE_THREAD_INTERN */ return thr; } #endif /* USE_THREADS */ @@ -2611,8 +2641,28 @@ struct thread *t; * Needed for SunOS with Sun's 'acc' for example. */ double -Perl_huge() +Perl_huge(void) { return HUGE_VAL; } #endif + +#ifdef PERL_GLOBAL_STRUCT +struct perl_vars * +Perl_GetVars(void) +{ + return &Perl_Vars; +} +#endif + +char ** +get_op_names(void) +{ + return op_name; +} + +char ** +get_op_descs(void) +{ + return op_desc; +}