summaryrefslogtreecommitdiff
path: root/libc/bios/cprintf.c
blob: 5f8beaa7253d19cde424b547324241da000350a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

#include <stdarg.h>
#define wchar(ch) putch(ch)

cprintf(char * fmt, va_list ap)
{
   register int c;
   int count = 0;
   int type, base;
   long val;
   char * cp;
   char padch=' ';
   int  minsize = 0;

   while(c=*fmt++)
   {
      if(c!='%')
      {
	 wchar(c);
	 count++;
      }
      else
      {
	 type=1;
	 do { c=*fmt++; } while( c>='0' && c<='9');

	 padch = *fmt;
	 minsize=0;
	 if(padch == '-') fmt++;

	 for(;;)
	 {
	    c=*fmt++;
	    if( c<'0' || c>'9' ) break;
	    minsize*=10; minsize+=c-'0';
	 }

	 while( c=='.' || (c>='0' && c<='9')) { c=*fmt++; }

	 if( padch == '-' ) minsize = -minsize;
	 else
	 if( padch == '0' ) padch='0'; else padch=' ';

	 if( c == 0 ) break;
	 if(c=='h')
	 {
	    c=*fmt++;
	    type = 0;
	 }
	 else if(c=='l')
	 {
	    c=*fmt++;
	    type = 2;
	 }

	 switch(c)
	 {
	    case 'x': base=16;   if(0) {
	    case 'o': base= 8; } if(0) {
	    case 'd': base=10; }
	       val=0;
	       switch(type)
	       {
		  case 0: val=va_arg(ap, short); break; 
		  case 1: val=va_arg(ap, int);   break;
		  case 2: val=va_arg(ap, long);  break;
	       }
	       cp = __numout(val,base);
	       if(0) {
	    case 's':
	          cp=va_arg(ap, char *);
	       }
	       if( minsize > 0 )
	       {
		  minsize -= strlen(cp);
		  while(minsize>0) { wchar(padch); minsize--; }
		  minsize=0;
	       }
	       if( minsize < 0 ) minsize= -minsize-strlen(cp);
	       while(*cp)
		  wchar(*cp++);
	       while(minsize>0) { wchar(' '); minsize--; }
	       break;
	    case 'c':
	       wchar(va_arg(ap, int));
	       break;
	    default:
	       wchar(c);
	       break;
	 }
      }
   }
   return count;
}



static char nstring[]="0123456789ABCDEF";

static unsigned char *
__numout(long i, int base)
{
   static unsigned char out[16];
   int n;
   int flg = 0;
   unsigned long val;

   if (i<0 && base==10)
   {
      flg = 1;
      i = -i;
   }
   val = i;

   for (n = 0; n < 15; n++)
      out[n] = ' ';
   out[15] = '\0';
   n = 14;
   do
   {
      out[n] = nstring[val % base];
      n--;
      val /= base;
   }
   while(val);
   if(flg) out[n--] = '-';
   return &out[n+1];
}