1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Copyright (c) 1995-1999 Kungliga Tekniska H�gskolan
3478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (Royal Institute of Technology, Stockholm, Sweden).
4478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * All rights reserved.
5478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
6478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Redistribution and use in source and binary forms, with or without
7478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * modification, are permitted provided that the following conditions
8478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * are met:
9478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
10478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
11478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
12478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
13478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
14478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
15478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *    documentation and/or other materials provided with the distribution.
16478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
17478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3. Neither the name of the Institute nor the names of its contributors
18478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *    may be used to endorse or promote products derived from this software
19478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *    without specific prior written permission.
20478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
21478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SUCH DAMAGE.
32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
34511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* $Id: snprintf.c,v 1.1 2004-04-05 22:43:51 guy Exp $ */
35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CONFIG_H
37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <config.h>
38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef lint
41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const char rcsid[] _U_ =
42511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall     "@(#) $Header: /tcpdump/master/libpcap/missing/snprintf.c,v 1.1 2004-04-05 22:43:51 guy Exp $";
43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdio.h>
46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdarg.h>
47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h>
48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h>
49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <ctype.h>
50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/types.h>
51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <pcap-int.h>
53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectenum format_flags {
55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    minus_flag     =  1,
56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    plus_flag      =  2,
57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    space_flag     =  4,
58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    alternate_flag =  8,
59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    zero_flag      = 16
60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project};
61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Common state
64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct state {
67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  unsigned char *str;
68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  unsigned char *s;
69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  unsigned char *theend;
70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  size_t sz;
71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  size_t max_sz;
72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int (*append_char)(struct state *, unsigned char);
73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int (*reserve)(struct state *, size_t);
74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* XXX - methods */
75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project};
76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef HAVE_VSNPRINTF
78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectsn_reserve (struct state *state, size_t n)
80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return state->s + n > state->theend;
82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectsn_append_char (struct state *state, unsigned char c)
86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (sn_reserve (state, 1)) {
88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return 1;
89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  } else {
90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    *state->s++ = c;
91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return 0;
92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if 0
97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectas_reserve (struct state *state, size_t n)
99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (state->s + n > state->theend) {
101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    int off = state->s - state->str;
102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    unsigned char *tmp;
103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (state->max_sz && state->sz >= state->max_sz)
105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return 1;
106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    state->sz = max(state->sz * 2, state->sz + n);
108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (state->max_sz)
109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      state->sz = min(state->sz, state->max_sz);
110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    tmp = realloc (state->str, state->sz);
111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (tmp == NULL)
112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return 1;
113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    state->str = tmp;
114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    state->s = state->str + off;
115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    state->theend = state->str + state->sz - 1;
116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return 0;
118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectas_append_char (struct state *state, unsigned char c)
122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(as_reserve (state, 1))
124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return 1;
125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  else {
126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    *state->s++ = c;
127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return 0;
128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectappend_number(struct state *state,
134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	      unsigned long num, unsigned base, char *rep,
135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	      int width, int prec, int flags, int minusp)
136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int len = 0;
138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int i;
139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* given precision, ignore zero flag */
141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(prec != -1)
142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    flags &= ~zero_flag;
143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  else
144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    prec = 1;
145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* zero value with zero precision -> "" */
146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(prec == 0 && num == 0)
147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return 0;
148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  do{
149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if((*state->append_char)(state, rep[num % base]))
150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return 1;
151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    len++;
152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    num /= base;
153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }while(num);
154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  prec -= len;
155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* pad with prec zeros */
156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  while(prec-- > 0){
157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if((*state->append_char)(state, '0'))
158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return 1;
159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    len++;
160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* add length of alternate prefix (added later) to len */
162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(flags & alternate_flag && (base == 16 || base == 8))
163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    len += base / 8;
164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* pad with zeros */
165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(flags & zero_flag){
166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    width -= len;
167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if(minusp || (flags & space_flag) || (flags & plus_flag))
168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      width--;
169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    while(width-- > 0){
170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if((*state->append_char)(state, '0'))
171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 1;
172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      len++;
173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* add alternate prefix */
176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(flags & alternate_flag && (base == 16 || base == 8)){
177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if(base == 16)
178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if((*state->append_char)(state, rep[10] + 23)) /* XXX */
179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 1;
180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if((*state->append_char)(state, '0'))
181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return 1;
182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* add sign */
184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(minusp){
185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if((*state->append_char)(state, '-'))
186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return 1;
187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    len++;
188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  } else if(flags & plus_flag) {
189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if((*state->append_char)(state, '+'))
190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return 1;
191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    len++;
192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  } else if(flags & space_flag) {
193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if((*state->append_char)(state, ' '))
194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return 1;
195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    len++;
196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(flags & minus_flag)
198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    /* swap before padding with spaces */
199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    for(i = 0; i < len / 2; i++){
200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      char c = state->s[-i-1];
201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      state->s[-i-1] = state->s[-len+i];
202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      state->s[-len+i] = c;
203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  width -= len;
205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  while(width-- > 0){
206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if((*state->append_char)(state,  ' '))
207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return 1;
208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    len++;
209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(!(flags & minus_flag))
211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    /* swap after padding with spaces */
212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    for(i = 0; i < len / 2; i++){
213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      char c = state->s[-i-1];
214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      state->s[-i-1] = state->s[-len+i];
215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      state->s[-len+i] = c;
216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return 0;
219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectappend_string (struct state *state,
223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	       unsigned char *arg,
224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	       int width,
225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	       int prec,
226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	       int flags)
227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(prec != -1)
229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    width -= prec;
230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  else
231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    width -= strlen((char *)arg);
232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(!(flags & minus_flag))
233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    while(width-- > 0)
234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if((*state->append_char) (state, ' '))
235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 1;
236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (prec != -1) {
237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    while (*arg && prec--)
238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if ((*state->append_char) (state, *arg++))
239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 1;
240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  } else {
241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    while (*arg)
242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if ((*state->append_char) (state, *arg++))
243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 1;
244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if(flags & minus_flag)
246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    while(width-- > 0)
247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if((*state->append_char) (state, ' '))
248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 1;
249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return 0;
250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectappend_char(struct state *state,
254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    unsigned char arg,
255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    int width,
256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    int flags)
257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  while(!(flags & minus_flag) && --width > 0)
259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if((*state->append_char) (state, ' '))
260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return 1;
261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if((*state->append_char) (state, arg))
263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return 1;
264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  while((flags & minus_flag) && --width > 0)
265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if((*state->append_char) (state, ' '))
266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return 1;
267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return 0;
269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This can't be made into a function...
273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define PARSE_INT_FORMAT(res, arg, unsig) \
276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectif (long_flag) \
277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     res = (unsig long)va_arg(arg, unsig long); \
278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectelse if (short_flag) \
279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     res = (unsig short)va_arg(arg, unsig int); \
280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectelse \
281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     res = (unsig int)va_arg(arg, unsig int)
282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * zyxprintf - return 0 or -1
285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectxyzprintf (struct state *state, const char *char_format, va_list ap)
289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  const unsigned char *format = (const unsigned char *)char_format;
291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  unsigned char c;
292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  while((c = *format++)) {
294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (c == '%') {
295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      int flags      = 0;
296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      int width      = 0;
297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      int prec       = -1;
298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      int long_flag  = 0;
299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      int short_flag = 0;
300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      /* flags */
302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      while((c = *format++)){
303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(c == '-')
304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  flags |= minus_flag;
305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else if(c == '+')
306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  flags |= plus_flag;
307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else if(c == ' ')
308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  flags |= space_flag;
309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else if(c == '#')
310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  flags |= alternate_flag;
311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else if(c == '0')
312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  flags |= zero_flag;
313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  break;
315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if((flags & space_flag) && (flags & plus_flag))
318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	flags ^= space_flag;
319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if((flags & minus_flag) && (flags & zero_flag))
321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	flags ^= zero_flag;
322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      /* width */
324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if (isdigit(c))
325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	do {
326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  width = width * 10 + c - '0';
327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  c = *format++;
328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	} while(isdigit(c));
329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      else if(c == '*') {
330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	width = va_arg(ap, int);
331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	c = *format++;
332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      /* precision */
335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if (c == '.') {
336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	prec = 0;
337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	c = *format++;
338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (isdigit(c))
339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  do {
340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    prec = prec * 10 + c - '0';
341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    c = *format++;
342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  } while(isdigit(c));
343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else if (c == '*') {
344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  prec = va_arg(ap, int);
345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  c = *format++;
346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      /* size */
350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if (c == 'h') {
352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	short_flag = 1;
353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	c = *format++;
354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      } else if (c == 'l') {
355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	long_flag = 1;
356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	c = *format++;
357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      switch (c) {
360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case 'c' :
361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(append_char(state, va_arg(ap, int), width, flags))
362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  return -1;
363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	break;
364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case 's' :
365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (append_string(state,
366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			  va_arg(ap, unsigned char*),
367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			  width,
368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			  prec,
369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			  flags))
370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  return -1;
371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	break;
372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case 'd' :
373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case 'i' : {
374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	long arg;
375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned long num;
376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int minusp = 0;
377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	PARSE_INT_FORMAT(arg, ap, signed);
379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (arg < 0) {
381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  minusp = 1;
382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  num = -arg;
383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	} else
384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  num = arg;
385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (append_number (state, num, 10, "0123456789",
387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			   width, prec, flags, minusp))
388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  return -1;
389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	break;
390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case 'u' : {
392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned long arg;
393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	PARSE_INT_FORMAT(arg, ap, unsigned);
395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (append_number (state, arg, 10, "0123456789",
397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			   width, prec, flags, 0))
398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  return -1;
399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	break;
400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case 'o' : {
402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned long arg;
403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	PARSE_INT_FORMAT(arg, ap, unsigned);
405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (append_number (state, arg, 010, "01234567",
407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			   width, prec, flags, 0))
408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  return -1;
409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	break;
410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case 'x' : {
412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned long arg;
413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	PARSE_INT_FORMAT(arg, ap, unsigned);
415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (append_number (state, arg, 0x10, "0123456789abcdef",
417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			   width, prec, flags, 0))
418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  return -1;
419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	break;
420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case 'X' :{
422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned long arg;
423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	PARSE_INT_FORMAT(arg, ap, unsigned);
425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (append_number (state, arg, 0x10, "0123456789ABCDEF",
427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			   width, prec, flags, 0))
428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  return -1;
429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	break;
430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case 'p' : {
432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned long arg = (unsigned long)va_arg(ap, void*);
433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (append_number (state, arg, 0x10, "0123456789ABCDEF",
435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			   width, prec, flags, 0))
436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  return -1;
437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	break;
438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case 'n' : {
440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int *arg = va_arg(ap, int*);
441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	*arg = state->s - state->str;
442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	break;
443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case '\0' :
445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  --format;
446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  /* FALLTHROUGH */
447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      case '%' :
448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if ((*state->append_char)(state, c))
449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  return -1;
450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	break;
451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      default :
452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (   (*state->append_char)(state, '%')
453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    || (*state->append_char)(state, c))
454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	  return -1;
455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	break;
456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    } else
458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if ((*state->append_char) (state, c))
459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return -1;
460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return 0;
462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef HAVE_SNPRINTF
465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectsnprintf (char *str, size_t sz, const char *format, ...)
467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  va_list args;
469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int ret;
470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  va_start(args, format);
472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  ret = vsnprintf (str, sz, format, args);
473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PARANOIA
475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    int ret2;
477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    char *tmp;
478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    tmp = malloc (sz);
480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (tmp == NULL)
481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      abort ();
482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    ret2 = vsprintf (tmp, format, args);
484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (ret != ret2 || strcmp(str, tmp))
485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      abort ();
486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    free (tmp);
487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  va_end(args);
491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return ret;
492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if 0
496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef HAVE_ASPRINTF
497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectasprintf (char **ret, const char *format, ...)
499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  va_list args;
501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int val;
502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  va_start(args, format);
504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  val = vasprintf (ret, format, args);
505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PARANOIA
507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    int ret2;
509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    char *tmp;
510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    tmp = malloc (val + 1);
511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (tmp == NULL)
512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      abort ();
513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    ret2 = vsprintf (tmp, format, args);
515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (val != ret2 || strcmp(*ret, tmp))
516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      abort ();
517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    free (tmp);
518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  va_end(args);
522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return val;
523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef HAVE_ASNPRINTF
527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectasnprintf (char **ret, size_t max_sz, const char *format, ...)
529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  va_list args;
531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int val;
532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  va_start(args, format);
534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  val = vasnprintf (ret, max_sz, format, args);
535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef PARANOIA
537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    int ret2;
539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    char *tmp;
540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    tmp = malloc (val + 1);
541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (tmp == NULL)
542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      abort ();
543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    ret2 = vsprintf (tmp, format, args);
545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (val != ret2 || strcmp(*ret, tmp))
546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      abort ();
547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    free (tmp);
548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  va_end(args);
552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return val;
553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef HAVE_VASPRINTF
557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvasprintf (char **ret, const char *format, va_list args)
559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return vasnprintf (ret, 0, format, args);
561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef HAVE_VASNPRINTF
566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int st;
570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  size_t len;
571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct state state;
572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.max_sz = max_sz;
574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.sz     = 1;
575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.str    = malloc(state.sz);
576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (state.str == NULL) {
577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    *ret = NULL;
578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return -1;
579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.s = state.str;
581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.theend = state.s + state.sz - 1;
582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.append_char = as_append_char;
583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.reserve     = as_reserve;
584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  st = xyzprintf (&state, format, args);
586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (st) {
587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    free (state.str);
588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    *ret = NULL;
589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return -1;
590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  } else {
591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    char *tmp;
592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    *state.s = '\0';
594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    len = state.s - state.str;
595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    tmp = realloc (state.str, len+1);
596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (tmp == NULL) {
597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      free (state.str);
598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      *ret = NULL;
599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return -1;
600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    *ret = tmp;
602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return len;
603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef HAVE_VSNPRINTF
609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvsnprintf (char *str, size_t sz, const char *format, va_list args)
611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct state state;
613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int ret;
614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  unsigned char *ustr = (unsigned char *)str;
615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.max_sz = 0;
617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.sz     = sz;
618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.str    = ustr;
619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.s      = ustr;
620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.theend = ustr + sz - 1;
621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.append_char = sn_append_char;
622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  state.reserve     = sn_reserve;
623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  ret = xyzprintf (&state, format, args);
625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  *state.s = '\0';
626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (ret)
627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return sz;
628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  else
629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return state.s - state.str;
630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
633