Initial integration of the MacPerl changes form Matthias.
Jarkko Hietaniemi [Tue, 2 Nov 1999 20:46:27 +0000 (20:46 +0000)]
p4raw-id: //depot/cfgperl@4508

16 files changed:
doio.c
ext/DynaLoader/DynaLoader_pm.PL
ext/Fcntl/Fcntl.pm
ext/Fcntl/Fcntl.xs
gv.c
mg.c
opcode.pl
perl.c
perl.h
pp_ctl.c
pp_hot.c
pp_sys.c
run.c
sv.c
toke.c
util.c

diff --git a/doio.c b/doio.c
index d9fd6df..f257d44 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -1126,6 +1126,9 @@ bool
 Perl_do_aexec5(pTHX_ SV *really, register SV **mark, register SV **sp,
               int fd, int do_report)
 {
+#ifdef MACOS_TRADITIONAL
+    Perl_croak(aTHX_ "exec? I'm not *that* kind of operating system");
+#else
     register char **a;
     char *tmps;
     STRLEN n_a;
@@ -1158,6 +1161,7 @@ Perl_do_aexec5(pTHX_ SV *really, register SV **mark, register SV **sp,
        }
     }
     do_execfree();
+#endif
     return FALSE;
 }
 
@@ -1174,7 +1178,7 @@ Perl_do_execfree(pTHX)
     }
 }
 
-#if !defined(OS2) && !defined(WIN32) && !defined(DJGPP) && !defined(EPOC)
+#if !defined(OS2) && !defined(WIN32) && !defined(DJGPP) && !defined(EPOC) && !defined(MACOS_TRADITIONAL)
 
 bool
 Perl_do_exec(pTHX_ char *cmd)
@@ -1555,6 +1559,10 @@ Perl_cando(pTHX_ Mode_t mode, Uid_t effective, register Stat_t *statbufp)
 bool
 Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective)
 {
+#ifdef MACOS_TRADITIONAL
+    /* This is simply not correct for AppleShare, but fix it yerself. */
+    return TRUE;
+#else
     if (testgid == (effective ? PL_egid : PL_gid))
        return TRUE;
 #ifdef HAS_GETGROUPS
@@ -1572,6 +1580,7 @@ Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective)
     }
 #endif
     return FALSE;
+#endif
 }
 
 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
index 3ce720b..e20ab42 100644 (file)
@@ -72,6 +72,7 @@ print OUT <<'EOT';
 # See dl_expandspec() for more details. Should be harmless but
 # inefficient to define on systems that don't need it.
 $do_expand = $Is_VMS = $^O eq 'VMS';
+$Is_MacOS  = $^O eq 'MacOS';
 
 @dl_require_symbols = ();       # names of symbols we need
 @dl_resolve_using   = ();       # names of files to link with
@@ -95,13 +96,22 @@ print OUT <<'EOT';
 
 # Add to @dl_library_path any extra directories we can gather
 # from environment variables.
-push(@dl_library_path, split(/:/, $ENV{$Config::Config{ldlibpthname}}))
-    if exists      $Config::Config{ldlibpthname}        &&
-                   $Config::Config{ldlibpthname}  ne '' &&
-       exists $ENV{$Config::Config{ldlibpthname}}       ;;
+if ($Is_MacOS) {
+    push(@dl_library_path, split(/,/, $ENV{LD_LIBRARY_PATH}))
+       if exists $ENV{LD_LIBRARY_PATH};
+} else {
+    push(@dl_library_path, split(/:/, $ENV{$Config::Config{ldlibpthname}}))
+       if exists      $Config::Config{ldlibpthname}        &&
+                       $Config::Config{ldlibpthname}  ne '' &&
+                exists $ENV{$Config::Config{ldlibpthname}}       ;;
+    push(@dl_library_path, split(/:/, $ENV{$Config::Config{ldlibpthname}}))
+       if exists      $Config::Config{ldlibpthname}        &&
+                       $Config::Config{ldlibpthname}  ne '' &&
+                exists $ENV{$Config::Config{ldlibpthname}}       ;;
 # E.g. HP-UX supports both its native SHLIB_PATH *and* LD_LIBRARY_PATH.
 push(@dl_library_path, split(/:/, $ENV{LD_LIBRARY_PATH}))
     if exists $ENV{LD_LIBRARY_PATH};
+}
 
 # No prizes for guessing why we don't say 'bootstrap DynaLoader;' here.
 boot_DynaLoader('DynaLoader') if defined(&boot_DynaLoader) &&
