XINU
fdoprnt.c
Go to the documentation of this file.
1 /* fdoprnt.c - _fdoprnt, _prtl2, _prtl8, _prtl10, _prtX16, _prtl16 */
2 
3 #include <stdarg.h>
4 
5 #define MAXSTR 80
6 #define NULL 0
7 
8 static void _prtl10(long num, char *str);
9 static void _prtl8(long num, char *str);
10 static void _prtX16(long num, char *str);
11 static void _prtl16(long num, char *str);
12 static void _prtl2(long num, char *str);
13 
14 /*------------------------------------------------------------------------
15  * _fdoprnt - Format and write output using 'func' to write characters.
16  * (Patched for Sun3 by Shawn Ostermann.)
17  * All arguments passed as 4 bytes, long==int.
18  *------------------------------------------------------------------------
19  */
20 void _fdoprnt(
21  char *fmt, /* format string */
22  va_list ap, /* ap list of values */
23  int (*func)(int, int), /* char output function */
24  int farg /* arg for char output */
25  )
26 {
27  int c;
28  int i;
29  int f; /* The format character (comes after %) */
30  char *str; /* Running pointer in string */
31  char string[20]; /* The string str points to this output */
32 
33  /* from number conversion */
34  int length; /* Length of string "str" */
35  char fill; /* Fill character (' ' or '0') */
36  int leftjust; /* 0 = right-justified, else left-just */
37  int fmax, fmin; /* Field specifications % MIN . MAX s */
38  int leading; /* No. of leading/trailing fill chars */
39  char sign; /* Set to '-' for negative decimals */
40  char digit1; /* Offset to add to first numeric digit */
41  long larg;
42 
43  for (;;)
44  {
45  /* Echo characters until '%' or end of fmt string */
46  while ((c = *fmt++) != '%')
47  {
48  if (c == '\0')
49  {
50  return;
51  }
52  (*func) (farg, c);
53  }
54  /* Echo "...%%..." as '%' */
55  if (*fmt == '%')
56  {
57  (*func) (farg, *fmt++);
58  continue;
59  }
60  /* Check for "%-..." == Left-justified output */
61  if ((leftjust = ((*fmt == '-')) ? 1 : 0))
62  {
63  fmt++;
64  }
65  /* Allow for zero-filled numeric outputs ("%0...") */
66  fill = (*fmt == '0') ? *fmt++ : ' ';
67  /* Allow for minimum field width specifier for %d,u,x,o,c,s */
68  /* Also allow %* for variable width (%0* as well) */
69  fmin = 0;
70  if (*fmt == '*')
71  {
72  fmin = va_arg(ap, int);
73 
74  ++fmt;
75  }
76  else
77  {
78  while ('0' <= *fmt && *fmt <= '9')
79  {
80  fmin = fmin * 10 + *fmt++ - '0';
81  }
82  }
83  /* Allow for maximum string width for %s */
84  fmax = 0;
85  if (*fmt == '.')
86  {
87  if (*(++fmt) == '*')
88  {
89  fmax = va_arg(ap, int);
90  ++fmt;
91  }
92  else
93  {
94  while ('0' <= *fmt && *fmt <= '9')
95  {
96  fmax = fmax * 10 + *fmt++ - '0';
97  }
98  }
99  }
100 
101  str = string;
102  if ((f = *fmt++) == '\0')
103  {
104  (*func) (farg, '%');
105  return;
106  }
107  sign = '\0'; /* sign == '-' for negative decimal */
108 
109  switch (f)
110  {
111  case 'c':
112  string[0] = va_arg(ap, int);
113  string[1] = '\0';
114  fmax = 0;
115  fill = ' ';
116  break;
117 
118  case 's':
119  str = va_arg(ap, char *);
120 
121  if (NULL == str)
122  {
123  str = "(null)";
124  }
125  fill = ' ';
126  break;
127 
128  case 'd':
129  larg = va_arg(ap, long);
130 
131  if (larg < 0)
132  {
133  sign = '-';
134  larg = -larg;
135  }
136  _prtl10(larg, str);
137  break;
138 
139  case 'u':
140  digit1 = '\0';
141  /* "negative" longs in unsigned format */
142  /* can't be computed with long division */
143  /* convert *args to "positive", digit1 */
144  /* = how much to add back afterwards */
145  larg = va_arg(ap, long);
146 
147  while (larg < 0)
148  {
149  larg -= 1000000000L;
150  ++digit1;
151  }
152  _prtl10(larg, str);
153  str[0] += digit1;
154  fmax = 0;
155  break;
156 
157  case 'o':
158  larg = va_arg(ap, long);
159 
160  _prtl8(larg, str);
161  fmax = 0;
162  break;
163 
164  case 'X':
165  larg = va_arg(ap, long);
166 
167  _prtX16(larg, str);
168  fmax = 0;
169  break;
170 
171  case 'x':
172  larg = va_arg(ap, long);
173 
174  _prtl16(larg, str);
175  fmax = 0;
176  break;
177 
178  case 'b':
179  larg = va_arg(ap, long);
180 
181  _prtl2(larg, str);
182  fmax = 0;
183  break;
184 
185  default:
186  (*func) (farg, f);
187  break;
188  }
189  for (length = 0; str[length] != '\0'; length++)
190  {;
191  }
192  if (fmin > MAXSTR || fmin < 0)
193  {
194  fmin = 0;
195  }
196  if (fmax > MAXSTR || fmax < 0)
197  {
198  fmax = 0;
199  }
200  leading = 0;
201  if (fmax != 0 || fmin != 0)
202  {
203  if (fmax != 0)
204  {
205  if (length > fmax)
206  {
207  length = fmax;
208  }
209  }
210  if (fmin != 0)
211  {
212  leading = fmin - length;
213  }
214  if (sign == '-')
215  {
216  --leading;
217  }
218  }
219  if (sign == '-' && fill == '0')
220  {
221  (*func) (farg, sign);
222  }
223  if (leftjust == 0)
224  {
225  for (i = 0; i < leading; i++)
226  {
227  (*func) (farg, fill);
228  }
229  }
230  if (sign == '-' && fill == ' ')
231  {
232  (*func) (farg, sign);
233  }
234  for (i = 0; i < length; i++)
235  {
236  (*func) (farg, str[i]);
237  }
238  if (leftjust != 0)
239  {
240  for (i = 0; i < leading; i++)
241  (*func) (farg, fill);
242  }
243  }
244 
245 }
246 
247 /*------------------------------------------------------------------------
248  * _prtl10 - Converts long to base 10 string.
249  *------------------------------------------------------------------------
250  */
251 static void _prtl10(
252  long num,
253  char *str
254  )
255 {
256  int i;
257  char temp[11];
258 
259  temp[0] = '\0';
260  for (i = 1; i <= 10; i++)
261  {
262  temp[i] = num % 10 + '0';
263  num /= 10;
264  }
265  for (i = 10; temp[i] == '0'; i--);
266  if (i == 0)
267  i++;
268  while (i >= 0)
269  *str++ = temp[i--];
270 }
271 
272 /*------------------------------------------------------------------------
273  * _prtl8 - Converts long to base 8 string.
274  *------------------------------------------------------------------------
275  */
276 static void _prtl8(
277  long num,
278  char *str
279  )
280 {
281  int i;
282  char temp[12];
283 
284  temp[0] = '\0';
285  for (i = 1; i <= 11; i++)
286  {
287  temp[i] = (num & 07) + '0';
288  num = num >> 3;
289  }
290  temp[11] &= '3';
291  for (i = 11; temp[i] == '0'; i--);
292  if (i == 0)
293  i++;
294  while (i >= 0)
295  *str++ = temp[i--];
296 }
297 
298 /*------------------------------------------------------------------------
299  * _prtl16 - Converts long to lowercase hex string.
300  *------------------------------------------------------------------------
301  */
302 static void _prtl16(
303  long num,
304  char *str
305  )
306 {
307  int i;
308  char temp[9];
309 
310  temp[0] = '\0';
311  for (i = 1; i <= 8; i++)
312  {
313  temp[i] = "0123456789abcdef"[num & 0x0F];
314  num = num >> 4;
315  }
316  for (i = 8; temp[i] == '0'; i--);
317  if (i == 0)
318  i++;
319  while (i >= 0)
320  *str++ = temp[i--];
321 }
322 
323 /*------------------------------------------------------------------------
324  * _prtX16 - Converts long to uppercase hex string.
325  *------------------------------------------------------------------------
326  */
327 static void _prtX16(
328  long num,
329  char *str
330  )
331 {
332  int i;
333  char temp[9];
334 
335  temp[0] = '\0';
336  for (i = 1; i <= 8; i++)
337  {
338  temp[i] = "0123456789ABCDEF"[num & 0x0F];
339  num = num >> 4;
340  }
341  for (i = 8; temp[i] == '0'; i--);
342  if (i == 0)
343  i++;
344  while (i >= 0)
345  *str++ = temp[i--];
346 }
347 
348 /*------------------------------------------------------------------------
349  * _prtl2 - Converts long to binary string.
350  *------------------------------------------------------------------------
351  */
352 static void _prtl2(
353  long num,
354  char *str
355  )
356 {
357  int i;
358  char temp[35];
359 
360  temp[0] = '\0';
361  for (i = 1; i <= 32; i++)
362  {
363  temp[i] = ((num % 2) == 0) ? '0' : '1';
364  num = num >> 1;
365  }
366  for (i = 32; temp[i] == '0'; i--);
367  if (i == 0)
368  i++;
369  while (i >= 0)
370  *str++ = temp[i--];
371 }
static void _prtl2(long num, char *str)
Definition: fdoprnt.c:352
static void _prtl10(long num, char *str)
Definition: fdoprnt.c:251
static void _prtX16(long num, char *str)
Definition: fdoprnt.c:327
static void _prtl16(long num, char *str)
Definition: fdoprnt.c:302
#define NULL
Definition: fdoprnt.c:6
void _fdoprnt(char *fmt, va_list ap, int(*func)(int, int), int farg)
Definition: fdoprnt.c:20
#define va_arg(va, type)
可変長引数の値を返し、次の引数へ進む。 「va_start()とva_end()の間」もしくは「va_copy()とva_end()の間...
Definition: stdarg.h:34
可変長引数を実現するための宣言およびマクロ
__builtin_va_list va_list
可変個の実引数を扱うための情報を保持するための型(__builtin_va_listはGCCに定義された型) ...
Definition: stdarg.h:7
static void _prtl8(long num, char *str)
Definition: fdoprnt.c:276
#define MAXSTR
Definition: fdoprnt.c:5