17d9cde10SStefan Roese /* 27d9cde10SStefan Roese * Tiny printf version for SPL 37d9cde10SStefan Roese * 47d9cde10SStefan Roese * Copied from: 57d9cde10SStefan Roese * http://www.sparetimelabs.com/printfrevisited/printfrevisited.php 67d9cde10SStefan Roese * 77d9cde10SStefan Roese * Copyright (C) 2004,2008 Kustaa Nyholm 87d9cde10SStefan Roese * 97d9cde10SStefan Roese * SPDX-License-Identifier: LGPL-2.1+ 107d9cde10SStefan Roese */ 117d9cde10SStefan Roese 127d9cde10SStefan Roese #include <common.h> 137d9cde10SStefan Roese #include <stdarg.h> 147d9cde10SStefan Roese #include <serial.h> 157d9cde10SStefan Roese 167d9cde10SStefan Roese static char *bf; 177d9cde10SStefan Roese static char zs; 187d9cde10SStefan Roese 197d9cde10SStefan Roese static void out(char c) 207d9cde10SStefan Roese { 217d9cde10SStefan Roese *bf++ = c; 227d9cde10SStefan Roese } 237d9cde10SStefan Roese 247d9cde10SStefan Roese static void out_dgt(char dgt) 257d9cde10SStefan Roese { 26*a5ecdd08SStefan Roese out(dgt + (dgt < 10 ? '0' : 'a' - 10)); 277d9cde10SStefan Roese zs = 1; 287d9cde10SStefan Roese } 297d9cde10SStefan Roese 30*a5ecdd08SStefan Roese static void div_out(unsigned int *num, unsigned int div) 317d9cde10SStefan Roese { 327d9cde10SStefan Roese unsigned char dgt = 0; 337d9cde10SStefan Roese 34*a5ecdd08SStefan Roese while (*num >= div) { 35*a5ecdd08SStefan Roese *num -= div; 367d9cde10SStefan Roese dgt++; 377d9cde10SStefan Roese } 387d9cde10SStefan Roese 397d9cde10SStefan Roese if (zs || dgt > 0) 407d9cde10SStefan Roese out_dgt(dgt); 417d9cde10SStefan Roese } 427d9cde10SStefan Roese 437d9cde10SStefan Roese int printf(const char *fmt, ...) 447d9cde10SStefan Roese { 457d9cde10SStefan Roese va_list va; 467d9cde10SStefan Roese char ch; 477d9cde10SStefan Roese char *p; 48*a5ecdd08SStefan Roese unsigned int num; 49*a5ecdd08SStefan Roese char buf[12]; 50*a5ecdd08SStefan Roese unsigned int div; 517d9cde10SStefan Roese 527d9cde10SStefan Roese va_start(va, fmt); 537d9cde10SStefan Roese 547d9cde10SStefan Roese while ((ch = *(fmt++))) { 557d9cde10SStefan Roese if (ch != '%') { 567d9cde10SStefan Roese putc(ch); 577d9cde10SStefan Roese } else { 587d9cde10SStefan Roese char lz = 0; 597d9cde10SStefan Roese char w = 0; 607d9cde10SStefan Roese 617d9cde10SStefan Roese ch = *(fmt++); 627d9cde10SStefan Roese if (ch == '0') { 637d9cde10SStefan Roese ch = *(fmt++); 647d9cde10SStefan Roese lz = 1; 657d9cde10SStefan Roese } 667d9cde10SStefan Roese 677d9cde10SStefan Roese if (ch >= '0' && ch <= '9') { 687d9cde10SStefan Roese w = 0; 697d9cde10SStefan Roese while (ch >= '0' && ch <= '9') { 70*a5ecdd08SStefan Roese w = (w * 10) + ch - '0'; 717d9cde10SStefan Roese ch = *fmt++; 727d9cde10SStefan Roese } 737d9cde10SStefan Roese } 747d9cde10SStefan Roese bf = buf; 757d9cde10SStefan Roese p = bf; 767d9cde10SStefan Roese zs = 0; 777d9cde10SStefan Roese 787d9cde10SStefan Roese switch (ch) { 797d9cde10SStefan Roese case 0: 807d9cde10SStefan Roese goto abort; 817d9cde10SStefan Roese case 'u': 827d9cde10SStefan Roese case 'd': 837d9cde10SStefan Roese num = va_arg(va, unsigned int); 847d9cde10SStefan Roese if (ch == 'd' && (int)num < 0) { 857d9cde10SStefan Roese num = -(int)num; 867d9cde10SStefan Roese out('-'); 877d9cde10SStefan Roese } 88*a5ecdd08SStefan Roese for (div = 1000000000; div; div /= 10) 89*a5ecdd08SStefan Roese div_out(&num, div); 907d9cde10SStefan Roese break; 917d9cde10SStefan Roese case 'x': 927d9cde10SStefan Roese num = va_arg(va, unsigned int); 93*a5ecdd08SStefan Roese for (div = 0x10000000; div; div /= 0x10) 94*a5ecdd08SStefan Roese div_out(&num, div); 957d9cde10SStefan Roese break; 967d9cde10SStefan Roese case 'c': 977d9cde10SStefan Roese out((char)(va_arg(va, int))); 987d9cde10SStefan Roese break; 997d9cde10SStefan Roese case 's': 1007d9cde10SStefan Roese p = va_arg(va, char*); 1017d9cde10SStefan Roese break; 1027d9cde10SStefan Roese case '%': 1037d9cde10SStefan Roese out('%'); 1047d9cde10SStefan Roese default: 1057d9cde10SStefan Roese break; 1067d9cde10SStefan Roese } 1077d9cde10SStefan Roese 1087d9cde10SStefan Roese *bf = 0; 1097d9cde10SStefan Roese bf = p; 1107d9cde10SStefan Roese while (*bf++ && w > 0) 1117d9cde10SStefan Roese w--; 1127d9cde10SStefan Roese while (w-- > 0) 1137d9cde10SStefan Roese putc(lz ? '0' : ' '); 1147d9cde10SStefan Roese while ((ch = *p++)) 1157d9cde10SStefan Roese putc(ch); 1167d9cde10SStefan Roese } 1177d9cde10SStefan Roese } 1187d9cde10SStefan Roese 1197d9cde10SStefan Roese abort: 1207d9cde10SStefan Roese va_end(va); 1217d9cde10SStefan Roese return 0; 1227d9cde10SStefan Roese } 123