diff options
author | Ulrich Drepper <drepper@redhat.com> | 1997-04-05 00:43:06 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1997-04-05 00:43:06 +0000 |
commit | 9106c38136e580b832b75b4f54e7e8dceb591455 (patch) | |
tree | 99410d5eb04608b46640ba00763f0568e4fc9c8b /stdio-common | |
parent | 5cb9ee67467a02d04d7394631ad9c95aa0359392 (diff) |
Correct handling of installable printf handlers.
Diffstat (limited to 'stdio-common')
-rw-r--r-- | stdio-common/printf-parse.h | 27 | ||||
-rw-r--r-- | stdio-common/printf.h | 17 | ||||
-rw-r--r-- | stdio-common/vfprintf.c | 3 |
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); |