@@ -148,18 +158,27 @@ sub bootstrap {
     # It may also edit @modparts if required.
     $modfname = &mod2fname(\@modparts) if defined &mod2fname;
 
-    my $modpname = join('/',@modparts);
+    my $modpname = join(($Is_MacOS ? ':' : '/'),@modparts);
 
     print STDERR "DynaLoader::bootstrap for $module ",
-               "(auto/$modpname/$modfname.$dl_dlext)\n" if $dl_debug;
+               ($Is_MacOS
+                      ? "(auto/$modpname/$modfname.$dl_dlext)\n" :
+                       "(:auto:$modpname:$modfname.$dl_dlext)\n")
+       if $dl_debug;
 
     foreach (@INC) {
        chop($_ = VMS::Filespec::unixpath($_)) if $Is_VMS;
-       my $dir = "$_/auto/$modpname";
+       my $dir;
+       if ($Is_MacOS) {
+           chop $_  if /:$/;
+           $dir = "$_:auto:$modpname";
+       } else {
+           $dir = "$_/auto/$modpname";
+       }
        next unless -d $dir; # skip over uninteresting directories
 
        # check for common cases to avoid autoload of dl_findfile
-       my $try = "$dir/$modfname.$dl_dlext";
+       my $try = $Is_MacOS ? "$dir:$modfname.$dl_dlext" : "$dir/$modfname.$dl_dlext";
        last if $file = ($do_expand) ? dl_expandspec($try) : (-f $try && $try);
 
        # no luck here, save dir for possible later dl_findfile search
@@ -254,6 +273,12 @@ print OUT <<'EOT';
            last arg unless wantarray;
            next;
         }
+       elsif ($Is_MacOS) {
+           if (m/:/ && -f $_) {
+               push(@found,$_);
+               last arg unless wantarray;
+           }
+       }
         elsif (m:/: && -f $_ && !$do_expand) {
            push(@found,$_);
            last arg unless wantarray;
@@ -264,6 +289,30 @@ print OUT <<'EOT';
         #  Using a -L prefix is the preferred option (faster and more robust)
         if (m:^-L:) { s/^-L//; push(@dirs, $_); next; }
 
+       if ($Is_MacOS) {
+            #  Otherwise we try to try to spot directories by a heuristic
+            #  (this is a more complicated issue than it first appears)
+           if (m/:/ && -d $_) {   push(@dirs, $_); next; }
+            #  Only files should get this far...
+            my(@names, $name);    # what filenames to look for
+           s/^-l//;
+           push(@names, $_);
+            foreach $dir (@dirs, @dl_library_path) {
+               next unless -d $dir;
+               $dir =~ s/^([^:]+)$/:$1/;
+               $dir =~ s/:$//;
+               foreach $name (@names) {
+                   my($file) = "$dir:$name";
+                    print STDERR " checking in $dir for $name\n" if $dl_debug;
+                   if (-f $file) {
+                       push(@found, $file);
+                       next arg; # no need to look any further
+                    }
+                }
+           }
+           next;
+       }
+       
         #  Otherwise we try to try to spot directories by a heuristic
         #  (this is a more complicated issue than it first appears)
         if (m:/: && -d $_) {   push(@dirs, $_); next; }
index 699ee4a..44bb0ae 100644 (file)
@@ -110,6 +110,8 @@ $VERSION = "1.03";
        O_TEXT
        O_TRUNC
        O_WRONLY
+       O_ALIAS
+       O_RSRC
        SEEK_SET
        SEEK_CUR
        SEEK_END
index 0dab7f1..08252b6 100644 (file)
@@ -504,6 +504,18 @@ constant(char *name, int arg)
 #else
                goto not_there;
 #endif
+           if (strEQ(name, "O_ALIAS"))
+#ifdef O_ALIAS
+               return O_ALIAS;
+#else
+               goto not_there;
+#endif
+           if (strEQ(name, "O_RSRC"))
+#ifdef O_RSRC
+               return O_RSRC;
+#else
+               goto not_there;
+#endif
        } else
          goto not_there;
        break;
diff --git a/gv.c b/gv.c
index aa4a649..d85da33 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -71,7 +71,11 @@ Perl_gv_fetchfile(pTHX_ const char *name)
     if (!isGV(gv)) {
        gv_init(gv, PL_defstash, tmpbuf, tmplen, FALSE);
        sv_setpv(GvSV(gv), name);
+#ifdef MACOS_TRADITIONAL
+       if (strchr(name, ':') && instr(name,".pm"))
+#else
        if (*name == '/' && (instr(name, "/lib/") || instr(name, ".pm")))
+#endif
            GvMULTI_on(gv);
        if (PERLDB_LINE)
            hv_magic(GvHVn(gv_AVadd(gv)), gv, 'L');
diff --git a/mg.c b/mg.c
index eed84f8..151b336 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -408,6 +408,14 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
        sv_setiv(sv, (IV)(PL_debug & 32767));
        break;
     case '\005':  /* ^E */
+#ifdef MACOS_TRADITIONAL
+       {
+           char msg[256];
+           
+           sv_setnv(sv,(double)gLastMacOSErr);
+           sv_setpv(sv, gLastMacOSErr ? GetSysErrText(gLastMacOSErr, msg) : "");       
+       }
+#else  
 #ifdef VMS
        {
 #          include <descrip.h>
@@ -453,6 +461,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
 #endif
 #endif
 #endif
+#endif
        SvNOK_on(sv);   /* what a wonderful hack! */
        break;
     case '\006':               /* ^F */
@@ -674,8 +683,10 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
        break;
     case '*':
        break;
+#ifndef MACOS_TRADITIONAL
     case '0':
        break;
+#endif
 #ifdef USE_THREADS
     case '@':
        sv_setsv(sv, thr->errsv);
@@ -1568,15 +1579,19 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
        DEBUG_x(dump_all());
        break;
     case '\005':  /* ^E */
-#ifdef VMS
-       set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
+#ifdef MACOS_TRADITIONAL
+       gLastMacOSErr = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv);
 #else
-#  ifdef WIN32
-       SetLastError( SvIV(sv) );
+#  ifdef VMS
+       set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv));
 #  else
-#    ifndef OS2
+#    ifdef WIN32
+       SetLastError( SvIV(sv) );
+#    else
+#      ifndef OS2
        /* will anyone ever use this? */
        SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4);
+#      endif
 #    endif
 #  endif
 #endif
@@ -1871,6 +1886,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
     case ':':
        PL_chopset = SvPV_force(sv,len);
        break;
+#ifndef MACOS_TRADITIONAL
     case '0':
        if (!PL_origalen) {
            s = PL_origargv[0];
@@ -1928,6 +1944,7 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
                PL_origargv[i] = Nullch;
        }
        break;
+#endif
 #ifdef USE_THREADS
     case '@':
        sv_setsv(thr->errsv, sv);
index c9174f2..1c5c3e2 100755 (executable)
--- a/opcode.pl
+++ b/opcode.pl
@@ -735,6 +735,10 @@ setpriority        setpriority             ck_fun          isT@    S S S
 
 # Time calls.
 
+# NOTE: MacOS patches the 'i' of time() away later when the interpreter
+# is created because in MacOS time() is already returning times > 2**31-1,
+# that is, non-integers.
+
 time           time                    ck_null         isT0    
 tms            times                   ck_null         0       
 localtime      localtime               ck_fun          t%      S?
