best makefile
[hexdump.git] / hexdump.c
CommitLineData
a1ab98f9
LM
1/* depend: */
2/* cflags: */
3/* linker: debug.o */
4
5#include <assert.h>
0304c8cc 6#include <limits.h>
a1ab98f9
LM
7#include <malloc.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include "debug.h"
13
14/* macros */
15
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))
19
20//#define BUFFERSIZE 4096
21#define BUFFERSIZE 256
22#define NBCOLS 8
4c4a10dd 23#define NBDIGITS 6
5bcbfcca 24#define SEQLEN 32
a1ab98f9
LM
25
26/* gobal variables */
27
4c4a10dd
LM
28int nbcols = NBCOLS;
29int nbdigits = NBDIGITS;
9e439809 30int offset = 0;
4c4a10dd
LM
31
32char buffer[BUFFERSIZE] = {0};
ce305529 33FILE *fin = NULL;
0304c8cc 34long int addrfile = 0;
ce305529 35FILE *fout = NULL;
a1ab98f9
LM
36char *progname = NULL;
37
5bcbfcca
LM
38/* type definitions */
39
40typedef struct {
41 char *sequence;
42 char bytes[SEQLEN];
43 int length;
44} sequence_t;
45
a1ab98f9
LM
46/* help function */
47
4c4a10dd 48int usage (int ret)
a1ab98f9
LM
49{
50 FILE *fd = ret ? stderr : stdout;
51 fprintf (fd, "usage: %s [-i file] [-h] [-n nbcols] [-o file] [-v]\n", progname);
5272fae8
LM
52 fprintf (fd, " -i: input file\n");
53 fprintf (fd, " -h: help message\n");
54 fprintf (fd, " -n: number of columns\n");
55 fprintf (fd, " -e: commands\n");
56 fprintf (fd, " -o: output file\n");
57 fprintf (fd, " -v: verbose level (%d)\n", verbose);
58 fprintf (fd, "\n");
0304c8cc 59 fprintf (fd, "commands: [/hstr/|addr|+nb] [a hstr] [d nb|-] [i hstr] [p nb|-] [s/h1/h2/[g]]\n");
cc02a838 60 fprintf (fd, " addr: move to address (0... octal, [1-9]... deci, 0x... hexa)\n");
0304c8cc 61 fprintf (fd, " +nb: move to offset (0... octal, [1-9]... deci, 0x... hexa)\n");
40c51071 62 fprintf (fd, " //: move to hexa string hstr\n");
5272fae8
LM
63 fprintf (fd, " a : append hexa string hstr to current address\n");
64 fprintf (fd, " d : delete nb bytes (- until end file)\n");
65 fprintf (fd, " i : insert hexa string hstr to current address\n");
66 fprintf (fd, " p : print nb bytes (- until end file)\n");
67 fprintf (fd, " s : substitute h1 by h2 (g for globally)\n");
a1ab98f9 68
4c4a10dd 69 return ret;
a1ab98f9
LM
70}
71
72/* get number of digits */
73
cc02a838 74unsigned int getnbdigits (unsigned long int l) {
a1ab98f9
LM
75 int n = 0;
76 while (l) {
77 n += 2;
78 l /= 256;
79 }
80 return n;
81}
82
83/* print a line */
84
1291ede6 85void printline (char *buffer, int nb, unsigned long int addr) {
a1ab98f9
LM
86 int i;
87
1291ede6 88 printf ("0x%0*lx:", nbdigits, addr);
a1ab98f9 89 for (i = 0; i < nb; i++) {
60e280f7 90 printf (" %02x", (unsigned char)buffer[i]);
a1ab98f9
LM
91 }
92 for (i = nb; i < nbcols; i++) {
93 printf (" ");
94 }
95 printf (" ");
96 for (i = 0; i < nb; i++) {
97 char c = buffer[i];
98 printf ("%c", (c > 31) && (c < 127) ? c : '.');
99 }
100 printf ("\n");
101}
102
ce305529 103/* write file function */
a1ab98f9 104
ce305529
LM
105int writefile (char *pt, int nb) {
106 if (fout) {
107 fwrite (pt, 1, nb, fout);
108 }
109 return 1;
110}
111
4c4a10dd
LM
112/* search sequence function */
113
5bcbfcca 114int searchseq (sequence_t *seq) {
4c4a10dd
LM
115 char *pt = buffer;
116 int nb = 0;
117 int i, j;
118 int valid = 0;
4c4a10dd 119
5bcbfcca 120 VERBOSE (DEBUG, printf ("search sequence: %s\n", seq->sequence));
4c4a10dd
LM
121
122 while (!feof (fin)) {
123 int nbread = fread (pt, 1, BUFFERSIZE - (pt - buffer), fin);
124 nb += nbread;
125 pt = buffer;
5bcbfcca 126 for (i = 0; i < nb - seq->length; i++) {
4c4a10dd 127 valid = 1;
5bcbfcca
LM
128 for (j = 0; (j < seq->length) && (valid); j++) {
129 if (pt[i + j] != seq->bytes[j]) {
4c4a10dd
LM
130 valid = 0;
131 }
132 }
133 if (valid) {
134 break;
135 }
136 }
137
138 if (!valid) {
5bcbfcca 139 writefile (buffer, nb - seq->length);
4c4a10dd 140 offset = 0;
5bcbfcca
LM
141 addrfile += nb - seq->length;
142 for (i = 0; i < seq->length; i++) {
143 buffer[i] = buffer[nb - seq->length + i];
4c4a10dd 144 }
5bcbfcca
LM
145 pt = buffer + seq->length;
146 nb = seq->length;
4c4a10dd
LM
147 } else {
148 writefile (buffer, i);
5bcbfcca 149 offset = seq->length;
4c4a10dd
LM
150 addrfile += i;
151 fseek (fin, i - nb, SEEK_CUR);
1286d873 152 VERBOSE (DEBUG, printf ("found sequence at 0x%0*lx\n", getnbdigits (addrfile), addrfile));
4c4a10dd
LM
153 return 0;
154 }
155 }
156
157 if (!valid) {
158 writefile (buffer, nb);
5bcbfcca 159 addrfile += seq->length;
4c4a10dd
LM
160 }
161
162 return 1;
163}
164
cc02a838
LM
165/* go to address function */
166
0304c8cc 167int gotoaddr (long int addr) {
cc02a838
LM
168 char buffer[BUFFERSIZE] = {0};
169
0304c8cc
LM
170 if (addr == -1) {
171 addr = LONG_MAX;
172 } else if (addrfile > addr) {
cc02a838
LM
173 return 1;
174 }
175
176 VERBOSE (DEBUG, printf ("look for address: 0x%04lx\n", addr));
177 while (!feof (fin)) {
178 int nbtoread = (addrfile + BUFFERSIZE > addr) ? addr - addrfile : BUFFERSIZE;
179 int nbread = fread (buffer, 1, nbtoread, fin);
180 writefile (buffer, nbread);
181 addrfile += nbread;
182 if (addrfile == addr) {
183 return 0;
184 }
185 }
186
187 return 1;
188}
189
9e439809
LM
190/* insert sequence function */
191
192int insertseq (sequence_t *seq) {
193 char buffer[BUFFERSIZE] = {0};
194
195 VERBOSE (DEBUG, printf ("insert (%d): '%s'\n", offset, seq->sequence);
196 int i;
197 for (i = 0; i < seq->length; i++) {
198 char c = seq->bytes[i];
199 printf (" 0x%02x (%c)", c, ((c >= 32) && (c < 127)) ? c : '.');
200 };
201 printf ("\n"));
202 if (offset > 0) {
203 int nbread = fread (buffer, 1, offset, fin);
204 if (nbread != offset) {
205 return 1;
206 }
207 writefile (buffer, offset);
208 offset = 0;
209 }
210 writefile (seq->bytes, seq->length);
211
212 return 0;
213}
214
ce305529
LM
215/* hexadecimal dump function */
216
4c4a10dd 217int hexdump (int len) {
a1ab98f9
LM
218 char buffer[BUFFERSIZE] = {0};
219 int i;
220
221 char *pt = buffer;
222
a1ab98f9
LM
223 int nb = 0;
224 while (!feof (fin)) {
5272fae8
LM
225 int nbtoread = BUFFERSIZE - (pt - buffer);
226 if ((len > 0) && (nbtoread > len)) {
227 nbtoread = len;
228 }
229 int nbread = fread (pt, 1, nbtoread, fin);
230 if (len > 0) {
231 len -= nbread;
232 }
233 nb += nbread;
a1ab98f9
LM
234 pt = buffer;
235
236 /* print line */
237 while ((nb - (int)(pt - buffer)) / nbcols > 0) {
4c4a10dd 238 printline (pt, nbcols, addrfile);
ce305529 239 writefile (pt, nbcols);
4c4a10dd 240 addrfile += nbcols;
a1ab98f9 241 pt += nbcols;
a1ab98f9
LM
242 }
243
244 /* copy end buffer */
245 nb -= pt - buffer;
246 for (i = 0; i < nb; i++) {
247 buffer[i] = pt[i];
248 }
249 pt = buffer + nb;
5272fae8
LM
250
251 /* end partial reading */
252 if (len == 0) {
253 break;
254 }
a1ab98f9
LM
255 }
256
257 /* last line */
258 if (nb > 0) {
4c4a10dd
LM
259 printline (buffer, nb, addrfile);
260 writefile (buffer, nb);
261 addrfile += nb;
a1ab98f9
LM
262 }
263
264 return 0;
265}
266
47db4fc7
LM
267/* parse octal string */
268
9e439809 269long int octal (char *s, int n) {
47db4fc7 270 int i;
cc02a838 271 unsigned long int l = 0;
47db4fc7
LM
272 for (i = 0; i < n; i++) {
273 if ((s[i] >= '0') && (s[i] <= '9')) {
274 l = l * 8 + s[i] - '0';
275 } else {
276 return -1;
277 }
278 }
279 return l;
280}
281
282/* parse hexa string */
283
9e439809 284long int hexa (char *s, int n) {
47db4fc7 285 int i;
cc02a838 286 unsigned long int l = 0;
47db4fc7
LM
287 for (i = 0; i < n; i++) {
288 l *= 16;
289 if ((s[i] >= '0') && (s[i] <= '9')) {
290 l += s[i] - '0';
291 } else if ((s[i] >= 'A') && (s[i] <= 'F')) {
292 l += s[i] + 10 - 'A';
293 } else if ((s[i] >= 'a') && (s[i] <= 'f')) {
294 l += s[i] + 10 - 'a';
295 } else {
296 return -1;
297 }
298 }
299 return l;
300}
301
4c4a10dd
LM
302/* special character function */
303
5bcbfcca 304int specialchar (char *s, char *b) {
4c4a10dd
LM
305 int i = 0, j = 0;
306 while (s[i] != 0) {
5bcbfcca
LM
307 if (j == SEQLEN) {
308 return 0;
309 }
4c4a10dd 310 if (s[i] != '\\') {
5bcbfcca 311 b[j++] = s[i++];
4c4a10dd
LM
312 continue;
313 }
314
47db4fc7 315 int l = -1;
4c4a10dd
LM
316 switch (s[i + 1]) {
317 case 'a': l = 0x07; i += 2; break;
318 case 'b': l = 0x08; i += 2; break;
319 case 'e': l = 0x1b; i += 2; break;
320 case 'f': l = 0x0c; i += 2; break;
321 case 'n': l = 0x0a; i += 2; break;
322 case 'r': l = 0x0d; i += 2; break;
323 case 't': l = 0x09; i += 2; break;
324 case 'v': l = 0x0b; i += 2; break;
f975557c 325 case '/': l = '/'; i += 2; break;
4c4a10dd
LM
326 case '\\': l = '\\'; i += 2; break;
327 case '\'': l = '\''; i += 2; break;
328 case '"': l = '"'; i += 2; break;
329 case '0':
330 case '1':
331 case '2':
332 case '3':
5bcbfcca 333 l = octal (s + i + 1, 3);
47db4fc7 334 if (l != -1) {
4c4a10dd
LM
335 i += 4;
336 }
337 break;
338 case 'x':
5bcbfcca 339 l = hexa (s + i + 2, 2);
47db4fc7 340 if (l != -1) {
4c4a10dd
LM
341 i += 4;
342 }
343 break;
344 default:
cc02a838 345 break;
4c4a10dd 346 }
5bcbfcca
LM
347 if (l != -1) {
348 VERBOSE (DEBUG, printf("l: 0x%02x '%c'\n", l, l));
349 }
350 b[j++] = (l != -1) ? l : s[i++];
4c4a10dd 351 }
4c4a10dd 352
5bcbfcca 353 return j;
4c4a10dd
LM
354}
355
1291ede6
LM
356/* remove space function */
357
358void removespace (char *s, char **p) {
359 while (*s) {
360 if ((*s == ' ') || (*s == '\t')) {
361 s++;
362 } else {
363 break;
364 }
365 }
366 if (p != NULL) {
367 *p = s;
368 }
369}
370
371/* get pattern function */
372
373int getpattern (sequence_t *seq, char *s, char **p) {
374
375 seq->sequence = s;
376 seq->length = 0;
377
378 while (*s) {
379 if ((*s == '\\') && ((s[1] == '/') || (s[1] == '\\'))) {
380 s++;
381 } else if (*s == '/') {
382 *s++ = 0;
383 break;
384 }
385 s++;
386 }
387 seq->length = specialchar (seq->sequence, seq->bytes);
388
389 if (p != NULL) {
390 *p = s;
391 }
392
393 return (seq->length == 0);
394}
395
396/* get hexa sequence function */
397
398int gethexaseq (sequence_t *seq, char *s, char **p) {
399 int i = 0;
400
401 seq->sequence = s;
402 seq->length = 0;
403
404 while (*s) {
405 if (((*s >= '0') && (*s <= '9')) ||
406 ((*s >= 'A') && (*s <= 'F')) ||
407 ((*s >= 'a') && (*s <= 'f'))) {
408 s++;
409 i++;
410 if (i % 2 == 0) {
411 seq->bytes[seq->length] = hexa (seq->sequence + 2 * seq->length, 2);
412 if (seq->bytes[seq->length] == -1) {
413 return 1;
414 }
415 seq->length++;
416 }
417 } else {
418 break;
419 }
420 }
421
422 if (p != NULL) {
423 *p = s;
424 }
425
426 return (seq->length == 0) || (i % 2 == 1);
427}
428
429/* get length function */
430
431long int getlength (char *s, char **p) {
432
433 while (*s != '\0') {
434 if ((*s == ' ') || (*s == '\t')) {
435 s++;
436 } else if ((*s >= '0') && (*s <= '9')) {
437 return strtol (s, p, 10);
438 } else if (*s == '-') {
439 if (p != NULL) {
440 *p = s + 1;
441 }
442 return -1;
443 } else {
444 VERBOSE (ERROR, fprintf (stderr, "unknown length (%s)\n", s));
445 return 0;
446 }
447 }
448
449 return 0;
450}
451
a1ab98f9
LM
452/* main function */
453
4c4a10dd 454int main (int argc, char *argv[])
a1ab98f9 455{
1291ede6 456 int rc = 0;
a1ab98f9
LM
457 char *input = NULL;
458 char *output = NULL;
5272fae8 459 char *commands = NULL;
0304c8cc 460 long int length = -1;
5bcbfcca 461 sequence_t seq = {0};
1291ede6 462 unsigned long int addr = 0;
6429544e 463 char c;
4c4a10dd 464
a1ab98f9
LM
465 /* get basename */
466 char *pt = progname = argv[0];
467 while (*pt) {
468 if ((*pt == '/') || (*pt == '\\')) {
469 progname = pt + 1;
470 }
471 pt++;
472 }
473
4c4a10dd
LM
474 while (argc-- > 1) {
475 char *arg = *(++argv);
476 if (arg[0] != '-') {
477 VERBOSE (ERROR, fprintf (stderr, "%s: invalid option -- %s\n", progname, arg));
478 return usage (1);
479 }
480 char c = arg[1];
a1ab98f9 481 switch (c) {
5272fae8 482 case 'e':
4c4a10dd
LM
483 arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
484 if (arg) {
40c51071
LM
485 //commands = (commands == NULL) ? arg :
486 // strcat (strcat (commands, " "), arg);
487 if (commands == NULL) {
488 commands = arg;
489 } else {
490 char *tmp = (char *) malloc (strlen (arg) + 1);
491 strcat (strcat (commands, " "), strcpy (tmp, arg));
492 free (tmp);
493 }
5272fae8
LM
494 }
495 break;
4c4a10dd
LM
496 case 'i':
497 input = (arg[2]) ? arg + 2 : (--argc > 0 ) ? *(++argv) : NULL;
498 break;
a1ab98f9 499 case 'n':
4c4a10dd
LM
500 arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
501 if (arg == NULL) {
502 VERBOSE (ERROR, fprintf (stderr, "%s: missing number of columns\n", progname));
503 return usage (1);
504 }
505 nbcols = atoi (arg);
a1ab98f9
LM
506 break;
507 case 'o':
4c4a10dd 508 output = (arg[2]) ? arg + 2 : (--argc > 0 ) ? *(++argv) : NULL;
a1ab98f9
LM
509 break;
510 case 'v':
4c4a10dd
LM
511 arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
512 if (arg == NULL) {
513 VERBOSE (ERROR, fprintf (stderr, "%s: missing verbose level\n", progname));
514 return usage (1);
515 }
516 verbose = atoi (arg);
a1ab98f9
LM
517 break;
518 case 'h':
519 default:
4c4a10dd 520 return usage (c != 'h');
a1ab98f9
LM
521 }
522 }
a1ab98f9
LM
523
524 /* check input */
a1ab98f9
LM
525 if (input) {
526 fin = fopen (input, "rb");
527 if (!fin) {
528 VERBOSE (ERROR, fprintf (stderr, "error: can't open file '%s'\n", input));
5272fae8 529 return 1;
a1ab98f9
LM
530 }
531 } else {
532 fin = stdin;
533 }
534
535 /* check output */
a1ab98f9 536 if (output) {
ce305529 537 fout = fopen (output, "wb");
a1ab98f9
LM
538 if (!fout) {
539 VERBOSE (ERROR, fprintf (stderr, "error: can't open file '%s'\n", output));
540 fclose (fin);
5272fae8 541 return 1;
a1ab98f9
LM
542 }
543 } else {
ce305529 544 //fout = stdout;
a1ab98f9
LM
545 }
546
4c4a10dd
LM
547 /* get file size */
548 if (fin != stdin) {
549 fseek (fin, 0 , SEEK_END);
cc02a838 550 unsigned long int filesize = ftell (fin);
4c4a10dd
LM
551 fseek (fin, 0 , SEEK_SET);
552 nbdigits = getnbdigits (filesize);
553 }
554
5272fae8 555 if (commands == NULL) {
3bf29ac6 556 VERBOSE (DEBUG, printf ("no command\n"));
4c4a10dd 557 hexdump (-1);
5272fae8
LM
558 } else {
559 VERBOSE (DEBUG, printf ("commands: %s\n", commands));
560 while ((*commands != '\0') && (rc == 0)) {
6429544e 561 switch (c = *commands++) {
5272fae8
LM
562 case ' ':
563 case '\t':
564 break;
565
1291ede6
LM
566 case '/': /* search pattern */
567 rc = getpattern (&seq, commands, &commands);
568 if (rc == 0) {
5bcbfcca 569 rc = searchseq (&seq);
1291ede6
LM
570 if (rc == 1) {
571 VERBOSE (ERROR, fprintf (stderr, "can't find pattern '%s'\n", seq.sequence));
572 }
4c4a10dd 573 } else {
1291ede6 574 VERBOSE (ERROR, fprintf (stderr, "erroneous pattern '%s'\n", seq.sequence));
4c4a10dd 575 }
5272fae8
LM
576 break;
577
578 case '0': /* read address */
cc02a838
LM
579 if (*commands == 'x') {
580 commands++;
581 addr = strtol (commands, &commands, 16);
582 } else {
583 addr = strtol (commands, &commands, 8);
584 }
585 if (addr) {
586 rc = gotoaddr (addr);
1291ede6
LM
587 if (rc == 1) {
588 VERBOSE (ERROR, fprintf (stderr, "can't find address (0x%0*lx)\n", getnbdigits (addr), addr));
589 }
cc02a838
LM
590 } else {
591 VERBOSE (ERROR, fprintf (stderr, "erroneous address\n"));
9e439809 592 rc = 1;
cc02a838 593 }
0304c8cc 594 offset = 0;
cc02a838
LM
595 break;
596
597 case '1':
598 case '2':
599 case '3':
600 case '4':
601 case '5':
602 case '6':
603 case '7':
604 case '8':
605 case '9': /* read address */
606 commands--;
607 addr = strtol (commands, &commands, 10);
3bf29ac6 608 rc = gotoaddr (addr);
1291ede6
LM
609 if (rc == 1) {
610 VERBOSE (ERROR, fprintf (stderr, "can't find address (0x%0*lx)\n", getnbdigits (addr), addr));
611 }
0304c8cc 612 offset = 0;
5272fae8
LM
613 break;
614
615 case 'a': /* append mode */
9e439809
LM
616 offset = 0;
617 /* fall through */
5272fae8 618
9e439809 619 case 'i': /* insert mode */
1291ede6
LM
620 removespace (commands, &commands);
621 rc = gethexaseq (&seq, commands, &commands);
622 if (rc == 0) {
9e439809 623 rc = insertseq (&seq);
1286d873
ML
624 if (rc == 1) {
625 VERBOSE (ERROR, fprintf (stderr, "can't jump (%d)\n", offset));
626 }
9e439809
LM
627 } else {
628 VERBOSE (ERROR, fprintf (stderr, "erroneous sequence '%s'\n", seq.sequence));
9e439809 629 }
0304c8cc 630 offset = 0;
5272fae8
LM
631 break;
632
0304c8cc
LM
633 case '+': /* relative move */
634 /* fall through */
635
9e439809 636 case 'd': /* delete mode */
6429544e 637 /* fall through */
5272fae8
LM
638
639 case 'p': /* print mode */
1291ede6
LM
640 length = getlength (commands, &commands);
641 if (length == 0){
642 VERBOSE (ERROR, fprintf (stderr, "erroneous length\n"));
643 rc = 1;
644 } else {
6429544e 645 switch (c) {
0304c8cc
LM
646 case '+':
647 rc = gotoaddr ((length > 0) ? addrfile + length : -1);
1291ede6
LM
648 if (rc == 1) {
649 VERBOSE (ERROR, fprintf (stderr, "can't find address (0x%0*lx)\n", getnbdigits (addr), addr));
650 }
0304c8cc
LM
651 break;
652
6429544e
LM
653 case 'd':
654 fseek (fin, length, SEEK_CUR);
655 break;
0304c8cc 656
6429544e
LM
657 case 'p':
658 hexdump (length);
659 break;
660 }
4c4a10dd 661 }
0304c8cc 662 offset = 0;
5272fae8
LM
663 break;
664
665 case 's': /* substitute mode */
1291ede6 666 if (*commands == '/') {
1286d873 667 rc = getpattern (&seq, ++commands, &commands);
1291ede6
LM
668 if (rc == 0) {
669 rc = searchseq (&seq);
670 if (rc == 0) {
671 fseek (fin, offset, SEEK_CUR);
672 rc = gethexaseq (&seq, commands, &commands);
1286d873 673 commands++;
1291ede6 674 if (rc == 0) {
1286d873 675 offset = 0;
1291ede6 676 rc = insertseq (&seq);
1286d873
ML
677 if (rc == 1) {
678 VERBOSE (ERROR, fprintf (stderr, "can't jump (%d)\n", offset));
679 }
1291ede6
LM
680 } else {
681 VERBOSE (ERROR, fprintf (stderr, "erroneous sequence '%s'\n", seq.sequence));
682 }
683 } else {
684 VERBOSE (ERROR, fprintf (stderr, "can't find pattern '%s'\n", seq.sequence));
685 }
686 } else {
687 VERBOSE (ERROR, fprintf (stderr, "erroneous pattern '%s'\n", seq.sequence));
688 }
1286d873
ML
689 } else {
690 VERBOSE (ERROR, fprintf (stderr, "erroneous sequence '%s'\n", seq.sequence));
691 rc = 1;
1291ede6 692 }
0304c8cc 693 offset = 0;
5272fae8
LM
694 break;
695
696 default:
1291ede6 697 VERBOSE (ERROR, fprintf (stderr, "unknown command '%c'\n", commands[-1]));
5272fae8
LM
698 rc = 1;
699 }
700 }
701 }
a1ab98f9 702
ce305529
LM
703 /* end of file */
704 if ((rc == 0) && (fout != NULL)) {
705 while (!feof (fin)) {
706 int nbread = fread (buffer, 1, BUFFERSIZE, fin);
707 if (nbread) {
708 fwrite (buffer, 1, nbread, fout);
709 }
710 }
711 }
712
a1ab98f9 713 /* close all */
5272fae8
LM
714 if (fin) fclose (fin);
715 if (fout) fclose (fout);
a1ab98f9 716
5272fae8 717 return rc;
a1ab98f9
LM
718}
719
a1ab98f9 720// test: hexdump.exe -h | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
f975557c
LM
721// test: hexdump.exe foo 2>&1 | grep -q 'invalid option'
722// test: hexdump.exe -n 2>&1 | grep -q 'missing number of columns'
723// test: hexdump.exe -v 2>&1 | grep -q 'missing verbose level'
a1ab98f9
LM
724// test: hexdump.exe -_ 2> /dev/null | awk 'END { if (NR == 0) { exit(0) } else exit (1) }'
725// test: hexdump.exe -_ 2>&1 | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
726// test: hexdump.exe -i hexdump.c | grep -q '0x[0-9a-f]*: '
f975557c
LM
727// test: hexdump.exe -i hexdump.ko 2>&1 | grep -q "can't open file"
728// test: hexdump.exe -i hexdump.c -o ko/test.c 2>&1 | grep -q "can't open file"
729// test: cat hexdump.c | hexdump.exe -n 3 | head -2 | tail -1 | grep -q '0x000003: 64 65 70 dep'
ce305529 730// test: hexdump.exe -i hexdump.c -n 3 | head -2 | tail -1 | grep -q '0x0003: 64 65 70 dep'
1286d873 731// test: hexdump.exe -i hexdump.c -v 3 -n 8 | grep -q 'no command'
ce305529 732// test: hexdump.exe -i hexdump.c -o test.c -e 'p 200' | tail -1 | grep -q '0x00c0:'
5bcbfcca 733// test: cmp hexdump.c test.c; x=$?; rm test.c; test x$x = x0
1286d873 734// test: hexdump.exe -i hexdump.c -n 8 -e ' /cflags/ p 17 /debug/ p 8' | grep -q '0x0019: 2a 2f 0a 2f 2a 20 6c 69 \*\/\./\* li'
5bcbfcca
LM
735// test: hexdump.exe -i hexdump.c -o test.c -e ' /cfl\x61gs/ p 16 /d\145bug/ p 8' | grep -q '0x0027: 64 65 62 75 67 2e 6f 20 debug.o'
736// test: cmp hexdump.c test.c; x=$?; rm test.c; test x$x = x0
737// test: hexdump.exe -i hexdump.c -e ' /\n/ p 8' | grep -q '0x000d: 0a 2f 2a 20 63 66 6c 61 \./\* cfla'
738// test: hexdump.exe -i hexdump.c -o test.c -e ' /\a\b\e\f\r\t\v/ p 8'; x=$?; test x$x = x1
739// test: cmp hexdump.c test.c; x=$?; rm test.c; test x$x = x0
1291ede6 740// test: hexdump.exe -i hexdump.c -v 3 -e " /\'/" -e ' /\"/' -e ' /\\/' -e ' /\x2a/' -e ' /\x3A/' | grep l: | wc -l | xargs test 5 =
f975557c 741// test: hexdump.exe -i hexdump.c -e ' /\n\/* vim:/ p -' | grep -q ': 74 3a 20 2a 2f 0a *t: \*\/\.'
6429544e 742// test: hexdump.exe -i hexdump.c -e 'p go_to_end' 2>&1 | grep -q 'unknown length'
1286d873 743// test: hexdump.exe -i hexdump.c -e ' /\x41BCD/' 2>&1 | grep -q "can't find pattern"
1291ede6 744// test: hexdump.exe -i hexdump.c -e ' //' 2>&1 | grep -q 'erroneous pattern'
f975557c 745// test: hexdump.exe -i hexdump.c -e 'foo' 2>&1 | grep -q 'unknown command'
cc02a838 746// test: hexdump.exe -i hexdump.c -e '0x20 p 8 64 p 8 0200 p 16' | grep -q '0x0080:'
1286d873
ML
747// test: hexdump.exe -i hexdump.c -e '07777777' 2>&1 | grep -q "can't find address"
748// test: hexdump.exe -i hexdump.c -e '0xFFFFFF' 2>&1 | grep -q "can't find address"
749// test: hexdump.exe -i hexdump.c -e '99999999' 2>&1 | grep -q "can't find address"
750// test: hexdump.exe -i hexdump.c -e '+9999999' 2>&1 | grep -q "can't find address"
3bf29ac6
LM
751// test: hexdump.exe -i hexdump.c -e '0xg' 2>&1 | grep -q 'erroneous address'
752// test: hexdump.exe -i hexdump.c -o test.c -e ' /cflags/ a 414e5a /link/ i 2F333B'
1286d873
ML
753// test: grep -q '[A]NZcflags' test.c && grep -q '[l]ink/3;er' test.c; x=$?; rm test.c; test x$x = x0
754// test: hexdump.exe -i hexdump.c -e ' /cflags/ a 414e5' 2>&1 | grep -q 'erroneous sequence'
6429544e 755// test: hexdump.exe -i hexdump.c -o test.c -e ' /lags/ d 2'
1286d873 756// test: grep -q '[c]fgs' test.c; x=$?; rm test.c; test x$x = x0
0304c8cc 757// test: hexdump.exe -i hexdump.c -o test.c -e ' /lags/ +2 i 2041'
1286d873
ML
758// test: grep -q '[c]fla Ags:' test.c; x=$?; rm test.c; test x$x = x0
759// test: hexdump.exe -i hexdump.c -o test.c -e ' s/lags/2041/'
760// test: grep -q '[c]f A:' test.c; x=$?; rm test.c; test x$x = x0
761// test: hexdump.exe -i hexdump.c -e ' s' 2>&1 | grep -q 'erroneous sequence'
762// test: hexdump.exe -i hexdump.c -e ' s//' 2>&1 | grep -q 'erroneous pattern'
763// test: hexdump.exe -i hexdump.c -e ' s/\x41BCD/2041/' 2>&1 | grep -q "can't find pattern"
764// test: hexdump.exe -i hexdump.c -e ' s/cflags/414e5/' 2>&1 | grep -q 'erroneous sequence'
60e280f7 765// test: hexdump.exe -i hexdump.exe | grep -q 'ffff'; test x$? = x1
a1ab98f9
LM
766
767/* vim: set ts=4 sw=4 et: */