* device/include/asm/pic16/features.h,
[fw/sdcc] / device / lib / pic16 / libc / stdio / vfprintf.c
1 /*-----------------------------------------------------------------
2     vfprintf.c - source file for reduced version of printf
3
4     Modified for pic16 port, by Vangelis Rokas, 2005 (vrokas@otenet.gr)
5     
6     Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
7
8     This library is free software; you can redistribute it and/or modify it
9     under the terms of the GNU Library General Public License as published by the
10     Free Software Foundation; either version 2, or (at your option) any
11     later version.
12
13     This library is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU Library General Public License for more details.
17
18     You should have received a copy of the GNU Library General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22     In other words, you are welcome to use, share and improve this program.
23     You are forbidden to forbid anyone else to use, share and improve
24     what you give them.   Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
26
27 /*
28 ** $Id$
29 */
30
31 /* following formats are supported :-
32    format     output type       argument-type
33      %u*       unsigned            *
34      %b        binary
35      %d        decimal             int
36      %ld       decimal             long
37      %hd       decimal             char
38      %x        hexadecimal         int
39      %lxX      hexadecimal         long
40      %hxX      hexadecimal         char
41      %o        octal               int
42      %lo       octal               long
43      %ho       octal               char
44      %c        character           char
45      %s        character           generic pointer
46 */
47
48 #include <ctype.h>
49 #include <stdarg.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52
53 #if _DEBUG
54 extern void io_long(unsigned long);
55 extern void io_str(char *);
56 extern void io_int(unsigned int);
57 #endif
58
59 unsigned int vfprintf(FILE *stream, char *fmt, va_list ap)
60 {
61   unsigned char radix;
62   unsigned char flong, fstr;
63   unsigned char fchar, nosign;
64   unsigned char upcase;
65   unsigned int count=0;
66   unsigned char *str, *ch;
67   __data char *str1;
68   long val;
69 //  static char buffer[16];
70   char buffer[16];
71
72
73 #if _DEBUG
74     io_str( "vfprintf: " );
75     io_long( (unsigned long)stream );
76     io_long( (unsigned long)fmt );
77 #endif
78
79 //    va_start(ap,fmt);
80     ch = fmt;
81     
82     while( *ch ) {                      //for (; *fmt ; fmt++ )
83         if (*ch == '%') {
84             flong = 0;
85             fstr = 0;
86             fchar = 0;
87             nosign = 0;
88             radix = 0;
89             upcase = 0;
90             ch++;
91
92             if(*ch == 'u') {
93               nosign = 1;
94               ch++;
95             }
96             
97             if(*ch == 'l') {
98               flong = 1;
99               ch++;
100             } else
101             if(*ch == 'h') {
102               fchar = 1;
103               ch++;
104             }
105             
106             if(*ch == 's')fstr = 1;
107             else if(*ch == 'd')radix = 10;
108             else if(*ch == 'x'){ radix = 16; upcase = 0; }
109             else if(*ch == 'X'){ radix = 16; upcase = 1; }
110             else if(*ch == 'c')radix = 0;
111             else if(*ch == 'o')radix = 8;
112             else if(*ch == 'b')radix = 2;
113             
114             if(fstr) {
115                 str = va_arg(ap, char *);
116                 while(*str) { __stream_putchar(stream, *str); str++; count++; }
117             } else {
118               val = 0;
119               if(flong) {
120                 val = va_arg(ap, long);
121 #if _DEBUG
122                 io_long(val);
123 #endif
124               }              
125               else
126               if(fchar) {
127                 val = va_arg(ap, char);
128 #if _DEBUG
129                 io_long(val);
130 #endif
131               }
132               else {
133                   val = va_arg(ap, int);
134 #if _DEBUG
135                 io_long(val);
136 #endif
137               }
138
139               if(radix) {
140                 if(nosign)
141                   ultoa(val, buffer, radix);
142                 else
143                   ltoa (val, buffer, radix);
144
145                 str1 = buffer;
146                 while( (*str1) ) {
147                   radix = *str1;
148                   if(upcase)
149                     radix = toupper( radix );
150                   __stream_putchar(stream, (unsigned char)radix);
151                   count++;
152                   str1++;
153                 }
154               } else {
155                 __stream_putchar(stream, (unsigned char)val);
156                 count++;
157               }
158             }
159           } else {
160             __stream_putchar(stream, *ch);
161             count++;
162           }
163
164         ch++;
165     }
166   
167   return (count);
168 }