diff --git a/perl.c b/perl.c
index 8324d52..067b1f3 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -220,6 +220,12 @@ perl_construct(pTHXx)
     PL_fdpid = newAV();                        /* for remembering popen pids by fd */
     PL_modglobal = newHV();            /* pointers to per-interpreter module globals */
 
+#ifdef MACOS_TRADITIONAL
+    /* In MacOS time() already returns values in excess of 2**31-1,
+     * therefore we patch the integerness away. */
+    PL_opargs[OP_TIME] &= ~OA_RETINTEGER;
+#endif
+
     ENTER;
 }
 
@@ -749,6 +755,11 @@ S_parse_body(pTHX_ va_list args)
            goto reswitch;
 
        case 'e':
+#ifdef MACOS_TRADITIONAL
+           /* ignore -e for Dev:Pseudo argument */
+           if (argv[1] && !strcmp(argv[1], "Dev:Pseudo"))
+               break; 
+#endif
            if (PL_euid != PL_uid || PL_egid != PL_gid)
                Perl_croak(aTHX_ "No -e allowed in setuid scripts");
            if (!PL_e_script) {
@@ -951,11 +962,14 @@ print \"  \\@INC:\\n    @INC\\n\";");
     }
 #endif
 
+#ifdef MACOS_TRADITIONAL
+    if (PL_doextract || gAlwaysExtract)
+#else
     if (PL_doextract) {
+#endif
        find_beginning();
        if (cddir && PerlDir_chdir(cddir) < 0)
            Perl_croak(aTHX_ "Can't chdir to %s",cddir);
-
     }
 
     PL_main_cv = PL_compcv = (CV*)NEWSV(1104,0);
@@ -1010,6 +1024,16 @@ print \"  \\@INC:\\n    @INC\\n\";");
 
     SETERRNO(0,SS$_NORMAL);
     PL_error_count = 0;
+#ifdef MACOS_TRADITIONAL
+    if (gSyntaxError = (yyparse() || PL_error_count)) {
+       if (PL_minus_c)
+           Perl_croak(aTHX_ "%s had compilation errors.\n", MPWFileName(PL_origfilename));
+       else {
+           Perl_croak(aTHX_ "Execution of %s aborted due to compilation errors.\n",
+                      MPWFileName(PL_origfilename));
+       }
+    }
+#else
     if (yyparse() || PL_error_count) {
        if (PL_minus_c)
            Perl_croak(aTHX_ "%s had compilation errors.\n", PL_origfilename);
@@ -1018,6 +1042,7 @@ print \"  \\@INC:\\n    @INC\\n\";");
                       PL_origfilename);
        }
     }
+#endif
     PL_curcop->cop_line = 0;
     PL_curstash = PL_defstash;
     PL_preprocess = FALSE;
@@ -1111,8 +1136,12 @@ S_run_body(pTHX_ va_list args)
                              PTR2UV(thr)));
 
        if (PL_minus_c) {
+#ifdef MACOS_TRADITIONAL
+           PerlIO_printf(PerlIO_stderr(), "# %s syntax OK\n", MPWFileName(PL_origfilename));
+#else
            PerlIO_printf(Perl_error_log, "%s syntax OK\n", PL_origfilename);
-           my_exit(0);
+#endif     
+my_exit(0);
        }
        if (PERLDB_SINGLE && PL_DBsingle)
            sv_setiv(PL_DBsingle, 1); 
@@ -1760,6 +1789,9 @@ Perl_moreswitches(pTHX_ char *s)
        s++;
        return s;
     case 'u':
+#ifdef MACOS_TRADITIONAL
+       Perl_croak(aTHX_ "Believe me, you don't want to use \"-u\" on a Macintosh");
+#endif
        PL_do_undump = TRUE;
        s++;
        return s;
@@ -1782,6 +1814,9 @@ Perl_moreswitches(pTHX_ char *s)
 #endif
 
        printf("\n\nCopyright 1987-1999, Larry Wall\n");
+#ifdef MACOS_TRADITIONAL
+        fputs("Macintosh port Copyright 1991-1999, Matthias Neeracher\n", stdout);
+#endif
 #ifdef MSDOS
        printf("\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n");
 #endif
@@ -2528,11 +2563,32 @@ S_find_beginning(pTHX)
     /* skip forward in input to the real script? */
 
     forbid_setid("-x");
