changeset 874:c326f55c74bd

More find cleanup
author Felix Janda <felix.janda@posteo.de>
date Sat, 20 Apr 2013 17:25:41 +0200
parents d90f14e011b8
children 2650f5f56bab
files toys/pending/find.c
diffstat 1 files changed, 92 insertions(+), 93 deletions(-) [+]
line wrap: on
line diff
--- a/toys/pending/find.c	Sun Apr 21 12:15:59 2013 -0500
+++ b/toys/pending/find.c	Sat Apr 20 17:25:41 2013 +0200
@@ -29,14 +29,6 @@
 #define FOR_find
 #include "toys.h"
 
-GLOBALS(
-  char *dir;
-)
-
-#define SECONDS_PER_DAY (24*60*60)
-
-int have_action;
-
 struct filter_node {
   struct filter_node *next;
   int op;
@@ -54,7 +46,13 @@
   } data;
 };
 
-static struct filter_node *filter_root;
+GLOBALS(
+  char *dir;
+  int have_action;
+  struct filter_node *filter_root;
+)
+
+#define SECONDS_PER_DAY (24*60*60)
 
 /* filter operation types */
 #define OP_UNKNOWN	0
@@ -75,6 +73,8 @@
 #define ACTION_PRINT0	21
 #define ACTION_EXEC	22
 
+#define IS_ACTION(x)    (x >= 20)
+
 #define TEST_LT		0
 #define TEST_EQ		1
 #define TEST_GT		2
@@ -204,8 +204,6 @@
 
 static int check_node_callback(struct dirtree *node)
 {
-  char *path;
-  int plen = 0;
   int result;
   struct filter_node *junk;
 
@@ -217,9 +215,11 @@
     (node->name[1]=='.' && !node->name[2])))
     return 0;
 
