PostGIS  2.1.10dev-r@@SVN_REVISION@@
vsprintf.c
Go to the documentation of this file.
1 /* Like vsprintf but provides a pointer to malloc'd storage, which must
2  be freed by the caller.
3  Copyright (C) 1994, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 
27 #if __STDC__
28 # include <stdarg.h>
29 #else
30 # include <varargs.h>
31 #endif
32 
33 #ifdef TEST
34 int global_total_width;
35 #endif
36 
37 /* Make sure we have a va_copy that will work on all platforms */
38 #ifndef va_copy
39 # ifdef __va_copy
40 # define va_copy(d, s) __va_copy((d), (s))
41 # else
42 # define va_copy(d, s) memcpy(&(d), &(s), sizeof(va_list))
43 # endif
44 #endif
45 
46 int lw_vasprintf (char **result, const char *format, va_list args);
47 int lw_asprintf
48 #if __STDC__
49 (char **result, const char *format, ...);
50 #else
51 (result, va_alist);
52 char **result;
53 va_dcl
54 #endif
55 
56 
57 static int
58 int_vasprintf (result, format, args)
59 char **result;
60 const char *format;
61 va_list *args;
62 {
63  const char *p = format;
64  /* Add one to make sure that it is never zero, which might cause malloc
65  to return NULL. */
66  int total_width = strlen (format) + 1;
67  va_list ap;
68 
69  memcpy (&ap, args, sizeof (va_list));
70 
71  while (*p != '\0')
72  {
73  if (*p++ == '%')
74  {
75  while (strchr ("-+ #0", *p))
76  ++p;
77  if (*p == '*')
78  {
79  ++p;
80  total_width += abs (va_arg (ap, int));
81  }
82  else
83  total_width += strtoul (p, (char **) &p, 10);
84  if (*p == '.')
85  {
86  ++p;
87  if (*p == '*')
88  {
89  ++p;
90  total_width += abs (va_arg (ap, int));
91  }
92  else
93  total_width += strtoul (p, (char **) &p, 10);
94  }
95  while (strchr ("hlLjtz", *p))
96  ++p;
97  /* Should be big enough for any format specifier except %s
98  and floats. */
99  total_width += 30;
100  switch (*p)
101  {
102  case 'd':
103  case 'i':
104  case 'o':
105  case 'u':
106  case 'x':
107  case 'X':
108  case 'c':
109  (void) va_arg (ap, int);
110  break;
111  case 'f':
112  {
113  double arg = va_arg (ap, double);
114  if (arg >= 1.0 || arg <= -1.0)
115  /* Since an ieee double can have an exponent of 307, we'll
116  make the buffer wide enough to cover the gross case. */
117  total_width += 307;
118  }
119  break;
120  case 'e':
121  case 'E':
122  case 'g':
123  case 'G':
124  (void) va_arg (ap, double);
125  break;
126  case 's':
127  total_width += strlen (va_arg (ap, char *));
128  break;
129  case 'p':
130  case 'n':
131  (void) va_arg (ap, char *);
132  break;
133  }
134  p++;
135  }
136  }
137 #ifdef TEST
138  global_total_width = total_width;
139 #endif
140  *result = malloc (total_width);
141  if (*result != NULL)
142  return vsprintf (*result, format, *args);
143  else
144  return 0;
145 }
146 
147 int
148 lw_vasprintf (result, format, args)
149 char **result;
150 const char *format;
151 va_list args;
152 {
153  va_list temp;
154 
155  va_copy(temp, args);
156 
157  return int_vasprintf (result, format, &temp);
158 }
159 
160 int
162 #if __STDC__
163 (char **result, const char *format, ...)
164 #else
165 (result, va_alist)
166 char **result;
167 va_dcl
168 #endif
169 {
170  va_list args;
171  int done;
172 
173 #if __STDC__
174  va_start (args, format);
175 #else
176  char *format;
177  va_start (args);
178  format = va_arg (args, char *);
179 #endif
180  done = lw_vasprintf (result, format, args);
181  va_end (args);
182 
183  return done;
184 }
int lw_asprintf(result, va_alist)
int lw_vasprintf(char **result, const char *format, va_list args)
Definition: vsprintf.c:148
char ** result
Definition: vsprintf.c:52
static va_dcl int int_vasprintf(char **result, const char *format, va_list *args)
Definition: vsprintf.c:58
#define va_copy(d, s)
Definition: vsprintf.c:42