aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-02-04 17:11:25 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-02-04 17:11:25 +0000
commitcf787cf3a54f21e643d760dc3f893233ecce4ad5 (patch)
tree87a9b5ac42b0f76ede0014bed1940abcfd21bb2a
parent10b7996c1bcdeb66675251f5dff3d3ad57ab44f8 (diff)
downloadbusybox-w32-cf787cf3a54f21e643d760dc3f893233ecce4ad5.tar.gz
busybox-w32-cf787cf3a54f21e643d760dc3f893233ecce4ad5.tar.bz2
busybox-w32-cf787cf3a54f21e643d760dc3f893233ecce4ad5.zip
find: support for !
-rw-r--r--findutils/Config.in18
-rw-r--r--findutils/find.c45
-rw-r--r--shell/msh.c2
3 files changed, 56 insertions, 9 deletions
diff --git a/findutils/Config.in b/findutils/Config.in
index 73ce36f51..e5f82986d 100644
--- a/findutils/Config.in
+++ b/findutils/Config.in
@@ -90,6 +90,24 @@ config FEATURE_FIND_USER
90 help 90 help
91 Support the 'find -user' option for searching by username or uid. 91 Support the 'find -user' option for searching by username or uid.
92 92
93config FEATURE_FIND_NOT
94 bool "Enable the 'not' (!) operator"
95 default y
96 depends on FIND
97 help
98 Support the '!' operator to invert the test results. If 'Enable
99 full-blown desktop' is enabled, then will also the non-POSIX
100 '-not' be supported.
101
102config FEATURE_FIND_NOT
103 bool "Enable the 'not' (!) operator"
104 default y
105 depends on FIND
106 help
107 Support the '!' operator to invert the test results. If 'Enable
108 full-blown desktop' is enabled, then will also the non-POSIX
109 '-not' be supported.
110
93config GREP 111config GREP
94 bool "grep" 112 bool "grep"
95 default n 113 default n
diff --git a/findutils/find.c b/findutils/find.c
index bfdd84497..5645b5a4d 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -55,6 +55,9 @@ typedef int (*action_fp)(const char *fileName, struct stat *statbuf, void *);
55 55
56typedef struct { 56typedef struct {
57 action_fp f; 57 action_fp f;
58#if ENABLE_FEATURE_FIND_NOT
59 smallint invert;
60#endif
58} action; 61} action;
59#define ACTS(name, arg...) typedef struct { action a; arg; } action_##name; 62#define ACTS(name, arg...) typedef struct { action a; arg; } action_##name;
60#define ACTF(name) static int func_##name(const char *fileName, struct stat *statbuf, action_##name* ap) 63#define ACTF(name) static int func_##name(const char *fileName, struct stat *statbuf, action_##name* ap)
@@ -118,12 +121,20 @@ static int exec_actions(action ***appp, const char *fileName, struct stat *statb
118 cur_group = -1; 121 cur_group = -1;
119 while ((app = appp[++cur_group])) { 122 while ((app = appp[++cur_group])) {
120 cur_action = -1; 123 cur_action = -1;
121 do { 124 while (1) {
122 ap = app[++cur_action]; 125 ap = app[++cur_action];
123 } while (ap && (rc = ap->f(fileName, statbuf, ap))); 126 if (!ap) {
124 if (!ap) { 127 /* all actions in group were successful */
125 /* all actions in group were successful */ 128 return rc;
126 break; 129 }
130 rc = ap->f(fileName, statbuf, ap);
131#if ENABLE_FEATURE_FIND_NOT
132 if (ap->invert) rc = !rc;
133#endif
134 if (!rc) {
135 /* current group failed, try next */
136 break;
137 }
127 } 138 }
128 } 139 }
129 return rc; 140 return rc;
@@ -331,6 +342,7 @@ static action*** parse_params(char **argv)
331 action*** appp; 342 action*** appp;
332 unsigned cur_group = 0; 343 unsigned cur_group = 0;
333 unsigned cur_action = 0; 344 unsigned cur_action = 0;
345 USE_FEATURE_FIND_NOT( smallint invert_flag = 0; )
334 346
335 action* alloc_action(int sizeof_struct, action_fp f) 347 action* alloc_action(int sizeof_struct, action_fp f)
336 { 348 {
@@ -339,11 +351,12 @@ static action*** parse_params(char **argv)
339 appp[cur_group][cur_action++] = ap = xmalloc(sizeof_struct); 351 appp[cur_group][cur_action++] = ap = xmalloc(sizeof_struct);
340 appp[cur_group][cur_action] = NULL; 352 appp[cur_group][cur_action] = NULL;
341 ap->f = f; 353 ap->f = f;
354 USE_FEATURE_FIND_NOT( ap->invert = invert_flag; )
342 return ap; 355 return ap;
343 } 356 }
344#define ALLOC_ACTION(name) (action_##name*)alloc_action(sizeof(action_##name), (action_fp) func_##name) 357#define ALLOC_ACTION(name) (action_##name*)alloc_action(sizeof(action_##name), (action_fp) func_##name)
345 358
346 appp = xzalloc(2 * sizeof(*appp)); /* appp[0],[1] == NULL */ 359 appp = xzalloc(2 * sizeof(appp[0])); /* appp[0],[1] == NULL */
347 360
348// Actions have side effects and return a true or false value 361// Actions have side effects and return a true or false value
349// We implement: -print, -print0, -exec 362// We implement: -print, -print0, -exec
@@ -367,27 +380,39 @@ static action*** parse_params(char **argv)
367 if (strcmp(arg, "-a") == 0 380 if (strcmp(arg, "-a") == 0
368 USE_DESKTOP(|| strcmp(arg, "-and") == 0) 381 USE_DESKTOP(|| strcmp(arg, "-and") == 0)
369 ) { 382 ) {
370 /* no special handling required */ 383 USE_FEATURE_FIND_NOT( invert_flag = 0; )
384 /* no further special handling required */
371 } 385 }
372 else if (strcmp(arg, "-o") == 0 386 else if (strcmp(arg, "-o") == 0
373 USE_DESKTOP(|| strcmp(arg, "-or") == 0) 387 USE_DESKTOP(|| strcmp(arg, "-or") == 0)
374 ) { 388 ) {
375 /* start new OR group */ 389 /* start new OR group */
390 USE_FEATURE_FIND_NOT( invert_flag = 0; )
376 cur_group++; 391 cur_group++;
377 appp = xrealloc(appp, (cur_group+2) * sizeof(*appp)); 392 appp = xrealloc(appp, (cur_group+2) * sizeof(*appp));
378 appp[cur_group] = NULL; 393 /*appp[cur_group] = NULL; - already NULL */
379 appp[cur_group+1] = NULL; 394 appp[cur_group+1] = NULL;
380 cur_action = 0; 395 cur_action = 0;
381 } 396 }
397#if ENABLE_FEATURE_FIND_NOT
398 else if (LONE_CHAR(arg, '!')
399 USE_DESKTOP(|| strcmp(arg, "-not") == 0)
400 ) {
401 invert_flag = 1;
402 }
403#endif
382 404
383 /* --- Tests and actions --- */ 405 /* --- Tests and actions --- */
384 else if (strcmp(arg, "-print") == 0) { 406 else if (strcmp(arg, "-print") == 0) {
385 need_print = 0; 407 need_print = 0;
408 /* GNU find ignores '!' here: "find ! -print" */
409 USE_FEATURE_FIND_NOT( invert_flag = 0; )
386 (void) ALLOC_ACTION(print); 410 (void) ALLOC_ACTION(print);
387 } 411 }
388#if ENABLE_FEATURE_FIND_PRINT0 412#if ENABLE_FEATURE_FIND_PRINT0
389 else if (strcmp(arg, "-print0") == 0) { 413 else if (strcmp(arg, "-print0") == 0) {
390 need_print = 0; 414 need_print = 0;
415 USE_FEATURE_FIND_NOT( invert_flag = 0; )
391 (void) ALLOC_ACTION(print0); 416 (void) ALLOC_ACTION(print0);
392 } 417 }
393#endif 418#endif
@@ -471,6 +496,7 @@ static action*** parse_params(char **argv)
471 int i; 496 int i;
472 action_exec *ap; 497 action_exec *ap;
473 need_print = 0; 498 need_print = 0;
499 USE_FEATURE_FIND_NOT( invert_flag = 0; )
474 ap = ALLOC_ACTION(exec); 500 ap = ALLOC_ACTION(exec);
475 ap->exec_argv = ++argv; /* first arg after -exec */ 501 ap->exec_argv = ++argv; /* first arg after -exec */
476 ap->exec_argc = 0; 502 ap->exec_argc = 0;
@@ -524,6 +550,7 @@ static action*** parse_params(char **argv)
524 argv = endarg; 550 argv = endarg;
525 } 551 }
526 else if (strcmp(arg, "-prune") == 0) { 552 else if (strcmp(arg, "-prune") == 0) {
553 USE_FEATURE_FIND_NOT( invert_flag = 0; )
527 (void) ALLOC_ACTION(prune); 554 (void) ALLOC_ACTION(prune);
528 } 555 }
529 else if (strcmp(arg, "-size") == 0) { 556 else if (strcmp(arg, "-size") == 0) {
@@ -555,6 +582,8 @@ int find_main(int argc, char **argv)
555 for (firstopt = 1; firstopt < argc; firstopt++) { 582 for (firstopt = 1; firstopt < argc; firstopt++) {
556 if (argv[firstopt][0] == '-') 583 if (argv[firstopt][0] == '-')
557 break; 584 break;
585 if (ENABLE_FEATURE_FIND_NOT && LONE_CHAR(argv[firstopt], '!'))
586 break;
558#if ENABLE_DESKTOP 587#if ENABLE_DESKTOP
559 if (LONE_CHAR(argv[firstopt], '(')) 588 if (LONE_CHAR(argv[firstopt], '('))
560 break; 589 break;
diff --git a/shell/msh.c b/shell/msh.c
index 817b84093..a2da540b3 100644
--- a/shell/msh.c
+++ b/shell/msh.c
@@ -1278,7 +1278,7 @@ struct op *scantree(struct op *head)
1278 1278
1279 DBGPRINTF5(("SCANTREE: checking node %p\n", head)); 1279 DBGPRINTF5(("SCANTREE: checking node %p\n", head));
1280 1280
1281 if ((head->type != TDOT) && (strcmp(".", head->words[0]) == 0)) { 1281 if ((head->type != TDOT) && LONE_CHAR(head->words[0], '.')) {
1282 DBGPRINTF5(("SCANTREE: dot found in node %p\n", head)); 1282 DBGPRINTF5(("SCANTREE: dot found in node %p\n", head));
1283 return head; 1283 return head;
1284 } 1284 }