dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnetC/libc/stdio __fbufsize.c,NONE,1.1 __flb


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnetC/libc/stdio __fbufsize.c,NONE,1.1 __flbf.c,NONE,1.1 __fpending.c,NONE,1.1 __fpurge.c,NONE,1.1 __freadable.c,NONE,1.1 __freading.c,NONE,1.1 __fsetlocking.c,NONE,1.1 __fwritable.c,NONE,1.1 __fwriting.c,NONE,1.1 _i18n_number.h,NONE,1.1 _itoa.c,NONE,1.1 _itoa.h,NONE,1.1 _itowa.c,NONE,1.1 _itowa.h,NONE,1.1 asprintf.c,NONE,1.1 clearerr.c,NONE,1.1 defs.c,NONE,1.1 dprintf.c,NONE,1.1 fclose.c,NONE,1.1 fcloseall.c,NONE,1.1 feof.c,NONE,1.1 ferror.c,NONE,1.1 fflush.c,NONE,1.1 fgetc.c,NONE,1.1 fgetpos.c,NONE,1.1 fgets.c,NONE,1.1 fileno.c,NONE,1.1 fmemopen.c,NONE,1.1 fopen.c,NONE,1.1 fopncook.c,NONE,1.1 fprintf.c,NONE,1.1 fputc.c,NONE,1.1 fputs.c,NONE,1.1 fread.c,NONE,1.1 freopen.c,NONE,1.1 fscanf.c,NONE,1.1 fseek.c,NONE,1.1 fsetpos.c,NONE,1.1 ftell.c,NONE,1.1 fwrite.c,NONE,1.1 getc.c,NONE,1.1 getchar.c,NONE,1.1 getdelim.c,NONE,1.1 getline.c,NONE,1.1 gets.c,NONE,1.1 getw.c,NONE,1.1 internals.c,NONE,1.1 itoa-digits.c,NONE,1.1 itoa-udigits.c,NONE,1.1 itowa-digits.c,NONE,1.1 linewrap.c,NONE,1.1 linewrap.h,NONE,1.1 memstream.c,NONE,1.1 newstream.c,NONE,1.1 perror.c,NONE,1.1 printf-parse.h,NONE,1.1 printf-prs.c,NONE,1.1 printf.h,NONE,1.1 printf_fp.c,NONE,1.1 printf_size.c,NONE,1.1 psignal.c,NONE,1.1 putc.c,NONE,1.1 putchar.c,NONE,1.1 puts.c,NONE,1.1 putw.c,NONE,1.1 rewind.c,NONE,1.1 scanf.c,NONE,1.1 setbuf.c,NONE,1.1 setbuffer.c,NONE,1.1 setlinebuf.c,NONE,1.1 setvbuf.c,NONE,1.1 snprintf.c,NONE,1.1 sprintf.c,NONE,1.1 sscanf.c,NONE,1.1 stdio_init.c,NONE,1.1 sysd-stdio.c,NONE,1.1 tempnam.c,NONE,1.1 tmpfile64.c,NONE,1.1 tmpnam.c,NONE,1.1 tmpnam_r.c,NONE,1.1 ungetc.c,NONE,1.1 vasprintf.c,NONE,1.1 vdprintf.c,NONE,1.1 vfprintf.c,NONE,1.1 vfscanf.c,NONE,1.1 vprintf.c,NONE,1.1 vscanf.c,NONE,1.1 vsnprintf.c,NONE,1.1 vsprintf.c,NONE,1.1 vsscanf.c,NONE,1.1 Makefile.am,1.1.1.1,1.2
Date: Sat, 28 Jun 2003 05:53:40 -0400

Update of /cvsroot/dotgnu-pnet/pnetC/libc/stdio
In directory subversions:/tmp/cvs-serv23212/libc/stdio

Modified Files:
        Makefile.am 
Added Files:
        __fbufsize.c __flbf.c __fpending.c __fpurge.c __freadable.c 
        __freading.c __fsetlocking.c __fwritable.c __fwriting.c 
        _i18n_number.h _itoa.c _itoa.h _itowa.c _itowa.h asprintf.c 
        clearerr.c defs.c dprintf.c fclose.c fcloseall.c feof.c 
        ferror.c fflush.c fgetc.c fgetpos.c fgets.c fileno.c 
        fmemopen.c fopen.c fopncook.c fprintf.c fputc.c fputs.c 
        fread.c freopen.c fscanf.c fseek.c fsetpos.c ftell.c fwrite.c 
        getc.c getchar.c getdelim.c getline.c gets.c getw.c 
        internals.c itoa-digits.c itoa-udigits.c itowa-digits.c 
        linewrap.c linewrap.h memstream.c newstream.c perror.c 
        printf-parse.h printf-prs.c printf.h printf_fp.c printf_size.c 
        psignal.c putc.c putchar.c puts.c putw.c rewind.c scanf.c 
        setbuf.c setbuffer.c setlinebuf.c setvbuf.c snprintf.c 
        sprintf.c sscanf.c stdio_init.c sysd-stdio.c tempnam.c 
        tmpfile64.c tmpnam.c tmpnam_r.c ungetc.c vasprintf.c 
        vdprintf.c vfprintf.c vfscanf.c vprintf.c vscanf.c vsnprintf.c 
        vsprintf.c vsscanf.c 
Log Message:


Port a number of files from glibc's stdio implementation
(most are done except the core printf/scanf routines).


--- NEW FILE ---
/* Copyright (C) 2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio_ext.h>

size_t
__fbufsize (FILE *fp)
{
  return fp->__bufsize;
}

--- NEW FILE ---
/* Copyright (C) 2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio_ext.h>

int
__flbf (FILE *fp)
{
  return fp->__linebuf;
}

--- NEW FILE ---
/* Copyright (C) 2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio_ext.h>

size_t
__fpending (FILE *fp)
{
  return (fp->__put_limit >= fp->__bufp ? fp->__bufp - fp->__buffer : 0);
}

--- NEW FILE ---
/* Copyright (C) 2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio_ext.h>

void
__fpurge (FILE *fp)
{
  fp->__get_limit = fp->__put_limit = fp->__bufp = fp->__buffer;
}

--- NEW FILE ---
/* Copyright (C) 2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio_ext.h>

int
__freadable (FILE *fp)
{
  return !!fp->__mode.__read;
}

--- NEW FILE ---
/* Copyright (C) 2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio_ext.h>

int
__freading (FILE *fp)
{
  /* This is not really right for unbuffered streams.  */
  return (!fp->__mode.__write || fp->__put_limit == fp->__buffer);
}

--- NEW FILE ---
/* Copyright (C) 2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio_ext.h>
#include <errno.h>
#include <stdlib.h>

int
__fsetlocking (FILE *fp, int type)
{
  /* We don't really support locking.  */

  switch (type)
    {
    case FSETLOCKING_QUERY:
    case FSETLOCKING_BYCALLER:
      break;
    case FSETLOCKING_INTERNAL:
      abort ();
    default:
      __set_errno (EINVAL);
      return -1;
    }

  return FSETLOCKING_BYCALLER;
}

--- NEW FILE ---
/* Copyright (C) 2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio_ext.h>

int
__fwritable (FILE *fp)
{
  return !!fp->__mode.__write;
}

--- NEW FILE ---
/* Copyright (C) 2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio_ext.h>

int
__fwriting (FILE *fp)
{
  /* This is not really right for unbuffered streams.  */
  return (!fp->__mode.__read || fp->__get_limit == fp->__buffer);
}

--- NEW FILE ---
/* Copyright (C) 2000 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <address@hidden>, 2000.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include "../locale/outdigits.h"
#include "../locale/outdigitswc.h"

static CHAR_T *
_i18n_number_rewrite (CHAR_T *w, CHAR_T *rear_ptr)
{
  CHAR_T *src, *s;

  /* Copy existing string so that nothing gets overwritten.  */
  src = (CHAR_T *) alloca ((rear_ptr - w) * sizeof (CHAR_T));
  s = (CHAR_T *) __mempcpy (src, w,
                            (rear_ptr - w) * sizeof (CHAR_T));
  w = rear_ptr;

  /* Process all characters in the string.  */
  while (--s >= src)
    {
      if (*s >= '0' && *s <= '9')
        {
          if (sizeof (CHAR_T) == 1)
            w = (CHAR_T *) outdigit_value ((char *) w, *s - '0');
          else
            *--w = (CHAR_T) outdigitwc_value (*s - '0');
        }
      else
        *--w = *s;
    }

  return w;
}

--- NEW FILE ---
/* Internal function for converting integers to ASCII.
   Copyright (C) 1994, 1995, 1996, 1999, 2000 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Torbjorn Granlund <address@hidden>
   and Ulrich Drepper <address@hidden>.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <gmp-mparam.h>
#include <gmp.h>
#include <stdlib/gmp-impl.h>
#include <stdlib/longlong.h>

#include "_itoa.h"


/* Canonize environment.  For some architectures not all values might
   be defined in the GMP header files.  */
#ifndef UMUL_TIME
# define UMUL_TIME 1
#endif
#ifndef UDIV_TIME
# define UDIV_TIME 3
#endif

/* Control memory layout.  */
#ifdef PACK
# undef PACK
# define PACK __attribute__ ((packed))
#else
# define PACK
#endif


/* Declare local types.  */
struct base_table_t
{
#if (UDIV_TIME > 2 * UMUL_TIME)
  mp_limb_t base_multiplier;
#endif
  char flag;
  char post_shift;
#if BITS_PER_MP_LIMB == 32
  struct
    {
      char normalization_steps;
      char ndigits;
      mp_limb_t base PACK;
#if UDIV_TIME > 2 * UMUL_TIME
      mp_limb_t base_ninv PACK;
#endif
    } big;
#endif
};

/* To reduce the memory needed we include some fields of the tables
   only conditionally.  */
#if UDIV_TIME > 2 * UMUL_TIME
# define SEL1(X) X,
# define SEL2(X) ,X
#else
# define SEL1(X)
# define SEL2(X)
#endif


/* Local variables.  */
const struct base_table_t _itoa_base_table[] =
{
#if BITS_PER_MP_LIMB == 64
  /*  2 */ {SEL1(0ul) 1, 1},
  /*  3 */ {SEL1(0xaaaaaaaaaaaaaaabul) 0, 1},
  /*  4 */ {SEL1(0ul) 1, 2},
  /*  5 */ {SEL1(0xcccccccccccccccdul) 0, 2},
  /*  6 */ {SEL1(0xaaaaaaaaaaaaaaabul) 0, 2},
  /*  7 */ {SEL1(0x2492492492492493ul) 1, 3},
  /*  8 */ {SEL1(0ul) 1, 3},
  /*  9 */ {SEL1(0xe38e38e38e38e38ful) 0, 3},
  /* 10 */ {SEL1(0xcccccccccccccccdul) 0, 3},
  /* 11 */ {SEL1(0x2e8ba2e8ba2e8ba3ul) 0, 1},
  /* 12 */ {SEL1(0xaaaaaaaaaaaaaaabul) 0, 3},
  /* 13 */ {SEL1(0x4ec4ec4ec4ec4ec5ul) 0, 2},
  /* 14 */ {SEL1(0x2492492492492493ul) 1, 4},
  /* 15 */ {SEL1(0x8888888888888889ul) 0, 3},
  /* 16 */ {SEL1(0ul) 1, 4},
  /* 17 */ {SEL1(0xf0f0f0f0f0f0f0f1ul) 0, 4},
  /* 18 */ {SEL1(0xe38e38e38e38e38ful) 0, 4},
  /* 19 */ {SEL1(0xd79435e50d79435ful) 0, 4},
  /* 20 */ {SEL1(0xcccccccccccccccdul) 0, 4},
  /* 21 */ {SEL1(0x8618618618618619ul) 1, 5},
  /* 22 */ {SEL1(0x2e8ba2e8ba2e8ba3ul) 0, 2},
  /* 23 */ {SEL1(0x642c8590b21642c9ul) 1, 5},
  /* 24 */ {SEL1(0xaaaaaaaaaaaaaaabul) 0, 4},
  /* 25 */ {SEL1(0x47ae147ae147ae15ul) 1, 5},
  /* 26 */ {SEL1(0x4ec4ec4ec4ec4ec5ul) 0, 3},
  /* 27 */ {SEL1(0x97b425ed097b425ful) 0, 4},
  /* 28 */ {SEL1(0x2492492492492493ul) 1, 5},
  /* 29 */ {SEL1(0x1a7b9611a7b9611bul) 1, 5},
  /* 30 */ {SEL1(0x8888888888888889ul) 0, 4},
  /* 31 */ {SEL1(0x0842108421084211ul) 1, 5},
  /* 32 */ {SEL1(0ul) 1, 5},
  /* 33 */ {SEL1(0x0f83e0f83e0f83e1ul) 0, 1},
  /* 34 */ {SEL1(0xf0f0f0f0f0f0f0f1ul) 0, 5},
  /* 35 */ {SEL1(0xea0ea0ea0ea0ea0ful) 0, 5},
  /* 36 */ {SEL1(0xe38e38e38e38e38ful) 0, 5}
#endif
#if BITS_PER_MP_LIMB == 32
  /*  2 */ {SEL1(0ul) 1, 1, {0, 31, 0x80000000ul SEL2(0xfffffffful)}},
  /*  3 */ {SEL1(0xaaaaaaabul) 0, 1, {0, 20, 0xcfd41b91ul SEL2(0x3b563c24ul)}},
  /*  4 */ {SEL1(0ul) 1, 2, {1, 15, 0x40000000ul SEL2(0xfffffffful)}},
  /*  5 */ {SEL1(0xcccccccdul) 0, 2, {1, 13, 0x48c27395ul SEL2(0xc25c2684ul)}},
  /*  6 */ {SEL1(0xaaaaaaabul) 0, 2, {0, 12, 0x81bf1000ul SEL2(0xf91bd1b6ul)}},
  /*  7 */ {SEL1(0x24924925ul) 1, 3, {1, 11, 0x75db9c97ul SEL2(0x1607a2cbul)}},
  /*  8 */ {SEL1(0ul) 1, 3, {1, 10, 0x40000000ul SEL2(0xfffffffful)}},
  /*  9 */ {SEL1(0x38e38e39ul) 0, 1, {0, 10, 0xcfd41b91ul SEL2(0x3b563c24ul)}},
  /* 10 */ {SEL1(0xcccccccdul) 0, 3, {2, 9, 0x3b9aca00ul SEL2(0x12e0be82ul)}},
  /* 11 */ {SEL1(0xba2e8ba3ul) 0, 3, {0, 9, 0x8c8b6d2bul SEL2(0xd24cde04ul)}},
  /* 12 */ {SEL1(0xaaaaaaabul) 0, 3, {3, 8, 0x19a10000ul SEL2(0x3fa39ab5ul)}},
  /* 13 */ {SEL1(0x4ec4ec4ful) 0, 2, {2, 8, 0x309f1021ul SEL2(0x50f8ac5ful)}},
  /* 14 */ {SEL1(0x24924925ul) 1, 4, {1, 8, 0x57f6c100ul SEL2(0x74843b1eul)}},
  /* 15 */ {SEL1(0x88888889ul) 0, 3, {0, 8, 0x98c29b81ul SEL2(0xad0326c2ul)}},
  /* 16 */ {SEL1(0ul) 1, 4, {3, 7, 0x10000000ul SEL2(0xfffffffful)}},
  /* 17 */ {SEL1(0xf0f0f0f1ul) 0, 4, {3, 7, 0x18754571ul SEL2(0x4ef0b6bdul)}},
  /* 18 */ {SEL1(0x38e38e39ul) 0, 2, {2, 7, 0x247dbc80ul SEL2(0xc0fc48a1ul)}},
  /* 19 */ {SEL1(0xaf286bcbul) 1, 5, {2, 7, 0x3547667bul SEL2(0x33838942ul)}},
  /* 20 */ {SEL1(0xcccccccdul) 0, 4, {1, 7, 0x4c4b4000ul SEL2(0xad7f29abul)}},
  /* 21 */ {SEL1(0x86186187ul) 1, 5, {1, 7, 0x6b5a6e1dul SEL2(0x313c3d15ul)}},
  /* 22 */ {SEL1(0xba2e8ba3ul) 0, 4, {0, 7, 0x94ace180ul SEL2(0xb8cca9e0ul)}},
  /* 23 */ {SEL1(0xb21642c9ul) 0, 4, {0, 7, 0xcaf18367ul SEL2(0x42ed6de9ul)}},
  /* 24 */ {SEL1(0xaaaaaaabul) 0, 4, {4, 6, 0x0b640000ul SEL2(0x67980e0bul)}},
  /* 25 */ {SEL1(0x51eb851ful) 0, 3, {4, 6, 0x0e8d4a51ul SEL2(0x19799812ul)}},
  /* 26 */ {SEL1(0x4ec4ec4ful) 0, 3, {3, 6, 0x1269ae40ul SEL2(0xbce85396ul)}},
  /* 27 */ {SEL1(0x2f684bdbul) 1, 5, {3, 6, 0x17179149ul SEL2(0x62c103a9ul)}},
  /* 28 */ {SEL1(0x24924925ul) 1, 5, {3, 6, 0x1cb91000ul SEL2(0x1d353d43ul)}},
  /* 29 */ {SEL1(0x8d3dcb09ul) 0, 4, {2, 6, 0x23744899ul SEL2(0xce1deceaul)}},
  /* 30 */ {SEL1(0x88888889ul) 0, 4, {2, 6, 0x2b73a840ul SEL2(0x790fc511ul)}},
  /* 31 */ {SEL1(0x08421085ul) 1, 5, {2, 6, 0x34e63b41ul SEL2(0x35b865a0ul)}},
  /* 32 */ {SEL1(0ul) 1, 5, {1, 6, 0x40000000ul SEL2(0xfffffffful)}},
  /* 33 */ {SEL1(0x3e0f83e1ul) 0, 3, {1, 6, 0x4cfa3cc1ul SEL2(0xa9aed1b3ul)}},
  /* 34 */ {SEL1(0xf0f0f0f1ul) 0, 5, {1, 6, 0x5c13d840ul SEL2(0x63dfc229ul)}},
  /* 35 */ {SEL1(0xd41d41d5ul) 1, 6, {1, 6, 0x6d91b519ul SEL2(0x2b0fee30ul)}},
  /* 36 */ {SEL1(0x38e38e39ul) 0, 3, {0, 6, 0x81bf1000ul SEL2(0xf91bd1b6ul)}}
#endif
};