+#ifdef MACOS_TRADITIONAL
+    /* Since the Mac OS does not honor !# arguments for us,
+     * we do it ourselves. */
+    while (PL_doextract || gAlwaysExtract) {
+       if ((s = sv_gets(PL_linestr, PL_rsfp, 0)) == Nullch) {
+           if (!gAlwaysExtract)
+               Perl_croak(aTHX_ "No Perl script found in input\n");
+               
+           if (PL_doextract)           /* require explicit override ? */
+               if (!OverrideExtract(PL_origfilename))
+                   Perl_croak(aTHX_ "User aborted script\n");
+               else
+                   PL_doextract = FALSE;
+               
+           /* Pater peccavi, file does not have #! */
+           PerlIO_rewind(PL_rsfp);
+           
+           break;
+       }
+#else
     while (PL_doextract) {
        if ((s = sv_gets(PL_linestr, PL_rsfp, 0)) == Nullch)
            Perl_croak(aTHX_ "No Perl script found in input\n");
+#endif
        if (*s == '#' && s[1] == '!' && (s = instr(s,"perl"))) {
-           PerlIO_ungetc(PL_rsfp, '\n');               /* to keep line count right */
+           PerlIO_ungetc(PL_rsfp, '\n');       /* to keep line count right */
            PL_doextract = FALSE;
            while (*s && !(isSPACE (*s) || *s == '#')) s++;
            s2 = s;
@@ -2712,8 +2768,9 @@ S_init_predump_symbols(pTHX)
 
     PL_statname = NEWSV(66,0);         /* last filename we did stat on */
 
-    if (!PL_osname)
-       PL_osname = savepv(OSNAME);
+    if (PL_osname)
+       Safefree(PL_osname);
+    PL_osname = savepv(OSNAME);
 }
 
 STATIC void
@@ -2751,8 +2808,13 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register
 
     TAINT;
     if (tmpgv = gv_fetchpv("0",TRUE, SVt_PV)) {
+#ifdef MACOS_TRADITIONAL
+       sv_setpv(GvSV(tmpgv),MPWFileName(PL_origfilename));
+       /* $0 is not majick on a Mac */
+#else
        sv_setpv(GvSV(tmpgv),PL_origfilename);
        magicname("0", "0", 1);
+#endif
     }
     if (tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))
 #ifdef OS2
@@ -2843,6 +2905,24 @@ S_init_perllib(pTHX)
 #ifdef ARCHLIB_EXP
     incpush(ARCHLIB_EXP, FALSE);
 #endif
+#ifdef MACOS_TRADITIONAL
+    {
+       struct stat tmpstatbuf;
+       SV * privdir = NEWSV(55, 0);
+       char * macperl = getenv("MACPERL") || "";
+       
+       Perl_sv_setpvf(privdir, "%slib:", macperl);
+       if (PerlLIO_stat(SvPVX(privdir), &tmpstatbuf) >= 0 && S_ISDIR(tmpstatbuf.st_mode))
+           incpush(SvPVX(privdir), TRUE);
+       Perl_sv_setpvf(privdir, "%ssite_perl:", macperl);
+       if (PerlLIO_stat(SvPVX(privdir), &tmpstatbuf) >= 0 && S_ISDIR(tmpstatbuf.st_mode))
+           incpush(SvPVX(privdir), TRUE);
+           
+       SvREFCNT_dec(privdir);
+    }
+    if (!PL_tainting)
+       incpush(":", FALSE);
+#else
 #ifndef PRIVLIB_EXP
 #define PRIVLIB_EXP "/usr/local/lib/perl5:/usr/local/lib/perl"
 #endif
@@ -2871,19 +2951,24 @@ S_init_perllib(pTHX)
 #endif
     if (!PL_tainting)
        incpush(".", FALSE);
+#endif /* MACOS_TRADITIONAL */
 }
 
-#if defined(DOSISH)
-#    define PERLLIB_SEP ';'
+#if defined(MACOS_TRADITIONAL)
+#      define PERLLIB_SEP ','
 #else
-#  if defined(VMS)
-#    define PERLLIB_SEP '|'
+#  if defined(DOSISH)
+#      define PERLLIB_SEP ';'
 #  else
-#    define PERLLIB_SEP ':'
+#    if defined(VMS)
+#      define PERLLIB_SEP '|'
+#    else
+#      define PERLLIB_SEP ':'
+#    endif
 #  endif
-#endif
+#endif 
 #ifndef PERLLIB_MANGLE
-#  define PERLLIB_MANGLE(s,n) (s)
+#    define PERLLIB_MANGLE(s,n) (s)
 #endif 
 
 STATIC void
@@ -2900,7 +2985,11 @@ S_incpush(pTHX_ char *p, int addsubdirs)
            STRLEN len = (sizeof(ARCHNAME) + strlen(PL_patchlevel)
                          + sizeof("//auto"));
            New(55, PL_archpat_auto, len, char);
-           sprintf(PL_archpat_auto, "/%s/%s/auto", ARCHNAME, PL_patchlevel);
+#ifdef MACOS_TRADITIONAL
+           sprintf(PL_archpat_auto, "%s:%s:auto:", ARCHNAME, PL_patchlevel);
+#else
+           sprintf(PL_archpat_auto, "/%s/%s/auto", ARCHNAME, PL_patchlevel);
+#endif
 #ifdef VMS
        for (len = sizeof(ARCHNAME) + 2;
             PL_archpat_auto[len] != '\0' && PL_archpat_auto[len] != '/'; len++)
@@ -2930,6 +3019,12 @@ S_incpush(pTHX_ char *p, int addsubdirs)
            sv_setpv(libdir, PERLLIB_MANGLE(p, 0));
            p = Nullch; /* break out */
        }
+#ifdef MACOS_TRADITIONAL
+       if (!strchr(SvPVX(libdir), ':'))
+           sv_insert(libdir, 0, 0, ":", 1);
+       if (SvPVX(libdir)[SvCUR(libdir)-1] != ':')
+           sv_catpv(libdir, ":");
+#endif
 
        /*
         * BEFORE pushing libdir onto @INC we may first push version- and
diff --git a/perl.h b/perl.h
index e3d34e7..a4737af 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -1458,7 +1458,11 @@ typedef union any ANY;
 #         if defined(EPOC)
 #           include "epocish.h"
 #         else
-#           include "unixish.h"
+#           if defined(MACOS_TRADITIONAL)
+#             include "macos/macish.h"
+#           else
+#             include "unixish.h"
+#           endif
 #         endif
 #       endif
 #     endif
index 9126007..e9a4f75 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2112,6 +2112,9 @@ PP(pp_goto)
                if (CvDEPTH(cv) < 2)
                    (void)SvREFCNT_inc(cv);
                else {  /* save temporaries on recursion? */
