about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--stdio-common/tst-printf.c23
-rw-r--r--stdio-common/vfprintf.c10
3 files changed, 40 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 2f3d4dd174..f49147a9f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2000-09-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* stdio-common/vfprintf.c (process_arg): Handle %hhn.
+	Add missing case in va_arg handling for numbers.
+	* stdio-common/tst-printf.c (main): Add tests for %hhu and %hhn
+	handling.  Reported by Joseph S. Myers <jsm28@cam.ac.uk>.
+
 2000-09-20  Bruno Haible  <haible@clisp.cons.org>
 
 	* iconvdata/iso-2022-jp.c (BODY for FROM_LOOP): Reject 0x80.
diff --git a/stdio-common/tst-printf.c b/stdio-common/tst-printf.c
index 5afa471fca..f0f0e55bc4 100644
--- a/stdio-common/tst-printf.c
+++ b/stdio-common/tst-printf.c
@@ -20,6 +20,7 @@
 #include </usr/include/stdio.h>
 #define EXIT_SUCCESS 0
 #else
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -262,10 +263,32 @@ I am ready for my first lesson today.";
     puts ("");
   }
 
+  printf ("printf (\"%%hhu\", %u) = %hhu\n", UCHAR_MAX + 2, UCHAR_MAX + 2);
+  printf ("printf (\"%%hu\", %u) = %hu\n", USHRT_MAX + 2, USHRT_MAX + 2);
+
   puts ("--- Should be no further output. ---");
   rfg1 ();
   rfg2 ();
 
+  {
+    char bytes[7];
+    char buf[20];
+
+    memset (bytes, '\xff', sizeof bytes);
+    sprintf (buf, "foo%hhn\n", &bytes[3]);
+    if (bytes[0] != '\xff' || bytes[1] != '\xff' || bytes[2] != '\xff'
+	|| bytes[4] != '\xff' || bytes[5] != '\xff' || bytes[6] != '\xff')
+      {
+	puts ("%hhn overwrite more bytes");
+	result = 1;
+      }
+    if (bytes[3] != 3)
+      {
+	puts ("%hhn wrote incorrect value");
+	result = 1;
+      }
+  }
+
   return result != 0;
 }
 
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 6219d795f8..adfb65100c 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -660,6 +660,8 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	    {								      \
 	      if (is_long_num)						      \
 		number.word = va_arg (ap, unsigned long int);		      \
+	      else if (is_char)						      \
+	        number.word = (unsigned char) va_arg (ap, unsigned int);      \
 	      else if (!is_short)					      \
 		number.word = va_arg (ap, unsigned int);		      \
 	      else							      \
@@ -935,6 +937,10 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	    *(long long int *) va_arg (ap, void *) = done;		      \
 	  else if (is_long_num)						      \
 	    *(long int *) va_arg (ap, void *) = done;			      \
+	  else if (is_char)						      \
+	    *(char *) va_arg (ap, void *) = done;			      \
+	  else if (is_long_num)						      \
+	    *(long int *) va_arg (ap, void *) = done;			      \
 	  else if (!is_short)						      \
 	    *(int *) va_arg (ap, void *) = done;			      \
 	  else								      \
@@ -945,6 +951,10 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	  *(long long int *) args_value[fspec->data_arg].pa_pointer = done;   \
 	else if (is_long_num)						      \
 	  *(long int *) args_value[fspec->data_arg].pa_pointer = done;	      \
+	else if (is_long_num)						      \
+	  *(long int *) args_value[fspec->data_arg].pa_pointer = done;	      \
+	else if (is_char)						      \
+	  *(char *) args_value[fspec->data_arg].pa_pointer = done;	      \
 	else if (!is_short)						      \
 	  *(int *) args_value[fspec->data_arg].pa_pointer = done;	      \
 	else								      \