/Modules/main.c

http://unladen-swallow.googlecode.com/ · C · 718 lines · 557 code · 86 blank · 75 comment · 157 complexity · 0730bab75d2a0975589a7aee3e9c9a7b MD5 · raw file

  1. /* Python interpreter main program */
  2. #include "Python.h"
  3. #include "osdefs.h"
  4. #include "code.h" /* For CO_FUTURE_DIVISION */
  5. #include "import.h"
  6. #ifdef __VMS
  7. #include <unixlib.h>
  8. #endif
  9. #if defined(MS_WINDOWS) || defined(__CYGWIN__)
  10. #ifdef HAVE_FCNTL_H
  11. #include <fcntl.h>
  12. #endif
  13. #endif
  14. #if (defined(PYOS_OS2) && !defined(PYCC_GCC)) || defined(MS_WINDOWS)
  15. #define PYTHONHOMEHELP "<prefix>\\lib"
  16. #else
  17. #if defined(PYOS_OS2) && defined(PYCC_GCC)
  18. #define PYTHONHOMEHELP "<prefix>/Lib"
  19. #else
  20. #define PYTHONHOMEHELP "<prefix>/pythonX.X"
  21. #endif
  22. #endif
  23. #include "pygetopt.h"
  24. #define COPYRIGHT \
  25. "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
  26. "for more information."
  27. #ifdef __cplusplus
  28. extern "C" {
  29. #endif
  30. /* For Py_GetArgcArgv(); set by main() */
  31. static char **orig_argv;
  32. static int orig_argc;
  33. /* command line options */
  34. #define BASE_OPTS "3RbBc:dEg*hiX:Jm:O*Q:sStuUvVW:x?"
  35. #ifndef RISCOS
  36. #define PROGRAM_OPTS BASE_OPTS
  37. #else /*RISCOS*/
  38. /* extra option saying that we are running under a special task window
  39. frontend; especially my_readline will behave different */
  40. #define PROGRAM_OPTS BASE_OPTS "w"
  41. /* corresponding flag */
  42. extern int Py_RISCOSWimpFlag;
  43. #endif /*RISCOS*/
  44. /* Short usage message (with %s for argv0) */
  45. static char *usage_line =
  46. "usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
  47. /* Long usage message, split into parts < 512 bytes */
  48. static char *usage_1 = "\
  49. Options and arguments (and corresponding environment variables):\n\
  50. -B : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x\n\
  51. -c cmd : program passed in as string (terminates option list)\n\
  52. -d : debug output from parser; also PYTHONDEBUG=x\n\
  53. -E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
  54. -h : print this help message and exit (also --help)\n\
  55. -i : inspect interactively after running script; forces a prompt even\n\
  56. if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
  57. ";
  58. static char *usage_2 = "\
  59. -m mod : run library module as a script (terminates option list)\n\
  60. -O# : optimize generated code; also PYTHONOPTIMIZE=x\n\
  61. -Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\
  62. -s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
  63. -S : don't imply 'import site' on initialization\n\
  64. -t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
  65. ";
  66. static char *usage_3 = "\
  67. -u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\
  68. see man page for details on internal buffering relating to '-u'\n\
  69. -v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
  70. can be supplied multiple times to increase verbosity\n\
  71. -V : print the Python version number and exit (also --version)\n\
  72. -W arg : warning control; arg is action:message:category:module:lineno\n\
  73. -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
  74. -Xjit=arg : control JIT compilation: -Xjit=whenhot (default), -Xjit=never,\n\
  75. -Xjit=always.\n\
  76. ";
  77. #ifdef WITH_PY3K_WARNINGS
  78. static char *usage_4 = "\
  79. -3 : warn about Python 3.x incompatibilities that 2to3 cannot trivially fix\n";
  80. #else
  81. static char *usage_4 = "";
  82. #endif
  83. #ifdef Py_REF_DEBUG
  84. static char *usage_5 = "\
  85. -R : show refcount information after execution\n";
  86. #else
  87. static char *usage_5 = "";
  88. #endif
  89. static char *usage_6 = "\
  90. file : program read from script file\n\
  91. - : program read from stdin (default; interactive mode if a tty)\n\
  92. arg ...: arguments passed to program in sys.argv[1:]\n\n\
  93. Other environment variables:\n\
  94. PYTHONSTARTUP: file executed on interactive startup (no default)\n\
  95. PYTHONPATH : '%c'-separated list of directories prefixed to the\n\
  96. default module search path. The result is sys.path.\n\
  97. ";
  98. static char *usage_7 = "\
  99. PYTHONHOME : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\
  100. The default module search path uses %s.\n\
  101. PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\
  102. PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n\
  103. ";
  104. static int
  105. usage(int exitcode, char* program)
  106. {
  107. FILE *f = exitcode ? stderr : stdout;
  108. fprintf(f, usage_line, program);
  109. if (exitcode)
  110. fprintf(f, "Try `python -h' for more information.\n");
  111. else {
  112. /* Avoid calling fprintf() with a non-string-literal
  113. format and no other arguments, or some versions of gcc
  114. will complain. */
  115. fprintf(f, "%s", usage_1);
  116. fprintf(f, "%s", usage_2);
  117. fprintf(f, "%s", usage_3);
  118. fprintf(f, "%s", usage_4);
  119. fprintf(f, "%s", usage_5);
  120. fprintf(f, usage_6, DELIM);
  121. fprintf(f, usage_7, DELIM, PYTHONHOMEHELP);
  122. }
  123. #if defined(__VMS)
  124. if (exitcode == 0) {
  125. /* suppress 'error' message */
  126. return 1;
  127. }
  128. else {
  129. /* STS$M_INHIB_MSG + SS$_ABORT */
  130. return 0x1000002c;
  131. }
  132. #else
  133. return exitcode;
  134. #endif
  135. /*NOTREACHED*/
  136. }
  137. static void RunStartupFile(PyCompilerFlags *cf)
  138. {
  139. char *startup = Py_GETENV("PYTHONSTARTUP");
  140. if (startup != NULL && startup[0] != '\0') {
  141. FILE *fp = fopen(startup, "r");
  142. if (fp != NULL) {
  143. (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
  144. PyErr_Clear();
  145. fclose(fp);
  146. } else {
  147. int save_errno;
  148. save_errno = errno;
  149. PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
  150. errno = save_errno;
  151. PyErr_SetFromErrnoWithFilename(PyExc_IOError,
  152. startup);
  153. PyErr_Print();
  154. PyErr_Clear();
  155. }
  156. }
  157. }
  158. static int RunModule(char *module, int set_argv0)
  159. {
  160. PyObject *runpy, *runmodule, *runargs, *result;
  161. runpy = PyImport_ImportModule("runpy");
  162. if (runpy == NULL) {
  163. fprintf(stderr, "Could not import runpy module\n");
  164. return -1;
  165. }
  166. runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
  167. if (runmodule == NULL) {
  168. fprintf(stderr, "Could not access runpy._run_module_as_main\n");
  169. Py_DECREF(runpy);
  170. return -1;
  171. }
  172. runargs = Py_BuildValue("(si)", module, set_argv0);
  173. if (runargs == NULL) {
  174. fprintf(stderr,
  175. "Could not create arguments for runpy._run_module_as_main\n");
  176. Py_DECREF(runpy);
  177. Py_DECREF(runmodule);
  178. return -1;
  179. }
  180. result = PyObject_Call(runmodule, runargs, NULL);
  181. if (result == NULL) {
  182. PyErr_Print();
  183. }
  184. Py_DECREF(runpy);
  185. Py_DECREF(runmodule);
  186. Py_DECREF(runargs);
  187. if (result == NULL) {
  188. return -1;
  189. }
  190. Py_DECREF(result);
  191. return 0;
  192. }
  193. static int RunMainFromImporter(char *filename)
  194. {
  195. PyObject *argv0 = NULL, *importer = NULL;
  196. if ((argv0 = PyString_FromString(filename)) &&
  197. (importer = PyImport_GetImporter(argv0)) &&
  198. (importer->ob_type != &PyNullImporter_Type))
  199. {
  200. /* argv0 is usable as an import source, so
  201. put it in sys.path[0] and import __main__ */
  202. PyObject *sys_path = NULL;
  203. if ((sys_path = PySys_GetObject("path")) &&
  204. !PyList_SetItem(sys_path, 0, argv0))
  205. {
  206. Py_INCREF(argv0);
  207. Py_DECREF(importer);
  208. sys_path = NULL;
  209. return RunModule("__main__", 0) != 0;
  210. }
  211. }
  212. Py_XDECREF(argv0);
  213. Py_XDECREF(importer);
  214. if (PyErr_Occurred()) {
  215. PyErr_Print();
  216. return 1;
  217. }
  218. return -1;
  219. }
  220. /* Main program */
  221. int
  222. Py_Main(int argc, char **argv)
  223. {
  224. int c;
  225. int sts;
  226. char *command = NULL;
  227. char *filename = NULL;
  228. char *module = NULL;
  229. FILE *fp = stdin;
  230. char *p;
  231. int unbuffered = 0;
  232. int skipfirstline = 0;
  233. int stdin_is_interactive = 0;
  234. int help = 0;
  235. int version = 0;
  236. int saw_unbuffered_flag = 0;
  237. PyCompilerFlags cf;
  238. cf.cf_flags = 0;
  239. orig_argc = argc; /* For Py_GetArgcArgv() */
  240. orig_argv = argv;
  241. #ifdef RISCOS
  242. Py_RISCOSWimpFlag = 0;
  243. #endif
  244. PySys_ResetWarnOptions();
  245. while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
  246. if (c == 'c') {
  247. /* -c is the last option; following arguments
  248. that look like options are left for the
  249. command to interpret. */
  250. command = (char *)malloc(strlen(_PyOS_optarg) + 2);
  251. if (command == NULL)
  252. Py_FatalError(
  253. "not enough memory to copy -c argument");
  254. strcpy(command, _PyOS_optarg);
  255. strcat(command, "\n");
  256. break;
  257. }
  258. if (c == 'm') {
  259. /* -m is the last option; following arguments
  260. that look like options are left for the
  261. module to interpret. */
  262. module = (char *)malloc(strlen(_PyOS_optarg) + 2);
  263. if (module == NULL)
  264. Py_FatalError(
  265. "not enough memory to copy -m argument");
  266. strcpy(module, _PyOS_optarg);
  267. break;
  268. }
  269. switch (c) {
  270. case 'b':
  271. Py_BytesWarningFlag++;
  272. break;
  273. case 'd':
  274. Py_DebugFlag++;
  275. break;
  276. case '3':
  277. #ifdef WITH_PY3K_WARNINGS
  278. Py_Py3kWarningFlag++;
  279. if (!Py_DivisionWarningFlag)
  280. Py_DivisionWarningFlag = 1;
  281. #else
  282. Py_FatalError("Py3k warnings are disabled in this "
  283. "build of Python");
  284. #endif
  285. break;
  286. case 'R':
  287. #ifdef Py_REF_DEBUG
  288. Py_ShowRefcountFlag++;
  289. #else
  290. Py_FatalError("-R requires a debug build of Python");
  291. #endif
  292. break;
  293. case 'Q':
  294. if (strcmp(_PyOS_optarg, "old") == 0) {
  295. Py_DivisionWarningFlag = 0;
  296. break;
  297. }
  298. if (strcmp(_PyOS_optarg, "warn") == 0) {
  299. Py_DivisionWarningFlag = 1;
  300. break;
  301. }
  302. if (strcmp(_PyOS_optarg, "warnall") == 0) {
  303. Py_DivisionWarningFlag = 2;
  304. break;
  305. }
  306. if (strcmp(_PyOS_optarg, "new") == 0) {
  307. /* This only affects __main__ */
  308. cf.cf_flags |= CO_FUTURE_DIVISION;
  309. /* And this tells the eval loop to treat
  310. BINARY_DIVIDE as BINARY_TRUE_DIVIDE */
  311. _Py_QnewFlag = 1;
  312. break;
  313. }
  314. fprintf(stderr,
  315. "-Q option should be `-Qold', "
  316. "`-Qwarn', `-Qwarnall', or `-Qnew' only\n");
  317. return usage(2, argv[0]);
  318. /* NOTREACHED */
  319. case 'i':
  320. Py_InspectFlag++;
  321. Py_InteractiveFlag++;
  322. break;
  323. case 'X':
  324. #ifdef WITH_LLVM
  325. /* Support both -Xjit=never and -Xjit never is a huge
  326. hassle due to the way _PyOS_GetOpt() works. This
  327. whole system should be replaced with something more
  328. flexible. */
  329. if (strncmp(_PyOS_optarg, "jit=", 4) == 0) {
  330. int r = Py_JitControlStrToEnum(_PyOS_optarg + 4,
  331. &Py_JitControl);
  332. if (r >= 0)
  333. break; /* Success */
  334. fprintf(stderr,
  335. "-Xjit value should be `whenhot'"
  336. ", `always`, or `never', not `%s'\n",
  337. _PyOS_optarg);
  338. } else
  339. #endif /* WITH_LLVM */
  340. if (strchr(_PyOS_optarg, '=') == NULL) {
  341. fprintf(stderr,
  342. "-Xfoo flags require = to separate args"
  343. " (`-Xfoo=bar', not `-Xfoo bar')\n");
  344. } else {
  345. fprintf(stderr,
  346. "Unknown -X option: `%s'\n",
  347. _PyOS_optarg);
  348. }
  349. return usage(2, argv[0]);
  350. /* NOTREACHED */
  351. /* case 'J': reserved for Jython */
  352. case 'O':
  353. if (_PyOS_optarg[0] == '0') {
  354. Py_OptimizeFlag = 0;
  355. break;
  356. }
  357. /* \0 indicates no argument was found. */
  358. if (_PyOS_optarg[0] == '\0') {
  359. Py_OptimizeFlag = 1;
  360. break;
  361. } else if (_PyOS_optarg[1] == '\0') {
  362. if (_PyOS_optarg[0] == '1') {
  363. Py_OptimizeFlag = 1;
  364. break;
  365. }
  366. if (_PyOS_optarg[0] == '2' ||
  367. _PyOS_optarg[0] == 'O') {
  368. Py_OptimizeFlag = 2;
  369. break;
  370. }
  371. }
  372. fprintf(stderr,
  373. "-O argument should be 0, 1, or 2\n");
  374. return usage(2, argv[0]);
  375. /* NOTREACHED */
  376. case 'B':
  377. Py_DontWriteBytecodeFlag++;
  378. break;
  379. case 's':
  380. Py_NoUserSiteDirectory++;
  381. break;
  382. case 'S':
  383. Py_NoSiteFlag++;
  384. break;
  385. case 'E':
  386. Py_IgnoreEnvironmentFlag++;
  387. break;
  388. case 't':
  389. Py_TabcheckFlag++;
  390. break;
  391. case 'u':
  392. unbuffered++;
  393. saw_unbuffered_flag = 1;
  394. break;
  395. case 'v':
  396. Py_VerboseFlag++;
  397. break;
  398. #ifdef RISCOS
  399. case 'w':
  400. Py_RISCOSWimpFlag = 1;
  401. break;
  402. #endif
  403. case 'x':
  404. skipfirstline = 1;
  405. break;
  406. /* case 'X': reserved for implementation-specific arguments */
  407. case 'U':
  408. Py_UnicodeFlag++;
  409. break;
  410. case 'h':
  411. case '?':
  412. help++;
  413. break;
  414. case 'V':
  415. version++;
  416. break;
  417. case 'W':
  418. PySys_AddWarnOption(_PyOS_optarg);
  419. break;
  420. /* This space reserved for other options */
  421. default:
  422. return usage(2, argv[0]);
  423. /*NOTREACHED*/
  424. }
  425. }
  426. if (help)
  427. return usage(0, argv[0]);
  428. if (version) {
  429. fprintf(stderr, "Python %s\n", PY_VERSION);
  430. return 0;
  431. }
  432. if (!Py_InspectFlag &&
  433. (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
  434. Py_InspectFlag = 1;
  435. if (!saw_unbuffered_flag &&
  436. (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
  437. unbuffered = 1;
  438. if (!Py_NoUserSiteDirectory &&
  439. (p = Py_GETENV("PYTHONNOUSERSITE")) && *p != '\0')
  440. Py_NoUserSiteDirectory = 1;
  441. if (command == NULL && module == NULL && _PyOS_optind < argc &&
  442. strcmp(argv[_PyOS_optind], "-") != 0)
  443. {
  444. #ifdef __VMS
  445. filename = decc$translate_vms(argv[_PyOS_optind]);
  446. if (filename == (char *)0 || filename == (char *)-1)
  447. filename = argv[_PyOS_optind];
  448. #else
  449. filename = argv[_PyOS_optind];
  450. #endif
  451. }
  452. stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);
  453. if (unbuffered) {
  454. #if defined(MS_WINDOWS) || defined(__CYGWIN__)
  455. _setmode(fileno(stdin), O_BINARY);
  456. _setmode(fileno(stdout), O_BINARY);
  457. #endif
  458. #ifdef HAVE_SETVBUF
  459. setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
  460. setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
  461. setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
  462. #else /* !HAVE_SETVBUF */
  463. setbuf(stdin, (char *)NULL);
  464. setbuf(stdout, (char *)NULL);
  465. setbuf(stderr, (char *)NULL);
  466. #endif /* !HAVE_SETVBUF */
  467. }
  468. else if (Py_InteractiveFlag) {
  469. #ifdef MS_WINDOWS
  470. /* Doesn't have to have line-buffered -- use unbuffered */
  471. /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
  472. setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
  473. #else /* !MS_WINDOWS */
  474. #ifdef HAVE_SETVBUF
  475. setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
  476. setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
  477. #endif /* HAVE_SETVBUF */
  478. #endif /* !MS_WINDOWS */
  479. /* Leave stderr alone - it should be unbuffered anyway. */
  480. }
  481. #ifdef __VMS
  482. else {
  483. setvbuf (stdout, (char *)NULL, _IOLBF, BUFSIZ);
  484. }
  485. #endif /* __VMS */
  486. #ifdef __APPLE__
  487. /* On MacOS X, when the Python interpreter is embedded in an
  488. application bundle, it gets executed by a bootstrapping script
  489. that does os.execve() with an argv[0] that's different from the
  490. actual Python executable. This is needed to keep the Finder happy,
  491. or rather, to work around Apple's overly strict requirements of
  492. the process name. However, we still need a usable sys.executable,
  493. so the actual executable path is passed in an environment variable.
  494. See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
  495. script. */
  496. if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0')
  497. Py_SetProgramName(p);
  498. else
  499. Py_SetProgramName(argv[0]);
  500. #else
  501. Py_SetProgramName(argv[0]);
  502. #endif
  503. Py_Initialize();
  504. if (Py_VerboseFlag ||
  505. (command == NULL && filename == NULL && module == NULL && stdin_is_interactive)) {
  506. fprintf(stderr, "Python %s on %s\n",
  507. Py_GetVersion(), Py_GetPlatform());
  508. fprintf(stderr, "[Unladen Swallow %s]\n", UNLADEN_VERSION);
  509. if (!Py_NoSiteFlag)
  510. fprintf(stderr, "%s\n", COPYRIGHT);
  511. }
  512. if (command != NULL) {
  513. /* Backup _PyOS_optind and force sys.argv[0] = '-c' */
  514. _PyOS_optind--;
  515. argv[_PyOS_optind] = "-c";
  516. }
  517. if (module != NULL) {
  518. /* Backup _PyOS_optind and force sys.argv[0] = '-c'
  519. so that PySys_SetArgv correctly sets sys.path[0] to ''*/
  520. _PyOS_optind--;
  521. argv[_PyOS_optind] = "-c";
  522. }
  523. PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
  524. if ((Py_InspectFlag || (command == NULL && filename == NULL && module == NULL)) &&
  525. isatty(fileno(stdin))) {
  526. PyObject *v;
  527. v = PyImport_ImportModule("readline");
  528. if (v == NULL)
  529. PyErr_Clear();
  530. else
  531. Py_DECREF(v);
  532. }
  533. if (command) {
  534. sts = PyRun_SimpleStringFlags(command, &cf) != 0;
  535. free(command);
  536. } else if (module) {
  537. sts = RunModule(module, 1);
  538. free(module);
  539. }
  540. else {
  541. if (filename == NULL && stdin_is_interactive) {
  542. Py_InspectFlag = 0; /* do exit on SystemExit */
  543. RunStartupFile(&cf);
  544. }
  545. /* XXX */
  546. sts = -1; /* keep track of whether we've already run __main__ */
  547. if (filename != NULL) {
  548. sts = RunMainFromImporter(filename);
  549. }
  550. if (sts==-1 && filename!=NULL) {
  551. if ((fp = fopen(filename, "r")) == NULL) {
  552. fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",
  553. argv[0], filename, errno, strerror(errno));
  554. return 2;
  555. }
  556. else if (skipfirstline) {
  557. int ch;
  558. /* Push back first newline so line numbers
  559. remain the same */
  560. while ((ch = getc(fp)) != EOF) {
  561. if (ch == '\n') {
  562. (void)ungetc(ch, fp);
  563. break;
  564. }
  565. }
  566. }
  567. {
  568. /* XXX: does this work on Win/Win64? (see posix_fstat) */
  569. struct stat sb;
  570. if (fstat(fileno(fp), &sb) == 0 &&
  571. S_ISDIR(sb.st_mode)) {
  572. fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename);
  573. fclose(fp);
  574. return 1;
  575. }
  576. }
  577. }
  578. if (sts==-1) {
  579. sts = PyRun_AnyFileExFlags(
  580. fp,
  581. filename == NULL ? "<stdin>" : filename,
  582. filename != NULL, &cf) != 0;
  583. }
  584. }
  585. /* Check this environment variable at the end, to give programs the
  586. * opportunity to set it from Python.
  587. */
  588. if (!Py_InspectFlag &&
  589. (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
  590. {
  591. Py_InspectFlag = 1;
  592. }
  593. if (Py_InspectFlag && stdin_is_interactive &&
  594. (filename != NULL || command != NULL || module != NULL)) {
  595. Py_InspectFlag = 0;
  596. /* XXX */
  597. sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
  598. }
  599. Py_WaitForThreadShutdown();
  600. Py_Finalize();
  601. #ifdef RISCOS
  602. if (Py_RISCOSWimpFlag)
  603. fprintf(stderr, "\x0cq\x0c"); /* make frontend quit */
  604. #endif
  605. #ifdef __INSURE__
  606. /* Insure++ is a memory analysis tool that aids in discovering
  607. * memory leaks and other memory problems. On Python exit, the
  608. * interned string dictionary is flagged as being in use at exit
  609. * (which it is). Under normal circumstances, this is fine because
  610. * the memory will be automatically reclaimed by the system. Under
  611. * memory debugging, it's a huge source of useless noise, so we
  612. * trade off slower shutdown for less distraction in the memory
  613. * reports. -baw
  614. */
  615. _Py_ReleaseInternedStrings();
  616. #endif /* __INSURE__ */
  617. return sts;
  618. }
  619. /* this is gonna seem *real weird*, but if you put some other code between
  620. Py_Main() and Py_GetArgcArgv() you will need to adjust the test in the
  621. while statement in Misc/gdbinit:ppystack */
  622. /* Make the *original* argc/argv available to other modules.
  623. This is rare, but it is needed by the secureware extension. */
  624. void
  625. Py_GetArgcArgv(int *argc, char ***argv)
  626. {
  627. *argc = orig_argc;
  628. *argv = orig_argv;
  629. }
  630. #ifdef __cplusplus
  631. }
  632. #endif