Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/newlib
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2006-09-07 00:03:27 +0400
committerJeff Johnston <jjohnstn@redhat.com>2006-09-07 00:03:27 +0400
commitd39002f9ca0725bbc4eed86bb5b98ae59b7296e8 (patch)
treed022116ca216389c49b443502b8b4517e577a8e0 /newlib
parenta046f426ed7e3b4a89b85f8e5795ef49702fcbf0 (diff)
2006-09-06 Eric Blake <ebb9@byu.net>
* libc/stdio/vfprintf.c (_vfprintf_r, get_arg): Add 'hh', 'j', 't', and 'z' modifiers.
Diffstat (limited to 'newlib')
-rw-r--r--newlib/ChangeLog5
-rw-r--r--newlib/libc/stdio/vfprintf.c107
2 files changed, 107 insertions, 5 deletions
diff --git a/newlib/ChangeLog b/newlib/ChangeLog
index 85c32e94d..33270bc4e 100644
--- a/newlib/ChangeLog
+++ b/newlib/ChangeLog
@@ -1,3 +1,8 @@
+2006-09-06 Eric Blake <ebb9@byu.net>
+
+ * libc/stdio/vfprintf.c (_vfprintf_r, get_arg): Add 'hh', 'j',
+ 't', and 'z' modifiers.
+
2006-09-01 Kazu Hirata <kazu@codesourcery.com>
Merge from newlib-csl-20060320-branch:
diff --git a/newlib/libc/stdio/vfprintf.c b/newlib/libc/stdio/vfprintf.c
index 370ffe0e5..9e5477aa6 100644
--- a/newlib/libc/stdio/vfprintf.c
+++ b/newlib/libc/stdio/vfprintf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1990 The Regents of the University of California.
+ * Copyright (c) 1990, 2006 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@@ -182,6 +182,7 @@ static char *rcsid = "$Id$";
#include <stdlib.h>
#include <string.h>
#include <limits.h>
+#include <stdint.h>
#include <wchar.h>
#include <string.h>
#include <sys/lock.h>
@@ -372,6 +373,7 @@ _EXFUN(get_arg, (struct _reent *data, int n, char *fmt,
#define SHORTINT 0x040 /* short integer */
#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
#define FPT 0x100 /* Floating point number */
+#define CHARINT 0x200 /* char as integer */
int _EXFUN(_VFPRINTF_R, (struct _reent *, FILE *, _CONST char *, va_list));
@@ -427,7 +429,7 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
#endif
int expt; /* integer value of exponent */
int expsize = 0; /* character count for expstr */
- int ndig; /* actual number of digits returned by cvt */
+ int ndig = 0; /* actual number of digits returned by cvt */
char expstr[7]; /* buffer for exponent string */
#endif
u_quad_t _uquad; /* integer arguments %[diouxX] */
@@ -517,20 +519,24 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
(flags&QUADINT ? GET_ARG (N, ap, quad_t) : \
flags&LONGINT ? GET_ARG (N, ap, long) : \
flags&SHORTINT ? (long)(short)GET_ARG (N, ap, int) : \
+ flags&CHARINT ? (long)(signed char)GET_ARG (N, ap, int) : \
(long)GET_ARG (N, ap, int))
#define UARG() \
(flags&QUADINT ? GET_ARG (N, ap, u_quad_t) : \
flags&LONGINT ? GET_ARG (N, ap, u_long) : \
flags&SHORTINT ? (u_long)(u_short)GET_ARG (N, ap, int) : \
+ flags&CHARINT ? (u_long)(unsigned char)GET_ARG (N, ap, int) : \
(u_long)GET_ARG (N, ap, u_int))
#else
#define SARG() \
(flags&LONGINT ? GET_ARG (N, ap, long) : \
flags&SHORTINT ? (long)(short)GET_ARG (N, ap, int) : \
+ flags&CHARINT ? (long)(signed char)GET_ARG (N, ap, int) : \
(long)GET_ARG (N, ap, int))
#define UARG() \
(flags&LONGINT ? GET_ARG (N, ap, u_long) : \
flags&SHORTINT ? (u_long)(u_short)GET_ARG (N, ap, int) : \
+ flags&CHARINT ? (u_long)(unsigned char)GET_ARG (N, ap, int) : \
(u_long)GET_ARG (N, ap, u_int))
#endif
@@ -747,7 +753,12 @@ reswitch: switch (ch) {
goto rflag;
#endif
case 'h':
- flags |= SHORTINT;
+ if (*fmt == 'h') {
+ fmt++;
+ flags |= CHARINT;
+ } else {
+ flags |= SHORTINT;
+ }
goto rflag;
case 'l':
if (*fmt == 'l') {
@@ -760,6 +771,43 @@ reswitch: switch (ch) {
case 'q':
flags |= QUADINT;
goto rflag;
+ case 'j':
+ if (sizeof (intmax_t) == sizeof (long))
+ flags |= LONGINT;
+ else
+ flags |= QUADINT;
+ goto rflag;
+ case 'z':
+ if (sizeof (size_t) < sizeof (int))
+ /* POSIX states size_t is 16 or more bits, as is short. */
+ flags |= SHORTINT;
+ else if (sizeof (size_t) == sizeof (int))
+ /* no flag needed */;
+ else if (sizeof (size_t) <= sizeof (long))
+ flags |= LONGINT;
+ else
+ /* POSIX states that at least one programming
+ environment must support size_t no wider than
+ long, but that means other environments can
+ have size_t as wide as long long. */
+ flags |= QUADINT;
+ goto rflag;
+ case 't':
+ if (sizeof (ptrdiff_t) < sizeof (int))
+ /* POSIX states ptrdiff_t is 16 or more bits, as
+ is short. */
+ flags |= SHORTINT;
+ else if (sizeof (ptrdiff_t) == sizeof (int))
+ /* no flag needed */;
+ else if (sizeof (ptrdiff_t) <= sizeof (long))
+ flags |= LONGINT;
+ else
+ /* POSIX states that at least one programming
+ environment must support ptrdiff_t no wider than
+ long, but that means other environments can
+ have ptrdiff_t as wide as long long. */
+ flags |= QUADINT;
+ goto rflag;
case 'c':
case 'C':
cp = buf;
@@ -916,6 +964,8 @@ reswitch: switch (ch) {
*GET_ARG (N, ap, long_ptr_t) = ret;
else if (flags & SHORTINT)
*GET_ARG (N, ap, short_ptr_t) = ret;
+ else if (flags & CHARINT)
+ *GET_ARG (N, ap, char_ptr_t) = ret;
else
*GET_ARG (N, ap, int_ptr_t) = ret;
continue; /* no output */
@@ -1526,7 +1576,7 @@ _DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt),
ACTION action;
int pos, last_arg;
int max_pos_arg = n;
- enum types { INT, LONG_INT, SHORT_INT, QUAD_INT, CHAR, CHAR_PTR, DOUBLE, LONG_DOUBLE, WIDE_CHAR };
+ enum types { INT, LONG_INT, SHORT_INT, CHAR_INT, QUAD_INT, CHAR, CHAR_PTR, DOUBLE, LONG_DOUBLE, WIDE_CHAR };
#ifdef _MB_CAPABLE
wchar_t wc;
mbstate_t wc_state;
@@ -1585,7 +1635,13 @@ _DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt),
switch (ch)
{
case 'h':
- flags |= SHORTINT;
+ if (*fmt == 'h')
+ {
+ flags |= CHARINT;
+ ++fmt;
+ }
+ else
+ flags |= SHORTINT;
break;
case 'L':
flags |= LONGDBL;
@@ -1593,6 +1649,43 @@ _DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt),
case 'q':
flags |= QUADINT;
break;
+ case 'j':
+ if (sizeof (intmax_t) == sizeof (long))
+ flags |= LONGINT;
+ else
+ flags |= QUADINT;
+ break;
+ case 'z':
+ if (sizeof (size_t) < sizeof (int))
+ /* POSIX states size_t is 16 or more bits, as is short. */
+ flags |= SHORTINT;
+ else if (sizeof (size_t) == sizeof (int))
+ /* no flag needed */;
+ else if (sizeof (size_t) <= sizeof (long))
+ flags |= LONGINT;
+ else
+ /* POSIX states that at least one programming
+ environment must support size_t no wider than
+ long, but that means other environments can
+ have size_t as wide as long long. */
+ flags |= QUADINT;
+ break;
+ case 't':
+ if (sizeof (ptrdiff_t) < sizeof (int))
+ /* POSIX states ptrdiff_t is 16 or more bits, as
+ is short. */
+ flags |= SHORTINT;
+ else if (sizeof (ptrdiff_t) == sizeof (int))
+ /* no flag needed */;
+ else if (sizeof (ptrdiff_t) <= sizeof (long))
+ flags |= LONGINT;
+ else
+ /* POSIX states that at least one programming
+ environment must support ptrdiff_t no wider than
+ long, but that means other environments can
+ have ptrdiff_t as wide as long long. */
+ flags |= QUADINT;
+ break;
case 'l':
default:
if (*fmt == 'l')
@@ -1621,6 +1714,8 @@ _DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt),
spec_type = LONG_INT;
else if (flags & SHORTINT)
spec_type = SHORT_INT;
+ else if (flags & CHARINT)
+ spec_type = CHAR_INT;
#ifndef _NO_LONGLONG
else if (flags & QUADINT)
spec_type = QUAD_INT;
@@ -1676,6 +1771,7 @@ _DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt),
args[numargs++].val_wint_t = va_arg (*ap, wint_t);
break;
case CHAR:
+ case CHAR_INT:
case SHORT_INT:
case INT:
args[numargs++].val_int = va_arg (*ap, int);
@@ -1761,6 +1857,7 @@ _DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt),
args[numargs++].val_wint_t = va_arg (*ap, wint_t);
break;
case INT:
+ case CHAR_INT:
case SHORT_INT:
case CHAR:
default: