Annotation of 43BSDReno/usr.bin/find/operator.c, revision 1.1.1.1

1.1       root        1: /*-
                      2:  * Copyright (c) 1990 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Cimarron D. Taylor of the University of California, Berkeley.
                      7:  *
                      8:  * Redistribution and use in source and binary forms are permitted provided
                      9:  * that: (1) source distributions retain this entire copyright notice and
                     10:  * comment, and (2) distributions including binaries display the following
                     11:  * acknowledgement:  ``This product includes software developed by the
                     12:  * University of California, Berkeley and its contributors'' in the
                     13:  * documentation or other materials provided with the distribution and in
                     14:  * all advertising materials mentioning features or use of this software.
                     15:  * Neither the name of the University nor the names of its contributors may
                     16:  * be used to endorse or promote products derived from this software without
                     17:  * specific prior written permission.
                     18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     19:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     20:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     21:  */
                     22: 
                     23: #ifndef lint
                     24: static char sccsid[] = "@(#)operator.c 5.1 (Berkeley) 4/16/90";
                     25: #endif /* not lint */
                     26: 
                     27: #include <sys/types.h>
                     28: #include <stdio.h>
                     29: #include "find.h"
                     30:     
                     31: /*
                     32:  * find_yanknode --
                     33:  *     destructively removes the top from the plan
                     34:  */
                     35: PLAN *
                     36: find_yanknode(planp)    
                     37:        PLAN **planp;           /* pointer to top of plan (modified) */
                     38: {
                     39:        PLAN *node;             /* top node removed from the plan */
                     40:     
                     41:        if ((node = (*planp)) == NULL)
                     42:                return(NULL);
                     43:        (*planp) = (*planp)->next;
                     44:        node->next = NULL;
                     45:        return(node);
                     46: }
                     47:  
                     48: /*
                     49:  * find_yankexpr --
                     50:  *     Removes one expression from the plan.  This is used mainly by
                     51:  *     find_squish_paren.  In comments below, an expression is either
                     52:  *     a simple node or a T_EXPR node containing a list of simple nodes.
                     53:  */
                     54: PLAN *
                     55: find_yankexpr(planp)    
                     56:        PLAN **planp;           /* pointer to top of plan (modified) */
                     57: {
                     58:        register PLAN *next;    /* temp node holding subexpression results */
                     59:        PLAN *node;             /* pointer to returned node or expression */
                     60:        PLAN *tail;             /* pointer to tail of subplan */
                     61:        PLAN *subplan;          /* pointer to head of ( ) expression */
                     62:        int f_expr();
                     63:     
                     64:        /* first pull the top node from the plan */
                     65:        if ((node = find_yanknode(planp)) == NULL)
                     66:                return(NULL);
                     67:     
                     68:        /*
                     69:         * If the node is an '(' then we recursively slurp up expressions
                     70:         * until we find its associated ')'.  If it's a closing paren we
                     71:         * just return it and unwind our recursion; all other nodes are
                     72:         * complete expressions, so just return them.
                     73:         */
                     74:        if (node->type == T_OPENPAREN)
                     75:                for (tail = subplan = NULL;;) {
                     76:                        if ((next = find_yankexpr(planp)) == NULL)
                     77:                                bad_arg("(", "missing closing ')'");
                     78:                        /*
                     79:                         * If we find a closing ')' we store the collected
                     80:                         * subplan in our '(' node and convert the node to
                     81:                         * a T_EXPR.  The ')' we found is ignored.  Otherwise,
                     82:                         * we just continue to add whatever we get to our
                     83:                         * subplan.
                     84:                         */
                     85:                        if (next->type == T_CLOSEPAREN) {
                     86:                                if (subplan == NULL)
                     87:                                        bad_arg("()", "empty inner expression");
                     88:                                node->p_data[0] = subplan;
                     89:                                node->type = T_EXPR;
                     90:                                node->eval = f_expr;
                     91:                                break;
                     92:                        } else {
                     93:                                if (subplan == NULL)
                     94:                                        tail = subplan = next;
                     95:                                else {
                     96:                                        tail->next = next;
                     97:                                        tail = next;
                     98:                                }
                     99:                                tail->next = NULL;
                    100:                        }
                    101:                }
                    102:        return(node);
                    103: }
                    104:  
                    105: /*
                    106:  * find_squish_paren --
                    107:  *     replaces "parentheisized" plans in our search plan with "expr" nodes.
                    108:  */
                    109: PLAN *
                    110: find_squish_paren(plan)
                    111:        PLAN *plan;             /* plan with ( ) nodes */
                    112: {
                    113:        register PLAN *expr;    /* pointer to next expression */
                    114:        register PLAN *tail;    /* pointer to tail of result plan */
                    115:        PLAN *result;           /* pointer to head of result plan */
                    116:     
                    117:        result = tail = NULL;
                    118: 
                    119:        /*
                    120:         * the basic idea is to have find_yankexpr do all our work and just
                    121:         * collect it's results together.
                    122:         */
                    123:        while ((expr = find_yankexpr(&plan)) != NULL) {
                    124:                /*
                    125:                 * if we find an unclaimed ')' it means there is a missing
                    126:                 * '(' someplace.
                    127:                 */
                    128:                if (expr->type == T_CLOSEPAREN)
                    129:                        bad_arg(")", "no beginning '('");
                    130: 
                    131:                /* add the expression to our result plan */
                    132:                if (result == NULL)
                    133:                        tail = result = expr;
                    134:                else {
                    135:                        tail->next = expr;
                    136:                        tail = expr;
                    137:                }
                    138:                tail->next = NULL;
                    139:        }
                    140:        return(result);
                    141: }
                    142:  
                    143: /*
                    144:  * find_squish_not --
                    145:  *     compresses "!" expressions in our search plan.
                    146:  */
                    147: PLAN *
                    148: find_squish_not(plan)
                    149:        PLAN *plan;             /* plan to process */
                    150: {
                    151:        register PLAN *next;    /* next node being processed */
                    152:        register PLAN *node;    /* temporary node used in T_NOT processing */
                    153:        register PLAN *tail;    /* pointer to tail of result plan */
                    154:        PLAN *result;           /* pointer to head of result plan */
                    155:     
                    156:        tail = result = next = NULL;
                    157:     
                    158:        while ((next = find_yanknode(&plan)) != NULL) {
                    159:                /*
                    160:                 * if we encounter a ( expression ) then look for nots in
                    161:                 * the expr subplan.
                    162:                 */
                    163:                if (next->type == T_EXPR)
                    164:                        next->p_data[0] = find_squish_not(next->p_data[0]);
                    165: 
                    166:                /*
                    167:                 * if we encounter a not, then snag the next node and place
                    168:                 * it in the not's subplan.  As an optimization we compress
                    169:                 * several not's to zero or one not.
                    170:                 */
                    171:                if (next->type == T_NOT) {
                    172:                        int notlevel = 1;
                    173: 
                    174:                        node = find_yanknode(&plan);
                    175:                        while (node->type == T_NOT) {
                    176:                                ++notlevel;
                    177:                                node = find_yanknode(&plan);
                    178:                        }
                    179:                        if (node == NULL)
                    180:                                bad_arg("!", "no following expression");
                    181:                        if (node->type == T_OR)
                    182:                                bad_arg("!", "nothing between ! and -o");
                    183:                        if (notlevel % 2 != 1)
                    184:                                next = node;
                    185:                        else
                    186:                                next->p_data[0] = node;
                    187:                }
                    188: 
                    189:                /* add the node to our result plan */
                    190:                if (result == NULL)
                    191:                        tail = result = next;
                    192:                else {
                    193:                        tail->next = next;
                    194:                        tail = next;
                    195:                }
                    196:                tail->next = NULL;
                    197:        }
                    198:        return(result);
                    199: }
                    200:  
                    201: /*
                    202:  * find_squish_or --
                    203:  *     compresses -o expressions in our search plan.
                    204:  */
                    205: PLAN *
                    206: find_squish_or(plan)
                    207:        PLAN *plan;             /* plan with ors to be squished */
                    208: {
                    209:        register PLAN *next;    /* next node being processed */
                    210:        register PLAN *tail;    /* pointer to tail of result plan */
                    211:        PLAN *result;           /* pointer to head of result plan */
                    212:     
                    213:        tail = result = next = NULL;
                    214:     
                    215:        while ((next = find_yanknode(&plan)) != NULL) {
                    216:                /*
                    217:                 * if we encounter a ( expression ) then look for or's in
                    218:                 * the expr subplan.
                    219:                 */
                    220:                if (next->type == T_EXPR)
                    221:                        next->p_data[0] = find_squish_or(next->p_data[0]);
                    222: 
                    223:                /* if we encounter a not then look for not's in the subplan */
                    224:                if (next->type == T_NOT)
                    225:                        next->p_data[0] = find_squish_or(next->p_data[0]);
                    226: 
                    227:                /*
                    228:                 * if we encounter an or, then place our collected plan in the
                    229:                 * or's first subplan and then recursively collect the
                    230:                 * remaining stuff into the second subplan and return the or.
                    231:                 */
                    232:                if (next->type == T_OR) {
                    233:                        if (result == NULL)
                    234:                                bad_arg("-o", "no expression before -o");
                    235:                        next->p_data[0] = result;
                    236:                        next->p_data[1] = find_squish_or(plan);
                    237:                        if (next->p_data[1] == NULL)
                    238:                                bad_arg("-o", "no expression after -o");
                    239:                        return(next);
                    240:                }
                    241: 
                    242:                /* add the node to our result plan */
                    243:                if (result == NULL)
                    244:                        tail = result = next;
                    245:                else {
                    246:                        tail->next = next;
                    247:                        tail = next;
                    248:                }
                    249:                tail->next = NULL;
                    250:        }
                    251:        return(result);
                    252: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.