Hi Leutz, wen's interessiert, ich hab ein minimales printf geschrieben. Aufruf und Parameterliste wie printf, im Moment werden aber nur: %i (6 Stellen, kann jeder selber erweitern) %c %s sowie \n \t unterstützt. Mein Projekt ist damit um ca. 5k kleiner geworden, mein printf braucht (keil-compiler) <300k Bleibt nur noch der retarget auf welches IO auch immer. Ich habe fürs retargeting an der fputc angesetzt, diese schreibt auf den UART. Für dieses printf hab ich die einfach weiterverwendet, man kann aber auch was eigenes statt der fputc einbauen, was z.B. auf den uart schreibt. Viel Spass damit! Anregungen und konstruktive Kritik erwünscht ;-) Anmerkung: Dies ist die erste Version g --------------- Header: #ifndef _THPRINTF_H_ #define _THPRINTF_H_ int thprintf(char *string, ...); #endif C-File: // Th printf /* Author: Thorsten de Buhr mail: thorsten@lasertechnix.de Use: Use is free, could run or not ;-) U may change every printf in cour code to thprintf, the rest is the same. U may use: %i, %s, %c \n, \t More is not implemented now. Have fun with this very small print-function, it uses ~300 bytes of code (printf uses >5k!) */ #include <stdarg.h> #include "../src/main.h" #include "../src/thprintf.h" int thprintf(char *string, ...) { va_list tag; int pointer=0, num_avaiable=0, i=0, j=0; char char_parse=0, *char_pointer=0; signed int int_tmp=0, int_tmp2=0; va_start(tag, string); do { char_parse = string[pointer]; // get char if(char_parse == '%') { pointer++; char_parse = string[pointer]; switch(char_parse) { case 'i': { int_tmp = va_arg(tag, int); num_avaiable=0; j=1000000; if(int_tmp <0) { fputc('-', 0); int_tmp*=(-1); } for(i=6; i>0; i--) { j/=10; int_tmp2 = int_tmp / j; if((int_tmp2) || (num_avaiable)) { num_avaiable=1; fputc(((int_tmp2))+48, 0); int_tmp%=j; } } if(!num_avaiable) fputc('0', 0); // Null ausgeben } break; case 'c': { fputc((char)va_arg(tag, int), 0); }break; case 's': { char_pointer = va_arg(tag, char*); while(*char_pointer) { fputc(*char_pointer, 0); char_pointer++; } break; } } } // end if '%' else if(char_parse == '\\') { pointer++; char_parse = string[pointer]; switch(char_parse) { case 'n': fputc('\n', 0); break; case 't': fputc('\t', 0); break; } } // end if '\' else fputc(char_parse, 0); pointer++; } while(char_parse); va_end(tag); return(0); }
Bin erstaunt das der Keil so etwas nicht in der LIB hat, ist beim SDCC standard, siehe printf_small, printf_tiny ...
Hi, ich weiss nicht, obs in der Keil so was gibt (mal schaun), aber das ist sicher nicht <300 byte gross ;-))
Bezeichnung SDCC ist printf_tiny (ca. 300 Byte). Kannst dir ja die LIB mal ansehen.
Hi, danke für den Tipp. Oki, das Ding ist in asm geschrieben, da kann ich mit der C-Ftk. nicht mithalten grins Dafür ist meins sehr leicht erweiterbar und anpassbar ;-) Greetz, th.
Hi Leutz, mittlerweile bin ich auf 256 Bytes runter... #include <stdarg.h> #include "../src/main.h" #include "../src/thprintf.h" int thprintf(char *string, ...) { va_list tag; int i=0; char *pointer=0; signed int int_tmp=0; va_start(tag, string); do { if(*string == '%') { switch(*(++string)) { case 'i': { int_tmp = va_arg(tag, int); pointer=(void*)0; //Pointer as marker if(int_tmp <0) { fputc('-', 0); int_tmp*=(-1); } for(i=MAX_NUM_DEC; i; i/=10) { if((int_tmp/i) || (pointer)) { pointer=(void*)1; fputc((int_tmp/i)+48, 0); int_tmp%=i; } } if(!(pointer)) fputc('0', 0); // Null ausgeben (Zahl = 0) } break; case 'c': { fputc((char)va_arg(tag, int), 0); } break; case 's': { pointer = va_arg(tag, char*); do { fputc(*pointer, 0); } while(*pointer++); break; } } } // end if '%' else if(*string == '\\') { switch(*(++string)) { case 'n': fputc('\n', 0); break; case 't': fputc('\t', 0); break; } } // end if '\' else fputc(*string, 0); } while(*(++string)); va_end(tag); return(0); } ------------------------------------------------------------------------ Hab versucht, das noch weiter zu schrumpfen, bin dabei aber leider wieder auf 292 bytes gekommen. Aber ich find die Lösung so böse-lustig, dass ich sie hier veröffentlichen möchte: #include <stdarg.h> #include "../src/main.h" #include "../src/thprintf.h" int thprintf(char *string, ...) { va_list tag; int i=0; int *pointer=0; va_start(tag, string); do { if(*string == '%') { switch(*(++string)) { case 'i': { //int_tmp = va_arg(tag, int); *pointer = va_arg(tag, int); if(*pointer <0) { fputc('-', 0); (*pointer)*=(-1); } // führende Nullen abtrennen for(i=MAX_NUM_DEC; i; i/=10) if(*pointer/i) break; for(; i;) { if((*pointer/i)) { fputc((*pointer/i)+48, 0); *pointer%=i; } else fputc('0', 0); i/=10; } } break; case 'c': { fputc((char)va_arg(tag, int), 0); } break; case 's': { pointer = (int*) va_arg(tag, char*); do { fputc(*pointer, 0); } while(*pointer++); break; } } } // end if '%' else if(*string == '\\') { switch(*(++string)) { case 'n': fputc('\n', 0); break; case 't': fputc('\t', 0); break; } } // end if '\' else fputc(*string, 0); } while(*(++string)); va_end(tag); return(0); } Vllt sind für den ein oder anderen ein paar anregungen drin. Greetz, Th. PS: Ich liebe solche spielchen mit C ;-) Nu bin ich erst mal am ende ... hat jemand lust, weiterzumachen ? Her damit grins
So, vorläufige Endversion. 180Byte ROM und 4Byte RAM mit Keil (-O3, oben war -O0). // Th printf /* Author: Thorsten de Buhr mail: thorsten@lasertechnix.de Use: Use is free, could run or not ;-) U may change every printf in cour code to thprintf, the rest is the same. U may use: %i, %s, %c \n, \t More is not implemented now. */ #include <stdarg.h> #include "../src/main.h" #include "../src/thprintf.h" int thprintf(char *string, ...) { va_list tag; int i=0; int *pointer=0; signed int int_tmp=0; va_start(tag, string); do { if(*string == '%') { switch(*(++string)) { case 'i': { int_tmp = va_arg(tag, int); if(int_tmp <0) { fputc('-', 0); int_tmp=-int_tmp; } pointer = (int*)int_tmp; for(i=MAX_NUM_DEC; i; i/=10) { if((int)pointer/i) { fputc((int_tmp/i)+48, 0); int_tmp%=i; } } } break; case 'c': { fputc((char)va_arg(tag, int), 0); } break; case 's': { pointer = (int*)va_arg(tag, char*); do { fputc(*pointer, 0); } while(*pointer++); } break; } } // end if '%' else if(*string == '\\') { switch(*(++string)) { case 'n': fputc('\n', 0); break; case 't': fputc('\t', 0); break; } } // end if '\' else fputc(*string, 0); } while(*(++string)); va_end(tag); return(0); } Greetz, th.
Thorsten Db wrote: > Nu bin ich erst mal am ende ... hat jemand lust, weiterzumachen ? Her > damit *grins* Z.B. hier: Beitrag "Zahlenausgabe" Peter
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.