sprintf.c (3400B)
1#include <types.h> 2#include <stdio.h> 3#include <stdarg.h> 4#include <stdlib.h> 5#include <stdint.h> 6 7typedef void (*emitter_t)(char, char **) OLDCALL; 8 9static const char _hex[] = "0123456789ABCDEF"; 10 11inline void _printhex(uint16_t u, emitter_t emitter, char ** pData) 12{ 13 (*emitter)(_hex[(uint8_t)(u >> 8) >> 4], pData); 14 (*emitter)(_hex[(uint8_t)(u >> 8) & 0x0fu], pData); 15 (*emitter)(_hex[((uint8_t)u >> 4) & 0x0fu], pData); 16 (*emitter)(_hex[(uint8_t)u & 0x0fu], pData); 17} 18 19inline void _printhexbyte(uint8_t u, emitter_t emitter, char ** pData) 20{ 21 (*emitter)(_hex[u >> 4], pData); 22 (*emitter)(_hex[u & 0x0fu], pData); 23} 24 25static void _printbuf(char * buf, emitter_t emitter, char ** pData) { 26 for (char *s = buf; *s; s++) (*emitter)(*s, pData); 27} 28 29void __printf(const char *format, emitter_t emitter, char **pData, va_list va) 30{ 31 char buf[16]; 32 while ((uint8_t)(*format)) { 33 if ((uint8_t)(*format) == '%') { 34 format++; 35 36 // 0 Padding is not supported, ignore 37 if ((uint8_t)(*format) == '0') format++; 38 39 // Width Specifier is not supported, ignore 1 digit worth 40 if ((uint8_t)((uint8_t)(*format) - '1') < 9u) format++; 41 42 switch ((uint8_t)(*format)) { 43 case 'h': { 44 switch ((uint8_t)(*++format)) { 45 case 'X' : 46 case 'x' : { 47 _printhexbyte(va_arg(va, char), emitter, pData); 48 break; 49 } 50 case 'u': 51 { 52 uitoa((unsigned char)va_arg(va, char), buf, 10); 53 _printbuf(buf, emitter, pData); 54 break; 55 } 56 case 'd': 57 { 58 itoa((signed char)va_arg(va, char), buf, 10); 59 _printbuf(buf, emitter, pData); 60 break; 61 } 62 } 63 break; 64 } 65 case 'c': { 66 char c = va_arg(va, char); 67 (*emitter)(c, pData); 68 break; 69 } 70 case 'u': 71 { 72 uitoa(va_arg(va, int), buf, 10); 73 _printbuf(buf, emitter, pData); 74 break; 75 } 76 case 'd': 77 { 78 itoa(va_arg(va, int), buf, 10); 79 _printbuf(buf, emitter, pData); 80 break; 81 } 82 case 'X': 83 case 'x': 84 { 85 _printhex(va_arg(va, int), emitter, pData); 86 break; 87 } 88 case 's': 89 { 90 _printbuf(va_arg(va, char *), emitter, pData); 91 break; 92 } 93 } 94 } else { 95 (*emitter)(*format, pData); 96 } 97 format++; 98 } 99} 100 101static void _sprintf_emitter(char c, char ** pData) OLDCALL { 102 **pData = c; 103 (*pData)++; 104} 105 106void sprintf(char *into, const char *format, ...) OLDCALL { 107 va_list va; 108 va_start(va, format); 109 110 __printf(format, _sprintf_emitter, &into, va); 111 _sprintf_emitter('\0', &into); 112}