History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Python/sysmodule.c (1 of 3706 files). Show all

Unified · Split

sys/src/cmd/python/Python/sysmodule.c+1468−0
@@ -0,0 +1,1468 @@
1+
2+/* System module */
3+
4+/*
5+Various bits of information used by the interpreter are collected in
6+module 'sys'.
7+Function member:
8+- exit(sts): raise SystemExit
9+Data members:
10+- stdin, stdout, stderr: standard file objects
11+- modules: the table of modules (dictionary)
12+- path: module search path (list of strings)
13+- argv: script arguments (list of strings)
14+- ps1, ps2: optional primary and secondary prompts (strings)
15+*/
16+
17+#include "Python.h"
18+#include "code.h"
19+#include "frameobject.h"
20+#include "eval.h"
21+
22+#include "osdefs.h"
23+
24+#ifdef MS_WINDOWS
25+#define WIN32_LEAN_AND_MEAN
26+#include "windows.h"
27+#endif /* MS_WINDOWS */
28+
29+#ifdef MS_COREDLL
30+extern void *PyWin_DLLhModule;
31+/* A string loaded from the DLL at startup: */
32+extern const char *PyWin_DLLVersionString;
33+#endif
34+
35+#ifdef __VMS
36+#include <unixlib.h>
37+#endif
38+
39+#ifdef MS_WINDOWS
40+#include <windows.h>
41+#endif
42+
43+#ifdef HAVE_LANGINFO_H
44+#include <locale.h>
45+#include <langinfo.h>
46+#endif
47+
48+PyObject *
49+PySys_GetObject(char *name)
50+{
51+ PyThreadState *tstate = PyThreadState_GET();
52+ PyObject *sd = tstate->interp->sysdict;
53+ if (sd == NULL)
54+ return NULL;
55+ return PyDict_GetItemString(sd, name);
56+}
57+
58+FILE *
59+PySys_GetFile(char *name, FILE *def)
60+{
61+ FILE *fp = NULL;
62+ PyObject *v = PySys_GetObject(name);
63+ if (v != NULL && PyFile_Check(v))
64+ fp = PyFile_AsFile(v);
65+ if (fp == NULL)
66+ fp = def;
67+ return fp;
68+}
69+
70+int
71+PySys_SetObject(char *name, PyObject *v)
72+{
73+ PyThreadState *tstate = PyThreadState_GET();
74+ PyObject *sd = tstate->interp->sysdict;
75+ if (v == NULL) {
76+ if (PyDict_GetItemString(sd, name) == NULL)
77+ return 0;
78+ else
79+ return PyDict_DelItemString(sd, name);
80+ }
81+ else
82+ return PyDict_SetItemString(sd, name, v);
83+}
84+
85+static PyObject *
86+sys_displayhook(PyObject *self, PyObject *o)
87+{
88+ PyObject *outf;
89+ PyInterpreterState *interp = PyThreadState_GET()->interp;
90+ PyObject *modules = interp->modules;
91+ PyObject *builtins = PyDict_GetItemString(modules, "__builtin__");
92+
93+ if (builtins == NULL) {
94+ PyErr_SetString(PyExc_RuntimeError, "lost __builtin__");
95+ return NULL;
96+ }
97+
98+ /* Print value except if None */
99+ /* After printing, also assign to '_' */
100+ /* Before, set '_' to None to avoid recursion */
101+ if (o == Py_None) {
102+ Py_INCREF(Py_None);
103+ return Py_None;
104+ }
105+ if (PyObject_SetAttrString(builtins, "_", Py_None) != 0)
106+ return NULL;
107+ if (Py_FlushLine() != 0)
108+ return NULL;
109+ outf = PySys_GetObject("stdout");
110+ if (outf == NULL) {
111+ PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
112+ return NULL;
113+ }
114+ if (PyFile_WriteObject(o, outf, 0) != 0)
115+ return NULL;
116+ PyFile_SoftSpace(outf, 1);
117+ if (Py_FlushLine() != 0)
118+ return NULL;
119+ if (PyObject_SetAttrString(builtins, "_", o) != 0)
120+ return NULL;
121+ Py_INCREF(Py_None);
122+ return Py_None;
123+}
124+
125+PyDoc_STRVAR(displayhook_doc,
126+"displayhook(object) -> None\n"
127+"\n"
128+"Print an object to sys.stdout and also save it in __builtin__.\n"
129+);
130+
131+static PyObject *
132+sys_excepthook(PyObject* self, PyObject* args)
133+{
134+ PyObject *exc, *value, *tb;
135+ if (!PyArg_UnpackTuple(args, "excepthook", 3, 3, &exc, &value, &tb))
136+ return NULL;
137+ PyErr_Display(exc, value, tb);
138+ Py_INCREF(Py_None);
139+ return Py_None;
140+}
141+
142+PyDoc_STRVAR(excepthook_doc,
143+"excepthook(exctype, value, traceback) -> None\n"
144+"\n"
145+"Handle an exception by displaying it with a traceback on sys.stderr.\n"
146+);
147+
148+static PyObject *
149+sys_exc_info(PyObject *self, PyObject *noargs)
150+{
151+ PyThreadState *tstate;
152+ tstate = PyThreadState_GET();
153+ return Py_BuildValue(
154+ "(OOO)",
155+ tstate->exc_type != NULL ? tstate->exc_type : Py_None,
156+ tstate->exc_value != NULL ? tstate->exc_value : Py_None,
157+ tstate->exc_traceback != NULL ?
158+ tstate->exc_traceback : Py_None);
159+}
160+
161+PyDoc_STRVAR(exc_info_doc,
162+"exc_info() -> (type, value, traceback)\n\
163+\n\
164+Return information about the most recent exception caught by an except\n\
165+clause in the current stack frame or in an older stack frame."
166+);
167+
168+static PyObject *
169+sys_exc_clear(PyObject *self, PyObject *noargs)
170+{
171+ PyThreadState *tstate = PyThreadState_GET();
172+ PyObject *tmp_type, *tmp_value, *tmp_tb;
173+ tmp_type = tstate->exc_type;
174+ tmp_value = tstate->exc_value;
175+ tmp_tb = tstate->exc_traceback;
176+ tstate->exc_type = NULL;
177+ tstate->exc_value = NULL;
178+ tstate->exc_traceback = NULL;
179+ Py_XDECREF(tmp_type);
180+ Py_XDECREF(tmp_value);
181+ Py_XDECREF(tmp_tb);
182+ /* For b/w compatibility */
183+ PySys_SetObject("exc_type", Py_None);
184+ PySys_SetObject("exc_value", Py_None);
185+ PySys_SetObject("exc_traceback", Py_None);
186+ Py_INCREF(Py_None);
187+ return Py_None;
188+}
189+
190+PyDoc_STRVAR(exc_clear_doc,
191+"exc_clear() -> None\n\
192+\n\
193+Clear global information on the current exception. Subsequent calls to\n\
194+exc_info() will return (None,None,None) until another exception is raised\n\
195+in the current thread or the execution stack returns to a frame where\n\
196+another exception is being handled."
197+);
198+
199+static PyObject *
200+sys_exit(PyObject *self, PyObject *args)
201+{
202+ PyObject *exit_code = 0;
203+ if (!PyArg_UnpackTuple(args, "exit", 0, 1, &exit_code))
204+ return NULL;
205+ /* Raise SystemExit so callers may catch it or clean up. */
206+ PyErr_SetObject(PyExc_SystemExit, exit_code);
207+ return NULL;
208+}
209+
210+PyDoc_STRVAR(exit_doc,
211+"exit([status])\n\
212+\n\
213+Exit the interpreter by raising SystemExit(status).\n\
214+If the status is omitted or None, it defaults to zero (i.e., success).\n\
215+If the status is numeric, it will be used as the system exit status.\n\
216+If it is another kind of object, it will be printed and the system\n\
217+exit status will be one (i.e., failure)."
218+);
219+
220+#ifdef Py_USING_UNICODE
221+
222+static PyObject *
223+sys_getdefaultencoding(PyObject *self)
224+{
225+ return PyString_FromString(PyUnicode_GetDefaultEncoding());
226+}
227+
228+PyDoc_STRVAR(getdefaultencoding_doc,
229+"getdefaultencoding() -> string\n\
230+\n\
231+Return the current default string encoding used by the Unicode \n\
232+implementation."
233+);
234+
235+static PyObject *
236+sys_setdefaultencoding(PyObject *self, PyObject *args)
237+{
238+ char *encoding;
239+ if (!PyArg_ParseTuple(args, "s:setdefaultencoding", &encoding))
240+ return NULL;
241+ if (PyUnicode_SetDefaultEncoding(encoding))
242+ return NULL;
243+ Py_INCREF(Py_None);
244+ return Py_None;
245+}
246+
247+PyDoc_STRVAR(setdefaultencoding_doc,
248+"setdefaultencoding(encoding)\n\
249+\n\
250+Set the current default string encoding used by the Unicode implementation."
251+);
252+
253+static PyObject *
254+sys_getfilesystemencoding(PyObject *self)
255+{
256+ if (Py_FileSystemDefaultEncoding)
257+ return PyString_FromString(Py_FileSystemDefaultEncoding);
258+ Py_INCREF(Py_None);
259+ return Py_None;
260+}
261+
262+PyDoc_STRVAR(getfilesystemencoding_doc,
263+"getfilesystemencoding() -> string\n\
264+\n\
265+Return the encoding used to convert Unicode filenames in\n\
266+operating system filenames."
267+);
268+
269+#endif
270+
271+/*
272+ * Cached interned string objects used for calling the profile and
273+ * trace functions. Initialized by trace_init().
274+ */
275+static PyObject *whatstrings[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
276+
277+static int
278+trace_init(void)
279+{
280+ static char *whatnames[7] = {"call", "exception", "line", "return",
281+ "c_call", "c_exception", "c_return"};
282+ PyObject *name;
283+ int i;
284+ for (i = 0; i < 7; ++i) {
285+ if (whatstrings[i] == NULL) {
286+ name = PyString_InternFromString(whatnames[i]);
287+ if (name == NULL)
288+ return -1;
289+ whatstrings[i] = name;
290+ }
291+ }
292+ return 0;
293+}
294+
295+
296+static PyObject *
297+call_trampoline(PyThreadState *tstate, PyObject* callback,
298+ PyFrameObject *frame, int what, PyObject *arg)
299+{
300+ PyObject *args = PyTuple_New(3);
301+ PyObject *whatstr;
302+ PyObject *result;
303+
304+ if (args == NULL)
305+ return NULL;
306+ Py_INCREF(frame);
307+ whatstr = whatstrings[what];
308+ Py_INCREF(whatstr);
309+ if (arg == NULL)
310+ arg = Py_None;
311+ Py_INCREF(arg);
312+ PyTuple_SET_ITEM(args, 0, (PyObject *)frame);
313+ PyTuple_SET_ITEM(args, 1, whatstr);
314+ PyTuple_SET_ITEM(args, 2, arg);
315+
316+ /* call the Python-level function */
317+ PyFrame_FastToLocals(frame);
318+ result = PyEval_CallObject(callback, args);
319+ PyFrame_LocalsToFast(frame, 1);
320+ if (result == NULL)
321+ PyTraceBack_Here(frame);
322+
323+ /* cleanup */
324+ Py_DECREF(args);
325+ return result;
326+}
327+
328+static int
329+profile_trampoline(PyObject *self, PyFrameObject *frame,
330+ int what, PyObject *arg)
331+{
332+ PyThreadState *tstate = frame->f_tstate;
333+ PyObject *result;
334+
335+ if (arg == NULL)
336+ arg = Py_None;
337+ result = call_trampoline(tstate, self, frame, what, arg);
338+ if (result == NULL) {
339+ PyEval_SetProfile(NULL, NULL);
340+ return -1;
341+ }
342+ Py_DECREF(result);
343+ return 0;
344+}
345+
346+static int
347+trace_trampoline(PyObject *self, PyFrameObject *frame,
348+ int what, PyObject *arg)
349+{
350+ PyThreadState *tstate = frame->f_tstate;
351+ PyObject *callback;
352+ PyObject *result;
353+
354+ if (what == PyTrace_CALL)
355+ callback = self;
356+ else
357+ callback = frame->f_trace;
358+ if (callback == NULL)
359+ return 0;
360+ result = call_trampoline(tstate, callback, frame, what, arg);
361+ if (result == NULL) {
362+ PyEval_SetTrace(NULL, NULL);
363+ Py_XDECREF(frame->f_trace);
364+ frame->f_trace = NULL;
365+ return -1;
366+ }
367+ if (result != Py_None) {
368+ PyObject *temp = frame->f_trace;
369+ frame->f_trace = NULL;
370+ Py_XDECREF(temp);
371+ frame->f_trace = result;
372+ }
373+ else {
374+ Py_DECREF(result);
375+ }
376+ return 0;
377+}
378+
379+static PyObject *
380+sys_settrace(PyObject *self, PyObject *args)
381+{
382+ if (trace_init() == -1)
383+ return NULL;
384+ if (args == Py_None)
385+ PyEval_SetTrace(NULL, NULL);
386+ else
387+ PyEval_SetTrace(trace_trampoline, args);
388+ Py_INCREF(Py_None);
389+ return Py_None;
390+}
391+
392+PyDoc_STRVAR(settrace_doc,
393+"settrace(function)\n\
394+\n\
395+Set the global debug tracing function. It will be called on each\n\
396+function call. See the debugger chapter in the library manual."
397+);
398+
399+static PyObject *
400+sys_setprofile(PyObject *self, PyObject *args)
401+{
402+ if (trace_init() == -1)
403+ return NULL;
404+ if (args == Py_None)
405+ PyEval_SetProfile(NULL, NULL);
406+ else
407+ PyEval_SetProfile(profile_trampoline, args);
408+ Py_INCREF(Py_None);
409+ return Py_None;
410+}
411+
412+PyDoc_STRVAR(setprofile_doc,
413+"setprofile(function)\n\
414+\n\
415+Set the profiling function. It will be called on each function call\n\
416+and return. See the profiler chapter in the library manual."
417+);
418+
419+static PyObject *
420+sys_setcheckinterval(PyObject *self, PyObject *args)
421+{
422+ if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval))
423+ return NULL;
424+ Py_INCREF(Py_None);
425+ return Py_None;
426+}
427+
428+PyDoc_STRVAR(setcheckinterval_doc,
429+"setcheckinterval(n)\n\
430+\n\
431+Tell the Python interpreter to check for asynchronous events every\n\
432+n instructions. This also affects how often thread switches occur."
433+);
434+
435+static PyObject *
436+sys_getcheckinterval(PyObject *self, PyObject *args)
437+{
438+ return PyInt_FromLong(_Py_CheckInterval);
439+}
440+
441+PyDoc_STRVAR(getcheckinterval_doc,
442+"getcheckinterval() -> current check interval; see setcheckinterval()."
443+);
444+
445+#ifdef WITH_TSC
446+static PyObject *
447+sys_settscdump(PyObject *self, PyObject *args)
448+{
449+ int bool;
450+ PyThreadState *tstate = PyThreadState_Get();
451+
452+ if (!PyArg_ParseTuple(args, "i:settscdump", &bool))
453+ return NULL;
454+ if (bool)
455+ tstate->interp->tscdump = 1;
456+ else
457+ tstate->interp->tscdump = 0;
458+ Py_INCREF(Py_None);
459+ return Py_None;
460+
461+}
462+
463+PyDoc_STRVAR(settscdump_doc,
464+"settscdump(bool)\n\
465+\n\
466+If true, tell the Python interpreter to dump VM measurements to\n\
467+stderr. If false, turn off dump. The measurements are based on the\n\
468+processor's time-stamp counter."
469+);
470+#endif /* TSC */
471+
472+static PyObject *
473+sys_setrecursionlimit(PyObject *self, PyObject *args)
474+{
475+ int new_limit;
476+ if (!PyArg_ParseTuple(args, "i:setrecursionlimit", &new_limit))
477+ return NULL;
478+ if (new_limit <= 0) {
479+ PyErr_SetString(PyExc_ValueError,
480+ "recursion limit must be positive");
481+ return NULL;
482+ }
483+ Py_SetRecursionLimit(new_limit);
484+ Py_INCREF(Py_None);
485+ return Py_None;
486+}
487+
488+PyDoc_STRVAR(setrecursionlimit_doc,
489+"setrecursionlimit(n)\n\
490+\n\
491+Set the maximum depth of the Python interpreter stack to n. This\n\
492+limit prevents infinite recursion from causing an overflow of the C\n\
493+stack and crashing Python. The highest possible limit is platform-\n\
494+dependent."
495+);
496+
497+static PyObject *
498+sys_getrecursionlimit(PyObject *self)
499+{
500+ return PyInt_FromLong(Py_GetRecursionLimit());
501+}
502+
503+PyDoc_STRVAR(getrecursionlimit_doc,
504+"getrecursionlimit()\n\
505+\n\
506+Return the current value of the recursion limit, the maximum depth\n\
507+of the Python interpreter stack. This limit prevents infinite\n\
508+recursion from causing an overflow of the C stack and crashing Python."
509+);
510+
511+#ifdef MS_WINDOWS
512+PyDoc_STRVAR(getwindowsversion_doc,
513+"getwindowsversion()\n\
514+\n\
515+Return information about the running version of Windows.\n\
516+The result is a tuple of (major, minor, build, platform, text)\n\
517+All elements are numbers, except text which is a string.\n\
518+Platform may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP\n\
519+"
520+);
521+
522+static PyObject *
523+sys_getwindowsversion(PyObject *self)
524+{
525+ OSVERSIONINFO ver;
526+ ver.dwOSVersionInfoSize = sizeof(ver);
527+ if (!GetVersionEx(&ver))
528+ return PyErr_SetFromWindowsErr(0);
529+ return Py_BuildValue("HHHHs",
530+ ver.dwMajorVersion,
531+ ver.dwMinorVersion,
532+ ver.dwBuildNumber,
533+ ver.dwPlatformId,
534+ ver.szCSDVersion);
535+}
536+
537+#endif /* MS_WINDOWS */
538+
539+#ifdef HAVE_DLOPEN
540+static PyObject *
541+sys_setdlopenflags(PyObject *self, PyObject *args)
542+{
543+ int new_val;
544+ PyThreadState *tstate = PyThreadState_GET();
545+ if (!PyArg_ParseTuple(args, "i:setdlopenflags", &new_val))
546+ return NULL;
547+ if (!tstate)
548+ return NULL;
549+ tstate->interp->dlopenflags = new_val;
550+ Py_INCREF(Py_None);
551+ return Py_None;
552+}
553+
554+PyDoc_STRVAR(setdlopenflags_doc,
555+"setdlopenflags(n) -> None\n\
556+\n\
557+Set the flags that will be used for dlopen() calls. Among other\n\
558+things, this will enable a lazy resolving of symbols when importing\n\
559+a module, if called as sys.setdlopenflags(0)\n\
560+To share symbols across extension modules, call as\n\
561+sys.setdlopenflags(dl.RTLD_NOW|dl.RTLD_GLOBAL)"
562+);
563+
564+static PyObject *
565+sys_getdlopenflags(PyObject *self, PyObject *args)
566+{
567+ PyThreadState *tstate = PyThreadState_GET();
568+ if (!tstate)
569+ return NULL;
570+ return PyInt_FromLong(tstate->interp->dlopenflags);
571+}
572+
573+PyDoc_STRVAR(getdlopenflags_doc,
574+"getdlopenflags() -> int\n\
575+\n\
576+Return the current value of the flags that are used for dlopen()\n\
577+calls. The flag constants are defined in the dl module."
578+);
579+#endif
580+
581+#ifdef USE_MALLOPT
582+/* Link with -lmalloc (or -lmpc) on an SGI */
583+#include <malloc.h>
584+
585+static PyObject *
586+sys_mdebug(PyObject *self, PyObject *args)
587+{
588+ int flag;
589+ if (!PyArg_ParseTuple(args, "i:mdebug", &flag))
590+ return NULL;
591+ mallopt(M_DEBUG, flag);
592+ Py_INCREF(Py_None);
593+ return Py_None;
594+}
595+#endif /* USE_MALLOPT */
596+
597+static PyObject *
598+sys_getrefcount(PyObject *self, PyObject *arg)
599+{
600+ return PyInt_FromSsize_t(arg->ob_refcnt);
601+}
602+
603+#ifdef Py_REF_DEBUG
604+static PyObject *
605+sys_gettotalrefcount(PyObject *self)
606+{
607+ return PyInt_FromSsize_t(_Py_GetRefTotal());
608+}
609+#endif /* Py_REF_DEBUG */
610+
611+PyDoc_STRVAR(getrefcount_doc,
612+"getrefcount(object) -> integer\n\
613+\n\
614+Return the reference count of object. The count returned is generally\n\
615+one higher than you might expect, because it includes the (temporary)\n\
616+reference as an argument to getrefcount()."
617+);
618+
619+#ifdef COUNT_ALLOCS
620+static PyObject *
621+sys_getcounts(PyObject *self)
622+{
623+ extern PyObject *get_counts(void);
624+
625+ return get_counts();
626+}
627+#endif
628+
629+PyDoc_STRVAR(getframe_doc,
630+"_getframe([depth]) -> frameobject\n\
631+\n\
632+Return a frame object from the call stack. If optional integer depth is\n\
633+given, return the frame object that many calls below the top of the stack.\n\
634+If that is deeper than the call stack, ValueError is raised. The default\n\
635+for depth is zero, returning the frame at the top of the call stack.\n\
636+\n\
637+This function should be used for internal and specialized\n\
638+purposes only."
639+);
640+
641+static PyObject *
642+sys_getframe(PyObject *self, PyObject *args)
643+{
644+ PyFrameObject *f = PyThreadState_GET()->frame;
645+ int depth = -1;
646+
647+ if (!PyArg_ParseTuple(args, "|i:_getframe", &depth))
648+ return NULL;
649+
650+ while (depth > 0 && f != NULL) {
651+ f = f->f_back;
652+ --depth;
653+ }
654+ if (f == NULL) {
655+ PyErr_SetString(PyExc_ValueError,
656+ "call stack is not deep enough");
657+ return NULL;
658+ }
659+ Py_INCREF(f);
660+ return (PyObject*)f;
661+}
662+
663+PyDoc_STRVAR(current_frames_doc,
664+"_current_frames() -> dictionary\n\
665+\n\
666+Return a dictionary mapping each current thread T's thread id to T's\n\
667+current stack frame.\n\
668+\n\
669+This function should be used for specialized purposes only."
670+);
671+
672+static PyObject *
673+sys_current_frames(PyObject *self, PyObject *noargs)
674+{
675+ return _PyThread_CurrentFrames();
676+}
677+
678+PyDoc_STRVAR(call_tracing_doc,
679+"call_tracing(func, args) -> object\n\
680+\n\
681+Call func(*args), while tracing is enabled. The tracing state is\n\
682+saved, and restored afterwards. This is intended to be called from\n\
683+a debugger from a checkpoint, to recursively debug some other code."
684+);
685+
686+static PyObject *
687+sys_call_tracing(PyObject *self, PyObject *args)
688+{
689+ PyObject *func, *funcargs;
690+ if (!PyArg_UnpackTuple(args, "call_tracing", 2, 2, &func, &funcargs))
691+ return NULL;
692+ return _PyEval_CallTracing(func, funcargs);
693+}
694+
695+PyDoc_STRVAR(callstats_doc,
696+"callstats() -> tuple of integers\n\
697+\n\
698+Return a tuple of function call statistics, if CALL_PROFILE was defined\n\
699+when Python was built. Otherwise, return None.\n\
700+\n\
701+When enabled, this function returns detailed, implementation-specific\n\
702+details about the number of function calls executed. The return value is\n\
703+a 11-tuple where the entries in the tuple are counts of:\n\
704+0. all function calls\n\
705+1. calls to PyFunction_Type objects\n\
706+2. PyFunction calls that do not create an argument tuple\n\
707+3. PyFunction calls that do not create an argument tuple\n\
708+ and bypass PyEval_EvalCodeEx()\n\
709+4. PyMethod calls\n\
710+5. PyMethod calls on bound methods\n\
711+6. PyType calls\n\
712+7. PyCFunction calls\n\
713+8. generator calls\n\
714+9. All other calls\n\
715+10. Number of stack pops performed by call_function()"
716+);
717+
718+#ifdef __cplusplus
719+extern "C" {
720+#endif
721+
722+#ifdef Py_TRACE_REFS
723+/* Defined in objects.c because it uses static globals if that file */
724+extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
725+#endif
726+
727+#ifdef DYNAMIC_EXECUTION_PROFILE
728+/* Defined in ceval.c because it uses static globals if that file */
729+extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *);
730+#endif
731+
732+#ifdef __cplusplus
733+}
734+#endif
735+
736+static PyMethodDef sys_methods[] = {
737+ /* Might as well keep this in alphabetic order */
738+ {"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,
739+ callstats_doc},
740+ {"_current_frames", sys_current_frames, METH_NOARGS,
741+ current_frames_doc},
742+ {"displayhook", sys_displayhook, METH_O, displayhook_doc},
743+ {"exc_info", sys_exc_info, METH_NOARGS, exc_info_doc},
744+ {"exc_clear", sys_exc_clear, METH_NOARGS, exc_clear_doc},
745+ {"excepthook", sys_excepthook, METH_VARARGS, excepthook_doc},
746+ {"exit", sys_exit, METH_VARARGS, exit_doc},
747+#ifdef Py_USING_UNICODE
748+ {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding,
749+ METH_NOARGS, getdefaultencoding_doc},
750+#endif
751+#ifdef HAVE_DLOPEN
752+ {"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS,
753+ getdlopenflags_doc},
754+#endif
755+#ifdef COUNT_ALLOCS
756+ {"getcounts", (PyCFunction)sys_getcounts, METH_NOARGS},
757+#endif
758+#ifdef DYNAMIC_EXECUTION_PROFILE
759+ {"getdxp", _Py_GetDXProfile, METH_VARARGS},
760+#endif
761+#ifdef Py_USING_UNICODE
762+ {"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding,
763+ METH_NOARGS, getfilesystemencoding_doc},
764+#endif
765+#ifdef Py_TRACE_REFS
766+ {"getobjects", _Py_GetObjects, METH_VARARGS},
767+#endif
768+#ifdef Py_REF_DEBUG
769+ {"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS},
770+#endif
771+ {"getrefcount", (PyCFunction)sys_getrefcount, METH_O, getrefcount_doc},
772+ {"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS,
773+ getrecursionlimit_doc},
774+ {"_getframe", sys_getframe, METH_VARARGS, getframe_doc},
775+#ifdef MS_WINDOWS
776+ {"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS,
777+ getwindowsversion_doc},
778+#endif /* MS_WINDOWS */
779+#ifdef USE_MALLOPT
780+ {"mdebug", sys_mdebug, METH_VARARGS},
781+#endif
782+#ifdef Py_USING_UNICODE
783+ {"setdefaultencoding", sys_setdefaultencoding, METH_VARARGS,
784+ setdefaultencoding_doc},
785+#endif
786+ {"setcheckinterval", sys_setcheckinterval, METH_VARARGS,
787+ setcheckinterval_doc},
788+ {"getcheckinterval", sys_getcheckinterval, METH_NOARGS,
789+ getcheckinterval_doc},
790+#ifdef HAVE_DLOPEN
791+ {"setdlopenflags", sys_setdlopenflags, METH_VARARGS,
792+ setdlopenflags_doc},
793+#endif
794+ {"setprofile", sys_setprofile, METH_O, setprofile_doc},
795+ {"setrecursionlimit", sys_setrecursionlimit, METH_VARARGS,
796+ setrecursionlimit_doc},
797+#ifdef WITH_TSC
798+ {"settscdump", sys_settscdump, METH_VARARGS, settscdump_doc},
799+#endif
800+ {"settrace", sys_settrace, METH_O, settrace_doc},
801+ {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc},
802+ {NULL, NULL} /* sentinel */
803+};
804+
805+static PyObject *
806+list_builtin_module_names(void)
807+{
808+ PyObject *list = PyList_New(0);
809+ int i;
810+ if (list == NULL)
811+ return NULL;
812+ for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
813+ PyObject *name = PyString_FromString(
814+ PyImport_Inittab[i].name);
815+ if (name == NULL)
816+ break;
817+ PyList_Append(list, name);
818+ Py_DECREF(name);
819+ }
820+ if (PyList_Sort(list) != 0) {
821+ Py_DECREF(list);
822+ list = NULL;
823+ }
824+ if (list) {
825+ PyObject *v = PyList_AsTuple(list);
826+ Py_DECREF(list);
827+ list = v;
828+ }
829+ return list;
830+}
831+
832+static PyObject *warnoptions = NULL;
833+
834+void
835+PySys_ResetWarnOptions(void)
836+{
837+ if (warnoptions == NULL || !PyList_Check(warnoptions))
838+ return;
839+ PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
840+}
841+
842+void
843+PySys_AddWarnOption(char *s)
844+{
845+ PyObject *str;
846+
847+ if (warnoptions == NULL || !PyList_Check(warnoptions)) {
848+ Py_XDECREF(warnoptions);
849+ warnoptions = PyList_New(0);
850+ if (warnoptions == NULL)
851+ return;
852+ }
853+ str = PyString_FromString(s);
854+ if (str != NULL) {
855+ PyList_Append(warnoptions, str);
856+ Py_DECREF(str);
857+ }
858+}
859+
860+/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
861+ Two literals concatenated works just fine. If you have a K&R compiler
862+ or other abomination that however *does* understand longer strings,
863+ get rid of the !!! comment in the middle and the quotes that surround it. */
864+PyDoc_VAR(sys_doc) =
865+PyDoc_STR(
866+"This module provides access to some objects used or maintained by the\n\
867+interpreter and to functions that interact strongly with the interpreter.\n\
868+\n\
869+Dynamic objects:\n\
870+\n\
871+argv -- command line arguments; argv[0] is the script pathname if known\n\
872+path -- module search path; path[0] is the script directory, else ''\n\
873+modules -- dictionary of loaded modules\n\
874+\n\
875+displayhook -- called to show results in an interactive session\n\
876+excepthook -- called to handle any uncaught exception other than SystemExit\n\
877+ To customize printing in an interactive session or to install a custom\n\
878+ top-level exception handler, assign other functions to replace these.\n\
879+\n\
880+exitfunc -- if sys.exitfunc exists, this routine is called when Python exits\n\
881+ Assigning to sys.exitfunc is deprecated; use the atexit module instead.\n\
882+\n\
883+stdin -- standard input file object; used by raw_input() and input()\n\
884+stdout -- standard output file object; used by the print statement\n\
885+stderr -- standard error object; used for error messages\n\
886+ By assigning other file objects (or objects that behave like files)\n\
887+ to these, it is possible to redirect all of the interpreter's I/O.\n\
888+\n\
889+last_type -- type of last uncaught exception\n\
890+last_value -- value of last uncaught exception\n\
891+last_traceback -- traceback of last uncaught exception\n\
892+ These three are only available in an interactive session after a\n\
893+ traceback has been printed.\n\
894+\n\
895+exc_type -- type of exception currently being handled\n\
896+exc_value -- value of exception currently being handled\n\
897+exc_traceback -- traceback of exception currently being handled\n\
898+ The function exc_info() should be used instead of these three,\n\
899+ because it is thread-safe.\n\
900+"
901+)
902+/* concatenating string here */
903+PyDoc_STR(
904+"\n\
905+Static objects:\n\
906+\n\
907+maxint -- the largest supported integer (the smallest is -maxint-1)\n\
908+maxunicode -- the largest supported character\n\
909+builtin_module_names -- tuple of module names built into this interpreter\n\
910+version -- the version of this interpreter as a string\n\
911+version_info -- version information as a tuple\n\
912+hexversion -- version information encoded as a single integer\n\
913+copyright -- copyright notice pertaining to this interpreter\n\
914+platform -- platform identifier\n\
915+executable -- pathname of this Python interpreter\n\
916+prefix -- prefix used to find the Python library\n\
917+exec_prefix -- prefix used to find the machine-specific Python library\n\
918+"
919+)
920+#ifdef MS_WINDOWS
921+/* concatenating string here */
922+PyDoc_STR(
923+"dllhandle -- [Windows only] integer handle of the Python DLL\n\
924+winver -- [Windows only] version number of the Python DLL\n\
925+"
926+)
927+#endif /* MS_WINDOWS */
928+PyDoc_STR(
929+"__stdin__ -- the original stdin; don't touch!\n\
930+__stdout__ -- the original stdout; don't touch!\n\
931+__stderr__ -- the original stderr; don't touch!\n\
932+__displayhook__ -- the original displayhook; don't touch!\n\
933+__excepthook__ -- the original excepthook; don't touch!\n\
934+\n\
935+Functions:\n\
936+\n\
937+displayhook() -- print an object to the screen, and save it in __builtin__._\n\
938+excepthook() -- print an exception and its traceback to sys.stderr\n\
939+exc_info() -- return thread-safe information about the current exception\n\
940+exc_clear() -- clear the exception state for the current thread\n\
941+exit() -- exit the interpreter by raising SystemExit\n\
942+getdlopenflags() -- returns flags to be used for dlopen() calls\n\
943+getrefcount() -- return the reference count for an object (plus one :-)\n\
944+getrecursionlimit() -- return the max recursion depth for the interpreter\n\
945+setcheckinterval() -- control how often the interpreter checks for events\n\
946+setdlopenflags() -- set the flags to be used for dlopen() calls\n\
947+setprofile() -- set the global profiling function\n\
948+setrecursionlimit() -- set the max recursion depth for the interpreter\n\
949+settrace() -- set the global debug tracing function\n\
950+"
951+)
952+/* end of sys_doc */ ;
953+
954+static int
955+_check_and_flush (FILE *stream)
956+{
957+ int prev_fail = ferror (stream);
958+ return fflush (stream) || prev_fail ? EOF : 0;
959+}
960+
961+/* Subversion branch and revision management */
962+static const char _patchlevel_revision[] = PY_PATCHLEVEL_REVISION;
963+static const char headurl[] = "$HeadURL: svn+ssh://pythondev@svn.python.org/python/tags/r251/Python/sysmodule.c $";
964+static int svn_initialized;
965+static char patchlevel_revision[50]; /* Just the number */
966+static char branch[50];
967+static char shortbranch[50];
968+static const char *svn_revision;
969+
970+static void
971+svnversion_init(void)
972+{
973+ const char *python, *br_start, *br_end, *br_end2, *svnversion;
974+ Py_ssize_t len;
975+ int istag;
976+
977+ if (svn_initialized)
978+ return;
979+
980+ python = strstr(headurl, "/python/");
981+ if (!python)
982+ Py_FatalError("subversion keywords missing");
983+
984+ br_start = python + 8;
985+ br_end = strchr(br_start, '/');
986+ assert(br_end);
987+
988+ /* Works even for trunk,
989+ as we are in trunk/Python/sysmodule.c */
990+ br_end2 = strchr(br_end+1, '/');
991+
992+ istag = strncmp(br_start, "tags", 4) == 0;
993+ if (strncmp(br_start, "trunk", 5) == 0) {
994+ strcpy(branch, "trunk");
995+ strcpy(shortbranch, "trunk");
996+
997+ }
998+ else if (istag || strncmp(br_start, "branches", 8) == 0) {
999+ len = br_end2 - br_start;
1000+ strncpy(branch, br_start, len);
1001+ branch[len] = '\0';
1002+
1003+ len = br_end2 - (br_end + 1);
1004+ strncpy(shortbranch, br_end + 1, len);
1005+ shortbranch[len] = '\0';
1006+ }
1007+ else {
1008+ Py_FatalError("bad HeadURL");
1009+ return;
1010+ }
1011+
1012+
1013+ svnversion = _Py_svnversion();
1014+ if (strcmp(svnversion, "exported") != 0)
1015+ svn_revision = svnversion;
1016+ else if (istag) {
1017+ len = strlen(_patchlevel_revision);
1018+ strncpy(patchlevel_revision, _patchlevel_revision + 11,
1019+ len - 13);
1020+ patchlevel_revision[len - 13] = '\0';
1021+ svn_revision = patchlevel_revision;
1022+ }
1023+ else
1024+ svn_revision = "";
1025+
1026+ svn_initialized = 1;
1027+}
1028+
1029+/* Return svnversion output if available.
1030+ Else return Revision of patchlevel.h if on branch.
1031+ Else return empty string */
1032+const char*
1033+Py_SubversionRevision()
1034+{
1035+ svnversion_init();
1036+ return svn_revision;
1037+}
1038+
1039+const char*
1040+Py_SubversionShortBranch()
1041+{
1042+ svnversion_init();
1043+ return shortbranch;
1044+}
1045+
1046+PyObject *
1047+_PySys_Init(void)
1048+{
1049+ PyObject *m, *v, *sysdict;
1050+ PyObject *sysin, *sysout, *syserr;
1051+ char *s;
1052+#ifdef MS_WINDOWS
1053+ char buf[128];
1054+#endif
1055+
1056+ m = Py_InitModule3("sys", sys_methods, sys_doc);
1057+ if (m == NULL)
1058+ return NULL;
1059+ sysdict = PyModule_GetDict(m);
1060+
1061+ {
1062+ /* XXX: does this work on Win/Win64? (see posix_fstat) */
1063+ struct stat sb;
1064+ if (fstat(fileno(stdin), &sb) == 0 &&
1065+ S_ISDIR(sb.st_mode)) {
1066+ /* There's nothing more we can do. */
1067+ /* Py_FatalError() will core dump, so just exit. */
1068+ PySys_WriteStderr("Python error: <stdin> is a directory, cannot continue\n");
1069+ exit(EXIT_FAILURE);
1070+ }
1071+ }
1072+
1073+ /* Closing the standard FILE* if sys.std* goes aways causes problems
1074+ * for embedded Python usages. Closing them when somebody explicitly
1075+ * invokes .close() might be possible, but the FAQ promises they get
1076+ * never closed. However, we still need to get write errors when
1077+ * writing fails (e.g. because stdout is redirected), so we flush the
1078+ * streams and check for errors before the file objects are deleted.
1079+ * On OS X, fflush()ing stdin causes an error, so we exempt stdin
1080+ * from that procedure.
1081+ */
1082+ sysin = PyFile_FromFile(stdin, "<stdin>", "r", NULL);
1083+ sysout = PyFile_FromFile(stdout, "<stdout>", "w", _check_and_flush);
1084+ syserr = PyFile_FromFile(stderr, "<stderr>", "w", _check_and_flush);
1085+ if (PyErr_Occurred())
1086+ return NULL;
1087+#ifdef MS_WINDOWS
1088+ if(isatty(_fileno(stdin)) && PyFile_Check(sysin)) {
1089+ sprintf(buf, "cp%d", GetConsoleCP());
1090+ if (!PyFile_SetEncoding(sysin, buf))
1091+ return NULL;
1092+ }
1093+ if(isatty(_fileno(stdout)) && PyFile_Check(sysout)) {
1094+ sprintf(buf, "cp%d", GetConsoleOutputCP());
1095+ if (!PyFile_SetEncoding(sysout, buf))
1096+ return NULL;
1097+ }
1098+ if(isatty(_fileno(stderr)) && PyFile_Check(syserr)) {
1099+ sprintf(buf, "cp%d", GetConsoleOutputCP());
1100+ if (!PyFile_SetEncoding(syserr, buf))
1101+ return NULL;
1102+ }
1103+#endif
1104+
1105+ PyDict_SetItemString(sysdict, "stdin", sysin);
1106+ PyDict_SetItemString(sysdict, "stdout", sysout);
1107+ PyDict_SetItemString(sysdict, "stderr", syserr);
1108+ /* Make backup copies for cleanup */
1109+ PyDict_SetItemString(sysdict, "__stdin__", sysin);
1110+ PyDict_SetItemString(sysdict, "__stdout__", sysout);
1111+ PyDict_SetItemString(sysdict, "__stderr__", syserr);
1112+ PyDict_SetItemString(sysdict, "__displayhook__",
1113+ PyDict_GetItemString(sysdict, "displayhook"));
1114+ PyDict_SetItemString(sysdict, "__excepthook__",
1115+ PyDict_GetItemString(sysdict, "excepthook"));
1116+ Py_XDECREF(sysin);
1117+ Py_XDECREF(sysout);
1118+ Py_XDECREF(syserr);
1119+ PyDict_SetItemString(sysdict, "version",
1120+ v = PyString_FromString(Py_GetVersion()));
1121+ Py_XDECREF(v);
1122+ PyDict_SetItemString(sysdict, "hexversion",
1123+ v = PyInt_FromLong(PY_VERSION_HEX));
1124+ Py_XDECREF(v);
1125+ svnversion_init();
1126+ v = Py_BuildValue("(ssz)", "CPython", branch, svn_revision);
1127+ PyDict_SetItemString(sysdict, "subversion", v);
1128+ Py_XDECREF(v);
1129+ /*
1130+ * These release level checks are mutually exclusive and cover
1131+ * the field, so don't get too fancy with the pre-processor!
1132+ */
1133+#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
1134+ s = "alpha";
1135+#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
1136+ s = "beta";
1137+#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
1138+ s = "candidate";
1139+#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
1140+ s = "final";
1141+#endif
1142+
1143+#define SET_SYS_FROM_STRING(key, value) \
1144+ v = value; \
1145+ if (v != NULL) \
1146+ PyDict_SetItemString(sysdict, key, v); \
1147+ Py_XDECREF(v)
1148+
1149+ SET_SYS_FROM_STRING("version_info",
1150+ Py_BuildValue("iiisi", PY_MAJOR_VERSION,
1151+ PY_MINOR_VERSION,
1152+ PY_MICRO_VERSION, s,
1153+ PY_RELEASE_SERIAL));
1154+ SET_SYS_FROM_STRING("api_version",
1155+ PyInt_FromLong(PYTHON_API_VERSION));
1156+ SET_SYS_FROM_STRING("copyright",
1157+ PyString_FromString(Py_GetCopyright()));
1158+ SET_SYS_FROM_STRING("platform",
1159+ PyString_FromString(Py_GetPlatform()));
1160+ SET_SYS_FROM_STRING("executable",
1161+ PyString_FromString(Py_GetProgramFullPath()));
1162+ SET_SYS_FROM_STRING("prefix",
1163+ PyString_FromString(Py_GetPrefix()));
1164+ SET_SYS_FROM_STRING("exec_prefix",
1165+ PyString_FromString(Py_GetExecPrefix()));
1166+ SET_SYS_FROM_STRING("maxint",
1167+ PyInt_FromLong(PyInt_GetMax()));
1168+#ifdef Py_USING_UNICODE
1169+ SET_SYS_FROM_STRING("maxunicode",
1170+ PyInt_FromLong(PyUnicode_GetMax()));
1171+#endif
1172+ SET_SYS_FROM_STRING("builtin_module_names",
1173+ list_builtin_module_names());
1174+ {
1175+ /* Assumes that longs are at least 2 bytes long.
1176+ Should be safe! */
1177+ unsigned long number = 1;
1178+ char *value;
1179+
1180+ s = (char *) &number;
1181+ if (s[0] == 0)
1182+ value = "big";
1183+ else
1184+ value = "little";
1185+ SET_SYS_FROM_STRING("byteorder",
1186+ PyString_FromString(value));
1187+ }
1188+#ifdef MS_COREDLL
1189+ SET_SYS_FROM_STRING("dllhandle",
1190+ PyLong_FromVoidPtr(PyWin_DLLhModule));
1191+ SET_SYS_FROM_STRING("winver",
1192+ PyString_FromString(PyWin_DLLVersionString));
1193+#endif
1194+#undef SET_SYS_FROM_STRING
1195+ if (warnoptions == NULL) {
1196+ warnoptions = PyList_New(0);
1197+ }
1198+ else {
1199+ Py_INCREF(warnoptions);
1200+ }
1201+ if (warnoptions != NULL) {
1202+ PyDict_SetItemString(sysdict, "warnoptions", warnoptions);
1203+ }
1204+
1205+ if (PyErr_Occurred())
1206+ return NULL;
1207+ return m;
1208+}
1209+
1210+static PyObject *
1211+makepathobject(char *path, int delim)
1212+{
1213+ int i, n;
1214+ char *p;
1215+ PyObject *v, *w;
1216+
1217+ n = 1;
1218+ p = path;
1219+ while ((p = strchr(p, delim)) != NULL) {
1220+ n++;
1221+ p++;
1222+ }
1223+ v = PyList_New(n);
1224+ if (v == NULL)
1225+ return NULL;
1226+ for (i = 0; ; i++) {
1227+ p = strchr(path, delim);
1228+ if (p == NULL)
1229+ p = strchr(path, '\0'); /* End of string */
1230+ w = PyString_FromStringAndSize(path, (Py_ssize_t) (p - path));
1231+ if (w == NULL) {
1232+ Py_DECREF(v);
1233+ return NULL;
1234+ }
1235+ PyList_SetItem(v, i, w);
1236+ if (*p == '\0')
1237+ break;
1238+ path = p+1;
1239+ }
1240+ return v;
1241+}
1242+
1243+void
1244+PySys_SetPath(char *path)
1245+{
1246+ PyObject *v;
1247+ if ((v = makepathobject(path, DELIM)) == NULL)
1248+ Py_FatalError("can't create sys.path");
1249+ if (PySys_SetObject("path", v) != 0)
1250+ Py_FatalError("can't assign sys.path");
1251+ Py_DECREF(v);
1252+}
1253+
1254+static PyObject *
1255+makeargvobject(int argc, char **argv)
1256+{
1257+ PyObject *av;
1258+ if (argc <= 0 || argv == NULL) {
1259+ /* Ensure at least one (empty) argument is seen */
1260+ static char *empty_argv[1] = {""};
1261+ argv = empty_argv;
1262+ argc = 1;
1263+ }
1264+ av = PyList_New(argc);
1265+ if (av != NULL) {
1266+ int i;
1267+ for (i = 0; i < argc; i++) {
1268+#ifdef __VMS
1269+ PyObject *v;
1270+
1271+ /* argv[0] is the script pathname if known */
1272+ if (i == 0) {
1273+ char* fn = decc$translate_vms(argv[0]);
1274+ if ((fn == (char *)0) || fn == (char *)-1)
1275+ v = PyString_FromString(argv[0]);
1276+ else
1277+ v = PyString_FromString(
1278+ decc$translate_vms(argv[0]));
1279+ } else
1280+ v = PyString_FromString(argv[i]);
1281+#else
1282+ PyObject *v = PyString_FromString(argv[i]);
1283+#endif
1284+ if (v == NULL) {
1285+ Py_DECREF(av);
1286+ av = NULL;
1287+ break;
1288+ }
1289+ PyList_SetItem(av, i, v);
1290+ }
1291+ }
1292+ return av;
1293+}
1294+
1295+void
1296+PySys_SetArgv(int argc, char **argv)
1297+{
1298+#if defined(HAVE_REALPATH)
1299+ char fullpath[MAXPATHLEN];
1300+#elif defined(MS_WINDOWS)
1301+ char fullpath[MAX_PATH];
1302+#endif
1303+ PyObject *av = makeargvobject(argc, argv);
1304+ PyObject *path = PySys_GetObject("path");
1305+ if (av == NULL)
1306+ Py_FatalError("no mem for sys.argv");
1307+ if (PySys_SetObject("argv", av) != 0)
1308+ Py_FatalError("can't assign sys.argv");
1309+ if (path != NULL) {
1310+ char *argv0 = argv[0];
1311+ char *p = NULL;
1312+ Py_ssize_t n = 0;
1313+ PyObject *a;
1314+#ifdef HAVE_READLINK
1315+ char link[MAXPATHLEN+1];
1316+ char argv0copy[2*MAXPATHLEN+1];
1317+ int nr = 0;
1318+ if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0)
1319+ nr = readlink(argv0, link, MAXPATHLEN);
1320+ if (nr > 0) {
1321+ /* It's a symlink */
1322+ link[nr] = '\0';
1323+ if (link[0] == SEP)
1324+ argv0 = link; /* Link to absolute path */
1325+ else if (strchr(link, SEP) == NULL)
1326+ ; /* Link without path */
1327+ else {
1328+ /* Must join(dirname(argv0), link) */
1329+ char *q = strrchr(argv0, SEP);
1330+ if (q == NULL)
1331+ argv0 = link; /* argv0 without path */
1332+ else {
1333+ /* Must make a copy */
1334+ strcpy(argv0copy, argv0);
1335+ q = strrchr(argv0copy, SEP);
1336+ strcpy(q+1, link);
1337+ argv0 = argv0copy;
1338+ }
1339+ }
1340+ }
1341+#endif /* HAVE_READLINK */
1342+#if SEP == '\\' /* Special case for MS filename syntax */
1343+ if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) {
1344+ char *q;
1345+#ifdef MS_WINDOWS
1346+ char *ptemp;
1347+ if (GetFullPathName(argv0,
1348+ sizeof(fullpath),
1349+ fullpath,
1350+ &ptemp)) {
1351+ argv0 = fullpath;
1352+ }
1353+#endif
1354+ p = strrchr(argv0, SEP);
1355+ /* Test for alternate separator */
1356+ q = strrchr(p ? p : argv0, '/');
1357+ if (q != NULL)
1358+ p = q;
1359+ if (p != NULL) {
1360+ n = p + 1 - argv0;
1361+ if (n > 1 && p[-1] != ':')
1362+ n--; /* Drop trailing separator */
1363+ }
1364+ }
1365+#else /* All other filename syntaxes */
1366+ if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) {
1367+#if defined(HAVE_REALPATH)
1368+ if (realpath(argv0, fullpath)) {
1369+ argv0 = fullpath;
1370+ }
1371+#endif
1372+ p = strrchr(argv0, SEP);
1373+ }
1374+ if (p != NULL) {
1375+#ifndef RISCOS
1376+ n = p + 1 - argv0;
1377+#else /* don't include trailing separator */
1378+ n = p - argv0;
1379+#endif /* RISCOS */
1380+#if SEP == '/' /* Special case for Unix filename syntax */
1381+ if (n > 1)
1382+ n--; /* Drop trailing separator */
1383+#endif /* Unix */
1384+ }
1385+#endif /* All others */
1386+ a = PyString_FromStringAndSize(argv0, n);
1387+ if (a == NULL)
1388+ Py_FatalError("no mem for sys.path insertion");
1389+ if (PyList_Insert(path, 0, a) < 0)
1390+ Py_FatalError("sys.path.insert(0) failed");
1391+ Py_DECREF(a);
1392+ }
1393+ Py_DECREF(av);
1394+}
1395+
1396+
1397+/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
1398+ Adapted from code submitted by Just van Rossum.
1399+
1400+ PySys_WriteStdout(format, ...)
1401+ PySys_WriteStderr(format, ...)
1402+
1403+ The first function writes to sys.stdout; the second to sys.stderr. When
1404+ there is a problem, they write to the real (C level) stdout or stderr;
1405+ no exceptions are raised.
1406+
1407+ Both take a printf-style format string as their first argument followed
1408+ by a variable length argument list determined by the format string.
1409+
1410+ *** WARNING ***
1411+
1412+ The format should limit the total size of the formatted output string to
1413+ 1000 bytes. In particular, this means that no unrestricted "%s" formats
1414+ should occur; these should be limited using "%.<N>s where <N> is a
1415+ decimal number calculated so that <N> plus the maximum size of other
1416+ formatted text does not exceed 1000 bytes. Also watch out for "%f",
1417+ which can print hundreds of digits for very large numbers.
1418+
1419+ */
1420+
1421+static void
1422+mywrite(char *name, FILE *fp, const char *format, va_list va)
1423+{
1424+ PyObject *file;
1425+ PyObject *error_type, *error_value, *error_traceback;
1426+
1427+ PyErr_Fetch(&error_type, &error_value, &error_traceback);
1428+ file = PySys_GetObject(name);
1429+ if (file == NULL || PyFile_AsFile(file) == fp)
1430+ vfprintf(fp, format, va);
1431+ else {
1432+ char buffer[1001];
1433+ const int written = PyOS_vsnprintf(buffer, sizeof(buffer),
1434+ format, va);
1435+ if (PyFile_WriteString(buffer, file) != 0) {
1436+ PyErr_Clear();
1437+ fputs(buffer, fp);
1438+ }
1439+ if (written < 0 || (size_t)written >= sizeof(buffer)) {
1440+ const char *truncated = "... truncated";
1441+ if (PyFile_WriteString(truncated, file) != 0) {
1442+ PyErr_Clear();
1443+ fputs(truncated, fp);
1444+ }
1445+ }
1446+ }
1447+ PyErr_Restore(error_type, error_value, error_traceback);
1448+}
1449+
1450+void
1451+PySys_WriteStdout(const char *format, ...)
1452+{
1453+ va_list va;
1454+
1455+ va_start(va, format);
1456+ mywrite("stdout", stdout, format, va);
1457+ va_end(va);
1458+}
1459+
1460+void
1461+PySys_WriteStderr(const char *format, ...)
1462+{
1463+ va_list va;
1464+
1465+ va_start(va, format);
1466+ mywrite("stderr", stderr, format, va);
1467+ va_end(va);
1468+}