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 include arch $(OBOS_ARCH) ;
SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc stdio-common ; 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 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 locale ;
SubDirHdrs $(OBOS_TOP) src kernel libroot posix glibc ; 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 # 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)>_itoa.c
# <$(SOURCE_GRIST)>_itowa.c # <$(SOURCE_GRIST)>_itowa.c
<$(SOURCE_GRIST)>asprintf.c <$(SOURCE_GRIST)>asprintf.c
@@ -23,11 +23,11 @@ KernelMergeObject posix_gnu_stdio_common.o :
<$(SOURCE_GRIST)>itoa-digits.c <$(SOURCE_GRIST)>itoa-digits.c
<$(SOURCE_GRIST)>itoa-udigits.c <$(SOURCE_GRIST)>itoa-udigits.c
# <$(SOURCE_GRIST)>itowa-digits.c # <$(SOURCE_GRIST)>itowa-digits.c
# <$(SOURCE_GRIST)>perror.c <$(SOURCE_GRIST)>perror.c
<$(SOURCE_GRIST)>printf-prs.c <$(SOURCE_GRIST)>printf-parse.c
<$(SOURCE_GRIST)>printf.c <$(SOURCE_GRIST)>printf.c
<$(SOURCE_GRIST)>printf_fp.c # <$(SOURCE_GRIST)>printf_fp.c
<$(SOURCE_GRIST)>printf_size.c # <$(SOURCE_GRIST)>printf_size.c
<$(SOURCE_GRIST)>putw.c <$(SOURCE_GRIST)>putw.c
<$(SOURCE_GRIST)>reg-printf.c <$(SOURCE_GRIST)>reg-printf.c
<$(SOURCE_GRIST)>scanf.c <$(SOURCE_GRIST)>scanf.c
@@ -35,9 +35,12 @@ KernelMergeObject posix_gnu_stdio_common.o :
<$(SOURCE_GRIST)>sprintf.c <$(SOURCE_GRIST)>sprintf.c
<$(SOURCE_GRIST)>sscanf.c <$(SOURCE_GRIST)>sscanf.c
<$(SOURCE_GRIST)>tempnam.c <$(SOURCE_GRIST)>tempnam.c
<$(SOURCE_GRIST)>tempname.c
<$(SOURCE_GRIST)>tmpnam.c <$(SOURCE_GRIST)>tmpnam.c
<$(SOURCE_GRIST)>tmpnam_r.c <$(SOURCE_GRIST)>tmpnam_r.c
<$(SOURCE_GRIST)>vfprintf.c <$(SOURCE_GRIST)>vfprintf.c
# <$(SOURCE_GRIST)>vfprintf_stub.c
# <$(SOURCE_GRIST)>vfscanf_stub.c
<$(SOURCE_GRIST)>vfscanf.c <$(SOURCE_GRIST)>vfscanf.c
# <$(SOURCE_GRIST)>vfwprintf.c # <$(SOURCE_GRIST)>vfwprintf.c
# <$(SOURCE_GRIST)>vfwscanf.c # <$(SOURCE_GRIST)>vfwscanf.c
@@ -20,4 +20,4 @@
/* Lower-case digits. */ /* Lower-case digits. */
const char _itoa_lower_digits[36] const char _itoa_lower_digits[36]
= "0123456789abcdefghijklmnopqrstuvwxyz"; = "0123456789abcdefghijklmnopqrstuvwxyz";
INTVARDEF(_itoa_lower_digits) //INTVARDEF(_itoa_lower_digits)
@@ -20,4 +20,4 @@
/* Upper-case digits. */ /* Upper-case digits. */
const char _itoa_upper_digits[36] const char _itoa_upper_digits[36]
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; = "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 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 License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA.
*/
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.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, /** Print a line on stderr consisting of the text in S, a colon,
a message describing the meaning of the contents of `errno' and a newline. * a space, a message describing the meaning of the contents of
If S is NULL or "", the colon and space are omitted. */ * `errno' and a newline.
* If S is NULL or "", the colon and space are omitted.
*/
void void
perror (const char *s) perror(const char *s)
{ {
int errnum = errno; const char *colon;
#ifdef USE_IN_LIBIO char buffer[1024];
FILE *fp;
int fd = -1;
if (s == NULL || *s == '\0')
s = colon = "";
else
colon = ": ";
/* The standard says that 'perror' must not change the orientation fprintf(stderr, "%s%s%s\n", s, colon, strerror_r(errno, buffer, sizeof(buffer)));
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
} }
libc_hidden_def (perror)
@@ -14,7 +14,9 @@
You should have received a copy of the GNU Lesser General Public 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 License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA.
*/
#include <stdio.h> #include <stdio.h>
#include <printf.h> #include <printf.h>
@@ -34,19 +36,12 @@
# define ISASCII(Ch) isascii (Ch) # define ISASCII(Ch) isascii (Ch)
# define MBRLEN(Cp, L, St) __mbrlen (Cp, L, St) # define MBRLEN(Cp, L, St) __mbrlen (Cp, L, St)
# ifdef USE_IN_LIBIO # define PUTC(C, F) putc (C, F)
# 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)
ssize_t __printf_pad __P ((FILE *, char pad, size_t n)); ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
# define PAD(Padchar) \ # define PAD(Padchar) \
if (width > 0) \ if (width > 0) \
{ if (__printf_pad (s, Padchar, width) == -1) \ { if (__printf_pad (s, Padchar, width) == -1) \
return -1; else done += width; } return -1; else done += width; }
# endif
#else #else
# define vfprintf vfwprintf # define vfprintf vfwprintf
# define CHAR_T wchar_t # 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 L_(Str) L##Str
# define ISDIGIT(Ch) iswdigit (Ch) # define ISDIGIT(Ch) iswdigit (Ch)
# ifdef USE_IN_LIBIO # define PUTC(C, F) wputc (C, F)
# 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)
ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n)); ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n));
# define PAD(Padchar) \ # define PAD(Padchar) \
if (width > 0) \ if (width > 0) \
{ if (__wprintf_pad (s, Padchar, width) == -1) \ { if (__wprintf_pad (s, Padchar, width) == -1) \
return -1; else done += width; } return -1; else done += width; }
# endif
#endif #endif
#include "printf-parse.h" #include "printf-parse.h"
size_t size_t
parse_printf_format (fmt, n, argtypes) parse_printf_format(const char *fmt, size_t n, int *argtypes)
const char *fmt;
size_t n;
int *argtypes;
{ {
size_t nargs; /* Number of arguments. */ size_t nargs = 0; /* Number of arguments. */
size_t max_ref_arg; /* Highest index used in a positional arg. */ size_t max_ref_arg = 0; /* Highest index used in a positional arg. */
struct printf_spec spec; struct printf_spec spec;
mbstate_t mbstate; mbstate_t mbstate;
nargs = 0; /* Search for format specifications. */
max_ref_arg = 0; 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. */ /* If the width is determined by an argument this is an int. */
for (fmt = find_spec (fmt, &mbstate); *fmt != '\0'; fmt = spec.next_fmt) if (spec.width_arg != -1 && (size_t)spec.width_arg < n)
{ argtypes[spec.width_arg] = PA_INT;
/* 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 the precision is determined by an argument this is an int. */
if (spec.width_arg != -1 && (size_t) spec.width_arg < n) if (spec.prec_arg != -1 && (size_t) spec.prec_arg < n)
argtypes[spec.width_arg] = PA_INT; argtypes[spec.prec_arg] = PA_INT;
/* If the precision is determined by an argument this is an int. */ if ((size_t) spec.data_arg < n) {
if (spec.prec_arg != -1 && (size_t) spec.prec_arg < n) switch (spec.ndata_args) {
argtypes[spec.prec_arg] = PA_INT; 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) return MAX(nargs, max_ref_arg);
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);
} }
@@ -87,15 +87,14 @@ read_int (const UCHAR_T * *pstr)
} }
/* Find the next spec in FORMAT, or the end of the string. Returns /* Find the next spec in FORMAT, or the end of the string. Returns
a pointer into FORMAT, to a '%' or a '\0'. */ a pointer into FORMAT, to a '%' or a '\0'. */
static inline const UCHAR_T * static inline const UCHAR_T *
#ifdef COMPILE_WPRINTF //#ifdef COMPILE_WPRINTF
find_spec (const UCHAR_T *format) find_spec (const UCHAR_T *format)
#else //#else
find_spec (const UCHAR_T *format, mbstate_t *ps) //find_spec (const UCHAR_T *format, mbstate_t *ps)
#endif //#endif
{ {
#ifdef COMPILE_WPRINTF #ifdef COMPILE_WPRINTF
return (const UCHAR_T *) __wcschrnul ((const CHAR_T *) format, L'%'); 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; int len;
/* Remove any hints of a wrong encoding. */ /* Remove any hints of a wrong encoding. */
ps->__count = 0; // ps->__count = 0;
if (! isascii (*format) && (len = __mbrlen (format, MB_CUR_MAX, ps)) > 0) // if (! isascii (*format) && (len = __mbrlen (format, MB_CUR_MAX, ps)) > 0)
format += len; // format += len;
else // else
++format; ++format;
} }
return 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 the number of args consumed by this spec; *MAX_REF_ARG is updated so it
remains the highest argument index used. */ remains the highest argument index used. */
static inline size_t static inline size_t
#ifdef COMPILE_WPRINTF //#ifdef COMPILE_WPRINTF
parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec, parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
size_t *max_ref_arg) size_t *max_ref_arg)
#else //#else
parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec, //parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
size_t *max_ref_arg, mbstate_t *ps) // size_t *max_ref_arg, mbstate_t *ps)
#endif //#endif
{ {
unsigned int n; unsigned int n;
size_t nargs = 0; 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. */ /* Find the next format spec. */
spec->end_of_fmt = format; spec->end_of_fmt = format;
#ifdef COMPILE_WPRINTF //#ifdef COMPILE_WPRINTF
spec->next_fmt = find_spec (format); spec->next_fmt = find_spec (format);
#else //#else
spec->next_fmt = find_spec (format, ps); // spec->next_fmt = find_spec (format, ps);
#endif //#endif
} }
return nargs; return nargs;
@@ -21,11 +21,7 @@
/* The gmp headers need some configuration frobs. */ /* The gmp headers need some configuration frobs. */
#define HAVE_ALLOCA 1 #define HAVE_ALLOCA 1
#ifdef USE_IN_LIBIO #include <stdio_private.h>
# include <libioP.h>
#else
# include <stdio.h>
#endif
#include <alloca.h> #include <alloca.h>
#include <ctype.h> #include <ctype.h>
#include <float.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) mp_limb_t _cy = __mpn_mul_1 (frac, frac, fracsize, 10);
frac[fracsize++] = _cy; if (_cy != 0)
frac[fracsize++] = _cy;
}
} }
return L'0' + hi; return L'0' + hi;
@@ -304,7 +302,7 @@ __printf_fp (FILE *fp,
multibyte representation for the thousands separator, multibyte representation for the thousands separator,
we must ensure the wide character thousands separator we must ensure the wide character thousands separator
is available, even if it is fake. */ is available, even if it is fake. */
thousands_sepwc = 0xfffffffe; thousands_sepwc = (wchar_t)0xfffffffe;
} }
} }
else else
@@ -19,15 +19,11 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA. */
#include <stdio_private.h>
#include <ctype.h> #include <ctype.h>
#include <ieee754.h> #include <ieee754.h>
#include <math.h> #include <math.h>
#include <printf.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 /* 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 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 License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */ 02111-1307 USA.
*/
#include <stdio_private.h>
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <printf.h> #include <printf.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
/* Array of functions indexed by format character. */ /* Array of functions indexed by format character. */
libc_freeres_ptr (printf_arginfo_function **__printf_arginfo_table) libc_freeres_ptr (printf_arginfo_function **__printf_arginfo_table)
attribute_hidden; attribute_hidden;