summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1997-12-13 05:57:13 +0000
committerGurusamy Sarathy <gsar@cpan.org>1997-12-13 05:57:13 +0000
commitf3022b429d0c08fdcadfe0f1de24a48240ed6d19 (patch)
treea031535913a35aa954adfd1cb360134e3b6d44e1
parent83921c945db40515d7fed77f435f5b7be4efe5d4 (diff)
parent4352c2672c688f561f692cdbaf9109f32e58a795 (diff)
downloadperl-f3022b429d0c08fdcadfe0f1de24a48240ed6d19.tar.gz
[win32] Integrate mainline. Builds and passes (Borland).
p4raw-id: //depot/win32/perl@363
-rwxr-xr-xConfigure149
-rw-r--r--README.threads6
-rw-r--r--config_h.SH12
-rw-r--r--doop.c12
-rw-r--r--ext/DynaLoader/dl_aix.xs59
-rw-r--r--global.sym4
-rw-r--r--hints/aix.sh21
-rw-r--r--op.c5
-rw-r--r--op.h3
-rw-r--r--perl.h1
-rw-r--r--perlvars.h8
-rw-r--r--pp_hot.c2
-rw-r--r--pp_sys.c2
-rw-r--r--sv.c53
-rw-r--r--sv.h9
-rw-r--r--thread.h1
-rw-r--r--util.c65
17 files changed, 268 insertions, 144 deletions
diff --git a/Configure b/Configure
index b8618cbe2b..934958b4ce 100755
--- a/Configure
+++ b/Configure
@@ -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.
diff --git a/doop.c b/doop.c
index 277f46ef7a..be3e674109 100644
--- a/doop.c
+++ b/doop.c
@@ -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
diff --git a/op.c b/op.c
index 35fd3a04c1..d508bfba5f 100644
--- a/op.c
+++ b/op.c
@@ -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;
diff --git a/op.h b/op.h
index fbb5b8c8dd..a203c44639 100644
--- a/op.h
+++ b/op.h
@@ -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)
diff --git a/perl.h b/perl.h
index 4381e2d929..a2aefa349e 100644
--- a/perl.h
+++ b/perl.h
@@ -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[{]}")
diff --git a/pp_hot.c b/pp_hot.c
index 5dc72eaf36..f4a69480b1 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -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;
diff --git a/pp_sys.c b/pp_sys.c
index 9dc62018df..42e8a9c19a 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -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;
diff --git a/sv.c b/sv.c
index 381c943cda..8e04c3c230 100644
--- a/sv.c
+++ b/sv.c
@@ -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",
diff --git a/sv.h b/sv.h
index 1adaffe719..ffcc4aa22d 100644
--- a/sv.h
+++ b/sv.h
@@ -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)
diff --git a/thread.h b/thread.h
index b6397cbfdd..2328f7ed82 100644
--- a/thread.h
+++ b/thread.h
@@ -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)
diff --git a/util.c b/util.c
index cb7a4f1424..86e148d720 100644
--- a/util.c
+++ b/util.c
@@ -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;
}