1 /*-------------------------------------------------------------------------
2 vprintf.c - formatted output conversion
4 Written By - Martijn van Balen aed@iae.nl (1999)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
30 extern void putchar(const char);
34 /****************************************************************************/
36 typedef char _generic *ptr_t;
38 //#define toupper(c) ((c)&=~0x20)
39 #define toupper(c) ((c)&=0xDF)
43 unsigned char byte[5];
50 static code char memory_id[] = "IXCP-";
61 /****************************************************************************/
63 static void output_char( char c ) reentrant
75 /*--------------------------------------------------------------------------*/
77 static void output_digit( unsigned char n ) reentrant
79 output_char( n <= 9 ? '0'+n : (lower_case ? n+(char)('a'-10) : n+(char)('A'-10)) );
82 /*--------------------------------------------------------------------------*/
84 static void output_2digits( unsigned char b ) reentrant
87 output_digit( b&0x0F );
90 /*--------------------------------------------------------------------------*/
92 static void calculate_digit( void )
96 for( i = 32; i != 0; i-- )
117 if (radix <= value.byte[4] )
119 value.byte[4] -= radix;
125 /*--------------------------------------------------------------------------*/
127 int vsprintf (const char *buf, const char *format, va_list ap)
138 unsigned char length;
144 output_to_string = 0;
148 output_to_string = 1;
171 width = 10*width + (c - '0');
175 /* first character of width is a zero */
178 goto get_conversion_spec;
181 lower_case = islower(c);
191 goto get_conversion_spec;
194 goto get_conversion_spec;
197 goto get_conversion_spec;
200 goto get_conversion_spec;
203 goto get_conversion_spec;
206 output_char( va_arg(ap,unsigned char) );
210 PTR = va_arg(ap,ptr_t);
212 length = strlen(PTR);
213 if ( ( !left_justify ) && (length < width) )
216 while( width-- != 0 )
223 output_char( *PTR++ );
225 if ( left_justify && (length < width))
228 while( width-- != 0 )
236 PTR = va_arg(ap,ptr_t);
238 output_char( memory_id[(value.byte[2] > 3) ? 4 : value.byte[2]] );
240 if ((value.byte[2] != 0x00) && (value.byte[2] != 0x03))
241 output_2digits( value.byte[1] );
242 output_2digits( value.byte[0] );
264 // nothing special, just output the character
271 // Apperently we have to output an integral type
272 // with radix "radix"
274 // store value in byte[0] (LSB) ... byte[3] (MSB)
277 value.l = va_arg(ap,char);
278 if (!signed_argument)
280 value.byte[1] = 0x00;
281 value.byte[2] = 0x00;
282 value.byte[3] = 0x00;
285 else if (long_argument)
287 value.l = va_arg(ap,long);
291 value.l = va_arg(ap,int);
292 if (!signed_argument)
294 value.byte[2] = 0x00;
295 value.byte[3] = 0x00;
299 if ( signed_argument )
309 while( (value.byte[0] != 0) || (value.byte[1] != 0) ||
310 (value.byte[2] != 0) || (value.byte[3] != 0) )
318 mov a,_value+4 ; a = <msd>
320 orl b,a ; b = <msd><lsd>
324 mov a,_value+4 ; a = <lsd>
335 // default width. We set it to 1 to output
336 // at least one character is case the value itself
337 // is zero (i.e. length==0)
341 /* prepend spaces if needed */
344 while ( width > length+1 )
351 if (signed_argument) // this now means the original value was negative
354 // adjust width to compensate for this character
357 else if (length != 0)
363 // adjust width to compensate for this character
366 else if (prefix_space)
369 // adjust width to compensate for this character
374 /* prepend zeroes/spaces if needed */
375 while ( width-- > length )
377 output_char( zero_padding ? '0' : ' ' );
380 /* output the digits */
387 pop acc ; a = <msd><lsd>
388 nop ; to disable the "optimizer"
391 anl a,#0x0F ; a = <msd>
395 anl a,#0x0F ; a = <lsd>
400 output_digit( value.byte[4] );
406 // nothing special, just output the character
411 // Copy \0 to the end of buf
412 // Modified by JB 17/12/99
413 if (output_to_string) output_char(0);
416 /*--------------------------------------------------------------------------*/
418 int vprintf (const char *format, va_list ap)
420 return vsprintf( 0, format, ap );