<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Procyon AVRlib: rprintf.c Source File</title>
<link href="dox.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.2 -->
<div class="qindex"><a class="qindex" href="main.html">Main Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="functions.html">Data Fields</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related Pages</a></div>
<h1>rprintf.c</h1><a href="rprintf_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment">00001 <span class="comment">/*! \file rprintf.c \brief printf routine and associated routines. */</span>
00002 <span class="comment">//*****************************************************************************</span>
00003 <span class="comment">//</span>
00004 <span class="comment">// File Name : 'rprintf.c'</span>
00005 <span class="comment">// Title : printf routine and associated routines</span>
00006 <span class="comment">// Author : Pascal Stang - Copyright (C) 2000-2002</span>
00007 <span class="comment">// Created : 2000.12.26</span>
00008 <span class="comment">// Revised : 2003.5.1</span>
00009 <span class="comment">// Version : 1.0</span>
00010 <span class="comment">// Target MCU : Atmel AVR series and other targets</span>
00011 <span class="comment">// Editor Tabs : 4</span>
00012 <span class="comment">//</span>
00013 <span class="comment">// NOTE: This code is currently below version 1.0, and therefore is considered</span>
00014 <span class="comment">// to be lacking in some functionality or documentation, or may not be fully</span>
00015 <span class="comment">// tested. Nonetheless, you can expect most functions to work.</span>
00016 <span class="comment">//</span>
00017 <span class="comment">// This code is distributed under the GNU Public License</span>
00018 <span class="comment">// which can be found at http://www.gnu.org/licenses/gpl.txt</span>
00019 <span class="comment">//</span>
00020 <span class="comment">//*****************************************************************************</span>
00021
00022 <span class="preprocessor">#include <avr/pgmspace.h></span>
00023 <span class="comment">//#include <string-avr.h></span>
00024 <span class="comment">//#include <stdlib.h></span>
00025 <span class="preprocessor">#include <stdarg.h></span>
00026 <span class="preprocessor">#include "<a class="code" href="global_8h.html">global.h</a>"</span>
00027 <span class="preprocessor">#include "<a class="code" href="rprintf_8h.html">rprintf.h</a>"</span>
00028
00029 <span class="preprocessor">#ifndef TRUE</span>
00030 <span class="preprocessor"></span><span class="preprocessor"> #define TRUE -1</span>
00031 <span class="preprocessor"></span><span class="preprocessor"> #define FALSE 0</span>
00032 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
00033 <span class="preprocessor"></span>
00034 <span class="preprocessor">#define INF 32766 // maximum field size to print</span>
00035 <span class="preprocessor"></span><span class="preprocessor">#define READMEMBYTE(a,char_ptr) ((a)?(pgm_read_byte(char_ptr)):(*char_ptr))</span>
00036 <span class="preprocessor"></span>
00037 <span class="preprocessor">#ifdef RPRINTF_COMPLEX</span>
00038 <span class="preprocessor"></span> <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> buf[128];
00039 <span class="preprocessor">#endif</span>
00040 <span class="preprocessor"></span>
00041 <span class="comment">// use this to store hex conversion in RAM</span>
00042 <span class="comment">//static char HexChars[] = "0123456789ABCDEF";</span>
00043 <span class="comment">// use this to store hex conversion in program memory</span>
00044 <span class="comment">//static prog_char HexChars[] = "0123456789ABCDEF";</span>
00045 <span class="keyword">static</span> <span class="keywordtype">char</span> __attribute__ ((progmem)) HexChars[] = "0123456789ABCDEF";
00046
00047 #define hexchar(x) pgm_read_byte( HexChars+((x)&0x0f) )
00048 <span class="comment">//#define hexchar(x) ((((x)&0x0F)>9)?((x)+'A'-10):((x)+'0'))</span>
00049
00050 <span class="comment">// function pointer to single character output routine</span>
00051 static <span class="keywordtype">void</span> (*rputchar)(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> c);
00052
00053 <span class="comment">// *** rprintf initialization ***</span>
00054 <span class="comment">// you must call this function once and supply the character output</span>
00055 <span class="comment">// routine before using other functions in this library</span>
00056 <span class="keywordtype">void</span> <a class="code" href="group__rprintf.html#ga0">rprintfInit</a>(<span class="keywordtype">void</span> (*putchar_func)(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> c))
00057 {
00058 rputchar = putchar_func;
00059 }
00060
00061 <span class="comment">// *** rprintfChar ***</span>
00062 <span class="comment">// send a character/byte to the current output device</span>
<a name="l00063"></a><a class="code" href="group__rprintf.html#ga1">00063</a> <span class="keywordtype">void</span> <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> c)
00064 {
00065 <span class="comment">// do LF -> CR/LF translation</span>
00066 <span class="keywordflow">if</span>(c == <span class="charliteral">'\n'</span>)
00067 rputchar(<span class="charliteral">'\r'</span>);
00068 <span class="comment">// send character</span>
00069 rputchar(c);
00070 }
00071
00072 <span class="comment">// *** rprintfStr ***</span>
00073 <span class="comment">// prints a null-terminated string stored in RAM</span>
<a name="l00074"></a><a class="code" href="group__rprintf.html#ga2">00074</a> <span class="keywordtype">void</span> <a class="code" href="group__rprintf.html#ga2">rprintfStr</a>(<span class="keywordtype">char</span> str[])
00075 {
00076 <span class="comment">// send a string stored in RAM</span>
00077 <span class="comment">// check to make sure we have a good pointer</span>
00078 <span class="keywordflow">if</span> (!str) <span class="keywordflow">return</span>;
00079
00080 <span class="comment">// print the string until a null-terminator</span>
00081 <span class="keywordflow">while</span> (*str)
00082 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(*str++);
00083 }
00084
00085 <span class="comment">// *** rprintfStrLen ***</span>
00086 <span class="comment">// prints a section of a string stored in RAM</span>
00087 <span class="comment">// begins printing at position indicated by <start></span>
00088 <span class="comment">// prints number of characters indicated by <len></span>
<a name="l00089"></a><a class="code" href="group__rprintf.html#ga3">00089</a> <span class="keywordtype">void</span> <a class="code" href="group__rprintf.html#ga3">rprintfStrLen</a>(<span class="keywordtype">char</span> str[], <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> start, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len)
00090 {
00091 <span class="keyword">register</span> <span class="keywordtype">int</span> i=0;
00092
00093 <span class="comment">// check to make sure we have a good pointer</span>
00094 <span class="keywordflow">if</span> (!str) <span class="keywordflow">return</span>;
00095 <span class="comment">// spin through characters up to requested start</span>
00096 <span class="comment">// keep going as long as there's no null</span>
00097 <span class="keywordflow">while</span>((i++<start) && (*str++));
00098 <span class="comment">// for(i=0; i<start; i++)</span>
00099 <span class="comment">// {</span>
00100 <span class="comment">// // keep steping through string as long as there's no null</span>
00101 <span class="comment">// if(*str) str++;</span>
00102 <span class="comment">// }</span>
00103
00104 <span class="comment">// then print exactly len characters</span>
00105 <span class="keywordflow">for</span>(i=0; i<len; i++)
00106 {
00107 <span class="comment">// print data out of the string as long as we haven't reached a null yet</span>
00108 <span class="comment">// at the null, start printing spaces</span>
00109 <span class="keywordflow">if</span>(*str)
00110 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(*str++);
00111 <span class="keywordflow">else</span>
00112 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">' '</span>);
00113 }
00114
00115 }
00116
00117 <span class="comment">// *** rprintfProgStr ***</span>
00118 <span class="comment">// prints a null-terminated string stored in program ROM</span>
<a name="l00119"></a><a class="code" href="group__rprintf.html#ga4">00119</a> <span class="keywordtype">void</span> <a class="code" href="group__rprintf.html#ga4">rprintfProgStr</a>(<span class="keyword">const</span> prog_char str[])
00120 {
00121 <span class="comment">// print a string stored in program memory</span>
00122 <span class="keyword">register</span> <span class="keywordtype">char</span> c;
00123
00124 <span class="comment">// check to make sure we have a good pointer</span>
00125 <span class="keywordflow">if</span> (!str) <span class="keywordflow">return</span>;
00126
00127 <span class="comment">// print the string until the null-terminator</span>
00128 <span class="keywordflow">while</span>((c = pgm_read_byte(str++)))
00129 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(c);
00130 }
00131
00132 <span class="comment">// *** rprintfCRLF ***</span>
00133 <span class="comment">// prints carriage return and line feed</span>
<a name="l00134"></a><a class="code" href="group__rprintf.html#ga5">00134</a> <span class="keywordtype">void</span> <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>(<span class="keywordtype">void</span>)
00135 {
00136 <span class="comment">// print CR/LF</span>
00137 <span class="comment">//rprintfChar('\r');</span>
00138 <span class="comment">// LF -> CR/LF translation built-in to rprintfChar()</span>
00139 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'\n'</span>);
00140 }
00141
00142 <span class="comment">// *** rprintfu04 ***</span>
00143 <span class="comment">// prints an unsigned 4-bit number in hex (1 digit)</span>
<a name="l00144"></a><a class="code" href="group__rprintf.html#ga6">00144</a> <span class="keywordtype">void</span> <a class="code" href="group__rprintf.html#ga6">rprintfu04</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> data)
00145 {
00146 <span class="comment">// print 4-bit hex value</span>
00147 <span class="comment">// char Character = data&0x0f;</span>
00148 <span class="comment">// if (Character>9)</span>
00149 <span class="comment">// Character+='A'-10;</span>
00150 <span class="comment">// else</span>
00151 <span class="comment">// Character+='0';</span>
00152 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(hexchar(data));
00153 }
00154
00155 <span class="comment">// *** rprintfu08 ***</span>
00156 <span class="comment">// prints an unsigned 8-bit number in hex (2 digits)</span>
<a name="l00157"></a><a class="code" href="group__rprintf.html#ga7">00157</a> <span class="keywordtype">void</span> <a class="code" href="group__rprintf.html#ga7">rprintfu08</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> data)
00158 {
00159 <span class="comment">// print 8-bit hex value</span>
00160 <a class="code" href="group__rprintf.html#ga6">rprintfu04</a>(data>>4);
00161 <a class="code" href="group__rprintf.html#ga6">rprintfu04</a>(data);
00162 }
00163
00164 <span class="comment">// *** rprintfu16 ***</span>
00165 <span class="comment">// prints an unsigned 16-bit number in hex (4 digits)</span>
<a name="l00166"></a><a class="code" href="group__rprintf.html#ga8">00166</a> <span class="keywordtype">void</span> <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> data)
00167 {
00168 <span class="comment">// print 16-bit hex value</span>
00169 <a class="code" href="group__rprintf.html#ga7">rprintfu08</a>(data>>8);
00170 <a class="code" href="group__rprintf.html#ga7">rprintfu08</a>(data);
00171 }
00172
00173 <span class="comment">// *** rprintfu32 ***</span>
00174 <span class="comment">// prints an unsigned 32-bit number in hex (8 digits)</span>
<a name="l00175"></a><a class="code" href="group__rprintf.html#ga9">00175</a> <span class="keywordtype">void</span> <a class="code" href="group__rprintf.html#ga9">rprintfu32</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> data)
00176 {
00177 <span class="comment">// print 32-bit hex value</span>
00178 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(data>>16);
00179 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(data);
00180 }
00181
00182 <span class="comment">// *** rprintfNum ***</span>
00183 <span class="comment">// special printf for numbers only</span>
00184 <span class="comment">// see formatting information below</span>
00185 <span class="comment">// Print the number "n" in the given "base"</span>
00186 <span class="comment">// using exactly "numDigits"</span>
00187 <span class="comment">// print +/- if signed flag "isSigned" is TRUE</span>
00188 <span class="comment">// use the character specified in "padchar" to pad extra characters</span>
00189 <span class="comment">//</span>
00190 <span class="comment">// Examples:</span>
00191 <span class="comment">// uartPrintfNum(10, 6, TRUE, ' ', 1234); --> " +1234"</span>
00192 <span class="comment">// uartPrintfNum(10, 6, FALSE, '0', 1234); --> "001234"</span>
00193 <span class="comment">// uartPrintfNum(16, 6, FALSE, '.', 0x5AA5); --> "..5AA5"</span>
<a name="l00194"></a><a class="code" href="group__rprintf.html#ga10">00194</a> <span class="keywordtype">void</span> <a class="code" href="group__rprintf.html#ga10">rprintfNum</a>(<span class="keywordtype">char</span> base, <span class="keywordtype">char</span> numDigits, <span class="keywordtype">char</span> isSigned, <span class="keywordtype">char</span> padchar, <span class="keywordtype">long</span> n)
00195 {
00196 <span class="comment">// define a global HexChars or use line below</span>
00197 <span class="comment">//static char HexChars[16] = "0123456789ABCDEF";</span>
00198 <span class="keywordtype">char</span> *p, buf[32];
00199 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> x;
00200 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> count;
00201
00202 <span class="comment">// prepare negative number</span>
00203 <span class="keywordflow">if</span>( isSigned && (n < 0) )
00204 {
00205 x = -n;
00206 }
00207 <span class="keywordflow">else</span>
00208 {
00209 x = n;
00210 }
00211
00212 <span class="comment">// setup little string buffer</span>
00213 count = (numDigits-1)-(isSigned?1:0);
00214 p = buf + <span class="keyword">sizeof</span> (buf);
00215 *--p = <span class="charliteral">'\0'</span>;
00216
00217 <span class="comment">// force calculation of first digit</span>
00218 <span class="comment">// (to prevent zero from not printing at all!!!)</span>
00219 *--p = hexchar(x%base); x /= base;
00220 <span class="comment">// calculate remaining digits</span>
00221 <span class="keywordflow">while</span>(count--)
00222 {
00223 <span class="keywordflow">if</span>(x != 0)
00224 {
00225 <span class="comment">// calculate next digit</span>
00226 *--p = hexchar(x%base); x /= base;
00227 }
00228 <span class="keywordflow">else</span>
00229 {
00230 <span class="comment">// no more digits left, pad out to desired length</span>
00231 *--p = padchar;
00232 }
00233 }
00234
00235 <span class="comment">// apply signed notation if requested</span>
00236 <span class="keywordflow">if</span>( isSigned )
00237 {
00238 <span class="keywordflow">if</span>(n < 0)
00239 {
00240 *--p = <span class="charliteral">'-'</span>;
00241 }
00242 <span class="keywordflow">else</span> <span class="keywordflow">if</span>(n > 0)
00243 {
00244 *--p = <span class="charliteral">'+'</span>;
00245 }
00246 <span class="keywordflow">else</span>
00247 {
00248 *--p = <span class="charliteral">' '</span>;
00249 }
00250 }
00251
00252 <span class="comment">// print the string right-justified</span>
00253 count = numDigits;
00254 <span class="keywordflow">while</span>(count--)
00255 {
00256 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(*p++);
00257 }
00258 }
00259
00260 <span class="preprocessor">#ifdef RPRINTF_FLOAT</span>
00261 <span class="preprocessor"></span><span class="comment">// *** rprintfFloat ***</span>
00262 <span class="comment">// floating-point print</span>
00263 <span class="keywordtype">void</span> rprintfFloat(<span class="keywordtype">char</span> numDigits, <span class="keywordtype">double</span> x)
00264 {
00265 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> firstplace = FALSE;
00266 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> negative;
00267 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> i, digit;
00268 <span class="keywordtype">double</span> place = 1.0;
00269
00270 <span class="comment">// save sign</span>
00271 negative = (x<0);
00272 <span class="comment">// convert to absolute value</span>
00273 x = (x>0)?(x):(-x);
00274
00275 <span class="comment">// find starting digit place</span>
00276 <span class="keywordflow">for</span>(i=0; i<15; i++)
00277 {
00278 <span class="keywordflow">if</span>((x/place) < 10.0)
00279 <span class="keywordflow">break</span>;
00280 <span class="keywordflow">else</span>
00281 place *= 10.0;
00282 }
00283 <span class="comment">// print polarity character</span>
00284 <span class="keywordflow">if</span>(negative)
00285 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'-'</span>);
00286 <span class="keywordflow">else</span>
00287 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'+'</span>);
00288
00289 <span class="comment">// print digits</span>
00290 <span class="keywordflow">for</span>(i=0; i<numDigits; i++)
00291 {
00292 digit = (x/place);
00293
00294 <span class="keywordflow">if</span>(digit | firstplace | (place == 1.0))
00295 {
00296 firstplace = TRUE;
00297 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(digit+0x30);
00298 }
00299 <span class="keywordflow">else</span>
00300 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">' '</span>);
00301
00302 <span class="keywordflow">if</span>(place == 1.0)
00303 {
00304 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'.'</span>);
00305 }
00306
00307 x -= (digit*place);
00308 place /= 10.0;
00309 }
00310 }
00311 <span class="preprocessor">#endif</span>
00312 <span class="preprocessor"></span>
00313 <span class="preprocessor">#ifdef RPRINTF_SIMPLE</span>
00314 <span class="preprocessor"></span><span class="comment">// *** rprintf1RamRom ***</span>
00315 <span class="comment">// called by rprintf() - does a simple printf (supports %d, %x, %c)</span>
00316 <span class="comment">// Supports:</span>
00317 <span class="comment">// %d - decimal</span>
00318 <span class="comment">// %x - hex</span>
00319 <span class="comment">// %c - character</span>
<a name="l00320"></a><a class="code" href="group__rprintf.html#ga11">00320</a> <span class="keywordtype">int</span> <a class="code" href="group__rprintf.html#ga11">rprintf1RamRom</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> stringInRom, <span class="keyword">const</span> <span class="keywordtype">char</span> *format, ...)
00321 {
00322 <span class="comment">// simple printf routine</span>
00323 <span class="comment">// define a global HexChars or use line below</span>
00324 <span class="comment">//static char HexChars[16] = "0123456789ABCDEF";</span>
00325 <span class="keywordtype">char</span> format_flag;
00326 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> u_val, div_val, base;
00327 va_list ap;
00328
00329 va_start(ap, format);
00330 <span class="keywordflow">for</span> (;;)
00331 {
00332 <span class="keywordflow">while</span> ((format_flag = READMEMBYTE(stringInRom,format++) ) != <span class="charliteral">'%'</span>)
00333 { <span class="comment">// Until '%' or '\0'</span>
00334 <span class="keywordflow">if</span> (!format_flag)
00335 {
00336 va_end(ap);
00337 <span class="keywordflow">return</span>(0);
00338 }
00339 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(format_flag);
00340 }
00341
00342 <span class="keywordflow">switch</span> (format_flag = READMEMBYTE(stringInRom,format++) )
00343 {
00344 <span class="keywordflow">case</span> <span class="charliteral">'c'</span>: format_flag = va_arg(ap,<span class="keywordtype">int</span>);
00345 <span class="keywordflow">default</span>: <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(format_flag); <span class="keywordflow">continue</span>;
00346 <span class="keywordflow">case</span> <span class="charliteral">'d'</span>: base = 10; div_val = 10000; <span class="keywordflow">goto</span> CONVERSION_LOOP;
00347 <span class="comment">// case 'x': base = 16; div_val = 0x10;</span>
00348 <span class="keywordflow">case</span> <span class="charliteral">'x'</span>: base = 16; div_val = 0x1000;
00349
00350 CONVERSION_LOOP:
00351 u_val = va_arg(ap,<span class="keywordtype">int</span>);
00352 <span class="keywordflow">if</span> (format_flag == <span class="charliteral">'d'</span>)
00353 {
00354 <span class="keywordflow">if</span> (((<span class="keywordtype">int</span>)u_val) < 0)
00355 {
00356 u_val = - u_val;
00357 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'-'</span>);
00358 }
00359 <span class="keywordflow">while</span> (div_val > 1 && div_val > u_val) div_val /= 10;
00360 }
00361 <span class="keywordflow">do</span>
00362 {
00363 <span class="comment">//rprintfChar(pgm_read_byte(HexChars+(u_val/div_val)));</span>
00364 <a class="code" href="group__rprintf.html#ga6">rprintfu04</a>(u_val/div_val);
00365 u_val %= div_val;
00366 div_val /= base;
00367 } <span class="keywordflow">while</span> (div_val);
00368 }
00369 }
00370 va_end(ap);
00371 }
00372 <span class="preprocessor">#endif</span>
00373 <span class="preprocessor"></span>
00374
00375 <span class="preprocessor">#ifdef RPRINTF_COMPLEX</span>
00376 <span class="preprocessor"></span><span class="comment">// *** rprintf2RamRom ***</span>
00377 <span class="comment">// called by rprintf() - does a more powerful printf (supports %d, %u, %o, %x, %c, %s)</span>
00378 <span class="comment">// Supports:</span>
00379 <span class="comment">// %d - decimal</span>
00380 <span class="comment">// %u - unsigned decimal</span>
00381 <span class="comment">// %o - octal</span>
00382 <span class="comment">// %x - hex</span>
00383 <span class="comment">// %c - character</span>
00384 <span class="comment">// %s - strings</span>
00385 <span class="comment">// and the width,precision,padding modifiers</span>
00386 <span class="comment">// **this printf does not support floating point numbers</span>
00387 <span class="keywordtype">int</span> rprintf2RamRom(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> stringInRom, <span class="keyword">const</span> <span class="keywordtype">char</span> *sfmt, ...)
00388 {
00389 <span class="keyword">register</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *f, *bp;
00390 <span class="keyword">register</span> <span class="keywordtype">long</span> l;
00391 <span class="keyword">register</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> u;
00392 <span class="keyword">register</span> <span class="keywordtype">int</span> i;
00393 <span class="keyword">register</span> <span class="keywordtype">int</span> fmt;
00394 <span class="keyword">register</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> pad = <span class="charliteral">' '</span>;
00395 <span class="keywordtype">int</span> flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
00396 <span class="keywordtype">int</span> sign = 0;
00397
00398 va_list ap;
00399 va_start(ap, sfmt);
00400
00401 f = (<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *) sfmt;
00402
00403 <span class="keywordflow">for</span> (; READMEMBYTE(stringInRom,f); f++)
00404 {
00405 <span class="keywordflow">if</span> (READMEMBYTE(stringInRom,f) != <span class="charliteral">'%'</span>)
00406 { <span class="comment">// not a format character</span>
00407 <span class="comment">// then just output the char</span>
00408 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(READMEMBYTE(stringInRom,f));
00409 }
00410 <span class="keywordflow">else</span>
00411 {
00412 f++; <span class="comment">// if we have a "%" then skip it</span>
00413 <span class="keywordflow">if</span> (READMEMBYTE(stringInRom,f) == <span class="charliteral">'-'</span>)
00414 {
00415 flush_left = 1; <span class="comment">// minus: flush left</span>
00416 f++;
00417 }
00418 <span class="keywordflow">if</span> (READMEMBYTE(stringInRom,f) == <span class="charliteral">'0'</span>
00419 || READMEMBYTE(stringInRom,f) == <span class="charliteral">'.'</span>)
00420 {
00421 <span class="comment">// padding with 0 rather than blank</span>
00422 pad = <span class="charliteral">'0'</span>;
00423 f++;
00424 }
00425 <span class="keywordflow">if</span> (READMEMBYTE(stringInRom,f) == <span class="charliteral">'*'</span>)
00426 { <span class="comment">// field width</span>
00427 f_width = va_arg(ap, <span class="keywordtype">int</span>);
00428 f++;
00429 }
00430 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (Isdigit(READMEMBYTE(stringInRom,f)))
00431 {
00432 f_width = atoiRamRom(stringInRom, (<span class="keywordtype">char</span> *) f);
00433 <span class="keywordflow">while</span> (Isdigit(READMEMBYTE(stringInRom,f)))
00434 f++; <span class="comment">// skip the digits</span>
00435 }
00436 <span class="keywordflow">if</span> (READMEMBYTE(stringInRom,f) == <span class="charliteral">'.'</span>)
00437 { <span class="comment">// precision</span>
00438 f++;
00439 <span class="keywordflow">if</span> (READMEMBYTE(stringInRom,f) == <span class="charliteral">'*'</span>)
00440 {
00441 prec = va_arg(ap, <span class="keywordtype">int</span>);
00442 f++;
00443 }
00444 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (Isdigit(READMEMBYTE(stringInRom,f)))
00445 {
00446 prec = atoiRamRom(stringInRom, (<span class="keywordtype">char</span> *) f);
00447 <span class="keywordflow">while</span> (Isdigit(READMEMBYTE(stringInRom,f)))
00448 f++; <span class="comment">// skip the digits</span>
00449 }
00450 }
00451 <span class="keywordflow">if</span> (READMEMBYTE(stringInRom,f) == <span class="charliteral">'#'</span>)
00452 { <span class="comment">// alternate form</span>
00453 hash = 1;
00454 f++;
00455 }
00456 <span class="keywordflow">if</span> (READMEMBYTE(stringInRom,f) == <span class="charliteral">'l'</span>)
00457 { <span class="comment">// long format</span>
00458 do_long = 1;
00459 f++;
00460 }
00461
00462 fmt = READMEMBYTE(stringInRom,f);
00463 bp = buf;
00464 <span class="keywordflow">switch</span> (fmt) { <span class="comment">// do the formatting</span>
00465 <span class="keywordflow">case</span> <span class="charliteral">'d'</span>: <span class="comment">// 'd' signed decimal</span>
00466 <span class="keywordflow">if</span> (do_long)
00467 l = va_arg(ap, <span class="keywordtype">long</span>);
00468 <span class="keywordflow">else</span>
00469 l = (long) (va_arg(ap, <span class="keywordtype">int</span>));
00470 <span class="keywordflow">if</span> (l < 0)
00471 {
00472 sign = 1;
00473 l = -l;
00474 }
00475 <span class="keywordflow">do</span> {
00476 *bp++ = l % 10 + <span class="charliteral">'0'</span>;
00477 } <span class="keywordflow">while</span> ((l /= 10) > 0);
00478 <span class="keywordflow">if</span> (sign)
00479 *bp++ = <span class="charliteral">'-'</span>;
00480 f_width = f_width - (bp - buf);
00481 <span class="keywordflow">if</span> (!flush_left)
00482 <span class="keywordflow">while</span> (f_width-- > 0)
00483 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(pad);
00484 <span class="keywordflow">for</span> (bp--; bp >= buf; bp--)
00485 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(*bp);
00486 <span class="keywordflow">if</span> (flush_left)
00487 <span class="keywordflow">while</span> (f_width-- > 0)
00488 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">' '</span>);
00489 <span class="keywordflow">break</span>;
00490 <span class="keywordflow">case</span> <span class="charliteral">'o'</span>: <span class="comment">// 'o' octal number</span>
00491 <span class="keywordflow">case</span> <span class="charliteral">'x'</span>: <span class="comment">// 'x' hex number</span>
00492 <span class="keywordflow">case</span> <span class="charliteral">'u'</span>: <span class="comment">// 'u' unsigned decimal</span>
00493 <span class="keywordflow">if</span> (do_long)
00494 u = va_arg(ap, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>);
00495 <span class="keywordflow">else</span>
00496 u = (<span class="keywordtype">unsigned</span> long) (va_arg(ap, <span class="keywordtype">unsigned</span>));
00497 <span class="keywordflow">if</span> (fmt == <span class="charliteral">'u'</span>)
00498 { <span class="comment">// unsigned decimal</span>
00499 <span class="keywordflow">do</span> {
00500 *bp++ = u % 10 + <span class="charliteral">'0'</span>;
00501 } <span class="keywordflow">while</span> ((u /= 10) > 0);
00502 }
00503 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (fmt == <span class="charliteral">'o'</span>)
00504 { <span class="comment">// octal</span>
00505 <span class="keywordflow">do</span> {
00506 *bp++ = u % 8 + <span class="charliteral">'0'</span>;
00507 } <span class="keywordflow">while</span> ((u /= 8) > 0);
00508 <span class="keywordflow">if</span> (hash)
00509 *bp++ = <span class="charliteral">'0'</span>;
00510 }
00511 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (fmt == <span class="charliteral">'x'</span>)
00512 { <span class="comment">// hex</span>
00513 <span class="keywordflow">do</span> {
00514 i = u % 16;
00515 <span class="keywordflow">if</span> (i < 10)
00516 *bp++ = i + <span class="charliteral">'0'</span>;
00517 <span class="keywordflow">else</span>
00518 *bp++ = i - 10 + <span class="charliteral">'a'</span>;
00519 } <span class="keywordflow">while</span> ((u /= 16) > 0);
00520 <span class="keywordflow">if</span> (hash)
00521 {
00522 *bp++ = <span class="charliteral">'x'</span>;
00523 *bp++ = <span class="charliteral">'0'</span>;
00524 }
00525 }
00526 i = f_width - (bp - buf);
00527 <span class="keywordflow">if</span> (!flush_left)
00528 <span class="keywordflow">while</span> (i-- > 0)
00529 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(pad);
00530 <span class="keywordflow">for</span> (bp--; bp >= buf; bp--)
00531 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>((<span class="keywordtype">int</span>) (*bp));
00532 <span class="keywordflow">if</span> (flush_left)
00533 <span class="keywordflow">while</span> (i-- > 0)
00534 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">' '</span>);
00535 <span class="keywordflow">break</span>;
00536 <span class="keywordflow">case</span> <span class="charliteral">'c'</span>: <span class="comment">// 'c' character</span>
00537 i = va_arg(ap, <span class="keywordtype">int</span>);
00538 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>((<span class="keywordtype">int</span>) (i));
00539 <span class="keywordflow">break</span>;
00540 <span class="keywordflow">case</span> <span class="charliteral">'s'</span>: <span class="comment">// 's' string</span>
00541 bp = va_arg(ap, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *);
00542 <span class="keywordflow">if</span> (!bp)
00543 bp = (<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *) <span class="stringliteral">"(nil)"</span>;
00544 f_width = f_width - strlen((<span class="keywordtype">char</span> *) bp);
00545 <span class="keywordflow">if</span> (!flush_left)
00546 <span class="keywordflow">while</span> (f_width-- > 0)
00547 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(pad);
00548 <span class="keywordflow">for</span> (i = 0; *bp && i < prec; i++)
00549 {
00550 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(*bp);
00551 bp++;
00552 }
00553 <span class="keywordflow">if</span> (flush_left)
00554 <span class="keywordflow">while</span> (f_width-- > 0)
00555 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">' '</span>);
00556 <span class="keywordflow">break</span>;
00557 <span class="keywordflow">case</span> <span class="charliteral">'%'</span>: <span class="comment">// '%' character</span>
00558 <a class="code" href="group__rprintf.html#ga1">rprintfChar</a>(<span class="charliteral">'%'</span>);
00559 <span class="keywordflow">break</span>;
00560 }
00561 flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
00562 sign = 0;
00563 pad = <span class="charliteral">' '</span>;
00564 }
00565 }
00566
00567 va_end(ap);
00568 <span class="keywordflow">return</span> 0;
00569 }
00570
00571 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> Isdigit(<span class="keywordtype">char</span> c)
00572 {
00573 <span class="keywordflow">if</span>((c >= 0x30) && (c <= 0x39))
00574 <span class="keywordflow">return</span> TRUE;
00575 <span class="keywordflow">else</span>
00576 <span class="keywordflow">return</span> FALSE;
00577 }
00578
00579 <span class="keywordtype">int</span> atoiRamRom(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> stringInRom, <span class="keywordtype">char</span> *str)
00580 {
00581 <span class="keywordtype">int</span> num = 0;;
00582
00583 <span class="keywordflow">while</span>(Isdigit(READMEMBYTE(stringInRom,str)))
00584 {
00585 num *= 10;
00586 num += ((READMEMBYTE(stringInRom,str++)) - 0x30);
00587 }
00588 <span class="keywordflow">return</span> num;
00589 }
00590
00591 <span class="preprocessor">#endif</span>
00592 <span class="preprocessor"></span>
00593 <span class="comment">//******************************************************************************</span>
00594 <span class="comment">// code below this line is commented out and can be ignored</span>
00595 <span class="comment">//******************************************************************************</span>
00596 <span class="comment">/*</span>
00597 <span class="comment">char* sprintf(const char *sfmt, ...)</span>
00598 <span class="comment">{</span>
00599 <span class="comment"> register unsigned char *f, *bp, *str;</span>
00600 <span class="comment"> register long l;</span>
00601 <span class="comment"> register unsigned long u;</span>
00602 <span class="comment"> register int i;</span>
00603 <span class="comment"> register int fmt;</span>
00604 <span class="comment"> register unsigned char pad = ' ';</span>
00605 <span class="comment"> int flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;</span>
00606 <span class="comment"> int sign = 0;</span>
00607 <span class="comment"></span>
00608 <span class="comment"> va_list ap;</span>
00609 <span class="comment"> va_start(ap, sfmt);</span>
00610 <span class="comment"></span>
00611 <span class="comment"> str = bufstring;</span>
00612 <span class="comment"> f = (unsigned char *) sfmt;</span>
00613 <span class="comment"></span>
00614 <span class="comment"> for (; *f; f++)</span>
00615 <span class="comment"> {</span>
00616 <span class="comment"> if (*f != '%')</span>
00617 <span class="comment"> { // not a format character</span>
00618 <span class="comment"> *str++ = (*f); // then just output the char</span>
00619 <span class="comment"> }</span>
00620 <span class="comment"> else </span>
00621 <span class="comment"> {</span>
00622 <span class="comment"> f++; // if we have a "%" then skip it</span>
00623 <span class="comment"> if (*f == '-')</span>
00624 <span class="comment"> {</span>
00625 <span class="comment"> flush_left = 1; // minus: flush left</span>
00626 <span class="comment"> f++;</span>
00627 <span class="comment"> }</span>
00628 <span class="comment"> if (*f == '0' || *f == '.')</span>
00629 <span class="comment"> {</span>
00630 <span class="comment"> // padding with 0 rather than blank</span>
00631 <span class="comment"> pad = '0';</span>
00632 <span class="comment"> f++;</span>
00633 <span class="comment"> }</span>
00634 <span class="comment"> if (*f == '*')</span>
00635 <span class="comment"> { // field width</span>
00636 <span class="comment"> f_width = va_arg(ap, int);</span>
00637 <span class="comment"> f++;</span>
00638 <span class="comment"> }</span>
00639 <span class="comment"> else if (Isdigit(*f))</span>
00640 <span class="comment"> {</span>
00641 <span class="comment"> f_width = atoi((char *) f);</span>
00642 <span class="comment"> while (Isdigit(*f))</span>
00643 <span class="comment"> f++; // skip the digits</span>
00644 <span class="comment"> }</span>
00645 <span class="comment"> if (*f == '.')</span>
00646 <span class="comment"> { // precision</span>
00647 <span class="comment"> f++;</span>
00648 <span class="comment"> if (*f == '*')</span>
00649 <span class="comment"> {</span>
00650 <span class="comment"> prec = va_arg(ap, int);</span>
00651 <span class="comment"> f++;</span>
00652 <span class="comment"> }</span>
00653 <span class="comment"> else if (Isdigit(*f))</span>
00654 <span class="comment"> {</span>
00655 <span class="comment"> prec = atoi((char *) f);</span>
00656 <span class="comment"> while (Isdigit(*f))</span>
00657 <span class="comment"> f++; // skip the digits</span>
00658 <span class="comment"> }</span>
00659 <span class="comment"> }</span>
00660 <span class="comment"> if (*f == '#')</span>
00661 <span class="comment"> { // alternate form</span>
00662 <span class="comment"> hash = 1;</span>
00663 <span class="comment"> f++;</span>
00664 <span class="comment"> }</span>
00665 <span class="comment"> if (*f == 'l')</span>
00666 <span class="comment"> { // long format</span>
00667 <span class="comment"> do_long = 1;</span>
00668 <span class="comment"> f++;</span>
00669 <span class="comment"> }</span>
00670 <span class="comment"></span>
00671 <span class="comment"> fmt = *f;</span>
00672 <span class="comment"> bp = buf;</span>
00673 <span class="comment"> switch (fmt) { // do the formatting</span>
00674 <span class="comment"> case 'd': // 'd' signed decimal</span>
00675 <span class="comment"> if (do_long)</span>
00676 <span class="comment"> l = va_arg(ap, long);</span>
00677 <span class="comment"> else</span>
00678 <span class="comment"> l = (long) (va_arg(ap, int));</span>
00679 <span class="comment"> if (l < 0)</span>
00680 <span class="comment"> {</span>
00681 <span class="comment"> sign = 1;</span>
00682 <span class="comment"> l = -l;</span>
00683 <span class="comment"> }</span>
00684 <span class="comment"> do {</span>
00685 <span class="comment"> *bp++ = l % 10 + '0';</span>
00686 <span class="comment"> } while ((l /= 10) > 0);</span>
00687 <span class="comment"> if (sign)</span>
00688 <span class="comment"> *bp++ = '-';</span>
00689 <span class="comment"> f_width = f_width - (bp - buf);</span>
00690 <span class="comment"> if (!flush_left)</span>
00691 <span class="comment"> while (f_width-- > 0)</span>
00692 <span class="comment"> *str++ = (pad);</span>
00693 <span class="comment"> for (bp--; bp >= buf; bp--)</span>
00694 <span class="comment"> *str++ = (*bp);</span>
00695 <span class="comment"> if (flush_left)</span>
00696 <span class="comment"> while (f_width-- > 0)</span>
00697 <span class="comment"> *str++ = (' ');</span>
00698 <span class="comment"> break;</span>
00699 <span class="comment"> case 'o': // 'o' octal number</span>
00700 <span class="comment"> case 'x': // 'x' hex number</span>
00701 <span class="comment"> case 'u': // 'u' unsigned decimal</span>
00702 <span class="comment"> if (do_long)</span>
00703 <span class="comment"> u = va_arg(ap, unsigned long);</span>
00704 <span class="comment"> else</span>
00705 <span class="comment"> u = (unsigned long) (va_arg(ap, unsigned));</span>
00706 <span class="comment"> if (fmt == 'u')</span>
00707 <span class="comment"> { // unsigned decimal</span>
00708 <span class="comment"> do {</span>
00709 <span class="comment"> *bp++ = u % 10 + '0';</span>
00710 <span class="comment"> } while ((u /= 10) > 0);</span>
00711 <span class="comment"> }</span>
00712 <span class="comment"> else if (fmt == 'o')</span>
00713 <span class="comment"> { // octal</span>
00714 <span class="comment"> do {</span>
00715 <span class="comment"> *bp++ = u % 8 + '0';</span>
00716 <span class="comment"> } while ((u /= 8) > 0);</span>
00717 <span class="comment"> if (hash)</span>
00718 <span class="comment"> *bp++ = '0';</span>
00719 <span class="comment"> }</span>
00720 <span class="comment"> else if (fmt == 'x')</span>
00721 <span class="comment"> { // hex</span>
00722 <span class="comment"> do {</span>
00723 <span class="comment"> i = u % 16;</span>
00724 <span class="comment"> if (i < 10)</span>
00725 <span class="comment"> *bp++ = i + '0';</span>
00726 <span class="comment"> else</span>
00727 <span class="comment"> *bp++ = i - 10 + 'a';</span>
00728 <span class="comment"> } while ((u /= 16) > 0);</span>
00729 <span class="comment"> if (hash)</span>
00730 <span class="comment"> {</span>
00731 <span class="comment"> *bp++ = 'x';</span>
00732 <span class="comment"> *bp++ = '0';</span>
00733 <span class="comment"> }</span>
00734 <span class="comment"> }</span>
00735 <span class="comment"> i = f_width - (bp - buf);</span>
00736 <span class="comment"> if (!flush_left)</span>
00737 <span class="comment"> while (i-- > 0)</span>
00738 <span class="comment"> *str++ = (pad);</span>
00739 <span class="comment"> for (bp--; bp >= buf; bp--)</span>
00740 <span class="comment"> *str++ = ((int) (*bp));</span>
00741 <span class="comment"> if (flush_left)</span>
00742 <span class="comment"> while (i-- > 0)</span>
00743 <span class="comment"> *str++ = (' ');</span>
00744 <span class="comment"> break;</span>
00745 <span class="comment"> case 'c': // 'c' character</span>
00746 <span class="comment"> i = va_arg(ap, int);</span>
00747 <span class="comment"> *str++ = ((int) (i));</span>
00748 <span class="comment"> break;</span>
00749 <span class="comment"> case 's': // 's' string</span>
00750 <span class="comment"> bp = va_arg(ap, unsigned char *);</span>
00751 <span class="comment"> if (!bp)</span>
00752 <span class="comment"> bp = (unsigned char *) "(nil)";</span>
00753 <span class="comment"> f_width = f_width - strlen((char *) bp);</span>
00754 <span class="comment"> if (!flush_left)</span>
00755 <span class="comment"> while (f_width-- > 0)</span>
00756 <span class="comment"> *str++ = (pad);</span>
00757 <span class="comment"> for (i = 0; *bp && i < prec; i++)</span>
00758 <span class="comment"> {</span>
00759 <span class="comment"> *str++ = (*bp);</span>
00760 <span class="comment"> bp++;</span>
00761 <span class="comment"> }</span>
00762 <span class="comment"> if (flush_left)</span>
00763 <span class="comment"> while (f_width-- > 0)</span>
00764 <span class="comment"> *str++ = (' ');</span>
00765 <span class="comment"> break;</span>
00766 <span class="comment"> case '%': // '%' character</span>
00767 <span class="comment"> *str++ = ('%');</span>
00768 <span class="comment"> break;</span>
00769 <span class="comment"> }</span>
00770 <span class="comment"> flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;</span>
00771 <span class="comment"> sign = 0;</span>
00772 <span class="comment"> pad = ' ';</span>
00773 <span class="comment"> }</span>
00774 <span class="comment"> }</span>
00775 <span class="comment"></span>
00776 <span class="comment"> va_end(ap);</span>
00777 <span class="comment"> // terminate string with null</span>
00778 <span class="comment"> *str++ = '\0';</span>
00779 <span class="comment"> return bufstring;</span>
00780 <span class="comment">}</span>
00781 <span class="comment"></span>
00782 <span class="comment">*/</span>
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Sun Oct 29 03:41:07 2006 for Procyon AVRlib by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.2 </small></address>
</body>
</html>
|