This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
sort pragma tweaks.
[perl5.git] / perl.c
diff --git a/perl.c b/perl.c
index e19ea45..8b3066e 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -21,7 +21,7 @@
 #include <unistd.h>
 #endif
 
-#if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE)
+#if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE) && !defined(PERL_MICRO)
 char *getenv (char *); /* Usually in <stdlib.h> */
 #endif
 
@@ -212,8 +212,7 @@ perl_construct(pTHXx)
 #endif
     }
 
-    PL_nrs = newSVpvn("\n", 1);
-    PL_rs = SvREFCNT_inc(PL_nrs);
+    PL_rs = newSVpvn("\n", 1);
 
     init_stacks();
 
@@ -259,7 +258,7 @@ perl_construct(pTHXx)
     sys_intern_init();
 #endif
 
-    PerlIO_init();                     /* Hook to IO system */
+    PerlIO_init(aTHX);                 /* Hook to IO system */
 
     PL_fdpid = newAV();                        /* for remembering popen pids by fd */
     PL_modglobal = newHV();            /* pointers to per-interpreter module globals */
@@ -273,6 +272,27 @@ perl_construct(pTHXx)
     New(31337, PL_reentrant_buffer,1, REBUF);
     New(31337, PL_reentrant_buffer->tmbuff,1, struct tm);
 #endif
+
+    /* Note that strtab is a rather special HV.  Assumptions are made
+       about not iterating on it, and not adding tie magic to it.
+       It is properly deallocated in perl_destruct() */
+    PL_strtab = newHV();
+
+#ifdef USE_5005THREADS
+    MUTEX_INIT(&PL_strtab_mutex);
+#endif
+    HvSHAREKEYS_off(PL_strtab);                        /* mandatory */
+    hv_ksplit(PL_strtab, 512);
+
+#if defined(__DYNAMIC__) && (defined(NeXT) || defined(__NeXT__))
+    _dyld_lookup_and_bind
+       ("__environ", (unsigned long *) &environ_pointer, NULL);
+#endif /* environ */
+
+#ifdef  USE_ENVIRON_ARRAY
+    PL_origenviron = environ;
+#endif
+
     ENTER;
 }
 
@@ -439,18 +459,26 @@ perl_destruct(pTHXx)
 
        DEBUG_P(debprofdump());
 
+#if defined(PERLIO_LAYERS)
+       /* No more IO - including error messages ! */
+       PerlIO_cleanup(aTHX);
+#endif
+
        /* The exit() function will do everything that needs doing. */
         return STATUS_NATIVE_EXPORT;;
     }
 
     /* jettison our possibly duplicated environment */
-
-#ifdef USE_ENVIRON_ARRAY
+    /* if PERL_USE_SAFE_PUTENV is defined environ will not have been copied
+     * so we certainly shouldn't free it here
+     */
+#if defined(USE_ENVIRON_ARRAY) && !defined(PERL_USE_SAFE_PUTENV)
     if (environ != PL_origenviron) {
        I32 i;
 
        for (i = 0; environ[i]; i++)
            safesysfree(environ[i]);
+
        /* Must use safesysfree() when working with environ. */
        safesysfree(environ);           
 
@@ -470,14 +498,14 @@ perl_destruct(pTHXx)
 
         while (i) {
             SV *resv = ary[--i];
-            REGEXP *re = (REGEXP *)SvIVX(resv);
+            REGEXP *re = INT2PTR(REGEXP *,SvIVX(resv));
 
             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);
            }
@@ -540,9 +568,6 @@ perl_destruct(pTHXx)
     SvREFCNT_dec(PL_rs);       /* $/ */
     PL_rs = Nullsv;
 
-    SvREFCNT_dec(PL_nrs);      /* $/ helper */
-    PL_nrs = Nullsv;
-
     PL_multiline = 0;          /* $* */
     Safefree(PL_osname);       /* $^O */
     PL_osname = Nullch;
@@ -568,10 +593,12 @@ perl_destruct(pTHXx)
 
     /* startup and shutdown function lists */
     SvREFCNT_dec(PL_beginav);
+    SvREFCNT_dec(PL_beginav_save);
     SvREFCNT_dec(PL_endav);
     SvREFCNT_dec(PL_checkav);
     SvREFCNT_dec(PL_initav);
     PL_beginav = Nullav;
+    PL_beginav_save = Nullav;
     PL_endav = Nullav;
     PL_checkav = Nullav;
     PL_initav = Nullav;
