svn commit: r187284 - head/lib/libc/stdio

David Schultz das at FreeBSD.org
Wed Jan 14 20:49:44 PST 2009


Author: das
Date: Thu Jan 15 04:49:43 2009
New Revision: 187284
URL: http://svn.freebsd.org/changeset/base/187284

Log:
  Reduce code duplication by moving functions that are identical in both
  vfprintf.c and vfwprintf.c (except for char/wchar_t differences) to a
  common header file.

Modified:
  head/lib/libc/stdio/printfcommon.h
  head/lib/libc/stdio/vfprintf.c
  head/lib/libc/stdio/vfwprintf.c

Modified: head/lib/libc/stdio/printfcommon.h
==============================================================================
--- head/lib/libc/stdio/printfcommon.h	Thu Jan 15 04:49:40 2009	(r187283)
+++ head/lib/libc/stdio/printfcommon.h	Thu Jan 15 04:49:43 2009	(r187284)
@@ -37,6 +37,28 @@
  * You must define CHAR to either char or wchar_t prior to including this.
  */
 
+
+#ifndef NO_FLOATING_POINT
+
+#define	dtoa		__dtoa
+#define	freedtoa	__freedtoa
+
+#include <float.h>
+#include <math.h>
+#include "floatio.h"
+#include "gdtoa.h"
+
+#define	DEFPREC		6
+
+static int exponent(CHAR *, int, CHAR);
+
+#endif /* !NO_FLOATING_POINT */
+
+static CHAR	*__ujtoa(uintmax_t, CHAR *, int, int, const char *, int, char,
+		    const char *);
+static CHAR	*__ultoa(u_long, CHAR *, int, int, const char *, int, char,
+		    const char *);
+
 #define NIOV 8
 struct io_state {
 	FILE *fp;
@@ -128,3 +150,197 @@ io_flush(struct io_state *iop)
 	iop->iovp = iop->iov;
 	return (__sprint(iop->fp, &iop->uio));
 }
