char *
Perl_instr(pTHX_ register const char *big, register const char *little)
{
- register const char *s, *x;
register I32 first;
if (!little)
if (!first)
return (char*)big;
while (*big) {
+ register const char *s, *x;
if (*big++ != first)
continue;
for (x=big,s=little; *s; /**/ ) {
char *
Perl_ninstr(pTHX_ register const char *big, register const char *bigend, const char *little, const char *lend)
{
- register const char *s, *x;
register const I32 first = *little;
register const char *littleend = lend;
return Nullch;
bigend -= littleend - little++;
while (big <= bigend) {
+ register const char *s, *x;
if (*big++ != first)
continue;
for (x=big,s=little; s < littleend; /**/ ) {
Perl_rninstr(pTHX_ register const char *big, const char *bigend, const char *little, const char *lend)
{
register const char *bigbeg;
- register const char *s, *x;
register const I32 first = *little;
register const char *littleend = lend;
bigbeg = big;
big = bigend - (littleend - little++);
while (big >= bigbeg) {
+ register const char *s, *x;
if (*big-- != first)
continue;
for (x=big+2,s=little; s < littleend; /**/ ) {
void
Perl_fbm_compile(pTHX_ SV *sv, U32 flags)
{
- register U8 *s;
+ const register U8 *s;
register U8 *table;
register U32 i;
STRLEN len;
if (mg && mg->mg_len >= 0)
mg->mg_len++;
}
- s = (U8*)SvPV_force(sv, len);
- (void)SvUPGRADE(sv, SVt_PVBM);
+ s = (U8*)SvPV_force_mutable(sv, len);
+ SvUPGRADE(sv, SVt_PVBM);
if (len == 0) /* TAIL might be on a zero-length string. */
return;
if (len > 2) {
- U8 mlen;
- unsigned char *sb;
+ const unsigned char *sb;
+ const U8 mlen = (len>255) ? 255 : (U8)len;
- if (len > 255)
- mlen = 255;
- else
- mlen = (U8)len;
Sv_Grow(sv, len + 256 + FBM_TABLE_OFFSET);
- table = (unsigned char*)(SvPVX(sv) + len + FBM_TABLE_OFFSET);
+ table = (unsigned char*)(SvPVX_mutable(sv) + len + FBM_TABLE_OFFSET);
s = table - 1 - FBM_TABLE_OFFSET; /* last char */
memset((void*)table, mlen, 256);
table[-1] = (U8)flags;
sv_magic(sv, Nullsv, PERL_MAGIC_bm, Nullch, 0); /* deep magic */
SvVALID_on(sv);
- s = (unsigned char*)(SvPVX(sv)); /* deeper magic */
+ s = (const unsigned char*)(SvPVX_const(sv)); /* deeper magic */
for (i = 0; i < len; i++) {
if (PL_freq[s[i]] < frequency) {
rarest = i;
{
register unsigned char *s;
STRLEN l;
- register unsigned char *little = (unsigned char *)SvPV(littlestr,l);
+ register const unsigned char *little
+ = (const unsigned char *)SvPV_const(littlestr,l);
register STRLEN littlelen = l;
register const I32 multiline = flags & FBMrf_MULTILINE;
/* This should be better than FBM if c1 == c2, and almost
as good otherwise: maybe better since we do less indirection.
And we save a lot of memory by caching no table. */
- register unsigned char c1 = little[0];
- register unsigned char c2 = little[1];
+ const unsigned char c1 = little[0];
+ const unsigned char c2 = little[1];
s = big + 1;
bigend--;
{ /* Do actual FBM. */
register const unsigned char *table = little + littlelen + FBM_TABLE_OFFSET;
- register unsigned char *oldlittle;
+ const register unsigned char *oldlittle;
if (littlelen > (STRLEN)(bigend - big))
return Nullch;
goto check_end;
}
else { /* less expensive than calling strncmp() */
- register unsigned char *olds = s;
+ register unsigned char * const olds = s;
tmp = littlelen;
char *
Perl_screaminstr(pTHX_ SV *bigstr, SV *littlestr, I32 start_shift, I32 end_shift, I32 *old_posp, I32 last)
{
- register unsigned char *s, *x;
- register unsigned char *big;
+ const register unsigned char *big;
register I32 pos;
register I32 previous;
register I32 first;
- register unsigned char *little;
+ const register unsigned char *little;
register I32 stop_pos;
- register unsigned char *littleend;
+ const register unsigned char *littleend;
I32 found = 0;
if (*old_posp == -1
cant_find:
if ( BmRARE(littlestr) == '\n'
&& BmPREVIOUS(littlestr) == SvCUR(littlestr) - 1) {
- little = (unsigned char *)(SvPVX(littlestr));
+ little = (const unsigned char *)(SvPVX_const(littlestr));
littleend = little + SvCUR(littlestr);
first = *little++;
goto check_tail;
return Nullch;
}
- little = (unsigned char *)(SvPVX(littlestr));
+ little = (const unsigned char *)(SvPVX_const(littlestr));
littleend = little + SvCUR(littlestr);
first = *little++;
/* The value of pos we can start at: */
previous = BmPREVIOUS(littlestr);
- big = (unsigned char *)(SvPVX(bigstr));
+ big = (const unsigned char *)(SvPVX_const(bigstr));
/* The value of pos we can stop at: */
stop_pos = SvCUR(bigstr) - end_shift - (SvCUR(littlestr) - 1 - previous);
if (previous + start_shift > stop_pos) {
}
big -= previous;
do {
+ const register unsigned char *s, *x;
if (pos >= stop_pos) break;
if (big[pos] != first)
continue;
if (!SvTAIL(littlestr) || (end_shift > 0))
return Nullch;
/* Ignore the trailing "\n". This code is not microoptimized */
- big = (unsigned char *)(SvPVX(bigstr) + SvCUR(bigstr));
+ big = (const unsigned char *)(SvPVX_const(bigstr) + SvCUR(bigstr));
stop_pos = littleend - little; /* Actual littlestr len */
if (stop_pos == 0)
return (char*)big;
char *
Perl_savepv(pTHX_ const char *pv)
{
- register char *newaddr;
-#ifdef PERL_MALLOC_WRAP
- STRLEN pvlen;
-#endif
if (!pv)
return Nullch;
+ else {
+ char *newaddr;
+ const STRLEN pvlen = strlen(pv)+1;
+ New(902,newaddr,pvlen,char);
+ return strcpy(newaddr,pv);
+ }
-#ifdef PERL_MALLOC_WRAP
- pvlen = strlen(pv)+1;
- New(902,newaddr,pvlen,char);
-#else
- New(902,newaddr,strlen(pv)+1,char);
-#endif
- return strcpy(newaddr,pv);
}
/* same thing but with a known length */
Perl_savesvpv(pTHX_ SV *sv)
{
STRLEN len;
- const char *pv = SvPV(sv, len);
+ const char *pv = SvPV_const(sv, len);
register char *newaddr;
++len;
/* Common code used by vcroak, vdie and vwarner */
-void S_vdie_common(pTHX_ const char *message, STRLEN msglen, I32 utf8);
-
-STATIC char *
-S_vdie_croak_common(pTHX_ const char* pat, va_list* args, STRLEN* msglen,
- I32* utf8)
-{
- dVAR;
- char *message;
-
- if (pat) {
- SV *msv = vmess(pat, args);
- if (PL_errors && SvCUR(PL_errors)) {
- sv_catsv(PL_errors, msv);
- message = SvPV(PL_errors, *msglen);
- SvCUR_set(PL_errors, 0);
- }
- else
- message = SvPV(msv,*msglen);
- *utf8 = SvUTF8(msv);
- }
- else {
- message = Nullch;
- }
-
- DEBUG_S(PerlIO_printf(Perl_debug_log,
- "%p: die/croak: message = %s\ndiehook = %p\n",
- thr, message, PL_diehook));
- if (PL_diehook) {
- S_vdie_common(aTHX_ message, *msglen, *utf8);
- }
- return message;
-}
-
-void
+STATIC void
S_vdie_common(pTHX_ const char *message, STRLEN msglen, I32 utf8)
{
HV *stash;
}
}
+STATIC const char *
+S_vdie_croak_common(pTHX_ const char* pat, va_list* args, STRLEN* msglen,
+ I32* utf8)
+{
+ dVAR;
+ const char *message;
+
+ if (pat) {
+ SV *msv = vmess(pat, args);
+ if (PL_errors && SvCUR(PL_errors)) {
+ sv_catsv(PL_errors, msv);
+ message = SvPV_const(PL_errors, *msglen);
+ SvCUR_set(PL_errors, 0);
+ }
+ else
+ message = SvPV_const(msv,*msglen);
+ *utf8 = SvUTF8(msv);
+ }
+ else {
+ message = Nullch;
+ }
+
+ DEBUG_S(PerlIO_printf(Perl_debug_log,
+ "%p: die/croak: message = %s\ndiehook = %p\n",
+ thr, message, PL_diehook));
+ if (PL_diehook) {
+ S_vdie_common(aTHX_ message, *msglen, *utf8);
+ }
+ return message;
+}
+
OP *
Perl_vdie(pTHX_ const char* pat, va_list *args)
{
JMPENV_JUMP(3);
}
else if (!message)
- message = SvPVx(ERRSV, msglen);
+ message = SvPVx_const(ERRSV, msglen);
write_to_stderr(message, msglen);
my_failure_exit();
Perl_vwarn(pTHX_ const char* pat, va_list *args)
{
dVAR;
- char *message;
+ const char *message;
HV *stash;
GV *gv;
CV *cv;
msv = vmess(pat, args);
utf8 = SvUTF8(msv);
- message = SvPV(msv, msglen);
+ message = SvPV_const(msv, msglen);
if (PL_warnhook) {
/* sv_2cv might call Perl_warn() */
if (ckDEAD(err)) {
SV * const msv = vmess(pat, args);
STRLEN msglen;
- const char *message = SvPV(msv, msglen);
+ const char *message = SvPV_const(msv, msglen);
const I32 utf8 = SvUTF8(msv);
if (PL_diehook) {
LOCK_FDPID_MUTEX;
sv = *av_fetch(PL_fdpid,p[This],TRUE);
UNLOCK_FDPID_MUTEX;
- (void)SvUPGRADE(sv,SVt_IV);
+ SvUPGRADE(sv,SVt_IV);
SvIV_set(sv, pid);
PL_forkprocess = pid;
/* If we managed to get status pipe check for exec fail */
LOCK_FDPID_MUTEX;
sv = *av_fetch(PL_fdpid,p[This],TRUE);
UNLOCK_FDPID_MUTEX;
- (void)SvUPGRADE(sv,SVt_IV);
+ SvUPGRADE(sv,SVt_IV);
SvIV_set(sv, pid);
PL_forkprocess = pid;
if (did_pipes && pid > 0) {
Pid_t pid2;
bool close_failed;
int saved_errno = 0;
-#ifdef VMS
- int saved_vaxc_errno;
-#endif
#ifdef WIN32
int saved_win32_errno;
#endif
#endif
if ((close_failed = (PerlIO_close(ptr) == EOF))) {
saved_errno = errno;
-#ifdef VMS
- saved_vaxc_errno = vaxc$errno;
-#endif
#ifdef WIN32
saved_win32_errno = GetLastError();
#endif
rsignal_restore(SIGQUIT, &qstat);
#endif
if (close_failed) {
- SETERRNO(saved_errno, saved_vaxc_errno);
+ SETERRNO(saved_errno, 0);
return -1;
}
return(pid2 < 0 ? pid2 : status == 0 ? 0 : (errno = 0, status));
sprintf(spid, "%"IVdf, (IV)pid);
sv = *hv_fetch(PL_pidstatus,spid,strlen(spid),TRUE);
- (void)SvUPGRADE(sv,SVt_IV);
+ SvUPGRADE(sv,SVt_IV);
SvIV_set(sv, status);
return;
}
if (strNE(a,b))
return FALSE;
if (fa == a)
- sv_setpv(tmpsv, ".");
+ sv_setpvn(tmpsv, ".", 1);
else
sv_setpvn(tmpsv, a, fa - a);
if (PerlLIO_stat(SvPVX_const(tmpsv), &tmpstatbuf1) < 0)
return FALSE;
if (fb == b)
- sv_setpv(tmpsv, ".");
+ sv_setpvn(tmpsv, ".", 1);
else
sv_setpvn(tmpsv, b, fb - b);
if (PerlLIO_stat(SvPVX_const(tmpsv), &tmpstatbuf2) < 0)
if (pthread_setspecific(PL_thr_key, t))
Perl_croak_nocontext("panic: pthread_setspecific");
# endif
+#else
+ (void)t;
#endif
}
int pathlen=0;
Direntry_t *dp;
- (void)SvUPGRADE(sv, SVt_PV);
+ SvUPGRADE(sv, SVt_PV);
if (PerlLIO_lstat(".", &statbuf) < 0) {
SV_CWD_RETURN_UNDEF;
=cut
*/
-char *
+const char *
Perl_scan_version(pTHX_ const char *s, SV *rv, bool qv)
{
const char *start = s;
- const char *pos = s;
- I32 saw_period = 0;
- bool saw_under = 0;
- SV* sv = newSVrv(rv, "version"); /* create an SV and upgrade the RV */
- (void)sv_upgrade(sv, SVt_PVAV); /* needs to be an AV type */
- AvREAL_on((AV*)sv);
-
- /* pre-scan the imput string to check for decimals */
+ const char *pos;
+ const char *last;
+ int saw_period = 0;
+ int saw_under = 0;
+ int width = 3;
+ AV *av = newAV();
+ SV* hv = newSVrv(rv, "version"); /* create an SV and upgrade the RV */
+ (void)sv_upgrade(hv, SVt_PVHV); /* needs to be an HV type */
+
+ if (*s == 'v') {
+ s++; /* get past 'v' */
+ qv = 1; /* force quoted version processing */
+ }
+
+ last = pos = s;
+
+ /* pre-scan the input string to check for decimals/underbars */
while ( *pos == '.' || *pos == '_' || isDIGIT(*pos) )
{
if ( *pos == '.' )
if ( saw_under )
Perl_croak(aTHX_ "Invalid version format (underscores before decimal)");
saw_period++ ;
+ last = pos;
}
else if ( *pos == '_' )
{
if ( saw_under )
Perl_croak(aTHX_ "Invalid version format (multiple underscores)");
saw_under = 1;
+ width = pos - last - 1; /* natural width of sub-version */
}
pos++;
}
- pos = s;
- if (*pos == 'v') {
- pos++; /* get past 'v' */
+ if ( saw_period > 1 ) {
qv = 1; /* force quoted version processing */
}
+
+ pos = s;
+
+ if ( qv )
+ hv_store((HV *)hv, "qv", 2, &PL_sv_yes, 0);
+ if ( saw_under ) {
+ hv_store((HV *)hv, "alpha", 5, &PL_sv_yes, 0);
+ }
+ if ( !qv && width < 3 )
+ hv_store((HV *)hv, "width", 5, newSViv(width), 0);
+
while (isDIGIT(*pos))
pos++;
if (!isALPHA(*pos)) {
I32 rev;
- if (*s == 'v') s++; /* get past 'v' */
-
for (;;) {
rev = 0;
{
/* this is atoi() that delimits on underscores */
- const char *end = pos;
+ const char *end = pos;
I32 mult = 1;
I32 orev;
- if ( s < pos && s > start && *(s-1) == '_' ) {
- mult *= -1; /* alpha version */
- }
+
/* the following if() will only be true after the decimal
* point of a version originally created with a bare
* floating point number, i.e. not quoted in any way
if ( PERL_ABS(orev) > PERL_ABS(rev) )
Perl_croak(aTHX_ "Integer overflow in version");
s++;
+ if ( *s == '_' )
+ s++;
}
}
else {
}
}
}
-
+
/* Append revision */
- av_push((AV *)sv, newSViv(rev));
- if ( (*pos == '.' || *pos == '_') && isDIGIT(pos[1]))
+ av_push(av, newSViv(rev));
+ if ( *pos == '.' && isDIGIT(pos[1]) )
+ s = ++pos;
+ else if ( *pos == '_' && isDIGIT(pos[1]) )
s = ++pos;
else if ( isDIGIT(*pos) )
s = pos;
s = pos;
break;
}
- while ( isDIGIT(*pos) ) {
- if ( saw_period == 1 && pos-s == 3 )
- break;
- pos++;
+ if ( qv ) {
+ while ( isDIGIT(*pos) )
+ pos++;
+ }
+ else {
+ int digits = 0;
+ while ( ( isDIGIT(*pos) || *pos == '_' ) && digits < 3 ) {
+ if ( *pos != '_' )
+ digits++;
+ pos++;
+ }
}
}
}
- if ( qv ) { /* quoted versions always become full version objects */
- I32 len = av_len((AV *)sv);
+ if ( qv ) { /* quoted versions always get at least three terms*/
+ I32 len = av_len(av);
/* This for loop appears to trigger a compiler bug on OS X, as it
loops infinitely. Yes, len is negative. No, it makes no sense.
Compiler in question is:
*/
len = 2 - len;
while (len-- > 0)
- av_push((AV *)sv, newSViv(0));
+ av_push(av, newSViv(0));
}
- return (char *)s;
+
+ if ( av_len(av) == -1 ) /* oops, someone forgot to pass a value */
+ av_push(av, newSViv(0));
+
+ /* And finally, store the AV in the hash */
+ hv_store((HV *)hv, "version", 7, (SV *)av, 0);
+ return s;
}
/*
if ( sv_derived_from(ver,"version") ) /* can just copy directly */
{
I32 key;
- AV *av = (AV *)SvRV(ver);
- SV* sv = newSVrv(rv, "version"); /* create an SV and upgrade the RV */
- (void)sv_upgrade(sv, SVt_PVAV); /* needs to be an AV type */
- AvREAL_on((AV*)sv);
- for ( key = 0; key <= av_len(av); key++ )
+ AV *av = newAV();
+ AV *sav;
+ /* This will get reblessed later if a derived class*/
+ SV* hv = newSVrv(rv, "version");
+ (void)sv_upgrade(hv, SVt_PVHV); /* needs to be an HV type */
+
+ if ( SvROK(ver) )
+ ver = SvRV(ver);
+
+ /* Begin copying all of the elements */
+ if ( hv_exists((HV *)ver, "qv", 2) )
+ hv_store((HV *)hv, "qv", 2, &PL_sv_yes, 0);
+
+ if ( hv_exists((HV *)ver, "alpha", 5) )
+ hv_store((HV *)hv, "alpha", 5, &PL_sv_yes, 0);
+
+ if ( hv_exists((HV*)ver, "width", 5 ) )
+ {
+ I32 width = SvIV(*hv_fetch((HV*)ver, "width", 5, FALSE));
+ hv_store((HV *)hv, "width", 5, newSViv(width), 0);
+ }
+
+ sav = (AV *)*hv_fetch((HV*)ver, "version", 7, FALSE);
+ /* This will get reblessed later if a derived class*/
+ for ( key = 0; key <= av_len(sav); key++ )
{
- const I32 rev = SvIV(*av_fetch(av, key, FALSE));
- av_push((AV *)sv, newSViv(rev));
+ const I32 rev = SvIV(*av_fetch(sav, key, FALSE));
+ av_push(av, newSViv(rev));
}
+
+ hv_store((HV *)hv, "version", 7, (SV *)av, 0);
return rv;
}
#ifdef SvVOK
#endif
else /* must be a string or something like a string */
{
- version = savesvpv(ver);
+ version = savepv(SvPV_nolen(ver));
}
(void)scan_version(version, ver, qv);
Safefree(version);
Perl_vnumify(pTHX_ SV *vs)
{
I32 i, len, digit;
+ int width;
+ bool alpha = FALSE;
SV *sv = newSV(0);
+ AV *av;
if ( SvROK(vs) )
vs = SvRV(vs);
- len = av_len((AV *)vs);
+
+ /* see if various flags exist */
+ if ( hv_exists((HV*)vs, "alpha", 5 ) )
+ alpha = TRUE;
+ if ( hv_exists((HV*)vs, "width", 5 ) )
+ width = SvIV(*hv_fetch((HV*)vs, "width", 5, FALSE));
+ else
+ width = 3;
+
+
+ /* attempt to retrieve the version array */
+ if ( !(av = (AV *)*hv_fetch((HV*)vs, "version", 7, FALSE) ) ) {
+ Perl_sv_catpv(aTHX_ sv,"0");
+ return sv;
+ }
+
+ len = av_len(av);
if ( len == -1 )
{
- Perl_sv_catpv(aTHX_ sv,"0");
+ sv_catpvn(sv,"0",1);
return sv;
}
- digit = SvIVX(*av_fetch((AV *)vs, 0, 0));
+
+ digit = SvIV(*av_fetch(av, 0, 0));
Perl_sv_setpvf(aTHX_ sv,"%d.", (int)PERL_ABS(digit));
for ( i = 1 ; i < len ; i++ )
{
- digit = SvIVX(*av_fetch((AV *)vs, i, 0));
- Perl_sv_catpvf(aTHX_ sv,"%03d", (int)PERL_ABS(digit));
+ digit = SvIV(*av_fetch(av, i, 0));
+ if ( width < 3 ) {
+ int denom = (int)pow(10,(3-width));
+ div_t term = div((int)PERL_ABS(digit),denom);
+ Perl_sv_catpvf(aTHX_ sv,"%0*d_%d", width, term.quot, term.rem);
+ }
+ else {
+ Perl_sv_catpvf(aTHX_ sv,"%0*d", width, (int)digit);
+ }
}
if ( len > 0 )
{
- digit = SvIVX(*av_fetch((AV *)vs, len, 0));
- if ( (int)PERL_ABS(digit) != 0 || len == 1 )
- {
- if ( digit < 0 ) /* alpha version */
- Perl_sv_catpv(aTHX_ sv,"_");
- /* Don't display additional trailing zeros */
- Perl_sv_catpvf(aTHX_ sv,"%03d", (int)PERL_ABS(digit));
- }
+ digit = SvIV(*av_fetch(av, len, 0));
+ if ( alpha && width == 3 ) /* alpha version */
+ Perl_sv_catpv(aTHX_ sv,"_");
+ /* Don't display additional trailing zeros */
+ if ( digit > 0 )
+ Perl_sv_catpvf(aTHX_ sv,"%0*d", width, (int)digit);
}
- else /* len == 0 */
+ else /* len == 1 */
{
- Perl_sv_catpv(aTHX_ sv,"000");
+ sv_catpvn(sv,"000",3);
}
return sv;
}
Perl_vnormal(pTHX_ SV *vs)
{
I32 i, len, digit;
+ bool alpha = FALSE;
SV *sv = newSV(0);
+ AV *av;
if ( SvROK(vs) )
vs = SvRV(vs);
- len = av_len((AV *)vs);
- if ( len == -1 )
- {
- Perl_sv_catpv(aTHX_ sv,"");
+
+ if ( hv_exists((HV*)vs, "alpha", 5 ) )
+ alpha = TRUE;
+ av = (AV *)*hv_fetch((HV*)vs, "version", 7, FALSE);
+
+ len = av_len(av);
+ if ( len == -1 ) {
+ sv_catpvn(sv,"",0);
return sv;
}
- digit = SvIVX(*av_fetch((AV *)vs, 0, 0));
- Perl_sv_setpvf(aTHX_ sv,"%"IVdf,(IV)digit);
- for ( i = 1 ; i <= len ; i++ )
- {
- digit = SvIVX(*av_fetch((AV *)vs, i, 0));
- if ( digit < 0 )
- Perl_sv_catpvf(aTHX_ sv,"_%"IVdf,(IV)-digit);
+ digit = SvIV(*av_fetch(av, 0, 0));
+ Perl_sv_setpvf(aTHX_ sv,"v%"IVdf,(IV)digit);
+ for ( i = 1 ; i <= len-1 ; i++ ) {
+ digit = SvIV(*av_fetch(av, i, 0));
+ Perl_sv_catpvf(aTHX_ sv, ".%"IVdf, (IV)digit);
+ }
+
+ if ( len > 0 ) {
+ /* handle last digit specially */
+ digit = SvIV(*av_fetch(av, len, 0));
+ if ( alpha )
+ Perl_sv_catpvf(aTHX_ sv, "_%"IVdf, (IV)digit);
else
- Perl_sv_catpvf(aTHX_ sv,".%"IVdf,(IV)digit);
+ Perl_sv_catpvf(aTHX_ sv, ".%"IVdf, (IV)digit);
}
-
+
if ( len <= 2 ) { /* short version, must be at least three */
for ( len = 2 - len; len != 0; len-- )
- Perl_sv_catpv(aTHX_ sv,".0");
+ sv_catpvn(sv,".0",2);
}
return sv;
-}
+}
/*
=for apidoc vstringify
SV *
Perl_vstringify(pTHX_ SV *vs)
{
- I32 len, digit;
+ I32 qv = 0;
if ( SvROK(vs) )
vs = SvRV(vs);
- len = av_len((AV *)vs);
- digit = SvIVX(*av_fetch((AV *)vs, len, 0));
- if ( len < 2 || ( len == 2 && digit < 0 ) )
- return vnumify(vs);
- else
+ if ( hv_exists((HV *)vs, "qv", 2) )
+ qv = 1;
+
+ if ( qv )
return vnormal(vs);
+ else
+ return vnumify(vs);
}
/*
*/
int
-Perl_vcmp(pTHX_ SV *lsv, SV *rsv)
+Perl_vcmp(pTHX_ SV *lhv, SV *rhv)
{
I32 i,l,m,r,retval;
- if ( SvROK(lsv) )
- lsv = SvRV(lsv);
- if ( SvROK(rsv) )
- rsv = SvRV(rsv);
- l = av_len((AV *)lsv);
- r = av_len((AV *)rsv);
+ bool lalpha = FALSE;
+ bool ralpha = FALSE;
+ I32 left = 0;
+ I32 right = 0;
+ AV *lav, *rav;
+ if ( SvROK(lhv) )
+ lhv = SvRV(lhv);
+ if ( SvROK(rhv) )
+ rhv = SvRV(rhv);
+
+ /* get the left hand term */
+ lav = (AV *)*hv_fetch((HV*)lhv, "version", 7, FALSE);
+ if ( hv_exists((HV*)lhv, "alpha", 5 ) )
+ lalpha = TRUE;
+
+ /* and the right hand term */
+ rav = (AV *)*hv_fetch((HV*)rhv, "version", 7, FALSE);
+ if ( hv_exists((HV*)rhv, "alpha", 5 ) )
+ ralpha = TRUE;
+
+ l = av_len(lav);
+ r = av_len(rav);
m = l < r ? l : r;
retval = 0;
i = 0;
while ( i <= m && retval == 0 )
{
- I32 left = SvIV(*av_fetch((AV *)lsv,i,0));
- I32 right = SvIV(*av_fetch((AV *)rsv,i,0));
- bool lalpha = left < 0 ? 1 : 0;
- bool ralpha = right < 0 ? 1 : 0;
- left = abs(left);
- right = abs(right);
- if ( left < right || (left == right && lalpha && !ralpha) )
+ left = SvIV(*av_fetch(lav,i,0));
+ right = SvIV(*av_fetch(rav,i,0));
+ if ( left < right )
retval = -1;
- if ( left > right || (left == right && ralpha && !lalpha) )
+ if ( left > right )
retval = +1;
i++;
}
+ /* tiebreaker for alpha with identical terms */
+ if ( retval == 0 && l == r && left == right && ( lalpha || ralpha ) )
+ {
+ if ( lalpha && !ralpha )
+ {
+ retval = -1;
+ }
+ else if ( ralpha && !lalpha)
+ {
+ retval = +1;
+ }
+ }
+
if ( l != r && retval == 0 ) /* possible match except for trailing 0's */
{
if ( l < r )
{
while ( i <= r && retval == 0 )
{
- if ( SvIV(*av_fetch((AV *)rsv,i,0)) != 0 )
+ if ( SvIV(*av_fetch(rav,i,0)) != 0 )
retval = -1; /* not a match after all */
i++;
}
{
while ( i <= l && retval == 0 )
{
- if ( SvIV(*av_fetch((AV *)lsv,i,0)) != 0 )
+ if ( SvIV(*av_fetch(lav,i,0)) != 0 )
retval = +1; /* not a match after all */
i++;
}
return myseed;
}
+#ifdef USE_ITHREADS
+bool
+Perl_stashpv_hvname_match(pTHX_ const COP *c, const HV *hv)
+{
+ const char * const stashpv = CopSTASHPV(c);
+ const char * const name = HvNAME_get(hv);
+
+ if (stashpv == name)
+ return TRUE;
+ if (stashpv && name)
+ if (strEQ(stashpv, name))
+ return TRUE;
+ return FALSE;
+}
+#endif
+
+
#ifdef PERL_GLOBAL_STRUCT
struct perl_vars *