/* print a line */
-void printline (char *buffer, int nb, int addr) {
+void printline (char *buffer, int nb, unsigned long int addr) {
int i;
- printf ("0x%0*x:", nbdigits, addr);
+ printf ("0x%0*lx:", nbdigits, addr);
for (i = 0; i < nb; i++) {
printf (" %02x", buffer[i]);
}
return j;
}
+/* remove space function */
+
+void removespace (char *s, char **p) {
+ while (*s) {
+ if ((*s == ' ') || (*s == '\t')) {
+ s++;
+ } else {
+ break;
+ }
+ }
+ if (p != NULL) {
+ *p = s;
+ }
+}
+
+/* get pattern function */
+
+int getpattern (sequence_t *seq, char *s, char **p) {
+
+ seq->sequence = s;
+ seq->length = 0;
+
+ while (*s) {
+ if ((*s == '\\') && ((s[1] == '/') || (s[1] == '\\'))) {
+ s++;
+ } else if (*s == '/') {
+ *s++ = 0;
+ break;
+ }
+ s++;
+ }
+ seq->length = specialchar (seq->sequence, seq->bytes);
+
+ if (p != NULL) {
+ *p = s;
+ }
+
+ return (seq->length == 0);
+}
+
+/* get hexa sequence function */
+
+int gethexaseq (sequence_t *seq, char *s, char **p) {
+ int i = 0;
+
+ seq->sequence = s;
+ seq->length = 0;
+
+ while (*s) {
+ if (((*s >= '0') && (*s <= '9')) ||
+ ((*s >= 'A') && (*s <= 'F')) ||
+ ((*s >= 'a') && (*s <= 'f'))) {
+ s++;
+ i++;
+ if (i % 2 == 0) {
+ seq->bytes[seq->length] = hexa (seq->sequence + 2 * seq->length, 2);
+ if (seq->bytes[seq->length] == -1) {
+ return 1;
+ }
+ seq->length++;
+ }
+ } else {
+ break;
+ }
+ }
+
+ if (p != NULL) {
+ *p = s;
+ }
+
+ return (seq->length == 0) || (i % 2 == 1);
+}
+
+/* get length function */
+
+long int getlength (char *s, char **p) {
+
+ while (*s != '\0') {
+ if ((*s == ' ') || (*s == '\t')) {
+ s++;
+ } else if ((*s >= '0') && (*s <= '9')) {
+ return strtol (s, p, 10);
+ } else if (*s == '-') {
+ if (p != NULL) {
+ *p = s + 1;
+ }
+ return -1;
+ } else {
+ VERBOSE (ERROR, fprintf (stderr, "unknown length (%s)\n", s));
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
/* main function */
int main (int argc, char *argv[])
{
- int i, rc = 0;
+ int rc = 0;
char *input = NULL;
char *output = NULL;
char *commands = NULL;
long int length = -1;
sequence_t seq = {0};
- long int addr = 0;
+ unsigned long int addr = 0;
char c;
/* get basename */
case 'e':
arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL;
if (arg) {
- if (commands == NULL) {
- commands = arg;
- } else {
- strcat (commands, " ");
- strcat (commands, arg);
- }
+ commands = (commands == NULL) ? arg :
+ strcat (strcat (commands, " "), arg);
}
break;
case 'i':
case '\t':
break;
- case '/': /* read patern */
- seq.sequence = commands;
- seq.length = 0;
- while (*commands) {
- if ((*commands == '\\') &&
- ((commands[1] == '/') || (commands[1] == '\\'))) {
- commands++;
- } else if (*commands == '/') {
- *commands++ = 0;
- break;
- }
- commands++;
- }
- seq.length = specialchar (seq.sequence, seq.bytes);
- if (seq.length != 0) {
+ case '/': /* search pattern */
+ rc = getpattern (&seq, commands, &commands);
+ if (rc == 0) {
rc = searchseq (&seq);
+ if (rc == 1) {
+ VERBOSE (ERROR, fprintf (stderr, "can't find pattern '%s'\n", seq.sequence));
+ }
} else {
- VERBOSE (ERROR, fprintf (stderr, "incorrect sequence (%s)\n", seq.sequence));
- rc = 1;
+ VERBOSE (ERROR, fprintf (stderr, "erroneous pattern '%s'\n", seq.sequence));
}
break;
}
if (addr) {
rc = gotoaddr (addr);
+ if (rc == 1) {
+ VERBOSE (ERROR, fprintf (stderr, "can't find address (0x%0*lx)\n", getnbdigits (addr), addr));
+ }
} else {
VERBOSE (ERROR, fprintf (stderr, "erroneous address\n"));
rc = 1;
commands--;
addr = strtol (commands, &commands, 10);
rc = gotoaddr (addr);
+ if (rc == 1) {
+ VERBOSE (ERROR, fprintf (stderr, "can't find address (0x%0*lx)\n", getnbdigits (addr), addr));
+ }
offset = 0;
break;
/* fall through */
case 'i': /* insert mode */
- while (*commands) {
- if ((*commands == ' ') || (*commands == '\t')) {
- commands++;
- } else {
- break;
- }
- }
- seq.sequence = commands;
- seq.length = 0;
- i = 0;
- while (*commands) {
- if ((*commands == ' ') || (*commands == '\t')) {
- *commands++ = '\0';
- break;
- } else {
- commands++;
- i++;
- if (i % 2 == 0) {
- seq.bytes[seq.length] = hexa (seq.sequence + 2 * seq.length, 2);
- if (seq.bytes[seq.length] == -1) {
- rc = 1;
- break;
- }
- seq.length++;
- }
- }
- }
- if ((seq.length > 0) && (rc == 0) && (i % 2 == 0)) {
+ removespace (commands, &commands);
+ rc = gethexaseq (&seq, commands, &commands);
+ if (rc == 0) {
rc = insertseq (&seq);
} else {
VERBOSE (ERROR, fprintf (stderr, "erroneous sequence '%s'\n", seq.sequence));
- rc = 1;
}
offset = 0;
break;
/* fall through */
case 'p': /* print mode */
- length = -1;
- while (*commands != '\0') {
- if ((*commands == ' ') || (*commands == '\t')) {
- commands++;
- } else if ((*commands >= '0') && (*commands <= '9')) {
- length = strtol (commands, &commands, 10);
- break;
- } else if (*commands == '-') {
- length = -1;
- commands++;
- break;
- } else {
- VERBOSE (ERROR, fprintf (stderr, "unknown length (%s)\n", commands));
- rc = 1;
- break;
- }
- }
- if (rc == 0) {
+ length = getlength (commands, &commands);
+ if (length == 0){
+ VERBOSE (ERROR, fprintf (stderr, "erroneous length\n"));
+ rc = 1;
+ } else {
switch (c) {
case '+':
rc = gotoaddr ((length > 0) ? addrfile + length : -1);
+ if (rc == 1) {
+ VERBOSE (ERROR, fprintf (stderr, "can't find address (0x%0*lx)\n", getnbdigits (addr), addr));
+ }
break;
case 'd':
break;
case 's': /* substitute mode */
+ if (*commands == '/') {
+ rc = getpattern (&seq, commands, &commands);
+ if (rc == 0) {
+ rc = searchseq (&seq);
+ if (rc == 0) {
+ fseek (fin, offset, SEEK_CUR);
+ rc = gethexaseq (&seq, commands, &commands);
+ if (rc == 0) {
+ rc = insertseq (&seq);
+ } else {
+ VERBOSE (ERROR, fprintf (stderr, "erroneous sequence '%s'\n", seq.sequence));
+ }
+ } else {
+ VERBOSE (ERROR, fprintf (stderr, "can't find pattern '%s'\n", seq.sequence));
+ }
+ } else {
+ VERBOSE (ERROR, fprintf (stderr, "erroneous pattern '%s'\n", seq.sequence));
+ }
+ }
offset = 0;
break;
default:
- VERBOSE (ERROR, fprintf (stderr, "unknown command (%c)\n", commands[-1]));
+ VERBOSE (ERROR, fprintf (stderr, "unknown command '%c'\n", commands[-1]));
rc = 1;
}
}
// test: hexdump.exe -i hexdump.c -e ' /\n/ p 8' | grep -q '0x000d: 0a 2f 2a 20 63 66 6c 61 \./\* cfla'
// test: hexdump.exe -i hexdump.c -o test.c -e ' /\a\b\e\f\r\t\v/ p 8'; x=$?; test x$x = x1
// test: cmp hexdump.c test.c; x=$?; rm test.c; test x$x = x0
-// test: hexdump.exe -i hexdump.c -v 3 -e " /\'/" -e ' /\"/' -e ' /\\/' -e ' /\x2a/' -e ' s/\x3A/' | grep l: | wc -l | xargs test 5 =
+// test: hexdump.exe -i hexdump.c -v 3 -e " /\'/" -e ' /\"/' -e ' /\\/' -e ' /\x2a/' -e ' /\x3A/' | grep l: | wc -l | xargs test 5 =
// test: hexdump.exe -i hexdump.c -e ' /\n\/* vim:/ p -' | grep -q ': 74 3a 20 2a 2f 0a *t: \*\/\.'
// test: hexdump.exe -i hexdump.c -e 'p go_to_end' 2>&1 | grep -q 'unknown length'
-// test: hexdump.exe -i hexdump.c -e ' //' 2>&1 | grep -q 'incorrect sequence'
+// test: hexdump.exe -i hexdump.c -e ' //' 2>&1 | grep -q 'erroneous pattern'
// test: hexdump.exe -i hexdump.c -e 'foo' 2>&1 | grep -q 'unknown command'
// test: hexdump.exe -i hexdump.c -e '0x20 p 8 64 p 8 0200 p 16' | grep -q '0x0080:'
// test: hexdump.exe -i hexdump.c -e '0xg' 2>&1 | grep -q 'erroneous address'