[PATCH] find ! ... (operator -not)
Denis Vlasenko
vda.linux at googlemail.com
Fri Feb 2 21:43:56 UTC 2007
On Friday 02 February 2007 16:01, Natanael Copa wrote:
> Hi,
>
> Attatched is a patch for support of the '!' operator for find.
>
> I created another macro ALLOC_TEST for actions that can be inverted with
> '!'. They are not really actions (like -print) but tests (like -name).
>
> It should not touch anything unless you have enabled the
> FEATURE_FIND_NOT config option.
parse_params():
invert_flag is never reset to 0. This must be a bug -
"not" shouldn't be applied to the second -name here, I think
(did not check it versus GNU find, tho...):
find ! -name '*.a' -o -name '*.b'
Now, to more cosmetic matters:
+#define LOGIC_XOR(a, b) ( (!(a)) != (!(b)) )
ACTS(print)
ACTS(name, const char *pattern;)
USE_FEATURE_FIND_PRINT0(ACTS(print0))
@@ -120,7 +124,13 @@
cur_action = -1;
do {
ap = app[++cur_action];
- } while (ap && (rc = ap->f(fileName, statbuf, ap)));
+ } while (ap &&
+#if ENABLE_FEATURE_FIND_NOT
+ (rc = LOGIC_XOR(ap->f(fileName, statbuf, ap), ap->invert))
+#else
+ (rc = ap->f(fileName, statbuf, ap))
+#endif
+ );
This is obscure. I propose to do this instead - much easier to read:
while ((app = appp[++cur_group])) {
cur_action = -1;
- do {
+ while (1) {
ap = app[++cur_action];
- } while (ap && (rc = ap->f(fileName, statbuf, ap)));
- if (!ap) {
- /* all actions in group were successful */
- break;
+ if (!ap) {
+ /* all actions in group were successful */
+ return rc;
+ }
+ rc = ap->f(fileName, statbuf, ap);
+#if ENABLE_FEATURE_FIND_NOT
+ if (ap->invert) rc = !rc;
+#endif
+ if (!rc) return rc;
}
}
return rc;
+#if ENABLE_FEATURE_FIND_NOT
+ else if (strcmp(arg, "!") == 0
+ USE_DESKTOP(|| strcmp(arg, "-not") == 0)
+ ) invert_flag = 1;
+#endif
Don't torture code reader please :) How about this?
+#if ENABLE_FEATURE_FIND_NOT
+ else if (strcmp(arg, "!") == 0
+ USE_DESKTOP(|| strcmp(arg, "-not") == 0)
+ ) {
+ invert_flag = 1;
+ }
+#endif
action* alloc_action(int sizeof_struct, action_fp f
USE_FEATURE_FIND_NOT(, int invert)
)
{
action *ap;
appp[cur_group] = xrealloc(appp[cur_group], (cur_action+2) * sizeof(*appp));
appp[cur_group][cur_action++] = ap = xmalloc(sizeof_struct);
appp[cur_group][cur_action] = NULL;
ap->f = f;
USE_FEATURE_FIND_NOT( ap->invert = invert; )
return ap;
}
#define ALLOC_ACTION(name) (action_##name*)alloc_action(sizeof(action_##name), (action_fp) func_##name USE_FEATURE_FIND_NOT(, 0))
#define ALLOC_TEST(name) (action_##name*)alloc_action(sizeof(action_##name), (action_fp) func_##name USE_FEATURE_FIND_NOT(, invert_flag))
You do not need to pass "int invert" to alloc_action. Just use invert_flag
in alloc_action body, and forcefully reset invert_flag = 0 whenever
you are about to do ALLOC_ACTION, like when you handle -print.
(GNU find doesn't error out on "find ! -print", it simply ignores "!").
Care to produce updated patch?
--
vda
More information about the busybox
mailing list