xref: /aosp_15_r20/external/tcpdump/missing/snprintf.c (revision 05b00f6010a2396e3db2409989fc67270046269f)
1*05b00f60SXin Li /*
2*05b00f60SXin Li  * Copyright (c) 1995-1999 Kungliga Tekniska H�gskolan
3*05b00f60SXin Li  * (Royal Institute of Technology, Stockholm, Sweden).
4*05b00f60SXin Li  * All rights reserved.
5*05b00f60SXin Li  *
6*05b00f60SXin Li  * Redistribution and use in source and binary forms, with or without
7*05b00f60SXin Li  * modification, are permitted provided that the following conditions
8*05b00f60SXin Li  * are met:
9*05b00f60SXin Li  *
10*05b00f60SXin Li  * 1. Redistributions of source code must retain the above copyright
11*05b00f60SXin Li  *    notice, this list of conditions and the following disclaimer.
12*05b00f60SXin Li  *
13*05b00f60SXin Li  * 2. Redistributions in binary form must reproduce the above copyright
14*05b00f60SXin Li  *    notice, this list of conditions and the following disclaimer in the
15*05b00f60SXin Li  *    documentation and/or other materials provided with the distribution.
16*05b00f60SXin Li  *
17*05b00f60SXin Li  * 3. Neither the name of the Institute nor the names of its contributors
18*05b00f60SXin Li  *    may be used to endorse or promote products derived from this software
19*05b00f60SXin Li  *    without specific prior written permission.
20*05b00f60SXin Li  *
21*05b00f60SXin Li  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22*05b00f60SXin Li  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*05b00f60SXin Li  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*05b00f60SXin Li  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25*05b00f60SXin Li  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*05b00f60SXin Li  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*05b00f60SXin Li  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*05b00f60SXin Li  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*05b00f60SXin Li  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*05b00f60SXin Li  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*05b00f60SXin Li  * SUCH DAMAGE.
32*05b00f60SXin Li  */
33*05b00f60SXin Li 
34*05b00f60SXin Li #ifdef HAVE_CONFIG_H
35*05b00f60SXin Li #include <config.h>
36*05b00f60SXin Li #endif
37*05b00f60SXin Li 
38*05b00f60SXin Li #include <stdio.h>
39*05b00f60SXin Li #include <stdarg.h>
40*05b00f60SXin Li #include <stdlib.h>
41*05b00f60SXin Li #include <string.h>
42*05b00f60SXin Li #include <ctype.h>
43*05b00f60SXin Li #include <sys/types.h>
44*05b00f60SXin Li 
45*05b00f60SXin Li #include "netdissect.h"
46*05b00f60SXin Li 
47*05b00f60SXin Li enum format_flags {
48*05b00f60SXin Li     minus_flag     =  1,
49*05b00f60SXin Li     plus_flag      =  2,
50*05b00f60SXin Li     space_flag     =  4,
51*05b00f60SXin Li     alternate_flag =  8,
52*05b00f60SXin Li     zero_flag      = 16
53*05b00f60SXin Li };
54*05b00f60SXin Li 
55*05b00f60SXin Li /*
56*05b00f60SXin Li  * Common state
57*05b00f60SXin Li  */
58*05b00f60SXin Li 
59*05b00f60SXin Li struct state {
60*05b00f60SXin Li   unsigned char *str;
61*05b00f60SXin Li   unsigned char *s;
62*05b00f60SXin Li   unsigned char *theend;
63*05b00f60SXin Li   size_t sz;
64*05b00f60SXin Li   size_t max_sz;
65*05b00f60SXin Li   int (*append_char)(struct state *, unsigned char);
66*05b00f60SXin Li   int (*reserve)(struct state *, size_t);
67*05b00f60SXin Li   /* XXX - methods */
68*05b00f60SXin Li };
69*05b00f60SXin Li 
70*05b00f60SXin Li #if 0
71*05b00f60SXin Li static int
72*05b00f60SXin Li as_reserve (struct state *state, size_t n)
73*05b00f60SXin Li {
74*05b00f60SXin Li   if (state->s + n > state->theend) {
75*05b00f60SXin Li     int off = state->s - state->str;
76*05b00f60SXin Li     unsigned char *tmp;
77*05b00f60SXin Li 
78*05b00f60SXin Li     if (state->max_sz && state->sz >= state->max_sz)
79*05b00f60SXin Li       return 1;
80*05b00f60SXin Li 
81*05b00f60SXin Li     state->sz = max(state->sz * 2, state->sz + n);
82*05b00f60SXin Li     if (state->max_sz)
83*05b00f60SXin Li       state->sz = min(state->sz, state->max_sz);
84*05b00f60SXin Li     tmp = realloc (state->str, state->sz);
85*05b00f60SXin Li     if (tmp == NULL)
86*05b00f60SXin Li       return 1;
87*05b00f60SXin Li     state->str = tmp;
88*05b00f60SXin Li     state->s = state->str + off;
89*05b00f60SXin Li     state->theend = state->str + state->sz - 1;
90*05b00f60SXin Li   }
91*05b00f60SXin Li   return 0;
92*05b00f60SXin Li }
93*05b00f60SXin Li 
94*05b00f60SXin Li static int
95*05b00f60SXin Li as_append_char (struct state *state, unsigned char c)
96*05b00f60SXin Li {
97*05b00f60SXin Li   if(as_reserve (state, 1))
98*05b00f60SXin Li     return 1;
99*05b00f60SXin Li   else {
100*05b00f60SXin Li     *state->s++ = c;
101*05b00f60SXin Li     return 0;
102*05b00f60SXin Li   }
103*05b00f60SXin Li }
104*05b00f60SXin Li #endif
105*05b00f60SXin Li 
106*05b00f60SXin Li static int
append_number(struct state * state,unsigned long num,unsigned base,char * rep,int width,int prec,int flags,int minusp)107*05b00f60SXin Li append_number(struct state *state,
108*05b00f60SXin Li 	      unsigned long num, unsigned base, char *rep,
109*05b00f60SXin Li 	      int width, int prec, int flags, int minusp)
110*05b00f60SXin Li {
111*05b00f60SXin Li   int len = 0;
112*05b00f60SXin Li   int i;
113*05b00f60SXin Li 
114*05b00f60SXin Li   /* given precision, ignore zero flag */
115*05b00f60SXin Li   if(prec != -1)
116*05b00f60SXin Li     flags &= ~zero_flag;
117*05b00f60SXin Li   else
118*05b00f60SXin Li     prec = 1;
119*05b00f60SXin Li   /* zero value with zero precision -> "" */
120*05b00f60SXin Li   if(prec == 0 && num == 0)
121*05b00f60SXin Li     return 0;
122*05b00f60SXin Li   do{
123*05b00f60SXin Li     if((*state->append_char)(state, rep[num % base]))
124*05b00f60SXin Li       return 1;
125*05b00f60SXin Li     len++;
126*05b00f60SXin Li     num /= base;
127*05b00f60SXin Li   }while(num);
128*05b00f60SXin Li   prec -= len;
129*05b00f60SXin Li   /* pad with prec zeros */
130*05b00f60SXin Li   while(prec-- > 0){
131*05b00f60SXin Li     if((*state->append_char)(state, '0'))
132*05b00f60SXin Li       return 1;
133*05b00f60SXin Li     len++;
134*05b00f60SXin Li   }
135*05b00f60SXin Li   /* add length of alternate prefix (added later) to len */
136*05b00f60SXin Li   if(flags & alternate_flag && (base == 16 || base == 8))
137*05b00f60SXin Li     len += base / 8;
138*05b00f60SXin Li   /* pad with zeros */
139*05b00f60SXin Li   if(flags & zero_flag){
140*05b00f60SXin Li     width -= len;
141*05b00f60SXin Li     if(minusp || (flags & space_flag) || (flags & plus_flag))
142*05b00f60SXin Li       width--;
143*05b00f60SXin Li     while(width-- > 0){
144*05b00f60SXin Li       if((*state->append_char)(state, '0'))
145*05b00f60SXin Li 	return 1;
146*05b00f60SXin Li       len++;
147*05b00f60SXin Li     }
148*05b00f60SXin Li   }
149*05b00f60SXin Li   /* add alternate prefix */
150*05b00f60SXin Li   if(flags & alternate_flag && (base == 16 || base == 8)){
151*05b00f60SXin Li     if(base == 16)
152*05b00f60SXin Li       if((*state->append_char)(state, rep[10] + 23)) /* XXX */
153*05b00f60SXin Li 	return 1;
154*05b00f60SXin Li     if((*state->append_char)(state, '0'))
155*05b00f60SXin Li       return 1;
156*05b00f60SXin Li   }
157*05b00f60SXin Li   /* add sign */
158*05b00f60SXin Li   if(minusp){
159*05b00f60SXin Li     if((*state->append_char)(state, '-'))
160*05b00f60SXin Li       return 1;
161*05b00f60SXin Li     len++;
162*05b00f60SXin Li   } else if(flags & plus_flag) {
163*05b00f60SXin Li     if((*state->append_char)(state, '+'))
164*05b00f60SXin Li       return 1;
165*05b00f60SXin Li     len++;
166*05b00f60SXin Li   } else if(flags & space_flag) {
167*05b00f60SXin Li     if((*state->append_char)(state, ' '))
168*05b00f60SXin Li       return 1;
169*05b00f60SXin Li     len++;
170*05b00f60SXin Li   }
171*05b00f60SXin Li   if(flags & minus_flag)
172*05b00f60SXin Li     /* swap before padding with spaces */
173*05b00f60SXin Li     for(i = 0; i < len / 2; i++){
174*05b00f60SXin Li       char c = state->s[-i-1];
175*05b00f60SXin Li       state->s[-i-1] = state->s[-len+i];
176*05b00f60SXin Li       state->s[-len+i] = c;
177*05b00f60SXin Li     }
178*05b00f60SXin Li   width -= len;
179*05b00f60SXin Li   while(width-- > 0){
180*05b00f60SXin Li     if((*state->append_char)(state,  ' '))
181*05b00f60SXin Li       return 1;
182*05b00f60SXin Li     len++;
183*05b00f60SXin Li   }
184*05b00f60SXin Li   if(!(flags & minus_flag))
185*05b00f60SXin Li     /* swap after padding with spaces */
186*05b00f60SXin Li     for(i = 0; i < len / 2; i++){
187*05b00f60SXin Li       char c = state->s[-i-1];
188*05b00f60SXin Li       state->s[-i-1] = state->s[-len+i];
189*05b00f60SXin Li       state->s[-len+i] = c;
190*05b00f60SXin Li     }
191*05b00f60SXin Li 
192*05b00f60SXin Li   return 0;
193*05b00f60SXin Li }
194*05b00f60SXin Li 
195*05b00f60SXin Li static int
append_string(struct state * state,unsigned char * arg,int width,int prec,int flags)196*05b00f60SXin Li append_string (struct state *state,
197*05b00f60SXin Li 	       unsigned char *arg,
198*05b00f60SXin Li 	       int width,
199*05b00f60SXin Li 	       int prec,
200*05b00f60SXin Li 	       int flags)
201*05b00f60SXin Li {
202*05b00f60SXin Li   if(prec != -1)
203*05b00f60SXin Li     width -= prec;
204*05b00f60SXin Li   else
205*05b00f60SXin Li     width -= strlen((char *)arg);
206*05b00f60SXin Li   if(!(flags & minus_flag))
207*05b00f60SXin Li     while(width-- > 0)
208*05b00f60SXin Li       if((*state->append_char) (state, ' '))
209*05b00f60SXin Li 	return 1;
210*05b00f60SXin Li   if (prec != -1) {
211*05b00f60SXin Li     while (*arg && prec--)
212*05b00f60SXin Li       if ((*state->append_char) (state, *arg++))
213*05b00f60SXin Li 	return 1;
214*05b00f60SXin Li   } else {
215*05b00f60SXin Li     while (*arg)
216*05b00f60SXin Li       if ((*state->append_char) (state, *arg++))
217*05b00f60SXin Li 	return 1;
218*05b00f60SXin Li   }
219*05b00f60SXin Li   if(flags & minus_flag)
220*05b00f60SXin Li     while(width-- > 0)
221*05b00f60SXin Li       if((*state->append_char) (state, ' '))
222*05b00f60SXin Li 	return 1;
223*05b00f60SXin Li   return 0;
224*05b00f60SXin Li }
225*05b00f60SXin Li 
226*05b00f60SXin Li static int
append_char(struct state * state,unsigned char arg,int width,int flags)227*05b00f60SXin Li append_char(struct state *state,
228*05b00f60SXin Li 	    unsigned char arg,
229*05b00f60SXin Li 	    int width,
230*05b00f60SXin Li 	    int flags)
231*05b00f60SXin Li {
232*05b00f60SXin Li   while(!(flags & minus_flag) && --width > 0)
233*05b00f60SXin Li     if((*state->append_char) (state, ' '))
234*05b00f60SXin Li       return 1;
235*05b00f60SXin Li 
236*05b00f60SXin Li   if((*state->append_char) (state, arg))
237*05b00f60SXin Li     return 1;
238*05b00f60SXin Li   while((flags & minus_flag) && --width > 0)
239*05b00f60SXin Li     if((*state->append_char) (state, ' '))
240*05b00f60SXin Li       return 1;
241*05b00f60SXin Li 
242*05b00f60SXin Li   return 0;
243*05b00f60SXin Li }
244*05b00f60SXin Li 
245*05b00f60SXin Li /*
246*05b00f60SXin Li  * This can't be made into a function...
247*05b00f60SXin Li  */
248*05b00f60SXin Li 
249*05b00f60SXin Li #define PARSE_INT_FORMAT(res, arg, unsig) \
250*05b00f60SXin Li if (long_flag) \
251*05b00f60SXin Li      res = (unsig long)va_arg(arg, unsig long); \
252*05b00f60SXin Li else if (short_flag) \
253*05b00f60SXin Li      res = (unsig short)va_arg(arg, unsig int); \
254*05b00f60SXin Li else \
255*05b00f60SXin Li      res = (unsig int)va_arg(arg, unsig int)
256*05b00f60SXin Li 
257*05b00f60SXin Li /*
258*05b00f60SXin Li  * zyxprintf - return 0 or -1
259*05b00f60SXin Li  */
260*05b00f60SXin Li 
261*05b00f60SXin Li static int
xyzprintf(struct state * state,const char * char_format,va_list ap)262*05b00f60SXin Li xyzprintf (struct state *state, const char *char_format, va_list ap)
263*05b00f60SXin Li {
264*05b00f60SXin Li   const unsigned char *format = (const unsigned char *)char_format;
265*05b00f60SXin Li   unsigned char c;
266*05b00f60SXin Li 
267*05b00f60SXin Li   while((c = *format++)) {
268*05b00f60SXin Li     if (c == '%') {
269*05b00f60SXin Li       int flags      = 0;
270*05b00f60SXin Li       int width      = 0;
271*05b00f60SXin Li       int prec       = -1;
272*05b00f60SXin Li       int long_flag  = 0;
273*05b00f60SXin Li       int short_flag = 0;
274*05b00f60SXin Li 
275*05b00f60SXin Li       /* flags */
276*05b00f60SXin Li       while((c = *format++)){
277*05b00f60SXin Li 	if(c == '-')
278*05b00f60SXin Li 	  flags |= minus_flag;
279*05b00f60SXin Li 	else if(c == '+')
280*05b00f60SXin Li 	  flags |= plus_flag;
281*05b00f60SXin Li 	else if(c == ' ')
282*05b00f60SXin Li 	  flags |= space_flag;
283*05b00f60SXin Li 	else if(c == '#')
284*05b00f60SXin Li 	  flags |= alternate_flag;
285*05b00f60SXin Li 	else if(c == '0')
286*05b00f60SXin Li 	  flags |= zero_flag;
287*05b00f60SXin Li 	else
288*05b00f60SXin Li 	  break;
289*05b00f60SXin Li       }
290*05b00f60SXin Li 
291*05b00f60SXin Li       if((flags & space_flag) && (flags & plus_flag))
292*05b00f60SXin Li 	flags ^= space_flag;
293*05b00f60SXin Li 
294*05b00f60SXin Li       if((flags & minus_flag) && (flags & zero_flag))
295*05b00f60SXin Li 	flags ^= zero_flag;
296*05b00f60SXin Li 
297*05b00f60SXin Li       /* width */
298*05b00f60SXin Li       if (isdigit(c))
299*05b00f60SXin Li 	do {
300*05b00f60SXin Li 	  width = width * 10 + c - '0';
301*05b00f60SXin Li 	  c = *format++;
302*05b00f60SXin Li 	} while(isdigit(c));
303*05b00f60SXin Li       else if(c == '*') {
304*05b00f60SXin Li 	width = va_arg(ap, int);
305*05b00f60SXin Li 	c = *format++;
306*05b00f60SXin Li       }
307*05b00f60SXin Li 
308*05b00f60SXin Li       /* precision */
309*05b00f60SXin Li       if (c == '.') {
310*05b00f60SXin Li 	prec = 0;
311*05b00f60SXin Li 	c = *format++;
312*05b00f60SXin Li 	if (isdigit(c))
313*05b00f60SXin Li 	  do {
314*05b00f60SXin Li 	    prec = prec * 10 + c - '0';
315*05b00f60SXin Li 	    c = *format++;
316*05b00f60SXin Li 	  } while(isdigit(c));
317*05b00f60SXin Li 	else if (c == '*') {
318*05b00f60SXin Li 	  prec = va_arg(ap, int);
319*05b00f60SXin Li 	  c = *format++;
320*05b00f60SXin Li 	}
321*05b00f60SXin Li       }
322*05b00f60SXin Li 
323*05b00f60SXin Li       /* size */
324*05b00f60SXin Li 
325*05b00f60SXin Li       if (c == 'h') {
326*05b00f60SXin Li 	short_flag = 1;
327*05b00f60SXin Li 	c = *format++;
328*05b00f60SXin Li       } else if (c == 'l') {
329*05b00f60SXin Li 	long_flag = 1;
330*05b00f60SXin Li 	c = *format++;
331*05b00f60SXin Li       }
332*05b00f60SXin Li 
333*05b00f60SXin Li       switch (c) {
334*05b00f60SXin Li       case 'c' :
335*05b00f60SXin Li 	if(append_char(state, va_arg(ap, int), width, flags))
336*05b00f60SXin Li 	  return -1;
337*05b00f60SXin Li 	break;
338*05b00f60SXin Li       case 's' :
339*05b00f60SXin Li 	if (append_string(state,
340*05b00f60SXin Li 			  va_arg(ap, unsigned char*),
341*05b00f60SXin Li 			  width,
342*05b00f60SXin Li 			  prec,
343*05b00f60SXin Li 			  flags))
344*05b00f60SXin Li 	  return -1;
345*05b00f60SXin Li 	break;
346*05b00f60SXin Li       case 'd' :
347*05b00f60SXin Li       case 'i' : {
348*05b00f60SXin Li 	long arg;
349*05b00f60SXin Li 	unsigned long num;
350*05b00f60SXin Li 	int minusp = 0;
351*05b00f60SXin Li 
352*05b00f60SXin Li 	PARSE_INT_FORMAT(arg, ap, signed);
353*05b00f60SXin Li 
354*05b00f60SXin Li 	if (arg < 0) {
355*05b00f60SXin Li 	  minusp = 1;
356*05b00f60SXin Li 	  num = -arg;
357*05b00f60SXin Li 	} else
358*05b00f60SXin Li 	  num = arg;
359*05b00f60SXin Li 
360*05b00f60SXin Li 	if (append_number (state, num, 10, "0123456789",
361*05b00f60SXin Li 			   width, prec, flags, minusp))
362*05b00f60SXin Li 	  return -1;
363*05b00f60SXin Li 	break;
364*05b00f60SXin Li       }
365*05b00f60SXin Li       case 'u' : {
366*05b00f60SXin Li 	unsigned long arg;
367*05b00f60SXin Li 
368*05b00f60SXin Li 	PARSE_INT_FORMAT(arg, ap, unsigned);
369*05b00f60SXin Li 
370*05b00f60SXin Li 	if (append_number (state, arg, 10, "0123456789",
371*05b00f60SXin Li 			   width, prec, flags, 0))
372*05b00f60SXin Li 	  return -1;
373*05b00f60SXin Li 	break;
374*05b00f60SXin Li       }
375*05b00f60SXin Li       case 'o' : {
376*05b00f60SXin Li 	unsigned long arg;
377*05b00f60SXin Li 
378*05b00f60SXin Li 	PARSE_INT_FORMAT(arg, ap, unsigned);
379*05b00f60SXin Li 
380*05b00f60SXin Li 	if (append_number (state, arg, 010, "01234567",
381*05b00f60SXin Li 			   width, prec, flags, 0))
382*05b00f60SXin Li 	  return -1;
383*05b00f60SXin Li 	break;
384*05b00f60SXin Li       }
385*05b00f60SXin Li       case 'x' : {
386*05b00f60SXin Li 	unsigned long arg;
387*05b00f60SXin Li 
388*05b00f60SXin Li 	PARSE_INT_FORMAT(arg, ap, unsigned);
389*05b00f60SXin Li 
390*05b00f60SXin Li 	if (append_number (state, arg, 0x10, "0123456789abcdef",
391*05b00f60SXin Li 			   width, prec, flags, 0))
392*05b00f60SXin Li 	  return -1;
393*05b00f60SXin Li 	break;
394*05b00f60SXin Li       }
395*05b00f60SXin Li       case 'X' :{
396*05b00f60SXin Li 	unsigned long arg;
397*05b00f60SXin Li 
398*05b00f60SXin Li 	PARSE_INT_FORMAT(arg, ap, unsigned);
399*05b00f60SXin Li 
400*05b00f60SXin Li 	if (append_number (state, arg, 0x10, "0123456789ABCDEF",
401*05b00f60SXin Li 			   width, prec, flags, 0))
402*05b00f60SXin Li 	  return -1;
403*05b00f60SXin Li 	break;
404*05b00f60SXin Li       }
405*05b00f60SXin Li       case 'p' : {
406*05b00f60SXin Li 	unsigned long arg = (unsigned long)va_arg(ap, void*);
407*05b00f60SXin Li 
408*05b00f60SXin Li 	if (append_number (state, arg, 0x10, "0123456789ABCDEF",
409*05b00f60SXin Li 			   width, prec, flags, 0))
410*05b00f60SXin Li 	  return -1;
411*05b00f60SXin Li 	break;
412*05b00f60SXin Li       }
413*05b00f60SXin Li       case 'n' : {
414*05b00f60SXin Li 	int *arg = va_arg(ap, int *);
415*05b00f60SXin Li 	*arg = state->s - state->str;
416*05b00f60SXin Li 	break;
417*05b00f60SXin Li       }
418*05b00f60SXin Li       case '\0' :
419*05b00f60SXin Li 	  --format;
420*05b00f60SXin Li 	  /* FALLTHROUGH */
421*05b00f60SXin Li       case '%' :
422*05b00f60SXin Li 	if ((*state->append_char)(state, c))
423*05b00f60SXin Li 	  return -1;
424*05b00f60SXin Li 	break;
425*05b00f60SXin Li       default :
426*05b00f60SXin Li 	if (   (*state->append_char)(state, '%')
427*05b00f60SXin Li 	    || (*state->append_char)(state, c))
428*05b00f60SXin Li 	  return -1;
429*05b00f60SXin Li 	break;
430*05b00f60SXin Li       }
431*05b00f60SXin Li     } else
432*05b00f60SXin Li       if ((*state->append_char) (state, c))
433*05b00f60SXin Li 	return -1;
434*05b00f60SXin Li   }
435*05b00f60SXin Li   return 0;
436*05b00f60SXin Li }
437*05b00f60SXin Li 
438*05b00f60SXin Li #if 0
439*05b00f60SXin Li #ifndef HAVE_ASPRINTF
440*05b00f60SXin Li int
441*05b00f60SXin Li asprintf (char **ret, const char *format, ...)
442*05b00f60SXin Li {
443*05b00f60SXin Li   va_list args;
444*05b00f60SXin Li   int val;
445*05b00f60SXin Li 
446*05b00f60SXin Li   va_start(args, format);
447*05b00f60SXin Li   val = vasprintf (ret, format, args);
448*05b00f60SXin Li 
449*05b00f60SXin Li #ifdef PARANOIA
450*05b00f60SXin Li   {
451*05b00f60SXin Li     int ret2;
452*05b00f60SXin Li     char *tmp;
453*05b00f60SXin Li     tmp = malloc (val + 1);
454*05b00f60SXin Li     if (tmp == NULL)
455*05b00f60SXin Li       abort ();
456*05b00f60SXin Li 
457*05b00f60SXin Li     ret2 = vsprintf (tmp, format, args);
458*05b00f60SXin Li     if (val != ret2 || strcmp(*ret, tmp))
459*05b00f60SXin Li       abort ();
460*05b00f60SXin Li     free (tmp);
461*05b00f60SXin Li   }
462*05b00f60SXin Li #endif
463*05b00f60SXin Li 
464*05b00f60SXin Li   va_end(args);
465*05b00f60SXin Li   return val;
466*05b00f60SXin Li }
467*05b00f60SXin Li #endif
468*05b00f60SXin Li 
469*05b00f60SXin Li #ifndef HAVE_VASNPRINTF
470*05b00f60SXin Li int
471*05b00f60SXin Li nd_vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
472*05b00f60SXin Li {
473*05b00f60SXin Li   int st;
474*05b00f60SXin Li   size_t len;
475*05b00f60SXin Li   struct state state;
476*05b00f60SXin Li 
477*05b00f60SXin Li   state.max_sz = max_sz;
478*05b00f60SXin Li   state.sz     = 1;
479*05b00f60SXin Li   state.str    = malloc(state.sz);
480*05b00f60SXin Li   if (state.str == NULL) {
481*05b00f60SXin Li     *ret = NULL;
482*05b00f60SXin Li     return -1;
483*05b00f60SXin Li   }
484*05b00f60SXin Li   state.s = state.str;
485*05b00f60SXin Li   state.theend = state.s + state.sz - 1;
486*05b00f60SXin Li   state.append_char = as_append_char;
487*05b00f60SXin Li   state.reserve     = as_reserve;
488*05b00f60SXin Li 
489*05b00f60SXin Li   st = xyzprintf (&state, format, args);
490*05b00f60SXin Li   if (st) {
491*05b00f60SXin Li     free (state.str);
492*05b00f60SXin Li     *ret = NULL;
493*05b00f60SXin Li     return -1;
494*05b00f60SXin Li   } else {
495*05b00f60SXin Li     char *tmp;
496*05b00f60SXin Li 
497*05b00f60SXin Li     *state.s = '\0';
498*05b00f60SXin Li     len = state.s - state.str;
499*05b00f60SXin Li     tmp = realloc (state.str, len+1);
500*05b00f60SXin Li     if (tmp == NULL) {
501*05b00f60SXin Li       free (state.str);
502*05b00f60SXin Li       *ret = NULL;
503*05b00f60SXin Li       return -1;
504*05b00f60SXin Li     }
505*05b00f60SXin Li     *ret = tmp;
506*05b00f60SXin Li     return len;
507*05b00f60SXin Li   }
508*05b00f60SXin Li }
509*05b00f60SXin Li #endif
510*05b00f60SXin Li #endif
511