+
+/*
+ * Convert an unsigned long to ASCII for printf purposes, returning
+ * a pointer to the first character of the string representation.
+ * Octal numbers can be forced to have a leading zero; hex numbers
+ * use the given digits.
+ */
+static CHAR *
+__ultoa(u_long val, CHAR *endp, int base, int octzero, const char *xdigs,
+	int needgrp, char thousep, const char *grp)
+{
+	CHAR *cp = endp;
+	long sval;
+	int ndig;
+
+	/*
+	 * Handle the three cases separately, in the hope of getting
+	 * better/faster code.
+	 */
+	switch (base) {
+	case 10:
+		if (val < 10) {	/* many numbers are 1 digit */
+			*--cp = to_char(val);
+			return (cp);
+		}
+		ndig = 0;
+		/*
+		 * On many machines, unsigned arithmetic is harder than
+		 * signed arithmetic, so we do at most one unsigned mod and
+		 * divide; this is sufficient to reduce the range of
+		 * the incoming value to where signed arithmetic works.
+		 */
+		if (val > LONG_MAX) {
+			*--cp = to_char(val % 10);
+			ndig++;
+			sval = val / 10;
+		} else
+			sval = val;
+		do {
+			*--cp = to_char(sval % 10);
+			ndig++;
+			/*
+			 * If (*grp == CHAR_MAX) then no more grouping
+			 * should be performed.
+			 */
+			if (needgrp && ndig == *grp && *grp != CHAR_MAX
+					&& sval > 9) {
+				*--cp = thousep;
+				ndig = 0;
+				/*
+				 * If (*(grp+1) == '\0') then we have to
+				 * use *grp character (last grouping rule)
+				 * for all next cases
+				 */
+				if (*(grp+1) != '\0')
+					grp++;
+			}
+			sval /= 10;
+		} while (sval != 0);
+		break;
+
+	case 8:
+		do {
+			*--cp = to_char(val & 7);
+			val >>= 3;
+		} while (val);
+		if (octzero && *cp != '0')
+			*--cp = '0';
+		break;
+
+	case 16:
+		do {
+			*--cp = xdigs[val & 15];
+			val >>= 4;
+		} while (val);
+		break;
+
+	default:			/* oops */
+		abort();
+	}
+	return (cp);
+}
+
+/* Identical to __ultoa, but for intmax_t. */
+static CHAR *
+__ujtoa(uintmax_t val, CHAR *endp, int base, int octzero, const char *xdigs,
+	int needgrp, char thousep, const char *grp)
+{
+	CHAR *cp = endp;
+	intmax_t sval;
+	int ndig;
+
+	/* quick test for small values; __ultoa is typically much faster */
+	/* (perhaps instead we should run until small, then call __ultoa?) */
+	if (val <= ULONG_MAX)
+		return (__ultoa((u_long)val, endp, base, octzero, xdigs,
+		    needgrp, thousep, grp));
+	switch (base) {
+	case 10:
+		if (val < 10) {
+			*--cp = to_char(val % 10);
+			return (cp);
+		}
+		ndig = 0;
+		if (val > INTMAX_MAX) {
+			*--cp = to_char(val % 10);
+			ndig++;
+			sval = val / 10;
+		} else
+			sval = val;
+		do {
+			*--cp = to_char(sval % 10);
+			ndig++;
+			/*
+			 * If (*grp == CHAR_MAX) then no more grouping
+			 * should be performed.
+			 */
+			if (needgrp && *grp != CHAR_MAX && ndig == *grp
+					&& sval > 9) {
+				*--cp = thousep;
+				ndig = 0;
+				/*
+				 * If (*(grp+1) == '\0') then we have to
+				 * use *grp character (last grouping rule)
+				 * for all next cases
+				 */
+				if (*(grp+1) != '\0')
+					grp++;
+			}
+			sval /= 10;
+		} while (sval != 0);
+		break;
+
+	case 8:
+		do {
+			*--cp = to_char(val & 7);
+			val >>= 3;
+		} while (val);
+		if (octzero && *cp != '0')
+			*--cp = '0';
+		break;
+
+	case 16:
+		do {
+			*--cp = xdigs[val & 15];
+			val >>= 4;
+		} while (val);
+		break;
+
+	default:
+		abort();
+	}
+	return (cp);
+}
+
+#ifndef NO_FLOATING_POINT
+
+static int
+exponent(CHAR *p0, int exp, CHAR fmtch)
+{
+	CHAR *p, *t;
+	CHAR expbuf[MAXEXPDIG];
+
+	p = p0;
+	*p++ = fmtch;
+	if (exp < 0) {
+		exp = -exp;
+		*p++ = '-';
+	}
+	else
+		*p++ = '+';
+	t = expbuf + MAXEXPDIG;
+	if (exp > 9) {
+		do {
+			*--t = to_char(exp % 10);
+		} while ((exp /= 10) > 9);
+		*--t = to_char(exp);
+		for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
+	}
+	else {
+		/*
+		 * Exponents for decimal floating point conversions
+		 * (%[eEgG]) must be at least two characters long,
+		 * whereas exponents for hexadecimal conversions can
+		 * be only one character long.
+		 */
+		if (fmtch == 'e' || fmtch == 'E')
+			*p++ = '0';
+		*p++ = to_char(exp);
+	}
+	return (p - p0);
+}
+
+#endif /* !NO_FLOATING_POINT */

Modified: head/lib/libc/stdio/vfprintf.c
==============================================================================
--- head/lib/libc/stdio/vfprintf.c	Thu Jan 15 04:49:40 2009	(r187283)
+++ head/lib/libc/stdio/vfprintf.c	Thu Jan 15 04:49:43 2009	(r187284)
@@ -66,10 +66,6 @@ __FBSDID("$FreeBSD$");
 
 static int	__sprint(FILE *, struct __suio *);
 static int	__sbprintf(FILE *, const char *, va_list) __printflike(2, 0);
-static char	*__ujtoa(uintmax_t, char *, int, int, const char *, int, char,
-		    const char *);
-static char	*__ultoa(u_long, char *, int, int, const char *, int, char,
-		    const char *);
 static char	*__wcsconv(wchar_t *, int);
 
 #define	CHAR	char
