caa3152c372da3ca971c0ac04180377a06398fbf
[fw/sdcc] / device / lib / pic16 / libc / stdio / printf_tiny.c
1 /*-----------------------------------------------------------------
2     printf_tiny.c - source file for reduced version of printf
3
4     Modified for pic16 port, by Vangelis Rokas, 2004 (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 /* This function uses function putchar() to dump a character
32  * to standard output. putchar() is defined in libc18f.lib
33  * as dummy function, which will be linked if no putchar()
34  * function is provided by the user.
35  * The user can write his own putchar() function and link it
36  * with the source *BEFORE* the libc18f.lib library. This way
37  * the linker will link the first function (i.e. the user's function) */
38
39 /* following formats are supported :-
40    format     output type       argument-type
41      %u*       unsigned            *
42
43      %b        binary
44      %d        decimal             int
45      %ld       decimal             long
46      %hd       decimal             char
47      %x        hexadecimal         int
48      %lxX      hexadecimal         long
49      %hxX      hexadecimal         char
50      %o        octal               int
51      %lo       octal               long
52      %ho       octal               char
53      %c        character           char
54      %s        character           generic pointer
55 */
56
57 #include <ctype.h>
58 #include <stdarg.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61
62 #if 0
63 #define DPUT(c) putchar( c )
64 #else
65 #define DPUT(c)
66 #endif
67
68 #define ISLONG          (flong)
69 #define ISSTR           (fstr)
70 #define ISCHAR          (fchar)
71 #define HAVESIGN        (nosign)
72
73
74 #if 1
75 extern void io_long(long);
76 extern void io_int(long);
77 extern void io_char(char);
78 #endif
79
80 void printf_tiny(char *fmt, ...) 
81 {
82   char radix;
83   char flong, fstr;
84   char fchar, nosign;
85   char upcase;
86
87   char *str, *ch;
88   __data char *str1;
89   long val;
90 //  static char buffer[16];
91   char buffer[16];
92   va_list ap ;
93
94     va_start(ap,fmt);
95     ch = fmt;
96     
97     while( *ch ) {                      //for (; *fmt ; fmt++ )
98         if (*ch == '%') {
99             ISLONG = 0;
100             ISSTR = 0;
101             ISCHAR = 0;
102             HAVESIGN = 0;
103             radix = 0;
104             upcase = 0;
105             ch++;
106
107             if(*ch == 'u') {
108               HAVESIGN = 1;
109               ch++;
110             }
111             
112             if(*ch == 'l') {
113               ISLONG = 1;
114               ch++;
115             } else
116             if(*ch == 'h') {
117               ISCHAR = 1;
118               ch++;
119             }
120             
121             if(*ch == 's')ISSTR = 1;
122             else if(*ch == 'd')radix = 10;
123             else if(*ch == 'x'){ radix = 16; upcase = 0; }
124             else if(*ch == 'X'){ radix = 16; upcase = 1; }
125             else if(*ch == 'c')radix = 0;
126             else if(*ch == 'o')radix = 8;
127             else if(*ch == 'b')radix = 2;
128             
129             if(ISSTR) {
130                 str = va_arg(ap, char *);
131                 while(*str) { putchar(*str);str++;}
132             } else {
133               if(ISLONG)val = va_arg(ap, long);
134               else
135               if(ISCHAR) {
136                   val = (unsigned char)va_arg(ap, int); // FIXME: SDCC casts char arguments into ints
137                   if (!HAVESIGN) val = (char)val; // FIXME cont'd: sign-extend if required
138               } else {
139                   val = va_arg(ap, int);
140               }
141
142               if(radix) {
143                 if(HAVESIGN)
144                   ultoa(val, buffer, radix);
145                 else
146                   ltoa (val, buffer, radix);
147
148                 str1 = buffer;
149                 while( (*str1) ) {
150                   radix = *str1;
151                   if(upcase)
152                     radix = toupper( radix );
153                   putchar ( radix );
154                   str1++;
155                 }
156               } else
157                 putchar((char)val);
158             }
159           } else
160             putchar(*ch);
161
162         ch++;
163     }
164 }