diff --git a/mak/MANIFEST b/mak/MANIFEST index 012347fcf5..e760921504 100644 --- a/mak/MANIFEST +++ b/mak/MANIFEST @@ -187,6 +187,8 @@ MANIFEST=\ src\core\sys\windows\threadaux.d \ src\core\sys\windows\windows.d \ src\core\sys\windows\winsock2.d \ + src\core\sys\windows\stdio_msvc12.d \ + src\core\sys\windows\stdio_msvc14.d \ \ src\gc\bits.d \ src\gc\config.d \ diff --git a/mak/SRCS b/mak/SRCS index 834c094ec4..f7a1bc27c8 100644 --- a/mak/SRCS +++ b/mak/SRCS @@ -75,6 +75,7 @@ SRCS=\ src\core\sys\windows\threadaux.d \ src\core\sys\windows\windows.d \ src\core\sys\windows\winsock2.d \ + src\core\sys\windows\stdio_msvc12.d \ \ src\gc\bits.d \ src\gc\config.d \ diff --git a/src/core/stdc/stdio.d b/src/core/stdc/stdio.d index 8174878c34..ae2966a8a5 100644 --- a/src/core/stdc/stdio.d +++ b/src/core/stdc/stdio.d @@ -259,14 +259,7 @@ else version( CRuntime_Microsoft ) /// struct _iobuf { - char* _ptr; - int _cnt; - char* _base; - int _flag; - int _file; - int _charbuf; - int _bufsiz; - char* _tmpfname; + void* undefined; } /// @@ -572,10 +565,6 @@ else version( CRuntime_Microsoft ) extern shared void function() _fcloseallp; - private extern shared FILE[_NFILE] _iob; - - shared(FILE)* __iob_func(); - /// shared FILE* stdin; // = &__iob_func()[0]; /// @@ -939,18 +928,18 @@ else version( CRuntime_DigitalMars ) else version( CRuntime_Microsoft ) { // No unsafe pointer manipulation. - extern (D) @trusted + @trusted { /// - void rewind(FILE* stream) { fseek(stream,0L,SEEK_SET); stream._flag = stream._flag & ~_IOERR; } + void rewind(FILE* stream); /// - pure void clearerr(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); } + pure void clearerr(FILE* stream); /// - pure int feof(FILE* stream) { return stream._flag&_IOEOF; } + pure int feof(FILE* stream); /// - pure int ferror(FILE* stream) { return stream._flag&_IOERR; } + pure int ferror(FILE* stream); /// - pure int fileno(FILE* stream) { return stream._file; } + pure int fileno(FILE* stream); } /// int _snprintf(char* s, size_t n, in char* fmt, ...); @@ -963,42 +952,10 @@ else version( CRuntime_Microsoft ) alias _vsnprintf vsnprintf; /// - uint _set_output_format(uint format); - /// - enum _TWO_DIGIT_EXPONENT = 1; + int _fputc_nolock(int c, FILE *fp); /// - int _filbuf(FILE *fp); - /// - int _flsbuf(int c, FILE *fp); - - /// - int _fputc_nolock(int c, FILE *fp) - { - fp._cnt = fp._cnt - 1; - if (fp._cnt >= 0) - { - *fp._ptr = cast(char)c; - fp._ptr = fp._ptr + 1; - return cast(char)c; - } - else - return _flsbuf(c, fp); - } - - /// - int _fgetc_nolock(FILE *fp) - { - fp._cnt = fp._cnt - 1; - if (fp._cnt >= 0) - { - char c = *fp._ptr; - fp._ptr = fp._ptr + 1; - return c; - } - else - return _filbuf(fp); - } + int _fgetc_nolock(FILE *fp); /// int _lock_file(FILE *fp); diff --git a/src/core/sys/windows/stdio_msvc12.d b/src/core/sys/windows/stdio_msvc12.d new file mode 100644 index 0000000000..e028a4048e --- /dev/null +++ b/src/core/sys/windows/stdio_msvc12.d @@ -0,0 +1,103 @@ +/** +* This module provides MS VC runtime helper function to be used +* with VS versions before VS 2015 +* +* Copyright: Copyright Digital Mars 2015. +* License: Distributed under the +* $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). +* (See accompanying file LICENSE) +* Source: $(DRUNTIMESRC core/sys/windows/_stdio_msvc12.d) +* Authors: Rainer Schuetze +*/ + +module core.sys.windows.stdio_msvc12; + +version( CRuntime_Microsoft ): + +import core.stdc.stdio; + +extern (C): +@system: +nothrow: +@nogc: + +alias stdio_FILE = core.stdc.stdio.FILE; + +FILE* __iob_func(); + +uint _set_output_format(uint format); + +enum _TWO_DIGIT_EXPONENT = 1; + +void init_msvc() +{ + // stdin,stdout and stderr internally in a static array __iob[3] + auto fp = __iob_func(); + stdin = cast(stdio_FILE*) &fp[0]; + stdout = cast(stdio_FILE*) &fp[1]; + stderr = cast(stdio_FILE*) &fp[2]; + + // ensure that sprintf generates only 2 digit exponent when writing floating point values + _set_output_format(_TWO_DIGIT_EXPONENT); +} + +struct _iobuf +{ + char* _ptr; + int _cnt; // _cnt and _base exchanged for VS2015 + char* _base; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char* _tmpfname; +} + +alias shared(_iobuf) FILE; + +int _filbuf(FILE *fp); +int _flsbuf(int c, FILE *fp); + +int _fputc_nolock(int c, FILE *fp) +{ + fp._cnt = fp._cnt - 1; + if (fp._cnt >= 0) + { + *fp._ptr = cast(char)c; + fp._ptr = fp._ptr + 1; + return cast(char)c; + } + else + return _flsbuf(c, fp); +} + +int _fgetc_nolock(FILE *fp) +{ + fp._cnt = fp._cnt - 1; + if (fp._cnt >= 0) + { + char c = *fp._ptr; + fp._ptr = fp._ptr + 1; + return c; + } + else + return _filbuf(fp); +} + +@trusted +{ + /// + void rewind(FILE* stream) + { + fseek(cast(stdio_FILE*)stream,0L,SEEK_SET); + stream._flag = stream._flag & ~_IOERR; + } + /// + pure void clearerr(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); } + /// + pure int feof(FILE* stream) { return stream._flag&_IOEOF; } + /// + pure int ferror(FILE* stream) { return stream._flag&_IOERR; } + /// + pure int fileno(FILE* stream) { return stream._file; } +} diff --git a/src/core/sys/windows/stdio_msvc14.d b/src/core/sys/windows/stdio_msvc14.d new file mode 100644 index 0000000000..f434543b99 --- /dev/null +++ b/src/core/sys/windows/stdio_msvc14.d @@ -0,0 +1,38 @@ +/** +* This module provides MS VC runtime helper function to be used +* with VS versions VS 2015 or later +* +* Copyright: Copyright Digital Mars 2015. +* License: Distributed under the +* $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). +* (See accompanying file LICENSE) +* Source: $(DRUNTIMESRC core/sys/windows/_stdio_msvc14.d) +* Authors: Rainer Schuetze +*/ + +module core.sys.windows.stdio_msvc14; + +version (CRuntime_Microsoft): + +import core.stdc.stdio; + +extern (C): +@system: +nothrow: +@nogc: + +shared(FILE)* __acrt_iob_func(uint); // VS2015+ + +void init_msvc() +{ + stdin = __acrt_iob_func(0); + stdout = __acrt_iob_func(1); + stderr = __acrt_iob_func(2); +} + +pragma(lib, "legacy_stdio_definitions.lib"); + +shared static this() +{ + // force linkage of ModuleInfo that includes the pragma(lib) above in its object file +} diff --git a/src/rt/dmain2.d b/src/rt/dmain2.d index d13b2536b1..4af1b13fa9 100644 --- a/src/rt/dmain2.d +++ b/src/rt/dmain2.d @@ -57,6 +57,11 @@ version (OSX) extern (C) __gshared void* __osx_stack_end = cast(void*)0xC0000000; } +version(CRuntime_Microsoft) +{ + extern(C) void init_msvc(); +} + /*********************************** * These are a temporary means of providing a GC hook for DLL use. They may be * replaced with some other similar functionality later. @@ -320,13 +325,7 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc) } version (CRuntime_Microsoft) { - auto fp = __iob_func(); - stdin = &fp[0]; - stdout = &fp[1]; - stderr = &fp[2]; - - // ensure that sprintf generates only 2 digit exponent when writing floating point values - _set_output_format(_TWO_DIGIT_EXPONENT); + init_msvc(); // enable full precision for reals version(Win64) diff --git a/win64.mak b/win64.mak index bc7b1dedb7..21b1755dc3 100644 --- a/win64.mak +++ b/win64.mak @@ -27,10 +27,12 @@ CFLAGS=/Z7 /I"$(VCDIR)"\INCLUDE /I"$(SDKDIR)"\Include DRUNTIME_BASE=druntime$(MODEL) DRUNTIME=lib\$(DRUNTIME_BASE).lib GCSTUB=lib\gcstub$(MODEL).obj +STDIO_VS12=lib\stdio_msvc12_$(MODEL).obj +STDIO_VS14=lib\stdio_msvc14_$(MODEL).obj DOCFMT= -target : import copydir copy $(DRUNTIME) $(GCSTUB) +target : import copydir copy $(DRUNTIME) $(GCSTUB) stdio_vs $(mak\COPY) $(mak\DOCS) @@ -660,6 +662,16 @@ src\rt\minit.obj : src\rt\minit.asm $(GCSTUB) : src\gcstub\gc.d win64.mak $(DMD) -c -of$(GCSTUB) src\gcstub\gc.d $(DFLAGS) +################### VS 2015 init code ######################### + +stdio_vs: $(STDIO_VS14) $(STDIO_VS12) + +$(STDIO_VS12) : src\core\sys\windows\stdio_msvc12.d win64.mak + $(DMD) -c -of$(STDIO_VS12) src\core\sys\windows\stdio_msvc12.d $(DFLAGS) + +$(STDIO_VS14) : src\core\sys\windows\stdio_msvc14.d win64.mak + $(DMD) -c -of$(STDIO_VS14) src\core\sys\windows\stdio_msvc14.d $(DFLAGS) + ################### Library generation ######################### $(DRUNTIME): $(OBJS) $(SRCS) win64.mak