/* linker: debug.o */
#include <assert.h>
-#include <getopt.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
//#define BUFFERSIZE 4096
#define BUFFERSIZE 256
#define NBCOLS 8
+#define NBDIGITS 6
/* gobal variables */
-char *buffer[BUFFERSIZE] = {0};
+int nbcols = NBCOLS;
+int nbdigits = NBDIGITS;
+int offset = 1;
+
+char buffer[BUFFERSIZE] = {0};
FILE *fin = NULL;
+int addrfile = 0;
FILE *fout = NULL;
char *progname = NULL;
/* help function */
-void usage (int ret)
+int usage (int ret)
{
FILE *fd = ret ? stderr : stdout;
fprintf (fd, "usage: %s [-i file] [-h] [-n nbcols] [-o file] [-v]\n", progname);
fprintf (fd, " p : print nb bytes (- until end file)\n");
fprintf (fd, " s : substitute h1 by h2 (g for globally)\n");
- exit (ret);
+ return ret;
}
/* get number of digits */
/* print a line */
-void printline (char *buffer, int nbcols, int nb, int addr, int nbdigits) {
+void printline (char *buffer, int nb, int addr) {
int i;
printf ("0x%0*x:", nbdigits, addr);
return 1;
}
+/* search sequence function */
+
+int searchseq (char *seq) {
+ char *pt = buffer;
+ int nb = 0;
+ int i, j;
+ int valid = 0;
+ int len = strlen (seq);
+
+ VERBOSE (DEBUG, printf ("search sequence: %s\n", seq));
+
+ while (!feof (fin)) {
+ int nbread = fread (pt, 1, BUFFERSIZE - (pt - buffer), fin);
+ nb += nbread;
+ pt = buffer;
+ for (i = 0; i < nb - len; i++) {
+ valid = 1;
+ for (j = 0; (j < len) && (valid); j++) {
+ if (pt[i + j] != seq[j]) {
+ valid = 0;
+ }
+ }
+ if (valid) {
+ break;
+ }
+ }
+
+ if (!valid) {
+ writefile (buffer, nb - len);
+ offset = 0;
+ addrfile += nb - len;
+ for (i = 0; i < len; i++) {
+ buffer[i] = buffer[nb - len + i];
+ }
+ pt = buffer + len;
+ nb = len;
+ } else {
+ writefile (buffer, i);
+ offset = len;
+ addrfile += i;
+ fseek (fin, i - nb, SEEK_CUR);
+ VERBOSE (DEBUG, printf ("found sequence (%d)\n", i - nb));
+ return 0;
+ }
+ }
+
+ if (!valid) {
+ writefile (buffer, nb);
+ addrfile += len;
+ }
+
+ return 1;
+}
+
/* hexadecimal dump function */
-int hexdump (int nbcols, int len) {
+int hexdump (int len) {
char buffer[BUFFERSIZE] = {0};
int i;
char *pt = buffer;
- /* get file size */
- int nbdigits = 0;
- if (fin != stdin) {
- fseek (fin, 0 , SEEK_END);
- long int filesize = ftell (fin);
- fseek (fin, 0 , SEEK_SET);
- nbdigits = getnbdigits (filesize);
- } else {
- nbdigits = 6;
- }
-
- int addr = 0;
int nb = 0;
while (!feof (fin)) {
int nbtoread = BUFFERSIZE - (pt - buffer);
/* print line */
while ((nb - (int)(pt - buffer)) / nbcols > 0) {
- printline (pt, nbcols, nbcols, addr, nbdigits);
+ printline (pt, nbcols, addrfile);
writefile (pt, nbcols);
+ addrfile += nbcols;
pt += nbcols;
- addr += nbcols;
}
/* copy end buffer */
/* last line */
if (nb > 0) {
- printline (buffer, nbcols, nb, addr, nbdigits);
- writefile (pt, nb);
+ printline (buffer, nb, addrfile);
+ writefile (buffer, nb);
+ addrfile += nb;
}
return 0;
}
+/* special character function */
+
+char *specialchar (char *s) {
+ int i = 0, j = 0;
+ while (s[i] != 0) {
+ if (s[i] != '\\') {
+ s[j++] = s[i++];
+ continue;
+ }
+
+ int l = 0;
+ switch (s[i + 1]) {
+ case 'a': l = 0x07; i += 2; break;
+ case 'b': l = 0x08; i += 2; break;
+ case 'e': l = 0x1b; i += 2; break;
+ case 'f': l = 0x0c; i += 2; break;
+ case 'n': l = 0x0a; i += 2; break;
+ case 'r': l = 0x0d; i += 2; break;
+ case 't': l = 0x09; i += 2; break;
+ case 'v': l = 0x0b; i += 2; break;
+ case '\\': l = '\\'; i += 2; break;
+ case '\'': l = '\''; i += 2; break;
+ case '"': l = '"'; i += 2; break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ if ((s[i + 2] >= '0') && (s[i + 2] <= '9') &&
+ (s[i + 3] >= '0') && (s[i + 3] <= '9')) {
+ l = (s[i + 1] - '0') * 8 * 8 + (s[i + 2] - '0') * 8 + s[i + 3] - '0';
+ i += 4;
+ }
+ break;
+ case 'x':
+ if ((((s[i + 2] >= '0') && (s[i + 2] <= '9')) ||
+ ((s[i + 2] >= 'A') && (s[i + 2] <= 'F')) ||
+ ((s[i + 2] >= 'a') && (s[i + 2] <= 'f'))) &&
+ (((s[i + 3] >= '0') && (s[i + 3] <= '9')) ||
+ ((s[i + 3] >= 'A') && (s[i + 3] <= 'F')) ||
+ ((s[i + 3] >= 'a') && (s[i + 3] <= 'f')))) {
+ l = s[i + 2] - '0';
+ if (s[i + 2] >= 'a') {
+ l += '0' + 10 - 'a';
+ } else if (s[i + 2] >= 'A') {
+ l += '0' + 10 - 'A';
+ }
+ l = l * 16 + s[i + 3] - '0';
+ if (s[i + 3] >= 'a') {
+ l += '0' + 10 - 'a';
+ } else if (s[i + 3] >= 'A') {
+ l += '0' + 10 - 'A';
+ }
+ i += 4;
+ }
+ break;
+ default:
+ }
+ VERBOSE (DEBUG, printf("l: 0x%02x '%c'\n", l, l));
+ s[j++] = (l != 0) ? l : s[i++];
+ }
+ s[j] = '\0';
+
+ return s;
+}
+
/* main function */
-int main (int argc, char *argv[])
+int main (int argc, char *argv[])
{
int rc = 0;
char *input = NULL;
char *output = NULL;
- int nbcols = NBCOLS;
char *commands = NULL;
int printlen = -1;
-
+ char *seq = NULL;
+ char *addr = NULL;
+
/* get basename */
char *pt = progname = argv[0];
while (*pt) {
pt++;
}
- int c;
- while ((c = getopt(argc, argv, "e:i:hn:o:v:")) != EOF) {
+ while (argc-- > 1) {
+ char *arg = *(++argv);
+ if (arg[0] != '-') {
+ VERBOSE (ERROR, fprintf (stderr, "%s: invalid option -- %s\n", progname, arg));
+ return usage (1);
+ }
+ char c = arg[1];
switch (c) {
- case 'i':
- input = optarg;
- break;
case 'e':
- if (commands == NULL) {
- commands = optarg;
- } else {
- strcat (commands, " ");
- strcat (commands, optarg);
+ arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
+ if (arg) {
+ arg = specialchar (arg);
+ if (commands == NULL) {
+ commands = arg;
+ } else {
+ strcat (commands, " ");
+ strcat (commands, arg);
+ }
}
break;
+ case 'i':
+ input = (arg[2]) ? arg + 2 : (--argc > 0 ) ? *(++argv) : NULL;
+ break;
case 'n':
- nbcols = atoi (optarg);
+ arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
+ if (arg == NULL) {
+ VERBOSE (ERROR, fprintf (stderr, "%s: missing number of columns\n", progname));
+ return usage (1);
+ }
+ nbcols = atoi (arg);
break;
case 'o':
- output = optarg;
+ output = (arg[2]) ? arg + 2 : (--argc > 0 ) ? *(++argv) : NULL;
break;
case 'v':
- verbose = atoi (optarg);
+ arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
+ if (arg == NULL) {
+ VERBOSE (ERROR, fprintf (stderr, "%s: missing verbose level\n", progname));
+ return usage (1);
+ }
+ verbose = atoi (arg);
break;
case 'h':
default:
- usage (c != 'h');
+ return usage (c != 'h');
}
}
- if (argc - optind != 0) {
- fprintf (stderr, "%s: invalid option -- %s\n", progname, argv[optind]);
- usage (1);
- }
/* check input */
if (input) {
//fout = stdout;
}
+ /* get file size */
+ if (fin != stdin) {
+ fseek (fin, 0 , SEEK_END);
+ long int filesize = ftell (fin);
+ fseek (fin, 0 , SEEK_SET);
+ nbdigits = getnbdigits (filesize);
+ }
+
if (commands == NULL) {
- hexdump (nbcols, -1);
+ hexdump (-1);
} else {
VERBOSE (DEBUG, printf ("commands: %s\n", commands));
while ((*commands != '\0') && (rc == 0)) {
break;
case '/': /* read patern */
+ seq = commands;
+ while (*commands) {
+ if (*commands == '/') {
+ *commands++ = 0;
+ break;
+ }
+ commands++;
+ }
+ if (*seq != 0) {
+ rc = searchseq (seq);
+ } else {
+ VERBOSE (ERROR, fprintf (stderr, "no sequence definied\n"));
+ rc = 1;
+ }
break;
case '0': /* read address */
break;
}
}
- if (rc == 0) hexdump (nbcols, printlen);
+ if (rc == 0) {
+ hexdump (printlen);
+ }
break;
case 's': /* substitute mode */
return rc;
}
-// test: hexdump.exe -h
// test: hexdump.exe -h | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
// test: hexdump.exe -_ 2> /dev/null | awk 'END { if (NR == 0) { exit(0) } else exit (1) }'
// test: hexdump.exe -_ 2>&1 | awk '/usage:/ { rc=1 } END { exit (1-rc) }'
// test: hexdump.exe -i hexdump.c -o test.c -e 'p 200' | tail -1 | grep -q '0x00c0:'
// test: cmp hexdump.c test.c
// test: rm test.c
+// test: hexdump.exe -i hexdump.c -e ' /cflags/ p 16 /debug/ p 8' | grep -q '0x0019: 2a 2f 0a 2f 2a 20 6c 69 \*/\./\* li'
+// test: hexdump.exe -i hexdump.c -o test.c -e ' /cflags/ p 16 /debug/ p 8' | grep -q '0x0027: 64 65 62 75 67 2e 6f 20 debug.o'
+// test: cmp hexdump.c test.c
+// test: rm test.c
/* vim: set ts=4 sw=4 et: */