X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device%2Flib%2Fvprintf.c;h=07b5cac365d817ece1ea3cd4df1cab459e40ef69;hb=018a6f8c8ded8202afb6e3eb0becf7b98e76a93c;hp=12a7cdb88a2aff6e39eb1cda58083959f1d5140c;hpb=b09af35f2f1cde7649d3ac4a6f5d2af6d97895a0;p=fw%2Fsdcc diff --git a/device/lib/vprintf.c b/device/lib/vprintf.c index 12a7cdb8..07b5cac3 100644 --- a/device/lib/vprintf.c +++ b/device/lib/vprintf.c @@ -1,421 +1,50 @@ /*------------------------------------------------------------------------- vprintf.c - formatted output conversion - + Written By - Martijn van Balen aed@iae.nl (1999) + Refactored by - Maarten Brock (2004) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, + This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! + what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ #include -#include -#include #include -extern void putchar(const char); - -#define PTR value.p - -/****************************************************************************/ - -typedef char _generic *ptr_t; - -//#define toupper(c) ((c)&=~0x20) -#define toupper(c) ((c)&=0xDF) - -typedef union -{ - unsigned char byte[5]; - long l; - unsigned long ul; - char _generic *p; -} value_t; - - -static code char memory_id[] = "IXCP-"; - -ptr_t output_ptr; -bit output_to_string; -bit lower_case; -bit lsd; - -data value_t value; - - unsigned short radix; - -/****************************************************************************/ - -static void output_char( char c ) reentrant +static void put_char_to_stdout( char c, void* p ) _REENTRANT { - if (output_to_string) - { - *output_ptr++ = c; - } - else - { - putchar( c ); - } + p; //make compiler happy + putchar( c ); } -/*--------------------------------------------------------------------------*/ - -static void output_digit( unsigned char n ) reentrant -{ - output_char( n <= 9 ? '0'+n : (lower_case ? n+(char)('a'-10) : n+(char)('A'-10)) ); -} - -/*--------------------------------------------------------------------------*/ - -static void output_2digits( unsigned char b ) reentrant -{ - output_digit( b>>4 ); - output_digit( b&0x0F ); -} - -/*--------------------------------------------------------------------------*/ - -static void calculate_digit( void ) +int vprintf (const char *format, va_list ap) { - unsigned char i; - - for( i = 32; i != 0; i-- ) - { -_asm - clr c - mov a,_value+0 - rlc a - mov _value+0,a - mov a,_value+1 - rlc a - mov _value+1,a - mov a,_value+2 - rlc a - mov _value+2,a - mov a,_value+3 - rlc a - mov _value+3,a - mov a,_value+4 - rlc a - mov _value+4,a -_endasm; - - if (radix <= value.byte[4] ) - { - value.byte[4] -= radix; - value.byte[0]++; - } - } + return _print_format( put_char_to_stdout, NULL, format, ap ); } -/*--------------------------------------------------------------------------*/ - -int vsprintf (const char *buf, const char *format, va_list ap) +int printf (const char *format, ...) { - bit left_justify; - bit zero_padding; - bit prefix_sign; - bit prefix_space; - bit signed_argument; - bit char_argument; - bit long_argument; - - unsigned char width; - unsigned char length; - char c; - - output_ptr = buf; - if ( !buf ) - { - output_to_string = 0; - } - else - { - output_to_string = 1; - } - - while( c=*format++ ) - { - if ( c == '%' ) - { - left_justify = 0; - zero_padding = 0; - prefix_sign = 0; - prefix_space = 0; - signed_argument = 0; - radix = 0; - char_argument = 0; - long_argument = 0; - width = 0; - -get_conversion_spec: + va_list arg; + int i; - c = *format++; + va_start (arg, format); + i = _print_format( put_char_to_stdout, NULL, format, arg ); + va_end (arg); - if (isdigit(c)) - { - width = 10*width + (c - '0'); - - if (width == 0) - { - /* first character of width is a zero */ - zero_padding = 1; - } - goto get_conversion_spec; - } - - lower_case = islower(c); - if (lower_case) - { - c = toupper(c); - } - - switch( c ) - { - case '-': - left_justify = 1; - goto get_conversion_spec; - case '+': - prefix_sign = 1; - goto get_conversion_spec; - case ' ': - prefix_space = 1; - goto get_conversion_spec; - case 'B': - char_argument = 1; - goto get_conversion_spec; - case 'L': - long_argument = 1; - goto get_conversion_spec; - - case 'C': - output_char( va_arg(ap,unsigned char) ); - break; - - case 'S': - PTR = va_arg(ap,ptr_t); - - length = strlen(PTR); - if ( ( !left_justify ) && (length < width) ) - { - width -= length; - while( width-- != 0 ) - { - output_char( ' ' ); - } - } - - while ( *PTR ) - output_char( *PTR++ ); - - if ( left_justify && (length < width)) - { - width -= length; - while( width-- != 0 ) - { - output_char( ' ' ); - } - } - break; - - case 'P': - PTR = va_arg(ap,ptr_t); - - output_char( memory_id[(value.byte[2] > 3) ? 4 : value.byte[2]] ); - output_char( ':' ); - if ((value.byte[2] != 0x00) && (value.byte[2] != 0x03)) - output_2digits( value.byte[1] ); - output_2digits( value.byte[0] ); - break; - - case 'D': - case 'I': - signed_argument = 1; - radix = 10; - break; - - case 'O': - radix = 8; - break; - - case 'U': - radix = 10; - break; - - case 'X': - radix = 16; - break; - - default: - // nothing special, just output the character - output_char( c ); - break; - } - - if (radix != 0) - { - // Apperently we have to output an integral type - // with radix "radix" - - // store value in byte[0] (LSB) ... byte[3] (MSB) - if (char_argument) - { - value.l = va_arg(ap,char); - if (!signed_argument) - { - value.byte[1] = 0x00; - value.byte[2] = 0x00; - value.byte[3] = 0x00; - } - } - else if (long_argument) - { - value.l = va_arg(ap,long); - } - else - { - value.l = va_arg(ap,int); - if (!signed_argument) - { - value.byte[2] = 0x00; - value.byte[3] = 0x00; - } - } - - if ( signed_argument ) - { - if (value.l < 0) - value.l = -value.l; - else - signed_argument = 0; - } - - length=0; - lsd = 1; - while( (value.byte[0] != 0) || (value.byte[1] != 0) || - (value.byte[2] != 0) || (value.byte[3] != 0) ) - { - value.byte[4] = 0; - calculate_digit(); - -_asm - jb _lsd,1$ - pop b ; b = - mov a,_value+4 ; a = - swap a - orl b,a ; b = - push b - sjmp 2$ -1$: - mov a,_value+4 ; a = - push acc -2$: -_endasm; - - length++; - lsd = ~lsd; - } - - if (width == 0) - { - // default width. We set it to 1 to output - // at least one character is case the value itself - // is zero (i.e. length==0) - width=1; - } - - /* prepend spaces if needed */ - if (!zero_padding) - { - while ( width > length+1 ) - { - output_char( ' ' ); - width--; - } - } - - if (signed_argument) // this now means the original value was negative - { - output_char( '-' ); - // adjust width to compensate for this character - width--; - } - else if (length != 0) - { - // value > 0 - if (prefix_sign) - { - output_char( '+' ); - // adjust width to compensate for this character - width--; - } - else if (prefix_space) - { - output_char( ' ' ); - // adjust width to compensate for this character - width--; - } - } - - /* prepend zeroes/spaces if needed */ - while ( width-- > length ) - { - output_char( zero_padding ? '0' : ' ' ); - } - - /* output the digits */ - while( length-- ) - { - lsd = ~lsd; - -_asm - jb _lsd,3$ - pop acc ; a = - nop ; to disable the "optimizer" - push acc - swap a - anl a,#0x0F ; a = - sjmp 4$ -3$: - pop acc - anl a,#0x0F ; a = -4$: - mov _value+4,a -_endasm; - - output_digit( value.byte[4] ); - } - } - } - else - { - // nothing special, just output the character - output_char( c ); - } - } - - // Copy \0 to the end of buf - // Modified by JB 17/12/99 - if (output_to_string) output_char(0); -} - -/*--------------------------------------------------------------------------*/ - -int vprintf (const char *format, va_list ap) -{ - return vsprintf( 0, format, ap ); + return i; }