ยปCore Development>Code coverage>Modules/main.c

Python code coverage for Modules/main.c

#countcontent
1n/a/* Python interpreter main program */
2n/a
3n/a#include "Python.h"
4n/a#include "osdefs.h"
5n/a
6n/a#include <locale.h>
7n/a
8n/a#if defined(MS_WINDOWS) || defined(__CYGWIN__)
9n/a#include <windows.h>
10n/a#ifdef HAVE_IO_H
11n/a#include <io.h>
12n/a#endif
13n/a#ifdef HAVE_FCNTL_H
14n/a#include <fcntl.h>
15n/a#endif
16n/a#endif
17n/a
18n/a#ifdef _MSC_VER
19n/a#include <crtdbg.h>
20n/a#endif
21n/a
22n/a#if defined(MS_WINDOWS)
23n/a#define PYTHONHOMEHELP "<prefix>\\lib"
24n/a#else
25n/a#define PYTHONHOMEHELP "<prefix>/pythonX.X"
26n/a#endif
27n/a
28n/a#include "pygetopt.h"
29n/a
30n/a#define COPYRIGHT \
31n/a "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
32n/a "for more information."
33n/a
34n/a#ifdef __cplusplus
35n/aextern "C" {
36n/a#endif
37n/a
38n/a/* For Py_GetArgcArgv(); set by main() */
39n/astatic wchar_t **orig_argv;
40n/astatic int orig_argc;
41n/a
42n/a/* command line options */
43n/a#define BASE_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?"
44n/a
45n/a#define PROGRAM_OPTS BASE_OPTS
46n/a
47n/a/* Short usage message (with %s for argv0) */
48n/astatic const char usage_line[] =
49n/a"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
50n/a
51n/a/* Long usage message, split into parts < 512 bytes */
52n/astatic const char usage_1[] = "\
53n/aOptions and arguments (and corresponding environment variables):\n\
54n/a-b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\
55n/a and comparing bytes/bytearray with str. (-bb: issue errors)\n\
56n/a-B : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x\n\
57n/a-c cmd : program passed in as string (terminates option list)\n\
58n/a-d : debug output from parser; also PYTHONDEBUG=x\n\
59n/a-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
60n/a-h : print this help message and exit (also --help)\n\
61n/a";
62n/astatic const char usage_2[] = "\
63n/a-i : inspect interactively after running script; forces a prompt even\n\
64n/a if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
65n/a-I : isolate Python from the user's environment (implies -E and -s)\n\
66n/a-m mod : run library module as a script (terminates option list)\n\
67n/a-O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\
68n/a-OO : remove doc-strings in addition to the -O optimizations\n\
69n/a-q : don't print version and copyright messages on interactive startup\n\
70n/a-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
71n/a-S : don't imply 'import site' on initialization\n\
72n/a";
73n/astatic const char usage_3[] = "\
74n/a-u : unbuffered binary stdout and stderr, stdin always buffered;\n\
75n/a also PYTHONUNBUFFERED=x\n\
76n/a see man page for details on internal buffering relating to '-u'\n\
77n/a-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
78n/a can be supplied multiple times to increase verbosity\n\
79n/a-V : print the Python version number and exit (also --version)\n\
80n/a when given twice, print more information about the build\n\
81n/a-W arg : warning control; arg is action:message:category:module:lineno\n\
82n/a also PYTHONWARNINGS=arg\n\
83n/a-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
84n/a-X opt : set implementation-specific option\n\
85n/a";
86n/astatic const char usage_4[] = "\
87n/afile : program read from script file\n\
88n/a- : program read from stdin (default; interactive mode if a tty)\n\
89n/aarg ...: arguments passed to program in sys.argv[1:]\n\n\
90n/aOther environment variables:\n\
91n/aPYTHONSTARTUP: file executed on interactive startup (no default)\n\
92n/aPYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
93n/a default module search path. The result is sys.path.\n\
94n/a";
95n/astatic const char usage_5[] =
96n/a"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
97n/a" The default module search path uses %s.\n"
98n/a"PYTHONCASEOK : ignore case in 'import' statements (Windows).\n"
99n/a"PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n"
100n/a"PYTHONFAULTHANDLER: dump the Python traceback on fatal errors.\n";
101n/astatic const char usage_6[] =
102n/a"PYTHONHASHSEED: if this variable is set to 'random', a random value is used\n"
103n/a" to seed the hashes of str, bytes and datetime objects. It can also be\n"
104n/a" set to an integer in the range [0,4294967295] to get hash values with a\n"
105n/a" predictable seed.\n"
106n/a"PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n"
107n/a" on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n"
108n/a" hooks.\n";
109n/a
110n/astatic int
111n/ausage(int exitcode, const wchar_t* program)
112n/a{
113n/a FILE *f = exitcode ? stderr : stdout;
114n/a
115n/a fprintf(f, usage_line, program);
116n/a if (exitcode)
117n/a fprintf(f, "Try `python -h' for more information.\n");
118n/a else {
119n/a fputs(usage_1, f);
120n/a fputs(usage_2, f);
121n/a fputs(usage_3, f);
122n/a fprintf(f, usage_4, (wint_t)DELIM);
123n/a fprintf(f, usage_5, (wint_t)DELIM, PYTHONHOMEHELP);
124n/a fputs(usage_6, f);
125n/a }
126n/a return exitcode;
127n/a}
128n/a
129n/astatic void RunStartupFile(PyCompilerFlags *cf)
130n/a{
131n/a char *startup = Py_GETENV("PYTHONSTARTUP");
132n/a if (startup != NULL && startup[0] != '\0') {
133n/a FILE *fp = _Py_fopen(startup, "r");
134n/a if (fp != NULL) {
135n/a (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
136n/a PyErr_Clear();
137n/a fclose(fp);
138n/a } else {
139n/a int save_errno;
140n/a
141n/a save_errno = errno;
142n/a PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
143n/a errno = save_errno;
144n/a PyErr_SetFromErrnoWithFilename(PyExc_IOError,
145n/a startup);
146n/a PyErr_Print();
147n/a PyErr_Clear();
148n/a }
149n/a }
150n/a}
151n/a
152n/astatic void RunInteractiveHook(void)
153n/a{
154n/a PyObject *sys, *hook, *result;
155n/a sys = PyImport_ImportModule("sys");
156n/a if (sys == NULL)
157n/a goto error;
158n/a hook = PyObject_GetAttrString(sys, "__interactivehook__");
159n/a Py_DECREF(sys);
160n/a if (hook == NULL)
161n/a PyErr_Clear();
162n/a else {
163n/a result = _PyObject_CallNoArg(hook);
164n/a Py_DECREF(hook);
165n/a if (result == NULL)
166n/a goto error;
167n/a else
168n/a Py_DECREF(result);
169n/a }
170n/a return;
171n/a
172n/aerror:
173n/a PySys_WriteStderr("Failed calling sys.__interactivehook__\n");
174n/a PyErr_Print();
175n/a PyErr_Clear();
176n/a}
177n/a
178n/a
179n/astatic int RunModule(wchar_t *modname, int set_argv0)
180n/a{
181n/a PyObject *module, *runpy, *runmodule, *runargs, *result;
182n/a runpy = PyImport_ImportModule("runpy");
183n/a if (runpy == NULL) {
184n/a fprintf(stderr, "Could not import runpy module\n");
185n/a PyErr_Print();
186n/a return -1;
187n/a }
188n/a runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
189n/a if (runmodule == NULL) {
190n/a fprintf(stderr, "Could not access runpy._run_module_as_main\n");
191n/a PyErr_Print();
192n/a Py_DECREF(runpy);
193n/a return -1;
194n/a }
195n/a module = PyUnicode_FromWideChar(modname, wcslen(modname));
196n/a if (module == NULL) {
197n/a fprintf(stderr, "Could not convert module name to unicode\n");
198n/a PyErr_Print();
199n/a Py_DECREF(runpy);
200n/a Py_DECREF(runmodule);
201n/a return -1;
202n/a }
203n/a runargs = Py_BuildValue("(Oi)", module, set_argv0);
204n/a if (runargs == NULL) {
205n/a fprintf(stderr,
206n/a "Could not create arguments for runpy._run_module_as_main\n");
207n/a PyErr_Print();
208n/a Py_DECREF(runpy);
209n/a Py_DECREF(runmodule);
210n/a Py_DECREF(module);
211n/a return -1;
212n/a }
213n/a result = PyObject_Call(runmodule, runargs, NULL);
214n/a if (result == NULL) {
215n/a PyErr_Print();
216n/a }
217n/a Py_DECREF(runpy);
218n/a Py_DECREF(runmodule);
219n/a Py_DECREF(module);
220n/a Py_DECREF(runargs);
221n/a if (result == NULL) {
222n/a return -1;
223n/a }
224n/a Py_DECREF(result);
225n/a return 0;
226n/a}
227n/a
228n/astatic int
229n/aRunMainFromImporter(wchar_t *filename)
230n/a{
231n/a PyObject *argv0 = NULL, *importer, *sys_path, *sys_path0;
232n/a int sts;
233n/a
234n/a argv0 = PyUnicode_FromWideChar(filename, wcslen(filename));
235n/a if (argv0 == NULL)
236n/a goto error;
237n/a
238n/a importer = PyImport_GetImporter(argv0);
239n/a if (importer == NULL)
240n/a goto error;
241n/a
242n/a if (importer == Py_None) {
243n/a Py_DECREF(argv0);
244n/a Py_DECREF(importer);
245n/a return -1;
246n/a }
247n/a Py_DECREF(importer);
248n/a
249n/a /* argv0 is usable as an import source, so put it in sys.path[0]
250n/a and import __main__ */
251n/a sys_path = PySys_GetObject("path");
252n/a if (sys_path == NULL) {
253n/a PyErr_SetString(PyExc_RuntimeError, "unable to get sys.path");
254n/a goto error;
255n/a }
256n/a sys_path0 = PyList_GetItem(sys_path, 0);
257n/a sts = 0;
258n/a if (!sys_path0) {
259n/a PyErr_Clear();
260n/a sts = PyList_Append(sys_path, argv0);
261n/a } else if (PyObject_IsTrue(sys_path0)) {
262n/a sts = PyList_Insert(sys_path, 0, argv0);
263n/a } else {
264n/a sts = PyList_SetItem(sys_path, 0, argv0);
265n/a }
266n/a if (sts) {
267n/a argv0 = NULL;
268n/a goto error;
269n/a }
270n/a Py_INCREF(argv0);
271n/a
272n/a sts = RunModule(L"__main__", 0);
273n/a return sts != 0;
274n/a
275n/aerror:
276n/a Py_XDECREF(argv0);
277n/a PyErr_Print();
278n/a return 1;
279n/a}
280n/a
281n/astatic int
282n/arun_command(wchar_t *command, PyCompilerFlags *cf)
283n/a{
284n/a PyObject *unicode, *bytes;
285n/a int ret;
286n/a
287n/a unicode = PyUnicode_FromWideChar(command, -1);
288n/a if (unicode == NULL)
289n/a goto error;
290n/a bytes = PyUnicode_AsUTF8String(unicode);
291n/a Py_DECREF(unicode);
292n/a if (bytes == NULL)
293n/a goto error;
294n/a ret = PyRun_SimpleStringFlags(PyBytes_AsString(bytes), cf);
295n/a Py_DECREF(bytes);
296n/a return ret != 0;
297n/a
298n/aerror:
299n/a PySys_WriteStderr("Unable to decode the command from the command line:\n");
300n/a PyErr_Print();
301n/a return 1;
302n/a}
303n/a
304n/astatic int
305n/arun_file(FILE *fp, const wchar_t *filename, PyCompilerFlags *p_cf)
306n/a{
307n/a PyObject *unicode, *bytes = NULL;
308n/a char *filename_str;
309n/a int run;
310n/a
311n/a /* call pending calls like signal handlers (SIGINT) */
312n/a if (Py_MakePendingCalls() == -1) {
313n/a PyErr_Print();
314n/a return 1;
315n/a }
316n/a
317n/a if (filename) {
318n/a unicode = PyUnicode_FromWideChar(filename, wcslen(filename));
319n/a if (unicode != NULL) {
320n/a bytes = PyUnicode_EncodeFSDefault(unicode);
321n/a Py_DECREF(unicode);
322n/a }
323n/a if (bytes != NULL)
324n/a filename_str = PyBytes_AsString(bytes);
325n/a else {
326n/a PyErr_Clear();
327n/a filename_str = "<encoding error>";
328n/a }
329n/a }
330n/a else
331n/a filename_str = "<stdin>";
332n/a
333n/a run = PyRun_AnyFileExFlags(fp, filename_str, filename != NULL, p_cf);
334n/a Py_XDECREF(bytes);
335n/a return run != 0;
336n/a}
337n/a
338n/a
339n/a/* Main program */
340n/a
341n/aint
342n/aPy_Main(int argc, wchar_t **argv)
343n/a{
344n/a int c;
345n/a int sts;
346n/a wchar_t *command = NULL;
347n/a wchar_t *filename = NULL;
348n/a wchar_t *module = NULL;
349n/a FILE *fp = stdin;
350n/a char *p;
351n/a#ifdef MS_WINDOWS
352n/a wchar_t *wp;
353n/a#endif
354n/a int skipfirstline = 0;
355n/a int stdin_is_interactive = 0;
356n/a int help = 0;
357n/a int version = 0;
358n/a int saw_unbuffered_flag = 0;
359n/a char *opt;
360n/a PyCompilerFlags cf;
361n/a PyObject *warning_option = NULL;
362n/a PyObject *warning_options = NULL;
363n/a
364n/a cf.cf_flags = 0;
365n/a
366n/a orig_argc = argc; /* For Py_GetArgcArgv() */
367n/a orig_argv = argv;
368n/a
369n/a /* Hash randomization needed early for all string operations
370n/a (including -W and -X options). */
371n/a _PyOS_opterr = 0; /* prevent printing the error in 1st pass */
372n/a while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
373n/a if (c == 'm' || c == 'c') {
374n/a /* -c / -m is the last option: following arguments are
375n/a not interpreter options. */
376n/a break;
377n/a }
378n/a if (c == 'E') {
379n/a Py_IgnoreEnvironmentFlag++;
380n/a break;
381n/a }
382n/a }
383n/a
384n/a opt = Py_GETENV("PYTHONMALLOC");
385n/a if (_PyMem_SetupAllocators(opt) < 0) {
386n/a fprintf(stderr,
387n/a "Error in PYTHONMALLOC: unknown allocator \"%s\"!\n", opt);
388n/a exit(1);
389n/a }
390n/a
391n/a Py_HashRandomizationFlag = 1;
392n/a _PyRandom_Init();
393n/a
394n/a PySys_ResetWarnOptions();
395n/a _PyOS_ResetGetOpt();
396n/a
397n/a while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
398n/a if (c == 'c') {
399n/a size_t len;
400n/a /* -c is the last option; following arguments
401n/a that look like options are left for the
402n/a command to interpret. */
403n/a
404n/a len = wcslen(_PyOS_optarg) + 1 + 1;
405n/a command = (wchar_t *)PyMem_RawMalloc(sizeof(wchar_t) * len);
406n/a if (command == NULL)
407n/a Py_FatalError(
408n/a "not enough memory to copy -c argument");
409n/a wcscpy(command, _PyOS_optarg);
410n/a command[len - 2] = '\n';
411n/a command[len - 1] = 0;
412n/a break;
413n/a }
414n/a
415n/a if (c == 'm') {
416n/a /* -m is the last option; following arguments
417n/a that look like options are left for the
418n/a module to interpret. */
419n/a module = _PyOS_optarg;
420n/a break;
421n/a }
422n/a
423n/a switch (c) {
424n/a case 'b':
425n/a Py_BytesWarningFlag++;
426n/a break;
427n/a
428n/a case 'd':
429n/a Py_DebugFlag++;
430n/a break;
431n/a
432n/a case 'i':
433n/a Py_InspectFlag++;
434n/a Py_InteractiveFlag++;
435n/a break;
436n/a
437n/a case 'I':
438n/a Py_IsolatedFlag++;
439n/a Py_NoUserSiteDirectory++;
440n/a Py_IgnoreEnvironmentFlag++;
441n/a break;
442n/a
443n/a /* case 'J': reserved for Jython */
444n/a
445n/a case 'O':
446n/a Py_OptimizeFlag++;
447n/a break;
448n/a
449n/a case 'B':
450n/a Py_DontWriteBytecodeFlag++;
451n/a break;
452n/a
453n/a case 's':
454n/a Py_NoUserSiteDirectory++;
455n/a break;
456n/a
457n/a case 'S':
458n/a Py_NoSiteFlag++;
459n/a break;
460n/a
461n/a case 'E':
462n/a /* Already handled above */
463n/a break;
464n/a
465n/a case 't':
466n/a /* ignored for backwards compatibility */
467n/a break;
468n/a
469n/a case 'u':
470n/a Py_UnbufferedStdioFlag = 1;
471n/a saw_unbuffered_flag = 1;
472n/a break;
473n/a
474n/a case 'v':
475n/a Py_VerboseFlag++;
476n/a break;
477n/a
478n/a case 'x':
479n/a skipfirstline = 1;
480n/a break;
481n/a
482n/a case 'h':
483n/a case '?':
484n/a help++;
485n/a break;
486n/a
487n/a case 'V':
488n/a version++;
489n/a break;
490n/a
491n/a case 'W':
492n/a if (warning_options == NULL)
493n/a warning_options = PyList_New(0);
494n/a if (warning_options == NULL)
495n/a Py_FatalError("failure in handling of -W argument");
496n/a warning_option = PyUnicode_FromWideChar(_PyOS_optarg, -1);
497n/a if (warning_option == NULL)
498n/a Py_FatalError("failure in handling of -W argument");
499n/a if (PyList_Append(warning_options, warning_option) == -1)
500n/a Py_FatalError("failure in handling of -W argument");
501n/a Py_DECREF(warning_option);
502n/a break;
503n/a
504n/a case 'X':
505n/a PySys_AddXOption(_PyOS_optarg);
506n/a break;
507n/a
508n/a case 'q':
509n/a Py_QuietFlag++;
510n/a break;
511n/a
512n/a case 'R':
513n/a /* Ignored */
514n/a break;
515n/a
516n/a /* This space reserved for other options */
517n/a
518n/a default:
519n/a return usage(2, argv[0]);
520n/a /*NOTREACHED*/
521n/a
522n/a }
523n/a }
524n/a
525n/a if (help)
526n/a return usage(0, argv[0]);
527n/a
528n/a if (version) {
529n/a printf("Python %s\n", version >= 2 ? Py_GetVersion() : PY_VERSION);
530n/a return 0;
531n/a }
532n/a
533n/a if (!Py_InspectFlag &&
534n/a (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
535n/a Py_InspectFlag = 1;
536n/a if (!saw_unbuffered_flag &&
537n/a (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
538n/a Py_UnbufferedStdioFlag = 1;
539n/a
540n/a if (!Py_NoUserSiteDirectory &&
541n/a (p = Py_GETENV("PYTHONNOUSERSITE")) && *p != '\0')
542n/a Py_NoUserSiteDirectory = 1;
543n/a
544n/a#ifdef MS_WINDOWS
545n/a if (!Py_IgnoreEnvironmentFlag && (wp = _wgetenv(L"PYTHONWARNINGS")) &&
546n/a *wp != L'\0') {
547n/a wchar_t *buf, *warning, *context = NULL;
548n/a
549n/a buf = (wchar_t *)PyMem_RawMalloc((wcslen(wp) + 1) * sizeof(wchar_t));
550n/a if (buf == NULL)
551n/a Py_FatalError(
552n/a "not enough memory to copy PYTHONWARNINGS");
553n/a wcscpy(buf, wp);
554n/a for (warning = wcstok_s(buf, L",", &context);
555n/a warning != NULL;
556n/a warning = wcstok_s(NULL, L",", &context)) {
557n/a PySys_AddWarnOption(warning);
558n/a }
559n/a PyMem_RawFree(buf);
560n/a }
561n/a#else
562n/a if ((p = Py_GETENV("PYTHONWARNINGS")) && *p != '\0') {
563n/a char *buf, *oldloc;
564n/a PyObject *unicode;
565n/a
566n/a /* settle for strtok here as there's no one standard
567n/a C89 wcstok */
568n/a buf = (char *)PyMem_RawMalloc(strlen(p) + 1);
569n/a if (buf == NULL)
570n/a Py_FatalError(
571n/a "not enough memory to copy PYTHONWARNINGS");
572n/a strcpy(buf, p);
573n/a oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL));
574n/a setlocale(LC_ALL, "");
575n/a for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) {
576n/a#ifdef __APPLE__
577n/a /* Use utf-8 on Mac OS X */
578n/a unicode = PyUnicode_FromString(p);
579n/a#else
580n/a unicode = PyUnicode_DecodeLocale(p, "surrogateescape");
581n/a#endif
582n/a if (unicode == NULL) {
583n/a /* ignore errors */
584n/a PyErr_Clear();
585n/a continue;
586n/a }
587n/a PySys_AddWarnOptionUnicode(unicode);
588n/a Py_DECREF(unicode);
589n/a }
590n/a setlocale(LC_ALL, oldloc);
591n/a PyMem_RawFree(oldloc);
592n/a PyMem_RawFree(buf);
593n/a }
594n/a#endif
595n/a if (warning_options != NULL) {
596n/a Py_ssize_t i;
597n/a for (i = 0; i < PyList_GET_SIZE(warning_options); i++) {
598n/a PySys_AddWarnOptionUnicode(PyList_GET_ITEM(warning_options, i));
599n/a }
600n/a }
601n/a
602n/a if (command == NULL && module == NULL && _PyOS_optind < argc &&
603n/a wcscmp(argv[_PyOS_optind], L"-") != 0)
604n/a {
605n/a filename = argv[_PyOS_optind];
606n/a }
607n/a
608n/a stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);
609n/a
610n/a#if defined(MS_WINDOWS) || defined(__CYGWIN__)
611n/a /* don't translate newlines (\r\n <=> \n) */
612n/a _setmode(fileno(stdin), O_BINARY);
613n/a _setmode(fileno(stdout), O_BINARY);
614n/a _setmode(fileno(stderr), O_BINARY);
615n/a#endif
616n/a
617n/a if (Py_UnbufferedStdioFlag) {
618n/a#ifdef HAVE_SETVBUF
619n/a setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
620n/a setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
621n/a setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
622n/a#else /* !HAVE_SETVBUF */
623n/a setbuf(stdin, (char *)NULL);
624n/a setbuf(stdout, (char *)NULL);
625n/a setbuf(stderr, (char *)NULL);
626n/a#endif /* !HAVE_SETVBUF */
627n/a }
628n/a else if (Py_InteractiveFlag) {
629n/a#ifdef MS_WINDOWS
630n/a /* Doesn't have to have line-buffered -- use unbuffered */
631n/a /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
632n/a setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
633n/a#else /* !MS_WINDOWS */
634n/a#ifdef HAVE_SETVBUF
635n/a setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
636n/a setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
637n/a#endif /* HAVE_SETVBUF */
638n/a#endif /* !MS_WINDOWS */
639n/a /* Leave stderr alone - it should be unbuffered anyway. */
640n/a }
641n/a
642n/a#ifdef __APPLE__
643n/a /* On MacOS X, when the Python interpreter is embedded in an
644n/a application bundle, it gets executed by a bootstrapping script
645n/a that does os.execve() with an argv[0] that's different from the
646n/a actual Python executable. This is needed to keep the Finder happy,
647n/a or rather, to work around Apple's overly strict requirements of
648n/a the process name. However, we still need a usable sys.executable,
649n/a so the actual executable path is passed in an environment variable.
650n/a See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
651n/a script. */
652n/a if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') {
653n/a wchar_t* buffer;
654n/a size_t len = strlen(p) + 1;
655n/a
656n/a buffer = PyMem_RawMalloc(len * sizeof(wchar_t));
657n/a if (buffer == NULL) {
658n/a Py_FatalError(
659n/a "not enough memory to copy PYTHONEXECUTABLE");
660n/a }
661n/a
662n/a mbstowcs(buffer, p, len);
663n/a Py_SetProgramName(buffer);
664n/a /* buffer is now handed off - do not free */
665n/a } else {
666n/a#ifdef WITH_NEXT_FRAMEWORK
667n/a char* pyvenv_launcher = getenv("__PYVENV_LAUNCHER__");
668n/a
669n/a if (pyvenv_launcher && *pyvenv_launcher) {
670n/a /* Used by Mac/Tools/pythonw.c to forward
671n/a * the argv0 of the stub executable
672n/a */
673n/a wchar_t* wbuf = Py_DecodeLocale(pyvenv_launcher, NULL);
674n/a
675n/a if (wbuf == NULL) {
676n/a Py_FatalError("Cannot decode __PYVENV_LAUNCHER__");
677n/a }
678n/a Py_SetProgramName(wbuf);
679n/a
680n/a /* Don't free wbuf, the argument to Py_SetProgramName
681n/a * must remain valid until Py_FinalizeEx is called.
682n/a */
683n/a } else {
684n/a Py_SetProgramName(argv[0]);
685n/a }
686n/a#else
687n/a Py_SetProgramName(argv[0]);
688n/a#endif
689n/a }
690n/a#else
691n/a Py_SetProgramName(argv[0]);
692n/a#endif
693n/a Py_Initialize();
694n/a Py_XDECREF(warning_options);
695n/a
696n/a if (!Py_QuietFlag && (Py_VerboseFlag ||
697n/a (command == NULL && filename == NULL &&
698n/a module == NULL && stdin_is_interactive))) {
699n/a fprintf(stderr, "Python %s on %s\n",
700n/a Py_GetVersion(), Py_GetPlatform());
701n/a if (!Py_NoSiteFlag)
702n/a fprintf(stderr, "%s\n", COPYRIGHT);
703n/a }
704n/a
705n/a if (command != NULL) {
706n/a /* Backup _PyOS_optind and force sys.argv[0] = '-c' */
707n/a _PyOS_optind--;
708n/a argv[_PyOS_optind] = L"-c";
709n/a }
710n/a
711n/a if (module != NULL) {
712n/a /* Backup _PyOS_optind and force sys.argv[0] = '-m'*/
713n/a _PyOS_optind--;
714n/a argv[_PyOS_optind] = L"-m";
715n/a }
716n/a
717n/a PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
718n/a
719n/a if ((Py_InspectFlag || (command == NULL && filename == NULL && module == NULL)) &&
720n/a isatty(fileno(stdin)) &&
721n/a !Py_IsolatedFlag) {
722n/a PyObject *v;
723n/a v = PyImport_ImportModule("readline");
724n/a if (v == NULL)
725n/a PyErr_Clear();
726n/a else
727n/a Py_DECREF(v);
728n/a }
729n/a
730n/a if (command) {
731n/a sts = run_command(command, &cf);
732n/a PyMem_RawFree(command);
733n/a } else if (module) {
734n/a sts = (RunModule(module, 1) != 0);
735n/a }
736n/a else {
737n/a
738n/a if (filename == NULL && stdin_is_interactive) {
739n/a Py_InspectFlag = 0; /* do exit on SystemExit */
740n/a RunStartupFile(&cf);
741n/a RunInteractiveHook();
742n/a }
743n/a /* XXX */
744n/a
745n/a sts = -1; /* keep track of whether we've already run __main__ */
746n/a
747n/a if (filename != NULL) {
748n/a sts = RunMainFromImporter(filename);
749n/a }
750n/a
751n/a if (sts==-1 && filename!=NULL) {
752n/a fp = _Py_wfopen(filename, L"r");
753n/a if (fp == NULL) {
754n/a char *cfilename_buffer;
755n/a const char *cfilename;
756n/a int err = errno;
757n/a cfilename_buffer = Py_EncodeLocale(filename, NULL);
758n/a if (cfilename_buffer != NULL)
759n/a cfilename = cfilename_buffer;
760n/a else
761n/a cfilename = "<unprintable file name>";
762n/a fprintf(stderr, "%ls: can't open file '%s': [Errno %d] %s\n",
763n/a argv[0], cfilename, err, strerror(err));
764n/a if (cfilename_buffer)
765n/a PyMem_Free(cfilename_buffer);
766n/a return 2;
767n/a }
768n/a else if (skipfirstline) {
769n/a int ch;
770n/a /* Push back first newline so line numbers
771n/a remain the same */
772n/a while ((ch = getc(fp)) != EOF) {
773n/a if (ch == '\n') {
774n/a (void)ungetc(ch, fp);
775n/a break;
776n/a }
777n/a }
778n/a }
779n/a {
780n/a struct _Py_stat_struct sb;
781n/a if (_Py_fstat_noraise(fileno(fp), &sb) == 0 &&
782n/a S_ISDIR(sb.st_mode)) {
783n/a fprintf(stderr,
784n/a "%ls: '%ls' is a directory, cannot continue\n",
785n/a argv[0], filename);
786n/a fclose(fp);
787n/a return 1;
788n/a }
789n/a }
790n/a }
791n/a
792n/a if (sts == -1)
793n/a sts = run_file(fp, filename, &cf);
794n/a }
795n/a
796n/a /* Check this environment variable at the end, to give programs the
797n/a * opportunity to set it from Python.
798n/a */
799n/a if (!Py_InspectFlag &&
800n/a (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
801n/a {
802n/a Py_InspectFlag = 1;
803n/a }
804n/a
805n/a if (Py_InspectFlag && stdin_is_interactive &&
806n/a (filename != NULL || command != NULL || module != NULL)) {
807n/a Py_InspectFlag = 0;
808n/a RunInteractiveHook();
809n/a /* XXX */
810n/a sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
811n/a }
812n/a
813n/a if (Py_FinalizeEx() < 0) {
814n/a /* Value unlikely to be confused with a non-error exit status or
815n/a other special meaning */
816n/a sts = 120;
817n/a }
818n/a
819n/a#ifdef __INSURE__
820n/a /* Insure++ is a memory analysis tool that aids in discovering
821n/a * memory leaks and other memory problems. On Python exit, the
822n/a * interned string dictionaries are flagged as being in use at exit
823n/a * (which it is). Under normal circumstances, this is fine because
824n/a * the memory will be automatically reclaimed by the system. Under
825n/a * memory debugging, it's a huge source of useless noise, so we
826n/a * trade off slower shutdown for less distraction in the memory
827n/a * reports. -baw
828n/a */
829n/a _Py_ReleaseInternedUnicodeStrings();
830n/a#endif /* __INSURE__ */
831n/a
832n/a return sts;
833n/a}
834n/a
835n/a/* this is gonna seem *real weird*, but if you put some other code between
836n/a Py_Main() and Py_GetArgcArgv() you will need to adjust the test in the
837n/a while statement in Misc/gdbinit:ppystack */
838n/a
839n/a/* Make the *original* argc/argv available to other modules.
840n/a This is rare, but it is needed by the secureware extension. */
841n/a
842n/avoid
843n/aPy_GetArgcArgv(int *argc, wchar_t ***argv)
844n/a{
845n/a *argc = orig_argc;
846n/a *argv = orig_argv;
847n/a}
848n/a
849n/a#ifdef __cplusplus
850n/a}
851n/a#endif