1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-12-24 17:51:17 +03:00

initial import

This commit is contained in:
Roland McGrath
1995-02-18 01:27:10 +00:00
commit 28f540f45b
2263 changed files with 218361 additions and 0 deletions

4
stdio/.cvsignore Normal file
View File

@@ -0,0 +1,4 @@
*.gz *.Z *.tar *.tgz
=*
TODO COPYING* AUTHORS copyr-* copying.*
glibc-*

114
stdio/Makefile Normal file
View File

@@ -0,0 +1,114 @@
# Copyright (C) 1991, 1992, 1993, 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
# modify it under the terms of the GNU Library General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
# The GNU C 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
# 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 Free Software Foundation, Inc., 675 Mass Ave,
# Cambridge, MA 02139, USA.
#
# Specific makefile for stdio.
#
subdir := stdio
headers := stdio.h stdio_lim.h printf.h
routines := \
ctermid cuserid \
feof ferror clearerr fileno \
newstream fopen freopen fdopen fopncook fmemopen \
setbuf setvbuf setbuffer setlinebuf \
fseek ftell rewind fgetpos fsetpos \
vfprintf vprintf printf_fp reg-printf printf-prs _itoa \
vsnprintf vsprintf vasprintf \
fprintf printf snprintf sprintf asprintf \
dprintf vdprintf \
vfscanf vscanf vsscanf \
fscanf scanf sscanf \
fread fwrite \
ungetc \
fgetc getc getchar getw \
fputc putc putchar putw \
fgets gets fputs puts \
getdelim getline \
perror psignal \
tmpfile tmpnam tempnam tempname \
fclose fflush \
remove rename \
memstream obstream \
internals sysd-stdio pipestream stdio_init libc_fatal
# Several mpn functions from GNU MP are used by the printf_fp function.
mpn-routines := add_1 add_n addmul_1 cmp divmod divmod_1 udiv_qrnnd \
lshift rshift mod_1 mul mul_1 mul_n sub_n submul_1
mpn-headers = longlong.h gmp.h gmp-impl.h gmp-mparam.h asm-syntax.h
routines := $(strip $(routines) $(mpn-routines)) \
dbl2mpn ldbl2mpn \
mpn2flt mpn2dbl mpn2ldbl
aux := errlist siglist defs glue mp_clz_tab fpioconst
distribute = $(mpn-headers) gen-mpn-copy _itoa.h fpioconst.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
include ../Rules
ifdef gmp-srcdir
gmp-srcdir := $(firstword $(filter-out ..//%,$(..)$(gmp-srcdir) $(gmp-srcdir)))
# Copy the mpn source files we use from the GNU MP source directory.
# `gmp-srcdir' is set by doing `configure --with-gmp=DIR'.
# (Do not try this at home. You need an as yet unreleased version of GNU MP.)
mpn-sysdep := $(addsuffix .c,$(mpn-routines)) \
$(addsuffix .S,$(mpn-routines)) \
$(addsuffix .s,$(mpn-routines)) gmp-mparam.h asm-syntax.h
mpn-try := $(addprefix $(gmp-srcdir)/mpn/*/,$(mpn-sysdep))
mpn-found := $(wildcard $(mpn-try))
mpn-found := $(filter-out $(patsubst %.S,%.s,$(filter %.s,$(mpn-found))),\
$(mpn-found))
include mpn-copy.mk
%.mk: gen-%; sh $< > $@
mpn-copy-1 := $(patsubst $(gmp-srcdir)/mpn/%,$(sysdep_dir)/%,$(mpn-found))
mpn-copy-sysdep := $(mpn-copy-sysdep) $(mpn-copy-1)
$(mpn-copy-1): $(sysdep_dir)/%: $(ignore gmp2glibc.sed) $(gmp-srcdir)/mpn/%
$(gmp2glibc)
mpn-stuff = $(mpn-copy-sysdep) $(mpn-copy)
# chmod so I don't edit them by mistake.
define gmp2glibc
$(ignore sed -f $^ > $@-tmp)
cp $< $@-tmp
chmod a-w $@-tmp
mv -f $@-tmp $@
endef
mpn-copy = $(filter-out $(mpn-sysdep),$(mpn-headers) mp_clz_tab.c)
$(mpn-copy): %: $(ignore gmp2glibc.sed) $(gmp-srcdir)/%; $(gmp2glibc)
.PHONY: copy-mpn clean-mpn
copy-mpn: $(mpn-stuff)
clean-mpn:
rm -f $(mpn-stuff)
endif

45
stdio/_itoa.c Normal file
View File

@@ -0,0 +1,45 @@
/* Internal function for converting integers to ASCII.
Copyright (C) 1994 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include "_itoa.h"
/* Lower-case digits. */
CONST char _itoa_lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
/* Upper-case digits. */
CONST char _itoa_upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *
DEFUN(_itoa, (value, buflim, base, upper_case),
unsigned long long int value AND char *buflim AND
unsigned int base AND int upper_case)
{
/* Base-36 digits for numbers. */
CONST char *digits = upper_case ? _itoa_upper_digits : _itoa_lower_digits;
register char *bp = buflim;
while (value > 0)
{
*--bp = digits[value % base];
value /= base;
}
return bp;
}

54
stdio/_itoa.h Normal file
View File

@@ -0,0 +1,54 @@
/* Internal function for converting integers to ASCII.
Copyright (C) 1994 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#ifndef _ITOA_H
#define _ITOA_H
#include <sys/cdefs.h>
extern const char _itoa_lower_digits[], _itoa_upper_digits[];
/* Convert VALUE into ASCII in base BASE (2..36).
Write backwards starting the character just before BUFLIM.
Return the address of the first (left-to-right) character in the number.
Use upper case letters iff UPPER_CASE is nonzero. */
extern char *_itoa __P ((unsigned long long int value, char *buflim,
unsigned int base, int upper_case));
#if defined (__GNUC__) && defined (__OPTIMIZE__)
extern __inline char *
_itoa (unsigned long long int value, char *buflim,
unsigned int base, int upper_case)
{
/* Base-36 digits for numbers. */
const char *digits = upper_case ? _itoa_upper_digits : _itoa_lower_digits;
register char *bp = buflim;
while (value > 0)
{
*--bp = digits[value % base];
value /= base;
}
return bp;
}
#endif
#endif /* itoa.h */

39
stdio/asprintf.c Normal file
View File

@@ -0,0 +1,39 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#include <stdio.h>
/* Write formatted output from FORMAT to a string which is
allocated with malloc and stored in *STRING_PTR. */
/* VARARGS2 */
int
DEFUN(asprintf, (string_ptr, format),
char **string_ptr AND CONST char *format DOTS)
{
va_list arg;
int done;
va_start(arg, format);
done = vasprintf(string_ptr, format, arg);
va_end(arg);
return done;
}

28
stdio/bug1.c Normal file
View File

@@ -0,0 +1,28 @@
#include <ansidecl.h>
#include <stdio.h>
#include <string.h>
int
DEFUN_VOID(main)
{
char *bp;
size_t size;
FILE *stream;
int lose = 0;
stream = open_memstream (&bp, &size);
fprintf (stream, "hello");
fflush (stream);
printf ("buf = %s, size = %d\n", bp, size);
lose |= size != 5;
lose |= strncmp (bp, "hello", size);
fprintf (stream, ", world");
fclose (stream);
printf ("buf = %s, size = %d\n", bp, size);
lose |= size != 12;
lose |= strncmp (bp, "hello, world", 12);
puts (lose ? "Test FAILED!" : "Test succeeded.");
return lose;
}

1
stdio/bug1.input Normal file
View File

@@ -0,0 +1 @@
95

12
stdio/bug2.c Normal file
View File

@@ -0,0 +1,12 @@
#include <ansidecl.h>
#include <stdio.h>
int
DEFUN_VOID(main)
{
int i;
puts ("This should print \"wow = I\" for I from 0 to 39 inclusive.");
for (i = 0; i < 40; i++)
printf ("%s = %d\n", "wow", i);
return 0;
}

52
stdio/bug3.c Normal file
View File

@@ -0,0 +1,52 @@
#include <ansidecl.h>
#include <stdio.h>
#include <string.h>
int
DEFUN_VOID(main)
{
FILE *f;
int i;
f = fopen("bugtest", "w+");
for (i=0; i<9000; i++)
putc ('x', f);
fseek (f, 8180L, 0);
fwrite ("Where does this text go?", 1, 24, f);
fflush (f);
rewind (f);
for (i=0; i<9000; i++)
{
int j;
if ((j = getc(f)) != 'x')
{
if (i != 8180)
{
printf ("Test FAILED!");
return 1;
}
else
{
char buf[25];
buf[0] = j;
fread (buf + 1, 1, 23, f);
buf[24] = '\0';
if (strcmp (buf, "Where does this text go?") != 0)
{
printf ("%s\nTest FAILED!\n", buf);
return 1;
}
i += 23;
}
}
}
fclose(f);
puts ("Test succeeded.");
return 0;
}

50
stdio/bug4.c Normal file
View File

@@ -0,0 +1,50 @@
#ifdef _LIBC
#include <ansidecl.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int stdio_block_read = 1, stdio_block_write = 1;
int
DEFUN(main, (argc, argv),
int argc AND char **argv)
{
FILE *f;
int i;
char buffer[31];
while ((i = getopt (argc, argv, "rw")) != EOF)
switch (i)
{
case 'r':
stdio_block_read = 0;
break;
case 'w':
stdio_block_write = 0;
break;
}
f = fopen("bugtest", "w+");
for (i=0; i<9000; i++) {
putc('x', f);
}
fseek(f, 8180L, 0);
fwrite("Where does this text come from?", 1, 31, f);
fseek(f, 8180L, 0);
fread(buffer, 1, 31, f);
fwrite(buffer, 1, 31, stdout);
fclose(f);
if (!memcmp (buffer, "Where does this text come from?", 31))
{
puts ("\nTest succeeded.");
return 0;
}
else
{
puts ("\nTest FAILED!");
return 1;
}
}

60
stdio/bug5.c Normal file
View File

@@ -0,0 +1,60 @@
/* If stdio is working correctly, after this is run infile and outfile
will have the same contents. If the bug (found in GNU C library 0.3)
exhibits itself, outfile will be missing the 2nd through 1023rd
characters. */
#include <ansidecl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static char buf[8192];
int
DEFUN_VOID(main)
{
FILE *in;
FILE *out;
static char inname[] = "infile";
static char outname[] = "outfile";
int i;
/* Create a test file. */
in = fopen (inname, "w+");
if (in == NULL)
{
perror (inname);
return 1;
}
for (i = 0; i < 1000; ++i)
fprintf (in, "%d\n", i);
out = fopen (outname, "w");
if (out == NULL)
{
perror (outname);
return 1;
}
if (fseek (in, 0L, SEEK_SET) != 0)
abort ();
putc (getc (in), out);
i = fread (buf, 1, sizeof (buf), in);
if (i == 0)
{
perror ("fread");
return 1;
}
if (fwrite (buf, 1, i, out) != i)
{
perror ("fwrite");
return 1;
}
fclose (in);
fclose (out);
puts ("There should be no further output from this test.");
fflush (stdout);
execlp ("cmp", "cmp", inname, outname, (char *) NULL);
perror ("execlp: cmp");
exit (1);
}

27
stdio/bug6.c Normal file
View File

@@ -0,0 +1,27 @@
#include <ansidecl.h>
#include <stdio.h>
int
DEFUN_VOID(main)
{
char buf[80];
int i;
int lost = 0;
scanf ("%2s", buf);
lost |= (buf[0] != 'X' || buf[1] != 'Y' || buf[2] != '\0');
if (lost)
puts ("test of %2s failed.");
scanf (" ");
scanf ("%d", &i);
lost |= (i != 1234);
if (lost)
puts ("test of %d failed.");
scanf ("%c", buf);
lost |= (buf[0] != 'L');
if (lost)
puts ("test of %c failed.\n");
puts (lost ? "Test FAILED!" : "Test succeeded.");
return lost;
}

1
stdio/bug6.input Normal file
View File

@@ -0,0 +1 @@
XY 1234L

53
stdio/bug7.c Normal file
View File

@@ -0,0 +1,53 @@
/* Regression test for fseek and freopen bugs. */
#include <stdio.h>
int
main ()
{
int lose = 0;
char filename[] = "/tmp/foo";
FILE *fp;
fp = fopen (filename, "w+");
fprintf (fp, "Hello world!\n");
fflush (fp);
fseek (fp, 5L, SEEK_SET);
if (fseek (fp, -1L, SEEK_CUR) < 0)
{
printf ("seek failed\n");
lose = 1;
}
fclose (fp);
remove (filename);
{
FILE *file1;
FILE *file2;
char filename1[] = "/tmp/foo";
char filename2[] = "/tmp/bar";
int ch;
file1 = fopen (filename1, "w");
fclose (file1);
file2 = fopen (filename2, "w");
fputc ('x', file2);
fclose (file2);
file1 = fopen (filename1, "r");
file2 = freopen (filename2, "r", file1);
if ((ch = fgetc (file2)) != 'x')
{
printf ("wrong character in reopened file, value = %d\n", ch);
lose = 1;
}
fclose (file1);
fclose (file2);
remove (filename1);
remove (filename2);
}
puts (lose ? "Test FAILED!" : "Test succeeded.");
return lose;
}

31
stdio/clearerr.c Normal file
View File

@@ -0,0 +1,31 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
#undef clearerr
/* Clear the EOF and error indicators for STREAM. */
void
DEFUN(clearerr, (stream), FILE *stream)
{
__clearerr(stream);
}

37
stdio/dprintf.c Normal file
View File

@@ -0,0 +1,37 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#include <stdio.h>
/* Write formatted output to D, according to the format string FORMAT. */
/* VARARGS2 */
int
DEFUN(dprintf, (d, format), int d AND CONST char *format DOTS)
{
va_list arg;
int done;
va_start(arg, format);
done = vdprintf(d, format, arg);
va_end(arg);
return done;
}

60
stdio/errnobug.c Normal file
View File

@@ -0,0 +1,60 @@
/* Regression test for reported old bug that errno is clobbered
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.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
int
main (void)
{
int fd[2];
FILE *f;
/* Get a stream that cannot seek. */
if (pipe (fd))
{
perror ("pipe");
return 1;
}
f = fdopen (fd[1], "w");
if (f == NULL)
{
perror ("fdopen");
return 1;
}
errno = 0;
if (fputs ("fnord", f))
{
perror ("fputs");
return 1;
}
if (errno)
{
perror ("errno gratuitously set -- TEST FAILED");
return 1;
}
puts ("Test succeeded.");
return 0;
}

69
stdio/fclose.c Normal file
View File

@@ -0,0 +1,69 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Close a stream. */
int
DEFUN(fclose, (stream), register FILE *stream)
{
int status;
if (stream == NULL)
{
/* Close all streams. */
register FILE *f;
for (f = __stdio_head; f != NULL; f = f->__next)
if (__validfp(f))
(void) fclose(f);
return 0;
}
if (!__validfp(stream))
{
errno = EINVAL;
return EOF;
}
if (stream->__mode.__write &&
/* Flush the buffer. */
__flshfp (stream, EOF) == EOF)
return EOF;
/* Free the buffer's storage. */
if (stream->__buffer != NULL && !stream->__userbuf)
free(stream->__buffer);
/* Close the system file descriptor. */
if (stream->__io_funcs.__close != NULL)
status = (*stream->__io_funcs.__close)(stream->__cookie);
else if (!stream->__seen && stream->__cookie != NULL)
status = __stdio_close(stream->__cookie);
else
status = 0;
/* Nuke the stream, making it available for re-use. */
__invalidate(stream);
return status < 0 ? EOF : 0;
}

37
stdio/feof.c Normal file
View File

@@ -0,0 +1,37 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
#undef feof
/* Return non-zero if STREAM has its EOF indicator set. */
int
DEFUN(feof, (stream), FILE *stream)
{
if (!__validfp(stream))
{
errno = EINVAL;
return(-1);
}
return(stream->__eof);
}

37
stdio/ferror.c Normal file
View File

@@ -0,0 +1,37 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
#undef ferror
/* Return non-zero if STREAM has its error indicator set. */
int
DEFUN(ferror, (stream), FILE *stream)
{
if (!__validfp(stream))
{
errno = EINVAL;
return(-1);
}
return(stream->__error);
}

45
stdio/fflush.c Normal file
View File

@@ -0,0 +1,45 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
/* Flush STREAM's buffer.
If STREAM is NULL, flush the buffers of all streams that are writing. */
int
DEFUN(fflush, (stream), register FILE *stream)
{
if (stream == NULL)
{
int lossage = 0;
for (stream = __stdio_head; stream != NULL; stream = stream->__next)
if (__validfp(stream) && stream->__mode.__write)
lossage |= fflush(stream) == EOF;
return lossage ? EOF : 0;
}
if (!__validfp(stream) || !stream->__mode.__write)
{
errno = EINVAL;
return EOF;
}
return __flshfp(stream, EOF);
}

35
stdio/fgetc.c Normal file
View File

@@ -0,0 +1,35 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
/* Read a character from STREAM. */
int
DEFUN(fgetc, (stream), FILE *stream)
{
if (!__validfp(stream) || !stream->__mode.__read)
{
errno = EINVAL;
return EOF;
}
return __getc(stream);
}

40
stdio/fgetpos.c Normal file
View File

@@ -0,0 +1,40 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
#undef fgetpos
/* Put the current position of STREAM in *POS. */
int
DEFUN(fgetpos, (stream, pos), FILE *stream AND fpos_t *pos)
{
if (!__validfp(stream) || pos == NULL)
{
errno = EINVAL;
return(-1);
}
*pos = ftell(stream);
if (*pos < 0L)
return(-1);
return(0);
}

121
stdio/fgets.c Normal file
View File

@@ -0,0 +1,121 @@
/* Copyright (C) 1991, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
/* Reads characters from STREAM into S, until either a newline character
is read, N - 1 characters have been read, or EOF is seen. Returns
the newline, unlike gets. Finishes by appending a null character and
returning S. If EOF is seen before any characters have been written
to S, the function returns NULL without appending the null character.
If there is a file error, always return NULL. */
char *
DEFUN(fgets, (s, n, stream), char *s AND int n AND register FILE *stream)
{
register char *p = s;
if (!__validfp(stream) || s == NULL || n <= 0)
{
errno = EINVAL;
return NULL;
}
if (ferror (stream))
return NULL;
if (stream->__buffer == NULL && stream->__userbuf)
{
/* Unbuffered stream. Not much optimization to do. */
register int c = 0;
while (--n > 0 && (c = getc (stream)) != EOF)
if ((*p++ = c) == '\n')
break;
if (c == EOF && (p == s || ferror (stream)))
return NULL;
*p = '\0';
return s;
}
/* Leave space for the null. */
--n;
if (n > 0 &&
(!stream->__seen || stream->__buffer == NULL || stream->__pushed_back))
{
/* Do one with getc to allocate a buffer. */
int c = getc (stream);
if (c == EOF)
return NULL;
*p++ = c;
if (c == '\n')
{
*p = '\0';
return s;
}
else
--n;
}
while (n > 0)
{
size_t i;
char *found;
i = stream->__get_limit - stream->__bufp;
if (i == 0)
{
/* Refill the buffer. */
int c = __fillbf (stream);
if (c == EOF)
break;
*p++ = c;
--n;
if (c == '\n')
{
*p = '\0';
return s;
}
i = stream->__get_limit - stream->__bufp;
}
if (i > n)
i = n;
found = (char *) __memccpy ((PTR) p, stream->__bufp, '\n', i);
if (found != NULL)
{
stream->__bufp += found - p;
p = found;
break;
}
stream->__bufp += i;
n -= i;
p += i;
}
if (p == s)
return NULL;
*p = '\0';
return ferror (stream) ? NULL : s;
}

48
stdio/fileno.c Normal file
View File

@@ -0,0 +1,48 @@
/* Copyright (C) 1991, 1993, 1994 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
/* Return the system file descriptor associated with STREAM. */
int
DEFUN(fileno, (stream), FILE *stream)
{
extern void __stdio_check_funcs __P ((FILE *));
if (! __validfp (stream))
{
errno = EINVAL;
return -1;
}
__stdio_check_funcs (stream);
if (stream->__io_funcs.__fileno == NULL)
{
#ifdef EOPNOTSUPP
errno = EOPNOTSUPP;
#else
errno = ENOSYS;
#endif
return -1;
}
return (*stream->__io_funcs.__fileno) (stream->__cookie);
}

108
stdio/fmemopen.c Normal file
View File

@@ -0,0 +1,108 @@
/* Copyright (C) 1991, 1992, 1993 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Defined in fopen.c. */
extern int EXFUN(__getmode, (CONST char *mode, __io_mode *mptr));
/* Open a new stream that will read and/or write from the buffer in
S, which is of LEN bytes. If the mode indicates appending, the
buffer pointer is set to point to the first '\0' in the buffer.
If S is NULL, the buffer is allocated by malloc and will be freed
when the stream is closed. The only purpose of this is to write
things and then read what's been written. If LEN is zero, writes will
always return errors and reads will always return end-of-file.
The stream is set up such that seeks and tells will always fail and
once the buffer is full of written characters or empty of characters
to read, attempted writes always return an output error and attempted
reads always return end-of-file. */
FILE *
DEFUN(fmemopen, (s, len, mode),
PTR s AND size_t len AND CONST char *mode)
{
__io_mode m;
register FILE *stream;
if (!__getmode (mode, &m))
return NULL;
stream = __newstream ();
if (stream == NULL)
return NULL;
stream->__mode = m;
/* Input gets EOF. */
stream->__room_funcs.__input = NULL;
/* Output gets error. */
stream->__room_funcs.__output = NULL;
/* Do nothing for close. */
stream->__io_funcs.__close = NULL;
/* Can't seek outside the buffer. */
stream->__io_funcs.__seek = NULL;
/* There is no associated file descriptor to fetch. */
stream->__io_funcs.__fileno = NULL;
stream->__seen = 1;
stream->__userbuf = s != NULL && len > 0;
if (s == NULL)
{
s = malloc (len);
if (s == NULL)
{
int save = errno;
(void) fclose (stream);
errno = save;
return NULL;
}
}
stream->__buffer = (char *) s;
stream->__bufsize = len;
stream->__bufp = stream->__buffer;
stream->__get_limit = (stream->__buffer +
(stream->__mode.__read ? stream->__bufsize : 0));
stream->__put_limit = (stream->__buffer +
(stream->__mode.__write ? stream->__bufsize : 0));
stream->__cookie = NULL;
if (stream->__mode.__append)
{
char *p = memchr (stream->__bufp, '\0',
stream->__get_limit - stream->__bufp);
if (p == NULL)
stream->__bufp = stream->__get_limit;
else
stream->__bufp = p;
}
else if (stream->__mode.__truncate)
memset ((PTR) stream->__buffer, 0, len);
return stream;
}

110
stdio/fopen.c Normal file
View File

@@ -0,0 +1,110 @@
/* Copyright (C) 1991, 1992, 1993 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define badmode() return ((errno = EINVAL), 0)
/* Dissect the given mode string into an __io_mode. */
int
DEFUN(__getmode, (mode, mptr), CONST char *mode AND __io_mode *mptr)
{
register unsigned char i;
if (mode == NULL)
badmode ();
memset ((PTR) mptr, 0, sizeof (*mptr));
switch (*mode)
{
case 'a':
mptr->__write = mptr->__create = mptr->__append = 1;
break;
case 'w':
mptr->__write = mptr->__create = mptr->__truncate = 1;
break;
case 'r':
mptr->__read = 1;
break;
default:
badmode ();
}
for (i = 1; i < 3; ++i)
{
++mode;
if (*mode == '\0')
break;
switch (*mode)
{
case '+':
mptr->__read = mptr->__write = 1;
break;
case 'b':
mptr->__binary = 1;
break;
}
}
if (!mptr->__read && !mptr->__write)
badmode ();
mptr->__exclusive = *mode == 'x';
return 1;
}
/* Open a new stream on the given file. */
FILE *
DEFUN(fopen, (filename, mode), CONST char *filename AND CONST char *mode)
{
FILE *stream;
__io_mode m;
if (filename == NULL)
{
errno = EINVAL;
return NULL;
}
if (!__getmode (mode, &m))
return NULL;
stream = __newstream ();
if (stream == NULL)
return NULL;
if (__stdio_open (filename, m, &stream->__cookie))
{
int save = errno;
(void) fclose (stream);
errno = save;
return NULL;
}
stream->__mode = m;
return stream;
}

48
stdio/fopncook.c Normal file
View File

@@ -0,0 +1,48 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
/* Defined in fopen.c. */
extern int EXFUN(__getmode, (CONST char *mode, __io_mode *mptr));
/* Open a new stream on the given magic cookie descriptor. */
FILE *
DEFUN(fopencookie, (cookie, mode, functions),
PTR cookie AND CONST char *mode AND __io_functions functions)
{
__io_mode m;
FILE *f;
if (!__getmode (mode, &m))
return NULL;
f = __newstream ();
if (f == NULL)
return NULL;
f->__cookie = cookie;
f->__mode = m;
f->__io_funcs = functions;
f->__room_funcs = __default_room_functions;
f->__seen = 1;
return f;
}

401
stdio/fpioconst.c Normal file
View File

@@ -0,0 +1,401 @@
/* Table of MP integer constants 10^(2^i), used for floating point <-> decimal.
Copyright (C) 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include "fpioconst.h"
#include <gmp-mparam.h> /* This defines BITS_PER_MP_LIMB. */
/* First page : 32-bit limbs
Second page : 64-bit limbs
Last page : table of pointers
*/
#if BITS_PER_MP_LIMB == 32
/* Table with constants of 10^(2^i), i=0..12 for 32-bit limbs. */
static const mp_limb _ten_p0[] =
{ 0x00000000, 0x00000000, 0x0000000a };
static const mp_limb _ten_p1[] =
{ 0x00000000, 0x00000000, 0x00000064 };
static const mp_limb _ten_p2[] =
{ 0x00000000, 0x00000000, 0x00002710 };
static const mp_limb _ten_p3[] =
{ 0x00000000, 0x00000000, 0x05f5e100 };
static const mp_limb _ten_p4[] =
{ 0x00000000, 0x00000000, 0x6fc10000, 0x002386f2 };
static const mp_limb _ten_p5[] =
{ 0x00000000, 0x00000000, 0x00000000, 0x85acef81, 0x2d6d415b, 0x000004ee };
static const mp_limb _ten_p6[] =
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xbf6a1f01, 0x6e38ed64,
0xdaa797ed, 0xe93ff9f4, 0x00184f03 };
static const mp_limb _ten_p7[] =
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x2e953e01, 0x03df9909, 0x0f1538fd, 0x2374e42f, 0xd3cff5ec, 0xc404dc08,
0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x0000024e };
static const mp_limb _ten_p8[] =
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x982e7c01, 0xbed3875b,
0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70, 0xd595d80f, 0x26b2716e,
0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0, 0x65f9ef17,
0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x000553f7 };
static const mp_limb _ten_p9[] =
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xfc6cf801, 0x77f27267, 0x8f9546dc, 0x5d96976f, 0xb83a8a97, 0xc31e1ad9,
0x46c40513, 0x94e65747, 0xc88976c1, 0x4475b579, 0x28f8733b, 0xaa1da1bf,
0x703ed321, 0x1e25cfea, 0xb21a2f22, 0xbc51fb2e, 0x96e14f5d, 0xbfa3edac,
0x329c57ae, 0xe7fc7153, 0xc3fc0695, 0x85a91924, 0xf95f635e, 0xb2908ee0,
0x93abade4, 0x1366732a, 0x9449775c, 0x69be5b0e, 0x7343afac, 0xb099bc81,
0x45a71d46, 0xa2699748, 0x8cb07303, 0x8a0b1f13, 0x8cab8a97, 0xc1d238d9,
0x633415d4, 0x0000001c };
static const mp_limb _ten_p10[] =
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2919f001, 0xf55b2b72,
0x6e7c215b, 0x1ec29f86, 0x991c4e87, 0x15c51a88, 0x140ac535, 0x4c7d1e1a,
0xcc2cd819, 0x0ed1440e, 0x896634ee, 0x7de16cfb, 0x1e43f61f, 0x9fce837d,
0x231d2b9c, 0x233e55c7, 0x65dc60d7, 0xf451218b, 0x1c5cd134, 0xc9635986,
0x922bbb9f, 0xa7e89431, 0x9f9f2a07, 0x62be695a, 0x8e1042c4, 0x045b7a74,
0x1abe1de3, 0x8ad822a5, 0xba34c411, 0xd814b505, 0xbf3fdeb3, 0x8fc51a16,
0xb1b896bc, 0xf56deeec, 0x31fb6bfd, 0xb6f4654b, 0x101a3616, 0x6b7595fb,
0xdc1a47fe, 0x80d98089, 0x80bda5a5, 0x9a202882, 0x31eb0f66, 0xfc8f1f90,
0x976a3310, 0xe26a7b7e, 0xdf68368a, 0x3ce3a0b8, 0x8e4262ce, 0x75a351a2,
0x6cb0b6c9, 0x44597583, 0x31b5653f, 0xc356e38a, 0x35faaba6, 0x0190fba0,
0x9fc4ed52, 0x88bc491b, 0x1640114a, 0x005b8041, 0xf4f3235e, 0x1e8d4649,
0x36a8de06, 0x73c55349, 0xa7e6bd2a, 0xc1a6970c, 0x47187094, 0xd2db49ef,
0x926c3f5b, 0xae6209d4, 0x2d433949, 0x34f4a3c6, 0xd4305d94, 0xd9d61a05,
0x00000325 };
static const mp_limb _ten_p11[] =
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x1333e001, 0xe3096865, 0xb27d4d3f, 0x49e28dcf, 0xec2e4721, 0xee87e354,
0xb6067584, 0x368b8abb, 0xa5e5a191, 0x2ed56d55, 0xfd827773, 0xea50d142,
0x51b78db2, 0x98342c9e, 0xc850dabc, 0x866ed6f1, 0x19342c12, 0x92794987,
0xd2f869c2, 0x66912e4a, 0x71c7fd8f, 0x57a7842d, 0x235552eb, 0xfb7fedcc,
0xf3861ce0, 0x38209ce1, 0x9713b449, 0x34c10134, 0x8c6c54de, 0xa7a8289c,
0x2dbb6643, 0xe3cb64f3, 0x8074ff01, 0xe3892ee9, 0x10c17f94, 0xa8f16f92,
0xa8281ed6, 0x967abbb3, 0x5a151440, 0x9952fbed, 0x13b41e44, 0xafe609c3,
0xa2bca416, 0xf111821f, 0xfb1264b4, 0x91bac974, 0xd6c7d6ab, 0x8e48ff35,
0x4419bd43, 0xc4a65665, 0x685e5510, 0x33554c36, 0xab498697, 0x0dbd21fe,
0x3cfe491d, 0x982da466, 0xcbea4ca7, 0x9e110c7b, 0x79c56b8a, 0x5fc5a047,
0x84d80e2e, 0x1aa9f444, 0x730f203c, 0x6a57b1ab, 0xd752f7a6, 0x87a7dc62,
0x944545ff, 0x40660460, 0x77c1a42f, 0xc9ac375d, 0xe866d7ef, 0x744695f0,
0x81428c85, 0xa1fc6b96, 0xd7917c7b, 0x7bf03c19, 0x5b33eb41, 0x5715f791,
0x8f6cae5f, 0xdb0708fd, 0xb125ac8e, 0x785ce6b7, 0x56c6815b, 0x6f46eadb,
0x4eeebeee, 0x195355d8, 0xa244de3c, 0x9d7389c0, 0x53761abd, 0xcf99d019,
0xde9ec24b, 0x0d76ce39, 0x70beb181, 0x2e55ecee, 0xd5f86079, 0xf56d9d4b,
0xfb8886fb, 0x13ef5a83, 0x408f43c5, 0x3f3389a4, 0xfad37943, 0x58ccf45c,
0xf82df846, 0x415c7f3e, 0x2915e818, 0x8b3d5cf4, 0x6a445f27, 0xf8dbb57a,
0xca8f0070, 0x8ad803ec, 0xb2e87c34, 0x038f9245, 0xbedd8a6c, 0xc7c9dee0,
0x0eac7d56, 0x2ad3fa14, 0xe0de0840, 0xf775677c, 0xf1bd0ad5, 0x92be221e,
0x87fa1fb9, 0xce9d04a4, 0xd2c36fa9, 0x3f6f7024, 0xb028af62, 0x907855ee,
0xd83e49d6, 0x4efac5dc, 0xe7151aab, 0x77cd8c6b, 0x0a753b7d, 0x0af908b4,
0x8c983623, 0xe50f3027, 0x94222771, 0x1d08e2d6, 0xf7e928e6, 0xf2ee5ca6,
0x1b61b93c, 0x11eb962b, 0x9648b21c, 0xce2bcba1, 0x34f77154, 0x7bbebe30,
0xe526a319, 0x8ce329ac, 0xde4a74d2, 0xb5dc53d5, 0x0009e8b3 };
static const mp_limb _ten_p12[] =
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2a67c001, 0xd4724e8d,
0x8efe7ae7, 0xf89a1e90, 0xef084117, 0x54e05154, 0x13b1bb51, 0x506be829,
0xfb29b172, 0xe599574e, 0xf0da6146, 0x806c0ed3, 0xb86ae5be, 0x45155e93,
0xc0591cc2, 0x7e1e7c34, 0x7c4823da, 0x1d1f4cce, 0x9b8ba1e8, 0xd6bfdf75,
0xe341be10, 0xc2dfae78, 0x016b67b2, 0x0f237f1a, 0x3dbeabcd, 0xaf6a2574,
0xcab3e6d7, 0x142e0e80, 0x61959127, 0x2c234811, 0x87009701, 0xcb4bf982,
0xf8169c84, 0x88052f8c, 0x68dde6d4, 0xbc131761, 0xff0b0905, 0x54ab9c41,
0x7613b224, 0x1a1c304e, 0x3bfe167b, 0x441c2d47, 0x4f6cea9c, 0x78f06181,
0xeb659fb8, 0x30c7ae41, 0x947e0d0e, 0xa1ebcad7, 0xd97d9556, 0x2130504d,
0x1a8309cb, 0xf2acd507, 0x3f8ec72a, 0xfd82373a, 0x95a842bc, 0x280f4d32,
0xf3618ac0, 0x811a4f04, 0x6dc3a5b4, 0xd3967a1b, 0x15b8c898, 0xdcfe388f,
0x454eb2a0, 0x8738b909, 0x10c4e996, 0x2bd9cc11, 0x3297cd0c, 0x655fec30,
0xae0725b1, 0xf4090ee8, 0x037d19ee, 0x398c6fed, 0x3b9af26b, 0xc994a450,
0xb5341743, 0x75a697b2, 0xac50b9c1, 0x3ccb5b92, 0xffe06205, 0xa8329761,
0xdfea5242, 0xeb83cadb, 0xe79dadf7, 0x3c20ee69, 0x1e0a6817, 0x7021b97a,
0x743074fa, 0x176ca776, 0x77fb8af6, 0xeca19beb, 0x92baf1de, 0xaf63b712,
0xde35c88b, 0xa4eb8f8c, 0xe137d5e9, 0x40b464a0, 0x87d1cde8, 0x42923bbd,
0xcd8f62ff, 0x2e2690f3, 0x095edc16, 0x59c89f1b, 0x1fa8fd5d, 0x5138753d,
0x390a2b29, 0x80152f18, 0x2dd8d925, 0xf984d83e, 0x7a872e74, 0xc19e1faf,
0xed4d542d, 0xecf9b5d0, 0x9462ea75, 0xc53c0adf, 0x0caea134, 0x37a2d439,
0xc8fa2e8a, 0x2181327e, 0x6e7bb827, 0x2d240820, 0x50be10e0, 0x5893d4b8,
0xab312bb9, 0x1f2b2322, 0x440b3f25, 0xbf627ede, 0x72dac789, 0xb608b895,
0x78787e2a, 0x86deb3f0, 0x6fee7aab, 0xbb9373f4, 0x27ecf57b, 0xf7d8b57e,
0xfca26a9f, 0x3d04e8d2, 0xc9df13cb, 0x3172826a, 0xcd9e8d7c, 0xa8fcd8e0,
0xb2c39497, 0x307641d9, 0x1cc939c1, 0x2608c4cf, 0xb6d1c7bf, 0x3d326a7e,
0xeeaf19e6, 0x8e13e25f, 0xee63302b, 0x2dfe6d97, 0x25971d58, 0xe41d3cc4,
0x0a80627c, 0xab8db59a, 0x9eea37c8, 0xe90afb77, 0x90ca19cf, 0x9ee3352c,
0x3613c850, 0xfe78d682, 0x788f6e50, 0x5b060904, 0xb71bd1a4, 0x3fecb534,
0xb32c450c, 0x20c33857, 0xa6e9cfda, 0x0239f4ce, 0x48497187, 0xa19adb95,
0xb492ed8a, 0x95aca6a8, 0x4dcd6cd9, 0xcf1b2350, 0xfbe8b12a, 0x1a67778c,
0x38eb3acc, 0xc32da383, 0xfb126ab1, 0xa03f40a8, 0xed5bf546, 0xe9ce4724,
0x4c4a74fd, 0x73a130d8, 0xd9960e2d, 0xa2ebd6c1, 0x94ab6feb, 0x6f233b7c,
0x49126080, 0x8e7b9a73, 0x4b8c9091, 0xd298f999, 0x35e836b5, 0xa96ddeff,
0x96119b31, 0x6b0dd9bc, 0xc6cc3f8d, 0x282566fb, 0x72b882e7, 0xd6769f3b,
0xa674343d, 0x00fc509b, 0xdcbf7789, 0xd6266a3f, 0xae9641fd, 0x4e89541b,
0x11953407, 0x53400d03, 0x8e0dd75a, 0xe5b53345, 0x108f19ad, 0x108b89bc,
0x41a4c954, 0xe03b2b63, 0x437b3d7f, 0x97aced8e, 0xcbd66670, 0x2c5508c2,
0x650ebc69, 0x5c4f2ef0, 0x904ff6bf, 0x9985a2df, 0x9faddd9e, 0x5ed8d239,
0x25585832, 0xe3e51cb9, 0x0ff4f1d4, 0x56c02d9a, 0x8c4ef804, 0xc1a08a13,
0x13fd01c8, 0xe6d27671, 0xa7c234f4, 0x9d0176cc, 0xd0d73df2, 0x4d8bfa89,
0x544f10cd, 0x2b17e0b2, 0xb70a5c7d, 0xfd86fe49, 0xdf373f41, 0x214495bb,
0x84e857fd, 0x00d313d5, 0x0496fcbe, 0xa4ba4744, 0xe8cac982, 0xaec29e6e,
0x87ec7038, 0x7000a519, 0xaeee333b, 0xff66e42c, 0x8afd6b25, 0x03b4f63b,
0xbd7991dc, 0x5ab8d9c7, 0x2ed4684e, 0x48741a6c, 0xaf06940d, 0x2fdc6349,
0xb03d7ecd, 0xe974996f, 0xac7867f9, 0x52ec8721, 0xbcdd9d4a, 0x8edd2d00,
0x3557de06, 0x41c759f8, 0x3956d4b9, 0xa75409f2, 0x123cd8a1, 0xb6100fab,
0x3e7b21e2, 0x2e8d623b, 0x92959da2, 0xbca35f77, 0x200c03a5, 0x35fcb457,
0x1bb6c6e4, 0xf74eb928, 0x3d5d0b54, 0x87cc1d21, 0x4964046f, 0x18ae4240,
0xd868b275, 0x8bd2b496, 0x1c5563f4, 0xc234d8f5, 0xf868e970, 0xf9151fff,
0xae7be4a2, 0x271133ee, 0xbb0fd922, 0x25254932, 0xa60a9fc0, 0x104bcd64,
0x30290145, 0x00000062 };
#define LAST_POW10 12
#elif BITS_PER_MP_LIMB == 64
/* Table with constants of 10^(2^i), i=0..12 for 64-bit limbs. */
static const mp_limb _ten_p0[] =
{ 0x0000000000000000, 0x000000000000000a };
static const mp_limb _ten_p1[] =
{ 0x0000000000000000, 0x0000000000000064 };
static const mp_limb _ten_p2[] =
{ 0x0000000000000000, 0x0000000000002710 };
static const mp_limb _ten_p3[] =
{ 0x0000000000000000, 0x0000000005f5e100 };
static const mp_limb _ten_p4[] =
{ 0x0000000000000000, 0x002386f26fc10000 };
static const mp_limb _ten_p5[] =
{ 0x0000000000000000, 0x85acef8100000000, 0x000004ee2d6d415b };
static const mp_limb _ten_p6[] =
{ 0x0000000000000000, 0x0000000000000000, 0x6e38ed64bf6a1f01,
0xe93ff9f4daa797ed, 0x0000000000184f03 };
static const mp_limb _ten_p7[] =
{ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x03df99092e953e01, 0x2374e42f0f1538fd, 0xc404dc08d3cff5ec,
0xa6337f19bccdb0da, 0x0000024ee91f2603 };
static const mp_limb _ten_p8[] =
{ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0xbed3875b982e7c01,
0x12152f87d8d99f72, 0xcf4a6e706bde50c6, 0x26b2716ed595d80f,
0x1d153624adc666b0, 0x63ff540e3c42d35a, 0x65f9ef17cc5573c0,
0x80dcc7f755bc28f2, 0x5fdcefcef46eeddc, 0x00000000000553f7 };
static const mp_limb _ten_p9[] =
{ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x77f27267fc6cf801, 0x5d96976f8f9546dc, 0xc31e1ad9b83a8a97,
0x94e6574746c40513, 0x4475b579c88976c1, 0xaa1da1bf28f8733b,
0x1e25cfea703ed321, 0xbc51fb2eb21a2f22, 0xbfa3edac96e14f5d,
0xe7fc7153329c57ae, 0x85a91924c3fc0695, 0xb2908ee0f95f635e,
0x1366732a93abade4, 0x69be5b0e9449775c, 0xb099bc817343afac,
0xa269974845a71d46, 0x8a0b1f138cb07303, 0xc1d238d98cab8a97,
0x0000001c633415d4 };
static const mp_limb _ten_p10[] =
{ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0xf55b2b722919f001,
0x1ec29f866e7c215b, 0x15c51a88991c4e87, 0x4c7d1e1a140ac535,
0x0ed1440ecc2cd819, 0x7de16cfb896634ee, 0x9fce837d1e43f61f,
0x233e55c7231d2b9c, 0xf451218b65dc60d7, 0xc96359861c5cd134,
0xa7e89431922bbb9f, 0x62be695a9f9f2a07, 0x045b7a748e1042c4,
0x8ad822a51abe1de3, 0xd814b505ba34c411, 0x8fc51a16bf3fdeb3,
0xf56deeecb1b896bc, 0xb6f4654b31fb6bfd, 0x6b7595fb101a3616,
0x80d98089dc1a47fe, 0x9a20288280bda5a5, 0xfc8f1f9031eb0f66,
0xe26a7b7e976a3310, 0x3ce3a0b8df68368a, 0x75a351a28e4262ce,
0x445975836cb0b6c9, 0xc356e38a31b5653f, 0x0190fba035faaba6,
0x88bc491b9fc4ed52, 0x005b80411640114a, 0x1e8d4649f4f3235e,
0x73c5534936a8de06, 0xc1a6970ca7e6bd2a, 0xd2db49ef47187094,
0xae6209d4926c3f5b, 0x34f4a3c62d433949, 0xd9d61a05d4305d94,
0x0000000000000325 };
static const mp_limb _ten_p11[] =
{ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0xe30968651333e001, 0x49e28dcfb27d4d3f, 0xee87e354ec2e4721,
0x368b8abbb6067584, 0x2ed56d55a5e5a191, 0xea50d142fd827773,
0x98342c9e51b78db2, 0x866ed6f1c850dabc, 0x9279498719342c12,
0x66912e4ad2f869c2, 0x57a7842d71c7fd8f, 0xfb7fedcc235552eb,
0x38209ce1f3861ce0, 0x34c101349713b449, 0xa7a8289c8c6c54de,
0xe3cb64f32dbb6643, 0xe3892ee98074ff01, 0xa8f16f9210c17f94,
0x967abbb3a8281ed6, 0x9952fbed5a151440, 0xafe609c313b41e44,
0xf111821fa2bca416, 0x91bac974fb1264b4, 0x8e48ff35d6c7d6ab,
0xc4a656654419bd43, 0x33554c36685e5510, 0x0dbd21feab498697,
0x982da4663cfe491d, 0x9e110c7bcbea4ca7, 0x5fc5a04779c56b8a,
0x1aa9f44484d80e2e, 0x6a57b1ab730f203c, 0x87a7dc62d752f7a6,
0x40660460944545ff, 0xc9ac375d77c1a42f, 0x744695f0e866d7ef,
0xa1fc6b9681428c85, 0x7bf03c19d7917c7b, 0x5715f7915b33eb41,
0xdb0708fd8f6cae5f, 0x785ce6b7b125ac8e, 0x6f46eadb56c6815b,
0x195355d84eeebeee, 0x9d7389c0a244de3c, 0xcf99d01953761abd,
0x0d76ce39de9ec24b, 0x2e55ecee70beb181, 0xf56d9d4bd5f86079,
0x13ef5a83fb8886fb, 0x3f3389a4408f43c5, 0x58ccf45cfad37943,
0x415c7f3ef82df846, 0x8b3d5cf42915e818, 0xf8dbb57a6a445f27,
0x8ad803ecca8f0070, 0x038f9245b2e87c34, 0xc7c9dee0bedd8a6c,
0x2ad3fa140eac7d56, 0xf775677ce0de0840, 0x92be221ef1bd0ad5,
0xce9d04a487fa1fb9, 0x3f6f7024d2c36fa9, 0x907855eeb028af62,
0x4efac5dcd83e49d6, 0x77cd8c6be7151aab, 0x0af908b40a753b7d,
0xe50f30278c983623, 0x1d08e2d694222771, 0xf2ee5ca6f7e928e6,
0x11eb962b1b61b93c, 0xce2bcba19648b21c, 0x7bbebe3034f77154,
0x8ce329ace526a319, 0xb5dc53d5de4a74d2, 0x000000000009e8b3 };
static const mp_limb _ten_p12[] =
{ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
0x0000000000000000, 0x0000000000000000, 0xd4724e8d2a67c001,
0xf89a1e908efe7ae7, 0x54e05154ef084117, 0x506be82913b1bb51,
0xe599574efb29b172, 0x806c0ed3f0da6146, 0x45155e93b86ae5be,
0x7e1e7c34c0591cc2, 0x1d1f4cce7c4823da, 0xd6bfdf759b8ba1e8,
0xc2dfae78e341be10, 0x0f237f1a016b67b2, 0xaf6a25743dbeabcd,
0x142e0e80cab3e6d7, 0x2c23481161959127, 0xcb4bf98287009701,
0x88052f8cf8169c84, 0xbc13176168dde6d4, 0x54ab9c41ff0b0905,
0x1a1c304e7613b224, 0x441c2d473bfe167b, 0x78f061814f6cea9c,
0x30c7ae41eb659fb8, 0xa1ebcad7947e0d0e, 0x2130504dd97d9556,
0xf2acd5071a8309cb, 0xfd82373a3f8ec72a, 0x280f4d3295a842bc,
0x811a4f04f3618ac0, 0xd3967a1b6dc3a5b4, 0xdcfe388f15b8c898,
0x8738b909454eb2a0, 0x2bd9cc1110c4e996, 0x655fec303297cd0c,
0xf4090ee8ae0725b1, 0x398c6fed037d19ee, 0xc994a4503b9af26b,
0x75a697b2b5341743, 0x3ccb5b92ac50b9c1, 0xa8329761ffe06205,
0xeb83cadbdfea5242, 0x3c20ee69e79dadf7, 0x7021b97a1e0a6817,
0x176ca776743074fa, 0xeca19beb77fb8af6, 0xaf63b71292baf1de,
0xa4eb8f8cde35c88b, 0x40b464a0e137d5e9, 0x42923bbd87d1cde8,
0x2e2690f3cd8f62ff, 0x59c89f1b095edc16, 0x5138753d1fa8fd5d,
0x80152f18390a2b29, 0xf984d83e2dd8d925, 0xc19e1faf7a872e74,
0xecf9b5d0ed4d542d, 0xc53c0adf9462ea75, 0x37a2d4390caea134,
0x2181327ec8fa2e8a, 0x2d2408206e7bb827, 0x5893d4b850be10e0,
0x1f2b2322ab312bb9, 0xbf627ede440b3f25, 0xb608b89572dac789,
0x86deb3f078787e2a, 0xbb9373f46fee7aab, 0xf7d8b57e27ecf57b,
0x3d04e8d2fca26a9f, 0x3172826ac9df13cb, 0xa8fcd8e0cd9e8d7c,
0x307641d9b2c39497, 0x2608c4cf1cc939c1, 0x3d326a7eb6d1c7bf,
0x8e13e25feeaf19e6, 0x2dfe6d97ee63302b, 0xe41d3cc425971d58,
0xab8db59a0a80627c, 0xe90afb779eea37c8, 0x9ee3352c90ca19cf,
0xfe78d6823613c850, 0x5b060904788f6e50, 0x3fecb534b71bd1a4,
0x20c33857b32c450c, 0x0239f4cea6e9cfda, 0xa19adb9548497187,
0x95aca6a8b492ed8a, 0xcf1b23504dcd6cd9, 0x1a67778cfbe8b12a,
0xc32da38338eb3acc, 0xa03f40a8fb126ab1, 0xe9ce4724ed5bf546,
0x73a130d84c4a74fd, 0xa2ebd6c1d9960e2d, 0x6f233b7c94ab6feb,
0x8e7b9a7349126080, 0xd298f9994b8c9091, 0xa96ddeff35e836b5,
0x6b0dd9bc96119b31, 0x282566fbc6cc3f8d, 0xd6769f3b72b882e7,
0x00fc509ba674343d, 0xd6266a3fdcbf7789, 0x4e89541bae9641fd,
0x53400d0311953407, 0xe5b533458e0dd75a, 0x108b89bc108f19ad,
0xe03b2b6341a4c954, 0x97aced8e437b3d7f, 0x2c5508c2cbd66670,
0x5c4f2ef0650ebc69, 0x9985a2df904ff6bf, 0x5ed8d2399faddd9e,
0xe3e51cb925585832, 0x56c02d9a0ff4f1d4, 0xc1a08a138c4ef804,
0xe6d2767113fd01c8, 0x9d0176cca7c234f4, 0x4d8bfa89d0d73df2,
0x2b17e0b2544f10cd, 0xfd86fe49b70a5c7d, 0x214495bbdf373f41,
0x00d313d584e857fd, 0xa4ba47440496fcbe, 0xaec29e6ee8cac982,
0x7000a51987ec7038, 0xff66e42caeee333b, 0x03b4f63b8afd6b25,
0x5ab8d9c7bd7991dc, 0x48741a6c2ed4684e, 0x2fdc6349af06940d,
0xe974996fb03d7ecd, 0x52ec8721ac7867f9, 0x8edd2d00bcdd9d4a,
0x41c759f83557de06, 0xa75409f23956d4b9, 0xb6100fab123cd8a1,
0x2e8d623b3e7b21e2, 0xbca35f7792959da2, 0x35fcb457200c03a5,
0xf74eb9281bb6c6e4, 0x87cc1d213d5d0b54, 0x18ae42404964046f,
0x8bd2b496d868b275, 0xc234d8f51c5563f4, 0xf9151ffff868e970,
0x271133eeae7be4a2, 0x25254932bb0fd922, 0x104bcd64a60a9fc0,
0x0000006230290145 };
#define LAST_POW10 12
#else
# error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
#endif
/* Each of array variable above defines one mpn integer which is a power of 10.
This table points to those variables, indexed by the exponent. */
const struct mp_power _fpioconst_pow10[LDBL_MAX_10_EXP_LOG + 1] =
{
{ _ten_p0, sizeof (_ten_p0) / sizeof (_ten_p0[0]), 4, },
{ _ten_p1, sizeof (_ten_p1) / sizeof (_ten_p0[1]), 7, 4 },
{ _ten_p2, sizeof (_ten_p2) / sizeof (_ten_p0[2]), 14, 10 },
{ _ten_p3, sizeof (_ten_p3) / sizeof (_ten_p0[3]), 27, 24 },
{ _ten_p4, sizeof (_ten_p4) / sizeof (_ten_p0[4]), 54, 50 },
{ _ten_p5, sizeof (_ten_p5) / sizeof (_ten_p0[5]), 107, 103 },
{ _ten_p6, sizeof (_ten_p6) / sizeof (_ten_p0[6]), 213, 210 },
{ _ten_p7, sizeof (_ten_p7) / sizeof (_ten_p0[7]), 426, 422 },
{ _ten_p8, sizeof (_ten_p8) / sizeof (_ten_p0[8]), 851, 848 },
{ _ten_p9, sizeof (_ten_p9) / sizeof (_ten_p0[9]), 1701, 1698 },
{ _ten_p10, sizeof (_ten_p10) / sizeof (_ten_p0[10]), 3402, 3399 },
{ _ten_p11, sizeof (_ten_p11) / sizeof (_ten_p0[11]), 6804, 6800 },
{ _ten_p12, sizeof (_ten_p12) / sizeof (_ten_p0[12]), 13607, 13604 }
};
#if LDBL_MAX_10_EXP_LOG > LAST_POW10
#error "Need to expand 10^(2^i) table for i up to" LDBL_MAX_10_EXP_LOG
#endif

