xref: /aosp_15_r20/external/libcups/cups/snprintf.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * snprintf functions for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2021 by OpenPrinting
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2007-2019 by Apple Inc.
6*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 1997-2007 by Easy Software Products.
7*5e7646d2SAndroid Build Coastguard Worker  *
8*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
9*5e7646d2SAndroid Build Coastguard Worker  * information.
10*5e7646d2SAndroid Build Coastguard Worker  */
11*5e7646d2SAndroid Build Coastguard Worker 
12*5e7646d2SAndroid Build Coastguard Worker /*
13*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
14*5e7646d2SAndroid Build Coastguard Worker  */
15*5e7646d2SAndroid Build Coastguard Worker 
16*5e7646d2SAndroid Build Coastguard Worker #include "string-private.h"
17*5e7646d2SAndroid Build Coastguard Worker 
18*5e7646d2SAndroid Build Coastguard Worker 
19*5e7646d2SAndroid Build Coastguard Worker #ifndef HAVE_VSNPRINTF
20*5e7646d2SAndroid Build Coastguard Worker /*
21*5e7646d2SAndroid Build Coastguard Worker  * '_cups_vsnprintf()' - Format a string into a fixed size buffer.
22*5e7646d2SAndroid Build Coastguard Worker  */
23*5e7646d2SAndroid Build Coastguard Worker 
24*5e7646d2SAndroid Build Coastguard Worker int					/* O - Number of bytes formatted */
_cups_vsnprintf(char * buffer,size_t bufsize,const char * format,va_list ap)25*5e7646d2SAndroid Build Coastguard Worker _cups_vsnprintf(char       *buffer,	/* O - Output buffer */
26*5e7646d2SAndroid Build Coastguard Worker                 size_t     bufsize,	/* O - Size of output buffer */
27*5e7646d2SAndroid Build Coastguard Worker 	        const char *format,	/* I - printf-style format string */
28*5e7646d2SAndroid Build Coastguard Worker 	        va_list    ap)		/* I - Pointer to additional arguments */
29*5e7646d2SAndroid Build Coastguard Worker {
30*5e7646d2SAndroid Build Coastguard Worker   char		*bufptr,		/* Pointer to position in buffer */
31*5e7646d2SAndroid Build Coastguard Worker 		*bufend,		/* Pointer to end of buffer */
32*5e7646d2SAndroid Build Coastguard Worker 		sign,			/* Sign of format width */
33*5e7646d2SAndroid Build Coastguard Worker 		size,			/* Size character (h, l, L) */
34*5e7646d2SAndroid Build Coastguard Worker 		type;			/* Format type character */
35*5e7646d2SAndroid Build Coastguard Worker   int		width,			/* Width of field */
36*5e7646d2SAndroid Build Coastguard Worker 		prec;			/* Number of characters of precision */
37*5e7646d2SAndroid Build Coastguard Worker   char		tformat[100],		/* Temporary format string for sprintf() */
38*5e7646d2SAndroid Build Coastguard Worker 		*tptr,			/* Pointer into temporary format */
39*5e7646d2SAndroid Build Coastguard Worker 		temp[1024];		/* Buffer for formatted numbers */
40*5e7646d2SAndroid Build Coastguard Worker   size_t	templen;		/* Length of "temp" */
41*5e7646d2SAndroid Build Coastguard Worker   char		*s;			/* Pointer to string */
42*5e7646d2SAndroid Build Coastguard Worker   int		slen;			/* Length of string */
43*5e7646d2SAndroid Build Coastguard Worker   int		bytes;			/* Total number of bytes needed */
44*5e7646d2SAndroid Build Coastguard Worker 
45*5e7646d2SAndroid Build Coastguard Worker 
46*5e7646d2SAndroid Build Coastguard Worker  /*
47*5e7646d2SAndroid Build Coastguard Worker   * Loop through the format string, formatting as needed...
48*5e7646d2SAndroid Build Coastguard Worker   */
49*5e7646d2SAndroid Build Coastguard Worker 
50*5e7646d2SAndroid Build Coastguard Worker   bufptr = buffer;
51*5e7646d2SAndroid Build Coastguard Worker   bufend = buffer + bufsize - 1;
52*5e7646d2SAndroid Build Coastguard Worker   bytes  = 0;
53*5e7646d2SAndroid Build Coastguard Worker 
54*5e7646d2SAndroid Build Coastguard Worker   while (*format)
55*5e7646d2SAndroid Build Coastguard Worker   {
56*5e7646d2SAndroid Build Coastguard Worker     if (*format == '%')
57*5e7646d2SAndroid Build Coastguard Worker     {
58*5e7646d2SAndroid Build Coastguard Worker       tptr = tformat;
59*5e7646d2SAndroid Build Coastguard Worker       *tptr++ = *format++;
60*5e7646d2SAndroid Build Coastguard Worker 
61*5e7646d2SAndroid Build Coastguard Worker       if (*format == '%')
62*5e7646d2SAndroid Build Coastguard Worker       {
63*5e7646d2SAndroid Build Coastguard Worker         if (bufptr && bufptr < bufend) *bufptr++ = *format;
64*5e7646d2SAndroid Build Coastguard Worker         bytes ++;
65*5e7646d2SAndroid Build Coastguard Worker         format ++;
66*5e7646d2SAndroid Build Coastguard Worker 	continue;
67*5e7646d2SAndroid Build Coastguard Worker       }
68*5e7646d2SAndroid Build Coastguard Worker       else if (strchr(" -+#\'", *format))
69*5e7646d2SAndroid Build Coastguard Worker       {
70*5e7646d2SAndroid Build Coastguard Worker         *tptr++ = *format;
71*5e7646d2SAndroid Build Coastguard Worker         sign = *format++;
72*5e7646d2SAndroid Build Coastguard Worker       }
73*5e7646d2SAndroid Build Coastguard Worker       else
74*5e7646d2SAndroid Build Coastguard Worker         sign = 0;
75*5e7646d2SAndroid Build Coastguard Worker 
76*5e7646d2SAndroid Build Coastguard Worker       if (*format == '*')
77*5e7646d2SAndroid Build Coastguard Worker       {
78*5e7646d2SAndroid Build Coastguard Worker        /*
79*5e7646d2SAndroid Build Coastguard Worker         * Get width from argument...
80*5e7646d2SAndroid Build Coastguard Worker 	*/
81*5e7646d2SAndroid Build Coastguard Worker 
82*5e7646d2SAndroid Build Coastguard Worker 	format ++;
83*5e7646d2SAndroid Build Coastguard Worker 	width = va_arg(ap, int);
84*5e7646d2SAndroid Build Coastguard Worker 
85*5e7646d2SAndroid Build Coastguard Worker         /* Note: Can't use snprintf here since we are implementing this function... */
86*5e7646d2SAndroid Build Coastguard Worker 	sprintf(tptr, "%d", width);
87*5e7646d2SAndroid Build Coastguard Worker 	tptr += strlen(tptr);
88*5e7646d2SAndroid Build Coastguard Worker       }
89*5e7646d2SAndroid Build Coastguard Worker       else
90*5e7646d2SAndroid Build Coastguard Worker       {
91*5e7646d2SAndroid Build Coastguard Worker 	width = 0;
92*5e7646d2SAndroid Build Coastguard Worker 
93*5e7646d2SAndroid Build Coastguard Worker 	while (isdigit(*format & 255))
94*5e7646d2SAndroid Build Coastguard Worker 	{
95*5e7646d2SAndroid Build Coastguard Worker 	  if (tptr < (tformat + sizeof(tformat) - 1))
96*5e7646d2SAndroid Build Coastguard Worker 	    *tptr++ = *format;
97*5e7646d2SAndroid Build Coastguard Worker 
98*5e7646d2SAndroid Build Coastguard Worker 	  width = width * 10 + *format++ - '0';
99*5e7646d2SAndroid Build Coastguard Worker 	}
100*5e7646d2SAndroid Build Coastguard Worker       }
101*5e7646d2SAndroid Build Coastguard Worker 
102*5e7646d2SAndroid Build Coastguard Worker       if (*format == '.')
103*5e7646d2SAndroid Build Coastguard Worker       {
104*5e7646d2SAndroid Build Coastguard Worker 	if (tptr < (tformat + sizeof(tformat) - 1))
105*5e7646d2SAndroid Build Coastguard Worker 	  *tptr++ = *format;
106*5e7646d2SAndroid Build Coastguard Worker 
107*5e7646d2SAndroid Build Coastguard Worker         format ++;
108*5e7646d2SAndroid Build Coastguard Worker 
109*5e7646d2SAndroid Build Coastguard Worker         if (*format == '*')
110*5e7646d2SAndroid Build Coastguard Worker 	{
111*5e7646d2SAndroid Build Coastguard Worker          /*
112*5e7646d2SAndroid Build Coastguard Worker 	  * Get precision from argument...
113*5e7646d2SAndroid Build Coastguard Worker 	  */
114*5e7646d2SAndroid Build Coastguard Worker 
115*5e7646d2SAndroid Build Coastguard Worker 	  format ++;
116*5e7646d2SAndroid Build Coastguard Worker 	  prec = va_arg(ap, int);
117*5e7646d2SAndroid Build Coastguard Worker 
118*5e7646d2SAndroid Build Coastguard Worker           /* Note: Can't use snprintf here since we are implementing this function... */
119*5e7646d2SAndroid Build Coastguard Worker 	  sprintf(tptr, "%d", prec);
120*5e7646d2SAndroid Build Coastguard Worker 	  tptr += strlen(tptr);
121*5e7646d2SAndroid Build Coastguard Worker 	}
122*5e7646d2SAndroid Build Coastguard Worker 	else
123*5e7646d2SAndroid Build Coastguard Worker 	{
124*5e7646d2SAndroid Build Coastguard Worker 	  prec = 0;
125*5e7646d2SAndroid Build Coastguard Worker 
126*5e7646d2SAndroid Build Coastguard Worker 	  while (isdigit(*format & 255))
127*5e7646d2SAndroid Build Coastguard Worker 	  {
128*5e7646d2SAndroid Build Coastguard Worker 	    if (tptr < (tformat + sizeof(tformat) - 1))
129*5e7646d2SAndroid Build Coastguard Worker 	      *tptr++ = *format;
130*5e7646d2SAndroid Build Coastguard Worker 
131*5e7646d2SAndroid Build Coastguard Worker 	    prec = prec * 10 + *format++ - '0';
132*5e7646d2SAndroid Build Coastguard Worker 	  }
133*5e7646d2SAndroid Build Coastguard Worker 	}
134*5e7646d2SAndroid Build Coastguard Worker       }
135*5e7646d2SAndroid Build Coastguard Worker       else
136*5e7646d2SAndroid Build Coastguard Worker         prec = -1;
137*5e7646d2SAndroid Build Coastguard Worker 
138*5e7646d2SAndroid Build Coastguard Worker       if (*format == 'l' && format[1] == 'l')
139*5e7646d2SAndroid Build Coastguard Worker       {
140*5e7646d2SAndroid Build Coastguard Worker         size = 'L';
141*5e7646d2SAndroid Build Coastguard Worker 
142*5e7646d2SAndroid Build Coastguard Worker 	if (tptr < (tformat + sizeof(tformat) - 2))
143*5e7646d2SAndroid Build Coastguard Worker 	{
144*5e7646d2SAndroid Build Coastguard Worker 	  *tptr++ = 'l';
145*5e7646d2SAndroid Build Coastguard Worker 	  *tptr++ = 'l';
146*5e7646d2SAndroid Build Coastguard Worker 	}
147*5e7646d2SAndroid Build Coastguard Worker 
148*5e7646d2SAndroid Build Coastguard Worker 	format += 2;
149*5e7646d2SAndroid Build Coastguard Worker       }
150*5e7646d2SAndroid Build Coastguard Worker       else if (*format == 'h' || *format == 'l' || *format == 'L')
151*5e7646d2SAndroid Build Coastguard Worker       {
152*5e7646d2SAndroid Build Coastguard Worker 	if (tptr < (tformat + sizeof(tformat) - 1))
153*5e7646d2SAndroid Build Coastguard Worker 	  *tptr++ = *format;
154*5e7646d2SAndroid Build Coastguard Worker 
155*5e7646d2SAndroid Build Coastguard Worker         size = *format++;
156*5e7646d2SAndroid Build Coastguard Worker       }
157*5e7646d2SAndroid Build Coastguard Worker 
158*5e7646d2SAndroid Build Coastguard Worker       if (!*format)
159*5e7646d2SAndroid Build Coastguard Worker         break;
160*5e7646d2SAndroid Build Coastguard Worker 
161*5e7646d2SAndroid Build Coastguard Worker       if (tptr < (tformat + sizeof(tformat) - 1))
162*5e7646d2SAndroid Build Coastguard Worker         *tptr++ = *format;
163*5e7646d2SAndroid Build Coastguard Worker 
164*5e7646d2SAndroid Build Coastguard Worker       type  = *format++;
165*5e7646d2SAndroid Build Coastguard Worker       *tptr = '\0';
166*5e7646d2SAndroid Build Coastguard Worker 
167*5e7646d2SAndroid Build Coastguard Worker       switch (type)
168*5e7646d2SAndroid Build Coastguard Worker       {
169*5e7646d2SAndroid Build Coastguard Worker 	case 'E' : /* Floating point formats */
170*5e7646d2SAndroid Build Coastguard Worker 	case 'G' :
171*5e7646d2SAndroid Build Coastguard Worker 	case 'e' :
172*5e7646d2SAndroid Build Coastguard Worker 	case 'f' :
173*5e7646d2SAndroid Build Coastguard Worker 	case 'g' :
174*5e7646d2SAndroid Build Coastguard Worker 	    if ((width + 2) > sizeof(temp))
175*5e7646d2SAndroid Build Coastguard Worker 	      break;
176*5e7646d2SAndroid Build Coastguard Worker 
177*5e7646d2SAndroid Build Coastguard Worker             /* Note: Can't use snprintf here since we are implementing this function... */
178*5e7646d2SAndroid Build Coastguard Worker 	    sprintf(temp, tformat, va_arg(ap, double));
179*5e7646d2SAndroid Build Coastguard Worker 	    templen = strlen(temp);
180*5e7646d2SAndroid Build Coastguard Worker 
181*5e7646d2SAndroid Build Coastguard Worker             bytes += (int)templen;
182*5e7646d2SAndroid Build Coastguard Worker 
183*5e7646d2SAndroid Build Coastguard Worker             if (bufptr)
184*5e7646d2SAndroid Build Coastguard Worker 	    {
185*5e7646d2SAndroid Build Coastguard Worker 	      if ((bufptr + templen) > bufend)
186*5e7646d2SAndroid Build Coastguard Worker 	      {
187*5e7646d2SAndroid Build Coastguard Worker 		strlcpy(bufptr, temp, (size_t)(bufend - bufptr));
188*5e7646d2SAndroid Build Coastguard Worker 		bufptr = bufend;
189*5e7646d2SAndroid Build Coastguard Worker 	      }
190*5e7646d2SAndroid Build Coastguard Worker 	      else
191*5e7646d2SAndroid Build Coastguard Worker 	      {
192*5e7646d2SAndroid Build Coastguard Worker 		memcpy(bufptr, temp, templen + 1);
193*5e7646d2SAndroid Build Coastguard Worker 		bufptr += templen;
194*5e7646d2SAndroid Build Coastguard Worker 	      }
195*5e7646d2SAndroid Build Coastguard Worker 	    }
196*5e7646d2SAndroid Build Coastguard Worker 	    break;
197*5e7646d2SAndroid Build Coastguard Worker 
198*5e7646d2SAndroid Build Coastguard Worker         case 'B' : /* Integer formats */
199*5e7646d2SAndroid Build Coastguard Worker 	case 'X' :
200*5e7646d2SAndroid Build Coastguard Worker 	case 'b' :
201*5e7646d2SAndroid Build Coastguard Worker         case 'd' :
202*5e7646d2SAndroid Build Coastguard Worker 	case 'i' :
203*5e7646d2SAndroid Build Coastguard Worker 	case 'o' :
204*5e7646d2SAndroid Build Coastguard Worker 	case 'u' :
205*5e7646d2SAndroid Build Coastguard Worker 	case 'x' :
206*5e7646d2SAndroid Build Coastguard Worker 	    if ((width + 2) > sizeof(temp))
207*5e7646d2SAndroid Build Coastguard Worker 	      break;
208*5e7646d2SAndroid Build Coastguard Worker 
209*5e7646d2SAndroid Build Coastguard Worker 	    /* Note: Can't use snprintf here since we are implementing this function... */
210*5e7646d2SAndroid Build Coastguard Worker 	    sprintf(temp, tformat, va_arg(ap, int));
211*5e7646d2SAndroid Build Coastguard Worker 	    templen = strlen(temp);
212*5e7646d2SAndroid Build Coastguard Worker 
213*5e7646d2SAndroid Build Coastguard Worker             bytes += (int)templen;
214*5e7646d2SAndroid Build Coastguard Worker 
215*5e7646d2SAndroid Build Coastguard Worker 	    if (bufptr)
216*5e7646d2SAndroid Build Coastguard Worker 	    {
217*5e7646d2SAndroid Build Coastguard Worker 	      if ((bufptr + templen) > bufend)
218*5e7646d2SAndroid Build Coastguard Worker 	      {
219*5e7646d2SAndroid Build Coastguard Worker 		strlcpy(bufptr, temp, (size_t)(bufend - bufptr));
220*5e7646d2SAndroid Build Coastguard Worker 		bufptr = bufend;
221*5e7646d2SAndroid Build Coastguard Worker 	      }
222*5e7646d2SAndroid Build Coastguard Worker 	      else
223*5e7646d2SAndroid Build Coastguard Worker 	      {
224*5e7646d2SAndroid Build Coastguard Worker 		memcpy(bufptr, temp, templen + 1);
225*5e7646d2SAndroid Build Coastguard Worker 		bufptr += templen;
226*5e7646d2SAndroid Build Coastguard Worker 	      }
227*5e7646d2SAndroid Build Coastguard Worker 	    }
228*5e7646d2SAndroid Build Coastguard Worker 	    break;
229*5e7646d2SAndroid Build Coastguard Worker 
230*5e7646d2SAndroid Build Coastguard Worker 	case 'p' : /* Pointer value */
231*5e7646d2SAndroid Build Coastguard Worker 	    if ((width + 2) > sizeof(temp))
232*5e7646d2SAndroid Build Coastguard Worker 	      break;
233*5e7646d2SAndroid Build Coastguard Worker 
234*5e7646d2SAndroid Build Coastguard Worker 	    /* Note: Can't use snprintf here since we are implementing this function... */
235*5e7646d2SAndroid Build Coastguard Worker 	    sprintf(temp, tformat, va_arg(ap, void *));
236*5e7646d2SAndroid Build Coastguard Worker 	    templen = strlen(temp);
237*5e7646d2SAndroid Build Coastguard Worker 
238*5e7646d2SAndroid Build Coastguard Worker             bytes += (int)templen;
239*5e7646d2SAndroid Build Coastguard Worker 
240*5e7646d2SAndroid Build Coastguard Worker 	    if (bufptr)
241*5e7646d2SAndroid Build Coastguard Worker 	    {
242*5e7646d2SAndroid Build Coastguard Worker 	      if ((bufptr + templen) > bufend)
243*5e7646d2SAndroid Build Coastguard Worker 	      {
244*5e7646d2SAndroid Build Coastguard Worker 		strlcpy(bufptr, temp, (size_t)(bufend - bufptr));
245*5e7646d2SAndroid Build Coastguard Worker 		bufptr = bufend;
246*5e7646d2SAndroid Build Coastguard Worker 	      }
247*5e7646d2SAndroid Build Coastguard Worker 	      else
248*5e7646d2SAndroid Build Coastguard Worker 	      {
249*5e7646d2SAndroid Build Coastguard Worker 		memcpy(bufptr, temp, templen + 1);
250*5e7646d2SAndroid Build Coastguard Worker 		bufptr += templen;
251*5e7646d2SAndroid Build Coastguard Worker 	      }
252*5e7646d2SAndroid Build Coastguard Worker 	    }
253*5e7646d2SAndroid Build Coastguard Worker 	    break;
254*5e7646d2SAndroid Build Coastguard Worker 
255*5e7646d2SAndroid Build Coastguard Worker         case 'c' : /* Character or character array */
256*5e7646d2SAndroid Build Coastguard Worker 	    bytes += width;
257*5e7646d2SAndroid Build Coastguard Worker 
258*5e7646d2SAndroid Build Coastguard Worker 	    if (bufptr)
259*5e7646d2SAndroid Build Coastguard Worker 	    {
260*5e7646d2SAndroid Build Coastguard Worker 	      if (width <= 1)
261*5e7646d2SAndroid Build Coastguard Worker 	        *bufptr++ = va_arg(ap, int);
262*5e7646d2SAndroid Build Coastguard Worker 	      else
263*5e7646d2SAndroid Build Coastguard Worker 	      {
264*5e7646d2SAndroid Build Coastguard Worker 		if ((bufptr + width) > bufend)
265*5e7646d2SAndroid Build Coastguard Worker 		  width = (int)(bufend - bufptr);
266*5e7646d2SAndroid Build Coastguard Worker 
267*5e7646d2SAndroid Build Coastguard Worker 		memcpy(bufptr, va_arg(ap, char *), (size_t)width);
268*5e7646d2SAndroid Build Coastguard Worker 		bufptr += width;
269*5e7646d2SAndroid Build Coastguard Worker 	      }
270*5e7646d2SAndroid Build Coastguard Worker 	    }
271*5e7646d2SAndroid Build Coastguard Worker 	    break;
272*5e7646d2SAndroid Build Coastguard Worker 
273*5e7646d2SAndroid Build Coastguard Worker 	case 's' : /* String */
274*5e7646d2SAndroid Build Coastguard Worker 	    if ((s = va_arg(ap, char *)) == NULL)
275*5e7646d2SAndroid Build Coastguard Worker 	      s = "(null)";
276*5e7646d2SAndroid Build Coastguard Worker 
277*5e7646d2SAndroid Build Coastguard Worker 	    slen = (int)strlen(s);
278*5e7646d2SAndroid Build Coastguard Worker 	    if (slen > width && prec != width)
279*5e7646d2SAndroid Build Coastguard Worker 	      width = slen;
280*5e7646d2SAndroid Build Coastguard Worker 
281*5e7646d2SAndroid Build Coastguard Worker             bytes += width;
282*5e7646d2SAndroid Build Coastguard Worker 
283*5e7646d2SAndroid Build Coastguard Worker 	    if (bufptr)
284*5e7646d2SAndroid Build Coastguard Worker 	    {
285*5e7646d2SAndroid Build Coastguard Worker 	      if ((bufptr + width) > bufend)
286*5e7646d2SAndroid Build Coastguard Worker 	        width = (int)(bufend - bufptr);
287*5e7646d2SAndroid Build Coastguard Worker 
288*5e7646d2SAndroid Build Coastguard Worker               if (slen > width)
289*5e7646d2SAndroid Build Coastguard Worker 	        slen = width;
290*5e7646d2SAndroid Build Coastguard Worker 
291*5e7646d2SAndroid Build Coastguard Worker 	      if (sign == '-')
292*5e7646d2SAndroid Build Coastguard Worker 	      {
293*5e7646d2SAndroid Build Coastguard Worker 		memcpy(bufptr, s, (size_t)slen);
294*5e7646d2SAndroid Build Coastguard Worker 		memset(bufptr + slen, ' ', (size_t)(width - slen));
295*5e7646d2SAndroid Build Coastguard Worker 	      }
296*5e7646d2SAndroid Build Coastguard Worker 	      else
297*5e7646d2SAndroid Build Coastguard Worker 	      {
298*5e7646d2SAndroid Build Coastguard Worker 		memset(bufptr, ' ', (size_t)(width - slen));
299*5e7646d2SAndroid Build Coastguard Worker 		memcpy(bufptr + width - slen, s, (size_t)slen);
300*5e7646d2SAndroid Build Coastguard Worker 	      }
301*5e7646d2SAndroid Build Coastguard Worker 
302*5e7646d2SAndroid Build Coastguard Worker 	      bufptr += width;
303*5e7646d2SAndroid Build Coastguard Worker 	    }
304*5e7646d2SAndroid Build Coastguard Worker 	    break;
305*5e7646d2SAndroid Build Coastguard Worker 
306*5e7646d2SAndroid Build Coastguard Worker 	case 'n' : /* Output number of chars so far */
307*5e7646d2SAndroid Build Coastguard Worker 	    *(va_arg(ap, int *)) = bytes;
308*5e7646d2SAndroid Build Coastguard Worker 	    break;
309*5e7646d2SAndroid Build Coastguard Worker       }
310*5e7646d2SAndroid Build Coastguard Worker     }
311*5e7646d2SAndroid Build Coastguard Worker     else
312*5e7646d2SAndroid Build Coastguard Worker     {
313*5e7646d2SAndroid Build Coastguard Worker       bytes ++;
314*5e7646d2SAndroid Build Coastguard Worker 
315*5e7646d2SAndroid Build Coastguard Worker       if (bufptr && bufptr < bufend)
316*5e7646d2SAndroid Build Coastguard Worker         *bufptr++ = *format;
317*5e7646d2SAndroid Build Coastguard Worker 
318*5e7646d2SAndroid Build Coastguard Worker       format ++;
319*5e7646d2SAndroid Build Coastguard Worker     }
320*5e7646d2SAndroid Build Coastguard Worker   }
321*5e7646d2SAndroid Build Coastguard Worker 
322*5e7646d2SAndroid Build Coastguard Worker  /*
323*5e7646d2SAndroid Build Coastguard Worker   * Nul-terminate the string and return the number of characters needed.
324*5e7646d2SAndroid Build Coastguard Worker   */
325*5e7646d2SAndroid Build Coastguard Worker 
326*5e7646d2SAndroid Build Coastguard Worker   if (bufptr && bufptr < bufend)
327*5e7646d2SAndroid Build Coastguard Worker 	*bufptr = '\0';
328*5e7646d2SAndroid Build Coastguard Worker 
329*5e7646d2SAndroid Build Coastguard Worker   return (bytes);
330*5e7646d2SAndroid Build Coastguard Worker }
331*5e7646d2SAndroid Build Coastguard Worker #endif /* !HAVE_VSNPRINT */
332*5e7646d2SAndroid Build Coastguard Worker 
333*5e7646d2SAndroid Build Coastguard Worker 
334*5e7646d2SAndroid Build Coastguard Worker #ifndef HAVE_SNPRINTF
335*5e7646d2SAndroid Build Coastguard Worker /*
336*5e7646d2SAndroid Build Coastguard Worker  * '_cups_snprintf()' - Format a string into a fixed size buffer.
337*5e7646d2SAndroid Build Coastguard Worker  */
338*5e7646d2SAndroid Build Coastguard Worker 
339*5e7646d2SAndroid Build Coastguard Worker int					/* O - Number of bytes formatted */
_cups_snprintf(char * buffer,size_t bufsize,const char * format,...)340*5e7646d2SAndroid Build Coastguard Worker _cups_snprintf(char       *buffer,	/* O - Output buffer */
341*5e7646d2SAndroid Build Coastguard Worker                size_t     bufsize,	/* O - Size of output buffer */
342*5e7646d2SAndroid Build Coastguard Worker                const char *format,	/* I - printf-style format string */
343*5e7646d2SAndroid Build Coastguard Worker 	       ...)			/* I - Additional arguments as needed */
344*5e7646d2SAndroid Build Coastguard Worker {
345*5e7646d2SAndroid Build Coastguard Worker   int		bytes;			/* Number of bytes formatted */
346*5e7646d2SAndroid Build Coastguard Worker   va_list 	ap;			/* Pointer to additional arguments */
347*5e7646d2SAndroid Build Coastguard Worker 
348*5e7646d2SAndroid Build Coastguard Worker 
349*5e7646d2SAndroid Build Coastguard Worker   va_start(ap, format);
350*5e7646d2SAndroid Build Coastguard Worker   bytes = vsnprintf(buffer, bufsize, format, ap);
351*5e7646d2SAndroid Build Coastguard Worker   va_end(ap);
352*5e7646d2SAndroid Build Coastguard Worker 
353*5e7646d2SAndroid Build Coastguard Worker   return (bytes);
354*5e7646d2SAndroid Build Coastguard Worker }
355*5e7646d2SAndroid Build Coastguard Worker #endif /* !HAVE_SNPRINTF */
356