Source-Changes-HG archive

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

[src/trunk]: src/lib/libc/stdio Change a while () {} into a do {} while() so ...



details:   https://anonhg.NetBSD.org/src/rev/32ad978509b8
branches:  trunk
changeset: 748141:32ad978509b8
user:      dsl <dsl%NetBSD.org@localhost>
date:      Wed Oct 14 21:25:52 2009 +0000

description:
Change a while () {} into a do {} while() so that fgets(buf, 1, file)
detects EOF on an empty file.
Fixes most of PR/41992

diffstat:

 lib/libc/stdio/fgets.c    |     8 +-
 lib/libc/stdio/vfprintf.c |  1181 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1185 insertions(+), 4 deletions(-)

diffs (truncated from 1223 to 300 lines):

diff -r c75e70b66b36 -r 32ad978509b8 lib/libc/stdio/fgets.c
--- a/lib/libc/stdio/fgets.c    Wed Oct 14 20:54:51 2009 +0000
+++ b/lib/libc/stdio/fgets.c    Wed Oct 14 21:25:52 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fgets.c,v 1.22 2009/02/05 03:22:37 lukem Exp $ */
+/*     $NetBSD: fgets.c,v 1.23 2009/10/14 21:25:52 dsl Exp $   */
 
 /*-
  * Copyright (c) 1990, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)fgets.c    8.2 (Berkeley) 12/22/93";
 #else
-__RCSID("$NetBSD: fgets.c,v 1.22 2009/02/05 03:22:37 lukem Exp $");
+__RCSID("$NetBSD: fgets.c,v 1.23 2009/10/14 21:25:52 dsl Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -74,7 +74,7 @@
        _SET_ORIENTATION(fp, -1);
        s = buf;
        n--;                    /* leave space for NUL */
-       while (n != 0) {
+       do {
                /*
                 * If the buffer is empty, refill it.
                 */
@@ -114,7 +114,7 @@
                (void)memcpy((void *)s, (void *)p, len);
                s += len;
                n -= len;
-       }
+       } while (n != 0);
        *s = 0;
        FUNLOCKFILE(fp);
        return (buf);
