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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #include <stdarg.h>
00069 #include <stdbool.h>
00070 #include <string.h>
00071
00072 #include <mc1322x.h>
00073 #include <stdint.h>
00074
00075 #define __putc(x) uart1_putc(x)
00076
00077
00078
00079
00080
00081 struct __print_ctx_t
00082 {
00083
00084 char* _ptr;
00085
00086 size_t _max_len;
00087 };
00088 typedef struct __print_ctx_t _print_ctx_t;
00089
00090
00091
00092
00093 #define _PRINTFMT_PAD_RIGHT 1
00094
00095
00096
00097
00098 #define _PRINTFMT_PAD_ZERO 2
00099
00100
00101
00102
00103 #define _PRINTFMT_INT_BUF_LEN 12
00104
00105
00106
00107
00108
00109 static void __print_char( _print_ctx_t* ctx, char c )
00110 {
00111 if( ctx ) {
00112 if( c == '\r' || c == '\n' ) {
00113 if( ctx->_max_len > 1 ) {
00114 *(ctx->_ptr)='\r';
00115 ctx->_max_len--;
00116 ctx->_ptr++;
00117 *(ctx->_ptr)='\n';
00118 ctx->_max_len--;
00119 ctx->_ptr++;
00120 } else {
00121 *(ctx->_ptr)='\n';
00122 ctx->_max_len--;
00123 ctx->_ptr++;
00124 }
00125 } else {
00126 if( ctx->_max_len ) {
00127 *(ctx->_ptr)=c;
00128 ctx->_max_len--;
00129 ctx->_ptr++;
00130 }
00131 }
00132 } else {
00133 __putc( (uint8_t)c );
00134 }
00135 }
00136
00137
00138
00139
00140 static int __print_str( _print_ctx_t* ctx,
00141 const char *string,
00142 int width,
00143 int pad,
00144 int print_limit,
00145 bool is_number )
00146 {
00147 int pc = 0;
00148 int padchar = ' ';
00149 int i, len;
00150
00151 if( width > 0 ) {
00152 register int len = 0;
00153 register const char *ptr;
00154 for( ptr = string; *ptr; ++ptr )
00155 ++len;
00156 if( len >= width )
00157 width = 0;
00158 else
00159 width -= len;
00160 if( pad & _PRINTFMT_PAD_ZERO )
00161 padchar = '0';
00162 }
00163 if( !( pad & _PRINTFMT_PAD_RIGHT ) ) {
00164 for( ; width > 0; --width ) {
00165 __print_char( ctx, padchar );
00166 ++pc;
00167 }
00168 }
00169
00170
00171 if( false == is_number ) {
00172
00173 for( ; print_limit && *string; ++string, --print_limit ) {
00174 __print_char( ctx, *string );
00175 ++pc;
00176 }
00177 }
00178
00179
00180 if( true == is_number ) {
00181
00182
00183
00184
00185 len = strlen( string );
00186 if( len < print_limit ) {
00187 i = print_limit - len;
00188 for( ; i; i-- ) {
00189 __print_char( ctx, '0' );
00190 ++pc;
00191 }
00192 }
00193 }
00194
00195
00196
00197
00198
00199 for( ; print_limit && *string; ++string, --print_limit ) {
00200 __print_char( ctx, *string );
00201 ++pc;
00202 }
00203
00204 for( ; width > 0; --width ) {
00205 __print_char( ctx, padchar );
00206 ++pc;
00207 }
00208
00209 return pc;
00210 }
00211
00212
00213
00214
00215 static int __print_int( _print_ctx_t* ctx,
00216 int i,
00217 int b,
00218 int sg,
00219 int width,
00220 int pad,
00221 int letbase,
00222 int print_limit )
00223 {
00224 char print_buf[_PRINTFMT_INT_BUF_LEN];
00225 register char *s;
00226 register int t, neg = 0, pc = 0;
00227 register unsigned int u = i;
00228
00229 if( i == 0 ) {
00230 print_buf[0] = '0';
00231 print_buf[1] = '\0';
00232 return __print_str( ctx, print_buf, width, pad, print_limit, true );
00233 }
00234
00235 if( sg && b == 10 && i < 0 ) {
00236 neg = 1;
00237 u = -i;
00238 }
00239
00240 s = print_buf + _PRINTFMT_INT_BUF_LEN - 1;
00241 *s = '\0';
00242
00243 while( u ) {
00244 t = u % b;
00245 if( t >= 10 )
00246 t += letbase - '0' - 10;
00247 *--s = t + '0';
00248 u /= b;
00249 }
00250
00251 if( neg ) {
00252 if( width && ( pad & _PRINTFMT_PAD_ZERO ) ) {
00253 __print_char( ctx, '-' );
00254 ++pc;
00255 --width;
00256 } else {
00257 *--s = '-';
00258 }
00259 }
00260
00261 return pc + __print_str( ctx, s, width, pad, print_limit, true );
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 static int __print_fmt( _print_ctx_t* ctx, const char *format, va_list args )
00276 {
00277 int width;
00278 int pad;
00279 int print_limit;
00280 int pc = 0;
00281 char scr[2];
00282
00283 for( ; *format != 0; ++format ) {
00284 if( *format == '%' ) {
00285 ++format;
00286 width = pad = print_limit = 0;
00287
00288 if( *format == '\0' ) {
00289 break;
00290 }
00291
00292 if( *format == '%' ) {
00293 goto out;
00294 }
00295
00296 if( *format == '-' ) {
00297 ++format;
00298 pad = _PRINTFMT_PAD_RIGHT;
00299 }
00300
00301 while( *format == '0' ) {
00302 ++format;
00303 pad |= _PRINTFMT_PAD_ZERO;
00304 }
00305
00306 for( ; *format >= '0' && *format <= '9'; ++format ) {
00307 width *= 10;
00308 width += *format - '0';
00309 }
00310
00311 if( *format == '.' ) {
00312 ++format;
00313 for( ; *format >= '0' && *format <= '9'; ++format ) {
00314 print_limit *= 10;
00315 print_limit += *format - '0';
00316 }
00317 }
00318
00319 if( 0 == print_limit ) {
00320 print_limit--;
00321 }
00322
00323 if( *format == 'l' ) {
00324 ++format;
00325 }
00326
00327 if( *format == 's' ) {
00328 register char *s = (char *) va_arg( args, int );
00329 pc += __print_str( ctx,
00330 s ? s : "(null)",
00331 width,
00332 pad,
00333 print_limit,
00334 false );
00335 continue;
00336 }
00337
00338 if( *format == 'd' ) {
00339 pc += __print_int( ctx, va_arg( args, int ), 10, 1, width, pad, 'a', print_limit );
00340 continue;
00341 }
00342
00343 if( ( *format == 'x' ) || ( *format == 'p' ) ) {
00344 pc += __print_int( ctx, va_arg( args, int ), 16, 0, width, pad, 'a', print_limit );
00345 continue;
00346 }
00347
00348 if( *format == 'X' ) {
00349 pc += __print_int( ctx, va_arg( args, int ), 16, 0, width, pad, 'A', print_limit );
00350 continue;
00351 }
00352
00353 if( *format == 'u' ) {
00354 pc += __print_int( ctx, va_arg( args, int ), 10, 0, width, pad, 'a', print_limit );
00355 continue;
00356 }
00357
00358 if( *format == 'c' ) {
00359
00360 scr[0] = (char) va_arg( args, int );
00361 scr[1] = '\0';
00362 pc += __print_str( ctx, scr, width, pad, print_limit, false );
00363 continue;
00364 }
00365 } else {
00366 out:
00367 __print_char( ctx, *format );
00368 ++pc;
00369 }
00370 }
00371
00372 if( ctx && ctx->_max_len ) {
00373 *(ctx->_ptr) = '\0';
00374 }
00375
00376 return pc;
00377 }
00378
00379 #define BLOCK_MEM_SIZE 1024
00380
00381 int sprintf( char *out, const char *format, ... )
00382 {
00383 int retval = 0;
00384 _print_ctx_t ctx;
00385 va_list args;
00386
00387 ctx._ptr = out;
00388 ctx._max_len = BLOCK_MEM_SIZE;
00389
00390 va_start( args, format );
00391 retval = __print_fmt( &ctx, format, args );
00392 va_end( args );
00393
00394 return retval;
00395 }
00396
00397 int printf( const char *format, ... )
00398 {
00399 int retval = 0;
00400
00401 va_list args;
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 va_start( args, format );
00427 retval = __print_fmt( NULL, format, args );
00428 va_end( args );
00429
00430 return retval;
00431 }