[Python-checkins] CVS: python/dist/src/Mac errno_unix.h,NONE,1.1.2.1 fopenRF.c,NONE,1.2.2.1 mkapplet.py,NONE,1.8.2.1 mwerksglue.c,NONE,1.1.2.1

Guido van Rossum gvanrossum@users.sourceforge.net
Mon, 20 Aug 2001 10:12:36 -0700


Update of /cvsroot/python/python/dist/src/Mac
In directory usw-pr-cvs1:/tmp/cvs-serv16167

Added Files:
      Tag: r22a2-branch
	errno_unix.h fopenRF.c mkapplet.py mwerksglue.c 
Log Message:
Merge Jack's changes from the trunk

--- NEW FILE: errno_unix.h ---

#define ENOTDIR		(-120)
#define EACCES		(-54)
#define EEXIST		(-48)
#define EBUSY		(-47)
#define EROFS		(-44)
#define ENOENT		(-43)
#define ENFILE		(-42)
#define	EIO			(-36)
#define ENOSPC		(-34)

#define ESRCH		3
#define EINTR		4
#define EBADF		9
#define ENODEV		19
#define EINVAL		22
#define EMFILE		24


--- NEW FILE: fopenRF.c ---

/*
 *  fopen.c
 *
 *  Copyright (c) 1991 Symantec Corporation.  All rights reserved.
 *
 */

#include <MacHeaders>

#include "stdio.h"
#include "errno.h"
#include "string.h"
#include "ansi_private.h"

extern long _ftype, _fcreator;

#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 *freopenRF();
FILE *__openRF();

FILE *
fopenRF(const char *filename, const char *mode)
{
	return(freopenRF(filename, mode, __getfile()));
}


