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