From 1c323788782c3a5d59153972e532cb079f14b120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se> Date: Wed, 4 Dec 2002 10:42:31 +0100 Subject: [PATCH] (format_length_string): Deleted function. (format_string): Deleted function. (sexp_vformat): New %t specifier, formatting an optional display type. Deleted %z specifier. Instead, introduced a new modifier "0" that can be used with %s, %l and %t, which says that the data is NUL-terminated. Rev: src/nettle/sexp-format.c:1.5 Rev: src/nettle/sexp.h:1.11 --- sexp-format.c | 304 +++++++++++++++++++++++++++++--------------------- sexp.h | 16 ++- 2 files changed, 188 insertions(+), 132 deletions(-) diff --git a/sexp-format.c b/sexp-format.c index 217ead31..5c98f7a7 100644 --- a/sexp-format.c +++ b/sexp-format.c @@ -71,27 +71,6 @@ format_prefix(struct nettle_buffer *buffer, return prefix_length + 1; } -static unsigned -format_length_string(struct nettle_buffer *buffer, - unsigned length, const char *s) -{ - unsigned done = format_prefix(buffer, length); - if (!done) - return 0; - - if (buffer && !nettle_buffer_write(buffer, length, s)) - return 0; - - return done + length; -} - -static unsigned -format_string(struct nettle_buffer *buffer, - const char *s) -{ - return format_length_string(buffer, strlen(s), s); -} - unsigned sexp_vformat(struct nettle_buffer *buffer, const char *format, va_list args) { @@ -127,133 +106,200 @@ sexp_vformat(struct nettle_buffer *buffer, const char *format, va_list args) break; case '%': - switch (*format++) - { - default: - abort(); - - case 'z': - { - const char *s = va_arg(args, const char *); - unsigned length = format_string(buffer, s); - - if (!length) - return 0; + { + int nul_flag = 0; - done += length; - break; + if (*format == '0') + { + format++; + nul_flag = 1; } - case 's': + switch (*format++) { - unsigned length = va_arg(args, unsigned); - const char *s = va_arg(args, const char *); - unsigned prefix_length = format_prefix(buffer, length); - - if (!prefix_length) - return 0; + default: + abort(); - done += prefix_length; + case 's': + { + const char *s; + unsigned length; + unsigned prefix_length; + + if (nul_flag) + { + s = va_arg(args, const char *); + length = strlen(s); + } + else + { + length = va_arg(args, unsigned); + s = va_arg(args, const char *); + } + + prefix_length = format_prefix(buffer, length); + + if (!prefix_length) + return 0; + + done += prefix_length; + + if (buffer && !nettle_buffer_write(buffer, length, s)) + return 0; + + done += length; + + break; + } + case 't': + { + const char *s; + unsigned length; + unsigned prefix_length; + + if (nul_flag) + { + s = va_arg(args, const char *); + if (!s) + break; + + length = strlen(s); + } + else + { + length = va_arg(args, unsigned); + s = va_arg(args, const char *); + if (!s) + break; + } + + if (buffer && !NETTLE_BUFFER_PUTC(buffer, '[')) + return 0; + done++; + + prefix_length = format_prefix(buffer, length); + + if (!prefix_length) + return 0; - if (buffer && !nettle_buffer_write(buffer, length, s)) - return 0; + done += prefix_length; - done += length; + if (buffer && !nettle_buffer_write(buffer, length, s)) + return 0; - break; - } - case 'l': - { - unsigned length = va_arg(args, unsigned); - const char *s = va_arg(args, const char *); + done += length; - if (buffer && !nettle_buffer_write(buffer, length, s)) - return 0; + if (buffer && !NETTLE_BUFFER_PUTC(buffer, ']')) + return 0; + done++; + + break; + } - done += length; - break; - } - case 'i': - { - uint32_t x = va_arg(args, uint32_t); - unsigned length; + case 'l': + { + const char *s; + unsigned length; + + if (nul_flag) + { + s = va_arg(args, const char *); + length = strlen(s); + } + else + { + length = va_arg(args, unsigned); + s = va_arg(args, const char *); + } + + if (buffer && !nettle_buffer_write(buffer, length, s)) + return 0; - if (x < 0x80) - length = 1; - else if (x < 0x8000L) - length = 2; - else if (x < 0x800000L) - length = 3; - else if (x < 0x80000000L) - length = 4; - else - length = 5; + done += length; + break; + } + case 'i': + { + uint32_t x = va_arg(args, uint32_t); + unsigned length; - if (buffer && !(NETTLE_BUFFER_PUTC(buffer, '0' + length) - && NETTLE_BUFFER_PUTC(buffer, ':'))) - return 0; - - done += (2 + length); - - if (buffer) - switch(length) - { - case 5: - /* Leading byte needed for the sign. */ - if (!NETTLE_BUFFER_PUTC(buffer, 0)) - return 0; - /* Fall through */ - case 4: - if (!NETTLE_BUFFER_PUTC(buffer, x >> 24)) - return 0; - /* Fall through */ - case 3: - if (!NETTLE_BUFFER_PUTC(buffer, (x >> 16) & 0xff)) - return 0; - /* Fall through */ - case 2: - if (!NETTLE_BUFFER_PUTC(buffer, (x >> 8) & 0xff)) - return 0; - /* Fall through */ - case 1: - if (!NETTLE_BUFFER_PUTC(buffer, x & 0xff)) - return 0; - break; - default: - abort(); - } - break; - } - case 'b': - { + if (x < 0x80) + length = 1; + else if (x < 0x8000L) + length = 2; + else if (x < 0x800000L) + length = 3; + else if (x < 0x80000000L) + length = 4; + else + length = 5; + + if (buffer && !(NETTLE_BUFFER_PUTC(buffer, '0' + length) + && NETTLE_BUFFER_PUTC(buffer, ':'))) + return 0; + + done += (2 + length); + + if (buffer) + switch(length) + { + case 5: + /* Leading byte needed for the sign. */ + if (!NETTLE_BUFFER_PUTC(buffer, 0)) + return 0; + /* Fall through */ + case 4: + if (!NETTLE_BUFFER_PUTC(buffer, x >> 24)) + return 0; + /* Fall through */ + case 3: + if (!NETTLE_BUFFER_PUTC(buffer, (x >> 16) & 0xff)) + return 0; + /* Fall through */ + case 2: + if (!NETTLE_BUFFER_PUTC(buffer, (x >> 8) & 0xff)) + return 0; + /* Fall through */ + case 1: + if (!NETTLE_BUFFER_PUTC(buffer, x & 0xff)) + return 0; + break; + default: + abort(); + } + break; + } + case 'b': + { #if HAVE_LIBGMP - const MP_INT *n = va_arg(args, const MP_INT *); - unsigned length; - unsigned prefix_length; + const MP_INT *n = va_arg(args, const MP_INT *); + unsigned length; + unsigned prefix_length; - length = nettle_mpz_sizeinbase_256_s(n); - prefix_length = format_prefix(buffer, length); - if (!prefix_length) - return 0; - - done += prefix_length; - - if (buffer) - { - uint8_t *space = nettle_buffer_space(buffer, length); - if (!space) - return 0; + length = nettle_mpz_sizeinbase_256_s(n); + prefix_length = format_prefix(buffer, length); + if (!prefix_length) + return 0; + + done += prefix_length; + + if (buffer) + { + uint8_t *space = nettle_buffer_space(buffer, length); + if (!space) + return 0; - nettle_mpz_get_str_256(length, space, n); - } + nettle_mpz_get_str_256(length, space, n); + } - done += length; + done += length; #else /* ! HAVE_LIBGMP */ - abort(); + abort(); #endif /* ! HAVE_LIBGMP */ - break; + break; + } } - } + } } } diff --git a/sexp.h b/sexp.h index 7baee5b8..aa86db24 100644 --- a/sexp.h +++ b/sexp.h @@ -137,10 +137,12 @@ struct nettle_buffer; * Format strings can contained matched parentheses, and the following * formatting specifiers: * - * %z NUL-terminated string, const uint8_t *. - * * %s String represented as unsigned length, const uint8_t *data. * + * %t Optional display type, represented as + * unsigned display_length, const uint8_t *display, + * display == NULL means no display type. + * * %i Non-negative small integer, uint32_t. * * %b Non-negative bignum, mpz_t. @@ -148,7 +150,15 @@ struct nettle_buffer; * %l Literal string (no length added), typically a balanced * subexpression. Represented as unsigned length, const uint8_t * *data. - */ + * + * Modifiers: + * + * %0 For %s, %t and %l, says that there's no length argument, + * instead the string is NUL-terminated, and there's only one + * const uint8_t * argument. + * + * FIXME: Allow literals, like "(x%b)". Allow "%(" for unbalanced + * parenthesis. */ unsigned sexp_format(struct nettle_buffer *buffer, -- GitLab