52
stdio/fpioconst.h Normal file
View File

@@ -0,0 +1,52 @@
/* Header file for constants used in floating point <-> decimal conversions.
Copyright (C) 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#ifndef _FPIOCONST_H
#define _FPIOCONST_H
#include <float.h>
#include "gmp.h"
/* These values are used by __printf_fp, where they are noncritical (if the
value is not large enough, it will just be slower); and by
strtof/strtod/strtold, where it is critical (it's used for overflow
detection).
XXX These should be defined in <float.h>. For the time being, we have the
IEEE754 values here. */
#define LDBL_MAX_10_EXP_LOG 12 /* = floor(log_2(LDBL_MAX_10_EXP)) */
#define DBL_MAX_10_EXP_LOG 8 /* = floor(log_2(DBL_MAX_10_EXP)) */
#define FLT_MAX_10_EXP_LOG 5 /* = floor(log_2(FLT_MAX_10_EXP)) */
/* Table of powers of ten. This is used by __printf_fp and by
strtof/strtod/strtold. */
struct mp_power
{
const mp_limb *array; /* The array with the number representation. */
mp_size_t arraysize; /* Size of the array. */
int p_expo; /* Exponent of the number 10^(2^i). */
int m_expo; /* Exponent of the number 10^-(2^i-1). */
};
extern const struct mp_power _fpioconst_pow10[LDBL_MAX_10_EXP_LOG + 1];
#endif /* fpioconst.h */

38
stdio/fprintf.c Normal file
View File

@@ -0,0 +1,38 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#include <stdio.h>
/* Write formatted output to STREAM from the format string FORMAT. */
/* VARARGS2 */
int
DEFUN(fprintf, (stream, format),
FILE *stream AND CONST char *format DOTS)
{
va_list arg;
int done;
va_start(arg, format);
done = vfprintf(stream, format, arg);
va_end(arg);
return done;
}

35
stdio/fputc.c Normal file
View File

@@ -0,0 +1,35 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
/* Write the character C to STREAM. */
int
DEFUN(fputc, (c, stream), int c AND FILE *stream)
{
if (!__validfp(stream) || !stream->__mode.__write)
{
errno = EINVAL;
return EOF;
}
return __putc(c, stream);
}

35
stdio/fputs.c Normal file
View File

@@ -0,0 +1,35 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
/* Write the string S to STREAM. */
int
DEFUN(fputs, (s, stream), CONST char *s AND FILE *stream)
{
register CONST size_t len = strlen (s);
if (len == 1)
return putc (*s, stream) == EOF ? EOF : 0;
if (fwrite ((PTR) s, 1, len, stream) != len)
return EOF;
return 0;
}

128
stdio/fread.c Normal file
View File

@@ -0,0 +1,128 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define default_func __default_room_functions.__input
/* Read NMEMB chunks of SIZE bytes each from STREAM into P. */
size_t
DEFUN(fread, (p, size, nmemb, stream),
PTR p AND size_t size AND size_t nmemb AND register FILE *stream)
{
register char *ptr = (char *) p;
register size_t to_read = size * nmemb;
size_t bytes = to_read;
if (!__validfp(stream) || !stream->__mode.__read)
{
errno = EINVAL;
return 0;
}
if (feof(stream) || ferror(stream))
return 0;
if (p == NULL || to_read == 0)
return 0;
if (!stream->__seen || stream->__buffer == NULL || stream->__pushed_back)
{
/* This stream has never been seen before, or it has a character
pushed back. Call __fillbf to deal with those cases. Life will
be simpler after this call. */
int c = __fillbf(stream);
if (c == EOF)
return 0;
*ptr++ = c;
if (--to_read == 0)
return 1;
}
read_from_buffer:;
if (stream->__bufp < stream->__get_limit)
{
/* First off, empty out the buffer. */
register size_t copy = stream->__get_limit - stream->__bufp;
if (copy > to_read)
copy = to_read;
to_read -= copy;
if (copy > 20)
memcpy((PTR) ptr, (PTR) stream->__bufp, copy);
else
{
register size_t i;
for (i = 0; i < copy; ++i)
ptr[i] = stream->__bufp[i];
}
stream->__bufp += copy;
if (to_read == 0)
return nmemb;
ptr += copy;
}
/* Reading directly into the user's buffer doesn't help when
using a user-specified input buffer filling/expanding function,
so we don't do it in that case. */
if (to_read >= stream->__bufsize &&
stream->__room_funcs.__input == default_func &&
stream->__offset == stream->__target)
{
/* Read directly into the user's buffer. */
if (stream->__io_funcs.__read != NULL)
while (to_read > 0)
{
register int count;
count = (*stream->__io_funcs.__read)(stream->__cookie,
ptr, to_read);
if (count > 0)
{
to_read -= count;
stream->__offset += count;
stream->__target += count;
ptr += count;
}
else if (count == 0)
{
stream->__eof = 1;
break;
}
else
{
stream->__error = 1;
break;
}
}
else
stream->__eof = 1;
}
else
{
int c = __fillbf(stream);
if (c == EOF)
return (bytes - to_read) / size;
*ptr++ = (char) c;
--to_read;
if (to_read > 0)
goto read_from_buffer;
}
return (bytes - to_read) / size;
}

74
stdio/freopen.c Normal file
View File

@@ -0,0 +1,74 @@
/* Copyright (C) 1991, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
/* Defined in fopen.c. */
extern int __getmode __P ((const char *, __io_mode *));
/* Defined in sysd-stdio.c. */
extern int __stdio_reopen __P ((const char *filename, __io_mode mode,
PTR *cookieptr, __io_close_fn closefn));
/* Replace STREAM, opening it on FILENAME. */
FILE *
DEFUN(freopen, (filename, mode, stream),
CONST char *filename AND CONST char *mode AND register FILE *stream)
{
__io_mode m;
PTR cookie;
if (!__getmode (mode, &m))
{
(void) fclose (stream);
errno = EINVAL;
return NULL;
}
if (stream->__mode.__write)
/* Flush the stream. */
(void) fflush (stream);
/* Open the file, attempting to preserve the old cookie value. */
cookie = stream->__cookie;
if (__stdio_reopen (filename, m, &cookie,
stream->__seen ?
stream->__io_funcs.__close :
__stdio_close))
{
int save = errno;
(void) fclose (stream);
errno = save;
return NULL;
}
/* Close the stream, first disabling its cookie close function because
__stdio_reopen has already dealt with closing the old cookie. */
stream->__seen = 1; /* It might have no functions yet. */
stream->__io_funcs.__close = NULL;
(void) fclose (stream);
stream->__magic = _IOMAGIC;
stream->__cookie = cookie;
stream->__mode = m;
return stream;
}

38
stdio/fscanf.c Normal file
View File

@@ -0,0 +1,38 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#include <stdio.h>
/* Read formatted input from STREAM according to the format string FORMAT. */
/* VARARGS2 */
int
DEFUN(fscanf, (stream, format),
FILE *stream AND CONST char *format DOTS)
{
va_list arg;
int done;
va_start(arg, format);
done = __vfscanf(stream, format, arg);
va_end(arg);
return done;
}

177
stdio/fseek.c Normal file
View File

@@ -0,0 +1,177 @@
/* Copyright (C) 1991, 1992, 1993, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
/* Move the file position of STREAM to OFFSET
bytes from the beginning of the file if WHENCE
is SEEK_SET, the end of the file is it is SEEK_END,
or the current position if it is SEEK_CUR. */
int
DEFUN(fseek, (stream, offset, whence),
register FILE *stream AND long int offset AND int whence)
{
long int o;
if (!__validfp (stream))
{
errno = EINVAL;
return EOF;
}
/* Write out any pending data. */
if (stream->__mode.__write && __flshfp (stream, EOF) == EOF)
return EOF;
/* Make sure we know the current offset info. */
if (__stdio_check_offset (stream) == EOF)
return EOF;
/* We are moving the file position, so we are no longer at EOF. */
stream->__eof = 0;
if (stream->__pushed_back)
{
/* Discard the character pushed back by ungetc. */
stream->__bufp = stream->__pushback_bufp;
stream->__pushed_back = 0;
}
/* Check the WHENCE argument for validity, and process OFFSET
into an absolute position in O. By the end of this switch,
either we have returned, or O contains an absolute position. */
o = offset;
switch (whence)
{
default:
errno = EINVAL;
return EOF;
case SEEK_END:
/* We don't know where the end of the file is,
so seek to the position in the file the user asked
for, and then look where that is. */
if (stream->__io_funcs.__seek == NULL)
{
errno = ESPIPE;
return EOF;
}
else
{
fpos_t pos = (fpos_t) o;
if ((*stream->__io_funcs.__seek)
(stream->__cookie, &pos, SEEK_END) < 0)
{
if (errno == ESPIPE)
stream->__io_funcs.__seek = NULL;
return EOF;
}
stream->__offset = pos;
/* Make O be absolute, rather than
relative to the end of the file. */
o = pos;
}
/* Fall through to try an absolute seek. */
case SEEK_SET:
/* Make O be relative to the buffer. */
o -= stream->__target;
/* Make O be relative to the current position in the buffer. */
o -= stream->__bufp - stream->__buffer;
/* Fall through to see if we can do it by
moving the pointer around in the buffer. */
case SEEK_CUR:
/* If the offset is small enough, we can just
move the pointer around in the buffer. */
#if 0 /* Why did I think this would ever work??? */
if (stream->__put_limit > stream->__buffer)
{
/* We are writing. */
if (stream->__bufp + o >= stream->__buffer &&
stream->__put_limit > stream->__bufp + o &&
stream->__get_limit > stream->__bufp + o)
{
/* We have read all the data we will change soon.
We can just move the pointer around. */
stream->__bufp += o;
return 0;
}
else
{
/* Flush the buffer. */
if (__flshfp(stream, EOF) == EOF)
return EOF;
}
} else
#endif
if (o < 0 ?
(-o <= stream->__bufp - stream->__buffer) :
(o <= stream->__get_limit - stream->__bufp))
{
stream->__bufp += o;
return 0;
}
/* Turn it into an absolute seek. */
o += stream->__bufp - stream->__buffer;
o += stream->__target;
break;
}
if (o < 0)
{
/* Negative file position is meaningless. */
errno = EINVAL;
return -1;
}
/* O is now an absolute position, the new target. */
stream->__target = o;
/* Set bufp and both end pointers to the beginning of the buffer.
The next i/o will force a call to the input/output room function. */
stream->__bufp
= stream->__get_limit = stream->__put_limit = stream->__buffer;
/* Make sure __flshfp doesn't think the put_limit is at the beginning
of the buffer because of line-buffering magic. */
stream->__linebuf_active = 0;
/* If there is no seek function, seeks always fail. */
if (stream->__io_funcs.__seek == NULL)
{
/* This is preemptive, since we don't actually do the seeking.
But it makes more sense for fseek to to fail with ESPIPE
than for the next reading or writing operation to fail
that way. */
errno = ESPIPE;
return EOF;
}
/* Don't actually seek. The next reading or writing operation
will force a call to the input or output room function,
which will move to the target file position before reading or writing. */
return 0;
}

37
stdio/fsetpos.c Normal file
View File

@@ -0,0 +1,37 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
#undef fsetpos
/* Set the file position of STREAM to *POS. */
int
DEFUN(fsetpos, (stream, pos), FILE *stream AND CONST fpos_t *pos)
{
if (pos == NULL)
{
errno = EINVAL;
return EOF;
}
return fseek(stream, *pos, SEEK_SET);
}

