This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
In S_mro_get_linear_isa_dfs(), add void casts to silence two warnings
[perl5.git] / perl.c
diff --git a/perl.c b/perl.c
index 3542162..98437a3 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -125,16 +125,22 @@ char *getenv (char *); /* Usually in <stdlib.h> */
 
 static I32 read_e_script(pTHX_ int idx, SV *buf_sv, int maxlen);
 
-#ifdef IAMSUID
-#ifndef DOSUID
-#define DOSUID
-#endif
-#endif /* IAMSUID */
-
-#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
 #ifdef DOSUID
-#undef DOSUID
-#endif
+#  ifdef IAMSUID
+/* Drop scriptname */
+#    define validate_suid(validarg, scriptname, fdscript, suidscript, linestr_sv, rsfp) S_validate_suid(aTHX_ validarg, fdscript, suidscript, linestr_sv, rsfp)
+#  else
+/* Drop suidscript */
+#    define validate_suid(validarg, scriptname, fdscript, suidscript, linestr_sv, rsfp) S_validate_suid(aTHX_ validarg, scriptname, fdscript, linestr_sv, rsfp)
+#  endif
+#else
+#  ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
+/* Drop everything. Heck, don't even try to call it */
+#    define validate_suid(validarg, scriptname, fdscript, suidscript, linestr_sv, rsfp) NOOP
+#  else
+/* Drop almost everything */
+#    define validate_suid(validarg, scriptname, fdscript, suidscript, linestr_sv, rsfp) S_validate_suid(aTHX_ rsfp)
+#  endif
 #endif
 
 #define CALL_BODY_EVAL(myop) \
@@ -181,6 +187,44 @@ S_init_tls_and_interp(PerlInterpreter *my_perl)
     }
 }
 
+
+/* these implement the PERL_SYS_INIT, PERL_SYS_INIT3, PERL_SYS_TERM macros */
+
+void
+Perl_sys_init(int* argc, char*** argv)
+{
+    dVAR;
+
+    PERL_ARGS_ASSERT_SYS_INIT;
+
+    PERL_UNUSED_ARG(argc); /* may not be used depending on _BODY macro */
+    PERL_UNUSED_ARG(argv);
+    PERL_SYS_INIT_BODY(argc, argv);
+}
+
+void
+Perl_sys_init3(int* argc, char*** argv, char*** env)
+{
+    dVAR;
+
+    PERL_ARGS_ASSERT_SYS_INIT3;
+
+    PERL_UNUSED_ARG(argc); /* may not be used depending on _BODY macro */
+    PERL_UNUSED_ARG(argv);
+    PERL_UNUSED_ARG(env);
+    PERL_SYS_INIT3_BODY(argc, argv, env);
+}
+
+void
+Perl_sys_term()
+{
+    dVAR;
+    if (!PL_veto_cleanup) {
+       PERL_SYS_TERM_BODY();
+    }
+}
+
+
 #ifdef PERL_IMPLICIT_SYS
 PerlInterpreter *
 perl_alloc_using(struct IPerlMem* ipM, struct IPerlMem* ipMS,
@@ -190,6 +234,9 @@ perl_alloc_using(struct IPerlMem* ipM, struct IPerlMem* ipMS,
                 struct IPerlProc* ipP)
 {
     PerlInterpreter *my_perl;
+
+    PERL_ARGS_ASSERT_PERL_ALLOC_USING;
+
     /* Newx() needs interpreter, so call malloc() instead */
     my_perl = (PerlInterpreter*)(*ipM->pMalloc)(ipM, sizeof(PerlInterpreter));
     S_init_tls_and_interp(my_perl);
@@ -250,11 +297,14 @@ void
 perl_construct(pTHXx)
 {
     dVAR;
-    PERL_UNUSED_ARG(my_perl);
+
+    PERL_ARGS_ASSERT_PERL_CONSTRUCT;
+
 #ifdef MULTIPLICITY
     init_interp();
     PL_perl_destruct_level = 1;
 #else
+    PERL_UNUSED_ARG(my_perl);
    if (PL_perl_destruct_level > 0)
        init_interp();
 #endif
@@ -268,15 +318,19 @@ perl_construct(pTHXx)
 
     sv_setpv(&PL_sv_no,PL_No);
     /* value lookup in void context - happens to have the side effect
-       of caching the numeric forms.  */
-    SvIV(&PL_sv_no);
+       of caching the numeric forms. However, as &PL_sv_no doesn't contain
+       a string that is a valid numer, we have to turn the public flags by
+       hand:  */
     SvNV(&PL_sv_no);
+    SvIV(&PL_sv_no);
+    SvIOK_on(&PL_sv_no);
+    SvNOK_on(&PL_sv_no);
     SvREADONLY_on(&PL_sv_no);
     SvREFCNT(&PL_sv_no) = (~(U32)0)/2;
 
     sv_setpv(&PL_sv_yes,PL_Yes);
-    SvIV(&PL_sv_yes);
     SvNV(&PL_sv_yes);
+    SvIV(&PL_sv_yes);
     SvREADONLY_on(&PL_sv_yes);
     SvREFCNT(&PL_sv_yes) = (~(U32)0)/2;
 
@@ -317,8 +371,9 @@ perl_construct(pTHXx)
     sv_setpvn(PERL_DEBUG_PAD(1), "", 0);       /* ext/re needs these */
     sv_setpvn(PERL_DEBUG_PAD(2), "", 0);       /* even without DEBUGGING. */
 #ifdef USE_ITHREADS
-    /* First entry is an array of empty elements */
-    Perl_av_create_and_push(aTHX_ &PL_regex_padav,(SV*)newAV());
+    /* First entry is a list of empty elements. It needs to be initialised
+       else all hell breaks loose in S_find_uninit_var().  */
+    Perl_av_create_and_push(aTHX_ &PL_regex_padav, newSVpvs(""));
     PL_regex_pad = AvARRAY(PL_regex_padav);
 #endif
 #ifdef USE_REENTRANT_API
@@ -435,6 +490,8 @@ Perl_dump_sv_child(pTHX_ SV *sv)
     int returned_errno;
     unsigned char buffer[256];
 
+    PERL_ARGS_ASSERT_DUMP_SV_CHILD;
+
     if(sock == -1 || debug_fd == -1)
        return;
 
@@ -531,13 +588,16 @@ int
 perl_destruct(pTHXx)
 {
     dVAR;
-    VOL int destruct_level;  /* 0=none, 1=full, 2=full with checks */
+    VOL signed char destruct_level;  /* see possible values in intrpvar.h */
     HV *hv;
 #ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
     pid_t child;
 #endif
 
+    PERL_ARGS_ASSERT_PERL_DESTRUCT;
+#ifndef MULTIPLICITY
     PERL_UNUSED_ARG(my_perl);
+#endif
 
     /* wait for all pseudo-forked children to finish */
     PERL_WAIT_FOR_CHILDREN;
@@ -836,28 +896,6 @@ perl_destruct(pTHXx)
      * REGEXPs in the parent interpreter
      * we need to manually ReREFCNT_dec for the clones
      */
-    {
-        I32 i = AvFILLp(PL_regex_padav) + 1;
-        SV * const * const ary = AvARRAY(PL_regex_padav);
-
-        while (i) {
-            SV * const resv = ary[--i];
-
-            if (SvFLAGS(resv) & SVf_BREAK) {
-                /* this is PL_reg_curpm, already freed
-                 * flag is set in regexec.c:S_regtry
-                 */
-                SvFLAGS(resv) &= ~SVf_BREAK;
-            }
-           else if(SvREPADTMP(resv)) {
-             SvREPADTMP_off(resv);
-           }
-            else if(SvIOKp(resv)) {
-               REGEXP *re = INT2PTR(REGEXP *,SvIVX(resv));
-                ReREFCNT_dec(re);
-            }
-        }
-    }
     SvREFCNT_dec(PL_regex_padav);
     PL_regex_padav = NULL;
     PL_regex_pad = NULL;
@@ -880,7 +918,6 @@ perl_destruct(pTHXx)
     }
 
     /* switches */
-    PL_preprocess   = FALSE;
     PL_minus_n      = FALSE;
     PL_minus_p      = FALSE;
     PL_minus_l      = FALSE;
@@ -1090,18 +1127,11 @@ perl_destruct(pTHXx)
     }
 
     /* Now absolutely destruct everything, somehow or other, loops or no. */
-    SvFLAGS(PL_fdpid) |= SVTYPEMASK;           /* don't clean out pid table now */
-    SvFLAGS(PL_strtab) |= SVTYPEMASK;          /* don't clean out strtab now */
 
     /* the 2 is for PL_fdpid and PL_strtab */
-    while (PL_sv_count > 2 && sv_clean_all())
+    while (sv_clean_all() > 2)
        ;
 
-    SvFLAGS(PL_fdpid) &= ~SVTYPEMASK;
-    SvFLAGS(PL_fdpid) |= SVt_PVAV;
-    SvFLAGS(PL_strtab) &= ~SVTYPEMASK;
-    SvFLAGS(PL_strtab) |= SVt_PVHV;
-
     AvREAL_off(PL_fdpid);              /* no surviving entries */
     SvREFCNT_dec(PL_fdpid);            /* needed in io_close() */
     PL_fdpid = NULL;
@@ -1191,7 +1221,8 @@ perl_destruct(pTHXx)
                        " flags=0x%"UVxf
                        " refcnt=%"UVuf pTHX__FORMAT "\n"
                        "\tallocated at %s:%d %s %s%s\n",
-                       (void*)sv, sv->sv_flags, sv->sv_refcnt pTHX__VALUE,
+                       (void*)sv, (UV)sv->sv_flags, (UV)sv->sv_refcnt
+                       pTHX__VALUE,
                        sv->sv_debug_file ? sv->sv_debug_file : "(unknown)",
                        sv->sv_debug_line,
                        sv->sv_debug_inpad ? "for" : "by",
@@ -1225,6 +1256,10 @@ perl_destruct(pTHXx)
     }
 #endif
 #endif
+#ifdef DEBUG_LEAKING_SCALARS_ABORT
+    if (PL_sv_count)
+       abort();
+#endif
     PL_sv_count = 0;
 
 #ifdef PERL_DEBUG_READONLY_OPS
@@ -1321,6 +1356,8 @@ perl_free(pTHXx)
 {
     dVAR;
 
+    PERL_ARGS_ASSERT_PERL_FREE;
+
     if (PL_veto_cleanup)
        return;
 
@@ -1332,10 +1369,17 @@ perl_free(pTHXx)
         */
        const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
        if (!s || atoi(s) == 0) {
+           const U32 old_debug = PL_debug;
            /* Emulate the PerlHost behaviour of free()ing all memory allocated in this
               thread at thread exit.  */
+           if (DEBUG_m_TEST) {
+               PerlIO_puts(Perl_debug_log, "Disabling memory debugging as we "
+                           "free this thread's memory\n");
+               PL_debug &= ~ DEBUG_m_FLAG;
+           }
            while(aTHXx->Imemory_debug_header.next != &(aTHXx->Imemory_debug_header))
                safesysfree(sTHX + (char *)(aTHXx->Imemory_debug_header.next));
+           PL_debug = old_debug;
        }
     }
 #endif
@@ -1465,14 +1509,14 @@ perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env)
     int ret;
     dJMPENV;
 
