summaryrefslogtreecommitdiffstats
path: root/Python/pythonmain.c
blob: 1ffba19531fa9b131df81959785bafe32c8a3c1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* Python interpreter main program */

#include <stdio.h>
#include <ctype.h>
#include "string.h"

extern char *getpythonpath();

#include "PROTO.h"
#include "grammar.h"
#include "node.h"
#include "parsetok.h"
#include "graminit.h"
#include "errcode.h"
#include "object.h"
#include "stringobject.h"
#include "sysmodule.h"

extern grammar gram; /* From graminit.c */

int debugging;

main(argc, argv)
	int argc;
	char **argv;
{
	char *filename = NULL;
	FILE *fp = stdin;
	int ret;

	initargs(&argc, &argv);
	
	initintr(); /* For intrcheck() */
	
	if (argc > 1 && strcmp(argv[1], "-") != 0)
		filename = argv[1];

	if (filename != NULL) {
		if ((fp = fopen(filename, "r")) == NULL) {
			fprintf(stderr, "python: can't open file '%s'\n",
				filename);
			exit(2);
		}
	}
	
	/* XXX what is the ideal initialization order? */
	
	initsys(argc-1, argv+1);
	inittime();
	initmath();
	
	setpythonpath(getpythonpath());
	
	initrun();
	initcalls();
	
	if (!isatty(fileno(fp))) {
		ret = runfile(fp, file_input, (char *)NULL, (char *)NULL);
	}
	else {
		sysset("ps1", newstringobject(">>> "));
		sysset("ps2", newstringobject("... "));
		for (;;) {
			object *v = sysget("ps1"), *w = sysget("ps2");
			char *ps1 = NULL, *ps2 = NULL;
			if (v != NULL && is_stringobject(v)) {
				INCREF(v);
				ps1 = getstringvalue(v);
			}
			else
				v = NULL;
			if (w != NULL && is_stringobject(w)) {
				INCREF(w);
				ps2 = getstringvalue(w);
			}
			else
				w = NULL;
			ret = runfile(fp, single_input, ps1, ps2);
			if (v != NULL)
				DECREF(v);
			if (w != NULL)
				DECREF(w);
			if (ret == E_EOF || ret == E_NOMEM)
				break;
		}
	}
	goaway(ret == E_DONE || ret == E_EOF ? 0 : 1);
	/*NOTREACHED*/
}

goaway(sts)
	int sts;
{
#ifdef THINK_C
	if (sts == 0)
		Click_On(0);
#endif
	closerun();
	donecalls();
	exit(sts);
	/*NOTREACHED*/
}

/* Parse input from a file and execute it */

static int
runfile(fp, start, ps1, ps2)
	FILE *fp;
	int start;
	char *ps1, *ps2;
{
	node *n;
	int ret;
	ret = parsefile(fp, &gram, start, ps1, ps2, &n);
	if (ret != E_DONE)
		return ret;
	return execute(n) == 0 ? E_DONE : E_ERROR;
}

/* Ask a yes/no question */

int
askyesno(prompt)
	char *prompt;
{
	char buf[256];
	
	printf("%s [ny] ", prompt);
	if (fgets(buf, sizeof buf, stdin) == NULL)
		return 0;
	return buf[0] == 'y' || buf[0] == 'Y';
}

#ifdef THINK_C

/* Check for file descriptor connected to interactive device.
   Pretend that stdin is always interactive, other files never. */

int
isatty(fd)
	int fd;
{
	return fd == fileno(stdin);
}

#endif

/*	WISH LIST

	- improved per-module error handling; different use of errno
	- possible new types:
		- iterator (for range, keys, ...)
	- improve interpreter error handling, e.g., true tracebacks
	- release parse trees when no longer needed (make them objects?)
	- faster parser (for long modules)
	- save precompiled modules on file?
	- fork threads, locking
	- allow syntax extensions
*/