Skip to content

Commit 4f24563

Browse files
srl295joaocgreis
authored andcommitted
build: work around VS2015 issue in ICU <56
This change is a backport of 4c06515. Original commit message: The particular ufile.c is from http://bugs.icu-project.org/trac/changeset/37704 and should be OK for ICU 54 and 55. Also, adds general mechanism for floating patches on top of ICU. Fixes: #2279 PR-URL: #2283 Reviewed-By: João Reis <[email protected]> Fixes: #25792 PR-URL: nodejs/node-v0.x-archive#25804 Reviewed-By: João Reis <[email protected]>
1 parent f693565 commit 4f24563

File tree

3 files changed

+730
-3
lines changed

3 files changed

+730
-3
lines changed

configure

+10-3
Original file line numberDiff line numberDiff line change
@@ -733,15 +733,22 @@ def write(filename, data):
733733

734734
do_not_edit = '# Do not edit. Generated by the configure script.\n'
735735

736-
def glob_to_var(dir_base, dir_sub):
736+
def glob_to_var(dir_base, dir_sub, patch_dir):
737737
list = []
738738
dir_all = os.path.join(dir_base, dir_sub)
739739
files = os.walk(dir_all)
740740
for ent in files:
741741
(path, dirs, files) = ent
742742
for file in files:
743743
if file.endswith('.cpp') or file.endswith('.c') or file.endswith('.h'):
744-
list.append('%s/%s' % (dir_sub, file))
744+
# srcfile uses "slash" as dir separator as its output is consumed by gyp
745+
srcfile = '%s/%s' % (dir_sub, file)
746+
if patch_dir:
747+
patchfile = '%s/%s/%s' % (dir_base, patch_dir, file)
748+
if os.path.isfile(patchfile):
749+
srcfile = '%s/%s' % (patch_dir, file)
750+
print 'Using version-specific floating patch %s' % patchfile
751+
list.append(srcfile)
745752
break
746753
return list
747754

