Annotation of mandoc/mansearch.3, Revision 1.4
1.4 ! schwarze 1: .\" $Id: mansearch.3,v 1.3 2014/12/12 21:44:33 schwarze Exp $
1.1 schwarze 2: .\"
3: .\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
4: .\"
5: .\" Permission to use, copy, modify, and distribute this software for any
6: .\" purpose with or without fee is hereby granted, provided that the above
7: .\" copyright notice and this permission notice appear in all copies.
8: .\"
9: .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: .\"
1.4 ! schwarze 17: .Dd $Mdocdate: December 12 2014 $
1.1 schwarze 18: .Dt MANSEARCH 3
19: .Os
20: .Sh NAME
21: .Nm mansearch ,
22: .Nm mansearch_setup
23: .Nd search manual page databases
24: .Sh SYNOPSIS
1.2 schwarze 25: .In stdint.h
1.4 ! schwarze 26: .In manconf.h
1.1 schwarze 27: .In mansearch.h
28: .Ft int
29: .Fo mansearch_setup
30: .Fa "int start"
31: .Fc
32: .Ft int
33: .Fo mansearch
34: .Fa "const struct mansearch *search"
35: .Fa "const struct manpaths *paths"
36: .Fa "int argc"
37: .Fa "char *argv[]"
38: .Fa "const char *outkey"
39: .Fa "struct manpage **res"
40: .Fa "size_t *sz"
41: .Fc
42: .Sh DESCRIPTION
43: The
44: .Fn mansearch
45: function returns information about manuals matching a search query from a
46: .Xr mandoc.db 5
47: SQLite3 database.
48: .Pp
49: The query arguments are as follows:
50: .Bl -tag -width Ds
51: .It Fa "const struct mansearch *search"
52: Search options, defined in
53: .In mansearch.h .
54: .It Fa "const struct manpaths *paths"
55: Directories to be searched, defined in
1.4 ! schwarze 56: .In manconf.h .
1.1 schwarze 57: .It Fa "int argc" , "char *argv[]"
58: Search criteria, usually taken from the command line.
59: .El
60: .Pp
61: The
62: .Fa "const char *outkey"
63: selects which data to return in the
64: .Va output
65: field of the
66: .Fa res
67: structures.
68: It takes any of the macro keys defined in
69: .Pa mansearch_const.c
70: and described in
71: .Xr apropos 1 .
72: .Pp
73: The output arguments are as follows:
74: .Bl -tag -width Ds
75: .It Fa "struct manpage **res"
76: Returns a pointer to an array of result structures defined in
77: .In mansearch.h .
78: The user is expected to call
79: .Xr free 3
80: on the
81: .Va file ,
82: .Va names ,
83: and
84: .Va output
85: fields of all structures, as well as the
86: .Fa res
87: array itself.
88: .It Fa "size_t *sz"
89: Returns the number of result structures contained in
90: .Fa res .
91: .El
92: .Pp
93: To speed up searches, the
94: .Fn mansearch_setup
95: function can optionally be called with a
96: .Fa start
97: argument of 1 before
98: .Fn mansearch
99: to set up an SQLite3 pagecache.
100: If it was called, it has to be called again with a
101: .Fa start
102: argument of 0 after the last call to
103: .Fn mansearch
104: to release the memory used for the pagecache.
105: .Sh IMPLEMENTATION NOTES
106: For each manual page tree, the search is done in two steps.
107: In the first step, a list of pages matching the search criteria is built.
108: In the second step, the requested information about these pages is
109: retrieved from the database and assembled into the
110: .Fa res
111: array.
112: .Pp
113: All function mentioned here are defined in the file
114: .Pa mansearch.c .
115: No functions except
116: .Fn mansearch
117: and
118: .Fn sql_statement
119: build any SQL code, and no functions except
120: .Fn mansearch ,
121: .Fn buildnames ,
122: and
123: .Fn buildoutput
124: execute it.
125: .Ss Finding matches
126: The query is built using the following grammar:
127: .Bd -literal -offset indent
128: <query> ::= "SELECT * FROM mpages WHERE" <condition>
129: <condition> ::= "(" <condition> ")" |
130: <condition> "OR" <condition> |
131: <condition> "AND" <condition> |
132: "desc" <operator> "?" |
133: "id IN (SELECT pageid FROM" <subquery> ")"
134: <subquery> ::= "names WHERE name" <operator> "?" |
135: "keys WHERE key" <operator> "? AND bits & ?"
136: <operator> ::= "MATCH" | "REGEXP"
137: .Ed
138: .Pp
139: The MATCH and REGEXP operators are implemented by the functions
140: .Fn sql_match
141: and
142: .Fn sql_regexp ,
143: respectively.
144: This is required because SQLite3 natively neither supports
145: case-insensitive substring matching nor regular expression matching,
146: but only string identity, shell globbing, and the weird home-brewed
147: LIKE operator.
148: .Pp
149: Command line parsing is done by the function
150: .Fn exprcomp
151: building a singly linked list of
152: .Vt expr
153: structures, using the helper functions
154: .Fn exprterm
155: and
156: .Fn exprspec .
157: The resulting SQL statement is assembled by the function
158: .Fn sql_statement
159: and evaluated in the main loop of the
160: .Fn mansearch
161: function.
162: .Ss Assembling the results
163: The names, sections, and architectures of the manuals found
164: are assembled into the
165: .Va names
166: field of the result structure by the function
167: .Fn buildnames ,
168: using the following query:
169: .Pp
170: .Dl "SELECT * FROM mlinks WHERE pageid=? ORDER BY sec, arch, name"
171: .Pp
172: If the
173: .Fa outkey
174: differs from
1.3 schwarze 175: .Qq Ic \&Nd ,
1.1 schwarze 176: the requested output data is assembled into the
177: .Va output
178: field of the result structure by the function
179: .Fn buildoutput ,
180: using the following query:
181: .Pp
182: .Dl "SELECT * FROM keys WHERE pageid=? AND bits & ?"
183: .Sh FILES
184: .Bl -tag -width mandoc.db -compact
185: .It Pa mandoc.db
186: The manual page database.
187: .El
188: .Sh EXAMPLES
189: The simplest invocation
190: .Pp
191: .Dl apropos keyword
192: .Pp
193: results in the following SQL query:
194: .Bd -literal
195: SELECT * FROM mpages WHERE (
196: id IN (SELECT pageid FROM names WHERE name MATCH 'keyword') OR
197: desc MATCH 'keyword'
198: );
199: .Ed
200: .Pp
201: A more complicated request like
202: .Pp
203: .Dl apropos -s 2 Nm,Xr=getuid
204: .Pp
205: results in:
206: .Bd -literal
207: SELECT * FROM mpages WHERE (
208: id IN (SELECT pageid FROM names WHERE name MATCH 'getuid') OR
209: id IN (SELECT pageid FROM keys WHERE key MATCH 'getuid' AND bits & 4)
210: ) AND id IN (SELECT pageid FROM keys WHERE key REGEXP '^2$' AND bits & 2);
211: .Ed
212: .Sh SEE ALSO
213: .Xr apropos 1 ,
214: .Xr mandoc.db 5 ,
215: .Xr makewhatis 8
216: .Sh HISTORY
217: The
218: .Fn mansearch
219: subsystem first appeared in
220: .Ox 5.6 .
221: .Sh AUTHORS
222: .An -nosplit
223: A module to search manual page databases was first written by
224: .An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
225: in 2011, at first using the Berkeley DB;
226: he rewrote it for SQLite3 in 2012.
227: The current version received major changes from
228: .An Ingo Schwarze Aq Mt schwarze@openbsd.org .
CVSweb