@@ -639,7 +666,9 @@ perl_destruct(pTHXx)
     SvREFCNT_dec(PL_utf8_xdigit);
     SvREFCNT_dec(PL_utf8_mark);
     SvREFCNT_dec(PL_utf8_toupper);
+    SvREFCNT_dec(PL_utf8_totitle);
     SvREFCNT_dec(PL_utf8_tolower);
+    SvREFCNT_dec(PL_utf8_tofold);
     PL_utf8_alnum      = Nullsv;
     PL_utf8_alnumc     = Nullsv;
     PL_utf8_ascii      = Nullsv;
@@ -657,6 +686,7 @@ perl_destruct(pTHXx)
     PL_utf8_toupper    = Nullsv;
     PL_utf8_totitle    = Nullsv;
     PL_utf8_tolower    = Nullsv;
+    PL_utf8_tofold     = Nullsv;
 
     if (!specialWARN(PL_compiling.cop_warnings))
        SvREFCNT_dec(PL_compiling.cop_warnings);
@@ -779,6 +809,11 @@ perl_destruct(pTHXx)
     if (PL_sv_count != 0 && ckWARN_d(WARN_INTERNAL))
        Perl_warner(aTHX_ WARN_INTERNAL,"Scalars leaked: %ld\n", (long)PL_sv_count);
 
+#if defined(PERLIO_LAYERS)
+    /* No more IO - including error messages ! */
+    PerlIO_cleanup(aTHX);
+#endif
+
     Safefree(PL_origfilename);
     Safefree(PL_reg_start_tmp);
     if (PL_reg_curpm)
@@ -862,11 +897,6 @@ perl_free(pTHXx)
 #    else
     void *host = w32_internal_host;
 #    endif
-#    ifndef NETWARE
-    if (PerlProc_lasthost()) {
-       PerlIO_cleanup();
-    }
-#    endif
     PerlMem_free(aTHXx);
 #    ifdef NETWARE
     nw5_delete_internal_host(host);
@@ -874,7 +904,6 @@ perl_free(pTHXx)
     win32_delete_internal_host(host);
 #    endif
 #  else
-    PerlIO_cleanup();
     PerlMem_free(aTHXx);
 #  endif
 #else
@@ -917,16 +946,11 @@ setuid perl scripts securely.\n");
 #endif
 #endif
 
-#if defined(__DYNAMIC__) && (defined(NeXT) || defined(__NeXT__))
-    _dyld_lookup_and_bind
-       ("__environ", (unsigned long *) &environ_pointer, NULL);
-#endif /* environ */
-
     PL_origargc = argc;
     {
         /* we copy rather than point to argv
          * since perl_clone will copy and perl_destruct
-         * has no way of knowing if we've made a copy or 
+         * has no way of knowing if we've made a copy or
          * just point to argv
          */
         int i = PL_origargc;
@@ -937,9 +961,7 @@ setuid perl scripts securely.\n");
         }
     }
 
-#ifdef  USE_ENVIRON_ARRAY
-    PL_origenviron = environ;
-#endif
+
 
     if (PL_do_undump) {
 
@@ -1427,10 +1449,12 @@ print \"  \\@INC:\\n    @INC\\n\";");
        PL_e_script = Nullsv;
     }
 
-    /* now that script is parsed, we can modify record separator */
-    SvREFCNT_dec(PL_rs);
-    PL_rs = SvREFCNT_inc(PL_nrs);
+/*
+   Not sure that this is still the right place to do this now that we
+   no longer use PL_nrs. HVDS 2001/09/09
+*/
     sv_setsv(get_sv("/", TRUE), PL_rs);
+
     if (PL_do_undump)
        my_unexec();
 
@@ -1472,6 +1496,9 @@ perl_run(pTHXx)
 #endif
 
     oldscope = PL_scopestack_ix;
+#ifdef VMS
+    VMSISH_HUSHED = 0;
+#endif
 
 #ifdef PERL_FLEXIBLE_EXCEPTIONS
  redo_body:
@@ -1494,7 +1521,7 @@ perl_run(pTHXx)
            LEAVE;
        FREETMPS;
        PL_curstash = PL_defstash;
