blob: c78a435e7363a7f800329de805fcdebb746d5e6f [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Python interpreter main program */
2
3/* XXX This is still a mess */
4
5#ifdef THINK_C
6#define USE_STDWIN
7#endif
8
9#include <stdio.h>
10#include <ctype.h>
11#include "string.h"
12
13#ifdef USE_STDWIN
14#include "stdwin.h"
15int use_stdwin;
16#endif
17
18extern char *getenv();
19
20#include "PROTO.h"
21#include "grammar.h"
22#include "node.h"
23#include "parsetok.h"
24#include "graminit.h"
25#include "errcode.h"
26#include "object.h"
27#include "stringobject.h"
28#include "sysmodule.h"
29
30extern grammar gram; /* From graminit.c */
31
32#ifndef PYTHONPATH
33
34#ifdef THINK_C
35
36#define PYTHONPATH ": :mod"
37
38#else /* !THINK_C */
39
40#ifdef AMOEBA
41#define PYTHONPATH ".:/profile/module/python"
42#else /* !AMOEBA */
43#define PYTHONPATH ".:/usr/local/lib/python"
44#endif /* !AMOEBA */
45
46#endif /* !THINK_C */
47
48#endif /* !PYTHONPATH */
49
50int debugging;
51
52main(argc, argv)
53 int argc;
54 char **argv;
55{
56 char *path;
57 char *filename = NULL;
58 FILE *fp = stdin;
59 int ret;
60
61#ifdef USE_STDWIN
62#ifdef THINK_C
63 wsetstdio(1);
64#else THINK_C
65 /* Must use "python -s" now to get stdwin support */
66 if (argc > 1 && strcmp(argv[1], "-s") == 0)
67 argv[1] = argv[0],
68 argc--, argv++,
69#endif /* !THINK_C */
70 use_stdwin = 1;
71 if (use_stdwin)
72 winitargs(&argc, &argv);
73#endif /* USE_STDWIN */
74
75#ifdef THINK_C_not_today
76 printf("argc = %d, argv[0] = '%s'\n", argc, argv[0]);
77 if (argc <= 1)
78 askargs(&argc, &argv);
79#endif
80
81 initintr(); /* For intrcheck() */
82
83 if (argc > 1 && strcmp(argv[1], "-") != 0)
84 filename = argv[1];
85
86 if (filename != NULL) {
87 if ((fp = fopen(filename, "r")) == NULL) {
88 fprintf(stderr, "python: can't open file '%s'\n",
89 filename);
90 exit(2);
91 }
92 }
93
94 /* XXX what is the ideal initialization order? */
95
96 initsys(argc-1, argv+1);
97 inittime();
98 initmath();
99
100#ifndef THINK_C
101 path = getenv("PYTHONPATH");
102 if (path == NULL)
103#endif
104 path = PYTHONPATH;
105 setpythonpath(path);
106
107 initrun();
108
109#ifdef USE_POSIX
110 initposix();
111#endif
112
113#ifdef THINK_C
114 initmac();
115#endif
116
117#ifdef USE_AUDIO
118 initaudio();
119#endif
120
121#ifdef USE_AMOEBA
122 initamoeba();
123#endif
124
125#ifdef USE_STDWIN
126 if (use_stdwin)
127 initstdwin();
128#endif
129
130#ifdef USE_GL
131 initgl();
132#endif
133
134#ifdef USE_PANEL
135 initpanel();
136#endif
137
138 if (!isatty(fileno(fp))) {
139 ret = runfile(fp, file_input, (char *)NULL, (char *)NULL);
140 }
141 else {
142 sysset("ps1", newstringobject(">>> "));
143 sysset("ps2", newstringobject("... "));
144 for (;;) {
145 object *v = sysget("ps1"), *w = sysget("ps2");
146 char *ps1 = NULL, *ps2 = NULL;
147 if (v != NULL && is_stringobject(v)) {
148 INCREF(v);
149 ps1 = getstringvalue(v);
150 }
151 else
152 v = NULL;
153 if (w != NULL && is_stringobject(w)) {
154 INCREF(w);
155 ps2 = getstringvalue(w);
156 }
157 else
158 w = NULL;
159 ret = runfile(fp, single_input, ps1, ps2);
160 if (v != NULL)
161 DECREF(v);
162 if (w != NULL)
163 DECREF(w);
164 if (ret == E_EOF || ret == E_NOMEM)
165 break;
166 }
167 }
168 goaway(ret == E_DONE || ret == E_EOF ? 0 : 1);
169 /*NOTREACHED*/
170}
171
172goaway(sts)
173 int sts;
174{
175 closerun();
176#ifdef USE_STDWIN
177 if (use_stdwin)
178 wdone();
179#endif
180#ifdef THINK_C
181#ifndef TRACE_REFS
182 /* Avoid 'click mouse to continue' in Lightspeed C */
183 if (sts == 0)
184 Click_On(0);
185#endif
186#endif
187 exit(sts);
188 /*NOTREACHED*/
189}
190
191/* Parse input from a file and execute it */
192
193static int
194runfile(fp, start, ps1, ps2)
195 FILE *fp;
196 int start;
197 char *ps1, *ps2;
198{
199 node *n;
200 int ret;
201 ret = parsefile(fp, &gram, start, ps1, ps2, &n);
202 if (ret != E_DONE)
203 return ret;
204 return execute(n) == 0 ? E_DONE : E_ERROR;
205}
206
207#ifdef THINK_C
208
209/* Ask a yes/no question */
210
211int
212askyesno(prompt)
213 char *prompt;
214{
215 char buf[256];
216
217 printf("%s [ny] ", prompt);
218 if (fgets(buf, sizeof buf, stdin) == NULL)
219 return 0;
220 return buf[0] == 'y' || buf[0] == 'Y';
221}
222
223/* Check for file descriptor connected to interactive device.
224 Pretend that stdin is always interactive, other files never. */
225
226int
227isatty(fd)
228 int fd;
229{
230 return fd == fileno(stdin);
231}
232
233/* Kludge to get arguments on the Mac */
234
235#define MAXARGS 20
236
237static char *
238nextarg(pnext)
239 char **pnext;
240{
241 char *ret;
242 char *p = *pnext;
243 while (isspace(*p))
244 p++;
245 if (*p == '\0')
246 return NULL;
247 ret = p;
248 while (!isspace(*p))
249 p++;
250 if (*p != '\0')
251 *p++ = '\0';
252 *pnext = p;
253 return ret;
254}
255
256static
257askargs(pargc, pargv)
258 int *pargc;
259 char ***pargv; /* sic */
260{
261 static char buf[256];
262 static char *argv[MAXARGS];
263 int argc;
264 char *p, *next;
265 fprintf(stderr, "Args: ");
266 if (fgets(buf, sizeof buf, stdin) == NULL)
267 return;
268 next = buf;
269 if ((p = nextarg(&next)) == NULL)
270 return;
271 if (*pargc > 0)
272 argv[0] = (*pargv)[0];
273 else
274 argv[0] = "PYTHON";
275 argc = 1;
276 argv[argc++] = p;
277 while (argc+1 < MAXARGS && (p = nextarg(&next)) != NULL)
278 argv[argc++] = p;
279 argv[argc] = NULL;
280 *pargc = argc;
281 *pargv = argv;
282}
283
284#endif
285
286/* WISH LIST
287
288 - improved per-module error handling; different use of errno
289 - possible new types:
290 - iterator (for range, keys, ...)
291 - improve interpreter error handling, e.g., true tracebacks
292 - release parse trees when no longer needed (make them objects?)
293 - faster parser (for long modules)
294 - save precompiled modules on file?
295 - fork threads, locking
296 - allow syntax extensions
297*/