Skip to content

Commit f09014e

Browse files
committed
mingw: add the mingw stdio functions back
We would rather use the ucrt for these, but sometimes dependencies on the mingw stdio functions creep in. 仕方ない. The cost is only paid if they are used; otherwise the symbols are garbage-collected at link time.
1 parent 51aec11 commit f09014e

31 files changed

+7501
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#define _GNU_SOURCE
2+
#define __CRT__NO_INLINE
3+
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <stdarg.h>
7+
8+
int __mingw_asprintf(char ** __restrict__ ret,
9+
const char * __restrict__ format,
10+
...) {
11+
va_list ap;
12+
int len;
13+
va_start(ap,format);
14+
/* Get Length */
15+
len = __mingw_vsnprintf(NULL,0,format,ap);
16+
if (len < 0) goto _end;
17+
/* +1 for \0 terminator. */
18+
*ret = malloc(len + 1);
19+
/* Check malloc fail*/
20+
if (!*ret) {
21+
len = -1;
22+
goto _end;
23+
}
24+
/* Write String */
25+
__mingw_vsnprintf(*ret,len+1,format,ap);
26+
/* Terminate explicitly */
27+
(*ret)[len] = '\0';
28+
_end:
29+
va_end(ap);
30+
return len;
31+
}
32+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* This file has no copyright assigned and is placed in the Public Domain.
3+
* This file is part of the mingw-w64 runtime package.
4+
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
5+
*/
6+
7+
#include <internal.h>
8+
9+
void __cdecl _lock(int locknum);
10+
void __cdecl _unlock(int locknum);
11+
void __cdecl _lock(__UNUSED_PARAM(int locknum)) { }
12+
void __cdecl _unlock(__UNUSED_PARAM(int locknum)) { }
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* fprintf.c
2+
*
3+
* $Id: fprintf.c,v 1.1 2008/08/11 22:41:55 keithmarshall Exp $
4+
*
5+
* Provides an implementation of the "fprintf" function, conforming
6+
* generally to C99 and SUSv3/POSIX specifications, with extensions
7+
* to support Microsoft's non-standard format specifications. This
8+
* is included in libmingwex.a, whence it may replace the Microsoft
9+
* function of the same name.
10+
*
11+
* Written by Keith Marshall <[email protected]>
12+
*
13+
* This implementation of "fprintf" will normally be invoked by calling
14+
* "__mingw_fprintf()" in preference to a direct reference to "fprintf()"
15+
* itself; this leaves the MSVCRT implementation as the default, which
16+
* will be deployed when user code invokes "fprint()". Users who then
17+
* wish to use this implementation may either call "__mingw_fprintf()"
18+
* directly, or may use conditional preprocessor defines, to redirect
19+
* references to "fprintf()" to "__mingw_fprintf()".
20+
*
21+
* Compiling this module with "-D INSTALL_AS_DEFAULT" will change this
22+
* recommended convention, such that references to "fprintf()" in user
23+
* code will ALWAYS be redirected to "__mingw_fprintf()"; if this option
24+
* is adopted, then users wishing to use the MSVCRT implementation of
25+
* "fprintf()" will be forced to use a "back-door" mechanism to do so.
26+
* Such a "back-door" mechanism is provided with MinGW, allowing the
27+
* MSVCRT implementation to be called as "__msvcrt_fprintf()"; however,
28+
* since users may not expect this behaviour, a standard libmingwex.a
29+
* installation does not employ this option.
30+
*
31+
*
32+
* This is free software. You may redistribute and/or modify it as you
33+
* see fit, without restriction of copyright.
34+
*
35+
* This software is provided "as is", in the hope that it may be useful,
36+
* but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of
37+
* MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE. At no
38+
* time will the author accept any form of liability for any damages,
39+
* however caused, resulting from the use of this software.
40+
*
41+
*/
42+
#include <stdio.h>
43+
#include <stdarg.h>
44+
45+
#include "mingw_pformat.h"
46+
47+
int __cdecl __fprintf (FILE *, const APICHAR *, ...) __MINGW_NOTHROW;
48+
49+
int __cdecl __fprintf(FILE *stream, const APICHAR *fmt, ...)
50+
{
51+
register int retval;
52+
va_list argv; va_start( argv, fmt );
53+
_lock_file( stream );
54+
retval = __pformat( PFORMAT_TO_FILE | PFORMAT_NOLIMIT, stream, 0, fmt, argv );
55+
_unlock_file( stream );
56+
va_end( argv );
57+
return retval;
58+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* This file has no copyright assigned and is placed in the Public Domain.
3+
* This file is part of the mingw-w64 runtime package.
4+
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
5+
*/
6+
#define __BUILD_WIDEAPI 1
7+
8+
#include "mingw_fprintf.c"
9+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <stdarg.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
5+
extern int __mingw_vfscanf (FILE *stream, const char *format, va_list argp);
6+
7+
int __mingw_fscanf (FILE *stream, const char *format, ...);
8+
9+
int
10+
__mingw_fscanf (FILE *stream, const char *format, ...)
11+
{
12+
va_list argp;
13+
int r;
14+
15+
va_start (argp, format);
16+
r = __mingw_vfscanf (stream, format, argp);
17+
va_end (argp);
18+
19+
return r;
20+
}
21+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <stdarg.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
5+
extern int __mingw_vfwscanf (FILE *stream, const wchar_t *format, va_list argp);
6+
7+
int __mingw_fwscanf (FILE *stream, const wchar_t *format, ...);
8+
9+
int
10+
__mingw_fwscanf (FILE *stream, const wchar_t *format, ...)
11+
{
12+
va_list argp;
13+
int r;
14+
15+
va_start (argp, format);
16+
r = __mingw_vfwscanf (stream, format, argp);
17+
va_end (argp);
18+
19+
return r;
20+
}
21+

lib/libc/mingw/stdio/mingw_lock.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#define _CRTIMP
2+
#include <stdio.h>
3+
#include <synchapi.h>
4+
#include "internal.h"
5+
6+
/***
7+
* Copy of MS functions _lock_file, _unlock_file which are missing from
8+
* msvcrt.dll and msvcr80.dll. They are needed to atomic/lock stdio
9+
* functions (printf, fprintf, vprintf, vfprintf). We need exactly the same
10+
* lock that MS uses in msvcrt.dll because we can mix mingw-w64 code with
11+
* original MS functions (puts, fputs for example).
12+
***/
13+
14+
15+
_CRTIMP void __cdecl _lock(int locknum);
16+
_CRTIMP void __cdecl _unlock(int locknum);
17+
#define _STREAM_LOCKS 16
18+
#define _IOLOCKED 0x8000
19+
20+
21+
/***
22+
* _lock_file - Lock a FILE
23+
*
24+
*Purpose:
25+
* Assert the lock for a stdio-level file
26+
*
27+
*Entry:
28+
* pf = __piob[] entry (pointer to a FILE or _FILEX)
29+
*
30+
*Exit:
31+
*
32+
*Exceptions:
33+
*
34+
*******************************************************************************/
35+
36+
void __cdecl _lock_file( FILE *pf )
37+
{
38+
/*
39+
* The way the FILE (pointed to by pf) is locked depends on whether
40+
* it is part of _iob[] or not
41+
*/
42+
if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) )
43+
{
44+
/*
45+
* FILE lies in _iob[] so the lock lies in _locktable[].
46+
*/
47+
_lock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) );
48+
/* We set _IOLOCKED to indicate we locked the stream */
49+
pf->_flag |= _IOLOCKED;
50+
}
51+
else
52+
/*
53+
* Not part of _iob[]. Therefore, *pf is a _FILEX and the
54+
* lock field of the struct is an initialized critical
55+
* section.
56+
*/
57+
EnterCriticalSection( &(((_FILEX *)pf)->lock) );
58+
}
59+
60+
void *__MINGW_IMP_SYMBOL(_lock_file) = _lock_file;
61+
62+
63+
/***
64+
* _unlock_file - Unlock a FILE
65+
*
66+
*Purpose:
67+
* Release the lock for a stdio-level file
68+
*
69+
*Entry:
70+
* pf = __piob[] entry (pointer to a FILE or _FILEX)
71+
*
72+
*Exit:
73+
*
74+
*Exceptions:
75+
*
76+
*******************************************************************************/
77+
78+
void __cdecl _unlock_file( FILE *pf )
79+
{
80+
/*
81+
* The way the FILE (pointed to by pf) is unlocked depends on whether
82+
* it is part of _iob[] or not
83+
*/
84+
if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) )
85+
{
86+
/*
87+
* FILE lies in _iob[] so the lock lies in _locktable[].
88+
* We reset _IOLOCKED to indicate we unlock the stream.
89+
*/
90+
pf->_flag &= ~_IOLOCKED;
91+
_unlock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) );
92+
}
93+
else
94+
/*
95+
* Not part of _iob[]. Therefore, *pf is a _FILEX and the
96+
* lock field of the struct is an initialized critical
97+
* section.
98+
*/
99+
LeaveCriticalSection( &(((_FILEX *)pf)->lock) );
100+
}
101+
102+
void *__MINGW_IMP_SYMBOL(_unlock_file) = _unlock_file;

0 commit comments

Comments
 (0)