diff options
-rwxr-xr-x | configure.ac | 2 | ||||
-rw-r--r-- | lib/qfstring.c | 117 |
2 files changed, 59 insertions, 60 deletions
diff --git a/configure.ac b/configure.ac index 61afe05d..7190557e 100755 --- a/configure.ac +++ b/configure.ac @@ -8,7 +8,7 @@ ## $Id$ AC_PREREQ(2.53) -AC_INIT(Quagga, 0.99.15ex09, [http://bugzilla.quagga.net]) +AC_INIT(Quagga, 0.99.15ex12, [http://bugzilla.quagga.net]) AC_CONFIG_SRCDIR(lib/zebra.h) AC_CONFIG_MACRO_DIR([m4]) diff --git a/lib/qfstring.c b/lib/qfstring.c index 583d729f..f0972fdf 100644 --- a/lib/qfstring.c +++ b/lib/qfstring.c @@ -19,19 +19,18 @@ * Boston, MA 02111-1307, USA. */ -#include <stdbool.h> -#include <stdint.h> - #include "qfstring.h" +#include "zassert.h" +#include <stdbool.h> /*============================================================================== */ /*------------------------------------------------------------------------------ - * Initialise qf_str -- to given size (which includes the '\n') + * Initialise qf_str -- to given size (which includes the '\0') * * Sets pointers and terminates an empty string with one byte reserved for the - * terminating '\n'. + * terminating '\0'. * * This operation is async-signal-safe. */ @@ -49,12 +48,12 @@ qfs_init(qf_str qfs, char* str, size_t size) /*------------------------------------------------------------------------------ * Initialise qf_str which already contains string -- to given size (which - * includes the '\n') + * includes the '\0') * * This may be used to prepare for appending to a buffer which already contains * something. * - * Sets pointers, setting the write pointer to the existing terminating '\n'. + * Sets pointers, setting the write pointer to the existing terminating '\0'. * * This operation is async-signal-safe. */ @@ -333,7 +332,7 @@ qfs_pointer(qf_str qfs, void* p_val, enum pf_flags flags, * * If the precision is < 0 it is ignored (unless pf_hex, see below). * - * If the precision is 0 it is ignored unless bf_precision is set. + * If the precision is 0 it is ignored unless pf_precision is set. * * Precedence issues: * @@ -653,11 +652,11 @@ enum arg_num_type ant_default = ant_int, }; -static enum pf_phase qfs_arg_string(qf_str qfs, va_list args, +static enum pf_phase qfs_arg_string(qf_str qfs, const char* src, enum pf_flags flags, int width, int precision) ; -static enum pf_phase qfs_arg_char(qf_str qfs, va_list args, +static enum pf_phase qfs_arg_char(qf_str qfs, char ch, enum pf_flags flags, int width, int precision) ; -static enum pf_phase qfs_arg_number(qf_str qfs, va_list args, +static enum pf_phase qfs_arg_number(qf_str qfs, va_list* p_va, enum pf_flags flags, int width, int precision, enum arg_num_type ant) ; /*------------------------------------------------------------------------------ @@ -668,24 +667,30 @@ static enum pf_phase qfs_arg_number(qf_str qfs, va_list args, extern void qfs_printf(qf_str qfs, const char* format, ...) { - va_list args; + va_list va ; - va_start (args, format); - qfs_vprintf(qfs, format, args); - va_end (args); + va_start (va, format); + qfs_vprintf(qfs, format, va); + va_end (va); } ; /*------------------------------------------------------------------------------ * Formatted print to qf_str -- cf vprintf() * * This operation is async-signal-safe. + * + * Operates on a copy of the va_list -- so the original is *unchanged*. */ extern void -qfs_vprintf(qf_str qfs, const char *format, va_list args) +qfs_vprintf(qf_str qfs, const char *format, va_list va) { + va_list vac ; + if (format == NULL) return ; + va_copy(vac, va) ; + while ((qfs->ptr < qfs->end) && (*format != '\0')) { /* Have space for one byte and current format byte is not '\0' */ @@ -770,15 +775,15 @@ qfs_vprintf(qf_str qfs, const char *format, va_list args) if (!star && !digit && (phase <= pfp_width)) { phase = pfp_width ; - width = va_arg(args, int) ; + width = va_arg(vac, int) ; } else if (!star && !digit && (phase == pfp_precision)) { - precision = va_arg(args, int) ; + precision = va_arg(vac, int) ; if (precision < 0) { precision = 0 ; - flags &= ~pf_precision ; + flags &= ~pf_precision ; /* completely ignore */ } ; } else @@ -827,34 +832,36 @@ qfs_vprintf(qf_str qfs, const char *format, va_list args) if (phase == pfp_num_type) phase = pfp_failed ; /* don't do 'l' etc. */ else - phase = qfs_arg_string(qfs, args, flags, width, precision) ; + phase = qfs_arg_string(qfs, va_arg(vac, char*), + flags, width, precision) ; break ; case 'c': if (phase == pfp_num_type) phase = pfp_failed ; /* don't do 'l' etc. */ else - phase = qfs_arg_char(qfs, args, flags, width, precision) ; + phase = qfs_arg_char(qfs, (char)va_arg(vac, int), + flags, width, precision) ; break ; case 'd': case 'i': - phase = qfs_arg_number(qfs, args, flags, width, precision, + phase = qfs_arg_number(qfs, &vac, flags, width, precision, ant) ; break ; case 'u': - phase = qfs_arg_number(qfs, args, flags | pf_unsigned, width, + phase = qfs_arg_number(qfs, &vac, flags | pf_unsigned, width, precision, ant) ; break ; case 'x': - phase = qfs_arg_number(qfs, args, flags | pf_hex_x, width, + phase = qfs_arg_number(qfs, &vac, flags | pf_hex_x, width, precision, ant) ; break ; case 'X': - phase = qfs_arg_number(qfs, args, flags | pf_hex_X, width, + phase = qfs_arg_number(qfs, &vac, flags | pf_hex_X, width, precision, ant) ; break ; @@ -862,7 +869,7 @@ qfs_vprintf(qf_str qfs, const char *format, va_list args) if (phase == pfp_num_type) phase = pfp_failed ; else - phase = qfs_arg_number(qfs, args, flags | pf_void_p, width, + phase = qfs_arg_number(qfs, &vac, flags | pf_void_p, width, precision, ant_ptr_t) ; break ; @@ -881,13 +888,15 @@ qfs_vprintf(qf_str qfs, const char *format, va_list args) } ; *qfs->ptr = '\0' ; + + va_end(vac) ; } ; /*------------------------------------------------------------------------------ * %s handler -- tolerates NULL pointer * * Accepts: width - * precision + * precision -- ignored if < 0 * pf_precision -- explicit precision * * Rejects: pf_commas -- "'" seen @@ -904,17 +913,20 @@ qfs_vprintf(qf_str qfs, const char *format, va_list args) * This operation is async-signal-safe. */ static enum pf_phase -qfs_arg_string(qf_str qfs, va_list args, enum pf_flags flags, +qfs_arg_string(qf_str qfs, const char* src, enum pf_flags flags, int width, int precision) { - const char* src ; int len ; - src = va_arg(args, char*) ; - if (flags != (flags & pf_precision)) return pfp_failed ; + if (precision < 0) /* make sure */ + { + precision = 0 ; + flags &= ~pf_precision ; + } ; + len = (src != NULL) ? strlen(src) : 0 ; if (((precision > 0) || (flags & pf_precision)) && (len > precision)) len = precision ; @@ -945,13 +957,8 @@ qfs_arg_string(qf_str qfs, va_list args, enum pf_flags flags, * This operation is async-signal-safe. */ static enum pf_phase -qfs_arg_char(qf_str qfs, va_list args, enum pf_flags flags, - int width, int precision) +qfs_arg_char(qf_str qfs, char ch, enum pf_flags flags, int width, int precision) { - unsigned char ch ; - - ch = va_arg(args, int) ; - if ((flags != 0) || (precision != 0)) return pfp_failed ; @@ -982,7 +989,7 @@ qfs_arg_char(qf_str qfs, va_list args, enum pf_flags flags, * This operation is async-signal-safe. */ static enum pf_phase -qfs_arg_number(qf_str qfs, va_list args, enum pf_flags flags, +qfs_arg_number(qf_str qfs, va_list* p_va, enum pf_flags flags, int width, int precision, enum arg_num_type ant) { uintmax_t u_val ; @@ -991,7 +998,7 @@ qfs_arg_number(qf_str qfs, va_list args, enum pf_flags flags, /* Special for hex with '0... if no explicit precision, set -1 for byte * and -2 for everything else -- see qfs_number(). */ - if (((flags & pf_precision) == 0) && (flags & pf_hex)) + if ((flags & (pf_hex | pf_precision)) == pf_hex) { if ((flags & (pf_commas | pf_zeros)) == (pf_commas | pf_zeros)) { @@ -1009,31 +1016,28 @@ qfs_arg_number(qf_str qfs, va_list args, enum pf_flags flags, { case ant_char: case ant_short: - u_val = va_arg(args, int) ; - break ; - case ant_int: - u_val = va_arg(args, unsigned int) ; + u_val = va_arg(*p_va, unsigned int) ; break ; case ant_long: - u_val = va_arg(args, unsigned long) ; + u_val = va_arg(*p_va, unsigned long) ; break ; case ant_long_long: - u_val = va_arg(args, unsigned long long) ; + u_val = va_arg(*p_va, unsigned long long) ; break ; case ant_intmax_t: - u_val = va_arg(args, uintmax_t) ; + u_val = va_arg(*p_va, uintmax_t) ; break ; case ant_size_t: - u_val = va_arg(args, size_t) ; + u_val = va_arg(*p_va, size_t) ; break ; case ant_ptr_t: - u_val = va_arg(args, uintptr_t) ; + u_val = va_arg(*p_va, uintptr_t) ; break ; default: @@ -1048,31 +1052,28 @@ qfs_arg_number(qf_str qfs, va_list args, enum pf_flags flags, { case ant_char: case ant_short: - s_val = va_arg(args, int) ; - break ; - case ant_int: - s_val = va_arg(args, signed int) ; + s_val = va_arg(*p_va, signed int) ; break ; case ant_long: - s_val = va_arg(args, signed long) ; + s_val = va_arg(*p_va, signed long) ; break ; case ant_long_long: - s_val = va_arg(args, signed long long) ; + s_val = va_arg(*p_va, signed long long) ; break ; case ant_intmax_t: - s_val = va_arg(args, intmax_t) ; + s_val = va_arg(*p_va, intmax_t) ; break ; case ant_size_t: - s_val = va_arg(args, ssize_t) ; + s_val = va_arg(*p_va, ssize_t) ; break ; case ant_ptr_t: - s_val = va_arg(args, intptr_t) ; + s_val = va_arg(*p_va, intptr_t) ; break ; default: @@ -1082,8 +1083,6 @@ qfs_arg_number(qf_str qfs, va_list args, enum pf_flags flags, qfs_signed(qfs, s_val, flags, width, precision) ; } ; - /* construct a digit string, the hard way */ - return pfp_done ; } ; |