]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/xd.c
9bootfat: rename open() to fileinit and make it static as its really a internal funct...
[plan9front.git] / sys / src / cmd / xd.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4
5 unsigned char   odata[16];
6 unsigned char   data[16];
7 int             ndata;
8 unsigned long   addr;
9 int             repeats;
10 int             swizzle;
11 int             flush;
12 int             abase=2;
13 int             xd(char *, int);
14 void            xprint(char *, ...);
15 void            initarg(void), swizz(void);
16 enum{
17         Narg=10
18 };
19 typedef struct Arg Arg;
20 typedef void fmtfn(char *);
21 struct Arg
22 {
23         int     ascii;          /* 0==none, 1==ascii */
24         int     loglen;         /* 0==1, 1==2, 2==4, 3==8 */
25         int     base;           /* 0==8, 1==10, 2==16 */
26         fmtfn   *fn;            /* function to call with data */
27         char    *afmt;          /* format to use to print address */
28         char    *fmt;           /* format to use to print data */
29 }arg[Narg];
30 int     narg;
31
32 fmtfn   fmt0, fmt1, fmt2, fmt3, fmtc;
33 fmtfn *fmt[4] = {
34         fmt0,
35         fmt1,
36         fmt2,
37         fmt3
38 };
39
40 char *dfmt[4][3] = {
41         " %.3uo",       " %.3ud",       " %.2ux",
42         " %.6uo",       " %.5ud",       " %.4ux",
43         " %.11luo",     " %.10lud",     " %.8lux",
44         " %.22lluo",    " %.20llud",    " %.16llux",
45 };
46
47 char *cfmt[3][3] = {
48         "   %c",        "   %c",        "  %c",
49         " %.3s",        " %.3s",        " %.2s",
50         " %.3uo",       " %.3ud",       " %.2ux",
51 };
52
53 char *afmt[2][3] = {
54         "%.7luo ",      "%.7lud ",      "%.7lux ",
55         "%7luo ",       "%7lud ",       "%7lux ",
56 };
57
58 Biobuf  bin;
59 Biobuf  bout;
60
61 void
62 main(int argc, char *argv[])
63 {
64         int i, err;
65         Arg *ap;
66
67         Binit(&bout, 1, OWRITE);
68         err = 0;
69         ap = 0;
70         while(argc>1 && argv[1][0]=='-' && argv[1][1]){
71                 --argc;
72                 argv++;
73                 argv[0]++;
74                 if(argv[0][0] == 'r'){
75                         repeats = 1;
76                         if(argv[0][1])
77                                 goto Usage;
78                         continue;
79                 }
80                 if(argv[0][0] == 's'){
81                         swizzle = 1;
82                         if(argv[0][1])
83                                 goto Usage;
84                         continue;
85                 }
86                 if(argv[0][0] == 'u'){
87                         flush = 1;
88                         if(argv[0][1])
89                                 goto Usage;
90                         continue;
91                 }
92                 if(argv[0][0] == 'a'){
93                         argv[0]++;
94                         switch(argv[0][0]){
95                         case 'o':
96                                 abase = 0;
97                                 break;
98                         case 'd':
99                                 abase = 1;
100                                 break;
101                         case 'x':
102                                 abase = 2;
103                                 break;
104                         default:
105                                 goto Usage;
106                         }
107                         if(argv[0][1])
108                                 goto Usage;
109                         continue;
110                 }
111                 ap = &arg[narg];
112                 initarg();
113                 while(argv[0][0]){
114                         switch(argv[0][0]){
115                         case 'c':
116                                 ap->ascii = 1;
117                                 ap->loglen = 0;
118                                 if(argv[0][1] || argv[0][-1]!='-')
119                                         goto Usage;
120                                 break;
121                         case 'o':
122                                 ap->base = 0;
123                                 break;
124                         case 'd':
125                                 ap->base = 1;
126                                 break;
127                         case 'x':
128                                 ap->base = 2;
129                                 break;
130                         case 'b':
131                         case '1':
132                                 ap->loglen = 0;
133                                 break;
134                         case 'w':
135                         case '2':
136                                 ap->loglen = 1;
137                                 break;
138                         case 'l':
139                         case '4':
140                                 ap->loglen = 2;
141                                 break;
142                         case 'v':
143                         case '8':
144                                 ap->loglen = 3;
145                                 break;
146                         default:
147                         Usage:
148    fprint(2, "usage: xd [-u] [-r] [-s] [-a{odx}] [-c|{b1w2l4v8}{odx}] ... file ...\n");
149                                 exits("usage");
150                         }
151                         argv[0]++;
152                 }
153                 if(ap->ascii)
154                         ap->fn = fmtc;
155                 else
156                         ap->fn = fmt[ap->loglen];
157                 ap->fmt = dfmt[ap->loglen][ap->base];
158                 ap->afmt = afmt[ap>arg][abase];
159         }
160         if(narg == 0)
161                 initarg();
162         if(argc == 1)
163                 err = xd(0, 0);
164         else if(argc == 2)
165                 err = xd(argv[1], 0);
166         else for(i=1; i<argc; i++)
167                 err |= xd(argv[i], 1);
168         exits(err? "error" : 0);
169 }
170
171 void
172 initarg(void)
173 {
174         Arg *ap;
175
176         ap = &arg[narg++];
177         if(narg >= Narg){
178                 fprint(2, "xd: too many formats (max %d)\n", Narg);
179                 exits("usage");
180         }
181         ap->ascii = 0;
182         ap->loglen = 2;
183         ap->base = 2;
184         ap->fn = fmt2;
185         ap->fmt = dfmt[ap->loglen][ap->base];
186         ap->afmt = afmt[narg>1][abase];
187 }
188
189 int
190 xd(char *name, int title)
191 {
192         int fd;
193         int i, star;
194         Arg *ap;
195         Biobuf *bp;
196
197         fd = 0;
198         if(name){
199                 bp = Bopen(name, OREAD);
200                 if(bp == 0){
201                         fprint(2, "xd: can't open %s\n", name);
202                         return 1;
203                 }
204         }else{
205                 bp = &bin;
206                 Binit(bp, fd, OREAD);
207         }
208         if(title)
209                 xprint("%s\n", name);
210         addr = 0;
211         star = 0;
212         while((ndata=Bread(bp, data, 16)) >= 0){
213                 if(ndata < 16)
214                         for(i=ndata; i<16; i++)
215                                 data[i] = 0;
216                 if(swizzle)
217                         swizz();
218                 if(ndata==16 && repeats){
219                         if(addr>0 && data[0]==odata[0]){
220                                 for(i=1; i<16; i++)
221                                         if(data[i] != odata[i])
222                                                 break;
223                                 if(i == 16){
224                                         addr += 16;
225                                         if(star == 0){
226                                                 star++;
227                                                 xprint("*\n", 0);
228                                         }
229                                         continue;
230                                 }
231                         }
232                         for(i=0; i<16; i++)
233                                 odata[i] = data[i];
234                         star = 0;
235                 }
236                 for(ap=arg; ap<&arg[narg]; ap++){
237                         xprint(ap->afmt, addr);
238                         (*ap->fn)(ap->fmt);
239                         xprint("\n", 0);
240                         if(flush)
241                                 Bflush(&bout);
242                 }
243                 addr += ndata;
244                 if(ndata<16){
245                         xprint(afmt[0][abase], addr);
246                         xprint("\n", 0);
247                         if(flush)
248                                 Bflush(&bout);
249                         break;
250                 }
251         }
252         Bterm(bp);
253         return 0;
254 }
255
256 void
257 swizz(void)
258 {
259         uchar *p, *q;
260         int i;
261         uchar swdata[16];
262
263         p = data;
264         q = swdata;
265         for(i=0; i<16; i++)
266                 *q++ = *p++;
267         p = data;
268         q = swdata;
269         for(i=0; i<4; i++){
270                 p[0] = q[3];
271                 p[1] = q[2];
272                 p[2] = q[1];
273                 p[3] = q[0];
274                 p += 4;
275                 q += 4;
276         }
277 }
278
279 void
280 fmt0(char *f)
281 {
282         int i;
283         for(i=0; i<ndata; i++)
284                 xprint(f, data[i]);
285 }
286
287 void
288 fmt1(char *f)
289 {
290         int i;
291         for(i=0; i<ndata; i+=sizeof(unsigned short))
292                 xprint(f, (data[i]<<8)|data[i+1]);
293 }
294
295 void
296 fmt2(char *f)
297 {
298         int i;
299         for(i=0; i<ndata; i+=sizeof(unsigned long))
300                 xprint(f, (data[i]<<24)|(data[i+1]<<16)|(data[i+2]<<8)|data[i+3]);
301 }
302
303 void
304 fmt3(char *f)
305 {
306         int i;
307         unsigned long long v;
308         for(i=0; i<ndata; i+=sizeof(unsigned long long)){
309                 v = (data[i]<<24)|(data[i+1]<<16)|(data[i+2]<<8)|data[i+3];
310                 v <<= 32;
311                 v |= (data[i+4]<<24)|(data[i+1+4]<<16)|(data[i+2+4]<<8)|data[i+3+4];
312                 if(Bprint(&bout, f, v)<0){
313                         fprint(2, "xd: i/o error\n");
314                         exits("i/o error");
315                 }
316         }
317 }
318
319 void
320 fmtc(char *f)
321 {
322         int i;
323
324         USED(f);
325         for(i=0; i<ndata; i++)
326                 switch(data[i]){
327                 case '\t':
328                         xprint(cfmt[1][2], "\\t");
329                         break;
330                 case '\r':
331                         xprint(cfmt[1][2], "\\r");
332                         break;
333                 case '\n':
334                         xprint(cfmt[1][2], "\\n");
335                         break;
336                 case '\b':
337                         xprint(cfmt[1][2], "\\b");
338                         break;
339                 default:
340                         if(data[i]>=0x7F || ' '>data[i])
341                                 xprint(cfmt[2][2], data[i]);
342                         else
343                                 xprint(cfmt[0][2], data[i]);
344                         break;
345                 }
346 }
347
348 void
349 xprint(char *fmt, ...)
350 {
351         va_list arglist;
352
353         va_start(arglist, fmt);
354         if(Bvprint(&bout, fmt, arglist)<0){
355                 fprint(2, "xd: i/o error\n");
356                 exits("i/o error");
357         }
358         va_end(arglist);
359 }