@@ -129,160 +125,6 @@ __sbprintf(FILE *fp, const char *fmt, va
 }
 
 /*
- * Convert an unsigned long to ASCII for printf purposes, returning
- * a pointer to the first character of the string representation.
- * Octal numbers can be forced to have a leading zero; hex numbers
- * use the given digits.
- */
-static char *
-__ultoa(u_long val, char *endp, int base, int octzero, const char *xdigs,
-	int needgrp, char thousep, const char *grp)
-{
-	char *cp = endp;
-	long sval;
-	int ndig;
-
-	/*
-	 * Handle the three cases separately, in the hope of getting
-	 * better/faster code.
-	 */
-	switch (base) {
-	case 10:
-		if (val < 10) {	/* many numbers are 1 digit */
-			*--cp = to_char(val);
-			return (cp);
-		}
-		ndig = 0;
-		/*
-		 * On many machines, unsigned arithmetic is harder than
-		 * signed arithmetic, so we do at most one unsigned mod and
-		 * divide; this is sufficient to reduce the range of
-		 * the incoming value to where signed arithmetic works.
-		 */
-		if (val > LONG_MAX) {
-			*--cp = to_char(val % 10);
-			ndig++;
-			sval = val / 10;
-		} else
-			sval = val;
-		do {
-			*--cp = to_char(sval % 10);
-			ndig++;
-			/*
-			 * If (*grp == CHAR_MAX) then no more grouping
-			 * should be performed.
-			 */
-			if (needgrp && ndig == *grp && *grp != CHAR_MAX
-					&& sval > 9) {
-				*--cp = thousep;
-				ndig = 0;
-				/*
-				 * If (*(grp+1) == '\0') then we have to
-				 * use *grp character (last grouping rule)
-				 * for all next cases
-				 */
-				if (*(grp+1) != '\0')
-					grp++;
-			}
-			sval /= 10;
-		} while (sval != 0);
-		break;
-
-	case 8:
-		do {
-			*--cp = to_char(val & 7);
-			val >>= 3;
-		} while (val);
-		if (octzero && *cp != '0')
-			*--cp = '0';
-		break;
-
-	case 16:
-		do {
-			*--cp = xdigs[val & 15];
-			val >>= 4;
-		} while (val);
-		break;
-
-	default:			/* oops */
-		abort();
-	}
-	return (cp);
-}
-
-/* Identical to __ultoa, but for intmax_t. */
-static char *
-__ujtoa(uintmax_t val, char *endp, int base, int octzero, const char *xdigs, 
-	int needgrp, char thousep, const char *grp)
-{
-	char *cp = endp;
-	intmax_t sval;
-	int ndig;
-
-	/* quick test for small values; __ultoa is typically much faster */
-	/* (perhaps instead we should run until small, then call __ultoa?) */
-	if (val <= ULONG_MAX)
-		return (__ultoa((u_long)val, endp, base, octzero, xdigs,
-		    needgrp, thousep, grp));
-	switch (base) {
-	case 10:
-		if (val < 10) {
-			*--cp = to_char(val % 10);
-			return (cp);
-		}
-		ndig = 0;
-		if (val > INTMAX_MAX) {
-			*--cp = to_char(val % 10);
-			ndig++;
-			sval = val / 10;
-		} else
-			sval = val;
-		do {
-			*--cp = to_char(sval % 10);
-			ndig++;
-			/*
-			 * If (*grp == CHAR_MAX) then no more grouping
-			 * should be performed.
-			 */
-			if (needgrp && *grp != CHAR_MAX && ndig == *grp
-					&& sval > 9) {
-				*--cp = thousep;
-				ndig = 0;
-				/*
-				 * If (*(grp+1) == '\0') then we have to
-				 * use *grp character (last grouping rule)
-				 * for all next cases
-				 */
-				if (*(grp+1) != '\0')
-					grp++;
-			}
-			sval /= 10;
-		} while (sval != 0);
-		break;
-
-	case 8:
-		do {
-			*--cp = to_char(val & 7);
-			val >>= 3;
-		} while (val);
-		if (octzero && *cp != '0')
-			*--cp = '0';
-		break;
-
-	case 16:
-		do {
-			*--cp = xdigs[val & 15];
-			val >>= 4;
-		} while (val);
-		break;
-
-	default:
-		abort();
-	}
-	return (cp);
-}
-
-/*
  * Convert a wide character string argument for the %ls format to a multibyte
  * string representation. If not -1, prec specifies the maximum number of
  * bytes to output, and also means that we can't assume that the wide char.
@@ -356,22 +198,6 @@ vfprintf(FILE * __restrict fp, const cha
 	return (ret);
 }
 
-#ifndef NO_FLOATING_POINT
-
-#define	dtoa		__dtoa
-#define	freedtoa	__freedtoa
-
-#include <float.h>
-#include <math.h>
-#include "floatio.h"
-#include "gdtoa.h"
-
-#define	DEFPREC		6
-
-static int exponent(char *, int, int);
-
-#endif /* !NO_FLOATING_POINT */
-
 /*
  * The size of the buffer we use as scratch space for integer
  * conversions, among other things.  Technically, we would need the
@@ -1159,42 +985,3 @@ error:
 	/* NOTREACHED */
 }
 