-       if (!(PL_exit_flags & PERL_EXIT_DESTRUCT_END) && 
+       if (!(PL_exit_flags & PERL_EXIT_DESTRUCT_END) &&
            PL_endav && !PL_minus_c)
            call_list(oldscope, PL_endav);
 #ifdef MYMALLOC
@@ -1543,7 +1570,7 @@ S_run_body(pTHX_ I32 oldscope)
 
        if (PL_minus_c) {
 #ifdef MACOS_TRADITIONAL
-           PerlIO_printf(Perl_error_log, "%s syntax OK\n", MacPerl_MPWFileName(PL_origfilename));
+           PerlIO_printf(Perl_error_log, "%s syntax OK\n", MacPerl_MPWFileName(PL_origfilename));
 #else
            PerlIO_printf(Perl_error_log, "%s syntax OK\n", PL_origfilename);
 #endif
@@ -2147,14 +2174,14 @@ Perl_moreswitches(pTHX_ char *s)
         I32 flags = 0;
        numlen = 4;
        rschar = (U32)grok_oct(s, &numlen, &flags, NULL);
-       SvREFCNT_dec(PL_nrs);
+       SvREFCNT_dec(PL_rs);
        if (rschar & ~((U8)~0))
-           PL_nrs = &PL_sv_undef;
+           PL_rs = &PL_sv_undef;
        else if (!rschar && numlen >= 2)
-           PL_nrs = newSVpvn("", 0);
+           PL_rs = newSVpvn("", 0);
        else {
            char ch = rschar;
-           PL_nrs = newSVpvn(&ch, 1);
+           PL_rs = newSVpvn(&ch, 1);
        }
        return s + numlen;
     }
@@ -2164,8 +2191,10 @@ Perl_moreswitches(pTHX_ char *s)
        return s;
     case 'F':
        PL_minus_F = TRUE;
-       PL_splitstr = savepv(s + 1);
-       s += strlen(s);
+       PL_splitstr = ++s;
+       while (*s && !isSPACE(*s)) ++s;
+       *s = '\0';
+       PL_splitstr = savepv(PL_splitstr);
        return s;
     case 'a':
        PL_minus_a = TRUE;
@@ -2244,7 +2273,7 @@ Perl_moreswitches(pTHX_ char *s)
                s++;
        }
        return s;
-    case 'I':  /* -I handled both here and in parse_perl() */
+    case 'I':  /* -I handled both here and in parse_body() */
        forbid_setid("-I");
        ++s;
        while (*s && isSPACE(*s))
@@ -2284,11 +2313,11 @@ Perl_moreswitches(pTHX_ char *s)
            s += numlen;
        }
        else {
-           if (RsPARA(PL_nrs)) {
+           if (RsPARA(PL_rs)) {
                PL_ors_sv = newSVpvn("\n\n",2);
            }
            else {
-               PL_ors_sv = newSVsv(PL_nrs);
+               PL_ors_sv = newSVsv(PL_rs);
            }
        }
        return s;
@@ -2390,7 +2419,8 @@ Perl_moreswitches(pTHX_ char *s)
                      "\n\nCopyright 1987-2001, Larry Wall\n");
 #ifdef MACOS_TRADITIONAL
        PerlIO_printf(PerlIO_stdout(),
-                     "\nMac OS port Copyright (c) 1991-2001, Matthias Neeracher\n");
+                     "\nMac OS port Copyright 1991-2001, Matthias Neeracher;\n"
+                     "maintained by Chris Nandor\n");
 #endif
 #ifdef MSDOS
        PerlIO_printf(PerlIO_stdout(),
@@ -2582,15 +2612,7 @@ S_init_main_stash(pTHX)
 {
     GV *gv;
 
-    /* Note that strtab is a rather special HV.  Assumptions are made
-       about not iterating on it, and not adding tie magic to it.
-       It is properly deallocated in perl_destruct() */
-    PL_strtab = newHV();
-#ifdef USE_5005THREADS
-    MUTEX_INIT(&PL_strtab_mutex);
-#endif
-    HvSHAREKEYS_off(PL_strtab);                        /* mandatory */
-    hv_ksplit(PL_strtab, 512);
+
 
     PL_curstash = PL_defstash = newHV();
     PL_curstname = newSVpvn("main",4);
@@ -2748,6 +2770,11 @@ sed %s -e \"/^[^#]/b\" \
                Perl_croak(aTHX_ "Can't do seteuid!\n");
        }
 #endif /* IAMSUID */
+
+        DEBUG_P(PerlIO_printf(Perl_debug_log,
+                              "PL_preprocess: cmd=\"%s\"\n",
+                              SvPVX(cmd)));
+
        PL_rsfp = PerlProc_popen(SvPVX(cmd), "r");
        SvREFCNT_dec(cmd);
        SvREFCNT_dec(cpp);
@@ -3352,17 +3379,10 @@ S_init_predump_symbols(pTHX)
     PL_osname = savepv(OSNAME);
 }
 
