Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.

Commit 83e9c91

Browse files
committed
core.stdc.stdio: add experimental support for MSVCRT 14 (VS 2015).
1 parent 999fae2 commit 83e9c91

File tree

2 files changed

+215
-31
lines changed

2 files changed

+215
-31
lines changed

src/core/stdc/stdio.d

+197-25
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ private
3030
}
3131
}
3232

33+
// uncomment for MSVCRT >= 14 (VS 2015)
34+
//version(LDC) { version(Win64) version = LDC_MSVCRT14; }
35+
3336
extern (C):
3437
@system:
3538
nothrow:
@@ -60,14 +63,23 @@ else version( Win64 )
6063
EOF = -1,
6164
FOPEN_MAX = 20,
6265
FILENAME_MAX = 260,
63-
TMP_MAX = 32767,
6466
_SYS_OPEN = 20, // non-standard
6567
}
6668

67-
enum int _NFILE = 512; // non-standard
69+
enum int _NFILE = 512; // non-standard
70+
71+
version( LDC_MSVCRT14 ) // requires MSVCRT >= 14 (VS 2015)
72+
{
73+
enum int TMP_MAX = int.max;
74+
enum int L_tmpnam = 260;
75+
}
76+
else
77+
{
78+
enum int TMP_MAX = short.max;
6879
enum string _P_tmpdir = "\\"; // non-standard
6980
enum wstring _wP_tmpdir = "\\"; // non-standard
7081
enum int L_tmpnam = _P_tmpdir.length + 12;
82+
}
7183
}
7284
else version( linux )
7385
{
@@ -198,8 +210,17 @@ version( Win32 )
198210
}
199211
else version( Win64 )
200212
{
201-
alias int fpos_t; //check this
213+
alias long fpos_t;
202214

215+
version( LDC_MSVCRT14 ) // requires MSVCRT >= 14 (VS 2015)
216+
{
217+
struct _iobuf
218+
{
219+
void* _Placeholder;
220+
}
221+
}
222+
else
223+
{
203224
struct _iobuf
204225
{
205226
char* _ptr;
@@ -211,6 +232,7 @@ else version( Win64 )
211232
int _bufsiz;
212233
char* _tmpfname;
213234
}
235+
}
214236

215237
alias shared(_iobuf) FILE;
216238
}
@@ -436,26 +458,37 @@ else version( Win64 )
436458
_IOFBF = 0,
437459
_IOLBF = 0x40,
438460
_IONBF = 4,
439-
_IOREAD = 1, // non-standard
440-
_IOWRT = 2, // non-standard
441-
_IOMYBUF = 8, // non-standard
442-
_IOEOF = 0x10, // non-standard
443-
_IOERR = 0x20, // non-standard
444-
_IOSTRG = 0x40, // non-standard
445-
_IORW = 0x80, // non-standard
446-
_IOAPP = 0x200, // non-standard
447-
_IOAPPEND = 0x200, // non-standard
448461
}
449462

450463
extern shared void function() _fcloseallp;
451464

