Add externs to avoid multiple definitions, and then add missing definitions.
[rrq/maintain_lilo.git] / diagnose / cprintf.c
1 /* Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk>
2  * This file is part of the Linux-8086 C library and is distributed
3  * under the GNU Library General Public License.
4  */
5
6 /* Modified 14-Jan-2002 by John Coffman <johninsd@san.rr.com> for inclusion
7  * in the set of LILO diagnostics.  This code is the property of Robert
8  * de Bath, and is used with his permission.
9  */
10
11 #include <stdarg.h>
12 /* #include <conio.h> */
13 #define ASM_CVT 1
14
15 #if __MSDOS__
16 #include <stdio.h>
17 #define putch(ch) fputc(ch,stdout)
18 #else
19 #define putch(ch) bios_putc(ch)
20 #endif
21
22 static unsigned char * __numout(long i, int base);
23
24 int cprintf(char * fmt, ...)
25 {
26    register int c;
27    int count = 0;
28    int type, base;
29    long val;
30    char * cp;
31    char padch=' ';
32    int  minsize, maxsize;
33    va_list ap;
34
35    va_start(ap, fmt);
36
37    while(c=*fmt++)
38    {
39       count++;
40       if(c!='%')
41       {
42          if (c=='\n') putch('\r');
43          putch(c);
44       }
45       else
46       {
47          type=1;
48          padch = *fmt;
49          maxsize=minsize=0;
50          if(padch == '-') fmt++;
51
52          for(;;)
53          {
54             c=*fmt++;
55             if( c<'0' || c>'9' ) break;
56             minsize*=10; minsize+=c-'0';
57          }
58
59          if( c == '.' )
60             for(;;)
61             {
62                c=*fmt++;
63                if( c<'0' || c>'9' ) break;
64                maxsize*=10; maxsize+=c-'0';
65             }
66
67          if( padch == '-' ) minsize = -minsize;
68          else
69          if( padch != '0' ) padch=' ';
70
71          if( c == 0 ) break;
72          if(c=='h')
73          {
74             c=*fmt++;
75             type = 0;
76          }
77          else if(c=='l')
78          {
79             c=*fmt++;
80             type = 2;
81          }
82
83          switch(c)
84          {
85             case 'x': base=16; type |= 4;   if(0) {
86             case 'o': base= 8; type |= 4; } if(0) {
87             case 'u': base=10; type |= 4; } if(0) {
88             case 'd': base=-10; }
89                switch(type)
90                {
91                   case 0: val=va_arg(ap, short); break; 
92                   case 1: val=va_arg(ap, int);   break;
93                   case 2: val=va_arg(ap, long);  break;
94                   case 4: val=va_arg(ap, unsigned short); break; 
95                   case 5: val=va_arg(ap, unsigned int);   break;
96                   case 6: val=va_arg(ap, unsigned long);  break;
97                   default:val=0; break;
98                }
99                cp = __numout(val,base);
100                if(0) {
101             case 's':
102                   cp=va_arg(ap, char *);
103                }
104                count--;
105                c = strlen(cp);
106                if( !maxsize ) maxsize = c;
107                if( minsize > 0 )
108                {
109                   minsize -= c;
110                   while(minsize>0) { putch(padch); count++; minsize--; }
111                   minsize=0;
112                }
113                if( minsize < 0 ) minsize= -minsize-c;
114                while(*cp && maxsize-->0 )
115                {
116                   putch(*cp++);
117                   count++;
118                }
119                while(minsize>0) { putch(' '); count++; minsize--; }
120                break;
121             case 'c':
122                putch(va_arg(ap, int));
123                break;
124             default:
125                putch(c);
126                break;
127          }
128       }
129    }
130    va_end(ap);
131    return count;
132 }
133
134 static char nstring[]="0123456789ABCDEF";
135
136 #if ASM_CVT==0
137 #define NUMLTH 11
138
139 static unsigned char *
140 __numout(long i, int base)
141 {
142    static unsigned char out[NUMLTH+1];
143    int n;
144    int flg = 0;
145    unsigned long val;
146
147    if (base<0)
148    {
149       base = -base;
150       if (i<0)
151       {
152          flg = 1;
153          i = -i;
154       }
155    }
156    val = i;
157
158    out[NUMLTH] = '\0';
159    n = NUMLTH-1;
160    do
161    {
162       out[n--] = nstring[val % base];
163       val /= base;
164    }
165    while(val);
166    if(flg) out[n--] = '-';
167    return &out[n+1];
168 }
169 #else
170
171 #asm
172 ! numout.s
173 !
174 #if 0
175 .data
176 _nstring:
177 .ascii  "0123456789ABCDEF"
178 .byte   0
179 #endif
180
181 .bss
182 ___out  lcomm   $C
183
184 .text
185 ___numout:
186 push    bp
187 mov     bp,sp
188 push    di
189 push    si
190 add     sp,*-4
191 mov     byte ptr -8[bp],*$0     ! flg = 0
192 mov     si,4[bp]        ; i or val.lo
193 mov     di,6[bp]        ; i or val.hi
194 mov     cx,8[bp]        ; base
195 test    cx,cx                   ! base < 0 ?
196 jge     .3num
197 neg  cx                         ! base = -base
198 or      di,di                   ! i < 0 ?
199 jns     .5num
200 mov     byte ptr -8[bp],*1      ! flg = 1
201 neg     di                      ! i = -i
202 neg     si
203 sbb     di,*0
204 .5num:
205 .3num:
206 mov     byte ptr [___out+$B],*$0        ! out[11] = nul
207 mov     -6[bp],*$A              ! n = 10
208
209 .9num:
210 !!!         out[n--] = nstring[val % base];
211 xor  dx,dx
212 xchg ax,di
213 div  cx
214 xchg ax,di
215 xchg ax,si
216 div  cx
217 xchg ax,si                      ! val(new) = val / base
218
219 mov  bx,dx                      ! dx = val % base
220
221 mov     al,_nstring[bx]
222 mov     bx,-6[bp]
223 dec     word ptr -6[bp]
224 mov     ___out[bx],al
225
226 mov  ax,si
227 or   ax,di                      ! while (val)
228 jne     .9num
229
230 cmp     byte ptr -8[bp],*$0     ! flg == 0 ?
231 je      .Dnum
232
233 mov     bx,-6[bp]
234 dec     word ptr -6[bp]
235 mov     byte ptr ___out[bx],*$2D        ! out[n--] = minus
236
237 .Dnum:
238 mov     ax,-6[bp]
239 add     ax,#___out+1
240
241 add     sp,*4
242 pop     si
243 pop     di
244 pop     bp
245 ret
246 #endasm
247
248 #endif