987434368174826baf62ce63c503ededbc366d33
16 #define CEIL(x, y) (((x) + (y) - 1) / (y))
17 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
18 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
20 //#define BUFFERSIZE 4096
21 #define BUFFERSIZE 256
26 char *progname
= NULL
;
32 FILE *fd
= ret
? stderr
: stdout
;
33 fprintf (fd
, "usage: %s [-i file] [-h] [-n nbcols] [-o file] [-v]\n", progname
);
34 fprintf (fd
, " -i: input file\n");
35 fprintf (fd
, " -h: help message\n");
36 fprintf (fd
, " -n: number of columns\n");
37 fprintf (fd
, " -e: commands\n");
38 fprintf (fd
, " -o: output file\n");
39 fprintf (fd
, " -v: verbose level (%d)\n", verbose
);
41 fprintf (fd
, "commands: [/hstr/|0xaddr] [a hstr] [d nb|-] [i hstr] [p nb|-] [s/h1/h2/[g]]\n");
42 fprintf (fd
, " 0x: move to address addr\n");
43 fprintf (fd
, " //: move to hexa stringi hstr\n");
44 fprintf (fd
, " a : append hexa string hstr to current address\n");
45 fprintf (fd
, " d : delete nb bytes (- until end file)\n");
46 fprintf (fd
, " i : insert hexa string hstr to current address\n");
47 fprintf (fd
, " p : print nb bytes (- until end file)\n");
48 fprintf (fd
, " s : substitute h1 by h2 (g for globally)\n");
53 /* get number of digits */
55 int getnbdigits (long int l
) {
66 void printline (char *buffer
, int nbcols
, int nb
, int addr
, int nbdigits
) {
69 printf ("0x%0*x:", nbdigits
, addr
);
70 for (i
= 0; i
< nb
; i
++) {
71 printf (" %02x", buffer
[i
]);
73 for (i
= nb
; i
< nbcols
; i
++) {
77 for (i
= 0; i
< nb
; i
++) {
79 printf ("%c", (c
> 31) && (c
< 127) ? c
: '.');
86 int hexdump (FILE *fin
, int nbcols
, int len
) {
87 char buffer
[BUFFERSIZE
] = {0};
95 fseek (fin
, 0 , SEEK_END
);
96 long int filesize
= ftell (fin
);
97 fseek (fin
, 0 , SEEK_SET
);
98 nbdigits
= getnbdigits (filesize
);
105 while (!feof (fin
)) {
106 int nbtoread
= BUFFERSIZE
- (pt
- buffer
);
107 if ((len
> 0) && (nbtoread
> len
)) {
110 int nbread
= fread (pt
, 1, nbtoread
, fin
);
118 while ((nb
- (int)(pt
- buffer
)) / nbcols
> 0) {
119 printline (pt
, nbcols
, nbcols
, addr
, nbdigits
);
124 /* copy end buffer */
126 for (i
= 0; i
< nb
; i
++) {
131 /* end partial reading */
139 printline (buffer
, nbcols
, nb
, addr
, nbdigits
);
147 int main (int argc
, char *argv
[])
153 char *commands
= NULL
;
157 char *pt
= progname
= argv
[0];
159 if ((*pt
== '/') || (*pt
== '\\')) {
166 while ((c
= getopt(argc
, argv
, "e:i:hn:o:v:")) != EOF
) {
172 if (commands
== NULL
) {
175 strcat (commands
, " ");
176 strcat (commands
, optarg
);
180 nbcols
= atoi (optarg
);
186 verbose
= atoi (optarg
);
193 if (argc
- optind
!= 0) {
194 fprintf (stderr
, "%s: invalid option -- %s\n", progname
, argv
[optind
]);
201 fin
= fopen (input
, "rb");
203 VERBOSE (ERROR
, fprintf (stderr
, "error: can't open file '%s'\n", input
));
213 fout
= fopen (input
, "wb");
215 VERBOSE (ERROR
, fprintf (stderr
, "error: can't open file '%s'\n", output
));
223 if (commands
== NULL
) {
224 hexdump (fin
, nbcols
, -1);
226 VERBOSE (DEBUG
, printf ("commands: %s\n", commands
));
227 while ((*commands
!= '\0') && (rc
== 0)) {
228 switch (*commands
++) {
233 case '/': /* read patern */
236 case '0': /* read address */
239 case 'a': /* append mode */
242 case 'd': /* delete mode */
245 case 'i': /* insert mode */
248 case 'p': /* print mode */
250 while (*commands
!= '\0') {
251 if ((*commands
== ' ') || (*commands
== '\t')) {
253 } else if ((*commands
>= '0') && (*commands
<= '9')) {
254 printlen
= strtol (commands
, &commands
, 10);
256 } else if (*commands
== '-') {
261 VERBOSE (ERROR
, fprintf (stderr
, "unkown print lenght (%s)\n", commands
));
266 if (rc
== 0) hexdump (fin
, nbcols
, printlen
);
269 case 's': /* substitute mode */
273 VERBOSE (ERROR
, fprintf (stderr
, "unknown command (%c)\n", commands
[-1]));
280 if (fin
) fclose (fin
);
281 if (fout
) fclose (fout
);
286 // test: hexdump.exe -h
287 // test: hexdump.exe -h | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
288 // test: hexdump.exe -_ 2> /dev/null | awk 'END { if (NR == 0) { exit(0) } else exit (1) }'
289 // test: hexdump.exe -_ 2>&1 | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
290 // test: hexdump.exe -i hexdump.c | grep -q '0x[0-9a-f]*: '
291 // test: hexdump.exe -i hexdump.c -n 3|head -2|tail -1| grep '0x0003: 64 65 70 dep'
293 /* vim: set ts=4 sw=4 et: */