FILE *
freopenRF(const char *filename, const char *mode, 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(const char *filename, int omode, int oflag, 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) {
		PBCreateSync((ParmBlkPtr)&pb);
		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 file  */
		
	PBOpenRFSync((ParmBlkPtr)&pb);
	if (pb.ioResult) {
		errno = pb.ioResult;
		if (oflag & F_CREAT)
			PBDeleteSync((ParmBlkPtr)&pb);
		return(NULL);
	}
	fp->refnum = pb.ioRefNum;
	
		/*  get/set file length  */
		
	if (oflag & F_TRUNC)
		PBSetEOFSync((ParmBlkPtr)&pb);
	else if (!(oflag & F_CREAT))
		PBGetEOFSync((ParmBlkPtr)&pb);
	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(StringPtr name, int oflag)
{
	FileParam pb;
	
	pb.ioNamePtr = name;
	pb.ioVRefNum = 0;
	pb.ioFVersNum = 0;
	pb.ioFDirIndex = 0;
	if (PBGetFInfoSync((ParmBlkPtr)&pb) == noErr) {
		if (oflag & F_BINARY)
			pb.ioFlFndrInfo.fdType = _ftype;
		else
			pb.ioFlFndrInfo.fdType = 'TEXT';
		pb.ioFlFndrInfo.fdCreator = _fcreator;
		PBSetFInfoSync((ParmBlkPtr)&pb);
	}
}


/*
 *  stdio_exit - stdio shutdown routine
 *
 */

static void
stdio_exit(void)
{
	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(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;
			PBReadSync((ParmBlkPtr)&pb);
			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->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;
				if (PBSetEOFSync((ParmBlkPtr)&pb) != noErr)
					break;
			}
			if (!fp->binary)
				replace(fp->ptr, fp->cnt, '\n', '\r');
			PBWriteSync((ParmBlkPtr)&pb);
			if (!pb.ioResult && pb.ioPosOffset > fp->len)
				fp->len = pb.ioPosOffset;
			break;
			
				/*  close  */

		case 2:
			pb.ioResult = close(fp);
			break;
	}
	
		/*  done  */
		
	if (pb.ioResult) {
		if (i < 2) {
			fp->pos -= fp->cnt;
			fp->cnt = 0;
		}
		fp->err = 1;
		errno = pb.ioResult;
		return(EOF);
	}
	return(0);
}


static int
close(FILE *fp)
{
	HFileParam pb;
	Str255 buf;
	register char *fcb = FCBSPtr + fp->refnum;
	VCB *vcb = fcbVPtr(fcb);
	register char *s;
	enum { none, MFS, HFS } del = none;
	
	pb.ioVRefNum = vcb->vcbVRefNum;
	if (fp->remove) {
		pb.ioNamePtr = buf;
		pb.ioFVersNum = 0;
	
			/*  close temporary file - HFS  */
			
		if (vcb->vcbSigWord == 0x4244) {
			pb.ioDirID = fcbDirID(fcb);
			s = fcbCName(fcb);
			memcpy(buf, s, Length(s) + 1);
			del = HFS;
		}
		
			/*  close temporary file - MFS  */
			
		else if (vcb->vcbSigWord == 0xD2D7) {
			for (pb.ioFDirIndex = 1; PBGetFInfoSync((ParmBlkPtr)&pb) == noErr; pb.ioFDirIndex++) {
				if (pb.ioFRefNum == fp->refnum) {
					del = MFS;
					break;
				}
			}
		}
	}
	
		/*  close file and flush volume buffer  */
	
	pb.ioFRefNum = fp->refnum;
	if (PBCloseSync((ParmBlkPtr)&pb) == noErr) {
		if (del == MFS)
			PBDeleteSync((ParmBlkPtr)&pb);
		else if (del == HFS)
			PBHDeleteSync((HParmBlkPtr)&pb);
		pb.ioNamePtr = 0;
		PBFlushVolSync((ParmBlkPtr)&pb);
	}
	return(pb.ioResult);
}


/*
 *  replace - routine for doing CR/LF conversion
 *
 */

static void
replace(register unsigned char *s, register size_t n, register int c1, register int c2)
{
#pragma options(honor_register)
	register unsigned char *t;
	
	for (; n && (t = memchr(s, c1, n)); s = t) {
		*t++ = c2;
		n -= t - s;
	}
}

--- NEW FILE: mkapplet.py ---
"""Create an applet from a Python script.

This puts up a dialog asking for a Python source file ('TEXT').
The output is a file with the same name but its ".py" suffix dropped.
It is created by copying an applet template and then adding a 'PYC '
resource named __main__ containing the compiled, marshalled script.
"""

import sys
sys.stdout = sys.stderr

import string
import os
import marshal
import imp
import macfs
import MacOS
from Res import *

# .pyc file (and 'PYC ' resource magic number)
MAGIC = imp.get_magic()

# Template file (searched on sys.path)
TEMPLATE = "PythonApplet"

# Specification of our resource
RESTYPE = 'PYC '
RESNAME = '__main__'

# A resource with this name sets the "owner" (creator) of the destination
OWNERNAME = "owner resource"

# OpenResFile mode parameters
READ = 1
WRITE = 2

def main():
	
	# Find the template
	# (there's no point in proceeding if we can't find it)
	
	for p in sys.path:
		template = os.path.join(p, TEMPLATE)
		try:
			tmpl = open(template, "rb")
			tmpl.close()
			break
		except IOError:
			continue
	else:
		die("Template %s not found" % `template`)
		return
	
	# Ask for source text if not specified in sys.argv[1:]
	
	if not sys.argv[1:]:
		srcfss, ok = macfs.StandardGetFile('TEXT')
		if not ok:
			return
		filename = srcfss.as_pathname()
		tp, tf = os.path.split(filename)
		if tf[-3:] == '.py':
			tf = tf[:-3]
		else:
			tf = tf + '.applet'
		dstfss, ok = macfs.StandardPutFile('Save application as:', tf)
		if not ok: return
		process(template, filename, dstfss.as_pathname())
	else:
		
		# Loop over all files to be processed
		for filename in sys.argv[1:]:
			process(template, filename, '')

undefs = ('????', '    ', '\0\0\0\0', 'BINA')

def process(template, filename, output):
	
	print "Processing", `filename`, "..."
	
	# Read the source and compile it
	# (there's no point overwriting the destination if it has a syntax error)
	
	fp = open(filename)
	text = fp.read()
	fp.close()
	try:
		code = compile(text, filename, "exec")
	except (SyntaxError, EOFError):
		die("Syntax error in script %s" % `filename`)
		return
	
	# Set the destination file name
	
	if string.lower(filename[-3:]) == ".py":
		destname = filename[:-3]
		rsrcname = destname + '.rsrc'
	else:
		destname = filename + ".applet"
		rsrcname = filename + '.rsrc'
	
	if output:
		destname = output
	# Copy the data from the template (creating the file as well)
	
	tmpl = open(template, "rb")
	dest = open(destname, "wb")
	data = tmpl.read()
	if data:
		dest.write(data)
	dest.close()
	tmpl.close()
	
	# Copy the creator of the template to the destination
	# unless it already got one.  Set type to APPL
	
	tctor, ttype = MacOS.GetCreatorAndType(template)
	ctor, type = MacOS.GetCreatorAndType(destname)
	if type in undefs: type = 'APPL'
	if ctor in undefs: ctor = tctor
	
	# Open the output resource fork
	
	try:
		output = FSpOpenResFile(destname, WRITE)
	except MacOS.Error:
		print "Creating resource fork..."
		CreateResFile(destname)
		output = FSpOpenResFile(destname, WRITE)
	
	# Copy the resources from the template
	
	input = FSpOpenResFile(template, READ)
	newctor = copyres(input, output)
	CloseResFile(input)
	if newctor: ctor = newctor
	
	# Copy the resources from the target specific resource template, if any
	
	try:
		input = FSpOpenResFile(rsrcname, READ)
	except MacOS.Error:
		pass
	else:
		newctor = copyres(input, output)
		CloseResFile(input)
		if newctor: ctor = newctor
	
	# Now set the creator and type of the destination
	
	MacOS.SetCreatorAndType(destname, ctor, type)
	
	# Make sure we're manipulating the output resource file now
	
	UseResFile(output)
	
	# Delete any existing 'PYC 'resource named __main__
	
	try:
		res = Get1NamedResource(RESTYPE, RESNAME)
		res.RmveResource()
	except Error:
		pass
	
	# Create the raw data for the resource from the code object
	
	data = marshal.dumps(code)
	del code
	data = (MAGIC + '\0\0\0\0') + data
	
	# Create the resource and write it
	
	id = 0
	while id < 128:
		id = Unique1ID(RESTYPE)
	res = Resource(data)
	res.AddResource(RESTYPE, id, RESNAME)
	res.WriteResource()
	res.ReleaseResource()
	
	# Close the output file
	
	CloseResFile(output)
	
	# Give positive feedback
	
	message("Applet %s created." % `destname`)


# Copy resources between two resource file descriptors.
# Exception: don't copy a __main__ resource.
# If a resource's name is "owner resource", its type is returned
# (so the caller can use it to set the destination's creator)

def copyres(input, output):
	ctor = None
	UseResFile(input)
	ntypes = Count1Types()
	for itype in range(1, 1+ntypes):
		type = Get1IndType(itype)
		nresources = Count1Resources(type)
		for ires in range(1, 1+nresources):
			res = Get1IndResource(type, ires)
			id, type, name = res.GetResInfo()
			lcname = string.lower(name)
			if (type, lcname) == (RESTYPE, RESNAME):
				continue # Don't copy __main__ from template
			if lcname == OWNERNAME: ctor = type
			size = res.SizeResource()
			attrs = res.GetResAttrs()
			print id, type, name, size, hex(attrs)
			res.LoadResource()
			res.DetachResource()
			UseResFile(output)
			try:
				res2 = Get1Resource(type, id)
			except MacOS.Error:
				res2 = None
			if res2:
				print "Overwriting..."
				res2.RmveResource()
			res.AddResource(type, id, name)
			res.WriteResource()
			attrs = attrs | res.GetResAttrs()
			print "New attrs =", hex(attrs)
			res.SetResAttrs(attrs)
			UseResFile(input)
	return ctor


# Show a message and exit

def die(str):
	message(str)
	sys.exit(1)


# Show a message

def message(str, id = 256):
	from Dlg import *
	d = GetNewDialog(id, -1)
	if not d:
		print "Error:", `str`
		print "DLOG id =", id, "not found."
		return
	tp, h, rect = d.GetDItem(2)
	SetIText(h, str)
	while 1:
		n = ModalDialog(None)
		if n == 1: break
	del d


if __name__ == '__main__':
	main()


--- NEW FILE: mwerksglue.c ---
/*
** Glue code for MetroWerks CodeWarrior, which misses
** unix-like routines for file-access.
*/

#ifdef __MWERKS__
#include <Types.h>
#include <Files.h>
#include <Strings.h>

#include <stdio.h>
#include <errno.h>

int
fileno(fp)
	FILE *fp;
{
	if (fp==stdin) return 0;
	else if (fp==stdout) return 1;
	else if (fp==stderr) return 2;
	else return 3;
}

int
isatty(fd)
	int fd;
{
	return (fd >= 0 && fd <= 2);
}

int
unlink(old)
	char *old;
{
	OSErr err;
	
	if ((err=FSDelete(c2pstr(old), 0)) == noErr)
		return 0;
	errno= err;
	return -1;
}

#endif /* __MWERKS__ */