Index: Include/import.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/import.h,v retrieving revision 2.29 diff -c -r2.29 import.h *** Include/import.h 29 Jul 2002 13:41:59 -0000 2.29 --- Include/import.h 6 Oct 2004 14:59:12 -0000 *************** *** 21,26 **** --- 21,29 ---- PyAPI_FUNC(void) PyImport_Cleanup(void); PyAPI_FUNC(int) PyImport_ImportFrozenModule(char *); + PyAPI_FUNC(struct filedescr *) _PyImport_FindModule( + const char *, PyObject *, char *, size_t, FILE **, PyObject **); + PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, char *); PyAPI_FUNC(PyObject *)_PyImport_FixupExtension(char *, char *); Index: Include/pythonrun.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pythonrun.h,v retrieving revision 2.64 diff -c -r2.64 pythonrun.h *** Include/pythonrun.h 19 Aug 2004 11:31:56 -0000 2.64 --- Include/pythonrun.h 6 Oct 2004 14:59:12 -0000 *************** *** 37,42 **** --- 37,44 ---- PyAPI_FUNC(int) PyRun_SimpleString(const char *); PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); + PyAPI_FUNC(int) PyRun_SimpleModule(const char *); + PyAPI_FUNC(int) PyRun_SimpleModuleFlags(const char *, PyCompilerFlags *); PyAPI_FUNC(int) PyRun_SimpleFile(FILE *, const char *); PyAPI_FUNC(int) PyRun_SimpleFileEx(FILE *, const char *, int); PyAPI_FUNC(int) PyRun_SimpleFileExFlags(FILE *, const char *, int, PyCompilerFlags *); Index: Modules/main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.83 diff -c -r1.83 main.c *** Modules/main.c 19 Aug 2004 11:07:49 -0000 1.83 --- Modules/main.c 6 Oct 2004 14:59:13 -0000 *************** *** 33,39 **** static int orig_argc; /* command line options */ ! #define BASE_OPTS "c:dEhiOQ:StuUvVW:xX" #ifndef RISCOS #define PROGRAM_OPTS BASE_OPTS --- 33,39 ---- static int orig_argc; /* command line options */ ! #define BASE_OPTS "c:dEhim:OQ:StuUvVW:xX" #ifndef RISCOS #define PROGRAM_OPTS BASE_OPTS *************** *** 47,53 **** /* Short usage message (with %s for argv0) */ static char *usage_line = ! "usage: %s [option] ... [-c cmd | file | -] [arg] ...\n"; /* Long usage message, split into parts < 512 bytes */ static char *usage_1 = "\ --- 47,53 ---- /* Short usage message (with %s for argv0) */ static char *usage_line = ! "usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n"; /* Long usage message, split into parts < 512 bytes */ static char *usage_1 = "\ *************** *** 60,74 **** and force prompts, even if stdin does not appear to be a terminal\n\ "; static char *usage_2 = "\ -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 = "\ -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\ --- 60,75 ---- 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\ "; 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,136 **** } } - /* Main program */ int --- 131,136 ---- *************** *** 140,145 **** --- 140,146 ---- int sts; char *command = NULL; char *filename = NULL; + char *module = NULL; FILE *fp = stdin; char *p; int inspect = 0; *************** *** 177,182 **** --- 178,195 ---- 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) + 1); + if (module == NULL) + Py_FatalError( + "not enough memory to copy -m argument"); + strcpy(module, _PyOS_optarg); + break; + } + switch (c) { case 'd': *************** *** 289,295 **** (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; ! if (command == NULL && _PyOS_optind < argc && strcmp(argv[_PyOS_optind], "-") != 0) { #ifdef __VMS --- 302,308 ---- (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; ! if (command == NULL && module == NULL && _PyOS_optind < argc && strcmp(argv[_PyOS_optind], "-") != 0) { #ifdef __VMS *************** *** 381,387 **** Py_Initialize(); if (Py_VerboseFlag || ! (command == NULL && filename == NULL && stdin_is_interactive)) { fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform()); if (!Py_NoSiteFlag) --- 394,400 ---- Py_Initialize(); if (Py_VerboseFlag || ! (command == NULL && filename == NULL && module == NULL && stdin_is_interactive)) { fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform()); if (!Py_NoSiteFlag) *************** *** 394,402 **** argv[_PyOS_optind] = "-c"; } PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind); ! if ((inspect || (command == NULL && filename == NULL)) && isatty(fileno(stdin))) { PyObject *v; v = PyImport_ImportModule("readline"); --- 407,421 ---- argv[_PyOS_optind] = "-c"; } + if (module != NULL) { + /* Backup _PyOS_optind and force sys.argv[0] to the module name only */ + _PyOS_optind--; + argv[_PyOS_optind] = module; + } + PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind); ! if ((inspect || (command == NULL && filename == NULL && module == NULL)) && isatty(fileno(stdin))) { PyObject *v; v = PyImport_ImportModule("readline"); *************** *** 409,415 **** if (command) { sts = PyRun_SimpleStringFlags(command, &cf) != 0; free(command); ! } else { if (filename == NULL && stdin_is_interactive) { RunStartupFile(&cf); --- 428,437 ---- if (command) { sts = PyRun_SimpleStringFlags(command, &cf) != 0; free(command); ! } else if (module) { ! sts = PyRun_SimpleModuleFlags(module, &cf) != 0; ! free(module); ! } else { if (filename == NULL && stdin_is_interactive) { RunStartupFile(&cf); *************** *** 431,437 **** } if (inspect && stdin_is_interactive && ! (filename != NULL || command != NULL)) /* XXX */ sts = PyRun_AnyFileFlags(stdin, "", &cf) != 0; --- 453,459 ---- } if (inspect && stdin_is_interactive && ! (filename != NULL || command != NULL || module != NULL)) /* XXX */ sts = PyRun_AnyFileFlags(stdin, "", &cf) != 0; Index: Python/import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.239 diff -c -r2.239 import.c *** Python/import.c 23 Sep 2004 04:37:36 -0000 2.239 --- Python/import.c 6 Oct 2004 14:59:14 -0000 *************** *** 1334,1339 **** --- 1334,1350 ---- return fdp; } + /* Helper for pythonrun.c + * Find the source file corresponding to a named module + */ + struct filedescr * + _PyImport_FindModule(const char *name, PyObject *path, char *buf, + size_t buflen, FILE **p_fp, PyObject **p_loader) + { + return find_module((char *) name, (char *) name, path, + buf, buflen, p_fp, p_loader); + } + /* case_ok(char* buf, int len, int namelen, char* name) * The arguments here are tricky, best shown by example: * /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0 Index: Python/pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.208 diff -c -r2.208 pythonrun.c *** Python/pythonrun.c 19 Aug 2004 11:31:58 -0000 2.208 --- Python/pythonrun.c 6 Oct 2004 14:59:15 -0000 *************** *** 12,17 **** --- 12,18 ---- #include "symtable.h" #include "eval.h" #include "marshal.h" + #include "osdefs.h" #include *************** *** 24,29 **** --- 25,33 ---- #undef BYTE #include "windows.h" #endif + /* importdl.h may include windows.h + - it must go after the 'fixed' windows.h include above */ + #include "importdl.h" extern char *Py_GetPath(void); *************** *** 893,898 **** --- 897,953 ---- return 0; } + int + PyRun_SimpleModule(const char *module) + { + return PyRun_SimpleModuleFlags(module, NULL); + } + + int + PyRun_SimpleModuleFlags(const char *module, PyCompilerFlags *flags) + { + FILE *fp = NULL; + struct filedescr *fdescr = NULL; + char filename[MAXPATHLEN]; + + /* Find the actual module source code */ + fdescr = _PyImport_FindModule(module, NULL, + filename, MAXPATHLEN, &fp, NULL); + + /* Clean up if we found a file we can't use */ + if (fp && fdescr && fdescr->type != PY_SOURCE && + fdescr->type != PY_COMPILED) { + fclose(fp); + fp = NULL; + } + + if (fp) { + /* We found the file - now it's business as usual */ + return PyRun_SimpleFileExFlags(fp, filename, 1, flags); + } else { + if (PyErr_Occurred()) { + PyErr_Print(); + if (Py_FlushLine()) { + PyErr_Clear(); + } + } else { + PyObject* err; + err = PySys_GetObject("stderr"); + if (fdescr) { + PyFile_WriteString( + "Non-executable module ", err); + } else { + PyFile_WriteString( + "Could not find module ", err); + } + PyFile_WriteString(module, err); + PyFile_WriteString( + " \n", err); + } + return -1; + } + } + static int parse_syntax_error(PyObject *err, PyObject **message, const char **filename, int *lineno, int *offset, const char **text)