54
stdio/ftell.c Normal file
View File

@@ -0,0 +1,54 @@
/* Copyright (C) 1991, 1992, 1994 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
/* Return the offset in bytes from the beginning
of the file of the file position of STREAM. */
long int
DEFUN(ftell, (stream), FILE *stream)
{
long int pos;
if (!__validfp (stream))
{
errno = EINVAL;
return -1L;
}
if (__stdio_check_offset (stream) == EOF)
return -1L;
/* Start with the file position associated with the beginning
of our buffer. */
pos = stream->__target;
if (stream->__pushed_back)
/* ungetc was just called, so our real buffer pointer is squirreled
away in STREAM->__pushback_bufp, not in STREAM->__bufp as normal.
Calling ungetc is supposed to decrement the file position. ANSI
says the file position is unspecified if you ungetc when the
position is zero; -1 seems as good as anything to me. */
pos += stream->__pushback_bufp - stream->__buffer - 1;
else
pos += stream->__bufp - stream->__buffer;
return pos;
}

208
stdio/fwrite.c Normal file
View File

@@ -0,0 +1,208 @@
/* Copyright (C) 1991, 1992, 1993, 1994 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
/* Write NMEMB chunks of SIZE bytes each from PTR onto STREAM. */
size_t
DEFUN(fwrite, (ptr, size, nmemb, stream),
CONST PTR ptr AND size_t size AND
size_t nmemb AND register FILE *stream)
{
register CONST unsigned char *p = (CONST unsigned char *) ptr;
register size_t to_write = size * nmemb;
register size_t written = 0;
int newlinep;
size_t buffer_space;
int default_func;
if (!__validfp (stream) || !stream->__mode.__write)
{
errno = EINVAL;
return 0;
}
if (ferror (stream))
return 0;
if (p == NULL || to_write == 0)
return 0;
if (!stream->__seen || stream->__put_limit == stream->__buffer)
{
/* This stream has never been seen before.
Calling __flshfp will give it a buffer
and I/O functions if it needs them. */
if (__flshfp (stream, *p++) == EOF)
return 0;
if (--to_write == 0)
return 1;
else
++written;
}
default_func
= stream->__room_funcs.__output == __default_room_functions.__output;
{
int save = errno;
if (__stdio_check_offset (stream) == EOF && errno != ESPIPE)
{
stream->__error = 1;
goto done;
}
errno = save;
}
if (stream->__buffer == NULL && default_func &&
stream->__offset == stream->__target)
write_through:
/* This is an unbuffered stream using the standard output
buffer-flushing function, so we just do a straight write. */
{
int count = (stream->__io_funcs.__write == NULL ? to_write :
(*stream->__io_funcs.__write) (stream->__cookie,
(CONST char *) p,
to_write));
if (count > 0)
{
written += count;
if (stream->__offset != -1)
{
stream->__offset += count;
stream->__target = stream->__offset;
}
to_write -= count;
p += count;
}
else
stream->__error = 1;
goto done;
}
/* We ignore the end pointer here since we want to find out how much space
is really in the buffer, even for a line-buffered stream. */
buffer_space = stream->__bufsize - (stream->__bufp - stream->__buffer);
newlinep = (stream->__linebuf &&
memchr ((CONST PTR) p, '\n', to_write) != NULL);
if (newlinep && stream->__bufp == stream->__buffer &&
stream->__offset == stream->__target)
/* The buffer's empty, and we want to write our data
out soon anyway, so just write it straight out. */
goto write_through;
if (stream->__bufsize == 0 && !default_func)
{
/* No buffer, and a special function.
We can't do much better than putc. */
while (to_write-- > 0)
{
if (__flshfp (stream, *p++) == EOF)
break;
else
++written;
}
}
else if (!default_func || buffer_space >= to_write)
fill_buffer:
/* There is enough room in the buffer for everything we
want to write or the user has specified his own output
buffer-flushing/expanding function. */
while (to_write > 0)
{
register size_t n = to_write;
if (n > buffer_space)
n = buffer_space;
buffer_space -= n;
written += n;
to_write -= n;
if (n < 20)
while (n-- > 0)
*stream->__bufp++ = *p++;
else
{
memcpy ((PTR) stream->__bufp, (PTR) p, n);
stream->__bufp += n;
p += n;
}
if (buffer_space == 0 || (to_write == 0 && newlinep))
{
/* We've filled the buffer, so flush it. */
if (fflush (stream) == EOF)
break;
/* Reset our record of the space available in the buffer,
since we have just flushed it. */
check_space:
buffer_space = (stream->__bufsize -
(stream->__bufp - stream->__buffer));
if (buffer_space == 0)
{
/* With a custom output-room function, flushing might
not create any buffer space. Try writing a single
character to create the space. */
if (__flshfp (stream, *p++) == EOF)
goto done;
++written;
--to_write;
goto check_space;
}
}
}
else
{
/* It won't all fit in the buffer. */
if (stream->__bufp != stream->__buffer)
{
/* There are characters in the buffer. Flush them. */
if (__flshfp (stream, EOF) == EOF)
goto done;
}
/* The buffer has been flushed.
Now either fill it or write directly. */
buffer_space = stream->__bufsize - (stream->__bufp - stream->__buffer);
if (stream->__offset == stream->__target &&
(buffer_space < to_write || newlinep))
/* What we have to write is bigger than the buffer,
or it contains a newline and we're line-buffered,
so write it out. */
goto write_through;
else
/* It will fit in the buffer. */
goto fill_buffer;
}
done:;
return (size_t) written / size;
}

31
stdio/gen-mpn-copy Normal file
View File

@@ -0,0 +1,31 @@
#!/bin/sh
translations='
pentium i386/i586
sparc8 sparc/sparc8
sparc9 sparc/sparc9
mc68000 m68k/m68000
mc68020 m68k/m68020
mc88100 m88k/m88100
mc88110 m88k/m88110
r3000 mips
r4000 mips/mips64
hppa1_0 hppa/hppa1.0
hppa1_1 hppa/hppa1.1
'
set $translations
while [ $# -ge 2 ]; do
gmp=$1 glibc=$2
shift; shift
echo 'mpn-found-1 := $(filter $(gmp-srcdir)/mpn/'$gmp'/%,$(mpn-found))
mpn-copy-1 := $(patsubst $(gmp-srcdir)/mpn/'$gmp'/%,$(sysdep_dir)/'$glibc\
'/%,$(mpn-found-1))
mpn-found := $(filter-out $(mpn-found-1),$(mpn-found))
mpn-copy-sysdep := $(mpn-copy-sysdep) $(mpn-copy-1)
$(mpn-copy-1): $(sysdep_dir)/'$glibc'/%: \
$(ignore gmp2glibc.sed) $(gmp-srcdir)/mpn/'$gmp'/%
$(gmp2glibc)'
done
exit 0

5
stdio/getc.c Normal file
View File

@@ -0,0 +1,5 @@
#include <ansidecl.h>
#include <stdio.h>
#undef getc
#define fgetc getc
#include <fgetc.c>

30
stdio/getchar.c Normal file
View File

@@ -0,0 +1,30 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#undef getchar
/* Read a character from stdin. */
int
DEFUN_VOID(getchar)
{
return __getc(stdin);
}

173
stdio/getdelim.c Normal file
View File

@@ -0,0 +1,173 @@
/* Copyright (C) 1991, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
(and null-terminate it). *LINEPTR is a pointer returned from malloc (or
NULL), pointing to *N characters of space. It is realloc'd as
necessary. Returns the number of characters read (not including the
null terminator), or -1 on error or EOF. */
ssize_t
DEFUN(__getdelim, (lineptr, n, terminator, stream),
char **lineptr AND size_t *n AND int terminator AND FILE *stream)
{
char *line, *p;
size_t size, copy;
if (!__validfp (stream) || lineptr == NULL || n == NULL)
{
errno = EINVAL;
return -1;
}
if (ferror (stream))
return -1;
/* Make sure we have a line buffer to start with. */
if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars. */
{
#ifndef MAX_CANON
#define MAX_CANON 256
#endif
line = realloc (*lineptr, MAX_CANON);
if (line == NULL)
return -1;
*lineptr = line;
*n = MAX_CANON;
}
line = *lineptr;
size = *n;
copy = size;
p = line;
if (stream->__buffer == NULL && stream->__userbuf)
{
/* Unbuffered stream. Not much optimization to do. */
while (1)
{
size_t len;
while (--copy > 0)
{
register int c = getc (stream);
if (c == EOF)
goto lose;
else if ((*p++ = c) == terminator)
goto win;
}
/* Need to enlarge the line buffer. */
len = p - line;
size *= 2;
line = realloc (line, size);
if (line == NULL)
goto lose;
*lineptr = line;
*n = size;
p = line + len;
copy = size - len;
}
}
else
{
/* Leave space for the terminating null. */
--copy;
if (!stream->__seen || stream->__buffer == NULL || stream->__pushed_back)
{
/* Do one with getc to allocate a buffer. */
int c = getc (stream);
if (c == EOF)
goto lose;
*p++ = c;
if (c == terminator)
goto win;
--copy;
}
while (1)
{
size_t i;
char *found;
i = stream->__get_limit - stream->__bufp;
if (i == 0)
{
/* Refill the buffer. */
int c = __fillbf (stream);
if (c == EOF)
goto lose;
*p++ = c;
if (c == terminator)
goto win;
--copy;
i = stream->__get_limit - stream->__bufp;
}
if (i > copy)
i = copy;
found = (char *) __memccpy ((PTR) p, stream->__bufp, terminator, i);
if (found != NULL)
{
stream->__bufp += found - p;
p = found;
goto win;
}
stream->__bufp += i;
p += i;
copy -= i;
if (copy == 0)
{
/* Need to enlarge the line buffer. */
size_t len = p - line;
size *= 2;
line = realloc (line, size);
if (line == NULL)
goto lose;
*lineptr = line;
*n = size;
p = line + len;
copy = size - len;
/* Leave space for the terminating null. */
--copy;
}
}
}
lose:
if (p == *lineptr)
return -1;
/* Return a partial line since we got an error in the middle. */
win:
*p = '\0';
return p - *lineptr;
}
weak_alias (__getdelim, getdelim)

33
stdio/getline.c Normal file
View File

@@ -0,0 +1,33 @@
/* Copyright (C) 1991, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stddef.h>
#include <stdio.h>
#undef __getline
/* Like getdelim, but always looks for a newline. */
ssize_t
DEFUN(__getline, (lineptr, n, stream),
char **lineptr AND size_t *n AND FILE *stream)
{
return __getdelim (lineptr, n, '\n', stream);
}
weak_alias (__getline, getline)

59
stdio/gets.c Normal file
View File

@@ -0,0 +1,59 @@
/* Copyright (C) 1991, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
link_warning ("the `gets' function is unreliable and should not be used.")
/* Read a newline-terminated string from stdin into S,
removing the trailing newline. Return S or NULL. */
char *
DEFUN(gets, (s), char *s)
{
register char *p = s;
register int c;
FILE *stream = stdin;
if (!__validfp(stream) || p == NULL)
{
errno = EINVAL;
return NULL;
}
if (feof(stream) || ferror(stream))
return NULL;
while ((c = getchar()) != EOF)
if (c == '\n')
break;
else
*p++ = c;
*p = '\0';
/* Return null if we had an error, or if we got EOF
before writing any characters. */
if (ferror (stream) || (feof (stream) && p == s))
return NULL;
return s;
}

33
stdio/getw.c Normal file
View File

@@ -0,0 +1,33 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
/* Read a word (int) from STREAM. */
int
DEFUN(getw, (stream), FILE *stream)
{
int w;
/* Is there a better way? */
if (fread((PTR) &w, sizeof(w), 1, stream) != 1)
return(EOF);
return(w);
}

114
stdio/glue.c Normal file
View File

@@ -0,0 +1,114 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
/* This file provides glue between Unix stdio and GNU stdio.
It supports use of Unix stdio `getc' and `putc' (and, by extension,
`getchar' and `putchar') macros on GNU stdio streams (they are slow, but
they work). It also supports all stdio operations (including Unix
`getc' and `putc') on Unix's stdin, stdout, and stderr (the elements of
`_iob').
The reasoning behind this is to allow programs (and especially
libraries) compiled with Unix header files to work with the GNU C
library. */
#include <ansidecl.h>
#include <stdio.h>
#include <errno.h>
typedef union
{
struct
{
int magic;
FILE **streamp; /* Overlaps GNU stdio `bufp' member. */
/* These two overlap the GNU stdio `get_limit' and `put_limit'
members. They must be <= `streamp'/`bufp' for GNU getc and putc
to do the right thing. */
FILE **streamp2, **streamp3;
} glue;
struct _iobuf
{
int _cnt;
unsigned char *_ptr;
unsigned char *_base;
int _bufsiz;
short int _flag;
char _file;
} unix_iobuf;
FILE gnu_stream;
} unix_FILE;
/* These are the Unix stdio's stdin, stdout, and stderr.
In Unix stdin is (&_iob[0]), stdout is (&_iob[1]), and stderr is
(&_iob[2]). The magic number marks these as glued streams. The
__validfp macro in stdio.h is used by every stdio function. It checks
for glued streams, and replaces them with the GNU stdio stream. */
unix_FILE _iob[] =
{
#define S(name) { { _GLUEMAGIC, &name, &name, &name } }
S (stdin),
S (stdout),
S (stderr),
#undef S
};
/* Called by the Unix stdio `getc' macro.
The macro is assumed to look something like:
(--file->_cnt < 0 ? _filbuf (file) ...)
In a Unix stdio FILE `_cnt' is the first element.
In a GNU stdio or glued FILE, the first element is the magic number. */
int
DEFUN(_filbuf, (file), unix_FILE *file)
{
switch (++file->glue.magic) /* Compensate for Unix getc's decrement. */
{
case _GLUEMAGIC:
/* This is a glued stream. */
return getc (*file->glue.streamp);
case _IOMAGIC:
/* This is a normal GNU stdio stream. */
return getc ((FILE *) file);
default:
/* Bogus stream. */
errno = EINVAL;
return EOF;
}
}
/* Called by the Unix stdio `putc' macro. Much like getc, above. */
int
DEFUN(_flsbuf, (c, file),
int c AND unix_FILE *file)
{
/* Compensate for putc's decrement. */
switch (++file->glue.magic)
{
case _GLUEMAGIC:
return putc (c, *file->glue.streamp);
case _IOMAGIC:
return putc (c, (FILE *) file);
default:
errno = EINVAL;
return EOF;
}
}

283
stdio/gmp-impl.h Normal file
View File

@@ -0,0 +1,283 @@
/* Include file for internal GNU MP types and definitions.
Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
The GNU MP 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 Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if ! defined (alloca)
#if defined (__GNUC__) || defined (__sparc__) || defined (sparc)
#define alloca __builtin_alloca
#endif
#endif
#ifndef NULL
#define NULL 0L
#endif
#if ! defined (__GNUC__)
#define inline /* Empty */
void *alloca();
#endif
#define ABS(x) (x >= 0 ? x : -x)
#define MIN(l,o) ((l) < (o) ? (l) : (o))
#define MAX(h,i) ((h) > (i) ? (h) : (i))
#include "gmp-mparam.h"
/* #include "longlong.h" */
#ifdef __STDC__
void *malloc (size_t);
void *realloc (void *, size_t);
void free (void *);
extern void * (*_mp_allocate_func) (size_t);
extern void * (*_mp_reallocate_func) (void *, size_t, size_t);
extern void (*_mp_free_func) (void *, size_t);
void *_mp_default_allocate (size_t);
void *_mp_default_reallocate (void *, size_t, size_t);
void _mp_default_free (void *, size_t);
#else
#define const /* Empty */
#define signed /* Empty */
void *malloc ();
void *realloc ();
void free ();
extern void * (*_mp_allocate_func) ();
extern void * (*_mp_reallocate_func) ();
extern void (*_mp_free_func) ();
void *_mp_default_allocate ();
void *_mp_default_reallocate ();
void _mp_default_free ();
#endif
/* Copy NLIMBS *limbs* from SRC to DST. */
#define MPN_COPY_INCR(DST, SRC, NLIMBS) \
do { \
mp_size_t __i; \
for (__i = 0; __i < (NLIMBS); __i++) \
(DST)[__i] = (SRC)[__i]; \
} while (0)
#define MPN_COPY_DECR(DST, SRC, NLIMBS) \
do { \
mp_size_t __i; \
for (__i = (NLIMBS) - 1; __i >= 0; __i--) \
(DST)[__i] = (SRC)[__i]; \
} while (0)
#define MPN_COPY MPN_COPY_INCR
/* Zero NLIMBS *limbs* AT DST. */
#define MPN_ZERO(DST, NLIMBS) \
do { \
mp_size_t __i; \
for (__i = 0; __i < (NLIMBS); __i++) \
(DST)[__i] = 0; \
} while (0)
#define MPN_NORMALIZE(DST, NLIMBS) \
do { \
while (NLIMBS > 0) \
{ \
if ((DST)[(NLIMBS) - 1] != 0) \
break; \
NLIMBS--; \
} \
} while (0)
#define MPN_NORMALIZE_NOT_ZERO(DST, NLIMBS) \
do { \
while (1) \
{ \
if ((DST)[(NLIMBS) - 1] != 0) \
break; \
NLIMBS--; \
} \
} while (0)
/* Swap (mp_ptr, mp_size_t) (U, UL) with (V, VL) */
#define MPN_SWAP(u, l, v, m) \
do { \
{ mp_ptr _; _ = (u), (u) = (v), (v) = _;} \
{ mp_size_t _; _ = (l), (l) = (m), (m) = _;} \
} while (0)
/* Return true iff the limb X has less bits than the limb Y. */
#define MPN_LESS_BITS_LIMB(x,y) ((x) < (y) && (x) < ((x) ^ (y)))
/* Return true iff (mp_ptr, mp_size_t) (U, UL) has less bits than (V, VL). */
#define MPN_LESS_BITS(u, l, v, m) \
((l) < (m) \
|| ((l) == (m) && (l) != 0 && MPN_LESS_BITS_LIMB ((u)[(l - 1)], (v)[(l) - 1])))
/* Return true iff (mp_ptr, mp_size_t) (U, UL) has more bits than (V, VL). */
#define MPN_MORE_BITS(u, l, v, m) MPN_LESS_BITS (v, m, u, l)
/* Perform twos complement on (mp_ptr, mp_size_t) (U, UL),
putting result at (v, VL). Precondition: U[0] != 0. */
#define MPN_COMPL_INCR(u, v, l) \
do { \
mp_size_t _ = 0; \
(u)[0] = -(v)[_]; \
while (_++ < (l)) \
(u)[_] = ~(v)[_]; \
} while (0)
#define MPN_COMPL MPN_COMPL_INCR
/* Initialize the MP_INT X with space for NLIMBS limbs.
X should be a temporary variable, and it will be automatically
cleared out when the running function returns.
We use __x here to make it possible to accept both mpz_ptr and mpz_t
arguments. */
#define MPZ_TMP_INIT(X, NLIMBS) \
do { \
mpz_ptr __x = (X); \
__x->alloc = (NLIMBS); \
__x->d = (mp_ptr) alloca ((NLIMBS) * BYTES_PER_MP_LIMB); \
} while (0)
#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
do { \
if ((size) < KARATSUBA_THRESHOLD) \
____mpn_mul_n_basecase (prodp, up, vp, size); \
else \
____mpn_mul_n (prodp, up, vp, size, tspace); \
} while (0);
#define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \
do { \
if ((size) < KARATSUBA_THRESHOLD) \
____mpn_sqr_n_basecase (prodp, up, size); \
else \
____mpn_sqr_n (prodp, up, size, tspace); \
} while (0);
/* Structure for conversion between internal binary format and
strings in base 2..36. */
struct bases
{
/* Number of digits in the conversion base that always fits in
an mp_limb. For example, for base 10 this is 10, since
2**32 = 4294967296 has ten digits. */
int chars_per_limb;
/* log(2)/log(conversion_base) */
float chars_per_bit_exactly;
/* big_base is conversion_base**chars_per_limb, i.e. the biggest
number that fits a word, built by factors of conversion_base.
Exception: For 2, 4, 8, etc, big_base is log2(base), i.e. the
number of bits used to represent each digit in the base. */
mp_limb big_base;
/* big_base_inverted is a BITS_PER_MP_LIMB bit approximation to
1/big_base, represented as a fixed-point number. Instead of
dividing by big_base an application can choose to multiply
by big_base_inverted. */
mp_limb big_base_inverted;
};
extern const struct bases __mp_bases[];
extern mp_size_t __gmp_default_fp_limb_precision;
/* Divide the two-limb number in (NH,,NL) by D, with DI being a 32 bit
approximation to (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB).
Put the quotient in Q and the remainder in R. */
#define udiv_qrnnd_preinv(q, r, nh, nl, d, di) \
do { \
mp_limb _q, _ql, _r; \
mp_limb _xh, _xl; \
umul_ppmm (_q, _ql, (nh), (di)); \
_q += (nh); /* DI is 2**BITS_PER_MP_LIMB too small */\
umul_ppmm (_xh, _xl, _q, (d)); \
sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \
if (_xh != 0) \
{ \
sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
_q += 1; \
if (_xh != 0) \
{ \
sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
_q += 1; \
} \
} \
if (_r >= (d)) \
{ \
_r -= (d); \
_q += 1; \
} \
(r) = _r; \
(q) = _q; \
} while (0)
#define udiv_qrnnd_preinv2gen(q, r, nh, nl, d, di, dnorm, lgup) \
do { \
mp_limb n2, n10, n1, nadj, q1; \
mp_limb _xh, _xl; \
n2 = ((nh) << (BITS_PER_MP_LIMB - (lgup))) + ((nl) >> 1 >> (l - 1));\
n10 = (nl) << (BITS_PER_MP_LIMB - (lgup)); \
n1 = ((mp_limb_signed) n10 >> (BITS_PER_MP_LIMB - 1)); \
nadj = n10 + (n1 & (dnorm)); \
umul_ppmm (_xh, _xl, di, n2 - n1); \
add_ssaaaa (_xh, _xl, _xh, _xl, 0, nadj); \
q1 = ~(n2 + _xh); \
umul_ppmm (_xh, _xl, q1, d); \
add_ssaaaa (_xh, _xl, _xh, _xl, nh, nl); \
_xh -= (d); \
(r) = _xl + ((d) & _xh); \
(q) = _xh - q1; \
} while (0)
#define udiv_qrnnd_preinv2norm(q, r, nh, nl, d, di) \
do { \
mp_limb n2, n10, n1, nadj, q1; \
mp_limb _xh, _xl; \
n2 = (nh); \
n10 = (nl); \
n1 = ((mp_limb_signed) n10 >> (BITS_PER_MP_LIMB - 1)); \
nadj = n10 + (n1 & (d)); \
umul_ppmm (_xh, _xl, di, n2 - n1); \
add_ssaaaa (_xh, _xl, _xh, _xl, 0, nadj); \
q1 = ~(n2 + _xh); \
umul_ppmm (_xh, _xl, q1, d); \
add_ssaaaa (_xh, _xl, _xh, _xl, nh, nl); \
_xh -= (d); \
(r) = _xl + ((d) & _xh); \
(q) = _xh - q1; \
} while (0)
#if defined (__GNUC__)
/* Define stuff for longlong.h asm macros. */
#if __GNUC_NEW_ATTR_MODE_SYNTAX
typedef unsigned int UQItype __attribute__ ((mode ("QI")));
typedef int SItype __attribute__ ((mode ("SI")));
typedef unsigned int USItype __attribute__ ((mode ("SI")));
typedef int DItype __attribute__ ((mode ("DI")));
typedef unsigned int UDItype __attribute__ ((mode ("DI")));
#else
typedef unsigned int UQItype __attribute__ ((mode (QI)));
typedef int SItype __attribute__ ((mode (SI)));
typedef unsigned int USItype __attribute__ ((mode (SI)));
typedef int DItype __attribute__ ((mode (DI)));
typedef unsigned int UDItype __attribute__ ((mode (DI)));
#endif
#endif
typedef mp_limb UWtype;
typedef unsigned int UHWtype;
#define W_TYPE_SIZE BITS_PER_MP_LIMB

525
stdio/gmp.h Normal file
View File

@@ -0,0 +1,525 @@
/* gmp.h -- Definitions for GNU multiple precision functions.
Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
The GNU MP 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 Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef __GMP_H__
#ifndef __GNU_MP__
#define __need_size_t
#include <stddef.h>
#ifdef __STDC__
#define __gmp_const const
#else
#define __gmp_const
#endif
#ifdef __GNUC__
#define __gmp_inline inline
#else
#define __gmp_inline
#endif
#ifdef _SHORT_LIMB
typedef unsigned int mp_limb;
typedef int mp_limb_signed;
#else
typedef unsigned long int mp_limb;
typedef long int mp_limb_signed;
#endif
typedef mp_limb * mp_ptr;
typedef __gmp_const mp_limb * mp_srcptr;
typedef int mp_size_t;
typedef long int mp_exp_t;
#ifndef __MP_SMALL__
typedef struct
{
long int alloc; /* Number of *limbs* allocated and pointed
to by the D field. */
long int size; /* abs(SIZE) is the number of limbs
the last field points to. If SIZE
is negative this is a negative
number. */
mp_limb *d; /* Pointer to the limbs. */
} __mpz_struct;
#else
typedef struct
{
short int alloc; /* Number of *limbs* allocated and pointed
to by the D field. */
short int size; /* abs(SIZE) is the number of limbs
the last field points to. If SIZE
is negative this is a negative
number. */
mp_limb *d; /* Pointer to the limbs. */
} __mpz_struct;
#endif
#endif /* __GNU_MP__ */
/* User-visible types. */
typedef __mpz_struct MP_INT;
typedef __mpz_struct mpz_t[1];
/* Structure for rational numbers. Zero is represented as 0/any, i.e.
the denominator is ignored. Negative numbers have the sign in
the numerator. */
typedef struct
{
__mpz_struct num;
__mpz_struct den;
#if 0
long int num_alloc; /* Number of limbs allocated
for the numerator. */
long int num_size; /* The absolute value of this field is the
length of the numerator; the sign is the
sign of the entire rational number. */
mp_ptr num; /* Pointer to the numerator limbs. */
long int den_alloc; /* Number of limbs allocated
for the denominator. */
long int den_size; /* Length of the denominator. (This field
should always be positive.) */
mp_ptr den; /* Pointer to the denominator limbs. */
#endif
} __mpq_struct;
typedef __mpq_struct MP_RAT;
typedef __mpq_struct mpq_t[1];
typedef struct
{
mp_size_t alloc; /* Number of *limbs* allocated and pointed
to by the D field. */
mp_size_t prec; /* Max precision, in number of `mp_limb's.
Set by mpf_init and modified by
mpf_set_prec. */
mp_size_t size; /* abs(SIZE) is the number of limbs
the last field points to. If SIZE
is negative this is a negative
number. */
mp_exp_t exp; /* Exponent, in the base of `mp_limb'. */
mp_limb *d; /* Pointer to the limbs. */
} __mpf_struct;
/* typedef __mpf_struct MP_FLOAT; */
typedef __mpf_struct mpf_t[1];
/* Types for function declarations in gmp files. */
/* ??? Should not pollute user name space ??? */
typedef __gmp_const __mpz_struct *mpz_srcptr;
typedef __mpz_struct *mpz_ptr;
typedef __gmp_const __mpf_struct *mpf_srcptr;
typedef __mpf_struct *mpf_ptr;
typedef __gmp_const __mpq_struct *mpq_srcptr;
typedef __mpq_struct *mpq_ptr;
#ifdef __STDC__
#define _PROTO(x) x
#else
#define _PROTO(x) ()
#endif
void mp_set_memory_functions _PROTO((void *(*) (size_t),
void *(*) (void *, size_t, size_t),
void (*) (void *, size_t)));
/**************** Integer (i.e. Z) routines. ****************/
void *_mpz_realloc _PROTO ((mpz_ptr, mp_size_t));
void mpz_abs _PROTO ((mpz_ptr, mpz_srcptr));
void mpz_add _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
void mpz_add_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_and _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
void mpz_clear _PROTO ((mpz_ptr));
void mpz_clrbit _PROTO ((mpz_ptr, unsigned long int));
int mpz_cmp _PROTO ((mpz_srcptr, mpz_srcptr));
int mpz_cmp_si _PROTO ((mpz_srcptr, signed long int));
int mpz_cmp_ui _PROTO ((mpz_srcptr, unsigned long int));
void mpz_com _PROTO ((mpz_ptr, mpz_srcptr));
void mpz_div_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_fac_ui _PROTO ((mpz_ptr, unsigned long int));
void mpz_gcd _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
unsigned long int mpz_gcd_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_gcdext _PROTO ((mpz_ptr, mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
/* signed */ long int mpz_get_si _PROTO ((mpz_srcptr));
char *mpz_get_str _PROTO ((char *, int, mpz_srcptr));
unsigned long int mpz_get_ui _PROTO ((mpz_srcptr));
mp_limb mpz_getlimbn _PROTO ((mpz_srcptr, mp_size_t));
mp_size_t mpz_hamdist _PROTO ((mpz_srcptr, mpz_srcptr));
void mpz_init _PROTO ((mpz_ptr));
#ifdef FILE
void mpz_inp_raw _PROTO ((mpz_ptr, FILE *));
int mpz_inp_str _PROTO ((mpz_ptr, FILE *, int));
#endif
void mpz_ior _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
void mpz_init_set _PROTO ((mpz_ptr, mpz_srcptr));
void mpz_init_set_si _PROTO ((mpz_ptr, signed long int));
int mpz_init_set_str _PROTO ((mpz_ptr, const char *, int));
void mpz_init_set_ui _PROTO ((mpz_ptr, unsigned long int));
void mpz_lcm _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
void mpz_mod_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_mul _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
void mpz_mul_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_mul_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_neg _PROTO ((mpz_ptr, mpz_srcptr));
#ifdef FILE
void mpz_out_raw _PROTO ((FILE *, mpz_srcptr));
void mpz_out_str _PROTO ((FILE *, int, mpz_srcptr));
#endif
int mpz_perfect_square_p _PROTO ((mpz_srcptr));
mp_size_t mpz_popcount _PROTO ((mpz_srcptr));
void mpz_pow_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_powm _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr));
void mpz_powm_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int, mpz_srcptr));
int mpz_probab_prime_p _PROTO ((mpz_srcptr, int));
void mpz_random _PROTO ((mpz_ptr, mp_size_t));
void mpz_random2 _PROTO ((mpz_ptr, mp_size_t));
void mpz_set _PROTO ((mpz_ptr, mpz_srcptr));
void mpz_set_si _PROTO ((mpz_ptr, signed long int));
int mpz_set_str _PROTO ((mpz_ptr, const char *, int));
void mpz_set_ui _PROTO ((mpz_ptr, unsigned long int));
size_t mpz_size _PROTO ((mpz_srcptr));
size_t mpz_sizeinbase _PROTO ((mpz_srcptr, int));
void mpz_sqrt _PROTO ((mpz_ptr, mpz_srcptr));
void mpz_sqrtrem _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr));
void mpz_sub _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
void mpz_sub_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_ui_pow_ui _PROTO ((mpz_ptr, unsigned long int, unsigned long int));
void mpz_fdiv_q _PROTO((mpz_ptr, mpz_srcptr, mpz_srcptr));
unsigned long int mpz_fdiv_q_ui _PROTO((mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_fdiv_qr _PROTO((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
unsigned long int mpz_fdiv_qr_ui _PROTO((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_fdiv_r _PROTO((mpz_ptr, mpz_srcptr, mpz_srcptr));
unsigned long int mpz_fdiv_r_ui _PROTO((mpz_ptr, mpz_srcptr, unsigned long int));
unsigned long int mpz_fdiv_ui _PROTO((mpz_srcptr, unsigned long int));
void mpz_tdiv_q _PROTO((mpz_ptr, mpz_srcptr, mpz_srcptr));
void mpz_tdiv_q_ui _PROTO((mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_tdiv_qr _PROTO((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
void mpz_tdiv_qr_ui _PROTO((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
void mpz_tdiv_r _PROTO((mpz_ptr, mpz_srcptr, mpz_srcptr));
void mpz_tdiv_r_ui _PROTO((mpz_ptr, mpz_srcptr, unsigned long int));
/**************** Rational (i.e. Q) routines. ****************/
void mpq_init _PROTO ((mpq_ptr));
void mpq_clear _PROTO ((mpq_ptr));
void mpq_set _PROTO ((mpq_ptr, mpq_srcptr));
void mpq_set_ui _PROTO ((mpq_ptr, unsigned long int, unsigned long int));
void mpq_set_si _PROTO ((mpq_ptr, signed long int, unsigned long int));
void mpq_add _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr));
void mpq_sub _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr));
void mpq_mul _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr));
void mpq_div _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr));
void mpq_neg _PROTO ((mpq_ptr, mpq_srcptr));
int mpq_cmp _PROTO ((mpq_srcptr, mpq_srcptr));
void mpq_inv _PROTO ((mpq_ptr, mpq_srcptr));
void mpq_set_num _PROTO ((mpq_ptr, mpz_srcptr));
void mpq_set_den _PROTO ((mpq_ptr, mpz_srcptr));
void mpq_get_num _PROTO ((mpz_ptr, mpq_srcptr));
void mpq_get_den _PROTO ((mpz_ptr, mpq_srcptr));
/**************** Float (i.e. F) routines. ****************/
void mpf_abs _PROTO ((mpf_ptr, mpf_srcptr));
void mpf_add _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr));
void mpf_add_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
void mpf_clear _PROTO ((mpf_ptr));
int mpf_cmp _PROTO ((mpf_srcptr, mpf_srcptr));
int mpf_cmp_si _PROTO ((mpf_srcptr, long int));
int mpf_cmp_ui _PROTO ((mpf_srcptr, unsigned long int));
void mpf_div _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr));
void mpf_div_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
void mpf_div_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
void mpf_dump _PROTO ((mpf_srcptr));
char *mpf_get_str _PROTO ((char *, mp_exp_t *, int, size_t, mpf_srcptr));
void mpf_init _PROTO ((mpf_ptr));
void mpf_init2 _PROTO ((mpf_ptr, mp_size_t));
#ifdef FILE
void mpf_inp_str _PROTO ((mpf_ptr, FILE *, int));
#endif
void mpf_init_set _PROTO ((mpf_ptr, mpf_srcptr));
void mpf_init_set_d _PROTO ((mpf_ptr, double));
void mpf_init_set_si _PROTO ((mpf_ptr, long int));
int mpf_init_set_str _PROTO ((mpf_ptr, char *, int));
void mpf_init_set_ui _PROTO ((mpf_ptr, unsigned long int));
void mpf_mul _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr));
void mpf_mul_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
void mpf_mul_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
void mpf_neg _PROTO ((mpf_ptr, mpf_srcptr));
#ifdef FILE
void mpf_out_str _PROTO ((mpf_ptr, int, size_t, FILE *));
#endif
void mpf_set _PROTO ((mpf_ptr, mpf_srcptr));
void mpf_set_d _PROTO ((mpf_ptr, double));
mp_size_t mpf_set_default_prec _PROTO ((mp_size_t));
void mpf_set_si _PROTO ((mpf_ptr, long int));
int mpf_set_str _PROTO ((mpf_ptr, const char *, int));
void mpf_set_ui _PROTO ((mpf_ptr, unsigned long int));
size_t mpf_size _PROTO ((mpf_srcptr));
void mpf_sqrt _PROTO ((mpf_ptr, mpf_srcptr));
void mpf_sqrt_ui _PROTO ((mpf_ptr, unsigned long int));
void mpf_sub _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr));
void mpf_sub_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
void mpf_ui_div _PROTO ((mpf_ptr, unsigned long int, mpf_srcptr));
/************ Low level positive-integer (i.e. N) routines. ************/
/* This is ugly, but we need to make usr calls reach the prefixed function. */
#define mpn_add_n __mpn_add_n
#define mpn_sub_n __mpn_sub_n
#define mpn_mul_1 __mpn_mul_1
#define mpn_addmul_1 __mpn_addmul_1
#define mpn_submul_1 __mpn_submul_1
#define mpn_lshift __mpn_lshift
#define mpn_rshift __mpn_rshift
#define mpn_sub __mpn_sub
#define mpn_add __mpn_add
#define mpn_normal_size __mpn_normal_size
#define mpn_cmp __mpn_cmp
#define mpn_add_1 __mpn_add_1
#define mpn_sub_1 __mpn_sub_1
#define mpn_mul_n __mpn_mul_n
#define mpn_mul __mpn_mul
#define mpn_divmod __mpn_divmod
#define mpn_divmod_1 __mpn_divmod_1
#define mpn_mod_1 __mpn_mod_1
#define mpn_sqrt __mpn_sqrt
#define mpn_next_bit_set __mpn_next_bit_set
#define mpn_popcount __mpn_popcount
#define mpn_hamdist __mpn_hamdist
#define mpn_random2 __mpn_random2
#define mpn_set_str __mpn_set_str
#define mpn_get_str __mpn_get_str
#define mpn_gcd_1 __mpn_gcd_1
mp_limb __mpn_add_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
mp_limb __mpn_sub_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
mp_limb __mpn_mul _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t));
void __mpn_mul_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
mp_limb __mpn_mul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb));
mp_limb __mpn_addmul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb));
mp_limb __mpn_submul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb));
mp_limb __mpn_divmod _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t));
mp_limb __mpn_divmod_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb));
mp_limb __mpn_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb));
mp_limb __mpn_lshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int));
mp_limb __mpn_rshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int));
mp_size_t __mpn_sqrt _PROTO ((mp_ptr, mp_ptr, mp_srcptr, mp_size_t));
int __mpn_cmp _PROTO ((mp_srcptr, mp_srcptr, mp_size_t));
mp_size_t __mpn_next_bit_set _PROTO ((mp_srcptr, mp_size_t));
mp_size_t __mpn_popcount _PROTO ((mp_srcptr, mp_size_t));
mp_size_t __mpn_hamdist _PROTO ((mp_srcptr, mp_srcptr, mp_size_t));
void __mpn_random2 _PROTO ((mp_ptr, mp_size_t));
mp_size_t __mpn_set_str _PROTO ((mp_ptr, const unsigned char *, size_t, int));
size_t __mpn_get_str _PROTO ((unsigned char *, int, mp_ptr, mp_size_t));
mp_limb __mpn_gcd_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb));
static __gmp_inline mp_limb
#if __STDC__
__mpn_add_1 (register mp_ptr res_ptr,
register mp_srcptr s1_ptr,
register mp_size_t s1_size,
register mp_limb s2_limb)
#else
__mpn_add_1 (res_ptr, s1_ptr, s1_size, s2_limb)
register mp_ptr res_ptr;
register mp_srcptr s1_ptr;
register mp_size_t s1_size;
register mp_limb s2_limb;
#endif
{
register mp_limb x;
x = *s1_ptr++;
s2_limb = x + s2_limb;
*res_ptr++ = s2_limb;
if (s2_limb < x)
{
while (--s1_size != 0)
{
x = *s1_ptr++ + 1;
*res_ptr++ = x;
if (x != 0)
goto fin;
}
return 1;
}
fin:
if (res_ptr != s1_ptr)
{
mp_size_t i;
for (i = 0; i < s1_size - 1; i++)
res_ptr[i] = s1_ptr[i];
}
return 0;
}
static __gmp_inline mp_limb
#if __STDC__
__mpn_add (register mp_ptr res_ptr,
register mp_srcptr s1_ptr,
register mp_size_t s1_size,
register mp_srcptr s2_ptr,
register mp_size_t s2_size)
#else
__mpn_add (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size)
register mp_ptr res_ptr;
register mp_srcptr s1_ptr;
register mp_size_t s1_size;
register mp_srcptr s2_ptr;
register mp_size_t s2_size;
#endif
{
mp_limb cy_limb = 0;
if (s2_size != 0)
cy_limb = __mpn_add_n (res_ptr, s1_ptr, s2_ptr, s2_size);
if (s1_size - s2_size != 0)
cy_limb = __mpn_add_1 (res_ptr + s2_size,
s1_ptr + s2_size,
s1_size - s2_size,
cy_limb);
return cy_limb;
}
static __gmp_inline mp_limb
#if __STDC__
__mpn_sub_1 (register mp_ptr res_ptr,
register mp_srcptr s1_ptr,
register mp_size_t s1_size,
register mp_limb s2_limb)
#else
__mpn_sub_1 (res_ptr, s1_ptr, s1_size, s2_limb)
register mp_ptr res_ptr;
register mp_srcptr s1_ptr;
register mp_size_t s1_size;
register mp_limb s2_limb;
#endif
{
register mp_limb x;
x = *s1_ptr++;
s2_limb = x - s2_limb;
*res_ptr++ = s2_limb;
if (s2_limb > x)
{
while (--s1_size != 0)
{
x = *s1_ptr++;
*res_ptr++ = x - 1;
if (x != 0)
goto fin;
}
return 1;
}
fin:
if (res_ptr != s1_ptr)
{
mp_size_t i;
for (i = 0; i < s1_size - 1; i++)
res_ptr[i] = s1_ptr[i];
}
return 0;
}
static __gmp_inline mp_limb
#if __STDC__
__mpn_sub (register mp_ptr res_ptr,
register mp_srcptr s1_ptr,
register mp_size_t s1_size,
register mp_srcptr s2_ptr,
register mp_size_t s2_size)
#else
__mpn_sub (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size)
register mp_ptr res_ptr;
register mp_srcptr s1_ptr;
register mp_size_t s1_size;
register mp_srcptr s2_ptr;
register mp_size_t s2_size;
#endif
{
mp_limb cy_limb = 0;
if (s2_size != 0)
cy_limb = __mpn_sub_n (res_ptr, s1_ptr, s2_ptr, s2_size);
if (s1_size - s2_size != 0)
cy_limb = __mpn_sub_1 (res_ptr + s2_size,
s1_ptr + s2_size,
s1_size - s2_size,
cy_limb);
return cy_limb;
}
static __gmp_inline mp_size_t
#if __STDC__
__mpn_normal_size (mp_srcptr ptr, mp_size_t size)
#else
__mpn_normal_size (ptr, size)
mp_srcptr ptr;
mp_size_t size;
#endif
{
while (size)
{
size--;
if (ptr[size] != 0)
return size + 1;
}
return 0;
}
/* Compatibility with GMP 1. */
#define mpz_mdiv mpz_fdiv_q
#define mpz_mdivmod mpz_fdiv_qr
#define mpz_mmod mpz_fdiv_r
#define mpz_mdiv_ui mpz_fdiv_q_ui
#define mpz_mdivmod_ui(q,r,n,d) \
((r == 0) ? mpz_fdiv_q_ui (q,n,d) : mpz_fdiv_qr_ui (q,r,n,d))
#define mpz_mmod_ui(r,n,d) \
((r == 0) ? mpz_fdiv_ui (n,d) : mpz_fdiv_r_ui (r,n,d))
/* ??? Before release...
#define mpz_div_2exp mpz_fdiv_q_2exp
#define mpz_mod_2exp mpz_fdiv_r_2exp
*/
/* Useful synonyms, but not quite compatible with GMP 1. */
#define mpz_div mpz_fdiv_q
#define mpz_divmod mpz_fdiv_qr
#define mpz_mod mpz_fdiv_r
#define mpz_div_ui mpz_fdiv_q_ui
#define mpz_divmod_ui mpz_fdiv_qr_ui
#define mpz_mod_ui mpz_fdiv_r_ui
#define __GNU_MP__ 2
#define __GNU_MP_VERSION 2
#define __GNU_MP_VERSION_MINOR -900 /* ??? */
#define __GMP_H__
#endif /* __GMP_H__ */

