Annotation of embedaddon/lrzsz/lib/vasprintf.c, revision 1.1.1.1
1.1 misho 1: /* Like vsprintf but provides a pointer to malloc'd storage, which must
2: be freed by the caller.
3: Copyright (C) 1994 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 <stdlib.h>
25: #include <string.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: /* unsigned long strtoul (); */
38: /* char *malloc (); */
39:
40: static int
41: int_vasprintf (result, format, args)
42: char **result;
43: const char *format;
44: va_list *args;
45: {
46: const char *p = format;
47: /* Add one to make sure that it is never zero, which might cause malloc
48: to return NULL. */
49: int total_width = strlen (format) + 1;
50: va_list ap;
51:
52: memcpy (&ap, args, sizeof (va_list));
53:
54: while (*p != '\0')
55: {
56: if (*p++ == '%')
57: {
58: while (strchr ("-+ #0", *p))
59: ++p;
60: if (*p == '*')
61: {
62: ++p;
63: total_width += abs (va_arg (ap, int));
64: }
65: else
66: total_width += strtoul (p, &p, 10);
67: if (*p == '.')
68: {
69: ++p;
70: if (*p == '*')
71: {
72: ++p;
73: total_width += abs (va_arg (ap, int));
74: }
75: else
76: total_width += strtoul (p, &p, 10);
77: }
78: while (strchr ("hlL", *p))
79: ++p;
80: /* Should be big enough for any format specifier except %s. */
81: total_width += 30;
82: switch (*p)
83: {
84: case 'd':
85: case 'i':
86: case 'o':
87: case 'u':
88: case 'x':
89: case 'X':
90: case 'c':
91: (void) va_arg (ap, int);
92: break;
93: case 'f':
94: case 'e':
95: case 'E':
96: case 'g':
97: case 'G':
98: (void) va_arg (ap, double);
99: break;
100: case 's':
101: total_width += strlen (va_arg (ap, char *));
102: break;
103: case 'p':
104: case 'n':
105: (void) va_arg (ap, char *);
106: break;
107: }
108: }
109: }
110: #ifdef TEST
111: global_total_width = total_width;
112: #endif
113: *result = malloc (total_width);
114: if (*result != NULL)
115: return vsprintf (*result, format, *args);
116: else
117: return 0;
118: }
119:
120: int
121: vasprintf (result, format, args)
122: char **result;
123: const char *format;
124: va_list args;
125: {
126: return int_vasprintf (result, format, &args);
127: }
128:
129: int
130: asprintf
131: #if __STDC__
132: (char **result, const char *format, ...)
133: #else
134: (result, va_alist)
135: char **result;
136: va_dcl
137: #endif
138: {
139: va_list args;
140: int done;
141:
142: #if __STDC__
143: va_start (args, format);
144: #else
145: char *format;
146: va_start (args);
147: format = va_arg (args, char *);
148: #endif
149: done = vasprintf (result, format, args);
150: va_end (args);
151:
152: return done;
153: }
154:
155: #ifdef TEST
156: void
157: checkit
158: #if __STDC__
159: (const char* format, ...)
160: #else
161: (va_alist)
162: va_dcl
163: #endif
164: {
165: va_list args;
166: char *result;
167:
168: #if __STDC__
169: va_start (args, format);
170: #else
171: char *format;
172: va_start (args);
173: format = va_arg (args, char *);
174: #endif
175: vasprintf (&result, format, args);
176: if (strlen (result) < global_total_width)
177: printf ("PASS: ");
178: else
179: printf ("FAIL: ");
180: printf ("%d %s\n", global_total_width, result);
181: }
182:
183: int
184: main ()
185: {
186: checkit ("%d", 0x12345678);
187: checkit ("%200d", 5);
188: checkit ("%.300d", 6);
189: checkit ("%100.150d", 7);
190: checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
191: 777777777777777777333333333333366666666666622222222222777777777777733333");
192: checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
193: }
194: #endif /* TEST */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>