Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d61deca

Browse files
Move _Py_char2wchar from python.c to main.c.
This fixes issue #8441: python.c is not included in the framework while main.c is and without this patch you get a link error when building Python.framework on OSX.
1 parent ceb513a commit d61deca

3 files changed

Lines changed: 105 additions & 103 deletions

File tree

Include/Python.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ extern "C" {
126126
/* _Py_Mangle is defined in compile.c */
127127
PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name);
128128

129-
/* _Py_char2wchar lives in python.c */
129+
/* _Py_char2wchar lives in main.c */
130130
PyAPI_FUNC(wchar_t *) _Py_char2wchar(char *);
131131
#ifdef __cplusplus
132132
}

Modules/main.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,110 @@ Py_GetArgcArgv(int *argc, wchar_t ***argv)
706706
*argv = orig_argv;
707707
}
708708

709+
710+
wchar_t*
711+
_Py_char2wchar(char* arg)
712+
{
713+
wchar_t *res;
714+
#ifdef HAVE_BROKEN_MBSTOWCS
715+
/* Some platforms have a broken implementation of
716+
* mbstowcs which does not count the characters that
717+
* would result from conversion. Use an upper bound.
718+
*/
719+
size_t argsize = strlen(arg);
720+
#else
721+
size_t argsize = mbstowcs(NULL, arg, 0);
722+
#endif
723+
size_t count;
724+
unsigned char *in;
725+
wchar_t *out;
726+
#ifdef HAVE_MBRTOWC
727+
mbstate_t mbs;
728+
#endif
729+
if (argsize != (size_t)-1) {
730+
res = (wchar_t *)PyMem_Malloc((argsize+1)*sizeof(wchar_t));
731+
if (!res)
732+
goto oom;
733+
count = mbstowcs(res, arg, argsize+1);
734+
if (count != (size_t)-1) {
735+
wchar_t *tmp;
736+
/* Only use the result if it contains no
737+
surrogate characters. */
738+
for (tmp = res; *tmp != 0 &&
739+
(*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
740+
;
741+
if (*tmp == 0)
742+
return res;
743+
}
744+
PyMem_Free(res);
745+
}
746+
/* Conversion failed. Fall back to escaping with surrogateescape. */
747+
#ifdef HAVE_MBRTOWC
748+
/* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
749+
750+
/* Overallocate; as multi-byte characters are in the argument, the
751+
actual output could use less memory. */
752+
argsize = strlen(arg) + 1;
753+
res = (wchar_t*)PyMem_Malloc(argsize*sizeof(wchar_t));
754+
if (!res) goto oom;
755+
in = (unsigned char*)arg;
756+
out = res;
757+
memset(&mbs, 0, sizeof mbs);
758+
while (argsize) {
759+
size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
760+
if (converted == 0)
761+
/* Reached end of string; null char stored. */
762+
break;
763+
if (converted == (size_t)-2) {
764+
/* Incomplete character. This should never happen,
765+
since we provide everything that we have -
766+
unless there is a bug in the C library, or I
767+
misunderstood how mbrtowc works. */
768+
fprintf(stderr, "unexpected mbrtowc result -2\n");
769+
return NULL;
770+
}
771+
if (converted == (size_t)-1) {
772+
/* Conversion error. Escape as UTF-8b, and start over
773+
in the initial shift state. */
774+
*out++ = 0xdc00 + *in++;
775+
argsize--;
776+
memset(&mbs, 0, sizeof mbs);
777+
continue;
778+
}
779+
if (*out >= 0xd800 && *out <= 0xdfff) {
780+
/* Surrogate character. Escape the original
781+
byte sequence with surrogateescape. */
782+
argsize -= converted;
783+
while (converted--)
784+
*out++ = 0xdc00 + *in++;
785+
continue;
786+
}
787+
/* successfully converted some bytes */
788+
in += converted;
789+
argsize -= converted;
790+
out++;
791+
}
792+
#else
793+
/* Cannot use C locale for escaping; manually escape as if charset
794+
is ASCII (i.e. escape all bytes > 128. This will still roundtrip
795+
correctly in the locale's charset, which must be an ASCII superset. */
796+
res = PyMem_Malloc((strlen(arg)+1)*sizeof(wchar_t));
797+
if (!res) goto oom;
798+
in = (unsigned char*)arg;
799+
out = res;
800+
while(*in)
801+
if(*in < 128)
802+
*out++ = *in++;
803+
else
804+
*out++ = 0xdc00 + *in++;
805+
*out = 0;
806+
#endif
807+
return res;
808+
oom:
809+
fprintf(stderr, "out of memory\n");
810+
return NULL;
811+
}
812+
709813
#ifdef __cplusplus
710814
}
711815
#endif

Modules/python.c

Lines changed: 0 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -14,108 +14,6 @@ wmain(int argc, wchar_t **argv)
1414
return Py_Main(argc, argv);
1515
}
1616
#else
17-
wchar_t*
18-
_Py_char2wchar(char* arg)
19-
{
20-
wchar_t *res;
21-
#ifdef HAVE_BROKEN_MBSTOWCS
22-
/* Some platforms have a broken implementation of
23-
* mbstowcs which does not count the characters that
24-
* would result from conversion. Use an upper bound.
25-
*/
26-
size_t argsize = strlen(arg);
27-
#else
28-
size_t argsize = mbstowcs(NULL, arg, 0);
29-
#endif
30-
size_t count;
31-
unsigned char *in;
32-
wchar_t *out;
33-
#ifdef HAVE_MBRTOWC
34-
mbstate_t mbs;
35-
#endif
36-
if (argsize != (size_t)-1) {
37-
res = (wchar_t *)PyMem_Malloc((argsize+1)*sizeof(wchar_t));
38-
if (!res)
39-
goto oom;
40-
count = mbstowcs(res, arg, argsize+1);
41-
if (count != (size_t)-1) {
42-
wchar_t *tmp;
43-
/* Only use the result if it contains no
44-
surrogate characters. */
45-
for (tmp = res; *tmp != 0 &&
46-
(*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
47-
;
48-
if (*tmp == 0)
49-
return res;
50-
}
51-
PyMem_Free(res);
52-
}
53-
/* Conversion failed. Fall back to escaping with surrogateescape. */
54-
#ifdef HAVE_MBRTOWC
55-
/* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
56-
57-
/* Overallocate; as multi-byte characters are in the argument, the
58-
actual output could use less memory. */
59-
argsize = strlen(arg) + 1;
60-
res = (wchar_t*)PyMem_Malloc(argsize*sizeof(wchar_t));
61-
if (!res) goto oom;
62-
in = (unsigned char*)arg;
63-
out = res;
64-
memset(&mbs, 0, sizeof mbs);
65-
while (argsize) {
66-
size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
67-
if (converted == 0)
68-
/* Reached end of string; null char stored. */
69-
break;
70-
if (converted == (size_t)-2) {
71-
/* Incomplete character. This should never happen,
72-
since we provide everything that we have -
73-
unless there is a bug in the C library, or I
74-
misunderstood how mbrtowc works. */
75-
fprintf(stderr, "unexpected mbrtowc result -2\n");
76-
return NULL;
77-
}
78-
if (converted == (size_t)-1) {
79-
/* Conversion error. Escape as UTF-8b, and start over
80-
in the initial shift state. */
81-
*out++ = 0xdc00 + *in++;
82-
argsize--;
83-
memset(&mbs, 0, sizeof mbs);
84-
continue;
85-
}
86-
if (*out >= 0xd800 && *out <= 0xdfff) {
87-
/* Surrogate character. Escape the original
88-
byte sequence with surrogateescape. */
89-
argsize -= converted;
90-
while (converted--)
91-
*out++ = 0xdc00 + *in++;
92-
continue;
93-
}
94-
/* successfully converted some bytes */
95-
in += converted;
96-
argsize -= converted;
97-
out++;
98-
}
99-
#else
100-
/* Cannot use C locale for escaping; manually escape as if charset
101-
is ASCII (i.e. escape all bytes > 128. This will still roundtrip
102-
correctly in the locale's charset, which must be an ASCII superset. */
103-
res = PyMem_Malloc((strlen(arg)+1)*sizeof(wchar_t));
104-
if (!res) goto oom;
105-
in = (unsigned char*)arg;
106-
out = res;
107-
while(*in)
108-
if(*in < 128)
109-
*out++ = *in++;
110-
else
111-
*out++ = 0xdc00 + *in++;
112-
*out = 0;
113-
#endif
114-
return res;
115-
oom:
116-
fprintf(stderr, "out of memory\n");
117-
return NULL;
118-
}
11917

12018
int
12119
main(int argc, char **argv)

0 commit comments

Comments
 (0)