[Python-checkins] python/dist/src/Modules main.c,1.83,1.84

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Thu Oct 7 08:46:28 CEST 2004


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27294/Modules

Modified Files:
	main.c 
Log Message:
SF patch #1035498:  -m option to run a module as a script
(Contributed by Nick Coghlan.)



Index: main.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -d -r1.83 -r1.84
--- main.c	19 Aug 2004 11:07:49 -0000	1.83
+++ main.c	7 Oct 2004 06:46:25 -0000	1.84
@@ -3,6 +3,7 @@
 #include "Python.h"
 #include "osdefs.h"
 #include "compile.h" /* For CO_FUTURE_DIVISION */
+#include "import.h"
 
 #ifdef __VMS
 #include <unixlib.h>
@@ -33,7 +34,7 @@
 static int  orig_argc;
 
 /* command line options */
-#define BASE_OPTS "c:dEhiOQ:StuUvVW:xX"
+#define BASE_OPTS "c:dEhim:OQ:StuUvVW:xX"
 
 #ifndef RISCOS
 #define PROGRAM_OPTS BASE_OPTS
@@ -47,7 +48,7 @@
 
 /* Short usage message (with %s for argv0) */
 static char *usage_line =
-"usage: %s [option] ... [-c cmd | file | -] [arg] ...\n";
+"usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
 
 /* Long usage message, split into parts < 512 bytes */
 static char *usage_1 = "\
@@ -60,15 +61,16 @@
          and force prompts, even if stdin does not appear to be a terminal\n\
 ";
 static char *usage_2 = "\
+-m mod : run library module as a script (terminates option list)\n\
 -O     : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\
 -OO    : remove doc-strings in addition to the -O optimizations\n\
 -Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\
 -S     : don't imply 'import site' on initialization\n\
 -t     : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
 -u     : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\
-         see man page for details on internal buffering relating to '-u'\n\
 ";
 static char *usage_3 = "\
+         see man page for details on internal buffering relating to '-u'\n\
 -v     : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\
 -V     : print the Python version number and exit\n\
 -W arg : warning control (arg is action:message:category:module:lineno)\n\
@@ -130,6 +132,28 @@
 	}
 }
 
+/* Get the path to a top-level module */
+static struct filedescr * FindModule(const char *module,
+				     FILE **fp, char **filename)
+{
+	struct filedescr *fdescr = NULL;
+	*fp = NULL;
+	*filename = malloc(MAXPATHLEN);
+
+	if (*filename == NULL)
+		return NULL;
+
+	/* Find the actual module source code */
+	fdescr = _PyImport_FindModule(module, NULL,
+					*filename, MAXPATHLEN, fp, NULL);
+
+	if (fdescr == NULL) {
+		free(*filename);
+		*filename = NULL;
+	}
+
+	return fdescr;
+}
 
 /* Main program */
 
@@ -140,6 +164,7 @@
 	int sts;
 	char *command = NULL;
 	char *filename = NULL;
+	char *module = NULL;
 	FILE *fp = stdin;
 	char *p;
 	int inspect = 0;
@@ -177,6 +202,18 @@
 			break;
 		}
 
+		if (c == 'm') {
+			/* -m is the last option; following arguments
+			   that look like options are left for the
+			   module to interpret. */
+			module = malloc(strlen(_PyOS_optarg) + 2);
+			if (module == NULL)
+				Py_FatalError(
+				   "not enough memory to copy -m argument");
+			strcpy(module, _PyOS_optarg);
+			break;
+		}
+
 		switch (c) {
 
 		case 'd':
@@ -289,7 +326,7 @@
 	    (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
 		unbuffered = 1;
 
-	if (command == NULL && _PyOS_optind < argc &&
+	if (command == NULL && module == NULL && _PyOS_optind < argc &&
 	    strcmp(argv[_PyOS_optind], "-") != 0)
 	{
 #ifdef __VMS
@@ -381,7 +418,7 @@
 	Py_Initialize();
 
 	if (Py_VerboseFlag ||
-	    (command == NULL && filename == NULL && stdin_is_interactive)) {
+	    (command == NULL && filename == NULL && module == NULL && stdin_is_interactive)) {
 		fprintf(stderr, "Python %s on %s\n",
 			Py_GetVersion(), Py_GetPlatform());
  		if (!Py_NoSiteFlag)
@@ -394,9 +431,34 @@
 		argv[_PyOS_optind] = "-c";
 	}
 
+	if (module != NULL) {
+		/* Backup _PyOS_optind and find the real file */
+                struct filedescr *fdescr = NULL;
+		_PyOS_optind--;
+		if ((fdescr = FindModule(module, &fp, &filename))) {
+			argv[_PyOS_optind] = filename;
+		} else {
+			fprintf(stderr, "%s: module %s not found\n",
+				argv[0], module);
+			return 2;
+		}
+		if (!fp) {
+			fprintf(stderr,
+				"%s: module %s has no associated file\n",
+				argv[0], module);
+			return 2;
+		}
+		if (!_PyImport_IsScript(fdescr)) {
+			fprintf(stderr,
+				"%s: module %s not usable as script\n  (%s)\n",
+				argv[0], module, filename);
+			return 2;
+		}
+	}
+
 	PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
 
-	if ((inspect || (command == NULL && filename == NULL)) &&
+	if ((inspect || (command == NULL && filename == NULL && module == NULL)) &&
 	    isatty(fileno(stdin))) {
 		PyObject *v;
 		v = PyImport_ImportModule("readline");
@@ -409,6 +471,10 @@
 	if (command) {
 		sts = PyRun_SimpleStringFlags(command, &cf) != 0;
 		free(command);
+	} else if (module) {
+		sts = PyRun_AnyFileExFlags(fp, filename, 1, &cf) != 0;
+		free(module);
+		free(filename);
 	}
 	else {
 		if (filename == NULL && stdin_is_interactive) {
@@ -431,7 +497,7 @@
 	}
 
 	if (inspect && stdin_is_interactive &&
-	    (filename != NULL || command != NULL))
+	    (filename != NULL || command != NULL || module != NULL))
 		/* XXX */
 		sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
 



More information about the Python-checkins mailing list