+#ifdef MACOS_TRADITIONAL
+                   MacStackAttack();
+#endif
                    if (CvDEPTH(cv) == 100 && ckWARN(WARN_RECURSION))
                        sub_crush_depth(cv);
                    if (CvDEPTH(cv) > AvFILLp(padlist)) {
@@ -2780,6 +2783,9 @@ PP(pp_require)
 
     /* prepare to compile file */
 
+#ifdef MACOS_TRADITIONAL
+    if (strchr(name, ':')
+#else
     if (*name == '/' ||
        (*name == '.' && 
            (name[1] == '/' ||
@@ -2794,12 +2800,25 @@ PP(pp_require)
        || (strchr(name,':')  || ((*name == '[' || *name == '<') &&
            (isALNUM(name[1]) || strchr("$-_]>",name[1]))))
 #endif
+#endif
     )
     {
        tryname = name;
        tryrsfp = doopen_pmc(name,PERL_SCRIPT_MODE);
+#ifdef MACOS_TRADITIONAL
+       /* We consider paths of the form :a:b ambiguous and interpret them first
+          as global then as local
+       */
+    if (name[0] == ':' && !tryrsfp && name[1] != ':' && strchr(name+2, ':'))
+       goto trylocal;
+#endif
     }
+#ifdef MACOS_TRADITIONAL
+    else 
+trylocal: {
+#else
     else {
+#endif
        AV *ar = GvAVn(PL_incgv);
        I32 i;
 #ifdef VMS
@@ -2917,6 +2936,24 @@ PP(pp_require)
                }
                else {
                    char *dir = SvPVx(dirsv, n_a);
+#ifdef MACOS_TRADITIONAL
+                   /* We have ensured in incpush that library ends with ':' */
+                   int   dirlen = strlen(dir);
+                   char *colon  = strchr(dir, ':') ? "" : ":";
+                   int   colons = (dir[dirlen-1] == ':') + (*name == ':');
+               
+                   switch (colons) {
+                   case 2:
+                       sv_setpvfaTHX_ (namesv, "%s%s%s", colon, dir, name+1);
+                       break;
+                   case 1:
+                       sv_setpvf(aTHX_ namesv, "%s%s%s", colon, dir, name);
+                       break;
+                   case 0: 
+                       sv_setpvf(aTHX_ namesv, "%s%s:%s", colon, dir, name);
+                       break;
+                   }
+#else
 #ifdef VMS
                    char *unixdir;
                    if ((unixdir = tounixpath(dir, Nullch)) == Nullch)
@@ -2926,8 +2963,13 @@ PP(pp_require)
 #else
                    Perl_sv_setpvf(aTHX_ namesv, "%s/%s", dir, name);
 #endif
+#endif
                    TAINT_PROPER("require");
                    tryname = SvPVX(namesv);
+#ifdef MACOS_TRADITIONAL
+               for (colon = tryname+dirlen; colon = strchr(colon, '/'); )
+                   *colon++ = ':';
+#endif
                    tryrsfp = doopen_pmc(tryname, PERL_SCRIPT_MODE);
                    if (tryrsfp) {
                        if (tryname[0] == '.' && tryname[1] == '/')
index 6f9528a..60dcd7d 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1190,6 +1190,11 @@ Perl_do_readline(pTHX)
                    }
                }
 #else /* !VMS */
+#ifdef MACOS_TRADITIONAL
+               sv_setpv(tmpcmd, "glob ");
+               sv_catsv(tmpcmd, tmpglob);
+               sv_catpv(tmpcmd, " |");
+#else
 #ifdef DOSISH
 #ifdef OS2
                sv_setpv(tmpcmd, "for a in ");
@@ -1221,6 +1226,7 @@ Perl_do_readline(pTHX)
 #endif
 #endif /* !CSH */
 #endif /* !DOSISH */
+#endif /* MACOS_TRADITIONAL */
                (void)do_open(PL_last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd),
                              FALSE, O_RDONLY, 0, Nullfp);
                fp = IoIFP(io);
@@ -2471,6 +2477,9 @@ try_autoload:
        if (CvDEPTH(cv) < 2)
            (void)SvREFCNT_inc(cv);
        else {  /* save temporaries on recursion? */
+#ifdef MACOS_TRADITIONAL
+           MacStackAttack();
+#endif
            if (CvDEPTH(cv) > AvFILLp(padlist)) {
                AV *av;
                AV *newpad = newAV();
index 9c73980..5e096e2 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -3537,7 +3537,7 @@ PP(pp_fork)
 
 PP(pp_wait)
 {
-#if !defined(DOSISH) || defined(OS2) || defined(WIN32)
+#if (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL) 
     djSP; dTARGET;
     Pid_t childpid;
     int argflags;
@@ -3553,7 +3553,7 @@ PP(pp_wait)
 
 PP(pp_waitpid)
 {
-#if !defined(DOSISH) || defined(OS2) || defined(WIN32)
+#if (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL) 
     djSP; dTARGET;
     Pid_t childpid;
     int optype;
diff --git a/run.c b/run.c
index a6391e9..cd831cb 100644 (file)
--- a/run.c
+++ b/run.c
@@ -22,7 +22,11 @@ Perl_runops_standard(pTHX)
 {
     dTHR;
 
-    while ( PL_op = CALL_FPTR(PL_op->op_ppaddr)(aTHX) ) ;
+    while ( PL_op = CALL_FPTR(PL_op->op_ppaddr)(aTHX) ) {
+#ifdef MACOS_TRADITIONAL
+       MACPERL_DO_ASYNC_TASKS();
+#endif 
+    }
 
     TAINT_NOT;
     return 0;
@@ -40,6 +44,9 @@ Perl_runops_debug(pTHX)
     }
 
     do {
+#ifdef MACOS_TRADITIONAL
+       MACPERL_DO_ASYNC_TASKS();
+#endif 
        if (PL_debug) {
            if (PL_watchaddr != 0 && *PL_watchaddr != PL_watchok)
                PerlIO_printf(Perl_debug_log,
diff --git a/sv.c b/sv.c
index 6324ffd..c107df4 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -5203,6 +5203,11 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
            if (args) {
                eptr = va_arg(*args, char*);
                if (eptr)
+#ifdef MACOS_TRADITIONAL
+                 if (alt)
+                   elen = *eptr++;
+                 else
+#endif
                    elen = strlen(eptr);
                else {
                    eptr = nullstr;
diff --git a/toke.c b/toke.c
index cbac39b..197609a 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -49,6 +49,13 @@ static void restore_lex_expect(pTHXo_ void *e);
  * 1999-02-27 mjd-perl-patch@plover.com */
 #define isCONTROLVAR(x) (isUPPER(x) || strchr("[\\]^_?", (x)))
 
+/* On MacOS, respect nonbreaking spaces */
+#ifdef MACOS_TRADITIONAL
+#define SPACE_OR_TAB(c) ((c)==' '||(c)=='\312'||(c)=='\t')
+#else
+#define SPACE_OR_TAB(c) ((c)==' '||(c)=='\t')
+#endif
+
 /* LEX_* are values for PL_lex_state, the state of the lexer.
  * They are arranged oddly so that the guard on the switch statement
  * can get by with a single comparison (if the compiler is smart enough).
@@ -449,10 +456,13 @@ S_incline(pTHX_ char *s)
     char ch;
     int sawline = 0;
 
+#ifdef MACOS_TRADITIONAL
+    MACPERL_DO_ASYNC_TASKS();
+#endif 
     PL_curcop->cop_line++;
     if (*s++ != '#')
        return;
-    while (*s == ' ' || *s == '\t') s++;
+    while (SPACE_OR_TAB(*s)) s++;
     if (strnEQ(s, "line ", 5)) {
        s += 5;
        sawline = 1;
@@ -462,7 +472,7 @@ S_incline(pTHX_ char *s)
     n = s;
     while (isDIGIT(*s))
        s++;
-    while (*s == ' ' || *s == '\t')
+    while (SPACE_OR_TAB(*s))
        s++;
     if (*s == '"' && (t = strchr(s+1, '"')))
        s++;
@@ -492,7 +502,7 @@ S_skipspace(pTHX_ register char *s)
 {
     dTHR;
     if (PL_lex_formbrack && PL_lex_brackets <= PL_lex_formbrack) {
-       while (s < PL_bufend && (*s == ' ' || *s == '\t'))
+       while (s < PL_bufend && SPACE_OR_TAB(*s))
            s++;
        return s;
     }
@@ -2470,6 +2480,7 @@ Perl_yylex(pTHX)
                        *s = '#';       /* Don't try to parse shebang line */
                }
 #endif /* ALTERNATE_SHEBANG */
+#ifndef MACOS_TRADITIONAL
                if (!d &&
                    *s == '#' &&
                    ipathend > ipath &&
@@ -2497,13 +2508,14 @@ Perl_yylex(pTHX)
                    PerlProc_execv(ipath, newargv);
                    Perl_croak(aTHX_ "Can't exec %s", ipath);
                }
+#endif
                if (d) {
                    U32 oldpdb = PL_perldb;
                    bool oldn = PL_minus_n;
                    bool oldp = PL_minus_p;
 
                    while (*d && !isSPACE(*d)) d++;
-                   while (*d == ' ' || *d == '\t') d++;
+                   while (SPACE_OR_TAB(*d)) d++;
 
                    if (*d++ == '-') {
                        do {
@@ -2545,6 +2557,9 @@ Perl_yylex(pTHX)
       "(Maybe you didn't strip carriage returns after a network transfer?)\n");
 #endif
     case ' ': case '\t': case '\f': case 013:
+#ifdef MACOS_TRADITIONAL
+    case '\312':
+#endif
        s++;
        goto retry;
     case '#':
@@ -2573,7 +2588,7 @@ Perl_yylex(pTHX)
            PL_bufptr = s;
            tmp = *s++;
 
-           while (s < PL_bufend && (*s == ' ' || *s == '\t'))
+           while (s < PL_bufend && SPACE_OR_TAB(*s))
                s++;
 
            if (strnEQ(s,"=>",2)) {
@@ -2839,20 +2854,20 @@ Perl_yylex(pTHX)
                PL_lex_brackstack[PL_lex_brackets++] = XOPERATOR;
            OPERATOR(HASHBRACK);
        case XOPERATOR:
-           while (s < PL_bufend && (*s == ' ' || *s == '\t'))
+           while (s < PL_bufend && SPACE_OR_TAB(*s))
                s++;
            d = s;
            PL_tokenbuf[0] = '\0';
            if (d < PL_bufend && *d == '-') {
                PL_tokenbuf[0] = '-';
                d++;
-               while (d < PL_bufend && (*d == ' ' || *d == '\t'))
+               while (d < PL_bufend && SPACE_OR_TAB(*d))
                    d++;
            }
            if (d < PL_bufend && isIDFIRST_lazy(d)) {
                d = scan_word(d, PL_tokenbuf + 1, sizeof PL_tokenbuf - 1,
                              FALSE, &len);
-               while (d < PL_bufend && (*d == ' ' || *d == '\t'))
+               while (d < PL_bufend && SPACE_OR_TAB(*d))
                    d++;
                if (*d == '}') {
                    char minus = (PL_tokenbuf[0] == '-');
@@ -3063,9 +3078,9 @@ Perl_yylex(pTHX)
        if (PL_lex_brackets < PL_lex_formbrack) {
            char *t;
 #ifdef PERL_STRICT_CR
-           for (t = s; *t == ' ' || *t == '\t'; t++) ;
+           for (t = s; SPACE_OR_TAB(*t); t++) ;
 #else
-           for (t = s; *t == ' ' || *t == '\t' || *t == '\r'; t++) ;
+           for (t = s; SPACE_OR_TAB(*t) || *t == '\r'; t++) ;
 #endif
            if (*t == '\n' || *t == '#') {
                s--;
@@ -3625,7 +3640,7 @@ Perl_yylex(pTHX)
                if (*s == '(') {
                    CLINE;
                    if (gv && GvCVu(gv)) {
-                       for (d = s + 1; *d == ' ' || *d == '\t'; d++) ;
+                       for (d = s + 1; SPACE_OR_TAB(*d); d++) ;
                        if (*d == ')' && (sv = cv_const_sv(GvCV(gv)))) {
                            s = d + 1;
                            goto its_constant;
@@ -5666,7 +5681,7 @@ S_scan_ident(pTHX_ register char *s, register char *send, char *dest, STRLEN des
        if (isSPACE(s[-1])) {
            while (s < send) {
                char ch = *s++;
-               if (ch != ' ' && ch != '\t') {
+               if (!SPACE_OR_TAB(ch)) {
                    *d = ch;
                    break;
                }
@@ -5692,7 +5707,7 @@ S_scan_ident(pTHX_ register char *s, register char *send, char *dest, STRLEN des
                    Perl_croak(aTHX_ ident_too_long);
            }
            *d = '\0';
-           while (s < send && (*s == ' ' || *s == '\t')) s++;
+           while (s < send && SPACE_OR_TAB(*s)) s++;
            if ((*s == '[' || (*s == '{' && strNE(dest, "sub")))) {
                dTHR;                   /* only for ckWARN */
                if (ckWARN(WARN_AMBIGUOUS) && keyword(dest, d - dest)) {
@@ -5967,7 +5982,7 @@ S_scan_heredoc(pTHX_ register char *s)
     e = PL_tokenbuf + sizeof PL_tokenbuf - 1;
     if (!outer)
        *d++ = '\n';
-    for (peek = s; *peek == ' ' || *peek == '\t'; peek++) ;
+    for (peek = s; SPACE_OR_TAB(*peek); peek++) ;
     if (*peek && strchr("`'\"",*peek)) {
        s = peek;
        term = *s++;
@@ -6798,9 +6813,9 @@ S_scan_formline(pTHX_ register char *s)
        if (*s == '.' || *s == '}') {
            /*SUPPRESS 530*/
 #ifdef PERL_STRICT_CR
-           for (t = s+1;*t == ' ' || *t == '\t'; t++) ;
+           for (t = s+1;SPACE_OR_TAB(*t); t++) ;
 #else
-           for (t = s+1;*t == ' ' || *t == '\t' || *t == '\r'; t++) ;
+           for (t = s+1;SPACE_OR_TAB(*t) || *t == '\r'; t++) ;
 #endif
            if (*t == '\n' || t == PL_bufend)
                break;
@@ -6981,19 +6996,35 @@ Perl_yyerror(pTHX_ char *s)
            Perl_sv_catpvf(aTHX_ where_sv, "\\%03o", yychar & 255);
        where = SvPVX(where_sv);
     }
+#ifdef MACOS_TRADITIONAL
+    msg = sv_2mortal(newSVpv("# ", 0));
+    sv_catpvf(msg, "%s, ", s);
+#else
     msg = sv_2mortal(newSVpv(s, 0));
     Perl_sv_catpvf(aTHX_ msg, " at %_ line %"IVdf", ",
               GvSV(PL_curcop->cop_filegv), (IV)PL_curcop->cop_line);
+#endif
     if (context)
        Perl_sv_catpvf(aTHX_ msg, "near \"%.*s\"\n", contlen, context);
     else
        Perl_sv_catpvf(aTHX_ msg, "%s\n", where);
-    if (PL_multi_start < PL_multi_end && (U32)(PL_curcop->cop_line - PL_multi_end) <= 1) {
+    if (PL_multi_start < PL_multi_end &&
+       (U32)(PL_curcop->cop_line - PL_multi_end) <= 1) {
+#ifdef MACOS_TRADITIONAL
+        Perl_sv_catpvf(aTHX_ msg,
+        "#   (Might be a runaway multi-line %c%c string starting on line %"IVdf")\n",
+                (int)PL_multi_open,(int)PL_multi_close,(IV)PL_multi_start);
+#else
         Perl_sv_catpvf(aTHX_ msg,
-        "  (Might be a runaway multi-line %c%c string starting on line %"IVdf")\n",
+        "   (Might be a runaway multi-line %c%c string starting on line %"IVdf")\n",
                 (int)PL_multi_open,(int)PL_multi_close,(IV)PL_multi_start);
+#endif
         PL_multi_end = 0;
     }
+#ifdef MACOS_TRADITIONAL
+    MacPosIndication(msg, SvPVX(GvSV(PL_curcop->cop_filegv)), PL_curcop->cop_line);
+    sv_catpvn(msg, "\n", 1);
+#endif
     if (PL_in_eval & EVAL_WARNONLY)
        Perl_warn(aTHX_ "%_", msg);
     else
diff --git a/util.c b/util.c
index 3f03744..cc09a64 100644 (file)
--- a/util.c
+++ b/util.c
@@ -78,6 +78,11 @@ long lastxycount[MAXXCOUNT][MAXYCOUNT];
  * XXX This advice seems to be widely ignored :-(   --AD  August 1996.
  */
 
+#ifdef MACOS_TRADITIONAL
+extern void * gSacrificialGoat;
+#define MAC_CHECK_GOAT(p) if (!gSacrificialGoat && p) { PerlMem_free(p); p = NULL; } else 
+#endif
+
 Malloc_t
 Perl_safesysmalloc(MEM_SIZE size)
 {
@@ -95,6 +100,9 @@ Perl_safesysmalloc(MEM_SIZE size)
        Perl_croak_nocontext("panic: malloc");
 #endif
     ptr = PerlMem_malloc(size?size:1); /* malloc(0) is NASTY on our system */
+#ifdef MACOS_TRADITIONAL
+    MAC_CHECK_GOAT(ptr);
+#endif
     DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05d) malloc %ld bytes\n",PTR2UV(ptr),PL_an++,(long)size));
     if (ptr != Nullch)
        return ptr;
@@ -139,6 +147,10 @@ Perl_safesysrealloc(Malloc_t where,MEM_SIZE size)
 #endif
     ptr = PerlMem_realloc(where,size);
 
+#ifdef MACOS_TRADITIONAL
+    MAC_CHECK_GOAT(ptr);
+#endif
     DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05d) rfree\n",PTR2UV(where),PL_an++));
     DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05d) realloc %ld bytes\n",PTR2UV(ptr),PL_an++,(long)size));
 
@@ -188,6 +200,9 @@ Perl_safesyscalloc(MEM_SIZE count, MEM_SIZE size)
 #endif
     size *= count;
     ptr = PerlMem_malloc(size?size:1); /* malloc(0) is NASTY on our system */
+#ifdef MACOS_TRADITIONAL
+    MAC_CHECK_GOAT(ptr);
+#endif
     DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05d) calloc %ld x %ld bytes\n",PTR2UV(ptr),PL_an++,(long)count,(long)size));
     if (ptr != Nullch) {
        memset((void*)ptr, 0, size);
@@ -1413,7 +1428,14 @@ Perl_vmess(pTHX_ const char *pat, va_list *args)
     SV *sv = mess_alloc();
     static char dgd[] = " during global destruction.\n";
 
+#ifdef MACOS_TRADITIONAL
+    sv_setpv(sv, "# ");
+    sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
+    if (SvPVX(sv)[2] == '#')
+       sv_insert(sv, 0, 2, "", 0);
+#else
     sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*));
+#endif
     if (!SvCUR(sv) || *(SvEND(sv) - 1) != '\n') {
        dTHR;
        if (PL_curcop->cop_line)
@@ -1432,6 +1454,12 @@ Perl_vmess(pTHX_ const char *pat, va_list *args)
            Perl_sv_catpvf(aTHX_ sv, " thread %ld", thr->tid);
 #endif
        sv_catpv(sv, PL_dirty ? dgd : ".\n");
+#ifdef MACOS_TRADITIONAL
+           if (PL_curcop->cop_line) {
+               MPWPosIndication(sv, SvPVX(GvSV(PL_curcop->cop_filegv)), PL_curcop->cop_line);
+               sv_catpv(sv, "\n");
+           }
+#endif
     }
     return sv;
 }
@@ -1601,6 +1629,9 @@ Perl_vcroak(pTHX_ const char* pat, va_list *args)
        errno = e;
 #endif
     }
+#ifdef MACOS_TRADITIONAL
+    MacPosCommit();
+#endif
     my_failure_exit();
 }
 
@@ -2222,7 +2253,7 @@ VTOH(vtohl,long)
 #endif
 
     /* VMS' my_popen() is in VMS.c, same with OS/2. */
-#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC)
+#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC) && !defined(MACOS_TRADITIONAL)
 PerlIO *
 Perl_my_popen(pTHX_ char *cmd, char *mode)
 {
@@ -2514,7 +2545,7 @@ Perl_rsignal_restore(pTHX_ int signo, Sigsave_t *save)
 #endif /* !HAS_SIGACTION */
 
     /* VMS' my_pclose() is in VMS.c; same with OS/2 */
-#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC)
+#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC) && !defined(MACOS_TRADITIONAL)
 I32
 Perl_my_pclose(pTHX_ PerlIO *ptr)
 {
@@ -2570,7 +2601,7 @@ Perl_my_pclose(pTHX_ PerlIO *ptr)
 }
 #endif /* !DOSISH */
 
-#if  !defined(DOSISH) || defined(OS2) || defined(WIN32)
+#if  (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL)
 I32
 Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags)
 {
@@ -3120,15 +3151,26 @@ Perl_find_script(pTHX_ char *scriptname, bool dosearch, char **search_ext, I32 f
     }
 #endif
 
+#ifdef MACOS_TRADITIONAL
+    if (dosearch && !strchr(scriptname, ':') &&
+       (s = PerlEnv_getenv("Commands")))
+#else
     if (dosearch && !strchr(scriptname, '/')
 #ifdef DOSISH
                 && !strchr(scriptname, '\\')
 #endif
-                && (s = PerlEnv_getenv("PATH"))) {
+                && (s = PerlEnv_getenv("PATH")))
+#endif
+    {
        bool seen_dot = 0;
        
        PL_bufend = s + strlen(s);
        while (s < PL_bufend) {
+#ifdef MACOS_TRADITIONAL
+           s = delimcpy(tmpbuf, tmpbuf + sizeof tmpbuf, s, PL_bufend,
+                       ',',
+                       &len);
+#else
 #if defined(atarist) || defined(DOSISH)
            for (len = 0; *s
 #  ifdef atarist
@@ -3145,10 +3187,15 @@ Perl_find_script(pTHX_ char *scriptname, bool dosearch, char **search_ext, I32 f
                        ':',
                        &len);
 #endif /* ! (atarist || DOSISH) */
+#endif /* MACOS_TRADITIONAL */
            if (s < PL_bufend)
                s++;
            if (len + 1 + strlen(scriptname) + MAX_EXT_LEN >= sizeof tmpbuf)
                continue;       /* don't search dir with too-long name */
+#ifdef MACOS_TRADITIONAL
+           if (len && tmpbuf[len - 1] != ':')
+               tmpbuf[len++] = ':';
+#else
            if (len
 #if defined(atarist) || defined(__MINT__) || defined(DOSISH)
                && tmpbuf[len - 1] != '/'
@@ -3158,6 +3205,7 @@ Perl_find_script(pTHX_ char *scriptname, bool dosearch, char **search_ext, I32 f
                tmpbuf[len++] = '/';
            if (len == 2 && tmpbuf[0] == '.')
                seen_dot = 1;
+#endif
            (void)strcpy(tmpbuf + len, scriptname);
 #endif  /* !VMS */
 
@@ -3182,7 +3230,7 @@ Perl_find_script(pTHX_ char *scriptname, bool dosearch, char **search_ext, I32 f
                continue;
            if (S_ISREG(PL_statbuf.st_mode)
                && cando(S_IRUSR,TRUE,&PL_statbuf)
-#ifndef DOSISH
+#if !defined(DOSISH) && !defined(MACOS_TRDITIONAL)
                && cando(S_IXUSR,TRUE,&PL_statbuf)
 #endif
                )