sysmodule.c revision cc88341e6d25a7ca9fc7765d93c436f02d84f83b
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
52#ifdef NT
53extern void *PyWin_DLLhModule;
54#endif
55
56object *
57sysget(name)
58	char *name;
59{
60	return dictlookup(sysdict, name);
61}
62
63FILE *
64sysgetfile(name, def)
65	char *name;
66	FILE *def;
67{
68	FILE *fp = NULL;
69	object *v = sysget(name);
70	if (v != NULL && is_fileobject(v))
71		fp = getfilefile(v);
72	if (fp == NULL)
73		fp = def;
74	return fp;
75}
76
77int
78sysset(name, v)
79	char *name;
80	object *v;
81{
82	if (v == NULL) {
83		if (dictlookup(sysdict, name) == NULL)
84			return 0;
85		else
86			return dictremove(sysdict, name);
87	}
88	else
89		return dictinsert(sysdict, name, v);
90}
91
92static object *
93sys_exit(self, args)
94	object *self;
95	object *args;
96{
97	/* Raise SystemExit so callers may catch it or clean up. */
98	err_setval(SystemExit, args);
99	return NULL;
100}
101
102static object *
103sys_settrace(self, args)
104	object *self;
105	object *args;
106{
107	if (args == None)
108		args = NULL;
109	else
110		XINCREF(args);
111	XDECREF(sys_trace);
112	sys_trace = args;
113	INCREF(None);
114	return None;
115}
116
117static object *
118sys_setprofile(self, args)
119	object *self;
120	object *args;
121{
122	if (args == None)
123		args = NULL;
124	else
125		XINCREF(args);
126	XDECREF(sys_profile);
127	sys_profile = args;
128	INCREF(None);
129	return None;
130}
131
132static object *
133sys_setcheckinterval(self, args)
134	object *self;
135	object *args;
136{
137	if (!newgetargs(args, "i", &sys_checkinterval))
138		return NULL;
139	INCREF(None);
140	return None;
141}
142
143#ifdef USE_MALLOPT
144/* Link with -lmalloc (or -lmpc) on an SGI */
145#include <malloc.h>
146
147static object *
148sys_mdebug(self, args)
149	object *self;
150	object *args;
151{
152	int flag;
153	if (!getargs(args, "i", &flag))
154		return NULL;
155	mallopt(M_DEBUG, flag);
156	INCREF(None);
157	return None;
158}
159#endif /* USE_MALLOPT */
160
161static object *
162sys_getrefcount(self, args)
163	object *self;
164	object *args;
165{
166	object *arg;
167	if (!getargs(args, "O", &arg))
168		return NULL;
169	return newintobject((long) arg->ob_refcnt);
170}
171
172#ifdef COUNT_ALLOCS
173static PyObject *
174sys_getcounts(self, args)
175	PyObject *self, *args;
176{
177	extern PyObject *get_counts Py_PROTO((void));
178
179	if (!PyArg_Parse(args, ""))
180		return NULL;
181	return get_counts();
182}
183#endif
184
185#ifdef Py_TRACE_REFS
186/* Defined in objects.c because it uses static globals if that file */
187extern PyObject *_Py_GetObjects Py_PROTO((PyObject *, PyObject *));
188#endif
189
190static struct methodlist sys_methods[] = {
191	{"exit",	sys_exit, 0},
192	{"getrefcount",	sys_getrefcount, 0},
193#ifdef COUNT_ALLOCS
194	{"getcounts",	sys_getcounts, 0},
195#endif
196#ifdef Py_TRACE_REFS
197	{"getobjects",	_Py_GetObjects, 1},
198#endif
199#ifdef USE_MALLOPT
200	{"mdebug",	sys_mdebug, 0},
201#endif
202	{"setprofile",	sys_setprofile, 0},
203	{"settrace",	sys_settrace, 0},
204	{"setcheckinterval",	sys_setcheckinterval, 1},
205	{NULL,		NULL}		/* sentinel */
206};
207
208static object *sysin, *sysout, *syserr;
209
210static object *
211list_builtin_module_names()
212{
213	object *list = newlistobject(0);
214	int i;
215	if (list == NULL)
216		return NULL;
217	for (i = 0; inittab[i].name != NULL; i++) {
218		object *name = newstringobject(inittab[i].name);
219		if (name == NULL)
220			break;
221		addlistitem(list, name);
222		DECREF(name);
223	}
224	if (sortlist(list) != 0) {
225		DECREF(list);
226		list = NULL;
227	}
228	return list;
229}
230
231void
232initsys()
233{
234	extern long getmaxint PROTO((void));
235	extern char *getversion PROTO((void));
236	extern char *getcopyright PROTO((void));
237	extern char *getplatform PROTO((void));
238	extern char *Py_GetPrefix PROTO((void));
239	extern char *Py_GetExecPrefix PROTO((void));
240	extern int fclose PROTO((FILE *));
241	object *m = initmodule("sys", sys_methods);
242	object *v;
243	sysdict = getmoduledict(m);
244	INCREF(sysdict);
245	/* NB keep an extra ref to the std files to avoid closing them
246	   when the user deletes them */
247	sysin = newopenfileobject(stdin, "<stdin>", "r", fclose);
248	sysout = newopenfileobject(stdout, "<stdout>", "w", fclose);
249	syserr = newopenfileobject(stderr, "<stderr>", "w", fclose);
250	if (err_occurred())
251		fatal("can't initialize sys.std{in,out,err}");
252	dictinsert(sysdict, "stdin", sysin);
253	dictinsert(sysdict, "stdout", sysout);
254	dictinsert(sysdict, "stderr", syserr);
255	dictinsert(sysdict, "version", v = newstringobject(getversion()));
256	XDECREF(v);
257	dictinsert(sysdict, "copyright", v = newstringobject(getcopyright()));
258	XDECREF(v);
259	dictinsert(sysdict, "platform", v = newstringobject(getplatform()));
260	XDECREF(v);
261	dictinsert(sysdict, "prefix", v = newstringobject(Py_GetPrefix()));
262	XDECREF(v);
263	dictinsert(sysdict, "exec_prefix",
264		   v = newstringobject(Py_GetExecPrefix()));
265	XDECREF(v);
266	dictinsert(sysdict, "maxint", v = newintobject(getmaxint()));
267	XDECREF(v);
268	dictinsert(sysdict, "modules", get_modules());
269	dictinsert(sysdict, "builtin_module_names",
270		   v = list_builtin_module_names());
271	XDECREF(v);
272#ifdef MS_COREDLL
273	dictinsert(sysdict, "dllhandle", v = newintobject((int)PyWin_DLLhModule));
274	XDECREF(v);
275	dictinsert(sysdict, "winver", v = newstringobject(MS_DLL_ID));
276	XDECREF(v);
277#endif
278	if (err_occurred())
279		fatal("can't insert sys.* objects in sys dict");
280}
281
282static object *
283makepathobject(path, delim)
284	char *path;
285	int delim;
286{
287	int i, n;
288	char *p;
289	object *v, *w;
290
291	n = 1;
292	p = path;
293	while ((p = strchr(p, delim)) != NULL) {
294		n++;
295		p++;
296	}
297	v = newlistobject(n);
298	if (v == NULL)
299		return NULL;
300	for (i = 0; ; i++) {
301		p = strchr(path, delim);
302		if (p == NULL)
303			p = strchr(path, '\0'); /* End of string */
304		w = newsizedstringobject(path, (int) (p - path));
305		if (w == NULL) {
306			DECREF(v);
307			return NULL;
308		}
309		setlistitem(v, i, w);
310		if (*p == '\0')
311			break;
312		path = p+1;
313	}
314	return v;
315}
316
317void
318setpythonpath(path)
319	char *path;
320{
321	object *v;
322	if ((v = makepathobject(path, DELIM)) == NULL)
323		fatal("can't create sys.path");
324	if (sysset("path", v) != 0)
325		fatal("can't assign sys.path");
326	DECREF(v);
327}
328
329static object *
330makeargvobject(argc, argv)
331	int argc;
332	char **argv;
333{
334	object *av;
335	if (argc <= 0 || argv == NULL) {
336		/* Ensure at least one (empty) argument is seen */
337		static char *empty_argv[1] = {""};
338		argv = empty_argv;
339		argc = 1;
340	}
341	av = newlistobject(argc);
342	if (av != NULL) {
343		int i;
344		for (i = 0; i < argc; i++) {
345			object *v = newstringobject(argv[i]);
346			if (v == NULL) {
347				DECREF(av);
348				av = NULL;
349				break;
350			}
351			setlistitem(av, i, v);
352		}
353	}
354	return av;
355}
356
357void
358setpythonargv(argc, argv)
359	int argc;
360	char **argv;
361{
362	object *av = makeargvobject(argc, argv);
363	object *path = sysget("path");
364	if (av == NULL)
365		fatal("no mem for sys.argv");
366	if (sysset("argv", av) != 0)
367		fatal("can't assign sys.argv");
368	if (path != NULL) {
369		char *p = NULL;
370		int n = 0;
371		object *a;
372#if SEP == '\\' /* Special case for MS filename syntax */
373		if (argc > 0 && argv[0] != NULL) {
374			char *q;
375			p = strrchr(argv[0], SEP);
376			/* Test for alternate separator */
377			q = strrchr(p ? p : argv[0], '/');
378			if (q != NULL)
379				p = q;
380			if (p != NULL) {
381				n = p + 1 - argv[0];
382				if (n > 1 && p[-1] != ':')
383					n--; /* Drop trailing separator */
384			}
385		}
386#else /* All other filename syntaxes */
387		if (argc > 0 && argv[0] != NULL)
388			p = strrchr(argv[0], SEP);
389		if (p != NULL) {
390			n = p + 1 - argv[0];
391#if SEP == '/' /* Special case for Unix filename syntax */
392			if (n > 1)
393				n--; /* Drop trailing separator */
394#endif /* Unix */
395		}
396#endif /* All others */
397		a = newsizedstringobject(argv[0], n);
398		if (a == NULL)
399			fatal("no mem for sys.path insertion");
400		if (inslistitem(path, 0, a) < 0)
401			fatal("sys.path.insert(0) failed");
402		DECREF(a);
403	}
404	DECREF(av);
405}
406