This source file includes following definitions.
- output_error
- hexchar
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <config.h>
23
24 #include <inttypes.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include <binary-io.h>
29 #include <unlocked-io.h>
30
31 static char *progname;
32
33 static _Noreturn void
34 output_error (void)
35 {
36 fprintf (stderr, "%s: write error\n", progname);
37 exit (EXIT_FAILURE);
38 }
39
40 static int
41 hexchar (int c)
42 {
43 return c - ('0' <= c && c <= '9' ? '0' : 'a' - 10);
44 }
45
46 int
47 main (int argc, char **argv)
48 {
49 int status = EXIT_SUCCESS;
50 int DEFAULT_GROUPING = 0x01;
51 int group_by = DEFAULT_GROUPING;
52 bool un_flag = false, iso_flag = false;
53 progname = *argv++;
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 for (; *argv && *argv[0] == '-' && (*argv)[1]; argv++)
69 {
70
71 if (!strcmp (*argv, "--"))
72 {
73 argv++;
74 break;
75 }
76 else if (!strcmp (*argv, "-un") || !strcmp (*argv, "-de"))
77 {
78 un_flag = true;
79 set_binary_mode (fileno (stdout), O_BINARY);
80 }
81 else if (!strcmp (*argv, "-hex"))
82 ;
83 else if (!strcmp (*argv, "-iso"))
84 iso_flag = true;
85 else if (!strcmp (*argv, "-group-by-8-bits"))
86 group_by = 0x00;
87 else if (!strcmp (*argv, "-group-by-16-bits"))
88 group_by = 0x01;
89 else if (!strcmp (*argv, "-group-by-32-bits"))
90 group_by = 0x03;
91 else if (!strcmp (*argv, "-group-by-64-bits"))
92 group_by = 0x07;
93 else
94 {
95 fprintf (stderr, "%s: invalid switch: \"%s\".\n", progname,
96 *argv);
97 fprintf (stderr, "usage: %s [-de] [-iso]\n", progname);
98 return EXIT_FAILURE;
99 }
100 }
101
102 char const *filename = *argv ? *argv++ : "-";
103
104 do
105 {
106 FILE *fp;
107
108 if (!strcmp (filename, "-"))
109 {
110 fp = stdin;
111 if (!un_flag)
112 set_binary_mode (fileno (stdin), O_BINARY);
113 }
114 else
115 {
116 fp = fopen (filename, un_flag ? "r" : "rb");
117 if (!fp)
118 {
119 perror (filename);
120 status = EXIT_FAILURE;
121 continue;
122 }
123 }
124
125 if (un_flag)
126 {
127 for (int c; 0 <= (c = getc (fp)); )
128 {
129
130 if (c != ' ')
131 continue;
132
133 for (int i = 0; i < 16; i++)
134 {
135 c = getc (fp);
136 if (c < 0 || c == ' ')
137 break;
138
139 int hc = hexchar (c);
140 c = getc (fp);
141 if (c < 0)
142 break;
143 putchar (hc * 0x10 + hexchar (c));
144
145 if ((i & group_by) == group_by)
146 {
147 c = getc (fp);
148 if (c < 0)
149 break;
150 }
151 }
152
153 while (0 <= c && c != '\n')
154 c = getc (fp);
155 if (c < 0)
156 break;
157 if (ferror (stdout))
158 output_error ();
159 }
160 }
161 else
162 {
163 int c = 0;
164 char string[18];
165 string[0] = ' ';
166 string[17] = '\0';
167 for (uintmax_t address = 0; 0 <= c; address += 0x10)
168 {
169 int i;
170 for (i = 0; i < 16; i++)
171 {
172 if (0 <= c)
173 c = getc (fp);
174 if (c < 0)
175 {
176 if (!i)
177 break;
178
179 fputs (" ", stdout);
180 string[i + 1] = '\0';
181 }
182 else
183 {
184 if (!i)
185 printf ("%08"PRIxMAX": ", address);
186
187 string[i + 1]
188 = (c < 0x20 || (0x7F <= c && (!iso_flag || c < 0xa0))
189 ? '.' : c);
190
191 printf ("%02x", c + 0u);
192 }
193
194 if ((i & group_by) == group_by)
195 putchar (' ');
196 }
197
198 if (i)
199 puts (string);
200
201 if (ferror (stdout))
202 output_error ();
203 }
204 }
205
206 bool trouble = ferror (fp) != 0;
207 trouble |= fp != stdin && fclose (fp) != 0;
208 if (trouble)
209 {
210 fprintf (stderr, "%s: read error\n", progname);
211 status = EXIT_FAILURE;
212 }
213
214 filename = *argv++;
215 }
216 while (filename);
217
218 if (ferror (stdout) || fclose (stdout) != 0)
219 output_error ();
220 return status;
221 }