]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/disk/kfs/print.c
fix real cause of iso name truncation
[plan9front.git] / sys / src / cmd / disk / kfs / print.c
1 #include        "all.h"
2
3 #define PTR     sizeof(char*)
4 #define SHORT   sizeof(int)
5 #define INT     sizeof(int)
6 #define LONG    sizeof(long)
7 #define IDIGIT  30
8 #define MAXCON  30
9
10 static  int     convcount  = { 10 };
11
12 #define PUT(o, c)       if((o)->p < (o)->ep) *(o)->p++ = c
13
14 static  int     noconv(Op*);
15 static  int     cconv(Op*);
16 static  int     dconv(Op*);
17 static  int     hconv(Op*);
18 static  int     lconv(Op*);
19 static  int     oconv(Op*);
20 static  int     sconv(Op*);
21 static  int     uconv(Op*);
22 static  int     xconv(Op*);
23 static  int     percent(Op*);
24
25 static
26 int     (*fmtconv[MAXCON])(Op*) =
27 {
28         noconv,
29         cconv, dconv, hconv, lconv,
30         oconv, sconv, uconv, xconv,
31         percent,
32 };
33 static
34 char    fmtindex[128] =
35 {
36         ['c'] 1,
37         ['d'] 2,
38         ['h'] 3,
39         ['l'] 4,
40         ['o'] 5,
41         ['s'] 6,
42         ['u'] 7,
43         ['x'] 8,
44         ['%'] 9,
45 };
46
47 int
48 fmtinstall(char c, int (*f)(Op*))
49 {
50
51         c &= 0177;
52         if(fmtindex[c] == 0) {
53                 if(convcount >= MAXCON)
54                         return 1;
55                 fmtindex[c] = convcount++;
56         }
57         fmtconv[fmtindex[c]] = f;
58         return 0;
59 }
60
61 char*
62 doprint(char *p, char *ep, char *fmt, void *argp)
63 {
64         int sf1, c;
65         Op o;
66
67         o.p = p;
68         o.ep = ep;
69         o.argp = argp;
70
71 loop:
72         c = *fmt++;
73         if(c != '%') {
74                 if(c == 0) {
75                         if(o.p < o.ep)
76                                 *o.p = 0;
77                         return o.p;
78                 }
79                 PUT(&o, c);
80                 goto loop;
81         }
82         o.f1 = 0;
83         o.f2 = -1;
84         o.f3 = 0;
85         c = *fmt++;
86         sf1 = 0;
87         if(c == '-') {
88                 sf1 = 1;
89                 c = *fmt++;
90         }
91         while(c >= '0' && c <= '9') {
92                 o.f1 = o.f1*10 + c-'0';
93                 c = *fmt++;
94         }
95         if(sf1)
96                 o.f1 = -o.f1;
97         if(c != '.')
98                 goto l1;
99         c = *fmt++;
100         while(c >= '0' && c <= '9') {
101                 if(o.f2 < 0)
102                         o.f2 = 0;
103                 o.f2 = o.f2*10 + c-'0';
104                 c = *fmt++;
105         }
106 l1:
107         if(c == 0)
108                 fmt--;
109         c = (*fmtconv[fmtindex[c&0177]])(&o);
110         if(c < 0) {
111                 o.f3 |= -c;
112                 c = *fmt++;
113                 goto l1;
114         }
115         o.argp = (char*)o.argp + c;
116         goto loop;
117 }
118
119 int
120 numbconv(Op *op, int base)
121 {
122         char b[IDIGIT];
123         int i, f, n, r;
124         long v;
125         short h;
126
127         f = 0;
128         switch(op->f3 & (FLONG|FSHORT|FUNSIGN)) {
129         case FLONG:
130                 v = *(long*)op->argp;
131                 r = LONG;
132                 break;
133
134         case FUNSIGN|FLONG:
135                 v = *(ulong*)op->argp;
136                 r = LONG;
137                 break;
138
139         case FSHORT:
140                 h = *(int*)op->argp;
141                 v = h;
142                 r = SHORT;
143                 break;
144
145         case FUNSIGN|FSHORT:
146                 h = *(int*)op->argp;
147                 v = (ushort)h;
148                 r = SHORT;
149                 break;
150
151         default:
152                 v = *(int*)op->argp;
153                 r = INT;
154                 break;
155
156         case FUNSIGN:
157                 v = *(unsigned*)op->argp;
158                 r = INT;
159                 break;
160         }
161         if(!(op->f3 & FUNSIGN) && v < 0) {
162                 v = -v;
163                 f = 1;
164         }
165         b[IDIGIT-1] = 0;
166         for(i = IDIGIT-2;; i--) {
167                 n = (ulong)v % base;
168                 n += '0';
169                 if(n > '9')
170                         n += 'a' - ('9'+1);
171                 b[i] = n;
172                 if(i < 2)
173                         break;
174                 v = (ulong)v / base;
175                 if(op->f2 >= 0 && i >= IDIGIT-op->f2)
176                         continue;
177                 if(v <= 0)
178                         break;
179         }
180 sout:
181         if(f)
182                 b[--i] = '-';
183         strconv(b+i, op, op->f1, -1);
184         return r;
185 }
186
187 void
188 strconv(char *o, Op *op, int f1, int f2)
189 {
190         int n, c;
191         char *p;
192
193         n = strlen(o);
194         if(f1 >= 0)
195                 while(n < f1) {
196                         PUT(op, ' ');
197                         n++;
198                 }
199         for(p=o; c = *p++;)
200                 if(f2 != 0) {
201                         PUT(op, c);
202                         f2--;
203                 }
204         if(f1 < 0) {
205                 f1 = -f1;
206                 while(n < f1) {
207                         PUT(op, ' ');
208                         n++;
209                 }
210         }
211 }
212
213 static  int
214 noconv(Op *op)
215 {
216
217         strconv("***", op, 0, -1);
218         return 0;
219 }
220
221 static  int
222 cconv(Op *op)
223 {
224         char b[2];
225
226         b[0] = *(int*)op->argp;
227         b[1] = 0;
228         strconv(b, op, op->f1, -1);
229         return INT;
230 }
231
232 static  int
233 dconv(Op *op)
234 {
235
236         return numbconv(op, 10);
237 }
238
239 static  int
240 hconv(Op *op)
241 {
242         USED(op);
243         return -FSHORT;
244 }
245
246 static  int
247 lconv(Op *op)
248 {
249         USED(op);
250         return -FLONG;
251 }
252
253 static  int
254 oconv(Op *op)
255 {
256         USED(op);
257         return numbconv(op, 8);
258 }
259
260 static  int
261 sconv(Op *op)
262 {
263
264         strconv(*(char**)op->argp, op, op->f1, op->f2);
265         return PTR;
266 }
267
268 static  int
269 uconv(Op *op)
270 {
271         USED(op);
272         return -FUNSIGN;
273 }
274
275 static  int
276 xconv(Op *op)
277 {
278
279         return numbconv(op, 16);
280 }
281
282 static  int
283 percent(Op *op)
284 {
285
286         PUT(op, '%');
287         return 0;
288 }