33#include "Python.h"
44#include "osdefs.h"
55#include "compile.h" /* For CO_FUTURE_DIVISION */
6+ #include "import.h"
67
78#ifdef __VMS
89#include <unixlib.h>
@@ -33,7 +34,7 @@ static char **orig_argv;
3334static int orig_argc ;
3435
3536/* command line options */
36- #define BASE_OPTS "c:dEhiOQ :StuUvVW:xX"
37+ #define BASE_OPTS "c:dEhim:OQ :StuUvVW:xX"
3738
3839#ifndef RISCOS
3940#define PROGRAM_OPTS BASE_OPTS
@@ -47,7 +48,7 @@ extern int Py_RISCOSWimpFlag;
4748
4849/* Short usage message (with %s for argv0) */
4950static char * usage_line =
50- "usage: %s [option] ... [-c cmd | file | -] [arg] ...\n" ;
51+ "usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n" ;
5152
5253/* Long usage message, split into parts < 512 bytes */
5354static char * usage_1 = "\
@@ -60,15 +61,16 @@ Options and arguments (and corresponding environment variables):\n\
6061 and force prompts, even if stdin does not appear to be a terminal\n\
6162" ;
6263static char * usage_2 = "\
64+ -m mod : run library module as a script (terminates option list)\n\
6365-O : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\
6466-OO : remove doc-strings in addition to the -O optimizations\n\
6567-Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\
6668-S : don't imply 'import site' on initialization\n\
6769-t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
6870-u : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\
69- see man page for details on internal buffering relating to '-u'\n\
7071" ;
7172static char * usage_3 = "\
73+ see man page for details on internal buffering relating to '-u'\n\
7274-v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\
7375-V : print the Python version number and exit\n\
7476-W arg : warning control (arg is action:message:category:module:lineno)\n\
@@ -130,6 +132,28 @@ static void RunStartupFile(PyCompilerFlags *cf)
130132 }
131133}
132134
135+ /* Get the path to a top-level module */
136+ static struct filedescr * FindModule (const char * module ,
137+ FILE * * fp , char * * filename )
138+ {
139+ struct filedescr * fdescr = NULL ;
140+ * fp = NULL ;
141+ * filename = malloc (MAXPATHLEN );
142+
143+ if (* filename == NULL )
144+ return NULL ;
145+
146+ /* Find the actual module source code */
147+ fdescr = _PyImport_FindModule (module , NULL ,
148+ * filename , MAXPATHLEN , fp , NULL );
149+
150+ if (fdescr == NULL ) {
151+ free (* filename );
152+ * filename = NULL ;
153+ }
154+
155+ return fdescr ;
156+ }
133157
134158/* Main program */
135159
@@ -140,6 +164,7 @@ Py_Main(int argc, char **argv)
140164 int sts ;
141165 char * command = NULL ;
142166 char * filename = NULL ;
167+ char * module = NULL ;
143168 FILE * fp = stdin ;
144169 char * p ;
145170 int inspect = 0 ;
@@ -177,6 +202,18 @@ Py_Main(int argc, char **argv)
177202 break ;
178203 }
179204
205+ if (c == 'm' ) {
206+ /* -m is the last option; following arguments
207+ that look like options are left for the
208+ module to interpret. */
209+ module = malloc (strlen (_PyOS_optarg ) + 2 );
210+ if (module == NULL )
211+ Py_FatalError (
212+ "not enough memory to copy -m argument" );
213+ strcpy (module , _PyOS_optarg );
214+ break ;
215+ }
216+
180217 switch (c ) {
181218
182219 case 'd' :
@@ -289,7 +326,7 @@ Py_Main(int argc, char **argv)
289326 (p = Py_GETENV ("PYTHONUNBUFFERED" )) && * p != '\0' )
290327 unbuffered = 1 ;
291328
292- if (command == NULL && _PyOS_optind < argc &&
329+ if (command == NULL && module == NULL && _PyOS_optind < argc &&
293330 strcmp (argv [_PyOS_optind ], "-" ) != 0 )
294331 {
295332#ifdef __VMS
@@ -381,7 +418,7 @@ Py_Main(int argc, char **argv)
381418 Py_Initialize ();
382419
383420 if (Py_VerboseFlag ||
384- (command == NULL && filename == NULL && stdin_is_interactive )) {
421+ (command == NULL && filename == NULL && module == NULL && stdin_is_interactive )) {
385422 fprintf (stderr , "Python %s on %s\n" ,
386423 Py_GetVersion (), Py_GetPlatform ());
387424 if (!Py_NoSiteFlag )
@@ -394,9 +431,34 @@ Py_Main(int argc, char **argv)
394431 argv [_PyOS_optind ] = "-c" ;
395432 }
396433
434+ if (module != NULL ) {
435+ /* Backup _PyOS_optind and find the real file */
436+ struct filedescr * fdescr = NULL ;
437+ _PyOS_optind -- ;
438+ if ((fdescr = FindModule (module , & fp , & filename ))) {
439+ argv [_PyOS_optind ] = filename ;
440+ } else {
441+ fprintf (stderr , "%s: module %s not found\n" ,
442+ argv [0 ], module );
443+ return 2 ;
444+ }
445+ if (!fp ) {
446+ fprintf (stderr ,
447+ "%s: module %s has no associated file\n" ,
448+ argv [0 ], module );
449+ return 2 ;
450+ }
451+ if (!_PyImport_IsScript (fdescr )) {
452+ fprintf (stderr ,
453+ "%s: module %s not usable as script\n (%s)\n" ,
454+ argv [0 ], module , filename );
455+ return 2 ;
456+ }
457+ }
458+
397459 PySys_SetArgv (argc - _PyOS_optind , argv + _PyOS_optind );
398460
399- if ((inspect || (command == NULL && filename == NULL )) &&
461+ if ((inspect || (command == NULL && filename == NULL && module == NULL )) &&
400462 isatty (fileno (stdin ))) {
401463 PyObject * v ;
402464 v = PyImport_ImportModule ("readline" );
@@ -409,6 +471,10 @@ Py_Main(int argc, char **argv)
409471 if (command ) {
410472 sts = PyRun_SimpleStringFlags (command , & cf ) != 0 ;
411473 free (command );
474+ } else if (module ) {
475+ sts = PyRun_AnyFileExFlags (fp , filename , 1 , & cf ) != 0 ;
476+ free (module );
477+ free (filename );
412478 }
413479 else {
414480 if (filename == NULL && stdin_is_interactive ) {
@@ -431,7 +497,7 @@ Py_Main(int argc, char **argv)
431497 }
432498
433499 if (inspect && stdin_is_interactive &&
434- (filename != NULL || command != NULL ))
500+ (filename != NULL || command != NULL || module != NULL ))
435501 /* XXX */
436502 sts = PyRun_AnyFileFlags (stdin , "<stdin>" , & cf ) != 0 ;
437503
0 commit comments