-STATIC void
-S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register char **env)
+void
+Perl_init_argv_symbols(pTHX_ register int argc, register char **argv)
 {
     char *s;
-    SV *sv;
-    GV* tmpgv;
-#ifdef NEED_ENVIRON_DUP_FOR_MODIFY
-    char **dup_env_base = 0;
-    int dup_env_count = 0;
-#endif
-
     argc--,argv++;     /* skip name of script */
     if (PL_doswitches) {
        for (; argc > 0 && **argv == '-'; argc--,argv++) {
@@ -3380,6 +3400,48 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register
                sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),1);
        }
     }
+    if ((PL_argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV))) {
+       GvMULTI_on(PL_argvgv);
+       (void)gv_AVadd(PL_argvgv);
+       av_clear(GvAVn(PL_argvgv));
+       for (; argc > 0; argc--,argv++) {
+           SV *sv = newSVpv(argv[0],0);
+           av_push(GvAVn(PL_argvgv),sv);
+           if (PL_widesyscalls)
+               (void)sv_utf8_decode(sv);
+       }
+    }
+}
+
+#ifdef HAS_PROCSELFEXE
+/* This is a function so that we don't hold on to MAXPATHLEN
+   bytes of stack longer than necessary
+ */
+STATIC void
+S_procself_val(pTHX_ SV *sv, char *arg0)
+{
+    char buf[MAXPATHLEN];
+    int len = readlink(PROCSELFEXE_PATH, buf, sizeof(buf) - 1);
+    if (len > 0) {
+       sv_setpvn(sv,buf,len);
+    }
+    else {
+       sv_setpv(sv,arg0);
+    }
+}
+#endif /* HAS_PROCSELFEXE */
+
+STATIC void
+S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register char **env)
+{
+    char *s;
+    SV *sv;
+    GV* tmpgv;
+#ifdef NEED_ENVIRON_DUP_FOR_MODIFY
+    char **dup_env_base = 0;
+    int dup_env_count = 0;
+#endif
+
     PL_toptarget = NEWSV(0,0);
     sv_upgrade(PL_toptarget, SVt_PVFM);
     sv_setpvn(PL_toptarget, "", 0);
@@ -3389,6 +3451,9 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register
     PL_formtarget = PL_bodytarget;
 
     TAINT;
+
+    init_argv_symbols(argc,argv);
+
     if ((tmpgv = gv_fetchpv("0",TRUE, SVt_PV))) {
 #ifdef MACOS_TRADITIONAL
        /* $0 is not majick on a Mac */
@@ -3398,22 +3463,16 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register
        magicname("0", "0", 1);
 #endif
     }
-    if ((tmpgv = gv_fetchpv("\030",TRUE, SVt_PV)))
+    if ((tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))) {/* $^X */
+#ifdef HAS_PROCSELFEXE
+       S_procself_val(aTHX_ GvSV(tmpgv), PL_origargv[0]);
+#else
 #ifdef OS2
        sv_setpv(GvSV(tmpgv), os2_execname(aTHX));
 #else
        sv_setpv(GvSV(tmpgv),PL_origargv[0]);
 #endif
-    if ((PL_argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV))) {
-       GvMULTI_on(PL_argvgv);
-       (void)gv_AVadd(PL_argvgv);
-       av_clear(GvAVn(PL_argvgv));
-       for (; argc > 0; argc--,argv++) {
-           SV *sv = newSVpv(argv[0],0);
-           av_push(GvAVn(PL_argvgv),sv);
-           if (PL_widesyscalls)
-               (void)sv_utf8_decode(sv);
-       }
+#endif
     }
     if ((PL_envgv = gv_fetchpv("ENV",TRUE, SVt_PVHV))) {
        HV *hv;
@@ -3473,8 +3532,11 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register
 #endif /* USE_ENVIRON_ARRAY */
     }
     TAINT_NOT;
-    if ((tmpgv = gv_fetchpv("$",TRUE, SVt_PV)))
+    if ((tmpgv = gv_fetchpv("$",TRUE, SVt_PV))) {
+        SvREADONLY_off(GvSV(tmpgv));
        sv_setiv(GvSV(tmpgv), (IV)PerlProc_getpid());
+        SvREADONLY_on(GvSV(tmpgv));
+    }
 }
 
 STATIC void