-
-#ifndef NO_FLOATING_POINT
-
-static int
-exponent(char *p0, int exp, int fmtch)
-{
-	char *p, *t;
-	char expbuf[MAXEXPDIG];
-
-	p = p0;
-	*p++ = fmtch;
-	if (exp < 0) {
-		exp = -exp;
-		*p++ = '-';
-	}
-	else
-		*p++ = '+';
-	t = expbuf + MAXEXPDIG;
-	if (exp > 9) {
-		do {
-			*--t = to_char(exp % 10);
-		} while ((exp /= 10) > 9);
-		*--t = to_char(exp);
-		for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
-	}
-	else {
-		/*
-		 * Exponents for decimal floating point conversions
-		 * (%[eEgG]) must be at least two characters long,
-		 * whereas exponents for hexadecimal conversions can
-		 * be only one character long.
-		 */
-		if (fmtch == 'e' || fmtch == 'E')
-			*p++ = '0';
-		*p++ = to_char(exp);
-	}
-	return (p - p0);
-}
-#endif /* !NO_FLOATING_POINT */

Modified: head/lib/libc/stdio/vfwprintf.c
==============================================================================
--- head/lib/libc/stdio/vfwprintf.c	Thu Jan 15 04:49:40 2009	(r187283)
+++ head/lib/libc/stdio/vfwprintf.c	Thu Jan 15 04:49:43 2009	(r187284)
@@ -69,10 +69,6 @@ __FBSDID("$FreeBSD$");
 static int	__sprint(FILE *, struct __suio *);
 static int	__sbprintf(FILE *, const wchar_t *, va_list);
 static wint_t	__xfputwc(wchar_t, FILE *);
-static wchar_t	*__ujtoa(uintmax_t, wchar_t *, int, int, const char *, int,
-		    char, const char *);
-static wchar_t	*__ultoa(u_long, wchar_t *, int, int, const char *, int,
-		    char, const char *);
 static wchar_t	*__mbsconv(char *, int);
 
 #define	CHAR	wchar_t
