Initial revision

This commit is contained in:
Guido van Rossum 1994-05-06 14:16:55 +00:00
parent fe16cc0338
commit dc0493ac67
4 changed files with 686 additions and 0 deletions

131
Mac/Relnotes-1.1 Normal file
View File

@ -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.)

131
Mac/USING Normal file
View File

@ -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.)

399
Mac/fopenRF.c Normal file
View File

@ -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;
}
}

25
Mac/scripts/crlf.py Executable file
View File

@ -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()