+    PERL_ARGS_ASSERT_PERL_PARSE;
+#ifndef MULTIPLICITY
     PERL_UNUSED_ARG(my_perl);
+#endif
 
-#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
-#ifdef IAMSUID
-#undef IAMSUID
-    Perl_croak(aTHX_ "suidperl is no longer needed since the kernel can now execute\n\
-setuid perl scripts securely.\n");
-#endif /* IAMSUID */
+#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW_AND_IAMSUID
+    Perl_croak(aTHX_ "suidperl is no longer needed since the kernel can now "
+              "execute\nsetuid perl scripts securely.\n");
 #endif
 
 #if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT)
@@ -1655,9 +1699,11 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
     char **argv = PL_origargv;
     const char *scriptname = NULL;
     VOL bool dosearch = FALSE;
+#ifdef DOSUID
     const char *validarg = "";
+#endif
     register SV *sv;
-    register char *s, c;
+    register char c;
     const char *cddir = NULL;
 #ifdef USE_SITECUSTOMIZE
     bool minus_f = FALSE;
@@ -1672,6 +1718,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
     SAVEFREESV(sv);
     init_main_stash();
 
+    {
+       const char *s;
     for (argc--,argv++; argc > 0; argc--,argv++) {
        if (argv[0][0] != '-' || !argv[0][1])
            break;
@@ -1743,7 +1791,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
            if (argv[1] && !strcmp(argv[1], "Dev:Pseudo"))
                break;
 #endif
-           forbid_setid('e', -1);
+           forbid_setid('e', FALSE);
            if (!PL_e_script) {
                PL_e_script = newSVpvs("");
                add_read_e_script = TRUE;
@@ -1767,7 +1815,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
            goto reswitch;
 
        case 'I':       /* -I handled both here and in moreswitches() */
-           forbid_setid('I', -1);
+           forbid_setid('I', FALSE);
            if (!*++s && (s=argv[1]) != NULL) {
                argc--,argv++;
            }
@@ -1783,13 +1831,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
            else
                Perl_croak(aTHX_ "No directory specified for -I");
            break;
-       case 'P':
-           forbid_setid('P', -1);
-           PL_preprocess = TRUE;
-           s++;
-           goto reswitch;
        case 'S':
-           forbid_setid('S', -1);
+           forbid_setid('S', FALSE);
            dosearch = TRUE;
            s++;
            goto reswitch;
@@ -1799,56 +1842,18 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
 
                Perl_av_create_and_push(aTHX_ &PL_preambleav, newSVpvs("use Config;"));
                if (*++s != ':')  {
-                   STRLEN opts;
-               
-                   opts_prog = newSVpvs("print Config::myconfig(),");
-#ifdef VMS
-                   sv_catpvs(opts_prog,"\"\\nCharacteristics of this PERLSHR image: \\n\",");
-#else
-                   sv_catpvs(opts_prog,"\"\\nCharacteristics of this binary (from libperl): \\n\",");
-#endif
-                   opts = SvCUR(opts_prog);
-
-                   Perl_sv_catpv(aTHX_ opts_prog,"\"  Compile-time options:"
+                   /* Can't do newSVpvs() as that would involve pre-processor
+                      condititionals inside a macro expansion.  */
+                   opts_prog = Perl_newSVpv(aTHX_ "$_ = join ' ', sort qw("
 #  ifdef DEBUGGING
                             " DEBUGGING"
 #  endif
-#  ifdef DEBUG_LEAKING_SCALARS
-                            " DEBUG_LEAKING_SCALARS"
-#  endif
-#  ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
-                            " DEBUG_LEAKING_SCALARS_FORK_DUMP"
-#  endif
-#  ifdef FAKE_THREADS
-                            " FAKE_THREADS"
-#  endif
-#  ifdef MULTIPLICITY
-                            " MULTIPLICITY"
-#  endif
-#  ifdef MYMALLOC
-                            " MYMALLOC"
-#  endif
 #  ifdef NO_MATHOMS
                             " NO_MATHOMS"
 #  endif
-#  ifdef PERL_DEBUG_READONLY_OPS
-                            " PERL_DEBUG_READONLY_OPS"
-#  endif
 #  ifdef PERL_DONT_CREATE_GVSV
                             " PERL_DONT_CREATE_GVSV"
 #  endif
-#  ifdef PERL_GLOBAL_STRUCT
-                            " PERL_GLOBAL_STRUCT"
-#  endif
-#  ifdef PERL_IMPLICIT_CONTEXT
-                            " PERL_IMPLICIT_CONTEXT"
-#  endif
-#  ifdef PERL_IMPLICIT_SYS
-                            " PERL_IMPLICIT_SYS"
-#  endif
-#  ifdef PERL_MAD
-                            " PERL_MAD"
-#  endif
 #  ifdef PERL_MALLOC_WRAP
                             " PERL_MALLOC_WRAP"
 #  endif
@@ -1867,85 +1872,24 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
 #  ifdef PERL_MEM_LOG_TIMESTAMP
                             " PERL_MEM_LOG_TIMESTAMP"
 #  endif
-#  ifdef PERL_NEED_APPCTX
-                            " PERL_NEED_APPCTX"
-#  endif
-#  ifdef PERL_NEED_TIMESBASE
-                            " PERL_NEED_TIMESBASE"
-#  endif
-#  ifdef PERL_OLD_COPY_ON_WRITE
-                            " PERL_OLD_COPY_ON_WRITE"
-#  endif
-#  ifdef PERL_POISON
-                            " PERL_POISON"
-#  endif
-#  ifdef PERL_TRACK_MEMPOOL
-                            " PERL_TRACK_MEMPOOL"
-#  endif
 #  ifdef PERL_USE_SAFE_PUTENV
                             " PERL_USE_SAFE_PUTENV"
 #  endif
-#  ifdef PERL_USES_PL_PIDSTATUS
-                            " PERL_USES_PL_PIDSTATUS"
-#  endif
-#  ifdef PL_OP_SLAB_ALLOC
-                            " PL_OP_SLAB_ALLOC"
-#  endif
-#  ifdef THREADS_HAVE_PIDS
-                            " THREADS_HAVE_PIDS"
-#  endif
-#  ifdef USE_64_BIT_ALL
-                            " USE_64_BIT_ALL"
-#  endif
-#  ifdef USE_64_BIT_INT
-                            " USE_64_BIT_INT"
-#  endif
-#  ifdef USE_ITHREADS
-                            " USE_ITHREADS"
-#  endif
-#  ifdef USE_LARGE_FILES
-                            " USE_LARGE_FILES"
-#  endif
-#  ifdef USE_LONG_DOUBLE
-                            " USE_LONG_DOUBLE"
-#  endif
-#  ifdef USE_PERLIO
-                            " USE_PERLIO"
-#  endif
-#  ifdef USE_REENTRANT_API
-                            " USE_REENTRANT_API"
-#  endif
-#  ifdef USE_SFIO
-                            " USE_SFIO"
-#  endif
 #  ifdef USE_SITECUSTOMIZE
                             " USE_SITECUSTOMIZE"
 #  endif              
-#  ifdef USE_SOCKS
-                            " USE_SOCKS"
-#  endif
-                            );
+                                            , 0);
 
-                   while (SvCUR(opts_prog) > opts+76) {
-                       /* find last space after "options: " and before col 76
-                        */
-
-                       const char *space;
-                       char * const pv = SvPV_nolen(opts_prog);
-                       const char c = pv[opts+76];
-                       pv[opts+76] = '\0';
-                       space = strrchr(pv+opts+26, ' ');
-                       pv[opts+76] = c;
-                       if (!space) break; /* "Can't happen" */
-
-                       /* break the line before that space */
-
-                       opts = space - pv;
-                       Perl_sv_insert(aTHX_ opts_prog, opts, 0,
-                                 STR_WITH_LEN("\\n                       "));
-                   }
+                   sv_catpv(opts_prog, PL_bincompat_options);
+                   /* Terminate the qw(, and then wrap at 76 columns.  */
+                   sv_catpvs(opts_prog, "); s/(?=.{53})(.{1,53}) /$1\\n                        /mg;print Config::myconfig(),");
+#ifdef VMS
+                   sv_catpvs(opts_prog,"\"\\nCharacteristics of this PERLSHR image: \\n");
+#else
+                   sv_catpvs(opts_prog,"\"\\nCharacteristics of this binary (from libperl): \\n");
+#endif
 
-                   sv_catpvs(opts_prog,"\\n\",");
+                   sv_catpvs(opts_prog,"  Compile-time options: $_\\n\",");
 
 #if defined(LOCAL_PATCH_COUNT)
                    if (LOCAL_PATCH_COUNT > 0) {
@@ -1960,15 +1904,13 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
                    }
 #endif
                    Perl_sv_catpvf(aTHX_ opts_prog,
-                                  "\"  Built under %s\\n\"",OSNAME);
+                                  "\"  Built under %s\\n",OSNAME);
 #ifdef __DATE__
 #  ifdef __TIME__
-                   Perl_sv_catpvf(aTHX_ opts_prog,
-                                  ",\"  Compiled at %s %s\\n\"",__DATE__,
-                                  __TIME__);
+                   sv_catpvs(opts_prog,
+                             "  Compiled at " __DATE__ " " __TIME__ "\\n\"");
 #  else
-                   Perl_sv_catpvf(aTHX_ opts_prog,",\"  Compiled on %s\\n\"",
-                                  __DATE__);
+                   sv_catpvs(opts_prog, "  Compiled on " __DATE__ "\\n\"");
 #  endif
 #endif
                    sv_catpvs(opts_prog, "; $\"=\"\\n    \"; "
@@ -2022,15 +1964,19 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
            Perl_croak(aTHX_ "Unrecognized switch: -%s  (-h will show valid options)",s);
        }
     }
+    }
+
   switch_end:
 
+    {
+       char *s;
+
     if (
 #ifndef SECURE_INTERNAL_GETENV
         !PL_tainting &&
 #endif
        (s = PerlEnv_getenv("PERL5OPT")))
     {
-       const char *popt = s;
        while (isSPACE(*s))
            s++;
        if (*s == '-' && *(s+1) == 'T') {
@@ -2041,7 +1987,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
        else {
            char *popt_copy = NULL;
            while (s && *s) {
-               char *d;
+               const char *d;
                while (isSPACE(*s))
                    s++;
                if (*s == '-') {
@@ -2052,14 +1998,14 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
                d = s;
                if (!*s)
                    break;
-               if (!strchr("CDIMUdmtwA", *s))
+               if (!strchr("CDIMUdmtw", *s))
                    Perl_croak(aTHX_ "Illegal switch in PERL5OPT: -%c", *s);
                while (++s && *s) {
                    if (isSPACE(*s)) {
                        if (!popt_copy) {
-                           popt_copy = SvPVX(sv_2mortal(newSVpv(popt,0)));
-                           s = popt_copy + (s - popt);
-                           d = popt_copy + (d - popt);
+                           popt_copy = SvPVX(sv_2mortal(newSVpv(d,0)));
+                           s = popt_copy + (s - d);
+                           d = popt_copy;
                        }
                        *s++ = '\0';
                        break;
@@ -2076,6 +2022,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
            }
        }
     }
+    }
 
 #ifdef USE_SITECUSTOMIZE
     if (!minus_f) {
@@ -2106,9 +2053,12 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
     init_perllib();
 
     {
-       int suidscript;
-       const int fdscript
-           = open_script(scriptname, dosearch, sv, &suidscript, &rsfp);
+       bool suidscript = FALSE;
+
+#ifdef DOSUID
+       const int fdscript =
+#endif
+           open_script(scriptname, dosearch, &suidscript, &rsfp);
 
        validate_suid(validarg, scriptname, fdscript, suidscript,
                linestr_sv, rsfp);
@@ -2136,10 +2086,10 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
 #endif
            ) {
 
-           /* This will croak if suidscript is >= 0, as -x cannot be used with
+           /* This will croak if suidscript is true, as -x cannot be used with
               setuid scripts.  */
            forbid_setid('x', suidscript);
-           /* Hence you can't get here if suidscript >= 0  */
+           /* Hence you can't get here if suidscript is true */
 
            find_beginning(linestr_sv, rsfp);
            if (cddir && PerlDir_chdir( (char *)cddir ) < 0)
@@ -2228,6 +2178,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
         }
     }
 
+    {
+       const char *s;
     if ((s = PerlEnv_getenv("PERL_SIGNALS"))) {
         if (strEQ(s, "unsafe"))
              PL_signals |=  PERL_SIGNALS_UNSAFE_FLAG;
@@ -2236,8 +2188,11 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
         else
              Perl_croak(aTHX_ "PERL_SIGNALS illegal: \"%s\"", s);
     }
+    }
 
 #ifdef PERL_MAD
+    {
+       const char *s;
     if ((s = PerlEnv_getenv("PERL_XMLDUMP"))) {
        PL_madskills = 1;
        PL_minus_c = 1;
@@ -2248,11 +2203,16 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
            if (!PL_xmlfp)
                Perl_croak(aTHX_ "Can't open %s", s);
        }
-       my_setenv("PERL_XMLDUMP", Nullch);      /* hide from subprocs */
+       my_setenv("PERL_XMLDUMP", NULL);        /* hide from subprocs */
     }
+    }
+
+    {
+       const char *s;
     if ((s = PerlEnv_getenv("PERL_MADSKILLS"))) {
        PL_madskills = atoi(s);
-       my_setenv("PERL_MADSKILLS", Nullch);    /* hide from subprocs */
+       my_setenv("PERL_MADSKILLS", NULL);      /* hide from subprocs */
+    }
     }
 #endif
 
@@ -2286,7 +2246,6 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
 #endif
     CopLINE_set(PL_curcop, 0);
     PL_curstash = PL_defstash;
-    PL_preprocess = FALSE;
     if (PL_e_script) {
        SvREFCNT_dec(PL_e_script);
        PL_e_script = NULL;
@@ -2305,8 +2264,11 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
     FREETMPS;
 
 #ifdef MYMALLOC
+    {
+       const char *s;
     if ((s=PerlEnv_getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2)
        dump_mstats("after compilation:");
+    }
 #endif
 
     ENTER;
@@ -2330,7 +2292,10 @@ perl_run(pTHXx)
     int ret = 0;
     dJMPENV;
 
+    PERL_ARGS_ASSERT_PERL_RUN;
+#ifndef MULTIPLICITY
     PERL_UNUSED_ARG(my_perl);
+#endif
 
     oldscope = PL_scopestack_ix;
 #ifdef VMS
@@ -2394,8 +2359,6 @@ S_run_body(pTHX_ I32 oldscope)
        if (!DEBUG_q_TEST)
          PERL_DEBUG(PerlIO_printf(Perl_debug_log, "\nEXECUTING...\n\n"));
 #endif
-       DEBUG_S(PerlIO_printf(Perl_debug_log, "main thread is 0x%"UVxf"\n",
-                             PTR2UV(thr)));
 
        if (PL_minus_c) {
 #ifdef MACOS_TRADITIONAL
@@ -2448,6 +2411,9 @@ SV*
 Perl_get_sv(pTHX_ const char *name, I32 create)
 {
     GV *gv;
+
+    PERL_ARGS_ASSERT_GET_SV;
+
     gv = gv_fetchpv(name, create, SVt_PV);
     if (gv)
        return GvSV(gv);
@@ -2470,6 +2436,9 @@ AV*
 Perl_get_av(pTHX_ const char *name, I32 create)
 {
     GV* const gv = gv_fetchpv(name, create, SVt_PVAV);
+
+    PERL_ARGS_ASSERT_GET_AV;
+
     if (create)
        return GvAVn(gv);
     if (gv)
@@ -2493,6 +2462,9 @@ HV*
 Perl_get_hv(pTHX_ const char *name, I32 create)
 {
     GV* const gv = gv_fetchpv(name, create, SVt_PVHV);
+
+    PERL_ARGS_ASSERT_GET_HV;
+
     if (create)
        return GvHVn(gv);
     if (gv)
@@ -2525,9 +2497,11 @@ Perl_get_cvn_flags(pTHX_ const char *name, STRLEN len, I32 flags)
     /* XXX this is probably not what they think they're getting.
      * It has the same effect as "sub name;", i.e. just a forward
      * declaration! */
+
+    PERL_ARGS_ASSERT_GET_CVN_FLAGS;
+
     if ((flags & ~GV_NOADD_MASK) && !GvCVu(gv)) {
-       SV *const sv = newSVpvn(name,len);
-       SvFLAGS(sv) |= flags & SVf_UTF8;
+       SV *const sv = newSVpvn_flags(name, len, flags & SVf_UTF8);
        return newSUB(start_subparse(FALSE, 0),
                      newSVOP(OP_CONST, 0, sv),
                      NULL, NULL);
@@ -2540,6 +2514,8 @@ Perl_get_cvn_flags(pTHX_ const char *name, STRLEN len, I32 flags)
 CV*
 Perl_get_cv(pTHX_ const char *name, I32 flags)
 {
+    PERL_ARGS_ASSERT_GET_CV;
+
     return get_cvn_flags(name, strlen(name), flags);
 }
 
@@ -2565,10 +2541,12 @@ Perl_call_argv(pTHX_ const char *sub_name, I32 flags, register char **argv)
     dVAR;
     dSP;
 
+    PERL_ARGS_ASSERT_CALL_ARGV;
+
     PUSHMARK(SP);
     if (argv) {
        while (*argv) {
-           XPUSHs(sv_2mortal(newSVpv(*argv,0)));
+           mXPUSHs(newSVpv(*argv,0));
            argv++;
        }
        PUTBACK;
@@ -2589,6 +2567,8 @@ Perl_call_pv(pTHX_ const char *sub_name, I32 flags)
                        /* name of the subroutine */
                        /* See G_* flags in cop.h */
 {
+    PERL_ARGS_ASSERT_CALL_PV;
+
     return call_sv((SV*)get_cv(sub_name, TRUE), flags);
 }
 
@@ -2606,6 +2586,8 @@ Perl_call_method(pTHX_ const char *methname, I32 flags)
                                /* name of the subroutine */
                        /* See G_* flags in cop.h */
 {
+    PERL_ARGS_ASSERT_CALL_METHOD;
+
     return call_sv(sv_2mortal(newSVpv(methname,0)), flags | G_METHOD);
 }
 
@@ -2620,7 +2602,7 @@ L<perlcall>.
 */
 
 I32
-Perl_call_sv(pTHX_ SV *sv, I32 flags)
+Perl_call_sv(pTHX_ SV *sv, VOL I32 flags)
                        /* See G_* flags in cop.h */
 {
     dVAR; dSP;
@@ -2634,18 +2616,23 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags)
     OP* const oldop = PL_op;
     dJMPENV;
 
+    PERL_ARGS_ASSERT_CALL_SV;
+
     if (flags & G_DISCARD) {
        ENTER;
        SAVETMPS;
     }
+    if (!(flags & G_WANT)) {
+       /* Backwards compatibility - as G_SCALAR was 0, it could be omitted.
+        */
+       flags |= G_SCALAR;
+    }
 
     Zero(&myop, 1, LOGOP);
     myop.op_next = NULL;
     if (!(flags & G_NOARGS))
        myop.op_flags |= OPf_STACKED;
-    myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID :
-                     (flags & G_ARRAY) ? OPf_WANT_LIST :
-                     OPf_WANT_SCALAR);
+    myop.op_flags |= OP_GIMME_REVERSE(flags);
     SAVEOP();
     PL_op = (OP*)&myop;
 
@@ -2667,7 +2654,9 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags)
        Zero(&method_op, 1, UNOP);
        method_op.op_next = PL_op;
        method_op.op_ppaddr = PL_ppaddr[OP_METHOD];
+       method_op.op_type = OP_METHOD;
        myop.op_ppaddr = PL_ppaddr[OP_ENTERSUB];
+       myop.op_type = OP_ENTERSUB;
        PL_op = (OP*)&method_op;
     }
 
@@ -2690,8 +2679,9 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags)
  redo_body:
            CALL_BODY_SUB((OP*)&myop);
            retval = PL_stack_sp - (PL_stack_base + oldmark);
-           if (!(flags & G_KEEPERR))
-               sv_setpvn(ERRSV,"",0);
+           if (!(flags & G_KEEPERR)) {
+               CLEAR_ERRSV();
+           }
            break;
        case 1:
            STATUS_ALL_FAILURE;
@@ -2712,7 +2702,7 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags)
                goto redo_body;
            }
            PL_stack_sp = PL_stack_base + oldmark;
-           if (flags & G_ARRAY)
+           if ((flags & G_WANT) == G_ARRAY)
                retval = 0;
            else {
                retval = 1;
@@ -2760,6 +2750,8 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags)
     OP* const oldop = PL_op;
     dJMPENV;
 
+    PERL_ARGS_ASSERT_EVAL_SV;
+
     if (flags & G_DISCARD) {
        ENTER;
        SAVETMPS;
@@ -2775,9 +2767,7 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags)
        myop.op_flags = OPf_STACKED;
     myop.op_next = NULL;
     myop.op_type = OP_ENTEREVAL;
-    myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID :
-                     (flags & G_ARRAY) ? OPf_WANT_LIST :
-                     OPf_WANT_SCALAR);
+    myop.op_flags |= OP_GIMME_REVERSE(flags);
     if (flags & G_KEEPERR)
        myop.op_flags |= OPf_SPECIAL;
 
@@ -2791,8 +2781,9 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags)
  redo_body:
        CALL_BODY_EVAL((OP*)&myop);
        retval = PL_stack_sp - (PL_stack_base + oldmark);
-       if (!(flags & G_KEEPERR))
-           sv_setpvn(ERRSV,"",0);
+       if (!(flags & G_KEEPERR)) {
+           CLEAR_ERRSV();
+       }
        break;
     case 1:
        STATUS_ALL_FAILURE;
@@ -2813,7 +2804,7 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags)
            goto redo_body;
        }
        PL_stack_sp = PL_stack_base + oldmark;
-       if (flags & G_ARRAY)
+       if ((flags & G_WANT) == G_ARRAY)
            retval = 0;
        else {
            retval = 1;
@@ -2848,6 +2839,8 @@ Perl_eval_pv(pTHX_ const char *p, I32 croak_on_error)
     dSP;
     SV* sv = newSVpv(p, 0);
 
+    PERL_ARGS_ASSERT_EVAL_PV;
+
     eval_sv(sv, G_SCALAR);
     SvREFCNT_dec(sv);
 
@@ -2881,6 +2874,9 @@ Perl_require_pv(pTHX_ const char *pv)
     dVAR;
     dSP;
     SV* sv;
+
+    PERL_ARGS_ASSERT_REQUIRE_PV;
+
     PUSHSTACKi(PERLSI_REQUIRE);
     PUTBACK;
     sv = Perl_newSVpvf(aTHX_ "require q%c%s%c", 0, pv, 0);
@@ -2894,6 +2890,8 @@ Perl_magicname(pTHX_ const char *sym, const char *name, I32 namlen)
 {
     register GV * const gv = gv_fetchpv(sym, GV_ADD, SVt_PV);
 
+    PERL_ARGS_ASSERT_MAGICNAME;
+
     if (gv)
        sv_magic(GvSV(gv), (SV*)gv, PERL_MAGIC_sv, name, namlen);
 }
@@ -2921,7 +2919,6 @@ S_usage(pTHX_ const char *name)           /* XXX move this out into a module ? */
 "-[mM][-]module    execute \"use/no module...\" before executing program",
 "-n                assume \"while (<>) { ... }\" loop around program",
 "-p                assume loop like -n but print line also, like sed",
-"-P                run program through C preprocessor before compilation",
 "-s                enable rudimentary parsing for switches after programfile",
 "-S                look for programfile using PATH environment variable",
 "-t                enable tainting warnings",
@@ -2939,6 +2936,8 @@ NULL
 };
     const char * const *p = usage_msg;
 
+    PERL_ARGS_ASSERT_USAGE;
+
     PerlIO_printf(PerlIO_stdout(),
                  "\nUsage: %s [switches] [--] [programfile] [arguments]",
                  name);
@@ -2961,7 +2960,7 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp)
       "  t  Trace execution",
       "  o  Method and overloading resolution",
       "  c  String/numeric conversions",
-      "  P  Print profiling info, preprocessor command for -P, source file input state",
+      "  P  Print profiling info, source file input state",
       "  m  Memory allocation",
       "  f  Format processing",
       "  r  Regular expression parsing and execution",
@@ -2970,7 +2969,6 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp)
       "  H  Hash dump -- usurps values()",
       "  X  Scratchpad allocation",
       "  D  Cleaning up",
