Hacks to get glibc's stdio-common working.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5473 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2003-11-24 19:59:26 +00:00
parent 348820b57c
commit 65a98eb199
9 changed files with 97 additions and 163 deletions
@@ -2,8 +2,8 @@ SubDir OBOS_TOP src kernel libroot posix glibc stdio-common ;
SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc include arch $(OBOS_ARCH) ;
SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc stdio-common ;
SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc libio ;
SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc include ;
SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc libio ;
SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc locale ;
SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc ;
@@ -11,7 +11,7 @@ SubDirCcFlags -imacrolibc-symbols.h ;
# ToDo: for now, all wide character functions are disabled
KernelMergeObject posix_gnu_stdio_common.o :
KernelMergeObject posix_gnu_stdio.o : #_common.o :
<$(SOURCE_GRIST)>_itoa.c
# <$(SOURCE_GRIST)>_itowa.c
<$(SOURCE_GRIST)>asprintf.c
@@ -23,11 +23,11 @@ KernelMergeObject posix_gnu_stdio_common.o :
<$(SOURCE_GRIST)>itoa-digits.c
<$(SOURCE_GRIST)>itoa-udigits.c
# <$(SOURCE_GRIST)>itowa-digits.c
# <$(SOURCE_GRIST)>perror.c
<$(SOURCE_GRIST)>printf-prs.c
<$(SOURCE_GRIST)>perror.c
<$(SOURCE_GRIST)>printf-parse.c
<$(SOURCE_GRIST)>printf.c
<$(SOURCE_GRIST)>printf_fp.c
<$(SOURCE_GRIST)>printf_size.c
# <$(SOURCE_GRIST)>printf_fp.c
# <$(SOURCE_GRIST)>printf_size.c
<$(SOURCE_GRIST)>putw.c
<$(SOURCE_GRIST)>reg-printf.c
<$(SOURCE_GRIST)>scanf.c
@@ -35,9 +35,12 @@ KernelMergeObject posix_gnu_stdio_common.o :
<$(SOURCE_GRIST)>sprintf.c
<$(SOURCE_GRIST)>sscanf.c
<$(SOURCE_GRIST)>tempnam.c
<$(SOURCE_GRIST)>tempname.c
<$(SOURCE_GRIST)>tmpnam.c
<$(SOURCE_GRIST)>tmpnam_r.c
<$(SOURCE_GRIST)>vfprintf.c
# <$(SOURCE_GRIST)>vfprintf_stub.c
# <$(SOURCE_GRIST)>vfscanf_stub.c
<$(SOURCE_GRIST)>vfscanf.c
# <$(SOURCE_GRIST)>vfwprintf.c
# <$(SOURCE_GRIST)>vfwscanf.c
@@ -20,4 +20,4 @@
/* Lower-case digits. */
const char _itoa_lower_digits[36]
= "0123456789abcdefghijklmnopqrstuvwxyz";
INTVARDEF(_itoa_lower_digits)
//INTVARDEF(_itoa_lower_digits)
@@ -20,4 +20,4 @@
/* Upper-case digits. */
const char _itoa_upper_digits[36]
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
INTVARDEF(_itoa_upper_digits)
//INTVARDEF(_itoa_upper_digits)
@@ -14,80 +14,32 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
02111-1307 USA.
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <wchar.h>
#ifdef USE_IN_LIBIO
# include "libioP.h"
#endif
static void
perror_internal (FILE *fp, const char *s, int errnum)
{
char buf[1024];
const char *colon;
const char *errstring;
if (s == NULL || *s == '\0')
s = colon = "";
else
colon = ": ";
errstring = __strerror_r (errnum, buf, sizeof buf);
#ifdef USE_IN_LIBIO
if (_IO_fwide (fp, 0) > 0)
(void) __fwprintf (fp, L"%s%s%s\n", s, colon, errstring);
else
#endif
(void) fprintf (fp, "%s%s%s\n", s, colon, errstring);
}
/* Print a line on stderr consisting of the text in S, a colon, a space,
a message describing the meaning of the contents of `errno' and a newline.
If S is NULL or "", the colon and space are omitted. */
/** Print a line on stderr consisting of the text in S, a colon,
* a space, a message describing the meaning of the contents of
* `errno' and a newline.
* If S is NULL or "", the colon and space are omitted.
*/
void
perror (const char *s)
perror(const char *s)
{
int errnum = errno;
#ifdef USE_IN_LIBIO
FILE *fp;
int fd = -1;
const char *colon;
char buffer[1024];
if (s == NULL || *s == '\0')
s = colon = "";
else
colon = ": ";
/* The standard says that 'perror' must not change the orientation
of the stream. What is supposed to happen when the stream isn't
oriented yet? In this case we'll create a new stream which is
using the same underlying file descriptor. */
if (__builtin_expect (_IO_fwide (stderr, 0) != 0, 1)
|| (fd = fileno (stderr)) == -1
|| (fd = __dup (fd)) == -1
|| (fp = fdopen (fd, "w+")) == NULL)
{
if (__builtin_expect (fd != -1, 0))
__close (fd);
/* Use standard error as is. */
perror_internal (stderr, s, errnum);
}
else
{
/* We don't have to do any special hacks regarding the file
position. Since the stderr stream wasn't used so far we just
write to the descriptor. */
perror_internal (fp, s, errnum);
/* Close the stream. */
fclose (fp);
((_IO_FILE *) stderr)->_offset = _IO_pos_BAD;
}
#else
perror_internal (stderr, s, errnum);
#endif
fprintf(stderr, "%s%s%s\n", s, colon, strerror_r(errno, buffer, sizeof(buffer)));
}
libc_hidden_def (perror)
@@ -14,7 +14,9 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
02111-1307 USA.
*/
#include <stdio.h>
#include <printf.h>
@@ -34,19 +36,12 @@
# define ISASCII(Ch) isascii (Ch)
# define MBRLEN(Cp, L, St) __mbrlen (Cp, L, St)
# ifdef USE_IN_LIBIO
# define PUT(F, S, N) _IO_sputn (F, S, N)
# define PAD(Padchar) \
if (width > 0) \
done += INTUSE(_IO_padn) (s, Padchar, width)
# else
# define PUTC(C, F) putc (C, F)
# define PUTC(C, F) putc (C, F)
ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
# define PAD(Padchar) \
if (width > 0) \
{ if (__printf_pad (s, Padchar, width) == -1) \
return -1; else done += width; }
# endif
#else
# define vfprintf vfwprintf
# define CHAR_T wchar_t
@@ -55,68 +50,55 @@ ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
# define L_(Str) L##Str
# define ISDIGIT(Ch) iswdigit (Ch)
# ifdef USE_IN_LIBIO
# define PUT(F, S, N) _IO_sputn (F, S, N)
# define PAD(Padchar) \
if (width > 0) \
done += _IO_wpadn (s, Padchar, width)
# else
# define PUTC(C, F) wputc (C, F)
# define PUTC(C, F) wputc (C, F)
ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n));
# define PAD(Padchar) \
if (width > 0) \
{ if (__wprintf_pad (s, Padchar, width) == -1) \
return -1; else done += width; }
# endif
#endif
#include "printf-parse.h"
size_t
parse_printf_format (fmt, n, argtypes)
const char *fmt;
size_t n;
int *argtypes;
parse_printf_format(const char *fmt, size_t n, int *argtypes)
{
size_t nargs; /* Number of arguments. */
size_t max_ref_arg; /* Highest index used in a positional arg. */
struct printf_spec spec;
mbstate_t mbstate;
size_t nargs = 0; /* Number of arguments. */
size_t max_ref_arg = 0; /* Highest index used in a positional arg. */
struct printf_spec spec;
mbstate_t mbstate;
nargs = 0;
max_ref_arg = 0;
/* Search for format specifications. */
for (fmt = find_spec(fmt /*, &mbstate*/); *fmt != '\0'; fmt = spec.next_fmt) {
/* Parse this spec. */
nargs += parse_one_spec(fmt, nargs, &spec, &max_ref_arg /*, &mbstate*/);
/* Search for format specifications. */
for (fmt = find_spec (fmt, &mbstate); *fmt != '\0'; fmt = spec.next_fmt)
{
/* Parse this spec. */
nargs += parse_one_spec (fmt, nargs, &spec, &max_ref_arg, &mbstate);
/* If the width is determined by an argument this is an int. */
if (spec.width_arg != -1 && (size_t)spec.width_arg < n)
argtypes[spec.width_arg] = PA_INT;
/* If the width is determined by an argument this is an int. */
if (spec.width_arg != -1 && (size_t) spec.width_arg < n)
argtypes[spec.width_arg] = PA_INT;
/* If the precision is determined by an argument this is an int. */
if (spec.prec_arg != -1 && (size_t) spec.prec_arg < n)
argtypes[spec.prec_arg] = PA_INT;
/* If the precision is determined by an argument this is an int. */
if (spec.prec_arg != -1 && (size_t) spec.prec_arg < n)
argtypes[spec.prec_arg] = PA_INT;
if ((size_t) spec.data_arg < n) {
switch (spec.ndata_args) {
case 0: /* No arguments. */
break;
case 1: /* One argument; we already have the type. */
argtypes[spec.data_arg] = spec.data_arg_type;
break;
default:
/* We have more than one argument for this format spec. We must
* call the arginfo function again to determine all the types.
*/
(*__printf_arginfo_table[spec.info.spec])
(&spec.info, n - spec.data_arg, &argtypes[spec.data_arg]);
break;
}
}
}
if ((size_t) spec.data_arg < n)
switch (spec.ndata_args)
{
case 0: /* No arguments. */
break;
case 1: /* One argument; we already have the type. */
argtypes[spec.data_arg] = spec.data_arg_type;
break;
default:
/* We have more than one argument for this format spec. We must
call the arginfo function again to determine all the types. */
(void) (*__printf_arginfo_table[spec.info.spec])
(&spec.info, n - spec.data_arg, &argtypes[spec.data_arg]);
break;
}
}
return MAX (nargs, max_ref_arg);
return MAX(nargs, max_ref_arg);
}
@@ -87,15 +87,14 @@ read_int (const UCHAR_T * *pstr)
}
/* Find the next spec in FORMAT, or the end of the string. Returns
a pointer into FORMAT, to a '%' or a '\0'. */
static inline const UCHAR_T *
#ifdef COMPILE_WPRINTF
//#ifdef COMPILE_WPRINTF
find_spec (const UCHAR_T *format)
#else
find_spec (const UCHAR_T *format, mbstate_t *ps)
#endif
//#else
//find_spec (const UCHAR_T *format, mbstate_t *ps)
//#endif
{
#ifdef COMPILE_WPRINTF
return (const UCHAR_T *) __wcschrnul ((const CHAR_T *) format, L'%');
@@ -105,10 +104,10 @@ find_spec (const UCHAR_T *format, mbstate_t *ps)
int len;
/* Remove any hints of a wrong encoding. */
ps->__count = 0;
if (! isascii (*format) && (len = __mbrlen (format, MB_CUR_MAX, ps)) > 0)
format += len;
else
// ps->__count = 0;
// if (! isascii (*format) && (len = __mbrlen (format, MB_CUR_MAX, ps)) > 0)
// format += len;
// else
++format;
}
return format;
@@ -127,13 +126,13 @@ extern printf_function **__printf_function_table attribute_hidden;
the number of args consumed by this spec; *MAX_REF_ARG is updated so it
remains the highest argument index used. */
static inline size_t
#ifdef COMPILE_WPRINTF
//#ifdef COMPILE_WPRINTF
parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
size_t *max_ref_arg)
#else
parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
size_t *max_ref_arg, mbstate_t *ps)
#endif
//#else
//parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
// size_t *max_ref_arg, mbstate_t *ps)
//#endif
{
unsigned int n;
size_t nargs = 0;
@@ -443,11 +442,11 @@ parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
{
/* Find the next format spec. */
spec->end_of_fmt = format;
#ifdef COMPILE_WPRINTF
//#ifdef COMPILE_WPRINTF
spec->next_fmt = find_spec (format);
#else
spec->next_fmt = find_spec (format, ps);
#endif
//#else
// spec->next_fmt = find_spec (format, ps);
//#endif
}
return nargs;
@@ -21,11 +21,7 @@
/* The gmp headers need some configuration frobs. */
#define HAVE_ALLOCA 1
#ifdef USE_IN_LIBIO
# include <libioP.h>
#else
# include <stdio.h>
#endif
#include <stdio_private.h>
#include <alloca.h>
#include <ctype.h>
#include <float.h>
@@ -236,9 +232,11 @@ __printf_fp (FILE *fp,
}
}
mp_limb_t _cy = __mpn_mul_1 (frac, frac, fracsize, 10);
if (_cy != 0)
frac[fracsize++] = _cy;
{
mp_limb_t _cy = __mpn_mul_1 (frac, frac, fracsize, 10);
if (_cy != 0)
frac[fracsize++] = _cy;
}
}
return L'0' + hi;
@@ -304,7 +302,7 @@ __printf_fp (FILE *fp,
multibyte representation for the thousands separator,
we must ensure the wide character thousands separator
is available, even if it is fake. */
thousands_sepwc = 0xfffffffe;
thousands_sepwc = (wchar_t)0xfffffffe;
}
}
else
@@ -19,15 +19,11 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <stdio_private.h>
#include <ctype.h>
#include <ieee754.h>
#include <math.h>
#include <printf.h>
#ifdef USE_IN_LIBIO
# include <libioP.h>
#else
# include <stdio.h>
#endif
/* This defines make it possible to use the same code for GNU C library and
@@ -14,14 +14,18 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
02111-1307 USA.
*/
#include <stdio_private.h>
#include <errno.h>
#include <limits.h>
#include <printf.h>
#include <stddef.h>
#include <stdlib.h>
/* Array of functions indexed by format character. */
libc_freeres_ptr (printf_arginfo_function **__printf_arginfo_table)
attribute_hidden;