452-
private extern shared FILE[_NFILE] _iob;
453-
454-
shared(FILE)* __iob_func();
465+
version( LDC_MSVCRT14 ) // requires MSVCRT >= 14 (VS 2015)
466+
{
467+
shared(FILE)* __acrt_iob_func(uint);
468+
shared FILE* stdin; // = __acrt_iob_func(0);
469+
shared FILE* stdout; // = __acrt_iob_func(1);
470+
shared FILE* stderr; // = __acrt_iob_func(2);
471+
}
472+
else
473+
{
474+
enum
475+
{
476+
_IOREAD = 1, // non-standard
477+
_IOWRT = 2, // non-standard
478+
_IOMYBUF = 8, // non-standard
479+
_IOEOF = 0x10, // non-standard
480+
_IOERR = 0x20, // non-standard
481+
_IOSTRG = 0x40, // non-standard
482+
_IORW = 0x80, // non-standard
483+
_IOAPP = 0x200, // non-standard
484+
_IOAPPEND = 0x200, // non-standard
485+
}
455486

456-
shared FILE* stdin; // = &__iob_func()[0];
457-
shared FILE* stdout; // = &__iob_func()[1];
458-
shared FILE* stderr; // = &__iob_func()[2];
487+
shared(FILE)* __iob_func();
488+
shared FILE* stdin; // = &__iob_func()[0];
489+
shared FILE* stdout; // = &__iob_func()[1];
490+
shared FILE* stderr; // = &__iob_func()[2];
491+
}
459492
}
460493
else version( linux )
461494
{
@@ -605,6 +638,110 @@ version (MinGW)
605638
int __mingw_scanf(in char* format, ...);
606639
alias __mingw_scanf scanf;
607640
}
641+
else version (LDC_MSVCRT14) // requires MSVCRT >= 14 (VS 2015)
642+
{
643+
// MS define the *printf and *scanf function families inline, forwarding to 4
644+
// basic functions.
645+
// We implement corresponding wrappers around these basic functions and use
646+
// special mangled names (__ldc_ prefix) to avoid duplicate symbols when
647+
// linking against other C/C++ objects with their own versions.
648+
649+
private
650+
{
651+
enum _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR = 2;
652+
653+
int __stdio_common_vfprintf(ulong _Options, FILE* _Stream,
654+
in char* _Format, void* _Locale, va_list _ArgList);
655+
int __stdio_common_vsprintf(ulong _Options, char* _Buffer, size_t _BufferCount,
656+
in char* _Format, void* _Locale, va_list _ArgList);
657+
658+
int __stdio_common_vfscanf(ulong _Options, FILE* _Stream,
659+
in char* _Format, void* _Locale, va_list _Arglist);
660+
int __stdio_common_vsscanf(ulong _Options, in char* _Buffer, size_t _BufferCount,
661+
in char* _Format, void* _Locale, va_list _ArgList);
662+
}
663+
664+
// *printf:
665+
pragma(mangle, "__ldc_vfprintf")
666+
int vfprintf(FILE* stream, in char* format, va_list args)
667+
{
668+
return __stdio_common_vfprintf(0, stream, format, null, args);
669+
}
670+
pragma(mangle, "__ldc_fprintf")
671+
int fprintf(FILE* stream, in char* format, ...)
672+
{
673+
va_list args;
674+
va_start(args, format);
675+
return vfprintf(stream, format, args);
676+
}
677+
678+
pragma(mangle, "__ldc_vprintf")
679+
int vprintf(in char* format, va_list args)
680+
{
681+
return vfprintf(stdout, format, args);
682+
}
683+
pragma(mangle, "__ldc_printf")
684+
int printf(in char* format, ...)
685+
{
686+
va_list args;
687+
va_start(args, format);
688+
return vprintf(format, args);
689+
}
690+
691+
pragma(mangle, "__ldc_vsprintf")
692+
int vsprintf(char* s, in char* format, va_list args)
693+
{
694+
return vsnprintf(s, size_t.max, format, args);
695+
}
696+
pragma(mangle, "__ldc_sprintf")
697+
int sprintf(char* s, in char* format, ...)
698+
{
699+
va_list args;
700+
va_start(args, format);
701+
return vsprintf(s, format, args);
702+
}
703+
704+
// *scanf:
705+
706+
pragma(mangle, "__ldc_vfscanf")
707+
int vfscanf(FILE* stream, in char* format, va_list args)
708+
{
709+
return __stdio_common_vfscanf(0, stream, format, null, args);
710+
}
711+
pragma(mangle, "__ldc_fscanf")
712+
int fscanf(FILE* stream, in char* format, ...)
713+
{
714+
va_list args;
715+
va_start(args, format);
716+
return vfscanf(stream, format, args);
717+
}
718+
719+
pragma(mangle, "__ldc_vscanf")
720+
int vscanf(in char* format, va_list args)
721+
{
722+
return vfscanf(stdin, format, args);
723+
}
724+
pragma(mangle, "__ldc_scanf")
725+
int scanf(in char* format, ...)
726+
{
727+
va_list args;
728+
va_start(args, format);
729+
return vscanf(format, args);
730+
}
731+
732+
pragma(mangle, "__ldc_vsscanf")
733+
int vsscanf(in char* s, in char* format, va_list args)
734+
{
735+
return __stdio_common_vsscanf(0, s, size_t.max, format, null, args);
736+
}
737+
pragma(mangle, "__ldc_sscanf")
738+
int sscanf(in char* s, in char* format, ...)
739+
{
740+
va_list args;
741+
va_start(args, format);
742+
return vsscanf(s, format, args);
743+
}
744+
}
608745
else
609746
{
610747
int fprintf(FILE* stream, in char* format, ...);
@@ -699,15 +836,49 @@ else version( Win32 )
699836
}
700837
else version( Win64 )
701838
{
702-
// No unsafe pointer manipulation.
703-
extern (D) @trusted
839+
version( LDC_MSVCRT14 ) // requires MSVCRT >= 14 (VS 2015)
704840
{
705-
void rewind(FILE* stream) { fseek(stream,0L,SEEK_SET); stream._flag = stream._flag & ~_IOERR; }
706-
pure void clearerr(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); }
707-
pure int feof(FILE* stream) { return stream._flag&_IOEOF; }
708-
pure int ferror(FILE* stream) { return stream._flag&_IOERR; }
709-
pure int fileno(FILE* stream) { return stream._file; }
841+
// No unsafe pointer manipulation.
842+
@trusted
843+
{
844+
void rewind(FILE* stream);
845+
pure void clearerr(FILE* stream);
846+
pure int feof(FILE* stream);
847+
pure int ferror(FILE* stream);
848+
pure int fileno(FILE* stream);
849+
}
850+
851+
///
852+
pragma(mangle, "__ldc_vsnprintf")
853+
int vsnprintf(char* s, size_t n, in char* format, va_list args)
854+
{
855+
int result = __stdio_common_vsprintf(
856+
_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR,
857+
s, n, format, null, args);
858+
return result < 0 ? -1 : result;
859+
}
860+
861+
///
862+
pragma(mangle, "__ldc_snprintf")
863+
int snprintf(char* s, size_t n, in char* format, ...)
864+
{
865+
va_list args;
866+
va_start(args, format);
867+
return vsnprintf(s, n, format, args);
868+
}
710869
}
870+
else
871+
{
872+
// No unsafe pointer manipulation.
873+
extern (D) @trusted
874+
{
875+
void rewind(FILE* stream) { fseek(stream, 0L, SEEK_SET); stream._flag = stream._flag & ~_IOERR; }
876+
pure void clearerr(FILE* stream) { stream._flag = stream._flag & ~(_IOERR | _IOEOF); }
877+
pure int feof(FILE* stream) { return stream._flag & _IOEOF; }
878+
pure int ferror(FILE* stream) { return stream._flag & _IOERR; }
879+
pure int fileno(FILE* stream) { return stream._file; }
880+
}
881+
711882
int _snprintf(char* s, size_t n, in char* fmt, ...);
712883
alias _snprintf snprintf;
713884

@@ -745,6 +916,7 @@ else version( Win64 )
745916
else
746917
return _filbuf(fp);
747918
}
919+
}
748920

