diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 1997-12-13 05:57:13 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 1997-12-13 05:57:13 +0000 |
commit | f3022b429d0c08fdcadfe0f1de24a48240ed6d19 (patch) | |
tree | a031535913a35aa954adfd1cb360134e3b6d44e1 | |
parent | 83921c945db40515d7fed77f435f5b7be4efe5d4 (diff) | |
parent | 4352c2672c688f561f692cdbaf9109f32e58a795 (diff) | |
download | perl-f3022b429d0c08fdcadfe0f1de24a48240ed6d19.tar.gz |
[win32] Integrate mainline. Builds and passes (Borland).
p4raw-id: //depot/win32/perl@363
-rwxr-xr-x | Configure | 149 | ||||
-rw-r--r-- | README.threads | 6 | ||||
-rw-r--r-- | config_h.SH | 12 | ||||
-rw-r--r-- | doop.c | 12 | ||||
-rw-r--r-- | ext/DynaLoader/dl_aix.xs | 59 | ||||
-rw-r--r-- | global.sym | 4 | ||||
-rw-r--r-- | hints/aix.sh | 21 | ||||
-rw-r--r-- | op.c | 5 | ||||
-rw-r--r-- | op.h | 3 | ||||
-rw-r--r-- | perl.h | 1 | ||||
-rw-r--r-- | perlvars.h | 8 | ||||
-rw-r--r-- | pp_hot.c | 2 | ||||
-rw-r--r-- | pp_sys.c | 2 | ||||
-rw-r--r-- | sv.c | 53 | ||||
-rw-r--r-- | sv.h | 9 | ||||
-rw-r--r-- | thread.h | 1 | ||||
-rw-r--r-- | util.c | 65 |
17 files changed, 268 insertions, 144 deletions
@@ -493,6 +493,7 @@ i_netdb='' i_neterrno='' i_niin='' i_sysin='' +d_pthreads_created_joinable='' d_pwage='' d_pwchange='' d_pwclass='' @@ -603,7 +604,6 @@ installprivlib='' privlib='' privlibexp='' prototype='' -pthreads_created_joinable='' randbits='' installscript='' scriptdir='' @@ -2099,8 +2099,15 @@ esac rp='What is your architecture name' . ./myread case "$usethreads" in -$define) archname="$ans-thread" - echo "usethreads selected... architecture name is now $archname." >&4 +$define) echo "Threads selected." >&4 + case "$ans" in + *-thread) echo "...and architecture name already ends in -thread." >&4 + archname="$ans" + ;; + *) archname="$ans-thread" + echo "...setting architecture name to $archname." >&4 + ;; + esac ;; *) archname="$ans" ;; esac @@ -6613,10 +6620,6 @@ eval $inlibc set gethostbyaddr d_gethbadd eval $inlibc -: see if getnetbyaddr exists -set getnetbyaddr d_getnbadd -eval $inlibc - : see if gethostent exists set gethostent d_gethent eval $inlibc @@ -6625,6 +6628,10 @@ eval $inlibc set getlogin d_getlogin eval $inlibc +: see if getnetbyaddr exists +set getnetbyaddr d_getnbadd +eval $inlibc + : see if getpgid exists set getpgid d_getpgid eval $inlibc @@ -8552,24 +8559,6 @@ EOM *) groupstype="$gidtype";; esac -case "$usethreads" in -$define) - - : see if sched_yield exists - set sched_yield d_sched_yield - eval $inlibc - - : see if pthread_yield exists - set pthread_yield d_pthread_yield - eval $inlibc - - ;; -*) - d_sched_yield=$undef - d_pthread_yield=$undef - ;; -esac - : see what type lseek is declared as in the kernel set off_t lseektype long stdio.h sys/types.h eval $typedef @@ -9289,8 +9278,10 @@ EOCP if $cc $ccflags -c -DGethbadd_addr_t="$xxx" -DGethbadd_alen_t="$yyy" try.c >/dev/null 2>&1 ; then gethbadd_addr_type="$xxx" gethbadd_alen_type="$yyy" - echo "Your system uses $xxx for the 1st argument to gethostbyaddr." >&4 - echo "and the the 2nd argument to gethostbyaddr is $yyy." >&4 + $cat >&4 <<EOM +Your system uses $xxx for the 1st argument to gethostbyaddr. +and the 2nd argument to gethostbyaddr is $yyy. +EOM break fi done @@ -9311,6 +9302,11 @@ EOCP gethbadd_alen_type="$ans" fi $rm -f try.[co] + else + $cat >&4 <<EOM +Your system uses $gethbadd_addr_type for the 1st argument to gethostbyaddr. +and the 2nd argument to gethostbyaddr is $gethbadd_alen_type. +EOM fi ;; *) gethbadd_addr_type='void *' @@ -9323,7 +9319,7 @@ esac : getnetbyaddr. case "$d_getnbadd" in $define) - if test "X$getnbadd_addr_type" = X -o "X$getnbadd_alen_type" = X; then + if test "X$getnbadd_net_type" = X; then $cat <<EOM Checking to see what type of arguments are expected by getnetbyaddr(). @@ -9370,6 +9366,8 @@ EOCP getnbadd_net_type="$ans" fi $rm -f try.[co] + else + echo "Your system uses $getnbadd_net_type for the 1st argument to getnetbyaddr." >&4 fi ;; *) getnbadd_net_type='long' @@ -9919,51 +9917,84 @@ eval $setvar : test whether pthreads are created in joinable -- aka undetached -- state if test "X$usethreads" != X; then -echo " " -echo 'Checking whether pthreads are created joinable.' >&4 + if test "X$d_pthreads_created_joinable" = X; then + echo >&4 "Checking whether pthreads are created joinable." $cat >try.c <<EOCP -/* Note: this program returns 1 if detached, 0 if not. - * Easier this way because the PTHREAD_CREATE_DETACHED is more - * portable than the obsolete PTHREAD_CREATE_UNDETACHED. - * Testing for joinable (aka undetached) as opposed to detached - * is then again logically more sensible because that's - * the more modern default state in the pthreads implementations. */ #include <pthread.h> #include <stdio.h> int main() { pthread_attr_t attr; int detachstate; - pthread_attr_init(&attr); - pthread_attr_getdetachstate(&attr, &detachstate); printf("%s\n", - detachstate == PTHREAD_CREATE_DETACHED ? - "detached" : "joinable"); + pthread_attr_init(&attr) == 0 && + pthread_attr_getdetachstate(&attr, &detachstate) == 0 && + detachstate == PTHREAD_CREATE_DETACHED ? + "detached" : "joinable"); exit(0); } EOCP - if $cc $ccflags $ldflags -o try try.c $libs >/dev/null 2>&1; then - yyy=`./try` - else - echo "(I can't seem to compile the test program--assuming they are.)" - yyy=joinable + : Compile and link separately because the used cc might not be + : able to link the right CRT and libs for pthreading. + if $cc $ccflags -c try.c >/dev/null 2>&1 && + $ld $ldflags -o try try$obj_ext $libs >/dev/null 2>&1; then + yyy=`./try` + else + echo "(I can't execute the test program--assuming they are.)" + yyy=joinable + fi + case "$yyy" in + detached) + val="$undef" + echo "Nope, they aren't." + ;; + *) + val="$define" + echo "Yup, they are." + ;; + esac + set d_pthreads_created_joinable + eval $setvar + $rm -f try try.* fi - case "$yyy" in - joinable) - val="$define" - echo "Yup, they are." - ;; - *) - val="$undef" - echo "Nope, they aren't." - ;; - esac - set d_pthreads_created_joinable - eval $setvar - $rm -f try try.* else d_pthreads_created_joinable=$undef fi +: see whether the various POSIXish _yields exist within given cccmd +$cat >try.c <<EOP +#include <pthread.h> +main() { + YIELD(); + exit(0); +} +EOP +: see if pthread_yield exists within given cccmd, +: if we do not usethreads this may well end up undef. +if $cc $ccflags -DYIELD=pthread_yield $ldflags -o try try.c $libs > /dev/null 2>&1; then + val="$define" + echo 'pthread_yield() found.' >&4 +else + val="$undef" + echo 'pthread_yield() NOT found.' >&4 +fi +set d_pthread_yield +eval $setvar + +: see if sched_yield exists within given cccmd, +: if we do not usethreads this may well end up undef. +if $cc $ccflags -DYIELD=sched_yield $ldflags -o try try.c $libs > /dev/null 2>&1; then + val="$define" + echo 'sched_yield() found.' >&4 +else + val="$undef" + echo 'sched_yield() NOT found.' >&4 +fi +set d_sched_yield +eval $setvar + +: common to both the pthread_yield and sched_yield tests +rm -f try try.* + echo " " echo "Looking for extensions..." >&4 cd ../ext @@ -10340,6 +10371,7 @@ d_pipe='$d_pipe' d_poll='$d_poll' d_portable='$d_portable' d_pthread_yield='$d_pthread_yield' +d_pthreads_created_joinable='$d_pthreads_created_joinable' d_pwage='$d_pwage' d_pwchange='$d_pwchange' d_pwclass='$d_pwclass' @@ -10608,7 +10640,6 @@ prefixexp='$prefixexp' privlib='$privlib' privlibexp='$privlibexp' prototype='$prototype' -pthreads_created_joinable='$pthreads_created_joinable' randbits='$randbits' ranlib='$ranlib' rd_nodata='$rd_nodata' diff --git a/README.threads b/README.threads index 427f38ad74..db54f7a1ce 100644 --- a/README.threads +++ b/README.threads @@ -70,6 +70,12 @@ For IRIX: For IRIX 6.3 and 6.4 the pthreads should work out of the box. Thanks to Hannu Napari <Hannu.Napari@hut.fi> for the IRIX pthreads patches information. +For AIX: + Change cc to xlc_r or cc_r. + Add -DUSE_THREADS -DNEED_PTHREAD_INIT -DDEBUGGING to ccflags and cppflags + Change optimize to -g + Add -lc_r to libswanted + Change -lc in lddflags to be -lpthread -lc_r -lc Now you can do a make diff --git a/config_h.SH b/config_h.SH index 7b625e3119..33009ab3c2 100644 --- a/config_h.SH +++ b/config_h.SH @@ -572,12 +572,6 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un- */ #$d_pthread_yield HAS_PTHREAD_YIELD -/* HAS_SCHED_YIELD: - * This symbol, if defined, indicates that the sched_yield routine is - * available to yield the execution of the current thread. - */ -#$d_sched_yield HAS_SCHED_YIELD - /* HAS_READDIR: * This symbol, if defined, indicates that the readdir routine is * available to read directory entries. You may have to include @@ -585,6 +579,12 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un- */ #$d_readdir HAS_READDIR /**/ +/* HAS_SCHED_YIELD: + * This symbol, if defined, indicates that the sched_yield + * routine is available to yield the execution of the current thread. + */ +#$d_sched_yield HAS_SCHED_YIELD + /* HAS_SEEKDIR: * This symbol, if defined, indicates that the seekdir routine is * available. You may have to include <dirent.h>. See I_DIRENT. @@ -31,7 +31,7 @@ do_trans(SV *sv, OP *arg) register I32 squash = op->op_private & OPpTRANS_SQUASH; STRLEN len; - if (SvREADONLY(sv)) + if (SvREADONLY(sv) && !(op->op_private & OPpTRANS_COUNTONLY)) croak(no_modify); tbl = (short*)cPVOP->op_pv; s = (U8*)SvPV(sv, len); @@ -52,6 +52,14 @@ do_trans(SV *sv, OP *arg) } s++; } + SvSETMAGIC(sv); + } + else if (op->op_private & OPpTRANS_COUNTONLY) { + while (s < send) { + if (tbl[*s] >= 0) + matches++; + s++; + } } else { d = s; @@ -74,8 +82,8 @@ do_trans(SV *sv, OP *arg) matches += send - d; /* account for disappeared chars */ *d = '\0'; SvCUR_set(sv, d - (U8*)SvPVX(sv)); + SvSETMAGIC(sv); } - SvSETMAGIC(sv); return matches; } diff --git a/ext/DynaLoader/dl_aix.xs b/ext/DynaLoader/dl_aix.xs index 548fe41a9c..4e865edd3b 100644 --- a/ext/DynaLoader/dl_aix.xs +++ b/ext/DynaLoader/dl_aix.xs @@ -77,16 +77,63 @@ static int readExports(ModulePtr); static void terminate(void); static void *findMain(void); +static char *strerror_failed = "(strerror failed)"; +static char *strerror_r_failed = "(strerror_r failed)"; + char *strerrorcat(char *str, int err) { - char buf[8192]; - strerror_r(err, buf, sizeof(buf)); - strcat(str,buf); + int strsiz = strlen(str); + int msgsiz; + char *msg; + +#ifdef USE_THREADS + char *buf = malloc(BUFSIZ); + + if (buf == 0) + return 0; + if (strerror_r(err, buf, sizeof(buf)) == 0) + msg = buf; + else + msg = strerror_r_failed; + msgsiz = strlen(msg); + if (strsiz + msgsiz < BUFSIZ) + strcat(str, msg); + free(buf); +#else + if ((msg = strerror(err)) == 0) + msg = strerror_failed; + msgsiz = strlen(msg); /* Note msg = buf and free() above. */ + if (strsiz + msgsiz < BUFSIZ) /* Do not move this after #endif. */ + strcat(str, msg); +#endif + return str; } + char *strerrorcpy(char *str, int err) { - char buf[8192]; - strerror_r(err, buf, sizeof(buf)); - strcpy(str,buf); + int msgsiz; + char *msg; + +#ifdef USE_THREADS + char *buf = malloc(BUFSIZ); + + if (buf == 0) + return 0; + if (strerror_r(err, buf, sizeof(buf)) == 0) + msg = buf; + else + msg = strerror_r_failed; + msgsiz = strlen(msg); + if (msgsiz < BUFSIZ) + strcpy(str, msg); + free(buf); +#else + if ((msg = strerror(err)) == 0) + msg = strerror_failed; + msgsiz = strlen(msg); /* Note msg = buf and free() above. */ + if (msgsiz < BUFSIZ) /* Do not move this after #endif. */ + strcpy(str, msg); +#endif + return str; } diff --git a/global.sym b/global.sym index 8b8c922bbf..969f752ab6 100644 --- a/global.sym +++ b/global.sym @@ -81,11 +81,8 @@ psig_name psig_ptr rcsid reall_srchlen -regdump regexec_flags regkind -regnext -regprop repeat_amg repeat_ass_amg rshift_amg @@ -881,7 +878,6 @@ q ref refkids regdump -regexec_flags regnext regprop repeatcpy diff --git a/hints/aix.sh b/hints/aix.sh index 41706ac3a6..569a292870 100644 --- a/hints/aix.sh +++ b/hints/aix.sh @@ -84,24 +84,19 @@ if [ "X$usethreads" != "X" ]; then xlc_r | cc_r) ;; cc | '') - cc=xlc_r + cc=xlc_r # Let us be stricter. ;; *) - case "$cc" in - gcc) - echo >&4 "You cannot use POSIX threads from GNU cc in AIX." - ;; - *) - echo >&4 "Unknown C compiler." - ;; - esac - echo >&4 "You should use the AIX C compilers called xlc_r or cc_r." - echo >&4 "Cannot continue, aborting." + cat >&4 <<EOM +Unknown C compiler '$cc'. +For pthreads you should use the AIX C compilers xlc_r or cc_r. +Cannot continue, aborting. +EOM exit 1 ;; esac - # Add the POSIX threads library and use the re-entrant libc. + # Add the POSIX threads library and the re-entrant libc. - lddlflags=`echo $lddlflags | sed 's/ -lc$/ -lpthreads -lc_r/'` + lddlflags=`echo $lddlflags | sed 's/ -lc$/ -lpthreads -lc_r -lc/'` fi @@ -1993,12 +1993,13 @@ pmtrans(OP *o, OP *expr, OP *repl) register I32 j; I32 Delete; I32 complement; + I32 squash; register short *tbl; tbl = (short*)cPVOPo->op_pv; complement = o->op_private & OPpTRANS_COMPLEMENT; Delete = o->op_private & OPpTRANS_DELETE; - /* squash = o->op_private & OPpTRANS_SQUASH; */ + squash = o->op_private & OPpTRANS_SQUASH; if (complement) { Zero(tbl, 256, short); @@ -2022,6 +2023,8 @@ pmtrans(OP *o, OP *expr, OP *repl) else { if (!rlen && !Delete) { r = t; rlen = tlen; + if (!squash) + o->op_private |= OPpTRANS_COUNTONLY; } for (i = 0; i < 256; i++) tbl[i] = -1; @@ -95,6 +95,7 @@ typedef U32 PADOFFSET; #define OPpRUNTIME 64 /* Pattern coming in on the stack */ /* Private for OP_TRANS */ +#define OPpTRANS_COUNTONLY 8 #define OPpTRANS_SQUASH 16 #define OPpTRANS_DELETE 32 #define OPpTRANS_COMPLEMENT 64 @@ -274,6 +275,8 @@ struct loop { #define OA_DEFGV 128 /* The next 4 bits encode op class information */ +#define OA_CLASS_MASK (15 << 8) + #define OA_BASEOP (0 << 8) #define OA_UNOP (1 << 8) #define OA_BINOP (2 << 8) @@ -979,6 +979,7 @@ typedef I32 (*filter_t) _((int, SV *, int)); # include <win32thread.h> # else # include <pthread.h> +typedef pthread_t perl_os_thread; typedef pthread_mutex_t perl_mutex; typedef pthread_cond_t perl_cond; typedef pthread_key_t perl_key; diff --git a/perlvars.h b/perlvars.h index b58ea16728..8a72312e57 100644 --- a/perlvars.h +++ b/perlvars.h @@ -158,8 +158,8 @@ PERLVARI(Gnumeric_local, bool, TRUE) /* Assume local numerics */ #endif /* !USE_LOCALE_NUMERIC */ /* constants (these are not literals to facilitate pointer comparisons) */ -PERLVARIC(GYes, char *, "1"); -PERLVARIC(GNo, char *, ""); -PERLVARIC(Ghexdigit, char *, "0123456789abcdef0123456789ABCDEFx"); -PERLVARIC(Gpatleave, char *, "\\.^$@dDwWsSbB+*?|()-nrtfeaxc0123456789[{]}"); +PERLVARIC(GYes, char *, "1") +PERLVARIC(GNo, char *, "") +PERLVARIC(Ghexdigit, char *, "0123456789abcdef0123456789ABCDEFx") +PERLVARIC(Gpatleave, char *, "\\.^$@dDwWsSbB+*?|()-nrtfeaxc0123456789[{]}") @@ -297,7 +297,7 @@ PP(pp_print) gv = defoutgv; if (SvMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) { if (MARK == ORIGMARK) { - EXTEND(SP, 1); + MEXTEND(SP, 1); ++MARK; Move(MARK, MARK + 1, (SP - MARK) + 1, SV*); ++SP; @@ -1147,7 +1147,7 @@ PP(pp_prtf) if (SvMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) { if (MARK == ORIGMARK) { - EXTEND(SP, 1); + MEXTEND(SP, 1); ++MARK; Move(MARK, MARK + 1, (SP - MARK) + 1, SV*); ++SP; @@ -1084,7 +1084,6 @@ sv_grow(SV* sv, unsigned long newlen) void sv_setiv(register SV *sv, IV i) { - dTHR; /* just for taint */ sv_check_thinkfirst(sv); switch (SvTYPE(sv)) { case SVt_NULL: @@ -1132,7 +1131,6 @@ sv_setuv(register SV *sv, UV u) void sv_setnv(register SV *sv, double num) { - dTHR; /* just for taint */ sv_check_thinkfirst(sv); switch (SvTYPE(sv)) { case SVt_NULL: @@ -1247,9 +1245,11 @@ sv_2iv(register SV *sv) if (SvPOKp(sv) && SvLEN(sv)) return asIV(sv); if (!SvROK(sv)) { - dTHR; /* just for localizing */ - if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) - warn(warn_uninit); + if (dowarn && !(SvFLAGS(sv) & SVs_PADTMP)) { + dTHR; + if (!localizing) + warn(warn_uninit); + } return 0; } } @@ -1323,9 +1323,11 @@ sv_2uv(register SV *sv) if (SvPOKp(sv) && SvLEN(sv)) return asUV(sv); if (!SvROK(sv)) { - dTHR; /* just for localizing */ - if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) - warn(warn_uninit); + if (dowarn && !(SvFLAGS(sv) & SVs_PADTMP)) { + dTHR; + if (!localizing) + warn(warn_uninit); + } return 0; } } @@ -1369,9 +1371,11 @@ sv_2uv(register SV *sv) SvUVX(sv) = asUV(sv); } else { - dTHR; /* just for localizing */ - if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) - warn(warn_uninit); + if (dowarn && !(SvFLAGS(sv) & SVs_PADTMP)) { + dTHR; + if (!localizing) + warn(warn_uninit); + } return 0; } DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2uv(%lu)\n", @@ -1397,9 +1401,11 @@ sv_2nv(register SV *sv) if (SvIOKp(sv)) return (double)SvIVX(sv); if (!SvROK(sv)) { - dTHR; /* just for localizing */ - if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) - warn(warn_uninit); + if (dowarn && !(SvFLAGS(sv) & SVs_PADTMP)) { + dTHR; + if (!localizing) + warn(warn_uninit); + } return 0; } } @@ -1603,9 +1609,11 @@ sv_2pv(register SV *sv, STRLEN *lp) goto tokensave; } if (!SvROK(sv)) { - dTHR; /* just for localizing */ - if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) - warn(warn_uninit); + if (dowarn && !(SvFLAGS(sv) & SVs_PADTMP)) { + dTHR; + if (!localizing) + warn(warn_uninit); + } *lp = 0; return ""; } @@ -2144,7 +2152,6 @@ sv_setsv(SV *dstr, register SV *sstr) void sv_setpvn(register SV *sv, register const char *ptr, register STRLEN len) { - dTHR; /* just for taint */ assert(len >= 0); /* STRLEN is probably unsigned, so this may elicit a warning, but it won't hurt. */ sv_check_thinkfirst(sv); @@ -2169,7 +2176,6 @@ sv_setpvn(register SV *sv, register const char *ptr, register STRLEN len) void sv_setpv(register SV *sv, register const char *ptr) { - dTHR; /* just for taint */ register STRLEN len; sv_check_thinkfirst(sv); @@ -2194,7 +2200,6 @@ sv_setpv(register SV *sv, register const char *ptr) void sv_usepvn(register SV *sv, register char *ptr, register STRLEN len) { - dTHR; /* just for taint */ sv_check_thinkfirst(sv); if (!SvUPGRADE(sv, SVt_PV)) return; @@ -2255,7 +2260,6 @@ sv_chop(register SV *sv, register char *ptr) /* like set but assuming ptr is in void sv_catpvn(register SV *sv, register char *ptr, register STRLEN len) { - dTHR; /* just for taint */ STRLEN tlen; char *junk; @@ -2284,7 +2288,6 @@ sv_catsv(SV *dstr, register SV *sstr) void sv_catpv(register SV *sv, register char *ptr) { - dTHR; /* just for taint */ register STRLEN len; STRLEN tlen; char *junk; @@ -2363,10 +2366,8 @@ sv_magic(register SV *sv, SV *obj, int how, char *name, I32 namlen) if (name) if (namlen >= 0) mg->mg_ptr = savepvn(name, namlen); - else if (namlen == HEf_SVKEY) { - dTHR; /* just for SvREFCNT_inc */ + else if (namlen == HEf_SVKEY) mg->mg_ptr = (char*)SvREFCNT_inc((SV*)name); - } switch (how) { case 0: @@ -3582,7 +3583,6 @@ sv_reset(register char *s, HV *stash) sv = GvSV(gv); (void)SvOK_off(sv); if (SvTYPE(sv) >= SVt_PV) { - dTHR; /* just for taint */ SvCUR_set(sv, 0); if (SvPVX(sv) != Nullch) *SvPVX(sv) = '\0'; @@ -3801,7 +3801,6 @@ sv_pvn_force(SV *sv, STRLEN *lp) *SvEND(sv) = '\0'; } if (!SvPOK(sv)) { - dTHR; /* just for taint */ SvPOK_on(sv); /* validate pointer */ SvTAINT(sv); DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2pv(%s)\n", @@ -490,7 +490,14 @@ struct xpvio { #define SvTAINTED_on(sv) STMT_START{ if(tainting){sv_taint(sv);} }STMT_END #define SvTAINTED_off(sv) STMT_START{ if(tainting){sv_untaint(sv);} }STMT_END -#define SvTAINT(sv) STMT_START{ if(tainted){SvTAINTED_on(sv);} }STMT_END +#define SvTAINT(sv) \ + STMT_START { \ + if (tainting) { \ + dTHR; \ + if (tainted) \ + SvTAINTED_on(sv); \ + } \ + } STMT_END #define SvPV_force(sv, lp) sv_pvn_force(sv, &lp) #define SvPV(sv, lp) sv_pvn(sv, &lp) @@ -5,7 +5,6 @@ #else /* POSIXish threads */ -typedef pthread_t perl_os_thread; #ifdef OLD_PTHREADS_API # define pthread_mutexattr_init(a) pthread_mutexattr_create(a) # define pthread_mutexattr_settype(a,t) pthread_mutexattr_setkind_np(a,t) @@ -822,18 +822,20 @@ fbm_compile(SV *sv) 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_magic(sv, Nullsv, 'B', Nullch, 0); /* deep magic */ SvVALID_on(sv); @@ -865,7 +867,15 @@ fbm_instr(unsigned char *big, register unsigned char *bigend, SV *littlestr) STRLEN len; char *l = SvPV(littlestr,len); if (!len) { - if (SvTAIL(littlestr)) { + 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 @@ -882,13 +892,32 @@ fbm_instr(unsigned char *big, register unsigned char *bigend, 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; } |