goto command
authorLaurent Mazet <mazet@softndesign.org>
Thu, 12 Jan 2023 22:07:29 +0000 (23:07 +0100)
committerLaurent Mazet <mazet@softndesign.org>
Thu, 12 Jan 2023 22:07:29 +0000 (23:07 +0100)
hexdump.c

index e6d51914026d448b72c7db25ae0bbc0535d8e800..dd4ba734d24fa68bdb38ddd1c5ff397f7fb50fc5 100644 (file)
--- a/hexdump.c
+++ b/hexdump.c
@@ -30,7 +30,7 @@ int offset = 1;
 
 char buffer[BUFFERSIZE] = {0};
 FILE *fin = NULL;
-int addrfile = 0;
+unsigned long int addrfile = 0;
 FILE *fout = NULL;
 char *progname = NULL;
 
@@ -55,8 +55,8 @@ int usage (int ret)
     fprintf (fd, " -o: output file\n");
     fprintf (fd, " -v: verbose level (%d)\n", verbose);
     fprintf (fd, "\n");
-    fprintf (fd, "commands: [/hstr/|0xaddr] [a hstr] [d nb|-] [i hstr] [p nb|-] [s/h1/h2/[g]]\n");
-    fprintf (fd, " 0x: move to address addr\n");
+    fprintf (fd, "commands: [/hstr/|addr] [a hstr] [d nb|-] [i hstr] [p nb|-] [s/h1/h2/[g]]\n");
+    fprintf (fd, " addr: move to address (0... octal, [1-9]... deci, 0x... hexa)\n");
     fprintf (fd, " //: move to hexa stringi hstr\n");
     fprintf (fd, " a : append hexa string hstr to current address\n");
     fprintf (fd, " d : delete nb bytes (- until end file)\n");
@@ -69,7 +69,7 @@ int usage (int ret)
 
 /* get number of digits */
 
-int getnbdigits (long int l) {
+unsigned int getnbdigits (unsigned long int l) {
     int n = 0;
     while (l) {
         n += 2;
@@ -160,6 +160,29 @@ int searchseq (sequence_t *seq) {
     return 1;
 }
 
+/* go to address function */
+
+int gotoaddr (unsigned long int addr) {
+    char buffer[BUFFERSIZE] = {0};
+
+    if (addrfile > addr) {
+        return 1;
+    }
+
+    VERBOSE (DEBUG, printf ("look for address: 0x%04lx\n", addr));
+    while (!feof (fin)) {
+        int nbtoread = (addrfile + BUFFERSIZE > addr) ? addr - addrfile : BUFFERSIZE;
+        int nbread = fread (buffer, 1, nbtoread, fin);
+        writefile (buffer, nbread);
+        addrfile += nbread;
+        if (addrfile == addr) {
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
 /* hexadecimal dump function */
 
 int hexdump (int len) {
@@ -214,9 +237,9 @@ int hexdump (int len) {
 
 /* parse octal string */
 
-long int octal (char *s, int n) {
+unsigned long int octal (char *s, int n) {
     int i;
-    long int l = 0;
+    unsigned long int l = 0;
     for (i = 0; i < n; i++) {
         if ((s[i] >= '0') && (s[i] <= '9')) {
             l = l * 8 + s[i] - '0';
@@ -229,9 +252,9 @@ long int octal (char *s, int n) {
 
 /* parse hexa string */
 
-long int hexa (char *s, int n) {
+unsigned long int hexa (char *s, int n) {
     int i;
-    long int l = 0;
+    unsigned long int l = 0;
     for (i = 0; i < n; i++) {
         l *= 16;
         if ((s[i] >= '0') && (s[i] <= '9')) {
@@ -290,6 +313,7 @@ int specialchar (char *s, char *b) {
             }
             break;
         default:
+            break;
         }
         if (l != -1) {
             VERBOSE (DEBUG, printf("l: 0x%02x '%c'\n", l, l));
@@ -310,7 +334,7 @@ int main (int argc, char *argv[])
     char *commands = NULL;
     int printlen = -1;
     sequence_t seq = {0};
-    char *addr = NULL;
+    unsigned long int addr = 0;
 
     /* get basename */
     char *pt = progname = argv[0];
@@ -394,7 +418,7 @@ int main (int argc, char *argv[])
     /* get file size */
     if (fin != stdin) {
         fseek (fin, 0 , SEEK_END);
-        long int filesize = ftell (fin);
+        unsigned long int filesize = ftell (fin);
         fseek (fin, 0 , SEEK_SET);
         nbdigits = getnbdigits (filesize);
     }
@@ -431,6 +455,35 @@ int main (int argc, char *argv[])
                 break;
 
             case '0': /* read address */
+                if (*commands == 'x') {
+                    commands++;
+                    addr = strtol (commands, &commands, 16);
+                } else {
+                    addr = strtol (commands, &commands, 8);
+                }
+                if (addr) {
+                    rc = gotoaddr (addr);
+                } else {
+                    VERBOSE (ERROR, fprintf (stderr, "erroneous address\n"));
+                }
+                break;
+
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9': /* read address */
+                commands--;
+                addr = strtol (commands, &commands, 10);
+                if (addr) {
+                    rc = gotoaddr (addr);
+                } else {
+                    VERBOSE (ERROR, fprintf (stderr, "erroneous address\n"));
+                }
                 break;
 
             case 'a': /* append mode */
@@ -514,7 +567,8 @@ int main (int argc, char *argv[])
 // 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 -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 print 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 'incorrect sequence'
 // 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:'
 
 /* vim: set ts=4 sw=4 et: */