1685295f4SBill Fenner /* 2685295f4SBill Fenner * Copyright (c) 1995-1999 Kungliga Tekniska H�gskolan 3685295f4SBill Fenner * (Royal Institute of Technology, Stockholm, Sweden). 4685295f4SBill Fenner * All rights reserved. 5685295f4SBill Fenner * 6685295f4SBill Fenner * Redistribution and use in source and binary forms, with or without 7685295f4SBill Fenner * modification, are permitted provided that the following conditions 8685295f4SBill Fenner * are met: 9685295f4SBill Fenner * 10685295f4SBill Fenner * 1. Redistributions of source code must retain the above copyright 11685295f4SBill Fenner * notice, this list of conditions and the following disclaimer. 12685295f4SBill Fenner * 13685295f4SBill Fenner * 2. Redistributions in binary form must reproduce the above copyright 14685295f4SBill Fenner * notice, this list of conditions and the following disclaimer in the 15685295f4SBill Fenner * documentation and/or other materials provided with the distribution. 16685295f4SBill Fenner * 17685295f4SBill Fenner * 3. Neither the name of the Institute nor the names of its contributors 18685295f4SBill Fenner * may be used to endorse or promote products derived from this software 19685295f4SBill Fenner * without specific prior written permission. 20685295f4SBill Fenner * 21685295f4SBill Fenner * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22685295f4SBill Fenner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23685295f4SBill Fenner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24685295f4SBill Fenner * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25685295f4SBill Fenner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26685295f4SBill Fenner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27685295f4SBill Fenner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28685295f4SBill Fenner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29685295f4SBill Fenner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30685295f4SBill Fenner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31685295f4SBill Fenner * SUCH DAMAGE. 32685295f4SBill Fenner */ 33685295f4SBill Fenner 34685295f4SBill Fenner #ifdef HAVE_CONFIG_H 35685295f4SBill Fenner #include <config.h> 36685295f4SBill Fenner #endif 37685295f4SBill Fenner 38685295f4SBill Fenner #include <stdio.h> 39685295f4SBill Fenner #include <stdarg.h> 40685295f4SBill Fenner #include <stdlib.h> 41685295f4SBill Fenner #include <string.h> 42685295f4SBill Fenner #include <ctype.h> 43685295f4SBill Fenner #include <sys/types.h> 44685295f4SBill Fenner 45*3340d773SGleb Smirnoff #include "netdissect.h" 46685295f4SBill Fenner 47685295f4SBill Fenner enum format_flags { 48685295f4SBill Fenner minus_flag = 1, 49685295f4SBill Fenner plus_flag = 2, 50685295f4SBill Fenner space_flag = 4, 51685295f4SBill Fenner alternate_flag = 8, 52685295f4SBill Fenner zero_flag = 16 53685295f4SBill Fenner }; 54685295f4SBill Fenner 55685295f4SBill Fenner /* 56685295f4SBill Fenner * Common state 57685295f4SBill Fenner */ 58685295f4SBill Fenner 59685295f4SBill Fenner struct state { 60685295f4SBill Fenner unsigned char *str; 61685295f4SBill Fenner unsigned char *s; 62685295f4SBill Fenner unsigned char *theend; 63685295f4SBill Fenner size_t sz; 64685295f4SBill Fenner size_t max_sz; 65685295f4SBill Fenner int (*append_char)(struct state *, unsigned char); 66685295f4SBill Fenner int (*reserve)(struct state *, size_t); 67685295f4SBill Fenner /* XXX - methods */ 68685295f4SBill Fenner }; 69685295f4SBill Fenner 70685295f4SBill Fenner #ifndef HAVE_VSNPRINTF 71685295f4SBill Fenner static int 72685295f4SBill Fenner sn_reserve (struct state *state, size_t n) 73685295f4SBill Fenner { 74685295f4SBill Fenner return state->s + n > state->theend; 75685295f4SBill Fenner } 76685295f4SBill Fenner 77685295f4SBill Fenner static int 78685295f4SBill Fenner sn_append_char (struct state *state, unsigned char c) 79685295f4SBill Fenner { 80685295f4SBill Fenner if (sn_reserve (state, 1)) { 81685295f4SBill Fenner return 1; 82685295f4SBill Fenner } else { 83685295f4SBill Fenner *state->s++ = c; 84685295f4SBill Fenner return 0; 85685295f4SBill Fenner } 86685295f4SBill Fenner } 87685295f4SBill Fenner #endif 88685295f4SBill Fenner 89a90e161bSBill Fenner #if 0 90685295f4SBill Fenner static int 91685295f4SBill Fenner as_reserve (struct state *state, size_t n) 92685295f4SBill Fenner { 93685295f4SBill Fenner if (state->s + n > state->theend) { 94685295f4SBill Fenner int off = state->s - state->str; 95685295f4SBill Fenner unsigned char *tmp; 96685295f4SBill Fenner 97685295f4SBill Fenner if (state->max_sz && state->sz >= state->max_sz) 98685295f4SBill Fenner return 1; 99685295f4SBill Fenner 100685295f4SBill Fenner state->sz = max(state->sz * 2, state->sz + n); 101685295f4SBill Fenner if (state->max_sz) 102685295f4SBill Fenner state->sz = min(state->sz, state->max_sz); 103685295f4SBill Fenner tmp = realloc (state->str, state->sz); 104685295f4SBill Fenner if (tmp == NULL) 105685295f4SBill Fenner return 1; 106685295f4SBill Fenner state->str = tmp; 107685295f4SBill Fenner state->s = state->str + off; 108685295f4SBill Fenner state->theend = state->str + state->sz - 1; 109685295f4SBill Fenner } 110685295f4SBill Fenner return 0; 111685295f4SBill Fenner } 112685295f4SBill Fenner 113685295f4SBill Fenner static int 114685295f4SBill Fenner as_append_char (struct state *state, unsigned char c) 115685295f4SBill Fenner { 116685295f4SBill Fenner if(as_reserve (state, 1)) 117685295f4SBill Fenner return 1; 118685295f4SBill Fenner else { 119685295f4SBill Fenner *state->s++ = c; 120685295f4SBill Fenner return 0; 121685295f4SBill Fenner } 122685295f4SBill Fenner } 123a90e161bSBill Fenner #endif 124685295f4SBill Fenner 125685295f4SBill Fenner static int 126685295f4SBill Fenner append_number(struct state *state, 127685295f4SBill Fenner unsigned long num, unsigned base, char *rep, 128685295f4SBill Fenner int width, int prec, int flags, int minusp) 129685295f4SBill Fenner { 130685295f4SBill Fenner int len = 0; 131685295f4SBill Fenner int i; 132685295f4SBill Fenner 133685295f4SBill Fenner /* given precision, ignore zero flag */ 134685295f4SBill Fenner if(prec != -1) 135685295f4SBill Fenner flags &= ~zero_flag; 136685295f4SBill Fenner else 137685295f4SBill Fenner prec = 1; 138685295f4SBill Fenner /* zero value with zero precision -> "" */ 139685295f4SBill Fenner if(prec == 0 && num == 0) 140685295f4SBill Fenner return 0; 141685295f4SBill Fenner do{ 142685295f4SBill Fenner if((*state->append_char)(state, rep[num % base])) 143685295f4SBill Fenner return 1; 144685295f4SBill Fenner len++; 145685295f4SBill Fenner num /= base; 146685295f4SBill Fenner }while(num); 147685295f4SBill Fenner prec -= len; 148685295f4SBill Fenner /* pad with prec zeros */ 149685295f4SBill Fenner while(prec-- > 0){ 150685295f4SBill Fenner if((*state->append_char)(state, '0')) 151685295f4SBill Fenner return 1; 152685295f4SBill Fenner len++; 153685295f4SBill Fenner } 154685295f4SBill Fenner /* add length of alternate prefix (added later) to len */ 155685295f4SBill Fenner if(flags & alternate_flag && (base == 16 || base == 8)) 156685295f4SBill Fenner len += base / 8; 157685295f4SBill Fenner /* pad with zeros */ 158685295f4SBill Fenner if(flags & zero_flag){ 159685295f4SBill Fenner width -= len; 160685295f4SBill Fenner if(minusp || (flags & space_flag) || (flags & plus_flag)) 161685295f4SBill Fenner width--; 162685295f4SBill Fenner while(width-- > 0){ 163685295f4SBill Fenner if((*state->append_char)(state, '0')) 164685295f4SBill Fenner return 1; 165685295f4SBill Fenner len++; 166685295f4SBill Fenner } 167685295f4SBill Fenner } 168685295f4SBill Fenner /* add alternate prefix */ 169685295f4SBill Fenner if(flags & alternate_flag && (base == 16 || base == 8)){ 170685295f4SBill Fenner if(base == 16) 171685295f4SBill Fenner if((*state->append_char)(state, rep[10] + 23)) /* XXX */ 172685295f4SBill Fenner return 1; 173685295f4SBill Fenner if((*state->append_char)(state, '0')) 174685295f4SBill Fenner return 1; 175685295f4SBill Fenner } 176685295f4SBill Fenner /* add sign */ 177685295f4SBill Fenner if(minusp){ 178685295f4SBill Fenner if((*state->append_char)(state, '-')) 179685295f4SBill Fenner return 1; 180685295f4SBill Fenner len++; 181685295f4SBill Fenner } else if(flags & plus_flag) { 182685295f4SBill Fenner if((*state->append_char)(state, '+')) 183685295f4SBill Fenner return 1; 184685295f4SBill Fenner len++; 185685295f4SBill Fenner } else if(flags & space_flag) { 186685295f4SBill Fenner if((*state->append_char)(state, ' ')) 187685295f4SBill Fenner return 1; 188685295f4SBill Fenner len++; 189685295f4SBill Fenner } 190685295f4SBill Fenner if(flags & minus_flag) 191685295f4SBill Fenner /* swap before padding with spaces */ 192685295f4SBill Fenner for(i = 0; i < len / 2; i++){ 193685295f4SBill Fenner char c = state->s[-i-1]; 194685295f4SBill Fenner state->s[-i-1] = state->s[-len+i]; 195685295f4SBill Fenner state->s[-len+i] = c; 196685295f4SBill Fenner } 197685295f4SBill Fenner width -= len; 198685295f4SBill Fenner while(width-- > 0){ 199685295f4SBill Fenner if((*state->append_char)(state, ' ')) 200685295f4SBill Fenner return 1; 201685295f4SBill Fenner len++; 202685295f4SBill Fenner } 203685295f4SBill Fenner if(!(flags & minus_flag)) 204685295f4SBill Fenner /* swap after padding with spaces */ 205685295f4SBill Fenner for(i = 0; i < len / 2; i++){ 206685295f4SBill Fenner char c = state->s[-i-1]; 207685295f4SBill Fenner state->s[-i-1] = state->s[-len+i]; 208685295f4SBill Fenner state->s[-len+i] = c; 209685295f4SBill Fenner } 210685295f4SBill Fenner 211685295f4SBill Fenner return 0; 212685295f4SBill Fenner } 213685295f4SBill Fenner 214685295f4SBill Fenner static int 215685295f4SBill Fenner append_string (struct state *state, 216685295f4SBill Fenner unsigned char *arg, 217685295f4SBill Fenner int width, 218685295f4SBill Fenner int prec, 219685295f4SBill Fenner int flags) 220685295f4SBill Fenner { 221685295f4SBill Fenner if(prec != -1) 222685295f4SBill Fenner width -= prec; 223685295f4SBill Fenner else 224685295f4SBill Fenner width -= strlen((char *)arg); 225685295f4SBill Fenner if(!(flags & minus_flag)) 226685295f4SBill Fenner while(width-- > 0) 227685295f4SBill Fenner if((*state->append_char) (state, ' ')) 228685295f4SBill Fenner return 1; 229685295f4SBill Fenner if (prec != -1) { 230685295f4SBill Fenner while (*arg && prec--) 231685295f4SBill Fenner if ((*state->append_char) (state, *arg++)) 232685295f4SBill Fenner return 1; 233685295f4SBill Fenner } else { 234685295f4SBill Fenner while (*arg) 235685295f4SBill Fenner if ((*state->append_char) (state, *arg++)) 236685295f4SBill Fenner return 1; 237685295f4SBill Fenner } 238685295f4SBill Fenner if(flags & minus_flag) 239685295f4SBill Fenner while(width-- > 0) 240685295f4SBill Fenner if((*state->append_char) (state, ' ')) 241685295f4SBill Fenner return 1; 242685295f4SBill Fenner return 0; 243685295f4SBill Fenner } 244685295f4SBill Fenner 245685295f4SBill Fenner static int 246685295f4SBill Fenner append_char(struct state *state, 247685295f4SBill Fenner unsigned char arg, 248685295f4SBill Fenner int width, 249685295f4SBill Fenner int flags) 250685295f4SBill Fenner { 251685295f4SBill Fenner while(!(flags & minus_flag) && --width > 0) 252685295f4SBill Fenner if((*state->append_char) (state, ' ')) 253685295f4SBill Fenner return 1; 254685295f4SBill Fenner 255685295f4SBill Fenner if((*state->append_char) (state, arg)) 256685295f4SBill Fenner return 1; 257685295f4SBill Fenner while((flags & minus_flag) && --width > 0) 258685295f4SBill Fenner if((*state->append_char) (state, ' ')) 259685295f4SBill Fenner return 1; 260685295f4SBill Fenner 261685295f4SBill Fenner return 0; 262685295f4SBill Fenner } 263685295f4SBill Fenner 264685295f4SBill Fenner /* 265685295f4SBill Fenner * This can't be made into a function... 266685295f4SBill Fenner */ 267685295f4SBill Fenner 268685295f4SBill Fenner #define PARSE_INT_FORMAT(res, arg, unsig) \ 269685295f4SBill Fenner if (long_flag) \ 270685295f4SBill Fenner res = (unsig long)va_arg(arg, unsig long); \ 271685295f4SBill Fenner else if (short_flag) \ 272685295f4SBill Fenner res = (unsig short)va_arg(arg, unsig int); \ 273685295f4SBill Fenner else \ 274685295f4SBill Fenner res = (unsig int)va_arg(arg, unsig int) 275685295f4SBill Fenner 276685295f4SBill Fenner /* 277685295f4SBill Fenner * zyxprintf - return 0 or -1 278685295f4SBill Fenner */ 279685295f4SBill Fenner 280685295f4SBill Fenner static int 281685295f4SBill Fenner xyzprintf (struct state *state, const char *char_format, va_list ap) 282685295f4SBill Fenner { 283685295f4SBill Fenner const unsigned char *format = (const unsigned char *)char_format; 284685295f4SBill Fenner unsigned char c; 285685295f4SBill Fenner 286685295f4SBill Fenner while((c = *format++)) { 287685295f4SBill Fenner if (c == '%') { 288685295f4SBill Fenner int flags = 0; 289685295f4SBill Fenner int width = 0; 290685295f4SBill Fenner int prec = -1; 291685295f4SBill Fenner int long_flag = 0; 292685295f4SBill Fenner int short_flag = 0; 293685295f4SBill Fenner 294685295f4SBill Fenner /* flags */ 295685295f4SBill Fenner while((c = *format++)){ 296685295f4SBill Fenner if(c == '-') 297685295f4SBill Fenner flags |= minus_flag; 298685295f4SBill Fenner else if(c == '+') 299685295f4SBill Fenner flags |= plus_flag; 300685295f4SBill Fenner else if(c == ' ') 301685295f4SBill Fenner flags |= space_flag; 302685295f4SBill Fenner else if(c == '#') 303685295f4SBill Fenner flags |= alternate_flag; 304685295f4SBill Fenner else if(c == '0') 305685295f4SBill Fenner flags |= zero_flag; 306685295f4SBill Fenner else 307685295f4SBill Fenner break; 308685295f4SBill Fenner } 309685295f4SBill Fenner 310685295f4SBill Fenner if((flags & space_flag) && (flags & plus_flag)) 311685295f4SBill Fenner flags ^= space_flag; 312685295f4SBill Fenner 313685295f4SBill Fenner if((flags & minus_flag) && (flags & zero_flag)) 314685295f4SBill Fenner flags ^= zero_flag; 315685295f4SBill Fenner 316685295f4SBill Fenner /* width */ 317685295f4SBill Fenner if (isdigit(c)) 318685295f4SBill Fenner do { 319685295f4SBill Fenner width = width * 10 + c - '0'; 320685295f4SBill Fenner c = *format++; 321685295f4SBill Fenner } while(isdigit(c)); 322685295f4SBill Fenner else if(c == '*') { 323685295f4SBill Fenner width = va_arg(ap, int); 324685295f4SBill Fenner c = *format++; 325685295f4SBill Fenner } 326685295f4SBill Fenner 327685295f4SBill Fenner /* precision */ 328685295f4SBill Fenner if (c == '.') { 329685295f4SBill Fenner prec = 0; 330685295f4SBill Fenner c = *format++; 331685295f4SBill Fenner if (isdigit(c)) 332685295f4SBill Fenner do { 333685295f4SBill Fenner prec = prec * 10 + c - '0'; 334685295f4SBill Fenner c = *format++; 335685295f4SBill Fenner } while(isdigit(c)); 336685295f4SBill Fenner else if (c == '*') { 337685295f4SBill Fenner prec = va_arg(ap, int); 338685295f4SBill Fenner c = *format++; 339685295f4SBill Fenner } 340685295f4SBill Fenner } 341685295f4SBill Fenner 342685295f4SBill Fenner /* size */ 343685295f4SBill Fenner 344685295f4SBill Fenner if (c == 'h') { 345685295f4SBill Fenner short_flag = 1; 346685295f4SBill Fenner c = *format++; 347685295f4SBill Fenner } else if (c == 'l') { 348685295f4SBill Fenner long_flag = 1; 349685295f4SBill Fenner c = *format++; 350685295f4SBill Fenner } 351685295f4SBill Fenner 352685295f4SBill Fenner switch (c) { 353685295f4SBill Fenner case 'c' : 354685295f4SBill Fenner if(append_char(state, va_arg(ap, int), width, flags)) 355685295f4SBill Fenner return -1; 356685295f4SBill Fenner break; 357685295f4SBill Fenner case 's' : 358685295f4SBill Fenner if (append_string(state, 359685295f4SBill Fenner va_arg(ap, unsigned char*), 360685295f4SBill Fenner width, 361685295f4SBill Fenner prec, 362685295f4SBill Fenner flags)) 363685295f4SBill Fenner return -1; 364685295f4SBill Fenner break; 365685295f4SBill Fenner case 'd' : 366685295f4SBill Fenner case 'i' : { 367685295f4SBill Fenner long arg; 368685295f4SBill Fenner unsigned long num; 369685295f4SBill Fenner int minusp = 0; 370685295f4SBill Fenner 371685295f4SBill Fenner PARSE_INT_FORMAT(arg, ap, signed); 372685295f4SBill Fenner 373685295f4SBill Fenner if (arg < 0) { 374685295f4SBill Fenner minusp = 1; 375685295f4SBill Fenner num = -arg; 376685295f4SBill Fenner } else 377685295f4SBill Fenner num = arg; 378685295f4SBill Fenner 379685295f4SBill Fenner if (append_number (state, num, 10, "0123456789", 380685295f4SBill Fenner width, prec, flags, minusp)) 381685295f4SBill Fenner return -1; 382685295f4SBill Fenner break; 383685295f4SBill Fenner } 384685295f4SBill Fenner case 'u' : { 385685295f4SBill Fenner unsigned long arg; 386685295f4SBill Fenner 387685295f4SBill Fenner PARSE_INT_FORMAT(arg, ap, unsigned); 388685295f4SBill Fenner 389685295f4SBill Fenner if (append_number (state, arg, 10, "0123456789", 390685295f4SBill Fenner width, prec, flags, 0)) 391685295f4SBill Fenner return -1; 392685295f4SBill Fenner break; 393685295f4SBill Fenner } 394685295f4SBill Fenner case 'o' : { 395685295f4SBill Fenner unsigned long arg; 396685295f4SBill Fenner 397685295f4SBill Fenner PARSE_INT_FORMAT(arg, ap, unsigned); 398685295f4SBill Fenner 399685295f4SBill Fenner if (append_number (state, arg, 010, "01234567", 400685295f4SBill Fenner width, prec, flags, 0)) 401685295f4SBill Fenner return -1; 402685295f4SBill Fenner break; 403685295f4SBill Fenner } 404685295f4SBill Fenner case 'x' : { 405685295f4SBill Fenner unsigned long arg; 406685295f4SBill Fenner 407685295f4SBill Fenner PARSE_INT_FORMAT(arg, ap, unsigned); 408685295f4SBill Fenner 409685295f4SBill Fenner if (append_number (state, arg, 0x10, "0123456789abcdef", 410685295f4SBill Fenner width, prec, flags, 0)) 411685295f4SBill Fenner return -1; 412685295f4SBill Fenner break; 413685295f4SBill Fenner } 414685295f4SBill Fenner case 'X' :{ 415685295f4SBill Fenner unsigned long arg; 416685295f4SBill Fenner 417685295f4SBill Fenner PARSE_INT_FORMAT(arg, ap, unsigned); 418685295f4SBill Fenner 419685295f4SBill Fenner if (append_number (state, arg, 0x10, "0123456789ABCDEF", 420685295f4SBill Fenner width, prec, flags, 0)) 421685295f4SBill Fenner return -1; 422685295f4SBill Fenner break; 423685295f4SBill Fenner } 424685295f4SBill Fenner case 'p' : { 425685295f4SBill Fenner unsigned long arg = (unsigned long)va_arg(ap, void*); 426685295f4SBill Fenner 427685295f4SBill Fenner if (append_number (state, arg, 0x10, "0123456789ABCDEF", 428685295f4SBill Fenner width, prec, flags, 0)) 429685295f4SBill Fenner return -1; 430685295f4SBill Fenner break; 431685295f4SBill Fenner } 432685295f4SBill Fenner case 'n' : { 433685295f4SBill Fenner int *arg = va_arg(ap, int*); 434685295f4SBill Fenner *arg = state->s - state->str; 435685295f4SBill Fenner break; 436685295f4SBill Fenner } 437685295f4SBill Fenner case '\0' : 438685295f4SBill Fenner --format; 439685295f4SBill Fenner /* FALLTHROUGH */ 440685295f4SBill Fenner case '%' : 441685295f4SBill Fenner if ((*state->append_char)(state, c)) 442685295f4SBill Fenner return -1; 443685295f4SBill Fenner break; 444685295f4SBill Fenner default : 445685295f4SBill Fenner if ( (*state->append_char)(state, '%') 446685295f4SBill Fenner || (*state->append_char)(state, c)) 447685295f4SBill Fenner return -1; 448685295f4SBill Fenner break; 449685295f4SBill Fenner } 450685295f4SBill Fenner } else 451685295f4SBill Fenner if ((*state->append_char) (state, c)) 452685295f4SBill Fenner return -1; 453685295f4SBill Fenner } 454685295f4SBill Fenner return 0; 455685295f4SBill Fenner } 456685295f4SBill Fenner 457685295f4SBill Fenner #ifndef HAVE_SNPRINTF 458685295f4SBill Fenner int 459685295f4SBill Fenner snprintf (char *str, size_t sz, const char *format, ...) 460685295f4SBill Fenner { 461685295f4SBill Fenner va_list args; 462685295f4SBill Fenner int ret; 463685295f4SBill Fenner 464685295f4SBill Fenner va_start(args, format); 465685295f4SBill Fenner ret = vsnprintf (str, sz, format, args); 466685295f4SBill Fenner 467685295f4SBill Fenner #ifdef PARANOIA 468685295f4SBill Fenner { 469685295f4SBill Fenner int ret2; 470685295f4SBill Fenner char *tmp; 471685295f4SBill Fenner 472685295f4SBill Fenner tmp = malloc (sz); 473685295f4SBill Fenner if (tmp == NULL) 474685295f4SBill Fenner abort (); 475685295f4SBill Fenner 476685295f4SBill Fenner ret2 = vsprintf (tmp, format, args); 477685295f4SBill Fenner if (ret != ret2 || strcmp(str, tmp)) 478685295f4SBill Fenner abort (); 479685295f4SBill Fenner free (tmp); 480685295f4SBill Fenner } 481685295f4SBill Fenner #endif 482685295f4SBill Fenner 483685295f4SBill Fenner va_end(args); 484685295f4SBill Fenner return ret; 485685295f4SBill Fenner } 486685295f4SBill Fenner #endif 487685295f4SBill Fenner 488a90e161bSBill Fenner #if 0 489685295f4SBill Fenner #ifndef HAVE_ASPRINTF 490685295f4SBill Fenner int 491685295f4SBill Fenner asprintf (char **ret, const char *format, ...) 492685295f4SBill Fenner { 493685295f4SBill Fenner va_list args; 494685295f4SBill Fenner int val; 495685295f4SBill Fenner 496685295f4SBill Fenner va_start(args, format); 497685295f4SBill Fenner val = vasprintf (ret, format, args); 498685295f4SBill Fenner 499685295f4SBill Fenner #ifdef PARANOIA 500685295f4SBill Fenner { 501685295f4SBill Fenner int ret2; 502685295f4SBill Fenner char *tmp; 503685295f4SBill Fenner tmp = malloc (val + 1); 504685295f4SBill Fenner if (tmp == NULL) 505685295f4SBill Fenner abort (); 506685295f4SBill Fenner 507685295f4SBill Fenner ret2 = vsprintf (tmp, format, args); 508685295f4SBill Fenner if (val != ret2 || strcmp(*ret, tmp)) 509685295f4SBill Fenner abort (); 510685295f4SBill Fenner free (tmp); 511685295f4SBill Fenner } 512685295f4SBill Fenner #endif 513685295f4SBill Fenner 514685295f4SBill Fenner va_end(args); 515685295f4SBill Fenner return val; 516685295f4SBill Fenner } 517685295f4SBill Fenner #endif 518685295f4SBill Fenner 519685295f4SBill Fenner #ifndef HAVE_ASNPRINTF 520685295f4SBill Fenner int 521685295f4SBill Fenner asnprintf (char **ret, size_t max_sz, const char *format, ...) 522685295f4SBill Fenner { 523685295f4SBill Fenner va_list args; 524685295f4SBill Fenner int val; 525685295f4SBill Fenner 526685295f4SBill Fenner va_start(args, format); 527685295f4SBill Fenner val = vasnprintf (ret, max_sz, format, args); 528685295f4SBill Fenner 529685295f4SBill Fenner #ifdef PARANOIA 530685295f4SBill Fenner { 531685295f4SBill Fenner int ret2; 532685295f4SBill Fenner char *tmp; 533685295f4SBill Fenner tmp = malloc (val + 1); 534685295f4SBill Fenner if (tmp == NULL) 535685295f4SBill Fenner abort (); 536685295f4SBill Fenner 537685295f4SBill Fenner ret2 = vsprintf (tmp, format, args); 538685295f4SBill Fenner if (val != ret2 || strcmp(*ret, tmp)) 539685295f4SBill Fenner abort (); 540685295f4SBill Fenner free (tmp); 541685295f4SBill Fenner } 542685295f4SBill Fenner #endif 543685295f4SBill Fenner 544685295f4SBill Fenner va_end(args); 545685295f4SBill Fenner return val; 546685295f4SBill Fenner } 547685295f4SBill Fenner #endif 548685295f4SBill Fenner 549685295f4SBill Fenner #ifndef HAVE_VASPRINTF 550685295f4SBill Fenner int 551685295f4SBill Fenner vasprintf (char **ret, const char *format, va_list args) 552685295f4SBill Fenner { 553685295f4SBill Fenner return vasnprintf (ret, 0, format, args); 554685295f4SBill Fenner } 555685295f4SBill Fenner #endif 556685295f4SBill Fenner 557685295f4SBill Fenner 558685295f4SBill Fenner #ifndef HAVE_VASNPRINTF 559685295f4SBill Fenner int 560685295f4SBill Fenner vasnprintf (char **ret, size_t max_sz, const char *format, va_list args) 561685295f4SBill Fenner { 562685295f4SBill Fenner int st; 563685295f4SBill Fenner size_t len; 564685295f4SBill Fenner struct state state; 565685295f4SBill Fenner 566685295f4SBill Fenner state.max_sz = max_sz; 567685295f4SBill Fenner state.sz = 1; 568685295f4SBill Fenner state.str = malloc(state.sz); 569685295f4SBill Fenner if (state.str == NULL) { 570685295f4SBill Fenner *ret = NULL; 571685295f4SBill Fenner return -1; 572685295f4SBill Fenner } 573685295f4SBill Fenner state.s = state.str; 574685295f4SBill Fenner state.theend = state.s + state.sz - 1; 575685295f4SBill Fenner state.append_char = as_append_char; 576685295f4SBill Fenner state.reserve = as_reserve; 577685295f4SBill Fenner 578685295f4SBill Fenner st = xyzprintf (&state, format, args); 579685295f4SBill Fenner if (st) { 580685295f4SBill Fenner free (state.str); 581685295f4SBill Fenner *ret = NULL; 582685295f4SBill Fenner return -1; 583685295f4SBill Fenner } else { 584685295f4SBill Fenner char *tmp; 585685295f4SBill Fenner 586685295f4SBill Fenner *state.s = '\0'; 587685295f4SBill Fenner len = state.s - state.str; 588685295f4SBill Fenner tmp = realloc (state.str, len+1); 589685295f4SBill Fenner if (tmp == NULL) { 590685295f4SBill Fenner free (state.str); 591685295f4SBill Fenner *ret = NULL; 592685295f4SBill Fenner return -1; 593685295f4SBill Fenner } 594685295f4SBill Fenner *ret = tmp; 595685295f4SBill Fenner return len; 596685295f4SBill Fenner } 597685295f4SBill Fenner } 598685295f4SBill Fenner #endif 599a90e161bSBill Fenner #endif 600685295f4SBill Fenner 601685295f4SBill Fenner #ifndef HAVE_VSNPRINTF 602685295f4SBill Fenner int 603685295f4SBill Fenner vsnprintf (char *str, size_t sz, const char *format, va_list args) 604685295f4SBill Fenner { 605685295f4SBill Fenner struct state state; 606685295f4SBill Fenner int ret; 607685295f4SBill Fenner unsigned char *ustr = (unsigned char *)str; 608685295f4SBill Fenner 609685295f4SBill Fenner state.max_sz = 0; 610685295f4SBill Fenner state.sz = sz; 611685295f4SBill Fenner state.str = ustr; 612685295f4SBill Fenner state.s = ustr; 613685295f4SBill Fenner state.theend = ustr + sz - 1; 614685295f4SBill Fenner state.append_char = sn_append_char; 615685295f4SBill Fenner state.reserve = sn_reserve; 616685295f4SBill Fenner 617685295f4SBill Fenner ret = xyzprintf (&state, format, args); 618685295f4SBill Fenner *state.s = '\0'; 619685295f4SBill Fenner if (ret) 620685295f4SBill Fenner return sz; 621685295f4SBill Fenner else 622685295f4SBill Fenner return state.s - state.str; 623685295f4SBill Fenner } 624685295f4SBill Fenner #endif 625685295f4SBill Fenner 626