Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1361 from kinke/vs2015_dmd
Browse files Browse the repository at this point in the history
Visual Studio 2015: exploit C99-conformant (v)snprintf in core.stdc.stdio
  • Loading branch information
rainers committed Aug 28, 2015
2 parents 9172466 + 5ff263e commit e054ff2
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 46 deletions.
36 changes: 18 additions & 18 deletions src/core/stdc/stdio.d
Expand Up @@ -71,19 +71,19 @@ else version( CRuntime_Microsoft )
FOPEN_MAX = 20,
///
FILENAME_MAX = 260,
///
/// Actually int.max since Visual Studio 2015.
TMP_MAX = 32767,
///
_SYS_OPEN = 20, // non-standard
}

///
enum int _NFILE = 512; // non-standard
///
/// Removed since Visual Studio 2015.
enum string _P_tmpdir = "\\"; // non-standard
///
/// Removed since Visual Studio 2015.
enum wstring _wP_tmpdir = "\\"; // non-standard
///
/// Actually 260 since Visual Studio 2015.
enum int L_tmpnam = _P_tmpdir.length + 12;
}
else version( CRuntime_Glibc )
Expand Down Expand Up @@ -543,23 +543,23 @@ else version( CRuntime_Microsoft )
_IOLBF = 0x40,
///
_IONBF = 4,
///
/// Removed since Visual Studio 2015.
_IOREAD = 1, // non-standard
///
/// Removed since Visual Studio 2015.
_IOWRT = 2, // non-standard
///
/// Removed since Visual Studio 2015.
_IOMYBUF = 8, // non-standard
///
/// Removed since Visual Studio 2015.
_IOEOF = 0x10, // non-standard
///
/// Removed since Visual Studio 2015.
_IOERR = 0x20, // non-standard
///
/// Removed since Visual Studio 2015.
_IOSTRG = 0x40, // non-standard
///
/// Removed since Visual Studio 2015.
_IORW = 0x80, // non-standard
///
/// Removed since Visual Studio 2015.
_IOAPP = 0x200, // non-standard
///
/// Removed since Visual Studio 2015.
_IOAPPEND = 0x200, // non-standard
}

Expand Down Expand Up @@ -941,19 +941,19 @@ else version( CRuntime_Microsoft )
///
pure int fileno(FILE* stream);
}

///
int _snprintf(char* s, size_t n, in char* fmt, ...);
int _snprintf(char* s, size_t n, in char* format, ...);
///
alias _snprintf snprintf;
int snprintf(char* s, size_t n, in char* format, ...);

///
int _vsnprintf(char* s, size_t n, in char* format, va_list arg);
int _vsnprintf(char* s, size_t n, in char* format, va_list arg);
///
alias _vsnprintf vsnprintf;
int vsnprintf(char* s, size_t n, in char* format, va_list arg);

///
int _fputc_nolock(int c, FILE *fp);

///
int _fgetc_nolock(FILE *fp);

Expand Down
49 changes: 21 additions & 28 deletions src/rt/stdio_msvc.c
Expand Up @@ -53,12 +53,21 @@ void init_msvc()
FILE* fp = __iob_func();
stdin = fp;
stdout = fp + 1;
stderr = fp + 1;
stderr = fp + 2;
}
if (&_set_output_format != (void*) &_nullfunc)
_set_output_format(1);
{
const int _TWO_DIGIT_EXPONENT = 1;
_set_output_format(_TWO_DIGIT_EXPONENT);
}
}

// VS2015+ provides C99-conformant (v)snprintf functions, so weakly
// link to legacy _(v)snprintf (not C99-conformant!) for VS2013- only

#pragma comment(linker, "/alternatename:snprintf=_snprintf")
#pragma comment(linker, "/alternatename:vsnprintf=_vsnprintf")

// VS2013- implements these functions as macros, VS2015+ provides symbols

#pragma comment(linker, "/alternatename:_fputc_nolock=_msvc_fputc_nolock")
Expand All @@ -70,13 +79,13 @@ void init_msvc()
#pragma comment(linker, "/alternatename:fileno=_msvc_fileno")

// VS2013- helper functions
int _filbuf(FILE *fp);
int _flsbuf(int c, FILE *fp);
int _filbuf(FILE* fp);
int _flsbuf(int c, FILE* fp);

#pragma comment(linker, "/alternatename:_filbuf=_nullfunc")
#pragma comment(linker, "/alternatename:_flsbuf=_nullfunc")

int _msvc_fputc_nolock(int c, FILE *fp)
int _msvc_fputc_nolock(int c, FILE* fp)
{
fp->_cnt = fp->_cnt - 1;
if (fp->_cnt >= 0)
Expand All @@ -89,7 +98,7 @@ int _msvc_fputc_nolock(int c, FILE *fp)
return _flsbuf(c, fp);
}

int _msvc_fgetc_nolock(FILE *fp)
int _msvc_fgetc_nolock(FILE* fp)
{
fp->_cnt = fp->_cnt - 1;
if (fp->_cnt >= 0)
Expand All @@ -104,38 +113,22 @@ int _msvc_fgetc_nolock(FILE *fp)

enum
{
_IOFBF = 0,
_IOLBF = 0x40,
_IONBF = 4,
_IOREAD = 1, // non-standard
_IOWRT = 2, // non-standard
_IOMYBUF = 8, // non-standard
_IOEOF = 0x10, // non-standard
_IOERR = 0x20, // non-standard
_IOSTRG = 0x40, // non-standard
_IORW = 0x80, // non-standard
_IOAPP = 0x200, // non-standard
_IOAPPEND = 0x200, // non-standard
SEEK_SET = 0,
_IOEOF = 0x10,
_IOERR = 0x20
};

enum
{
SEEK_SET,
SEEK_CUR,
SEEK_END
};

int fseek(FILE *fp, long off, int whence);
int fseek(FILE* fp, long off, int whence);

void _msvc_rewind(FILE* stream)
{
fseek(stream, 0L, SEEK_SET);
stream->_flag = stream->_flag & ~_IOERR;
}
///

void _msvc_clearerr(FILE* stream)
{
stream->_flag = stream->_flag & ~(_IOERR|_IOEOF);
stream->_flag = stream->_flag & ~(_IOERR | _IOEOF);
}

int _msvc_feof(FILE* stream)
Expand Down

0 comments on commit e054ff2

Please sign in to comment.