mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-05 21:00:05 +00:00
Tue Dec 5 02:27:32 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu>
* libio/Makefile [routines]: Remove iofscanf, add iopopen, pclose. * libio/iofscanf.c: Remove file. * libio/iogetdelim.c (_IO_getdelim): Correct stupid bug at string termination. * libio/iopopen.c: New file from GNU libio. * libio/memstream.c: Fixed bug in fclose handling. Instead of providing a close callback we need a finish callback. * libio/pclose.c: New file. Derived from popen.c in GNU libio. * posix/gnu/types.h: Fixed typo. * stdio-common/errnobug.c: fputs returns EOF in error case. Do not test for != 0. * stdio-common/printf-parse.h (parse_one_spec): Do not force padding with ' ' if precision is given. Fix by HJ Lu. * stdio-common/printf_fp.c: Fix comment. * stdio-common/tfformat.c, stdio-common/tiformat.c, stdio-common/tstdiomisc.c: New files from GNU libio test suite. * stdio-common/tstgetln.c: Provide ssize_t type when testing libio. * stdio-common/vfprintf.c (outchar): Use PUTC instead of putc. (vfprintf): Cleasr args_type array before using it. When printing 0 as an integer with precision 0 nothing must be written for the number. Based on patch by HJ Lu. * stdio-common/vfscanf.c: Remove fixed input buffer. Now we have a dynamically extended buffer. * stdlib/strtod.c: Merge with version in Linux libc. This fixes some bugs with handling of very small numbers and has different solution for formaer patches. * sysdeps/i386/i586/add_n.S, sysdeps/i386/i586/sub_n.S: Rename macros r1 and r2 to t1, and t2 resp. This is necessary because glibc headers also define r1. Tue Dec 5 02:27:32 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu> * libio/Makefile [routines]: Remove iofscanf, add iopopen, pclose. * libio/iofscanf.c: Remove file. * libio/iogetdelim.c (_IO_getdelim): Correct stupid bug at string termination. * libio/iopopen.c: New file from GNU libio. * libio/memstream.c: Fixed bug in fclose handling. Instead of providing a close callback we need a finish callback. * libio/pclose.c: New file. Derived from popen.c in GNU libio. * posix/gnu/types.h: Fixed typo. * stdio-common/errnobug.c: fputs returns EOF in error case. Do not test for != 0. * stdio-common/printf-parse.h (parse_one_spec): Do not force padding with ' ' if precision is given. Fix by HJ Lu. * stdio-common/printf_fp.c: Fix comment. * stdio-common/tfformat.c, stdio-common/tiformat.c, stdio-common/tstdiomisc.c: New files from GNU libio test suite. * stdio-common/tstgetln.c: Provide ssize_t type when testing libio. * stdio-common/vfprintf.c (outchar): Use PUTC instead of putc. (vfprintf): Cleasr args_type array before using it. When printing 0 as an integer with precision 0 nothing must be written for the number. Based on patch by HJ Lu. * stdio-common/vfscanf.c: Remove fixed input buffer. Now we have a dynamically extended buffer. * stdlib/strtod.c: Merge with version in Linux libc. This fixes some bugs with handling of very small numbers and has different solution for formaer patches. * sysdeps/i386/i586/add_n.S, sysdeps/i386/i586/sub_n.S: Rename macros r1 and r2 to t1, and t2 resp. This is necessary because glibc headers also define r1.
This commit is contained in:
parent
b5a08c5aca
commit
77a58cad3f
49
ChangeLog
49
ChangeLog
@ -1,3 +1,52 @@
|
||||
Tue Dec 5 02:27:32 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu>
|
||||
|
||||
* libio/Makefile [routines]: Remove iofscanf, add iopopen, pclose.
|
||||
|
||||
* libio/iofscanf.c: Remove file.
|
||||
|
||||
* libio/iogetdelim.c (_IO_getdelim): Correct stupid bug at string
|
||||
termination.
|
||||
|
||||
* libio/iopopen.c: New file from GNU libio.
|
||||
|
||||
* libio/memstream.c: Fixed bug in fclose handling. Instead of
|
||||
providing a close callback we need a finish callback.
|
||||
|
||||
* libio/pclose.c: New file. Derived from popen.c in GNU libio.
|
||||
|
||||
* posix/gnu/types.h: Fixed typo.
|
||||
|
||||
* stdio-common/errnobug.c: fputs returns EOF in error case. Do
|
||||
not test for != 0.
|
||||
|
||||
* stdio-common/printf-parse.h (parse_one_spec): Do not force
|
||||
padding with ' ' if precision is given. Fix by HJ Lu.
|
||||
|
||||
* stdio-common/printf_fp.c: Fix comment.
|
||||
|
||||
* stdio-common/tfformat.c, stdio-common/tiformat.c,
|
||||
stdio-common/tstdiomisc.c: New files from GNU libio test suite.
|
||||
|
||||
* stdio-common/tstgetln.c: Provide ssize_t type when testing
|
||||
libio.
|
||||
|
||||
* stdio-common/vfprintf.c (outchar): Use PUTC instead of putc.
|
||||
(vfprintf): Cleasr args_type array before using it.
|
||||
When printing 0 as an integer with precision 0 nothing must be
|
||||
written for the number.
|
||||
Based on patch by HJ Lu.
|
||||
|
||||
* stdio-common/vfscanf.c: Remove fixed input buffer. Now we
|
||||
have a dynamically extended buffer.
|
||||
|
||||
* stdlib/strtod.c: Merge with version in Linux libc. This fixes
|
||||
some bugs with handling of very small numbers and has different
|
||||
solution for formaer patches.
|
||||
|
||||
* sysdeps/i386/i586/add_n.S, sysdeps/i386/i586/sub_n.S: Rename
|
||||
macros r1 and r2 to t1, and t2 resp. This is necessary because
|
||||
glibc headers also define r1.
|
||||
|
||||
Mon Dec 4 12:10:28 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
|
||||
|
||||
* stdlib/gen-mpn-copy (translations): Updated for new layout in
|
||||
|
@ -25,14 +25,14 @@ headers := stdio.h libio.h
|
||||
|
||||
routines := \
|
||||
filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen \
|
||||
iofopncook iofprintf iofputs iofread iofscanf iofsetpos ioftell \
|
||||
iofwrite iogetdelim iogetline iogets iopadn ioprims ioputs \
|
||||
iofopncook iofprintf iofputs iofread iofsetpos ioftell \
|
||||
iofwrite iogetdelim iogetline iogets iopadn iopopen ioprims ioputs \
|
||||
ioseekoff ioseekpos iosetbuffer iosetvbuf iosprintf ioungetc \
|
||||
iovsprintf iovsscanf \
|
||||
\
|
||||
clearerr feof ferror fgetc fileno fputc freopen fseek getc getchar \
|
||||
memstream putc putchar rewind setbuf setlinebuf vasprintf vdprintf \
|
||||
vscanf vsnprintf \
|
||||
memstream pclose putc putchar rewind setbuf setlinebuf vasprintf \
|
||||
vdprintf vscanf vsnprintf \
|
||||
\
|
||||
libc_fatal
|
||||
|
||||
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 1993, 1995 Free Software Foundation
|
||||
|
||||
This file is part of the GNU IO Library. This library is free
|
||||
software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this library; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
As a special exception, if you link this library with files
|
||||
compiled with a GNU compiler to produce an executable, this does not cause
|
||||
the resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public License. */
|
||||
|
||||
#include "libioP.h"
|
||||
|
||||
#ifdef __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
_IO_fscanf
|
||||
#ifdef __STDC__
|
||||
(_IO_FILE *fp, const char* format, ...)
|
||||
#else
|
||||
(fp, format, va_alist) _IO_FILE *fp; char *format; va_dcl
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
va_list args;
|
||||
CHECK_FILE (fp, EOF);
|
||||
_IO_va_start (args, format);
|
||||
ret = _IO_vfscanf (fp, format, args, NULL);
|
||||
va_end (args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
weak_alias (_IO_fscanf, fscanf)
|
@ -79,11 +79,11 @@ _IO_getdelim (lineptr, n, delimiter, fp)
|
||||
t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len);
|
||||
if (t != NULL)
|
||||
len = (t - fp->_IO_read_ptr) + 1;
|
||||
/* make enough space for len+1 (for final NUL) bytes. */
|
||||
/* Make enough space for len+1 (for final NUL) bytes. */
|
||||
needed = cur_len + len + 1;
|
||||
if (needed > *n)
|
||||
{
|
||||
if (t == NULL && needed < 2 * *n)
|
||||
if (needed < 2 * *n)
|
||||
needed = 2 * *n; /* Be generous. */
|
||||
*n = needed;
|
||||
*lineptr = (char *) realloc (*lineptr, needed);
|
||||
@ -97,7 +97,7 @@ _IO_getdelim (lineptr, n, delimiter, fp)
|
||||
break;
|
||||
len = fp->_IO_read_end - fp->_IO_read_ptr;
|
||||
}
|
||||
lineptr[cur_len] = '\0';
|
||||
(*lineptr)[cur_len] = '\0';
|
||||
return cur_len;
|
||||
}
|
||||
|
||||
|
@ -30,13 +30,13 @@ struct _IO_FILE_memstream
|
||||
|
||||
|
||||
static int _IO_mem_sync __P ((_IO_FILE* fp));
|
||||
static int _IO_mem_close __P ((_IO_FILE* fp));
|
||||
static void _IO_mem_finish __P ((_IO_FILE* fp));
|
||||
|
||||
|
||||
static const struct _IO_jump_t _IO_mem_jumps =
|
||||
{
|
||||
JUMP_INIT_DUMMY,
|
||||
JUMP_INIT (finish, _IO_str_finish),
|
||||
JUMP_INIT (finish, _IO_mem_finish),
|
||||
JUMP_INIT (overflow, _IO_str_overflow),
|
||||
JUMP_INIT (underflow, _IO_str_underflow),
|
||||
JUMP_INIT (uflow, _IO_default_uflow),
|
||||
@ -51,7 +51,7 @@ static const struct _IO_jump_t _IO_mem_jumps =
|
||||
JUMP_INIT (read, _IO_default_read),
|
||||
JUMP_INIT (write, _IO_default_write),
|
||||
JUMP_INIT (seek, _IO_default_seek),
|
||||
JUMP_INIT (close, _IO_mem_close),
|
||||
JUMP_INIT (close, _IO_default_close),
|
||||
JUMP_INIT (stat, _IO_default_stat)
|
||||
};
|
||||
|
||||
@ -79,6 +79,9 @@ open_memstream (bufloc, sizeloc)
|
||||
fp->_sf._s._allocate_buffer = (_IO_alloc_type) malloc;
|
||||
fp->_sf._s._free_buffer = (_IO_free_type) free;
|
||||
|
||||
fp->bufloc = bufloc;
|
||||
fp->sizeloc = sizeloc;
|
||||
|
||||
return &fp->_sf._f;
|
||||
}
|
||||
|
||||
@ -102,28 +105,28 @@ _IO_mem_sync (fp)
|
||||
else
|
||||
*fp->_IO_write_ptr = '\0';
|
||||
|
||||
*mp->bufloc = fp->_IO_buf_base;
|
||||
*mp->sizeloc = _IO_blen (fp);
|
||||
*mp->bufloc = fp->_IO_write_base;
|
||||
*mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _IO_mem_close (fp)
|
||||
static void
|
||||
_IO_mem_finish (fp)
|
||||
_IO_FILE* fp;
|
||||
{
|
||||
struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
|
||||
int res;
|
||||
|
||||
res = _IO_default_close (fp);
|
||||
if (res < 0)
|
||||
return res;
|
||||
*mp->bufloc = (char *) realloc (fp->_IO_write_base,
|
||||
fp->_IO_write_ptr - fp->_IO_write_base + 1);
|
||||
if (*mp->bufloc != NULL)
|
||||
{
|
||||
(*mp->bufloc)[fp->_IO_write_ptr - fp->_IO_write_base] = '\0';
|
||||
*mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base;
|
||||
}
|
||||
|
||||
*mp->bufloc = (char *) realloc (fp->_IO_buf_base, _IO_blen (fp) + 1);
|
||||
if (*mp->bufloc == NULL)
|
||||
return -1;
|
||||
(*mp->bufloc)[_IO_blen (fp)] = '\0';
|
||||
*mp->sizeloc = _IO_blen (fp);
|
||||
fp->_IO_buf_base = NULL;
|
||||
|
||||
return 0;
|
||||
_IO_default_finish (fp);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -13,7 +13,7 @@ Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave,
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _GNU_TYPES_H
|
||||
|
@ -39,7 +39,8 @@ distribute := _itoa.h printf-parse.h
|
||||
tests := tst-printf tstscanf test_rdwr test-popen tstgetln test-fseek \
|
||||
temptest tst-fileno test-fwrite \
|
||||
xbug errnobug \
|
||||
bug1 bug2 bug3 bug4 bug5 bug6 bug7
|
||||
bug1 bug2 bug3 bug4 bug5 bug6 bug7 \
|
||||
tfformat tiformat tstdiomisc
|
||||
|
||||
|
||||
include ../Rules
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Regression test for reported old bug that errno is clobbered
|
||||
by the first successful output to a stream on an unseekable object.
|
||||
by the first successful output to a stream on an unseekable object.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
@ -43,7 +43,7 @@ main (void)
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if (fputs ("fnord", f))
|
||||
if (fputs ("fnord", f) == EOF)
|
||||
{
|
||||
perror ("fputs");
|
||||
return 1;
|
||||
|
@ -32,7 +32,7 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
struct printf_spec
|
||||
{
|
||||
/* Information parsed from the format spec. */
|
||||
/* Information parsed from the format spec. */
|
||||
struct printf_info info;
|
||||
|
||||
/* Pointers into the format string for the end of this format
|
||||
@ -260,10 +260,6 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
|
||||
else
|
||||
/* "%.?" is treated like "%.0?". */
|
||||
spec->info.prec = 0;
|
||||
|
||||
/* If there was a precision specified, ignore the 0 flag and always
|
||||
pad with spaces. */
|
||||
spec->info.pad = ' ';
|
||||
}
|
||||
|
||||
/* Check for type modifiers. */
|
||||
@ -364,7 +360,7 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
|
||||
break;
|
||||
}
|
||||
|
||||
if (spec->data_arg == -1 && spec->ndata_args > 0)
|
||||
if (spec->data_arg == -1 && spec->ndata_args > 0)
|
||||
{
|
||||
/* There are args consumed, but no positional spec.
|
||||
Use the next sequential arg position. */
|
||||
|
@ -345,7 +345,7 @@ __printf_fp (fp, info, args)
|
||||
scalesize = 0;
|
||||
if (exponent > 2)
|
||||
{
|
||||
/* |FP| >= 1.0. */
|
||||
/* |FP| >= 8.0. */
|
||||
int scaleexpo = 0;
|
||||
int explog = LDBL_MAX_10_EXP_LOG;
|
||||
int exp10 = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1992, 1995 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -19,6 +19,10 @@ Cambridge, MA 02139, USA. */
|
||||
#include <ansidecl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef USE_IN_LIBIO
|
||||
# define ssize_t _IO_ssize_t
|
||||
#endif
|
||||
|
||||
int
|
||||
DEFUN_VOID(main)
|
||||
{
|
||||
|
@ -96,7 +96,7 @@ ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
|
||||
do \
|
||||
{ \
|
||||
register const int outc = (x); \
|
||||
if (putc (outc, s) == EOF) \
|
||||
if (PUTC (outc, s) == EOF) \
|
||||
return -1; \
|
||||
else \
|
||||
++done; \
|
||||
@ -230,11 +230,12 @@ vfprintf (s, format, ap)
|
||||
|
||||
/* Allocate memory for the argument descriptions. */
|
||||
args_type = alloca (nargs * sizeof (int));
|
||||
memset (args_type, 0, nargs * sizeof (int));
|
||||
args_value = alloca (nargs * sizeof (union printf_arg));
|
||||
|
||||
/* XXX Could do sanity check here:
|
||||
Initialize args_type elts to zero.
|
||||
If any is still zero after this loop, format is invalid. */
|
||||
/* XXX Could do sanity check here: If any element in ARGS_TYPE is
|
||||
still zero after this loop, format is invalid. For now we simply
|
||||
use 0 as the value. */
|
||||
|
||||
/* Fill in the types of all the arguments. */
|
||||
for (cnt = 0; cnt < nspecs; ++cnt)
|
||||
@ -287,6 +288,8 @@ vfprintf (s, format, ap)
|
||||
default:
|
||||
if ((args_type[cnt] & PA_FLAG_PTR) != 0)
|
||||
args_value[cnt].pa_pointer = va_arg (ap, void *);
|
||||
else
|
||||
args_value[cnt].pa_long_double = 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -420,15 +423,27 @@ vfprintf (s, format, ap)
|
||||
char *const workend = &work[sizeof(work) - 1];
|
||||
register char *w;
|
||||
|
||||
/* Supply a default precision if none was given. */
|
||||
if (specs[cnt].info.prec == -1)
|
||||
specs[cnt].info.prec = 1;
|
||||
/* Supply a default precision if none was given. */
|
||||
specs[cnt].info.prec = 1;
|
||||
else
|
||||
/* We have to take care for the '0' flag. If a
|
||||
precision is given it must be ignored. */
|
||||
specs[cnt].info.pad = ' ';
|
||||
|
||||
/* Put the number in WORK. */
|
||||
w = _itoa (num, workend + 1, base, specs[cnt].info.spec == 'X');
|
||||
w -= 1;
|
||||
if (specs[cnt].info.group && grouping)
|
||||
w = group_number (w, workend, grouping, thousands_sep);
|
||||
/* If the precision is 0 and the number is 0 nothing has
|
||||
to be written for the number. */
|
||||
if (specs[cnt].info.prec == 0 && num == 0)
|
||||
w = workend;
|
||||
else
|
||||
{
|
||||
/* Put the number in WORK. */
|
||||
w = _itoa (num, workend + 1, base,
|
||||
specs[cnt].info.spec == 'X');
|
||||
w -= 1;
|
||||
if (specs[cnt].info.group && grouping)
|
||||
w = group_number (w, workend, grouping, thousands_sep);
|
||||
}
|
||||
specs[cnt].info.width -= workend - w;
|
||||
specs[cnt].info.prec -= workend - w;
|
||||
|
||||
@ -618,8 +633,18 @@ vfprintf (s, format, ap)
|
||||
}
|
||||
|
||||
#ifdef USE_IN_LIBIO
|
||||
#undef vfprintf
|
||||
# undef vfprintf
|
||||
# ifdef strong_alias
|
||||
/* This is for glibc. */
|
||||
strong_alias (_IO_vfprintf, vfprintf)
|
||||
# else
|
||||
# if defined __ELF__ || defined __GNU_LIBRARY__
|
||||
# include <gnu-stabs.h>
|
||||
# ifdef weak_alias
|
||||
weak_alias (_IO_vfprintf, vfprintf);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -132,6 +132,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
|
||||
int base;
|
||||
/* Signedness for integral numbers. */
|
||||
int number_signed;
|
||||
/* Decimal point character. */
|
||||
wchar_t decimal;
|
||||
/* Integral holding variables. */
|
||||
union
|
||||
{
|
||||
@ -144,9 +146,24 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
|
||||
register char *str, **strptr;
|
||||
size_t strsize;
|
||||
/* Workspace. */
|
||||
char work[200];
|
||||
char *w; /* Pointer into WORK. */
|
||||
wchar_t decimal; /* Decimal point character. */
|
||||
char *tw; /* Temporary pointer. */
|
||||
char *wp = NULL; /* Workspace. */
|
||||
size_t wpsize = 0; /* Currently used bytes in workspace. */
|
||||
size_t wpmax = 0; /* Maximal size of workspace. */
|
||||
#define ADDW(Ch) \
|
||||
do \
|
||||
{ \
|
||||
if (wpsize == wpmax) \
|
||||
{ \
|
||||
char *old = wp; \
|
||||
wpmax = 200 > 2 * wpmax ? 200 : 2 * wpmax; \
|
||||
wp = (char *) alloca (wpmax); \
|
||||
if (wpsize > 0) \
|
||||
memcpy (wp, old, wpsize); \
|
||||
} \
|
||||
wp[wpsize++] = (Ch); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
ARGCHECK (s, format);
|
||||
|
||||
@ -338,7 +355,6 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
|
||||
conv_error ();
|
||||
|
||||
/* Find the conversion specifier. */
|
||||
w = work;
|
||||
fc = *f++;
|
||||
if (fc != '[' && fc != 'c' && fc != 'n')
|
||||
/* Eat whitespace. */
|
||||
@ -490,7 +506,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
|
||||
/* Check for a sign. */
|
||||
if (c == '-' || c == '+')
|
||||
{
|
||||
*w++ = c;
|
||||
ADDW (c);
|
||||
if (width > 0)
|
||||
--width;
|
||||
(void) inchar ();
|
||||
@ -501,7 +517,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
|
||||
{
|
||||
if (width > 0)
|
||||
--width;
|
||||
*w++ = '0';
|
||||
ADDW ('0');
|
||||
|
||||
(void) inchar ();
|
||||
|
||||
@ -523,40 +539,40 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
|
||||
if (base == 0)
|
||||
base = 10;
|
||||
|
||||
/* Read the number into WORK. */
|
||||
/* Read the number into workspace. */
|
||||
do
|
||||
{
|
||||
if (base == 16 ? !isxdigit (c) :
|
||||
(!isdigit (c) || c - '0' >= base))
|
||||
break;
|
||||
*w++ = c;
|
||||
ADDW (c);
|
||||
if (width > 0)
|
||||
--width;
|
||||
}
|
||||
while (inchar () != EOF && width != 0);
|
||||
|
||||
if (w == work ||
|
||||
(w - work == 1 && (work[0] == '+' || work[0] == '-')))
|
||||
if (wpsize == 0 ||
|
||||
(wpsize == 1 && (wp[0] == '+' || wp[0] == '-')))
|
||||
/* There was no number. */
|
||||
conv_error ();
|
||||
|
||||
/* Convert the number. */
|
||||
*w = '\0';
|
||||
ADDW ('\0');
|
||||
if (is_longlong)
|
||||
{
|
||||
if (number_signed)
|
||||
num.q = __strtoq_internal (work, &w, base, group_flag);
|
||||
num.q = __strtoq_internal (wp, &tw, base, group_flag);
|
||||
else
|
||||
num.uq = __strtouq_internal (work, &w, base, group_flag);
|
||||
num.uq = __strtouq_internal (wp, &tw, base, group_flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (number_signed)
|
||||
num.l = __strtol_internal (work, &w, base, group_flag);
|
||||
num.l = __strtol_internal (wp, &tw, base, group_flag);
|
||||
else
|
||||
num.ul = __strtoul_internal (work, &w, base, group_flag);
|
||||
num.ul = __strtoul_internal (wp, &tw, base, group_flag);
|
||||
}
|
||||
if (w == work)
|
||||
if (wp == tw)
|
||||
conv_error ();
|
||||
|
||||
if (do_assign)
|
||||
@ -599,7 +615,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
|
||||
/* Check for a sign. */
|
||||
if (c == '-' || c == '+')
|
||||
{
|
||||
*w++ = c;
|
||||
ADDW (c);
|
||||
if (inchar () == EOF)
|
||||
/* EOF is only an input error before we read any chars. */
|
||||
conv_error ();
|
||||
@ -611,17 +627,18 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
|
||||
do
|
||||
{
|
||||
if (isdigit (c))
|
||||
*w++ = c;
|
||||
else if (got_e && w[-1] == 'e' && (c == '-' || c == '+'))
|
||||
*w++ = c;
|
||||
ADDW (c);
|
||||
else if (got_e && wp[wpsize - 1] == 'e'
|
||||
&& (c == '-' || c == '+'))
|
||||
ADDW (c);
|
||||
else if (!got_e && tolower (c) == 'e')
|
||||
{
|
||||
*w++ = 'e';
|
||||
ADDW ('e');
|
||||
got_e = got_dot = 1;
|
||||
}
|
||||
else if (c == decimal && !got_dot)
|
||||
{
|
||||
*w++ = c;
|
||||
ADDW (c);
|
||||
got_dot = 1;
|
||||
}
|
||||
else
|
||||
@ -630,33 +647,34 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
|
||||
--width;
|
||||
} while (inchar () != EOF && width != 0);
|
||||
|
||||
if (w == work)
|
||||
if (wpsize == 0)
|
||||
conv_error();
|
||||
if (w[-1] == '-' || w[-1] == '+' || w[-1] == 'e')
|
||||
if (wp[wpsize - 1] == '-' || wp[wpsize - 1] == '+'
|
||||
|| wp[wpsize - 1] == 'e')
|
||||
conv_error ();
|
||||
|
||||
/* Convert the number. */
|
||||
*w = '\0';
|
||||
ADDW ('\0');
|
||||
if (is_long_double)
|
||||
{
|
||||
long double d = __strtold_internal (work, &w, group_flag);
|
||||
if (do_assign && w != work)
|
||||
long double d = __strtold_internal (wp, &tw, group_flag);
|
||||
if (do_assign && tw != wp)
|
||||
*ARG (long double *) = d;
|
||||
}
|
||||
else if (is_long)
|
||||
{
|
||||
double d = __strtod_internal (work, &w, group_flag);
|
||||
if (do_assign && w != work)
|
||||
double d = __strtod_internal (wp, &tw, group_flag);
|
||||
if (do_assign && tw != wp)
|
||||
*ARG (double *) = d;
|
||||
}
|
||||
else
|
||||
{
|
||||
float d = __strtof_internal (work, &w, group_flag);
|
||||
if (do_assign && w != work)
|
||||
float d = __strtof_internal (wp, &tw, group_flag);
|
||||
if (do_assign && tw != wp)
|
||||
*ARG (float *) = d;
|
||||
}
|
||||
|
||||
if (w == work)
|
||||
if (tw == wp)
|
||||
conv_error ();
|
||||
|
||||
if (do_assign)
|
||||
@ -680,23 +698,23 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
|
||||
while ((fc = *f++) != '\0' && fc != ']')
|
||||
{
|
||||
if (fc == '-' && *f != '\0' && *f != ']' &&
|
||||
w > work && w[-1] <= *f)
|
||||
wpsize > 0 && wp[wpsize - 1] <= *f)
|
||||
/* Add all characters from the one before the '-'
|
||||
up to (but not including) the next format char. */
|
||||
for (fc = w[-1] + 1; fc < *f; ++fc)
|
||||
*w++ = fc;
|
||||
for (fc = wp[wpsize - 1] + 1; fc < *f; ++fc)
|
||||
ADDW (fc);
|
||||
else
|
||||
/* Add the character to the list. */
|
||||
*w++ = fc;
|
||||
ADDW (fc);
|
||||
}
|
||||
if (fc == '\0')
|
||||
conv_error();
|
||||
|
||||
*w = '\0';
|
||||
ADDW ('\0');
|
||||
num.ul = read_in;
|
||||
do
|
||||
{
|
||||
if ((strchr (work, c) == NULL) != not_in)
|
||||
if ((strchr (wp, c) == NULL) != not_in)
|
||||
break;
|
||||
STRING_ADD_CHAR (c);
|
||||
if (width > 0)
|
||||
|
@ -359,7 +359,10 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
}
|
||||
}
|
||||
else
|
||||
grouping = NULL;
|
||||
{
|
||||
grouping = NULL;
|
||||
thousands = L'\0';
|
||||
}
|
||||
|
||||
/* Find the locale's decimal point character. */
|
||||
if (mbtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
|
||||
@ -373,7 +376,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
bits = 0;
|
||||
|
||||
/* Parse string to get maximal legal prefix. We need the number of
|
||||
characters of the interger part, the fractional part and the exponent. */
|
||||
characters of the integer part, the fractional part and the exponent. */
|
||||
cp = nptr - 1;
|
||||
/* Ignore leading white space. */
|
||||
do
|
||||
@ -470,7 +473,8 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
int_no = dig_no;
|
||||
lead_zero = int_no == 0 ? -1 : 0;
|
||||
|
||||
/* Read the fractional digits. */
|
||||
/* Read the fractional digits. A special case are the 'american style'
|
||||
numbers like `16.' i.e. with decimal but without trailing digits. */
|
||||
if (c == decimal)
|
||||
{
|
||||
if (isdigit (cp[1]))
|
||||
@ -506,11 +510,18 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
|
||||
if (isdigit (c))
|
||||
{
|
||||
int exp_limit;
|
||||
|
||||
/* Get the exponent limit. */
|
||||
exp_limit = exp_negative ?
|
||||
-MIN_10_EXP + MANT_DIG - int_no :
|
||||
MAX_10_EXP - int_no + lead_zero;
|
||||
|
||||
do
|
||||
{
|
||||
if ((!exp_negative && exponent * 10 + int_no > MAX_10_EXP)
|
||||
|| (exp_negative
|
||||
&& exponent * 10 + int_no > -MIN_10_EXP + MANT_DIG))
|
||||
exponent *= 10;
|
||||
|
||||
if (exponent > exp_limit)
|
||||
/* The exponent is too large/small to represent a valid
|
||||
number. */
|
||||
{
|
||||
@ -530,7 +541,6 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
exponent *= 10;
|
||||
exponent += c - '0';
|
||||
c = *++cp;
|
||||
}
|
||||
@ -563,6 +573,15 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
if (dig_no == 0)
|
||||
return 0.0;
|
||||
|
||||
if (lead_zero)
|
||||
{
|
||||
/* Find the decimal point */
|
||||
while (*startp != decimal) startp++;
|
||||
startp += lead_zero + 1;
|
||||
exponent -= lead_zero;
|
||||
dig_no -= lead_zero;
|
||||
}
|
||||
|
||||
/* Now we have the number of digits in total and the integer digits as well
|
||||
as the exponent and its sign. We can decide whether the read digits are
|
||||
really integer digits or belong to the fractional part; i.e. we normalize
|
||||
@ -580,7 +599,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
|
||||
}
|
||||
|
||||
if (exponent - MAX(0, lead_zero) < MIN_10_EXP - (DIG + 1))
|
||||
if (exponent < MIN_10_EXP - (DIG + 1))
|
||||
{
|
||||
errno = ERANGE;
|
||||
return 0.0;
|
||||
@ -728,7 +747,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
/* We construct a fraction and the result of the division gives us
|
||||
the needed digits. The denominator is 1.0 multiplied by the
|
||||
exponent of the lowest digit; i.e. 0.123 gives 123 / 1000 and
|
||||
123e6 gives 123 / 1000000. */
|
||||
123e-6 gives 123 / 1000000. */
|
||||
|
||||
int expbit;
|
||||
int cnt;
|
||||
@ -748,9 +767,9 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
digits we should have enough bits for the result. The remaining
|
||||
decimal digits give us the information that more bits are following.
|
||||
This can be used while rounding. (One added as a safety margin.) */
|
||||
if (dig_no - int_no - lead_zero > (MANT_DIG - bits + 2) / 3 + 1)
|
||||
if (dig_no - int_no > (MANT_DIG - bits + 2) / 3 + 1)
|
||||
{
|
||||
dig_no = int_no + lead_zero + (MANT_DIG - bits + 2) / 3 + 1;
|
||||
dig_no = int_no + (MANT_DIG - bits + 2) / 3 + 1;
|
||||
more_bits = 1;
|
||||
}
|
||||
else
|
||||
@ -789,14 +808,6 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
if (psrc == num)
|
||||
memcpy (den, num, densize * sizeof (mp_limb));
|
||||
|
||||
/* If we have leading zeroes now reduce the number of significant digits
|
||||
and set the pointer to the first non-0 digit. */
|
||||
if (lead_zero > 0)
|
||||
{
|
||||
startp += lead_zero + 1; /* +1 for radix character */
|
||||
dig_no -= lead_zero;
|
||||
}
|
||||
|
||||
/* Read the fractional digits from the string. */
|
||||
(void) str_to_mpn (startp, dig_no - int_no, num, &numsize, &exponent);
|
||||
|
||||
@ -898,23 +909,34 @@ INTERNAL (STRTOF) (nptr, endptr, group)
|
||||
|
||||
if (numsize < densize)
|
||||
{
|
||||
if (bits <= 0)
|
||||
exponent -= BITS_PER_MP_LIMB;
|
||||
if (num[0] >= d1)
|
||||
{
|
||||
/* The nominator of the number occupies fewer bits than
|
||||
the denominator but the one limb is bigger than the
|
||||
high limb of the nominator. */
|
||||
n1 = 0;
|
||||
n0 = num[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bits + BITS_PER_MP_LIMB <= MANT_DIG)
|
||||
__mpn_lshift_1 (retval, RETURN_LIMB_SIZE,
|
||||
BITS_PER_MP_LIMB, 0);
|
||||
if (bits <= 0)
|
||||
exponent -= BITS_PER_MP_LIMB;
|
||||
else
|
||||
{
|
||||
used = MANT_DIG - bits;
|
||||
if (used > 0)
|
||||
__mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, 0);
|
||||
if (bits + BITS_PER_MP_LIMB <= MANT_DIG)
|
||||
__mpn_lshift_1 (retval, RETURN_LIMB_SIZE,
|
||||
BITS_PER_MP_LIMB, 0);
|
||||
else
|
||||
{
|
||||
used = MANT_DIG - bits;
|
||||
if (used > 0)
|
||||
__mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, 0);
|
||||
}
|
||||
bits += BITS_PER_MP_LIMB;
|
||||
}
|
||||
bits += BITS_PER_MP_LIMB;
|
||||
n1 = num[0];
|
||||
n0 = 0;
|
||||
}
|
||||
n1 = num[0];
|
||||
n0 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -27,16 +27,16 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
size (sp + 16)
|
||||
*/
|
||||
|
||||
#define r1 %eax
|
||||
#define r2 %edx
|
||||
#include "sysdep.h"
|
||||
#include "asm-syntax.h"
|
||||
|
||||
#define t1 %eax
|
||||
#define t2 %edx
|
||||
#define src1 %esi
|
||||
#define src2 %ebp
|
||||
#define dst %edi
|
||||
#define x %ebx
|
||||
|
||||
#include "sysdep.h"
|
||||
#include "asm-syntax.h"
|
||||
|
||||
.text
|
||||
ALIGN (3)
|
||||
.globl C_SYMBOL_NAME(__mpn_add_n)
|
||||
@ -54,77 +54,77 @@ C_SYMBOL_NAME(__mpn_add_n:)
|
||||
movl (src2),x
|
||||
|
||||
decl %ecx
|
||||
movl %ecx,r2
|
||||
movl %ecx,t2
|
||||
shrl $3,%ecx
|
||||
andl $7,r2
|
||||
andl $7,t2
|
||||
testl %ecx,%ecx /* zero carry flag */
|
||||
jz Lend
|
||||
pushl r2
|
||||
pushl t2
|
||||
|
||||
ALIGN (3)
|
||||
Loop: movl 28(dst),%eax /* fetch destination cache line */
|
||||
leal 32(dst),dst
|
||||
|
||||
L1: movl (src1),r1
|
||||
movl 4(src1),r2
|
||||
adcl x,r1
|
||||
L1: movl (src1),t1
|
||||
movl 4(src1),t2
|
||||
adcl x,t1
|
||||
movl 4(src2),x
|
||||
adcl x,r2
|
||||
adcl x,t2
|
||||
movl 8(src2),x
|
||||
movl r1,-32(dst)
|
||||
movl r2,-28(dst)
|
||||
movl t1,-32(dst)
|
||||
movl t2,-28(dst)
|
||||
|
||||
L2: movl 8(src1),r1
|
||||
movl 12(src1),r2
|
||||
adcl x,r1
|
||||
L2: movl 8(src1),t1
|
||||
movl 12(src1),t2
|
||||
adcl x,t1
|
||||
movl 12(src2),x
|
||||
adcl x,r2
|
||||
adcl x,t2
|
||||
movl 16(src2),x
|
||||
movl r1,-24(dst)
|
||||
movl r2,-20(dst)
|
||||
movl t1,-24(dst)
|
||||
movl t2,-20(dst)
|
||||
|
||||
L3: movl 16(src1),r1
|
||||
movl 20(src1),r2
|
||||
adcl x,r1
|
||||
L3: movl 16(src1),t1
|
||||
movl 20(src1),t2
|
||||
adcl x,t1
|
||||
movl 20(src2),x
|
||||
adcl x,r2
|
||||
adcl x,t2
|
||||
movl 24(src2),x
|
||||
movl r1,-16(dst)
|
||||
movl r2,-12(dst)
|
||||
movl t1,-16(dst)
|
||||
movl t2,-12(dst)
|
||||
|
||||
L4: movl 24(src1),r1
|
||||
movl 28(src1),r2
|
||||
adcl x,r1
|
||||
L4: movl 24(src1),t1
|
||||
movl 28(src1),t2
|
||||
adcl x,t1
|
||||
movl 28(src2),x
|
||||
adcl x,r2
|
||||
adcl x,t2
|
||||
movl 32(src2),x
|
||||
movl r1,-8(dst)
|
||||
movl r2,-4(dst)
|
||||
movl t1,-8(dst)
|
||||
movl t2,-4(dst)
|
||||
|
||||
leal 32(src1),src1
|
||||
leal 32(src2),src2
|
||||
decl %ecx
|
||||
jnz Loop
|
||||
|
||||
popl r2
|
||||
popl t2
|
||||
Lend:
|
||||
decl r2 /* test r2 w/o clobbering carry */
|
||||
decl t2 /* test t2 w/o clobbering carry */
|
||||
js Lend2
|
||||
incl r2
|
||||
incl t2
|
||||
Loop2:
|
||||
leal 4(dst),dst
|
||||
movl (src1),r1
|
||||
adcl x,r1
|
||||
movl (src1),t1
|
||||
adcl x,t1
|
||||
movl 4(src2),x
|
||||
movl r1,-4(dst)
|
||||
movl t1,-4(dst)
|
||||
leal 4(src1),src1
|
||||
leal 4(src2),src2
|
||||
decl r2
|
||||
decl t2
|
||||
jnz Loop2
|
||||
Lend2:
|
||||
movl (src1),r1
|
||||
adcl x,r1
|
||||
movl r1,(dst)
|
||||
movl (src1),t1
|
||||
adcl x,t1
|
||||
movl t1,(dst)
|
||||
|
||||
sbbl %eax,%eax
|
||||
negl %eax
|
||||
|
@ -27,16 +27,16 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
size (sp + 16)
|
||||
*/
|
||||
|
||||
#define r1 %eax
|
||||
#define r2 %edx
|
||||
#include "sysdep.h"
|
||||
#include "asm-syntax.h"
|
||||
|
||||
#define t1 %eax
|
||||
#define t2 %edx
|
||||
#define src1 %esi
|
||||
#define src2 %ebp
|
||||
#define dst %edi
|
||||
#define x %ebx
|
||||
|
||||
#include "sysdep.h"
|
||||
#include "asm-syntax.h"
|
||||
|
||||
.text
|
||||
ALIGN (3)
|
||||
.globl C_SYMBOL_NAME(__mpn_sub_n)
|
||||
@ -54,77 +54,77 @@ C_SYMBOL_NAME(__mpn_sub_n:)
|
||||
movl (src2),x
|
||||
|
||||
decl %ecx
|
||||
movl %ecx,r2
|
||||
movl %ecx,t2
|
||||
shrl $3,%ecx
|
||||
andl $7,r2
|
||||
andl $7,t2
|
||||
testl %ecx,%ecx /* zero carry flag */
|
||||
jz Lend
|
||||
pushl r2
|
||||
pushl t2
|
||||
|
||||
ALIGN (3)
|
||||
Loop: movl 28(dst),%eax /* fetch destination cache line */
|
||||
leal 32(dst),dst
|
||||
|
||||
L1: movl (src1),r1
|
||||
movl 4(src1),r2
|
||||
sbbl x,r1
|
||||
L1: movl (src1),t1
|
||||
movl 4(src1),t2
|
||||
sbbl x,t1
|
||||
movl 4(src2),x
|
||||
sbbl x,r2
|
||||
sbbl x,t2
|
||||
movl 8(src2),x
|
||||
movl r1,-32(dst)
|
||||
movl r2,-28(dst)
|
||||
movl t1,-32(dst)
|
||||
movl t2,-28(dst)
|
||||
|
||||
L2: movl 8(src1),r1
|
||||
movl 12(src1),r2
|
||||
sbbl x,r1
|
||||
L2: movl 8(src1),t1
|
||||
movl 12(src1),t2
|
||||
sbbl x,t1
|
||||
movl 12(src2),x
|
||||
sbbl x,r2
|
||||
sbbl x,t2
|
||||
movl 16(src2),x
|
||||
movl r1,-24(dst)
|
||||
movl r2,-20(dst)
|
||||
movl t1,-24(dst)
|
||||
movl t2,-20(dst)
|
||||
|
||||
L3: movl 16(src1),r1
|
||||
movl 20(src1),r2
|
||||
sbbl x,r1
|
||||
L3: movl 16(src1),t1
|
||||
movl 20(src1),t2
|
||||
sbbl x,t1
|
||||
movl 20(src2),x
|
||||
sbbl x,r2
|
||||
sbbl x,t2
|
||||
movl 24(src2),x
|
||||
movl r1,-16(dst)
|
||||
movl r2,-12(dst)
|
||||
movl t1,-16(dst)
|
||||
movl t2,-12(dst)
|
||||
|
||||
L4: movl 24(src1),r1
|
||||
movl 28(src1),r2
|
||||
sbbl x,r1
|
||||
L4: movl 24(src1),t1
|
||||
movl 28(src1),t2
|
||||
sbbl x,t1
|
||||
movl 28(src2),x
|
||||
sbbl x,r2
|
||||
sbbl x,t2
|
||||
movl 32(src2),x
|
||||
movl r1,-8(dst)
|
||||
movl r2,-4(dst)
|
||||
movl t1,-8(dst)
|
||||
movl t2,-4(dst)
|
||||
|
||||
leal 32(src1),src1
|
||||
leal 32(src2),src2
|
||||
decl %ecx
|
||||
jnz Loop
|
||||
|
||||
popl r2
|
||||
popl t2
|
||||
Lend:
|
||||
decl r2 /* test r2 w/o clobbering carry */
|
||||
decl t2 /* test t2 w/o clobbering carry */
|
||||
js Lend2
|
||||
incl r2
|
||||
incl t2
|
||||
Loop2:
|
||||
leal 4(dst),dst
|
||||
movl (src1),r1
|
||||
sbbl x,r1
|
||||
movl (src1),t1
|
||||
sbbl x,t1
|
||||
movl 4(src2),x
|
||||
movl r1,-4(dst)
|
||||
movl t1,-4(dst)
|
||||
leal 4(src1),src1
|
||||
leal 4(src2),src2
|
||||
decl r2
|
||||
decl t2
|
||||
jnz Loop2
|
||||
Lend2:
|
||||
movl (src1),r1
|
||||
sbbl x,r1
|
||||
movl r1,(dst)
|
||||
movl (src1),t1
|
||||
sbbl x,t1
|
||||
movl t1,(dst)
|
||||
|
||||
sbbl %eax,%eax
|
||||
negl %eax
|
||||
|
Loading…
Reference in New Issue
Block a user