667
stdio/internals.c Normal file
View File

@@ -0,0 +1,667 @@
/* Copyright (C) 1991, 1992, 1993, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Make sure that FP has its functions set. */
void
DEFUN(__stdio_check_funcs, (fp), register FILE *fp)
{
if (!fp->__seen)
{
/* Initialize the stream's info, including buffering info.
This may give a buffer, change I/O functions, etc.
If no buffer is set (and the stream is not made explicitly
unbuffered), we allocate a buffer below, using the bufsize
set by this function. */
extern void EXFUN(__stdio_init_stream, (FILE *));
fp->__room_funcs = __default_room_functions;
fp->__io_funcs = __default_io_functions;
__stdio_init_stream (fp);
fp->__seen = 1;
}
}
/* Minimum size of a buffer we will allocate by default.
If this much memory is not available,
the stream in question will be made unbuffered instead. */
#define MIN_BUFSIZE 128
/* Figure out what kind of buffering (none, line, or full)
and what buffer size to give FP. */
static void
DEFUN(init_stream, (fp), register FILE *fp)
{
__stdio_check_funcs (fp);
if (fp->__buffer == NULL && !fp->__userbuf)
{
int save;
if (fp->__bufsize == 0)
fp->__bufsize = BUFSIZ;
/* Try to get however many bytes of buffering __stdio_pickbuf
specified, but if that much memory isn't available,
try half as much each time until it succeeds or the buffer
size becomes too small to be useful. */
save = errno;
while (fp->__bufsize >= MIN_BUFSIZE)
{
fp->__buffer = (char *) malloc(fp->__bufsize);
if (fp->__buffer == NULL)
fp->__bufsize /= 2;
else
break;
}
errno = save;
if (fp->__buffer == NULL)
{
/* We can't get space for the buffer, so make it unbuffered. */
fp->__userbuf = 1;
fp->__bufsize = 0;
}
}
if (fp->__bufp == NULL)
{
/* Set the buffer pointer to the beginning of the buffer. */
fp->__bufp = fp->__buffer;
fp->__put_limit = fp->__get_limit = fp->__buffer;
}
}
/* Determine the current file position of STREAM if it is unknown. */
int
DEFUN(__stdio_check_offset, (stream), FILE *stream)
{
init_stream (stream);
if (stream->__offset == (fpos_t) -1)
{
/* This stream's offset is unknown or unknowable. */
if (stream->__io_funcs.__seek == NULL)
{
/* Unknowable. */
errno = ESPIPE;
return EOF;
}
else
{
/* Unknown. Find it out. */
fpos_t pos = (fpos_t) 0;
if ((*stream->__io_funcs.__seek)(stream->__cookie,
&pos, SEEK_CUR) < 0)
{
if (errno == ESPIPE)
/* Object is incapable of seeking. */
stream->__io_funcs.__seek = NULL;
return EOF;
}
stream->__offset = pos;
}
}
if (stream->__target == (fpos_t) -1)
/* This stream was opened on an existing object with
an unknown file position. The position is now known.
Make this the target position. */
stream->__target = stream->__offset;
return 0;
}
/* Move FP's file position to its target file position,
seeking as necessary and updating its `offset' field.
Sets ferror(FP) (and possibly errno) for errors. */
static void
DEFUN(seek_to_target, (fp), FILE *fp)
{
int save = errno;
if (__stdio_check_offset (fp) == EOF)
{
if (errno == ESPIPE)
errno = save;
else
fp->__error = 1;
}
else if (fp->__target != fp->__offset)
{
/* We are not at the target file position.
Seek to that position. */
if (fp->__io_funcs.__seek == NULL)
{
/* We can't seek! */
errno = ESPIPE;
fp->__error = 1;
}
else
{
fpos_t pos = fp->__target;
if ((*fp->__io_funcs.__seek)(fp->__cookie, &pos, SEEK_SET) < 0)
/* Seek failed! */
fp->__error = 1;
else
{
fp->__offset = pos;
if (pos != fp->__target)
/* Seek didn't go to the right place! */
fp->__error = 1;
}
}
}
}
/* Flush the buffer for FP.
If C is not EOF, it is also to be written.
If the stream is line buffered and C is a newline, it is written
to the output, otherwise it is put in the buffer after it has been
flushed to avoid a system call for a single character.
This is the default `output room' function. */
static void
DEFUN(flushbuf, (fp, c),
register FILE *fp AND int c)
{
int flush_only = c == EOF;
size_t buffer_written;
size_t to_write;
/* Set if target and get_limit have already been twiddled appropriately. */
int twiddled = 0;
if (fp->__put_limit == fp->__buffer)
{
/* The stream needs to be primed for writing. */
size_t buffer_offset = 0;
/* If the user has read some of the buffer, the target position
is incremented for each character he has read. */
fp->__target += fp->__bufp - fp->__buffer;
if (fp->__mode.__read && fp->__room_funcs.__input != NULL &&
!fp->__mode.__append)
{
int save = errno;
CONST int aligned = (fp->__buffer == NULL ||
__stdio_check_offset(fp) == EOF ||
fp->__target % fp->__bufsize == 0);
errno = save;
if (!aligned)
{
/* Move to a block (buffer size) boundary and read in a block.
Then the output will be written as a whole block, too. */
CONST size_t o = fp->__target % fp->__bufsize;
fp->__target -= o;
if ((*fp->__room_funcs.__input)(fp) == EOF && ferror(fp))
return;
else
__clearerr(fp);
if (fp->__get_limit - fp->__buffer < o)
/* Oops. We didn't read enough (probably because we got EOF).
Forget we even mentioned it. */
fp->__target += o;
else
/* Start bufp as far into the buffer as we were into
this block before we read it. */
buffer_offset = o;
}
/* The target position is now set to where the beginning of the
buffer maps to; and the get_limit was set by the input-room
function. */
twiddled = 1;
}
if (fp->__buffer != NULL)
{
/* Set up to write output into the buffer. */
fp->__put_limit = fp->__buffer + fp->__bufsize;
fp->__bufp = fp->__buffer + buffer_offset;
if (!flush_only)
{
/* Put C in the buffer to be written out.
We only need to actually write it out now if
it is a newline on a line-buffered stream. */
*fp->__bufp++ = (unsigned char) c;
if (!fp->__linebuf || (unsigned char) c != '\n')
{
/* There is no need to flush C from the buffer right now.
Record that nothing was written from the buffer,
and go do clean-up at end. */
buffer_written = 0;
goto end;
}
else
/* We put C in the buffer, so don't write it again later. */
flush_only = 1;
}
}
if (fp->__bufp - fp->__buffer <= buffer_offset)
{
/* There is nothing new in the buffer, only data that
was read back aligned from the file. */
buffer_written = 0;
goto end;
}
}
/* If there is read data in the buffer past what was written,
write all of that as well. Otherwise, just write what has been
written into the buffer. */
buffer_written = fp->__bufp - fp->__buffer;
to_write = (buffer_written == 0 ? 0 :
fp->__get_limit > fp->__bufp ?
fp->__get_limit - fp->__buffer :
buffer_written);
if (fp->__io_funcs.__write == NULL || (to_write == 0 && flush_only))
{
/* There is no writing function or we're coming from an fflush
call with nothing in the buffer, so just say the buffer's
been flushed, increment the file offset, and return. */
fp->__bufp = fp->__buffer;
fp->__offset += to_write;
goto end;
}
if (to_write > 0)
{
int wrote;
/* Go to the target file position. Don't bother if appending;
the write will just ignore the file position anyway. */
if (!fp->__mode.__append)
seek_to_target (fp);
if (!ferror(fp))
{
/* Write out the buffered data. */
wrote = (*fp->__io_funcs.__write)(fp->__cookie, fp->__buffer,
to_write);
if (wrote > 0)
{
if (fp->__mode.__append)
/* The write has written the data to the end of the file
and updated the file position to after the data. Don't
bother to find the current position; we can get it
later if we need it. */
fp->__offset = fp->__target = -1;
else
/* Record that we've moved forward in the file. */
fp->__offset += wrote;
}
if (wrote < (int) to_write)
/* The writing function should always write
the whole buffer unless there is an error. */
fp->__error = 1;
}
}
/* Reset the buffer pointer to the beginning of the buffer. */
fp->__bufp = fp->__buffer;
/* If we're not just flushing, write the last character, C. */
if (!flush_only && !ferror(fp))
{
if (fp->__buffer == NULL || (fp->__linebuf && (unsigned char) c == '\n'))
{
/* Either we're unbuffered, or we're line-buffered and
C is a newline, so really write it out immediately. */
char cc = (unsigned char) c;
if ((*fp->__io_funcs.__write)(fp->__cookie, &cc, 1) < 1)
fp->__error = 1;
else
{
/* Record that we've moved forward in the file. */
++fp->__offset;
++fp->__target;
}
}
else
/* Just put C in the buffer. */
*fp->__bufp++ = (unsigned char) c;
}
end:
if (!twiddled)
{
/* The new target position moves up as
much as the user wrote into the buffer. */
fp->__target += buffer_written;
/* Set the reading limit to the beginning of the buffer,
so the next `getc' will call __fillbf. */
fp->__get_limit = fp->__buffer;
}
if (feof(fp) || ferror(fp))
fp->__bufp = fp->__put_limit;
}
/* Fill the buffer for FP and return the first character read (or EOF).
This is the default `input_room' function. */
static int
DEFUN(fillbuf, (fp), register FILE *fp)
{
/* How far into the buffer we read we want to start bufp. */
size_t buffer_offset = 0;
register char *buffer;
register size_t to_read, nread = 0;
/* This must be unsigned to avoid sign extension in return. */
unsigned char c;
if (fp->__io_funcs.__read == NULL)
{
/* There is no read function, so always return EOF. */
fp->__eof = 1;
goto end;
}
if (fp->__buffer == NULL)
{
/* We're unbuffered, so we want to read only one character. */
buffer = (char *) &c;
to_read = 1;
}
else
{
/* We're buffered, so try to fill the buffer. */
buffer = fp->__buffer;
to_read = fp->__bufsize;
}
/* We're reading, so we're not at the end-of-file. */
fp->__eof = 0;
/* Go to the target file position. */
{
int save = errno;
if (__stdio_check_offset (fp) == 0 && fp->__target != fp->__offset)
{
/* Move to a block (buffer size) boundary. */
if (fp->__bufsize != 0)
{
buffer_offset = fp->__target % fp->__bufsize;
fp->__target -= buffer_offset;
}
seek_to_target (fp);
}
errno = save;
}
while (!ferror(fp) && !feof(fp) && nread <= buffer_offset)
{
/* Try to fill the buffer. */
int count = (*fp->__io_funcs.__read)(fp->__cookie, buffer, to_read);
if (count == 0)
fp->__eof = 1;
else if (count < 0)
fp->__error = 1;
else
{
buffer += count;
nread += count;
to_read -= count;
/* Record that we've moved forward in the file. */
fp->__offset += count;
}
}
if (fp->__buffer == NULL)
/* There is no buffer, so return the character we read
without all the buffer pointer diddling. */
return (feof(fp) || ferror(fp)) ? EOF : c;
/* Reset the buffer pointer to the beginning of the buffer
(plus whatever offset we may have set above). */
fp->__bufp = fp->__buffer + buffer_offset;
end:;
if (feof(fp) || ferror(fp))
{
/* Set both end pointers to the beginning of the buffer so
the next i/o call will force a call to __fillbf/__flshfp. */
fp->__put_limit = fp->__get_limit = fp->__buffer;
return EOF;
}
/* Set the end pointer to one past the last character we read. */
fp->__get_limit = fp->__buffer + nread;
/* Make it so the next `putc' will call __flshfp. */
fp->__put_limit = fp->__buffer;
/* Return the first character in the buffer. */
return *((unsigned char *) (fp->__bufp++));
}
/* Default I/O and room functions. */
extern __io_read_fn __stdio_read;
extern __io_write_fn __stdio_write;
extern __io_seek_fn __stdio_seek;
extern __io_close_fn __stdio_close;
extern __io_fileno_fn __stdio_fileno;
CONST __io_functions __default_io_functions =
{
__stdio_read, __stdio_write, __stdio_seek, __stdio_close, __stdio_fileno
};
CONST __room_functions __default_room_functions =
{
fillbuf, flushbuf
};
/* Flush the buffer for FP and also write C if FLUSH_ONLY is nonzero.
This is the function used by putc and fflush. */
int
DEFUN(__flshfp, (fp, c),
register FILE *fp AND int c)
{
int flush_only = c == EOF;
if (!__validfp(fp) || !fp->__mode.__write)
{
errno = EINVAL;
return EOF;
}
if (ferror(fp))
return EOF;
if (fp->__pushed_back)
{
/* Discard the char pushed back by ungetc. */
fp->__bufp = fp->__pushback_bufp;
fp->__pushed_back = 0;
}
/* Make sure the stream is initialized (has functions and buffering). */
init_stream(fp);
/* Do this early, so a `putc' on such a stream will never return success. */
if (fp->__room_funcs.__output == NULL)
{
/* A NULL `output room' function means
to always return an output error. */
fp->__error = 1;
return EOF;
}
if (!flush_only &&
/* Will C fit into the buffer?
See below about linebuf_active. */
fp->__bufp < (fp->__linebuf_active ? fp->__buffer + fp->__bufsize :
fp->__put_limit))
{
/* The character will fit in the buffer, so put it there. */
*fp->__bufp++ = (unsigned char) c;
if (fp->__linebuf && (unsigned char) c == '\n')
flush_only = 1;
else
return (unsigned char) c;
}
if (fp->__linebuf_active)
/* This is an active line-buffered stream, so its put-limit is set
to the beginning of the buffer in order to force a __flshfp call
on each putc (see below). We undo this hack here (by setting
the limit to the end of the buffer) to simplify the interface
with the output-room function. */
fp->__put_limit = fp->__buffer + fp->__bufsize;
/* Make room in the buffer. */
(*fp->__room_funcs.__output) (fp, flush_only ? EOF : (unsigned char) c);
if (fp->__linebuf)
{
/* This is a line-buffered stream, and it is now ready to do
some output. We call this an "active line-buffered stream".
We set the put_limit to the beginning of the buffer,
so the next `putc' call will force a call to this function.
Setting the linebuf_active flag tells the code above
(on the next call) to undo this hackery. */
fp->__put_limit = fp->__buffer;
fp->__linebuf_active = 1;
}
if (ferror (fp))
return EOF;
if (flush_only)
return 0;
return (unsigned char) c;
}
/* Fill the buffer for FP and return the first character read.
This is the function used by getc. */
int
DEFUN(__fillbf, (fp), register FILE *fp)
{
register int c;
fpos_t new_target;
if (!__validfp(fp) || !fp->__mode.__read)
{
errno = EINVAL;
return EOF;
}
if (fp->__pushed_back)
{
/* Return the char pushed back by ungetc. */
fp->__bufp = fp->__pushback_bufp;
fp->__pushed_back = 0;
return fp->__pushback;
}
/* Make sure the stream is initialized (has functions and buffering). */
init_stream(fp);
/* If we're trying to read the first character of a new
line of input from an unbuffered or line buffered stream,
we must flush all line-buffered output streams. */
if (fp->__buffer == NULL || fp->__linebuf)
{
register FILE *f;
for (f = __stdio_head; f != NULL; f = f->__next)
if (__validfp (f) && f->__linebuf && f->__mode.__write)
(void) __flshfp (f, EOF);
}
/* Note we must do this after flushing all line-buffered
streams, or else __flshfp would undo it! */
if (fp->__linebuf_active)
{
/* This is an active line-buffered stream, meaning it is in the midst
of writing, but has a bogus put_limit. Restore it to normality. */
fp->__put_limit = fp->__buffer + fp->__bufsize;
fp->__linebuf_active = 0;
}
/* We want the beginning of the buffer to now
map to just past the last data we read. */
new_target = fp->__target + (fp->__get_limit - fp->__buffer);
if (fp->__put_limit > fp->__buffer)
{
/* There is written data in the buffer.
Flush it out. */
if (fp->__room_funcs.__output == NULL)
fp->__error = 1;
else
(*fp->__room_funcs.__output) (fp, EOF);
}
fp->__target = new_target;
if (ferror(fp))
c = EOF;
else if (fp->__room_funcs.__input != NULL)
{
c = (*fp->__room_funcs.__input)(fp);
if (fp->__buffer == NULL)
/* This is an unbuffered stream, so the target sync above
won't do anything the next time around. Instead, note that
we have read one character. The (nonexistent) buffer now
maps to the position just past that character. */
++fp->__target;
}
else
{
/* A NULL `input_room' function means always return EOF. */
fp->__eof = 1;
c = EOF;
}
return c;
}
/* Nuke a stream, but don't kill its link in the chain. */
void
DEFUN(__invalidate, (stream), register FILE *stream)
{
/* Save its link. */
register FILE *next = stream->__next;
/* Pulverize the fucker. */
memset((PTR) stream, 0, sizeof(FILE));
/* Restore the deceased's link. */
stream->__next = next;
}

1295
stdio/longlong.h Normal file

File diff suppressed because it is too large Load Diff

177
stdio/memstream.c Normal file
View File

@@ -0,0 +1,177 @@
/* Copyright (C) 1991, 1992, 1994 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct memstream_info
{
char **buffer;
size_t *bufsize;
};
/* Enlarge STREAM's buffer. */
static void
DEFUN(enlarge_buffer, (stream, c),
register FILE *stream AND int c)
{
struct memstream_info *info = (struct memstream_info *) stream->__cookie;
size_t need;
if (stream->__put_limit != stream->__buffer)
/* Record how much has actually been written into the buffer. */
*info->bufsize = stream->__bufp - stream->__buffer;
if (stream->__target != -1
&& stream->__target > *info->bufsize)
/* Our target (where the buffer maps to) is always zero except when
the user just did a SEEK_END fseek. If he sought within the
buffer, we need do nothing and will zero the target below. If he
sought past the end of the object, grow and zero-fill the buffer
up to the target address. */
need = stream->__target;
else
need = *info->bufsize;
/* We always need an extra character in the buffer. Either we are
writing C, or we are flushing and need to write a NUL terminator. */
++need;
if (stream->__bufsize < need)
{
/* Enlarge the buffer. */
char *newbuf;
size_t newsize;
if (stream->__bufsize * 2 < need)
newsize = need;
else
newsize = stream->__bufsize * 2;
newbuf = (char *) realloc ((PTR) stream->__buffer, newsize);
if (newbuf == NULL)
{
stream->__error = 1;
return;
}
*info->buffer = stream->__buffer = newbuf;
stream->__bufsize = newsize;
}
stream->__target = stream->__offset = 0;
stream->__get_limit = stream->__bufp = stream->__buffer + *info->bufsize;
stream->__put_limit = stream->__buffer + stream->__bufsize;
need -= stream->__bufp - stream->__buffer + 1;
if (need > 0)
{
/* We are extending the buffer after an fseek; zero-fill new space. */
bzero (stream->__bufp, need);
stream->__bufp += need;
}
if (c != EOF)
*stream->__bufp++ = (unsigned char) c;
else
*stream->__bufp = '\0';
}
/* Seek function for memstreams.
There is no external state to munge. */
static int
DEFUN(seek, (cookie, pos, whence),
PTR cookie AND fpos_t *pos AND int whence)
{
switch (whence)
{
case SEEK_SET:
case SEEK_CUR:
return 0;
case SEEK_END:
/* Return the position relative to the end of the object.
fseek has just flushed us, so the info is consistent. */
*pos += *((struct memstream_info *) cookie)->bufsize;
return 0;
default:
__libc_fatal ("memstream::seek called with bogus WHENCE\n");
return -1;
}
}
static int
DEFUN(free_info, (cookie), PTR cookie)
{
#if 0
struct memstream_info *info = (struct memstream_info *) cookie;
char *buf;
buf = (char *) realloc ((PTR) *info->buffer, *info->bufsize);
if (buf != NULL)
*info->buffer = buf;
#endif
free (cookie);
return 0;
}
/* Open a stream that writes into a malloc'd buffer that is expanded as
necessary. *BUFLOC and *SIZELOC are updated with the buffer's location
and the number of characters written on fflush or fclose. */
FILE *
DEFUN(open_memstream, (bufloc, sizeloc),
char **bufloc AND size_t *sizeloc)
{
FILE *stream;
struct memstream_info *info;
if (bufloc == NULL || sizeloc == NULL)
{
errno = EINVAL;
return NULL;
}
stream = fmemopen ((char *) NULL, BUFSIZ, "w+");
if (stream == NULL)
return NULL;
info = (struct memstream_info *) malloc (sizeof (struct memstream_info));
if (info == NULL)
{
int save = errno;
(void) fclose (stream);
errno = save;
return NULL;
}
stream->__room_funcs.__output = enlarge_buffer;
stream->__io_funcs.__seek = seek;
stream->__io_funcs.__close = free_info;
stream->__cookie = (PTR) info;
stream->__userbuf = 1;
info->buffer = bufloc;
info->bufsize = sizeloc;
*bufloc = stream->__buffer;
return stream;
}

39
stdio/mp_clz_tab.c Normal file
View File