-      "  S  Thread synchronization",
       "  T  Tokenising",
       "  R  Include reference counts of dumped variables (eg when using -Ds)",
       "  J  Do not s,t,P-debug (Jump over) opcodes within package DB",
@@ -2981,6 +2979,9 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp)
       NULL
     };
     int i = 0;
+
+    PERL_ARGS_ASSERT_GET_DEBUG_OPTS;
+
     if (isALPHA(**s)) {
        /* if adding extra options, remember to update DEBUG_MASK */
        static const char debopts[] = "psltocPmfrxuUHXDSTRJvCAq";
@@ -3013,11 +3014,14 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp)
 
 /* This routine handles any switches that can be given during run */
 
-char *
-Perl_moreswitches(pTHX_ char *s)
+const char *
+Perl_moreswitches(pTHX_ const char *s)
 {
     dVAR;
     UV rschar;
+    const char option = *s; /* used to remember option in -m/-M code */
+
+    PERL_ARGS_ASSERT_MORESWITCHES;
 
     switch (*s) {
     case '0':
@@ -3083,7 +3087,7 @@ Perl_moreswitches(pTHX_ char *s)
        s++;
        return s;
     case 'd':
-       forbid_setid('d', -1);
+       forbid_setid('d', FALSE);
        s++;
 
         /* -dt indicates to the debugger that threads will be used */
@@ -3095,21 +3099,23 @@ Perl_moreswitches(pTHX_ char *s)
        /* The following permits -d:Mod to accepts arguments following an =
           in the fashion that -MSome::Mod does. */
        if (*s == ':' || *s == '=') {
-            const char *start;
+           const char *start = ++s;
+           const char *const end = s + strlen(s);
            SV * const sv = newSVpvs("use Devel::");
-           start = ++s;
+
            /* We now allow -d:Module=Foo,Bar */
            while(isALNUM(*s) || *s==':') ++s;
            if (*s != '=')
-               sv_catpv(sv, start);
+               sv_catpvn(sv, start, end - start);
            else {
                sv_catpvn(sv, start, s-start);
                /* Don't use NUL as q// delimiter here, this string goes in the
                 * environment. */
                Perl_sv_catpvf(aTHX_ sv, " split(/,/,q{%s});", ++s);
            }
-           s += strlen(s);
+           s = end;
            my_setenv("PERL5DB", SvPV_nolen_const(sv));
+           SvREFCNT_dec(sv);
        }
        if (!PL_perldb) {
            PL_perldb = PERLDB_ALL;
@@ -3119,7 +3125,7 @@ Perl_moreswitches(pTHX_ char *s)
     case 'D':
     {  
 #ifdef DEBUGGING
-       forbid_setid('D', -1);
+       forbid_setid('D', FALSE);
        s++;
        PL_debug = get_debug_opts( (const char **)&s, 1) | DEBUG_TOP_FLAG;
 #else /* !DEBUGGING */
@@ -3155,12 +3161,12 @@ Perl_moreswitches(pTHX_ char *s)
        }
        return s;
     case 'I':  /* -I handled both here and in parse_body() */
-       forbid_setid('I', -1);
+       forbid_setid('I', FALSE);
        ++s;
        while (*s && isSPACE(*s))
            ++s;
        if (*s) {
-           char *e, *p;
+           const char *e, *p;
            p = s;
            /* ignore trailing spaces (possibly followed by other switches) */
            do {
@@ -3204,14 +3210,16 @@ Perl_moreswitches(pTHX_ char *s)
        }
        return s;
     case 'M':
-       forbid_setid('M', -1);  /* XXX ? */
+       forbid_setid('M', FALSE);       /* XXX ? */
        /* FALL THROUGH */
     case 'm':
-       forbid_setid('m', -1);  /* XXX ? */
+       forbid_setid('m', FALSE);       /* XXX ? */
        if (*++s) {
-           char *start;
+           const char *start;
+           const char *end;
            SV *sv;
            const char *use = "use ";
+           bool colon = FALSE;
            /* -M-foo == 'no foo'       */
            /* Leading space on " no " is deliberate, to make both
               possibilities the same length.  */
@@ -3219,29 +3227,42 @@ Perl_moreswitches(pTHX_ char *s)
            sv = newSVpvn(use,4);
            start = s;
            /* We allow -M'Module qw(Foo Bar)'  */
-           while(isALNUM(*s) || *s==':') ++s;
+           while(isALNUM(*s) || *s==':') {
+               if( *s++ == ':' ) {
+                   if( *s == ':' ) 
+                       s++;
+                   else
+                       colon = TRUE;
+               }
+           }
+           if (s == start)
+               Perl_croak(aTHX_ "Module name required with -%c option",
+                                   option);
+           if (colon) 
+               Perl_croak(aTHX_ "Invalid module name %.*s with -%c option: "
+                                   "contains single ':'",
+                                   (int)(s - start), start, option);
+           end = s + strlen(s);
            if (*s != '=') {
-               sv_catpv(sv, start);
-               if (*(start-1) == 'm') {
+               sv_catpvn(sv, start, end - start);
+               if (option == 'm') {
                    if (*s != '\0')
                        Perl_croak(aTHX_ "Can't use '%c' after -mname", *s);
                    sv_catpvs( sv, " ()");
                }
            } else {
-                if (s == start)
-                    Perl_croak(aTHX_ "Module name required with -%c option",
-                              s[-1]);
                sv_catpvn(sv, start, s-start);
-               sv_catpvs(sv, " split(/,/,q");
-               sv_catpvs(sv, "\0");        /* Use NUL as q//-delimiter. */
-               sv_catpv(sv, ++s);
+               /* Use NUL as q''-delimiter.  */
+               sv_catpvs(sv, " split(/,/,q\0");
+               ++s;
+               sv_catpvn(sv, s, end - s);
                sv_catpvs(sv,  "\0)");
            }
-           s += strlen(s);
+           s = end;
            Perl_av_create_and_push(aTHX_ &PL_preambleav, sv);
        }
        else
-           Perl_croak(aTHX_ "Missing argument to -%c", *(s-1));
+           Perl_croak(aTHX_ "Missing argument to -%c", option);
        return s;
     case 'n':
        PL_minus_n = TRUE;
@@ -3252,7 +3273,7 @@ Perl_moreswitches(pTHX_ char *s)
        s++;
        return s;
     case 's':
-       forbid_setid('s', -1);
+       forbid_setid('s', FALSE);
        PL_doswitches = TRUE;
        s++;
        return s;
@@ -3410,8 +3431,10 @@ Internet, point your browser at http://www.perl.org/, the Perl Home Page.\n\n");
        return s;
     case '*':
     case ' ':
-       if (s[1] == '-')        /* Additional switches on #! line. */
-           return s+2;
+        while( *s == ' ' )
+          ++s;
+       if (s[0] == '-')        /* Additional switches on #! line. */
+           return s+1;
        break;
     case '-':
     case 0:
@@ -3425,10 +3448,6 @@ Internet, point your browser at http://www.perl.org/, the Perl Home Page.\n\n");
     case 'S':                  /* OS/2 needs -S on "extproc" line. */
        break;
 #endif
-    case 'P':
-       if (PL_preprocess)
-           return s+1;
-       /* FALL THROUGH */
     default:
        Perl_croak(aTHX_ "Can't emulate -%.1s on #! line",s);
     }
@@ -3544,7 +3563,7 @@ S_init_main_stash(pTHX)
     gv_SVadd(PL_errgv);
 #endif
     sv_grow(ERRSV, 240);       /* Preallocate - for immediate signals. */
-    sv_setpvn(ERRSV, "", 0);
+    CLEAR_ERRSV();
     PL_curstash = PL_defstash;
     CopSTASH_set(&PL_compiling, PL_defstash);
     PL_debstash = GvHV(gv_fetchpvs("DB::", GV_ADDMULTI, SVt_PVHV));
@@ -3555,19 +3574,13 @@ S_init_main_stash(pTHX)
 }
 
 STATIC int
-S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv,
-             int *suidscript, PerlIO **rsfpp)
+S_open_script(pTHX_ const char *scriptname, bool dosearch,
+             bool *suidscript, PerlIO **rsfpp)
 {
-#ifndef IAMSUID
-    const char *quote;
-    const char *code;
-    const char *cpp_discard_flag;
-    const char *perl;
-#endif
     int fdscript = -1;
     dVAR;
 
-    *suidscript = -1;
+    PERL_ARGS_ASSERT_OPEN_SCRIPT;
 
     if (PL_e_script) {
        PL_origfilename = savepvs("-e");
@@ -3591,7 +3604,7 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv,
                 * Is it a mistake to use a similar /dev/fd/ construct for
                 * suidperl?
                 */
-               *suidscript = 1;
+               *suidscript = TRUE;
                /* PSz 20 Feb 04  
                 * Be supersafe and do some sanity-checks.
                 * Still, can we be sure we got the right thing?
@@ -3634,76 +3647,10 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv,
  * perl with that fd as it has always done.
  */
     }
-    if (*suidscript != 1) {
+    if (*suidscript) {
        Perl_croak(aTHX_ "suidperl needs (suid) fd script\n");
     }
 #else /* IAMSUID */
-    else if (PL_preprocess) {
-       const char * const cpp_cfg = CPPSTDIN;
-       SV * const cpp = newSVpvs("");
-       SV * const cmd = newSV(0);
-
-       if (cpp_cfg[0] == 0) /* PERL_MICRO? */
-            Perl_croak(aTHX_ "Can't run with cpp -P with CPPSTDIN undefined");
-       if (strEQ(cpp_cfg, "cppstdin"))
-           Perl_sv_catpvf(aTHX_ cpp, "%s/", BIN_EXP);
-       sv_catpv(cpp, cpp_cfg);
-
-#       ifndef VMS
-           sv_catpvs(sv, "-I");
-           sv_catpv(sv,PRIVLIB_EXP);
-#       endif
-
-       DEBUG_P(PerlIO_printf(Perl_debug_log,
-                             "PL_preprocess: scriptname=\"%s\", cpp=\"%s\", sv=\"%s\", CPPMINUS=\"%s\"\n",
-                             scriptname, SvPVX_const (cpp), SvPVX_const (sv),
-                             CPPMINUS));
-
-#       if defined(MSDOS) || defined(WIN32) || defined(VMS)
-            quote = "\"";
-#       else
-            quote = "'";
-#       endif
-
-#       ifdef VMS
-            cpp_discard_flag = "";
-#       else
-            cpp_discard_flag = "-C";
-#       endif
-
-#       ifdef OS2
-            perl = os2_execname(aTHX);
-#       else
-            perl = PL_origargv[0];
-#       endif
-
-
-        /* This strips off Perl comments which might interfere with
-           the C pre-processor, including #!.  #line directives are
-           deliberately stripped to avoid confusion with Perl's version
-           of #line.  FWP played some golf with it so it will fit
-           into VMS's 255 character buffer.
-        */
-        if( PL_doextract )
-            code = "(1../^#!.*perl/i)|/^\\s*#(?!\\s*((ifn?|un)def|(el|end)?if|define|include|else|error|pragma)\\b)/||!($|=1)||print";
-        else
-            code = "/^\\s*#(?!\\s*((ifn?|un)def|(el|end)?if|define|include|else|error|pragma)\\b)/||!($|=1)||print";
-
-        Perl_sv_setpvf(aTHX_ cmd, "\
-%s -ne%s%s%s %s | %"SVf" %s %"SVf" %s",
-                       perl, quote, code, quote, scriptname, SVfARG(cpp),
-                       cpp_discard_flag, SVfARG(sv), CPPMINUS);
-
-       PL_doextract = FALSE;
-
-        DEBUG_P(PerlIO_printf(Perl_debug_log,
-                              "PL_preprocess: cmd=\"%s\"\n",
-                              SvPVX_const(cmd)));
-
-       *rsfpp = PerlProc_popen((char *)SvPVX_const(cmd), (char *)"r");
-       SvREFCNT_dec(cmd);
-       SvREFCNT_dec(cpp);
-    }
     else if (!*scriptname) {
        forbid_setid(0, *suidscript);
        *rsfpp = PerlIO_stdin();
@@ -3902,14 +3849,22 @@ S_fd_on_nosuid_fs(pTHX_ int fd)
 }
 #endif /* IAMSUID */
 
+#ifdef DOSUID
 STATIC void
-S_validate_suid(pTHX_ const char *validarg, const char *scriptname,
-               int fdscript, int suidscript, SV *linestr_sv, PerlIO *rsfp)
+S_validate_suid(pTHX_ const char *validarg,
+#  ifndef IAMSUID
+               const char *scriptname,
+#  endif
+               int fdscript,
+#  ifdef IAMSUID
+               bool suidscript,
+#  endif
+               SV *linestr_sv, PerlIO *rsfp)
 {
     dVAR;
-#ifdef IAMSUID
-    /* int which; */
-#endif /* IAMSUID */
+    const char *s, *s2;
+
+    PERL_ARGS_ASSERT_VALIDATE_SUID;
 
     /* do we need to emulate setuid on scripts? */
 
@@ -3938,9 +3893,6 @@ S_validate_suid(pTHX_ const char *validarg, const char *scriptname,
      * Configure script will set this up for you if you want it.
      */
 
-#ifdef DOSUID
-    const char *s, *s2;
-
     if (PerlLIO_fstat(PerlIO_fileno(rsfp),&PL_statbuf) < 0)    /* normal stat is insecure */
        Perl_croak(aTHX_ "Can't stat script \"%s\"",PL_origfilename);
     if (PL_statbuf.st_mode & (S_ISUID|S_ISGID)) {
@@ -3948,8 +3900,8 @@ S_validate_suid(pTHX_ const char *validarg, const char *scriptname,
        const char *linestr;
        const char *s_end;
 
-#ifdef IAMSUID
-       if (fdscript < 0 || suidscript != 1)
+#  ifdef IAMSUID
+       if (fdscript < 0 || !suidscript)
            Perl_croak(aTHX_ "Need (suid) fdscript in suidperl\n");     /* We already checked this */
        /* PSz 11 Nov 03
         * Since the script is opened by perl, not suidperl, some of these
@@ -3959,16 +3911,16 @@ S_validate_suid(pTHX_ const char *validarg, const char *scriptname,
        /* PSz 27 Feb 04
         * Do checks even for systems with no HAS_SETREUID.
         * We used to swap, then re-swap UIDs with
-#ifdef HAS_SETREUID
+#    ifdef HAS_SETREUID
            if (setreuid(PL_euid,PL_uid) < 0
                || PerlProc_getuid() != PL_euid || PerlProc_geteuid() != PL_uid)
                Perl_croak(aTHX_ "Can't swap uid and euid");
-#endif
-#ifdef HAS_SETREUID
+#    endif
+#    ifdef HAS_SETREUID
            if (setreuid(PL_uid,PL_euid) < 0
                || PerlProc_getuid() != PL_uid || PerlProc_geteuid() != PL_euid)
                Perl_croak(aTHX_ "Can't reswap uid and euid");
-#endif
+#    endif
         */
 
        /* On this access check to make sure the directories are readable,
@@ -4029,12 +3981,12 @@ S_validate_suid(pTHX_ const char *validarg, const char *scriptname,
         * operating systems do not have such mount options anyway...)
         * Seems safe enough to do as root.
         */
-#if !defined(NO_NOSUID_CHECK)
+#    if !defined(NO_NOSUID_CHECK)
        if (fd_on_nosuid_fs(PerlIO_fileno(rsfp))) {
            Perl_croak(aTHX_ "Setuid script on nosuid or noexec filesystem\n");
        }
-#endif
-#endif /* IAMSUID */
+#    endif
+#  endif /* IAMSUID */
 
        if (!S_ISREG(PL_statbuf.st_mode)) {
            Perl_croak(aTHX_ "Setuid script not plain file\n");
@@ -4098,14 +4050,14 @@ S_validate_suid(pTHX_ const char *validarg, const char *scriptname,
              || ((s_end - s) == len+2 && isSPACE(s[len+1]))))
            Perl_croak(aTHX_ "Args must match #! line");
 
-#ifndef IAMSUID
+#  ifndef IAMSUID
        if (fdscript < 0 &&
            PL_euid != PL_uid && (PL_statbuf.st_mode & S_ISUID) &&
            PL_euid == PL_statbuf.st_uid)
            if (!PL_do_undump)
                Perl_croak(aTHX_ "YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
 FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n");
-#endif /* IAMSUID */
+#  endif /* IAMSUID */
 
        if (fdscript < 0 &&
            PL_euid) {  /* oops, we're not the setuid root perl */
@@ -4123,7 +4075,7 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n");
             * fdscript to avoid loops), and do the execs
             * even for root.
             */
-#ifndef IAMSUID
+#  ifndef IAMSUID
            int which;
            /* PSz 11 Nov 03
             * Pass fd script to suidperl.
@@ -4151,15 +4103,15 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n");
            }
            PL_origargv[which] = savepv(Perl_form(aTHX_ "/dev/fd/%d/%s",
                                          PerlIO_fileno(rsfp), PL_origargv[which]));
-#if defined(HAS_FCNTL) && defined(F_SETFD)
+#    if defined(HAS_FCNTL) && defined(F_SETFD)
            fcntl(PerlIO_fileno(rsfp),F_SETFD,0);       /* ensure no close-on-exec */
-#endif
+#    endif
            PERL_FPU_PRE_EXEC
            PerlProc_execv(Perl_form(aTHX_ "%s/sperl"PERL_FS_VER_FMT, BIN_EXP,
                                     (int)PERL_REVISION, (int)PERL_VERSION,
                                     (int)PERL_SUBVERSION), PL_origargv);
            PERL_FPU_POST_EXEC
-#endif /* IAMSUID */
+#  endif /* IAMSUID */
            Perl_croak(aTHX_ "Can't do setuid (cannot exec sperl)\n");
        }
 
@@ -4170,54 +4122,54 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n");
  * in the sense that we only want to set EGID; but are there any machines
  * with either of the latter, but not the former? Same with UID, later.
  */
-#ifdef HAS_SETEGID
+#  ifdef HAS_SETEGID
            (void)setegid(PL_statbuf.st_gid);
-#else
-#ifdef HAS_SETREGID
+#  else
+#    ifdef HAS_SETREGID
            (void)setregid((Gid_t)-1,PL_statbuf.st_gid);
-#else
-#ifdef HAS_SETRESGID
+#    else
+#      ifdef HAS_SETRESGID
            (void)setresgid((Gid_t)-1,PL_statbuf.st_gid,(Gid_t)-1);
-#else
+#      else
            PerlProc_setgid(PL_statbuf.st_gid);
-#endif
-#endif
-#endif
+#      endif
+#    endif
+#  endif
            if (PerlProc_getegid() != PL_statbuf.st_gid)
                Perl_croak(aTHX_ "Can't do setegid!\n");
        }
        if (PL_statbuf.st_mode & S_ISUID) {
            if (PL_statbuf.st_uid != PL_euid)
-#ifdef HAS_SETEUID
+#  ifdef HAS_SETEUID
                (void)seteuid(PL_statbuf.st_uid);       /* all that for this */
-#else
-#ifdef HAS_SETREUID
+#  else
+#    ifdef HAS_SETREUID
                 (void)setreuid((Uid_t)-1,PL_statbuf.st_uid);
-#else
-#ifdef HAS_SETRESUID
+#    else
+#      ifdef HAS_SETRESUID
                 (void)setresuid((Uid_t)-1,PL_statbuf.st_uid,(Uid_t)-1);
-#else
+#      else
                PerlProc_setuid(PL_statbuf.st_uid);
-#endif
-#endif
-#endif
+#      endif
+#    endif
+#  endif
            if (PerlProc_geteuid() != PL_statbuf.st_uid)
                Perl_croak(aTHX_ "Can't do seteuid!\n");
        }
        else if (PL_uid) {                      /* oops, mustn't run as root */
-#ifdef HAS_SETEUID
+#  ifdef HAS_SETEUID
           (void)seteuid((Uid_t)PL_uid);
-#else
-#ifdef HAS_SETREUID
+#  else
+#    ifdef HAS_SETREUID
           (void)setreuid((Uid_t)-1,(Uid_t)PL_uid);
-#else
-#ifdef HAS_SETRESUID
+#    else
+#      ifdef HAS_SETRESUID
           (void)setresuid((Uid_t)-1,(Uid_t)PL_uid,(Uid_t)-1);
-#else
+#      else
           PerlProc_setuid((Uid_t)PL_uid);
-#endif
-#endif
-#endif
+#      endif
+#    endif
+#  endif
            if (PerlProc_geteuid() != PL_uid)
                Perl_croak(aTHX_ "Can't do seteuid!\n");
        }
@@ -4225,10 +4177,8 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n");
        if (!cando(S_IXUSR,TRUE,&PL_statbuf))
            Perl_croak(aTHX_ "Effective UID cannot exec script\n");     /* they can't do this */
     }
-#ifdef IAMSUID
-    else if (PL_preprocess)    /* PSz 13 Nov 03  Caught elsewhere, useless(?!) here */
-       Perl_croak(aTHX_ "-P not allowed for setuid/setgid script\n");
-    else if (fdscript < 0 || suidscript != 1)
+#  ifdef IAMSUID
+    else if (fdscript < 0 || !suidscript)
        /* PSz 13 Nov 03  Caught elsewhere, useless(?!) here */
        Perl_croak(aTHX_ "(suid) fdscript needed in suidperl\n");
     else {
@@ -4274,28 +4224,32 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n");
     /* PSz 11 Nov 03
      * Keep original arguments: suidperl already has fd script.
      */
-/*  for (which = 1; PL_origargv[which] && PL_origargv[which] != scriptname; which++) ; */
-/*  if (!PL_origargv[which]) {                                         */
-/*     errno = EPERM;                                                  */
-/*     Perl_croak(aTHX_ "Permission denied\n");                        */
-/*  }                                                                  */
-/*  PL_origargv[which] = savepv(Perl_form(aTHX_ "/dev/fd/%d/%s",       */
-/*                               PerlIO_fileno(rsfp), PL_origargv[which]));    */
-#if defined(HAS_FCNTL) && defined(F_SETFD)
+#  if defined(HAS_FCNTL) && defined(F_SETFD)
     fcntl(PerlIO_fileno(rsfp),F_SETFD,0);      /* ensure no close-on-exec */
-#endif
+#  endif
     PERL_FPU_PRE_EXEC
     PerlProc_execv(Perl_form(aTHX_ "%s/perl"PERL_FS_VER_FMT, BIN_EXP,
                             (int)PERL_REVISION, (int)PERL_VERSION,
                             (int)PERL_SUBVERSION), PL_origargv);/* try again */
     PERL_FPU_POST_EXEC
     Perl_croak(aTHX_ "Can't do setuid (suidperl cannot exec perl)\n");
-#endif /* IAMSUID */
+#  endif /* IAMSUID */
+}
+
 #else /* !DOSUID */
-    PERL_UNUSED_ARG(fdscript);
-    PERL_UNUSED_ARG(suidscript);
+
+#  ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
+/* Don't even need this function.  */
+#  else
+STATIC void
+S_validate_suid(pTHX_ PerlIO *rsfp)
+{
+    PERL_ARGS_ASSERT_VALIDATE_SUID;
+
     if (PL_euid != PL_uid || PL_egid != PL_gid) {      /* (suidperl doesn't exist, in fact) */
-#ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
+#  ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
+       dVAR;
+
        PerlLIO_fstat(PerlIO_fileno(rsfp),&PL_statbuf); /* may be either wrapped or real suid */
        if ((PL_euid != PL_uid && PL_euid == PL_statbuf.st_uid && PL_statbuf.st_mode & S_ISUID)
            ||
@@ -4304,25 +4258,25 @@ FIX YOUR KERNEL, OR PUT A C WRAPPER AROUND THIS SCRIPT!\n");
            if (!PL_do_undump)
                Perl_croak(aTHX_ "YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
-#endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
+#  endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
        /* not set-id, must be wrapped */
     }
-#endif /* DOSUID */
-    PERL_UNUSED_ARG(validarg);
-    PERL_UNUSED_ARG(scriptname);
-    PERL_UNUSED_ARG(linestr_sv);
 }
+#  endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
+#endif /* DOSUID */
 
 STATIC void
 S_find_beginning(pTHX_ SV* linestr_sv, PerlIO *rsfp)
 {
     dVAR;
-    register char *s;
+    const char *s;
     register const char *s2;
 #ifdef MACOS_TRADITIONAL
     int maclines = 0;
 #endif
 
+    PERL_ARGS_ASSERT_FIND_BEGINNING;
+
     /* skip forward in input to the real script? */
 
 #ifdef MACOS_TRADITIONAL
@@ -4450,7 +4404,7 @@ Perl_doing_taint(int argc, char *argv[], char *envp[])
    "program input from stdin", which is substituted in place of '\0', which
    could never be a command line flag.  */
 STATIC void
-S_forbid_setid(pTHX_ const char flag, const int suidscript)
+S_forbid_setid(pTHX_ const char flag, const bool suidscript) /* g */
 {
     dVAR;
     char string[3] = "-x";
@@ -4489,7 +4443,7 @@ S_forbid_setid(pTHX_ const char flag, const int suidscript)
      * 
      * Also see comments about root running a setuid script, elsewhere.
      */
-    if (suidscript >= 0)
+    if (suidscript)
         Perl_croak(aTHX_ "No %s allowed with (suid) fdscript", message);
 #ifdef IAMSUID
     /* PSz 11 Nov 03  Catch it in suidperl, always! */
@@ -4628,6 +4582,9 @@ void
 Perl_init_argv_symbols(pTHX_ register int argc, register char **argv)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_INIT_ARGV_SYMBOLS;
+
     argc--,argv++;     /* skip name of script */
     if (PL_doswitches) {
        for (; argc > 0 && **argv == '-'; argc--,argv++) {
@@ -4670,6 +4627,8 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register
     dVAR;
     GV* tmpgv;
 
+    PERL_ARGS_ASSERT_INIT_POSTDUMP_SYMBOLS;
+
     PL_toptarget = newSV_type(SVt_PVFM);
     sv_setpvn(PL_toptarget, "", 0);
     PL_bodytarget = newSV_type(SVt_PVFM);
@@ -4714,18 +4673,21 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register
            environ[0] = NULL;
        }
        if (env) {
-         char *s;
+         char *s, *old_var;
          SV *sv;
          for (; *env; env++) {
-           if (!(s = strchr(*env,'=')) || s == *env)
+           old_var = *env;
+
+           if (!(s = strchr(old_var,'=')) || s == old_var)
                continue;
+
 #if defined(MSDOS) && !defined(DJGPP)
            *s = '\0';
-           (void)strupr(*env);
+           (void)strupr(old_var);
            *s = '=';
 #endif
            sv = newSVpv(s+1, 0);
-           (void)hv_store(hv, *env, s - *env, sv, 0);
+           (void)hv_store(hv, old_var, s - old_var, sv, 0);
            if (env_is_not_environ)
                mg_set(sv);
          }
@@ -4900,6 +4862,9 @@ S_incpush_if_exists(pTHX_ SV *dir)
 {
     dVAR;
     Stat_t tmpstatbuf;
+
+    PERL_ARGS_ASSERT_INCPUSH_IF_EXISTS;
+
     if (PerlLIO_stat(SvPVX_const(dir), &tmpstatbuf) >= 0 &&
        S_ISDIR(tmpstatbuf.st_mode)) {
        av_push(GvAVn(PL_incgv), dir);
@@ -4991,7 +4956,8 @@ S_incpush(pTHX_ const char *dir, bool addsubdirs, bool addoldvers, bool usesep,
                   SvPOK() won't be true.  */
                assert(caret_X);
                assert(SvPOKp(caret_X));
-               prefix_sv = newSVpvn(SvPVX(caret_X), SvCUR(caret_X));
+               prefix_sv = newSVpvn_flags(SvPVX(caret_X), SvCUR(caret_X),
+                                          SvUTF8(caret_X));
                /* Firstly take off the leading .../
                   If all else fail we'll do the paths relative to the current
                   directory.  */
@@ -5142,6 +5108,8 @@ Perl_call_list(pTHX_ I32 oldscope, AV *paramList)
     int ret;
     dJMPENV;
 
+    PERL_ARGS_ASSERT_CALL_LIST;
+
     while (av_len(paramList) >= 0) {
        cv = (CV*)av_shift(paramList);
        if (PL_savebegin) {
@@ -5235,8 +5203,6 @@ void
 Perl_my_exit(pTHX_ U32 status)
 {
     dVAR;
-    DEBUG_S(PerlIO_printf(Perl_debug_log, "my_exit: thread %p, status %lu\n",
-                         (void*)thr, (unsigned long) status));
     switch (status) {
     case 0:
        STATUS_ALL_SUCCESS;