projekty/Source/example1/src/printf.c

Go to the documentation of this file.
00001 /*
00002         Copyright 2001, 2002 Georges Menie (www.menie.org)
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU Lesser General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU Lesser General Public License for more details.
00013 
00014     You should have received a copy of the GNU Lesser General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 */
00018 
00019 /*
00020         putchar is the only external dependency for this file,
00021         if you have a working putchar, just remove the following
00022         define. If the function should be called something else,
00023         replace outbyte(c) by your own function call.
00024 */
00025 #include "printf.h"
00026 
00027 void outbyte(int c)
00028 {
00029         UARTWriteChar(c);
00030 }
00031 #define putchar(c) outbyte(c)
00032 
00033 void printchar(char **str, int c)
00034 {
00035 //      extern int putchar(int c);
00036         if (str) {
00037                 **str = c;
00038                 ++(*str);
00039                 WD_Reset();
00040         }
00041         else (void)putchar(c);
00042 }
00043 
00044 #define PAD_RIGHT 1
00045 #define PAD_ZERO 2
00046 
00047 int prints(char **out, const char *string, int width, int pad)
00048 {
00049         register int pc = 0, padchar = ' ';
00050 
00051         if (width > 0) {
00052                 register int len = 0;
00053                 register const char *ptr;
00054                 for (ptr = string; *ptr; ++ptr) ++len;
00055                 if (len >= width) width = 0;
00056                 else width -= len;
00057                 if (pad & PAD_ZERO) padchar = '0';
00058         }
00059         if (!(pad & PAD_RIGHT)) {
00060                 for ( ; width > 0; --width) {
00061                         printchar (out, padchar);
00062                         ++pc;
00063                 }
00064         }
00065         for ( ; *string ; ++string) {
00066                 printchar (out, *string);
00067                 ++pc;
00068         }
00069         for ( ; width > 0; --width) {
00070                 printchar (out, padchar);
00071                 ++pc;
00072         }
00073 
00074         return pc;
00075 }
00076 
00077 /* the following should be enough for 32 bit int */
00078 #define PRINT_BUF_LEN 12
00079 
00080 int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
00081 {
00082         char print_buf[PRINT_BUF_LEN];
00083         register char *s;
00084         register int t, neg = 0, pc = 0;
00085         register unsigned int u = i;
00086 
00087         if (i == 0) {
00088                 print_buf[0] = '0';
00089                 print_buf[1] = '\0';
00090                 return prints (out, print_buf, width, pad);
00091         }
00092 
00093         if (sg && b == 10 && i < 0) {
00094                 neg = 1;
00095                 u = -i;
00096         }
00097 
00098         s = print_buf + PRINT_BUF_LEN-1;
00099         *s = '\0';
00100 
00101         while (u) {
00102                 t = u % b;
00103                 if( t >= 10 )
00104                         t += letbase - '0' - 10;
00105                 *--s = t + '0';
00106                 u /= b;
00107         }
00108 
00109         if (neg) {
00110                 if( width && (pad & PAD_ZERO) ) {
00111                         printchar (out, '-');
00112                         ++pc;
00113                         --width;
00114                 }
00115                 else {
00116                         *--s = '-';
00117                 }
00118         }
00119 
00120         return pc + prints (out, s, width, pad);
00121 }
00122 
00123 int print(char **out, int *varg)
00124 {
00125         register int width, pad;
00126         register int pc = 0;
00127         register char *format = (char *)(*varg++);
00128         char scr[2];
00129 
00130         for (; *format != 0; ++format) {
00131         #if 1
00132                 WD_Reset();
00133         #endif
00134                 if (*format == '%') {
00135                         ++format;
00136                         width = pad = 0;
00137                         if (*format == '\0') break;
00138                         if (*format == '%') goto out;
00139                         if (*format == '-') {
00140                                 ++format;
00141                                 pad = PAD_RIGHT;
00142                         }
00143                         while (*format == '0') {
00144                                 ++format;
00145                                 pad |= PAD_ZERO;
00146                         }
00147                         for ( ; *format >= '0' && *format <= '9'; ++format) {
00148                                 width *= 10;
00149                                 width += *format - '0';
00150                         }
00151                         if( *format == 's' ) {
00152                                 register char *s = *((char **)varg++);
00153                                 pc += prints (out, s?s:"(null)", width, pad);
00154                                 continue;
00155                         }
00156                         if( *format == 'd' ) {
00157                                 pc += printi (out, *varg++, 10, 1, width, pad, 'a');
00158                                 continue;
00159                         }
00160                         if( *format == 'x' ) {
00161                                 pc += printi (out, *varg++, 16, 0, width, pad, 'a');
00162                                 continue;
00163                         }
00164                         if( *format == 'X' ) {
00165                                 pc += printi (out, *varg++, 16, 0, width, pad, 'A');
00166                                 continue;
00167                         }
00168                         if( *format == 'u' ) {
00169                                 pc += printi (out, *varg++, 10, 0, width, pad, 'a');
00170                                 continue;
00171                         }
00172                         if( *format == 'c' ) {
00173                                 /* char are converted to int then pushed on the stack */
00174                                 scr[0] = *varg++;
00175                                 scr[1] = '\0';
00176                                 pc += prints (out, scr, width, pad);
00177                                 continue;
00178                         }
00179                 }
00180                 else {
00181                 out:
00182                         printchar (out, *format);
00183                         ++pc;
00184                 }
00185         }
00186         if (out) **out = '\0';
00187         WD_Reset();
00188         return pc;
00189 }
00190 
00191 /* assuming sizeof(void *) == sizeof(int) */
00192 
00193 int printf(const char *format, ...)
00194 {
00195         register int *varg = (int *)(&format);
00196         return print(0, varg);
00197 }
00198 
00199 int sprintf(char *out, const char *format, ...)
00200 {
00201         register int *varg = (int *)(&format);
00202         return print(&out, varg);
00203 }
00204 
00205 /* if you compile this file with
00206  *   gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c
00207  * you will get a normal warning:
00208  *   printf.c:214: warning: spurious trailing `%' in format
00209  * this line is testing an invalid % at the end of the format string.
00210  *
00211  * this should display (on 32bit int machine) :
00212  *
00213  * Hello world!
00214  * printf test
00215  * (null) is null pointer
00216  * 5 = 5
00217  * -2147483647 = - max int
00218  * char a = 'a'
00219  * hex ff = ff
00220  * hex 00 = 00
00221  * signed -3 = unsigned 4294967293 = hex fffffffd
00222  * 0 message(s)
00223  * 0 message(s) with %
00224  * justif: "left      "
00225  * justif: "     right"
00226  *  3: 0003 zero padded
00227  *  3: 3    left justif.
00228  *  3:    3 right justif.
00229  * -3: -003 zero padded
00230  * -3: -3   left justif.
00231  * -3:   -3 right justif.
00232  */
00233 
00234 //#endif

Generated on Fri Sep 21 13:41:54 2007 for example1 by  doxygen 1.4.7