summaryrefslogtreecommitdiff
path: root/stdio-common
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-04-05 00:43:06 +0000
committerUlrich Drepper <drepper@redhat.com>1997-04-05 00:43:06 +0000
commit9106c38136e580b832b75b4f54e7e8dceb591455 (patch)
tree99410d5eb04608b46640ba00763f0568e4fc9c8b /stdio-common
parent5cb9ee67467a02d04d7394631ad9c95aa0359392 (diff)
Correct handling of installable printf handlers.
Diffstat (limited to 'stdio-common')
-rw-r--r--stdio-common/printf-parse.h27
-rw-r--r--stdio-common/printf.h17
-rw-r--r--stdio-common/vfprintf.c3
3 files changed, 33 insertions, 14 deletions
diff --git a/stdio-common/printf-parse.h b/stdio-common/printf-parse.h
index 141164b04b..f1fecdb275 100644
--- a/stdio-common/printf-parse.h
+++ b/stdio-common/printf-parse.h
@@ -1,5 +1,5 @@
/* Internal header for parsing printf format strings.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997 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
@@ -106,8 +106,9 @@ find_spec (const char *format, mbstate_t *ps)
}
-/* This is defined in reg-printf.c. */
-extern printf_arginfo_function **__printf_arginfo_table;
+/* 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
@@ -299,8 +300,9 @@ parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
/* Get the format specification. */
spec->info.spec = (wchar_t) *format++;
- if (__printf_arginfo_table != NULL &&
- __printf_arginfo_table[spec->info.spec] != NULL)
+ 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])
@@ -362,15 +364,14 @@ parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
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;
- posn += spec->ndata_args;
- nargs += spec->ndata_args;
- }
+ 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')
diff --git a/stdio-common/printf.h b/stdio-common/printf.h
index 6d9e8a455f..c49172b88c 100644
--- a/stdio-common/printf.h
+++ b/stdio-common/printf.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 93, 95, 96 Free Software Foundation, Inc.
+/* 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
@@ -122,6 +122,21 @@ enum
#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 __P ((FILE *__fp, __const struct printf_info *__info,
+ __const void *__const *args));
+
+/* This is the appropriate argument information function for `printf_size'. */
+extern int printf_size_info __P ((__const struct printf_info *__info,
+ size_t __n, int *__argtypes));
+
+
__END_DECLS
#endif /* printf.h */
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 4bd564fdc0..82348af237 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -1084,6 +1084,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
goto do_positional;
}
+ /* The format is correctly handled. */
+ ++nspecs_done;
+
/* Look for next format specifier. */
f = find_spec ((end_of_spec = ++f), &mbstate);