Return to apropos.c CVS log | Up to [cvsweb.bsd.lv] / mandoc |
version 1.9, 2011/11/09 10:53:48 | version 1.14, 2011/11/18 07:02:19 | ||
---|---|---|---|
|
|
||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | */ | ||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
#include <assert.h> | #include <assert.h> | ||
#include <getopt.h> | #include <getopt.h> | ||
#include <limits.h> | #include <limits.h> | ||
|
|
||
#include <stdlib.h> | #include <stdlib.h> | ||
#include <string.h> | #include <string.h> | ||
#include "apropos.h" | #include "apropos_db.h" | ||
#include "mandoc.h" | #include "mandoc.h" | ||
struct type { | |||
int mask; | |||
const char *name; /* command-line type name */ | |||
}; | |||
static const struct type types[] = { | |||
{ TYPE_NAME, "name" }, | |||
{ TYPE_FUNCTION, "func" }, | |||
{ TYPE_UTILITY, "utility" }, | |||
{ TYPE_INCLUDES, "incl" }, | |||
{ TYPE_VARIABLE, "var" }, | |||
{ TYPE_STANDARD, "stand" }, | |||
{ TYPE_AUTHOR, "auth" }, | |||
{ TYPE_CONFIG, "conf" }, | |||
{ TYPE_DESC, "desc" }, | |||
{ TYPE_XREF, "xref" }, | |||
{ TYPE_PATH, "path" }, | |||
{ TYPE_ENV, "env" }, | |||
{ TYPE_ERR, "err" }, | |||
{ INT_MAX, "all" }, | |||
{ 0, NULL } | |||
}; | |||
static int cmp(const void *, const void *); | static int cmp(const void *, const void *); | ||
static void list(struct rec *, size_t, void *); | static void list(struct res *, size_t, void *); | ||
static void usage(void); | static void usage(void); | ||
static char *progname; | static char *progname; | ||
|
|
||
int | int | ||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||
{ | { | ||
int ch, i; | int ch; | ||
char *q, *v; | size_t terms; | ||
struct opts opts; | struct opts opts; | ||
struct expr *e; | |||
extern int optind; | extern int optind; | ||
extern char *optarg; | extern char *optarg; | ||
memset(&opts, 0, sizeof(struct opts)); | memset(&opts, 0, sizeof(struct opts)); | ||
q = NULL; | |||
progname = strrchr(argv[0], '/'); | progname = strrchr(argv[0], '/'); | ||
if (progname == NULL) | if (progname == NULL) | ||
progname = argv[0]; | progname = argv[0]; | ||
else | else | ||
++progname; | ++progname; | ||
while (-1 != (ch = getopt(argc, argv, "S:s:It:"))) | while (-1 != (ch = getopt(argc, argv, "S:s:"))) | ||
switch (ch) { | switch (ch) { | ||
case ('S'): | case ('S'): | ||
opts.arch = optarg; | opts.arch = optarg; | ||
|
|
||
case ('s'): | case ('s'): | ||
opts.cat = optarg; | opts.cat = optarg; | ||
break; | break; | ||
case ('I'): | |||
opts.flags |= OPTS_INSENS; | |||
break; | |||
case ('t'): | |||
while (NULL != (v = strsep(&optarg, ","))) { | |||
if ('\0' == *v) | |||
continue; | |||
for (i = 0; types[i].mask; i++) { | |||
if (strcmp(types[i].name, v)) | |||
continue; | |||
break; | |||
} | |||
if (0 == types[i].mask) | |||
break; | |||
opts.types |= types[i].mask; | |||
} | |||
if (NULL == v) | |||
break; | |||
fprintf(stderr, "%s: Bad type\n", v); | |||
return(EXIT_FAILURE); | |||
default: | default: | ||
usage(); | usage(); | ||
return(EXIT_FAILURE); | return(EXIT_FAILURE); | ||
|
|
||
argc -= optind; | argc -= optind; | ||
argv += optind; | argv += optind; | ||
if (0 == argc || '\0' == **argv) { | if (0 == argc) | ||
usage(); | |||
return(EXIT_SUCCESS); | return(EXIT_SUCCESS); | ||
} else | |||
q = *argv; | |||
if (0 == opts.types) | if (NULL == (e = exprcomp(argc, argv, &terms))) { | ||
opts.types = TYPE_NAME | TYPE_DESC; | fprintf(stderr, "Bad expression\n"); | ||
return(EXIT_FAILURE); | |||
} | |||
/* | /* | ||
* Configure databases. | * Configure databases. | ||
|
|
||
* The index database is a recno. | * The index database is a recno. | ||
*/ | */ | ||
apropos_search(&opts, q, NULL, list); | ch = apropos_search(&opts, e, terms, NULL, list); | ||
return(EXIT_SUCCESS); | exprfree(e); | ||
if (0 == ch) | |||
fprintf(stderr, "%s: Database error\n", progname); | |||
return(ch ? EXIT_SUCCESS : EXIT_FAILURE); | |||
} | } | ||
/* ARGSUSED */ | /* ARGSUSED */ | ||
static void | static void | ||
list(struct rec *res, size_t sz, void *arg) | list(struct res *res, size_t sz, void *arg) | ||
{ | { | ||
int i; | int i; | ||
qsort(res, sz, sizeof(struct rec), cmp); | qsort(res, sz, sizeof(struct res), cmp); | ||
for (i = 0; i < (int)sz; i++) | for (i = 0; i < (int)sz; i++) | ||
printf("%s(%s%s%s) - %s\n", res[i].title, | printf("%s(%s%s%s) - %s\n", res[i].title, | ||
|
|
||
cmp(const void *p1, const void *p2) | cmp(const void *p1, const void *p2) | ||
{ | { | ||
return(strcmp(((const struct rec *)p1)->title, | return(strcmp(((const struct res *)p1)->title, | ||
((const struct rec *)p2)->title)); | ((const struct res *)p2)->title)); | ||
} | } | ||
static void | static void | ||
usage(void) | usage(void) | ||
{ | { | ||
fprintf(stderr, "usage: %s " | fprintf(stderr, "usage: %s [-S arch] [-s section] " | ||
"[-I] " | "expression...\n", progname); | ||
"[-S arch] " | |||
"[-s section] " | |||
"[-t type[,...]] " | |||
"key\n", progname); | |||
} | } |