@@ -0,0 +1,39 @@
/* __clz_tab -- support for longlong.h
Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
The GNU MP 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 Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if 0
#include "gmp.h"
#include "gmp-impl.h"
#endif
#if 0
const
#endif
unsigned char __clz_tab[] =
{
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
};

54
stdio/newstream.c Normal file
View File

@@ -0,0 +1,54 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
/* Return a new, zeroed, stream.
You must set its cookie and io_mode.
The first operation will give it a buffer unless you do.
It will also give it the default functions unless you set the `seen' flag.
Returns NULL if a stream can't be created. */
FILE *
DEFUN_VOID(__newstream)
{
register FILE *stream;
stream = __stdio_head;
while (__validfp (stream))
stream = stream->__next;
if (stream == NULL)
{
/* None to reuse. */
stream = (FILE *) malloc (sizeof (FILE));
if (stream == NULL)
return NULL;
stream->__next = __stdio_head;
__stdio_head = stream;
}
__invalidate (stream);
stream->__magic = _IOMAGIC;
stream->__offset = (fpos_t) -1;
stream->__target = (fpos_t) -1;
return stream;
}

187
stdio/obstream.c Normal file
View File

@@ -0,0 +1,187 @@
/* Copyright (C) 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#include <obstack.h>
#include <stdarg.h>
#include <string.h>
/* Output-room function for obstack streams. */
static void
DEFUN(grow, (stream, c), FILE *stream AND int c)
{
struct obstack *const obstack = (struct obstack *) stream->__cookie;
/* Move the end of the object back to include only the portion
of the buffer which the user has already written into. */
obstack_blank_fast (obstack, - (stream->__put_limit - stream->__bufp));
if (stream->__target > obstack_object_size (obstack))
{
/* Our target (where the buffer maps to) is always zero except when
the user just did a SEEK_END fseek. If he sought within the
buffer, we need do nothing and will zero the target below. If he
sought past the end of the object, grow and zero-fill the object
up to the target address. */
obstack_blank (obstack,
stream->__target - obstack_object_size (obstack));
/* fseek has just flushed us, so the put limit points
to the end of the written data. */
bzero (stream->__put_limit,
stream->__target - stream->__bufsize);
}
if (c != EOF)
obstack_1grow (obstack, (unsigned char) c);
/* The stream buffer always maps exactly to the object on the top
of the obstack. The start of the buffer is the start of the object.
The put limit points just past the end of the object. On fflush, the
obstack is sync'd so the end of the object points just past the last
character written to the stream. */
stream->__target = stream->__offset = 0;
stream->__buffer = obstack_base (obstack);
stream->__bufsize = obstack_room (obstack);
stream->__bufp = obstack_next_free (obstack);
stream->__get_limit = stream->__bufp;
if (c == EOF)
/* This is fflush. Make the stream buffer, the object,
and the characters actually written all match. */
stream->__put_limit = stream->__get_limit;
else
{
/* Extend the buffer (and the object) to include
the rest of the obstack chunk (which is unitialized).
Data past bufp is undefined. */
stream->__put_limit = stream->__buffer + stream->__bufsize;
obstack_blank_fast (obstack, stream->__put_limit - stream->__bufp);
}
}
/* Seek function for obstack streams.
There is no external state to munge. */
static int
DEFUN(seek, (cookie, pos, whence),
PTR cookie AND fpos_t *pos AND int whence)
{
switch (whence)
{
case SEEK_SET:
case SEEK_CUR:
return 0;
case SEEK_END:
/* Return the position relative to the end of the object.
fseek has just flushed us, so the obstack is consistent. */
*pos += obstack_object_size ((struct obstack *) cookie);
return 0;
default:
__libc_fatal ("obstream::seek called with bogus WHENCE\n");
return -1;
}
}
/* Input room function for obstack streams.
Only what has been written to the stream can be read back. */
static int
DEFUN(input, (stream), FILE *stream)
{
/* Re-sync with the obstack, growing the object if necessary. */
grow (stream, EOF);
if (stream->__bufp < stream->__get_limit)
return (unsigned char) *stream->__bufp++;
stream->__eof = 1;
return EOF;
}
/* Initialize STREAM to talk to OBSTACK. */
static void
DEFUN(init_obstream, (stream, obstack),
FILE *stream AND struct obstack *obstack)
{
stream->__mode.__write = 1;
stream->__mode.__read = 1;
/* Input can read only what has been written. */
stream->__room_funcs.__input = input;
/* Do nothing for close. */
stream->__io_funcs.__close = NULL;
/* When the buffer is full, grow the obstack. */
stream->__room_funcs.__output = grow;
/* Seek within the object, and extend it. */
stream->__io_funcs.__seek = seek;
stream->__target = stream->__offset = 0;
stream->__seen = 1;
/* Don't deallocate that buffer! */
stream->__userbuf = 1;
/* We don't have to initialize the buffer.
The first read attempt will call grow, which will do all the work. */
}
FILE *
open_obstack_stream (obstack)
struct obstack *obstack;
{
register FILE *stream;
stream = __newstream ();
if (stream == NULL)
return NULL;
init_obstream (stream, obstack);
return stream;
}
int
DEFUN(obstack_vprintf, (obstack, format, args),
struct obstack *obstack AND const char *format AND va_list args)
{
FILE f;
bzero (&f, sizeof (f));
init_obstream (&f, obstack);
return vfprintf (&f, format, args);
}
int
DEFUN(obstack_printf, (obstack, format),
struct obstack *obstack AND const char *format DOTS)
{
int result;
va_list ap;
va_start (ap, format);
result = obstack_vprintf (obstack, format, ap);
va_end (ap);
return result;
}

42
stdio/perror.c Normal file
View File

@@ -0,0 +1,42 @@
/* Copyright (C) 1991, 1992, 1993 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#include <errno.h>
extern char *_strerror_internal __P ((int, char buf[1024]));
/* 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
DEFUN(perror, (s), register CONST char *s)
{
char buf[1024];
int errnum = errno;
CONST char *colon;
if (s == NULL || *s == '\0')
s = colon = "";
else
colon = ": ";
(void) fprintf (stderr, "%s%s%s\n",
s, colon, _strerror_internal (errnum, buf));
}

211
stdio/printf-prs.c Normal file
View File

@@ -0,0 +1,211 @@
/* Copyright (C) 1991, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#include <printf.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#ifdef __GNUC__
#define HAVE_LONGLONG
#endif
extern printf_arginfo_function *__printf_arginfo_table[];
size_t
DEFUN(parse_printf_format, (fmt, n, argtypes),
CONST char *fmt AND size_t n AND int *argtypes)
{
register CONST char *f;
size_t need = 0;
for (f = strchr (fmt, '%'); f != NULL; f = strchr (f, '%'))
{
struct printf_info info;
printf_arginfo_function *arginfo;
++f;
info.space = info.showsign = info.left = info.alt = info.group = 0;
info.pad = ' ';
while (*f == ' ' || *f == '+' || *f == '-' || *f == '#' || *f == '0' ||
*f == '\'')
switch (*f++)
{
case ' ':
info.space = 1;
break;
case '+':
info.showsign = 1;
break;
case '-':
info.left = 1;
break;
case '#':
info.alt = 1;
break;
case '\'':
info.group = 1;
break;
case '0':
info.pad = '0';
break;
}
if (info.left)
info.pad = ' ';
/* Get the field width. */
if (*f == '*')
{
if (++need < n)
*argtypes++ = PA_INT;
info.width = INT_MIN;
++f;
}
else
{
info.width = 0;
while (isdigit(*f))
{
info.width *= 10;
info.width += *f++ - '0';
}
}
/* Get the precision. */
/* -1 means none given; 0 means explicit 0. */
info.prec = -1;
if (*f == '.')
{
++f;
if (*f == '*')
{
/* The precision is given in an argument. */
if (++need < n)
*argtypes++ = PA_INT;
info.prec = INT_MIN;
++f;
}
else if (isdigit(*f))
{
info.prec = 0;
while (*f != '\0' && isdigit(*f))
{
info.prec *= 10;
info.prec += *f++ - '0';
}
}
}
/* Check for type modifiers. */
info.is_short = info.is_long = info.is_long_double = 0;
while (*f == 'h' || *f == 'l' || *f == 'L')
switch (*f++)
{
case 'h':
/* int's are short int's. */
info.is_short = 1;
break;
case 'l':
#ifdef HAVE_LONGLONG
if (info.is_long)
/* A double `l' is equivalent to an `L'. */
info.is_long_double = 1;
else
#endif
/* int's are long int's. */
info.is_long = 1;
break;
case 'L':
/* double's are long double's, and int's are long long int's. */
info.is_long_double = 1;
break;
}
if (*f == '\0')
return need;
info.spec = *f++;
arginfo = __printf_arginfo_table[info.spec];
if (arginfo != NULL)
{
size_t nargs
= (*arginfo) (&info, need > n ? 0 : n - need, argtypes);
need += nargs;
argtypes += nargs;
}
else
{
int type;
switch (info.spec)
{
case 'i':
case 'd':
case 'u':
case 'o':
case 'X':
case 'x':
type = PA_INT;
break;
case 'e':
case 'E':
case 'f':
case 'g':
case 'G':
type = PA_DOUBLE;
break;
case 'c':
type = PA_CHAR;
break;
case 's':
type = PA_STRING;
break;
case 'p':
type = PA_POINTER;
break;
case 'n':
type = PA_INT | PA_FLAG_PTR;
break;
default:
/* No arg for an unknown spec. */
continue;
}
if (info.is_long_double)
type |= PA_FLAG_LONG_DOUBLE;
if (info.is_long)
type |= PA_FLAG_LONG;
if (info.is_short)
type |= PA_FLAG_SHORT;
if (++need < n)
*argtypes++ = type;
}
}
return need;
}

37
stdio/printf.c Normal file
View File

@@ -0,0 +1,37 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#include <stdio.h>
/* Write formatted output to stdout from the format string FORMAT. */
/* VARARGS1 */
int
DEFUN(printf, (format), CONST char *format DOTS)
{
va_list arg;
int done;
va_start(arg, format);
done = vprintf(format, arg);
va_end(arg);
return done;
}

114
stdio/printf.h Normal file
View File

@@ -0,0 +1,114 @@
/* Copyright (C) 1991, 1992, 1993, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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,
Cambridge, MA 02139, USA. */
#ifndef _PRINTF_H
#define _PRINTF_H 1
#include <features.h>
__BEGIN_DECLS
#define __need_FILE
#include <stdio.h>
#define __need_size_t
#include <stddef.h>
#include <stdarg.h> /* Need va_list. */
struct printf_info
{
int prec; /* Precision. */
int width; /* Width. */
unsigned char spec; /* Format letter. */
unsigned int is_long_double:1;/* L flag. */
unsigned int is_short:1; /* h flag. */
unsigned int is_long:1; /* l flag. */
unsigned int alt:1; /* # flag. */
unsigned int space:1; /* Space flag. */
unsigned int left:1; /* - flag. */
unsigned int showsign:1; /* + flag. */
unsigned int group:1; /* ' flag. */
char pad; /* Padding character. */
};
/* Type of a printf specifier-handler function.
STREAM is the FILE on which to write output.
INFO gives information about the format specification.
Arguments can be read from ARGS.
The function should return the number of characters written,
or -1 for errors. */
typedef int printf_function __P ((FILE * __stream,
__const struct printf_info * __info,
va_list * __args));
typedef int printf_arginfo_function __P ((__const struct printf_info * __info,
size_t __n,
int *__argtypes));
/* Register FUNC to be called to format SPEC specifiers.
ARGINFO, if not NULL, is a function used by `parse_printf_format'
to determine how many arguments a SPEC conversion requires,
and what their types are. */
extern int register_printf_function __P ((int __spec, printf_function __func,
printf_arginfo_function __arginfo));
/* Parse FMT, and fill in N elements of ARGTYPES with the
types needed for the conversions FMT specifies. Returns
the number of arguments required by FMT.
The ARGINFO function registered with a user-defined format is passed a
`struct printf_info' describing the format spec being parsed. A width
or precision of INT_MIN means a `*' was used to indicate that the
width/precision will come from an arg. The function should fill in the
array it is passed with the types of the arguments it wants, and return
the number of arguments it wants. */
extern size_t parse_printf_format __P ((__const char *__fmt,
size_t __n,
int *__argtypes));
/* Codes returned by `parse_printf_format' for basic types.
These values cover all the standard format specifications.
Users can add new values after PA_LAST for their own types. */
enum
{ /* C type: */
PA_INT, /* int */
PA_CHAR, /* int, cast to char */
PA_STRING, /* const char *, a '\0'-terminated string */
PA_POINTER, /* void * */
PA_FLOAT, /* float */
PA_DOUBLE, /* double */
PA_LAST
};
/* Flag bits that can be set in a type returned by `parse_printf_format'. */
#define PA_FLAG_MASK 0xff00
#define PA_FLAG_LONG_LONG (1 << 8)
#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG
#define PA_FLAG_LONG (1 << 9)
#define PA_FLAG_SHORT (1 << 10)
#define PA_FLAG_PTR (1 << 11)
__END_DECLS
#endif /* printf.h */

991
stdio/printf_fp.c Normal file
View File

@@ -0,0 +1,991 @@
/* Floating point output for `printf'.
Copyright (C) 1995 Free Software Foundation, Inc.
Written by Ulrich Drepper.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#ifdef USE_IN_LIBIO
# include <libioP.h>
#else
# include <stdio.h>
#endif
#include <alloca.h>
#include <ansidecl.h>
#include <ctype.h>
#include <float.h>
#include <gmp-mparam.h>
#include <gmp.h>
#include <gmp-impl.h>
#include <longlong.h>
#include <localeinfo.h>
#include <math.h>
#include <printf.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
/* #define NDEBUG 1 */
#include <assert.h>
/* This defines make it possible to use the same code for GNU C library and
the GNU I/O library. */
#ifdef USE_IN_LIBIO
# define PUT(f, s, n) _IO_sputn (f, s, n)
# define PAD(f, c, n) _IO_padn (f, c, n)
/* We use this file GNU C library and GNU I/O library. So make
names equal. */
# undef putc
# define putc(c, f) _IO_putc (c, f)
# define size_t _IO_size_t
# define FILE _IO_FILE
#else /* ! USE_IN_LIBIO */
# define PUT(f, s, n) fwrite (s, 1, n, f)
# define PAD(f, c, n) __printf_pad (f, c, n)
ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c. */
#endif /* USE_IN_LIBIO */
/* Macros for doing the actual output. */
#define outchar(ch) \
do \
{ \
register CONST int outc = (ch); \
if (putc (outc, fp) == EOF) \
return -1; \
++done; \
} while (0)
#define PRINT(ptr, len) \
do \
{ \
register size_t outlen = (len); \
if (len > 20) \
{ \
if (PUT (fp, ptr, outlen) != outlen) \
return -1; \
ptr += outlen; \
done += outlen; \
} \
else \
{ \
while (outlen-- > 0) \
outchar (*ptr++); \
} \
} while (0)
#define PADN(ch, len) \
do \
{ \
if (PAD (fp, ch, len) != len) \
return -1; \
done += len; \
} \
while (0)
/* We use the GNU MP library to handle large numbers.
An MP variable occupies a varying number of entries in its array. We keep
track of this number for efficiency reasons. Otherwise we would always
have to process the whole array. */
#define MPN_VAR(name) mp_limb *name; mp_size_t name##size
#define MPN_ASSIGN(dst,src) \
memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb))
#define MPN_GE(u,v) \
(u##size > v##size || (u##size == v##size && __mpn_cmp (u, v, u##size) >= 0))
extern int __isinfl (long double), __isnanl (long double);
extern mp_size_t __mpn_extract_double (mp_ptr res_ptr, mp_size_t size,
int *expt, int *is_neg,
double value);
extern mp_size_t __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
int *expt, int *is_neg,
long double value);
#include "fpioconst.h"
static unsigned int guess_grouping (unsigned int intdig_max,
const char *grouping, wchar_t sepchar);
static char *group_number (char *buf, char *bufend, unsigned int intdig_no,
const char *grouping, wchar_t thousands_sep);
int
__printf_fp (fp, info, args)
FILE *fp;
const struct printf_info *info;
va_list *args;
{
/* The floating-point value to output. */
union
{
double dbl;
LONG_DOUBLE ldbl;
}
fpnum;
/* Locale-dependent representation of decimal point. */
wchar_t decimal;
/* Locale-dependent thousands separator and grouping specification. */
wchar_t thousands_sep;
const char *grouping;
/* "NaN" or "Inf" for the special cases. */
CONST char *special = NULL;
/* We need just a few limbs for the input before shifting to the right
position. */
mp_limb fp_input[(LDBL_MANT_DIG + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB];
/* We need to shift the contents of fp_input by this amount of bits. */
int to_shift;
/* The significant of the floting-point value in question */
MPN_VAR(frac);
/* and the exponent. */
int exponent;
/* Sign of the exponent. */
int expsign = 0;
/* Sign of float number. */
int is_neg = 0;
/* Scaling factor. */
MPN_VAR(scale);
/* Temporary bignum value. */
MPN_VAR(tmp);
/* Digit which is result of last hack_digit() call. */
int digit;
/* The type of output format that will be used: 'e'/'E' or 'f'. */
int type;
/* Counter for number of written characters. */
int done = 0;
/* General helper (carry limb). */
mp_limb cy;
char hack_digit (void)
{
mp_limb hi;
if (expsign != 0 && type == 'f' && exponent-- > 0)
hi = 0;
else if (scalesize == 0)
{
hi = frac[fracsize - 1];
cy = __mpn_mul_1 (frac, frac, fracsize - 1, 10);
frac[fracsize - 1] = cy;
}
else
{
if (fracsize < scalesize)
hi = 0;
else
{
hi = __mpn_divmod (tmp, frac, fracsize, scale, scalesize);
tmp[fracsize - scalesize] = hi;
hi = tmp[0];
fracsize = __mpn_normal_size (frac, scalesize);
if (fracsize == 0)
{
/* We're not prepared for an mpn variable with zero
limbs. */
fracsize = 1;
return '0' + hi;
}
}
cy = __mpn_mul_1 (frac, frac, fracsize, 10);
if (cy != 0)
frac[fracsize++] = cy;
}
return '0' + hi;
}
/* Figure out the decimal point character. */
if (mbtowc (&decimal, _numeric_info->decimal_point,
strlen (_numeric_info->decimal_point)) <= 0)
decimal = (wchar_t) *_numeric_info->decimal_point;
if (info->group)
{
grouping = _numeric_info->grouping; /* Cache the grouping info array. */
if (*grouping <= 0 || *grouping == CHAR_MAX)
grouping = NULL;
else
{
/* Figure out the thousands seperator character. */
if (mbtowc (&thousands_sep, _numeric_info->thousands_sep,
strlen (_numeric_info->thousands_sep)) <= 0)
thousands_sep = (wchar_t) *_numeric_info->thousands_sep;
if (thousands_sep == L'\0')
grouping = NULL;
}
}
else
grouping = NULL;
/* Fetch the argument value. */
if (info->is_long_double && sizeof (long double) > sizeof (double))
{
fpnum.ldbl = va_arg (*args, LONG_DOUBLE);
/* Check for special values: not a number or infinity. */
if (__isnanl (fpnum.ldbl))
{
special = "NaN";
is_neg = 0;
}
else if (__isinfl (fpnum.ldbl))
{
special = "Inf";
is_neg = fpnum.ldbl < 0;
}
else
{
fracsize = __mpn_extract_long_double (fp_input,
(sizeof (fp_input) /
sizeof (fp_input[0])),
&exponent, &is_neg,
fpnum.ldbl);
to_shift = 1 + fracsize * BITS_PER_MP_LIMB - LDBL_MANT_DIG;
}
}
else
{
fpnum.dbl = va_arg (*args, double);
/* Check for special values: not a number or infinity. */
if (__isnan (fpnum.dbl))
{
special = "NaN";
is_neg = 0;
}
else if (__isinf (fpnum.dbl))
{
special = "Inf";
is_neg = fpnum.dbl < 0;
}
else
{
fracsize = __mpn_extract_double (fp_input,
(sizeof (fp_input)
/ sizeof (fp_input[0])),
&exponent, &is_neg, fpnum.dbl);
to_shift = 1 + fracsize * BITS_PER_MP_LIMB - DBL_MANT_DIG;
}
}
if (special)
{
int width = info->prec > info->width ? info->prec : info->width;
if (is_neg || info->showsign || info->space)
--width;
width -= 3;
if (!info->left && width > 0)
PADN (' ', width);
if (is_neg)
outchar ('-');
else if (info->showsign)
outchar ('+');
else if (info->space)
outchar (' ');
PRINT (special, 3);
if (info->left && width > 0)
PADN (' ', width);
return done;
}
/* We need three multiprecision variables. Now that we have the exponent
of the number we can allocate the needed memory. It would be more
efficient to use variables of the fixed maximum size but because this
would be really big it could lead to memory problems. */
{
mp_size_t bignum_size = ((ABS (exponent) + BITS_PER_MP_LIMB - 1)
/ BITS_PER_MP_LIMB + 3) * sizeof (mp_limb);
frac = (mp_limb *) alloca (bignum_size);
tmp = (mp_limb *) alloca (bignum_size);
scale = (mp_limb *) alloca (bignum_size);
}
/* We now have to distinguish between numbers with positive and negative
exponents because the method used for the one is not applicable/efficient
for the other. */
scalesize = 0;
if (exponent > 2)
{
/* |FP| >= 1.0. */
int scaleexpo = 0;
int explog = LDBL_MAX_10_EXP_LOG;
int exp10 = 0;
const struct mp_power *tens = &_fpioconst_pow10[explog + 1];
int cnt_h, cnt_l, i;
if ((exponent + to_shift) % BITS_PER_MP_LIMB == 0)
{
MPN_COPY_DECR (frac + (exponent + to_shift) / BITS_PER_MP_LIMB,
fp_input, fracsize);
fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB;
}
else
{
cy = __mpn_lshift (frac + (exponent + to_shift) / BITS_PER_MP_LIMB,
fp_input, fracsize,
(exponent + to_shift) % BITS_PER_MP_LIMB);
fracsize += (exponent + to_shift) / BITS_PER_MP_LIMB;
if (cy)
frac[fracsize++] = cy;
}
MPN_ZERO (frac, (exponent + to_shift) / BITS_PER_MP_LIMB);
assert (tens > &_fpioconst_pow10[0]);
do
{
--tens;
/* The number of the product of two binary numbers with n and m
bits respectively has m+n or m+n-1 bits. */
if (exponent >= scaleexpo + tens->p_expo - 1)
{
if (scalesize == 0)
MPN_ASSIGN (tmp, tens->array);
else
{
cy = __mpn_mul (tmp, scale, scalesize,
tens->array + 2, tens->arraysize - 2);
tmpsize = scalesize + tens->arraysize - 2;
if (cy == 0)
--tmpsize;
}
if (MPN_GE (frac, tmp))
{
int cnt;
MPN_ASSIGN (scale, tmp);
count_leading_zeros (cnt, scale[scalesize - 1]);
scaleexpo = (scalesize - 2) * BITS_PER_MP_LIMB - cnt - 1;
exp10 |= 1 << explog;
}
}
--explog;
}
while (tens > &_fpioconst_pow10[0]);
exponent = exp10;
/* Optimize number representations. We want to represent the numbers
with the lowest number of bytes possible without losing any
bytes. Also the highest bit in the scaling factor has to be set
(this is a requirement of the MPN division routines). */
if (scalesize > 0)
{
/* Determine minimum number of zero bits at the end of
both numbers. */
for (i = 0; scale[i] == 0 && frac[i] == 0; i++)
;
/* Determine number of bits the scaling factor is misplaced. */
count_leading_zeros (cnt_h, scale[scalesize - 1]);
if (cnt_h == 0)
{
/* The highest bit of the scaling factor is already set. So
we only have to remove the trailing empty limbs. */
if (i > 0)
{
MPN_COPY_INCR (scale, scale + i, scalesize - i);
scalesize -= i;
MPN_COPY_INCR (frac, frac + i, fracsize - i);
fracsize -= i;
}
}
else
{
if (scale[i] != 0)
{
count_trailing_zeros (cnt_l, scale[i]);
if (frac[i] != 0)
{
int cnt_l2;
count_trailing_zeros (cnt_l2, frac[i]);
if (cnt_l2 < cnt_l)
cnt_l = cnt_l2;
}
}
else
count_trailing_zeros (cnt_l, frac[i]);
/* Now shift the numbers to their optimal position. */
if (i == 0 && BITS_PER_MP_LIMB - cnt_h > cnt_l)
{
/* We cannot save any memory. So just roll both numbers
so that the scaling factor has its highest bit set. */
(void) __mpn_lshift (scale, scale, scalesize, cnt_h);
cy = __mpn_lshift (frac, frac, fracsize, cnt_h);
if (cy != 0)
frac[fracsize++] = cy;
}
else if (BITS_PER_MP_LIMB - cnt_h <= cnt_l)
{
/* We can save memory by removing the trailing zero limbs
and by packing the non-zero limbs which gain another
free one. */
(void) __mpn_rshift (scale, scale + i, scalesize - i,
BITS_PER_MP_LIMB - cnt_h);
scalesize -= i + 1;
(void) __mpn_rshift (frac, frac + i, fracsize - i,
BITS_PER_MP_LIMB - cnt_h);
fracsize -= frac[fracsize - i - 1] == 0 ? i + 1 : i;
}
else
{
/* We can only save the memory of the limbs which are zero.
The non-zero parts occupy the same number of limbs. */
(void) __mpn_rshift (scale, scale + (i - 1),
scalesize - (i - 1),
BITS_PER_MP_LIMB - cnt_h);
scalesize -= i;
(void) __mpn_rshift (frac, frac + (i - 1),
fracsize - (i - 1),
BITS_PER_MP_LIMB - cnt_h);
fracsize -= frac[fracsize - (i - 1) - 1] == 0 ? i : i - 1;
}
}
}
}
else if (exponent < 0)
{
/* |FP| < 1.0. */
int exp10 = 0;
int explog = LDBL_MAX_10_EXP_LOG;
const struct mp_power *tens = &_fpioconst_pow10[explog + 1];
mp_size_t used_limbs = fracsize - 1;
/* Now shift the input value to its right place. */
cy = __mpn_lshift (frac, fp_input, fracsize, to_shift);
frac[fracsize++] = cy;
assert (cy == 1 || (frac[fracsize - 2] == 0 && frac[0] == 0));
expsign = 1;
exponent = -exponent;
assert (tens != &_fpioconst_pow10[0]);
do
{
--tens;
if (exponent >= tens->m_expo)
{
int i, incr, cnt_h, cnt_l;
mp_limb topval[2];
/* The __mpn_mul function expects the first argument to be
bigger than the second. */
if (fracsize < tens->arraysize - 2)
cy = __mpn_mul (tmp, &tens->array[2], tens->arraysize - 2,
frac, fracsize);
else
cy = __mpn_mul (tmp, frac, fracsize,
&tens->array[2], tens->arraysize - 2);
tmpsize = fracsize + tens->arraysize - 2;
if (cy == 0)
--tmpsize;
count_leading_zeros (cnt_h, tmp[tmpsize - 1]);
incr = (tmpsize - fracsize) * BITS_PER_MP_LIMB
+ BITS_PER_MP_LIMB - 1 - cnt_h;
assert (incr <= tens->p_expo);
/* If we increased the exponent by exactly 3 we have to test
for overflow. This is done by comparing with 10 shifted
to the right position. */
if (incr == exponent + 3)
if (cnt_h <= BITS_PER_MP_LIMB - 4)
{
topval[0] = 0;
topval[1] = 10 << (BITS_PER_MP_LIMB - 4 - cnt_h);
}
else
{
topval[0] = 10 << (BITS_PER_MP_LIMB - 4);
topval[1] = 0;
(void) __mpn_lshift (topval, topval, 2,
BITS_PER_MP_LIMB - cnt_h);
}
/* We have to be careful when multiplying the last factor.
If the result is greater than 1.0 be have to test it
against 10.0. If it is greater or equal to 10.0 the
multiplication was not valid. This is because we cannot
determine the number of bits in the result in advance. */
if (incr < exponent + 3
|| (incr == exponent + 3 &&
(tmp[tmpsize - 1] < topval[1]
|| (tmp[tmpsize - 1] == topval[1]
&& tmp[tmpsize - 2] < topval[0]))))
{
/* The factor is right. Adapt binary and decimal
exponents. */
exponent -= incr;
exp10 |= 1 << explog;
/* If this factor yields a number greater or equal to
1.0, we must not shift the non-fractional digits down. */
if (exponent < 0)
cnt_h += -exponent;
/* Now we optimize the number representation. */
for (i = 0; tmp[i] == 0; ++i);
if (cnt_h == BITS_PER_MP_LIMB - 1)
{
MPN_COPY (frac, tmp + i, tmpsize - i);
fracsize = tmpsize - i;
}
else
{
count_trailing_zeros (cnt_l, tmp[i]);
/* Now shift the numbers to their optimal position. */
if (i == 0 && BITS_PER_MP_LIMB - 1 - cnt_h > cnt_l)
{
/* We cannot save any memory. Just roll the
number so that the leading digit is in a
seperate limb. */
cy = __mpn_lshift (frac, tmp, tmpsize, cnt_h + 1);
fracsize = tmpsize + 1;
frac[fracsize - 1] = cy;
}
else if (BITS_PER_MP_LIMB - 1 - cnt_h <= cnt_l)
{
(void) __mpn_rshift (frac, tmp + i, tmpsize - i,
BITS_PER_MP_LIMB - 1 - cnt_h);
fracsize = tmpsize - i;
}
else
{
/* We can only save the memory of the limbs which
are zero. The non-zero parts occupy the same
number of limbs. */
(void) __mpn_rshift (frac, tmp + (i - 1),
tmpsize - (i - 1),
BITS_PER_MP_LIMB - 1 - cnt_h);
fracsize = tmpsize - (i - 1);
}
}
used_limbs = fracsize - 1;
}
}
--explog;
}
while (tens != &_fpioconst_pow10[1] && exponent > 0);
/* All factors but 10^-1 are tested now. */
if (exponent > 0)
{
cy = __mpn_mul_1 (tmp, frac, fracsize, 10);
tmpsize = fracsize;
assert (cy == 0 || tmp[tmpsize - 1] < 20);
(void) __mpn_rshift (frac, tmp, tmpsize, MIN (4, exponent));
fracsize = tmpsize;
exp10 |= 1;
assert (frac[fracsize - 1] < 10);
}
exponent = exp10;
}
else
{
/* This is a special case. We don't need a factor because the
numbers are in the range of 0.0 <= fp < 8.0. We simply
shift it to the right place and divide it by 1.0 to get the
leading digit. (Of course this division is not really made.) */
assert (0 <= exponent && exponent < 3 &&
exponent + to_shift < BITS_PER_MP_LIMB);
/* Now shift the input value to its right place. */
cy = __mpn_lshift (frac, fp_input, fracsize, (exponent + to_shift));
frac[fracsize++] = cy;
exponent = 0;
}
{
int width = info->width;
char *buffer, *startp, *cp;
int chars_needed;
int expscale;
int intdig_max, intdig_no = 0;
int fracdig_min, fracdig_max, fracdig_no = 0;
int dig_max;
int significant;
if (tolower (info->spec) == 'e')
{
type = info->spec;
intdig_max = 1;
fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
chars_needed = 1 + 1 + fracdig_max + 1 + 1 + 4;
/* d . ddd e +- ddd */
dig_max = INT_MAX; /* Unlimited. */
significant = 1; /* Does not matter here. */
}
else if (info->spec == 'f')
{
type = 'f';
fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
if (expsign == 0)
{
intdig_max = exponent + 1;
/* This can be really big! */ /* XXX Maybe malloc if too big? */
chars_needed = exponent + 1 + 1 + fracdig_max;
}
else
{
intdig_max = 1;
chars_needed = 1 + 1 + fracdig_max;
}
dig_max = INT_MAX; /* Unlimited. */
significant = 1; /* Does not matter here. */
}
else
{
dig_max = info->prec < 0 ? 6 : (info->prec == 0 ? 1 : info->prec);
if ((expsign == 0 && exponent >= dig_max)
|| (expsign != 0 && exponent > 4))
{
type = isupper (info->spec) ? 'E' : 'e';
fracdig_max = dig_max - 1;
intdig_max = 1;
chars_needed = 1 + 1 + fracdig_max + 1 + 1 + 4;
}
else
{
type = 'f';
intdig_max = expsign == 0 ? exponent + 1 : 0;
fracdig_max = dig_max - intdig_max;
/* We need space for the significant digits and perhaps for
leading zeros when < 1.0. Pessimistic guess: dig_max. */
chars_needed = dig_max + dig_max + 1;
}
fracdig_min = info->alt ? fracdig_max : 0;
significant = 0; /* We count significant digits. */
}
if (grouping)
/* Guess the number of groups we will make, and thus how
many spaces we need for separator characters. */
chars_needed += guess_grouping (intdig_max, grouping, thousands_sep);
/* Allocate buffer for output. We need two more because while rounding
it is possible that we need two more characters in front of all the
other output. */
buffer = alloca (2 + chars_needed);
cp = startp = buffer + 2; /* Let room for rounding. */
/* Do the real work: put digits in allocated buffer. */
if (expsign == 0 || type != 'f')
{
assert (expsign == 0 || intdig_max == 1);
while (intdig_no < intdig_max)
{
++intdig_no;
*cp++ = hack_digit ();
}
significant = 1;
if (info->alt
|| fracdig_min > 0
|| (fracdig_max > 0 && (fracsize > 1 || frac[0] != 0)))
*cp++ = decimal;
}
else
{
/* |fp| < 1.0 and the selected type is 'f', so put "0."
in the buffer. */
*cp++ = '0';
--exponent;
*cp++ = decimal;
}
/* Generate the needed number of fractional digits. */
while (fracdig_no < fracdig_min
|| (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0)))
{
++fracdig_no;
*cp = hack_digit ();
if (*cp != '0')
significant = 1;
else if (significant == 0)
{
++fracdig_max;
if (fracdig_min > 0)
++fracdig_min;
}
++cp;
}
/* Do rounding. */
digit = hack_digit ();
if (digit > '4')
{
char *tp = cp;
if (digit == '5')
/* This is the critical case. */
if (fracsize == 1 && frac[0] == 0)
/* Rest of the number is zero -> round to even.
(IEEE 754-1985 4.1 says this is the default rounding.) */
if ((*(cp - 1) & 1) == 0)
goto do_expo;
if (fracdig_no > 0)
{
/* Process fractional digits. Terminate if not rounded or
radix character is reached. */
while (*--tp != decimal && *tp == '9')
*tp = '0';
if (*tp != decimal)
/* Round up. */
(*tp)++;
}
if (fracdig_no == 0 || *tp == decimal)
{
/* Round the integer digits. */
if (*(tp - 1) == decimal)
--tp;
while (--tp >= startp && *tp == '9')
*tp = '0';
if (tp >= startp)
/* Round up. */
(*tp)++;
else
/* It is more citical. All digits were 9's. */
{
if (type != 'f')
{
*startp = '1';
exponent += expsign == 0 ? 1 : -1;
}
else if (intdig_no == dig_max)
{
/* This is the case where for type %g the number fits
really in the range for %f output but after rounding
the number of digits is too big. */
*--startp = decimal;
*--startp = '1';
if (info->alt || fracdig_no > 0)
{
/* Overwrite the old radix character. */
startp[intdig_no + 2] = '0';
++fracdig_no;
}
fracdig_no += intdig_no;
intdig_no = 1;
fracdig_max = intdig_max - intdig_no;
++exponent;
/* Now we must print the exponent. */
type = isupper (info->spec) ? 'E' : 'e';
}
else
{
/* We can simply add another another digit before the
radix. */
*--startp = '1';
++intdig_no;
}
/* While rounding the number of digits can change.
If the number now exceeds the limits remove some
fractional digits. */
if (intdig_no + fracdig_no > dig_max)
{
cp -= intdig_no + fracdig_no - dig_max;
fracdig_no -= intdig_no + fracdig_no - dig_max;
}
}
}
}
do_expo:
/* Now remove unnecessary '0' at the end of the string. */
while (fracdig_no > fracdig_min && *(cp - 1) == '0')
{
--cp;
--fracdig_no;
}
/* If we eliminate all fractional digits we perhaps also can remove
the radix character. */
if (fracdig_no == 0 && !info->alt && *(cp - 1) == decimal)
--cp;
if (grouping)
/* Add in separator characters, overwriting the same buffer. */
cp = group_number (startp, cp, intdig_no, grouping, thousands_sep);
/* Write the exponent if it is needed. */
if (type != 'f')
{
*cp++ = type;
*cp++ = expsign ? '-' : '+';
/* Find the magnitude of the exponent. */
expscale = 10;
while (expscale <= exponent)
expscale *= 10;
if (exponent < 10)
/* Exponent always has at least two digits. */
*cp++ = '0';
else
do
{
expscale /= 10;
*cp++ = '0' + (exponent / expscale);
exponent %= expscale;
}
while (expscale > 10);
*cp++ = '0' + exponent;
}
/* Compute number of characters which must be filled with the padding
character. */
if (is_neg || info->showsign || info->space)
--width;
width -= cp - startp;
if (!info->left && info->pad != '0' && width > 0)
PADN (info->pad, width);
if (is_neg)
outchar ('-');
else if (info->showsign)
outchar ('+');
else if (info->space)
outchar (' ');
if (!info->left && info->pad == '0' && width > 0)
PADN ('0', width);
PRINT (startp, cp - startp);
if (info->left && width > 0)
PADN (info->pad, width);
}
return done;
}
/* Return the number of extra grouping characters that will be inserted
into a number with INTDIG_MAX integer digits. */
static unsigned int
guess_grouping (unsigned int intdig_max, const char *grouping, wchar_t sepchar)
{
unsigned int groups;
/* We treat all negative values like CHAR_MAX. */
if (*grouping == CHAR_MAX || *grouping <= 0)
/* No grouping should be done. */
return 0;
groups = 0;
while (intdig_max > *grouping)
{
++groups;
intdig_max -= *grouping++;
if (*grouping == CHAR_MAX || *grouping < 0)
/* No more grouping should be done. */
break;
else if (*grouping == 0)
{
/* Same grouping repeats. */
groups += intdig_max / grouping[-1];
break;
}
}
return groups;
}
/* Group the INTDIG_NO integer digits of the number in [BUF,BUFEND).
There is guaranteed enough space past BUFEND to extend it.
Return the new end of buffer. */
static char *
group_number (char *buf, char *bufend, unsigned int intdig_no,
const char *grouping, wchar_t thousands_sep)
{
unsigned int groups = guess_grouping (intdig_no, grouping, thousands_sep);
char *p;
if (groups == 0)
return bufend;
/* Move the fractional part down. */
memmove (buf + intdig_no + groups, buf + intdig_no,
bufend - (buf + intdig_no));
p = buf + intdig_no + groups - 1;
do
{
unsigned int len = *grouping++;
do
*p-- = buf[--intdig_no];
while (--len > 0);
*p-- = thousands_sep;
if (*grouping == CHAR_MAX || *grouping < 0)
/* No more grouping should be done. */
break;
else if (*grouping == 0)
/* Same grouping repeats. */
--grouping;
} while (intdig_no > *grouping);
/* Copy the remaining ungrouped digits. */
do
*p-- = buf[--intdig_no];
while (p > buf);
return bufend + groups;
}

