[Python-checkins] r82711 - in python/branches/import_unicode: Include/Python.h Modules/main.c

victor.stinner python-checkins at python.org
Fri Jul 9 01:33:21 CEST 2010


Author: victor.stinner
Date: Fri Jul  9 01:33:21 2010
New Revision: 82711

Log:
create _Py_wchar2char()

Use it in _wfopen() (implementation for non Windows OS)

Modified:
   python/branches/import_unicode/Include/Python.h
   python/branches/import_unicode/Modules/main.c

Modified: python/branches/import_unicode/Include/Python.h
==============================================================================
--- python/branches/import_unicode/Include/Python.h	(original)
+++ python/branches/import_unicode/Include/Python.h	Fri Jul  9 01:33:21 2010
@@ -128,8 +128,10 @@
 /* _Py_Mangle is defined in compile.c */
 PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name);
 
-/* _Py_char2wchar lives in main.c */
+/* _Py_char2wchar and _Py_wchar2char lives in main.c */
 PyAPI_FUNC(wchar_t *) _Py_char2wchar(char *);
+PyAPI_FUNC(char*) _Py_wchar2char(const wchar_t *text);
+
 #ifdef __cplusplus
 }
 #endif

Modified: python/branches/import_unicode/Modules/main.c
==============================================================================
--- python/branches/import_unicode/Modules/main.c	(original)
+++ python/branches/import_unicode/Modules/main.c	Fri Jul  9 01:33:21 2010
@@ -105,20 +105,21 @@
 static FILE*
 _wfopen(const wchar_t *path, const wchar_t *mode)
 {
-    char cpath[PATH_MAX];
+    FILE *f;
+    char *cpath;
     char cmode[10];
     size_t r;
-    r = wcstombs(cpath, path, PATH_MAX);
-    if (r == (size_t)-1 || r >= PATH_MAX) {
-        errno = EINVAL;
+    cpath = _Py_wchar2char(path);
+    if (cpath == NULL)
         return NULL;
-    }
     r = wcstombs(cmode, mode, 10);
     if (r == (size_t)-1 || r >= 10) {
         errno = EINVAL;
         return NULL;
     }
-    return fopen(cpath, cmode);
+    f = fopen(cpath, cmode);
+    PyMem_Free(cpath);
+    return f;
 }
 #endif
 
@@ -711,6 +712,43 @@
     *argv = orig_argv;
 }
 
+char*
+_Py_wchar2char(const wchar_t *text)
+{
+    char *result, *bytes;
+    size_t i, len, converted, size;
+    wchar_t c;
+
+    len = wcslen(text);
+    /* FIXME: use better heuristic for the buffer size */
+    size = len * 10 + 1; /* +1 for the nul byte at the end */
+    result = PyMem_Malloc(size);
+    if (result == NULL)
+        return NULL;
+
+    bytes = result;
+    for (i=0; i < len; i++) {
+        c = text[i];
+        if (c >= 0xd800 && c <= 0xdfff) {
+            /* Surrogate character */
+            *bytes++ = c - 0xdc00;
+            size--;
+            continue;
+        } else {
+            wchar_t buf[2];
+            buf[0] = c;
+            buf[1] = 0;
+            converted = wcstombs(bytes, buf, size);
+            if (converted == (size_t)-1 || converted == 0) {
+                PyMem_Free(result);
+                return NULL;
+            }
+            bytes += converted;
+            size -= converted;
+        }
+    }
+    return result;
+}
 
 wchar_t*
 _Py_char2wchar(char* arg)


More information about the Python-checkins mailing list