honeyd/vasprintf.c

Mon, 28 Jan 2013 17:37:18 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 28 Jan 2013 17:37:18 +0100
changeset 758
a2c6460cfb16
permissions
-rw-r--r--

Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.

michael@574 1 /* Like vsprintf but provides a pointer to malloc'd storage, which must
michael@574 2 be freed by the caller.
michael@574 3 Copyright (C) 1994, 2003 Free Software Foundation, Inc.
michael@574 4
michael@574 5 This file is part of the libiberty library.
michael@574 6 Libiberty is free software; you can redistribute it and/or
michael@574 7 modify it under the terms of the GNU Library General Public
michael@574 8 License as published by the Free Software Foundation; either
michael@574 9 version 2 of the License, or (at your option) any later version.
michael@574 10
michael@574 11 Libiberty is distributed in the hope that it will be useful,
michael@574 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
michael@574 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
michael@574 14 Library General Public License for more details.
michael@574 15
michael@574 16 You should have received a copy of the GNU Library General Public
michael@574 17 License along with libiberty; see the file COPYING.LIB. If
michael@574 18 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
michael@574 19 Boston, MA 02111-1307, USA. */
michael@574 20
michael@574 21 #include <stdarg.h>
michael@574 22 #include <stdio.h>
michael@574 23 #include <stdlib.h>
michael@574 24 #include <string.h>
michael@574 25 #include "vasprintf.h"
michael@574 26
michael@574 27 /*
michael@574 28
michael@574 29 @deftypefn Extension int vasprintf (char **@var{resptr}, const char *@var{format}, va_list @var{args})
michael@574 30
michael@574 31 Like @code{vsprintf}, but instead of passing a pointer to a buffer,
michael@574 32 you pass a pointer to a pointer. This function will compute the size
michael@574 33 of the buffer needed, allocate memory with @code{malloc}, and store a
michael@574 34 pointer to the allocated memory in @code{*@var{resptr}}. The value
michael@574 35 returned is the same as @code{vsprintf} would return. If memory could
michael@574 36 not be allocated, minus one is returned and @code{NULL} is stored in
michael@574 37 @code{*@var{resptr}}.
michael@574 38
michael@574 39 @end deftypefn
michael@574 40
michael@574 41 */
michael@574 42
michael@574 43 static int int_vasprintf(char **, const char *, va_list);
michael@574 44
michael@574 45 static int
michael@574 46 int_vasprintf (result, format, args)
michael@574 47 char **result;
michael@574 48 const char *format;
michael@574 49 va_list args;
michael@574 50 {
michael@574 51 const char *p = format;
michael@574 52 /* Add one to make sure that it is never zero, which might cause malloc
michael@574 53 to return NULL. */
michael@574 54 int total_width = strlen (format) + 1;
michael@574 55 va_list ap;
michael@574 56
michael@574 57 memcpy ((void *) &ap, (const void *) &args, sizeof (va_list));
michael@574 58
michael@574 59 while (*p != '\0')
michael@574 60 {
michael@574 61 if (*p++ == '%')
michael@574 62 {
michael@574 63 while (strchr ("-+ #0", *p))
michael@574 64 ++p;
michael@574 65 if (*p == '*')
michael@574 66 {
michael@574 67 ++p;
michael@574 68 total_width += abs (va_arg (ap, int));
michael@574 69 }
michael@574 70 else
michael@574 71 total_width += strtoul (p, (char **) &p, 10);
michael@574 72 if (*p == '.')
michael@574 73 {
michael@574 74 ++p;
michael@574 75 if (*p == '*')
michael@574 76 {
michael@574 77 ++p;
michael@574 78 total_width += abs (va_arg (ap, int));
michael@574 79 }
michael@574 80 else
michael@574 81 total_width += strtoul (p, (char **) &p, 10);
michael@574 82 }
michael@574 83 while (strchr ("hlL", *p))
michael@574 84 ++p;
michael@574 85 /* Should be big enough for any format specifier except %s and floats. */
michael@574 86 total_width += 30;
michael@574 87 switch (*p)
michael@574 88 {
michael@574 89 case 'd':
michael@574 90 case 'i':
michael@574 91 case 'o':
michael@574 92 case 'u':
michael@574 93 case 'x':
michael@574 94 case 'X':
michael@574 95 case 'c':
michael@574 96 (void) va_arg (ap, int);
michael@574 97 break;
michael@574 98 case 'f':
michael@574 99 case 'e':
michael@574 100 case 'E':
michael@574 101 case 'g':
michael@574 102 case 'G':
michael@574 103 (void) va_arg (ap, double);
michael@574 104 /* Since an ieee double can have an exponent of 307, we'll
michael@574 105 make the buffer wide enough to cover the gross case. */
michael@574 106 total_width += 307;
michael@574 107 break;
michael@574 108 case 's':
michael@574 109 total_width += strlen (va_arg (ap, char *));
michael@574 110 break;
michael@574 111 case 'p':
michael@574 112 case 'n':
michael@574 113 (void) va_arg (ap, char *);
michael@574 114 break;
michael@574 115 }
michael@574 116 p++;
michael@574 117 }
michael@574 118 }
michael@574 119 *result = (char *) malloc (total_width);
michael@574 120 if (*result != NULL)
michael@574 121 return vsprintf (*result, format, args);
michael@574 122 else
michael@574 123 return -1;
michael@574 124 }
michael@574 125
michael@574 126 int
michael@574 127 vasprintf (result, format, args)
michael@574 128 char **result;
michael@574 129 const char *format;
michael@574 130 va_list args;
michael@574 131 {
michael@574 132 return int_vasprintf (result, format, args);
michael@574 133 }

mercurial