49
stdio/psignal.c Normal file
View File

@@ -0,0 +1,49 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#include <signal.h>
#ifndef HAVE_GNU_LD
#define _sys_siglist sys_siglist
#endif
/* Defined in sys_siglist.c. */
extern CONST char *CONST _sys_siglist[];
/* Print out on stderr a line consisting of the test in S, a colon, a space,
a message describing the meaning of the signal number SIG and a newline.
If S is NULL or "", the colon and space are omitted. */
void
DEFUN(psignal, (sig, s), int sig AND register CONST char *s)
{
CONST char *colon;
if (s == NULL || s == '\0')
s = colon = "";
else
colon = ": ";
if (sig >= 0 && sig < NSIG)
(void) fprintf(stderr, "%s%s%s\n", s, colon, _sys_siglist[sig]);
else
(void) fprintf(stderr, "%s%sUnknown signal %d\n", s, colon, sig);
}

5
stdio/putc.c Normal file
View File

@@ -0,0 +1,5 @@
#include <ansidecl.h>
#include <stdio.h>
#undef putc
#define fputc putc
#include <fputc.c>

30
stdio/putchar.c Normal file
View File

@@ -0,0 +1,30 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#undef putchar
/* Write the character C on stdout. */
int
DEFUN(putchar, (c), int c)
{
return __putc(c, stdout);
}

32
stdio/puts.c Normal file
View File

@@ -0,0 +1,32 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#undef puts
/* Write the string in S and a newline to stdout. */
int
DEFUN(puts, (s), CONST char *s)
{
return(fputs(s, stdout) || putchar('\n') == EOF ? EOF : 0);
}

31
stdio/putw.c Normal file
View File

@@ -0,0 +1,31 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
/* Write the word (int) W to STREAM. */
int
DEFUN(putw, (w, stream), int w AND FILE *stream)
{
/* Is there a better way? */
if (fwrite((CONST PTR) &w, sizeof(w), 1, stream) < 1)
return(EOF);
return(0);
}

47
stdio/reg-printf.c Normal file
View File

@@ -0,0 +1,47 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <limits.h>
#include <printf.h>
/* Array of functions indexed by format character. */
static printf_function *printf_funcs[UCHAR_MAX + 1];
printf_arginfo_function *__printf_arginfo_table[UCHAR_MAX + 1];
printf_function **__printf_function_table;
/* Register FUNC to be called to format SPEC specifiers. */
int
DEFUN(register_printf_function, (spec, converter, arginfo),
int spec AND printf_function converter AND
printf_arginfo_function arginfo)
{
if (spec < 0 || spec > (int) UCHAR_MAX)
{
errno = EINVAL;
return -1;
}
__printf_function_table = printf_funcs;
__printf_arginfo_table[spec] = arginfo;
printf_funcs[spec] = converter;
return 0;
}

33
stdio/rewind.c Normal file
View File

@@ -0,0 +1,33 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#undef rewind
/* Rewind STREAM to the beginning of the
file and clear its error and EOF flags. */
void
DEFUN(rewind, (stream), FILE *stream)
{
clearerr(stream);
(void) fseek(stream, 0L, SEEK_SET);
clearerr(stream);
}

37
stdio/scanf.c Normal file
View File

@@ -0,0 +1,37 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#include <stdio.h>
/* Read formatted input from stdin according to the format string FORMAT. */
/* VARARGS1 */
int
DEFUN(scanf, (format), CONST char *format DOTS)
{
va_list arg;
int done;
va_start(arg, format);
done = vscanf(format, arg);
va_end(arg);
return done;
}

30
stdio/setbuf.c Normal file
View File

@@ -0,0 +1,30 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stddef.h>
#include <stdio.h>
/* If BUF is NULL, make STREAM unbuffered.
If not, make BUF, which is BUFSIZ bytes long, be its buffer. */
void
DEFUN(setbuf, (stream, buf), FILE *stream AND char *buf)
{
(void) setvbuf(stream, buf, buf != NULL ? _IOFBF : _IONBF, BUFSIZ);
}

30
stdio/setbuffer.c Normal file
View File

@@ -0,0 +1,30 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stddef.h>
#include <stdio.h>
/* If BUF is NULL, make stream unbuffered.
If not, make BUF, which is N bytes long, be its buffer. */
void
DEFUN(setbuffer, (stream, buf, n), FILE *stream AND char *buf AND size_t n)
{
(void) setvbuf(stream, buf, buf != NULL ? _IOFBF : _IONBF, n);
}

29
stdio/setlinebuf.c Normal file
View File

@@ -0,0 +1,29 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
/* Make STREAM line buffered. */
void
DEFUN(setlinebuf, (stream), FILE *stream)
{
if (stream->__buffer != NULL || !stream->__userbuf)
stream->__linebuf = 1;
}

85
stdio/setvbuf.c Normal file
View File

@@ -0,0 +1,85 @@
/* Copyright (C) 1991, 1993 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
/* Make STREAM use the buffering method given in MODE.
If MODE indicates full or line buffering, use BUF,
a buffer of SIZE bytes; if BUF is NULL, malloc a buffer. */
int
DEFUN(setvbuf, (stream, buf, mode, size),
FILE *stream AND char *buf AND int mode AND size_t size)
{
if (!__validfp(stream))
{
errno = EINVAL;
return EOF;
}
/* The ANSI standard says setvbuf can only be called before any I/O is done,
but we allow it to replace an old buffer, flushing it first. */
if (stream->__buffer != NULL)
{
(void) fflush(stream);
/* Free the old buffer if it was malloc'd. */
if (!stream->__userbuf)
free(stream->__buffer);
}
stream->__get_limit = stream->__put_limit = NULL;
stream->__bufp = stream->__buffer = NULL;
stream->__userbuf = stream->__linebuf = stream->__linebuf_active = 0;
switch (mode)
{
default:
errno = EINVAL;
return EOF;
case _IONBF: /* Unbuffered. */
stream->__buffer = NULL;
stream->__bufsize = 0;
stream->__userbuf = 1;
break;
case _IOLBF: /* Line buffered. */
stream->__linebuf = 1;
case _IOFBF: /* Fully buffered. */
if (size == 0)
{
errno = EINVAL;
return EOF;
}
stream->__bufsize = size;
if (buf != NULL)
stream->__userbuf = 1;
else if ((buf = (char *) malloc(size)) == NULL)
return EOF;
stream->__buffer = buf;
break;
}
stream->__bufp = stream->__buffer;
stream->__get_limit = stream->__buffer;
/* The next output operation will prime the stream for writing. */
stream->__put_limit = stream->__buffer;
return 0;
}

39
stdio/snprintf.c Normal file
View File

@@ -0,0 +1,39 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#include <stdio.h>
/* Write formatted output into S, according to the format
string FORMAT, writing no more than MAXLEN characters. */
/* VARARGS3 */
int
DEFUN(snprintf, (s, maxlen, format),
char *s AND size_t maxlen AND CONST char *format DOTS)
{
va_list arg;
int done;
va_start(arg, format);
done = vsnprintf(s, maxlen, format, arg);
va_end(arg);
return done;
}

37
stdio/sprintf.c Normal file
View File

@@ -0,0 +1,37 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#include <stdio.h>
/* Write formatted output into S, according to the format string FORMAT. */
/* VARARGS2 */
int
DEFUN(sprintf, (s, format), char *s AND CONST char *format DOTS)
{
va_list arg;
int done;
va_start(arg, format);
done = vsprintf(s, format, arg);
va_end(arg);
return done;
}

37
stdio/sscanf.c Normal file
View File

@@ -0,0 +1,37 @@
/* Copyright (C) 1991 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#include <stdio.h>
/* Read formatted input from S, according to the format string FORMAT. */
/* VARARGS2 */
int
DEFUN(sscanf, (s, format), CONST char *s AND CONST char *format DOTS)
{
va_list arg;
int done;
va_start(arg, format);
done = __vsscanf(s, format, arg);
va_end(arg);
return done;
}

681
stdio/stdio.h Normal file
View File

@@ -0,0 +1,681 @@
/* Copyright (C) 1991, 1992, 1993, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
/*
* ANSI Standard: 4.9 INPUT/OUTPUT <stdio.h>
*/
#ifndef _STDIO_H
#if !defined(__need_FILE)
#define _STDIO_H 1
#include <features.h>
__BEGIN_DECLS
#define __need_size_t
#define __need_NULL
#include <stddef.h>
#define __need___va_list
#include <stdarg.h>
#ifndef __GNUC_VA_LIST
#define __gnuc_va_list __ptr_t
#endif
#include <gnu/types.h>
#endif /* Don't need FILE. */
#undef __need_FILE
#ifndef __FILE_defined
/* The opaque type of streams. */
typedef struct __stdio_file FILE;
#define __FILE_defined 1
#endif /* FILE not defined. */
#ifdef _STDIO_H
/* The type of the second argument to `fgetpos' and `fsetpos'. */
typedef __off_t fpos_t;
/* The mode of I/O, as given in the MODE argument to fopen, etc. */
typedef struct
{
unsigned int __read:1; /* Open for reading. */
unsigned int __write:1; /* Open for writing. */
unsigned int __append:1; /* Open for appending. */
unsigned int __binary:1; /* Opened binary. */
unsigned int __create:1; /* Create the file. */
unsigned int __exclusive:1; /* Error if it already exists. */
unsigned int __truncate:1; /* Truncate the file on opening. */
} __io_mode;
/* Functions to do I/O and file management for a stream. */
/* Read NBYTES bytes from COOKIE into a buffer pointed to by BUF.
Return number of bytes read. */
typedef __ssize_t __io_read_fn __P ((__ptr_t __cookie, char *__buf,
size_t __nbytes));
/* Write N bytes pointed to by BUF to COOKIE. Write all N bytes
unless there is an error. Return number of bytes written, or -1 if
there is an error without writing anything. If the file has been
opened for append (__mode.__append set), then set the file pointer
to the end of the file and then do the write; if not, just write at
the current file pointer. */
typedef __ssize_t __io_write_fn __P ((__ptr_t __cookie, __const char *__buf,
size_t __n));
/* Move COOKIE's file position to *POS bytes from the
beginning of the file (if W is SEEK_SET),
the current position (if W is SEEK_CUR),
or the end of the file (if W is SEEK_END).
Set *POS to the new file position.
Returns zero if successful, nonzero if not. */
typedef int __io_seek_fn __P ((__ptr_t __cookie, fpos_t *__pos, int __w));
/* Close COOKIE. */
typedef int __io_close_fn __P ((__ptr_t __cookie));
/* Return the file descriptor associated with COOKIE,
or -1 on error. There need not be any associated file descriptor. */
typedef int __io_fileno_fn __P ((__ptr_t __cookie));
#ifdef __USE_GNU
/* User-visible names for the above. */
typedef __io_read_fn cookie_read_function_t;
typedef __io_write_fn cookie_write_function_t;
typedef __io_seek_fn cookie_seek_function_t;
typedef __io_close_fn cookie_close_function_t;
typedef __io_fileno_fn cookie_fileno_function_t;
#endif
/* Low level interface, independent of FILE representation. */
#if defined (__USE_GNU) && !defined (_LIBC)
/* Define the user-visible type, with user-friendly member names. */
typedef struct
{
__io_read_fn *read; /* Read bytes. */
__io_write_fn *write; /* Write bytes. */
__io_seek_fn *seek; /* Seek/tell file position. */
__io_close_fn *close; /* Close file. */
__io_fileno_fn *fileno; /* Return file descriptor. */
} cookie_io_functions_t;
/* This name is still used in the prototypes in this file. */
typedef cookie_io_functions_t __io_functions;
#else
/* Stick to ANSI-safe names. */
typedef struct
{
__io_read_fn *__read; /* Read bytes. */
__io_write_fn *__write; /* Write bytes. */
__io_seek_fn *__seek; /* Seek/tell file position. */
__io_close_fn *__close; /* Close file. */
__io_fileno_fn *__fileno; /* Return file descriptor. */
} __io_functions;
#endif
/* Higher level interface, dependent on FILE representation. */
typedef struct
{
/* Make room in the input buffer. */
int (*__input) __P ((FILE *__stream));
/* Make room in the output buffer. */
void (*__output) __P ((FILE *__stream, int __c));
} __room_functions;
extern __const __io_functions __default_io_functions;
extern __const __room_functions __default_room_functions;
/* Default close function. */
extern __io_close_fn __stdio_close;
/* Open FILE with mode M, store cookie in *COOKIEPTR. */
extern int __stdio_open __P ((__const char *__file, __io_mode __m,
__ptr_t *__cookieptr));
/* Put out an error message for when stdio needs to die. */
extern void __stdio_errmsg __P ((__const char *__msg, size_t __len));
/* Generate a unique file name (and possibly open it with mode "w+b"). */
extern char *__stdio_gen_tempname __P ((__const char *__dir,
__const char *__pfx,
int __dir_search,
size_t *__lenptr,
FILE **__streamptr));
/* Print out MESSAGE on the error output and abort. */
extern void __libc_fatal __P ((__const char *__message))
__attribute__ ((__noreturn__));
/* The FILE structure. */
struct __stdio_file
{
/* Magic number for validation. Must be negative in open streams
for the glue to Unix stdio getc/putc to work.
NOTE: stdio/glue.c has special knowledge of these first four members. */
int __magic;
#define _IOMAGIC 0xfedabeeb /* Magic number to fill `__magic'. */
#define _GLUEMAGIC 0xfeedbabe /* Magic for glued Unix streams. */
char *__bufp; /* Pointer into the buffer. */
char *__get_limit; /* Reading limit. */
char *__put_limit; /* Writing limit. */
char *__buffer; /* Base of buffer. */
size_t __bufsize; /* Size of the buffer. */
__ptr_t __cookie; /* Magic cookie. */
__io_mode __mode; /* File access mode. */
__io_functions __io_funcs; /* I/O functions. */
__room_functions __room_funcs;/* I/O buffer room functions. */
fpos_t __offset; /* Current file position. */
fpos_t __target; /* Target file position. */
FILE *__next; /* Next FILE in the linked list. */
char *__pushback_bufp; /* Old bufp if char pushed back. */
unsigned char __pushback; /* Pushed-back character. */
unsigned int __pushed_back:1; /* A char has been pushed back. */
unsigned int __eof:1; /* End of file encountered. */
unsigned int __error:1; /* Error encountered. */
unsigned int __userbuf:1; /* Buffer from user (should not be freed). */
unsigned int __linebuf:1; /* Flush on newline. */
unsigned int __linebuf_active:1; /* put_limit is not really in use. */
unsigned int __seen:1; /* This stream has been seen. */
unsigned int __ispipe:1; /* Nonzero if opened by popen. */
};
/* All macros used internally by other macros here and by stdio functions begin
with `__'. All of these may evaluate their arguments more than once. */
/* Nonzero if STREAM is a valid stream.
STREAM must be a modifiable lvalue (wow, I got to use that term).
See stdio/glue.c for what the confusing bit is about. */
#define __validfp(stream) \
(stream != NULL && \
((stream->__magic == _GLUEMAGIC && \
(stream = *(((struct { int __magic; FILE **__p; } *) stream)->__p))), \
(stream->__magic == _IOMAGIC)))
/* Clear the error and EOF indicators of STREAM. */
#define __clearerr(stream) ((stream)->__error = (stream)->__eof = 0)
/* Nuke STREAM, making it unusable but available for reuse. */
extern void __invalidate __P ((FILE *__stream));
/* Make sure STREAM->__offset and STREAM->__target are initialized.
Returns 0 if successful, or EOF on
error (but doesn't set STREAM->__error). */
extern int __stdio_check_offset __P ((FILE *__stream));
/* The possibilities for the third argument to `setvbuf'. */
#define _IOFBF 0x1 /* Full buffering. */
#define _IOLBF 0x2 /* Line buffering. */
#define _IONBF 0x4 /* No buffering. */
/* Default buffer size. */
#define BUFSIZ 1024
/* End of file character.
Some things throughout the library rely on this being -1. */
#define EOF (-1)
/* The possibilities for the third argument to `fseek'.
These values should not be changed. */
#define SEEK_SET 0 /* Seek from beginning of file. */
#define SEEK_CUR 1 /* Seek from current position. */
#define SEEK_END 2 /* Seek from end of file. */
#ifdef __USE_SVID
/* Default path prefix for `tempnam' and `tmpnam'. */
#define P_tmpdir "/usr/tmp"
#endif
/* Get the values:
L_tmpnam How long an array of chars must be to be passed to `tmpnam'.
TMP_MAX The minimum number of unique filenames generated by tmpnam
(and tempnam when it uses tmpnam's name space),
or tempnam (the two are separate).
L_ctermid How long an array to pass to `ctermid'.
L_cuserid How long an array to pass to `cuserid'.
FOPEN_MAX Mininum number of files that can be open at once.
FILENAME_MAX Maximum length of a filename. */
#include <stdio_lim.h>
/* All the known streams are in a linked list
linked by the `next' field of the FILE structure. */
extern FILE *__stdio_head; /* Head of the list. */
/* Standard streams. */
extern FILE *stdin, *stdout, *stderr;
#ifdef __STRICT_ANSI__
/* ANSI says these are macros; satisfy pedants. */
#define stdin stdin
#define stdout stdout
#define stderr stderr
#endif
/* Remove file FILENAME. */
extern int remove __P ((__const char *__filename));
/* Rename file OLD to NEW. */
extern int rename __P ((__const char *__old, __const char *__new));
/* Create a temporary file and open it read/write. */
extern FILE *tmpfile __P ((void));
/* Generate a temporary filename. */
extern char *tmpnam __P ((char *__s));
#ifdef __USE_SVID
/* Generate a unique temporary filename using up to five characters of PFX
if it is not NULL. The directory to put this file in is searched for
as follows: First the environment variable "TMPDIR" is checked.
If it contains the name of a writable directory, that directory is used.
If not and if DIR is not NULL, that value is checked. If that fails,
P_tmpdir is tried and finally "/tmp". The storage for the filename
is allocated by `malloc'. */
extern char *tempnam __P ((__const char *__dir, __const char *__pfx));
#endif
/* This performs actual output when necessary, flushing
STREAM's buffer and optionally writing another character. */
extern int __flshfp __P ((FILE *__stream, int __c));
/* Close STREAM, or all streams if STREAM is NULL. */
extern int fclose __P ((FILE *__stream));
/* Flush STREAM, or all streams if STREAM is NULL. */
extern int fflush __P ((FILE *__stream));
/* Open a file and create a new stream for it. */
extern FILE *fopen __P ((__const char *__filename, __const char *__modes));
/* Open a file, replacing an existing stream with it. */
extern FILE *freopen __P ((__const char *__filename,
__const char *__modes, FILE *__stream));
/* Return a new, zeroed, stream.
You must set its cookie and io_mode.
The first operation will give it a buffer unless you do.
It will also give it the default functions unless you set the `seen' flag.
The offset is set to -1, meaning it will be determined by doing a
stationary seek. You can set it to avoid the initial tell call.
The target is set to -1, meaning it will be set to the offset
before the target is needed.
Returns NULL if a stream can't be created. */
extern FILE *__newstream __P ((void));
#ifdef __USE_POSIX
/* Create a new stream that refers to an existing system file descriptor. */
extern FILE *fdopen __P ((int __fd, __const char *__modes));
#endif
#ifdef __USE_GNU
/* Create a new stream that refers to the given magic cookie,
and uses the given functions for input and output. */
extern FILE *fopencookie __P ((__ptr_t __magic_cookie, __const char *__modes,
__io_functions __io_funcs));
/* Create a new stream that refers to a memory buffer. */
extern FILE *fmemopen __P ((__ptr_t __s, size_t __len, __const char *__modes));
/* Open a stream that writes into a malloc'd buffer that is expanded as
necessary. *BUFLOC and *SIZELOC are updated with the buffer's location
and the number of characters written on fflush or fclose. */
extern FILE *open_memstream __P ((char **__bufloc, size_t *__sizeloc));
#endif
/* If BUF is NULL, make STREAM unbuffered.
Else make it use buffer BUF, of size BUFSIZ. */
extern void setbuf __P ((FILE *__stream, char *__buf));
/* Make STREAM use buffering mode MODE.
If BUF is not NULL, use N bytes of it for buffering;
else allocate an internal buffer N bytes long. */
extern int setvbuf __P ((FILE *__stream, char *__buf,
int __modes, size_t __n));
#ifdef __USE_BSD
/* If BUF is NULL, make STREAM unbuffered.
Else make it use SIZE bytes of BUF for buffering. */
extern void setbuffer __P ((FILE *__stream, char *__buf, size_t __size));
/* Make STREAM line-buffered. */
extern void setlinebuf __P ((FILE *__stream));
#endif
/* Write formatted output to STREAM. */
extern int fprintf __P ((FILE *__stream, __const char *__format, ...));
/* Write formatted output to stdout. */
extern int printf __P ((__const char *__format, ...));
/* Write formatted output to S. */
extern int sprintf __P ((char *__s, __const char *__format, ...));
/* Write formatted output to S from argument list ARG. */
extern int vfprintf __P ((FILE *__s, __const char *__format,
__gnuc_va_list __arg));
/* Write formatted output to stdout from argument list ARG. */
extern int vprintf __P ((__const char *__format, __gnuc_va_list __arg));
/* Write formatted output to S from argument list ARG. */
extern int vsprintf __P ((char *__s, __const char *__format,
__gnuc_va_list __arg));
#ifdef __OPTIMIZE__
extern __inline int
vprintf (const char *__fmt, __gnuc_va_list __arg)
{
return vfprintf (stdout, __fmt, __arg);
}
#endif /* Optimizing. */
#ifdef __USE_GNU
/* Maximum chars of output to write in MAXLEN. */
extern int snprintf __P ((char *__s, size_t __maxlen,
__const char *__format, ...));
extern int vsnprintf __P ((char *__s, size_t __maxlen,
__const char *__format, __gnuc_va_list __arg));
/* Write formatted output to a string dynamically allocated with `malloc'.
Store the address of the string in *PTR. */
extern int vasprintf __P ((char **__ptr, __const char *__f,
__gnuc_va_list __arg));
extern int asprintf __P ((char **__ptr, __const char *__fmt, ...));
/* Write formatted output to a file descriptor. */
extern int vdprintf __P ((int __fd, __const char *__fmt,
__gnuc_va_list __arg));
extern int dprintf __P ((int __fd, __const char *__fmt, ...));
#endif
/* Read formatted input from STREAM. */
extern int fscanf __P ((FILE *__stream, __const char *__format, ...));
/* Read formatted input from stdin. */
extern int scanf __P ((__const char *__format, ...));
/* Read formatted input from S. */
extern int sscanf __P ((__const char *__s, __const char *__format, ...));
#ifdef __USE_GNU
/* Read formatted input from S into argument list ARG. */
extern int __vfscanf __P ((FILE *__s, __const char *__format,
__gnuc_va_list __arg));
extern int vfscanf __P ((FILE *__s, __const char *__format,
__gnuc_va_list __arg));
/* Read formatted input from stdin into argument list ARG. */
extern int vscanf __P ((__const char *__format, __gnuc_va_list __arg));
/* Read formatted input from S into argument list ARG. */
extern int __vsscanf __P ((__const char *__s, __const char *__format,
__gnuc_va_list __arg));
extern int vsscanf __P ((__const char *__s, __const char *__format,
__gnuc_va_list __arg));
#ifdef __OPTIMIZE__
extern __inline int
vfscanf (FILE *__s, const char *__fmt, __gnuc_va_list __arg)
{
return __vfscanf (__s, __fmt, __arg);
}
extern __inline int
vscanf (const char *__fmt, __gnuc_va_list __arg)
{
return __vfscanf (stdin, __fmt, __arg);
}
extern __inline int
vsscanf (const char *__s, const char *__fmt, __gnuc_va_list __arg)
{
return __vsscanf (__s, __fmt, __arg);
}
#endif /* Optimizing. */
#endif /* Use GNU. */
/* This does actual reading when necessary, filling STREAM's
buffer and returning the first character in it. */
extern int __fillbf __P ((FILE *__stream));
/* Read a character from STREAM. */
extern int fgetc __P ((FILE *__stream));
extern int getc __P ((FILE *__stream));
/* Read a character from stdin. */
extern int getchar __P ((void));
/* The C standard explicitly says this can
re-evaluate its argument, so it does. */
#define __getc(stream) \
((stream)->__bufp < (stream)->__get_limit ? \
(int) ((unsigned char) *(stream)->__bufp++) : __fillbf(stream))
/* The C standard explicitly says this is a macro,
so we always do the optimization for it. */
#define getc(stream) __getc(stream)
#ifdef __OPTIMIZE__
extern __inline int
getchar (void)
{
return __getc (stdin);
}
#endif /* Optimizing. */
/* Write a character to STREAM. */
extern int fputc __P ((int __c, FILE *__stream));
extern int putc __P ((int __c, FILE *__stream));
/* Write a character to stdout. */
extern int putchar __P ((int __c));
/* The C standard explicitly says this can
re-evaluate its arguments, so it does. */
#define __putc(c, stream) \
((stream)->__bufp < (stream)->__put_limit ? \
(int) (unsigned char) (*(stream)->__bufp++ = (unsigned char) (c)) : \
__flshfp ((stream), (unsigned char) (c)))
/* The C standard explicitly says this can be a macro,
so we always do the optimization for it. */
#define putc(c, stream) __putc ((c), (stream))
#ifdef __OPTIMIZE__
extern __inline int
putchar (int __c)
{
return __putc (__c, stdout);
}
#endif
#if defined(__USE_SVID) || defined(__USE_MISC)
/* Get a word (int) from STREAM. */
extern int getw __P ((FILE *__stream));
/* Write a word (int) to STREAM. */
extern int putw __P ((int __w, FILE *__stream));
#endif
/* Get a newline-terminated string of finite length from STREAM. */
extern char *fgets __P ((char *__s, int __n, FILE *__stream));
/* Get a newline-terminated string from stdin, removing the newline.
DO NOT USE THIS FUNCTION!! There is no limit on how much it will read. */
extern char *gets __P ((char *__s));
#ifdef __USE_GNU
#include <sys/types.h>
/* Read up to (and including) a DELIMITER from STREAM into *LINEPTR
(and null-terminate it). *LINEPTR is a pointer returned from malloc (or
NULL), pointing to *N characters of space. It is realloc'd as
necessary. Returns the number of characters read (not including the
null terminator), or -1 on error or EOF. */
ssize_t __getdelim __P ((char **__lineptr, size_t *__n,
int __delimiter, FILE *__stream));
ssize_t getdelim __P ((char **__lineptr, size_t *__n,
int __delimiter, FILE *__stream));
/* Like `getdelim', but reads up to a newline. */
ssize_t __getline __P ((char **__lineptr, size_t *__n, FILE *__stream));
ssize_t getline __P ((char **__lineptr, size_t *__n, FILE *__stream));
#ifdef __OPTIMIZE__
extern __inline ssize_t
__getline (char **__lineptr, size_t *__n, FILE *__stream)
{
return __getdelim (__lineptr, __n, '\n', __stream);
}
extern __inline ssize_t
getdelim (char **__lineptr, size_t *__n, int __delimiter, FILE *__stream)
{
return __getdelim (__lineptr, __n, __delimiter, __stream);
}
extern __inline ssize_t
getline (char **__lineptr, size_t *__n, FILE *__stream)
{
return __getline (__lineptr, __n, __stream);
}
#endif /* Optimizing. */
#endif
/* Write a string to STREAM. */
extern int fputs __P ((__const char *__s, FILE *__stream));
/* Write a string, followed by a newline, to stdout. */
extern int puts __P ((__const char *__s));
/* Push a character back onto the input buffer of STREAM. */
extern int ungetc __P ((int __c, FILE *__stream));
/* Read chunks of generic data from STREAM. */
extern size_t fread __P ((__ptr_t __ptr, size_t __size,
size_t __n, FILE *__stream));
/* Write chunks of generic data to STREAM. */
extern size_t fwrite __P ((__const __ptr_t __ptr, size_t __size,
size_t __n, FILE *__s));
/* Seek to a certain position on STREAM. */
extern int fseek __P ((FILE *__stream, long int __off, int __whence));
/* Return the current position of STREAM. */
extern long int ftell __P ((FILE *__stream));
/* Rewind to the beginning of STREAM. */
extern void rewind __P ((FILE *__stream));
/* Get STREAM's position. */
extern int fgetpos __P ((FILE *__stream, fpos_t *__pos));
/* Set STREAM's position. */
extern int fsetpos __P ((FILE *__stream, __const fpos_t *__pos));
/* Clear the error and EOF indicators for STREAM. */
extern void clearerr __P ((FILE *__stream));
/* Return the EOF indicator for STREAM. */
extern int feof __P ((FILE *__stream));
/* Return the error indicator for STREAM. */
extern int ferror __P ((FILE *__stream));
#ifdef __OPTIMIZE__
#define feof(stream) ((stream)->__eof != 0)
#define ferror(stream) ((stream)->__error != 0)
#endif /* Optimizing. */
/* Print a message describing the meaning of the value of errno. */
extern void perror __P ((__const char *__s));
#ifdef __USE_BSD
extern int sys_nerr;
extern char *sys_errlist[];
#endif
#ifdef __USE_GNU
extern int _sys_nerr;
extern char *_sys_errlist[];
#endif
#ifdef __USE_POSIX
/* Return the system file descriptor for STREAM. */
extern int fileno __P ((FILE *__stream));
#endif /* Use POSIX. */
#if (defined (__USE_POSIX2) || defined(__USE_SVID) || defined(__USE_BSD) || \
defined(__USE_MISC))
/* Create a new stream connected to a pipe running the given command. */
extern FILE *popen __P ((__const char *__command, __const char *__modes));
/* Close a stream opened by popen and return the status of its child. */
extern int pclose __P ((FILE *__stream));
#endif
#ifdef __USE_POSIX
/* Return the name of the controlling terminal. */
extern char *ctermid __P ((char *__s));
/* Return the name of the current user. */
extern char *cuserid __P ((char *__s));
#endif
#ifdef __USE_GNU
struct obstack; /* See <obstack.h>. */
/* Open a stream that writes to OBSTACK. */
extern FILE *open_obstack_stream __P ((struct obstack *__obstack));
/* Write formatted output to an obstack. */
extern int obstack_printf __P ((struct obstack *__obstack,
__const char *__format, ...));
extern int obstack_vprintf __P ((struct obstack *__obstack,
__const char *__format,
__gnuc_va_list __args));
#endif
__END_DECLS
#endif /* <stdio.h> included. */
#endif /* stdio.h */

