annotate Python/fileutils.c @ 84172:e353f64dfd95

importlib.abc.SourceLoader.get_source() was re-raising SyntaxError and UnicodeDecodeError as ImportError. That was over-reaching the point of raising ImportError in get_source() (which is to signal the source code was not found when it should have). Conflating the two exceptions with ImportError could lead to masking errors with the source which should be known outside of whether there was an error simply getting the source to begin with.
author Brett Cannon <brett@python.org>
date Sun, 16 Jun 2013 18:05:54 -0400
parents 88a21c5a97ef
children dfc020b4b123
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
1 #include "Python.h"
80406
5db6d9ddf6e8 Issue #15835: Define PATH_MAX on HP-UX.
Stefan Krah <skrah@bytereef.org>
parents: 75353
diff changeset
2 #include "osdefs.h"
65164
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
3 #ifdef MS_WINDOWS
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
4 # include <windows.h>
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
5 #endif
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
6
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
7 #ifdef HAVE_LANGINFO_H
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
8 #include <locale.h>
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
9 #include <langinfo.h>
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
10 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
11
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
12 #ifdef __APPLE__
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
13 extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size);
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
14 #endif
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
15
75353
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
16 PyObject *
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
17 _Py_device_encoding(int fd)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
18 {
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
19 #if defined(MS_WINDOWS) || defined(MS_WIN64)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
20 UINT cp;
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
21 #endif
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
22 if (!_PyVerify_fd(fd) || !isatty(fd)) {
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
23 Py_RETURN_NONE;
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
24 }
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
25 #if defined(MS_WINDOWS) || defined(MS_WIN64)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
26 if (fd == 0)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
27 cp = GetConsoleCP();
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
28 else if (fd == 1 || fd == 2)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
29 cp = GetConsoleOutputCP();
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
30 else
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
31 cp = 0;
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
32 /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
33 has no console */
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
34 if (cp != 0)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
35 return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
36 #elif defined(CODESET)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
37 {
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
38 char *codeset = nl_langinfo(CODESET);
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
39 if (codeset != NULL && codeset[0] != 0)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
40 return PyUnicode_FromString(codeset);
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
41 }
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
42 #endif
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
43 Py_RETURN_NONE;
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
44 }
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
45
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
46 #if !defined(__APPLE__) && !defined(MS_WINDOWS)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
47 extern int _Py_normalize_encoding(const char *, char *, size_t);
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
48
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
49 /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale.
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
50 On these operating systems, nl_langinfo(CODESET) announces an alias of the
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
51 ASCII encoding, whereas mbstowcs() and wcstombs() functions use the
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
52 ISO-8859-1 encoding. The problem is that os.fsencode() and os.fsdecode() use
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
53 locale.getpreferredencoding() codec. For example, if command line arguments
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
54 are decoded by mbstowcs() and encoded back by os.fsencode(), we get a
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
55 UnicodeEncodeError instead of retrieving the original byte string.
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
56
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
57 The workaround is enabled if setlocale(LC_CTYPE, NULL) returns "C",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
58 nl_langinfo(CODESET) announces "ascii" (or an alias to ASCII), and at least
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
59 one byte in range 0x80-0xff can be decoded from the locale encoding. The
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
60 workaround is also enabled on error, for example if getting the locale
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
61 failed.
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
62
81535
Philip Jenvey <pjenvey@underboss.org>
parents: 81259
diff changeset
63 Values of force_ascii:
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
64
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
65 1: the workaround is used: _Py_wchar2char() uses
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
66 encode_ascii_surrogateescape() and _Py_char2wchar() uses
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
67 decode_ascii_surrogateescape()
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
68 0: the workaround is not used: _Py_wchar2char() uses wcstombs() and
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
69 _Py_char2wchar() uses mbstowcs()
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
70 -1: unknown, need to call check_force_ascii() to get the value
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
71 */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
72 static int force_ascii = -1;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
73
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
74 static int
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
75 check_force_ascii(void)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
76 {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
77 char *loc;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
78 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
79 char *codeset, **alias;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
80 char encoding[100];
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
81 int is_ascii;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
82 unsigned int i;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
83 char* ascii_aliases[] = {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
84 "ascii",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
85 "646",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
86 "ansi-x3.4-1968",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
87 "ansi-x3-4-1968",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
88 "ansi-x3.4-1986",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
89 "cp367",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
90 "csascii",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
91 "ibm367",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
92 "iso646-us",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
93 "iso-646.irv-1991",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
94 "iso-ir-6",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
95 "us",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
96 "us-ascii",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
97 NULL
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
98 };
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
99 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
100
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
101 loc = setlocale(LC_CTYPE, NULL);
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
102 if (loc == NULL)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
103 goto error;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
104 if (strcmp(loc, "C") != 0) {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
105 /* the LC_CTYPE locale is different than C */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
106 return 0;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
107 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
108
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
109 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
110 codeset = nl_langinfo(CODESET);
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
111 if (!codeset || codeset[0] == '\0') {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
112 /* CODESET is not set or empty */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
113 goto error;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
114 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
115 if (!_Py_normalize_encoding(codeset, encoding, sizeof(encoding)))
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
116 goto error;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
117
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
118 is_ascii = 0;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
119 for (alias=ascii_aliases; *alias != NULL; alias++) {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
120 if (strcmp(encoding, *alias) == 0) {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
121 is_ascii = 1;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
122 break;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
123 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
124 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
125 if (!is_ascii) {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
126 /* nl_langinfo(CODESET) is not "ascii" or an alias of ASCII */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
127 return 0;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
128 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
129
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
130 for (i=0x80; i<0xff; i++) {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
131 unsigned char ch;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
132 wchar_t wch;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
133 size_t res;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
134
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
135 ch = (unsigned char)i;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
136 res = mbstowcs(&wch, (char*)&ch, 1);
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
137 if (res != (size_t)-1) {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
138 /* decoding a non-ASCII character from the locale encoding succeed:
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
139 the locale encoding is not ASCII, force ASCII */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
140 return 1;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
141 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
142 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
143 /* None of the bytes in the range 0x80-0xff can be decoded from the locale
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
144 encoding: the locale encoding is really ASCII */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
145 return 0;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
146 #else
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
147 /* nl_langinfo(CODESET) is not available: always force ASCII */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
148 return 1;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
149 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
150
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
151 error:
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
152 /* if an error occured, force the ASCII encoding */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
153 return 1;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
154 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
155
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
156 static char*
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
157 encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
158 {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
159 char *result = NULL, *out;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
160 size_t len, i;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
161 wchar_t ch;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
162
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
163 if (error_pos != NULL)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
164 *error_pos = (size_t)-1;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
165
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
166 len = wcslen(text);
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
167
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
168 result = PyMem_Malloc(len + 1); /* +1 for NUL byte */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
169 if (result == NULL)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
170 return NULL;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
171
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
172 out = result;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
173 for (i=0; i<len; i++) {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
174 ch = text[i];
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
175
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
176 if (ch <= 0x7f) {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
177 /* ASCII character */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
178 *out++ = (char)ch;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
179 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
180 else if (0xdc80 <= ch && ch <= 0xdcff) {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
181 /* UTF-8b surrogate */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
182 *out++ = (char)(ch - 0xdc00);
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
183 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
184 else {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
185 if (error_pos != NULL)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
186 *error_pos = i;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
187 PyMem_Free(result);
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
188 return NULL;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
189 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
190 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
191 *out = '\0';
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
192 return result;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
193 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
194 #endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
195
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
196 #if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC))
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
197 static wchar_t*
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
198 decode_ascii_surrogateescape(const char *arg, size_t *size)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
199 {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
200 wchar_t *res;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
201 unsigned char *in;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
202 wchar_t *out;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
203
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
204 res = PyMem_Malloc((strlen(arg)+1)*sizeof(wchar_t));
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
205 if (!res)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
206 return NULL;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
207
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
208 in = (unsigned char*)arg;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
209 out = res;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
210 while(*in)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
211 if(*in < 128)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
212 *out++ = *in++;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
213 else
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
214 *out++ = 0xdc00 + *in++;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
215 *out = 0;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
216 if (size != NULL)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
217 *size = out - res;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
218 return res;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
219 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
220 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
221
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
222
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
223 /* Decode a byte string from the locale encoding with the
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
224 surrogateescape error handler (undecodable bytes are decoded as characters
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
225 in range U+DC80..U+DCFF). If a byte sequence can be decoded as a surrogate
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
226 character, escape the bytes using the surrogateescape error handler instead
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
227 of decoding them.
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
228
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
229 Use _Py_wchar2char() to encode the character string back to a byte string.
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
230
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
231 Return a pointer to a newly allocated wide character string (use
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
232 PyMem_Free() to free the memory) and write the number of written wide
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
233 characters excluding the null character into *size if size is not NULL, or
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
234 NULL on error (decoding or memory allocation error). If size is not NULL,
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
235 *size is set to (size_t)-1 on memory error and (size_t)-2 on decoding
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
236 error.
66094
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
237
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
238 Conversion errors should never happen, unless there is a bug in the C
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
239 library. */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
240 wchar_t*
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
241 _Py_char2wchar(const char* arg, size_t *size)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
242 {
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
243 #ifdef __APPLE__
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
244 wchar_t *wstr;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
245 wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg));
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
246 if (size != NULL) {
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
247 if (wstr != NULL)
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
248 *size = wcslen(wstr);
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
249 else
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
250 *size = (size_t)-1;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
251 }
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
252 return wstr;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
253 #else
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
254 wchar_t *res;
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
255 size_t argsize;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
256 size_t count;
83673
2ea629da4f54 Fix a compiler warning: in and out are unused in _Py_char2wchar() if
Victor Stinner <victor.stinner@gmail.com>
parents: 81535
diff changeset
257 #ifdef HAVE_MBRTOWC
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
258 unsigned char *in;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
259 wchar_t *out;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
260 mbstate_t mbs;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
261 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
262
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
263 #ifndef MS_WINDOWS
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
264 if (force_ascii == -1)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
265 force_ascii = check_force_ascii();
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
266
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
267 if (force_ascii) {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
268 /* force ASCII encoding to workaround mbstowcs() issue */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
269 res = decode_ascii_surrogateescape(arg, size);
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
270 if (res == NULL)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
271 goto oom;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
272 return res;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
273 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
274 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
275
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
276 #ifdef HAVE_BROKEN_MBSTOWCS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
277 /* Some platforms have a broken implementation of
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
278 * mbstowcs which does not count the characters that
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
279 * would result from conversion. Use an upper bound.
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
280 */
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
281 argsize = strlen(arg);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
282 #else
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
283 argsize = mbstowcs(NULL, arg, 0);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
284 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
285 if (argsize != (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
286 res = (wchar_t *)PyMem_Malloc((argsize+1)*sizeof(wchar_t));
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
287 if (!res)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
288 goto oom;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
289 count = mbstowcs(res, arg, argsize+1);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
290 if (count != (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
291 wchar_t *tmp;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
292 /* Only use the result if it contains no
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
293 surrogate characters. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
294 for (tmp = res; *tmp != 0 &&
80057
13dd8199c112 Issue #16330: Use surrogate-related macros
Victor Stinner <victor.stinner@gmail.com>
parents: 75353
diff changeset
295 !Py_UNICODE_IS_SURROGATE(*tmp); tmp++)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
296 ;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
297 if (*tmp == 0) {
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
298 if (size != NULL)
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
299 *size = count;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
300 return res;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
301 }
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
302 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
303 PyMem_Free(res);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
304 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
305 /* Conversion failed. Fall back to escaping with surrogateescape. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
306 #ifdef HAVE_MBRTOWC
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
307 /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
308
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
309 /* Overallocate; as multi-byte characters are in the argument, the
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
310 actual output could use less memory. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
311 argsize = strlen(arg) + 1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
312 res = (wchar_t*)PyMem_Malloc(argsize*sizeof(wchar_t));
66094
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
313 if (!res)
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
314 goto oom;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
315 in = (unsigned char*)arg;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
316 out = res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
317 memset(&mbs, 0, sizeof mbs);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
318 while (argsize) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
319 size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
320 if (converted == 0)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
321 /* Reached end of string; null char stored. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
322 break;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
323 if (converted == (size_t)-2) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
324 /* Incomplete character. This should never happen,
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
325 since we provide everything that we have -
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
326 unless there is a bug in the C library, or I
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
327 misunderstood how mbrtowc works. */
66094
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
328 PyMem_Free(res);
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
329 if (size != NULL)
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
330 *size = (size_t)-2;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
331 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
332 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
333 if (converted == (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
334 /* Conversion error. Escape as UTF-8b, and start over
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
335 in the initial shift state. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
336 *out++ = 0xdc00 + *in++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
337 argsize--;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
338 memset(&mbs, 0, sizeof mbs);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
339 continue;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
340 }
80057
13dd8199c112 Issue #16330: Use surrogate-related macros
Victor Stinner <victor.stinner@gmail.com>
parents: 75353
diff changeset
341 if (Py_UNICODE_IS_SURROGATE(*out)) {
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
342 /* Surrogate character. Escape the original
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
343 byte sequence with surrogateescape. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
344 argsize -= converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
345 while (converted--)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
346 *out++ = 0xdc00 + *in++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
347 continue;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
348 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
349 /* successfully converted some bytes */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
350 in += converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
351 argsize -= converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
352 out++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
353 }
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
354 if (size != NULL)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
355 *size = out - res;
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
356 #else /* HAVE_MBRTOWC */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
357 /* Cannot use C locale for escaping; manually escape as if charset
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
358 is ASCII (i.e. escape all bytes > 128. This will still roundtrip
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
359 correctly in the locale's charset, which must be an ASCII superset. */
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
360 res = decode_ascii_surrogateescape(arg, size);
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
361 if (res == NULL)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
362 goto oom;
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
363 #endif /* HAVE_MBRTOWC */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
364 return res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
365 oom:
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
366 if (size != NULL)
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
367 *size = (size_t)-1;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
368 return NULL;
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
369 #endif /* __APPLE__ */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
370 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
371
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
372 /* Encode a (wide) character string to the locale encoding with the
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
373 surrogateescape error handler (characters in range U+DC80..U+DCFF are
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
374 converted to bytes 0x80..0xFF).
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
375
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
376 This function is the reverse of _Py_char2wchar().
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
377
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
378 Return a pointer to a newly allocated byte string (use PyMem_Free() to free
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
379 the memory), or NULL on encoding or memory allocation error.
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
380
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
381 If error_pos is not NULL: *error_pos is the index of the invalid character
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
382 on encoding error, or (size_t)-1 otherwise. */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
383 char*
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
384 _Py_wchar2char(const wchar_t *text, size_t *error_pos)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
385 {
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
386 #ifdef __APPLE__
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
387 Py_ssize_t len;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
388 PyObject *unicode, *bytes = NULL;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
389 char *cpath;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
390
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
391 unicode = PyUnicode_FromWideChar(text, wcslen(text));
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
392 if (unicode == NULL)
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
393 return NULL;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
394
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
395 bytes = _PyUnicode_AsUTF8String(unicode, "surrogateescape");
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
396 Py_DECREF(unicode);
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
397 if (bytes == NULL) {
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
398 PyErr_Clear();
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
399 if (error_pos != NULL)
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
400 *error_pos = (size_t)-1;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
401 return NULL;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
402 }
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
403
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
404 len = PyBytes_GET_SIZE(bytes);
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
405 cpath = PyMem_Malloc(len+1);
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
406 if (cpath == NULL) {
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
407 PyErr_Clear();
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
408 Py_DECREF(bytes);
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
409 if (error_pos != NULL)
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
410 *error_pos = (size_t)-1;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
411 return NULL;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
412 }
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
413 memcpy(cpath, PyBytes_AsString(bytes), len + 1);
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
414 Py_DECREF(bytes);
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
415 return cpath;
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
416 #else /* __APPLE__ */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
417 const size_t len = wcslen(text);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
418 char *result = NULL, *bytes = NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
419 size_t i, size, converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
420 wchar_t c, buf[2];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
421
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
422 #ifndef MS_WINDOWS
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
423 if (force_ascii == -1)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
424 force_ascii = check_force_ascii();
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
425
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
426 if (force_ascii)
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
427 return encode_ascii_surrogateescape(text, error_pos);
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
428 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
429
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
430 /* The function works in two steps:
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
431 1. compute the length of the output buffer in bytes (size)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
432 2. outputs the bytes */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
433 size = 0;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
434 buf[1] = 0;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
435 while (1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
436 for (i=0; i < len; i++) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
437 c = text[i];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
438 if (c >= 0xdc80 && c <= 0xdcff) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
439 /* UTF-8b surrogate */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
440 if (bytes != NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
441 *bytes++ = c - 0xdc00;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
442 size--;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
443 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
444 else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
445 size++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
446 continue;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
447 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
448 else {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
449 buf[0] = c;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
450 if (bytes != NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
451 converted = wcstombs(bytes, buf, size);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
452 else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
453 converted = wcstombs(NULL, buf, 0);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
454 if (converted == (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
455 if (result != NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
456 PyMem_Free(result);
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
457 if (error_pos != NULL)
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
458 *error_pos = i;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
459 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
460 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
461 if (bytes != NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
462 bytes += converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
463 size -= converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
464 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
465 else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
466 size += converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
467 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
468 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
469 if (result != NULL) {
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
470 *bytes = '\0';
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
471 break;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
472 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
473
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
474 size += 1; /* nul byte at the end */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
475 result = PyMem_Malloc(size);
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
476 if (result == NULL) {
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
477 if (error_pos != NULL)
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
478 *error_pos = (size_t)-1;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
479 return NULL;
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
480 }
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
481 bytes = result;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
482 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
483 return result;
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
484 #endif /* __APPLE__ */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
485 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
486
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
487 /* In principle, this should use HAVE__WSTAT, and _wstat
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
488 should be detected by autoconf. However, no current
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
489 POSIX system provides that function, so testing for
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
490 it is pointless.
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
491 Not sure whether the MS_WINDOWS guards are necessary:
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
492 perhaps for cygwin/mingw builds?
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
493 */
65164
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
494 #if defined(HAVE_STAT) && !defined(MS_WINDOWS)
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
495
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
496 /* Get file status. Encode the path to the locale encoding. */
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
497
65164
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
498 int
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
499 _Py_wstat(const wchar_t* path, struct stat *buf)
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
500 {
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
501 int err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
502 char *fname;
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
503 fname = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
504 if (fname == NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
505 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
506 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
507 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
508 err = stat(fname, buf);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
509 PyMem_Free(fname);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
510 return err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
511 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
512 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
513
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
514 #ifdef HAVE_STAT
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
515
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
516 /* Call _wstat() on Windows, or encode the path to the filesystem encoding and
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
517 call stat() otherwise. Only fill st_mode attribute on Windows.
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
518
74058
2a140b01d343 import.c now catchs _Py_stat() exceptions
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74002
diff changeset
519 Return 0 on success, -1 on _wstat() / stat() error, -2 if an exception was
2a140b01d343 import.c now catchs _Py_stat() exceptions
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74002
diff changeset
520 raised. */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
521
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
522 int
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
523 _Py_stat(PyObject *path, struct stat *statbuf)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
524 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
525 #ifdef MS_WINDOWS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
526 int err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
527 struct _stat wstatbuf;
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
528 wchar_t *wpath;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
529
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
530 wpath = PyUnicode_AsUnicode(path);
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
531 if (wpath == NULL)
74058
2a140b01d343 import.c now catchs _Py_stat() exceptions
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74002
diff changeset
532 return -2;
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
533 err = _wstat(wpath, &wstatbuf);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
534 if (!err)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
535 statbuf->st_mode = wstatbuf.st_mode;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
536 return err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
537 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
538 int ret;
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
539 PyObject *bytes = PyUnicode_EncodeFSDefault(path);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
540 if (bytes == NULL)
74058
2a140b01d343 import.c now catchs _Py_stat() exceptions
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74002
diff changeset
541 return -2;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
542 ret = stat(PyBytes_AS_STRING(bytes), statbuf);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
543 Py_DECREF(bytes);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
544 return ret;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
545 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
546 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
547
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
548 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
549
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
550 /* Open a file. Use _wfopen() on Windows, encode the path to the locale
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
551 encoding and use fopen() otherwise. */
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
552
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
553 FILE *
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
554 _Py_wfopen(const wchar_t *path, const wchar_t *mode)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
555 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
556 #ifndef MS_WINDOWS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
557 FILE *f;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
558 char *cpath;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
559 char cmode[10];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
560 size_t r;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
561 r = wcstombs(cmode, mode, 10);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
562 if (r == (size_t)-1 || r >= 10) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
563 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
564 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
565 }
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
566 cpath = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
567 if (cpath == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
568 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
569 f = fopen(cpath, cmode);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
570 PyMem_Free(cpath);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
571 return f;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
572 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
573 return _wfopen(path, mode);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
574 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
575 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
576
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
577 /* Call _wfopen() on Windows, or encode the path to the filesystem encoding and
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
578 call fopen() otherwise.
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
579
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
580 Return the new file object on success, or NULL if the file cannot be open or
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
581 (if PyErr_Occurred()) on unicode error */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
582
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
583 FILE*
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
584 _Py_fopen(PyObject *path, const char *mode)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
585 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
586 #ifdef MS_WINDOWS
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
587 wchar_t *wpath;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
588 wchar_t wmode[10];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
589 int usize;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
590
74129
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
591 if (!PyUnicode_Check(path)) {
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
592 PyErr_Format(PyExc_TypeError,
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
593 "str file path expected under Windows, got %R",
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
594 Py_TYPE(path));
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
595 return NULL;
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
596 }
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
597 wpath = PyUnicode_AsUnicode(path);
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
598 if (wpath == NULL)
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
599 return NULL;
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
600
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
601 usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, sizeof(wmode));
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
602 if (usize == 0)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
603 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
604
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
605 return _wfopen(wpath, wmode);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
606 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
607 FILE *f;
74085
a882aa30a713 _Py_fopen now allows bytes filenames under non-Windows platforms.
Antoine Pitrou <solipsis@pitrou.net>
parents: 74058
diff changeset
608 PyObject *bytes;
a882aa30a713 _Py_fopen now allows bytes filenames under non-Windows platforms.
Antoine Pitrou <solipsis@pitrou.net>
parents: 74058
diff changeset
609 if (!PyUnicode_FSConverter(path, &bytes))
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
610 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
611 f = fopen(PyBytes_AS_STRING(bytes), mode);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
612 Py_DECREF(bytes);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
613 return f;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
614 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
615 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
616
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
617 #ifdef HAVE_READLINK
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
618
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
619 /* Read value of symbolic link. Encode the path to the locale encoding, decode
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
620 the result from the locale encoding. Return -1 on error. */
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
621
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
622 int
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
623 _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
624 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
625 char *cpath;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
626 char cbuf[PATH_MAX];
65409
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
627 wchar_t *wbuf;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
628 int res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
629 size_t r1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
630
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
631 cpath = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
632 if (cpath == NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
633 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
634 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
635 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
636 res = (int)readlink(cpath, cbuf, PATH_MAX);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
637 PyMem_Free(cpath);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
638 if (res == -1)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
639 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
640 if (res == PATH_MAX) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
641 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
642 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
643 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
644 cbuf[res] = '\0'; /* buf will be null terminated */
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
645 wbuf = _Py_char2wchar(cbuf, &r1);
65410
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
646 if (wbuf == NULL) {
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
647 errno = EINVAL;
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
648 return -1;
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
649 }
65409
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
650 if (bufsiz <= r1) {
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
651 PyMem_Free(wbuf);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
652 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
653 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
654 }
65409
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
655 wcsncpy(buf, wbuf, bufsiz);
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
656 PyMem_Free(wbuf);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
657 return (int)r1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
658 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
659 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
660
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
661 #ifdef HAVE_REALPATH
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
662
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
663 /* Return the canonicalized absolute pathname. Encode path to the locale
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
664 encoding, decode the result from the locale encoding.
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
665 Return NULL on error. */
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
666
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
667 wchar_t*
65166
8fd5d06462e6 _Py_wrealpath() requires the size of the output buffer
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65165
diff changeset
668 _Py_wrealpath(const wchar_t *path,
8fd5d06462e6 _Py_wrealpath() requires the size of the output buffer
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65165
diff changeset
669 wchar_t *resolved_path, size_t resolved_path_size)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
670 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
671 char *cpath;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
672 char cresolved_path[PATH_MAX];
65411
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
673 wchar_t *wresolved_path;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
674 char *res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
675 size_t r;
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
676 cpath = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
677 if (cpath == NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
678 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
679 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
680 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
681 res = realpath(cpath, cresolved_path);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
682 PyMem_Free(cpath);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
683 if (res == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
684 return NULL;
65411
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
685
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
686 wresolved_path = _Py_char2wchar(cresolved_path, &r);
65411
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
687 if (wresolved_path == NULL) {
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
688 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
689 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
690 }
65411
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
691 if (resolved_path_size <= r) {
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
692 PyMem_Free(wresolved_path);
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
693 errno = EINVAL;
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
694 return NULL;
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
695 }
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
696 wcsncpy(resolved_path, wresolved_path, resolved_path_size);
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
697 PyMem_Free(wresolved_path);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
698 return resolved_path;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
699 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
700 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
701
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
702 /* Get the current directory. size is the buffer size in wide characters
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
703 including the null character. Decode the path from the locale encoding.
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
704 Return NULL on error. */
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
705
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
706 wchar_t*
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
707 _Py_wgetcwd(wchar_t *buf, size_t size)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
708 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
709 #ifdef MS_WINDOWS
84034
88a21c5a97ef Issue #9566: Fix compiler warning on Windows 64-bit
Victor Stinner <victor.stinner@gmail.com>
parents: 83673
diff changeset
710 int isize = (int)Py_MIN(size, INT_MAX);
88a21c5a97ef Issue #9566: Fix compiler warning on Windows 64-bit
Victor Stinner <victor.stinner@gmail.com>
parents: 83673
diff changeset
711 return _wgetcwd(buf, isize);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
712 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
713 char fname[PATH_MAX];
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
714 wchar_t *wname;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
715 size_t len;
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
716
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
717 if (getcwd(fname, PATH_MAX) == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
718 return NULL;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
719 wname = _Py_char2wchar(fname, &len);
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
720 if (wname == NULL)
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
721 return NULL;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
722 if (size <= len) {
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
723 PyMem_Free(wname);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
724 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
725 }
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
726 wcsncpy(buf, wname, size);
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
727 PyMem_Free(wname);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
728 return buf;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
729 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
730 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
731