print command
authorLaurent Mazet <laurent.mazet@thalesgroup.com>
Tue, 10 Jan 2023 13:56:41 +0000 (14:56 +0100)
committerLaurent Mazet <laurent.mazet@thalesgroup.com>
Tue, 10 Jan 2023 13:56:41 +0000 (14:56 +0100)
hexdump.c

index 32cb1a5dc20f8cc39ac4e3f64c36cd2e92962348..987434368174826baf62ce63c503ededbc366d33 100644 (file)
--- a/hexdump.c
+++ b/hexdump.c
@@ -31,11 +31,21 @@ void usage (int ret)
 {
     FILE *fd = ret ? stderr : stdout;
     fprintf (fd, "usage: %s [-i file] [-h] [-n nbcols] [-o file] [-v]\n", progname);
-    fprintf (fd, " -i : input file\n");
-    fprintf (fd, " -h : help message\n");
-    fprintf (fd, " -n : number of columns\n");
-    fprintf (fd, " -o : output file\n");
-    fprintf (fd, " -v : verbose level (%d)\n", verbose);
+    fprintf (fd, " -i: input file\n");
+    fprintf (fd, " -h: help message\n");
+    fprintf (fd, " -n: number of columns\n");
+    fprintf (fd, " -e: commands\n");
+    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, " //: 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");
+    fprintf (fd, " i : insert hexa string hstr to current address\n");
+    fprintf (fd, " p : print nb bytes (- until end file)\n");
+    fprintf (fd, " s : substitute h1 by h2 (g for globally)\n");
 
     exit (ret);
 }
@@ -73,7 +83,7 @@ void printline (char *buffer, int nbcols, int nb, int addr, int nbdigits) {
 
 /* indent function */
 
-int hexdump (FILE *fin, int nbcols) {
+int hexdump (FILE *fin, int nbcols, int len) {
     char buffer[BUFFERSIZE] = {0};
     int i;
 
@@ -93,7 +103,15 @@ int hexdump (FILE *fin, int nbcols) {
     int addr = 0;
     int nb = 0;
     while (!feof (fin)) {
-        nb += fread (pt, 1, BUFFERSIZE - (pt - buffer), fin);
+        int nbtoread = BUFFERSIZE - (pt - buffer);
+        if ((len > 0) && (nbtoread > len)) {
+            nbtoread = len;
+        }
+        int nbread = fread (pt, 1, nbtoread, fin);
+        if (len > 0) {
+            len -= nbread;
+        }
+        nb += nbread;
         pt = buffer;
 
         /* print line */
@@ -109,6 +127,11 @@ int hexdump (FILE *fin, int nbcols) {
             buffer[i] = pt[i];
         }
         pt = buffer + nb;
+
+        /* end partial reading */
+        if (len == 0) {
+            break;
+        }
     }
 
     /* last line */
@@ -123,9 +146,12 @@ int hexdump (FILE *fin, int nbcols) {
 
 int main (int argc, char *argv[]) 
 {
+    int rc = 0;
     char *input = NULL;
     char *output = NULL;
     int nbcols = NBCOLS;
+    char *commands = NULL;
+    int printlen = -1;
    
     /* get basename */
     char *pt = progname = argv[0];
@@ -137,11 +163,19 @@ int main (int argc, char *argv[])
     }
 
     int c;
-    while ((c = getopt(argc, argv, "i:hn:o:v:")) != EOF) {
+    while ((c = getopt(argc, argv, "e:i:hn:o:v:")) != EOF) {
         switch (c) {
         case 'i':
             input = optarg;
             break;
+        case 'e':
+            if (commands == NULL) {
+                commands = optarg;
+            } else {
+                strcat (commands, " ");
+                strcat (commands, optarg);
+            }
+            break;
         case 'n':
             nbcols = atoi (optarg);
             break;
@@ -167,6 +201,7 @@ int main (int argc, char *argv[])
         fin = fopen (input, "rb");
         if (!fin) {
             VERBOSE (ERROR, fprintf (stderr, "error: can't open file '%s'\n", input));
+            return 1;
         }
     } else {
         fin = stdin;
@@ -179,18 +214,73 @@ int main (int argc, char *argv[])
         if (!fout) {
             VERBOSE (ERROR, fprintf (stderr, "error: can't open file '%s'\n", output));
             fclose (fin);
+            return 1;
         }
     } else {
         fout = stdout;
     }
 
-    hexdump (fin, nbcols);
+    if (commands == NULL) {
+        hexdump (fin, nbcols, -1);
+    } else {
+        VERBOSE (DEBUG, printf ("commands: %s\n", commands));
+        while ((*commands != '\0') && (rc == 0)) {
+            switch (*commands++) {
+            case ' ':
+            case '\t':
+                break;
+
+            case '/': /* read patern */
+                break;
+
+            case '0': /* read address */
+                break;
+
+            case 'a': /* append mode */
+                break;
+
+            case 'd': /* delete mode */
+                break;
+
+            case 'i': /* insert mode */
+                break;
+
+            case 'p': /* print mode */
+                printlen = -1;
+                while (*commands != '\0') {
+                    if ((*commands == ' ') || (*commands == '\t')) {
+                        commands++;
+                    } else if ((*commands >= '0') && (*commands <= '9')) {
+                        printlen = strtol (commands, &commands, 10);
+                        break;
+                    } else if (*commands == '-') {
+                        printlen = -1;
+                        commands++;
+                        break;
+                    } else {
+                        VERBOSE (ERROR, fprintf (stderr, "unkown print lenght (%s)\n", commands));
+                        rc = 1;
+                        break;
+                    }
+                }
+                if (rc == 0) hexdump (fin, nbcols, printlen);
+                break;
+
+            case 's': /* substitute mode */
+                break;
+
+            default:
+                VERBOSE (ERROR, fprintf (stderr, "unknown command (%c)\n", commands[-1]));
+                rc = 1;
+            }
+        }
+    }
 
     /* close all */
-    fclose (fin);
-    fclose (fout);
+    if (fin) fclose (fin);
+    if (fout) fclose (fout);
 
-    return 0;
+    return rc;
 }
 
 // test: hexdump.exe -h