1*7d9cde10SStefan Roese /* 2*7d9cde10SStefan Roese * Tiny printf version for SPL 3*7d9cde10SStefan Roese * 4*7d9cde10SStefan Roese * Copied from: 5*7d9cde10SStefan Roese * http://www.sparetimelabs.com/printfrevisited/printfrevisited.php 6*7d9cde10SStefan Roese * 7*7d9cde10SStefan Roese * Copyright (C) 2004,2008 Kustaa Nyholm 8*7d9cde10SStefan Roese * 9*7d9cde10SStefan Roese * SPDX-License-Identifier: LGPL-2.1+ 10*7d9cde10SStefan Roese */ 11*7d9cde10SStefan Roese 12*7d9cde10SStefan Roese #include <common.h> 13*7d9cde10SStefan Roese #include <stdarg.h> 14*7d9cde10SStefan Roese #include <serial.h> 15*7d9cde10SStefan Roese 16*7d9cde10SStefan Roese static char *bf; 17*7d9cde10SStefan Roese static char buf[12]; 18*7d9cde10SStefan Roese static unsigned int num; 19*7d9cde10SStefan Roese static char uc; 20*7d9cde10SStefan Roese static char zs; 21*7d9cde10SStefan Roese 22*7d9cde10SStefan Roese static void out(char c) 23*7d9cde10SStefan Roese { 24*7d9cde10SStefan Roese *bf++ = c; 25*7d9cde10SStefan Roese } 26*7d9cde10SStefan Roese 27*7d9cde10SStefan Roese static void out_dgt(char dgt) 28*7d9cde10SStefan Roese { 29*7d9cde10SStefan Roese out(dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10)); 30*7d9cde10SStefan Roese zs = 1; 31*7d9cde10SStefan Roese } 32*7d9cde10SStefan Roese 33*7d9cde10SStefan Roese static void div_out(unsigned int div) 34*7d9cde10SStefan Roese { 35*7d9cde10SStefan Roese unsigned char dgt = 0; 36*7d9cde10SStefan Roese 37*7d9cde10SStefan Roese num &= 0xffff; /* just for testing the code with 32 bit ints */ 38*7d9cde10SStefan Roese while (num >= div) { 39*7d9cde10SStefan Roese num -= div; 40*7d9cde10SStefan Roese dgt++; 41*7d9cde10SStefan Roese } 42*7d9cde10SStefan Roese 43*7d9cde10SStefan Roese if (zs || dgt > 0) 44*7d9cde10SStefan Roese out_dgt(dgt); 45*7d9cde10SStefan Roese } 46*7d9cde10SStefan Roese 47*7d9cde10SStefan Roese int printf(const char *fmt, ...) 48*7d9cde10SStefan Roese { 49*7d9cde10SStefan Roese va_list va; 50*7d9cde10SStefan Roese char ch; 51*7d9cde10SStefan Roese char *p; 52*7d9cde10SStefan Roese 53*7d9cde10SStefan Roese va_start(va, fmt); 54*7d9cde10SStefan Roese 55*7d9cde10SStefan Roese while ((ch = *(fmt++))) { 56*7d9cde10SStefan Roese if (ch != '%') { 57*7d9cde10SStefan Roese putc(ch); 58*7d9cde10SStefan Roese } else { 59*7d9cde10SStefan Roese char lz = 0; 60*7d9cde10SStefan Roese char w = 0; 61*7d9cde10SStefan Roese 62*7d9cde10SStefan Roese ch = *(fmt++); 63*7d9cde10SStefan Roese if (ch == '0') { 64*7d9cde10SStefan Roese ch = *(fmt++); 65*7d9cde10SStefan Roese lz = 1; 66*7d9cde10SStefan Roese } 67*7d9cde10SStefan Roese 68*7d9cde10SStefan Roese if (ch >= '0' && ch <= '9') { 69*7d9cde10SStefan Roese w = 0; 70*7d9cde10SStefan Roese while (ch >= '0' && ch <= '9') { 71*7d9cde10SStefan Roese w = (((w << 2) + w) << 1) + ch - '0'; 72*7d9cde10SStefan Roese ch = *fmt++; 73*7d9cde10SStefan Roese } 74*7d9cde10SStefan Roese } 75*7d9cde10SStefan Roese bf = buf; 76*7d9cde10SStefan Roese p = bf; 77*7d9cde10SStefan Roese zs = 0; 78*7d9cde10SStefan Roese 79*7d9cde10SStefan Roese switch (ch) { 80*7d9cde10SStefan Roese case 0: 81*7d9cde10SStefan Roese goto abort; 82*7d9cde10SStefan Roese case 'u': 83*7d9cde10SStefan Roese case 'd': 84*7d9cde10SStefan Roese num = va_arg(va, unsigned int); 85*7d9cde10SStefan Roese if (ch == 'd' && (int)num < 0) { 86*7d9cde10SStefan Roese num = -(int)num; 87*7d9cde10SStefan Roese out('-'); 88*7d9cde10SStefan Roese } 89*7d9cde10SStefan Roese div_out(10000); 90*7d9cde10SStefan Roese div_out(1000); 91*7d9cde10SStefan Roese div_out(100); 92*7d9cde10SStefan Roese div_out(10); 93*7d9cde10SStefan Roese out_dgt(num); 94*7d9cde10SStefan Roese break; 95*7d9cde10SStefan Roese case 'x': 96*7d9cde10SStefan Roese case 'X': 97*7d9cde10SStefan Roese uc = ch == 'X'; 98*7d9cde10SStefan Roese num = va_arg(va, unsigned int); 99*7d9cde10SStefan Roese div_out(0x1000); 100*7d9cde10SStefan Roese div_out(0x100); 101*7d9cde10SStefan Roese div_out(0x10); 102*7d9cde10SStefan Roese out_dgt(num); 103*7d9cde10SStefan Roese break; 104*7d9cde10SStefan Roese case 'c': 105*7d9cde10SStefan Roese out((char)(va_arg(va, int))); 106*7d9cde10SStefan Roese break; 107*7d9cde10SStefan Roese case 's': 108*7d9cde10SStefan Roese p = va_arg(va, char*); 109*7d9cde10SStefan Roese break; 110*7d9cde10SStefan Roese case '%': 111*7d9cde10SStefan Roese out('%'); 112*7d9cde10SStefan Roese default: 113*7d9cde10SStefan Roese break; 114*7d9cde10SStefan Roese } 115*7d9cde10SStefan Roese 116*7d9cde10SStefan Roese *bf = 0; 117*7d9cde10SStefan Roese bf = p; 118*7d9cde10SStefan Roese while (*bf++ && w > 0) 119*7d9cde10SStefan Roese w--; 120*7d9cde10SStefan Roese while (w-- > 0) 121*7d9cde10SStefan Roese putc(lz ? '0' : ' '); 122*7d9cde10SStefan Roese while ((ch = *p++)) 123*7d9cde10SStefan Roese putc(ch); 124*7d9cde10SStefan Roese } 125*7d9cde10SStefan Roese } 126*7d9cde10SStefan Roese 127*7d9cde10SStefan Roese abort: 128*7d9cde10SStefan Roese va_end(va); 129*7d9cde10SStefan Roese return 0; 130*7d9cde10SStefan Roese } 131