mirror of
https://sourceware.org/git/glibc.git
synced 2025-12-24 17:51:17 +03:00
initial import
This commit is contained in:
4
stdio/.cvsignore
Normal file
4
stdio/.cvsignore
Normal file
@@ -0,0 +1,4 @@
|
||||
*.gz *.Z *.tar *.tgz
|
||||
=*
|
||||
TODO COPYING* AUTHORS copyr-* copying.*
|
||||
glibc-*
|
||||
114
stdio/Makefile
Normal file
114
stdio/Makefile
Normal 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
45
stdio/_itoa.c
Normal 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
54
stdio/_itoa.h
Normal 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
39
stdio/asprintf.c
Normal 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
28
stdio/bug1.c
Normal 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
1
stdio/bug1.input
Normal file
@@ -0,0 +1 @@
|
||||
95
|
||||
12
stdio/bug2.c
Normal file
12
stdio/bug2.c
Normal 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
52
stdio/bug3.c
Normal 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
50
stdio/bug4.c
Normal 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
60
stdio/bug5.c
Normal 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
27
stdio/bug6.c
Normal 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
1
stdio/bug6.input
Normal file
@@ -0,0 +1 @@
|
||||
XY 1234L
|
||||
53
stdio/bug7.c
Normal file
53
stdio/bug7.c
Normal 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
31
stdio/clearerr.c
Normal 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
37
stdio/dprintf.c
Normal 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
60
stdio/errnobug.c
Normal 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
69
stdio/fclose.c
Normal 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
37
stdio/feof.c
Normal 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
37
stdio/ferror.c
Normal 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
45
stdio/fflush.c
Normal 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
35
stdio/fgetc.c
Normal 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
40
stdio/fgetpos.c
Normal 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
121
stdio/fgets.c
Normal 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
48
stdio/fileno.c
Normal 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
108
stdio/fmemopen.c
Normal 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
110
stdio/fopen.c
Normal 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
48
stdio/fopncook.c
Normal 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
401
stdio/fpioconst.c
Normal 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
52
stdio/fpioconst.h
Normal 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
38
stdio/fprintf.c
Normal 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
35
stdio/fputc.c
Normal 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
35
stdio/fputs.c
Normal 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
128
stdio/fread.c
Normal 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
74
stdio/freopen.c
Normal 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
38
stdio/fscanf.c
Normal 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
177
stdio/fseek.c
Normal 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
37
stdio/fsetpos.c
Normal 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
54
stdio/ftell.c
Normal 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
208
stdio/fwrite.c
Normal 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
31
stdio/gen-mpn-copy
Normal 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
5
stdio/getc.c
Normal 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
30
stdio/getchar.c
Normal 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
173
stdio/getdelim.c
Normal 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
33
stdio/getline.c
Normal 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
59
stdio/gets.c
Normal 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
33
stdio/getw.c
Normal 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
114
stdio/glue.c
Normal 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
283
stdio/gmp-impl.h
Normal 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
525
stdio/gmp.h
Normal 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
667
stdio/internals.c
Normal 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
1295
stdio/longlong.h
Normal file
File diff suppressed because it is too large
Load Diff
177
stdio/memstream.c
Normal file
177
stdio/memstream.c
Normal 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
39
stdio/mp_clz_tab.c
Normal 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
54
stdio/newstream.c
Normal 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
187
stdio/obstream.c
Normal 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
42
stdio/perror.c
Normal 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
211
stdio/printf-prs.c
Normal 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
37
stdio/printf.c
Normal 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
114
stdio/printf.h
Normal 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
991
stdio/printf_fp.c
Normal 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
49
stdio/psignal.c
Normal 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
5
stdio/putc.c
Normal 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
30
stdio/putchar.c
Normal 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
32
stdio/puts.c
Normal 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
31
stdio/putw.c
Normal 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
47
stdio/reg-printf.c
Normal 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
33
stdio/rewind.c
Normal 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
37
stdio/scanf.c
Normal 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
30
stdio/setbuf.c
Normal 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
30
stdio/setbuffer.c
Normal 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
29
stdio/setlinebuf.c
Normal 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
85
stdio/setvbuf.c
Normal 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
39
stdio/snprintf.c
Normal 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
37
stdio/sprintf.c
Normal 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
37
stdio/sscanf.c
Normal 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
681
stdio/stdio.h
Normal 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
50
stdio/tempnam.c
Normal 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
31
stdio/temptest.c
Normal 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
67
stdio/test-fseek.c
Normal 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
68
stdio/test-fwrite.c
Normal 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
67
stdio/test-popen.c
Normal 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
129
stdio/test_rdwr.c
Normal 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
43
stdio/tmpfile.c
Normal 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
42
stdio/tmpnam.c
Normal 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
37
stdio/tst-fileno.c
Normal 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
298
stdio/tst-printf.c
Normal 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
46
stdio/tstgetln.c
Normal 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
3
stdio/tstgetln.input
Normal file
@@ -0,0 +1,3 @@
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
|
||||
z
|
||||
100
stdio/tstscanf.c
Normal file
100
stdio/tstscanf.c
Normal 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
7
stdio/tstscanf.input
Normal 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
58
stdio/ungetc.c
Normal 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
86
stdio/vasprintf.c
Normal 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
51
stdio/vdprintf.c
Normal 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
907
stdio/vfprintf.c
Normal 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
570
stdio/vfscanf.c
Normal 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
33
stdio/vprintf.c
Normal 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
32
stdio/vscanf.c
Normal 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
56
stdio/vsnprintf.c
Normal 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
50
stdio/vsprintf.c
Normal 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
Reference in New Issue
Block a user