diff options
Diffstat (limited to 'crypto/kerberosIV/lib/roken/snprintf.c')
| -rw-r--r-- | crypto/kerberosIV/lib/roken/snprintf.c | 254 |
1 files changed, 177 insertions, 77 deletions
diff --git a/crypto/kerberosIV/lib/roken/snprintf.c b/crypto/kerberosIV/lib/roken/snprintf.c index b0757e551df1..62f5b1068bb8 100644 --- a/crypto/kerberosIV/lib/roken/snprintf.c +++ b/crypto/kerberosIV/lib/roken/snprintf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995-1997, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -38,7 +38,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: snprintf.c,v 1.13 1997/05/25 02:00:31 assar Exp $"); +RCSID("$Id: snprintf.c,v 1.19 1999/03/27 16:32:57 joda Exp $"); #endif #include <stdio.h> #include <stdarg.h> @@ -47,21 +47,30 @@ RCSID("$Id: snprintf.c,v 1.13 1997/05/25 02:00:31 assar Exp $"); #include <ctype.h> #include <roken.h> +enum format_flags { + minus_flag = 1, + plus_flag = 2, + space_flag = 4, + alternate_flag = 8, + zero_flag = 16 +}; + /* * Common state */ struct state { - char *str; - char *s; - char *theend; + unsigned char *str; + unsigned char *s; + unsigned char *theend; size_t sz; size_t max_sz; - int (*append_char)(struct state *, char); + int (*append_char)(struct state *, unsigned char); int (*reserve)(struct state *, size_t); /* XXX - methods */ }; +#ifndef HAVE_VSNPRINTF static int sn_reserve (struct state *state, size_t n) { @@ -69,31 +78,30 @@ sn_reserve (struct state *state, size_t n) } static int -sn_append_char (struct state *state, char c) +sn_append_char (struct state *state, unsigned char c) { if (sn_reserve (state, 1)) { - *state->s++ = '\0'; return 1; } else { *state->s++ = c; return 0; } } +#endif static int as_reserve (struct state *state, size_t n) { - while (state->s + n > state->theend) { + if (state->s + n > state->theend) { int off = state->s - state->str; - char *tmp; + unsigned char *tmp; if (state->max_sz && state->sz >= state->max_sz) return 1; + state->sz = max(state->sz * 2, state->sz + n); if (state->max_sz) - state->sz = min(state->max_sz, state->sz*2); - else - state->sz *= 2; + state->sz = min(state->sz, state->max_sz); tmp = realloc (state->str, state->sz); if (tmp == NULL) return 1; @@ -105,7 +113,7 @@ as_reserve (struct state *state, size_t n) } static int -as_append_char (struct state *state, char c) +as_append_char (struct state *state, unsigned char c) { if(as_reserve (state, 1)) return 1; @@ -116,61 +124,110 @@ as_append_char (struct state *state, char c) } static int -append_number (struct state *state, - unsigned long num, unsigned base, char *rep, - int width, int zerop, int minusp) +append_number(struct state *state, + unsigned long num, unsigned base, unsigned char *rep, + int width, int prec, int flags, int minusp) { - int i, len; + int len = 0; + int i; - len = 0; - if (num == 0) { - ++len; - if((*state->append_char) (state, '0')) - return 1; - } - while (num > 0) { - ++len; - if ((*state->append_char) (state, rep[num % base])) + /* given precision, ignore zero flag */ + if(prec != -1) + flags &= ~zero_flag; + else + prec = 1; + /* zero value with zero precision -> "" */ + if(prec == 0 && num == 0) + return 0; + do{ + if((*state->append_char)(state, rep[num % base])) return 1; + len++; num /= base; + }while(num); + prec -= len; + /* pad with prec zeros */ + while(prec-- > 0){ + if((*state->append_char)(state, '0')) + return 1; + len++; } - if (minusp) { - ++len; - if ((*state->append_char) (state, '-')) + /* add length of alternate prefix (added later) to len */ + if(flags & alternate_flag && (base == 16 || base == 8)) + len += base / 8; + /* pad with zeros */ + if(flags & zero_flag){ + width -= len; + if(minusp || (flags & space_flag) || (flags & plus_flag)) + width--; + while(width-- > 0){ + if((*state->append_char)(state, '0')) + return 1; + len++; + } + } + /* add alternate prefix */ + if(flags & alternate_flag && (base == 16 || base == 8)){ + if(base == 16) + if((*state->append_char)(state, rep[10] + 23)) /* XXX */ + return 1; + if((*state->append_char)(state, '0')) return 1; } - - for (i = 0; i < len / 2; ++i) { - char c; - - c = state->s[-i-1]; - state->s[-i-1] = state->s[-len+i]; - state->s[-len+i] = c; + /* add sign */ + if(minusp){ + if((*state->append_char)(state, '-')) + return 1; + len++; + } else if(flags & plus_flag) { + if((*state->append_char)(state, '+')) + return 1; + len++; + } else if(flags & space_flag) { + if((*state->append_char)(state, ' ')) + return 1; + len++; } - - if (width > len) { - if ((*state->reserve) (state, width - len)) + if(flags & minus_flag) + /* swap before padding with spaces */ + for(i = 0; i < len / 2; i++){ + char c = state->s[-i-1]; + state->s[-i-1] = state->s[-len+i]; + state->s[-len+i] = c; + } + width -= len; + while(width-- > 0){ + if((*state->append_char)(state, ' ')) return 1; - -#ifdef HAVE_MEMMOVE - memmove (state->s + width - 2 * len, state->s - len, len); -#else - bcopy (state->s - len, state->s + width - 2 * len, len); -#endif - for (i = 0; i < width - len; ++i) - state->s[-len+i] = (zerop ? '0' : ' '); - state->s += width - len; - + len++; } + if(!(flags & minus_flag)) + /* swap after padding with spaces */ + for(i = 0; i < len / 2; i++){ + char c = state->s[-i-1]; + state->s[-i-1] = state->s[-len+i]; + state->s[-len+i] = c; + } + return 0; } static int append_string (struct state *state, - char *arg, - int prec) + unsigned char *arg, + int width, + int prec, + int flags) { - if (prec) { + if(prec != -1) + width -= prec; + else + width -= strlen(arg); + if(!(flags & minus_flag)) + while(width-- > 0) + if((*state->append_char) (state, ' ')) + return 1; + if (prec != -1) { while (*arg && prec--) if ((*state->append_char) (state, *arg++)) return 1; @@ -179,6 +236,29 @@ append_string (struct state *state, if ((*state->append_char) (state, *arg++)) return 1; } + if(flags & minus_flag) + while(width-- > 0) + if((*state->append_char) (state, ' ')) + return 1; + return 0; +} + +static int +append_char(struct state *state, + unsigned char arg, + int width, + int flags) +{ + while(!(flags & minus_flag) && --width > 0) + if((*state->append_char) (state, ' ')) + return 1; + + if((*state->append_char) (state, arg)) + return 1; + while((flags & minus_flag) && --width > 0) + if((*state->append_char) (state, ' ')) + return 1; + return 0; } @@ -199,25 +279,40 @@ else \ */ static int -xyzprintf (struct state *state, const char *format, va_list ap) +xyzprintf (struct state *state, const char *char_format, va_list ap) { - char c; + const unsigned char *format = (const unsigned char *)char_format; + unsigned char c; while((c = *format++)) { if (c == '%') { - int zerop = 0; + int flags = 0; int width = 0; - int prec = 0; + int prec = -1; int long_flag = 0; int short_flag = 0; - c = *format++; - /* flags */ - if (c == '0') { - zerop = 1; - c = *format++; + while((c = *format++)){ + if(c == '-') + flags |= minus_flag; + else if(c == '+') + flags |= plus_flag; + else if(c == ' ') + flags |= space_flag; + else if(c == '#') + flags |= alternate_flag; + else if(c == '0') + flags |= zero_flag; + else + break; } + + if((flags & space_flag) && (flags & plus_flag)) + flags ^= space_flag; + + if((flags & minus_flag) && (flags & zero_flag)) + flags ^= zero_flag; /* width */ if (isdigit(c)) @@ -232,6 +327,7 @@ xyzprintf (struct state *state, const char *format, va_list ap) /* precision */ if (c == '.') { + prec = 0; c = *format++; if (isdigit(c)) do { @@ -256,13 +352,15 @@ xyzprintf (struct state *state, const char *format, va_list ap) switch (c) { case 'c' : - if ((*state->append_char)(state, (unsigned char)va_arg(ap, int))) + if(append_char(state, va_arg(ap, int), width, flags)) return -1; break; case 's' : if (append_string(state, - va_arg(ap, char*), - prec)) + va_arg(ap, unsigned char*), + width, + prec, + flags)) return -1; break; case 'd' : @@ -271,7 +369,7 @@ xyzprintf (struct state *state, const char *format, va_list ap) unsigned long num; int minusp = 0; - PARSE_INT_FORMAT(arg, ap, ); + PARSE_INT_FORMAT(arg, ap, signed); if (arg < 0) { minusp = 1; @@ -280,7 +378,7 @@ xyzprintf (struct state *state, const char *format, va_list ap) num = arg; if (append_number (state, num, 10, "0123456789", - width, zerop, minusp)) + width, prec, flags, minusp)) return -1; break; } @@ -290,7 +388,7 @@ xyzprintf (struct state *state, const char *format, va_list ap) PARSE_INT_FORMAT(arg, ap, unsigned); if (append_number (state, arg, 10, "0123456789", - width, zerop, 0)) + width, prec, flags, 0)) return -1; break; } @@ -300,7 +398,7 @@ xyzprintf (struct state *state, const char *format, va_list ap) PARSE_INT_FORMAT(arg, ap, unsigned); if (append_number (state, arg, 010, "01234567", - width, zerop, 0)) + width, prec, flags, 0)) return -1; break; } @@ -310,7 +408,7 @@ xyzprintf (struct state *state, const char *format, va_list ap) PARSE_INT_FORMAT(arg, ap, unsigned); if (append_number (state, arg, 0x10, "0123456789abcdef", - width, zerop, 0)) + width, prec, flags, 0)) return -1; break; } @@ -320,7 +418,7 @@ xyzprintf (struct state *state, const char *format, va_list ap) PARSE_INT_FORMAT(arg, ap, unsigned); if (append_number (state, arg, 0x10, "0123456789ABCDEF", - width, zerop, 0)) + width, prec, flags, 0)) return -1; break; } @@ -328,10 +426,15 @@ xyzprintf (struct state *state, const char *format, va_list ap) unsigned long arg = (unsigned long)va_arg(ap, void*); if (append_number (state, arg, 0x10, "0123456789ABCDEF", - width, zerop, 0)) + width, prec, flags, 0)) return -1; break; } + case 'n' : { + int *arg = va_arg(ap, int*); + *arg = state->s - state->str; + break; + } case '%' : if ((*state->append_char)(state, c)) return -1; @@ -458,10 +561,7 @@ vasnprintf (char **ret, size_t max_sz, const char *format, va_list args) struct state state; state.max_sz = max_sz; - if (max_sz) - state.sz = min(1, max_sz); - else - state.sz = 1; + state.sz = 1; state.str = malloc(state.sz); if (state.str == NULL) { *ret = NULL; @@ -483,7 +583,7 @@ vasnprintf (char **ret, size_t max_sz, const char *format, va_list args) *state.s = '\0'; len = state.s - state.str; tmp = realloc (state.str, len+1); - if (state.str == NULL) { + if (tmp == NULL) { free (state.str); *ret = NULL; return -1; |