@@ -973,7 +980,7 @@ def configure_intl(o):
973980
for i in icu_src:
974981
var = 'icu_src_%s' % i
975982
path = '../../deps/icu/source/%s' % icu_src[i]
976-
icu_config['variables'][var] = glob_to_var('tools/icu', path)
983+
icu_config['variables'][var] = glob_to_var('tools/icu', path, 'patches/%s/source/%s' % (icu_ver_major, icu_src[i]) )
977984
# write updated icu_config.gypi with a bunch of paths
978985
write(icu_config_name, do_not_edit +
979986
pprint.pformat(icu_config, indent=2) + '\n')
+360
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
/*
2+
******************************************************************************
3+
*
4+
* Copyright (C) 1998-2015, International Business Machines
5+
* Corporation and others. All Rights Reserved.
6+
*
7+
******************************************************************************
8+
*
9+
* File ufile.c
10+
*
11+
* Modification History:
12+
*
13+
* Date Name Description
14+
* 11/19/98 stephen Creation.
15+
* 03/12/99 stephen Modified for new C API.
16+
* 06/16/99 stephen Changed T_LocaleBundle to u_locbund
17+
* 07/19/99 stephen Fixed to use ucnv's default codepage.
18+
******************************************************************************
19+
*/
20+
21+
/*
22+
* fileno is not declared when building with GCC in strict mode.
23+
*/
24+
#if defined(__GNUC__) && defined(__STRICT_ANSI__)
25+
#undef __STRICT_ANSI__
26+
#endif
27+
28+
#include "locmap.h"
29+
#include "unicode/ustdio.h"
30+
31+
#if !UCONFIG_NO_CONVERSION
32+
33+
#include "ufile.h"
34+
#include "unicode/uloc.h"
35+
#include "unicode/ures.h"
36+
#include "unicode/ucnv.h"
37+
#include "unicode/ustring.h"
38+
#include "cstring.h"
39+
#include "cmemory.h"
40+
41+
#if U_PLATFORM_USES_ONLY_WIN32_API && !defined(fileno)
42+
/* Windows likes to rename Unix-like functions */
43+
#define fileno _fileno
44+
#endif
45+
46+
static UFILE*
47+
finit_owner(FILE *f,
48+
const char *locale,
49+
const char *codepage,
50+
UBool takeOwnership
51+
)
52+
{
53+
UErrorCode status = U_ZERO_ERROR;
54+
UFILE *result;
55+
if(f == NULL) {
56+
return 0;
57+
}
58+
result = (UFILE*) uprv_malloc(sizeof(UFILE));
59+
if(result == NULL) {
60+
return 0;
61+
}
62+
63+
uprv_memset(result, 0, sizeof(UFILE));
64+
result->fFileno = fileno(f);
65+
66+
#if U_PLATFORM_USES_ONLY_WIN32_API && _MSC_VER < 1900
67+
/*
68+
* Below is a very old workaround (ICU ticket:231).
69+
*
70+
* Previously, 'FILE*' from inside and outside ICU's DLL
71+
* were different, because they pointed into local copies
72+
* of the io block. At least by VS 2015 the implementation
73+
* is something like:
74+
* stdio = _acrt_iob_func(0)
75+
* .. which is a function call, so should return the same pointer
76+
* regardless of call site.
77+
* As of _MSC_VER 1900 this patch is retired, at 16 years old.
78+
*/
79+
if (0 <= result->fFileno && result->fFileno <= 2) {
80+
/* stdin, stdout and stderr need to be special cased for Windows 98 */
81+
#if _MSC_VER >= 1400
82+
result->fFile = &__iob_func()[_fileno(f)];
83+
#else
84+
result->fFile = &_iob[_fileno(f)];
85+
#endif
86+
}
87+
else
88+
#endif
89+
{
90+
result->fFile = f;
91+
}
92+
93+
result->str.fBuffer = result->fUCBuffer;
94+
result->str.fPos = result->fUCBuffer;
95+
result->str.fLimit = result->fUCBuffer;
96+
97+
#if !UCONFIG_NO_FORMATTING
98+
/* if locale is 0, use the default */
99+
if(u_locbund_init(&result->str.fBundle, locale) == 0) {
100+
/* DO NOT FCLOSE HERE! */
101+
uprv_free(result);
102+
return 0;
103+
}
104+
#endif
105+
106+
/* If the codepage is not "" use the ucnv_open default behavior */
107+
if(codepage == NULL || *codepage != '\0') {
108+
result->fConverter = ucnv_open(codepage, &status);
109+
}
110+
/* else result->fConverter is already memset'd to NULL. */
111+
112+
if(U_SUCCESS(status)) {
113+
result->fOwnFile = takeOwnership;
114+
}
115+
else {
116+
#if !UCONFIG_NO_FORMATTING
117+
u_locbund_close(&result->str.fBundle);
118+
#endif
119+
/* DO NOT fclose here!!!!!! */
120+
uprv_free(result);
121+
result = NULL;
122+
}
123+
124+
return result;
125+
}
126+
127+
U_CAPI UFILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
128+
u_finit(FILE *f,
129+
const char *locale,
130+
const char *codepage)
131+
{
132+
return finit_owner(f, locale, codepage, FALSE);
133+
}
134+
135+
U_CAPI UFILE* U_EXPORT2
136+
u_fadopt(FILE *f,
137+
const char *locale,
138+
const char *codepage)
139+
{
140+
return finit_owner(f, locale, codepage, TRUE);
141+
}
142+
143+
U_CAPI UFILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
144+
u_fopen(const char *filename,
145+
const char *perm,
146+
const char *locale,
147+
const char *codepage)
148+
{
149+
UFILE *result;
150+
FILE *systemFile = fopen(filename, perm);
151+
if(systemFile == 0) {
152+
return 0;
153+
}
154+
155+
result = finit_owner(systemFile, locale, codepage, TRUE);
156+
157+
if (!result) {
158+
/* Something bad happened.
159+
Maybe the converter couldn't be opened. */
160+
fclose(systemFile);
161+
}
162+
163+
return result; /* not a file leak */
164+
}
165+
166+
U_CAPI UFILE* U_EXPORT2
167+
u_fopen_u(const UChar *filename,
168+
const char *perm,
169+
const char *locale,
170+
const char *codepage)
171+
{
172+
UFILE *result;
173+
char buffer[256];
174+
175+
u_austrcpy(buffer, filename);
176+
177+
result = u_fopen(buffer, perm, locale, codepage);
178+
#if U_PLATFORM_USES_ONLY_WIN32_API
179+
/* Try Windows API _wfopen if the above fails. */
180+
if (!result) {
181+
FILE *systemFile = _wfopen(filename, (UChar*)perm);
182+
if (systemFile) {
183+
result = finit_owner(systemFile, locale, codepage, TRUE);
184+
}
185+
if (!result) {
186+
/* Something bad happened.
187+
Maybe the converter couldn't be opened. */
188+
fclose(systemFile);
189+
}
190+
}
191+
#endif
192+
return result; /* not a file leak */
193+
}
194+
195+
U_CAPI UFILE* U_EXPORT2
196+
u_fstropen(UChar *stringBuf,
197+
int32_t capacity,
198+
const char *locale)
199+
{
200+
UFILE *result;
201+
202+
if (capacity < 0) {
203+
return NULL;
204+
}
205+
206+
result = (UFILE*) uprv_malloc(sizeof(UFILE));
207+
/* Null pointer test */
208+
if (result == NULL) {
209+
return NULL; /* Just get out. */
210+
}
211+
uprv_memset(result, 0, sizeof(UFILE));
212+
result->str.fBuffer = stringBuf;
213+
result->str.fPos = stringBuf;
214+
result->str.fLimit = stringBuf+capacity;
215+
216+
#if !UCONFIG_NO_FORMATTING
217+
/* if locale is 0, use the default */
218+
if(u_locbund_init(&result->str.fBundle, locale) == 0) {
219+
/* DO NOT FCLOSE HERE! */
220+
uprv_free(result);
221+
return 0;
222+
}
223+
#endif
224+
225+
return result;
226+
}
227+
228+
U_CAPI UBool U_EXPORT2
229+
u_feof(UFILE *f)
230+
{
231+
UBool endOfBuffer;
232+
if (f == NULL) {
233+
return TRUE;
234+
}
235+
endOfBuffer = (UBool)(f->str.fPos >= f->str.fLimit);
236+
if (f->fFile != NULL) {
237+
return endOfBuffer && feof(f->fFile);
238+
}
239+
return endOfBuffer;
240+
}
241+
242+
U_CAPI void U_EXPORT2
243+
u_fflush(UFILE *file)
244+
{
245+
ufile_flush_translit(file);
246+
ufile_flush_io(file);
247+
if (file->fFile) {
248+
fflush(file->fFile);
249+
}
250+
else if (file->str.fPos < file->str.fLimit) {
251+
*(file->str.fPos++) = 0;
252+
}
253+
/* TODO: flush input */
254+
}
255+
256+
U_CAPI void
257+
u_frewind(UFILE *file)
258+
{
259+
u_fflush(file);
260+
ucnv_reset(file->fConverter);
261+
if (file->fFile) {
262+
rewind(file->fFile);
263+
file->str.fLimit = file->fUCBuffer;
264+
file->str.fPos = file->fUCBuffer;
265+
}
266+
else {
267+
file->str.fPos = file->str.fBuffer;
268+
}
269+
}
270+
271+
U_CAPI void U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
272+
u_fclose(UFILE *file)
273+
{
274+
if (file) {
275+
u_fflush(file);
276+
ufile_close_translit(file);
277+
278+
if(file->fOwnFile)
279+
fclose(file->fFile);
280+
281+
#if !UCONFIG_NO_FORMATTING
282+
u_locbund_close(&file->str.fBundle);
283+
#endif
284+
285+
ucnv_close(file->fConverter);
286+
uprv_free(file);
287+
}
288+
}
289+
290+
U_CAPI FILE* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
291+
u_fgetfile( UFILE *f)
292+
{
293+
return f->fFile;
294+
}
295+
296+
#if !UCONFIG_NO_FORMATTING
297+
298+
U_CAPI const char* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
299+
u_fgetlocale( UFILE *file)
300+
{
301+
return file->str.fBundle.fLocale;
302+
}
303+
304+
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
305+
u_fsetlocale(UFILE *file,
306+
const char *locale)
307+
{
308+
u_locbund_close(&file->str.fBundle);
309+
310+
return u_locbund_init(&file->str.fBundle, locale) == 0 ? -1 : 0;
311+
}
312+
313+
#endif
314+
315+
U_CAPI const char* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
316+
u_fgetcodepage(UFILE *file)
317+
{
318+
UErrorCode status = U_ZERO_ERROR;
319+
const char *codepage = NULL;
320+
321+
if (file->fConverter) {
322+
codepage = ucnv_getName(file->fConverter, &status);
323+
if(U_FAILURE(status))
324+
return 0;
325+
}
326+
return codepage;
327+
}
328+
329+
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
330+
u_fsetcodepage( const char *codepage,
331+
UFILE *file)
332+
{
333+
UErrorCode status = U_ZERO_ERROR;
334+
int32_t retVal = -1;
335+
336+
/* We use the normal default codepage for this system, and not the one for the locale. */
337+
if ((file->str.fPos == file->str.fBuffer) && (file->str.fLimit == file->str.fBuffer)) {
338+
ucnv_close(file->fConverter);
339+
file->fConverter = ucnv_open(codepage, &status);
340+
if(U_SUCCESS(status)) {
341+
retVal = 0;
342+
}
343+
}
344+
return retVal;
345+
}
346+
347+
348+
U_CAPI UConverter * U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
349+
u_fgetConverter(UFILE *file)
350+
{
351+
return file->fConverter;
352+
}
353+
#if !UCONFIG_NO_FORMATTING
354+
U_CAPI const UNumberFormat* U_EXPORT2 u_fgetNumberFormat(UFILE *file)
355+
{
356+
return u_locbund_getNumberFormat(&file->str.fBundle, UNUM_DECIMAL);
357+
}
358+
#endif
359+
360+
#endif

0 commit comments

Comments
 (0)