Initial revision
diff --git a/Mac/Relnotes-1.1 b/Mac/Relnotes-1.1
new file mode 100644
index 0000000..3c67fb7
--- /dev/null
+++ b/Mac/Relnotes-1.1
@@ -0,0 +1,131 @@
+PYTHON RELEASE NOTES FOR THE MACINTOSH
+
+VERSION 1.0.2
+
+For the most part, Python on the Mac works just like Python under UNIX.
+The most important differences are:
+
+- Since there is no shell environment on the Mac, the start-up file
+  has a fixed name: PythonStartup.  If a file by this name exists
+  (either in the current folder or in the system folder) it is executed
+  when an interactive interpreter is started.
+
+- The default search path for modules is different: first the current
+  directory is searched, then the subdirectories 'lib', 'lib:stdwin' and
+  'demo'.  As always, you can change this (e.g. in your PythonStartup
+  file) by assigning or appending to sys.path -- use Macintosh pathnames!
+  (The default contains no absolute paths because these are unlikely
+  to make sense on other people's hard disks.)
+
+- The user interface for typing interactive commands is different.
+  This is actually the THINK C console I/O module, which is based on
+  the Mac toolbox TextEdit.  A standard Edit menu provides Cut, Copy,
+  Paste and Clear (Undo is only there for Desk Accessories).  A minimal
+  File menu provides Quit, which immediately exits the application,
+  without the usual cleanup.  You can Copy from previous output,
+  but you can't scroll back beyond the 24x80 screen.  The TAB key
+  always brings you to the end of the current input line; indentation
+  must be entered with spaces (a single space is enough).
+  End-of-file is generated by Command-D; Command-Period interrupts.
+  There is an annoying limit in the length of an input line to a single
+  screen line (less the prompt).  Use \ to input long statements.
+  Change your program if it requires long lines typed on input.
+  Even though there is no resize box, the window can be resized by
+  dragging its bottom right corner, but the maximum size is 24x80.
+
+- Tabs in module files are interpreted as 4 (four!) spaces.  This is
+  consistent with most Mac editors that I know.  For individual files
+  you can change the tab size with a comment like
+
+	# vi:set tabsize=8:
+
+  (exactly as shown here, including the colons!).  If you are consistent
+  in always using tabs for indentation on UNIX, your files will be
+  parsed correctly on the Mac, although they may look funny if you
+  have nicely lined-up comments or tables using tabs.  Never using tabs
+  also works.  Mixing tabs and spaces to simulate 4-character indentation
+  levels is likely to fail.
+
+- You can start a script from the Finder by selecting the script and
+  the Python interpreter together and then double clicking.  If you
+  make the owner of the script PYTH (the type should always be TEXT)
+  Python will be launched if you double click it!
+  There is no way to pass command line arguments to Python scripts.
+
+- The set of built-in modules is different:
+
+  = Operating system functions for the 'os' module is provided by the
+    built-in module 'mac', not 'posix'.  This doesn't have all the
+    functions from posix, for obvious reasons (if you know the Mac
+    O/S a little bit).  The functions in os.path are provided by
+    macpath, they know about Mac pathnames etc.
+    
+  = None of the UNIX specific modules ('socket', 'pwd', 'grp' etc.)
+    exists.
+    
+  = Module 'stdwin' is always available.  It uses the Mac version of
+    STDWIN, which interfaces directly with the Mac toolbox.  The most
+    important difference is in the font names; setfont() has a second
+    argument specifying the point size and an optional third one
+    specifying the variation: a single letter character string,
+    'i' for italics, 'b' for bold.  Note that when STDWIN is waiting
+    for events, the standard File and Edit menus are inactive but
+    still visible, and (most annoyingly) the Apple menu is also inactive;
+    conversely, menus put up by STDWIN are not active when the Python is
+    reading from the keyboard.  If you open Python together with a text
+    file containing a Python script, the script will be executed and
+    a console window is only generated when the script uses standard
+    input or output.  A script that uses STDWIN exclusively for its I/O
+    will have a working Apple menu and no extraneous File/Edit menus.
+    (This is because both stdwin and stdio try to initialize the
+    windowing environment; whoever gets there first owns the Apple menu.)
+    LIMITATIONS: a few recent additions to STDWIN for X11 have not yet
+    been added to the Mac version.  There are no bitmap objects, and
+    the setwinpos() and setwinsize() methods are non--functional.
+
+- Because launching an application on the Mac is so tedious, you will
+  want to edit your program with a desk accessory editor (e.g., Sigma
+  edit) and test the changed version without leaving Python.  This is
+  possible but requires some care.  Make sure the program is a module
+  file (filename must be a Python identifier followed by '.py').  You
+  can then import it when you test it for the first time.  There are
+  now three possibilities: it contains a syntax error; it gets a runtime
+  error (unhandled exception); or it runs OK but gives wrong results.
+  (If it gives correct results, you are done testing and don't need
+  to read the rest of this paragraph. :-)  Note that the following
+  is not Mac-specific -- it's just that on UNIX it's easier to restart
+  the entire script so it's rarely useful.
+  
+  Recovery from a syntax error is easy: edit the file and import it
+  again.
+  
+  Recovery from wrong output is almost as easy: edit the file and,
+  instead of importing it, call the function reload() with the module
+  name as argument (e.g., if your module is called foo, type
+  "reload(foo)").
+  
+  Recovery from an exception is trickier.  Once the syntax is correct,
+  a 'module' entry is placed in an internal table, and following import
+  statements will not re-read the file, even if the module's initialization
+  terminated with an error (one reason why this is done is so that
+  mutually recursive modules are initialized only once).  You must
+  therefore force re-reading the module with reload(), however, if this
+  happens the first time you try to import the module, the import statement
+  itself has not completed, and your workspace does not know the module
+  name (even though the internal table of moduesl does!).  The trick is
+  to first import the module again, then reload it.  For instance,
+  "import foo; reload(foo)".  Because the module object already exists
+  internally, the import statement does not attempt to execute the
+  module again -- it just places it in your workspace.
+  
+  When you edit a module you don't have to worry about the corresponding
+  '.pyc' file (a "compiled" version of the module, which loads much faster
+  than the textual version): the interpreter notices that the '.py' file
+  has changed (because its modification time has changed) and ignores the
+  '.pyc' file.  When parsing is successful, a new '.pyc' file is written;
+  if this fails (no write permission, disk full or whatever) it is
+  silently skipped but attempted again the next time the same module
+  is loaded.  (Thus, if you plan to place a Python library on a read-only
+  disk, it is advisable to "warm the cache" by making the disk writable
+  and importing all modules once.  The standard module 'importall' helps
+  in doing this.)
diff --git a/Mac/USING b/Mac/USING
new file mode 100644
index 0000000..3c67fb7
--- /dev/null
+++ b/Mac/USING
@@ -0,0 +1,131 @@
+PYTHON RELEASE NOTES FOR THE MACINTOSH
+
+VERSION 1.0.2
+
+For the most part, Python on the Mac works just like Python under UNIX.
+The most important differences are:
+
+- Since there is no shell environment on the Mac, the start-up file
+  has a fixed name: PythonStartup.  If a file by this name exists
+  (either in the current folder or in the system folder) it is executed
+  when an interactive interpreter is started.
+
+- The default search path for modules is different: first the current
+  directory is searched, then the subdirectories 'lib', 'lib:stdwin' and
+  'demo'.  As always, you can change this (e.g. in your PythonStartup
+  file) by assigning or appending to sys.path -- use Macintosh pathnames!
+  (The default contains no absolute paths because these are unlikely
+  to make sense on other people's hard disks.)
+
+- The user interface for typing interactive commands is different.
+  This is actually the THINK C console I/O module, which is based on
+  the Mac toolbox TextEdit.  A standard Edit menu provides Cut, Copy,
+  Paste and Clear (Undo is only there for Desk Accessories).  A minimal
+  File menu provides Quit, which immediately exits the application,
+  without the usual cleanup.  You can Copy from previous output,
+  but you can't scroll back beyond the 24x80 screen.  The TAB key
+  always brings you to the end of the current input line; indentation
+  must be entered with spaces (a single space is enough).
+  End-of-file is generated by Command-D; Command-Period interrupts.
+  There is an annoying limit in the length of an input line to a single
+  screen line (less the prompt).  Use \ to input long statements.
+  Change your program if it requires long lines typed on input.
+  Even though there is no resize box, the window can be resized by
+  dragging its bottom right corner, but the maximum size is 24x80.
+
+- Tabs in module files are interpreted as 4 (four!) spaces.  This is
+  consistent with most Mac editors that I know.  For individual files
+  you can change the tab size with a comment like
+
+	# vi:set tabsize=8:
+
+  (exactly as shown here, including the colons!).  If you are consistent
+  in always using tabs for indentation on UNIX, your files will be
+  parsed correctly on the Mac, although they may look funny if you
+  have nicely lined-up comments or tables using tabs.  Never using tabs
+  also works.  Mixing tabs and spaces to simulate 4-character indentation
+  levels is likely to fail.
+
+- You can start a script from the Finder by selecting the script and
+  the Python interpreter together and then double clicking.  If you
+  make the owner of the script PYTH (the type should always be TEXT)
+  Python will be launched if you double click it!
+  There is no way to pass command line arguments to Python scripts.
+
+- The set of built-in modules is different:
+
+  = Operating system functions for the 'os' module is provided by the
+    built-in module 'mac', not 'posix'.  This doesn't have all the
+    functions from posix, for obvious reasons (if you know the Mac
+    O/S a little bit).  The functions in os.path are provided by
+    macpath, they know about Mac pathnames etc.
+    
+  = None of the UNIX specific modules ('socket', 'pwd', 'grp' etc.)
+    exists.
+    
+  = Module 'stdwin' is always available.  It uses the Mac version of
+    STDWIN, which interfaces directly with the Mac toolbox.  The most
+    important difference is in the font names; setfont() has a second
+    argument specifying the point size and an optional third one
+    specifying the variation: a single letter character string,
+    'i' for italics, 'b' for bold.  Note that when STDWIN is waiting
+    for events, the standard File and Edit menus are inactive but
+    still visible, and (most annoyingly) the Apple menu is also inactive;
+    conversely, menus put up by STDWIN are not active when the Python is
+    reading from the keyboard.  If you open Python together with a text
+    file containing a Python script, the script will be executed and
+    a console window is only generated when the script uses standard
+    input or output.  A script that uses STDWIN exclusively for its I/O
+    will have a working Apple menu and no extraneous File/Edit menus.
+    (This is because both stdwin and stdio try to initialize the
+    windowing environment; whoever gets there first owns the Apple menu.)
+    LIMITATIONS: a few recent additions to STDWIN for X11 have not yet
+    been added to the Mac version.  There are no bitmap objects, and
+    the setwinpos() and setwinsize() methods are non--functional.
+
+- Because launching an application on the Mac is so tedious, you will
+  want to edit your program with a desk accessory editor (e.g., Sigma
+  edit) and test the changed version without leaving Python.  This is
+  possible but requires some care.  Make sure the program is a module
+  file (filename must be a Python identifier followed by '.py').  You
+  can then import it when you test it for the first time.  There are
+  now three possibilities: it contains a syntax error; it gets a runtime
+  error (unhandled exception); or it runs OK but gives wrong results.
+  (If it gives correct results, you are done testing and don't need
+  to read the rest of this paragraph. :-)  Note that the following
+  is not Mac-specific -- it's just that on UNIX it's easier to restart
+  the entire script so it's rarely useful.
+  
+  Recovery from a syntax error is easy: edit the file and import it
+  again.
+  
+  Recovery from wrong output is almost as easy: edit the file and,
+  instead of importing it, call the function reload() with the module
+  name as argument (e.g., if your module is called foo, type
+  "reload(foo)").
+  
+  Recovery from an exception is trickier.  Once the syntax is correct,
+  a 'module' entry is placed in an internal table, and following import
+  statements will not re-read the file, even if the module's initialization
+  terminated with an error (one reason why this is done is so that
+  mutually recursive modules are initialized only once).  You must
+  therefore force re-reading the module with reload(), however, if this
+  happens the first time you try to import the module, the import statement
+  itself has not completed, and your workspace does not know the module
+  name (even though the internal table of moduesl does!).  The trick is
+  to first import the module again, then reload it.  For instance,
+  "import foo; reload(foo)".  Because the module object already exists
+  internally, the import statement does not attempt to execute the
+  module again -- it just places it in your workspace.
+  
+  When you edit a module you don't have to worry about the corresponding
+  '.pyc' file (a "compiled" version of the module, which loads much faster
+  than the textual version): the interpreter notices that the '.py' file
+  has changed (because its modification time has changed) and ignores the
+  '.pyc' file.  When parsing is successful, a new '.pyc' file is written;
+  if this fails (no write permission, disk full or whatever) it is
+  silently skipped but attempted again the next time the same module
+  is loaded.  (Thus, if you plan to place a Python library on a read-only
+  disk, it is advisable to "warm the cache" by making the disk writable
+  and importing all modules once.  The standard module 'importall' helps
+  in doing this.)
diff --git a/Mac/fopenRF.c b/Mac/fopenRF.c
new file mode 100644
index 0000000..f18f7d9
--- /dev/null
+++ b/Mac/fopenRF.c
@@ -0,0 +1,399 @@
+
+/*
+ *  fopenRF.c -- Clone of fopen.c to open Mac resource forks.
+ *
+ *  Copyright (c) 1989 Symantec Corporation.  All rights reserved.
+ *
+ */
+
+#include "stdio.h"
+#include "errno.h"
+#include "string.h"
+#include "ansi_private.h"
+
+FILE *fopenRF(char *, char *);
+FILE *freopenRF(char *, char *, FILE *);
+FILE *__openRF(char *, int, int, FILE *);
+
+#include <Files.h>
+
+#define fcbVPtr(fcb)		(* (VCB **) (fcb + 20))
+#define fcbDirID(fcb)		(* (long *) (fcb + 58))
+#define fcbCName(fcb)		(fcb + 62)
+
+static void setfiletype(StringPtr, int);
+static void stdio_exit(void);
+static int fileio(FILE *, int);
+static int close(FILE *);
+static void replace(unsigned char *, size_t, int, int);
+
+
+FILE *
+fopenRF(filename, mode)
+char *filename, *mode;
+{
+	return(freopenRF(filename, mode, __getfile()));
+}
+
+
+FILE *
+freopenRF(filename, mode, fp)
+char *filename;
+register char *mode;
+register FILE *fp;
+{
+	int omode, oflag;
+	
+		/*  interpret "rwa"  */
+	
+	if (mode[0] == 'r') {
+		omode = fsRdPerm;
+		oflag = 0;
+	}
+	else if (mode[0] == 'w') {
+		omode = fsWrPerm;
+		oflag = F_CREAT+F_TRUNC;
+	}
+	else if (mode[0] == 'a') {
+		omode = fsWrPerm;
+		oflag = F_CREAT+F_APPEND;
+	}
+	else {
+		errno = EINVAL;
+		return(NULL);
+	}
+		
+		/*  interpret "b+"  */
+		
+	if (mode[1] == 'b') {
+		oflag |= F_BINARY;
+		if (mode[2] == '+')
+			omode = fsRdWrPerm;
+	}
+	else if (mode[1] == '+') {
+		omode = fsRdWrPerm;
+		if (mode[2] == 'b')
+			oflag |= F_BINARY;
+	}
+	
+		/*  open the file  */
+		
+	return(__openRF(filename, omode, oflag, fp));
+}
+
+
+FILE *
+__openRF(filename, omode, oflag, fp)
+char *filename;
+int omode, oflag;
+register FILE *fp;
+{
+	ioParam pb;
+	char pname[FILENAME_MAX];
+
+	if (fp == NULL)
+		return(NULL);
+	fclose(fp);
+	
+		/*  set up pb  */
+	
+	pb.ioNamePtr = __c2p(filename, pname);
+	pb.ioVRefNum = 0;
+	pb.ioVersNum = 0;
+	pb.ioPermssn = omode;
+	pb.ioMisc = 0;
+
+		/*  create file  */
+
+	if (oflag & F_CREAT) {
+		asm {
+			lea		pb,a0
+			_PBCreate
+		}
+		if (pb.ioResult == noErr)
+			oflag &= ~F_TRUNC;
+		else if (pb.ioResult == dupFNErr && !(oflag & F_EXCL))
+			oflag &= ~F_CREAT;
+		else {
+			errno = pb.ioResult;
+			return(NULL);
+		}
+	}
+	
+		/*  open resource file  */
+		
+	asm {
+		lea		pb,a0
+		_PBOpenRF
+	}
+	if (pb.ioResult) {
+		errno = pb.ioResult;
+		if (oflag & F_CREAT) asm {
+			lea		pb,a0
+			_PBDelete
+		}
+		return(NULL);
+	}
+	fp->refnum = pb.ioRefNum;
+	
+		/*  get/set file length  */
+		
+	if (oflag & F_TRUNC) asm {
+		lea		pb,a0
+		_PBSetEOF
+	}
+	else if (!(oflag & F_CREAT)) asm {
+		lea		pb,a0
+		_PBGetEOF
+	}
+	fp->len = (fpos_t) pb.ioMisc;
+		
+		/*  initialize rest of FILE structure  */
+		
+	if (oflag & F_APPEND) {
+		fp->append = 1;
+		fp->pos = fp->len;
+	}
+	if (oflag & F_BINARY)
+		fp->binary = 1;
+	setvbuf(fp, NULL, _IOFBF, BUFSIZ);
+	fp->proc = fileio;
+
+		/*  set file type  */
+
+	if (oflag & (F_CREAT|F_TRUNC))
+		setfiletype(pb.ioNamePtr, oflag);
+		
+		/*  done  */
+		
+	__atexit_stdio(stdio_exit);
+	return(fp);
+}
+
+
+/*
+ *  setfiletype - set type/creator of new file
+ *
+ */
+
+static void
+setfiletype(name, oflag)
+StringPtr name;
+int oflag;
+{
+	fileParam pb;
+	
+	pb.ioNamePtr = name;
+	pb.ioVRefNum = 0;
+	pb.ioFVersNum = 0;
+	pb.ioFDirIndex = 0;
+	asm {
+		lea		pb,a0
+		_PBGetFInfo
+		bmi.s	@1
+	}
+	pb.ioFlFndrInfo.fdType = pb.ioFlFndrInfo.fdCreator = '????';
+	if (!(oflag & F_BINARY))
+		pb.ioFlFndrInfo.fdType = 'TEXT';
+	asm {
+		lea		pb,a0
+		_PBSetFInfo
+@1	}
+}
+
+
+/*
+ *  stdio_exit - stdio shutdown routine
+ *
+ */
+
+static void
+stdio_exit()
+{
+	register FILE *fp;
+	int n;
+	
+	for (fp = &__file[0], n = FOPEN_MAX; n--; fp++)
+		fclose(fp);
+}
+
+
+/*
+ *  fileio - I/O handler proc for files and devices
+ *
+ */
+
+static int
+fileio(fp, i)
+register FILE *fp;
+int i;
+{
+	ioParam pb;
+	
+	pb.ioRefNum = fp->refnum;
+	switch (i) {
+	
+				/*  read  */
+			
+		case 0:
+			pb.ioBuffer = (Ptr) fp->ptr;
+			pb.ioReqCount = fp->cnt;
+			pb.ioPosMode = fp->refnum > 0 ? fsFromStart : fsAtMark;
+			pb.ioPosOffset = fp->pos - fp->cnt;
+			asm {
+				lea		pb,a0
+				_PBRead
+			}
+			if (pb.ioResult == eofErr) {
+				fp->pos = pb.ioPosOffset;
+				if (fp->cnt = pb.ioActCount)
+					pb.ioResult = 0;
+				else {
+					fp->eof = 1;
+					return(EOF);
+				}
+			}
+			if (pb.ioResult) {
+				fp->pos -= fp->cnt;
+				fp->cnt = 0;
+			}
+			else if (!fp->binary)
+				replace(fp->ptr, fp->cnt, '\r', '\n');
+			break;
+			
+				/*  write  */
+
+		case 1:
+			pb.ioBuffer = (Ptr) fp->ptr;
+			pb.ioReqCount = fp->cnt;
+			pb.ioPosMode = fp->refnum > 0 ? fsFromStart : fsAtMark;
+			if ((pb.ioPosOffset = fp->pos - fp->cnt) > fp->len) {
+				pb.ioMisc = (Ptr) pb.ioPosOffset;
+				asm {
+					lea		pb,a0
+					_PBSetEOF
+					bmi.s	@1
+				}
+			}
+			if (!fp->binary)
+				replace(fp->ptr, fp->cnt, '\n', '\r');
+			asm {
+				lea		pb,a0
+				_PBWrite
+@1			}
+			if (pb.ioResult) {
+				fp->pos -= fp->cnt;
+				fp->cnt = 0;
+			}
+			else if (pb.ioPosOffset > fp->len)
+				fp->len = pb.ioPosOffset;
+			break;
+			
+				/*  close  */
+
+		case 2:
+			pb.ioResult = close(fp);
+			break;
+	}
+	
+		/*  done  */
+		
+	if (pb.ioResult) {
+		fp->err = 1;
+		errno = pb.ioResult;
+		return(EOF);
+	}
+	return(0);
+}
+
+
+static int
+close(fp)
+register FILE *fp;
+{
+	HFileParam pb;
+	Str255 buf;
+	register char *fcb = FCBSPtr + fp->refnum;
+	VCB *vcb = fcbVPtr(fcb);
+	register char *s;
+	
+	pb.ioNamePtr = buf;
+	pb.ioFRefNum = fp->refnum;
+	pb.ioVRefNum = vcb->vcbVRefNum;
+	pb.ioFVersNum = 0;
+	
+		/*  close temporary file - HFS  */
+		
+	if (fp->delete && vcb->vcbSigWord == 0x4244) {
+		pb.ioDirID = fcbDirID(fcb);
+		s = fcbCName(fcb);
+		asm {
+			lea		buf,a0
+			moveq	#0,d0
+			move.b	(s),d0
+@1			move.b	(s)+,(a0)+
+			dbra	d0,@1
+			lea		pb,a0
+			_PBClose
+			bmi.s	@9
+			_PBHDelete
+		}
+	}
+	
+		/*  close temporary file - MFS  */
+		
+	else if (fp->delete && vcb->vcbSigWord == 0xD2D7) {
+		pb.ioFDirIndex = 1;
+		do asm {
+			lea		pb,a0
+			_PBGetFInfo
+			bmi.s	@2
+			addq.w	#1,pb.ioFDirIndex
+		} while (pb.ioFRefNum != fp->refnum);
+		asm {
+			lea		pb,a0
+			_PBClose
+			bmi.s	@9
+			_PBDelete
+		}
+	}
+	
+		/*  normal case - just close file  */
+		
+	else {
+		asm {
+@2			lea		pb,a0
+			_PBClose
+			bmi.s	@9
+		}
+	}
+	
+		/*  flush volume buffer  */
+		
+	pb.ioNamePtr = 0;
+	asm {
+		lea		pb,a0
+		_PBFlshVol
+@9	}
+	return(pb.ioResult);
+}
+
+
+/*
+ *  replace - routine for doing CR/LF conversion
+ *
+ */
+
+static void
+replace(s, n, c1, c2)
+register unsigned char *s;
+register size_t n;
+register int c1, c2;
+{
+	register unsigned char *t;
+	
+	for (; n && (t = memchr(s, c1, n)); s = t) {
+		*t++ = c2;
+		n -= t - s;
+	}
+}
diff --git a/Mac/scripts/crlf.py b/Mac/scripts/crlf.py
new file mode 100755
index 0000000..f52867a
--- /dev/null
+++ b/Mac/scripts/crlf.py
@@ -0,0 +1,25 @@
+#! /usr/local/bin/python
+
+import sys
+import os
+import string
+
+def main():
+	args = sys.argv[1:]
+	if not args:
+		print 'no files'
+		sys.exit(1)
+	for file in args:
+		print file, '...'
+		data = open(file, 'r').read()
+		lines = string.splitfields(data, '\r')
+		newdata = string.joinfields(lines, '\n')
+		if newdata != data:
+			print 'rewriting...'
+			os.rename(file, file + '~')
+			open(file, 'w').write(newdata)
+			print 'done.'
+		else:
+			print 'no change.'
+
+main()