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 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)option.c 5.11 (Berkeley) 08/21/91"; 13 #endif /* not lint */ 14 15 #include <sys/types.h> 16 #include <sys/stat.h> 17 #include <fts.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include "find.h" 22 23 typedef struct _option { 24 char *name; /* option name */ 25 enum ntype token; /* token type */ 26 PLAN *(*create)(); /* create function */ 27 #define O_NONE 0x01 /* no call required */ 28 #define O_ZERO 0x02 /* pass: nothing */ 29 #define O_ARGV 0x04 /* pass: argv, increment argv */ 30 #define O_ARGVP 0x08 /* pass: *argv, N_OK || N_EXEC */ 31 int flags; 32 } OPTION; 33 34 /* NB: the following table must be sorted lexically. */ 35 static OPTION options[] = { 36 "!", N_NOT, c_not, O_ZERO, 37 "(", N_OPENPAREN, c_openparen, O_ZERO, 38 ")", N_CLOSEPAREN, c_closeparen, O_ZERO, 39 "-a", N_AND, NULL, O_NONE, 40 "-and", N_AND, NULL, O_NONE, 41 "-atime", N_ATIME, c_atime, O_ARGV, 42 "-ctime", N_CTIME, c_ctime, O_ARGV, 43 "-depth", N_DEPTH, c_depth, O_ZERO, 44 "-exec", N_EXEC, c_exec, O_ARGVP, 45 "-follow", N_FOLLOW, c_follow, O_ZERO, 46 "-fstype", N_FSTYPE, c_fstype, O_ARGV, 47 "-group", N_GROUP, c_group, O_ARGV, 48 "-inum", N_INUM, c_inum, O_ARGV, 49 "-links", N_LINKS, c_links, O_ARGV, 50 "-ls", N_LS, c_ls, O_ZERO, 51 "-mtime", N_MTIME, c_mtime, O_ARGV, 52 "-name", N_NAME, c_name, O_ARGV, 53 "-newer", N_NEWER, c_newer, O_ARGV, 54 "-nogroup", N_NOGROUP, c_nogroup, O_ZERO, 55 "-nouser", N_NOUSER, c_nouser, O_ZERO, 56 "-o", N_OR, c_or, O_ZERO, 57 "-ok", N_OK, c_exec, O_ARGVP, 58 "-or", N_OR, c_or, O_ZERO, 59 "-path", N_PATH, c_path, O_ARGV, 60 "-perm", N_PERM, c_perm, O_ARGV, 61 "-print", N_PRINT, c_print, O_ZERO, 62 "-prune", N_PRUNE, c_prune, O_ZERO, 63 "-size", N_SIZE, c_size, O_ARGV, 64 "-type", N_TYPE, c_type, O_ARGV, 65 "-user", N_USER, c_user, O_ARGV, 66 "-xdev", N_XDEV, c_xdev, O_ZERO, 67 }; 68 69 /* 70 * find_create -- 71 * create a node corresponding to a command line argument. 72 * 73 * TODO: 74 * add create/process function pointers to node, so we can skip 75 * this switch stuff. 76 */ 77 PLAN * 78 find_create(argvp) 79 char ***argvp; 80 { 81 register OPTION *p; 82 PLAN *new; 83 char **argv; 84 OPTION *option(); 85 86 argv = *argvp; 87 88 if ((p = option(*argv)) == NULL) { 89 (void)fprintf(stderr, "find: unknown option %s.\n", *argv); 90 exit(1); 91 } 92 ++argv; 93 if (p->flags & (O_ARGV|O_ARGVP) && !*argv) { 94 (void)fprintf(stderr, 95 "find: %s requires additional arguments.\n", *--argv); 96 exit(1); 97 } 98 99 switch(p->flags) { 100 case O_NONE: 101 new = NULL; 102 break; 103 case O_ZERO: 104 new = (p->create)(); 105 break; 106 case O_ARGV: 107 new = (p->create)(*argv++); 108 break; 109 case O_ARGVP: 110 new = (p->create)(&argv, p->token == N_OK); 111 break; 112 } 113 *argvp = argv; 114 return(new); 115 } 116 117 OPTION * 118 option(name) 119 char *name; 120 { 121 OPTION tmp; 122 int typecompare __P((const void *, const void *)); 123 124 tmp.name = name; 125 return((OPTION *)bsearch(&tmp, options, 126 sizeof(options)/sizeof(OPTION), sizeof(OPTION), typecompare)); 127 } 128 129 typecompare(a, b) 130 const void *a, *b; 131 { 132 return(strcmp(((OPTION *)a)->name, ((OPTION *)b)->name)); 133 } 134