a6dddd91841c9d1d069b8dcc2ae33d2b1777c3a4
[chise/xemacs-chise.git] / lib-src / hexl.c
1 /* Synched up with: FSF 19.28. */
2
3 #include <config.h>
4
5 #include <stdio.h>
6 #include <ctype.h>
7 #ifdef WINDOWSNT
8 #include <io.h>
9 #include <fcntl.h>
10 #endif
11
12 #if __STDC__ || defined(STDC_HEADERS)
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <string.h>
16 #endif
17
18 #define DEFAULT_GROUPING        0x01
19 #define DEFAULT_BASE            16
20
21 #undef TRUE
22 #undef FALSE
23 #define TRUE  (1)
24 #define FALSE (0)
25
26 int base = DEFAULT_BASE, un_flag = FALSE, iso_flag = FALSE, endian = 1;
27 int group_by = DEFAULT_GROUPING;
28 char *progname;
29
30 void usage (void);
31
32 int
33 main (int argc, char *argv[])
34 {
35   register long address;
36   char string[18];
37   FILE *fp;
38   
39   progname = *argv++; --argc;
40   
41   /*
42   ** -hex               hex dump
43   ** -oct               Octal dump
44   ** -group-by-8-bits
45   ** -group-by-16-bits
46   ** -group-by-32-bits
47   ** -group-by-64-bits
48   ** -iso               iso character set.
49   ** -big-endian        Big Endian
50   ** -little-endian     Little Endian
51   ** -un || -de from hexl format to binary.
52   ** --         End switch list.
53   ** <filename> dump filename
54   ** -          (as filename == stdin)
55   */
56     
57   while (*argv && *argv[0] == '-' && (*argv)[1])
58     {
59       /* A switch! */
60       if (!strcmp (*argv, "--"))
61         {
62           --argc; argv++;
63           break;
64         }
65       else if (!strcmp (*argv, "-un") || !strcmp (*argv, "-de"))
66         {
67           un_flag = TRUE;
68           --argc; argv++;
69         }
70       else if (!strcmp (*argv, "-hex"))
71         {
72           base = 16;
73           --argc; argv++;
74         }
75       else if (!strcmp (*argv, "-iso"))
76         {
77           iso_flag = TRUE;
78           --argc; argv++;
79         }
80       else if (!strcmp (*argv, "-oct"))
81         {
82           base = 8;
83           --argc; argv++;
84         }
85       else if (!strcmp (*argv, "-big-endian"))
86         {
87           endian = 1;
88           --argc; argv++;
89         }
90       else if (!strcmp (*argv, "-little-endian"))
91         {
92           endian = 0;
93           --argc; argv++;
94         }
95       else if (!strcmp (*argv, "-group-by-8-bits"))
96         {
97           group_by = 0x00;
98           --argc; argv++;
99         }
100       else if (!strcmp (*argv, "-group-by-16-bits"))
101         {
102           group_by = 0x01;
103           --argc; argv++;
104         }
105       else if (!strcmp (*argv, "-group-by-32-bits"))
106         {
107           group_by = 0x03;
108           --argc; argv++;
109         }
110       else if (!strcmp (*argv, "-group-by-64-bits"))
111         {
112           group_by = 0x07;
113           endian = 0;
114           --argc; argv++;
115         }
116       else
117         {
118           (void) fprintf (stderr, "%s: invalid switch: \"%s\".\n", progname,
119                    *argv);
120           usage ();
121         }
122     }
123
124   do
125     {
126       if (*argv == NULL)
127         fp = stdin;
128       else
129         {
130           char *filename = *argv++;
131
132           if (!strcmp (filename, "-"))
133             fp = stdin;
134           else if ((fp = fopen (filename, "r")) == NULL)
135             {
136               perror (filename);
137               continue;
138             }
139         }
140
141       if (un_flag)
142         {
143           char buf[18];
144
145 #ifdef WINDOWSNT
146           _setmode (_fileno (stdout), O_BINARY);
147 #endif
148           for (;;)
149             {
150               register int i, c, d;
151
152 #define hexchar(x) (isdigit (x) ? x - '0' : x - 'a' + 10)
153
154               fread (buf, 1, 10, fp); /* skip 10 bytes */
155
156               for (i=0; i < 16; ++i)
157                 {
158                   if ((c = getc (fp)) == ' ' || c == EOF)
159                     break;
160
161                   d = getc (fp);
162                   c = hexchar (c) * 0x10 + hexchar (d);
163                   putchar (c);
164
165                   if ((i&group_by) == group_by)
166                     getc (fp);
167                 }
168
169               if (c == ' ')
170                 {
171                   while ((c = getc (fp)) != '\n' && c != EOF)
172                     ;
173
174                   if (c == EOF)
175                     break;
176                 }
177               else
178                 {
179                   if (i < 16)
180                     break;
181
182                   fread (buf, 1, 18, fp); /* skip 18 bytes */
183                 }
184             }
185         }
186       else
187         {
188 #ifdef WINDOWSNT
189           _setmode (_fileno (fp), O_BINARY);
190 #endif
191           address = 0;
192           string[0] = ' ';
193           string[17] = '\0';
194           for (;;)
195             {
196               register int i, c;
197
198               for (i=0; i < 16; ++i)
199                 {
200                   if ((c = getc (fp)) == EOF)
201                     {
202                       if (!i)
203                         break;
204
205                       fputs ("  ", stdout);
206                       string[i+1] = '\0';
207                     }
208                   else
209                     {
210                       if (!i)
211                         (void) printf ("%08lx: ", address);
212
213                       if (iso_flag)
214                         string[i+1] =
215                           (c < 0x20 || (c >= 0x7F && c < 0xa0)) ? '.' :c;
216                       else
217                         string[i+1] = (c < 0x20 || c >= 0x7F) ? '.' : c;
218
219                       (void) printf ("%02x", c);
220                     }
221
222                   if ((i&group_by) == group_by)
223                     putchar (' ');
224                 }
225
226               if (i)
227                 puts (string);
228
229               if (c == EOF)
230                 break;
231
232               address += 0x10;
233
234             }
235         }
236
237       if (fp != stdin)
238         (void) fclose (fp);
239
240     } while (*argv != NULL);
241   return 0;
242 }
243
244 void
245 usage ()
246 {
247   (void) fprintf (stderr, "usage: %s [-de] [-iso]\n", progname);
248   exit (1);
249 }