-  result = evaluate(filter_root, node, &junk);
-  if (result & !have_action) {
+  result = evaluate(TT.filter_root, node, &junk);
+  if (result & !TT.have_action) {
     /* default action is just print the path */
+    char *path;
+    int plen = 0;
     path = dirtree_path(node, &plen);
     printf("%s\n", path);
     free(path);
@@ -231,93 +231,92 @@
 static void build_filter_list(void)
 {
   struct filter_node *node_list, *op_stack, *node, *op_node, *next;
-  char *arg, **arg_array;
-  int i, j;
+  char **arg;
+  int j;
   int prevop = 0;
 
   /* part optargs here and build a filter list in prefix format */
 
   TT.dir = ".";
   node_list = NULL;
-  have_action = 0;
-  for(i=0; toys.optargs[i]; i++) {
-    node = (struct filter_node *)
-      xmalloc(sizeof(struct filter_node));
+  TT.have_action = 0;
+  for (arg = toys.optargs; *arg; arg++) {
+    struct {
+      char *arg;
+      int op;
+      int extrarg;
+    } arg_map[] = {{"-o", OP_OR, 0},
+                   {"-a", OP_AND, 0},
+                   {"!", OP_NOT, 0},
+                   {"(", LPAREN, 0},
+                   {")", RPAREN, 0},
+                   {"-name", CHECK_NAME, 1},
+                   {"-mtime", CHECK_MTIME, 1},
+                   {"-type", CHECK_TYPE, 1},
+                   {"-print", ACTION_PRINT, 0},
+                   {"-print0", ACTION_PRINT0, 0},
+                   {"-exec", ACTION_EXEC, 1}
+    };
+    mode_t types[]={S_IFREG,S_IFDIR,S_IFCHR,S_IFBLK,S_IFLNK,S_IFSOCK,S_IFIFO};
+    char **arg_array;
+    node = (struct filter_node *) xmalloc(sizeof(struct filter_node));
     node->op = OP_UNKNOWN;
-    arg = toys.optargs[i];
-    if (!strcmp(arg, "-o")) node->op = OP_OR;
-    if (!strcmp(arg, "-a")) node->op = OP_AND;
-    if (!strcmp(arg, "!")) node->op = OP_NOT;
-    if (!strcmp(arg, "(")) node->op = LPAREN;
-    if (!strcmp(arg, ")")) node->op = RPAREN;
-
-    if (!strcmp(arg, "-name")) {
-      node->op = CHECK_NAME;
-      arg = toys.optargs[++i];
-      if (!arg) error_exit("Missing argument to -name");
-      node->data.name_regex = arg;
+    for (j=0; j < sizeof(arg_map)/sizeof(*arg_map); j++) {
+      if (!strcmp(*arg, arg_map[j].arg)) {
+        node->op = arg_map[j].op;
+        if (arg_map[j].extrarg && !*(++arg))
+	   error_exit("Missing argument to %s", arg_map[j].arg);
+	break;
+      }
     }
 
-    if (!strcmp(arg, "-mtime")) {
-      node->op = CHECK_MTIME;
-      arg = toys.optargs[++i];
-      if (!arg) error_exit("Missing argument to -mtime");
-      switch(arg[0]) {
-        case '+':
-          node->data.t.time_op=TEST_GT;
+    switch(node->op) {
+      case CHECK_NAME:
+        node->data.name_regex = *arg;
+        break;
+      case CHECK_MTIME:
+        switch(**arg) {
+          case '+':
+            node->data.t.time_op=TEST_GT;
+            arg++;
+            break;
+          case '-':
+            node->data.t.time_op=TEST_LT;
+            arg++;
+            break;
+          default:
+            node->data.t.time_op=TEST_EQ;
+            break;
+        }
+        /* convert to days (very crudely) */
+        node->data.t.time = atoi(*arg)/SECONDS_PER_DAY;
+        break;
+      case CHECK_TYPE:
+        if (-1 == (j = stridx("fdcblsp", **arg)))
+          error_exit("bad type '%s'", *arg);
+        else node->data.type = types[j];
+        break;
+      case ACTION_EXEC:
+        arg_array = xmalloc(sizeof(char *));
+        for (j = 0; *arg && strcmp(*arg, ";"); j++) {
+          /* new method */
+          arg_array = xrealloc(arg_array, sizeof(char *) * (j+2));
+          arg_array[j] = *arg;
+          if (!strcmp(*arg, "{}")) node->data.e.arg_path_index = j;
+
           arg++;
-          break;
-        case '-':
-          node->data.t.time_op=TEST_LT;
-          arg++;
-          break;
-        default:
-          node->data.t.time_op=TEST_EQ;
-          break;
-      }
-      /* convert to days (very crudely) */
-      node->data.t.time = atoi(arg)/SECONDS_PER_DAY;
+        }
+        if (!*arg) error_exit("need ';' in exec");
+        arg_array[j] = 0;
+        node->data.e.exec_args = arg_array;
+        break;
     }
 
-    if (!strcmp(arg, "-type")) {
-      mode_t types[]={S_IFREG,S_IFDIR,S_IFCHR,S_IFBLK,S_IFLNK,S_IFSOCK,S_IFIFO};
-      int j;
+    TT.have_action |= IS_ACTION(node->op);
 
-      node->op = CHECK_TYPE;
-      arg = toys.optargs[++i];
-      if (!arg) error_exit("Missing argument to -type");
-      if (-1 == (j = stridx("fdcblsp", *arg)))
-        error_exit("bad type '%s'", arg);
-      else node->data.type = types[j];
-    }
-    if (!strcmp(arg, "-print")) {
-      node->op = ACTION_PRINT;
-      have_action = 1;
-    }
-    if (!strcmp(arg, "-print0")) {
-      node->op = ACTION_PRINT0;
-      have_action = 1;
-    }
-    if (!strcmp(arg, "-exec")) {
-      node->op = ACTION_EXEC;
-      have_action = 1;
-      arg_array = xmalloc(sizeof(char *));
-      arg = toys.optargs[++i];
-      for (j = 0; arg && strcmp(arg, ";"); j++) {
-        /* new method */
-        arg_array = xrealloc(arg_array, sizeof(char *) * (j+2));
-        arg_array[j] = arg;
-        if (!strcmp(arg, "{}")) node->data.e.arg_path_index = j;
-
-        arg = toys.optargs[++i];
-      }
-      if (!arg) error_exit("need ';' in exec");
-      arg_array[j] = 0;
-      node->data.e.exec_args = arg_array;
-    }
     if (node->op == OP_UNKNOWN) {
-      if (arg[0] == '-') error_exit("bad option '%s'", arg);
-      else TT.dir = arg;
+      if (**arg == '-') error_exit("bad option '%s'", *arg);
+      else TT.dir = *arg;
     }  else {
       // add OP_AND where necessary
       if (node_list) {
@@ -340,7 +339,7 @@
   }
 
   /* now convert from infix to prefix */
-  filter_root = NULL;
+  TT.filter_root = NULL;
   op_stack = NULL;
   node = node_list;
   while( node ) {
@@ -358,8 +357,8 @@
           /* remove from op_stack */
           op_stack = op_node->next;
           /* push to output */
-          op_node->next = filter_root;
-          filter_root = op_node;
+          op_node->next = TT.filter_root;
+          TT.filter_root = op_node;
           /* get next node */
           op_node = op_stack;
         }
@@ -373,8 +372,8 @@
     }
     else {
         /* push to output */
-        node->next = filter_root;
-        filter_root = node;
+        node->next = TT.filter_root;
+        TT.filter_root = node;
     }
     node = next;
   }
@@ -383,8 +382,8 @@
   op_node = op_stack;
   while (op_node) {
     op_stack = op_node->next;
-    op_node->next = filter_root;
-    filter_root = op_node;
+    op_node->next = TT.filter_root;
+    TT.filter_root = op_node;
     op_node = op_stack;
   }
 }