1*4d9fdb46SRobert Mustacchi /*
2*4d9fdb46SRobert Mustacchi Copyright (c) 2019-2019, David Anderson
3*4d9fdb46SRobert Mustacchi All rights reserved.
4*4d9fdb46SRobert Mustacchi 
5*4d9fdb46SRobert Mustacchi Redistribution and use in source and binary forms, with
6*4d9fdb46SRobert Mustacchi or without modification, are permitted provided that the
7*4d9fdb46SRobert Mustacchi following conditions are met:
8*4d9fdb46SRobert Mustacchi 
9*4d9fdb46SRobert Mustacchi     Redistributions of source code must retain the above
10*4d9fdb46SRobert Mustacchi     copyright notice, this list of conditions and the following
11*4d9fdb46SRobert Mustacchi     disclaimer.
12*4d9fdb46SRobert Mustacchi 
13*4d9fdb46SRobert Mustacchi     Redistributions in binary form must reproduce the above
14*4d9fdb46SRobert Mustacchi     copyright notice, this list of conditions and the following
15*4d9fdb46SRobert Mustacchi     disclaimer in the documentation and/or other materials
16*4d9fdb46SRobert Mustacchi     provided with the distribution.
17*4d9fdb46SRobert Mustacchi 
18*4d9fdb46SRobert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19*4d9fdb46SRobert Mustacchi CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20*4d9fdb46SRobert Mustacchi INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21*4d9fdb46SRobert Mustacchi OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*4d9fdb46SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23*4d9fdb46SRobert Mustacchi CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*4d9fdb46SRobert Mustacchi SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25*4d9fdb46SRobert Mustacchi NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26*4d9fdb46SRobert Mustacchi LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*4d9fdb46SRobert Mustacchi HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*4d9fdb46SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29*4d9fdb46SRobert Mustacchi OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30*4d9fdb46SRobert Mustacchi EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*4d9fdb46SRobert Mustacchi */
32*4d9fdb46SRobert Mustacchi 
33*4d9fdb46SRobert Mustacchi /*  A lighly generalized data buffer.
34*4d9fdb46SRobert Mustacchi     Works for more than just strings,
35*4d9fdb46SRobert Mustacchi     but has features (such as ensuring
36*4d9fdb46SRobert Mustacchi     data always has a NUL byte following
37*4d9fdb46SRobert Mustacchi     the data area used) most useful for C strings.
38*4d9fdb46SRobert Mustacchi 
39*4d9fdb46SRobert Mustacchi     All these return either TRUE (the values altered)
40*4d9fdb46SRobert Mustacchi     or FALSE (something went wrong, quite likely
41*4d9fdb46SRobert Mustacchi     the caller presented a bad format string for the
42*4d9fdb46SRobert Mustacchi     value).
43*4d9fdb46SRobert Mustacchi */
44*4d9fdb46SRobert Mustacchi 
45*4d9fdb46SRobert Mustacchi #include "config.h"
46*4d9fdb46SRobert Mustacchi #include <stdio.h> /* for malloc */
47*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
48*4d9fdb46SRobert Mustacchi #include <stdlib.h> /* for malloc */
49*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
50*4d9fdb46SRobert Mustacchi #include <string.h> /* for strlen */
51*4d9fdb46SRobert Mustacchi #ifdef HAVE_MALLOC_H
52*4d9fdb46SRobert Mustacchi /* Useful include for some Windows compilers. */
53*4d9fdb46SRobert Mustacchi #include <malloc.h>
54*4d9fdb46SRobert Mustacchi #endif /* HAVE_MALLOC_H */
55*4d9fdb46SRobert Mustacchi #include "dwarfstring.h"
56*4d9fdb46SRobert Mustacchi #ifndef TRUE
57*4d9fdb46SRobert Mustacchi #define TRUE 1
58*4d9fdb46SRobert Mustacchi #endif /* TRUE */
59*4d9fdb46SRobert Mustacchi #ifndef FALSE
60*4d9fdb46SRobert Mustacchi #define FALSE 0
61*4d9fdb46SRobert Mustacchi #endif /* FALSE */
62*4d9fdb46SRobert Mustacchi 
63*4d9fdb46SRobert Mustacchi #ifdef HAVE_UNUSED_ATTRIBUTE
64*4d9fdb46SRobert Mustacchi #define  UNUSEDARG __attribute__ ((unused))
65*4d9fdb46SRobert Mustacchi #else
66*4d9fdb46SRobert Mustacchi #define  UNUSEDARG
67*4d9fdb46SRobert Mustacchi #endif
68*4d9fdb46SRobert Mustacchi 
69*4d9fdb46SRobert Mustacchi 
70*4d9fdb46SRobert Mustacchi static unsigned long minimumnewlen = 30;
71*4d9fdb46SRobert Mustacchi /*
72*4d9fdb46SRobert Mustacchi struct dwarfstring_s {
73*4d9fdb46SRobert Mustacchi    char *        s_data;
74*4d9fdb46SRobert Mustacchi    unsigned long s_size;
75*4d9fdb46SRobert Mustacchi    unsigned long s_avail;
76*4d9fdb46SRobert Mustacchi    unsigned char s_malloc;
77*4d9fdb46SRobert Mustacchi };
78*4d9fdb46SRobert Mustacchi */
79*4d9fdb46SRobert Mustacchi 
80*4d9fdb46SRobert Mustacchi int
dwarfstring_constructor(struct dwarfstring_s * g)81*4d9fdb46SRobert Mustacchi dwarfstring_constructor(struct dwarfstring_s *g)
82*4d9fdb46SRobert Mustacchi {
83*4d9fdb46SRobert Mustacchi     g->s_data = "";
84*4d9fdb46SRobert Mustacchi     g->s_size = 0;
85*4d9fdb46SRobert Mustacchi     g->s_avail = 0;
86*4d9fdb46SRobert Mustacchi     g->s_malloc = FALSE;
87*4d9fdb46SRobert Mustacchi     return TRUE;
88*4d9fdb46SRobert Mustacchi }
89*4d9fdb46SRobert Mustacchi 
90*4d9fdb46SRobert Mustacchi static int
dwarfstring_resize_to(struct dwarfstring_s * g,unsigned long newlen)91*4d9fdb46SRobert Mustacchi dwarfstring_resize_to(struct dwarfstring_s *g,unsigned long newlen)
92*4d9fdb46SRobert Mustacchi {
93*4d9fdb46SRobert Mustacchi     char *b = 0;
94*4d9fdb46SRobert Mustacchi     unsigned long lastpos =
95*4d9fdb46SRobert Mustacchi         g->s_size - g->s_avail;
96*4d9fdb46SRobert Mustacchi     unsigned long malloclen = newlen+1;
97*4d9fdb46SRobert Mustacchi 
98*4d9fdb46SRobert Mustacchi     if(malloclen < minimumnewlen) {
99*4d9fdb46SRobert Mustacchi         malloclen = minimumnewlen;
100*4d9fdb46SRobert Mustacchi     }
101*4d9fdb46SRobert Mustacchi     b = malloc(malloclen);
102*4d9fdb46SRobert Mustacchi     if (!b) {
103*4d9fdb46SRobert Mustacchi         return FALSE;
104*4d9fdb46SRobert Mustacchi     }
105*4d9fdb46SRobert Mustacchi     if (lastpos > 0) {
106*4d9fdb46SRobert Mustacchi         memcpy(b,g->s_data,lastpos);
107*4d9fdb46SRobert Mustacchi     }
108*4d9fdb46SRobert Mustacchi     if (g->s_malloc) {
109*4d9fdb46SRobert Mustacchi         free(g->s_data);
110*4d9fdb46SRobert Mustacchi         g->s_data = 0;
111*4d9fdb46SRobert Mustacchi     }
112*4d9fdb46SRobert Mustacchi     g->s_data = b;
113*4d9fdb46SRobert Mustacchi     g->s_data[lastpos] = 0;
114*4d9fdb46SRobert Mustacchi     g->s_size = newlen;
115*4d9fdb46SRobert Mustacchi     g->s_avail = newlen - lastpos;
116*4d9fdb46SRobert Mustacchi     g->s_malloc = TRUE;
117*4d9fdb46SRobert Mustacchi     return TRUE;
118*4d9fdb46SRobert Mustacchi }
119*4d9fdb46SRobert Mustacchi 
120*4d9fdb46SRobert Mustacchi int
dwarfstring_reset(struct dwarfstring_s * g)121*4d9fdb46SRobert Mustacchi dwarfstring_reset(struct dwarfstring_s *g)
122*4d9fdb46SRobert Mustacchi {
123*4d9fdb46SRobert Mustacchi     if (!g->s_size) {
124*4d9fdb46SRobert Mustacchi         /* In initial condition, nothing to do. */
125*4d9fdb46SRobert Mustacchi         return TRUE;
126*4d9fdb46SRobert Mustacchi     }
127*4d9fdb46SRobert Mustacchi     g->s_avail = g->s_size;
128*4d9fdb46SRobert Mustacchi     g->s_data[0] = 0;
129*4d9fdb46SRobert Mustacchi     return TRUE;
130*4d9fdb46SRobert Mustacchi }
131*4d9fdb46SRobert Mustacchi 
132*4d9fdb46SRobert Mustacchi int
dwarfstring_constructor_fixed(struct dwarfstring_s * g,unsigned long len)133*4d9fdb46SRobert Mustacchi dwarfstring_constructor_fixed(struct dwarfstring_s *g,unsigned long len)
134*4d9fdb46SRobert Mustacchi {
135*4d9fdb46SRobert Mustacchi     int r = FALSE;
136*4d9fdb46SRobert Mustacchi 
137*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(g);
138*4d9fdb46SRobert Mustacchi     if (len == 0) {
139*4d9fdb46SRobert Mustacchi         return TRUE;
140*4d9fdb46SRobert Mustacchi     }
141*4d9fdb46SRobert Mustacchi     r = dwarfstring_resize_to(g,len);
142*4d9fdb46SRobert Mustacchi     if (!r) {
143*4d9fdb46SRobert Mustacchi         return FALSE;
144*4d9fdb46SRobert Mustacchi     }
145*4d9fdb46SRobert Mustacchi     return TRUE;
146*4d9fdb46SRobert Mustacchi }
147*4d9fdb46SRobert Mustacchi 
148*4d9fdb46SRobert Mustacchi int
dwarfstring_constructor_static(struct dwarfstring_s * g,char * space,unsigned long len)149*4d9fdb46SRobert Mustacchi dwarfstring_constructor_static(struct dwarfstring_s *g,
150*4d9fdb46SRobert Mustacchi     char * space,
151*4d9fdb46SRobert Mustacchi     unsigned long len)
152*4d9fdb46SRobert Mustacchi {
153*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(g);
154*4d9fdb46SRobert Mustacchi     g->s_data = space;
155*4d9fdb46SRobert Mustacchi     g->s_data[0] = 0;
156*4d9fdb46SRobert Mustacchi     g->s_size = len;
157*4d9fdb46SRobert Mustacchi     g->s_avail = len;
158*4d9fdb46SRobert Mustacchi     g->s_malloc = FALSE;
159*4d9fdb46SRobert Mustacchi     return TRUE;
160*4d9fdb46SRobert Mustacchi }
161*4d9fdb46SRobert Mustacchi 
162*4d9fdb46SRobert Mustacchi void
dwarfstring_destructor(struct dwarfstring_s * g)163*4d9fdb46SRobert Mustacchi dwarfstring_destructor(struct dwarfstring_s *g)
164*4d9fdb46SRobert Mustacchi {
165*4d9fdb46SRobert Mustacchi     if (g->s_malloc) {
166*4d9fdb46SRobert Mustacchi         free(g->s_data);
167*4d9fdb46SRobert Mustacchi         g->s_data = 0;
168*4d9fdb46SRobert Mustacchi         g->s_malloc = 0;
169*4d9fdb46SRobert Mustacchi     }
170*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(g);
171*4d9fdb46SRobert Mustacchi }
172*4d9fdb46SRobert Mustacchi 
173*4d9fdb46SRobert Mustacchi /*  For the case where one wants just the first 'len'
174*4d9fdb46SRobert Mustacchi     characters of 'str'. NUL terminator provided
175*4d9fdb46SRobert Mustacchi     for you in s_data.
176*4d9fdb46SRobert Mustacchi */
177*4d9fdb46SRobert Mustacchi int
dwarfstring_append_length(struct dwarfstring_s * g,char * str,unsigned long slen)178*4d9fdb46SRobert Mustacchi dwarfstring_append_length(struct dwarfstring_s *g,char *str,
179*4d9fdb46SRobert Mustacchi     unsigned long slen)
180*4d9fdb46SRobert Mustacchi {
181*4d9fdb46SRobert Mustacchi     unsigned long lastpos = g->s_size - g->s_avail;
182*4d9fdb46SRobert Mustacchi     int r = 0;
183*4d9fdb46SRobert Mustacchi 
184*4d9fdb46SRobert Mustacchi     if (!str  || slen ==0) {
185*4d9fdb46SRobert Mustacchi         return TRUE;
186*4d9fdb46SRobert Mustacchi     }
187*4d9fdb46SRobert Mustacchi     if (slen >= g->s_avail) {
188*4d9fdb46SRobert Mustacchi         unsigned long newlen = 0;
189*4d9fdb46SRobert Mustacchi 
190*4d9fdb46SRobert Mustacchi         newlen = g->s_size + slen+2;
191*4d9fdb46SRobert Mustacchi         r = dwarfstring_resize_to(g,newlen);
192*4d9fdb46SRobert Mustacchi         if (!r) {
193*4d9fdb46SRobert Mustacchi             return FALSE;
194*4d9fdb46SRobert Mustacchi         }
195*4d9fdb46SRobert Mustacchi     }
196*4d9fdb46SRobert Mustacchi     memcpy(g->s_data + lastpos,str,slen);
197*4d9fdb46SRobert Mustacchi     g->s_avail -= slen;
198*4d9fdb46SRobert Mustacchi     g->s_data[g->s_size - g->s_avail] = 0;
199*4d9fdb46SRobert Mustacchi     return TRUE;
200*4d9fdb46SRobert Mustacchi }
201*4d9fdb46SRobert Mustacchi 
202*4d9fdb46SRobert Mustacchi int
dwarfstring_append(struct dwarfstring_s * g,char * str)203*4d9fdb46SRobert Mustacchi dwarfstring_append(struct dwarfstring_s *g,char *str)
204*4d9fdb46SRobert Mustacchi {
205*4d9fdb46SRobert Mustacchi     unsigned long dlen = 0;
206*4d9fdb46SRobert Mustacchi 
207*4d9fdb46SRobert Mustacchi     if(!str) {
208*4d9fdb46SRobert Mustacchi         return TRUE;
209*4d9fdb46SRobert Mustacchi     }
210*4d9fdb46SRobert Mustacchi     dlen = strlen(str);
211*4d9fdb46SRobert Mustacchi     return dwarfstring_append_length(g,str,dlen);
212*4d9fdb46SRobert Mustacchi }
213*4d9fdb46SRobert Mustacchi 
214*4d9fdb46SRobert Mustacchi char *
dwarfstring_string(struct dwarfstring_s * g)215*4d9fdb46SRobert Mustacchi dwarfstring_string(struct dwarfstring_s *g)
216*4d9fdb46SRobert Mustacchi {
217*4d9fdb46SRobert Mustacchi     return g->s_data;
218*4d9fdb46SRobert Mustacchi }
219*4d9fdb46SRobert Mustacchi 
220*4d9fdb46SRobert Mustacchi unsigned long
dwarfstring_strlen(struct dwarfstring_s * g)221*4d9fdb46SRobert Mustacchi dwarfstring_strlen(struct dwarfstring_s *g)
222*4d9fdb46SRobert Mustacchi {
223*4d9fdb46SRobert Mustacchi     return g->s_size - g->s_avail;
224*4d9fdb46SRobert Mustacchi }
225*4d9fdb46SRobert Mustacchi 
226*4d9fdb46SRobert Mustacchi static int
_dwarfstring_append_spaces(dwarfstring * data,size_t count)227*4d9fdb46SRobert Mustacchi _dwarfstring_append_spaces(dwarfstring *data,
228*4d9fdb46SRobert Mustacchi    size_t count)
229*4d9fdb46SRobert Mustacchi {
230*4d9fdb46SRobert Mustacchi     int res = 0;
231*4d9fdb46SRobert Mustacchi     char spacebuf[] = {"                                       "};
232*4d9fdb46SRobert Mustacchi     size_t charct = sizeof(spacebuf)-1;
233*4d9fdb46SRobert Mustacchi     size_t l = count;
234*4d9fdb46SRobert Mustacchi 
235*4d9fdb46SRobert Mustacchi     while (l > charct) {
236*4d9fdb46SRobert Mustacchi         res = dwarfstring_append_length(data,spacebuf,charct);
237*4d9fdb46SRobert Mustacchi         l -= charct;
238*4d9fdb46SRobert Mustacchi         if (res != TRUE) {
239*4d9fdb46SRobert Mustacchi             return res;
240*4d9fdb46SRobert Mustacchi         }
241*4d9fdb46SRobert Mustacchi     }
242*4d9fdb46SRobert Mustacchi     /* ASSERT: l > 0 */
243*4d9fdb46SRobert Mustacchi     res = dwarfstring_append_length(data,spacebuf,l);
244*4d9fdb46SRobert Mustacchi     return res;
245*4d9fdb46SRobert Mustacchi }
246*4d9fdb46SRobert Mustacchi static int
_dwarfstring_append_zeros(dwarfstring * data,size_t l)247*4d9fdb46SRobert Mustacchi _dwarfstring_append_zeros(dwarfstring *data, size_t l)
248*4d9fdb46SRobert Mustacchi {
249*4d9fdb46SRobert Mustacchi     int res = 0;
250*4d9fdb46SRobert Mustacchi     static char zeros[] = {"0000000000000000000000000000000000000000"};
251*4d9fdb46SRobert Mustacchi     size_t charct = sizeof(zeros)-1;
252*4d9fdb46SRobert Mustacchi 
253*4d9fdb46SRobert Mustacchi     while (l > charct) {
254*4d9fdb46SRobert Mustacchi         res = dwarfstring_append_length(data,zeros,charct);
255*4d9fdb46SRobert Mustacchi         l -= charct;
256*4d9fdb46SRobert Mustacchi         if (res != TRUE) {
257*4d9fdb46SRobert Mustacchi             return res;
258*4d9fdb46SRobert Mustacchi         }
259*4d9fdb46SRobert Mustacchi     }
260*4d9fdb46SRobert Mustacchi     /* ASSERT: l > 0 */
261*4d9fdb46SRobert Mustacchi     dwarfstring_append_length(data,zeros,l);
262*4d9fdb46SRobert Mustacchi     return res;
263*4d9fdb46SRobert Mustacchi }
264*4d9fdb46SRobert Mustacchi 
265*4d9fdb46SRobert Mustacchi 
dwarfstring_append_printf_s(dwarfstring * data,char * format,char * s)266*4d9fdb46SRobert Mustacchi int dwarfstring_append_printf_s(dwarfstring *data,
267*4d9fdb46SRobert Mustacchi     char *format,char *s)
268*4d9fdb46SRobert Mustacchi {
269*4d9fdb46SRobert Mustacchi     size_t stringlen = strlen(s);
270*4d9fdb46SRobert Mustacchi     size_t next = 0;
271*4d9fdb46SRobert Mustacchi     long val = 0;
272*4d9fdb46SRobert Mustacchi     char *endptr = 0;
273*4d9fdb46SRobert Mustacchi     const char *numptr = 0;
274*4d9fdb46SRobert Mustacchi     /* was %[-]fixedlen.  Zero means no len provided. */
275*4d9fdb46SRobert Mustacchi     size_t fixedlen = 0;
276*4d9fdb46SRobert Mustacchi     /* was %-, nonzero means left-justify */
277*4d9fdb46SRobert Mustacchi     long leftjustify = 0;
278*4d9fdb46SRobert Mustacchi     size_t prefixlen = 0;
279*4d9fdb46SRobert Mustacchi     int res = 0;
280*4d9fdb46SRobert Mustacchi 
281*4d9fdb46SRobert Mustacchi     while (format[next] && format[next] != '%') {
282*4d9fdb46SRobert Mustacchi         ++next;
283*4d9fdb46SRobert Mustacchi         ++prefixlen;
284*4d9fdb46SRobert Mustacchi     }
285*4d9fdb46SRobert Mustacchi     if (prefixlen) {
286*4d9fdb46SRobert Mustacchi         dwarfstring_append_length(data,format,prefixlen);
287*4d9fdb46SRobert Mustacchi     }
288*4d9fdb46SRobert Mustacchi     if (!format[next]) {
289*4d9fdb46SRobert Mustacchi         return TRUE;
290*4d9fdb46SRobert Mustacchi     }
291*4d9fdb46SRobert Mustacchi     next++;
292*4d9fdb46SRobert Mustacchi     if (format[next] == '-') {
293*4d9fdb46SRobert Mustacchi         leftjustify++;
294*4d9fdb46SRobert Mustacchi         next++;
295*4d9fdb46SRobert Mustacchi     }
296*4d9fdb46SRobert Mustacchi     numptr = format+next;
297*4d9fdb46SRobert Mustacchi     val = strtol(numptr,&endptr,10);
298*4d9fdb46SRobert Mustacchi     if ( endptr != numptr) {
299*4d9fdb46SRobert Mustacchi         fixedlen = val;
300*4d9fdb46SRobert Mustacchi     }
301*4d9fdb46SRobert Mustacchi     next = (endptr - format);
302*4d9fdb46SRobert Mustacchi     if (format[next] != 's') {
303*4d9fdb46SRobert Mustacchi         return FALSE;
304*4d9fdb46SRobert Mustacchi     }
305*4d9fdb46SRobert Mustacchi     next++;
306*4d9fdb46SRobert Mustacchi 
307*4d9fdb46SRobert Mustacchi     if (fixedlen && (stringlen >= fixedlen)) {
308*4d9fdb46SRobert Mustacchi         /*  Ignore  leftjustify (if any) and the stringlen
309*4d9fdb46SRobert Mustacchi             as the actual string overrides those. */
310*4d9fdb46SRobert Mustacchi         leftjustify = 0;
311*4d9fdb46SRobert Mustacchi     }
312*4d9fdb46SRobert Mustacchi     if (leftjustify) {
313*4d9fdb46SRobert Mustacchi 
314*4d9fdb46SRobert Mustacchi         dwarfstring_append_length(data,s,stringlen);
315*4d9fdb46SRobert Mustacchi         if(fixedlen) {
316*4d9fdb46SRobert Mustacchi             size_t trailingspaces = fixedlen - stringlen;
317*4d9fdb46SRobert Mustacchi 
318*4d9fdb46SRobert Mustacchi             _dwarfstring_append_spaces(data,trailingspaces);
319*4d9fdb46SRobert Mustacchi         }
320*4d9fdb46SRobert Mustacchi     } else {
321*4d9fdb46SRobert Mustacchi         if (fixedlen && fixedlen < stringlen) {
322*4d9fdb46SRobert Mustacchi             /*  This lets us have fixedlen < stringlen by
323*4d9fdb46SRobert Mustacchi                 taking all the chars from s*/
324*4d9fdb46SRobert Mustacchi             dwarfstring_append_length(data,s,stringlen);
325*4d9fdb46SRobert Mustacchi         } else {
326*4d9fdb46SRobert Mustacchi             if(fixedlen) {
327*4d9fdb46SRobert Mustacchi                 size_t leadingspaces = fixedlen - stringlen;
328*4d9fdb46SRobert Mustacchi                 size_t k = 0;
329*4d9fdb46SRobert Mustacchi 
330*4d9fdb46SRobert Mustacchi                 for ( ; k < leadingspaces; ++k) {
331*4d9fdb46SRobert Mustacchi                     dwarfstring_append_length(data," ",1);
332*4d9fdb46SRobert Mustacchi                 }
333*4d9fdb46SRobert Mustacchi             }
334*4d9fdb46SRobert Mustacchi             dwarfstring_append_length(data,s,stringlen);
335*4d9fdb46SRobert Mustacchi         }
336*4d9fdb46SRobert Mustacchi     }
337*4d9fdb46SRobert Mustacchi     if (!format[next]) {
338*4d9fdb46SRobert Mustacchi         return TRUE;
339*4d9fdb46SRobert Mustacchi     }
340*4d9fdb46SRobert Mustacchi     {
341*4d9fdb46SRobert Mustacchi         char * startpt = format+next;
342*4d9fdb46SRobert Mustacchi         size_t suffixlen = strlen(startpt);
343*4d9fdb46SRobert Mustacchi 
344*4d9fdb46SRobert Mustacchi         res = dwarfstring_append_length(data,startpt,suffixlen);
345*4d9fdb46SRobert Mustacchi     }
346*4d9fdb46SRobert Mustacchi     return res;
347*4d9fdb46SRobert Mustacchi }
348*4d9fdb46SRobert Mustacchi 
349*4d9fdb46SRobert Mustacchi static char v32m[] = {"-2147483648"};
350*4d9fdb46SRobert Mustacchi static char v64m[] = {"-9223372036854775808"};
351*4d9fdb46SRobert Mustacchi static char dtable[10] = {
352*4d9fdb46SRobert Mustacchi '0','1','2','3','4','5','6','7','8','9'
353*4d9fdb46SRobert Mustacchi };
354*4d9fdb46SRobert Mustacchi static char xtable[16] = {
355*4d9fdb46SRobert Mustacchi '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
356*4d9fdb46SRobert Mustacchi };
357*4d9fdb46SRobert Mustacchi static char Xtable[16] = {
358*4d9fdb46SRobert Mustacchi '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
359*4d9fdb46SRobert Mustacchi };
360*4d9fdb46SRobert Mustacchi 
361*4d9fdb46SRobert Mustacchi /*  We deal with formats like:
362*4d9fdb46SRobert Mustacchi     %d   %5d %05d %+d %+5d %-5d (and ld and lld too). */
dwarfstring_append_printf_i(dwarfstring * data,char * format,dwarfstring_i v)363*4d9fdb46SRobert Mustacchi int dwarfstring_append_printf_i(dwarfstring *data,
364*4d9fdb46SRobert Mustacchi     char *format,
365*4d9fdb46SRobert Mustacchi     dwarfstring_i v)
366*4d9fdb46SRobert Mustacchi {
367*4d9fdb46SRobert Mustacchi     int res = TRUE;
368*4d9fdb46SRobert Mustacchi     size_t next = 0;
369*4d9fdb46SRobert Mustacchi     long val = 0;
370*4d9fdb46SRobert Mustacchi     char *endptr = 0;
371*4d9fdb46SRobert Mustacchi     const char *numptr = 0;
372*4d9fdb46SRobert Mustacchi     size_t fixedlen = 0;
373*4d9fdb46SRobert Mustacchi     int leadingzero = 0;
374*4d9fdb46SRobert Mustacchi     int minuscount = 0; /*left justify */
375*4d9fdb46SRobert Mustacchi     int pluscount = 0;
376*4d9fdb46SRobert Mustacchi     int lcount = 0;
377*4d9fdb46SRobert Mustacchi     int ucount = 0;
378*4d9fdb46SRobert Mustacchi     int dcount = 0;
379*4d9fdb46SRobert Mustacchi     int xcount = 0;
380*4d9fdb46SRobert Mustacchi     int Xcount = 0;
381*4d9fdb46SRobert Mustacchi     char *ctable = dtable;
382*4d9fdb46SRobert Mustacchi     size_t prefixlen = 0;
383*4d9fdb46SRobert Mustacchi     int done = 0;
384*4d9fdb46SRobert Mustacchi 
385*4d9fdb46SRobert Mustacchi     while (format[next] && format[next] != '%') {
386*4d9fdb46SRobert Mustacchi         ++next;
387*4d9fdb46SRobert Mustacchi         ++prefixlen;
388*4d9fdb46SRobert Mustacchi     }
389*4d9fdb46SRobert Mustacchi     dwarfstring_append_length(data,format,prefixlen);
390*4d9fdb46SRobert Mustacchi     if (format[next] != '%') {
391*4d9fdb46SRobert Mustacchi         /*   No % operator found, we are done */
392*4d9fdb46SRobert Mustacchi         return TRUE;
393*4d9fdb46SRobert Mustacchi     }
394*4d9fdb46SRobert Mustacchi     next++;
395*4d9fdb46SRobert Mustacchi     if (format[next] == '-') {
396*4d9fdb46SRobert Mustacchi         minuscount++;
397*4d9fdb46SRobert Mustacchi         return FALSE;
398*4d9fdb46SRobert Mustacchi     }
399*4d9fdb46SRobert Mustacchi     if (format[next] == '+') {
400*4d9fdb46SRobert Mustacchi         pluscount++;
401*4d9fdb46SRobert Mustacchi         next++;
402*4d9fdb46SRobert Mustacchi     }
403*4d9fdb46SRobert Mustacchi     if (format[next] == '0') {
404*4d9fdb46SRobert Mustacchi         leadingzero = 1;
405*4d9fdb46SRobert Mustacchi         next++;
406*4d9fdb46SRobert Mustacchi     }
407*4d9fdb46SRobert Mustacchi     numptr = format+next;
408*4d9fdb46SRobert Mustacchi     val = strtol(numptr,&endptr,10);
409*4d9fdb46SRobert Mustacchi     if ( endptr != numptr) {
410*4d9fdb46SRobert Mustacchi         fixedlen = val;
411*4d9fdb46SRobert Mustacchi     }
412*4d9fdb46SRobert Mustacchi     next = (endptr - format);
413*4d9fdb46SRobert Mustacchi     /*  Following is lx lu or u or llx llu , we take
414*4d9fdb46SRobert Mustacchi         all this to mean 64 bits, */
415*4d9fdb46SRobert Mustacchi #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT)
416*4d9fdb46SRobert Mustacchi     if (format[next] == 'I') {
417*4d9fdb46SRobert Mustacchi         /*lcount++;*/
418*4d9fdb46SRobert Mustacchi         next++;
419*4d9fdb46SRobert Mustacchi     }
420*4d9fdb46SRobert Mustacchi     if (format[next] == '6') {
421*4d9fdb46SRobert Mustacchi         /*lcount++;*/
422*4d9fdb46SRobert Mustacchi         next++;
423*4d9fdb46SRobert Mustacchi     }
424*4d9fdb46SRobert Mustacchi     if (format[next] == '4') {
425*4d9fdb46SRobert Mustacchi         /*lcount++;*/
426*4d9fdb46SRobert Mustacchi         next++;
427*4d9fdb46SRobert Mustacchi     }
428*4d9fdb46SRobert Mustacchi #endif /* HAVE_NONSTANDARD_PRINTF_64_FORMAT */
429*4d9fdb46SRobert Mustacchi     if (format[next] == 'l') {
430*4d9fdb46SRobert Mustacchi         lcount++;
431*4d9fdb46SRobert Mustacchi         next++;
432*4d9fdb46SRobert Mustacchi     }
433*4d9fdb46SRobert Mustacchi     if (format[next] == 'l') {
434*4d9fdb46SRobert Mustacchi         lcount++;
435*4d9fdb46SRobert Mustacchi         next++;
436*4d9fdb46SRobert Mustacchi     }
437*4d9fdb46SRobert Mustacchi     if (format[next] == 'u') {
438*4d9fdb46SRobert Mustacchi         ucount++;
439*4d9fdb46SRobert Mustacchi         next++;
440*4d9fdb46SRobert Mustacchi     }
441*4d9fdb46SRobert Mustacchi     if (format[next] == 'd') {
442*4d9fdb46SRobert Mustacchi         dcount++;
443*4d9fdb46SRobert Mustacchi         next++;
444*4d9fdb46SRobert Mustacchi     }
445*4d9fdb46SRobert Mustacchi     if (format[next] == 'x') {
446*4d9fdb46SRobert Mustacchi         xcount++;
447*4d9fdb46SRobert Mustacchi         next++;
448*4d9fdb46SRobert Mustacchi     }
449*4d9fdb46SRobert Mustacchi     if (format[next] == 'X') {
450*4d9fdb46SRobert Mustacchi         Xcount++;
451*4d9fdb46SRobert Mustacchi         next++;
452*4d9fdb46SRobert Mustacchi     }
453*4d9fdb46SRobert Mustacchi     if (format[next] == 's') {
454*4d9fdb46SRobert Mustacchi         /* ESBERR("ESBERR_pct_scount_in_i"); */
455*4d9fdb46SRobert Mustacchi         return FALSE;
456*4d9fdb46SRobert Mustacchi     }
457*4d9fdb46SRobert Mustacchi     if (xcount || Xcount) {
458*4d9fdb46SRobert Mustacchi         /*  Use the printf_u for %x and the like
459*4d9fdb46SRobert Mustacchi             just copying the entire format makes
460*4d9fdb46SRobert Mustacchi             it easier for coders to understand
461*4d9fdb46SRobert Mustacchi             nothing much was done */
462*4d9fdb46SRobert Mustacchi         dwarfstring_append(data,format+prefixlen);
463*4d9fdb46SRobert Mustacchi         return FALSE;
464*4d9fdb46SRobert Mustacchi     }
465*4d9fdb46SRobert Mustacchi     if (!dcount || (lcount >2) ||
466*4d9fdb46SRobert Mustacchi         (Xcount+xcount+dcount+ucount) > 1) {
467*4d9fdb46SRobert Mustacchi         /* error */
468*4d9fdb46SRobert Mustacchi         /* ESBERR("ESBERR_xcount_etc_i"); */
469*4d9fdb46SRobert Mustacchi         return FALSE;
470*4d9fdb46SRobert Mustacchi     }
471*4d9fdb46SRobert Mustacchi     if (pluscount && minuscount) {
472*4d9fdb46SRobert Mustacchi         /* We don't allow  format +- */
473*4d9fdb46SRobert Mustacchi         return FALSE;
474*4d9fdb46SRobert Mustacchi     }
475*4d9fdb46SRobert Mustacchi     {
476*4d9fdb46SRobert Mustacchi         char digbuf[36];
477*4d9fdb46SRobert Mustacchi         char *digptr = digbuf+sizeof(digbuf) -1;
478*4d9fdb46SRobert Mustacchi         size_t digcharlen = 0;
479*4d9fdb46SRobert Mustacchi         dwarfstring_i remaining = v;
480*4d9fdb46SRobert Mustacchi         int vissigned = 0;
481*4d9fdb46SRobert Mustacchi         dwarfstring_i divisor = 10;
482*4d9fdb46SRobert Mustacchi 
483*4d9fdb46SRobert Mustacchi         *digptr = 0;
484*4d9fdb46SRobert Mustacchi         --digptr;
485*4d9fdb46SRobert Mustacchi         if (v < 0) {
486*4d9fdb46SRobert Mustacchi             vissigned = 1;
487*4d9fdb46SRobert Mustacchi             /*  This test is for twos-complement
488*4d9fdb46SRobert Mustacchi                 machines and would be better done via
489*4d9fdb46SRobert Mustacchi                 configure with a compile-time check
490*4d9fdb46SRobert Mustacchi                 so we do not need a size test at runtime. */
491*4d9fdb46SRobert Mustacchi             if (sizeof(v) == 8) {
492*4d9fdb46SRobert Mustacchi                 dwarfstring_u vm = 0x7fffffffffffffffULL;
493*4d9fdb46SRobert Mustacchi                 if (vm == (dwarfstring_u)~v) {
494*4d9fdb46SRobert Mustacchi                     memcpy(digbuf,v64m,sizeof(v64m));
495*4d9fdb46SRobert Mustacchi                     digcharlen = sizeof(v64m)-1;
496*4d9fdb46SRobert Mustacchi                     digptr = digbuf;
497*4d9fdb46SRobert Mustacchi                     done = 1;
498*4d9fdb46SRobert Mustacchi                 } else {
499*4d9fdb46SRobert Mustacchi                     remaining = -v;
500*4d9fdb46SRobert Mustacchi                 }
501*4d9fdb46SRobert Mustacchi             } else if (sizeof(v) == 4) {
502*4d9fdb46SRobert Mustacchi                 dwarfstring_u vm = 0x7fffffffL;
503*4d9fdb46SRobert Mustacchi                 if (vm == (dwarfstring_u)~v) {
504*4d9fdb46SRobert Mustacchi                     memcpy(digbuf,v32m,sizeof(v32m));
505*4d9fdb46SRobert Mustacchi                     digcharlen = sizeof(v32m)-1;
506*4d9fdb46SRobert Mustacchi                     digptr = digbuf;
507*4d9fdb46SRobert Mustacchi                     done = 1;
508*4d9fdb46SRobert Mustacchi                 } else {
509*4d9fdb46SRobert Mustacchi                     remaining = -v;
510*4d9fdb46SRobert Mustacchi                 }
511*4d9fdb46SRobert Mustacchi             }else {
512*4d9fdb46SRobert Mustacchi                 /* ESBERR("ESBERR_sizeof_v_i"); */
513*4d9fdb46SRobert Mustacchi                 /* error */
514*4d9fdb46SRobert Mustacchi                 return FALSE;
515*4d9fdb46SRobert Mustacchi             }
516*4d9fdb46SRobert Mustacchi         }
517*4d9fdb46SRobert Mustacchi         if(!done) {
518*4d9fdb46SRobert Mustacchi             for ( ;; ) {
519*4d9fdb46SRobert Mustacchi                 dwarfstring_u dig = 0;
520*4d9fdb46SRobert Mustacchi 
521*4d9fdb46SRobert Mustacchi                 dig = remaining % divisor;
522*4d9fdb46SRobert Mustacchi                 remaining /= divisor;
523*4d9fdb46SRobert Mustacchi                 *digptr = ctable[dig];
524*4d9fdb46SRobert Mustacchi                 digcharlen++;
525*4d9fdb46SRobert Mustacchi                 if (!remaining) {
526*4d9fdb46SRobert Mustacchi                     break;
527*4d9fdb46SRobert Mustacchi                 }
528*4d9fdb46SRobert Mustacchi                 --digptr;
529*4d9fdb46SRobert Mustacchi             }
530*4d9fdb46SRobert Mustacchi             if (vissigned) { /* could check minuscount instead */
531*4d9fdb46SRobert Mustacchi                 --digptr;
532*4d9fdb46SRobert Mustacchi                 digcharlen++;
533*4d9fdb46SRobert Mustacchi                 *digptr = '-';
534*4d9fdb46SRobert Mustacchi             } else if (pluscount) {
535*4d9fdb46SRobert Mustacchi                 --digptr;
536*4d9fdb46SRobert Mustacchi                 digcharlen++;
537*4d9fdb46SRobert Mustacchi                 *digptr = '+';
538*4d9fdb46SRobert Mustacchi             }
539*4d9fdb46SRobert Mustacchi         }
540*4d9fdb46SRobert Mustacchi         if (fixedlen > 0) {
541*4d9fdb46SRobert Mustacchi             if (fixedlen <= digcharlen) {
542*4d9fdb46SRobert Mustacchi                 dwarfstring_append_length(data,digptr,digcharlen);
543*4d9fdb46SRobert Mustacchi             } else {
544*4d9fdb46SRobert Mustacchi                 size_t prefixcount = fixedlen - digcharlen;
545*4d9fdb46SRobert Mustacchi                 if (!leadingzero) {
546*4d9fdb46SRobert Mustacchi                     _dwarfstring_append_spaces(data,prefixcount);
547*4d9fdb46SRobert Mustacchi                     dwarfstring_append_length(data,digptr,digcharlen);
548*4d9fdb46SRobert Mustacchi                 } else {
549*4d9fdb46SRobert Mustacchi                     if (*digptr == '-') {
550*4d9fdb46SRobert Mustacchi                         dwarfstring_append_length(data,"-",1);
551*4d9fdb46SRobert Mustacchi                         _dwarfstring_append_zeros(data,prefixcount);
552*4d9fdb46SRobert Mustacchi                         digptr++;
553*4d9fdb46SRobert Mustacchi                         dwarfstring_append_length(data,digptr,
554*4d9fdb46SRobert Mustacchi                             digcharlen-1);
555*4d9fdb46SRobert Mustacchi                     } else if (*digptr == '+') {
556*4d9fdb46SRobert Mustacchi                         dwarfstring_append_length(data,"+",1);
557*4d9fdb46SRobert Mustacchi                         _dwarfstring_append_zeros(data,prefixcount);
558*4d9fdb46SRobert Mustacchi                         digptr++;
559*4d9fdb46SRobert Mustacchi                         dwarfstring_append_length(data,digptr,
560*4d9fdb46SRobert Mustacchi                             digcharlen-1);
561*4d9fdb46SRobert Mustacchi                     } else {
562*4d9fdb46SRobert Mustacchi                         _dwarfstring_append_zeros(data,prefixcount);
563*4d9fdb46SRobert Mustacchi                         dwarfstring_append_length(data,digptr,
564*4d9fdb46SRobert Mustacchi                             digcharlen);
565*4d9fdb46SRobert Mustacchi                     }
566*4d9fdb46SRobert Mustacchi                 }
567*4d9fdb46SRobert Mustacchi             }
568*4d9fdb46SRobert Mustacchi         } else {
569*4d9fdb46SRobert Mustacchi             res = dwarfstring_append_length(data,digptr,digcharlen);
570*4d9fdb46SRobert Mustacchi         }
571*4d9fdb46SRobert Mustacchi     }
572*4d9fdb46SRobert Mustacchi     if (format[next]) {
573*4d9fdb46SRobert Mustacchi         size_t trailinglen = strlen(format+next);
574*4d9fdb46SRobert Mustacchi         res = dwarfstring_append_length(data,format+next,trailinglen);
575*4d9fdb46SRobert Mustacchi     }
576*4d9fdb46SRobert Mustacchi     return res;
577*4d9fdb46SRobert Mustacchi }
578*4d9fdb46SRobert Mustacchi 
579*4d9fdb46SRobert Mustacchi #if 0
580*4d9fdb46SRobert Mustacchi /*  Counts hex chars. divide by two to get bytes from input
581*4d9fdb46SRobert Mustacchi     integer. */
582*4d9fdb46SRobert Mustacchi static unsigned
583*4d9fdb46SRobert Mustacchi trimleadingzeros(char *ptr,unsigned digits,unsigned keepcount)
584*4d9fdb46SRobert Mustacchi {
585*4d9fdb46SRobert Mustacchi     char *cp = ptr;
586*4d9fdb46SRobert Mustacchi     unsigned leadzeroscount = 0;
587*4d9fdb46SRobert Mustacchi     unsigned trimoff = 0;
588*4d9fdb46SRobert Mustacchi 
589*4d9fdb46SRobert Mustacchi     for(; *cp; ++cp) {
590*4d9fdb46SRobert Mustacchi         if (*cp == '0') {
591*4d9fdb46SRobert Mustacchi             leadzeroscount++;
592*4d9fdb46SRobert Mustacchi             continue;
593*4d9fdb46SRobert Mustacchi         }
594*4d9fdb46SRobert Mustacchi     }
595*4d9fdb46SRobert Mustacchi     trimoff = keepcount - digits;
596*4d9fdb46SRobert Mustacchi     if (trimoff&1) {
597*4d9fdb46SRobert Mustacchi         trimoff--;
598*4d9fdb46SRobert Mustacchi     }
599*4d9fdb46SRobert Mustacchi     return trimoff;
600*4d9fdb46SRobert Mustacchi }
601*4d9fdb46SRobert Mustacchi #endif /* 0 */
602*4d9fdb46SRobert Mustacchi 
603*4d9fdb46SRobert Mustacchi /* With gcc version 5.4.0 20160609  a version using
604*4d9fdb46SRobert Mustacchi    const char *formatp instead of format[next]
605*4d9fdb46SRobert Mustacchi    and deleting the 'next' variable
606*4d9fdb46SRobert Mustacchi    is a few hundredths of a second slower, repeatably.
607*4d9fdb46SRobert Mustacchi 
608*4d9fdb46SRobert Mustacchi    We deal with formats like:
609*4d9fdb46SRobert Mustacchi    %u   %5u %05u (and ld and lld too).
610*4d9fdb46SRobert Mustacchi    %x   %5x %05x (and ld and lld too).  */
611*4d9fdb46SRobert Mustacchi 
dwarfstring_append_printf_u(dwarfstring * data,char * format,dwarfstring_u v)612*4d9fdb46SRobert Mustacchi int dwarfstring_append_printf_u(dwarfstring *data,
613*4d9fdb46SRobert Mustacchi     char *format,
614*4d9fdb46SRobert Mustacchi     dwarfstring_u v)
615*4d9fdb46SRobert Mustacchi {
616*4d9fdb46SRobert Mustacchi 
617*4d9fdb46SRobert Mustacchi     size_t next = 0;
618*4d9fdb46SRobert Mustacchi     long val = 0;
619*4d9fdb46SRobert Mustacchi     char *endptr = 0;
620*4d9fdb46SRobert Mustacchi     const char *numptr = 0;
621*4d9fdb46SRobert Mustacchi     size_t fixedlen = 0;
622*4d9fdb46SRobert Mustacchi     int leadingzero = 0;
623*4d9fdb46SRobert Mustacchi     int lcount = 0;
624*4d9fdb46SRobert Mustacchi     int ucount = 0;
625*4d9fdb46SRobert Mustacchi     int dcount = 0;
626*4d9fdb46SRobert Mustacchi     int xcount = 0;
627*4d9fdb46SRobert Mustacchi     int Xcount = 0;
628*4d9fdb46SRobert Mustacchi     char *ctable = 0;
629*4d9fdb46SRobert Mustacchi     size_t divisor = 0;
630*4d9fdb46SRobert Mustacchi     size_t prefixlen = 0;
631*4d9fdb46SRobert Mustacchi 
632*4d9fdb46SRobert Mustacchi     while (format[next] && format[next] != '%') {
633*4d9fdb46SRobert Mustacchi         ++next;
634*4d9fdb46SRobert Mustacchi         ++prefixlen;
635*4d9fdb46SRobert Mustacchi     }
636*4d9fdb46SRobert Mustacchi     dwarfstring_append_length(data,format,prefixlen);
637*4d9fdb46SRobert Mustacchi     if (format[next] != '%') {
638*4d9fdb46SRobert Mustacchi         /*   No % operator found, we are done */
639*4d9fdb46SRobert Mustacchi         return TRUE;
640*4d9fdb46SRobert Mustacchi     }
641*4d9fdb46SRobert Mustacchi     next++;
642*4d9fdb46SRobert Mustacchi     if (format[next] == '-') {
643*4d9fdb46SRobert Mustacchi         /*ESBERR("ESBERR_printf_u - format not supported"); */
644*4d9fdb46SRobert Mustacchi         next++;
645*4d9fdb46SRobert Mustacchi     }
646*4d9fdb46SRobert Mustacchi     if (format[next] == '0') {
647*4d9fdb46SRobert Mustacchi         leadingzero = 1;
648*4d9fdb46SRobert Mustacchi         next++;
649*4d9fdb46SRobert Mustacchi     }
650*4d9fdb46SRobert Mustacchi     numptr = format+next;
651*4d9fdb46SRobert Mustacchi     val = strtol(numptr,&endptr,10);
652*4d9fdb46SRobert Mustacchi     if ( endptr != numptr) {
653*4d9fdb46SRobert Mustacchi         fixedlen = val;
654*4d9fdb46SRobert Mustacchi     }
655*4d9fdb46SRobert Mustacchi     next = (endptr - format);
656*4d9fdb46SRobert Mustacchi     /*  Following is lx lu or u or llx llu , we take
657*4d9fdb46SRobert Mustacchi         all this to mean 64 bits, */
658*4d9fdb46SRobert Mustacchi #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT)
659*4d9fdb46SRobert Mustacchi     if (format[next] == 'I') {
660*4d9fdb46SRobert Mustacchi         /*lcount++;*/
661*4d9fdb46SRobert Mustacchi         next++;
662*4d9fdb46SRobert Mustacchi     }
663*4d9fdb46SRobert Mustacchi     if (format[next] == '6') {
664*4d9fdb46SRobert Mustacchi         /*lcount++;*/
665*4d9fdb46SRobert Mustacchi         next++;
666*4d9fdb46SRobert Mustacchi     }
667*4d9fdb46SRobert Mustacchi     if (format[next] == '4') {
668*4d9fdb46SRobert Mustacchi         /*lcount++;*/
669*4d9fdb46SRobert Mustacchi         next++;
670*4d9fdb46SRobert Mustacchi     }
671*4d9fdb46SRobert Mustacchi #endif /* HAVE_NONSTANDARD_PRINTF_64_FORMAT */
672*4d9fdb46SRobert Mustacchi     if (format[next] == 'l') {
673*4d9fdb46SRobert Mustacchi         lcount++;
674*4d9fdb46SRobert Mustacchi         next++;
675*4d9fdb46SRobert Mustacchi     }
676*4d9fdb46SRobert Mustacchi     if (format[next] == 'l') {
677*4d9fdb46SRobert Mustacchi         lcount++;
678*4d9fdb46SRobert Mustacchi         next++;
679*4d9fdb46SRobert Mustacchi     }
680*4d9fdb46SRobert Mustacchi     if (format[next] == 'u') {
681*4d9fdb46SRobert Mustacchi         ucount++;
682*4d9fdb46SRobert Mustacchi         next++;
683*4d9fdb46SRobert Mustacchi     }
684*4d9fdb46SRobert Mustacchi     if (format[next] == 'd') {
685*4d9fdb46SRobert Mustacchi         dcount++;
686*4d9fdb46SRobert Mustacchi         next++;
687*4d9fdb46SRobert Mustacchi     }
688*4d9fdb46SRobert Mustacchi     if (format[next] == 'x') {
689*4d9fdb46SRobert Mustacchi         xcount++;
690*4d9fdb46SRobert Mustacchi         next++;
691*4d9fdb46SRobert Mustacchi     }
692*4d9fdb46SRobert Mustacchi     if (format[next] == 'X') {
693*4d9fdb46SRobert Mustacchi         Xcount++;
694*4d9fdb46SRobert Mustacchi         next++;
695*4d9fdb46SRobert Mustacchi     }
696*4d9fdb46SRobert Mustacchi     if (format[next] == 's') {
697*4d9fdb46SRobert Mustacchi         /* ESBERR("ESBERR_pct_scount_in_u"); */
698*4d9fdb46SRobert Mustacchi         return FALSE;
699*4d9fdb46SRobert Mustacchi     }
700*4d9fdb46SRobert Mustacchi 
701*4d9fdb46SRobert Mustacchi     if ( (Xcount +xcount+dcount+ucount) > 1) {
702*4d9fdb46SRobert Mustacchi         /* ESBERR("ESBERR_pct_xcount_etc_u"); */
703*4d9fdb46SRobert Mustacchi         return FALSE;
704*4d9fdb46SRobert Mustacchi     }
705*4d9fdb46SRobert Mustacchi     if (lcount > 2) {
706*4d9fdb46SRobert Mustacchi         /* ESBERR("ESBERR_pct_lcount_error_u"); */
707*4d9fdb46SRobert Mustacchi         /* error */
708*4d9fdb46SRobert Mustacchi         return FALSE;
709*4d9fdb46SRobert Mustacchi     }
710*4d9fdb46SRobert Mustacchi     if (dcount > 0) {
711*4d9fdb46SRobert Mustacchi         /*ESBERR("ESBERR_pct_dcount_error_u");*/
712*4d9fdb46SRobert Mustacchi         /* error */
713*4d9fdb46SRobert Mustacchi         return FALSE;
714*4d9fdb46SRobert Mustacchi     }
715*4d9fdb46SRobert Mustacchi     if (ucount) {
716*4d9fdb46SRobert Mustacchi         divisor = 10;
717*4d9fdb46SRobert Mustacchi         ctable = dtable;
718*4d9fdb46SRobert Mustacchi     } else {
719*4d9fdb46SRobert Mustacchi         divisor = 16;
720*4d9fdb46SRobert Mustacchi         if (xcount) {
721*4d9fdb46SRobert Mustacchi             ctable = xtable;
722*4d9fdb46SRobert Mustacchi         } else {
723*4d9fdb46SRobert Mustacchi             ctable = Xtable;
724*4d9fdb46SRobert Mustacchi         }
725*4d9fdb46SRobert Mustacchi     }
726*4d9fdb46SRobert Mustacchi     {
727*4d9fdb46SRobert Mustacchi         char digbuf[36];
728*4d9fdb46SRobert Mustacchi         char *digptr = 0;
729*4d9fdb46SRobert Mustacchi         unsigned digcharlen = 0;
730*4d9fdb46SRobert Mustacchi         dwarfstring_u remaining = v;
731*4d9fdb46SRobert Mustacchi 
732*4d9fdb46SRobert Mustacchi         if (divisor == 16) {
733*4d9fdb46SRobert Mustacchi             digptr = digbuf+sizeof(digbuf) -1;
734*4d9fdb46SRobert Mustacchi             for ( ;; ) {
735*4d9fdb46SRobert Mustacchi                 dwarfstring_u dig;
736*4d9fdb46SRobert Mustacchi                 dig = remaining & 0xf;
737*4d9fdb46SRobert Mustacchi                 remaining = remaining >> 4;
738*4d9fdb46SRobert Mustacchi                 *digptr = ctable[dig];
739*4d9fdb46SRobert Mustacchi                 ++digcharlen;
740*4d9fdb46SRobert Mustacchi                 if (!remaining) {
741*4d9fdb46SRobert Mustacchi                     break;
742*4d9fdb46SRobert Mustacchi                 }
743*4d9fdb46SRobert Mustacchi                 --digptr;
744*4d9fdb46SRobert Mustacchi             }
745*4d9fdb46SRobert Mustacchi         } else {
746*4d9fdb46SRobert Mustacchi             digptr = digbuf+sizeof(digbuf) -1;
747*4d9fdb46SRobert Mustacchi             *digptr = 0;
748*4d9fdb46SRobert Mustacchi             --digptr;
749*4d9fdb46SRobert Mustacchi             for ( ;; ) {
750*4d9fdb46SRobert Mustacchi                 dwarfstring_u dig;
751*4d9fdb46SRobert Mustacchi                 dig = remaining % divisor;
752*4d9fdb46SRobert Mustacchi                 remaining /= divisor;
753*4d9fdb46SRobert Mustacchi                 *digptr = ctable[dig];
754*4d9fdb46SRobert Mustacchi                 ++digcharlen;
755*4d9fdb46SRobert Mustacchi                 if (!remaining) {
756*4d9fdb46SRobert Mustacchi                     break;
757*4d9fdb46SRobert Mustacchi                 }
758*4d9fdb46SRobert Mustacchi                 --digptr;
759*4d9fdb46SRobert Mustacchi             }
760*4d9fdb46SRobert Mustacchi         }
761*4d9fdb46SRobert Mustacchi         if (fixedlen <= digcharlen) {
762*4d9fdb46SRobert Mustacchi             dwarfstring_append_length(data,digptr,digcharlen);
763*4d9fdb46SRobert Mustacchi         } else {
764*4d9fdb46SRobert Mustacchi             if (!leadingzero) {
765*4d9fdb46SRobert Mustacchi                 size_t justcount = fixedlen - digcharlen;
766*4d9fdb46SRobert Mustacchi                 _dwarfstring_append_spaces(data,justcount);
767*4d9fdb46SRobert Mustacchi                 dwarfstring_append_length(data,digptr,digcharlen);
768*4d9fdb46SRobert Mustacchi             } else {
769*4d9fdb46SRobert Mustacchi                 size_t prefixcount = fixedlen - digcharlen;
770*4d9fdb46SRobert Mustacchi                 _dwarfstring_append_zeros(data,prefixcount);
771*4d9fdb46SRobert Mustacchi                 dwarfstring_append_length(data,digptr,digcharlen);
772*4d9fdb46SRobert Mustacchi             }
773*4d9fdb46SRobert Mustacchi         }
774*4d9fdb46SRobert Mustacchi     }
775*4d9fdb46SRobert Mustacchi     if (format[next]) {
776*4d9fdb46SRobert Mustacchi         size_t trailinglen = strlen(format+next);
777*4d9fdb46SRobert Mustacchi         dwarfstring_append_length(data,format+next,trailinglen);
778*4d9fdb46SRobert Mustacchi     }
779*4d9fdb46SRobert Mustacchi     return FALSE;
780*4d9fdb46SRobert Mustacchi }
781