summaryrefslogtreecommitdiff
path: root/universal.c
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>2000-02-26 06:31:10 +0000
committerGurusamy Sarathy <gsar@cpan.org>2000-02-26 06:31:10 +0000
commit1571675a79745e7e3690e10ecdcf919c638d572b (patch)
treebcde2527119a19f04043c5a69c3f7e734361bad6 /universal.c
parentb46bc2b69fd0825253e7e513bb1c568567aa6ab0 (diff)
downloadperl-1571675a79745e7e3690e10ecdcf919c638d572b.tar.gz
support for version vectors in UNIVERSAL::VERSION(), so that
C<use Foo v1.2.3> etc., work; tests for the same TODO: XS_VERSION_BOOTCHECK needs to be revisited in light of this p4raw-id: //depot/perl@5265
Diffstat (limited to 'universal.c')
-rw-r--r--universal.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/universal.c b/universal.c
index 6ccff2f003..0e5a89b2c0 100644
--- a/universal.c
+++ b/universal.c
@@ -197,11 +197,10 @@ XS(XS_UNIVERSAL_VERSION)
GV *gv;
SV *sv;
char *undef;
- NV req;
- if(SvROK(ST(0))) {
+ if (SvROK(ST(0))) {
sv = (SV*)SvRV(ST(0));
- if(!SvOBJECT(sv))
+ if (!SvOBJECT(sv))
Perl_croak(aTHX_ "Cannot find version of an unblessed reference");
pkg = SvSTASH(sv);
}
@@ -222,12 +221,56 @@ XS(XS_UNIVERSAL_VERSION)
undef = "(undef)";
}
- if (items > 1 && (undef || (req = SvNV(ST(1)), req > SvNV(sv)))) {
- STRLEN n_a;
- Perl_croak(aTHX_ "%s version %s required--this is only version %s",
- HvNAME(pkg), SvPV(ST(1),n_a), undef ? undef : SvPV(sv,n_a));
+ if (items > 1) {
+ STRLEN len;
+ SV *req = ST(1);
+
+ if (undef)
+ Perl_croak(aTHX_ "%s does not define $%s::VERSION--version check failed",
+ HvNAME(pkg), HvNAME(pkg));
+
+ if (!SvNIOK(sv) && SvPOK(sv)) {
+ char *str = SvPVx(sv,len);
+ while (len) {
+ --len;
+ /* XXX could DWIM "1.2.3" here */
+ if (!isDIGIT(str[len]) && str[len] != '.' && str[len] != '_')
+ break;
+ }
+ if (len) {
+ if (SvNIOKp(req) && SvPOK(req)) {
+ /* they said C<use Foo v1.2.3> and $Foo::VERSION
+ * doesn't look like a float: do string compare */
+ if (sv_cmp(req,sv) == 1) {
+ Perl_croak(aTHX_ "%s version v%vd required--"
+ "this is only version v%vd",
+ HvNAME(pkg), req, sv);
+ }
+ goto finish;
+ }
+ /* they said C<use Foo 1.002_003> and $Foo::VERSION
+ * doesn't look like a float: force numeric compare */
+ SvUPGRADE(sv, SVt_PVNV);
+ SvNVX(sv) = str_to_version(sv);
+ SvPOK_off(sv);
+ SvNOK_on(sv);
+ }
+ }
+ /* if we get here, we're looking for a numeric comparison,
+ * so force the required version into a float, even if they
+ * said C<use Foo v1.2.3> */
+ if (SvNIOKp(req) && SvPOK(req)) {
+ NV n = SvNV(req);
+ req = sv_newmortal();
+ sv_setnv(req, n);
+ }
+
+ if (SvNV(req) > SvNV(sv))
+ Perl_croak(aTHX_ "%s version %s required--this is only version %s",
+ HvNAME(pkg), SvPV(req,len), SvPV(sv,len));
}
+finish:
ST(0) = sv;
XSRETURN(1);