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