Simple printf and sprintf - Raspberry Pi Forums


i added crude divide , module functions works fine.
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); }

gertk wrote: while (value >= divisor){
value -= divisor;
cc++;
}
over second of cpu print single integer! , not handle negative or unsigned quantities correctly.

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

Popular posts from this blog

CAN'T INSTALL MAMBELFISH 1.5 FROM DIRECTORY - Joomla! Forum - community, help and support

error: expected initializer before 'void'

CPU load monitoring using GPIO and leds - Raspberry Pi Forums