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