diff -r c75e70b66b36 -r 32ad978509b8 lib/libc/stdio/vfprintf.c
--- a/lib/libc/stdio/vfprintf.c Wed Oct 14 20:54:51 2009 +0000
+++ b/lib/libc/stdio/vfprintf.c Wed Oct 14 21:25:52 2009 +0000
@@ -1,2 +1,1183 @@
+#if 0
+/* Contains my POSITIONAL_PARAMS code */
+/*     $NetBSD: vfprintf.c,v 1.58 2009/10/14 21:25:52 dsl Exp $        */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char *sccsid = "@(#)vfprintf.c  5.50 (Berkeley) 12/16/92";
+#else
+__RCSID("$NetBSD: vfprintf.c,v 1.58 2009/10/14 21:25:52 dsl Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Actual printf innards.
+ *
+ * This code is large and complicated...
+ */
+
+#include "namespace.h"
+#include <sys/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include "reentrant.h"
+#include "local.h"
+#include "fvwrite.h"
+#include "extern.h"
+
+#ifdef FLOATING_POINT
+#define POSITIONAL_PARAMS
+#endif
+
+static int __sprint __P((FILE *, struct __suio *));
+static int __sbprintf __P((FILE *, const char *, va_list)) 
+     __attribute__((__format__(__printf__, 2, 0)));
+#ifdef POSITIONAL_PARAMS
+#define NL_ARGMAX      9       /* minimum required by IEEE Std 1003.1-2001 */
+
+union parg {
+       int             flags;
+       uintmax_t       _uintmax;
+       void            *_pointer;
+       double          _double;
+};
+static void set_printf_args(union parg *, const char *, _BSD_VA_LIST_);
+#endif
+
+/*
+ * Flush out all the vectors defined by the given uio,
+ * then reset it so that it can be reused.
+ */
+/* NB: async-signal-safe when fp->_flags & __SAFE */
+static int
+__sprint(fp, uio)
+       FILE *fp;
+       struct __suio *uio;
+{
+       int err;
+
+       _DIAGASSERT(fp != NULL);
+       _DIAGASSERT(uio != NULL);
+
+       if (uio->uio_resid == 0) {
+               uio->uio_iovcnt = 0;
+               return (0);
+       }
+       err = __sfvwrite(fp, uio);
+       uio->uio_resid = 0;
+       uio->uio_iovcnt = 0;
+       return (err);
+}
+
+/*
+ * Helper function for `fprintf to unbuffered unix file': creates a
+ * temporary buffer.  We only work on write-only files; this avoids
+ * worries about ungetc buffers and so forth.
+ */
+static int
+__sbprintf(fp, fmt, ap)
+       FILE *fp;
+       const char *fmt;
+       va_list ap;
+{
+       int ret;
+       FILE fake;
+       struct __sfileext fakeext;
+       unsigned char buf[BUFSIZ];
+
+       _DIAGASSERT(fp != NULL);
+       _DIAGASSERT(fmt != NULL);
+
+       _FILEEXT_SETUP(&fake, &fakeext);
+
+       /* copy the important variables */
+       fake._flags = fp->_flags & ~__SNBF;
+       fake._file = fp->_file;
+       fake._cookie = fp->_cookie;
+       fake._write = fp->_write;
+
+       /* set up the buffer */
+       fake._bf._base = fake._p = buf;
+       fake._bf._size = fake._w = sizeof(buf);
+       fake._lbfsize = 0;      /* not actually used, but Just In Case */
+
+       /* do the work, then copy any error status */
+       ret = vfprintf(&fake, fmt, ap);
+       if (ret >= 0 && fflush(&fake))
+               ret = -1;
+       if (fake._flags & __SERR)
+               fp->_flags |= __SERR;
+       return (ret);
+}
+
+
+#ifndef NO_FLOATING_POINT
+#include <locale.h>
+#include <math.h>
+#include "floatio.h"
+
+#define        BUF             (MAXEXP+MAXFRACT+1)     /* + decimal point */
+#define        DEFPREC         6
+
+static char *cvt __P((double, int, int, char *, int *, int, int *));
+static int exponent __P((char *, int, int));
+
+#else /* FLOATING_POINT */
+
+#define        BUF             40
+
+#endif /* NO_FLOATING_POINT */
+
+/*
+ * Macros for converting digits to letters and vice versa
+ */
+#define        to_digit(c)     ((c) - '0')
+#define is_digit(c)    ((unsigned)to_digit(c) <= 9)
+#define        to_char(n)      ((char)((n) + '0'))
+
+/*
+ * Flags used during conversion.
+ */
+#define        ALT             0x001           /* alternate form */
+#define        HEXPREFIX       0x002           /* add 0x or 0X prefix */
+#define        LADJUST         0x004           /* left adjustment */
+#define        LONGDBL         0x008           /* long double; unimplemented */
+#define        LONGINT         0x010           /* long integer */
+#define        QUADINT         0x020           /* quad integer */
+#define        SHORTINT        0x040           /* short integer */
+#define        MAXINT          0x080           /* (unsigned) intmax_t */
+#define        PTRINT          0x100           /* (unsigned) ptrdiff_t */
+#define        SIZEINT         0x200           /* (signed) size_t */
+#define        ZEROPAD         0x400           /* zero (as opposed to blank) pad */
+#define FPT            0x800           /* Floating point number */
+#ifdef POSITIONAL_PARAMS
+#define POINTER                0x10000         /* Pointer to something */
+#define SIGNED         0x20000         /* signed value */
+#define CHARINT                0x40000         /* move above when %hhd implemented */
+#endif
+
+int
+vfprintf(fp, fmt0, ap)
+       FILE *fp;
+       const char *fmt0;
+       _BSD_VA_LIST_ ap;
+{
+       int ret;
+
+       FLOCKFILE(fp);
+       ret = __vfprintf_unlocked(fp, fmt0, ap);
+       FUNLOCKFILE(fp);
+
+       return ret;
+}
+       
+           
+
+/* NB: async-signal-safe when fp->_flags & __SAFE */
+int
+__vfprintf_unlocked(fp, fmt0, ap)
+       FILE *fp;
+       const char *fmt0;
+       _BSD_VA_LIST_ ap;
+{
+       const char *fmt;/* format string */
+       int ch; /* character from fmt */
+       int n, m;       /* handy integers (short term usage) */
+       const char *cp; /* handy char pointer (short term usage) */
+       char *bp;       /* handy char pointer (short term usage) */
+       struct __siov *iovp;/* for PRINT macro */
+       int flags;      /* flags as above */
+       int ret;                /* return value accumulator */
+       int width;              /* width from format (%8d), or 0 */
+       int prec;               /* precision from format (%.3d), or -1 */
+       char sign;              /* sign prefix (' ', '+', '-', or \0) */
+       wchar_t wc;
+       mbstate_t ps;
+#ifndef NO_FLOATING_POINT
+       char *decimal_point = NULL;
+       char softsign;          /* temporary negative sign for floats */
+       double _double;         /* double precision arguments %[eEfgG] */
+       int expt;               /* integer value of exponent */
+       int expsize = 0;        /* character count for expstr */
+       int ndig;               /* actual number of digits returned by cvt */
+       char expstr[7];         /* buffer for exponent string */
+       char *dtoaresult = NULL;
+#endif
+
+#ifdef __GNUC__                        /* gcc has builtin quad type (long long) SOS */
+#define        quad_t    long long
+#define        u_quad_t  unsigned long long
+#endif
+
+#define        INTMAX_T        intmax_t
+#define        UINTMAX_T       uintmax_t
+
+       UINTMAX_T _uintmax;     /* integer arguments %[diouxX] */
+       enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
+       int dprec;              /* a copy of prec if [diouxX], 0 otherwise */
+       int realsz;             /* field size expanded by dprec */



Home | Main Index | Thread Index | Old Index