Initial revision
This commit is contained in:
parent
fe16cc0338
commit
dc0493ac67
|
@ -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.)
|
|
@ -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.)
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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()
|
Loading…
Reference in New Issue