summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2011-11-27 18:54:01 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2011-11-27 18:54:01 +0000
commitdd0e5f88129e79f476e873d84e50a2df6c0fb422 (patch)
tree2d2b5131656fc873d94e534c9f43e52d1c4a04f8
parent9c9b2be283f5e152e4043a33013ba3f871580670 (diff)
downloadmandoc-dd0e5f88129e79f476e873d84e50a2df6c0fb422.tar.gz
Get us a whatis(1) mode for apropos(1).
This is from a patch to tech@ as critiqued by schwarze@, checked in to get the ball rolling.
-rw-r--r--apropos.c20
-rw-r--r--apropos_db.c46
-rw-r--r--apropos_db.h1
-rw-r--r--whatis.1118
4 files changed, 176 insertions, 9 deletions
diff --git a/apropos.c b/apropos.c
index 8ba45765..95c92d03 100644
--- a/apropos.c
+++ b/apropos.c
@@ -38,7 +38,7 @@ static char *progname;
int
main(int argc, char *argv[])
{
- int ch, rc;
+ int ch, rc, whatis;
struct manpaths paths;
size_t terms;
struct opts opts;
@@ -53,12 +53,13 @@ main(int argc, char *argv[])
else
++progname;
+ whatis = 0 == strcmp(progname, "whatis");
+
memset(&paths, 0, sizeof(struct manpaths));
memset(&opts, 0, sizeof(struct opts));
auxpaths = defpaths = NULL;
e = NULL;
- rc = 0;
while (-1 != (ch = getopt(argc, argv, "M:m:S:s:")))
switch (ch) {
@@ -76,20 +77,23 @@ main(int argc, char *argv[])
break;
default:
usage();
- goto out;
+ return(EXIT_FAILURE);
}
argc -= optind;
argv += optind;
- if (0 == argc) {
- rc = 1;
- goto out;
- }
+ if (0 == argc)
+ return(EXIT_SUCCESS);
+
+ rc = 0;
manpath_parse(&paths, defpaths, auxpaths);
- if (NULL == (e = exprcomp(argc, argv, &terms))) {
+ e = whatis ? termcomp(argc, argv, &terms) :
+ exprcomp(argc, argv, &terms);
+
+ if (NULL == e) {
fprintf(stderr, "%s: Bad expression\n", progname);
goto out;
}
diff --git a/apropos_db.c b/apropos_db.c
index fd302d87..7a423083 100644
--- a/apropos_db.c
+++ b/apropos_db.c
@@ -579,6 +579,50 @@ recfree(struct rec *rec)
free(rec->matches);
}
+/*
+ * Compile a list of straight-up terms.
+ * The arguments are re-written into ~[[:<:]]term[[:>:]], or "term"
+ * surrounded by word boundaries, then pumped through exprterm().
+ * Terms are case-insensitive.
+ * This emulates whatis(1) behaviour.
+ */
+struct expr *
+termcomp(int argc, char *argv[], size_t *tt)
+{
+ char *buf;
+ int pos;
+ struct expr *e, *next;
+ size_t sz;
+
+ buf = NULL;
+ e = NULL;
+ *tt = 0;
+
+ for (pos = 0; pos < argc; pos++) {
+ sz = strlen(argv[pos]) + 16;
+ buf = mandoc_realloc(buf, sz);
+ strlcpy(buf, "~[[:<:]]", sz);
+ strlcat(buf, argv[pos], sz);
+ strlcat(buf, "[[:>:]]", sz);
+ if (NULL == (next = exprterm(buf, 0))) {
+ free(buf);
+ exprfree(e);
+ return(NULL);
+ }
+ if (NULL != e)
+ e->next = next;
+ e = next;
+ (*tt)++;
+ }
+
+ free(buf);
+ return(e);
+}
+
+/*
+ * Compile a sequence of logical expressions.
+ * See apropos.1 for a grammar of this sequence.
+ */
struct expr *
exprcomp(int argc, char *argv[], size_t *tt)
{
@@ -729,7 +773,7 @@ exprterm(char *buf, int cs)
e.mask = TYPE_Nm | TYPE_Nd;
if (e.regex) {
- i = REG_EXTENDED | REG_NOSUB | cs ? 0 : REG_ICASE;
+ i = REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE);
if (regcomp(&e.re, e.v, i))
return(NULL);
}
diff --git a/apropos_db.h b/apropos_db.h
index 3e0b347b..2591d87e 100644
--- a/apropos_db.h
+++ b/apropos_db.h
@@ -45,6 +45,7 @@ int apropos_search(int, char **, const struct opts *,
void (*)(struct res *, size_t, void *));
struct expr *exprcomp(int, char *[], size_t *);
void exprfree(struct expr *);
+struct expr *termcomp(int, char *[], size_t *);
__END_DECLS
diff --git a/whatis.1 b/whatis.1
new file mode 100644
index 00000000..9415e265
--- /dev/null
+++ b/whatis.1
@@ -0,0 +1,118 @@
+.\" $Id$
+.\"
+.\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate$
+.Dt WHATIS 1
+.Os
+.Sh NAME
+.Nm whatis
+.Nd search manual page databases
+.Sh SYNOPSIS
+.Nm
+.Op Fl M Ar manpath
+.Op Fl m Ar manpath
+.Op Fl S Ar arch
+.Op Fl s Ar section
+.Ar term...
+.Sh DESCRIPTION
+The
+.Nm
+utility searches for manuals named or described with
+.Ar term
+in manual page databases generated by
+.Xr mandocdb 8 .
+Its arguments are as follows:
+.Bl -tag -width Ds
+.It Fl M Ar manpath
+Use the colon-separated path instead of the default list of paths
+searched for
+.Xr mandocdb 8
+databases.
+Invalid paths, or paths without manual databases, are ignored.
+.It Fl m Ar manpath
+Prepend the colon-separated paths to the list of paths searched
+for
+.Xr mandocdb 8
+databases.
+Invalid paths, or paths without manual databases, are ignored.
+.It Fl S Ar arch
+Search only for a particular architecture.
+.It Fl s Ar cat
+Search only for a manual section.
+See
+.Xr man 1
+for a listing of manual sections.
+.El
+.Pp
+By default,
+.Nm
+searches for
+.Xr mandocdb 8
+databases in the default paths stipulated by
+.Xr man 1 .
+Results are sorted by manual title, with output formatted as
+.Pp
+.D1 title(sec) \- description
+.Pp
+Where
+.Qq title
+is the manual's title (note multiple manual names may exist for one
+title),
+.Qq sec
+is the manual section, and
+.Qq description
+is the manual's short description.
+If an architecture is specified for the manual, it is displayed as
+.Pp
+.D1 title(cat/arch) \- description
+.Pp
+Resulting manuals may be accessed as
+.Pp
+.Dl $ man \-s sec title
+.Pp
+If an architecture is specified in the output, use
+.Pp
+.Dl $ man \-s sec \-S arch title
+.Pp
+.Nm
+is identical to running
+.Xr apropos 1
+as follows:
+.Pp
+.Dl $ apropos -- -i '~[[:<:]]term[[:>:]]'
+.Sh ENVIRONMENT
+.Bl -tag -width Ds
+.It Ev MANPATH
+Colon-separated paths overriding the default list of paths searched for
+manual databases.
+Invalid paths, or paths without manual databases, are ignored.
+Overridden by
+.Fl M .
+.El
+.\" .Sh FILES
+.Sh EXIT STATUS
+.Ex -std
+.Sh SEE ALSO
+.Xr apropos 1 ,
+.Xr man 1 ,
+.Xr mandoc 1 ,
+.Xr mandocdb 8
+.Sh AUTHORS
+The
+.Nm
+utility was written by
+.An Kristaps Dzonsons ,
+.Mt kristaps@bsd.lv .