Pristine Ack-5.5
[Ack-5.5.git] / modules / src / print / format.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5 /* $Id: format.c,v 1.9 1994/06/24 11:20:16 ceriel Exp $ */
6
7 #include <system.h>
8 #include "print.h"
9
10 extern char *long2str();
11
12 static int
13 integral(c)
14 {
15         switch (c) {
16         case 'b':
17                 return -2;
18         case 'd':
19                 return 10;
20         case 'o':
21                 return -8;
22         case 'u':
23                 return -10;
24         case 'x':
25                 return -16;
26         }
27         return 0;
28 }
29
30 /*FORMAT1 $
31         %s = char *
32         %l = long
33         %c = int
34         %[uxbo] = unsigned int
35         %d = int
36 $ */
37 int
38 _format(buf, fmt, argp)
39         char *buf, *fmt;
40         register va_list argp;
41 {
42         register char *pf = fmt;
43         register char *pb = buf;
44
45         while (*pf) {
46                 if (*pf == '%') {
47                         register width, base, pad, npad;
48                         char *arg;
49                         char cbuf[2];
50                         char *badformat = "<bad format>";
51                         
52                         /* get padder */
53                         if (*++pf == '0') {
54                                 pad = '0';
55                                 ++pf;
56                         }
57                         else
58                                 pad = ' ';
59                         
60                         /* get width */
61                         width = 0;
62                         while (*pf >= '0' && *pf <= '9')
63                                 width = 10 * width + *pf++ - '0';
64                         
65                         if (*pf == 's') {
66                                 arg = va_arg(argp, char *);
67                         }
68                         else
69                         if (*pf == 'c') {
70                                 cbuf[0] = va_arg(argp, int);
71                                 cbuf[1] = '\0';
72                                 arg = &cbuf[0];
73                         }
74                         else
75                         if (*pf == 'l') {
76                                 /* alignment ??? */
77                                 if (base = integral(*++pf)) {
78                                         arg = long2str(va_arg(argp,long), base);
79                                 }
80                                 else {
81                                         pf--;
82                                         arg = badformat;
83                                 }
84                         }
85                         else
86                         if (base = integral(*pf)) {
87                                 arg = long2str((long)va_arg(argp,int), base);
88                         }
89                         else
90                         if (*pf == '%')
91                                 arg = "%";
92                         else
93                                 arg = badformat;
94
95                         npad = width - strlen(arg);
96
97                         while (npad-- > 0)
98                                 *pb++ = pad;
99                         
100                         while (*pb++ = *arg++);
101                         pb--;
102                         pf++;
103                 }
104                 else
105                         *pb++ = *pf++;
106         }
107         return pb - buf;
108 }