honeyd/vasprintf.c

Mon, 17 Sep 2012 19:10:10 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 17 Sep 2012 19:10:10 +0200
changeset 689
9fe04d4d4e5a
permissions
-rw-r--r--

Update to new version of vendor software although Oracle fails to deliver.
More specifically, newer db(3) patch revisions exist but Oracle has
removed them from the canonical download server URI for Berkely DB.

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