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