diff options
Diffstat (limited to 'Python/sysmodule.c')
| -rw-r--r-- | Python/sysmodule.c | 1021 | 
1 files changed, 356 insertions, 665 deletions
| diff --git a/Python/sysmodule.c b/Python/sysmodule.c index ea095d2..814eccb 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -15,14 +15,16 @@ Data members:  */  #include "Python.h" +#include "structseq.h"  #include "code.h"  #include "frameobject.h" +#include "eval.h"  #include "osdefs.h"  #ifdef MS_WINDOWS  #define WIN32_LEAN_AND_MEAN -#include <windows.h> +#include "windows.h"  #endif /* MS_WINDOWS */  #ifdef MS_COREDLL @@ -35,13 +37,17 @@ extern const char *PyWin_DLLVersionString;  #include <unixlib.h>  #endif +#ifdef MS_WINDOWS +#include <windows.h> +#endif +  #ifdef HAVE_LANGINFO_H  #include <locale.h>  #include <langinfo.h>  #endif  PyObject * -PySys_GetObject(const char *name) +PySys_GetObject(char *name)  {      PyThreadState *tstate = PyThreadState_GET();      PyObject *sd = tstate->interp->sysdict; @@ -50,8 +56,20 @@ PySys_GetObject(const char *name)      return PyDict_GetItemString(sd, name);  } +FILE * +PySys_GetFile(char *name, FILE *def) +{ +    FILE *fp = NULL; +    PyObject *v = PySys_GetObject(name); +    if (v != NULL && PyFile_Check(v)) +        fp = PyFile_AsFile(v); +    if (fp == NULL) +        fp = def; +    return fp; +} +  int -PySys_SetObject(const char *name, PyObject *v) +PySys_SetObject(char *name, PyObject *v)  {      PyThreadState *tstate = PyThreadState_GET();      PyObject *sd = tstate->interp->sysdict; @@ -65,79 +83,16 @@ PySys_SetObject(const char *name, PyObject *v)          return PyDict_SetItemString(sd, name, v);  } -/* Write repr(o) to sys.stdout using sys.stdout.encoding and 'backslashreplace' -   error handler. If sys.stdout has a buffer attribute, use -   sys.stdout.buffer.write(encoded), otherwise redecode the string and use -   sys.stdout.write(redecoded). - -   Helper function for sys_displayhook(). */ -static int -sys_displayhook_unencodable(PyObject *outf, PyObject *o) -{ -    PyObject *stdout_encoding = NULL; -    PyObject *encoded, *escaped_str, *repr_str, *buffer, *result; -    char *stdout_encoding_str; -    int ret; - -    stdout_encoding = PyObject_GetAttrString(outf, "encoding"); -    if (stdout_encoding == NULL) -        goto error; -    stdout_encoding_str = _PyUnicode_AsString(stdout_encoding); -    if (stdout_encoding_str == NULL) -        goto error; - -    repr_str = PyObject_Repr(o); -    if (repr_str == NULL) -        goto error; -    encoded = PyUnicode_AsEncodedString(repr_str, -                                        stdout_encoding_str, -                                        "backslashreplace"); -    Py_DECREF(repr_str); -    if (encoded == NULL) -        goto error; - -    buffer = PyObject_GetAttrString(outf, "buffer"); -    if (buffer) { -        result = PyObject_CallMethod(buffer, "write", "(O)", encoded); -        Py_DECREF(buffer); -        Py_DECREF(encoded); -        if (result == NULL) -            goto error; -        Py_DECREF(result); -    } -    else { -        PyErr_Clear(); -        escaped_str = PyUnicode_FromEncodedObject(encoded, -                                                  stdout_encoding_str, -                                                  "strict"); -        Py_DECREF(encoded); -        if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) { -            Py_DECREF(escaped_str); -            goto error; -        } -        Py_DECREF(escaped_str); -    } -    ret = 0; -    goto finally; - -error: -    ret = -1; -finally: -    Py_XDECREF(stdout_encoding); -    return ret; -} -  static PyObject *  sys_displayhook(PyObject *self, PyObject *o)  {      PyObject *outf;      PyInterpreterState *interp = PyThreadState_GET()->interp;      PyObject *modules = interp->modules; -    PyObject *builtins = PyDict_GetItemString(modules, "builtins"); -    int err; +    PyObject *builtins = PyDict_GetItemString(modules, "__builtin__");      if (builtins == NULL) { -        PyErr_SetString(PyExc_RuntimeError, "lost builtins module"); +        PyErr_SetString(PyExc_RuntimeError, "lost __builtin__");          return NULL;      } @@ -150,25 +105,17 @@ sys_displayhook(PyObject *self, PyObject *o)      }      if (PyObject_SetAttrString(builtins, "_", Py_None) != 0)          return NULL; +    if (Py_FlushLine() != 0) +        return NULL;      outf = PySys_GetObject("stdout"); -    if (outf == NULL || outf == Py_None) { +    if (outf == NULL) {          PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");          return NULL;      } -    if (PyFile_WriteObject(o, outf, 0) != 0) { -        if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { -            /* repr(o) is not encodable to sys.stdout.encoding with -             * sys.stdout.errors error handler (which is probably 'strict') */ -            PyErr_Clear(); -            err = sys_displayhook_unencodable(outf, o); -            if (err) -                return NULL; -        } -        else { -            return NULL; -        } -    } -    if (PyFile_WriteString("\n", outf) != 0) +    if (PyFile_WriteObject(o, outf, 0) != 0) +        return NULL; +    PyFile_SoftSpace(outf, 1); +    if (Py_FlushLine() != 0)          return NULL;      if (PyObject_SetAttrString(builtins, "_", o) != 0)          return NULL; @@ -179,7 +126,7 @@ sys_displayhook(PyObject *self, PyObject *o)  PyDoc_STRVAR(displayhook_doc,  "displayhook(object) -> None\n"  "\n" -"Print an object to sys.stdout and also save it in builtins._\n" +"Print an object to sys.stdout and also save it in __builtin__._\n"  );  static PyObject * @@ -220,6 +167,43 @@ clause in the current stack frame or in an older stack frame."  );  static PyObject * +sys_exc_clear(PyObject *self, PyObject *noargs) +{ +    PyThreadState *tstate; +    PyObject *tmp_type, *tmp_value, *tmp_tb; + +    if (PyErr_WarnPy3k("sys.exc_clear() not supported in 3.x; " +                       "use except clauses", 1) < 0) +        return NULL; + +    tstate = PyThreadState_GET(); +    tmp_type = tstate->exc_type; +    tmp_value = tstate->exc_value; +    tmp_tb = tstate->exc_traceback; +    tstate->exc_type = NULL; +    tstate->exc_value = NULL; +    tstate->exc_traceback = NULL; +    Py_XDECREF(tmp_type); +    Py_XDECREF(tmp_value); +    Py_XDECREF(tmp_tb); +    /* For b/w compatibility */ +    PySys_SetObject("exc_type", Py_None); +    PySys_SetObject("exc_value", Py_None); +    PySys_SetObject("exc_traceback", Py_None); +    Py_INCREF(Py_None); +    return Py_None; +} + +PyDoc_STRVAR(exc_clear_doc, +"exc_clear() -> None\n\ +\n\ +Clear global information on the current exception.  Subsequent calls to\n\ +exc_info() will return (None,None,None) until another exception is raised\n\ +in the current thread or the execution stack returns to a frame where\n\ +another exception is being handled." +); + +static PyObject *  sys_exit(PyObject *self, PyObject *args)  {      PyObject *exit_code = 0; @@ -240,11 +224,12 @@ If it is another kind of object, it will be printed and the system\n\  exit status will be one (i.e., failure)."  ); +#ifdef Py_USING_UNICODE  static PyObject *  sys_getdefaultencoding(PyObject *self)  { -    return PyUnicode_FromString(PyUnicode_GetDefaultEncoding()); +    return PyString_FromString(PyUnicode_GetDefaultEncoding());  }  PyDoc_STRVAR(getdefaultencoding_doc, @@ -255,47 +240,40 @@ implementation."  );  static PyObject * -sys_getfilesystemencoding(PyObject *self) +sys_setdefaultencoding(PyObject *self, PyObject *args)  { -    if (Py_FileSystemDefaultEncoding) -        return PyUnicode_FromString(Py_FileSystemDefaultEncoding); +    char *encoding; +    if (!PyArg_ParseTuple(args, "s:setdefaultencoding", &encoding)) +        return NULL; +    if (PyUnicode_SetDefaultEncoding(encoding)) +        return NULL;      Py_INCREF(Py_None);      return Py_None;  } -PyDoc_STRVAR(getfilesystemencoding_doc, -"getfilesystemencoding() -> string\n\ +PyDoc_STRVAR(setdefaultencoding_doc, +"setdefaultencoding(encoding)\n\  \n\ -Return the encoding used to convert Unicode filenames in\n\ -operating system filenames." +Set the current default string encoding used by the Unicode implementation."  );  static PyObject * -sys_intern(PyObject *self, PyObject *args) +sys_getfilesystemencoding(PyObject *self)  { -    PyObject *s; -    if (!PyArg_ParseTuple(args, "U:intern", &s)) -        return NULL; -    if (PyUnicode_CheckExact(s)) { -        Py_INCREF(s); -        PyUnicode_InternInPlace(&s); -        return s; -    } -    else { -        PyErr_Format(PyExc_TypeError, -                        "can't intern %.400s", s->ob_type->tp_name); -        return NULL; -    } +    if (Py_FileSystemDefaultEncoding) +        return PyString_FromString(Py_FileSystemDefaultEncoding); +    Py_INCREF(Py_None); +    return Py_None;  } -PyDoc_STRVAR(intern_doc, -"intern(string) -> string\n\ +PyDoc_STRVAR(getfilesystemencoding_doc, +"getfilesystemencoding() -> string\n\  \n\ -``Intern'' the given string.  This enters the string in the (global)\n\ -table of interned strings whose purpose is to speed up dictionary lookups.\n\ -Return the string itself or the previously interned string object with the\n\ -same value."); +Return the encoding used to convert Unicode filenames in\n\ +operating system filenames." +); +#endif  /*   * Cached interned string objects used for calling the profile and @@ -312,7 +290,7 @@ trace_init(void)      int i;      for (i = 0; i < 7; ++i) {          if (whatstrings[i] == NULL) { -            name = PyUnicode_InternFromString(whatnames[i]); +            name = PyString_InternFromString(whatnames[i]);              if (name == NULL)                  return -1;              whatstrings[i] = name; @@ -483,18 +461,12 @@ Return the profiling function set with sys.setprofile.\n\  See the profiler chapter in the library manual."  ); -static int _check_interval = 100; -  static PyObject *  sys_setcheckinterval(PyObject *self, PyObject *args)  { -    if (PyErr_WarnEx(PyExc_DeprecationWarning, -                     "sys.getcheckinterval() and sys.setcheckinterval() " -                     "are deprecated.  Use sys.setswitchinterval() " -                     "instead.", 1) < 0) -        return NULL; -    if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_check_interval)) +    if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval))          return NULL; +    _Py_Ticker = _Py_CheckInterval;      Py_INCREF(Py_None);      return Py_None;  } @@ -509,59 +481,13 @@ n instructions.  This also affects how often thread switches occur."  static PyObject *  sys_getcheckinterval(PyObject *self, PyObject *args)  { -    if (PyErr_WarnEx(PyExc_DeprecationWarning, -                     "sys.getcheckinterval() and sys.setcheckinterval() " -                     "are deprecated.  Use sys.getswitchinterval() " -                     "instead.", 1) < 0) -        return NULL; -    return PyLong_FromLong(_check_interval); +    return PyInt_FromLong(_Py_CheckInterval);  }  PyDoc_STRVAR(getcheckinterval_doc,  "getcheckinterval() -> current check interval; see setcheckinterval()."  ); -#ifdef WITH_THREAD -static PyObject * -sys_setswitchinterval(PyObject *self, PyObject *args) -{ -    double d; -    if (!PyArg_ParseTuple(args, "d:setswitchinterval", &d)) -        return NULL; -    if (d <= 0.0) { -        PyErr_SetString(PyExc_ValueError, -                        "switch interval must be strictly positive"); -        return NULL; -    } -    _PyEval_SetSwitchInterval((unsigned long) (1e6 * d)); -    Py_INCREF(Py_None); -    return Py_None; -} - -PyDoc_STRVAR(setswitchinterval_doc, -"setswitchinterval(n)\n\ -\n\ -Set the ideal thread switching delay inside the Python interpreter\n\ -The actual frequency of switching threads can be lower if the\n\ -interpreter executes long sequences of uninterruptible code\n\ -(this is implementation-specific and workload-dependent).\n\ -\n\ -The parameter must represent the desired switching delay in seconds\n\ -A typical value is 0.005 (5 milliseconds)." -); - -static PyObject * -sys_getswitchinterval(PyObject *self, PyObject *args) -{ -    return PyFloat_FromDouble(1e-6 * _PyEval_GetSwitchInterval()); -} - -PyDoc_STRVAR(getswitchinterval_doc, -"getswitchinterval() -> current thread switch interval; see setswitchinterval()." -); - -#endif /* WITH_THREAD */ -  #ifdef WITH_TSC  static PyObject *  sys_settscdump(PyObject *self, PyObject *args) @@ -605,57 +531,6 @@ sys_setrecursionlimit(PyObject *self, PyObject *args)      return Py_None;  } -static PyTypeObject Hash_InfoType; - -PyDoc_STRVAR(hash_info_doc, -"hash_info\n\ -\n\ -A struct sequence providing parameters used for computing\n\ -numeric hashes.  The attributes are read only."); - -static PyStructSequence_Field hash_info_fields[] = { -    {"width", "width of the type used for hashing, in bits"}, -    {"modulus", "prime number giving the modulus on which the hash " -                "function is based"}, -    {"inf", "value to be used for hash of a positive infinity"}, -    {"nan", "value to be used for hash of a nan"}, -    {"imag", "multiplier used for the imaginary part of a complex number"}, -    {NULL, NULL} -}; - -static PyStructSequence_Desc hash_info_desc = { -    "sys.hash_info", -    hash_info_doc, -    hash_info_fields, -    5, -}; - -static PyObject * -get_hash_info(void) -{ -    PyObject *hash_info; -    int field = 0; -    hash_info = PyStructSequence_New(&Hash_InfoType); -    if (hash_info == NULL) -        return NULL; -    PyStructSequence_SET_ITEM(hash_info, field++, -                              PyLong_FromLong(8*sizeof(Py_hash_t))); -    PyStructSequence_SET_ITEM(hash_info, field++, -                              PyLong_FromSsize_t(_PyHASH_MODULUS)); -    PyStructSequence_SET_ITEM(hash_info, field++, -                              PyLong_FromLong(_PyHASH_INF)); -    PyStructSequence_SET_ITEM(hash_info, field++, -                              PyLong_FromLong(_PyHASH_NAN)); -    PyStructSequence_SET_ITEM(hash_info, field++, -                              PyLong_FromLong(_PyHASH_IMAG)); -    if (PyErr_Occurred()) { -        Py_CLEAR(hash_info); -        return NULL; -    } -    return hash_info; -} - -  PyDoc_STRVAR(setrecursionlimit_doc,  "setrecursionlimit(n)\n\  \n\ @@ -668,7 +543,7 @@ dependent."  static PyObject *  sys_getrecursionlimit(PyObject *self)  { -    return PyLong_FromLong(Py_GetRecursionLimit()); +    return PyInt_FromLong(Py_GetRecursionLimit());  }  PyDoc_STRVAR(getrecursionlimit_doc, @@ -686,7 +561,7 @@ PyDoc_STRVAR(getwindowsversion_doc,  Return information about the running version of Windows as a named tuple.\n\  The members are named: major, minor, build, platform, service_pack,\n\  service_pack_major, service_pack_minor, suite_mask, and product_type. For\n\ -backward compatibiliy, only the first 5 items are available by indexing.\n\ +backward compatibility, only the first 5 items are available by indexing.\n\  All elements are numbers, except service_pack which is a string. Platform\n\  may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP/Vista/7,\n\  3 for Windows CE. Product_type may be 1 for a workstation, 2 for a domain\n\ @@ -731,15 +606,15 @@ sys_getwindowsversion(PyObject *self)      if (version == NULL)          return NULL; -    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMajorVersion)); -    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMinorVersion)); -    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwBuildNumber)); -    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwPlatformId)); -    PyStructSequence_SET_ITEM(version, pos++, PyUnicode_FromString(ver.szCSDVersion)); -    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMajor)); -    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMinor)); -    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask)); -    PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwMajorVersion)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwMinorVersion)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwBuildNumber)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwPlatformId)); +    PyStructSequence_SET_ITEM(version, pos++, PyString_FromString(ver.szCSDVersion)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wServicePackMajor)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wServicePackMinor)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wSuiteMask)); +    PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wProductType));      return version;  } @@ -779,7 +654,7 @@ sys_getdlopenflags(PyObject *self, PyObject *args)      PyThreadState *tstate = PyThreadState_GET();      if (!tstate)          return NULL; -    return PyLong_FromLong(tstate->interp->dlopenflags); +    return PyInt_FromLong(tstate->interp->dlopenflags);  }  PyDoc_STRVAR(getdlopenflags_doc, @@ -813,7 +688,6 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)      static PyObject *str__sizeof__ = NULL, *gc_head_size = NULL;      static char *kwlist[] = {"object", "default", 0};      PyObject *o, *dflt = NULL; -    PyObject *method;      if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof",                                       kwlist, &o, &dflt)) @@ -821,7 +695,7 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)      /* Initialize static variable for GC head size */      if (gc_head_size == NULL) { -        gc_head_size = PyLong_FromSsize_t(sizeof(PyGC_Head)); +        gc_head_size = PyInt_FromSsize_t(sizeof(PyGC_Head));          if (gc_head_size == NULL)              return NULL;      } @@ -830,20 +704,26 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds)      if (PyType_Ready(Py_TYPE(o)) < 0)          return NULL; -    method = _PyObject_LookupSpecial(o, "__sizeof__", -                                     &str__sizeof__); -    if (method == NULL) { -        if (!PyErr_Occurred()) -            PyErr_Format(PyExc_TypeError, -                         "Type %.100s doesn't define __sizeof__", -                         Py_TYPE(o)->tp_name); -    } +    /* Instance of old-style class */ +    if (PyInstance_Check(o)) +        res = PyInt_FromSsize_t(PyInstance_Type.tp_basicsize); +    /* all other objects */      else { -        res = PyObject_CallFunctionObjArgs(method, NULL); -        Py_DECREF(method); +        PyObject *method = _PyObject_LookupSpecial(o, "__sizeof__", +                                                   &str__sizeof__); +        if (method == NULL) { +            if (!PyErr_Occurred()) +                PyErr_Format(PyExc_TypeError, +                             "Type %.100s doesn't define __sizeof__", +                             Py_TYPE(o)->tp_name); +        } +        else { +            res = PyObject_CallFunctionObjArgs(method, NULL); +            Py_DECREF(method); +        }      } -    /* Has a default value been given */ +    /* Has a default value been given? */      if ((res == NULL) && (dflt != NULL) &&          PyErr_ExceptionMatches(PyExc_TypeError))      { @@ -871,14 +751,14 @@ Return the size of object in bytes.");  static PyObject *  sys_getrefcount(PyObject *self, PyObject *arg)  { -    return PyLong_FromSsize_t(arg->ob_refcnt); +    return PyInt_FromSsize_t(arg->ob_refcnt);  }  #ifdef Py_REF_DEBUG  static PyObject *  sys_gettotalrefcount(PyObject *self)  { -    return PyLong_FromSsize_t(_Py_GetRefTotal()); +    return PyInt_FromSsize_t(_Py_GetRefTotal());  }  #endif /* Py_REF_DEBUG */ @@ -1029,10 +909,13 @@ static PyMethodDef sys_methods[] = {       current_frames_doc},      {"displayhook",     sys_displayhook, METH_O, displayhook_doc},      {"exc_info",        sys_exc_info, METH_NOARGS, exc_info_doc}, +    {"exc_clear",       sys_exc_clear, METH_NOARGS, exc_clear_doc},      {"excepthook",      sys_excepthook, METH_VARARGS, excepthook_doc},      {"exit",            sys_exit, METH_VARARGS, exit_doc}, +#ifdef Py_USING_UNICODE      {"getdefaultencoding", (PyCFunction)sys_getdefaultencoding,       METH_NOARGS, getdefaultencoding_doc}, +#endif  #ifdef HAVE_DLOPEN      {"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS,       getdlopenflags_doc}, @@ -1043,8 +926,10 @@ static PyMethodDef sys_methods[] = {  #ifdef DYNAMIC_EXECUTION_PROFILE      {"getdxp",          _Py_GetDXProfile, METH_VARARGS},  #endif +#ifdef Py_USING_UNICODE      {"getfilesystemencoding", (PyCFunction)sys_getfilesystemencoding,       METH_NOARGS, getfilesystemencoding_doc}, +#endif  #ifdef Py_TRACE_REFS      {"getobjects",      _Py_GetObjects, METH_VARARGS},  #endif @@ -1061,20 +946,17 @@ static PyMethodDef sys_methods[] = {      {"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS,       getwindowsversion_doc},  #endif /* MS_WINDOWS */ -    {"intern",          sys_intern,     METH_VARARGS, intern_doc},  #ifdef USE_MALLOPT      {"mdebug",          sys_mdebug, METH_VARARGS},  #endif +#ifdef Py_USING_UNICODE +    {"setdefaultencoding", sys_setdefaultencoding, METH_VARARGS, +     setdefaultencoding_doc}, +#endif      {"setcheckinterval",        sys_setcheckinterval, METH_VARARGS,       setcheckinterval_doc},      {"getcheckinterval",        sys_getcheckinterval, METH_NOARGS,       getcheckinterval_doc}, -#ifdef WITH_THREAD -    {"setswitchinterval",       sys_setswitchinterval, METH_VARARGS, -     setswitchinterval_doc}, -    {"getswitchinterval",       sys_getswitchinterval, METH_NOARGS, -     getswitchinterval_doc}, -#endif  #ifdef HAVE_DLOPEN      {"setdlopenflags", sys_setdlopenflags, METH_VARARGS,       setdlopenflags_doc}, @@ -1100,7 +982,7 @@ list_builtin_module_names(void)      if (list == NULL)          return NULL;      for (i = 0; PyImport_Inittab[i].name != NULL; i++) { -        PyObject *name = PyUnicode_FromString( +        PyObject *name = PyString_FromString(              PyImport_Inittab[i].name);          if (name == NULL)              break; @@ -1130,26 +1012,21 @@ PySys_ResetWarnOptions(void)  }  void -PySys_AddWarnOptionUnicode(PyObject *unicode) +PySys_AddWarnOption(char *s)  { +    PyObject *str; +      if (warnoptions == NULL || !PyList_Check(warnoptions)) {          Py_XDECREF(warnoptions);          warnoptions = PyList_New(0);          if (warnoptions == NULL)              return;      } -    PyList_Append(warnoptions, unicode); -} - -void -PySys_AddWarnOption(const wchar_t *s) -{ -    PyObject *unicode; -    unicode = PyUnicode_FromWideChar(s, -1); -    if (unicode == NULL) -        return; -    PySys_AddWarnOptionUnicode(unicode); -    Py_DECREF(unicode); +    str = PyString_FromString(s); +    if (str != NULL) { +        PyList_Append(warnoptions, str); +        Py_DECREF(str); +    }  }  int @@ -1158,61 +1035,6 @@ PySys_HasWarnOptions(void)      return (warnoptions != NULL && (PyList_Size(warnoptions) > 0)) ? 1 : 0;  } -static PyObject *xoptions = NULL; - -static PyObject * -get_xoptions(void) -{ -    if (xoptions == NULL || !PyDict_Check(xoptions)) { -        Py_XDECREF(xoptions); -        xoptions = PyDict_New(); -    } -    return xoptions; -} - -void -PySys_AddXOption(const wchar_t *s) -{ -    PyObject *opts; -    PyObject *name = NULL, *value = NULL; -    const wchar_t *name_end; -    int r; - -    opts = get_xoptions(); -    if (opts == NULL) -        goto error; - -    name_end = wcschr(s, L'='); -    if (!name_end) { -        name = PyUnicode_FromWideChar(s, -1); -        value = Py_True; -        Py_INCREF(value); -    } -    else { -        name = PyUnicode_FromWideChar(s, name_end - s); -        value = PyUnicode_FromWideChar(name_end + 1, -1); -    } -    if (name == NULL || value == NULL) -        goto error; -    r = PyDict_SetItem(opts, name, value); -    Py_DECREF(name); -    Py_DECREF(value); -    return; - -error: -    Py_XDECREF(name); -    Py_XDECREF(value); -    /* No return value, therefore clear error state if possible */ -    if (_Py_atomic_load_relaxed(&_PyThreadState_Current)) -        PyErr_Clear(); -} - -PyObject * -PySys_GetXOptions(void) -{ -    return get_xoptions(); -} -  /* XXX This doc string is too long to be a single string literal in VC++ 5.0.     Two literals concatenated works just fine.  If you have a K&R compiler     or other abomination that however *does* understand longer strings, @@ -1233,8 +1055,11 @@ excepthook -- called to handle any uncaught exception other than SystemExit\n\    To customize printing in an interactive session or to install a custom\n\    top-level exception handler, assign other functions to replace these.\n\  \n\ -stdin -- standard input file object; used by input()\n\ -stdout -- standard output file object; used by print()\n\ +exitfunc -- if sys.exitfunc exists, this routine is called when Python exits\n\ +  Assigning to sys.exitfunc is deprecated; use the atexit module instead.\n\ +\n\ +stdin -- standard input file object; used by raw_input() and input()\n\ +stdout -- standard output file object; used by the print statement\n\  stderr -- standard error object; used for error messages\n\    By assigning other file objects (or objects that behave like files)\n\    to these, it is possible to redirect all of the interpreter's I/O.\n\ @@ -1244,6 +1069,12 @@ last_value -- value of last uncaught exception\n\  last_traceback -- traceback of last uncaught exception\n\    These three are only available in an interactive session after a\n\    traceback has been printed.\n\ +\n\ +exc_type -- type of exception currently being handled\n\ +exc_value -- value of exception currently being handled\n\ +exc_traceback -- traceback of exception currently being handled\n\ +  The function exc_info() should be used instead of these three,\n\ +  because it is thread-safe.\n\  "  )  /* concatenating string here */ @@ -1251,18 +1082,18 @@ PyDoc_STR(  "\n\  Static objects:\n\  \n\ -float_info -- a dict with information about the float implementation.\n\ -int_info -- a struct sequence with information about the int implementation.\n\ +float_info -- a dict with information about the float inplementation.\n\ +long_info -- a struct sequence with information about the long implementation.\n\ +maxint -- the largest supported integer (the smallest is -maxint-1)\n\  maxsize -- the largest supported length of containers.\n\  maxunicode -- the largest supported character\n\  builtin_module_names -- tuple of module names built into this interpreter\n\ -subversion -- subversion information of the build as tuple\n\  version -- the version of this interpreter as a string\n\  version_info -- version information as a named tuple\n\  hexversion -- version information encoded as a single integer\n\  copyright -- copyright notice pertaining to this interpreter\n\  platform -- platform identifier\n\ -executable -- pathname of this Python interpreter\n\ +executable -- absolute path of the executable binary of the Python interpreter\n\  prefix -- prefix used to find the Python library\n\  exec_prefix -- prefix used to find the machine-specific Python library\n\  float_repr_style -- string indicating the style of repr() output for floats\n\ @@ -1285,9 +1116,10 @@ __excepthook__ -- the original excepthook; don't touch!\n\  \n\  Functions:\n\  \n\ -displayhook() -- print an object to the screen, and save it in builtins._\n\ +displayhook() -- print an object to the screen, and save it in __builtin__._\n\  excepthook() -- print an exception and its traceback to sys.stderr\n\  exc_info() -- return thread-safe information about the current exception\n\ +exc_clear() -- clear the exception state for the current thread\n\  exit() -- exit the interpreter by raising SystemExit\n\  getdlopenflags() -- returns flags to be used for dlopen() calls\n\  getprofile() -- get the global profiling function\n\ @@ -1304,9 +1136,14 @@ settrace() -- set the global debug tracing function\n\  )  /* end of sys_doc */ ; +static int +_check_and_flush (FILE *stream) +{ +  int prev_fail = ferror (stream); +  return fflush (stream) || prev_fail ? EOF : 0; +} +  /* Subversion branch and revision management */ -static const char _patchlevel_revision[] = PY_PATCHLEVEL_REVISION; -static const char headurl[] = "$HeadURL$";  static int svn_initialized;  static char patchlevel_revision[50]; /* Just the number */  static char branch[50]; @@ -1316,64 +1153,14 @@ static const char *svn_revision;  static void  svnversion_init(void)  { -    const char *python, *br_start, *br_end, *br_end2, *svnversion; -    Py_ssize_t len; -    int istag = 0; -      if (svn_initialized)          return; - -    python = strstr(headurl, "/python/"); -    if (!python) { -        strcpy(branch, "unknown branch"); -        strcpy(shortbranch, "unknown"); -    } -    else { -        br_start = python + 8; -        br_end = strchr(br_start, '/'); -        assert(br_end); - -        /* Works even for trunk, -           as we are in trunk/Python/sysmodule.c */ -        br_end2 = strchr(br_end+1, '/'); - -        istag = strncmp(br_start, "tags", 4) == 0; -        if (strncmp(br_start, "trunk", 5) == 0) { -            strcpy(branch, "trunk"); -            strcpy(shortbranch, "trunk"); -        } -        else if (istag || strncmp(br_start, "branches", 8) == 0) { -            len = br_end2 - br_start; -            strncpy(branch, br_start, len); -            branch[len] = '\0'; - -            len = br_end2 - (br_end + 1); -            strncpy(shortbranch, br_end + 1, len); -            shortbranch[len] = '\0'; -        } -        else { -            Py_FatalError("bad HeadURL"); -            return; -        } -    } - - -    svnversion = _Py_svnversion(); -    if (strcmp(svnversion, "Unversioned directory") != 0 && strcmp(svnversion, "exported") != 0) -        svn_revision = svnversion; -    else if (istag) { -        len = strlen(_patchlevel_revision); -        assert(len >= 13); -        assert(len < (sizeof(patchlevel_revision) + 13)); -        strncpy(patchlevel_revision, _patchlevel_revision + 11, -            len - 13); -        patchlevel_revision[len - 13] = '\0'; -        svn_revision = patchlevel_revision; -    } -    else -        svn_revision = ""; -      svn_initialized = 1; +    *patchlevel_revision = '\0'; +    strcpy(branch, ""); +    strcpy(shortbranch, "unknown"); +    svn_revision = ""; +    return;  }  /* Return svnversion output if available. @@ -1399,11 +1186,13 @@ PyDoc_STRVAR(flags__doc__,  \n\  Flags provided through command line arguments or environment vars."); -static PyTypeObject FlagsType; +static PyTypeObject FlagsType = {0, 0, 0, 0, 0, 0};  static PyStructSequence_Field flags_fields[] = {      {"debug",                   "-d"}, +    {"py3k_warning",            "-3"},      {"division_warning",        "-Q"}, +    {"division_new",            "-Qnew"},      {"inspect",                 "-i"},      {"interactive",             "-i"},      {"optimize",                "-O or -OO"}, @@ -1411,14 +1200,16 @@ static PyStructSequence_Field flags_fields[] = {      {"no_user_site",            "-s"},      {"no_site",                 "-S"},      {"ignore_environment",      "-E"}, +    {"tabcheck",                "-t or -tt"},      {"verbose",                 "-v"},  #ifdef RISCOS      {"riscos_wimp",             "???"},  #endif      /* {"unbuffered",                   "-u"}, */ +    {"unicode",                 "-U"},      /* {"skip_first",                   "-x"}, */ -    {"bytes_warning",           "-b"}, -    {"quiet",                   "-q"}, +    {"bytes_warning", "-b"}, +    {"hash_randomization", "-R"},      {0}  }; @@ -1427,9 +1218,9 @@ static PyStructSequence_Desc flags_desc = {      flags__doc__,       /* doc */      flags_fields,       /* fields */  #ifdef RISCOS -    13 +    17  #else -    12 +    16  #endif  }; @@ -1444,10 +1235,12 @@ make_flags(void)          return NULL;  #define SetFlag(flag) \ -    PyStructSequence_SET_ITEM(seq, pos++, PyLong_FromLong(flag)) +    PyStructSequence_SET_ITEM(seq, pos++, PyInt_FromLong(flag))      SetFlag(Py_DebugFlag); +    SetFlag(Py_Py3kWarningFlag);      SetFlag(Py_DivisionWarningFlag); +    SetFlag(_Py_QnewFlag);      SetFlag(Py_InspectFlag);      SetFlag(Py_InteractiveFlag);      SetFlag(Py_OptimizeFlag); @@ -1455,14 +1248,16 @@ make_flags(void)      SetFlag(Py_NoUserSiteDirectory);      SetFlag(Py_NoSiteFlag);      SetFlag(Py_IgnoreEnvironmentFlag); +    SetFlag(Py_TabcheckFlag);      SetFlag(Py_VerboseFlag);  #ifdef RISCOS      SetFlag(Py_RISCOSWimpFlag);  #endif      /* SetFlag(saw_unbuffered_flag); */ +    SetFlag(Py_UnicodeFlag);      /* SetFlag(skipfirstline); */      SetFlag(Py_BytesWarningFlag); -    SetFlag(Py_QuietFlag); +    SetFlag(Py_HashRandomizationFlag);  #undef SetFlag      if (PyErr_Occurred()) { @@ -1476,7 +1271,7 @@ PyDoc_STRVAR(version_info__doc__,  \n\  Version information as a named tuple."); -static PyTypeObject VersionInfoType; +static PyTypeObject VersionInfoType = {0, 0, 0, 0, 0, 0};  static PyStructSequence_Field version_info_fields[] = {      {"major", "Major release number"}, @@ -1521,9 +1316,9 @@ make_version_info(void)  #endif  #define SetIntItem(flag) \ -    PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag)) +    PyStructSequence_SET_ITEM(version_info, pos++, PyInt_FromLong(flag))  #define SetStrItem(flag) \ -    PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag)) +    PyStructSequence_SET_ITEM(version_info, pos++, PyString_FromString(flag))      SetIntItem(PY_MAJOR_VERSION);      SetIntItem(PY_MINOR_VERSION); @@ -1540,25 +1335,14 @@ make_version_info(void)      return version_info;  } -static struct PyModuleDef sysmodule = { -    PyModuleDef_HEAD_INIT, -    "sys", -    sys_doc, -    -1, /* multiple "initialization" just copies the module dict. */ -    sys_methods, -    NULL, -    NULL, -    NULL, -    NULL -}; -  PyObject *  _PySys_Init(void)  {      PyObject *m, *v, *sysdict; +    PyObject *sysin, *sysout, *syserr;      char *s; -    m = PyModule_Create(&sysmodule); +    m = Py_InitModule3("sys", sys_methods, sys_doc);      if (m == NULL)          return NULL;      sysdict = PyModule_GetDict(m); @@ -1586,19 +1370,43 @@ _PySys_Init(void)      }  #endif -    /* stdin/stdout/stderr are now set by pythonrun.c */ +    /* Closing the standard FILE* if sys.std* goes aways causes problems +     * for embedded Python usages. Closing them when somebody explicitly +     * invokes .close() might be possible, but the FAQ promises they get +     * never closed. However, we still need to get write errors when +     * writing fails (e.g. because stdout is redirected), so we flush the +     * streams and check for errors before the file objects are deleted. +     * On OS X, fflush()ing stdin causes an error, so we exempt stdin +     * from that procedure. +     */ +    sysin = PyFile_FromFile(stdin, "<stdin>", "r", NULL); +    sysout = PyFile_FromFile(stdout, "<stdout>", "w", _check_and_flush); +    syserr = PyFile_FromFile(stderr, "<stderr>", "w", _check_and_flush); +    if (PyErr_Occurred()) +        return NULL; +    PyDict_SetItemString(sysdict, "stdin", sysin); +    PyDict_SetItemString(sysdict, "stdout", sysout); +    PyDict_SetItemString(sysdict, "stderr", syserr); +    /* Make backup copies for cleanup */ +    PyDict_SetItemString(sysdict, "__stdin__", sysin); +    PyDict_SetItemString(sysdict, "__stdout__", sysout); +    PyDict_SetItemString(sysdict, "__stderr__", syserr);      PyDict_SetItemString(sysdict, "__displayhook__",                           PyDict_GetItemString(sysdict, "displayhook"));      PyDict_SetItemString(sysdict, "__excepthook__",                           PyDict_GetItemString(sysdict, "excepthook")); +    Py_XDECREF(sysin); +    Py_XDECREF(sysout); +    Py_XDECREF(syserr); +      SET_SYS_FROM_STRING("version", -                         PyUnicode_FromString(Py_GetVersion())); +                         PyString_FromString(Py_GetVersion()));      SET_SYS_FROM_STRING("hexversion", -                         PyLong_FromLong(PY_VERSION_HEX)); +                         PyInt_FromLong(PY_VERSION_HEX));      svnversion_init();      SET_SYS_FROM_STRING("subversion", -                        Py_BuildValue("(sss)", "CPython", branch, +                         Py_BuildValue("(ssz)", "CPython", branch,                                        svn_revision));      SET_SYS_FROM_STRING("_mercurial",                          Py_BuildValue("(szz)", "CPython", _Py_hgidentifier(), @@ -1606,31 +1414,31 @@ _PySys_Init(void)      SET_SYS_FROM_STRING("dont_write_bytecode",                           PyBool_FromLong(Py_DontWriteBytecodeFlag));      SET_SYS_FROM_STRING("api_version", -                        PyLong_FromLong(PYTHON_API_VERSION)); +                        PyInt_FromLong(PYTHON_API_VERSION));      SET_SYS_FROM_STRING("copyright", -                        PyUnicode_FromString(Py_GetCopyright())); +                        PyString_FromString(Py_GetCopyright()));      SET_SYS_FROM_STRING("platform", -                        PyUnicode_FromString(Py_GetPlatform())); +                        PyString_FromString(Py_GetPlatform()));      SET_SYS_FROM_STRING("executable", -                        PyUnicode_FromWideChar( -                               Py_GetProgramFullPath(), -1)); +                        PyString_FromString(Py_GetProgramFullPath()));      SET_SYS_FROM_STRING("prefix", -                        PyUnicode_FromWideChar(Py_GetPrefix(), -1)); +                        PyString_FromString(Py_GetPrefix()));      SET_SYS_FROM_STRING("exec_prefix", -                        PyUnicode_FromWideChar(Py_GetExecPrefix(), -1)); +                        PyString_FromString(Py_GetExecPrefix()));      SET_SYS_FROM_STRING("maxsize", -                        PyLong_FromSsize_t(PY_SSIZE_T_MAX)); +                        PyInt_FromSsize_t(PY_SSIZE_T_MAX)); +    SET_SYS_FROM_STRING("maxint", +                        PyInt_FromLong(PyInt_GetMax())); +    SET_SYS_FROM_STRING("py3kwarning", +                        PyBool_FromLong(Py_Py3kWarningFlag));      SET_SYS_FROM_STRING("float_info",                          PyFloat_GetInfo()); -    SET_SYS_FROM_STRING("int_info", +    SET_SYS_FROM_STRING("long_info",                          PyLong_GetInfo()); -    /* initialize hash_info */ -    if (Hash_InfoType.tp_name == 0) -        PyStructSequence_InitType(&Hash_InfoType, &hash_info_desc); -    SET_SYS_FROM_STRING("hash_info", -                        get_hash_info()); +#ifdef Py_USING_UNICODE      SET_SYS_FROM_STRING("maxunicode", -                        PyLong_FromLong(PyUnicode_GetMax())); +                        PyInt_FromLong(PyUnicode_GetMax())); +#endif      SET_SYS_FROM_STRING("builtin_module_names",                          list_builtin_module_names());      { @@ -1645,17 +1453,13 @@ _PySys_Init(void)          else              value = "little";          SET_SYS_FROM_STRING("byteorder", -                            PyUnicode_FromString(value)); +                            PyString_FromString(value));      }  #ifdef MS_COREDLL      SET_SYS_FROM_STRING("dllhandle",                          PyLong_FromVoidPtr(PyWin_DLLhModule));      SET_SYS_FROM_STRING("winver", -                        PyUnicode_FromString(PyWin_DLLVersionString)); -#endif -#ifdef ABIFLAGS -    SET_SYS_FROM_STRING("abiflags", -                        PyUnicode_FromString(ABIFLAGS)); +                        PyString_FromString(PyWin_DLLVersionString));  #endif      if (warnoptions == NULL) {          warnoptions = PyList_New(0); @@ -1667,11 +1471,6 @@ _PySys_Init(void)          PyDict_SetItemString(sysdict, "warnoptions", warnoptions);      } -    v = get_xoptions(); -    if (v != NULL) { -        PyDict_SetItemString(sysdict, "_xoptions", v); -    } -      /* version_info */      if (VersionInfoType.tp_name == 0)          PyStructSequence_InitType(&VersionInfoType, &version_info_desc); @@ -1701,10 +1500,10 @@ _PySys_Init(void)      /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */  #ifndef PY_NO_SHORT_FLOAT_REPR      SET_SYS_FROM_STRING("float_repr_style", -                        PyUnicode_FromString("short")); +                        PyString_FromString("short"));  #else      SET_SYS_FROM_STRING("float_repr_style", -                        PyUnicode_FromString("legacy")); +                        PyString_FromString("legacy"));  #endif  #undef SET_SYS_FROM_STRING @@ -1714,15 +1513,15 @@ _PySys_Init(void)  }  static PyObject * -makepathobject(const wchar_t *path, wchar_t delim) +makepathobject(char *path, int delim)  {      int i, n; -    const wchar_t *p; +    char *p;      PyObject *v, *w;      n = 1;      p = path; -    while ((p = wcschr(p, delim)) != NULL) { +    while ((p = strchr(p, delim)) != NULL) {          n++;          p++;      } @@ -1730,10 +1529,10 @@ makepathobject(const wchar_t *path, wchar_t delim)      if (v == NULL)          return NULL;      for (i = 0; ; i++) { -        p = wcschr(path, delim); +        p = strchr(path, delim);          if (p == NULL) -            p = path + wcslen(path); /* End of string */ -        w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path)); +            p = strchr(path, '\0'); /* End of string */ +        w = PyString_FromStringAndSize(path, (Py_ssize_t) (p - path));          if (w == NULL) {              Py_DECREF(v);              return NULL; @@ -1747,7 +1546,7 @@ makepathobject(const wchar_t *path, wchar_t delim)  }  void -PySys_SetPath(const wchar_t *path) +PySys_SetPath(char *path)  {      PyObject *v;      if ((v = makepathobject(path, DELIM)) == NULL) @@ -1758,12 +1557,12 @@ PySys_SetPath(const wchar_t *path)  }  static PyObject * -makeargvobject(int argc, wchar_t **argv) +makeargvobject(int argc, char **argv)  {      PyObject *av;      if (argc <= 0 || argv == NULL) {          /* Ensure at least one (empty) argument is seen */ -        static wchar_t *empty_argv[1] = {L""}; +        static char *empty_argv[1] = {""};          argv = empty_argv;          argc = 1;      } @@ -1778,14 +1577,14 @@ makeargvobject(int argc, wchar_t **argv)              if (i == 0) {                  char* fn = decc$translate_vms(argv[0]);                  if ((fn == (char *)0) || fn == (char *)-1) -                    v = PyUnicode_FromString(argv[0]); +                    v = PyString_FromString(argv[0]);                  else -                    v = PyUnicode_FromString( +                    v = PyString_FromString(                          decc$translate_vms(argv[0]));              } else -                v = PyUnicode_FromString(argv[i]); +                v = PyString_FromString(argv[i]);  #else -            PyObject *v = PyUnicode_FromWideChar(argv[i], -1); +            PyObject *v = PyString_FromString(argv[i]);  #endif              if (v == NULL) {                  Py_DECREF(av); @@ -1798,184 +1597,116 @@ makeargvobject(int argc, wchar_t **argv)      return av;  } -#define _HAVE_SCRIPT_ARGUMENT(argc, argv) \ -  (argc > 0 && argv0 != NULL && \ -   wcscmp(argv0, L"-c") != 0 && wcscmp(argv0, L"-m") != 0) - -static void -sys_update_path(int argc, wchar_t **argv) +void +PySys_SetArgvEx(int argc, char **argv, int updatepath)  { -    wchar_t *argv0; -    wchar_t *p = NULL; -    Py_ssize_t n = 0; -    PyObject *a; -    PyObject *path; -#ifdef HAVE_READLINK -    wchar_t link[MAXPATHLEN+1]; -    wchar_t argv0copy[2*MAXPATHLEN+1]; -    int nr = 0; -#endif  #if defined(HAVE_REALPATH) -    wchar_t fullpath[MAXPATHLEN]; +    char fullpath[MAXPATHLEN];  #elif defined(MS_WINDOWS) && !defined(MS_WINCE) -    wchar_t fullpath[MAX_PATH]; +    char fullpath[MAX_PATH];  #endif - -    path = PySys_GetObject("path"); -    if (path == NULL) -        return; - -    argv0 = argv[0]; - +    PyObject *av = makeargvobject(argc, argv); +    PyObject *path = PySys_GetObject("path"); +    if (av == NULL) +        Py_FatalError("no mem for sys.argv"); +    if (PySys_SetObject("argv", av) != 0) +        Py_FatalError("can't assign sys.argv"); +    if (updatepath && path != NULL) { +        char *argv0 = argv[0]; +        char *p = NULL; +        Py_ssize_t n = 0; +        PyObject *a;  #ifdef HAVE_READLINK -    if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) -        nr = _Py_wreadlink(argv0, link, MAXPATHLEN); -    if (nr > 0) { -        /* It's a symlink */ -        link[nr] = '\0'; -        if (link[0] == SEP) -            argv0 = link; /* Link to absolute path */ -        else if (wcschr(link, SEP) == NULL) -            ; /* Link without path */ -        else { -            /* Must join(dirname(argv0), link) */ -            wchar_t *q = wcsrchr(argv0, SEP); -            if (q == NULL) -                argv0 = link; /* argv0 without path */ +        char link[MAXPATHLEN+1]; +        char argv0copy[2*MAXPATHLEN+1]; +        int nr = 0; +        if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) +            nr = readlink(argv0, link, MAXPATHLEN); +        if (nr > 0) { +            /* It's a symlink */ +            link[nr] = '\0'; +            if (link[0] == SEP) +                argv0 = link; /* Link to absolute path */ +            else if (strchr(link, SEP) == NULL) +                ; /* Link without path */              else { -                /* Must make a copy */ -                wcscpy(argv0copy, argv0); -                q = wcsrchr(argv0copy, SEP); -                wcscpy(q+1, link); -                argv0 = argv0copy; +                /* Must join(dirname(argv0), link) */ +                char *q = strrchr(argv0, SEP); +                if (q == NULL) +                    argv0 = link; /* argv0 without path */ +                else { +                    /* Must make a copy */ +                    strcpy(argv0copy, argv0); +                    q = strrchr(argv0copy, SEP); +                    strcpy(q+1, link); +                    argv0 = argv0copy; +                }              }          } -    }  #endif /* HAVE_READLINK */  #if SEP == '\\' /* Special case for MS filename syntax */ -    if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) { -        wchar_t *q; +        if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { +            char *q;  #if defined(MS_WINDOWS) && !defined(MS_WINCE) -        /* This code here replaces the first element in argv with the full -        path that it represents. Under CE, there are no relative paths so -        the argument must be the full path anyway. */ -        wchar_t *ptemp; -        if (GetFullPathNameW(argv0, -                           sizeof(fullpath)/sizeof(fullpath[0]), -                           fullpath, -                           &ptemp)) { -            argv0 = fullpath; -        } +            /* This code here replaces the first element in argv with the full +            path that it represents. Under CE, there are no relative paths so +            the argument must be the full path anyway. */ +            char *ptemp; +            if (GetFullPathName(argv0, +                               sizeof(fullpath), +                               fullpath, +                               &ptemp)) { +                argv0 = fullpath; +            }  #endif -        p = wcsrchr(argv0, SEP); -        /* Test for alternate separator */ -        q = wcsrchr(p ? p : argv0, '/'); -        if (q != NULL) -            p = q; -        if (p != NULL) { -            n = p + 1 - argv0; -            if (n > 1 && p[-1] != ':') -                n--; /* Drop trailing separator */ +            p = strrchr(argv0, SEP); +            /* Test for alternate separator */ +            q = strrchr(p ? p : argv0, '/'); +            if (q != NULL) +                p = q; +            if (p != NULL) { +                n = p + 1 - argv0; +                if (n > 1 && p[-1] != ':') +                    n--; /* Drop trailing separator */ +            }          } -    }  #else /* All other filename syntaxes */ -    if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) { +        if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) {  #if defined(HAVE_REALPATH) -        if (_Py_wrealpath(argv0, fullpath, PATH_MAX)) { -            argv0 = fullpath; -        } +            if (realpath(argv0, fullpath)) { +                argv0 = fullpath; +            }  #endif -        p = wcsrchr(argv0, SEP); -    } -    if (p != NULL) { -        n = p + 1 - argv0; +            p = strrchr(argv0, SEP); +        } +        if (p != NULL) { +#ifndef RISCOS +            n = p + 1 - argv0; +#else /* don't include trailing separator */ +            n = p - argv0; +#endif /* RISCOS */  #if SEP == '/' /* Special case for Unix filename syntax */ -        if (n > 1) -            n--; /* Drop trailing separator */ +            if (n > 1) +                n--; /* Drop trailing separator */  #endif /* Unix */ -    } +        }  #endif /* All others */ -    a = PyUnicode_FromWideChar(argv0, n); -    if (a == NULL) -        Py_FatalError("no mem for sys.path insertion"); -    if (PyList_Insert(path, 0, a) < 0) -        Py_FatalError("sys.path.insert(0) failed"); -    Py_DECREF(a); -} - -void -PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) -{ -    PyObject *av = makeargvobject(argc, argv); -    if (av == NULL) -        Py_FatalError("no mem for sys.argv"); -    if (PySys_SetObject("argv", av) != 0) -        Py_FatalError("can't assign sys.argv"); +        a = PyString_FromStringAndSize(argv0, n); +        if (a == NULL) +            Py_FatalError("no mem for sys.path insertion"); +        if (PyList_Insert(path, 0, a) < 0) +            Py_FatalError("sys.path.insert(0) failed"); +        Py_DECREF(a); +    }      Py_DECREF(av); -    if (updatepath) -        sys_update_path(argc, argv);  }  void -PySys_SetArgv(int argc, wchar_t **argv) +PySys_SetArgv(int argc, char **argv)  {      PySys_SetArgvEx(argc, argv, 1);  } -/* Reimplementation of PyFile_WriteString() no calling indirectly -   PyErr_CheckSignals(): avoid the call to PyObject_Str(). */ - -static int -sys_pyfile_write_unicode(PyObject *unicode, PyObject *file) -{ -    PyObject *writer = NULL, *args = NULL, *result = NULL; -    int err; - -    if (file == NULL) -        return -1; - -    writer = PyObject_GetAttrString(file, "write"); -    if (writer == NULL) -        goto error; - -    args = PyTuple_Pack(1, unicode); -    if (args == NULL) -        goto error; - -    result = PyEval_CallObject(writer, args); -    if (result == NULL) { -        goto error; -    } else { -        err = 0; -        goto finally; -    } - -error: -    err = -1; -finally: -    Py_XDECREF(writer); -    Py_XDECREF(args); -    Py_XDECREF(result); -    return err; -} - -static int -sys_pyfile_write(const char *text, PyObject *file) -{ -    PyObject *unicode = NULL; -    int err; - -    if (file == NULL) -        return -1; - -    unicode = PyUnicode_FromString(text); -    if (unicode == NULL) -        return -1; - -    err = sys_pyfile_write_unicode(unicode, file); -    Py_DECREF(unicode); -    return err; -}  /* APIs to write to sys.stdout or sys.stderr using a printf-like interface.     Adapted from code submitted by Just van Rossum. @@ -1987,10 +1718,6 @@ sys_pyfile_write(const char *text, PyObject *file)        there is a problem, they write to the real (C level) stdout or stderr;        no exceptions are raised. -      PyErr_CheckSignals() is not called to avoid the execution of the Python -      signal handlers: they may raise a new exception whereas sys_write() -      ignores all exceptions. -        Both take a printf-style format string as their first argument followed        by a variable length argument list determined by the format string. @@ -2006,86 +1733,50 @@ sys_pyfile_write(const char *text, PyObject *file)   */  static void -sys_write(char *name, FILE *fp, const char *format, va_list va) +mywrite(char *name, FILE *fp, const char *format, va_list va)  {      PyObject *file;      PyObject *error_type, *error_value, *error_traceback; -    char buffer[1001]; -    int written;      PyErr_Fetch(&error_type, &error_value, &error_traceback);      file = PySys_GetObject(name); -    written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); -    if (sys_pyfile_write(buffer, file) != 0) { -        PyErr_Clear(); -        fputs(buffer, fp); -    } -    if (written < 0 || (size_t)written >= sizeof(buffer)) { -        const char *truncated = "... truncated"; -        if (sys_pyfile_write(truncated, file) != 0) -            fputs(truncated, fp); -    } -    PyErr_Restore(error_type, error_value, error_traceback); -} - -void -PySys_WriteStdout(const char *format, ...) -{ -    va_list va; - -    va_start(va, format); -    sys_write("stdout", stdout, format, va); -    va_end(va); -} - -void -PySys_WriteStderr(const char *format, ...) -{ -    va_list va; - -    va_start(va, format); -    sys_write("stderr", stderr, format, va); -    va_end(va); -} - -static void -sys_format(char *name, FILE *fp, const char *format, va_list va) -{ -    PyObject *file, *message; -    PyObject *error_type, *error_value, *error_traceback; -    char *utf8; - -    PyErr_Fetch(&error_type, &error_value, &error_traceback); -    file = PySys_GetObject(name); -    message = PyUnicode_FromFormatV(format, va); -    if (message != NULL) { -        if (sys_pyfile_write_unicode(message, file) != 0) { +    if (file == NULL || PyFile_AsFile(file) == fp) +        vfprintf(fp, format, va); +    else { +        char buffer[1001]; +        const int written = PyOS_vsnprintf(buffer, sizeof(buffer), +                                           format, va); +        if (PyFile_WriteString(buffer, file) != 0) {              PyErr_Clear(); -            utf8 = _PyUnicode_AsString(message); -            if (utf8 != NULL) -                fputs(utf8, fp); +            fputs(buffer, fp); +        } +        if (written < 0 || (size_t)written >= sizeof(buffer)) { +            const char *truncated = "... truncated"; +            if (PyFile_WriteString(truncated, file) != 0) { +                PyErr_Clear(); +                fputs(truncated, fp); +            }          } -        Py_DECREF(message);      }      PyErr_Restore(error_type, error_value, error_traceback);  }  void -PySys_FormatStdout(const char *format, ...) +PySys_WriteStdout(const char *format, ...)  {      va_list va;      va_start(va, format); -    sys_format("stdout", stdout, format, va); +    mywrite("stdout", stdout, format, va);      va_end(va);  }  void -PySys_FormatStderr(const char *format, ...) +PySys_WriteStderr(const char *format, ...)  {      va_list va;      va_start(va, format); -    sys_format("stderr", stderr, format, va); +    mywrite("stderr", stderr, format, va);      va_end(va);  } | 
