summaryrefslogtreecommitdiffstats
path: root/Mac/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Mac/Python')
-rw-r--r--Mac/Python/macmain.c340
1 files changed, 252 insertions, 88 deletions
diff --git a/Mac/Python/macmain.c b/Mac/Python/macmain.c
index c32365e..dea2261 100644
--- a/Mac/Python/macmain.c
+++ b/Mac/Python/macmain.c
@@ -22,36 +22,119 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
******************************************************************/
-/* Macintosh Python main program */
+/* Python interpreter main program */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "Python.h"
+#include "pythonresources.h"
+#include "import.h"
+#include "marshal.h"
-#include "rename2.h"
-#include "mymalloc.h"
+#include <Memory.h>
+#include <Resources.h>
+#include <stdio.h>
+#include <Events.h>
+#include <Windows.h>
+#include <Desk.h>
-#ifdef THINK_C
-#define CONSOLE_IO
+#ifdef __MWERKS__
+#include <SIOUX.h>
#endif
-#include <stdio.h>
-#include <string.h>
+#define STARTUP "PythonStartup"
-#ifdef CONSOLE_IO
-#include <console.h>
-#endif
+extern int Py_DebugFlag; /* For parser.c, declared in pythonrun.c */
+extern int Py_VerboseFlag; /* For import.c, declared in pythonrun.c */
+extern int Py_SuppressPrintingFlag; /* For ceval.c, declared in pythonrun.c */
+
+
+/* Subroutines that live in their own file */
+extern char *getversion();
+extern char *getcopyright();
+
+
+/* For getprogramname(); set by main() */
+static char *argv0;
+/* For getargcargv(); set by main() */
+static char **orig_argv;
+static int orig_argc;
+
+#ifdef USE_MAC_APPLET_SUPPORT
+/* Applet support */
+
+/* Run a compiled Python Python script from 'PYC ' resource __main__ */
+static int
+run_main_resource()
+{
+ Handle h;
+ long size;
+ PyObject *code;
+ PyObject *result;
+
+ h = GetNamedResource('PYC ', "\p__main__");
+ if (h == NULL) {
+ Alert(NOPYC_ALERT, NULL);
+ return 1;
+ }
+ size = GetResourceSizeOnDisk(h);
+ HLock(h);
+ code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
+ HUnlock(h);
+ ReleaseResource(h);
+ if (code == NULL) {
+ PyErr_Print();
+ return 1;
+ }
+ result = PyImport_ExecCodeModule("__main__", code);
+ Py_DECREF(code);
+ if (result == NULL) {
+ PyErr_Print();
+ return 1;
+ }
+ Py_DECREF(result);
+ return 0;
+}
+
+/* Initialization sequence for applets */
+void
+PyMac_InitApplet()
+{
+ int argc;
+ char **argv;
+ int err;
+
+#ifdef USE_MAC_SHARED_LIBRARY
+ PyMac_AddLibResources();
+#endif
#ifdef __MWERKS__
-#include <SIOUX.h>
+ SIOUXSettings.asktosaveonclose = 0;
+ SIOUXSettings.showstatusline = 0;
+ SIOUXSettings.tabspaces = 4;
#endif
+ argc = PyMac_GetArgv(&argv);
+ Py_Initialize();
+ PySys_SetArgv(argc, argv);
+ err = run_main_resource();
+ fflush(stderr);
+ fflush(stdout);
+#ifdef __MWERKS__
+ if (!err)
+ SIOUXSettings.autocloseonquit = 1;
+ else
+ printf("\n[Terminated]\n");
+#endif
+ /* XXX Should we bother to Py_Exit(sts)? */
+}
-extern char *fileargument;
+#endif /* USE_MAC_APPLET_SUPPORT */
-main(argc, argv)
+/* For normal application */
+void
+PyMac_InitApplication()
+{
int argc;
char **argv;
-{
+
#ifdef USE_MAC_SHARED_LIBRARY
PyMac_AddLibResources();
#endif
@@ -60,84 +143,165 @@ main(argc, argv)
SIOUXSettings.showstatusline = 0;
SIOUXSettings.tabspaces = 4;
#endif
-#ifdef USE_STDWIN
-#ifdef THINK_C
- /* This is done to initialize the Think console I/O library before stdwin.
- If we don't do this, the console I/O library will only be usable for
- output, and the interactive version of the interpreter will quit
- immediately because it sees an EOF from stdin.
- The disadvantage is that when using STDWIN, your stdwin menus will
- appear next to the console I/O's File and Edit menus, and you will have
- an empty console window in your application (though it can be removed
- by clever use of console library I believe).
- Remove this line if you want to be able to double-click Python scripts
- that use STDWIN and never use stdin for input.
- (A more dynamic solution may be possible e.g. based on bits in the
- SIZE resource or whatever... Have fun, and let me know if you find
- a better way!) */
- printf("\n");
-#endif
-#ifdef BUILD_APPLET_TEMPLATE
- /* Make argv[0] and [1] be application name. The "argument" will later
- ** be recognized as APPL type and interpreted as being a .pyc file.
- ** XXXX Should be changed. Argv[0] should be the shared lib location or
- ** something, so we can find our Lib directory, etc.
- */
- {
- char *progname;
- extern char *getappname();
+ argc = PyMac_GetArgv(&argv);
+ if ( argc > 1 ) {
+ /* We're running a script. Attempt to change current directory */
+ char curwd[256], *endp;
- progname = getappname();
- if ( (argv = (char **)malloc(3*sizeof(char *))) == NULL ) {
- fprintf(stderr, "No memory\n");
- exit(1);
+ strcpy(curwd, argv[1]);
+ endp = strrchr(curwd, ':');
+ if ( endp && endp > curwd ) {
+ *endp = '\0';
+
+ chdir(curwd);
}
- argv[0] = malloc(strlen(progname)+1);
- argv[1] = malloc(strlen(progname)+1);
- argv[2] = NULL;
- if ( argv[0] == NULL || argv[1] == NULL ) {
- fprintf(stderr, "No memory\n");
- exit(1);
+ }
+ Py_Main(argc, argv);
+}
+
+/*
+** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
+*/
+void
+PyMac_InteractiveOptions(int *inspect, int *verbose, int *suppress_print,
+ int *unbuffered, int *debugging)
+{
+ KeyMap rmap;
+ unsigned char *map;
+ short item, type;
+ ControlHandle handle;
+ DialogPtr dialog;
+ Rect rect;
+
+ GetKeys(rmap);
+ map = (unsigned char *)rmap;
+ if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
+ return;
+
+ dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
+ if ( dialog == NULL ) {
+ printf("Option dialog not found - cannot set options\n");
+ return;
+ }
+ while (1) {
+ handle = NULL;
+ ModalDialog(NULL, &item);
+ if ( item == OPT_OK )
+ break;
+ if ( item == OPT_CANCEL ) {
+ DisposDialog(dialog);
+ exit(0);
+ }
+#define OPT_ITEM(num, var) \
+ if ( item == (num) ) { \
+ *(var) = !*(var); \
+ GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
+ SetCtlValue(handle, (short)*(var)); \
}
- strcpy(argv[0], progname);
- strcpy(argv[1], progname);
- argc = 2;
+
+ OPT_ITEM(OPT_INSPECT, inspect);
+ OPT_ITEM(OPT_VERBOSE, verbose);
+ OPT_ITEM(OPT_SUPPRESS, suppress_print);
+ OPT_ITEM(OPT_UNBUFFERED, unbuffered);
+ OPT_ITEM(OPT_DEBUGGING, debugging);
+
+#undef OPT_ITEM
}
+ DisposDialog(dialog);
+}
+/* Main program */
+
+int
+Py_Main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int sts;
+ char *command = NULL;
+ char *filename = NULL;
+ FILE *fp = stdin;
+ char *p;
+ int inspect = 0;
+ int unbuffered = 0;
+
+ orig_argc = argc; /* For getargcargv() */
+ orig_argv = argv;
+ argv0 = argv[0]; /* For getprogramname() */
+
+ PyMac_InteractiveOptions(&inspect, &Py_VerboseFlag, &Py_SuppressPrintingFlag,
+ &unbuffered, &Py_DebugFlag);
+
+
+ if (unbuffered) {
+#ifndef MPW
+ setbuf(stdout, (char *)NULL);
+ setbuf(stderr, (char *)NULL);
#else
- /* Use STDWIN's wargs() to set argc/argv to list of files to open */
- wargs(&argc, &argv);
+ /* On MPW (3.2) unbuffered seems to hang */
+ setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
+ setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
#endif
- /* Put About Python... in Apple menu */
- {
- extern char *about_message;
- extern char *about_item;
- extern char *getversion(), *getcopyright();
- static char buf[1024];
- sprintf(buf, "Python %s\r\
-\r\
-%s\r\
-\r\
-Author: Guido van Rossum <guido@cwi.nl>\r\
-FTP: host ftp.cwi.nl, directory pub/python\r\
-Newsgroup: comp.lang.python\r\
-\r\
-Motto: \"Nobody expects the Spanish Inquisition!\"",
+ }
+
+ filename = argv[1];
+
+ if (Py_VerboseFlag ||
+ command == NULL && filename == NULL && isatty((int)fileno(fp)))
+ fprintf(stderr, "Python %s\n%s\n",
getversion(), getcopyright());
- about_message = buf;
- about_item = "About Python...";
+
+ if (filename != NULL) {
+ if ((fp = fopen(filename, "r")) == NULL) {
+ fprintf(stderr, "%s: can't open file '%s'\n",
+ argv[0], filename);
+ exit(2);
+ }
}
-#endif /* USE_STDWIN */
-#ifdef CONSOLE_IO
- if (argc >= 1 && argv[0][0] != '\0') {
- static char buf[256];
- buf[0] = strlen(argv[0]);
- strncpy(buf+1, argv[0], buf[0]);
- console_options.title = (unsigned char *)buf;
+
+ Py_Initialize();
+
+ PySys_SetArgv(argc-1, argv+1);
+
+ if (filename == NULL && isatty((int)fileno(fp))) {
+ FILE *fp = fopen(STARTUP, "r");
+ if (fp != NULL) {
+ (void) PyRun_SimpleFile(fp, STARTUP);
+ PyErr_Clear();
+ fclose(fp);
+ }
}
- else
- console_options.title = "\pPython";
-#endif /* CONSOLE_IO */
- if ( argc > 1 )
- fileargument = argv[1]; /* Mod by Jack to do chdir */
- realmain(argc, argv);
+ sts = PyRun_AnyFile(
+ fp, filename == NULL ? "<stdin>" : filename) != 0;
+ if (filename != NULL)
+ fclose(fp);
+
+ if (inspect && isatty((int)fileno(stdin)) &&
+ (filename != NULL || command != NULL))
+ sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
+
+ Py_Exit(sts);
+ /*NOTREACHED*/
+}
+
+
+/* Return the program name -- some code out there needs this. */
+
+char *
+getprogramname()
+{
+ return argv0;
+}
+
+
+/* Make the *original* argc/argv available to other modules.
+ This is rare, but it is needed by the secureware extension. */
+
+void
+getargcargv(argc,argv)
+ int *argc;
+ char ***argv;
+{
+ *argc = orig_argc;
+ *argv = orig_argv;
}