source: trunk/minix/lib/sysutil/kprintf.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

  • Property svn:executable set to *
File size: 3.6 KB
Line 
1/* printf() - system services printf() Author: Kees J. Bot
2 * 15 Jan 1994
3 */
4#define nil 0
5#include <stdarg.h>
6#include <stddef.h>
7#include <limits.h>
8
9#define isdigit(c) ((unsigned) ((c) - '0') < (unsigned) 10)
10
11#if !__STDC__
12/* Classic C stuff, ignore. */
13void kputc();
14int printf(fmt) char *fmt;
15#else
16
17/* Printf() uses kputc() to print characters. */
18void kputc(int c);
19
20#define count_kputc(c) do { charcount++; kputc(c); } while(0)
21
22int printf(const char *fmt, ...)
23#endif
24{
25 int c, charcount = 0;
26 enum { LEFT, RIGHT } adjust;
27 enum { LONG, INT } intsize;
28 int fill;
29 int width, max, len, base;
30 static char X2C_tab[]= "0123456789ABCDEF";
31 static char x2c_tab[]= "0123456789abcdef";
32 char *x2c;
33 char *p;
34 long i;
35 unsigned long u;
36 char temp[8 * sizeof(long) / 3 + 2];
37
38 va_list argp;
39
40 va_start(argp, fmt);
41
42 while ((c= *fmt++) != 0) {
43 if (c != '%') {
44 /* Ordinary character. */
45 count_kputc(c);
46 continue;
47 }
48
49 /* Format specifier of the form:
50 * %[adjust][fill][width][.max]keys
51 */
52 c= *fmt++;
53
54 adjust= RIGHT;
55 if (c == '-') {
56 adjust= LEFT;
57 c= *fmt++;
58 }
59
60 fill= ' ';
61 if (c == '0') {
62 fill= '0';
63 c= *fmt++;
64 }
65
66 width= 0;
67 if (c == '*') {
68 /* Width is specified as an argument, e.g. %*d. */
69 width= va_arg(argp, int);
70 c= *fmt++;
71 } else
72 if (isdigit(c)) {
73 /* A number tells the width, e.g. %10d. */
74 do {
75 width= width * 10 + (c - '0');
76 } while (isdigit(c= *fmt++));
77 }
78
79 max= INT_MAX;
80 if (c == '.') {
81 /* Max field length coming up. */
82 if ((c= *fmt++) == '*') {
83 max= va_arg(argp, int);
84 c= *fmt++;
85 } else
86 if (isdigit(c)) {
87 max= 0;
88 do {
89 max= max * 10 + (c - '0');
90 } while (isdigit(c= *fmt++));
91 }
92 }
93
94 /* Set a few flags to the default. */
95 x2c= x2c_tab;
96 i= 0;
97 base= 10;
98 intsize= INT;
99 if (c == 'l' || c == 'L') {
100 /* "Long" key, e.g. %ld. */
101 intsize= LONG;
102 c= *fmt++;
103 }
104 if (c == 0) break;
105
106 switch (c) {
107 /* Decimal. */
108 case 'd':
109 i= intsize == LONG ? va_arg(argp, long)
110 : va_arg(argp, int);
111 u= i < 0 ? -i : i;
112 goto int2ascii;
113
114 /* Octal. */
115 case 'o':
116 base= 010;
117 goto getint;
118
119 /* Pointer, interpret as %X or %lX. */
120 case 'p':
121 if (sizeof(char *) > sizeof(int)) intsize= LONG;
122
123 /* Hexadecimal. %X prints upper case A-F, not %lx. */
124 case 'X':
125 x2c= X2C_tab;
126 case 'x':
127 base= 0x10;
128 goto getint;
129
130 /* Unsigned decimal. */
131 case 'u':
132 getint:
133 u= intsize == LONG ? va_arg(argp, unsigned long)
134 : va_arg(argp, unsigned int);
135 int2ascii:
136 p= temp + sizeof(temp)-1;
137 *p= 0;
138 do {
139 *--p= x2c[(ptrdiff_t) (u % base)];
140 } while ((u /= base) > 0);
141 goto string_length;
142
143 /* A character. */
144 case 'c':
145 p= temp;
146 *p= va_arg(argp, int);
147 len= 1;
148 goto string_print;
149
150 /* Simply a percent. */
151 case '%':
152 p= temp;
153 *p= '%';
154 len= 1;
155 goto string_print;
156
157 /* A string. The other cases will join in here. */
158 case 's':
159 p= va_arg(argp, char *);
160
161 string_length:
162 for (len= 0; p[len] != 0 && len < max; len++) {}
163
164 string_print:
165 width -= len;
166 if (i < 0) width--;
167 if (fill == '0' && i < 0) count_kputc('-');
168 if (adjust == RIGHT) {
169 while (width > 0) { count_kputc(fill); width--; }
170 }
171 if (fill == ' ' && i < 0) count_kputc('-');
172 while (len > 0) { count_kputc((unsigned char) *p++); len--; }
173 while (width > 0) { count_kputc(fill); width--; }
174 break;
175
176 /* Unrecognized format key, echo it back. */
177 default:
178 count_kputc('%');
179 count_kputc(c);
180 }
181 }
182
183 /* Mark the end with a null (should be something else, like -1). */
184 kputc(0);
185 va_end(argp);
186 return charcount;
187}
188
189/*
190 * $PchId: kprintf.c,v 1.5 1996/04/11 06:59:05 philip Exp $
191 */
Note: See TracBrowser for help on using the repository browser.