50
stdio/tempnam.c Normal file
View File

@@ -0,0 +1,50 @@
/* Copyright (C) 1991, 1993 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Generate a unique temporary filename using up to five characters of PFX
if it is not NULL. The directory to put this file in is searched for
as follows: First the environment variable "TMPDIR" is checked.
If it contains the name of a writable directory, that directory is used.
If not and if DIR is not NULL, that value is checked. If that fails,
P_tmpdir is tried and finally "/tmp". The storage for the filename
is allocated by `malloc'. */
char *
DEFUN(tempnam, (dir, pfx), CONST char *dir AND CONST char *pfx)
{
size_t len;
register char *s;
register char *t = __stdio_gen_tempname(dir, pfx, 1, &len, (FILE **) NULL);
if (t == NULL)
return NULL;
s = (char *) malloc(len);
if (s == NULL)
return NULL;
(void) memcpy(s, t, len);
return s;
}

31
stdio/temptest.c Normal file
View File

@@ -0,0 +1,31 @@
#include <ansidecl.h>
#include <stdio.h>
#include <string.h>
char *files[500];
int
main ()
{
char *fn;
FILE *fp;
int i;
for (i = 0; i < 500; i++) {
fn = __stdio_gen_tempname((CONST char *) NULL,
"file", 0, (size_t *) NULL, (FILE **) NULL);
if (fn == NULL) {
printf ("__stdio_gen_tempname failed\n");
exit (1);
}
files[i] = strdup (fn);
printf ("file: %s\n", fn);
fp = fopen (fn, "w");
fclose (fp);
}
for (i = 0; i < 500; i++)
remove (files[i]);
exit (0);
}

67
stdio/test-fseek.c Normal file
View File

@@ -0,0 +1,67 @@
#include <ansidecl.h>
#include <stdio.h>
#define TESTFILE "test.dat"
int
main __P((void))
{
FILE *fp;
int i, j;
puts ("\nFile seek test");
fp = fopen (TESTFILE, "w");
if (fp == NULL)
{
perror (TESTFILE);
return 1;
}
for (i = 0; i < 256; i++)
putc (i, fp);
if (freopen (TESTFILE, "r", fp) != fp)
{
perror ("Cannot open file for reading");
return 1;
}
for (i = 1; i <= 255; i++)
{
printf ("%3d\n", i);
fseek (fp, (long) -i, SEEK_END);
if ((j = getc (fp)) != 256 - i)
{
printf ("SEEK_END failed %d\n", j);
break;
}
if (fseek (fp, (long) i, SEEK_SET))
{
puts ("Cannot SEEK_SET");
break;
}
if ((j = getc (fp)) != i)
{
printf ("SEEK_SET failed %d\n", j);
break;
}
if (fseek (fp, (long) i, SEEK_SET))
{
puts ("Cannot SEEK_SET");
break;
}
if (fseek (fp, (long) (i >= 128 ? -128 : 128), SEEK_CUR))
{
puts ("Cannot SEEK_CUR");
break;
}
if ((j = getc (fp)) != (i >= 128 ? i - 128 : i + 128))
{
printf ("SEEK_CUR failed %d\n", j);
break;
}
}
fclose (fp);
puts ((i > 255) ? "Test succeeded." : "Test FAILED!");
return (i > 255) ? 0 : 1;
}

68
stdio/test-fwrite.c Normal file
View File

@@ -0,0 +1,68 @@
#include <stdio.h>
#include <string.h>
int
main ()
{
FILE *f = tmpfile ();
char obuf[99999], ibuf[sizeof obuf];
char *line;
size_t linesz;
if (! f)
{
perror ("tmpfile");
return 1;
}
if (fputs ("line\n", f) == EOF)
{
perror ("fputs");
return 1;
}
memset (obuf, 'z', sizeof obuf);
memset (ibuf, 'y', sizeof ibuf);
if (fwrite (obuf, sizeof obuf, 1, f) != 1)
{
perror ("fwrite");
return 1;
}
rewind (f);
line = NULL;
linesz = 0;
if (getline (&line, &linesz, f) != 5)
{
perror ("getline");
return 1;
}
if (strcmp (line, "line\n"))
{
puts ("Lines differ. Test FAILED!");
return 1;
}
if (fread (ibuf, sizeof ibuf, 1, f) != 1)
{
perror ("fread");
return 1;
}
if (memcmp (ibuf, obuf, sizeof ibuf))
{
puts ("Buffers differ. Test FAILED!");
return 1;
}
asprintf (&line, "\
GDB is free software and you are welcome to distribute copies of it\n\
under certain conditions; type \"show copying\" to see the conditions.\n\
There is absolutely no warranty for GDB; type \"show warranty\" for details.\n\
");
puts ("Test succeeded.");
return 0;
}

67
stdio/test-popen.c Normal file
View File

@@ -0,0 +1,67 @@
#include <ansidecl.h>
#include <stdio.h>
#include <stdlib.h>
void
DEFUN(write_data, (stream), FILE *stream)
{
int i;
for (i=0; i<100; i++)
fprintf (stream, "%d\n", i);
if (ferror (stream)) {
fprintf (stderr, "Output to stream failed.\n");
exit (1);
}
}
void
DEFUN(read_data, (stream), FILE *stream)
{
int i, j;
for (i=0; i<100; i++)
{
if (fscanf (stream, "%d\n", &j) != 1 || j != i)
{
if (ferror (stream))
perror ("fscanf");
puts ("Test FAILED!");
exit (1);
}
}
}
int
DEFUN_VOID(main)
{
FILE *output, *input;
int wstatus, rstatus;
output = popen ("/bin/cat >tstpopen.tmp", "w");
if (output == NULL)
{
perror ("popen");
puts ("Test FAILED!");
exit (1);
}
write_data (output);
wstatus = pclose (output);
printf ("writing pclose returned %d\n", wstatus);
input = popen ("/bin/cat tstpopen.tmp", "r");
if (input == NULL)
{
perror ("tstpopen.tmp");
puts ("Test FAILED!");
exit (1);
}
read_data (input);
rstatus = pclose (input);
printf ("reading pclose returned %d\n", rstatus);
puts (wstatus | rstatus ? "Test FAILED!" : "Test succeeded.");
exit (wstatus | rstatus);
}

129
stdio/test_rdwr.c Normal file
View File

@@ -0,0 +1,129 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
DEFUN(main, (argc, argv), int argc AND char **argv)
{
static CONST char hello[] = "Hello, world.\n";
static CONST char replace[] = "Hewwo, world.\n";
static CONST size_t replace_from = 2, replace_to = 4;
char filename[FILENAME_MAX];
char *name = strrchr(*argv, '/');
char buf[BUFSIZ];
FILE *f;
int lose = 0;
if (name != NULL)
++name;
else
name = *argv;
(void) sprintf(filename, "/tmp/%s.test", name);
f = fopen(filename, "w+");
if (f == NULL)
{
perror(filename);
exit(1);
}
(void) fputs(hello, f);
rewind(f);
(void) fgets(buf, sizeof(buf), f);
rewind(f);
(void) fputs(buf, f);
rewind(f);
{
register size_t i;
for (i = 0; i < replace_from; ++i)
{
int c = getc(f);
if (c == EOF)
{
printf("EOF at %u.\n", i);
lose = 1;
break;
}
else if (c != hello[i])
{
printf("Got '%c' instead of '%c' at %u.\n",
(unsigned char) c, hello[i], i);
lose = 1;
break;
}
}
}
{
long int where = ftell(f);
if (where == replace_from)
{
register size_t i;
for (i = replace_from; i < replace_to; ++i)
if (putc(replace[i], f) == EOF)
{
printf("putc('%c') got %s at %u.\n",
replace[i], strerror(errno), i);
lose = 1;
break;
}
}
else if (where == -1L)
{
printf("ftell got %s (should be at %u).\n",
strerror(errno), replace_from);
lose = 1;
}
else
{
printf("ftell returns %u; should be %u.\n", where, replace_from);
lose = 1;
}
}
if (!lose)
{
rewind(f);
if (fgets(buf, sizeof(buf), f) == NULL)
{
printf("fgets got %s.\n", strerror(errno));
lose = 1;
}
else if (strcmp(buf, replace))
{
printf("Read \"%s\" instead of \"%s\".\n", buf, replace);
lose = 1;
}
}
if (lose)
printf("Test FAILED! Losing file is \"%s\".\n", filename);
else
{
(void) remove(filename);
puts("Test succeeded.");
}
exit(lose ? EXIT_FAILURE : EXIT_SUCCESS);
}

43
stdio/tmpfile.c Normal file
View File

@@ -0,0 +1,43 @@
/* Copyright (C) 1991, 1993 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
/* This returns a new stream opened on a temporary file (generated
by tmpnam) The file is opened with mode "w+b" (binary read/write).
If we couldn't generate a unique filename or the file couldn't
be opened, NULL is returned. */
FILE *
DEFUN_VOID(tmpfile)
{
char *filename;
FILE *f;
filename = __stdio_gen_tempname ((char *) NULL, "tmpf", 0,
(size_t *) NULL, &f);
if (filename == NULL)
return NULL;
/* Note that this relies on the Unix semantics that
a file is not really removed until it is closed. */
(void) remove (filename);
return f;
}

42
stdio/tmpnam.c Normal file
View File

@@ -0,0 +1,42 @@
/* Copyright (C) 1991, 1993 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
/* Generate a unique filename in P_tmpdir. */
char *
DEFUN(tmpnam, (s), register char *s)
{
register char *t = __stdio_gen_tempname((CONST char *) NULL,
(CONST char *) NULL, 0,
(size_t *) NULL, (FILE **) NULL);
if (t == NULL)
return NULL;
if (s != NULL)
(void) strcpy(s, t);
else
s = t;
return s;
}

37
stdio/tst-fileno.c Normal file
View File

@@ -0,0 +1,37 @@
/* Copyright (C) 1994 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#include <unistd.h>
static int
DEFUN(check, (name, stream, fd), CONST char *name AND FILE *stream AND int fd)
{
int sfd = fileno (stream);
printf ("(fileno (%s) = %d) %c= %d\n", name, sfd, sfd == fd ? '=' : '!', fd);
return sfd != fd;
}
int
DEFUN_VOID(main)
{
exit (check ("stdin", stdin, STDIN_FILENO) ||
check ("stdout", stdout, STDOUT_FILENO) ||
check ("stderr", stderr, STDERR_FILENO));
}

298
stdio/tst-printf.c Normal file
View File

@@ -0,0 +1,298 @@
/* Copyright (C) 1991, 1992, 1993, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#ifdef BSD
#include </usr/include/stdio.h>
#define EXIT_SUCCESS 0
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
#include <float.h>
void
DEFUN(fmtchk, (fmt), CONST char *fmt)
{
(void) fputs(fmt, stdout);
(void) printf(":\t`");
(void) printf(fmt, 0x12);
(void) printf("'\n");
}
void
DEFUN(fmtst1chk, (fmt), CONST char *fmt)
{
(void) fputs(fmt, stdout);
(void) printf(":\t`");
(void) printf(fmt, 4, 0x12);
(void) printf("'\n");
}
void
DEFUN(fmtst2chk, (fmt), CONST char *fmt)
{
(void) fputs(fmt, stdout);
(void) printf(":\t`");
(void) printf(fmt, 4, 4, 0x12);
(void) printf("'\n");
}
/* This page is covered by the following copyright: */
/* (C) Copyright C E Chew
*
* Feel free to copy, use and distribute this software provided:
*
* 1. you do not pretend that you wrote it
* 2. you leave this copyright notice intact.
*/
/*
* Extracted from exercise.c for glibc-1.05 bug report by Bruce Evans.
*/
#define DEC -123
#define INT 255
#define UNS (~0)
/* Formatted Output Test
*
* This exercises the output formatting code.
*/
void
DEFUN_VOID(fp_test)
{
int i, j, k, l;
char buf[7];
char *prefix = buf;
char tp[20];
puts("\nFormatted output test");
printf("prefix 6d 6o 6x 6X 6u\n");
strcpy(prefix, "%");
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
for (k = 0; k < 2; k++) {
for (l = 0; l < 2; l++) {
strcpy(prefix, "%");
if (i == 0) strcat(prefix, "-");
if (j == 0) strcat(prefix, "+");
if (k == 0) strcat(prefix, "#");
if (l == 0) strcat(prefix, "0");
printf("%5s |", prefix);
strcpy(tp, prefix);
strcat(tp, "6d |");
printf(tp, DEC);
strcpy(tp, prefix);
strcat(tp, "6o |");
printf(tp, INT);
strcpy(tp, prefix);
strcat(tp, "6x |");
printf(tp, INT);
strcpy(tp, prefix);
strcat(tp, "6X |");
printf(tp, INT);
strcpy(tp, prefix);
strcat(tp, "6u |");
printf(tp, UNS);
printf("\n");
}
}
}
}
printf("%10s\n", (char *) NULL);
printf("%-10s\n", (char *) NULL);
}
int
DEFUN_VOID(main)
{
static char shortstr[] = "Hi, Z.";
static char longstr[] = "Good morning, Doctor Chandra. This is Hal. \
I am ready for my first lesson today.";
fmtchk("%.4x");
fmtchk("%04x");
fmtchk("%4.4x");
fmtchk("%04.4x");
fmtchk("%4.3x");
fmtchk("%04.3x");
fmtst1chk("%.*x");
fmtst1chk("%0*x");
fmtst2chk("%*.*x");
fmtst2chk("%0*.*x");
#ifndef BSD
printf("bad format:\t\"%z\"\n");
printf("nil pointer (padded):\t\"%10p\"\n", (PTR) NULL);
#endif
printf("decimal negative:\t\"%d\"\n", -2345);
printf("octal negative:\t\"%o\"\n", -2345);
printf("hex negative:\t\"%x\"\n", -2345);
printf("long decimal number:\t\"%ld\"\n", -123456L);
printf("long octal negative:\t\"%lo\"\n", -2345L);
printf("long unsigned decimal number:\t\"%lu\"\n", -123456L);
printf("zero-padded LDN:\t\"%010ld\"\n", -123456L);
printf("left-adjusted ZLDN:\t\"%-010ld\"\n", -123456);
printf("space-padded LDN:\t\"%10ld\"\n", -123456L);
printf("left-adjusted SLDN:\t\"%-10ld\"\n", -123456L);
printf("zero-padded string:\t\"%010s\"\n", shortstr);
printf("left-adjusted Z string:\t\"%-010s\"\n", shortstr);
printf("space-padded string:\t\"%10s\"\n", shortstr);
printf("left-adjusted S string:\t\"%-10s\"\n", shortstr);
printf("null string:\t\"%s\"\n", (char *)NULL);
printf("limited string:\t\"%.22s\"\n", longstr);
printf("e-style >= 1:\t\"%e\"\n", 12.34);
printf("e-style >= .1:\t\"%e\"\n", 0.1234);
printf("e-style < .1:\t\"%e\"\n", 0.001234);
printf("e-style big:\t\"%.60e\"\n", 1e20);
printf ("e-style == .1:\t\"%e\"\n", 0.1);
printf("f-style >= 1:\t\"%f\"\n", 12.34);
printf("f-style >= .1:\t\"%f\"\n", 0.1234);
printf("f-style < .1:\t\"%f\"\n", 0.001234);
printf("g-style >= 1:\t\"%g\"\n", 12.34);
printf("g-style >= .1:\t\"%g\"\n", 0.1234);
printf("g-style < .1:\t\"%g\"\n", 0.001234);
printf("g-style big:\t\"%.60g\"\n", 1e20);
printf (" %6.5f\n", .099999999860301614);
printf (" %6.5f\n", .1);
printf ("x%5.4fx\n", .5);
printf ("%#03x\n", 1);
{
double d = FLT_MIN;
int niter = 17;
while (niter-- != 0)
printf ("%.17e\n", d / 2);
fflush (stdout);
}
printf ("%15.5e\n", 4.9406564584124654e-324);
#define FORMAT "|%12.4f|%12.4e|%12.4g|\n"
printf (FORMAT, 0.0, 0.0, 0.0);
printf (FORMAT, 1.0, 1.0, 1.0);
printf (FORMAT, -1.0, -1.0, -1.0);
printf (FORMAT, 100.0, 100.0, 100.0);
printf (FORMAT, 1000.0, 1000.0, 1000.0);
printf (FORMAT, 10000.0, 10000.0, 10000.0);
printf (FORMAT, 12345.0, 12345.0, 12345.0);
printf (FORMAT, 100000.0, 100000.0, 100000.0);
printf (FORMAT, 123456.0, 123456.0, 123456.0);
#undef FORMAT
{
char buf[20];
printf ("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n",
snprintf (buf, sizeof (buf), "%30s", "foo"), sizeof (buf), buf);
}
fp_test ();
printf ("%e should be 1.234568e+06\n", 1234567.8);
printf ("%f should be 1234567.800000\n", 1234567.8);
printf ("%g should be 1.23457e+06\n", 1234567.8);
printf ("%g should be 123.456\n", 123.456);
printf ("%g should be 1e+06\n", 1000000.0);
printf ("%g should be 10\n", 10.0);
printf ("%g should be 0.02\n", 0.02);
{
double x=1.0;
printf("%.17f\n",(1.0/x/10.0+1.0)*x-x);
}
puts ("--- Should be no further output. ---");
rfg1 ();
rfg2 ();
exit(EXIT_SUCCESS);
}
rfg1 ()
{
char buf[100];
sprintf (buf, "%5.s", "xyz");
if (strcmp (buf, " ") != 0)
printf ("got: '%s', expected: '%s'\n", buf, " ");
sprintf (buf, "%5.f", 33.3);
if (strcmp (buf, " 33") != 0)
printf ("got: '%s', expected: '%s'\n", buf, " 33");
sprintf (buf, "%8.e", 33.3e7);
if (strcmp (buf, " 3e+08") != 0)
printf ("got: '%s', expected: '%s'\n", buf, " 3e+08");
sprintf (buf, "%8.E", 33.3e7);
if (strcmp (buf, " 3E+08") != 0)
printf ("got: '%s', expected: '%s'\n", buf, " 3E+08");
sprintf (buf, "%.g", 33.3);
if (strcmp (buf, "3e+01") != 0)
printf ("got: '%s', expected: '%s'\n", buf, "3e+01");
sprintf (buf, "%.G", 33.3);
if (strcmp (buf, "3E+01") != 0)
printf ("got: '%s', expected: '%s'\n", buf, "3E+01");
return 0;
}
rfg2 ()
{
int prec;
char buf[100];
prec = 0;
sprintf (buf, "%.*g", prec, 3.3);
if (strcmp (buf, "3") != 0)
printf ("got: '%s', expected: '%s'\n", buf, "3");
prec = 0;
sprintf (buf, "%.*G", prec, 3.3);
if (strcmp (buf, "3") != 0)
printf ("got: '%s', expected: '%s'\n", buf, "3");
prec = 0;
sprintf (buf, "%7.*G", prec, 3.33);
if (strcmp (buf, " 3") != 0)
printf ("got: '%s', expected: '%s'\n", buf, " 3");
prec = 3;
sprintf (buf, "%04.*o", prec, 33);
if (strcmp (buf, " 041") != 0)
printf ("got: '%s', expected: '%s'\n", buf, " 041");
prec = 7;
sprintf (buf, "%09.*u", prec, 33);
if (strcmp (buf, " 0000033") != 0)
printf ("got: '%s', expected: '%s'\n", buf, " 0000033");
prec = 3;
sprintf (buf, "%04.*x", prec, 33);
if (strcmp (buf, " 021") != 0)
printf ("got: '%s', expected: '%s'\n", buf, " 021");
prec = 3;
sprintf (buf, "%04.*X", prec, 33);
if (strcmp (buf, " 021") != 0)
printf ("got: '%s', expected: '%s'\n", buf, " 021");
return 0;
}

46
stdio/tstgetln.c Normal file
View File

@@ -0,0 +1,46 @@
/* Copyright (C) 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
int
DEFUN_VOID(main)
{
char *buf = NULL;
size_t size = 0;
ssize_t len;
while ((len = getline (&buf, &size, stdin)) != -1)
{
printf ("bufsize %u; read %d: ", size, len);
if (fwrite (buf, len, 1, stdout) != 1)
{
perror ("fwrite");
return 1;
}
}
if (ferror (stdin))
{
perror ("getline");
return 1;
}
return 0;
}

3
stdio/tstgetln.input Normal file
View File

@@ -0,0 +1,3 @@
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
z

100
stdio/tstscanf.c Normal file
View File

@@ -0,0 +1,100 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#ifdef BSD
#include </usr/include/stdio.h>
#else
#include <stdio.h>
#endif
#include <stdlib.h>
#include <string.h>
int
DEFUN(main, (argc, argv), int argc AND char **argv)
{
char buf[BUFSIZ];
FILE *in = stdin, *out = stdout;
if (argc == 2 && !strcmp (argv[1], "-opipe"))
{
out = popen ("/bin/cat", "w");
if (out == NULL)
{
perror ("popen: /bin/cat");
exit (EXIT_FAILURE);
}
}
else if (argc == 3 && !strcmp (argv[1], "-ipipe"))
{
sprintf (buf, "/bin/cat %s", argv[2]);
in = popen (buf, "r");
}
{
char name[50];
fprintf (out,
"sscanf (\"thompson\", \"%%s\", name) == %d, name == \"%s\"\n",
sscanf ("thompson", "%s", name),
name);
}
fputs ("Testing scanf (vfscanf)\n", out);
fputs ("Test 1:\n", out);
{
int n, i;
float x;
char name[50];
n = fscanf (in, "%d%f%s", &i, &x, name);
fprintf (out, "n = %d, i = %d, x = %f, name = \"%.50s\"\n",
n, i, x, name);
}
fprintf (out, "Residual: \"%s\"\n", fgets (buf, sizeof (buf), in));
fputs ("Test 2:\n", out);
{
int i;
float x;
char name[50];
(void) fscanf (in, "%2d%f%*d %[0123456789]", &i, &x, name);
fprintf (out, "i = %d, x = %f, name = \"%.50s\"\n", i, x, name);
}
fprintf (out, "Residual: \"%s\"\n", fgets (buf, sizeof (buf), in));
fputs ("Test 3:\n", out);
{
float quant;
char units[21], item[21];
while (!feof (in) && !ferror (in))
{
int count;
quant = 0.0;
units[0] = item[0] = '\0';
count = fscanf (in, "%f%20s of %20s", &quant, units, item);
(void) fscanf (in, "%*[^\n]");
fprintf (out, "count = %d, quant = %f, item = %.21s, units = %.21s\n",
count, quant, item, units);
}
}
fprintf (out, "Residual: \"%s\"\n", fgets (buf, sizeof (buf), in));
if (out != stdout)
pclose (out);
exit(EXIT_SUCCESS);
}

7
stdio/tstscanf.input Normal file
View File

@@ -0,0 +1,7 @@
25 54.32E-1 thompson
56789 0123 56a72
2 quarts of oil
-12.8degrees Celsius
lots of luck
10.0LBS of fertilizer
100ergs of energy

58
stdio/ungetc.c Normal file
View File

@@ -0,0 +1,58 @@
/* Copyright (C) 1991, 1993 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <stdio.h>
/* Push the character C back onto the input stream of STREAM. */
int
DEFUN(ungetc, (c, stream), register int c AND register FILE *stream)
{
if (!__validfp(stream) || !stream->__mode.__read)
{
errno = EINVAL;
return EOF;
}
if (c == EOF)
return EOF;
if (stream->__pushed_back)
/* There is already a char pushed back. */
return EOF;
if ((stream->__linebuf_active || stream->__put_limit > stream->__buffer) &&
/* This is a read-write stream with something in its buffer.
Flush the stream. */
__flshfp (stream, EOF) == EOF)
return EOF;
stream->__pushback = (unsigned char) c;
/* Tell __fillbf we've pushed back a char. */
stream->__pushed_back = 1;
stream->__pushback_bufp = stream->__bufp;
/* Make the next getc call __fillbf. It will return C. */
stream->__bufp = stream->__get_limit;
/* We just gave it another character to read, so it's not at EOF. */
stream->__eof = 0;
return stream->__pushback;
}

86
stdio/vasprintf.c Normal file
View File

@@ -0,0 +1,86 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Enlarge STREAM's buffer. */
static void
DEFUN(enlarge_buffer, (stream, c),
register FILE *stream AND int c)
{
ptrdiff_t bufp_offset = stream->__bufp - stream->__buffer;
char *newbuf;
stream->__bufsize += 100;
newbuf = (char *) realloc ((PTR) stream->__buffer, stream->__bufsize);
if (newbuf == NULL)
{
free ((PTR) stream->__buffer);
stream->__buffer = stream->__bufp
= stream->__put_limit = stream->__get_limit = NULL;
stream->__error = 1;
}
else
{
stream->__buffer = newbuf;
stream->__bufp = stream->__buffer + bufp_offset;
stream->__get_limit = stream->__put_limit;
stream->__put_limit = stream->__buffer + stream->__bufsize;
if (c != EOF)
*stream->__bufp++ = (unsigned char) c;
}
}
/* Write formatted output from FORMAT to a string which is
allocated with malloc and stored in *STRING_PTR. */
int
DEFUN(vasprintf, (string_ptr, format, args),
char **string_ptr AND CONST char *format AND va_list args)
{
FILE f;
int done;
memset ((PTR) &f, 0, sizeof (f));
f.__magic = _IOMAGIC;
f.__bufsize = 100;
f.__buffer = (char *) malloc (f.__bufsize);
if (f.__buffer == NULL)
return -1;
f.__bufp = f.__buffer;
f.__put_limit = f.__buffer + f.__bufsize;
f.__mode.__write = 1;
f.__room_funcs.__output = enlarge_buffer;
f.__seen = 1;
done = vfprintf (&f, format, args);
if (done < 0)
return done;
*string_ptr = realloc (f.__buffer, (f.__bufp - f.__buffer) + 1);
if (*string_ptr == NULL)
*string_ptr = f.__buffer;
(*string_ptr)[f.__bufp - f.__buffer] = '\0';
return done;
}

51
stdio/vdprintf.c Normal file
View File

@@ -0,0 +1,51 @@
/* Copyright (C) 1991, 1992, 1993 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
/* Write formatted output to file descriptor D according to the format string
FORMAT, using the argument list in ARG. */
int
DEFUN(vdprintf, (d, format, arg),
int d AND CONST char *format AND va_list arg)
{
int done;
FILE f;
/* Create an unbuffered stream talking to D on the stack. */
memset ((PTR) &f, 0, sizeof(f));
f.__magic = _IOMAGIC;
f.__mode.__write = 1;
f.__cookie = (PTR) (long int) d; /* Casting to long quiets GCC on Alpha. */
f.__room_funcs = __default_room_functions;
f.__io_funcs = __default_io_functions;
f.__seen = 1;
f.__userbuf = 1;
/* vfprintf will use a buffer on the stack for the life of the call,
and flush it when finished. */
done = vfprintf (&f, format, arg);
return done;
}

907
stdio/vfprintf.c Normal file
View File

