1 /*---------------------------------------------------*/
3 /* Public Domain version of printf */
4 /* Rud Merriam, Compsult, Inc. Houston, Tx. */
5 /* For Embedded Systems Programming, 1991 */
7 /*---------------------------------------------------*/
8 #include "xil_printf.h"
10 #include "xil_assert.h"
15 typedef struct params_s {
25 static void padding( const s32 l_flag,const params_t *par);
26 static void outs(const charptr lp, params_t *par);
27 static s32 getnum( charptr* linep);
29 /*---------------------------------------------------*/
30 /* The purpose of this routine is to output data the */
31 /* same as the standard printf function without the */
32 /* overhead most run-time libraries involve. Usually */
33 /* the printf brings in many kilobytes of code and */
34 /* that is unacceptable in most embedded systems. */
35 /*---------------------------------------------------*/
38 /*---------------------------------------------------*/
40 /* This routine puts pad characters into the output */
43 static void padding( const s32 l_flag, const params_t *par)
47 if ((par->do_padding != 0) && (l_flag != 0) && (par->len < par->num1)) {
49 for (; i<(par->num1); i++) {
50 outbyte( par->pad_character);
55 /*---------------------------------------------------*/
57 /* This routine moves a string to the output buffer */
58 /* as directed by the padding and positioning flags. */
60 static void outs(const charptr lp, params_t *par)
64 /* pad on left if needed */
65 if(LocalPtr != NULL) {
66 par->len = (s32)strlen( LocalPtr);
68 padding( !(par->left_flag), par);
70 /* Move string to the buffer */
71 while (((*LocalPtr) != (char8)0) && ((par->num2) != 0)) {
77 /* Pad on right if needed */
78 /* CR 439175 - elided next stmt. Seemed bogus. */
79 /* par->len = strlen( lp) */
80 padding( par->left_flag, par);
83 /*---------------------------------------------------*/
85 /* This routine moves a number to the output buffer */
86 /* as directed by the padding and positioning flags. */
89 static void outnum( const s32 n, const s32 base, params_t *par)
95 const char8 digits[] = "0123456789ABCDEF";
97 for(i = 0; i<32; i++) {
101 /* Check if number is negative */
102 if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) {
111 /* Build number (backwards) in outbuf */
114 outbuf[i] = digits[(num % base)];
127 /* Move the converted number to the buffer and */
128 /* add in the padding where needed. */
129 par->len = (s32)strlen(outbuf);
130 padding( !(par->left_flag), par);
131 while (&outbuf[i] >= outbuf) {
132 outbyte( outbuf[i] );
135 padding( par->left_flag, par);
138 /*---------------------------------------------------*/
140 /* This routine moves a 64-bit number to the output */
141 /* buffer as directed by the padding and positioning */
145 static void outnum1( const s64 n, const s32 base, params_t *par)
151 const char8 digits[] = "0123456789ABCDEF";
153 for(i = 0; i<64; i++) {
157 /* Check if number is negative */
158 if ((par->unsigned_flag == 0) && (base == 10) && (n < 0L)) {
167 /* Build number (backwards) in outbuf */
170 outbuf[i] = digits[(num % base)];
183 /* Move the converted number to the buffer and */
184 /* add in the padding where needed. */
185 par->len = (s32)strlen(outbuf);
186 padding( !(par->left_flag), par);
187 while (&outbuf[i] >= outbuf) {
188 outbyte( outbuf[i] );
191 padding( par->left_flag, par);
193 /*---------------------------------------------------*/
195 /* This routine gets a number from the format */
198 static s32 getnum( charptr* linep)
201 s32 ResultIsDigit = 0;
206 ResultIsDigit = isdigit(((s32)*cptr));
208 while (ResultIsDigit != 0) {
210 n = ((n*10) + (((s32)*cptr) - (s32)'0'));
213 ResultIsDigit = isdigit(((s32)*cptr));
216 ResultIsDigit = isdigit(((s32)*cptr));
218 *linep = ((charptr )(cptr));
222 /*---------------------------------------------------*/
224 /* This routine operates just like a printf/sprintf */
225 /* routine. It outputs a set of data under the */
226 /* control of a formatting string. Not all of the */
227 /* standard C format control are supported. The ones */
228 /* provided are primarily those needed for embedded */
229 /* systems work. Primarily the floating point */
230 /* routines are omitted. Other formats could be */
231 /* added easily by following the examples shown for */
232 /* the supported formats. */
235 /* void esp_printf( const func_ptr f_ptr,
236 const charptr ctrl1, ...) */
237 void xil_printf( const char8 *ctrl1, ...)
247 char8 *ctrl = (char8 *)ctrl1;
249 va_start( argp, ctrl1);
251 while ((ctrl != NULL) && (*ctrl != (char8)0)) {
253 /* move format string chars to buffer until a */
254 /* format control is found. */
261 /* initialize all the flags for this format. */
264 par.unsigned_flag = 0;
267 par.pad_character = ' ';
283 if (isdigit((s32)ch) != 0) {
285 par.num2 = getnum(&ctrl);
289 par.pad_character = '0';
292 par.num1 = getnum(&ctrl);
302 switch (tolower((s32)ch)) {
324 par.unsigned_flag = 1;
329 outnum1((s64)va_arg(argp, s64), 10L, &par);
332 outnum( va_arg(argp, s32), 10L, &par);
337 par.unsigned_flag = 1;
338 outnum1((s64)va_arg(argp, s64), 16L, &par);
342 par.unsigned_flag = 1;
343 if (long_flag != 0) {
344 outnum1((s64)va_arg(argp, s64), 16L, &par);
347 outnum((s32)va_arg(argp, s32), 16L, &par);
353 outs( va_arg( argp, char *), &par);
358 outbyte( va_arg( argp, s32));
365 outbyte( ((char8)0x07));
368 outbyte( ((char8)0x08));
371 outbyte( ((char8)0x0D));
374 outbyte( ((char8)0x0D));
375 outbyte( ((char8)0x0A));
400 /*---------------------------------------------------*/