• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <stdarg.h>
30 #include "libc_private.h"
31 
hex2asc(int n)32 static int hex2asc(int n)
33 {
34     n &= 15;
35     if(n > 9){
36         return ('a' - 10) + n;
37     } else {
38         return '0' + n;
39     }
40 }
41 
xputs(const char * s,void (* xputc)(unsigned n,void * cookie),void * cookie)42 static void xputs(const char *s, void (*xputc)(unsigned n, void *cookie), void *cookie)
43 {
44     while (*s) {
45         xputc(*s++, cookie);
46     }
47 }
48 
__xprintf(const char * fmt,va_list ap,void (* xputc)(unsigned n,void * cookie),void * cookie)49 void __xprintf(const char *fmt, va_list ap,
50                void (*xputc)(unsigned n, void *cookie),
51                void *cookie)
52 {
53     char scratch[16];
54 
55     for(;;){
56         switch(*fmt){
57         case 0:
58             va_end(ap);
59             return;
60         case '%':
61             switch(fmt[1]) {
62             case 'c': {
63                 unsigned n = va_arg(ap, unsigned);
64                 xputc(n, cookie);
65                 fmt += 2;
66                 continue;
67             }
68             case 'h': {
69                 unsigned n = va_arg(ap, unsigned);
70                 xputc(hex2asc(n >> 12), cookie);
71                 xputc(hex2asc(n >> 8), cookie);
72                 xputc(hex2asc(n >> 4), cookie);
73                 xputc(hex2asc(n >> 0), cookie);
74                 fmt += 2;
75                 continue;
76             }
77             case 'b': {
78                 unsigned n = va_arg(ap, unsigned);
79                 xputc(hex2asc(n >> 4), cookie);
80                 xputc(hex2asc(n >> 0), cookie);
81                 fmt += 2;
82                 continue;
83             }
84             case 'p':
85             case 'X':
86             case 'x': {
87                 unsigned n = va_arg(ap, unsigned);
88                 char *p = scratch + 15;
89                 *p = 0;
90                 do {
91                     *--p = hex2asc(n);
92                     n = n >> 4;
93                 } while(n != 0);
94                 while(p > (scratch + 7)) *--p = '0';
95                 xputs(p, xputc, cookie);
96                 fmt += 2;
97                 continue;
98             }
99             case 'd': {
100                 int n = va_arg(ap, int);
101                 char *p = scratch + 15;
102                 *p = 0;
103                 if(n < 0) {
104                     xputc('-', cookie);
105                     n = -n;
106                 }
107                 do {
108                     *--p = (n % 10) + '0';
109                     n /= 10;
110                 } while(n != 0);
111                 xputs(p, xputc, cookie);
112                 fmt += 2;
113                 continue;
114             }
115             case 's': {
116                 char *s = va_arg(ap, char*);
117                 if(s == 0) s = "(null)";
118                 xputs(s, xputc, cookie);
119                 fmt += 2;
120                 continue;
121             }
122             }
123             xputc(*fmt++, cookie);
124             break;
125         case '\n':
126             xputc('\r', cookie);
127         default:
128             xputc(*fmt++, cookie);
129         }
130     }
131 }
132