Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3c897cf

Browse files
committedMar 1, 2015
core.stdc.stdio: add experimental support for MSVCRT 14 (VS 2015).
1 parent 999fae2 commit 3c897cf

File tree

2 files changed

+204
-31
lines changed

2 files changed

+204
-31
lines changed
 

‎src/core/stdc/stdio.d

+186-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,100 @@ 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,
644+
// forwarding to 4 basic functions.
645+
// We implement corresponding D wrappers around these basic functions.
646+
647+
private
648+
{
649+
enum _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR = 2;
650+
651+
int __stdio_common_vfprintf(ulong _Options, FILE* _Stream,
652+
in char* _Format, void* _Locale, va_list _ArgList);
653+
int __stdio_common_vsprintf(ulong _Options, char* _Buffer, size_t _BufferCount,
654+
in char* _Format, void* _Locale, va_list _ArgList);
655+
656+
int __stdio_common_vfscanf(ulong _Options, FILE* _Stream,
657+
in char* _Format, void* _Locale, va_list _Arglist);
658+
int __stdio_common_vsscanf(ulong _Options, in char* _Buffer, size_t _BufferCount,
659+
in char* _Format, void* _Locale, va_list _ArgList);
660+
}
661+
662+
extern (D)
663+
{
664+
// *printf:
665+
666+
int vfprintf(FILE* stream, in char* format, va_list args)
667+
{
668+
return __stdio_common_vfprintf(0, stream, format, null, args);
669+
}
670+
int fprintf(FILE* stream, in char* format, ...)
671+
{
672+
va_list args;
673+
va_start(args, format);
674+
return vfprintf(stream, format, args);
675+
}
676+
677+
int vprintf(in char* format, va_list args)
678+
{
679+
return vfprintf(stdout, format, args);
680+
}
681+
int printf(in char* format, ...)
682+
{
683+
va_list args;
684+
va_start(args, format);
685+
return vprintf(format, args);
686+
}
687+
688+
int vsprintf(char* s, in char* format, va_list args)
689+
{
690+
return vsnprintf(s, size_t.max, format, args);
691+
}
692+
int sprintf(char* s, in char* format, ...)
693+
{
694+
va_list args;
695+
va_start(args, format);
696+
return vsprintf(s, format, args);
697+
}
698+
699+
// *scanf:
700+
701+
int vfscanf(FILE* stream, in char* format, va_list args)
702+
{
703+
return __stdio_common_vfscanf(0, stream, format, null, args);
704+
}
705+
int fscanf(FILE* stream, in char* format, ...)
706+
{
707+
va_list args;
708+
va_start(args, format);
709+
return vfscanf(stream, format, args);
710+
}
711+
712+
int vscanf(in char* format, va_list args)
713+
{
714+
return vfscanf(stdin, format, args);
715+
}
716+
int scanf(in char* format, ...)
717+
{
718+
va_list args;
719+
va_start(args, format);
720+
return vscanf(format, args);
721+
}
722+
723+
int vsscanf(in char* s, in char* format, va_list args)
724+
{
725+
return __stdio_common_vsscanf(0, s, size_t.max, format, null, args);
726+
}
727+
int sscanf(in char* s, in char* format, ...)
728+
{
729+
va_list args;
730+
va_start(args, format);
731+
return vsscanf(s, format, args);
732+
}
733+
}
734+
}
608735
else
609736
{
610737
int fprintf(FILE* stream, in char* format, ...);
@@ -699,15 +826,48 @@ else version( Win32 )
699826
}
700827
else version( Win64 )
701828
{
702-
// No unsafe pointer manipulation.
703-
extern (D) @trusted
829+
version( LDC_MSVCRT14 ) // requires MSVCRT >= 14 (VS 2015)
704830
{
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; }
831+
// No unsafe pointer manipulation.
832+
@trusted
833+
{
834+
void rewind(FILE* stream);
835+
pure void clearerr(FILE* stream);
836+
pure int feof(FILE* stream);
837+
pure int ferror(FILE* stream);
838+
pure int fileno(FILE* stream);
839+
}
840+
841+
extern (D)
842+
{
843+
int vsnprintf(char* s, size_t n, in char* format, va_list args)
844+
{
845+
int result = __stdio_common_vsprintf(
846+
_CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR,
847+
s, n, format, null, args);
848+
return result < 0 ? -1 : result;
849+
}
850+
851+
int snprintf(char* s, size_t n, in char* format, ...)
852+
{
853+
va_list args;
854+
va_start(args, format);
855+
return vsnprintf(s, n, format, args);
856+
}
857+
}
710858
}
859+
else
860+
{
861+
// No unsafe pointer manipulation.
862+
extern (D) @trusted
863+
{
864+
void rewind(FILE* stream) { fseek(stream, 0L, SEEK_SET); stream._flag = stream._flag & ~_IOERR; }
865+
pure void clearerr(FILE* stream) { stream._flag = stream._flag & ~(_IOERR | _IOEOF); }
866+
pure int feof(FILE* stream) { return stream._flag & _IOEOF; }
867+
pure int ferror(FILE* stream) { return stream._flag & _IOERR; }
868+
pure int fileno(FILE* stream) { return stream._file; }
869+
}
870+
711871
int _snprintf(char* s, size_t n, in char* fmt, ...);
712872
alias _snprintf snprintf;
713873

@@ -745,6 +905,7 @@ else version( Win64 )
745905
else
746906
return _filbuf(fp);
747907
}
908+
}
748909

749910
int _lock_file(FILE *fp);
750911
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)
This repository has been archived.