@@ -0,0 +1,907 @@
/* Copyright (C) 1991, 1992, 1993, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <localeinfo.h>
#include <ctype.h>
#include <errno.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <printf.h>
#include <assert.h>
#include <stddef.h>
#include "_itoa.h"
/* This function from the GNU C library is also used in libio.
To compile for use in libio, compile with -DUSE_IN_LIBIO. */
#ifdef USE_IN_LIBIO
/* This code is for use in libio. */
#include <libioP.h>
#define PUT(f, s, n) _IO_sputn (f, s, n)
#define PAD(padchar) _IO_padn (s, padchar, width)
#define PUTC(c, f) _IO_putc(c, f)
#define vfprintf _IO_vfprintf
#define size_t _IO_size_t
#define FILE _IO_FILE
#define va_list _IO_va_list
#undef BUFSIZ
#define BUFSIZ _IO_BUFSIZ
#define ARGCHECK(s, format) \
do \
{ \
/* Check file argument for consistence. */ \
CHECK_FILE(s, -1); \
if (s->_flags & _IO_NO_WRITES || format == NULL) \
{ \
MAYBE_SET_EINVAL; \
return -1; \
} \
} while (0)
#define UNBUFFERED_P(s) ((s)->_IO_file_flags & _IO_UNBUFFERED)
#else /* ! USE_IN_LIBIO */
/* This code is for use in the GNU C library. */
#include <stdio.h>
#define PUTC(c, f) putc (c, f)
#define PUT(f, s, n) fwrite (s, 1, n, f)
ssize_t __printf_pad __P ((FILE *, char pad, int n));
#define PAD(padchar) __printf_pad (s, padchar, width)
#define ARGCHECK(s, format) \
do \
{ \
/* Check file argument for consistence. */ \
if (!__validfp(s) || !s->__mode.__write || format == NULL) \
{ \
errno = EINVAL; \
return -1; \
} \
if (!s->__seen) \
{ \
if (__flshfp (s, EOF) == EOF) \
return -1; \
} \
} while (0)
#define UNBUFFERED_P(s) ((s)->__buffer == NULL)
#endif /* USE_IN_LIBIO */
#define outchar(x) \
do \
{ \
register CONST int outc = (x); \
if (putc(outc, s) == EOF) \
return -1; \
else \
++done; \
} while (0)
/* Advances STRING after writing LEN chars of it. */
#define outstring(string, len) \
do \
{ \
if (len > 20) \
{ \
if (PUT (s, string, len) != len) \
return -1; \
done += len; \
string += len; \
} \
else \
while (len-- > 0) \
outchar (*string++); \
} while (0)
/* Helper function to provide temporary buffering for unbuffered streams. */
static int buffered_vfprintf __P ((FILE *stream, const char *fmt, va_list));
/* Cast the next arg, of type ARGTYPE, into CASTTYPE, and put it in VAR. */
#define castarg(var, argtype, casttype) \
var = (casttype) va_arg(args, argtype)
/* Get the next arg, of type TYPE, and put it in VAR. */
#define nextarg(var, type) castarg(var, type, type)
static printf_function printf_unknown;
extern printf_function **__printf_function_table;
#ifdef __GNUC__
#define HAVE_LONGLONG
#define LONGLONG long long
#else
#define LONGLONG long
#endif
static char *group_number __P ((char *, char *, const char *, wchar_t));
int
DEFUN(vfprintf, (s, format, args),
register FILE *s AND CONST char *format AND va_list args)
{
/* The character used as thousands separator. */
wchar_t thousands_sep;
/* The string describing the size of groups of digits. */
const char *grouping;
/* Pointer into the format string. */
register CONST char *f;
/* Number of characters written. */
register size_t done = 0;
ARGCHECK (s, format);
if (UNBUFFERED_P (s))
/* Use a helper function which will allocate a local temporary buffer
for the stream and then call us again. */
return buffered_vfprintf (s, format, args);
/* Reset multibyte characters to their initial state. */
(void) mblen ((char *) NULL, 0);
/* Figure out the thousands seperator character. */
if (mbtowc (&thousands_sep, _numeric_info->thousands_sep,
strlen (_numeric_info->thousands_sep)) <= 0)
thousands_sep = (wchar_t) *_numeric_info->thousands_sep;
grouping = _numeric_info->grouping; /* Cache the grouping info array. */
if (*grouping == '\0' || thousands_sep == L'\0')
grouping = NULL;
f = format;
while (*f != '\0')
{
/* Type modifiers. */
char is_short, is_long, is_long_double;
#ifdef HAVE_LONGLONG
/* We use the `L' modifier for `long long int'. */
#define is_longlong is_long_double
#else
#define is_longlong 0
#endif
/* Format spec modifiers. */
char space, showsign, left, alt, group;
/* Padding character: ' ' or '0'. */
char pad;
/* Width of a field. */
register int width;
/* Precision of a field. */
int prec;
/* Decimal integer is negative. */
char is_neg;
/* Current character of the format. */
char fc;
/* Base of a number to be written. */
int base;
/* Integral values to be written. */
unsigned LONGLONG int num;
LONGLONG int signed_num;
/* String to be written. */
CONST char *str;
char errorbuf[1024]; /* Buffer sometimes used by %m. */
/* Auxiliary function to do output. */
printf_function *function;
if (!isascii(*f))
{
/* Non-ASCII, may be a multibyte. */
int len = mblen (f, strlen (f));
if (len > 0)
{
outstring (f, len);
continue;
}
}
if (*f != '%')
{
/* This isn't a format spec, so write everything out until the
next one. To properly handle multibyte characters, we cannot
just search for a '%'. Since multibyte characters are hairy
(and dealt with above), if we hit any byte above 127 (only
those can start a multibyte character) we just punt back to
that code. */
do
outchar (*f++);
while (*f != '\0' && *f != '%' && isascii (*f));
continue;
}
++f;
/* Check for "%%". Note that although the ANSI standard lists
'%' as a conversion specifier, it says "The complete format
specification shall be `%%'," so we can avoid all the width
and precision processing. */
if (*f == '%')
{
++f;
outchar('%');
continue;
}
/* Check for spec modifiers. */
space = showsign = left = alt = group = 0;
pad = ' ';
while (*f == ' ' || *f == '+' || *f == '-' || *f == '#' || *f == '0' ||
*f == '\'')
switch (*f++)
{
case ' ':
/* Output a space in place of a sign, when there is no sign. */
space = 1;
break;
case '+':
/* Always output + or - for numbers. */
showsign = 1;
break;
case '-':
/* Left-justify things. */
left = 1;
break;
case '#':
/* Use the "alternate form":
Hex has 0x or 0X, FP always has a decimal point. */
alt = 1;
break;
case '0':
/* Pad with 0s. */
pad = '0';
break;
case '\'':
/* Show grouping in numbers if the locale information
indicates any. */
group = 1;
break;
}
if (left)
pad = ' ';
/* Get the field width. */
width = 0;
if (*f == '*')
{
/* The field width is given in an argument.
A negative field width indicates left justification. */
nextarg(width, int);
if (width < 0)
{
width = - width;
left = 1;
}
++f;
}
else
while (isdigit (*f))
{
width *= 10;
width += *f++ - '0';
}
/* Get the precision. */
/* -1 means none given; 0 means explicit 0. */
prec = -1;
if (*f == '.')
{
++f;
if (*f == '*')
{
/* The precision is given in an argument. */
nextarg(prec, int);
/* Avoid idiocy. */
if (prec < 0)
prec = -1;
++f;
}
else if (isdigit (*f))
{
prec = *f++ - '0';
while (*f != '\0' && isdigit (*f))
{
prec *= 10;
prec += *f++ - '0';
}
}
else
/* "%.?" is treated like "%.0?". */
prec = 0;
}
/* If there was a precision specified, ignore the 0 flag and always
pad with spaces. */
if (prec != -1)
pad = ' ';
/* Check for type modifiers. */
is_short = is_long = is_long_double = 0;
while (*f == 'h' || *f == 'l' || *f == 'L' || *f == 'q')
switch (*f++)
{
case 'h':
/* int's are short int's. */
is_short = 1;
break;
case 'l':
#ifdef HAVE_LONGLONG
if (is_long)
/* A double `l' is equivalent to an `L'. */
is_longlong = 1;
else
#endif
/* int's are long int's. */
is_long = 1;
break;
case 'L':
/* double's are long double's, and int's are long long int's. */
is_long_double = 1;
break;
case 'Z':
/* int's are size_t's. */
#ifdef HAVE_LONGLONG
assert (sizeof(size_t) <= sizeof(unsigned long long int));
is_longlong = sizeof(size_t) > sizeof(unsigned long int);
#endif
is_long = sizeof(size_t) > sizeof(unsigned int);
break;
case 'q':
/* 4.4 uses this for long long. */
#ifdef HAVE_LONGLONG
is_longlong = 1;
#else
is_long = 1;
#endif
break;
}
/* Format specification. */
fc = *f++;
function = (__printf_function_table == NULL ? NULL :
__printf_function_table[fc]);
if (function == NULL)
switch (fc)
{
case 'i':
case 'd':
/* Decimal integer. */
base = 10;
if (is_longlong)
nextarg(signed_num, LONGLONG int);
else if (is_long)
nextarg(signed_num, long int);
else if (!is_short)
castarg(signed_num, int, long int);
else
castarg(signed_num, int, short int);
is_neg = signed_num < 0;
num = is_neg ? (- signed_num) : signed_num;
goto number;
case 'u':
/* Decimal unsigned integer. */
base = 10;
goto unsigned_number;
case 'o':
/* Octal unsigned integer. */
base = 8;
goto unsigned_number;
case 'X':
/* Hexadecimal unsigned integer. */
case 'x':
/* Hex with lower-case digits. */
base = 16;
unsigned_number:
/* Unsigned number of base BASE. */
if (is_longlong)
castarg(num, LONGLONG int, unsigned LONGLONG int);
else if (is_long)
castarg(num, long int, unsigned long int);
else if (!is_short)
castarg(num, int, unsigned int);
else
castarg(num, int, unsigned short int);
/* ANSI only specifies the `+' and
` ' flags for signed conversions. */
is_neg = showsign = space = 0;
number:
/* Number of base BASE. */
{
char work[BUFSIZ];
char *CONST workend = &work[sizeof(work) - 1];
register char *w;
/* Supply a default precision if none was given. */
if (prec == -1)
prec = 1;
/* Put the number in WORK. */
w = _itoa (num, workend + 1, base, fc == 'X') - 1;
if (group && grouping)
w = group_number (w, workend, grouping, thousands_sep);
width -= workend - w;
prec -= workend - w;
if (alt && base == 8 && prec <= 0)
{
*w-- = '0';
--width;
}
if (prec > 0)
{
width -= prec;
while (prec-- > 0)
*w-- = '0';
}
if (alt && base == 16)
width -= 2;
if (is_neg || showsign || space)
--width;
if (!left && pad == ' ')
PAD (' ');
if (is_neg)
outchar('-');
else if (showsign)
outchar('+');
else if (space)
outchar(' ');
if (alt && base == 16)
{
outchar ('0');
outchar (fc);
}
if (!left && pad == '0')
PAD ('0');
/* Write the number. */
while (++w <= workend)
outchar(*w);
if (left)
PAD (' ');
}
break;
case 'e':
case 'E':
case 'f':
case 'g':
case 'G':
{
/* Floating-point number. */
extern printf_function __printf_fp;
function = __printf_fp;
goto use_function;
}
case 'c':
/* Character. */
nextarg(num, int);
if (!left)
{
--width;
PAD (' ');
}
outchar ((unsigned char) num);
if (left)
PAD (' ');
break;
case 's':
{
static CONST char null[] = "(null)";
size_t len;
nextarg(str, CONST char *);
string:
if (str == NULL)
/* Write "(null)" if there's space. */
if (prec == -1 || prec >= (int) sizeof(null) - 1)
{
str = null;
len = sizeof(null) - 1;
}
else
{
str = "";
len = 0;
}
else
len = strlen(str);
if (prec != -1 && (size_t) prec < len)
len = prec;
width -= len;
if (!left)
PAD (' ');
outstring (str, len);
if (left)
PAD (' ');
}
break;
case 'p':
/* Generic pointer. */
{
CONST PTR ptr;
nextarg(ptr, CONST PTR);
if (ptr != NULL)
{
/* If the pointer is not NULL, write it as a %#x spec. */
base = 16;
fc = 'x';
alt = 1;
num = (unsigned LONGLONG int) (unsigned long int) ptr;
is_neg = 0;
group = 0;
goto number;
}
else
{
/* Write "(nil)" for a nil pointer. */
static CONST char nil[] = "(nil)";
register CONST char *p;
width -= sizeof (nil) - 1;
if (!left)
PAD (' ');
for (p = nil; *p != '\0'; ++p)
outchar (*p);
if (left)
PAD (' ');
}
}
break;
case 'n':
/* Answer the count of characters written. */
if (is_longlong)
{
LONGLONG int *p;
nextarg(p, LONGLONG int *);
*p = done;
}
else if (is_long)
{
long int *p;
nextarg(p, long int *);
*p = done;
}
else if (!is_short)
{
int *p;
nextarg(p, int *);
*p = done;
}
else
{
short int *p;
nextarg(p, short int *);
*p = done;
}
break;
case 'm':
{
extern char *_strerror_internal __P ((int, char buf[1024]));
str = _strerror_internal (errno, errorbuf);
goto string;
}
default:
/* Unrecognized format specifier. */
function = printf_unknown;
goto use_function;
}
else
use_function:
{
int function_done;
struct printf_info info;
info.prec = prec;
info.width = width;
info.spec = fc;
info.is_long_double = is_long_double;
info.is_short = is_short;
info.is_long = is_long;
info.alt = alt;
info.space = space;
info.left = left;
info.showsign = showsign;
info.group = group;
info.pad = pad;
function_done = (*function) (s, &info, &args);
if (function_done < 0)
return -1;
done += function_done;
}
}
return done;
}
static int
DEFUN(printf_unknown, (s, info, arg),
FILE *s AND CONST struct printf_info *info AND va_list *arg)
{
int done = 0;
char work[BUFSIZ];
char *CONST workend = &work[sizeof(work) - 1];
register char *w;
register int prec = info->prec, width = info->width;
outchar('%');
if (info->alt)
outchar ('#');
if (info->group)
outchar ('\'');
if (info->showsign)
outchar ('+');
else if (info->space)
outchar (' ');
if (info->left)
outchar ('-');
if (info->pad == '0')
outchar ('0');
w = workend;
while (width > 0)
{
*w-- = '0' + (width % 10);
width /= 10;
}
while (++w <= workend)
outchar(*w);
if (info->prec != -1)
{
outchar('.');
w = workend;
while (prec > 0)
{
*w-- = '0' + (prec % 10);
prec /= 10;
}
while (++w <= workend)
outchar(*w);
}
outchar(info->spec);
return done;
}
/* Group the digits according to the grouping rules of the current locale.
The interpretation of GROUPING is as in `struct lconv' from <locale.h>. */
static char *
group_number (char *w, char *workend, const char *grouping,
wchar_t thousands_sep)
{
int len;
char *src, *s;
/* We treat all negative values like CHAR_MAX. */
if (*grouping == CHAR_MAX || *grouping < 0)
/* No grouping should be done. */
return w;
len = *grouping;
/* Copy existing string so that nothing gets overwritten. */
src = (char *) alloca (workend - w);
memcpy (src, w + 1, workend - w);
s = &src[workend - w - 1];
w = workend;
/* Process all characters in the string. */
while (s >= src)
{
*w-- = *s--;
if (--len == 0 && s >= src)
{
/* A new group begins. */
*w-- = thousands_sep;
len = *grouping++;
if (*grouping == '\0')
/* The previous grouping repeats ad infinitum. */
--grouping;
else if (*grouping == CHAR_MAX || *grouping < 0)
{
/* No further grouping to be done.
Copy the rest of the number. */
do
*w-- = *s--;
while (s >= src);
break;
}
}
}
return w;
}
#ifdef USE_IN_LIBIO
/* Helper "class" for `fprintf to unbuffered': creates a temporary buffer. */
struct helper_file
{
struct _IO_FILE_plus _f;
_IO_FILE *_put_stream;
};
static int
DEFUN(_IO_helper_overflow, (s, c), _IO_FILE *s AND int c)
{
_IO_FILE *target = ((struct helper_file*) s)->_put_stream;
int used = s->_IO_write_ptr - s->_IO_write_base;
if (used)
{
_IO_size_t written = _IO_sputn (target, s->_IO_write_base, used);
s->_IO_write_ptr -= written;
}
return _IO_putc (c, s);
}
static const struct _IO_jump_t _IO_helper_jumps =
{
_IO_helper_overflow,
_IO_default_underflow,
_IO_default_xsputn,
_IO_default_xsgetn,
_IO_default_read,
_IO_default_write,
_IO_default_doallocate,
_IO_default_pbackfail,
_IO_default_setbuf,
_IO_default_sync,
_IO_default_finish,
_IO_default_close,
_IO_default_stat,
_IO_default_seek,
_IO_default_seekoff,
_IO_default_seekpos,
_IO_default_uflow
};
static int
DEFUN(buffered_vfprintf, (s, format, args),
register _IO_FILE *s AND char CONST *format AND _IO_va_list args)
{
char buf[_IO_BUFSIZ];
struct helper_file helper;
register _IO_FILE *hp = (_IO_FILE *) &helper;
int result, to_flush;
/* Initialize helper. */
helper._put_stream = s;
hp->_IO_write_base = buf;
hp->_IO_write_ptr = buf;
hp->_IO_write_end = buf + sizeof buf;
hp->_IO_file_flags = _IO_MAGIC|_IO_NO_READS;
hp->_jumps = (struct _IO_jump_t *) &_IO_helper_jumps;
/* Now print to helper instead. */
result = _IO_vfprintf (hp, format, args);
/* Now flush anything from the helper to the S. */
if ((to_flush = hp->_IO_write_ptr - hp->_IO_write_base) > 0)
{
if (_IO_sputn (s, hp->_IO_write_base, to_flush) != to_flush)
return -1;
}
return result;
}
#else /* !USE_IN_LIBIO */
static int
DEFUN(buffered_vfprintf, (s, format, args),
register FILE *s AND char CONST *format AND va_list args)
{
char buf[BUFSIZ];
int result;
s->__bufp = s->__buffer = buf;
s->__bufsize = sizeof buf;
s->__put_limit = s->__buffer + s->__bufsize;
s->__get_limit = s->__buffer;
/* Now use buffer to print. */
result = vfprintf (s, format, args);
if (fflush (s) == EOF)
return -1;
s->__buffer = s->__bufp = s->__get_limit = s->__put_limit = NULL;
s->__bufsize = 0;
return result;
}
/* Pads string with given number of a specified character.
This code is taken from iopadn.c of the GNU I/O library. */
#define PADSIZE 16
static const char blanks[PADSIZE] =
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
static const char zeroes[PADSIZE] =
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
ssize_t
__printf_pad (s, pad, count)
FILE *s;
char pad;
int count;
{
CONST char *padptr;
register int i;
size_t written = 0, w;
padptr = pad == ' ' ? blanks : zeroes;
for (i = count; i >= PADSIZE; i -= PADSIZE)
{
w = PUT(s, padptr, PADSIZE);
written += w;
if (w != PADSIZE)
return written;
}
if (i > 0)
{
w = PUT(s, padptr, i);
written += w;
}
return written;
}
#undef PADSIZE
#endif /* USE_IN_LIBIO */

570
stdio/vfscanf.c Normal file
View File

@@ -0,0 +1,570 @@
/* Copyright (C) 1991, 1992, 1993, 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <localeinfo.h>
#include <errno.h>
#include <limits.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __GNUC__
#define HAVE_LONGLONG
#define LONGLONG long long
#else
#define LONGLONG long
#endif
#define inchar() ((c = getc(s)) == EOF ? EOF : (++read_in, c))
#define conv_error() return ((c == EOF || ungetc(c, s)), done)
#define input_error() return (done == 0 ? EOF : done)
#define memory_error() return ((errno = ENOMEM), EOF)
/* Read formatted input from S according to the format string
FORMAT, using the argument list in ARG.
Return the number of assignments made, or -1 for an input error. */
int
DEFUN(__vfscanf, (s, format, arg),
FILE *s AND CONST char *format AND va_list argptr)
{
va_list arg = (va_list) argptr;
register CONST char *f = format;
register char fc; /* Current character of the format. */
register size_t done = 0; /* Assignments done. */
register size_t read_in = 0; /* Chars read in. */
register int c; /* Last char read. */
register int do_assign; /* Whether to do an assignment. */
register int width; /* Maximum field width. */
/* Type modifiers. */
char is_short, is_long, is_long_double;
#ifdef HAVE_LONGLONG
/* We use the `L' modifier for `long long int'. */
#define is_longlong is_long_double
#else
#define is_longlong 0
#endif
int malloc_string; /* Args are char ** to be filled in. */
/* Status for reading F-P nums. */
char got_dot, got_e;
/* If a [...] is a [^...]. */
char not_in;
/* Base for integral numbers. */
int base;
/* Signedness for integral numbers. */
int number_signed;
/* Integral holding variables. */
long int num;
unsigned long int unum;
/* Character-buffer pointer. */
register char *str, **strptr;
size_t strsize;
/* Workspace. */
char work[200];
char *w; /* Pointer into WORK. */
wchar_t decimal; /* Decimal point character. */
if (!__validfp(s) || !s->__mode.__read || format == NULL)
{
errno = EINVAL;
return EOF;
}
/* Figure out the decimal point character. */
if (mbtowc(&decimal, _numeric_info->decimal_point,
strlen(_numeric_info->decimal_point)) <= 0)
decimal = (wchar_t) *_numeric_info->decimal_point;
c = inchar();
/* Run through the format string. */
while (*f != '\0')
{
if (!isascii(*f))
{
/* Non-ASCII, may be a multibyte. */
int len = mblen(f, strlen(f));
if (len > 0)
{
while (len-- > 0)
if (c == EOF)
input_error();
else if (c == *f++)
(void) inchar();
else
conv_error();
continue;
}
}
fc = *f++;
if (fc != '%')
{
/* Characters other than format specs must just match. */
if (c == EOF)
input_error();
if (isspace(fc))
{
/* Whitespace characters match any amount of whitespace. */
while (isspace (c))
inchar ();
continue;
}
else if (c == fc)
(void) inchar();
else
conv_error();
continue;
}
/* Check for the assignment-suppressant. */
if (*f == '*')
{
do_assign = 0;
++f;
}
else
do_assign = 1;
/* Find the maximum field width. */
width = 0;
while (isdigit(*f))
{
width *= 10;
width += *f++ - '0';
}
if (width == 0)
width = -1;
/* Check for type modifiers. */
is_short = is_long = is_long_double = malloc_string = 0;
while (*f == 'h' || *f == 'l' || *f == 'L' || *f == 'a' || *f == 'q')
switch (*f++)
{
case 'h':
/* int's are short int's. */
is_short = 1;
break;
case 'l':
if (is_long)
/* A double `l' is equivalent to an `L'. */
is_longlong = 1;
else
/* int's are long int's. */
is_long = 1;
break;
case 'q':
case 'L':
/* double's are long double's, and int's are long long int's. */
is_long_double = 1;
break;
case 'a':
/* String conversions (%s, %[) take a `char **'
arg and fill it in with a malloc'd pointer. */
malloc_string = 1;
break;
}
/* End of the format string? */
if (*f == '\0')
conv_error();
/* Find the conversion specifier. */
w = work;
fc = *f++;
if (fc != '[' && fc != 'c' && fc != 'n')
/* Eat whitespace. */
while (isspace(c))
(void) inchar();
switch (fc)
{
case '%': /* Must match a literal '%'. */
if (c != fc)
conv_error();
break;
case 'n': /* Answer number of assignments done. */
if (do_assign)
*va_arg(arg, int *) = read_in;
break;
case 'c': /* Match characters. */
if (do_assign)
{
str = va_arg (arg, char *);
if (str == NULL)
conv_error ();
}
if (c == EOF)
input_error();
if (width == -1)
width = 1;
if (do_assign)
{
do
*str++ = c;
while (inchar() != EOF && --width > 0);
}
else
while (inchar() != EOF && width > 0)
--width;
if (do_assign)
++done;
break;
case 's': /* Read a string. */
#define STRING_ARG \
if (do_assign) \
{ \
if (malloc_string) \
{ \
/* The string is to be stored in a malloc'd buffer. */ \
strptr = va_arg (arg, char **); \
if (strptr == NULL) \
conv_error (); \
/* Allocate an initial buffer. */ \
strsize = 100; \
*strptr = str = malloc (strsize); \
} \
else \
str = va_arg (arg, char *); \
if (str == NULL) \
conv_error (); \
}
STRING_ARG;
if (c == EOF)
input_error ();
do
{
if (isspace (c))
break;
#define STRING_ADD_CHAR(c) \
if (do_assign) \
{ \
*str++ = c; \
if (malloc_string && str == *strptr + strsize) \
{ \
/* Enlarge the buffer. */ \
str = realloc (*strptr, strsize * 2); \
if (str == NULL) \
{ \
/* Can't allocate that much. Last-ditch effort. */\
str = realloc (*strptr, strsize + 1); \
if (str == NULL) \
{ \
/* We lose. Oh well. \
Terminate the string and stop converting, \
so at least we don't swallow any input. */ \
(*strptr)[strsize] = '\0'; \
++done; \
conv_error (); \
} \
else \
{ \
*strptr = str; \
str += strsize; \
++strsize; \
} \
} \
else \
{ \
*strptr = str; \
str += strsize; \
strsize *= 2; \
} \
} \
}
STRING_ADD_CHAR (c);
} while (inchar () != EOF && (width <= 0 || --width > 0));
if (do_assign)
{
*str = '\0';
++done;
}
break;
case 'x': /* Hexadecimal integer. */
case 'X': /* Ditto. */
base = 16;
number_signed = 0;
goto number;
case 'o': /* Octal integer. */
base = 8;
number_signed = 0;
goto number;
case 'u': /* Unsigned decimal integer. */
base = 10;
number_signed = 0;
goto number;
case 'd': /* Signed decimal integer. */
base = 10;
number_signed = 1;
goto number;
case 'i': /* Generic number. */
base = 0;
number_signed = 1;
number:
if (c == EOF)
input_error();
/* Check for a sign. */
if (c == '-' || c == '+')
{
*w++ = c;
if (width > 0)
--width;
(void) inchar();
}
/* Look for a leading indication of base. */
if (c == '0')
{
if (width > 0)
--width;
*w++ = '0';
(void) inchar();
if (tolower(c) == 'x')
{
if (base == 0)
base = 16;
if (base == 16)
{
if (width > 0)
--width;
(void) inchar();
}
}
else if (base == 0)
base = 8;
}
if (base == 0)
base = 10;
/* Read the number into WORK. */
do
{
if (base == 16 ? !isxdigit(c) :
(!isdigit(c) || c - '0' >= base))
break;
*w++ = c;
if (width > 0)
--width;
} while (inchar() != EOF && width != 0);
if (w == work ||
(w - work == 1 && (work[0] == '+' || work[0] == '-')))
/* There was on number. */
conv_error();
/* Convert the number. */
*w = '\0';
if (number_signed)
num = strtol (work, &w, base);
else
unum = strtoul (work, &w, base);
if (w == work)
conv_error ();
if (do_assign)
{
if (! number_signed)
{
if (is_longlong)
*va_arg (arg, unsigned LONGLONG int *) = unum;
else if (is_long)
*va_arg (arg, unsigned long int *) = unum;
else if (is_short)
*va_arg (arg, unsigned short int *)
= (unsigned short int) unum;
else
*va_arg(arg, unsigned int *) = (unsigned int) unum;
}
else
{
if (is_longlong)
*va_arg(arg, LONGLONG int *) = num;
else if (is_long)
*va_arg(arg, long int *) = num;
else if (is_short)
*va_arg(arg, short int *) = (short int) num;
else
*va_arg(arg, int *) = (int) num;
}
++done;
}
break;
case 'e': /* Floating-point numbers. */
case 'E':
case 'f':
case 'g':
case 'G':
if (c == EOF)
input_error();
/* Check for a sign. */
if (c == '-' || c == '+')
{
*w++ = c;
if (inchar() == EOF)
/* EOF is only an input error before we read any chars. */
conv_error();
if (width > 0)
--width;
}
got_dot = got_e = 0;
do
{
if (isdigit(c))
*w++ = c;
else if (got_e && w[-1] == 'e' && (c == '-' || c == '+'))
*w++ = c;
else if (!got_e && tolower(c) == 'e')
{
*w++ = 'e';
got_e = got_dot = 1;
}
else if (c == decimal && !got_dot)
{
*w++ = c;
got_dot = 1;
}
else
break;
if (width > 0)
--width;
} while (inchar() != EOF && width != 0);
if (w == work)
conv_error();
if (w[-1] == '-' || w[-1] == '+' || w[-1] == 'e')
conv_error();
/* Convert the number. */
*w = '\0';
if (is_long_double)
{
long double d = __strtold (work, &w);
if (do_assign && w != work)
*va_arg (arg, long double *) = d;
}
else if (is_long)
{
double d = strtod (work, &w);
if (do_assign && w != work)
*va_arg (arg, double *) = d;
}
else
{
float d = __strtof (work, &w);
if (do_assign && w != work)
*va_arg (arg, float *) = d;
}
if (w == work)
conv_error ();
if (do_assign)
++done;
break;
case '[': /* Character class. */
STRING_ARG;
if (c == EOF)
input_error();
if (*f == '^')
{
++f;
not_in = 1;
}
else
not_in = 0;
while ((fc = *f++) != '\0' && fc != ']')
{
if (fc == '-' && *f != '\0' && *f != ']' &&
w > work && w[-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;
else
/* Add the character to the list. */
*w++ = fc;
}
if (fc == '\0')
conv_error();
*w = '\0';
unum = read_in;
do
{
if ((strchr (work, c) == NULL) != not_in)
break;
STRING_ADD_CHAR (c);
if (width > 0)
--width;
} while (inchar () != EOF && width != 0);
if (read_in == unum)
conv_error ();
if (do_assign)
{
*str = '\0';
++done;
}
break;
case 'p': /* Generic pointer. */
base = 16;
/* A PTR must be the same size as a `long int'. */
is_long = 1;
goto number;
}
}
conv_error();
}
weak_alias (__vfscanf, vfscanf)

33
stdio/vprintf.c Normal file
View File

@@ -0,0 +1,33 @@
/* Copyright (C) 1991, 1993 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#undef __OPTIMIZE__ /* Avoid inline `vprintf' function. */
#include <stdio.h>
#undef vprintf
/* Write formatted output to stdout according to the
format string FORMAT, using the argument list in ARG. */
int
DEFUN(vprintf, (format, arg), CONST char *format AND __gnuc_va_list arg)
{
return vfprintf (stdout, format, arg);
}

32
stdio/vscanf.c Normal file
View File

@@ -0,0 +1,32 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#include <stdio.h>
#undef vscanf
/* Read formatted input from stdin according to the format
string in FORMAT, using the argument list in ARG. */
int
DEFUN(vscanf, (format, arg), CONST char *format AND va_list arg)
{
return vfscanf (stdin, format, arg);
}

56
stdio/vsnprintf.c Normal file
View File

@@ -0,0 +1,56 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
/*
* Write formatted output to S according to the format string
* FORMAT, using the argument list in ARG, writing no more
* than MAXLEN characters.
*/
int
DEFUN(vsnprintf, (s, maxlen, format, arg),
char *s AND size_t maxlen AND CONST char *format AND va_list arg)
{
int done;
FILE f;
memset((PTR) &f, 0, sizeof(f));
f.__magic = _IOMAGIC;
f.__mode.__write = 1;
/* The buffer size is one less than MAXLEN
so we have space for the null terminator. */
f.__bufp = f.__buffer = (char *) s;
f.__bufsize = maxlen - 1;
f.__put_limit = f.__buffer + f.__bufsize;
f.__get_limit = f.__buffer;
/* After the buffer is full (MAXLEN characters have been written),
any more characters written will go to the bit bucket. */
f.__room_funcs = __default_room_functions;
f.__io_funcs.__write = NULL;
f.__seen = 1;
done = vfprintf(&f, format, arg);
*f.__bufp = '\0';
return done;
}

50
stdio/vsprintf.c Normal file
View File

@@ -0,0 +1,50 @@
/* Copyright (C) 1991, 1992 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
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
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 Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
/* Write formatted output to S according to the format string
FORMAT, using the argument list in ARG. */
int
DEFUN(vsprintf, (s, format, arg),
char *s AND CONST char *format AND va_list arg)
{
int done;
FILE f;
memset((PTR) &f, 0, sizeof(f));
f.__magic = _IOMAGIC;
f.__mode.__write = 1;
f.__bufp = f.__buffer = (char *) s;
f.__put_limit = (char *) ULONG_MAX;
f.__bufsize = (size_t) (f.__put_limit - f.__bufp);
f.__get_limit = f.__buffer;
f.__room_funcs.__output = NULL;
f.__seen = 1;
done = vfprintf(&f, format, arg);
*f.__bufp = '\0';
return done;
}

Some files were not shown because too many files have changed in this diff Show More