Simple printf and sprintf - Raspberry Pi Forums
i added crude divide , module functions works fine.
simple printf , sprintf function georges menie
simple printf , sprintf function georges menie
code: select all
/* copyright 2001, 2002 georges menie (http://www.menie.org) program free software; can redistribute and/or modify under terms of gnu lesser general public license published free software foundation; either version 2 of license, or (at option) later version. program distributed in hope useful, without warranty; without implied warranty of merchantability or fitness particular purpose. see gnu lesser general public license more details. should have received copy of gnu lesser general public license along program; if not, write free software foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa */ /* putchar external dependency file, if have working putchar, remove following define. if function should called else, replace serial_putchar(c) own function call. */ // define default character out function here #define putchar(c) serial_putchar(c) // crude divide , modulo function here // integer modulo v d int mymod(int value, int divisor) { int cc=0; // division 0 if (divisor==0) return 0xffffffff; while (value >= divisor){ value -= divisor; cc++; } return value; } // integer divide v d int mydiv(int value, int divisor) { int cc=0; // division zero.. if (divisor==0) return 0xffffffff; while (value >= divisor){ value -= divisor; cc++; } return cc; } static void printchar(char **str, int c) { extern int putchar(int c); if (str) { **str = c; ++(*str); } else (void)putchar(c); } #define pad_right 1 #define pad_zero 2 static int prints(char **out, const char *string, int width, int pad) { register int pc = 0, padchar = ' '; if (width > 0) { register int len = 0; register const char *ptr; for (ptr = string; *ptr; ++ptr) ++len; if (len >= width) width = 0; else width -= len; if (pad & pad_zero) padchar = '0'; } if (!(pad & pad_right)) { for ( ; width > 0; --width) { printchar (out, padchar); ++pc; } } for ( ; *string ; ++string) { printchar (out, *string); ++pc; } for ( ; width > 0; --width) { printchar (out, padchar); ++pc; } return pc; } /* following should enough 32 bit int */ #define print_buf_len 12 static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase) { char print_buf[print_buf_len]; register char *s; register int t, neg = 0, pc = 0; register unsigned int u = i; if (i == 0) { print_buf[0] = '0'; print_buf[1] = '\0'; return prints (out, print_buf, width, pad); } if (sg && b == 10 && < 0) { neg = 1; u = -i; } s = print_buf + print_buf_len-1; *s = '\0'; while (u) { t = mymod(u,b); if( t >= 10 ) t += letbase - '0' - 10; *--s = t + '0'; // u /= b u = mydiv(u,b); } if (neg) { if( width && (pad & pad_zero) ) { printchar (out, '-'); ++pc; --width; } else { *--s = '-'; } } return pc + prints (out, s, width, pad); } static int print(char **out, int *varg) { register int width, pad; register int pc = 0; register char *format = (char *)(*varg++); char scr[2]; for (; *format != 0; ++format) { if (*format == '%') { ++format; width = pad = 0; if (*format == '\0') break; if (*format == '%') goto out; if (*format == '-') { ++format; pad = pad_right; } while (*format == '0') { ++format; pad |= pad_zero; } for ( ; *format >= '0' && *format <= '9'; ++format) { width *= 10; width += *format - '0'; } if( *format == 's' ) { register char *s = *((char **)varg++); pc += prints (out, s?s:"(null)", width, pad); continue; } if( *format == 'd' ) { pc += printi (out, *varg++, 10, 1, width, pad, 'a'); continue; } if( *format == 'x' ) { pc += printi (out, *varg++, 16, 0, width, pad, 'a'); continue; } if( *format == 'x' ) { pc += printi (out, *varg++, 16, 0, width, pad, 'a'); continue; } if( *format == 'u' ) { pc += printi (out, *varg++, 10, 0, width, pad, 'a'); continue; } if( *format == 'c' ) { /* char converted int pushed on stack */ scr[0] = *varg++; scr[1] = '\0'; pc += prints (out, scr, width, pad); continue; } } else { out: printchar (out, *format); ++pc; } } if (out) **out = '\0'; return pc; } /* assuming sizeof(void *) == sizeof(int) */ int printf(const char *format, ...) { register int *varg = (int *)(&format); return print(0, varg); } int sprintf(char *out, const char *format, ...) { register int *varg = (int *)(&format); return print(&out, varg); }
over second of cpu print single integer! , not handle negative or unsigned quantities correctly.gertk wrote: while (value >= divisor){
value -= divisor;
cc++;
}
correct naïve way integer division bit @ time using shifts. suggest work out how use optimized implementations supplied gcc instead. not these better, gcc smart enough eliminate divisions entirely divisor known. (for instance, (x/10) implemented (((long long)x*1717986919>>34)+(x<0)).)
raspberrypi
Comments
Post a Comment