sysmodule.c revision b0352fa3fccf9e8c76bc52aa93333bbecaf04948
1/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5                        All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* System module */
26
27/*
28Various bits of information used by the interpreter are collected in
29module 'sys'.
30Function member:
31- exit(sts): raise SystemExit
32Data members:
33- stdin, stdout, stderr: standard file objects
34- modules: the table of modules (dictionary)
35- path: module search path (list of strings)
36- argv: script arguments (list of strings)
37- ps1, ps2: optional primary and secondary prompts (strings)
38*/
39
40#include "allobjects.h"
41
42#include "sysmodule.h"
43#include "import.h"
44#include "modsupport.h"
45#include "osdefs.h"
46
47object *sys_trace, *sys_profile;
48int sys_checkinterval = 10;
49
50static object *sysdict;
51
52object *
53sysget(name)
54	char *name;
55{
56	return dictlookup(sysdict, name);
57}
58
59FILE *
60sysgetfile(name, def)
61	char *name;
62	FILE *def;
63{
64	FILE *fp = NULL;
65	object *v = sysget(name);
66	if (v != NULL && is_fileobject(v))
67		fp = getfilefile(v);
68	if (fp == NULL)
69		fp = def;
70	return fp;
71}
72
73int
74sysset(name, v)
75	char *name;
76	object *v;
77{
78	if (v == NULL) {
79		if (dictlookup(sysdict, name) == NULL)
80			return 0;
81		else
82			return dictremove(sysdict, name);
83	}
84	else
85		return dictinsert(sysdict, name, v);
86}
87
88static object *
89sys_exit(self, args)
90	object *self;
91	object *args;
92{
93	/* Raise SystemExit so callers may catch it or clean up. */
94	err_setval(SystemExit, args);
95	return NULL;
96}
97
98static object *
99sys_settrace(self, args)
100	object *self;
101	object *args;
102{
103	if (args == None)
104		args = NULL;
105	else
106		XINCREF(args);
107	XDECREF(sys_trace);
108	sys_trace = args;
109	INCREF(None);
110	return None;
111}
112
113static object *
114sys_setprofile(self, args)
115	object *self;
116	object *args;
117{
118	if (args == None)
119		args = NULL;
120	else
121		XINCREF(args);
122	XDECREF(sys_profile);
123	sys_profile = args;
124	INCREF(None);
125	return None;
126}
127
128static object *
129sys_setcheckinterval(self, args)
130	object *self;
131	object *args;
132{
133	if (!newgetargs(args, "i", &sys_checkinterval))
134		return NULL;
135	INCREF(None);
136	return None;
137}
138
139#ifdef USE_MALLOPT
140/* Link with -lmalloc (or -lmpc) on an SGI */
141#include <malloc.h>
142
143static object *
144sys_mdebug(self, args)
145	object *self;
146	object *args;
147{
148	int flag;
149	if (!getargs(args, "i", &flag))
150		return NULL;
151	mallopt(M_DEBUG, flag);
152	INCREF(None);
153	return None;
154}
155#endif /* USE_MALLOPT */
156
157static object *
158sys_getrefcount(self, args)
159	object *self;
160	object *args;
161{
162	object *arg;
163	if (!getargs(args, "O", &arg))
164		return NULL;
165	return newintobject((long) arg->ob_refcnt);
166}
167
168#ifdef COUNT_ALLOCS
169static PyObject *
170sys_getcounts(self, args)
171	PyObject *self, *args;
172{
173	extern PyObject *get_counts Py_PROTO((void));
174
175	if (!PyArg_Parse(args, ""))
176		return NULL;
177	return get_counts();
178}
179#endif
180
181#ifdef TRACE_REFS
182extern PyObject *getobjects Py_PROTO((PyObject *, PyObject *));
183#endif
184static struct methodlist sys_methods[] = {
185	{"exit",	sys_exit, 0},
186	{"getrefcount",	sys_getrefcount, 0},
187#ifdef COUNT_ALLOCS
188	{"getcounts",	sys_getcounts, 0},
189#endif
190#ifdef TRACE_REFS
191	{"getobjects",	getobjects, 1},
192#endif
193#ifdef USE_MALLOPT
194	{"mdebug",	sys_mdebug, 0},
195#endif
196	{"setprofile",	sys_setprofile, 0},
197	{"settrace",	sys_settrace, 0},
198	{"setcheckinterval",	sys_setcheckinterval, 1},
199	{NULL,		NULL}		/* sentinel */
200};
201
202static object *sysin, *sysout, *syserr;
203
204static object *
205list_builtin_module_names()
206{
207	object *list = newlistobject(0);
208	int i;
209	if (list == NULL)
210		return NULL;
211	for (i = 0; inittab[i].name != NULL; i++) {
212		object *name = newstringobject(inittab[i].name);
213		if (name == NULL)
214			break;
215		addlistitem(list, name);
216		DECREF(name);
217	}
218	if (sortlist(list) != 0) {
219		DECREF(list);
220		list = NULL;
221	}
222	return list;
223}
224
225void
226initsys()
227{
228	extern long getmaxint PROTO((void));
229	extern char *getversion PROTO((void));
230	extern char *getcopyright PROTO((void));
231	extern char *getplatform PROTO((void));
232	extern int fclose PROTO((FILE *));
233	object *m = initmodule("sys", sys_methods);
234	object *v;
235	sysdict = getmoduledict(m);
236	INCREF(sysdict);
237	/* NB keep an extra ref to the std files to avoid closing them
238	   when the user deletes them */
239	sysin = newopenfileobject(stdin, "<stdin>", "r", fclose);
240	sysout = newopenfileobject(stdout, "<stdout>", "w", fclose);
241	syserr = newopenfileobject(stderr, "<stderr>", "w", fclose);
242	if (err_occurred())
243		fatal("can't initialize sys.std{in,out,err}");
244	dictinsert(sysdict, "stdin", sysin);
245	dictinsert(sysdict, "stdout", sysout);
246	dictinsert(sysdict, "stderr", syserr);
247	dictinsert(sysdict, "version", v = newstringobject(getversion()));
248	XDECREF(v);
249	dictinsert(sysdict, "copyright", v = newstringobject(getcopyright()));
250	XDECREF(v);
251	dictinsert(sysdict, "platform", v = newstringobject(getplatform()));
252	XDECREF(v);
253	dictinsert(sysdict, "maxint", v = newintobject(getmaxint()));
254	XDECREF(v);
255	dictinsert(sysdict, "modules", get_modules());
256	dictinsert(sysdict, "builtin_module_names",
257		   v = list_builtin_module_names());
258	XDECREF(v);
259	if (err_occurred())
260		fatal("can't insert sys.* objects in sys dict");
261}
262
263static object *
264makepathobject(path, delim)
265	char *path;
266	int delim;
267{
268	int i, n;
269	char *p;
270	object *v, *w;
271
272	n = 1;
273	p = path;
274	while ((p = strchr(p, delim)) != NULL) {
275		n++;
276		p++;
277	}
278	v = newlistobject(n);
279	if (v == NULL)
280		return NULL;
281	for (i = 0; ; i++) {
282		p = strchr(path, delim);
283		if (p == NULL)
284			p = strchr(path, '\0'); /* End of string */
285		w = newsizedstringobject(path, (int) (p - path));
286		if (w == NULL) {
287			DECREF(v);
288			return NULL;
289		}
290		setlistitem(v, i, w);
291		if (*p == '\0')
292			break;
293		path = p+1;
294	}
295	return v;
296}
297
298void
299setpythonpath(path)
300	char *path;
301{
302	object *v;
303	if ((v = makepathobject(path, DELIM)) == NULL)
304		fatal("can't create sys.path");
305	if (sysset("path", v) != 0)
306		fatal("can't assign sys.path");
307	DECREF(v);
308}
309
310static object *
311makeargvobject(argc, argv)
312	int argc;
313	char **argv;
314{
315	object *av;
316	if (argc <= 0 || argv == NULL) {
317		/* Ensure at least one (empty) argument is seen */
318		static char *empty_argv[1] = {""};
319		argv = empty_argv;
320		argc = 1;
321	}
322	av = newlistobject(argc);
323	if (av != NULL) {
324		int i;
325		for (i = 0; i < argc; i++) {
326			object *v = newstringobject(argv[i]);
327			if (v == NULL) {
328				DECREF(av);
329				av = NULL;
330				break;
331			}
332			setlistitem(av, i, v);
333		}
334	}
335	return av;
336}
337
338void
339setpythonargv(argc, argv)
340	int argc;
341	char **argv;
342{
343	object *av = makeargvobject(argc, argv);
344	if (av == NULL)
345		fatal("no mem for sys.argv");
346	if (sysset("argv", av) != 0)
347		fatal("can't assign sys.argv");
348	DECREF(av);
349}
350