rprintf.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdarg.h>
00027 #include <string.h>
00028 #include "rprintf.h"
00029
00030 #define SCRATCH 12 //32Bits go up to 4GB + 1 Byte for \0
00031
00032
00033 #define USE_LONG // %lx, %Lu and so on, else only 16 bit integer is allowed
00034
00035 #define USE_STRING // %s, %S Strings as parameters
00036 #define USE_CHAR // %c, %C Chars as parameters
00037 #define USE_INTEGER // %i, %I Remove this format flag. %d, %D does the same
00038 #define USE_HEX // %x, %X Hexadezimal output
00039 #define USE_UPPERHEX // %x, %X outputs A,B,C... else a,b,c...
00040 #ifndef USE_HEX
00041 #undef USE_UPPERHEX // ;)
00042 #endif
00043 #define USE_UPPER // uncommenting this removes %C,%D,%I,%O,%S,%U,%X and %L..
00044
00045 #define PADDING //SPACE and ZERO padding
00046
00047
00048 static int (*putcharfunc)(int c);
00049
00050 void rprintf_devopen( int(*put)(int) )
00051 {
00052 putcharfunc = put;
00053 }
00054
00055 static void myputchar(unsigned char c)
00056 {
00057 if(c == '\n') putcharfunc('\r');
00058 putcharfunc(c);
00059 }
00060
00061 void rprintf(char const *format, ...)
00062 {
00063 unsigned char scratch[SCRATCH];
00064 unsigned char format_flag;
00065 unsigned short base;
00066 unsigned char *ptr;
00067 unsigned char issigned=0;
00068 va_list ap;
00069
00070 #ifdef USE_LONG
00071
00072 unsigned char islong=0;
00073 unsigned long u_val=0;
00074 long s_val=0;
00075 #else
00076 unsigned int u_val=0;
00077 int s_val=0;
00078 #endif
00079
00080 unsigned char fill;
00081 unsigned char width;
00082
00083 va_start (ap, format);
00084 for (;;){
00085 while ((format_flag = *(format++)) != '%'){
00086 if (!format_flag){va_end (ap); return;}
00087 myputchar(format_flag);
00088 }
00089
00090 issigned=0;
00091 base = 10;
00092
00093 format_flag = *format++;
00094
00095 #ifdef PADDING
00096 width=0;
00097 fill=0;
00098 if(format_flag=='0' || format_flag==' ')
00099 {
00100 fill=format_flag;
00101 format_flag = *format++;
00102 if(format_flag>='0' && format_flag<='9')
00103 {
00104 width=format_flag-'0';
00105 format_flag = *format++;
00106 }
00107 }
00108 #endif
00109
00110 #ifdef USE_LONG
00111 islong=0;
00112 #ifdef USE_UPPER
00113 if(format_flag=='l' || format_flag=='L')
00114 #else
00115 if(format_flag=='l')
00116 #endif
00117 {
00118 islong=1;
00119 format_flag = *format++;
00120 }
00121 #endif
00122
00123 switch (format_flag)
00124 {
00125 #ifdef USE_CHAR
00126 case 'c':
00127 #ifdef USE_UPPER
00128 case 'C':
00129 #endif
00130 format_flag = va_arg(ap,int);
00131
00132 #endif
00133
00134 default:
00135 myputchar(format_flag);
00136 continue;
00137
00138 #ifdef USE_STRING
00139 #ifdef USE_UPPER
00140 case 'S':
00141 #endif
00142 case 's':
00143 ptr = (unsigned char*)va_arg(ap,char *);
00144 while(*ptr) { myputchar(*ptr); ptr++; }
00145 continue;
00146 #endif
00147
00148 #ifdef USE_OCTAL
00149 case 'o':
00150 #ifdef USE_UPPER
00151 case 'O':
00152 #endif
00153 base = 8;
00154 myputchar('0');
00155 goto CONVERSION_LOOP;
00156 #endif
00157
00158 #ifdef USE_INTEGER //don't use %i, is same as %d
00159 case 'i':
00160 #ifdef USE_UPPER
00161 case 'I':
00162 #endif
00163 #endif
00164 case 'd':
00165 #ifdef USE_UPPER
00166 case 'D':
00167 #endif
00168 issigned=1;
00169
00170 case 'u':
00171 #ifdef USE_UPPER
00172 case 'U':
00173 #endif
00174
00175
00176
00177 #ifdef USE_HEX
00178 goto CONVERSION_LOOP;
00179 case 'x':
00180 #ifdef USE_UPPER
00181 case 'X':
00182 #endif
00183 base = 16;
00184 #endif
00185
00186 CONVERSION_LOOP:
00187
00188 if(issigned)
00189 {
00190 #ifdef USE_LONG
00191 if(islong) { s_val = va_arg(ap,long); }
00192 else { s_val = va_arg(ap,int); }
00193 #else
00194 s_val = va_arg(ap,int);
00195 #endif
00196
00197 if(s_val < 0)
00198 {
00199 s_val = - s_val;
00200 myputchar('-');
00201 }
00202
00203 u_val = (unsigned long)s_val;
00204 }
00205 else
00206 {
00207 #ifdef USE_LONG
00208 if(islong) { u_val = va_arg(ap,unsigned long); }
00209 else { u_val = va_arg(ap,unsigned int); }
00210 #else
00211 u_val = va_arg(ap,unsigned int);
00212 #endif
00213 }
00214
00215 ptr = scratch + SCRATCH;
00216 *--ptr = 0;
00217 do
00218 {
00219 char ch = u_val % base + '0';
00220 #ifdef USE_HEX
00221 if (ch > '9')
00222 {
00223 ch += 'a' - '9' - 1;
00224 #ifdef USE_UPPERHEX
00225 ch-=0x20;
00226 #endif
00227 }
00228 #endif
00229 *--ptr = ch;
00230 u_val /= base;
00231
00232 #ifdef PADDING
00233 if(width) width--;
00234 #endif
00235 } while (u_val);
00236
00237 #ifdef PADDING
00238 while(width--) *--ptr = fill;
00239 #endif
00240
00241 while(*ptr) { myputchar(*ptr); ptr++; }
00242 }
00243 }
00244 }