From 905febe44eb2b872425a1c4331184e02d4ab7e52 Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Fri, 8 Jun 2012 10:47:17 +0000 Subject: Remove lint from Makefile. Disable some parts of the build (man.cgi, etc.) while sqlite3 is being merged in nice and slow. Remove the bit swapping stuff in config.h.post. Remove apropos_db (replaced by mansearch). --- Makefile | 280 +++---------------- apropos_db.c | 879 ---------------------------------------------------------- apropos_db.h | 73 ----- config.h.post | 14 - 4 files changed, 41 insertions(+), 1205 deletions(-) delete mode 100644 apropos_db.c delete mode 100644 apropos_db.h diff --git a/Makefile b/Makefile index 304237b4..96832d5c 100644 --- a/Makefile +++ b/Makefile @@ -24,9 +24,8 @@ VDATE = 23 March 2012 CFLAGS += -DUSE_WCHAR # If your system has manpath(1), uncomment this. This is most any -# system that's not OpenBSD or NetBSD. If uncommented, apropos(1), -# mandocdb(8), and man.cgi will popen(3) manpath(1) to get the MANPATH -# variable. +# system that's not OpenBSD or NetBSD. If uncommented, manpage(1) and +# mandocdb(8) will use manpath(1) to get the MANPATH variable. #CFLAGS += -DUSE_MANPATH # If your system supports static binaries only, uncomment this. This @@ -34,7 +33,7 @@ CFLAGS += -DUSE_WCHAR # requires -pthreads for static libdb). STATIC = -static -CFLAGS += -g -DHAVE_CONFIG_H -DVERSION="\"$(VERSION)\"" +CFLAGS += -I/usr/local/include -g -DHAVE_CONFIG_H -DVERSION="\"$(VERSION)\"" CFLAGS += -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings PREFIX = /usr/local WWWPREFIX = /var/www @@ -52,29 +51,17 @@ INSTALL_LIB = $(INSTALL) -m 0644 INSTALL_SOURCE = $(INSTALL) -m 0644 INSTALL_MAN = $(INSTALL_DATA) -# Non-BSD systems (Linux, etc.) need -ldb to compile mandocdb and -# apropos. -# However, if you don't have -ldb at all (or it's not native), then -# comment out apropos and mandocdb. -# -#DBLIB = -ldb -DBBIN = apropos mandocdb man.cgi catman whatis -DBLN = llib-lapropos.ln llib-lmandocdb.ln llib-lman.cgi.ln llib-lcatman.ln +DBLIB = -L/usr/local/lib -lsqlite3 +DBBIN = mandocdb manpage apropos all: mandoc preconv demandoc $(DBBIN) SRCS = Makefile \ TODO \ - apropos.1 \ - apropos.c \ - apropos_db.c \ - apropos_db.h \ arch.c \ arch.in \ att.c \ att.in \ - catman.8 \ - catman.c \ cgi.c \ chars.c \ chars.in \ @@ -106,7 +93,6 @@ SRCS = Makefile \ main.h \ man.7 \ man.c \ - man.cgi.7 \ man-cgi.css \ man.h \ man_hash.c \ @@ -166,17 +152,12 @@ SRCS = Makefile \ test-strptime.c \ tree.c \ vol.c \ - vol.in \ - whatis.1 + vol.in LIBMAN_OBJS = man.o \ man_hash.o \ man_macro.o \ man_validate.o -LIBMAN_LNS = man.ln \ - man_hash.ln \ - man_macro.ln \ - man_validate.ln LIBMDOC_OBJS = arch.o \ att.o \ @@ -188,16 +169,6 @@ LIBMDOC_OBJS = arch.o \ mdoc_validate.o \ st.o \ vol.o -LIBMDOC_LNS = arch.ln \ - att.ln \ - lib.ln \ - mdoc.ln \ - mdoc_argv.ln \ - mdoc_hash.ln \ - mdoc_macro.ln \ - mdoc_validate.ln \ - st.ln \ - vol.ln LIBROFF_OBJS = eqn.o \ roff.o \ @@ -205,12 +176,6 @@ LIBROFF_OBJS = eqn.o \ tbl_data.o \ tbl_layout.o \ tbl_opts.o -LIBROFF_LNS = eqn.ln \ - roff.ln \ - tbl.ln \ - tbl_data.ln \ - tbl_layout.ln \ - tbl_opts.ln LIBMANDOC_OBJS = $(LIBMAN_OBJS) \ $(LIBMDOC_OBJS) \ @@ -219,52 +184,35 @@ LIBMANDOC_OBJS = $(LIBMAN_OBJS) \ mandoc.o \ msec.o \ read.o -LIBMANDOC_LNS = $(LIBMAN_LNS) \ - $(LIBMDOC_LNS) \ - $(LIBROFF_LNS) \ - chars.ln \ - mandoc.ln \ - msec.ln \ - read.ln COMPAT_OBJS = compat_fgetln.o \ compat_getsubopt.o \ compat_strlcat.o \ compat_strlcpy.o -COMPAT_LNS = compat_fgetln.ln \ - compat_getsubopt.ln \ - compat_strlcat.ln \ - compat_strlcpy.ln - -arch.o arch.ln: arch.in -att.o att.ln: att.in -chars.o chars.ln: chars.in -lib.o lib.ln: lib.in -msec.o msec.ln: msec.in -roff.o roff.ln: predefs.in -st.o st.ln: st.in -vol.o vol.ln: vol.in - -$(LIBMAN_OBJS) $(LIBMAN_LNS): libman.h -$(LIBMDOC_OBJS) $(LIBMDOC_LNS): libmdoc.h -$(LIBROFF_OBJS) $(LIBROFF_LNS): libroff.h -$(LIBMANDOC_OBJS) $(LIBMANDOC_LNS): mandoc.h mdoc.h man.h libmandoc.h config.h - -$(COMPAT_OBJS) $(COMPAT_LNS): config.h + +arch.o: arch.in +att.o: att.in +chars.o: chars.in +lib.o: lib.in +msec.o: msec.in +roff.o: predefs.in +st.o: st.in +vol.o: vol.in + +$(LIBMAN_OBJS): libman.h +$(LIBMDOC_OBJS): libmdoc.h +$(LIBROFF_OBJS): libroff.h +$(LIBMANDOC_OBJS): mandoc.h mdoc.h man.h libmandoc.h config.h +$(COMPAT_OBJS): config.h MANDOC_HTML_OBJS = eqn_html.o \ html.o \ man_html.o \ mdoc_html.o \ tbl_html.o -MANDOC_HTML_LNS = eqn_html.ln \ - html.ln \ - man_html.ln \ - mdoc_html.ln \ - tbl_html.ln +$(MANDOC_HTML_OBJS): html.h MANDOC_MAN_OBJS = mdoc_man.o -MANDOC_MAN_LNS = mdoc_man.ln MANDOC_TERM_OBJS = eqn_term.o \ man_term.o \ @@ -273,13 +221,7 @@ MANDOC_TERM_OBJS = eqn_term.o \ term_ascii.o \ term_ps.o \ tbl_term.o -MANDOC_TERM_LNS = eqn_term.ln \ - man_term.ln \ - mdoc_term.ln \ - term.ln \ - term_ascii.ln \ - term_ps.ln \ - tbl_term.ln +$(MANDOC_TERM_OBJS): term.h MANDOC_OBJS = $(MANDOC_HTML_OBJS) \ $(MANDOC_MAN_OBJS) \ @@ -287,73 +229,24 @@ MANDOC_OBJS = $(MANDOC_HTML_OBJS) \ main.o \ out.o \ tree.o -MANDOC_LNS = $(MANDOC_HTML_LNS) \ - $(MANDOC_MAN_LNS) \ - $(MANDOC_TERM_LNS) \ - main.ln \ - out.ln \ - tree.ln - -$(MANDOC_HTML_OBJS) $(MANDOC_HTML_LNS): html.h -$(MANDOC_TERM_OBJS) $(MANDOC_TERM_LNS): term.h -$(MANDOC_OBJS) $(MANDOC_LNS): main.h mandoc.h mdoc.h man.h config.h out.h +$(MANDOC_OBJS): main.h mandoc.h mdoc.h man.h config.h out.h MANDOCDB_OBJS = mandocdb.o manpath.o -MANDOCDB_LNS = mandocdb.ln manpath.ln - -$(MANDOCDB_OBJS) $(MANDOCDB_LNS): mandocdb.h mandoc.h mdoc.h man.h config.h manpath.h +$(MANDOCDB_OBJS): mandocdb.h mandoc.h mdoc.h man.h config.h manpath.h PRECONV_OBJS = preconv.o -PRECONV_LNS = preconv.ln - -$(PRECONV_OBJS) $(PRECONV_LNS): config.h - -APROPOS_OBJS = apropos.o apropos_db.o manpath.o -APROPOS_LNS = apropos.ln apropos_db.ln manpath.ln - -$(APROPOS_OBJS) $(APROPOS_LNS): config.h mandoc.h apropos_db.h manpath.h mandocdb.h - -CGI_OBJS = $(MANDOC_HTML_OBJS) \ - $(MANDOC_MAN_OBJS) \ - $(MANDOC_TERM_OBJS) \ - cgi.o \ - apropos_db.o \ - manpath.o \ - out.o \ - tree.o - -CGI_LNS = $(MANDOC_HTML_LNS) \ - $(MANDOC_MAN_LNS) \ - $(MANDOC_TERM_LNS) \ - cgi.ln \ - apropos_db.ln \ - manpath.ln \ - out.ln \ - tree.ln - -$(CGI_OBJS) $(CGI_LNS): main.h mdoc.h man.h out.h config.h mandoc.h apropos_db.h manpath.h mandocdb.h +$(PRECONV_OBJS): config.h -CATMAN_OBJS = catman.o manpath.o -CATMAN_LNS = catman.ln manpath.ln +APROPOS_OBJS = apropos.o mansearch.o manpath.o +$(APROPOS_OBJS): config.h manpath.h mandocdb.h mansearch.h -$(CATMAN_OBJS) $(CATMAN_LNS): config.h mandoc.h manpath.h mandocdb.h +MANPAGE_OBJS = manpage.o mansearch.o manpath.o +$(MANPAGE_OBJS): config.h manpath.h mandocdb.h mansearch.h DEMANDOC_OBJS = demandoc.o -DEMANDOC_LNS = demandoc.ln - -$(DEMANDOC_OBJS) $(DEMANDOC_LNS): config.h - -INDEX_MANS = apropos.1.html \ - apropos.1.xhtml \ - apropos.1.ps \ - apropos.1.pdf \ - apropos.1.txt \ - catman.8.html \ - catman.8.xhtml \ - catman.8.ps \ - catman.8.pdf \ - catman.8.txt \ - demandoc.1.html \ +$(DEMANDOC_OBJS): config.h + +INDEX_MANS = demandoc.1.html \ demandoc.1.xhtml \ demandoc.1.ps \ demandoc.1.pdf \ @@ -363,11 +256,6 @@ INDEX_MANS = apropos.1.html \ mandoc.1.ps \ mandoc.1.pdf \ mandoc.1.txt \ - whatis.1.html \ - whatis.1.xhtml \ - whatis.1.ps \ - whatis.1.pdf \ - whatis.1.txt \ mandoc.3.html \ mandoc.3.xhtml \ mandoc.3.ps \ @@ -383,11 +271,6 @@ INDEX_MANS = apropos.1.html \ man.7.ps \ man.7.pdf \ man.7.txt \ - man.cgi.7.html \ - man.cgi.7.xhtml \ - man.cgi.7.ps \ - man.cgi.7.pdf \ - man.cgi.7.txt \ mandoc_char.7.html \ mandoc_char.7.xhtml \ mandoc_char.7.ps \ @@ -430,38 +313,18 @@ INDEX_OBJS = $(INDEX_MANS) \ www: index.html -lint: llib-lmandoc.ln llib-lpreconv.ln llib-ldemandoc.ln $(DBLN) - clean: rm -f libmandoc.a $(LIBMANDOC_OBJS) - rm -f llib-llibmandoc.ln $(LIBMANDOC_LNS) + rm -f apropos $(APROPOS_OBJS) rm -f mandocdb $(MANDOCDB_OBJS) - rm -f llib-lmandocdb.ln $(MANDOCDB_LNS) rm -f preconv $(PRECONV_OBJS) - rm -f llib-lpreconv.ln $(PRECONV_LNS) - rm -f apropos whatis $(APROPOS_OBJS) - rm -f llib-lapropos.ln $(APROPOS_LNS) - rm -f man.cgi $(CGI_OBJS) - rm -f llib-lman.cgi.ln $(CGI_LNS) - rm -f catman $(CATMAN_OBJS) - rm -f llib-lcatman.ln $(CATMAN_LNS) + rm -f manpage $(MANPAGE_OBJS) rm -f demandoc $(DEMANDOC_OBJS) - rm -f llib-ldemandoc.ln $(DEMANDOC_LNS) rm -f mandoc $(MANDOC_OBJS) - rm -f llib-lmandoc.ln $(MANDOC_LNS) - rm -f config.h config.log $(COMPAT_OBJS) $(COMPAT_LNS) - rm -f mdocml.tar.gz mdocml-win32.zip mdocml-win64.zip mdocml-macosx.zip + rm -f config.h config.log $(COMPAT_OBJS) + rm -f mdocml.tar.gz rm -f index.html $(INDEX_OBJS) - rm -rf test-fgetln.dSYM - rm -rf test-strlcpy.dSYM - rm -rf test-strlcat.dSYM - rm -rf test-strptime.dSYM - rm -rf test-mmap.dSYM - rm -rf test-getsubopt.dSYM - rm -rf apropos.dSYM - rm -rf catman.dSYM - rm -rf mandocdb.dSYM - rm -rf whatis.dSYM + rm -rf *.dSYM install: all mkdir -p $(DESTDIR)$(BINDIR) @@ -482,7 +345,7 @@ install: all installcgi: all mkdir -p $(DESTDIR)$(CGIBINDIR) mkdir -p $(DESTDIR)$(HTDOCDIR) - $(INSTALL_PROGRAM) man.cgi $(DESTDIR)$(CGIBINDIR) + #$(INSTALL_PROGRAM) man.cgi $(DESTDIR)$(CGIBINDIR) $(INSTALL_DATA) example.style.css $(DESTDIR)$(HTDOCDIR)/man.css $(INSTALL_DATA) man-cgi.css $(DESTDIR)$(HTDOCDIR) @@ -500,54 +363,24 @@ installwww: www libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS) $(AR) rs $@ $(COMPAT_OBJS) $(LIBMANDOC_OBJS) -llib-llibmandoc.ln: $(COMPAT_LNS) $(LIBMANDOC_LNS) - $(LINT) $(LINTFLAGS) -Clibmandoc $(COMPAT_LNS) $(LIBMANDOC_LNS) - mandoc: $(MANDOC_OBJS) libmandoc.a $(CC) $(LDFLAGS) -o $@ $(MANDOC_OBJS) libmandoc.a -llib-lmandoc.ln: $(MANDOC_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Cmandoc $(MANDOC_LNS) llib-llibmandoc.ln - mandocdb: $(MANDOCDB_OBJS) libmandoc.a $(CC) $(LDFLAGS) -o $@ $(MANDOCDB_OBJS) libmandoc.a $(DBLIB) -llib-lmandocdb.ln: $(MANDOCDB_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Cmandocdb $(MANDOCDB_LNS) llib-llibmandoc.ln - preconv: $(PRECONV_OBJS) $(CC) $(LDFLAGS) -o $@ $(PRECONV_OBJS) -llib-lpreconv.ln: $(PRECONV_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Cpreconv $(PRECONV_LNS) llib-llibmandoc.ln - -whatis: apropos - cp -f apropos whatis +manpage: $(MANPAGE_OBJS) libmandoc.a + $(CC) $(LDFLAGS) -o $@ $(MANPAGE_OBJS) libmandoc.a $(DBLIB) apropos: $(APROPOS_OBJS) libmandoc.a $(CC) $(LDFLAGS) -o $@ $(APROPOS_OBJS) libmandoc.a $(DBLIB) -llib-lapropos.ln: $(APROPOS_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Capropos $(APROPOS_LNS) llib-llibmandoc.ln - -catman: $(CATMAN_OBJS) libmandoc.a - $(CC) $(LDFLAGS) -o $@ $(CATMAN_OBJS) libmandoc.a $(DBLIB) - -llib-lcatman.ln: $(CATMAN_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Ccatman $(CATMAN_LNS) llib-llibmandoc.ln - -man.cgi: $(CGI_OBJS) libmandoc.a - $(CC) $(LDFLAGS) $(STATIC) -o $@ $(CGI_OBJS) libmandoc.a $(DBLIB) - -llib-lman.cgi.ln: $(CGI_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Cman.cgi $(CGI_LNS) llib-llibmandoc.ln - demandoc: $(DEMANDOC_OBJS) libmandoc.a $(CC) $(LDFLAGS) -o $@ $(DEMANDOC_OBJS) libmandoc.a -llib-ldemandoc.ln: $(DEMANDOC_LNS) llib-llibmandoc.ln - $(LINT) $(LINTFLAGS) -Cdemandoc $(DEMANDOC_LNS) llib-llibmandoc.ln - mdocml.md5: mdocml.tar.gz md5 mdocml.tar.gz >$@ @@ -557,37 +390,6 @@ mdocml.tar.gz: $(SRCS) ( cd .dist/ && tar zcf ../$@ ./ ) rm -rf .dist/ -mdocml-win32.zip: $(SRCS) - mkdir -p .win32/mdocml-$(VERSION)/ - $(INSTALL_SOURCE) $(SRCS) .win32 - cp .win32/Makefile .win32/Makefile.old - egrep -v -e DUSE_WCHAR -e ^DBBIN .win32/Makefile.old >.win32/Makefile - ( cd .win32; \ - CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar CFLAGS='-DOSNAME=\"Windows\"' make; \ - make install PREFIX=mdocml-$(VERSION) ; \ - zip -r ../$@ mdocml-$(VERSION) ) - rm -rf .win32 - -mdocml-win64.zip: $(SRCS) - mkdir -p .win64/mdocml-$(VERSION)/ - $(INSTALL_SOURCE) $(SRCS) .win64 - cp .win64/Makefile .win64/Makefile.old - egrep -v -e DUSE_WCHAR -e ^DBBIN .win64/Makefile.old >.win64/Makefile - ( cd .win64; \ - CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar CFLAGS='-DOSNAME=\"Windows\"' make; \ - make install PREFIX=mdocml-$(VERSION) ; \ - zip -r ../$@ mdocml-$(VERSION) ) - rm -rf .win64 - -mdocml-macosx.zip: $(SRCS) - mkdir -p .macosx/mdocml-$(VERSION)/ - $(INSTALL_SOURCE) $(SRCS) .macosx - ( cd .macosx; \ - CFLAGS="-arch i386 -arch x86_64 -arch ppc" LDFLAGS="-arch i386 -arch x86_64 -arch ppc" make; \ - make install PREFIX=mdocml-$(VERSION) ; \ - zip -r ../$@ mdocml-$(VERSION) ) - rm -rf .macosx - index.html: $(INDEX_OBJS) config.h: config.h.pre config.h.post diff --git a/apropos_db.c b/apropos_db.c deleted file mode 100644 index e51b6ef1..00000000 --- a/apropos_db.c +++ /dev/null @@ -1,879 +0,0 @@ -/* $Id: apropos_db.c,v 1.32 2012/03/25 00:48:47 kristaps Exp $ */ -/* - * Copyright (c) 2011, 2012 Kristaps Dzonsons - * Copyright (c) 2011 Ingo Schwarze - * - * 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. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__linux__) -# include -# include -#elif defined(__APPLE__) -# include -# include -#else -# include -#endif - -#include "mandocdb.h" -#include "apropos_db.h" -#include "mandoc.h" - -#define RESFREE(_x) \ - do { \ - free((_x)->file); \ - free((_x)->cat); \ - free((_x)->title); \ - free((_x)->arch); \ - free((_x)->desc); \ - free((_x)->matches); \ - } while (/*CONSTCOND*/0) - -struct expr { - int regex; /* is regex? */ - int index; /* index in match array */ - uint64_t mask; /* type-mask */ - int and; /* is rhs of logical AND? */ - char *v; /* search value */ - regex_t re; /* compiled re, if regex */ - struct expr *next; /* next in sequence */ - struct expr *subexpr; -}; - -struct type { - uint64_t mask; - const char *name; -}; - -struct rectree { - struct res *node; /* record array for dir tree */ - int len; /* length of record array */ -}; - -static const struct type types[] = { - { TYPE_An, "An" }, - { TYPE_Ar, "Ar" }, - { TYPE_At, "At" }, - { TYPE_Bsx, "Bsx" }, - { TYPE_Bx, "Bx" }, - { TYPE_Cd, "Cd" }, - { TYPE_Cm, "Cm" }, - { TYPE_Dv, "Dv" }, - { TYPE_Dx, "Dx" }, - { TYPE_Em, "Em" }, - { TYPE_Er, "Er" }, - { TYPE_Ev, "Ev" }, - { TYPE_Fa, "Fa" }, - { TYPE_Fl, "Fl" }, - { TYPE_Fn, "Fn" }, - { TYPE_Fn, "Fo" }, - { TYPE_Ft, "Ft" }, - { TYPE_Fx, "Fx" }, - { TYPE_Ic, "Ic" }, - { TYPE_In, "In" }, - { TYPE_Lb, "Lb" }, - { TYPE_Li, "Li" }, - { TYPE_Lk, "Lk" }, - { TYPE_Ms, "Ms" }, - { TYPE_Mt, "Mt" }, - { TYPE_Nd, "Nd" }, - { TYPE_Nm, "Nm" }, - { TYPE_Nx, "Nx" }, - { TYPE_Ox, "Ox" }, - { TYPE_Pa, "Pa" }, - { TYPE_Rs, "Rs" }, - { TYPE_Sh, "Sh" }, - { TYPE_Ss, "Ss" }, - { TYPE_St, "St" }, - { TYPE_Sy, "Sy" }, - { TYPE_Tn, "Tn" }, - { TYPE_Va, "Va" }, - { TYPE_Va, "Vt" }, - { TYPE_Xr, "Xr" }, - { UINT64_MAX, "any" }, - { 0, NULL } -}; - -static DB *btree_open(void); -static int btree_read(const DBT *, const DBT *, - const struct mchars *, - uint64_t *, recno_t *, char **); -static int expreval(const struct expr *, int *); -static void exprexec(const struct expr *, - const char *, uint64_t, struct res *); -static int exprmark(const struct expr *, - const char *, uint64_t, int *); -static struct expr *exprexpr(int, char *[], int *, int *, size_t *); -static struct expr *exprterm(char *, int); -static DB *index_open(void); -static int index_read(const DBT *, const DBT *, int, - const struct mchars *, struct res *); -static void norm_string(const char *, - const struct mchars *, char **); -static size_t norm_utf8(unsigned int, char[7]); -static int single_search(struct rectree *, const struct opts *, - const struct expr *, size_t terms, - struct mchars *, int); - -/* - * Open the keyword mandoc-db database. - */ -static DB * -btree_open(void) -{ - BTREEINFO info; - DB *db; - - memset(&info, 0, sizeof(BTREEINFO)); - info.lorder = 4321; - info.flags = R_DUP; - - db = dbopen(MANDOC_DB, O_RDONLY, 0, DB_BTREE, &info); - if (NULL != db) - return(db); - - return(NULL); -} - -/* - * Read a keyword from the database and normalise it. - * Return 0 if the database is insane, else 1. - */ -static int -btree_read(const DBT *k, const DBT *v, const struct mchars *mc, - uint64_t *mask, recno_t *rec, char **buf) -{ - uint64_t vbuf[2]; - - /* Are our sizes sane? */ - if (k->size < 2 || sizeof(vbuf) != v->size) - return(0); - - /* Is our string nil-terminated? */ - if ('\0' != ((const char *)k->data)[(int)k->size - 1]) - return(0); - - norm_string((const char *)k->data, mc, buf); - memcpy(vbuf, v->data, v->size); - *mask = betoh64(vbuf[0]); - *rec = betoh64(vbuf[1]); - return(1); -} - -/* - * Take a Unicode codepoint and produce its UTF-8 encoding. - * This isn't the best way to do this, but it works. - * The magic numbers are from the UTF-8 packaging. - * They're not as scary as they seem: read the UTF-8 spec for details. - */ -static size_t -norm_utf8(unsigned int cp, char out[7]) -{ - int rc; - - rc = 0; - - if (cp <= 0x0000007F) { - rc = 1; - out[0] = (char)cp; - } else if (cp <= 0x000007FF) { - rc = 2; - out[0] = (cp >> 6 & 31) | 192; - out[1] = (cp & 63) | 128; - } else if (cp <= 0x0000FFFF) { - rc = 3; - out[0] = (cp >> 12 & 15) | 224; - out[1] = (cp >> 6 & 63) | 128; - out[2] = (cp & 63) | 128; - } else if (cp <= 0x001FFFFF) { - rc = 4; - out[0] = (cp >> 18 & 7) | 240; - out[1] = (cp >> 12 & 63) | 128; - out[2] = (cp >> 6 & 63) | 128; - out[3] = (cp & 63) | 128; - } else if (cp <= 0x03FFFFFF) { - rc = 5; - out[0] = (cp >> 24 & 3) | 248; - out[1] = (cp >> 18 & 63) | 128; - out[2] = (cp >> 12 & 63) | 128; - out[3] = (cp >> 6 & 63) | 128; - out[4] = (cp & 63) | 128; - } else if (cp <= 0x7FFFFFFF) { - rc = 6; - out[0] = (cp >> 30 & 1) | 252; - out[1] = (cp >> 24 & 63) | 128; - out[2] = (cp >> 18 & 63) | 128; - out[3] = (cp >> 12 & 63) | 128; - out[4] = (cp >> 6 & 63) | 128; - out[5] = (cp & 63) | 128; - } else - return(0); - - out[rc] = '\0'; - return((size_t)rc); -} - -/* - * Normalise strings from the index and database. - * These strings are escaped as defined by mandoc_char(7) along with - * other goop in mandoc.h (e.g., soft hyphens). - * This function normalises these into a nice UTF-8 string. - * Returns 0 if the database is fucked. - */ -static void -norm_string(const char *val, const struct mchars *mc, char **buf) -{ - size_t sz, bsz; - char utfbuf[7]; - const char *seq, *cpp; - int len, u, pos; - enum mandoc_esc esc; - static const char res[] = { '\\', '\t', - ASCII_NBRSP, ASCII_HYPH, '\0' }; - - /* Pre-allocate by the length of the input */ - - bsz = strlen(val) + 1; - *buf = mandoc_realloc(*buf, bsz); - pos = 0; - - while ('\0' != *val) { - /* - * Halt on the first escape sequence. - * This also halts on the end of string, in which case - * we just copy, fallthrough, and exit the loop. - */ - if ((sz = strcspn(val, res)) > 0) { - memcpy(&(*buf)[pos], val, sz); - pos += (int)sz; - val += (int)sz; - } - - if (ASCII_HYPH == *val) { - (*buf)[pos++] = '-'; - val++; - continue; - } else if ('\t' == *val || ASCII_NBRSP == *val) { - (*buf)[pos++] = ' '; - val++; - continue; - } else if ('\\' != *val) - break; - - /* Read past the slash. */ - - val++; - u = 0; - - /* - * Parse the escape sequence and see if it's a - * predefined character or special character. - */ - - esc = mandoc_escape(&val, &seq, &len); - if (ESCAPE_ERROR == esc) - break; - - /* - * XXX - this just does UTF-8, but we need to know - * beforehand whether we should do text substitution. - */ - - switch (esc) { - case (ESCAPE_SPECIAL): - if (0 != (u = mchars_spec2cp(mc, seq, len))) - break; - /* FALLTHROUGH */ - default: - continue; - } - - /* - * If we have a Unicode codepoint, try to convert that - * to a UTF-8 byte string. - */ - - cpp = utfbuf; - if (0 == (sz = norm_utf8(u, utfbuf))) - continue; - - /* Copy the rendered glyph into the stream. */ - - sz = strlen(cpp); - bsz += sz; - - *buf = mandoc_realloc(*buf, bsz); - - memcpy(&(*buf)[pos], cpp, sz); - pos += (int)sz; - } - - (*buf)[pos] = '\0'; -} - -/* - * Open the filename-index mandoc-db database. - * Returns NULL if opening failed. - */ -static DB * -index_open(void) -{ - DB *db; - - db = dbopen(MANDOC_IDX, O_RDONLY, 0, DB_RECNO, NULL); - if (NULL != db) - return(db); - - return(NULL); -} - -/* - * Safely unpack from an index file record into the structure. - * Returns 1 if an entry was unpacked, 0 if the database is insane. - */ -static int -index_read(const DBT *key, const DBT *val, int index, - const struct mchars *mc, struct res *rec) -{ - size_t left; - char *np, *cp; - char type; - -#define INDEX_BREAD(_dst) \ - do { \ - if (NULL == (np = memchr(cp, '\0', left))) \ - return(0); \ - norm_string(cp, mc, &(_dst)); \ - left -= (np - cp) + 1; \ - cp = np + 1; \ - } while (/* CONSTCOND */ 0) - - if (0 == (left = val->size)) - return(0); - - cp = val->data; - assert(sizeof(recno_t) == key->size); - memcpy(&rec->rec, key->data, key->size); - rec->volume = index; - - if ('d' == (type = *cp++)) - rec->type = RESTYPE_MDOC; - else if ('a' == type) - rec->type = RESTYPE_MAN; - else if ('c' == type) - rec->type = RESTYPE_CAT; - else - return(0); - - left--; - INDEX_BREAD(rec->file); - INDEX_BREAD(rec->cat); - INDEX_BREAD(rec->title); - INDEX_BREAD(rec->arch); - INDEX_BREAD(rec->desc); - return(1); -} - -/* - * Search mandocdb databases in paths for expression "expr". - * Filter out by "opts". - * Call "res" with the results, which may be zero. - * Return 0 if there was a database error, else return 1. - */ -int -apropos_search(int pathsz, char **paths, const struct opts *opts, - const struct expr *expr, size_t terms, void *arg, - size_t *sz, struct res **resp, - void (*res)(struct res *, size_t, void *)) -{ - struct rectree tree; - struct mchars *mc; - int i, rc; - - memset(&tree, 0, sizeof(struct rectree)); - - rc = 0; - mc = mchars_alloc(); - *sz = 0; - *resp = NULL; - - /* - * Main loop. Change into the directory containing manpage - * databases. Run our expession over each database in the set. - */ - - for (i = 0; i < pathsz; i++) { - assert('/' == paths[i][0]); - if (chdir(paths[i])) - continue; - if (single_search(&tree, opts, expr, terms, mc, i)) - continue; - - resfree(tree.node, tree.len); - mchars_free(mc); - return(0); - } - - (*res)(tree.node, tree.len, arg); - *sz = tree.len; - *resp = tree.node; - mchars_free(mc); - return(1); -} - -static int -single_search(struct rectree *tree, const struct opts *opts, - const struct expr *expr, size_t terms, - struct mchars *mc, int vol) -{ - int root, leaf, ch; - DBT key, val; - DB *btree, *idx; - char *buf; - struct res *rs; - struct res r; - uint64_t mask; - recno_t rec; - - root = -1; - leaf = -1; - btree = NULL; - idx = NULL; - buf = NULL; - rs = tree->node; - - memset(&r, 0, sizeof(struct res)); - - if (NULL == (btree = btree_open())) - return(1); - - if (NULL == (idx = index_open())) { - (*btree->close)(btree); - return(1); - } - - while (0 == (ch = (*btree->seq)(btree, &key, &val, R_NEXT))) { - if ( ! btree_read(&key, &val, mc, &mask, &rec, &buf)) - break; - - /* - * See if this keyword record matches any of the - * expressions we have stored. - */ - if ( ! exprmark(expr, buf, mask, NULL)) - continue; - - /* - * O(log n) scan for prior records. Since a record - * number is unbounded, this has decent performance over - * a complex hash function. - */ - - for (leaf = root; leaf >= 0; ) - if (rec > rs[leaf].rec && - rs[leaf].rhs >= 0) - leaf = rs[leaf].rhs; - else if (rec < rs[leaf].rec && - rs[leaf].lhs >= 0) - leaf = rs[leaf].lhs; - else - break; - - /* - * If we find a record, see if it has already evaluated - * to true. If it has, great, just keep going. If not, - * try to evaluate it now and continue anyway. - */ - - if (leaf >= 0 && rs[leaf].rec == rec) { - if (0 == rs[leaf].matched) - exprexec(expr, buf, mask, &rs[leaf]); - continue; - } - - /* - * We have a new file to examine. - * Extract the manpage's metadata from the index - * database, then begin partial evaluation. - */ - - key.data = &rec; - key.size = sizeof(recno_t); - - if (0 != (*idx->get)(idx, &key, &val, 0)) - break; - - r.lhs = r.rhs = -1; - if ( ! index_read(&key, &val, vol, mc, &r)) - break; - - /* XXX: this should be elsewhere, I guess? */ - - if (opts->cat && strcasecmp(opts->cat, r.cat)) - continue; - - if (opts->arch && *r.arch) - if (strcasecmp(opts->arch, r.arch)) - continue; - - tree->node = rs = mandoc_realloc - (rs, (tree->len + 1) * sizeof(struct res)); - - memcpy(&rs[tree->len], &r, sizeof(struct res)); - memset(&r, 0, sizeof(struct res)); - rs[tree->len].matches = - mandoc_calloc(terms, sizeof(int)); - - exprexec(expr, buf, mask, &rs[tree->len]); - - /* Append to our tree. */ - - if (leaf >= 0) { - if (rec > rs[leaf].rec) - rs[leaf].rhs = tree->len; - else - rs[leaf].lhs = tree->len; - } else - root = tree->len; - - tree->len++; - } - - (*btree->close)(btree); - (*idx->close)(idx); - - free(buf); - RESFREE(&r); - return(1 == ch); -} - -void -resfree(struct res *rec, size_t sz) -{ - size_t i; - - for (i = 0; i < sz; i++) - RESFREE(&rec[i]); - free(rec); -} - -/* - * 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 = argc - 1; pos >= 0; pos--) { - sz = strlen(argv[pos]) + 18; - buf = mandoc_realloc(buf, sz); - strlcpy(buf, "Nm~[[:<:]]", sz); - strlcat(buf, argv[pos], sz); - strlcat(buf, "[[:>:]]", sz); - if (NULL == (next = exprterm(buf, 0))) { - free(buf); - exprfree(e); - return(NULL); - } - next->next = e; - 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) -{ - int pos, lvl; - struct expr *e; - - pos = lvl = 0; - *tt = 0; - - e = exprexpr(argc, argv, &pos, &lvl, tt); - - if (0 == lvl && pos >= argc) - return(e); - - exprfree(e); - return(NULL); -} - -/* - * Compile an array of tokens into an expression. - * An informal expression grammar is defined in apropos(1). - * Return NULL if we fail doing so. All memory will be cleaned up. - * Return the root of the expression sequence if alright. - */ -static struct expr * -exprexpr(int argc, char *argv[], int *pos, int *lvl, size_t *tt) -{ - struct expr *e, *first, *next; - int log; - - first = next = NULL; - - for ( ; *pos < argc; (*pos)++) { - e = next; - - /* - * Close out a subexpression. - */ - - if (NULL != e && 0 == strcmp(")", argv[*pos])) { - if (--(*lvl) < 0) - goto err; - break; - } - - /* - * Small note: if we're just starting, don't let "-a" - * and "-o" be considered logical operators: they're - * just tokens unless pairwise joining, in which case we - * record their existence (or assume "OR"). - */ - log = 0; - - if (NULL != e && 0 == strcmp("-a", argv[*pos])) - log = 1; - else if (NULL != e && 0 == strcmp("-o", argv[*pos])) - log = 2; - - if (log > 0 && ++(*pos) >= argc) - goto err; - - /* - * Now we parse the term part. This can begin with - * "-i", in which case the expression is case - * insensitive. - */ - - if (0 == strcmp("(", argv[*pos])) { - ++(*pos); - ++(*lvl); - next = mandoc_calloc(1, sizeof(struct expr)); - next->subexpr = exprexpr(argc, argv, pos, lvl, tt); - if (NULL == next->subexpr) { - free(next); - next = NULL; - } - } else if (0 == strcmp("-i", argv[*pos])) { - if (++(*pos) >= argc) - goto err; - next = exprterm(argv[*pos], 0); - } else - next = exprterm(argv[*pos], 1); - - if (NULL == next) - goto err; - - next->and = log == 1; - next->index = (int)(*tt)++; - - /* Append to our chain of expressions. */ - - if (NULL == first) { - assert(NULL == e); - first = next; - } else { - assert(NULL != e); - e->next = next; - } - } - - return(first); -err: - exprfree(first); - return(NULL); -} - -/* - * Parse a terminal expression with the grammar as defined in - * apropos(1). - * Return NULL if we fail the parse. - */ -static struct expr * -exprterm(char *buf, int cs) -{ - struct expr e; - struct expr *p; - char *key; - int i; - - memset(&e, 0, sizeof(struct expr)); - - /* Choose regex or substring match. */ - - if (NULL == (e.v = strpbrk(buf, "=~"))) { - e.regex = 0; - e.v = buf; - } else { - e.regex = '~' == *e.v; - *e.v++ = '\0'; - } - - /* Determine the record types to search for. */ - - e.mask = 0; - if (buf < e.v) { - while (NULL != (key = strsep(&buf, ","))) { - i = 0; - while (types[i].mask && - strcmp(types[i].name, key)) - i++; - e.mask |= types[i].mask; - } - } - if (0 == e.mask) - e.mask = TYPE_Nm | TYPE_Nd; - - if (e.regex) { - i = REG_EXTENDED | REG_NOSUB | (cs ? 0 : REG_ICASE); - if (regcomp(&e.re, e.v, i)) - return(NULL); - } - - e.v = mandoc_strdup(e.v); - - p = mandoc_calloc(1, sizeof(struct expr)); - memcpy(p, &e, sizeof(struct expr)); - return(p); -} - -void -exprfree(struct expr *p) -{ - struct expr *pp; - - while (NULL != p) { - if (p->subexpr) - exprfree(p->subexpr); - if (p->regex) - regfree(&p->re); - free(p->v); - pp = p->next; - free(p); - p = pp; - } -} - -static int -exprmark(const struct expr *p, const char *cp, - uint64_t mask, int *ms) -{ - - for ( ; p; p = p->next) { - if (p->subexpr) { - if (exprmark(p->subexpr, cp, mask, ms)) - return(1); - continue; - } else if ( ! (mask & p->mask)) - continue; - - if (p->regex) { - if (regexec(&p->re, cp, 0, NULL, 0)) - continue; - } else if (NULL == strcasestr(cp, p->v)) - continue; - - if (NULL == ms) - return(1); - else - ms[p->index] = 1; - } - - return(0); -} - -static int -expreval(const struct expr *p, int *ms) -{ - int match; - - /* - * AND has precedence over OR. Analysis is left-right, though - * it doesn't matter because there are no side-effects. - * Thus, step through pairwise ANDs and accumulate their Boolean - * evaluation. If we encounter a single true AND collection or - * standalone term, the whole expression is true (by definition - * of OR). - */ - - for (match = 0; p && ! match; p = p->next) { - /* Evaluate a subexpression, if applicable. */ - if (p->subexpr && ! ms[p->index]) - ms[p->index] = expreval(p->subexpr, ms); - - match = ms[p->index]; - for ( ; p->next && p->next->and; p = p->next) { - /* Evaluate a subexpression, if applicable. */ - if (p->next->subexpr && ! ms[p->next->index]) - ms[p->next->index] = - expreval(p->next->subexpr, ms); - match = match && ms[p->next->index]; - } - } - - return(match); -} - -/* - * First, update the array of terms for which this expression evaluates - * to true. - * Second, logically evaluate all terms over the updated array of truth - * values. - * If this evaluates to true, mark the expression as satisfied. - */ -static void -exprexec(const struct expr *e, const char *cp, - uint64_t mask, struct res *r) -{ - - assert(0 == r->matched); - exprmark(e, cp, mask, r->matches); - r->matched = expreval(e, r->matches); -} diff --git a/apropos_db.h b/apropos_db.h deleted file mode 100644 index 72d4c204..00000000 --- a/apropos_db.h +++ /dev/null @@ -1,73 +0,0 @@ -/* $Id: apropos_db.h,v 1.13 2012/03/24 01:46:25 kristaps Exp $ */ -/* - * Copyright (c) 2011, 2012 Kristaps Dzonsons - * - * 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. - */ -#ifndef APROPOS_H -#define APROPOS_H - -enum restype { - RESTYPE_MAN, /* man(7) file */ - RESTYPE_MDOC, /* mdoc(7) file */ - RESTYPE_CAT /* pre-formatted file */ -}; - -struct res { - enum restype type; /* input file type */ - char *file; /* file in file-system */ - char *cat; /* category (3p, 3, etc.) */ - char *title; /* title (FOO, etc.) */ - char *arch; /* arch (or empty string) */ - char *desc; /* description (from Nd) */ - unsigned int rec; /* record in index */ - /* - * The index volume. This indexes into the array of directories - * searched for manual page databases. - */ - unsigned int volume; - /* - * The following fields are used internally. - * - * Maintain a binary tree for checking the uniqueness of `rec' - * when adding elements to the results array. - * Since the results array is dynamic, use offset in the array - * instead of a pointer to the structure. - */ - int lhs; - int rhs; - int matched; /* expression is true */ - int *matches; /* partial truth evaluations */ -}; - -struct opts { - const char *arch; /* restrict to architecture */ - const char *cat; /* restrict to manual section */ -}; - -__BEGIN_DECLS - -struct expr; - -int apropos_search(int, char **, const struct opts *, - const struct expr *, size_t, - void *, size_t *, struct res **, - void (*)(struct res *, size_t, void *)); -struct expr *exprcomp(int, char *[], size_t *); -void exprfree(struct expr *); -void resfree(struct res *, size_t); -struct expr *termcomp(int, char *[], size_t *); - -__END_DECLS - -#endif /*!APROPOS_H*/ diff --git a/config.h.post b/config.h.post index 90d1edf9..d04dac99 100644 --- a/config.h.post +++ b/config.h.post @@ -15,20 +15,6 @@ # endif #endif -#if defined(__APPLE__) -# define htobe32(x) OSSwapHostToBigInt32(x) -# define betoh32(x) OSSwapBigToHostInt32(x) -# define htobe64(x) OSSwapHostToBigInt64(x) -# define betoh64(x) OSSwapBigToHostInt64(x) -#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) -# define betoh32(x) be32toh(x) -# define betoh64(x) be64toh(x) -#elif defined(__OpenBSD__) -/* Nothing */ -#else -/* XXX Fallback */ -#endif - #ifndef HAVE_STRLCAT extern size_t strlcat(char *, const char *, size_t); #endif -- cgit v1.2.3-56-ge451