home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Modules / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  10.3 KB  |  462 lines

  1. /* Python interpreter main program */
  2.  
  3. #include "Python.h"
  4. #include "osdefs.h"
  5.  
  6. #ifdef HAVE_UNISTD_H
  7. #include <unistd.h>
  8. #endif
  9.  
  10. #ifdef MS_WINDOWS
  11. #include <fcntl.h>
  12. #endif
  13.  
  14. #if defined(PYOS_OS2) || defined(MS_WINDOWS)
  15. #define PYTHONHOMEHELP "<prefix>\\lib"
  16. #else
  17. #define PYTHONHOMEHELP "<prefix>/python2.0"
  18. #endif
  19.  
  20. #define COPYRIGHT \
  21.     "Type \"copyright\", \"credits\" or \"license\" for more information."
  22.  
  23. /* Interface to getopt(): */
  24. extern int optind;
  25. extern char *optarg;
  26. extern int getopt(); /* PROTO((int, char **, char *)); -- not standardized */
  27.  
  28.  
  29. /* For Py_GetArgcArgv(); set by main() */
  30. static char **orig_argv;
  31. static int  orig_argc;
  32.  
  33. /* Short usage message (with %s for argv0) */
  34. static char *usage_line =
  35. "usage: %s [option] ... [-c cmd | file | -] [arg] ...\n";
  36.  
  37. /* Long usage message, split into parts < 512 bytes */
  38. static char *usage_top = "\
  39. Options and arguments (and corresponding environment variables):\n\
  40. -d     : debug output from parser (also PYTHONDEBUG=x)\n\
  41. -i     : inspect interactively after running script, (also PYTHONINSPECT=x)\n\
  42.          and force prompts, even if stdin does not appear to be a terminal\n\
  43. -O     : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\
  44. -OO    : remove doc-strings in addition to the -O optimizations\n\
  45. -S     : don't imply 'import site' on initialization\n\
  46. -t     : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
  47. ";
  48. static char *usage_mid = "\
  49. -u     : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\
  50. -U     : Unicode literals: treats '...' literals like u'...'\n\
  51. -v     : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\
  52. -x     : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
  53. -h     : print this help message and exit\n\
  54. -V     : print the Python version number and exit\n\
  55. -c cmd : program passed in as string (terminates option list)\n\
  56. file   : program read from script file\n\
  57. -      : program read from stdin (default; interactive mode if a tty)\n\
  58. ";
  59. static char *usage_bot = "\
  60. arg ...: arguments passed to program in sys.argv[1:]\n\
  61. Other environment variables:\n\
  62. PYTHONSTARTUP: file executed on interactive startup (no default)\n\
  63. PYTHONPATH   : '%c'-separated list of directories prefixed to the\n\
  64.                default module search path.  The result is sys.path.\n\
  65. PYTHONHOME   : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\
  66.                The default module search path uses %s.\n\
  67. ";
  68.  
  69.  
  70. static void
  71. usage(int exitcode, char* program)
  72. {
  73.     fprintf(stderr, usage_line, program);
  74.     fprintf(stderr, usage_top);
  75.     fprintf(stderr, usage_mid);
  76.     fprintf(stderr, usage_bot, DELIM, DELIM, PYTHONHOMEHELP);
  77. #ifdef _AMIGA
  78.             fprintf(stderr,"Python and Python programs can also be started from the Workbench,\ntooltypes will be converted to command-line arguments.\n");
  79. #endif
  80.     exit(exitcode);
  81.     /*NOTREACHED*/
  82. }
  83.  
  84.  
  85. #ifdef __SASC
  86. extern char __stdiowin[] = "CON:0/12/640/200/Python";
  87. extern char __stdiov37[] = "/AUTO";
  88. #endif
  89.  
  90. #ifdef _AMIGA
  91. #include <proto/dos.h>
  92. #include <proto/exec.h>
  93. #endif /* AMIGA */
  94.  
  95. #ifdef INET225
  96. #include <proto/socket.h>
  97.  
  98. struct Library *SockBase = NULL;
  99.  
  100. int checksocketlib(void)
  101. {
  102.     if(!SockBase)
  103.     {
  104.         if(SockBase=OpenLibrary("inet:libs/socket.library",4))
  105.         {
  106.             setup_sockets(FD_SETSIZE, &errno);
  107.         }
  108.         else
  109.         {
  110.             PyErr_SetString(PyExc_SystemError, "Couldn't open inet:libs/socket.library V4+ (I-Net225 started?)");
  111.             return 0;
  112.         }
  113.     }
  114.     return 1;
  115. }
  116.  
  117. int checkusergrouplib(void)
  118. {
  119.     return checksocketlib();
  120. }
  121.  
  122. #endif /* INET225 */
  123.  
  124. #ifdef AMITCP
  125. #include <proto/socket.h>
  126. #include <amitcp/socketbasetags.h>
  127.  
  128. /* proto for special AmiTCP utility funcion; see _chkufb.c */
  129. extern long _install_AmiTCP_callback(void);
  130.  
  131.  
  132. /* global h_errno */
  133. int h_errno = 0;
  134.  
  135. struct Library *UserGroupBase = NULL;
  136. struct Library *SocketBase = NULL;
  137.  
  138. int checkusergrouplib(void)
  139. {
  140.     if(!UserGroupBase)
  141.     {
  142.         if(!(UserGroupBase=OpenLibrary("usergroup.library",4)))
  143.         {
  144.             PyErr_SetString(PyExc_SystemError, "Couldn't open usergroup.library");
  145.             return 0;
  146.         }
  147.     }
  148.     return 1;
  149. }
  150.  
  151. int checksocketlib(void)
  152. {
  153.     if(!SocketBase)
  154.     {
  155.         if(SocketBase=OpenLibrary("bsdsocket.library",4))
  156.         {
  157.             /*
  158.              * Succesfull. Now tell bsdsocket.library:
  159.              * - the address of our errno
  160.              * - the address of our h_errno
  161.              * - our program name
  162.              */
  163.             SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), &errno,
  164.                            SBTM_SETVAL(SBTC_HERRNOLONGPTR), &h_errno,
  165.                            SBTM_SETVAL(SBTC_LOGTAGPTR), "Python",
  166.                            TAG_END);
  167.         }
  168.         else
  169.         {
  170.             PyErr_SetString(PyExc_SystemError, "Couldn't open bsdsocket.library (start AmiTCP)");
  171.             return 0;
  172.         }
  173.     }
  174.     return 1;
  175. }
  176.  
  177. #endif
  178.  
  179. #ifdef _AMIGA
  180. BOOL from_WB = FALSE;    /* not static! getpath.c needs it! */
  181. static void AmigaCleanup(void)
  182. {
  183. #ifdef AMITCP
  184.     if(UserGroupBase)
  185.     {
  186.         CloseLibrary(UserGroupBase);
  187.         UserGroupBase=NULL;
  188.     }
  189.     if(SocketBase)
  190.     {
  191.         CloseLibrary(SocketBase);
  192.         SocketBase=NULL;
  193.     }
  194. #endif
  195. #ifdef INET225
  196.     if(SockBase)
  197.     {
  198.         cleanup_sockets();
  199.         CloseLibrary(SockBase);
  200.         SockBase = NULL;
  201.     }
  202. #endif
  203.     if(from_WB) Delay(112); // small exit delay before closing WB window
  204. }
  205. #endif
  206.  
  207.  
  208. /* Main program */
  209.  
  210. DL_EXPORT(int)
  211. Py_Main(int argc, char **argv)
  212. {
  213.     int c;
  214.     int sts;
  215.     char *command = NULL;
  216.     char *filename = NULL;
  217.     FILE *fp = stdin;
  218.     char *p;
  219.     int inspect = 0;
  220.     int unbuffered = 0;
  221.     int skipfirstline = 0;
  222.     int stdin_is_interactive = 0;
  223.     int help = 0;
  224.     int version = 0;
  225.  
  226. #ifdef _AMIGA
  227.     if(argc == 0)
  228.     {
  229.         /* Invoked from WorkBench... use WorkBench arguments  */
  230.         /* Make sure <dos.h> was included earlier in order to */
  231.         /* declare _WBArgc and _WBArgv.                       */
  232.         argc = _WBArgc;
  233.         argv = _WBArgv;
  234.         from_WB = TRUE;
  235.     }
  236.  
  237.     atexit(AmigaCleanup);   /* cleanup func */
  238. //  setbuf(stderr,NULL);    /* set error output UNBUFFERED */
  239.  
  240. #endif
  241.  
  242.     orig_argc = argc;    /* For Py_GetArgcArgv() */
  243.     orig_argv = argv;
  244.  
  245.     if ((p = getenv("PYTHONINSPECT")) && *p != '\0')
  246.         inspect = 1;
  247.     if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0')
  248.         unbuffered = 1;
  249.  
  250.     while ((c = getopt(argc, argv, "c:diOStuUvxXhV")) != EOF) {
  251.         if (c == 'c') {
  252.             /* -c is the last option; following arguments
  253.                that look like options are left for the
  254.                the command to interpret. */
  255.             command = malloc(strlen(optarg) + 2);
  256.             if (command == NULL)
  257.                 Py_FatalError(
  258.                    "not enough memory to copy -c argument");
  259.             strcpy(command, optarg);
  260.             strcat(command, "\n");
  261.             break;
  262.         }
  263.         
  264.         switch (c) {
  265.  
  266.         case 'd':
  267.             Py_DebugFlag++;
  268.             break;
  269.  
  270.         case 'i':
  271.             inspect++;
  272.             Py_InteractiveFlag++;
  273.             break;
  274.  
  275.         case 'O':
  276.             Py_OptimizeFlag++;
  277.             break;
  278.  
  279.         case 'S':
  280.             Py_NoSiteFlag++;
  281.             break;
  282.  
  283.         case 't':
  284.             Py_TabcheckFlag++;
  285.             break;
  286.  
  287.         case 'u':
  288.             unbuffered++;
  289.             break;
  290.  
  291.         case 'v':
  292.             Py_VerboseFlag++;
  293.             break;
  294.  
  295.         case 'x':
  296.             skipfirstline = 1;
  297.             break;
  298.  
  299.         case 'U':
  300.             Py_UnicodeFlag++;
  301.             break;
  302.         case 'h':
  303.             help++;
  304.             break;
  305.         case 'V':
  306.             version++;
  307.             break;
  308.  
  309.         /* This space reserved for other options */
  310.  
  311.         default:
  312.             usage(2, argv[0]);
  313.             /*NOTREACHED*/
  314.  
  315.         }
  316.     }
  317.  
  318.     if (help)
  319.         usage(0, argv[0]);
  320.  
  321.     if (version) {
  322.         fprintf(stderr, "Python %s\n", PY_VERSION);
  323.         exit(0);
  324.     }
  325.  
  326.     if (command == NULL && optind < argc &&
  327.         strcmp(argv[optind], "-") != 0)
  328.     {
  329.         filename = argv[optind];
  330.         if (filename != NULL) {
  331.             if ((fp = fopen(filename, "r")) == NULL) {
  332.                 fprintf(stderr, "%s: can't open file '%s'\n",
  333.                     argv[0], filename);
  334.                 exit(2);
  335.             }
  336.             else if (skipfirstline) {
  337.                 int ch;
  338.                 /* Push back first newline so line numbers
  339.                    remain the same */
  340.                 while ((ch = getc(fp)) != EOF) {
  341.                     if (ch == '\n') {
  342.                         (void)ungetc(ch, fp);
  343.                         break;
  344.                     }
  345.                 }
  346.             }
  347.         }
  348.     }
  349.  
  350.     stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);
  351.  
  352.     if (unbuffered) {
  353. #ifdef MS_WINDOWS
  354.         _setmode(fileno(stdin), O_BINARY);
  355.         _setmode(fileno(stdout), O_BINARY);
  356. #endif
  357. #ifndef MPW
  358. #ifdef HAVE_SETVBUF
  359.         setvbuf(stdin,  (char *)NULL, _IONBF, BUFSIZ);
  360.         setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
  361.         setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
  362. #else /* !HAVE_SETVBUF */
  363.         setbuf(stdin,  (char *)NULL);
  364.         setbuf(stdout, (char *)NULL);
  365.         setbuf(stderr, (char *)NULL);
  366. #endif /* !HAVE_SETVBUF */
  367. #else /* MPW */
  368.         /* On MPW (3.2) unbuffered seems to hang */
  369.         setvbuf(stdin,  (char *)NULL, _IOLBF, BUFSIZ);
  370.         setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
  371.         setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
  372. #endif /* MPW */
  373.     }
  374.     else if (Py_InteractiveFlag) {
  375. #ifdef MS_WINDOWS
  376.         /* Doesn't have to have line-buffered -- use unbuffered */
  377.         /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
  378.         setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
  379. #else /* !MS_WINDOWS */
  380. #ifdef HAVE_SETVBUF
  381.         setvbuf(stdin,  (char *)NULL, _IOLBF, BUFSIZ);
  382.         setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
  383. #endif /* HAVE_SETVBUF */
  384. #endif /* !MS_WINDOWS */
  385.         /* Leave stderr alone - it should be unbuffered anyway. */
  386.       }
  387.  
  388.     Py_SetProgramName(argv[0]);
  389.     Py_Initialize();
  390.  
  391. #ifdef AMITCP
  392.     /** Sadly, this function cannot be called as a SAS/C standard **/
  393.     /** constructor function. It needs to have the interpreter **/
  394.     /** initialised because it uses the Python Error functions... **/
  395.     (void)_install_AmiTCP_callback();
  396. #endif
  397.  
  398.     if (Py_VerboseFlag ||
  399.         (command == NULL && filename == NULL && stdin_is_interactive))
  400.         fprintf(stderr, "Python %s on %s\n%s\n",
  401.             Py_GetVersion(), Py_GetPlatform(), COPYRIGHT);
  402.     
  403.     
  404.     if (command != NULL) {
  405.         /* Backup optind and force sys.argv[0] = '-c' */
  406.         optind--;
  407.         argv[optind] = "-c";
  408.     }
  409.  
  410.     PySys_SetArgv(argc-optind, argv+optind);
  411.  
  412.     if ((inspect || (command == NULL && filename == NULL)) &&
  413.         isatty(fileno(stdin))) {
  414.         PyObject *v;
  415.         v = PyImport_ImportModule("readline");
  416.         if (v == NULL)
  417.             PyErr_Clear();
  418.         else
  419.             Py_DECREF(v);
  420.     }
  421.  
  422.     if (command) {
  423.         sts = PyRun_SimpleString(command) != 0;
  424.         free(command);
  425.     }
  426.     else {
  427.         if (filename == NULL && stdin_is_interactive) {
  428.             char *startup = getenv("PYTHONSTARTUP");
  429.             if (startup != NULL && startup[0] != '\0') {
  430.                 FILE *fp = fopen(startup, "r");
  431.                 if (fp != NULL) {
  432.                     (void) PyRun_SimpleFile(fp, startup);
  433.                     PyErr_Clear();
  434.                     fclose(fp);
  435.                 }
  436.             }
  437.         }
  438.         sts = PyRun_AnyFileEx(
  439.             fp,
  440.             filename == NULL ? "<stdin>" : filename,
  441.             filename != NULL) != 0;
  442.     }
  443.  
  444.     if (inspect && stdin_is_interactive &&
  445.         (filename != NULL || command != NULL))
  446.         sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
  447.  
  448.     Py_Finalize();
  449.     return sts;
  450. }
  451.  
  452.  
  453. /* Make the *original* argc/argv available to other modules.
  454.    This is rare, but it is needed by the secureware extension. */
  455.  
  456. void
  457. Py_GetArgcArgv(int *argc, char ***argv)
  458. {
  459.     *argc = orig_argc;
  460.     *argv = orig_argv;
  461. }
  462.