Index: Doc/api/concrete.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/concrete.tex,v retrieving revision 1.21 diff -u -r1.21 concrete.tex --- Doc/api/concrete.tex 28 Mar 2003 18:07:16 -0000 1.21 +++ Doc/api/concrete.tex 29 Mar 2003 14:22:27 -0000 @@ -2002,6 +2002,12 @@ creation. \end{cfuncdesc} +\begin{cfuncdesc}{int}{PyFile_Encoding}{PyFileObject *p, char *enc} + Set the file's encoding for Unicode output to \var{enc}. Return + 1 on success and 0 on failure. + \versionadded{2.3} +\end{cfuncdesc} + \begin{cfuncdesc}{int}{PyFile_SoftSpace}{PyObject *p, int newflag} This function exists for internal use by the interpreter. Sets the \member{softspace} attribute of \var{p} to \var{newflag} and Index: Include/fileobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/fileobject.h,v retrieving revision 2.31 diff -u -r2.31 fileobject.h --- Include/fileobject.h 12 Aug 2002 07:21:56 -0000 2.31 +++ Include/fileobject.h 29 Mar 2003 14:22:27 -0000 @@ -24,6 +24,7 @@ int f_newlinetypes; /* Types of newlines seen */ int f_skipnextlf; /* Skip next \n */ #endif + PyObject *f_encoding; } PyFileObject; PyAPI_DATA(PyTypeObject) PyFile_Type; @@ -33,6 +34,7 @@ PyAPI_FUNC(PyObject *) PyFile_FromString(char *, char *); PyAPI_FUNC(void) PyFile_SetBufSize(PyObject *, int); +PyAPI_FUNC(int) PyFile_SetEncoding(PyObject *, const char *); PyAPI_FUNC(PyObject *) PyFile_FromFile(FILE *, char *, char *, int (*)(FILE *)); PyAPI_FUNC(FILE *) PyFile_AsFile(PyObject *); Index: Objects/fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.176 diff -u -r2.176 fileobject.c --- Objects/fileobject.c 9 Feb 2003 01:10:02 -0000 2.176 +++ Objects/fileobject.c 29 Mar 2003 14:22:34 -0000 @@ -116,6 +116,7 @@ Py_DECREF(f->f_name); Py_DECREF(f->f_mode); + Py_DECREF(f->f_encoding); #ifdef Py_USING_UNICODE if (wname) f->f_name = PyUnicode_FromObject(wname); @@ -133,7 +134,9 @@ f->f_newlinetypes = NEWLINE_UNKNOWN; f->f_skipnextlf = 0; #endif - + Py_INCREF(Py_None); + f->f_encoding = Py_None; + if (f->f_name == NULL || f->f_mode == NULL) return NULL; f->f_fp = fp; @@ -302,6 +305,21 @@ } } +/* Set the encoding used to output Unicode strings. + Returh 1 on success, 0 on failure. */ + +int +PyFile_SetEncoding(PyObject *f, const char *enc) +{ + PyFileObject *file = (PyFileObject*)f; + PyObject *str = PyString_FromString(enc); + if (!str) + return 0; + Py_DECREF(file->f_encoding); + file->f_encoding = str; + return 1; +} + static PyObject * err_closed(void) { @@ -323,6 +341,7 @@ } Py_XDECREF(f->f_name); Py_XDECREF(f->f_mode); + Py_XDECREF(f->f_encoding); drop_readahead(f); f->ob_type->tp_free((PyObject *)f); } @@ -1667,6 +1686,8 @@ "file mode ('r', 'U', 'w', 'a', possibly with 'b' or '+' added)"}, {"name", T_OBJECT, OFF(f_name), RO, "file name"}, + {"encoding", T_OBJECT, OFF(f_encoding), RO, + "file encoding"}, /* getattr(f, "closed") is implemented without this table */ {NULL} /* Sentinel */ }; @@ -1851,6 +1872,8 @@ ((PyFileObject *)self)->f_name = not_yet_string; Py_INCREF(not_yet_string); ((PyFileObject *)self)->f_mode = not_yet_string; + Py_INCREF(Py_None); + ((PyFileObject *)self)->f_encoding = Py_None; } return self; } @@ -2033,11 +2056,28 @@ } else if (PyFile_Check(f)) { FILE *fp = PyFile_AsFile(f); + PyObject *enc = ((PyFileObject*)f)->f_encoding; + int result; if (fp == NULL) { err_closed(); return -1; } +#ifdef Py_USING_UNICODE + if (PyUnicode_Check(v) && enc != Py_None) { + char *cenc = PyString_AS_STRING(enc); + value = PyUnicode_AsEncodedString(v, cenc, "strict"); + if (value == NULL) + return -1; + } else { + value = v; + Py_INCREF(value); + } + result = PyObject_Print(value, fp, flags); + Py_DECREF(value); + return result; +#else return PyObject_Print(v, fp, flags); +#endif } writer = PyObject_GetAttrString(f, "write"); if (writer == NULL) Index: Python/sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.116 diff -u -r2.116 sysmodule.c --- Python/sysmodule.c 5 Mar 2003 15:13:47 -0000 2.116 +++ Python/sysmodule.c 29 Mar 2003 14:22:35 -0000 @@ -31,6 +31,15 @@ extern const char *PyWin_DLLVersionString; #endif +#ifdef MS_WINDOWS +#include +#endif + +#ifdef HAVE_LANGINFO_H +#include +#include +#endif + PyObject * PySys_GetObject(char *name) { @@ -858,6 +867,12 @@ PyObject *m, *v, *sysdict; PyObject *sysin, *sysout, *syserr; char *s; +#ifdef MS_WINDOWS + char buf[10]; +#endif +#if defined(HAVE_LANGINFO_H) && defined(CODESET) + char *oldloc, *codeset; +#endif m = Py_InitModule3("sys", sys_methods, sys_doc); sysdict = PyModule_GetDict(m); @@ -867,6 +882,34 @@ syserr = PyFile_FromFile(stderr, "", "w", NULL); if (PyErr_Occurred()) return NULL; +#ifdef MS_WINDOWS + if(isatty(_fileno(stdin))){ + sprintf(buf, "cp%d", GetConsoleCP()); + if (!PyFile_SetEncoding(sysin, buf)) + return NULL; + } + if(isatty(_fileno(stdout))) { + sprintf(buf, "cp%d", GetConsoleOutputCP()); + if (!PyFile_SetEncoding(sysout, buf)) + return NULL; + } +#endif + +#if defined(HAVE_LANGINFO_H) && defined(CODESET) + oldloc = setlocale(LC_CTYPE, 0); + setlocale(LC_CTYPE, ""); + codeset = nl_langinfo(CODESET); + setlocale(LC_CTYPE, oldloc); + if(codeset && isatty(fileno(stdin))){ + if (!PyFile_SetEncoding(sysin, codeset)) + return NULL; + } + if(codeset && isatty(fileno(stdout))) { + if (!PyFile_SetEncoding(sysout, codeset)) + return NULL; + } +#endif + PyDict_SetItemString(sysdict, "stdin", sysin); PyDict_SetItemString(sysdict, "stdout", sysout); PyDict_SetItemString(sysdict, "stderr", syserr);