@@ -171,160 +167,6 @@ __xfputwc(wchar_t wc, FILE *fp)
 }
 
 /*
- * Convert an unsigned long to ASCII for printf purposes, returning
- * a pointer to the first character of the string representation.
- * Octal numbers can be forced to have a leading zero; hex numbers
- * use the given digits.
- */
-static wchar_t *
-__ultoa(u_long val, wchar_t *endp, int base, int octzero, const char *xdigs,
-	int needgrp, char thousep, const char *grp)
-{
-	wchar_t *cp = endp;
-	long sval;
-	int ndig;
-
-	/*
-	 * Handle the three cases separately, in the hope of getting
-	 * better/faster code.
-	 */
-	switch (base) {
-	case 10:
-		if (val < 10) {	/* many numbers are 1 digit */
-			*--cp = to_char(val);
-			return (cp);
-		}
-		ndig = 0;
-		/*
-		 * On many machines, unsigned arithmetic is harder than
-		 * signed arithmetic, so we do at most one unsigned mod and
-		 * divide; this is sufficient to reduce the range of
-		 * the incoming value to where signed arithmetic works.
-		 */
-		if (val > LONG_MAX) {
-			*--cp = to_char(val % 10);
-			ndig++;
-			sval = val / 10;
-		} else
-			sval = val;
-		do {
-			*--cp = to_char(sval % 10);
-			ndig++;
-			/*
-			 * If (*grp == CHAR_MAX) then no more grouping
-			 * should be performed.
-			 */
-			if (needgrp && ndig == *grp && *grp != CHAR_MAX
-					&& sval > 9) {
-				*--cp = thousep;
-				ndig = 0;
-				/*
-				 * If (*(grp+1) == '\0') then we have to
-				 * use *grp character (last grouping rule)
-				 * for all next cases
-				 */
-				if (*(grp+1) != '\0')
-					grp++;
-			}
-			sval /= 10;
-		} while (sval != 0);
-		break;
-
-	case 8:
-		do {
-			*--cp = to_char(val & 7);
-			val >>= 3;
-		} while (val);
-		if (octzero && *cp != '0')
-			*--cp = '0';
-		break;
-
-	case 16:
-		do {
-			*--cp = xdigs[val & 15];
-			val >>= 4;
-		} while (val);
-		break;
-
-	default:			/* oops */
-		abort();
-	}
-	return (cp);
-}
-
-/* Identical to __ultoa, but for intmax_t. */
-static wchar_t *
-__ujtoa(uintmax_t val, wchar_t *endp, int base, int octzero,
-	const char *xdigs, int needgrp, char thousep, const char *grp)
-{
-	wchar_t *cp = endp;
-	intmax_t sval;
-	int ndig;
-
-	/* quick test for small values; __ultoa is typically much faster */
-	/* (perhaps instead we should run until small, then call __ultoa?) */
-	if (val <= ULONG_MAX)
-		return (__ultoa((u_long)val, endp, base, octzero, xdigs,
-		    needgrp, thousep, grp));
-	switch (base) {
-	case 10:
-		if (val < 10) {
-			*--cp = to_char(val % 10);
-			return (cp);
-		}
-		ndig = 0;
-		if (val > INTMAX_MAX) {
-			*--cp = to_char(val % 10);
-			ndig++;
-			sval = val / 10;
-		} else
-			sval = val;
-		do {
-			*--cp = to_char(sval % 10);
-			ndig++;
-			/*
-			 * If (*grp == CHAR_MAX) then no more grouping
-			 * should be performed.
-			 */
-			if (needgrp && *grp != CHAR_MAX && ndig == *grp
-					&& sval > 9) {
-				*--cp = thousep;
-				ndig = 0;
-				/*
-				 * If (*(grp+1) == '\0') then we have to
-				 * use *grp character (last grouping rule)
-				 * for all next cases
-				 */
-				if (*(grp+1) != '\0')
-					grp++;
-			}
-			sval /= 10;
-		} while (sval != 0);
-		break;
-
-	case 8:
-		do {
-			*--cp = to_char(val & 7);
-			val >>= 3;
-		} while (val);
-		if (octzero && *cp != '0')
-			*--cp = '0';
-		break;
-
-	case 16:
-		do {
-			*--cp = xdigs[val & 15];
-			val >>= 4;
-		} while (val);
-		break;
-
-	default:
-		abort();
-	}
-	return (cp);
-}
-
-/*
  * Convert a multibyte character string argument for the %s format to a wide
  * string representation. ``prec'' specifies the maximum number of bytes
  * to output. If ``prec'' is greater than or equal to zero, we can't assume
@@ -413,22 +255,6 @@ vfwprintf(FILE * __restrict fp, const wc
 	return (ret);
 }
 
-#ifndef NO_FLOATING_POINT
-
-#define	dtoa		__dtoa
-#define	freedtoa	__freedtoa
-
-#include <float.h>
-#include <math.h>
-#include "floatio.h"
-#include "gdtoa.h"
-
-#define	DEFPREC		6
-
-static int exponent(wchar_t *, int, wchar_t);
-
-#endif /* !NO_FLOATING_POINT */
-
 /*
  * The size of the buffer we use as scratch space for integer
  * conversions, among other things.  Technically, we would need the
@@ -1206,43 +1032,3 @@ error:
 	return (ret);
 	/* NOTREACHED */
 }
-
-
-#ifndef NO_FLOATING_POINT
-
-static int
-exponent(wchar_t *p0, int exp, wchar_t fmtch)
-{
-	wchar_t *p, *t;
-	wchar_t expbuf[MAXEXPDIG];
-
-	p = p0;
-	*p++ = fmtch;
-	if (exp < 0) {
-		exp = -exp;
-		*p++ = '-';
-	}
-	else
-		*p++ = '+';
-	t = expbuf + MAXEXPDIG;
-	if (exp > 9) {
-		do {
-			*--t = to_char(exp % 10);
-		} while ((exp /= 10) > 9);
-		*--t = to_char(exp);
-		for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
-	}
-	else {
-		/*
-		 * Exponents for decimal floating point conversions
-		 * (%[eEgG]) must be at least two characters long,
-		 * whereas exponents for hexadecimal conversions can
-		 * be only one character long.
-		 */
-		if (fmtch == 'e' || fmtch == 'E')
-			*p++ = '0';
-		*p++ = to_char(exp);
-	}
-	return (p - p0);
-}
-#endif /* !NO_FLOATING_POINT */


More information about the svn-src-head mailing list