/* Lower-case digits.  */
extern const char _itoa_lower_digits[];
/* Upper-case digits.  */
extern const char _itoa_upper_digits[];


char *
_itoa (value, buflim, base, upper_case)
     unsigned long long int value;
     char *buflim;
     unsigned int base;
     int upper_case;
{
  const char *digits = upper_case ? _itoa_upper_digits : _itoa_lower_digits;
  char *bp = buflim;
  const struct base_table_t *brec = &_itoa_base_table[base - 2];

  switch (base)
    {
#define RUN_2N(BITS) \
      do                                                                      \
        {                                                                     \
          /* `unsigned long long int' always has 64 bits.  */                 \
          mp_limb_t work_hi = value >> (64 - BITS_PER_MP_LIMB);               \
                                                                              \
          if (BITS_PER_MP_LIMB == 32)                                         \
            {                                                                 \
              if (work_hi != 0)                                               \
                {                                                             \
                  mp_limb_t work_lo;                                          \
                  int cnt;                                                    \
                                                                              \
                  work_lo = value & 0xfffffffful;                             \
                  for (cnt = BITS_PER_MP_LIMB / BITS; cnt > 0; --cnt)         \
                    {                                                         \
                      *--bp = digits[work_lo & ((1ul << BITS) - 1)];          \
                      work_lo >>= BITS;                                       \
                    }                                                         \
                  if (BITS_PER_MP_LIMB % BITS != 0)                           \
                    {                                                         \
                      work_lo                                                 \
                        |= ((work_hi                                          \
                             & ((1 << (BITS - BITS_PER_MP_LIMB%BITS))         \
                                - 1))                                         \
                            << BITS_PER_MP_LIMB % BITS);                      \
                      work_hi >>= BITS - BITS_PER_MP_LIMB % BITS;             \
                      if (work_hi == 0)                                       \
                        work_hi = work_lo;                                    \
                      else                                                    \
                        *--bp = digits[work_lo];                              \
                    }                                                         \
                }                                                             \
              else                                                            \
                work_hi = value & 0xfffffffful;                               \
            }                                                                 \
          do                                                                  \
            {                                                                 \
              *--bp = digits[work_hi & ((1 << BITS) - 1)];                    \
              work_hi >>= BITS;                                               \
            }                                                                 \
          while (work_hi != 0);                                               \
        }                                                                     \
      while (0)
    case 8:
      RUN_2N (3);
      break;

    case 16:
      RUN_2N (4);
      break;

    default:
      {
#if BITS_PER_MP_LIMB == 64
        mp_limb_t base_multiplier = brec->base_multiplier;
        if (brec->flag)
          while (value != 0)
            {
              mp_limb_t quo, rem, x, dummy;

              umul_ppmm (x, dummy, value, base_multiplier);
              quo = (x + ((value - x) >> 1)) >> (brec->post_shift - 1);
              rem = value - quo * base;
              *--bp = digits[rem];
              value = quo;
            }
        else
          while (value != 0)
            {
              mp_limb_t quo, rem, x, dummy;

              umul_ppmm (x, dummy, value, base_multiplier);
              quo = x >> brec->post_shift;
              rem = value - quo * base;
              *--bp = digits[rem];
              value = quo;
            }
#endif
#if BITS_PER_MP_LIMB == 32
        mp_limb_t t[3];
        int n;

        /* First convert x0 to 1-3 words in base s->big.base.
           Optimize for frequent cases of 32 bit numbers.  */
        if ((mp_limb_t) (value >> 32) >= 1)
          {
#if UDIV_TIME > 2 * UMUL_TIME || UDIV_NEEDS_NORMALIZATION
            int big_normalization_steps = brec->big.normalization_steps;
            mp_limb_t big_base_norm
              = brec->big.base << big_normalization_steps;
#endif
            if ((mp_limb_t) (value >> 32) >= brec->big.base)
              {
                mp_limb_t x1hi, x1lo, r;
                /* If you want to optimize this, take advantage of
                   that the quotient in the first udiv_qrnnd will
                   always be very small.  It might be faster just to
                   subtract in a tight loop.  */

#if UDIV_TIME > 2 * UMUL_TIME
                mp_limb_t x, xh, xl;

                if (big_normalization_steps == 0)
                  xh = 0;
                else
                  xh = (mp_limb_t) (value >> (64 - big_normalization_steps));
                xl = (mp_limb_t) (value >> (32 - big_normalization_steps));
                udiv_qrnnd_preinv (x1hi, r, xh, xl, big_base_norm,
                                   brec->big.base_ninv);

                xl = ((mp_limb_t) value) << big_normalization_steps;
                udiv_qrnnd_preinv (x1lo, x, r, xl, big_base_norm,
                                   brec->big.base_ninv);
                t[2] = x >> big_normalization_steps;

                if (big_normalization_steps == 0)
                  xh = x1hi;
                else
                  xh = ((x1hi << big_normalization_steps)
                        | (x1lo >> (32 - big_normalization_steps)));
                xl = x1lo << big_normalization_steps;
                udiv_qrnnd_preinv (t[0], x, xh, xl, big_base_norm,
                                   brec->big.base_ninv);
                t[1] = x >> big_normalization_steps;
#elif UDIV_NEEDS_NORMALIZATION
                mp_limb_t x, xh, xl;

                if (big_normalization_steps == 0)
                  xh = 0;
                else
                  xh = (mp_limb_t) (value >> 64 - big_normalization_steps);
                xl = (mp_limb_t) (value >> 32 - big_normalization_steps);
                udiv_qrnnd (x1hi, r, xh, xl, big_base_norm);

                xl = ((mp_limb_t) value) << big_normalization_steps;
                udiv_qrnnd (x1lo, x, r, xl, big_base_norm);
                t[2] = x >> big_normalization_steps;

                if (big_normalization_steps == 0)
                  xh = x1hi;
                else
                  xh = ((x1hi << big_normalization_steps)
                        | (x1lo >> 32 - big_normalization_steps));
                xl = x1lo << big_normalization_steps;
                udiv_qrnnd (t[0], x, xh, xl, big_base_norm);
                t[1] = x >> big_normalization_steps;
#else
                udiv_qrnnd (x1hi, r, 0, (mp_limb_t) (value >> 32),
                            brec->big.base);
                udiv_qrnnd (x1lo, t[2], r, (mp_limb_t) value, brec->big.base);
                udiv_qrnnd (t[0], t[1], x1hi, x1lo, brec->big.base);
#endif
                n = 3;
              }
            else
              {
#if (UDIV_TIME > 2 * UMUL_TIME)
                mp_limb_t x;

                value <<= brec->big.normalization_steps;
                udiv_qrnnd_preinv (t[0], x, (mp_limb_t) (value >> 32),
                                   (mp_limb_t) value, big_base_norm,
                                   brec->big.base_ninv);
                t[1] = x >> brec->big.normalization_steps;
#elif UDIV_NEEDS_NORMALIZATION
                mp_limb_t x;

                value <<= big_normalization_steps;
                udiv_qrnnd (t[0], x, (mp_limb_t) (value >> 32),
                            (mp_limb_t) value, big_base_norm);
                t[1] = x >> big_normalization_steps;
#else
                udiv_qrnnd (t[0], t[1], (mp_limb_t) (value >> 32),
                            (mp_limb_t) value, brec->big.base);
#endif
                n = 2;
              }
          }
        else
          {
            t[0] = value;
            n = 1;
          }

        /* Convert the 1-3 words in t[], word by word, to ASCII.  */
        do
          {
            mp_limb_t ti = t[--n];
            int ndig_for_this_limb = 0;

#if UDIV_TIME > 2 * UMUL_TIME
            mp_limb_t base_multiplier = brec->base_multiplier;
            if (brec->flag)
              while (ti != 0)
                {
                  mp_limb_t quo, rem, x, dummy;

                  umul_ppmm (x, dummy, ti, base_multiplier);
                  quo = (x + ((ti - x) >> 1)) >> (brec->post_shift - 1);
                  rem = ti - quo * base;
                  *--bp = digits[rem];
                  ti = quo;
                  ++ndig_for_this_limb;
                }
            else
              while (ti != 0)
                {
                  mp_limb_t quo, rem, x, dummy;

                  umul_ppmm (x, dummy, ti, base_multiplier);
                  quo = x >> brec->post_shift;
                  rem = ti - quo * base;
                  *--bp = digits[rem];
                  ti = quo;
                  ++ndig_for_this_limb;
                }
#else
            while (ti != 0)
              {
                mp_limb_t quo, rem;

                quo = ti / base;
                rem = ti % base;
                *--bp = digits[rem];
                ti = quo;
                ++ndig_for_this_limb;
              }
#endif
            /* If this wasn't the most significant word, pad with zeros.  */
            if (n != 0)
              while (ndig_for_this_limb < brec->big.ndigits)
                {
                  *--bp = '0';
                  ++ndig_for_this_limb;
                }
          }
        while (n != 0);
#endif
      }
      break;
    }

  return bp;
}

--- NEW FILE ---
/* Internal function for converting integers to ASCII.
   Copyright (C) 1994, 95, 96, 97, 98, 99 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#ifndef _ITOA_H
#define _ITOA_H
#include <sys/cdefs.h>

/* 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 (unsigned long long int value, char *buflim,
                    unsigned int base, int upper_case);

#ifndef __CSCC__

static inline char * __attribute__ ((unused))
_itoa_word (unsigned long value, char *buflim,
            unsigned int base, int upper_case)
{
  extern const char _itoa_upper_digits[], _itoa_lower_digits[];
  const char *digits = upper_case ? _itoa_upper_digits : _itoa_lower_digits;
  char *bp = buflim;

  switch (base)
    {
#define SPECIAL(Base)                                                         \
    case Base:                                                                \
      do                                                                      \
        *--bp = digits[value % Base];                                         \
      while ((value /= Base) != 0);                                           \
      break

      SPECIAL (10);
      SPECIAL (16);
      SPECIAL (8);
    default:
      do
        *--bp = digits[value % base];
      while ((value /= base) != 0);
    }
  return bp;
}

static inline char * __attribute__ ((unused))
_fitoa_word (unsigned long value, char *buf, unsigned int base, int upper_case)
{
  char tmpbuf[sizeof (value) * 4];              /* Worst case length: base 2.  
*/
  char *cp = _itoa_word (value, tmpbuf + sizeof (value) * 4, base, upper_case);
  while (cp < tmpbuf + sizeof (value) * 4)
    *buf++ = *cp++;
  return buf;
}

static inline char * __attribute__ ((unused))
_fitoa (unsigned long long value, char *buf, unsigned int base, int upper_case)
{
  char tmpbuf[sizeof (value) * 4];              /* Worst case length: base 2.  
*/
  char *cp = _itoa (value, tmpbuf + sizeof (value) * 4, base, upper_case);
  while (cp < tmpbuf + sizeof (value) * 4)
    *buf++ = *cp++;
  return buf;
}

#endif

#endif  /* itoa.h */

--- NEW FILE ---
/* Internal function for converting integers to ASCII.
   Copyright (C) 1994, 1995, 1996, 1999, 2000 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Torbjorn Granlund <address@hidden>
   and Ulrich Drepper <address@hidden>.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <gmp-mparam.h>
#include <gmp.h>
#include <stdlib/gmp-impl.h>
#include <stdlib/longlong.h>

#include "_itowa.h"


/* Canonize environment.  For some architectures not all values might
   be defined in the GMP header files.  */
#ifndef UMUL_TIME
# define UMUL_TIME 1
#endif
#ifndef UDIV_TIME
# define UDIV_TIME 3
#endif

/* Control memory layout.  */
#ifdef PACK
# undef PACK
# define PACK __attribute__ ((packed))
#else
# define PACK
#endif


/* Declare local types.  */
struct base_table_t
{
#if (UDIV_TIME > 2 * UMUL_TIME)
  mp_limb_t base_multiplier;
#endif
  char flag;
  char post_shift;
#if BITS_PER_MP_LIMB == 32
  struct
    {
      char normalization_steps;
      char ndigits;
      mp_limb_t base PACK;
#if UDIV_TIME > 2 * UMUL_TIME
      mp_limb_t base_ninv PACK;
#endif
    } big;
#endif
};

/* To reduce the memory needed we include some fields of the tables
   only conditionally.  */
#if UDIV_TIME > 2 * UMUL_TIME
# define SEL1(X) X,
# define SEL2(X) ,X
#else
# define SEL1(X)
# define SEL2(X)
#endif

/* Factor table for the different bases.  */
extern const struct base_table_t _itoa_base_table[];

/* Lower-case digits.  */
extern const wchar_t _itowa_lower_digits[];
/* Upper-case digits.  */
extern const wchar_t _itowa_upper_digits[];


