BSD 1 development
[unix-history] / portlib / printf.c
CommitLineData
520d5775
EA
1# include "iodec.h"
2# define BUFSIZ 80
3
4/**
5 ** formated print
6 **/
7
8printf(parlist)
9char *parlist;
10{
11 register char *fmt, c;
12 char buf[BUFSIZ];
13 extern char *__prtshort(), *__prtld(), *__prtld();
14 double *dblptr;
15 int mode;
16 char *fd;
17 register char **p;
18 int width, prec;
19 int left, longf;
20 char padchar;
21 char *s;
22 int n;
23 auto (*fn)();
24 int len;
25
26 p = &parlist;
27 fd = 0;
28 mode = 0; /* mode zero, putchar */
29 if (parlist + 1 < MAXFILES + 1)
30 {
31 mode++; /* mode one, cputc */
32 fd = *p++;
33 }
34 if (fd == -1)
35 {
36 mode++; /* mode two, string */
37 fd = *p++;
38 }
39 fmt = *p++;
40
41 while (c = *fmt++)
42 {
43 if (c != '%')
44 {
45 __putch(mode, &fd, c);
46 continue;
47 }
48 left = 0;
49 if ((c = *fmt++) == '-')
50 {
51 c = *fmt++;
52 left++;
53 }
54 padchar = ' ';
55 if (c == '0')
56 {
57 padchar = c;
58 c = *fmt++;
59 }
60 width = -1;
61 while (c >= '0' && c <= '9')
62 {
63 if (width < 0)
64 width = 0;
65 width = width * 10 + (c - '0');
66 c = *fmt++;
67 }
68 prec = -1;
69 if (c == '.')
70 {
71 prec = 0;
72 c = *fmt++;
73 }
74 while (c >= '0' && c <= '9')
75 {
76 prec = prec * 10 + (c - '0');
77 c = *fmt++;
78 }
79 longf = 0;
80 if (c == 'l')
81 {
82 longf++;
83 c = *fmt++;
84 }
85 /* we now have all the prelims out of the way;
86 let's see what we want to print */
87
88 s = buf;
89 switch (c)
90 {
91
92 case 'd': /* decimal signed */
93 case 'D':
94 if (longf)
95 fn = __prtld;
96 else
97 fn = __prtshort;
98 __prtint(p++, buf, 10, 1, fn, 0);
99 if (longf)
100 p++;
101 break;
102
103 case 'u': /* decimal unsigned */
104 case 'U':
105 __prtint(p++, buf, 10, 0, __prtshort, 0);
106 break;
107
108 case 'o': /* octal unsigned */
109 case 'O':
110 __prtint(p++, buf, 8, 0, __prtshort, 0);
111 break;
112
113 case 'x': /* hexadecimal unsigned */
114 case 'X':
115 __prtint(p++, buf, 16, 0, __prtshort, c == 'X');
116 break;
117
118 case 's': /* string */
119 case 'S':
120 s = *p++;
121 break;
122
123 case 'c': /* character */
124 case 'C':
125 n = *p++;
126 buf[0] = n;
127 buf[1] = '\0';
128 break;
129
130 case 'e': /* exponential */
131 case 'E':
132 case 'f': /* floating */
133 case 'F':
134 case 'g': /* e or f */
135 case 'G':
136 case 'n':
137 case 'N':
138 dblptr = p;
139 if (prec < 0)
140 prec = 7;
141 ftoa(*dblptr, buf, sizeof buf - 1, prec, c);
142 while (*s == ' ')
143 s++;
144 p =+ 4;
145 prec = -1;
146 break;
147
148 default: /* just print the character */
149 __putch(mode, &fd, c);
150 continue;
151
152 }
153 len = __length(s);
154 if (prec < len && prec >= 0)
155 len = prec;
156 n = width - len;
157 if (!left)
158 {
159 if (padchar != ' ' && *s == '-')
160 {
161 len--;
162 __putch(mode, &fd, *s++);
163 }
164 while (n-- > 0)
165 __putch(mode, &fd, padchar);
166 }
167 while (len--)
168 __putch(mode, &fd, *s++);
169 while (n-- > 0)
170 __putch(mode, &fd, padchar);
171 }
172 if (mode == 2)
173 *fd = '\0';
174}
175
176
177__putch(mode, pfd, c)
178int mode;
179char c;
180char **pfd;
181{
182 switch (mode)
183 {
184
185 case 0:
186 putchar(c);
187 break;
188
189 case 1:
190 cputc(c, *pfd);
191 break;
192
193 case 2:
194 *(*pfd)++ = c;
195 break;
196
197 }
198 return (c);
199}
200
201
202char *__prtld(pobj, pbuf, base, signed, digs)
203long *pobj;
204char **pbuf;
205int base;
206int signed;
207char *digs;
208{
209 long n;
210 register char *p;
211
212 p = digs;
213 n = *pobj;
214 if (signed && n < 0)
215 {
216 *(*pbuf)++ = '-';
217 n = -n;
218 }
219 for (; n != 0; n =/ base)
220 *p++ = n % base;
221 return (p);
222}