OSDN Git Service

dd cleanup: binary search is overkill, eliminate struct pair,
authorRob Landley <rob@landley.net>
Sun, 9 Jul 2017 07:13:00 +0000 (02:13 -0500)
committerRob Landley <rob@landley.net>
Sun, 9 Jul 2017 07:13:00 +0000 (02:13 -0500)
simplify strstarteq, use local variable "conv" instead of toys.optargs.

toys/pending/dd.c

index 2160e72..aebc90e 100644 (file)
@@ -7,7 +7,7 @@
  *
  * todo: ctrl-c doesn't work, the read() is restarting.
 
-USE_DD(NEWTOY(dd, NULL, TOYFLAG_USR|TOYFLAG_BIN))
+USE_DD(NEWTOY(dd, 0, TOYFLAG_USR|TOYFLAG_BIN))
 
 config DD
   bool "dd"
@@ -52,22 +52,10 @@ GLOBALS(
   } in, out;
 );
 
-#define C_SYNC    0x0100
-#define C_FSYNC   0x0200
-#define C_NOERROR 0x0400
-#define C_NOTRUNC 0x0800
-
-struct pair {
-  char *name;
-  unsigned val;
-};
-
-static struct pair clist[] = {
-  { "fsync",    C_FSYNC },
-  { "noerror",  C_NOERROR },
-  { "notrunc",  C_NOTRUNC },
-  { "sync",     C_SYNC },
-};
+#define C_FSYNC   1
+#define C_NOERROR 2
+#define C_NOTRUNC 4
+#define C_SYNC    8
 
 static void status()
 {
@@ -112,24 +100,14 @@ int strstarteq(char **a, char *b)
 {
   char *aa = *a;
 
-  if (!strstart(&aa, b)) return 0;
-  if (*aa != '=') return 0;
-  *a = ++aa;
-
-  return 1;
-}
-
-static int comp(const void *a, const void *b) //const to shut compiler up
-{
-  return strcmp(((struct pair*)a)->name, ((struct pair*)b)->name);
+  return strstart(&aa, b) && *aa == '=' && (*a = aa+1);
 }
 
 void dd_main()
 {
-  struct pair *res, key;
   char **args;
   unsigned long long bs = 0;
-  int trunc = O_TRUNC;
+  int trunc = O_TRUNC, conv = 0;
 
   TT.show_xfer = TT.show_records = 1;
   TT.c_count = ULLONG_MAX;
@@ -154,13 +132,14 @@ void dd_main()
       else if (!strcmp(arg, "none")) TT.show_xfer = TT.show_records = 0;
       else error_exit("unknown status '%s'", arg);
     } else if (strstarteq(&arg, "conv")) {
-      while (arg) {
-        key.name = strsep(&arg, ",");
-        if (!(res = bsearch(&key, clist, ARRAY_LEN(clist), 
-                sizeof(struct pair), comp)))
-          error_exit("unknown conversion %s", key.name);
-
-        toys.optflags |= res->val;
+      char *ss, *convs[] = {"fsync", "noerror", "notrunc", "sync"};
+      int i, len;
+
+      while ((ss = comma_iterate(&arg, &len))) {
+        for (i = 0; i<ARRAY_LEN(convs); i++)
+          if (len == strlen(convs[i]) && !strncmp(ss, convs[i], len)) break;
+        if (i == ARRAY_LEN(convs)) error_exit("bad conv=%.*s", len, ss);
+        conv |= 1<<i;
       }
     } else error_exit("bad arg %s", arg);
   }
@@ -179,7 +158,7 @@ void dd_main()
   if (!TT.in.name) TT.in.name = "stdin";
   else TT.in.fd = xopenro(TT.in.name);
 
-  if (toys.optflags&C_NOTRUNC) trunc = 0;
+  if (conv&C_NOTRUNC) trunc = 0;
 
   //setup output
   if (!TT.out.name) {
@@ -196,7 +175,7 @@ void dd_main()
 
         if (n < 0) {
           perror_msg("%s", TT.in.name);
-          if (toys.optflags & C_NOERROR) status();
+          if (conv&C_NOERROR) status();
           else return;
         } else if (!n) {
           xprintf("%s: Can't skip\n", TT.in.name);
@@ -224,16 +203,16 @@ void dd_main()
     }
 
     TT.in.bp = TT.in.buff + TT.in.count;
-    if (toys.optflags & C_SYNC) memset(TT.in.bp, 0, TT.in.sz);
+    if (conv&C_SYNC) memset(TT.in.bp, 0, TT.in.sz);
     if (!(n = read(TT.in.fd, TT.in.bp, TT.in.sz))) break;
     if (n < 0) { 
       if (errno == EINTR) continue;
       //read error case.
       perror_msg("%s: read error", TT.in.name);
-      if (!(toys.optflags & C_NOERROR)) exit(1);
+      if (!(conv&C_NOERROR)) exit(1);
       status();
       xlseek(TT.in.fd, TT.in.sz, SEEK_CUR);
-      if (!(toys.optflags & C_SYNC)) continue;
+      if (!(conv&C_SYNC)) continue;
       // if SYNC, then treat as full block of nuls
       n = TT.in.sz;
     }
@@ -242,7 +221,7 @@ void dd_main()
       TT.in.count += n;
     } else {
       TT.in_part++;
-      if (toys.optflags & C_SYNC) TT.in.count += TT.in.sz;
+      if (conv&C_SYNC) TT.in.count += TT.in.sz;
       else TT.in.count += n;
     }
 
@@ -259,8 +238,8 @@ void dd_main()
     }
   }
   if (TT.out.count) write_out(1); //write any remaining input blocks
-  if (toys.optflags & C_FSYNC && fsync(TT.out.fd) < 0) 
-    perror_exit("%s: fsync fail", TT.out.name);
+  if ((conv&C_FSYNC) && fsync(TT.out.fd)<0)
+    perror_exit("%s: fsync", TT.out.name);
 
   close(TT.in.fd);
   close(TT.out.fd);