wchar_t *
_itowa (value, buflim, base, upper_case)
     unsigned long long int value;
     wchar_t *buflim;
     unsigned int base;
     int upper_case;
{
  const wchar_t *digits = (upper_case
                           ? _itowa_upper_digits : _itowa_lower_digits);
  wchar_t *bp = buflim;
  const struct base_table_t *brec = &_itoa_base_table[base - 2];

  switch (base)
    {
#define RUN_2N(BITS) \
      do                                                                      \
        {                                                                     \
          /* `unsigned long long int' always has 64 bits.  */                 \
          mp_limb_t work_hi = value >> (64 - BITS_PER_MP_LIMB);               \
                                                                              \
          if (BITS_PER_MP_LIMB == 32)                                         \
            {                                                                 \
              if (work_hi != 0)                                               \
                {                                                             \
                  mp_limb_t work_lo;                                          \
                  int cnt;                                                    \
                                                                              \
                  work_lo = value & 0xfffffffful;                             \
                  for (cnt = BITS_PER_MP_LIMB / BITS; cnt > 0; --cnt)         \
                    {                                                         \
                      *--bp = digits[work_lo & ((1ul << BITS) - 1)];          \
                      work_lo >>= BITS;                                       \
                    }                                                         \
                  if (BITS_PER_MP_LIMB % BITS != 0)                           \
                    {                                                         \
                      work_lo                                                 \
                        |= ((work_hi                                          \
                             & ((1 << (BITS - BITS_PER_MP_LIMB%BITS))         \
                                - 1))                                         \
                            << BITS_PER_MP_LIMB % BITS);                      \
                      work_hi >>= BITS - BITS_PER_MP_LIMB % BITS;             \
                      if (work_hi == 0)                                       \
                        work_hi = work_lo;                                    \
                      else                                                    \
                        *--bp = digits[work_lo];                              \
                    }                                                         \
                }                                                             \
              else                                                            \
                work_hi = value & 0xfffffffful;                               \
            }                                                                 \
          do                                                                  \
            {                                                                 \
              *--bp = digits[work_hi & ((1 << BITS) - 1)];                    \
              work_hi >>= BITS;                                               \
            }                                                                 \
          while (work_hi != 0);                                               \
        }                                                                     \
      while (0)
    case 8:
      RUN_2N (3);
      break;

    case 16:
      RUN_2N (4);
      break;

    default:
      {
#if BITS_PER_MP_LIMB == 64
        mp_limb_t base_multiplier = brec->base_multiplier;
        if (brec->flag)
          while (value != 0)
            {
              mp_limb_t quo, rem, x, dummy;

              umul_ppmm (x, dummy, value, base_multiplier);
              quo = (x + ((value - x) >> 1)) >> (brec->post_shift - 1);
              rem = value - quo * base;
              *--bp = digits[rem];
              value = quo;
            }
        else
          while (value != 0)
            {
              mp_limb_t quo, rem, x, dummy;

              umul_ppmm (x, dummy, value, base_multiplier);
              quo = x >> brec->post_shift;
              rem = value - quo * base;
              *--bp = digits[rem];
              value = quo;
            }
#endif
#if BITS_PER_MP_LIMB == 32
        mp_limb_t t[3];
        int n;

        /* First convert x0 to 1-3 words in base s->big.base.
           Optimize for frequent cases of 32 bit numbers.  */
        if ((mp_limb_t) (value >> 32) >= 1)
          {
#if UDIV_TIME > 2 * UMUL_TIME || UDIV_NEEDS_NORMALIZATION
            int big_normalization_steps = brec->big.normalization_steps;
            mp_limb_t big_base_norm
              = brec->big.base << big_normalization_steps;
#endif
            if ((mp_limb_t) (value >> 32) >= brec->big.base)
              {
                mp_limb_t x1hi, x1lo, r;
                /* If you want to optimize this, take advantage of
                   that the quotient in the first udiv_qrnnd will
                   always be very small.  It might be faster just to
                   subtract in a tight loop.  */

#if UDIV_TIME > 2 * UMUL_TIME
                mp_limb_t x, xh, xl;

                if (big_normalization_steps == 0)
                  xh = 0;
                else
                  xh = (mp_limb_t) (value >> (64 - big_normalization_steps));
                xl = (mp_limb_t) (value >> (32 - big_normalization_steps));
                udiv_qrnnd_preinv (x1hi, r, xh, xl, big_base_norm,
                                   brec->big.base_ninv);

                xl = ((mp_limb_t) value) << big_normalization_steps;
                udiv_qrnnd_preinv (x1lo, x, r, xl, big_base_norm,
                                   brec->big.base_ninv);
                t[2] = x >> big_normalization_steps;

                if (big_normalization_steps == 0)
                  xh = x1hi;
                else
                  xh = ((x1hi << big_normalization_steps)
                        | (x1lo >> (32 - big_normalization_steps)));
                xl = x1lo << big_normalization_steps;
                udiv_qrnnd_preinv (t[0], x, xh, xl, big_base_norm,
                                   brec->big.base_ninv);
                t[1] = x >> big_normalization_steps;
#elif UDIV_NEEDS_NORMALIZATION
                mp_limb_t x, xh, xl;

                if (big_normalization_steps == 0)
                  xh = 0;
                else
                  xh = (mp_limb_t) (value >> 64 - big_normalization_steps);
                xl = (mp_limb_t) (value >> 32 - big_normalization_steps);
                udiv_qrnnd (x1hi, r, xh, xl, big_base_norm);

                xl = ((mp_limb_t) value) << big_normalization_steps;
                udiv_qrnnd (x1lo, x, r, xl, big_base_norm);
                t[2] = x >> big_normalization_steps;

                if (big_normalization_steps == 0)
                  xh = x1hi;
                else
                  xh = ((x1hi << big_normalization_steps)
                        | (x1lo >> 32 - big_normalization_steps));
                xl = x1lo << big_normalization_steps;
                udiv_qrnnd (t[0], x, xh, xl, big_base_norm);
                t[1] = x >> big_normalization_steps;
#else
                udiv_qrnnd (x1hi, r, 0, (mp_limb_t) (value >> 32),
                            brec->big.base);
                udiv_qrnnd (x1lo, t[2], r, (mp_limb_t) value, brec->big.base);
                udiv_qrnnd (t[0], t[1], x1hi, x1lo, brec->big.base);
#endif
                n = 3;
              }
            else
              {
#if (UDIV_TIME > 2 * UMUL_TIME)
                mp_limb_t x;

                value <<= brec->big.normalization_steps;
                udiv_qrnnd_preinv (t[0], x, (mp_limb_t) (value >> 32),
                                   (mp_limb_t) value, big_base_norm,
                                   brec->big.base_ninv);
                t[1] = x >> brec->big.normalization_steps;
#elif UDIV_NEEDS_NORMALIZATION
                mp_limb_t x;

                value <<= big_normalization_steps;
                udiv_qrnnd (t[0], x, (mp_limb_t) (value >> 32),
                            (mp_limb_t) value, big_base_norm);
                t[1] = x >> big_normalization_steps;
#else
                udiv_qrnnd (t[0], t[1], (mp_limb_t) (value >> 32),
                            (mp_limb_t) value, brec->big.base);
#endif
                n = 2;
              }
          }
        else
          {
            t[0] = value;
            n = 1;
          }

        /* Convert the 1-3 words in t[], word by word, to ASCII.  */
        do
          {
            mp_limb_t ti = t[--n];
            int ndig_for_this_limb = 0;

#if UDIV_TIME > 2 * UMUL_TIME
            mp_limb_t base_multiplier = brec->base_multiplier;
            if (brec->flag)
              while (ti != 0)
                {
                  mp_limb_t quo, rem, x, dummy;

                  umul_ppmm (x, dummy, ti, base_multiplier);
                  quo = (x + ((ti - x) >> 1)) >> (brec->post_shift - 1);
                  rem = ti - quo * base;
                  *--bp = digits[rem];
                  ti = quo;
                  ++ndig_for_this_limb;
                }
            else
              while (ti != 0)
                {
                  mp_limb_t quo, rem, x, dummy;

                  umul_ppmm (x, dummy, ti, base_multiplier);
                  quo = x >> brec->post_shift;
                  rem = ti - quo * base;
                  *--bp = digits[rem];
                  ti = quo;
                  ++ndig_for_this_limb;
                }
#else
            while (ti != 0)
              {
                mp_limb_t quo, rem;

                quo = ti / base;
                rem = ti % base;
                *--bp = digits[rem];
                ti = quo;
                ++ndig_for_this_limb;
              }
#endif
            /* If this wasn't the most significant word, pad with zeros.  */
            if (n != 0)
              while (ndig_for_this_limb < brec->big.ndigits)
                {
                  *--bp = '0';
                  ++ndig_for_this_limb;
                }
          }
        while (n != 0);
#endif
      }
      break;
    }

  return bp;
}

--- NEW FILE ---
/* Internal function for converting integers to ASCII.
   Copyright (C) 1994, 95, 96, 97, 98, 99 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#ifndef _ITOWA_H
#define _ITOWA_H        1
#include <features.h>
#include <wchar.h>

/* 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 wchar_t *_itowa (unsigned long long int value, wchar_t *buflim,
                        unsigned int base, int upper_case);

static inline wchar_t *
__attribute__ ((unused))
_itowa_word (unsigned long value, wchar_t *buflim,
             unsigned int base, int upper_case)
{
  extern const wchar_t _itowa_upper_digits[], _itowa_lower_digits[];
  const wchar_t *digits = (upper_case
                           ? _itowa_upper_digits : _itowa_lower_digits);
  wchar_t *bp = buflim;

  switch (base)
    {
#define SPECIAL(Base)                                                         \
    case Base:                                                                \
      do                                                                      \
        *--bp = digits[value % Base];                                         \
      while ((value /= Base) != 0);                                           \
      break

      SPECIAL (10);
      SPECIAL (16);
      SPECIAL (8);
    default:
      do
        *--bp = digits[value % base];
      while ((value /= base) != 0);
    }
  return bp;
}

#endif  /* itowa.h */

--- NEW FILE ---
/* Copyright (C) 1991, 1995, 1997, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdarg.h>
#include <stdio.h>

#ifdef USE_IN_LIBIO
# include <libio/libioP.h>
# define vasprintf(s, f, a) _IO_vasprintf (s, f, a)
#endif

/* Write formatted output from FORMAT to a string which is
   allocated with malloc and stored in *STRING_PTR.  */
/* VARARGS2 */
int
__asprintf (char **string_ptr, const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = vasprintf (string_ptr, format, arg);
  va_end (arg);

  return done;
}
weak_alias (__asprintf, asprintf)

--- NEW FILE ---
/* Copyright (C) 1991, 1997, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>

#undef  clearerr


/* Clear the EOF and error indicators for STREAM.  */
void
clearerr (FILE *stream)
{
  __clearerr (stream);
}

weak_alias (clearerr, clearerr_unlocked)

--- NEW FILE ---
/* Definitions of global stdio data structures.
   Copyright (C) 1991, 1995, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>

/* This file should define the following
   variables as appropriate for the system.  */

FILE *stdin, *stdout, *stderr;

/* Pointer to the first stream in the list.  */
FILE *__stdio_head;

/* This function MUST be in this file!
   This is because we want _cleanup to go into the __libc_atexit set
   when any stdio code is used (and to use any stdio code, one must reference
   something defined in this file), and since only local symbols can be made
   set elements, having the set element stab entry here and _cleanup elsewhere
   loses; and having them both elsewhere loses because there is no reference
   to cause _cleanup to be linked in.  */

void
_cleanup ()
{
  __fcloseall ();
}


#ifdef  HAVE_GNU_LD
text_set_element (__libc_atexit, _cleanup);
#endif

