relative move command
authorLaurent Mazet <mazet@softndesign.org>
Sat, 14 Jan 2023 15:41:34 +0000 (16:41 +0100)
committerLaurent Mazet <mazet@softndesign.org>
Sat, 14 Jan 2023 15:41:34 +0000 (16:41 +0100)
hexdump.c

index cc278231aee0940521c7caf3de26726b9c5b0b63..dab192bac85922e29c6ceb204596a7d45f3ae557 100644 (file)
--- a/hexdump.c
+++ b/hexdump.c
@@ -3,6 +3,7 @@
 /* linker: debug.o */
 
 #include <assert.h>
+#include <limits.h>
 #include <malloc.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -30,7 +31,7 @@ int offset = 0;
 
 char buffer[BUFFERSIZE] = {0};
 FILE *fin = NULL;
-unsigned long int addrfile = 0;
+long int addrfile = 0;
 FILE *fout = NULL;
 char *progname = NULL;
 
@@ -55,8 +56,9 @@ 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/|addr] [a hstr] [d nb|-] [i hstr] [p nb|-] [s/h1/h2/[g]]\n");
+    fprintf (fd, "commands: [/hstr/|addr|+nb] [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, " +nb: move to offset (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");
@@ -162,10 +164,12 @@ int searchseq (sequence_t *seq) {
 
 /* go to address function */
 
-int gotoaddr (unsigned long int addr) {
+int gotoaddr (long int addr) {
     char buffer[BUFFERSIZE] = {0};
 
-    if (addrfile > addr) {
+    if (addr == -1) {
+        addr = LONG_MAX;
+    } else if (addrfile > addr) {
         return 1;
     }
 
@@ -357,9 +361,9 @@ int main (int argc, char *argv[])
     char *input = NULL;
     char *output = NULL;
     char *commands = NULL;
-    int length = -1;
+    long int length = -1;
     sequence_t seq = {0};
-    unsigned long int addr = 0;
+    long int addr = 0;
     char c;
 
     /* get basename */
@@ -495,6 +499,7 @@ int main (int argc, char *argv[])
                     VERBOSE (ERROR, fprintf (stderr, "erroneous address\n"));
                     rc = 1;
                 }
+                offset = 0;
                 break;
 
             case '1':
@@ -509,6 +514,7 @@ int main (int argc, char *argv[])
                 commands--;
                 addr = strtol (commands, &commands, 10);
                 rc = gotoaddr (addr);
+                offset = 0;
                 break;
 
             case 'a': /* append mode */
@@ -549,8 +555,12 @@ int main (int argc, char *argv[])
                     VERBOSE (ERROR, fprintf (stderr, "erroneous sequence '%s'\n", seq.sequence));
                     rc = 1;
                 }
+                offset = 0;
                 break;
 
+            case '+': /* relative move */
+                /* fall through */
+
             case 'd': /* delete mode */
                 /* fall through */
 
@@ -574,17 +584,24 @@ int main (int argc, char *argv[])
                 }
                 if (rc == 0) {
                     switch (c) {
+                    case '+':
+                        rc = gotoaddr ((length > 0) ? addrfile + length : -1);
+                        break;
+
                     case 'd':
                         fseek (fin, length, SEEK_CUR);
                         break;
+
                     case 'p':
                         hexdump (length);
                         break;
                     }
                 }
+                offset = 0;
                 break;
 
             case 's': /* substitute mode */
+                offset = 0;
                 break;
 
             default:
@@ -642,5 +659,7 @@ int main (int argc, char *argv[])
 // test: hexdump.exe -i hexdump.c -e ' /cflags/ a 414e5' 2>&1 | grep 'erroneous sequence'
 // test: hexdump.exe -i hexdump.c -o test.c -e ' /lags/ d 2'
 // test: grep -q cfgs test.c; x=$?; rm test.c; test x$x = x0
+// test: hexdump.exe -i hexdump.c -o test.c -e ' /lags/ +2 i 2041'
+// test: grep -q 'cf Ags' test.c; x=$?; rm test.c; test x$x = x0
 
 /* vim: set ts=4 sw=4 et: */