| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | /***********************************************************
 | 
					
						
							| 
									
										
										
										
											1995-01-04 19:12:13 +00:00
										 |  |  | Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, | 
					
						
							|  |  |  | The Netherlands. | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         All Rights Reserved | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Permission to use, copy, modify, and distribute this software and its  | 
					
						
							|  |  |  | documentation for any purpose and without fee is hereby granted,  | 
					
						
							|  |  |  | provided that the above copyright notice appear in all copies and that | 
					
						
							|  |  |  | both that copyright notice and this permission notice appear in  | 
					
						
							|  |  |  | supporting documentation, and that the names of Stichting Mathematisch | 
					
						
							|  |  |  | Centrum or CWI not be used in advertising or publicity pertaining to | 
					
						
							|  |  |  | distribution of the software without specific, written prior permission. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO | 
					
						
							|  |  |  | THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | 
					
						
							|  |  |  | FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE | 
					
						
							|  |  |  | FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
					
						
							|  |  |  | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 
					
						
							|  |  |  | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | 
					
						
							|  |  |  | OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ******************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Python interpreter top-level routines, including init/exit */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "allobjects.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "grammar.h"
 | 
					
						
							|  |  |  | #include "node.h"
 | 
					
						
							|  |  |  | #include "parsetok.h"
 | 
					
						
							|  |  |  | #include "graminit.h"
 | 
					
						
							|  |  |  | #include "errcode.h"
 | 
					
						
							|  |  |  | #include "sysmodule.h"
 | 
					
						
							| 
									
										
										
										
											1995-01-09 17:53:26 +00:00
										 |  |  | #include "bltinmodule.h"
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | #include "compile.h"
 | 
					
						
							| 
									
										
										
										
											1992-08-05 19:58:53 +00:00
										 |  |  | #include "eval.h"
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | #include "ceval.h"
 | 
					
						
							|  |  |  | #include "pythonrun.h"
 | 
					
						
							|  |  |  | #include "import.h"
 | 
					
						
							| 
									
										
										
										
											1994-09-14 13:31:04 +00:00
										 |  |  | #include "marshal.h"
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #ifdef HAVE_SIGNAL_H
 | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | #include <signal.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-30 12:52:46 +00:00
										 |  |  | #ifdef THINK_C
 | 
					
						
							|  |  |  | #include <console.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-02-02 14:30:20 +00:00
										 |  |  | #ifdef __MWERKS__
 | 
					
						
							|  |  |  | #include <SIOUX.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-03-14 15:01:17 +00:00
										 |  |  | #ifdef NT
 | 
					
						
							|  |  |  | #undef BYTE
 | 
					
						
							|  |  |  | #include "windows.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | extern char *getpythonpath(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern grammar gram; /* From graminit.c */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-11-01 16:28:59 +00:00
										 |  |  | /* Forward */ | 
					
						
							| 
									
										
										
										
											1995-01-09 17:53:26 +00:00
										 |  |  | static void initmain PROTO((void)); | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | static object *run_err_node PROTO((node *n, char *filename, | 
					
						
							| 
									
										
										
										
											1993-11-01 16:28:59 +00:00
										 |  |  | 				   object *globals, object *locals)); | 
					
						
							|  |  |  | static object *run_node PROTO((node *n, char *filename, | 
					
						
							|  |  |  | 			       object *globals, object *locals)); | 
					
						
							| 
									
										
										
										
											1995-02-07 15:30:45 +00:00
										 |  |  | static object *run_pyc_file PROTO((FILE *fp, char *filename, | 
					
						
							|  |  |  | 				   object *globals, object *locals)); | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | static void err_input PROTO((perrdetail *)); | 
					
						
							| 
									
										
										
										
											1993-11-23 17:53:17 +00:00
										 |  |  | static void initsigs PROTO((void)); | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | int debugging; /* Needed by parser.c */ | 
					
						
							|  |  |  | int verbose; /* Needed by import.c */ | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | int suppress_print; /* Needed by ceval.c */ | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Initialize all */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | initall() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static int inited; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (inited) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	inited = 1; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	initimport(); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	/* Modules '__builtin__' and 'sys' are initialized here,
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	   they are needed by random bits of the interpreter. | 
					
						
							|  |  |  | 	   All other modules are optional and are initialized | 
					
						
							|  |  |  | 	   when they are first imported. */ | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	initbuiltin(); /* Also initializes builtin exceptions */ | 
					
						
							|  |  |  | 	initsys(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	setpythonpath(getpythonpath()); | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	initsigs(); /* Signal handling stuff, including initintr() */ | 
					
						
							| 
									
										
										
										
											1995-01-09 17:53:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	initmain(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Create __main__ module */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | initmain() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	object *m, *d; | 
					
						
							|  |  |  | 	m = add_module("__main__"); | 
					
						
							|  |  |  | 	if (m == NULL) | 
					
						
							|  |  |  | 		fatal("can't create __main__ module"); | 
					
						
							|  |  |  | 	d = getmoduledict(m); | 
					
						
							|  |  |  | 	if (dictlookup(d, "__builtins__") == NULL) { | 
					
						
							| 
									
										
										
										
											1995-01-12 11:37:57 +00:00
										 |  |  | 		if (dictinsert(d, "__builtins__", getbuiltins())) | 
					
						
							| 
									
										
										
										
											1995-01-09 17:53:26 +00:00
										 |  |  | 			fatal("can't add __builtins__ to __main__"); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Parse input from a file and execute it */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | run(fp, filename) | 
					
						
							|  |  |  | 	FILE *fp; | 
					
						
							|  |  |  | 	char *filename; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (filename == NULL) | 
					
						
							|  |  |  | 		filename = "???"; | 
					
						
							|  |  |  | 	if (isatty((int)fileno(fp))) | 
					
						
							|  |  |  | 		return run_tty_loop(fp, filename); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return run_script(fp, filename); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | run_tty_loop(fp, filename) | 
					
						
							|  |  |  | 	FILE *fp; | 
					
						
							|  |  |  | 	char *filename; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	object *v; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 	v = sysget("ps1"); | 
					
						
							|  |  |  | 	if (v == NULL) { | 
					
						
							|  |  |  | 		sysset("ps1", v = newstringobject(">>> ")); | 
					
						
							|  |  |  | 		XDECREF(v); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	v = sysget("ps2"); | 
					
						
							|  |  |  | 	if (v == NULL) { | 
					
						
							|  |  |  | 		sysset("ps2", v = newstringobject("... ")); | 
					
						
							|  |  |  | 		XDECREF(v); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		ret = run_tty_1(fp, filename); | 
					
						
							|  |  |  | #ifdef REF_DEBUG
 | 
					
						
							| 
									
										
										
										
											1995-03-29 16:57:48 +00:00
										 |  |  | 		fprintf(stderr, "[%ld refs]\n", _Py_RefTotal); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 		if (ret == E_EOF) | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		if (ret == E_NOMEM) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		*/ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | run_tty_1(fp, filename) | 
					
						
							|  |  |  | 	FILE *fp; | 
					
						
							|  |  |  | 	char *filename; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	object *m, *d, *v, *w; | 
					
						
							|  |  |  | 	node *n; | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	perrdetail err; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	char *ps1, *ps2; | 
					
						
							|  |  |  | 	v = sysget("ps1"); | 
					
						
							|  |  |  | 	w = sysget("ps2"); | 
					
						
							|  |  |  | 	if (v != NULL && is_stringobject(v)) { | 
					
						
							|  |  |  | 		INCREF(v); | 
					
						
							|  |  |  | 		ps1 = getstringvalue(v); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		v = NULL; | 
					
						
							|  |  |  | 		ps1 = ""; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (w != NULL && is_stringobject(w)) { | 
					
						
							|  |  |  | 		INCREF(w); | 
					
						
							|  |  |  | 		ps2 = getstringvalue(w); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		w = NULL; | 
					
						
							|  |  |  | 		ps2 = ""; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1992-08-05 19:58:53 +00:00
										 |  |  | 	BGN_SAVE | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	n = parsefile(fp, filename, &gram, single_input, ps1, ps2, &err); | 
					
						
							| 
									
										
										
										
											1992-08-05 19:58:53 +00:00
										 |  |  | 	END_SAVE | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	XDECREF(v); | 
					
						
							|  |  |  | 	XDECREF(w); | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	if (n == NULL) { | 
					
						
							|  |  |  | 		if (err.error == E_EOF) { | 
					
						
							|  |  |  | 			if (err.text) | 
					
						
							|  |  |  | 				free(err.text); | 
					
						
							|  |  |  | 			return E_EOF; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		err_input(&err); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 		print_error(); | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 		return err.error; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	m = add_module("__main__"); | 
					
						
							|  |  |  | 	if (m == NULL) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	d = getmoduledict(m); | 
					
						
							|  |  |  | 	v = run_node(n, filename, d, d); | 
					
						
							|  |  |  | 	if (v == NULL) { | 
					
						
							|  |  |  | 		print_error(); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	DECREF(v); | 
					
						
							| 
									
										
										
										
											1995-01-04 19:12:13 +00:00
										 |  |  | 	flushline(); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | run_script(fp, filename) | 
					
						
							|  |  |  | 	FILE *fp; | 
					
						
							|  |  |  | 	char *filename; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	object *m, *d, *v; | 
					
						
							| 
									
										
										
										
											1994-09-14 13:31:04 +00:00
										 |  |  | 	char *ext; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	m = add_module("__main__"); | 
					
						
							|  |  |  | 	if (m == NULL) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	d = getmoduledict(m); | 
					
						
							| 
									
										
										
										
											1994-09-14 13:31:04 +00:00
										 |  |  | 	ext = filename + strlen(filename) - 4; | 
					
						
							| 
									
										
										
										
											1995-02-13 11:44:56 +00:00
										 |  |  | #ifdef macintosh
 | 
					
						
							|  |  |  | 	/* On a mac, we also assume a pyc file for types 'PYC ' and 'APPL' */ | 
					
						
							|  |  |  | 	if ( strcmp(ext, ".pyc") == 0 || getfiletype(filename) == 'PYC ' || | 
					
						
							|  |  |  | 					getfiletype(filename) == 'APPL' ) { | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											1994-09-14 13:31:04 +00:00
										 |  |  | 	if ( strcmp(ext, ".pyc") == 0 ) { | 
					
						
							| 
									
										
										
										
											1995-02-13 11:44:56 +00:00
										 |  |  | #endif /* macintosh */
 | 
					
						
							| 
									
										
										
										
											1994-09-14 13:31:04 +00:00
										 |  |  | 		/* Try to run a pyc file. First, re-open in binary */ | 
					
						
							| 
									
										
										
										
											1994-12-14 12:58:37 +00:00
										 |  |  | 		/* Don't close, done in main: fclose(fp); */ | 
					
						
							| 
									
										
										
										
											1994-09-14 13:31:04 +00:00
										 |  |  | 		if( (fp = fopen(filename, "rb")) == NULL ) { | 
					
						
							|  |  |  | 			fprintf(stderr, "python: Can't reopen .pyc file\n"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		v = run_pyc_file(fp, filename, d, d); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		v = run_file(fp, filename, file_input, d, d); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	if (v == NULL) { | 
					
						
							|  |  |  | 		print_error(); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	DECREF(v); | 
					
						
							| 
									
										
										
										
											1995-01-04 19:12:13 +00:00
										 |  |  | 	flushline(); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | run_command(command) | 
					
						
							|  |  |  | 	char *command; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	object *m, *d, *v; | 
					
						
							|  |  |  | 	m = add_module("__main__"); | 
					
						
							|  |  |  | 	if (m == NULL) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	d = getmoduledict(m); | 
					
						
							|  |  |  | 	v = run_string(command, file_input, d, d); | 
					
						
							|  |  |  | 	if (v == NULL) { | 
					
						
							|  |  |  | 		print_error(); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	DECREF(v); | 
					
						
							| 
									
										
										
										
											1995-01-04 19:12:13 +00:00
										 |  |  | 	flushline(); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | print_error() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	object *exception, *v, *tb, *f; | 
					
						
							|  |  |  | 	err_fetch(&exception, &v, &tb); | 
					
						
							| 
									
										
										
										
											1995-01-04 19:12:13 +00:00
										 |  |  | 	flushline(); | 
					
						
							| 
									
										
										
										
											1995-03-30 11:01:44 +00:00
										 |  |  | 	fflush(stdout); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	if (exception == NULL) | 
					
						
							|  |  |  | 		fatal("print_error called but no exception"); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	if (exception == SystemExit) { | 
					
						
							|  |  |  | 		if (v == NULL || v == None) | 
					
						
							|  |  |  | 			goaway(0); | 
					
						
							|  |  |  | 		if (is_intobject(v)) | 
					
						
							|  |  |  | 			goaway((int)getintvalue(v)); | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											1992-09-25 21:59:05 +00:00
										 |  |  | 			/* OK to use real stderr here */ | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 			printobject(v, stderr, PRINT_RAW); | 
					
						
							|  |  |  | 			fprintf(stderr, "\n"); | 
					
						
							|  |  |  | 			goaway(1); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	sysset("last_type", exception); | 
					
						
							|  |  |  | 	sysset("last_value", v); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	sysset("last_traceback", tb); | 
					
						
							| 
									
										
										
										
											1992-09-25 21:59:05 +00:00
										 |  |  | 	f = sysget("stderr"); | 
					
						
							|  |  |  | 	if (f == NULL) | 
					
						
							|  |  |  | 		fprintf(stderr, "lost sys.stderr\n"); | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 		tb_print(tb, f); | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 		if (exception == SyntaxError) { | 
					
						
							|  |  |  | 			object *message; | 
					
						
							|  |  |  | 			char *filename, *text; | 
					
						
							|  |  |  | 			int lineno, offset; | 
					
						
							|  |  |  | 			if (!getargs(v, "(O(ziiz))", &message, | 
					
						
							|  |  |  | 				     &filename, &lineno, &offset, &text)) | 
					
						
							|  |  |  | 				err_clear(); | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				char buf[10]; | 
					
						
							|  |  |  | 				writestring("  File \"", f); | 
					
						
							|  |  |  | 				if (filename == NULL) | 
					
						
							|  |  |  | 					writestring("<string>", f); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					writestring(filename, f); | 
					
						
							|  |  |  | 				writestring("\", line ", f); | 
					
						
							|  |  |  | 				sprintf(buf, "%d", lineno); | 
					
						
							|  |  |  | 				writestring(buf, f); | 
					
						
							|  |  |  | 				writestring("\n", f); | 
					
						
							|  |  |  | 				if (text != NULL) { | 
					
						
							| 
									
										
										
										
											1994-09-19 08:08:50 +00:00
										 |  |  | 					char *nl; | 
					
						
							|  |  |  | 					if (offset > 0 && | 
					
						
							|  |  |  | 					    offset == strlen(text)) | 
					
						
							|  |  |  | 						offset--; | 
					
						
							|  |  |  | 					for (;;) { | 
					
						
							|  |  |  | 						nl = strchr(text, '\n'); | 
					
						
							|  |  |  | 						if (nl == NULL || | 
					
						
							|  |  |  | 						    nl-text >= offset) | 
					
						
							|  |  |  | 							break; | 
					
						
							|  |  |  | 						offset -= (nl+1-text); | 
					
						
							|  |  |  | 						text = nl+1; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 					while (*text == ' ' || *text == '\t') { | 
					
						
							|  |  |  | 						text++; | 
					
						
							|  |  |  | 						offset--; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					writestring("    ", f); | 
					
						
							|  |  |  | 					writestring(text, f); | 
					
						
							|  |  |  | 					if (*text == '\0' || | 
					
						
							|  |  |  | 					    text[strlen(text)-1] != '\n') | 
					
						
							|  |  |  | 						writestring("\n", f); | 
					
						
							|  |  |  | 					writestring("    ", f); | 
					
						
							|  |  |  | 					offset--; | 
					
						
							|  |  |  | 					while (offset > 0) { | 
					
						
							|  |  |  | 						writestring(" ", f); | 
					
						
							|  |  |  | 						offset--; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					writestring("^\n", f); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				INCREF(message); | 
					
						
							|  |  |  | 				DECREF(v); | 
					
						
							|  |  |  | 				v = message; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1995-02-07 15:30:45 +00:00
										 |  |  | 		if (is_classobject(exception)) { | 
					
						
							|  |  |  | 			object* className = ((classobject*)exception)->cl_name; | 
					
						
							|  |  |  | 			if (className == NULL) | 
					
						
							|  |  |  | 				writestring("<unknown>", f); | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				if (writeobject(className, f, PRINT_RAW) != 0) | 
					
						
							|  |  |  | 					err_clear(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if (writeobject(exception, f, PRINT_RAW) != 0) | 
					
						
							|  |  |  | 				err_clear(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1992-09-25 21:59:05 +00:00
										 |  |  | 		if (v != NULL && v != None) { | 
					
						
							|  |  |  | 			writestring(": ", f); | 
					
						
							|  |  |  | 			if (writeobject(v, f, PRINT_RAW) != 0) | 
					
						
							|  |  |  | 				err_clear(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		writestring("\n", f); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	XDECREF(exception); | 
					
						
							|  |  |  | 	XDECREF(v); | 
					
						
							| 
									
										
										
										
											1995-01-02 19:04:15 +00:00
										 |  |  | 	XDECREF(tb); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | object * | 
					
						
							|  |  |  | run_string(str, start, globals, locals) | 
					
						
							|  |  |  | 	char *str; | 
					
						
							|  |  |  | 	int start; | 
					
						
							| 
									
										
										
										
											1993-03-30 17:46:03 +00:00
										 |  |  | 	object *globals, *locals; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	return run_err_node(parse_string(str, start), | 
					
						
							|  |  |  | 			    "<string>", globals, locals); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | object * | 
					
						
							|  |  |  | run_file(fp, filename, start, globals, locals) | 
					
						
							|  |  |  | 	FILE *fp; | 
					
						
							|  |  |  | 	char *filename; | 
					
						
							|  |  |  | 	int start; | 
					
						
							| 
									
										
										
										
											1993-03-30 17:46:03 +00:00
										 |  |  | 	object *globals, *locals; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	return run_err_node(parse_file(fp, filename, start), | 
					
						
							|  |  |  | 			    filename, globals, locals); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-07-05 10:31:29 +00:00
										 |  |  | static object * | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | run_err_node(n, filename, globals, locals) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	node *n; | 
					
						
							|  |  |  | 	char *filename; | 
					
						
							| 
									
										
										
										
											1993-03-30 17:46:03 +00:00
										 |  |  | 	object *globals, *locals; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	if (n == NULL) | 
					
						
							|  |  |  | 		return  NULL; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	return run_node(n, filename, globals, locals); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-07-05 10:31:29 +00:00
										 |  |  | static object * | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | run_node(n, filename, globals, locals) | 
					
						
							|  |  |  | 	node *n; | 
					
						
							|  |  |  | 	char *filename; | 
					
						
							| 
									
										
										
										
											1993-03-30 17:46:03 +00:00
										 |  |  | 	object *globals, *locals; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	codeobject *co; | 
					
						
							|  |  |  | 	object *v; | 
					
						
							|  |  |  | 	co = compile(n, filename); | 
					
						
							|  |  |  | 	freetree(n); | 
					
						
							|  |  |  | 	if (co == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											1995-07-18 14:51:37 +00:00
										 |  |  | 	v = eval_code(co, globals, locals); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	DECREF(co); | 
					
						
							|  |  |  | 	return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-26 00:40:38 +00:00
										 |  |  | static object * | 
					
						
							| 
									
										
										
										
											1994-09-14 13:31:04 +00:00
										 |  |  | run_pyc_file(fp, filename, globals, locals) | 
					
						
							|  |  |  | 	FILE *fp; | 
					
						
							|  |  |  | 	char *filename; | 
					
						
							|  |  |  | 	object *globals, *locals; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	codeobject *co; | 
					
						
							|  |  |  | 	object *v; | 
					
						
							|  |  |  | 	long magic; | 
					
						
							|  |  |  | 	long get_pyc_magic(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	magic = rd_long(fp); | 
					
						
							|  |  |  | 	if (magic != get_pyc_magic()) { | 
					
						
							|  |  |  | 		err_setstr(RuntimeError, | 
					
						
							|  |  |  | 			   "Bad magic number in .pyc file"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	(void) rd_long(fp); | 
					
						
							|  |  |  | 	v = rd_object(fp); | 
					
						
							|  |  |  | 	fclose(fp); | 
					
						
							|  |  |  | 	if (v == NULL || !is_codeobject(v)) { | 
					
						
							|  |  |  | 		XDECREF(v); | 
					
						
							|  |  |  | 		err_setstr(RuntimeError, | 
					
						
							|  |  |  | 			   "Bad code object in .pyc file"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	co = (codeobject *)v; | 
					
						
							| 
									
										
										
										
											1995-07-18 14:51:37 +00:00
										 |  |  | 	v = eval_code(co, globals, locals); | 
					
						
							| 
									
										
										
										
											1994-09-14 13:31:04 +00:00
										 |  |  | 	DECREF(co); | 
					
						
							|  |  |  | 	return v; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-03-30 17:46:03 +00:00
										 |  |  | object * | 
					
						
							|  |  |  | compile_string(str, filename, start) | 
					
						
							|  |  |  | 	char *str; | 
					
						
							|  |  |  | 	char *filename; | 
					
						
							|  |  |  | 	int start; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	node *n; | 
					
						
							|  |  |  | 	codeobject *co; | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	n = parse_string(str, start); | 
					
						
							|  |  |  | 	if (n == NULL) | 
					
						
							| 
									
										
										
										
											1993-03-30 17:46:03 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	co = compile(n, filename); | 
					
						
							|  |  |  | 	freetree(n); | 
					
						
							|  |  |  | 	return (object *)co; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | /* Simplified interface to parsefile -- return node or set exception */ | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | node * | 
					
						
							|  |  |  | parse_file(fp, filename, start) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	FILE *fp; | 
					
						
							|  |  |  | 	char *filename; | 
					
						
							|  |  |  | 	int start; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	node *n; | 
					
						
							|  |  |  | 	perrdetail err; | 
					
						
							| 
									
										
										
										
											1992-08-05 19:58:53 +00:00
										 |  |  | 	BGN_SAVE | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	n = parsefile(fp, filename, &gram, start, | 
					
						
							|  |  |  | 				(char *)0, (char *)0, &err); | 
					
						
							| 
									
										
										
										
											1992-08-05 19:58:53 +00:00
										 |  |  | 	END_SAVE | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	if (n == NULL) | 
					
						
							|  |  |  | 		err_input(&err); | 
					
						
							|  |  |  | 	return n; | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | /* Simplified interface to parsestring -- return node or set exception */ | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | node * | 
					
						
							|  |  |  | parse_string(str, start) | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	char *str; | 
					
						
							|  |  |  | 	int start; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	node *n; | 
					
						
							|  |  |  | 	perrdetail err; | 
					
						
							|  |  |  | 	n = parsestring(str, &gram, start, &err); | 
					
						
							|  |  |  | 	if (n == NULL) | 
					
						
							|  |  |  | 		err_input(&err); | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Set the error appropriate to the given input error code (see errcode.h) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | err_input(err) | 
					
						
							|  |  |  | 	perrdetail *err; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	object *v, *w; | 
					
						
							|  |  |  | 	char *msg = NULL; | 
					
						
							|  |  |  | 	v = mkvalue("(ziiz)", err->filename, | 
					
						
							|  |  |  | 			    err->lineno, err->offset, err->text); | 
					
						
							|  |  |  | 	if (err->text != NULL) { | 
					
						
							|  |  |  | 		free(err->text); | 
					
						
							|  |  |  | 		err->text = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	switch (err->error) { | 
					
						
							|  |  |  | 	case E_SYNTAX: | 
					
						
							|  |  |  | 		msg = "invalid syntax"; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case E_TOKEN: | 
					
						
							|  |  |  | 		msg = "invalid token"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case E_INTR: | 
					
						
							|  |  |  | 		err_set(KeyboardInterrupt); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	case E_NOMEM: | 
					
						
							|  |  |  | 		err_nomem(); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	case E_EOF: | 
					
						
							|  |  |  | 		msg = "unexpected EOF while parsing"; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		fprintf(stderr, "error=%d\n", err->error); | 
					
						
							|  |  |  | 		msg = "unknown parsing error"; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	w = mkvalue("(sO)", msg, v); | 
					
						
							|  |  |  | 	XDECREF(v); | 
					
						
							|  |  |  | 	err_setval(SyntaxError, w); | 
					
						
							|  |  |  | 	XDECREF(w); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Print fatal error message and abort */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | fatal(msg) | 
					
						
							|  |  |  | 	char *msg; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1994-09-29 09:38:33 +00:00
										 |  |  | 	fprintf(stderr, "Fatal Python error: %s\n", msg); | 
					
						
							| 
									
										
										
										
											1995-01-26 00:40:38 +00:00
										 |  |  | #ifdef macintosh
 | 
					
						
							|  |  |  | 	for (;;); | 
					
						
							| 
									
										
										
										
											1995-03-14 15:01:17 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef NT
 | 
					
						
							|  |  |  | 	OutputDebugString("Fatal Python error:"); | 
					
						
							|  |  |  | 	OutputDebugString(msg); | 
					
						
							|  |  |  | 	OutputDebugString("\n"); | 
					
						
							| 
									
										
										
										
											1995-01-26 00:40:38 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	abort(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Clean up and exit */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #ifdef WITH_THREAD
 | 
					
						
							|  |  |  | #include "thread.h"
 | 
					
						
							|  |  |  | int threads_started = 0; /* Set by threadmodule.c and maybe others */ | 
					
						
							| 
									
										
										
										
											1992-08-17 08:59:08 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-09-07 14:38:28 +00:00
										 |  |  | #define NEXITFUNCS 32
 | 
					
						
							|  |  |  | static void (*exitfuncs[NEXITFUNCS])(); | 
					
						
							|  |  |  | static int nexitfuncs = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int Py_AtExit(func) | 
					
						
							|  |  |  | 	void (*func) PROTO((void)); | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (nexitfuncs >= NEXITFUNCS) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	exitfuncs[nexitfuncs++] = func; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | cleanup() | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1992-09-03 20:28:00 +00:00
										 |  |  | 	object *exitfunc = sysget("exitfunc"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (exitfunc) { | 
					
						
							|  |  |  | 		object *res; | 
					
						
							|  |  |  | 		sysset("exitfunc", (object *)NULL); | 
					
						
							| 
									
										
										
										
											1995-07-18 14:51:37 +00:00
										 |  |  | 		res = call_object(exitfunc, (object *)NULL); | 
					
						
							| 
									
										
										
										
											1992-09-03 20:28:00 +00:00
										 |  |  | 		if (res == NULL) { | 
					
						
							|  |  |  | 			fprintf(stderr, "Error in sys.exitfunc:\n"); | 
					
						
							|  |  |  | 			print_error(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	flushline(); | 
					
						
							| 
									
										
										
										
											1994-09-07 14:38:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (nexitfuncs > 0) | 
					
						
							|  |  |  | 		(*exitfuncs[--nexitfuncs])(); | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-10-11 12:54:31 +00:00
										 |  |  | #ifdef COUNT_ALLOCS
 | 
					
						
							|  |  |  | extern void dump_counts PROTO((void)); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | void | 
					
						
							|  |  |  | goaway(sts) | 
					
						
							|  |  |  | 	int sts; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	cleanup(); | 
					
						
							| 
									
										
										
										
											1992-08-05 19:58:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-10-11 12:54:31 +00:00
										 |  |  | #ifdef COUNT_ALLOCS
 | 
					
						
							|  |  |  | 	dump_counts(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #ifdef WITH_THREAD
 | 
					
						
							| 
									
										
										
										
											1992-08-05 19:58:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Other threads may still be active, so skip most of the
 | 
					
						
							|  |  |  | 	   cleanup actions usually done (these are mostly for | 
					
						
							|  |  |  | 	   debugging anyway). */ | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											1992-08-12 15:27:32 +00:00
										 |  |  | 	(void) save_thread(); | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #ifndef NO_EXIT_PROG
 | 
					
						
							| 
									
										
										
										
											1992-08-17 08:59:08 +00:00
										 |  |  | 	if (threads_started) | 
					
						
							|  |  |  | 		_exit_prog(sts); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		exit_prog(sts); | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #else /* !NO_EXIT_PROG */
 | 
					
						
							|  |  |  | 	if (threads_started) | 
					
						
							|  |  |  | 		_exit(sts); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		exit(sts); | 
					
						
							|  |  |  | #endif /* !NO_EXIT_PROG */
 | 
					
						
							| 
									
										
										
										
											1992-08-05 19:58:53 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #else /* WITH_THREAD */
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	doneimport(); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	err_clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef REF_DEBUG
 | 
					
						
							| 
									
										
										
										
											1995-03-29 16:57:48 +00:00
										 |  |  | 	fprintf(stderr, "[%ld refs]\n", _Py_RefTotal); | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef TRACE_REFS
 | 
					
						
							|  |  |  | 	if (askyesno("Print left references?")) { | 
					
						
							|  |  |  | 		printrefs(stderr); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif /* TRACE_REFS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-02-02 14:30:20 +00:00
										 |  |  | 	/* XXXX Jack thinks it would be nicer to pause if any output has
 | 
					
						
							|  |  |  | 	** been generated since the last interaction with the user... | 
					
						
							|  |  |  | 	*/ | 
					
						
							| 
									
										
										
										
											1995-01-30 12:52:46 +00:00
										 |  |  | #ifdef THINK_C
 | 
					
						
							|  |  |  | 	if (sts == 0) | 
					
						
							|  |  |  | 		console_options.pause_atexit = 0; | 
					
						
							| 
									
										
										
										
											1995-02-02 14:30:20 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef __MWERKS__
 | 
					
						
							|  |  |  | 	if (sts == 0) | 
					
						
							|  |  |  | 		SIOUXSettings.autocloseonquit = 1; | 
					
						
							| 
									
										
										
										
											1995-02-13 11:44:56 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		SIOUXSettings.showstatusline = 1; | 
					
						
							| 
									
										
										
										
											1995-01-30 12:52:46 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	exit(sts); | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #endif /* WITH_THREAD */
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 	/*NOTREACHED*/ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #ifdef HAVE_SIGNAL_H
 | 
					
						
							|  |  |  | static RETSIGTYPE | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | sighandler(sig) | 
					
						
							|  |  |  | 	int sig; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	signal(sig, SIG_DFL); /* Don't catch recursive signals */ | 
					
						
							|  |  |  | 	cleanup(); /* Do essential clean-up */ | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #ifdef HAVE_GETPID
 | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | 	kill(getpid(), sig); /* Pretend the signal killed us */ | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	exit(1); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | 	/*NOTREACHED*/ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-07-05 10:31:29 +00:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | initsigs() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	RETSIGTYPE (*t)(); | 
					
						
							|  |  |  | #ifdef HAVE_SIGNAL_H
 | 
					
						
							|  |  |  | #ifdef SIGPIPE
 | 
					
						
							|  |  |  | 	signal(SIGPIPE, SIG_IGN); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGHUP
 | 
					
						
							|  |  |  | 	t = signal(SIGHUP, SIG_IGN); | 
					
						
							|  |  |  | 	if (t == SIG_DFL) | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | 		signal(SIGHUP, sighandler); | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		signal(SIGHUP, t); | 
					
						
							|  |  |  | #endif              
 | 
					
						
							|  |  |  | #ifdef SIGTERM
 | 
					
						
							|  |  |  | 	t = signal(SIGTERM, SIG_IGN); | 
					
						
							|  |  |  | 	if (t == SIG_DFL) | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | 		signal(SIGTERM, sighandler); | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		signal(SIGTERM, t); | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #endif /* HAVE_SIGNAL_H */
 | 
					
						
							|  |  |  | 	initintr(); /* May imply initsignal() */ | 
					
						
							| 
									
										
										
										
											1992-10-18 18:53:57 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | #ifdef TRACE_REFS
 | 
					
						
							|  |  |  | /* Ask a yes/no question */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-03 20:28:00 +00:00
										 |  |  | int | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | askyesno(prompt) | 
					
						
							|  |  |  | 	char *prompt; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char buf[256]; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	printf("%s [ny] ", prompt); | 
					
						
							|  |  |  | 	if (fgets(buf, sizeof buf, stdin) == NULL) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	return buf[0] == 'y' || buf[0] == 'Y'; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1994-08-29 12:50:44 +00:00
										 |  |  | #ifdef MPW
 | 
					
						
							| 
									
										
										
										
											1992-08-04 12:41:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Check for file descriptor connected to interactive device.
 | 
					
						
							|  |  |  |    Pretend that stdin is always interactive, other files never. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | isatty(fd) | 
					
						
							|  |  |  | 	int fd; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return fd == fileno(stdin); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |