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