annotate Python/fileutils.c @ 81257:c256764e2b3f 3.2

Issue #16455: On FreeBSD and Solaris, if the locale is C, the ASCII/surrogateescape codec is now used, instead of the locale encoding, to decode the command line arguments. This change fixes inconsistencies with os.fsencode() and os.fsdecode() because these operating systems announces an ASCII locale encoding, whereas the ISO-8859-1 encoding is used in practice.
author Victor Stinner <victor.stinner@gmail.com>
date Thu, 03 Jan 2013 01:08:58 +0100
parents af6fd3ca6de9
children 5bb289e4fb35
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"
65164
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
2 #ifdef MS_WINDOWS
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
3 # include <windows.h>
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
4 #endif
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
5
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
6 #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
7 #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
8 #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
9 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
10
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
11 #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
12 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
13 #endif
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
14
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
15 #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
16 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
17
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
18 /* 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
19 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
20 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
21 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
22 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
23 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
24 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
25
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
26 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
27 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
28 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
29 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
30 failed.
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
31
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
32 Values of locale_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
33
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
34 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
35 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
36 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
37 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
38 _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
39 -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
40 */
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
41 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
42
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
43 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
44 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
45 {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
46 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
47 #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
48 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
49 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
50 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
51 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
52 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
53 "ascii",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
54 "646",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
55 "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
56 "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
57 "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
58 "cp367",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
59 "csascii",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
60 "ibm367",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
61 "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
62 "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
63 "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
64 "us",
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
65 "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
66 NULL
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
67 };
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
68 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
69
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
70 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
71 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
72 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
73 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
74 /* 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
75 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
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
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 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
80 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
81 /* 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
82 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
83 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
84 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
85 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
86
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
87 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
88 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
89 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
90 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
91 break;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
92 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
93 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
94 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
95 /* 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
96 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
97 }
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 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
100 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
101 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
102 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
103
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
104 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
105 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
106 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
107 /* 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
108 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
109 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
110 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
111 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
112 /* 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
113 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
114 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
115 #else
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
116 /* 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
117 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
118 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
119
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
120 error:
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
121 /* 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
122 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
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 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
126 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
127 {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
128 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
129 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
130 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
131
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
132 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
133 *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
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 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
136
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
137 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
138 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
139 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
140
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
141 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
142 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
143 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
144
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
145 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
146 /* 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
147 *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
148 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
149 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
150 /* 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
151 *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
152 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
153 else {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
154 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
155 *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
156 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
157 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
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 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
160 *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
161 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
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 #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
164
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
165 #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
166 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
167 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
168 {
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
169 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
170 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
171 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
172
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
173 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
174 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
175 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
176
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
177 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
178 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
179 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
180 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
181 *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
182 else
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
183 *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
184 *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
185 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
186 *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
187 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
188 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
189 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
190
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
191
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
192 /* Decode a byte string from the locale encoding with the
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
193 surrogateescape error handler (undecodable bytes are decoded as characters
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
194 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
195 character, escape the bytes using the surrogateescape error handler instead
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
196 of decoding them.
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
197
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
198 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
199
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
200 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
201 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
202 characters excluding the null character into *size if size is not NULL, or
66094
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
203 NULL on error (conversion or memory allocation error).
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
204
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
205 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
206 library. */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
207 wchar_t*
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
208 _Py_char2wchar(const char* arg, size_t *size)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
209 {
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
210 #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
211 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
212 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
213 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
214 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
215 *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
216 else
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
217 *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
218 }
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
219 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
220 #else
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
221 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
222 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
223 size_t count;
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
224 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
225 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
226 #ifdef 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
227 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
228 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
229
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
230 #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
231 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
232 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
233
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
234 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
235 /* 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
236 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
237 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
238 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
239 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
240 }
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
241 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
242
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
243 #ifdef HAVE_BROKEN_MBSTOWCS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
244 /* Some platforms have a broken implementation of
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
245 * mbstowcs which does not count the characters that
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
246 * would result from conversion. Use an upper bound.
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
247 */
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
248 argsize = strlen(arg);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
249 #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
250 argsize = mbstowcs(NULL, arg, 0);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
251 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
252 if (argsize != (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
253 res = (wchar_t *)PyMem_Malloc((argsize+1)*sizeof(wchar_t));
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
254 if (!res)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
255 goto oom;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
256 count = mbstowcs(res, arg, argsize+1);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
257 if (count != (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
258 wchar_t *tmp;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
259 /* Only use the result if it contains no
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
260 surrogate characters. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
261 for (tmp = res; *tmp != 0 &&
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
262 (*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
263 ;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
264 if (*tmp == 0) {
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
265 if (size != NULL)
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
266 *size = count;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
267 return res;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
268 }
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
269 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
270 PyMem_Free(res);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
271 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
272 /* Conversion failed. Fall back to escaping with surrogateescape. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
273 #ifdef HAVE_MBRTOWC
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
274 /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
275
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
276 /* Overallocate; as multi-byte characters are in the argument, the
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
277 actual output could use less memory. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
278 argsize = strlen(arg) + 1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
279 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
280 if (!res)
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
281 goto oom;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
282 in = (unsigned char*)arg;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
283 out = res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
284 memset(&mbs, 0, sizeof mbs);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
285 while (argsize) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
286 size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
287 if (converted == 0)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
288 /* Reached end of string; null char stored. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
289 break;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
290 if (converted == (size_t)-2) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
291 /* Incomplete character. This should never happen,
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
292 since we provide everything that we have -
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
293 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
294 misunderstood how mbrtowc works. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
295 fprintf(stderr, "unexpected mbrtowc result -2\n");
66094
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
296 PyMem_Free(res);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
297 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
298 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
299 if (converted == (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
300 /* Conversion error. Escape as UTF-8b, and start over
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
301 in the initial shift state. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
302 *out++ = 0xdc00 + *in++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
303 argsize--;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
304 memset(&mbs, 0, sizeof mbs);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
305 continue;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
306 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
307 if (*out >= 0xd800 && *out <= 0xdfff) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
308 /* Surrogate character. Escape the original
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
309 byte sequence with surrogateescape. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
310 argsize -= converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
311 while (converted--)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
312 *out++ = 0xdc00 + *in++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
313 continue;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
314 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
315 /* successfully converted some bytes */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
316 in += converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
317 argsize -= converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
318 out++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
319 }
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
320 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
321 *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
322 #else /* HAVE_MBRTOWC */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
323 /* 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
324 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
325 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
326 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
327 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
328 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
329 #endif /* HAVE_MBRTOWC */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
330 return res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
331 oom:
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
332 fprintf(stderr, "out of memory\n");
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
333 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
334 #endif /* __APPLE__ */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
335 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
336
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
337 /* 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
338 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
339 converted to bytes 0x80..0xFF).
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
340
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
341 This function is the reverse of _Py_char2wchar().
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
342
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
343 Return a pointer to a newly allocated byte string (use PyMem_Free() to free
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
344 the memory), or NULL on conversion or memory allocation error.
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
345
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
346 If error_pos is not NULL: *error_pos is the index of the invalid character
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
347 on conversion error, or (size_t)-1 otherwise. */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
348 char*
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
349 _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
350 {
80702
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
351 #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
352 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
353 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
354 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
355
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
356 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
357 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
358 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
359
80704
af6fd3ca6de9 Issue #16416: Fix compilation error
Victor Stinner <victor.stinner@gmail.com>
parents: 80702
diff changeset
360 bytes = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode),
af6fd3ca6de9 Issue #16416: Fix compilation error
Victor Stinner <victor.stinner@gmail.com>
parents: 80702
diff changeset
361 PyUnicode_GET_SIZE(unicode),
af6fd3ca6de9 Issue #16416: Fix compilation error
Victor Stinner <victor.stinner@gmail.com>
parents: 80702
diff changeset
362 "surrogateescape");
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 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
364 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
365 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
366 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
367 *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
368 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
369 }
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
370
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
371 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
372 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
373 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
374 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
375 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
376 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
377 *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
378 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
379 }
c838c9b117f1 Issue #16416: On Mac OS X, operating system data are now always
Victor Stinner <victor.stinner@gmail.com>
parents: 66094
diff changeset
380 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
381 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
382 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
383 #else /* __APPLE__ */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
384 const size_t len = wcslen(text);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
385 char *result = NULL, *bytes = NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
386 size_t i, size, converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
387 wchar_t c, buf[2];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
388
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
389 #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
390 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
391 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
392
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
393 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
394 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
395 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
396
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
397 /* The function works in two steps:
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
398 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
399 2. outputs the bytes */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
400 size = 0;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
401 buf[1] = 0;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
402 while (1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
403 for (i=0; i < len; i++) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
404 c = text[i];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
405 if (c >= 0xdc80 && c <= 0xdcff) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
406 /* UTF-8b surrogate */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
407 if (bytes != NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
408 *bytes++ = c - 0xdc00;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
409 size--;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
410 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
411 else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
412 size++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
413 continue;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
414 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
415 else {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
416 buf[0] = c;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
417 if (bytes != NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
418 converted = wcstombs(bytes, buf, size);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
419 else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
420 converted = wcstombs(NULL, buf, 0);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
421 if (converted == (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
422 if (result != NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
423 PyMem_Free(result);
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
424 if (error_pos != NULL)
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
425 *error_pos = i;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
426 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
427 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
428 if (bytes != NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
429 bytes += converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
430 size -= converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
431 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
432 else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
433 size += converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
434 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
435 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
436 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
437 *bytes = '\0';
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
438 break;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
439 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
440
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
441 size += 1; /* nul byte at the end */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
442 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
443 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
444 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
445 *error_pos = (size_t)-1;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
446 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
447 }
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
448 bytes = result;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
449 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
450 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
451 #endif /* __APPLE__ */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
452 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
453
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
454 /* In principle, this should use HAVE__WSTAT, and _wstat
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
455 should be detected by autoconf. However, no current
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
456 POSIX system provides that function, so testing for
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
457 it is pointless.
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
458 Not sure whether the MS_WINDOWS guards are necessary:
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
459 perhaps for cygwin/mingw builds?
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
460 */
65164
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
461 #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
462
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
463 /* 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
464
65164
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
465 int
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
466 _Py_wstat(const wchar_t* path, struct stat *buf)
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
467 {
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
468 int err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
469 char *fname;
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
470 fname = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
471 if (fname == NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
472 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
473 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
474 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
475 err = stat(fname, buf);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
476 PyMem_Free(fname);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
477 return err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
478 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
479 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
480
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
481 #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
482
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
483 /* 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
484 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
485
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
486 Return 0 on success, -1 on _wstat() / stat() error or (if PyErr_Occurred())
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
487 unicode error. */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
488
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
489 int
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
490 _Py_stat(PyObject *path, struct stat *statbuf)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
491 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
492 #ifdef MS_WINDOWS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
493 int err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
494 struct _stat wstatbuf;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
495
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
496 err = _wstat(PyUnicode_AS_UNICODE(path), &wstatbuf);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
497 if (!err)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
498 statbuf->st_mode = wstatbuf.st_mode;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
499 return err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
500 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
501 int ret;
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
502 PyObject *bytes = PyUnicode_EncodeFSDefault(path);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
503 if (bytes == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
504 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
505 ret = stat(PyBytes_AS_STRING(bytes), statbuf);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
506 Py_DECREF(bytes);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
507 return ret;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
508 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
509 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
510
81257
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
511 #endif
c256764e2b3f Issue #16455: On FreeBSD and Solaris, if the locale is C, the
Victor Stinner <victor.stinner@gmail.com>
parents: 80704
diff changeset
512
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
513 /* 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
514 encoding and use fopen() otherwise. */
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
515
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
516 FILE *
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
517 _Py_wfopen(const wchar_t *path, const wchar_t *mode)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
518 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
519 #ifndef MS_WINDOWS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
520 FILE *f;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
521 char *cpath;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
522 char cmode[10];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
523 size_t r;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
524 r = wcstombs(cmode, mode, 10);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
525 if (r == (size_t)-1 || r >= 10) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
526 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
527 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
528 }
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
529 cpath = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
530 if (cpath == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
531 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
532 f = fopen(cpath, cmode);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
533 PyMem_Free(cpath);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
534 return f;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
535 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
536 return _wfopen(path, mode);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
537 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
538 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
539
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
540 /* 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
541 call fopen() otherwise.
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
542
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
543 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
544 (if PyErr_Occurred()) on unicode error */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
545
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
546 FILE*
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
547 _Py_fopen(PyObject *path, const char *mode)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
548 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
549 #ifdef MS_WINDOWS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
550 wchar_t wmode[10];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
551 int usize;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
552
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
553 usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, sizeof(wmode));
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
554 if (usize == 0)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
555 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
556
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
557 return _wfopen(PyUnicode_AS_UNICODE(path), wmode);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
558 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
559 FILE *f;
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
560 PyObject *bytes = PyUnicode_EncodeFSDefault(path);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
561 if (bytes == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
562 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
563 f = fopen(PyBytes_AS_STRING(bytes), mode);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
564 Py_DECREF(bytes);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
565 return f;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
566 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
567 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
568
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
569 #ifdef HAVE_READLINK
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
570
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
571 /* Read value of symbolic link. Encode the path to the locale encoding, decode
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
572 the result from the locale encoding. */
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
573
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
574 int
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
575 _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
576 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
577 char *cpath;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
578 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
579 wchar_t *wbuf;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
580 int res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
581 size_t r1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
582
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
583 cpath = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
584 if (cpath == NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
585 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
586 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
587 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
588 res = (int)readlink(cpath, cbuf, PATH_MAX);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
589 PyMem_Free(cpath);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
590 if (res == -1)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
591 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
592 if (res == PATH_MAX) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
593 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
594 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
595 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
596 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
597 wbuf = _Py_char2wchar(cbuf, &r1);
65410
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
598 if (wbuf == NULL) {
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
599 errno = EINVAL;
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
600 return -1;
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
601 }
65409
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
602 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
603 PyMem_Free(wbuf);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
604 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
605 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
606 }
65409
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
607 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
608 PyMem_Free(wbuf);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
609 return (int)r1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
610 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
611 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
612
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
613 #ifdef HAVE_REALPATH
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
614
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
615 /* Return the canonicalized absolute pathname. Encode path to the locale
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
616 encoding, decode the result from the locale encoding. */
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
617
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
618 wchar_t*
65166
8fd5d06462e6 _Py_wrealpath() requires the size of the output buffer
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65165
diff changeset
619 _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
620 wchar_t *resolved_path, size_t resolved_path_size)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
621 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
622 char *cpath;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
623 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
624 wchar_t *wresolved_path;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
625 char *res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
626 size_t r;
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
627 cpath = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
628 if (cpath == NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
629 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
630 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
631 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
632 res = realpath(cpath, cresolved_path);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
633 PyMem_Free(cpath);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
634 if (res == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
635 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
636
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
637 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
638 if (wresolved_path == NULL) {
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
639 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
640 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
641 }
65411
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
642 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
643 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
644 errno = EINVAL;
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
645 return NULL;
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
646 }
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
647 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
648 PyMem_Free(wresolved_path);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
649 return resolved_path;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
650 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
651 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
652
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
653 /* Get the current directory. size is the buffer size in wide characters
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
654 including the null character. Decode the path from the locale encoding. */
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
655
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
656 wchar_t*
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
657 _Py_wgetcwd(wchar_t *buf, size_t size)
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 #ifdef MS_WINDOWS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
660 return _wgetcwd(buf, size);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
661 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
662 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
663 wchar_t *wname;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
664 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
665
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
666 if (getcwd(fname, PATH_MAX) == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
667 return NULL;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
668 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
669 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
670 return NULL;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
671 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
672 PyMem_Free(wname);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
673 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
674 }
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
675 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
676 PyMem_Free(wname);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
677 return buf;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
678 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
679 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
680