For S_incpush(), dir is never NULL, and len is always > 0.
[p5sagit/p5-mst-13.2.git] / perl.c
diff --git a/perl.c b/perl.c
index 6e4e3e4..7f98351 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -1624,11 +1624,14 @@ perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env)
     return ret;
 }
 
-#define INCPUSH_ADD_SUB_DIRS   0x01
-#define INCPUSH_ADD_OLD_VERS   0x02
-#define INCPUSH_NOT_BASEDIR    0x04
-#define INCPUSH_CAN_RELOCATE   0x08
-#define INCPUSH_UNSHIFT                0x10
+#define INCPUSH_UNSHIFT                        0x01
+#define INCPUSH_ADD_OLD_VERS           0x02
+#define INCPUSH_ADD_VERSIONED_SUB_DIRS 0x04
+#define INCPUSH_ADD_ARCHONLY_SUB_DIRS  0x08
+#define INCPUSH_NOT_BASEDIR            0x10
+#define INCPUSH_CAN_RELOCATE           0x20
+#define INCPUSH_ADD_SUB_DIRS   \
+    (INCPUSH_ADD_VERSIONED_SUB_DIRS|INCPUSH_ADD_ARCHONLY_SUB_DIRS)
 
 STATIC void *
 S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
@@ -4093,9 +4096,9 @@ S_init_perllib(pTHX)
 {
     dVAR;
 #ifndef VMS
-    const char *perl5lib;
+    const char *perl5lib = NULL;
 #endif
-    char *s;
+    const char *s;
 #ifdef WIN32
     STRLEN len;
 #endif
@@ -4140,7 +4143,8 @@ S_init_perllib(pTHX)
     ARCHLIB PRIVLIB SITEARCH SITELIB VENDORARCH and VENDORLIB
 */
 #ifdef APPLLIB_EXP
-    S_incpush_use_sep(aTHX_ STR_WITH_LEN(APPLLIB_EXP), INCPUSH_ADD_SUB_DIRS|INCPUSH_CAN_RELOCATE);
+    S_incpush_use_sep(aTHX_ STR_WITH_LEN(APPLLIB_EXP),
+                     INCPUSH_ADD_SUB_DIRS|INCPUSH_CAN_RELOCATE);
 #endif
 
 #ifdef MACOS_TRADITIONAL
@@ -4158,10 +4162,12 @@ S_init_perllib(pTHX)
        
        Perl_sv_setpvf(aTHX_ privdir, "%slib:", macperl);
        if (PerlLIO_stat(SvPVX(privdir), &tmpstatbuf) >= 0 && S_ISDIR(tmpstatbuf.st_mode))
-           incpush_use_sep(SvPVX(privdir), SvCUR(privdir), INCPUSH_ADD_SUB_DIRS);
+           incpush_use_sep(SvPVX(privdir), SvCUR(privdir),
+                           INCPUSH_ADD_SUB_DIRS);
        Perl_sv_setpvf(aTHX_ privdir, "%ssite_perl:", macperl);
        if (PerlLIO_stat(SvPVX(privdir), SvCUR(privdir), &tmpstatbuf) >= 0 && S_ISDIR(tmpstatbuf.st_mode))
-           incpush_use_sep(SvPVX(privdir), SvCUR(privdir), INCPUSH_ADD_SUB_DIRS);
+           incpush_use_sep(SvPVX(privdir), SvCUR(privdir),
+                           INCPUSH_ADD_SUB_DIRS);
        
        SvREFCNT_dec(privdir);
        if (!PL_tainting)
@@ -4172,7 +4178,8 @@ S_init_perllib(pTHX)
     /* sitearch is always relative to sitelib on Windows for
      * DLL-based path intuition to work correctly */
 #  if !defined(WIN32)
-       S_incpush_use_sep(aTHX_ STR_WITH_LEN(SITEARCH_EXP), INCPUSH_CAN_RELOCATE);
+       S_incpush_use_sep(aTHX_ STR_WITH_LEN(SITEARCH_EXP),
+                         INCPUSH_CAN_RELOCATE);
 #  endif
 #endif
 
@@ -4187,16 +4194,12 @@ S_init_perllib(pTHX)
 #  endif
 #endif
 
-#if defined(SITELIB_STEM) && defined(PERL_INC_VERSION_LIST)
-    /* Search for version-specific dirs below here */
-    S_incpush_use_sep(aTHX_ STR_WITH_LEN(SITELIB_STEM), INCPUSH_CAN_RELOCATE);
-#endif
-
 #ifdef PERL_VENDORARCH_EXP
     /* vendorarch is always relative to vendorlib on Windows for
      * DLL-based path intuition to work correctly */
 #  if !defined(WIN32)
-    S_incpush_use_sep(aTHX_ STR_WITH_LEN(PERL_VENDORARCH_EXP), INCPUSH_CAN_RELOCATE);
+    S_incpush_use_sep(aTHX_ STR_WITH_LEN(PERL_VENDORARCH_EXP),
+                     INCPUSH_CAN_RELOCATE);
 #  endif
 #endif
 
@@ -4207,15 +4210,11 @@ S_init_perllib(pTHX)
        if (s)
            incpush_use_sep(s, len, INCPUSH_ADD_SUB_DIRS|INCPUSH_CAN_RELOCATE);
 #  else
-       S_incpush_use_sep(aTHX_ STR_WITH_LEN(PERL_VENDORLIB_EXP), INCPUSH_CAN_RELOCATE);
+       S_incpush_use_sep(aTHX_ STR_WITH_LEN(PERL_VENDORLIB_EXP),
+                         INCPUSH_CAN_RELOCATE);
 #  endif
 #endif
 
-#if defined(PERL_VENDORLIB_STEM) && defined(PERL_INC_VERSION_LIST)
-    /* Search for version-specific dirs below here */
-    S_incpush_use_sep(aTHX_ STR_WITH_LEN(PERL_VENDORLIB_STEM), INCPUSH_CAN_RELOCATE);
-#endif
-
 #ifdef ARCHLIB_EXP
     S_incpush_use_sep(aTHX_ STR_WITH_LEN(ARCHLIB_EXP), INCPUSH_CAN_RELOCATE);
 #endif
@@ -4237,7 +4236,8 @@ S_init_perllib(pTHX)
 #endif
 
 #ifdef PERL_OTHERLIBDIRS
-    S_incpush_use_sep(aTHX_ STR_WITH_LEN(PERL_OTHERLIBDIRS), INCPUSH_ADD_SUB_DIRS
+    S_incpush_use_sep(aTHX_ STR_WITH_LEN(PERL_OTHERLIBDIRS),
+                     INCPUSH_ADD_VERSIONED_SUB_DIRS|INCPUSH_NOT_BASEDIR
                      |INCPUSH_CAN_RELOCATE);
 #endif
 #endif /* MACOS_TRADITIONAL */
@@ -4265,7 +4265,8 @@ S_init_perllib(pTHX)
        int idx = 0;
        if (my_trnlnm("PERL5LIB",buf,0))
            do {
-               incpush_use_sep(buf, 0, INCPUSH_ADD_OLD_VERS|INCPUSH_NOT_BASEDIR);
+               incpush_use_sep(buf, 0,
+                               INCPUSH_ADD_OLD_VERS|INCPUSH_NOT_BASEDIR);
            } while (my_trnlnm("PERL5LIB",buf,++idx));
 #endif /* VMS */
     }
@@ -4274,23 +4275,28 @@ S_init_perllib(pTHX)
     ARCHLIB PRIVLIB SITEARCH SITELIB VENDORARCH and VENDORLIB
 */
 #ifdef APPLLIB_EXP
-    S_incpush_use_sep(aTHX_ STR_WITH_LEN(APPLLIB_EXP), INCPUSH_ADD_OLD_VERS|INCPUSH_NOT_BASEDIR|INCPUSH_CAN_RELOCATE);
+    S_incpush_use_sep(aTHX_ STR_WITH_LEN(APPLLIB_EXP), INCPUSH_ADD_OLD_VERS
+                     |INCPUSH_NOT_BASEDIR|INCPUSH_CAN_RELOCATE);
 #endif
 
 #ifndef MACOS_TRADITIONAL
 #if defined(SITELIB_STEM) && defined(PERL_INC_VERSION_LIST)
     /* Search for version-specific dirs below here */
-    S_incpush_use_sep(aTHX_ STR_WITH_LEN(SITELIB_STEM), INCPUSH_ADD_OLD_VERS|INCPUSH_NOT_BASEDIR|INCPUSH_CAN_RELOCATE);
+    S_incpush_use_sep(aTHX_ STR_WITH_LEN(SITELIB_STEM),
+                     INCPUSH_ADD_OLD_VERS|INCPUSH_CAN_RELOCATE);
 #endif
 
 
 #if defined(PERL_VENDORLIB_STEM) && defined(PERL_INC_VERSION_LIST)
     /* Search for version-specific dirs below here */
-    S_incpush_use_sep(aTHX_ STR_WITH_LEN(PERL_VENDORLIB_STEM), INCPUSH_ADD_OLD_VERS|INCPUSH_NOT_BASEDIR|INCPUSH_CAN_RELOCATE);
+    S_incpush_use_sep(aTHX_ STR_WITH_LEN(PERL_VENDORLIB_STEM),
+                     INCPUSH_ADD_OLD_VERS|INCPUSH_CAN_RELOCATE);
 #endif
 
 #ifdef PERL_OTHERLIBDIRS
-    S_incpush_use_sep(aTHX_ STR_WITH_LEN(PERL_OTHERLIBDIRS), INCPUSH_ADD_OLD_VERS|INCPUSH_NOT_BASEDIR|INCPUSH_CAN_RELOCATE);
+    S_incpush_use_sep(aTHX_ STR_WITH_LEN(PERL_OTHERLIBDIRS),
+                     INCPUSH_ADD_OLD_VERS|INCPUSH_ADD_ARCHONLY_SUB_DIRS
+                     |INCPUSH_CAN_RELOCATE);
 #endif
 
     if (!PL_tainting)
@@ -4319,7 +4325,7 @@ S_init_perllib(pTHX)
    Generate a new SV if we do this, to save needing to copy the SV we push
    onto @INC  */
 STATIC SV *
-S_incpush_if_exists(pTHX_ AV *const av, SV *dir)
+S_incpush_if_exists(pTHX_ AV *const av, SV *dir, SV *const stem)
 {
     dVAR;
     Stat_t tmpstatbuf;
@@ -4329,7 +4335,10 @@ S_incpush_if_exists(pTHX_ AV *const av, SV *dir)
     if (PerlLIO_stat(SvPVX_const(dir), &tmpstatbuf) >= 0 &&
        S_ISDIR(tmpstatbuf.st_mode)) {
        av_push(av, dir);
-       dir = newSV(0);
+       dir = newSVsv(stem);
+    } else {
+       /* Truncate dir back to stem.  */
+       SvCUR_set(dir, SvCUR(stem));
     }
     return dir;
 }
@@ -4338,23 +4347,24 @@ STATIC void
 S_incpush(pTHX_ const char *const dir, STRLEN len, U32 flags)
 {
     dVAR;
-    const U8 addsubdirs  = (U8)flags & INCPUSH_ADD_SUB_DIRS;
+    const U8 using_sub_dirs
+       = (U8)flags & (INCPUSH_ADD_VERSIONED_SUB_DIRS
+                      |INCPUSH_ADD_ARCHONLY_SUB_DIRS|INCPUSH_ADD_OLD_VERS);
+    const U8 add_versioned_sub_dirs
+       = (U8)flags & INCPUSH_ADD_VERSIONED_SUB_DIRS;
+    const U8 add_archonly_sub_dirs
+       = (U8)flags & INCPUSH_ADD_ARCHONLY_SUB_DIRS;
     const U8 addoldvers  = (U8)flags & INCPUSH_ADD_OLD_VERS;
     const U8 canrelocate = (U8)flags & INCPUSH_CAN_RELOCATE;
     const U8 unshift     = (U8)flags & INCPUSH_UNSHIFT;
     const U8 push_basedir = (flags & INCPUSH_NOT_BASEDIR) ? 0 : 1;
-    SV *subdir = NULL;
-    AV *inc;
-
-    if (!dir || !*dir)
-       return;
+    AV *const inc = GvAVn(PL_incgv);
 
-    inc = GvAVn(PL_incgv);
-
-    if (addsubdirs || addoldvers) {
-       subdir = newSV(0);
-    }
+    PERL_ARGS_ASSERT_INCPUSH;
+    assert(len > 0);
 
+    /* Could remove this vestigial extra block, if we don't mind a lot of
+       re-indenting diff noise.  */
     {
        SV *libdir;
        /* Change 20189146be79a0596543441fa369c6bf7f85103f, to fix RT#6665,
@@ -4364,8 +4374,7 @@ S_incpush(pTHX_ const char *const dir, STRLEN len, U32 flags)
           pushing. Hence to make it work, need to push the architecture
           (etc) libraries onto a temporary array, then "unshift" that onto
           the front of @INC.  */
-       AV *const av
-           = (addsubdirs || addoldvers) ? (unshift ? newAV() : inc) : NULL;
+       AV *const av = (using_sub_dirs) ? (unshift ? newAV() : inc) : NULL;
 
        if (len) {
            /* I am not convinced that this is valid when PERLLIB_MANGLE is
@@ -4491,7 +4500,8 @@ S_incpush(pTHX_ const char *const dir, STRLEN len, U32 flags)
         * BEFORE pushing libdir onto @INC we may first push version- and
         * archname-specific sub-directories.
         */
-       if (addsubdirs || addoldvers) {
+       if (using_sub_dirs) {
+           SV *subdir;
 #ifdef PERL_INC_VERSION_LIST
            /* Configure terminates PERL_INC_VERSION_LIST with a NULL */
            const char * const incverlist[] = { PERL_INC_VERSION_LIST };
@@ -4501,6 +4511,7 @@ S_incpush(pTHX_ const char *const dir, STRLEN len, U32 flags)
            char *unix;
            STRLEN len;
 
+
            if ((unix = tounixspec_ts(SvPV(libdir,len),NULL)) != NULL) {
                len = strlen(unix);
                while (unix[len-1] == '/') len--;  /* Cosmetic */
@@ -4511,7 +4522,10 @@ S_incpush(pTHX_ const char *const dir, STRLEN len, U32 flags)
                              "Failed to unixify @INC element \"%s\"\n",
                              SvPV(libdir,len));
 #endif
-           if (addsubdirs) {
+
+           subdir = newSVsv(libdir);
+
+           if (add_versioned_sub_dirs) {
 #ifdef MACOS_TRADITIONAL
 #define PERL_ARCH_FMT_PREFIX   ""
 #define PERL_ARCH_FMT_SUFFIX   ":"
@@ -4522,35 +4536,36 @@ S_incpush(pTHX_ const char *const dir, STRLEN len, U32 flags)
 #define PERL_ARCH_FMT_PATH     "/" PERL_FS_VERSION
 #endif
                /* .../version/archname if -d .../version/archname */
-               sv_setsv(subdir, libdir);
                sv_catpvs(subdir, PERL_ARCH_FMT_PATH \
                          PERL_ARCH_FMT_PREFIX ARCHNAME PERL_ARCH_FMT_SUFFIX);
-               subdir = S_incpush_if_exists(aTHX_ av, subdir);
+               subdir = S_incpush_if_exists(aTHX_ av, subdir, libdir);
 
                /* .../version if -d .../version */
-               sv_setsv(subdir, libdir);
                sv_catpvs(subdir, PERL_ARCH_FMT_PATH);
-               subdir = S_incpush_if_exists(aTHX_ av, subdir);
-
-               /* .../archname if -d .../archname */
-               sv_setsv(subdir, libdir);
-               sv_catpvs(subdir,
-                         PERL_ARCH_FMT_PREFIX ARCHNAME PERL_ARCH_FMT_SUFFIX);
-               subdir = S_incpush_if_exists(aTHX_ av, subdir);
-
+               subdir = S_incpush_if_exists(aTHX_ av, subdir, libdir);
            }
 
 #ifdef PERL_INC_VERSION_LIST
            if (addoldvers) {
                for (incver = incverlist; *incver; incver++) {
                    /* .../xxx if -d .../xxx */
-                   Perl_sv_setpvf(aTHX_ subdir, "%"SVf PERL_ARCH_FMT_PREFIX \
-                                  "%s" PERL_ARCH_FMT_SUFFIX,
-                                  SVfARG(libdir), *incver);
-                   subdir = S_incpush_if_exists(aTHX_ av, subdir);
+                   Perl_sv_catpvf(aTHX_ subdir, PERL_ARCH_FMT_PREFIX \
+                                  "%s" PERL_ARCH_FMT_SUFFIX, *incver);
+                   subdir = S_incpush_if_exists(aTHX_ av, subdir, libdir);
                }
            }
 #endif
+
+           if (add_archonly_sub_dirs) {
+               /* .../archname if -d .../archname */
+               sv_catpvs(subdir,
+                         PERL_ARCH_FMT_PREFIX ARCHNAME PERL_ARCH_FMT_SUFFIX);
+               subdir = S_incpush_if_exists(aTHX_ av, subdir, libdir);
+
+           }
+
+           assert (SvREFCNT(subdir) == 1);
+           SvREFCNT_dec(subdir);
        }
 
        /* finally add this lib directory at the end of @INC */
@@ -4583,10 +4598,6 @@ S_incpush(pTHX_ const char *const dir, STRLEN len, U32 flags)
            SvREFCNT_dec(libdir);
        }
     }
-    if (subdir) {
-       assert (SvREFCNT(subdir) == 1);
-       SvREFCNT_dec(subdir);
-    }
 }
 
 STATIC void