summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Hall <chris.hall@highwayman.com>2011-03-21 10:23:16 +0000
committerChris Hall <chris.hall@highwayman.com>2011-03-21 10:23:16 +0000
commit6481583be322b0ba223a0140500a0a6d50546dd9 (patch)
tree15fdd1d0cd7ab1ee731506da5a5ed56e5debb4bb
parent5cffb8de373bbd19c9db36239cf41951e266953e (diff)
downloadquagga-6481583be322b0ba223a0140500a0a6d50546dd9.tar.bz2
quagga-6481583be322b0ba223a0140500a0a6d50546dd9.tar.xz
Correct logging output on 32-bit machines.ex12
v0.99.15ex12 Construction of log messages using qfs_printf()/qfs_vprintf() did not produce the intended results on 32-bit machines -- so that some logging messages were garbled. On 64-bit machines the log messages were formed as expected.
-rwxr-xr-xconfigure.ac2
-rw-r--r--lib/qfstring.c117
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 ;
} ;