749921
int _lock_file(FILE *fp);
750922
int _unlock_file(FILE *fp);

src/rt/dmain2.d

+18-6
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ version (FreeBSD)
3737
import core.stdc.fenv;
3838
}
3939

40+
// uncomment for MSVCRT >= 14 (VS 2015)
41+
//version(LDC) { version(Win64) version = LDC_MSVCRT14; }
42+
4043
extern (C) void _STI_monitor_staticctor();
4144
extern (C) void _STD_monitor_staticdtor();
4245
extern (C) void _STI_critical_init();
@@ -266,13 +269,22 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)
266269

267270
version (Win64)
268271
{
269-
auto fp = __iob_func();
270-
stdin = &fp[0];
271-
stdout = &fp[1];
272-
stderr = &fp[2];
272+
version (LDC_MSVCRT14) // requires MSVCRT >= 14 (VS 2015)
273+
{
274+
stdin = __acrt_iob_func(0);
275+
stdout = __acrt_iob_func(1);
276+
stderr = __acrt_iob_func(2);
277+
}
278+
else
279+
{
280+
auto fp = __iob_func();
281+
stdin = &fp[0];
282+
stdout = &fp[1];
283+
stderr = &fp[2];
273284

274-
// ensure that sprintf generates only 2 digit exponent when writing floating point values
275-
_set_output_format(_TWO_DIGIT_EXPONENT);
285+
// ensure that *printf generates only 2 digit exponent when writing floating point values
286+
_set_output_format(_TWO_DIGIT_EXPONENT);
287+
}
276288

277289
// enable full precision for reals
278290
asm

0 commit comments

Comments
 (0)