--- NEW FILE ---
/* Copyright (C) 1991, 1995, 1997, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdarg.h>
#include <stdio.h>

#ifdef USE_IN_LIBIO
# include <libio/libioP.h>
# define vdprintf(d, f, a) _IO_vdprintf (d, f, a)
#endif

/* Write formatted output to D, according to the format string FORMAT.  */
/* VARARGS2 */
int
dprintf (int d, const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = vdprintf (d, format, arg);
  va_end (arg);

  return done;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1995, 1996, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>


/* Close a stream.  */
int
fclose (stream)
     FILE *stream;
{
  int status;

  if (!__validfp (stream))
    {
      __set_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;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1995, 1996 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>


/* Close a stream.  */
int
__fcloseall ()
{
  /* Close all streams.  */
  register FILE *f;
  for (f = __stdio_head; f != NULL; f = f->__next)
    if (__validfp(f))
      (void) fclose(f);
  return 0;
}
weak_alias (__fcloseall, fcloseall)

--- NEW FILE ---
/* Copyright (C) 1991, 1996, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>

#undef  feof
#undef  feof_unlocked

/* Return non-zero if STREAM has its EOF indicator set.  */
int
feof (stream)
     FILE *stream;
{
  if (!__validfp (stream))
    {
      __set_errno (EINVAL);
      return -1;
    }

  return stream->__eof;
}

weak_alias (feof, feof_unlocked)

--- NEW FILE ---
/* Copyright (C) 1991, 1996, 1997, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>

#undef  ferror
#undef  ferror_unlocked


/* Return non-zero if STREAM has its error indicator set.  */
int
ferror (stream)
     FILE *stream;
{
  if (!__validfp (stream))
    {
      __set_errno (EINVAL);
      return -1;
    }

  return stream->__error;
}

weak_alias (ferror, ferror_unlocked)

--- NEW FILE ---
/* Copyright (C) 1991, 1996, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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
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)
    {
      __set_errno (EINVAL);
      return EOF;
    }

  return __flshfp (stream, EOF);
}

weak_alias(fflush, fflush_unlocked)

--- NEW FILE ---
/* Copyright (C) 1991, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>


/* Read a character from STREAM.  */
int
fgetc (stream)
     FILE *stream;
{
  if (!__validfp (stream) || !stream->__mode.__read)
    {
      __set_errno (EINVAL);
      return EOF;
    }

  return __getc (stream);
}

--- NEW FILE ---
/* Copyright (C) 1991, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>

#undef  fgetpos


/* Put the current position of STREAM in *POS.  */
int
fgetpos (stream, pos)
     FILE *stream;
     fpos_t *pos;
{
  if (!__validfp (stream) || pos == NULL)
    {
      __set_errno (EINVAL);
      return -1;
    }

  *pos = ftell (stream);
  if (*pos < 0L)
    return -1;
  return 0;
}

--- NEW FILE ---
/* Copyright (C) 1991, 92, 95, 96, 97, 98 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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 *
fgets (s, n, stream)
     char *s;
     int n;
     FILE *stream;
{
  register char *p = s;

  if (!__validfp (stream) || s == NULL || n <= 0)
    {
      __set_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 > (size_t) n)
        i = n;

      found = (char *) memccpy ((void *) 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;
}

weak_alias (fgets, fgets_unlocked)

--- NEW FILE ---
/* Copyright (C) 1991, 93, 94, 96, 97, 98 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>

/* Return the system file descriptor associated with STREAM.  */
int
fileno (stream)
     FILE *stream;
{
  extern void __stdio_check_funcs __P ((FILE *));

  if (! __validfp (stream))
    {
      __set_errno (EINVAL);
      return -1;
    }

  __stdio_check_funcs (stream);

  if (stream->__io_funcs.__fileno == NULL)
    {
#ifdef EOPNOTSUPP
      __set_errno (EOPNOTSUPP);
#else
      __set_errno (ENOSYS);
#endif
      return -1;
    }

  return (*stream->__io_funcs.__fileno) (stream->__cookie);
}

weak_alias(fileno, fileno_unlocked)

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1993, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/* Defined in fopen.c.  */
extern int __getmode __P ((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 *
fmemopen (s, len, mode)
     void *s;
     size_t len;
     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);
          __set_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 ((void *) stream->__buffer, 0, len);

  return stream;
}

--- NEW FILE ---
/* Copyright (C) 1991, 92, 93, 96, 97, 98 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define badmode()       return ((__set_errno (EINVAL)), 0)

/* Dissect the given mode string into an __io_mode.  */
int
__getmode (const char *mode, __io_mode *mptr)
{
  register unsigned char i;

  if (mode == NULL)
    badmode ();

  memset ((void *) 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 < 4; ++i)
    {
      switch (*++mode)
        {
        case '\0':
          break;
        case '+':
          mptr->__read = mptr->__write = 1;
          continue;
        case 'b':
          mptr->__binary = 1;
          continue;
        case 'x':
          mptr->__exclusive = 1;
          continue;
        }
      break;
    }

  if (!mptr->__read && !mptr->__write)
    badmode ();

  return 1;
}

/* Open a new stream on the given file.  */
FILE *
fopen (filename, mode)
     const char *filename;
     const char *mode;
{
  FILE *stream;
  __io_mode m;

  if (filename == NULL)
    {
      __set_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);
      __set_errno (save);
      return NULL;
    }

  stream->__mode = m;

  return stream;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>


/* Defined in fopen.c.  */
extern int __getmode __P ((const char *mode, __io_mode *mptr));

/* Open a new stream on the given magic cookie descriptor.  */
FILE *
fopencookie (cookie, mode, functions)
     void *cookie;
     const char *mode;
     __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;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdarg.h>
#include <stdio.h>


/* Write formatted output to STREAM from the format string FORMAT.  */
/* VARARGS2 */
int
fprintf (FILE *stream, const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = vfprintf (stream, format, arg);
  va_end (arg);

  return done;
}

#ifdef USE_IN_LIBIO
/* We define the function with the real name here.  But deep down in
   libio the original function _IO_fprintf is also needed.  So make
   an alias.  */
weak_alias (fprintf, _IO_fprintf)
#endif

--- NEW FILE ---
/* Copyright (C) 1991, 1996, 1997, 1998, 1999 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>


/* Write the character C to STREAM.  */
int
fputc (c, stream)
     int c;
     FILE *stream;
{
  if (!__validfp (stream) || !stream->__mode.__write)
    {
      __set_errno (EINVAL);
      return EOF;
    }

  return __putc (c, stream);
}

#ifndef fputc
weak_alias (fputc, fputc_unlocked)
#endif

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1997, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>
#include <string.h>


/* Write the string S to STREAM.  */
int
fputs (const char *s, FILE *stream)
{
  const size_t len = strlen (s);
  if (len == 1)
    return putc (*s, stream) == EOF ? EOF : 0;
  if (fwrite ((void *) s, 1, len, stream) != len)
    return EOF;
  return 0;
}
weak_alias (fputs, fputs_unlocked)

--- NEW FILE ---
/* Copyright (C) 1991, 92, 95, 96, 97, 98 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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
fread (p, size, nmemb, stream)
     void *p;
     size_t size;
     size_t nmemb;
     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)
    {
      __set_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((void *) ptr, (void *) 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;
                if (stream->__offset != -1)
                  {
                    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;
}

weak_alias (fread, fread_unlocked)

--- NEW FILE ---
/* Copyright (C) 1991, 1994, 1995, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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,
                                void *cookieptr, __io_close_fn *closefn));

/* Replace STREAM, opening it on FILENAME.  */
FILE *
freopen (filename, mode, stream)
     const char *filename;
     const char *mode;
     register FILE *stream;
{
  __io_mode m;
  void *cookie;

  if (!__getmode (mode, &m))
    {
      (void) fclose (stream);
      __set_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);
      __set_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;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdarg.h>
#include <stdio.h>

/* Read formatted input from STREAM according to the format string FORMAT.  */
/* VARARGS2 */
int
fscanf (FILE *stream, const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = __vfscanf (stream, format, arg);
  va_end (arg);

  return done;
}

--- NEW FILE ---
/* Copyright (C) 1991, 92, 93, 95, 96, 97 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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
fseek (stream, offset, whence)
     register FILE *stream;
     long int offset;
     int whence;
{
  long int o;

  if (!__validfp (stream))
    {
      __set_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.  */
  stream->__offset = -1;
  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:
      __set_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)
        {
          __set_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.  */
      __set_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.  */
      __set_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;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>

#undef  fsetpos


/* Set the file position of STREAM to *POS.  */
int
fsetpos (stream, pos)
     FILE *stream;
     const fpos_t *pos;
{
  if (pos == NULL)
    {
      __set_errno (EINVAL);
      return EOF;
    }

  return fseek (stream, *pos, SEEK_SET);
}

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1994, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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
ftell (stream)
     FILE *stream;
{
  long int pos;

  if (!__validfp (stream))
    {
      __set_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;
}

--- NEW FILE ---
/* Copyright (C) 1991, 92, 93, 94, 96, 97, 98 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>
#include <string.h>


/* Write NMEMB chunks of SIZE bytes each from PTR onto STREAM.  */
size_t
fwrite (ptr, size, nmemb, stream)
     const void *ptr;
     size_t size;
     size_t nmemb;
     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)
    {
      __set_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;
      }

    __set_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 void *) 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)
    {
      /* 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.  */
    fill_buffer:
      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 ((void *) stream->__bufp, (void *) p, n);
              stream->__bufp += n;
              p += n;
            }

          if (to_write == 0)
            /* Done writing.  */
            break;
          else if (buffer_space == 0)
            {
              /* We have 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;
                }
            }
        }

      /* We have written all the data into the buffer.  If we are
         line-buffered and just put a newline in the buffer, flush now to
         make sure it gets out.  */
      if (newlinep)
        fflush (stream);
    }
  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;
}

weak_alias (fwrite, fwrite_unlocked)

--- NEW FILE ---
#include <stdio.h>
#undef  getc
#define fgetc   getc
#include <fgetc.c>

weak_alias (getc, getc_unlocked)

--- NEW FILE ---
/* Copyright (C) 1991, 1997, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>

#undef getchar


/* Read a character from stdin.  */
int
getchar (void)
{
  return __getc (stdin);
}

weak_alias (getchar, getchar_unlocked)

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1995, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.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
__getdelim (lineptr, n, terminator, stream)
     char **lineptr;
     size_t *n;
     int terminator;
     FILE *stream;
{
  char *line, *p;
  size_t size, copy;

  if (!__validfp (stream) || lineptr == NULL || n == NULL)
    {
      __set_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 ((void *) 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)

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1995, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stddef.h>
#include <stdio.h>

#undef __getline

#ifdef USE_IN_LIBIO
# include "../libio/libioP.h"
# undef ssize_t
# define ssize_t _IO_ssize_t
# define __getdelim _IO_getdelim
#endif

/* Like getdelim, but always looks for a newline.  */
ssize_t
__getline (char **lineptr, size_t *n, FILE *stream)
{
  return __getdelim (lineptr, n, '\n', stream);
}

weak_alias (__getline, getline)

--- NEW FILE ---
/* Copyright (C) 1991, 1994, 1995, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>
#include <errno.h>
#include <string.h>

link_warning (gets, "the `gets' function is dangerous and should not be used.")

/* Read a newline-terminated string from stdin into S,
   removing the trailing newline.  Return S or NULL.  */
char *
gets (s)
     char *s;
{
  register char *p = s;
  register int c;
  FILE *stream = stdin;

  if (!__validfp (stream) || p == NULL)
    {
      __set_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;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1997, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>

#ifdef USE_IN_LIBIO
# include <libio/iolibio.h>
# define fread(p, m, n, s) _IO_fread (p, m, n, s)
#endif

/* Read a word (int) from STREAM.  */
int
getw (FILE *stream)
{
  int w;

  /* Is there a better way?  */
  if (fread ((void *) &w, sizeof (w), 1, stream) != 1)
    return EOF;
  return w;
}

--- NEW FILE ---
/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/* Make sure that FP has its functions set.  */
void
__stdio_check_funcs (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 __stdio_init_stream __P ((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
init_stream (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;
        }
      __set_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
__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.  */
          __set_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
seek_to_target (FILE *fp)
{
  int save = errno;
  if (__stdio_check_offset (fp) == EOF)
    {
      if (errno == ESPIPE)
        __set_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!  */
          __set_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!
                     This should never happen.  */
#ifdef EGRATUITOUS
                  /* It happens in the Hurd when the io server doesn't
                     obey the protocol for io_seek.  */
                  __set_errno (EGRATUITOUS);
#else
                  /* I don't think this can happen in Unix.  */
                  __set_errno (ESPIPE); /* ??? */
#endif
                  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
flushbuf (register FILE *fp, 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 (fp->__target == -1)
        /* For an unseekable object, data recently read bears no relation
           to data we will write later.  Discard the buffer.  */
        fp->__get_limit = fp->__buffer;
      else
        /* 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);
          __set_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 ((size_t) (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 ((size_t) (fp->__bufp - fp->__buffer) <= buffer_offset && flush_only)
        {
          /* 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;
      if (fp->__offset != -1)
        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 if (fp->__offset != -1)
                /* 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 if (fp->__offset != -1)
            {
              /* 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)
    {
      if (fp->__target != -1)
        /* 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
fillbuf (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);
      }
    __set_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;
          if (fp->__offset != -1)
            /* 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
__flshfp (fp, c)
     register FILE *fp;
     int c;
{
  int flush_only = c == EOF;

  if (!__validfp (fp) || !fp->__mode.__write)
    {
      __set_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
__fillbf (fp)
     register FILE *fp;
{
  register int c;
  fpos_t new_target;

  if (!__validfp (fp) || !fp->__mode.__read)
    {
      __set_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
__invalidate (stream)
     register FILE *stream;
{
  /* Save its link.  */
  register FILE *next = stream->__next;

  /* Pulverize the deceased.  */
  memset((void *) stream, 0, sizeof(FILE));

  /* Restore the deceased's link.  */
  stream->__next = next;
}

--- NEW FILE ---
/* Digits.
   Copyright (C) 1994, 1995, 1996, 1999, 2000 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

/* Lower-case digits.  */
const char _itoa_lower_digits[36]
        = "0123456789abcdefghijklmnopqrstuvwxyz";

--- NEW FILE ---
/* Digits.
   Copyright (C) 1994, 1995, 1996, 1999, 2000 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

/* Upper-case digits.  */
const char _itoa_upper_digits[36]
        = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

--- NEW FILE ---
/* Digits.
   Copyright (C) 1994, 1995, 1996, 1999 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <wchar.h>

/* Lower-case digits.  */
const wchar_t _itowa_lower_digits[36]
        = L"0123456789abcdefghijklmnopqrstuvwxyz";
/* Upper-case digits.  */
const wchar_t _itowa_upper_digits[36]
        = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

--- NEW FILE ---
/* Word-wrapping and line-truncating streams.
   Copyright (C) 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

#include <linewrap.h>

void __line_wrap_output (FILE *, int);

/* Install our hooks into a stream.  */
static void
wrap_stream (FILE *stream, struct line_wrap_data *d)
{
  static __io_close_fn lwclose;
  static __io_fileno_fn lwfileno;

  stream->__cookie = d;
  stream->__room_funcs.__output = &__line_wrap_output;
  stream->__io_funcs.__close = &lwclose;
  stream->__io_funcs.__fileno = &lwfileno;
  stream->__io_funcs.__seek = NULL; /* Cannot seek.  */
}

/* Restore a stream to its original state.  */
static void
unwrap_stream (FILE *stream, struct line_wrap_data *d)
{
  stream->__cookie = d->cookie;
  stream->__room_funcs.__output = d->output;
  stream->__io_funcs.__close = d->close;
  stream->__io_funcs.__fileno = d->fileno;
  stream->__io_funcs.__seek = d->seek;
}

/* If WRAPPER_COOKIE points to a 0 pointer, then STREAM is assumed to be
   wrapped, and will be unwrapped, storing the wrapper cookie into
   WRAPPER_COOKIE.  Otherwise, nothing is done.  */
static void
ensure_unwrapped (FILE *stream, struct line_wrap_data **wrapper_cookie)
{
  if (*wrapper_cookie == 0)
    {
      *wrapper_cookie = stream->__cookie;
      unwrap_stream (stream, *wrapper_cookie);
    }
}

/* If WRAPPER_COOKIE points to a non-0 pointer, then STREAM is assumed to
   *have been unwrapped with ensure_unwrapped, will be wrapped with
   *WRAPPER_COOKIE, and *WRAPPER_COOKIE zeroed.  Otherwise, nothing is done. */
static void
ensure_wrapped (FILE *stream, struct line_wrap_data **wrapper_cookie)
{
  if (*wrapper_cookie)
    {
      wrap_stream (stream, *wrapper_cookie);
      *wrapper_cookie = 0;
    }
}

/* Cookie io functions that might get called on a wrapped stream.
   Must pass the original cookie to the original functions.  */

static int
lwclose (void *cookie)
{
  struct line_wrap_data *d = cookie;
  return (*d->close) (d->cookie);
}

static int
lwfileno (void *cookie)
{
  struct line_wrap_data *d = cookie;
  return (*d->fileno) (d->cookie);
}

/* Process STREAM's buffer so that line wrapping is done from POINT_OFFS to
   the end of its buffer.  If WRAPPER_COOKIE is 0, and it's necessary to
   flush some data, STREAM is unwrapped, and the line wrap stdio cookie
   stored in WRAPPER_COOKIE; otherwise, stream is assumed to already be
   unwrapped, and WRAPPER_COOKIE to point to the line wrap data.  Returns C
   or EOF if C was output.  */
static int
lwupdate (FILE *stream, int c, struct line_wrap_data **wrapper_cookie)
{
  char *buf, *nl;
  size_t len;
  struct line_wrap_data *d = *wrapper_cookie ? *wrapper_cookie : 
stream->__cookie;

  /* Scan the buffer for newlines.  */
  buf = stream->__buffer + d->point_offs;
  while ((buf < stream->__bufp || (c != EOF && c != '\n')) && !stream->__error)
    {
      size_t r;

      if (d->point_col == 0 && d->lmargin != 0)
        {
          /* We are starting a new line.  Print spaces to the left margin.  */
          const size_t pad = d->lmargin;
          if (stream->__bufp + pad < stream->__put_limit)
            {
              /* We can fit in them in the buffer by moving the
                 buffer text up and filling in the beginning.  */
              memmove (buf + pad, buf, stream->__bufp - buf);
              stream->__bufp += pad; /* Compensate for bigger buffer. */
              memset (buf, ' ', pad); /* Fill in the spaces.  */
              buf += pad; /* Don't bother searching them.  */
            }
          else
            {
              /* No buffer space for spaces.  Must flush.  */
              size_t i;
              char *olimit;

              ensure_unwrapped (stream, wrapper_cookie);

              len = stream->__bufp - buf;
              olimit = stream->__put_limit;
              stream->__bufp = stream->__put_limit = buf;
              for (i = 0; i < pad; ++i)
                (*d->output) (stream, ' ');
              stream->__put_limit = olimit;
              memmove (stream->__bufp, buf, len);
              stream->__bufp += len;
            }
          d->point_col = pad;
        }

      len = stream->__bufp - buf;
      nl = memchr (buf, '\n', len);

      if (d->point_col < 0)
        d->point_col = 0;

      if (!nl)
        {
          /* The buffer ends in a partial line.  */

          if (d->point_col + len + (c != EOF && c != '\n') < d->rmargin)
            {
              /* The remaining buffer text is a partial line and fits
                 within the maximum line width.  Advance point for the
                 characters to be written and stop scanning.  */
              d->point_col += len;
              break;
            }
          else
            /* Set the end-of-line pointer for the code below to
               the end of the buffer.  */
            nl = stream->__bufp;
        }
      else if ((size_t) d->point_col + (nl - buf) < d->rmargin)
        {
          /* The buffer contains a full line that fits within the maximum
             line width.  Reset point and scan the next line.  */
          d->point_col = 0;
          buf = nl + 1;
          continue;
        }

      /* This line is too long.  */
      r = d->rmargin - 1;

      if (d->wmargin < 0)
        {
          /* Truncate the line by overwriting the excess with the
             newline and anything after it in the buffer.  */
          if (nl < stream->__bufp)
            {
              memmove (buf + (r - d->point_col), nl, stream->__bufp - nl);
              stream->__bufp -= buf + (r - d->point_col) - nl;
              /* Reset point for the next line and start scanning it.  */
              d->point_col = 0;
              buf += r + 1; /* Skip full line plus \n. */
            }
          else
            {
              /* The buffer ends with a partial line that is beyond the
                 maximum line width.  Advance point for the characters
                 written, and discard those past the max from the buffer.  */
              d->point_col += len;
              stream->__bufp -= d->point_col - r;
              if (c != '\n')
                /* Swallow the extra character too.  */
                c = EOF;
              break;
            }
        }
      else
        {
          /* Do word wrap.  Go to the column just past the maximum line
             width and scan back for the beginning of the word there.
             Then insert a line break.  */

          char *p, *nextline;
          int i;

          p = buf + (r + 1 - d->point_col);
          while (p >= buf && !isblank (*p))
            --p;
          nextline = p + 1;     /* This will begin the next line.  */

          if (nextline > buf)
            {
              /* Swallow separating blanks.  */
              do
                --p;
              while (isblank (*p));
              nl = p + 1;       /* The newline will replace the first blank. */
            }
          else
            {
              /* A single word that is greater than the maximum line width.
                 Oh well.  Put it on an overlong line by itself.  */
              p = buf + (r + 1 - d->point_col);
              /* Find the end of the long word.  */
              do
                ++p;
              while (p < nl && !isblank (*p));
              if (p == nl)
                {
                  /* It already ends a line.  No fussing required.  */
                  d->point_col = 0;
                  buf = nl + 1;
                  continue;
                }
              /* We will move the newline to replace the first blank.  */
              nl = p;
              /* Swallow separating blanks.  */
              do
                ++p;
              while (isblank (*p));
              /* The next line will start here.  */
              nextline = p;
            }

          /* Temporarily reset bufp to include just the first line.  */
          stream->__bufp = nl;
          if (nextline - (nl + 1) < d->wmargin)
            /* The margin needs more blanks than we removed.
               Output the first line so we can use the space.  */
            {
              ensure_unwrapped (stream, wrapper_cookie);
              (*d->output) (stream, '\n');
            }
          else
            /* We can fit the newline and blanks in before
               the next word.  */
            *stream->__bufp++ = '\n';

          /* Reset the counter of what has been output this line.  If wmargin
             is 0, we want to avoid the lmargin getting added, so we set
             point_col to a magic value of -1 in that case.  */
          d->point_col = d->wmargin ? d->wmargin : -1;

          /* Add blanks up to the wrap margin column.  */
          for (i = 0; i < d->wmargin; ++i)
            *stream->__bufp++ = ' ';

          /* Copy the tail of the original buffer into the current buffer
             position.  */
          if (stream->__bufp != nextline)
            memmove (stream->__bufp, nextline, buf + len - nextline);
          len -= nextline - buf;

          /* Continue the scan on the remaining lines in the buffer.  */
          buf = stream->__bufp;

          /* Restore bufp to include all the remaining text.  */
          stream->__bufp += len;
        }
    }

  /* Remember that we've scanned as far as the end of the buffer.  */
  d->point_offs = stream->__bufp - stream->__buffer;

  return c;
}

/* This function is called when STREAM must be flushed.
   C is EOF or a character to be appended to the buffer contents.  */
void
__line_wrap_output (FILE *stream, int c)
{
  struct line_wrap_data *d = 0;

  c = lwupdate (stream, c, &d);

  if (!stream->__error)
    {
      ensure_unwrapped (stream, &d);
      (*d->output) (stream, c);
      d->point_offs = 0;        /* The buffer now holds nothing.  */
      if (c == '\n')
        d->point_col = 0;
      else if (c != EOF)
        ++d->point_col;
    }

  ensure_wrapped (stream, &d);
}

/* Modify STREAM so that it prefixes lines written on it with LMARGIN spaces
   and limits them to RMARGIN columns total.  If WMARGIN >= 0, words that
   extend past RMARGIN are wrapped by replacing the whitespace before them
   with a newline and WMARGIN spaces.  Otherwise, chars beyond RMARGIN are
   simply dropped until a newline.  Returns STREAM after modifying it, or
   NULL if there was an error.  */
FILE *
line_wrap_stream (FILE *stream, size_t lmargin, size_t rmargin, ssize_t wmargin)
{
  struct line_wrap_data *d;
  d = malloc (sizeof *d);

  if (!d)
    return NULL;

  /* Ensure full setup before we start tweaking.  */
  fflush (stream);

  /* Initialize our wrapping state.  */
  d->point_col = 0;
  d->point_offs = 0;

  /* Save the original cookie and output and close hooks.  */
  d->cookie = stream->__cookie;
  d->output = stream->__room_funcs.__output;
  d->close = stream->__io_funcs.__close;
  d->fileno = stream->__io_funcs.__fileno;
  d->seek = stream->__io_funcs.__seek;

  /* Take over the stream.  */
  wrap_stream (stream, d);

  /* Line-wrapping streams are normally line-buffered.  This is not
     required, just assumed desired.  The wrapping feature should continue
     to work if the stream is switched to full or no buffering.  */
  stream->__linebuf = 1;

  d->lmargin = lmargin;
  d->rmargin = rmargin;
  d->wmargin = wmargin;

  return stream;
}

/* Remove the hooks placed in STREAM by `line_wrap_stream'.  */
void
line_unwrap_stream (FILE *stream)
{
  struct line_wrap_data *d = stream->__cookie;
  unwrap_stream (stream, d);
  free (d);
}

/* Functions on wrapped streams.  */

/* Returns true if STREAM is line wrapped.  */
int
line_wrapped (FILE *stream)
{
  return (stream->__room_funcs.__output == &__line_wrap_output);
}

/* If STREAM is not line-wrapped, return 0.  Otherwise all pending text
   buffered text in STREAM so that the POINT_OFFS field refers to the last
   position in the stdio buffer, and return the line wrap state object for
   STREAM.  Since all text has been processed, this means that (1) the
   POINT_COL field refers to the column at which any new text would be added,
   and (2) any changes to the margin parameters will only affect new text.  */
struct line_wrap_data *
__line_wrap_update (FILE *stream)
{
  if (line_wrapped (stream))
    {
      struct line_wrap_data *d = stream->__cookie, *wc = 0;

      if (stream->__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.  */
        stream->__put_limit = stream->__buffer + stream->__bufsize;

      lwupdate (stream, EOF, &wc);

      if (stream->__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 flshfp.  Setting the linebuf_active
             flag tells the code above (on the next call) to undo this
             hackery.  */
          stream->__put_limit = stream->__buffer;
          stream->__linebuf_active = 1;
        }

      ensure_wrapped (stream, &wc);

      return d;
    }
  else
    return 0;
}

/* If STREAM is not line-wrapped return -1, else return its left margin.  */
size_t
line_wrap_lmargin (FILE *stream)
{
  if (! line_wrapped (stream))
    return -1;
  return ((struct line_wrap_data *)stream->__cookie)->lmargin;
}

/* If STREAM is not line-wrapped return -1, else set its left margin to
   LMARGIN and return the old value.  */
size_t
line_wrap_set_lmargin (FILE *stream, size_t lmargin)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  if (d)
    {
      size_t old = d->lmargin;
      d->lmargin = lmargin;
      return old;
    }
  else
    return -1;
}

/* If STREAM is not line-wrapped return -1, else return its left margin.  */
size_t
line_wrap_rmargin (FILE *stream)
{
  if (! line_wrapped (stream))
    return -1;
  return ((struct line_wrap_data *)stream->__cookie)->rmargin;
}

/* If STREAM is not line-wrapped return -1, else set its right margin to
   RMARGIN and return the old value.  */
size_t
line_wrap_set_rmargin (FILE *stream, size_t rmargin)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  if (d)
    {
      size_t old = d->rmargin;
      d->rmargin = rmargin;
      return old;
    }
  else
    return -1;
}

/* If STREAM is not line-wrapped return -1, else return its wrap margin.  */
size_t
line_wrap_wmargin (FILE *stream)
{
  if (! line_wrapped (stream))
    return -1;
  return ((struct line_wrap_data *)stream->__cookie)->wmargin;
}

/* If STREAM is not line-wrapped return -1, else set its left margin to
   WMARGIN and return the old value.  */
size_t
line_wrap_set_wmargin (FILE *stream, size_t wmargin)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  if (d)
    {
      size_t old = d->wmargin;
      d->wmargin = wmargin;
      return old;
    }
  else
    return -1;
}

/* If STREAM is not line-wrapped return -1, else return the column number of
   the current output point.  */
size_t
line_wrap_point (FILE *stream)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  return d ? (d->point_col >= 0 ? d->point_col : 0) : -1;
}

#ifdef TEST
int
main (int argc, char **argv)
{
  int c;
  puts ("stopme");
  line_wrap_stream (stdout, atoi (argv[1]), atoi (argv[2] ?: "-1"));
  while ((c = getchar()) != EOF) putchar (c);
  return 0;
}
#endif

--- NEW FILE ---
/* Word-wrapping and line-truncating streams.
   Copyright (C) 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#ifndef __LINEWRAP_H__
#define __LINEWRAP_H__

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include <features.h>

#include <string.h>             /* Need size_t.  */

__BEGIN_DECLS

/* We keep this data for each line-wrapping stream.  */
struct line_wrap_data
  {
    size_t lmargin, rmargin;    /* Left and right margins.  */
    ssize_t wmargin;            /* Margin to wrap to, or -1 to truncate.  */

    /* Point in stdio buffer to which we've processed for wrapping, but
       not output.  */
    size_t point_offs;
    /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin.  */
    ssize_t point_col;

    /* Original cookie and hooks from the stream.  */
    void *cookie;
    void (*output) (FILE *, int);
    __io_close_fn *close;
    __io_fileno_fn *fileno;
    __io_seek_fn *seek;
  };

/* Modify STREAM so that it prefixes lines written on it with LMARGIN spaces
   and limits them to RMARGIN columns total.  If WMARGIN >= 0, words that
   extend past RMARGIN are wrapped by replacing the whitespace before them
   with a newline and WMARGIN spaces.  Otherwise, chars beyond RMARGIN are
   simply dropped until a newline.  Returns STREAM after modifying it, or
   NULL if there was an error.  */
FILE *line_wrap_stream (FILE *stream,
                        size_t lmargin, size_t rmargin, ssize_t wmargin);

/* Remove the hooks placed in STREAM by `line_wrap_stream'.  */
void line_unwrap_stream (FILE *stream);

/* Returns true if STREAM is line wrapped.  */
extern int line_wrapped (FILE *stream);

/* If STREAM is not line-wrapped return -1, else return its left margin.  */
extern size_t line_wrap_lmargin (FILE *stream);

/* If STREAM is not line-wrapped return -1, else set its left margin to
   LMARGIN and return the old value.  */
extern size_t line_wrap_set_lmargin (FILE *stream, size_t lmargin);

/* If STREAM is not line-wrapped return -1, else return its left margin.  */
extern size_t line_wrap_rmargin (FILE *stream);

/* If STREAM is not line-wrapped return -1, else set its right margin to
   RMARGIN and return the old value.  */
extern size_t line_wrap_set_rmargin (FILE *stream, size_t rmargin);

/* If STREAM is not line-wrapped return -1, else return its wrap margin.  */
extern size_t line_wrap_wmargin (FILE *stream);

/* If STREAM is not line-wrapped return -1, else set its left margin to
   WMARGIN and return the old value.  */
extern size_t line_wrap_set_wmargin (FILE *stream, size_t wmargin);

/* If STREAM is not line-wrapped return -1, else return the column number of
   the current output point.  */
extern size_t line_wrap_point (FILE *stream);

#ifdef  __OPTIMIZE__

extern void __line_wrap_output (FILE *, int); /* private */

/* If STREAM is not line-wrapped, return 0.  Otherwise all pending text
   buffered text in STREAM so that the POINT_OFFS field refers to the last
   position in the stdio buffer, and return the line wrap state object for
   STREAM.  Since all text has been processed, this means that (1) the
   POINT_COL field refers to the column at which any new text would be added,
   and (2) any changes to the margin parameters will only affect new text.  */
extern struct line_wrap_data *__line_wrap_update (FILE *stream); /* private */

/* Returns true if STREAM is line wrapped.  */
extern inline int
line_wrapped (FILE *stream)
{
  return (stream->__room_funcs.__output == &__line_wrap_output);
}

/* If STREAM is not line-wrapped return -1, else return its left margin.  */
extern inline size_t
line_wrap_lmargin (FILE *stream)
{
  if (! line_wrapped (stream))
    return -1;
  return ((struct line_wrap_data *)stream->__cookie)->lmargin;
}

/* If STREAM is not line-wrapped return -1, else set its left margin to
   LMARGIN and return the old value.  */
extern inline size_t
line_wrap_set_lmargin (FILE *stream, size_t lmargin)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  if (d)
    {
      size_t old = d->lmargin;
      d->lmargin = lmargin;
      return old;
    }
  else
    return -1;
}

/* If STREAM is not line-wrapped return -1, else return its left margin.  */
extern inline size_t
line_wrap_rmargin (FILE *stream)
{
  if (! line_wrapped (stream))
    return -1;
  return ((struct line_wrap_data *)stream->__cookie)->rmargin;
}

/* If STREAM is not line-wrapped return -1, else set its right margin to
   RMARGIN and return the old value.  */
extern inline size_t
line_wrap_set_rmargin (FILE *stream, size_t rmargin)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  if (d)
    {
      size_t old = d->rmargin;
      d->rmargin = rmargin;
      return old;
    }
  else
    return -1;
}

/* If STREAM is not line-wrapped return -1, else return its wrap margin.  */
extern inline size_t
line_wrap_wmargin (FILE *stream)
{
  if (! line_wrapped (stream))
    return -1;
  return ((struct line_wrap_data *)stream->__cookie)->wmargin;
}

/* If STREAM is not line-wrapped return -1, else set its left margin to
   WMARGIN and return the old value.  */
extern inline size_t
line_wrap_set_wmargin (FILE *stream, size_t wmargin)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  if (d)
    {
      size_t old = d->wmargin;
      d->wmargin = wmargin;
      return old;
    }
  else
    return -1;
}

/* If STREAM is not line-wrapped return -1, else return the column number of
   the current output point.  */
extern inline size_t
line_wrap_point (FILE *stream)
{
  struct line_wrap_data *d = __line_wrap_update (stream);
  return d ? (d->point_col >= 0 ? d->point_col : 0) : -1;
}

#endif /* Optimizing.  */

__END_DECLS

#endif /* __LINEWRAP_H__ */

--- NEW FILE ---
/* Copyright (C) 1991, 92, 94, 95, 96, 97 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

struct memstream_info
  {
    char **buffer;
    size_t *bufsize;
  };

/* Enlarge STREAM's buffer.  */
static void
enlarge_buffer (register FILE *stream, 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
      && (size_t) 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 ((void *) 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.  */
      memset (stream->__bufp, '\0', 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
seek (void *cookie, fpos_t *pos, 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
free_info (void *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 *
open_memstream (bufloc, sizeloc)
     char **bufloc;
     size_t *sizeloc;
{
  FILE *stream;
  struct memstream_info *info;

  if (bufloc == NULL || sizeloc == NULL)
    {
      __set_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);
      __set_errno (save);
      return NULL;
    }

  stream->__room_funcs.__output = enlarge_buffer;
  stream->__io_funcs.__seek = seek;
  stream->__io_funcs.__close = free_info;
  stream->__cookie = (void *) info;
  stream->__userbuf = 1;

  info->buffer = bufloc;
  info->bufsize = sizeloc;

  *bufloc = stream->__buffer;

  return stream;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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 *
__newstream (void)
{
  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;
}

--- NEW FILE ---
/* Copyright (C) 1991-1993,1997,1998,2000,2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <wchar.h>
#ifdef USE_IN_LIBIO
# include "libioP.h"
#endif

static void
perror_internal (FILE *fp, const char *s, int errnum)
{
  char buf[1024];
  const char *colon;
  const char *errstring;

  if (s == NULL || *s == '\0')
    s = colon = "";
  else
    colon = ": ";

  errstring = __strerror_r (errnum, buf, sizeof buf);

#ifdef USE_IN_LIBIO
  if (_IO_fwide (fp, 0) > 0)
    (void) __fwprintf (fp, L"%s%s%s\n", s, colon, errstring);
  else
#endif
    (void) fprintf (fp, "%s%s%s\n", s, colon, errstring);
}


/* Print a line on stderr consisting of the text in S, a colon, a space,
   a message describing the meaning of the contents of `errno' and a newline.
   If S is NULL or "", the colon and space are omitted.  */
void
perror (const char *s)
{
  int errnum = errno;
#ifdef USE_IN_LIBIO
  FILE *fp;
  int fd = -1;


  /* The standard says that 'perror' must not change the orientation
     of the stream.  What is supposed to happen when the stream isn't
     oriented yet?  In this case we'll create a new stream which is
     using the same underlying file descriptor.  */
  if (__builtin_expect (_IO_fwide (stderr, 0) != 0, 1)
      || fileno_unlocked (stderr) == -1
      || (fd = __dup (fileno_unlocked (stderr))) == -1
      || (fp = fdopen (fd, "w+")) == NULL)
    {
      if (__builtin_expect (fd != -1, 0))
        __close (fd);

      /* Use standard error as is.  */
      perror_internal (stderr, s, errnum);
    }
  else
    {
      /* We don't have to do any special hacks regarding the file
         position.  Since the stderr stream wasn't used so far we just
         write to the descriptor.  */
      perror_internal (fp, s, errnum);
      /* Close the stream.  */
      fclose (fp);

      ((_IO_FILE *) stderr)->_offset = _IO_pos_BAD;
    }
#else
  perror_internal (stderr, s, errnum);
#endif
}

--- NEW FILE ---
/* Internal header for parsing printf format strings.
   Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc.
   This file is part of th GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <ctype.h>
#include <limits.h>
#include <printf.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>

#define NDEBUG 1
#include <assert.h>


struct printf_spec
  {
    /* Information parsed from the format spec.  */
    struct printf_info info;

    /* Pointers into the format string for the end of this format
       spec and the next (or to the end of the string if no more).  */
    const UCHAR_T *end_of_fmt, *next_fmt;

    /* Position of arguments for precision and width, or -1 if `info' has
       the constant value.  */
    int prec_arg, width_arg;

    int data_arg;               /* Position of data argument.  */
    int data_arg_type;          /* Type of first argument.  */
    /* Number of arguments consumed by this format specifier.  */
    size_t ndata_args;
  };


/* The various kinds off arguments that can be passed to printf.  */
union __native__ printf_arg
  {
    unsigned char pa_char;
    wchar_t pa_wchar;
    short int pa_short_int;
    int pa_int;
    long int pa_long_int;
    long long int pa_long_long_int;
    unsigned short int pa_u_short_int;
    unsigned int pa_u_int;
    unsigned long int pa_u_long_int;
    unsigned long long int pa_u_long_long_int;
    float pa_float;
    double pa_double;
    long double pa_long_double;
    const char *pa_string;
    const wchar_t *pa_wstring;
    void *pa_pointer;
  };


/* Read a simple integer from a string and update the string pointer.
   It is assumed that the first character is a digit.  */
static unsigned int
read_int (const UCHAR_T * *pstr)
{
  unsigned int retval = **pstr - L_('0');

  while (ISDIGIT (*++(*pstr)))
    {
      retval *= 10;
      retval += **pstr - L_('0');
    }

  return retval;
}



/* Find the next spec in FORMAT, or the end of the string.  Returns
   a pointer into FORMAT, to a '%' or a '\0'.  */
static const UCHAR_T *
#ifdef COMPILE_WPRINTF
find_spec (const UCHAR_T *format)
#else
find_spec (const UCHAR_T *format, mbstate_t *ps)
#endif
{
#ifdef COMPILE_WPRINTF
  return (const UCHAR_T *) __wcschrnul ((const CHAR_T *) format, L'%');
#else
  while (*format != L_('\0') && *format != L_('%'))
    {
      int len;

      /* Remove any hints of a wrong encoding.  */
      ps->__count = 0;
      if (! isascii (*format) && (len = __mbrlen (format, MB_CUR_MAX, ps)) > 0)
        format += len;
      else
        ++format;
    }
  return format;
#endif
}


/* These are defined in reg-printf.c.  */
extern printf_arginfo_function *__printf_arginfo_table[];
extern printf_function **__printf_function_table;


/* FORMAT must point to a '%' at the beginning of a spec.  Fills in *SPEC
   with the parsed details.  POSN is the number of arguments already
   consumed.  At most MAXTYPES - POSN types are filled in TYPES.  Return
   the number of args consumed by this spec; *MAX_REF_ARG is updated so it
   remains the highest argument index used.  */
static size_t
#ifdef COMPILE_WPRINTF
parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
                size_t *max_ref_arg)
#else
parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
                size_t *max_ref_arg, mbstate_t *ps)
#endif
{
  unsigned int n;
  size_t nargs = 0;

  /* Skip the '%'.  */
  ++format;

  /* Clear information structure.  */
  spec->data_arg = -1;
  spec->info.alt = 0;
  spec->info.space = 0;
  spec->info.left = 0;
  spec->info.showsign = 0;
  spec->info.group = 0;
  spec->info.i18n = 0;
  spec->info.pad = ' ';
  spec->info.wide = sizeof (UCHAR_T) > 1;

  /* Test for positional argument.  */
  if (ISDIGIT (*format))
    {
      const UCHAR_T *begin = format;

      n = read_int (&format);

      if (n > 0 && *format == L_('$'))
        /* Is positional parameter.  */
        {
          ++format;             /* Skip the '$'.  */
          spec->data_arg = n - 1;
          *max_ref_arg = MAX (*max_ref_arg, n);
        }
      else
        /* Oops; that was actually the width and/or 0 padding flag.
           Step back and read it again.  */
        format = begin;
    }

  /* Check for spec modifiers.  */
  do
    {
      switch (*format)
        {
        case L_(' '):
          /* Output a space in place of a sign, when there is no sign.  */
          spec->info.space = 1;
          continue;
        case L_('+'):
          /* Always output + or - for numbers.  */
          spec->info.showsign = 1;
          continue;
        case L_('-'):
          /* Left-justify things.  */
          spec->info.left = 1;
          continue;
        case L_('#'):
          /* Use the "alternate form":
             Hex has 0x or 0X, FP always has a decimal point.  */
          spec->info.alt = 1;
          continue;
        case L_('0'):
          /* Pad with 0s.  */
          spec->info.pad = '0';
          continue;
        case L_('\''):
          /* Show grouping in numbers if the locale information
             indicates any.  */
          spec->info.group = 1;
          continue;
        case L_('I'):
          /* Use the internationalized form of the output.  Currently
             means to use the `outdigits' of the current locale.  */
          spec->info.i18n = 1;
          continue;
        default:
          break;
        }
      break;
    }
  while (*++format);

  if (spec->info.left)
    spec->info.pad = ' ';

  /* Get the field width.  */
  spec->width_arg = -1;
  spec->info.width = 0;
  if (*format == L_('*'))
    {
      /* The field width is given in an argument.
         A negative field width indicates left justification.  */
      const UCHAR_T *begin = ++format;

      if (ISDIGIT (*format))
        {
          /* The width argument might be found in a positional parameter.  */
          n = read_int (&format);

          if (n > 0 && *format == L_('$'))
            {
              spec->width_arg = n - 1;
              *max_ref_arg = MAX (*max_ref_arg, n);
              ++format;         /* Skip '$'.  */
            }
        }

      if (spec->width_arg < 0)
        {
          /* Not in a positional parameter.  Consume one argument.  */
          spec->width_arg = posn++;
          ++nargs;
          format = begin;       /* Step back and reread.  */
        }
    }
  else if (ISDIGIT (*format))
    /* Constant width specification.  */
    spec->info.width = read_int (&format);

  /* Get the precision.  */
  spec->prec_arg = -1;
  /* -1 means none given; 0 means explicit 0.  */
  spec->info.prec = -1;
  if (*format == L_('.'))
    {
      ++format;
      if (*format == L_('*'))
        {
          /* The precision is given in an argument.  */
          const UCHAR_T *begin = ++format;

          if (ISDIGIT (*format))
            {
              n = read_int (&format);

              if (n > 0 && *format == L_('$'))
                {
                  spec->prec_arg = n - 1;
                  *max_ref_arg = MAX (*max_ref_arg, n);
                  ++format;
                }
            }

          if (spec->prec_arg < 0)
            {
              /* Not in a positional parameter.  */
              spec->prec_arg = posn++;
              ++nargs;
              format = begin;
            }
        }
      else if (ISDIGIT (*format))
        spec->info.prec = read_int (&format);
      else
        /* "%.?" is treated like "%.0?".  */
        spec->info.prec = 0;
    }

  /* Check for type modifiers.  */
  spec->info.is_long_double = 0;
  spec->info.is_short = 0;
  spec->info.is_long = 0;
  spec->info.is_char = 0;

  switch (*format++)
    {
    case L_('h'):
      /* ints are short ints or chars.  */
      if (*format != L_('h'))
        spec->info.is_short = 1;
      else
        {
          ++format;
          spec->info.is_char = 1;
        }
      break;
    case L_('l'):
      /* ints are long ints.  */
      spec->info.is_long = 1;
      if (*format != L_('l'))
        break;
      ++format;
      /* FALLTHROUGH */
    case L_('L'):
      /* doubles are long doubles, and ints are long long ints.  */
    case L_('q'):
      /* 4.4 uses this for long long.  */
      spec->info.is_long_double = 1;
      break;
    case L_('z'):
    case L_('Z'):
      /* ints are size_ts.  */
      assert (sizeof (size_t) <= sizeof (unsigned long long int));
#if LONG_MAX != LONG_LONG_MAX
      spec->info.is_long_double = sizeof (size_t) > sizeof (unsigned long int);
#endif
      spec->info.is_long = sizeof (size_t) > sizeof (unsigned int);
      break;
    case L_('t'):
      assert (sizeof (ptrdiff_t) <= sizeof (long long int));
#if LONG_MAX != LONG_LONG_MAX
      spec->info.is_long_double = (sizeof (ptrdiff_t) > sizeof (long int));
#endif
      spec->info.is_long = sizeof (ptrdiff_t) > sizeof (int);
      break;
    case L_('j'):
      assert (sizeof (uintmax_t) <= sizeof (unsigned long long int));
#if LONG_MAX != LONG_LONG_MAX
      spec->info.is_long_double = (sizeof (uintmax_t)
                                   > sizeof (unsigned long int));
#endif
      spec->info.is_long = sizeof (uintmax_t) > sizeof (unsigned int);
      break;
    default:
      /* Not a recognized modifier.  Backup.  */
      --format;
      break;
    }

  /* Get the format specification.  */
  spec->info.spec = (wchar_t) *format++;
  if (__printf_function_table != NULL
      && spec->info.spec <= UCHAR_MAX
      && __printf_arginfo_table[spec->info.spec] != NULL)
    /* We don't try to get the types for all arguments if the format
       uses more than one.  The normal case is covered though.  */
    spec->ndata_args = (*__printf_arginfo_table[spec->info.spec])
      (&spec->info, 1, &spec->data_arg_type);
  else
    {
      /* Find the data argument types of a built-in spec.  */
      spec->ndata_args = 1;

      switch (spec->info.spec)
        {
        case L'i':
        case L'd':
        case L'u':
        case L'o':
        case L'X':
        case L'x':
#if LONG_MAX != LONG_LONG_MAX
          if (spec->info.is_long_double)
            spec->data_arg_type = PA_INT|PA_FLAG_LONG_LONG;
          else
#endif
            if (spec->info.is_long)
              spec->data_arg_type = PA_INT|PA_FLAG_LONG;
            else if (spec->info.is_short)
              spec->data_arg_type = PA_INT|PA_FLAG_SHORT;
            else if (spec->info.is_char)
              spec->data_arg_type = PA_CHAR;
            else
              spec->data_arg_type = PA_INT;
          break;
        case L'e':
        case L'E':
        case L'f':
        case L'F':
        case L'g':
        case L'G':
        case L'a':
        case L'A':
          if (spec->info.is_long_double)
            spec->data_arg_type = PA_DOUBLE|PA_FLAG_LONG_DOUBLE;
          else
            spec->data_arg_type = PA_DOUBLE;
          break;
        case L'c':
          spec->data_arg_type = PA_CHAR;
          break;
        case L'C':
          spec->data_arg_type = PA_WCHAR;
          break;
        case L's':
          spec->data_arg_type = PA_STRING;
          break;
        case L'S':
          spec->data_arg_type = PA_WSTRING;
          break;
        case L'p':
          spec->data_arg_type = PA_POINTER;
          break;
        case L'n':
          spec->data_arg_type = PA_INT|PA_FLAG_PTR;
          break;

        case L'm':
        default:
          /* An unknown spec will consume no args.  */
          spec->ndata_args = 0;
          break;
        }
    }

  if (spec->data_arg == -1 && spec->ndata_args > 0)
    {
      /* There are args consumed, but no positional spec.  Use the
         next sequential arg position.  */
      spec->data_arg = posn;
      nargs += spec->ndata_args;
    }

  if (spec->info.spec == L'\0')
    /* Format ended before this spec was complete.  */
    spec->end_of_fmt = spec->next_fmt = format - 1;
  else
    {
      /* Find the next format spec.  */
      spec->end_of_fmt = format;
#ifdef COMPILE_WPRINTF
      spec->next_fmt = find_spec (format);
#else
      spec->next_fmt = find_spec (format, ps);
#endif
    }

  return nargs;
}

--- NEW FILE ---
/* Copyright (C) 1991,1992,1995,1996,1999,2000 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>
#include <printf.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <sys/param.h>

#ifndef COMPILE_WPRINTF
# define CHAR_T         char
# define UCHAR_T        unsigned char
# define INT_T          int
# define L_(Str)        Str
# define ISDIGIT(Ch)    isdigit (Ch)
# define ISASCII(Ch)    isascii (Ch)
# define MBRLEN(Cp, L, St) __mbrlen (Cp, L, St)

# ifdef USE_IN_LIBIO
#  define PUT(F, S, N)  _IO_sputn (F, S, N)
#  define PAD(Padchar)                                                        \
  if (width > 0)                                                              \
    done += _IO_padn (s, Padchar, width)
# else
#  define PUTC(C, F)    putc (C, F)
ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
# define PAD(Padchar)                                                         \
  if (width > 0)                                                              \
    { if (__printf_pad (s, Padchar, width) == -1)                             \
        return -1; else done += width; }
# endif
#else
# define vfprintf       vfwprintf
# define CHAR_T         wchar_t
# define UCHAR_T        uwchar_t
# define INT_T          wint_t
# define L_(Str)        L##Str
# define ISDIGIT(Ch)    iswdigit (Ch)

# ifdef USE_IN_LIBIO
# define PUT(F, S, N)   _IO_sputn (F, S, N)
# define PAD(Padchar)                                                         \
  if (width > 0)                                                              \
    done += _IO_wpadn (s, Padchar, width)
# else
#  define PUTC(C, F)    wputc (C, F)
ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n));
# define PAD(Padchar)                                                         \
  if (width > 0)                                                              \
    { if (__wprintf_pad (s, Padchar, width) == -1)                            \
        return -1; else done += width; }
# endif
#endif

#include "printf-parse.h"


size_t
parse_printf_format (fmt, n, argtypes)
      const char *fmt;
      size_t n;
      int *argtypes;
{
  size_t nargs;                 /* Number of arguments.  */
  size_t max_ref_arg;           /* Highest index used in a positional arg.  */
  struct printf_spec spec;
  mbstate_t mbstate;

  nargs = 0;
  max_ref_arg = 0;

  /* Search for format specifications.  */
  for (fmt = find_spec (fmt, &mbstate); *fmt != '\0'; fmt = spec.next_fmt)
    {
      /* Parse this spec.  */
      nargs += parse_one_spec (fmt, nargs, &spec, &max_ref_arg, &mbstate);

      /* If the width is determined by an argument this is an int.  */
      if (spec.width_arg != -1 && (size_t) spec.width_arg < n)
        argtypes[spec.width_arg] = PA_INT;

      /* If the precision is determined by an argument this is an int.  */
      if (spec.prec_arg != -1 && (size_t) spec.prec_arg < n)
        argtypes[spec.prec_arg] = PA_INT;

      if ((size_t) spec.data_arg < n)
        switch (spec.ndata_args)
          {
          case 0:               /* No arguments.  */
            break;
          case 1:               /* One argument; we already have the type.  */
            argtypes[spec.data_arg] = spec.data_arg_type;
            break;
          default:
            /* We have more than one argument for this format spec.  We must
               call the arginfo function again to determine all the types.  */
            (void) (*__printf_arginfo_table[spec.info.spec])
              (&spec.info, n - spec.data_arg, &argtypes[spec.data_arg]);
            break;
          }
    }

  return MAX (nargs, max_ref_arg);
}

--- NEW FILE ---
/* Copyright (C) 1991-1993,1995-1999,2000,2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#ifndef _PRINTF_H

#define _PRINTF_H       1
#include <features.h>

__BEGIN_DECLS

#define __need_FILE
#include <stdio.h>
#define __need_size_t
#define __need_wchar_t
#include <stddef.h>


struct printf_info
{
  int prec;                     /* Precision.  */
  int width;                    /* Width.  */
  wchar_t 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.  */
  unsigned int extra:1;         /* For special use.  */
  unsigned int is_char:1;       /* hh flag.  */
  unsigned int wide:1;          /* Nonzero for wide character streams.  */
  unsigned int i18n:1;          /* I flag.  */
  wchar_t 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.
   ARGS is a vector of pointers to the argument data;
   the number of pointers will be the number returned
   by the associated arginfo function for the same INFO.

   The function should return the number of characters written,
   or -1 for errors.  */

typedef int printf_function (FILE *__stream,
                             __const struct printf_info *__info,
                             __const void *__const *__args);

/* Type of a printf specifier-arginfo function.
   INFO gives information about the format specification.
   N, ARGTYPES, and return value are as for parse_printf_format.  */

typedef int printf_arginfo_function (__const struct printf_info *__info,
                                     size_t __n, int *__argtypes);


/* Register FUNC to be called to format SPEC specifiers; ARGINFO must be
   specified to determine how many arguments a SPEC conversion requires and
   what their types are.  */

extern int register_printf_function (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 (__const char *__restrict __fmt, size_t __n,
                                   int *__restrict __argtypes) __THROW;


/* 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_WCHAR,                     /* wide char */
  PA_STRING,                    /* const char *, a '\0'-terminated string */
  PA_WSTRING,                   /* const wchar_t *, wide character 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)



/* Function which can be registered as `printf'-handlers.  */

/* Print floating point value using using abbreviations for the orders
   of magnitude used for numbers ('k' for kilo, 'm' for mega etc).  If
   the format specifier is a uppercase character powers of 1000 are
   used.  Otherwise powers of 1024.  */
extern int printf_size (FILE *__restrict __fp,
                        __const struct printf_info *__info,
                        __const void *__const *__restrict __args) __THROW;

/* This is the appropriate argument information function for `printf_size'.  */
extern int printf_size_info (__const struct printf_info *__restrict
                             __info, size_t __n, int *__restrict __argtypes)
     __THROW;


__END_DECLS

#endif /* printf.h  */

--- NEW FILE ---
/* Floating point output for `printf'.
   Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Written by Ulrich Drepper <address@hidden>, 1995.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */
[...1197 lines suppressed...]

      if (*grouping == CHAR_MAX
#if CHAR_MIN < 0
          || *grouping < 0
#endif
          )
        /* No more grouping should be done.  */
        break;
      else if (*grouping == 0)
        /* Same grouping repeats.  */
        --grouping;
    } while (intdig_no > (unsigned int) *grouping);

  /* Copy the remaining ungrouped digits.  */
  do
    *p-- = buf[--intdig_no];
  while (p > buf);

  return bufend + ngroups;
}

--- NEW FILE ---
/* Print size value using units for orders of magnitude.
   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <address@hidden>, 1997.
   Based on a proposal by Larry McVoy <address@hidden>.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <ctype.h>
#include <ieee754.h>
#include <math.h>
#include <printf.h>
#ifdef USE_IN_LIBIO
# include <libioP.h>
#else
# include <stdio.h>
#endif


/* This defines make it possible to use the same code for GNU C library and
   the GNU I/O library.  */
#ifdef USE_IN_LIBIO
# define PUT(f, s, n) _IO_sputn (f, s, n)
# define PAD(f, c, n) (wide ? _IO_wpadn (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) (wide \
                     ? (int)_IO_putwc_unlocked (c, f) : _IO_putc_unlocked (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, wptr, len)                                                 \
  do                                                                          \
    {                                                                         \
      register size_t outlen = (len);                                         \
      if (len > 20)                                                           \
        {                                                                     \
          if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen)   \
            return -1;                                                        \
          ptr += outlen;                                                      \
          done += outlen;                                                     \
        }                                                                     \
      else                                                                    \
        {                                                                     \
          if (wide)                                                           \
            while (outlen-- > 0)                                              \
              outchar (*wptr++);                                              \
          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)

/* Prototype for helper functions.  */
extern int __printf_fp (FILE *fp, const struct printf_info *info,
                        const void *const *args);


int
printf_size (FILE *fp, const struct printf_info *info, const void *const *args)
{
  /* Units for the both formats.  */
#define BINARY_UNITS    " kmgtpezy"
#define DECIMAL_UNITS   " KMGTPEZY"
  static const char units[2][sizeof (BINARY_UNITS)] =
  {
    BINARY_UNITS,       /* For binary format.  */
    DECIMAL_UNITS       /* For decimal format.  */
  };
  const char *tag = units[isupper (info->spec) != 0];
  int divisor = isupper (info->spec) ? 1000 : 1024;

  /* The floating-point value to output.  */
  union __native__
    {
      union ieee754_double dbl;
      union ieee854_long_double ldbl;
    }
  fpnum;
  const void *ptr = &fpnum;

  int negative = 0;

  /* "NaN" or "Inf" for the special cases.  */
  const char *special = NULL;
  const wchar_t *wspecial = NULL;

  struct printf_info fp_info;
  int done = 0;
  int wide = info->wide;


  /* Fetch the argument value.  */
#ifndef __NO_LONG_DOUBLE_MATH
  if (info->is_long_double && sizeof (long double) > sizeof (double))
    {
      fpnum.ldbl.d = *(const long double *) args[0];

      /* Check for special values: not a number or infinity.  */
      if (__isnanl (fpnum.ldbl.d))
        {
          special = "nan";
          wspecial = L"nan";
          negative = 0;
        }
      else if (__isinfl (fpnum.ldbl.d))
        {
          special = "inf";
          wspecial = L"inf";

          negative = fpnum.ldbl.d < 0;
        }
      else
        while (fpnum.ldbl.d >= divisor && tag[1] != '\0')
          {
            fpnum.ldbl.d /= divisor;
            ++tag;
          }
    }
  else
#endif  /* no long double */
    {
      fpnum.dbl.d = *(const double *) args[0];

      /* Check for special values: not a number or infinity.  */
      if (__isnan (fpnum.dbl.d))
        {
          special = "nan";
          wspecial = L"nan";
          negative = 0;
        }
      else if (__isinf (fpnum.dbl.d))
        {
          special = "inf";
          wspecial = L"inf";

          negative = fpnum.dbl.d < 0;
        }
      else
        while (fpnum.dbl.d >= divisor && tag[1] != '\0')
          {
            fpnum.dbl.d /= divisor;
            ++tag;
          }
    }

  if (special)
    {
      int width = 0;
      width = info->prec > width ? info->prec : width;

      if (negative || info->showsign || info->space)
        --width;
      width -= 3;

      if (!info->left && width > 0)
        PADN (' ', width);

      if (negative)
        outchar ('-');
      else if (info->showsign)
        outchar ('+');
      else if (info->space)
        outchar (' ');

      PRINT (special, wspecial, 3);

      if (info->left && width > 0)
        PADN (' ', width);

      return done;
    }

  /* Prepare to print the number.  We want to use `__printf_fp' so we
     have to prepare a `printf_info' structure.  */
  fp_info.spec = 'f';
  fp_info.prec = info->prec < 0 ? 3 : info->prec;
  fp_info.is_long_double = info->is_long_double;
  fp_info.is_short = info->is_short;
  fp_info.is_long = info->is_long;
  fp_info.alt = info->alt;
  fp_info.space = info->space;
  fp_info.left = info->left;
  fp_info.showsign = info->showsign;
  fp_info.group = info->group;
  fp_info.extra = info->extra;
  fp_info.pad = info->pad;
  fp_info.wide = wide;

  if (fp_info.left && fp_info.pad == L' ')
    {
      /* We must do the padding ourself since the unit character must
         be placed before the padding spaces.  */
      fp_info.width = 0;

      done = __printf_fp (fp, &fp_info, &ptr);
      if (done > 0)
        {
          outchar (*tag);
          if (info->width > done)
            PADN (' ', info->width - done);
        }
    }
  else
    {
      /* We can let __printf_fp do all the printing and just add our
         unit character afterwards.  */
      fp_info.width = info->width - 1;

      done = __printf_fp (fp, &fp_info, &ptr);
      if (done > 0)
        outchar (*tag);
    }

  return done;
}

/* This is the function used by `vfprintf' to determine number and
   type of the arguments.  */
int
printf_size_info (const struct printf_info *info, size_t n, int *argtypes)
{
  /* We need only one double or long double argument.  */
  if (n >= 1)
    argtypes[0] = PA_DOUBLE | (info->is_long_double ? PA_FLAG_LONG_DOUBLE : 0);

  return 1;
}

--- NEW FILE ---
/* Copyright (C) 1991,1992,1995,1996,1997,2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <libintl.h>
#ifdef USE_IN_LIBIO
# include <wchar.h>
#endif


#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
psignal (int sig, const char *s)
{
  const char *colon, *desc;

  if (s == NULL || s == '\0')
    s = colon = "";
  else
    colon = ": ";

  if (sig >= 0 && sig < NSIG && (desc = _sys_siglist[sig]) != NULL)
    {
#ifdef USE_IN_LIBIO
      if (_IO_fwide (stderr, 0) > 0)
        (void) __fwprintf (stderr, L"%s%s%s\n", s, colon, _(desc));
      else
#endif
        (void) fprintf (stderr, "%s%s%s\n", s, colon, _(desc));
    }
  else
    {
      char *buf;

      (void) __asprintf (&buf, _("%s%sUnknown signal %d\n"), s, colon, sig);

#ifdef USE_IN_LIBIO
      if (_IO_fwide (stderr, 0) > 0)
        (void) __fwprintf (stderr, L"%s",  buf);
      else
#endif
        (void) fputs (buf, stderr);

      free (buf);
    }
}

--- NEW FILE ---
#include <stdio.h>
#undef  putc
#define fputc   putc
#define fputc_unlocked  putc_unlocked
#include <fputc.c>
weak_alias (putc, putc_unlocked)

--- NEW FILE ---
/* Copyright (C) 1991, 1997, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>

#undef  putchar


/* Write the character C on stdout.  */
int
putchar (int c)
{
  return __putc (c, stdout);
}

weak_alias (putchar, putchar_unlocked)

--- NEW FILE ---
/* Copyright (C) 1991, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stddef.h>
#include <stdio.h>
#include <string.h>

#undef  puts


/* Write the string in S and a newline to stdout.  */
int
puts (const char *s)
{
  return fputs (s, stdout) || putchar ('\n') == EOF ? EOF : 0;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1997, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>

#ifdef USE_IN_LIBIO
# include <libio/iolibio.h>
# define fwrite(p, n, m, s) _IO_fwrite (p, n, m, s)
#endif

/* Write the word (int) W to STREAM.  */
int
putw (int w, FILE *stream)
{
  /* Is there a better way?  */
  if (fwrite ((const void *) &w, sizeof (w), 1, stream) < 1)
    return EOF;
  return 0;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>

#undef  rewind


/* Rewind STREAM to the beginning of the
   file and clear its error and EOF flags.  */
void
rewind (FILE *stream)
{
  clearerr (stream);
  (void) fseek (stream, 0L, SEEK_SET);
  clearerr (stream);
}

--- NEW FILE ---
/* Copyright (C) 1991, 1995, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdarg.h>
#include <stdio.h>


/* Read formatted input from stdin according to the format string FORMAT.  */
/* VARARGS1 */
int
scanf (const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
#ifdef USE_IN_LIBIO
  done = _IO_vfscanf (stdin, format, arg, NULL);
#else
  done = vfscanf (stdin, format, arg);
#endif
  va_end (arg);

  return done;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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
setbuf (FILE *stream, char *buf)
{
  (void) setvbuf (stream, buf, buf != NULL ? _IOFBF : _IONBF, BUFSIZ);
}

--- NEW FILE ---
/* Copyright (C) 1991, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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
setbuffer (FILE *stream, char *buf, size_t n)
{
  (void) setvbuf (stream, buf, buf != NULL ? _IOFBF : _IONBF, n);
}

--- NEW FILE ---
/* Copyright (C) 1991, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>


/* Make STREAM line buffered.  */
void
setlinebuf (FILE *stream)
{
  if (stream->__buffer != NULL || !stream->__userbuf)
    stream->__linebuf = 1;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1993, 1995, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.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
setvbuf (stream, buf, mode, size)
     FILE *stream;
     char *buf;
     int mode;
     size_t size;
{
  if (!__validfp (stream))
    {
      __set_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:
      __set_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)
        {
          __set_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;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1995, 1997, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdarg.h>
#include <stdio.h>

#ifdef USE_IN_LIBIO
# include <libio/libioP.h>
# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
#endif

/* Write formatted output into S, according to the format
   string FORMAT, writing no more than MAXLEN characters.  */
/* VARARGS3 */
int
__snprintf (char *s, size_t maxlen, const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = __vsnprintf (s, maxlen, format, arg);
  va_end (arg);

  return done;
}
weak_alias (__snprintf, snprintf)

--- NEW FILE ---
/* Copyright (C) 1991, 1995, 1997, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdarg.h>
#include <stdio.h>

#ifdef USE_IN_LIBIO
# include <libio/iolibio.h>
# define vsprintf(s, f, a) _IO_vsprintf (s, f, a)
#endif

/* Write formatted output into S, according to the format string FORMAT.  */
/* VARARGS2 */
int
sprintf (char *s, const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = vsprintf (s, format, arg);
  va_end (arg);

  return done;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1995, 1996, 1998 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdarg.h>
#include <stdio.h>

#ifdef USE_IN_LIBIO
# include <libio/iolibio.h>
# define __vsscanf(s, f, a) _IO_vsscanf (s, f, a)
#endif

/* Read formatted input from S, according to the format string FORMAT.  */
/* VARARGS2 */
int
sscanf (const char *s, const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = __vsscanf (s, format, arg);
  va_end (arg);

  return done;
}

#ifdef USE_IN_LIBIO
# undef _IO_sscanf
/* This is for libg++.  */
strong_alias (sscanf, _IO_sscanf)
#endif

--- NEW FILE ---
/* Copyright (C) 1991, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>

/* Initialize STREAM as necessary.
   This may change I/O functions, give a buffer, etc.
   If no buffer is allocated, but the bufsize is set,
   the bufsize will be used to allocate the buffer.  */
void
__stdio_init_stream (stream)
     FILE *stream;
{
  stream->__bufsize = BUFSIZ;
}

--- NEW FILE ---
/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

extern int __open(const char *__path, int __flags, ...);
extern int __close(int __fd);
extern ssize_t __read(int __fd, void *__buf, size_t __count);
extern ssize_t __write(int __fd, const void *__buf, size_t __count);
extern off_t __lseek(int __fd, off_t __offset, int __whence);
extern int __dup2(int __oldfd, int __newfd);

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;

/* Read N bytes into BUF from COOKIE.  */
int
__stdio_read (void *cookie, char *buf, size_t n)
{
  const int fd = (int) cookie;
#if defined EINTR && defined EINTR_REPEAT
  int save = errno;
  int nread;

 try:;
  __set_errno (0);
  nread = __read (fd, buf, (int) n);
  if (nread < 0)
    {
      if (errno == EINTR)
        goto try;
      return -1;
    }
  __set_errno (save);
  return nread;

#else   /* No EINTR.  */
  return __read (fd, buf, n);
#endif
}


/* Write N bytes from BUF to COOKIE.  */
int
__stdio_write (void *cookie, const char *buf, size_t n)
{
  const int fd = (int) cookie;
  register size_t written = 0;

  while (n > 0)
    {
      int count = __write (fd, buf, (int) n);
      if (count > 0)
        {
          buf += count;
          written += count;
          n -= count;
        }
      else if (count < 0
#if defined EINTR && defined EINTR_REPEAT
               && errno != EINTR
#endif
               )
        /* Write error.  */
        return -1;
    }

  return (int) written;
}


/* Move COOKIE's file position *POS bytes, according to WHENCE.
   The new file position is stored in *POS.
   Returns zero if successful, nonzero if not.  */
int
__stdio_seek (void *cookie, fpos_t *pos, int whence)
{
  off_t new;
  new = __lseek ((int) cookie, (off_t) *pos, whence);
  if (new < 0)
    return 1;
  *pos = (fpos_t) new;
  return 0;
}


/* Close COOKIE.  */
int
__stdio_close (void *cookie)
{
  return __close ((int) cookie);
}

/* Return the POSIX.1 file descriptor associated with COOKIE,
   or -1 for errors.  If COOKIE does not relate to any POSIX.1 file
   descriptor, this should return -1 with errno set to EOPNOTSUPP.  */
int
__stdio_fileno (void *cookie)
{
  return (int) cookie;
}


/* Open the given file with the mode given in the __io_mode argument.  */
int
__stdio_open (const char *filename, __io_mode m, void **cookieptr)
{
  int fd;
  int mode;

  if (m.__read && m.__write)
    mode = O_RDWR;
  else
    mode = m.__read ? O_RDONLY : O_WRONLY;

  if (m.__append)
    mode |= O_APPEND;
  if (m.__exclusive)
    mode |= O_EXCL;
  if (m.__truncate)
    mode |= O_TRUNC;

  if (m.__create)
    fd = __open (filename, mode | O_CREAT,
                 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
  else
    fd = __open (filename, mode);

  if (fd < 0)
    return -1;

  *cookieptr = (void *) fd;
  return 0;
}


/* Open FILENAME with the mode in M.  Use the same magic cookie
   already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN.  */
int
__stdio_reopen (const char *filename, __io_mode m, void **cookieptr,
                __io_close_fn *closefn)
{
  void *newcookie;

  /* We leave the old descriptor open while we open the file.
     That way ``freopen ("/dev/stdin", "r", stdin)'' works.  */

  if (__stdio_open (filename, m, &newcookie))
    {
      if (errno == ENFILE || errno == EMFILE)
        {
          /* We are out of file descriptors.  Try closing the old one and
             retrying the open.  */
          (void) (*closefn) (*cookieptr);
          if (__stdio_open (filename, m, &newcookie))
            return -1;
        }
      else
        return -1;
    }

  if (newcookie != *cookieptr)
    {
      if (closefn != __stdio_close ||
          /* Try to move the descriptor to the desired one.  */
          __dup2 ((int) newcookie, (int) *cookieptr) < 0)
        /* Didn't work.  Give the caller the new cookie.  */
        *cookieptr = newcookie;
    }

  return 0;
}

--- NEW FILE ---
/* Copyright (C) 1991,1993,1996-1999,2000 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.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 *
tempnam (const char *dir, const char *pfx)
{
  char buf[FILENAME_MAX];

  if (__path_search (buf, FILENAME_MAX, dir, pfx, 1))
    return NULL;

  if (__gen_tempname (buf, __GT_NOCREATE))
    return NULL;

  return __strdup (buf);
}

link_warning (tempnam,
              "the use of `tempnam' is dangerous, better use `mkstemp'")

--- NEW FILE ---
/* Copyright (C) 1991,1993,1996,1997,1998,1999 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>
#include <unistd.h>

#ifdef USE_IN_LIBIO
# include <iolibio.h>
# define __fdopen _IO_fdopen
#endif

/* 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 *
tmpfile64 ()
{
  char buf[FILENAME_MAX];
  int fd;
  FILE *f;

  if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
    return NULL;
  fd = __gen_tempname (buf, __GT_BIGFILE);
  if (fd < 0)
    return NULL;

  /* Note that this relies on the Unix semantics that
     a file is not really removed until it is closed.  */
  (void) remove (buf);

  if ((f = __fdopen (fd, "w+b")) == NULL)
    __close (fd);

  return f;
}

--- NEW FILE ---
/* Copyright (C) 1991,1993,1996-1999,2000 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>
#include <string.h>

static char tmpnam_buffer[L_tmpnam];

/* Generate a unique filename in P_tmpdir.

   This function is *not* thread safe!  */
char *
tmpnam (char *s)
{
  /* By using two buffers we manage to be thread safe in the case
     where S != NULL.  */
  char tmpbufmem[L_tmpnam];
  char *tmpbuf = s ?: tmpbufmem;

  /* In the following call we use the buffer pointed to by S if
     non-NULL although we don't know the size.  But we limit the size
     to L_tmpnam characters in any case.  */
  if (__builtin_expect (__path_search (tmpbuf, L_tmpnam, NULL, NULL, 0),
                        0))
    return NULL;

  if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE), 0))
    return NULL;

  if (s == NULL)
    return (char *) memcpy (tmpnam_buffer, tmpbuf, L_tmpnam);

  return s;
}

link_warning (tmpnam,
              "the use of `tmpnam' is dangerous, better use `mkstemp'")

--- NEW FILE ---
/* Copyright (C) 1991,1993,1996-1999,2000 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stdio.h>

/* Generate a unique filename in P_tmpdir.  If S is NULL return NULL.
   This makes this function thread safe.  */
char *
tmpnam_r (char *s)
{
  if (s == NULL)
    return NULL;

  if (__path_search (s, L_tmpnam, NULL, NULL, 0))
    return NULL;
  if (__gen_tempname (s, __GT_NOCREATE))
    return NULL;

  return s;
}

link_warning (tmpnam_r,
              "the use of `tmpnam_r' is dangerous, better use `mkstemp'")

--- NEW FILE ---
/* Copyright (C) 1991, 1993, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdio.h>


/* Push the character C back onto the input stream of STREAM.  */
int
ungetc (c, stream)
     int c;
     FILE *stream;
{
  if (!__validfp (stream) || !stream->__mode.__read)
    {
      __set_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;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>



/* Enlarge STREAM's buffer.  */
static void
enlarge_buffer (FILE *stream, int c)
{
  ptrdiff_t bufp_offset = stream->__bufp - stream->__buffer;
  char *newbuf;

  stream->__bufsize += 100;
  newbuf = (char *) realloc ((void *) stream->__buffer, stream->__bufsize);
  if (newbuf == NULL)
    {
      free ((void *) 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
vasprintf (char **string_ptr,
           const char *format,
           va_list args)
{
  FILE f;
  int done;

  memset ((void *) &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;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1993, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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
vdprintf (int d, const char *format, va_list arg)
{
  int done;
  FILE f;

  /* Create an unbuffered stream talking to D on the stack.  */
  memset ((void *) &f, 0, sizeof(f));
  f.__magic = _IOMAGIC;
  f.__mode.__write = 1;
  f.__cookie = (void *) (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;
}

--- NEW FILE ---
#include <stdio.h>

int
vfprintf (FILE *s, const char *format, va_list ap)
{
  return 0;
}

/* FIXME */

#if 0
/* Copyright (C) 1991-1999, 2000, 2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

[...2178 lines suppressed...]
strong_alias (_IO_vfwprintf, __vfwprintf);
weak_alias (_IO_vfwprintf, vfwprintf);
#  else
strong_alias (_IO_vfprintf, vfprintf);
#  endif
# else
#  if defined __ELF__ || defined __GNU_LIBRARY__
#   include <gnu-stabs.h>
#   ifdef weak_alias
#    ifdef COMPILE_WPRINTF
weak_alias (_IO_vfwprintf, vfwprintf);
#    else
weak_alias (_IO_vfprintf, vfprintf);
#    endif
#   endif
#  endif
# endif
#endif

#endif

--- NEW FILE ---
/* Copyright (C) 1991-1999, 2000, 2001 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <assert.h>
[...2408 lines suppressed...]
# ifdef COMPILE_WSCANF
int
__vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
{
  return _IO_vfwscanf (s, format, argptr, NULL);
}
# else
int
__vfscanf (FILE *s, const char *format, va_list argptr)
{
  return _IO_vfscanf (s, format, argptr, NULL);
}
# endif
#endif

#ifdef COMPILE_WSCANF
weak_alias (__vfwscanf, vfwscanf)
#else
weak_alias (__vfscanf, vfscanf)
#endif

--- NEW FILE ---
/* Copyright (C) 1991, 1993, 1995, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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
vprintf (format, arg)
     const char *format;
     __gnuc_va_list arg;
{
  return vfprintf (stdout, format, arg);
}

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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
__vscanf (const char *format, va_list arg)
{
  return vfscanf (stdin, format, arg);
}
weak_alias (__vscanf, vscanf)

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1995, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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
__vsnprintf (char *s, size_t maxlen, const char *format, va_list arg)
{
  int done;
  FILE f;

  /* We have to handle the case of MAXLEN == 0 special.  */
  if (maxlen == 0)
    return 0;

  memset ((void *) &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;
}
weak_alias (__vsnprintf, vsnprintf)

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#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
vsprintf (s, format, arg)
     char *s;
     const char *format;
     va_list arg;
{
  int done;
  FILE f;

  memset ((void *) &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;
}

--- NEW FILE ---
/* Copyright (C) 1991, 1992, 1995, 1996, 1997 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 Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#undef  vsscanf


/* Read formatted input from S according to the format
   string FORMAT, using the argument list in ARG.  */
int
__vsscanf (s, format, arg)
     const char *s;
     const char *format;
     va_list arg;
{
  FILE f;

  if (s == NULL)
    {
      __set_errno (EINVAL);
      return -1;
    }

  memset ((void *) &f, 0, sizeof (f));
  f.__magic = _IOMAGIC;
  f.__mode.__read = 1;
  f.__bufp = f.__buffer = (char *) s;
  f.__bufsize = strlen(s);
  f.__get_limit = f.__buffer + f.__bufsize;
  f.__put_limit = f.__buffer;
  /* After the buffer is empty (strlen(S) characters have been read),
     any more read attempts will get EOF.  */
  f.__room_funcs.__input = NULL;
  f.__seen = 1;

  return __vfscanf (&f, format, arg);
}


weak_alias (__vsscanf, vsscanf)

Index: Makefile.am
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetC/libc/stdio/Makefile.am,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** Makefile.am 16 Aug 2002 03:19:44 -0000      1.1.1.1
--- Makefile.am 28 Jun 2003 09:53:37 -0000      1.2
***************
*** 3,8 ****
  noinst_LIBRARIES = libCStdio.a
  
! libCStdio_a_SOURCES = printf.c
  
  AM_CFLAGS = -I$(top_srcdir)/include \
                        -imacros $(top_srcdir)/include/libc-symbols.h
--- 3,102 ----
  noinst_LIBRARIES = libCStdio.a
  
! libCStdio_a_SOURCES = \
!       asprintf.c \
!       clearerr.c \
!       defs.c \
!       dprintf.c \
!       __fbufsize.c \
!       fcloseall.c \
!       fclose.c \
!       feof.c \
!       ferror.c \
!       fflush.c \
!       fgetc.c \
!       fgetpos.c \
!       fgets.c \
!       fileno.c \
!       __flbf.c \
!       fmemopen.c \
!       fopen.c \
!       fopncook.c \
!       __fpending.c \
!       fprintf.c \
!       __fpurge.c \
!       fputc.c \
!       fputs.c \
!       __freadable.c \
!       fread.c \
!       __freading.c \
!       freopen.c \
!       fseek.c \
!       __fsetlocking.c \
!       fsetpos.c \
!       ftell.c \
!       __fwritable.c \
!       fwrite.c \
!       __fwriting.c \
!       getc.c \
!       getchar.c \
!       getdelim.c \
!       getline.c \
!       gets.c \
!       getw.c \
!       internals.c \
!       linewrap.c \
!       memstream.c \
!       newstream.c \
!       printf.c \
!       putc.c \
!       putchar.c \
!       puts.c \
!       putw.c \
!       rewind.c \
!       setbuf.c \
!       setbuffer.c \
!       setlinebuf.c \
!       setvbuf.c \
!       snprintf.c \
!       sprintf.c \
!       stdio_init.c \
!       sysd-stdio.c \
!       ungetc.c \
!       vasprintf.c \
!       vdprintf.c \
!       vfprintf.c \
!       vprintf.c \
!       vsnprintf.c \
!       vsprintf.c \
!       _i18n_number.h \
!       _itoa.h \
!       _itowa.h \
!       linewrap.h \
!       printf.h \
!       printf-parse.h
! 
! ## Files are that are still TODO
! ##            fscanf.c
! ##            _itoa.c
! ##            itoa-digits.c
! ##            itoa-udigits.c
! ##            _itowa.c
! ##            itowa-digits.c
! ##            perror.c
! ##            printf_fp.c
! ##            printf-prs.c
! ##            printf_size.c
! ##            psignal.c
! ##            scanf.c
! ##            sscanf.c
! ##            tempnam.c
! ##            tmpfile64.c
! ##            tmpnam.c
! ##            tmpnam_r.c
! ##            vfscanf.c
! ##            vscanf.c
! ##            vsscanf.c
  
  AM_CFLAGS = -I$(top_srcdir)/include \
+                       -I$(top_srcdir)/libc \
                        -imacros $(top_srcdir)/include/libc-symbols.h





reply via email to

[Prev in Thread] Current Thread [Next in Thread]