386BSD 0.0 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Fri, 24 May 1991 22:17:32 +0000 (14:17 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Fri, 24 May 1991 22:17:32 +0000 (14:17 -0800)
Work on file usr/src/usr.bin/find/Makefile
Work on file usr/src/usr.bin/find/operator.c
Work on file usr/src/usr.bin/find/misc.c

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.0/src

usr/src/usr.bin/find/Makefile [new file with mode: 0644]
usr/src/usr.bin/find/misc.c [new file with mode: 0644]
usr/src/usr.bin/find/operator.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/find/Makefile b/usr/src/usr.bin/find/Makefile
new file mode 100644 (file)
index 0000000..7fc747b
--- /dev/null
@@ -0,0 +1,8 @@
+#      @(#)Makefile    5.2 (Berkeley) 5/24/91
+
+PROG=  find
+SRCS=  find.c function.c ls.c main.c misc.c operator.c option.c
+DPADD= ${LIBUTIL}
+LDADD= -lutil
+
+.include <bsd.prog.mk>
diff --git a/usr/src/usr.bin/find/misc.c b/usr/src/usr.bin/find/misc.c
new file mode 100644 (file)
index 0000000..3ff4d5a
--- /dev/null
@@ -0,0 +1,152 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Cimarron D. Taylor of the University of California, Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)misc.c     5.8 (Berkeley) 5/24/91";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "find.h"
+/*
+ * brace_subst --
+ *     Replace occurrences of {} in s1 with s2 and return the result string.
+ */
+void
+brace_subst(orig, store, path, len)
+       char *orig, **store, *path;
+       int len;
+{
+       register int plen;
+       register char ch, *p;
+
+       plen = strlen(path);
+       for (p = *store; ch = *orig; ++orig)
+               if (ch == '{' && orig[1] == '}') {
+                       while ((p - *store) + plen > len)
+                               if (!(*store = realloc(*store, len *= 2)))
+                                       err("%s", strerror(errno));
+                       bcopy(path, p, plen);
+                       p += plen;
+                       ++orig;
+               } else
+                       *p++ = ch;
+       *p = '\0';
+}
+
+/*
+ * queryuser --
+ *     print a message to standard error and then read input from standard
+ *     input. If the input is 'y' then 1 is returned.
+ */
+queryuser(argv)
+       register char **argv;
+{
+       int ch, first, nl;
+
+       (void)fprintf(stderr, "\"%s", *argv);
+       while (*++argv)
+               (void)fprintf(stderr, " %s", *argv);
+       (void)fprintf(stderr, "\"? ");
+       (void)fflush(stderr);
+
+       first = ch = getchar();
+       for (nl = 0;;) {
+               if (ch == '\n') {
+                       nl = 1;
+                       break;
+               }
+               if (ch == EOF)
+                       break;
+               ch = getchar();
+       }
+
+       if (!nl) {
+               (void)fprintf(stderr, "\n");
+               (void)fflush(stderr);
+       }
+        return(first == 'y');
+}
+/*
+ * emalloc --
+ *     malloc with error checking.
+ */
+void *
+emalloc(len)
+       u_int len;
+{
+       void *p;
+
+       if (p = malloc(len))
+               return(p);
+       err("%s", strerror(errno));
+       /* NOTREACHED */
+}
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#if __STDC__
+err(const char *fmt, ...)
+#else
+err(fmt, va_alist)
+       char *fmt;
+        va_dcl
+#endif
+{
+       va_list ap;
+#if __STDC__
+       va_start(ap, fmt);
+#else
+       va_start(ap);
+#endif
+       (void)fprintf(stderr, "find: ");
+       (void)vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       (void)fprintf(stderr, "\n");
+       exit(1);
+       /* NOTREACHED */
+}
diff --git a/usr/src/usr.bin/find/operator.c b/usr/src/usr.bin/find/operator.c
new file mode 100644 (file)
index 0000000..b62add6
--- /dev/null
@@ -0,0 +1,267 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Cimarron D. Taylor of the University of California, Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)operator.c 5.4 (Berkeley) 5/24/91";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include "find.h"
+    
+/*
+ * yanknode --
+ *     destructively removes the top from the plan
+ */
+static PLAN *
+yanknode(planp)    
+       PLAN **planp;           /* pointer to top of plan (modified) */
+{
+       PLAN *node;             /* top node removed from the plan */
+    
+       if ((node = (*planp)) == NULL)
+               return(NULL);
+       (*planp) = (*planp)->next;
+       node->next = NULL;
+       return(node);
+}
+/*
+ * yankexpr --
+ *     Removes one expression from the plan.  This is used mainly by
+ *     paren_squish.  In comments below, an expression is either a
+ *     simple node or a N_EXPR node containing a list of simple nodes.
+ */
+static PLAN *
+yankexpr(planp)    
+       PLAN **planp;           /* pointer to top of plan (modified) */
+{
+       register PLAN *next;    /* temp node holding subexpression results */
+       PLAN *node;             /* pointer to returned node or expression */
+       PLAN *tail;             /* pointer to tail of subplan */
+       PLAN *subplan;          /* pointer to head of ( ) expression */
+       int f_expr();
+    
+       /* first pull the top node from the plan */
+       if ((node = yanknode(planp)) == NULL)
+               return(NULL);
+    
+       /*
+        * If the node is an '(' then we recursively slurp up expressions
+        * until we find its associated ')'.  If it's a closing paren we
+        * just return it and unwind our recursion; all other nodes are
+        * complete expressions, so just return them.
+        */
+       if (node->type == N_OPENPAREN)
+               for (tail = subplan = NULL;;) {
+                       if ((next = yankexpr(planp)) == NULL)
+                               err("%s: %s", "(", "missing closing ')'");
+                       /*
+                        * If we find a closing ')' we store the collected
+                        * subplan in our '(' node and convert the node to
+                        * a N_EXPR.  The ')' we found is ignored.  Otherwise,
+                        * we just continue to add whatever we get to our
+                        * subplan.
+                        */
+                       if (next->type == N_CLOSEPAREN) {
+                               if (subplan == NULL)
+                                       err("%s: %s",
+                                           "()", "empty inner expression");
+                               node->p_data[0] = subplan;
+                               node->type = N_EXPR;
+                               node->eval = f_expr;
+                               break;
+                       } else {
+                               if (subplan == NULL)
+                                       tail = subplan = next;
+                               else {
+                                       tail->next = next;
+                                       tail = next;
+                               }
+                               tail->next = NULL;
+                       }
+               }
+       return(node);
+}
+/*
+ * paren_squish --
+ *     replaces "parentheisized" plans in our search plan with "expr" nodes.
+ */
+PLAN *
+paren_squish(plan)
+       PLAN *plan;             /* plan with ( ) nodes */
+{
+       register PLAN *expr;    /* pointer to next expression */
+       register PLAN *tail;    /* pointer to tail of result plan */
+       PLAN *result;           /* pointer to head of result plan */
+    
+       result = tail = NULL;
+
+       /*
+        * the basic idea is to have yankexpr do all our work and just
+        * collect it's results together.
+        */
+       while ((expr = yankexpr(&plan)) != NULL) {
+               /*
+                * if we find an unclaimed ')' it means there is a missing
+                * '(' someplace.
+                */
+               if (expr->type == N_CLOSEPAREN)
+                       err("%s: %s", ")", "no beginning '('");
+
+               /* add the expression to our result plan */
+               if (result == NULL)
+                       tail = result = expr;
+               else {
+                       tail->next = expr;
+                       tail = expr;
+               }
+               tail->next = NULL;
+       }
+       return(result);
+}
+/*
+ * not_squish --
+ *     compresses "!" expressions in our search plan.
+ */
+PLAN *
+not_squish(plan)
+       PLAN *plan;             /* plan to process */
+{
+       register PLAN *next;    /* next node being processed */
+       register PLAN *node;    /* temporary node used in N_NOT processing */
+       register PLAN *tail;    /* pointer to tail of result plan */
+       PLAN *result;           /* pointer to head of result plan */
+    
+       tail = result = next = NULL;
+    
+       while ((next = yanknode(&plan)) != NULL) {
+               /*
+                * if we encounter a ( expression ) then look for nots in
+                * the expr subplan.
+                */
+               if (next->type == N_EXPR)
+                       next->p_data[0] = not_squish(next->p_data[0]);
+
+               /*
+                * if we encounter a not, then snag the next node and place
+                * it in the not's subplan.  As an optimization we compress
+                * several not's to zero or one not.
+                */
+               if (next->type == N_NOT) {
+                       int notlevel = 1;
+
+                       node = yanknode(&plan);
+                       while (node->type == N_NOT) {
+                               ++notlevel;
+                               node = yanknode(&plan);
+                       }
+                       if (node == NULL)
+                               err("%s: %s", "!", "no following expression");
+                       if (node->type == N_OR)
+                               err("%s: %s", "!", "nothing between ! and -o");
+                       if (notlevel % 2 != 1)
+                               next = node;
+                       else
+                               next->p_data[0] = node;
+               }
+
+               /* add the node to our result plan */
+               if (result == NULL)
+                       tail = result = next;
+               else {
+                       tail->next = next;
+                       tail = next;
+               }
+               tail->next = NULL;
+       }
+       return(result);
+}
+/*
+ * or_squish --
+ *     compresses -o expressions in our search plan.
+ */
+PLAN *
+or_squish(plan)
+       PLAN *plan;             /* plan with ors to be squished */
+{
+       register PLAN *next;    /* next node being processed */
+       register PLAN *tail;    /* pointer to tail of result plan */
+       PLAN *result;           /* pointer to head of result plan */
+    
+       tail = result = next = NULL;
+    
+       while ((next = yanknode(&plan)) != NULL) {
+               /*
+                * if we encounter a ( expression ) then look for or's in
+                * the expr subplan.
+                */
+               if (next->type == N_EXPR)
+                       next->p_data[0] = or_squish(next->p_data[0]);
+
+               /* if we encounter a not then look for not's in the subplan */
+               if (next->type == N_NOT)
+                       next->p_data[0] = or_squish(next->p_data[0]);
+
+               /*
+                * if we encounter an or, then place our collected plan in the
+                * or's first subplan and then recursively collect the
+                * remaining stuff into the second subplan and return the or.
+                */
+               if (next->type == N_OR) {
+                       if (result == NULL)
+                               err("%s: %s", "-o", "no expression before -o");
+                       next->p_data[0] = result;
+                       next->p_data[1] = or_squish(plan);
+                       if (next->p_data[1] == NULL)
+                               err("%s: %s", "-o", "no expression after -o");
+                       return(next);
+               }
+
+               /* add the node to our result plan */
+               if (result == NULL)
+                       tail = result = next;
+               else {
+                       tail->next = next;
+                       tail = next;
+               }
+               tail->next = NULL;
+       }
+       return(result);
+}