-#define MAN_ARGS DB *hash, \
- struct buf *buf, \
- struct buf *dbuf, \
- const struct man_node *n
-#define MDOC_ARGS DB *hash, \
- struct buf *buf, \
- struct buf *dbuf, \
- const struct mdoc_node *n, \
- const struct mdoc_meta *m
-
-static void buf_appendmdoc(struct buf *,
- const struct mdoc_node *, int);
-static void buf_append(struct buf *, const char *);
-static void buf_appendb(struct buf *,
- const void *, size_t);
-static void dbt_put(DB *, const char *, DBT *, DBT *);
-static void hash_put(DB *, const struct buf *, uint64_t);
-static void hash_reset(DB **);
-static void index_merge(const struct of *, struct mparse *,
- struct buf *, struct buf *, DB *,
- DB *, const char *, DB *, const char *,
- recno_t, const recno_t *, size_t);
-static void index_prune(const struct of *, DB *,
- const char *, DB *, const char *,
- recno_t *, recno_t **, size_t *);
-static void ofile_argbuild(int, char *[], struct of **);
-static int ofile_dirbuild(const char *, const char *,
- const char *, int, struct of **);
-static void ofile_free(struct of *);
-static void pformatted(DB *, struct buf *, struct buf *,
- const struct of *);
-static int pman_node(MAN_ARGS);
-static void pmdoc_node(MDOC_ARGS);
-static void pmdoc_An(MDOC_ARGS);
-static void pmdoc_Cd(MDOC_ARGS);
-static void pmdoc_Er(MDOC_ARGS);
-static void pmdoc_Ev(MDOC_ARGS);
-static void pmdoc_Fd(MDOC_ARGS);
-static void pmdoc_In(MDOC_ARGS);
-static void pmdoc_Fn(MDOC_ARGS);
-static void pmdoc_Fo(MDOC_ARGS);
-static void pmdoc_Nd(MDOC_ARGS);
-static void pmdoc_Nm(MDOC_ARGS);
-static void pmdoc_Pa(MDOC_ARGS);
-static void pmdoc_St(MDOC_ARGS);
-static void pmdoc_Vt(MDOC_ARGS);
-static void pmdoc_Xr(MDOC_ARGS);
-static void usage(void);
-
-typedef void (*pmdoc_nf)(MDOC_ARGS);
-
-static const pmdoc_nf mdocs[MDOC_MAX] = {
- NULL, /* Ap */
- NULL, /* Dd */
- NULL, /* Dt */
- NULL, /* Os */
- NULL, /* Sh */
- NULL, /* Ss */
- NULL, /* Pp */
- NULL, /* D1 */
- NULL, /* Dl */
- NULL, /* Bd */
- NULL, /* Ed */
- NULL, /* Bl */
- NULL, /* El */
- NULL, /* It */
- NULL, /* Ad */
- pmdoc_An, /* An */
- NULL, /* Ar */
- pmdoc_Cd, /* Cd */
- NULL, /* Cm */
- NULL, /* Dv */
- pmdoc_Er, /* Er */
- pmdoc_Ev, /* Ev */
- NULL, /* Ex */
- NULL, /* Fa */
- pmdoc_Fd, /* Fd */
- NULL, /* Fl */
- pmdoc_Fn, /* Fn */
- NULL, /* Ft */
- NULL, /* Ic */
- pmdoc_In, /* In */
- NULL, /* Li */
- pmdoc_Nd, /* Nd */
- pmdoc_Nm, /* Nm */
- NULL, /* Op */
- NULL, /* Ot */
- pmdoc_Pa, /* Pa */
- NULL, /* Rv */
- pmdoc_St, /* St */
- pmdoc_Vt, /* Va */
- pmdoc_Vt, /* Vt */
- pmdoc_Xr, /* Xr */
- NULL, /* %A */
- NULL, /* %B */
- NULL, /* %D */
- NULL, /* %I */
- NULL, /* %J */
- NULL, /* %N */
- NULL, /* %O */
- NULL, /* %P */
- NULL, /* %R */
- NULL, /* %T */
- NULL, /* %V */
- NULL, /* Ac */
- NULL, /* Ao */
- NULL, /* Aq */
- NULL, /* At */
- NULL, /* Bc */
- NULL, /* Bf */
- NULL, /* Bo */
- NULL, /* Bq */
- NULL, /* Bsx */
- NULL, /* Bx */
- NULL, /* Db */
- NULL, /* Dc */
- NULL, /* Do */
- NULL, /* Dq */
- NULL, /* Ec */
- NULL, /* Ef */
- NULL, /* Em */
- NULL, /* Eo */
- NULL, /* Fx */
- NULL, /* Ms */
- NULL, /* No */
- NULL, /* Ns */
- NULL, /* Nx */
- NULL, /* Ox */
- NULL, /* Pc */
- NULL, /* Pf */
- NULL, /* Po */
- NULL, /* Pq */
- NULL, /* Qc */
- NULL, /* Ql */
- NULL, /* Qo */
- NULL, /* Qq */
- NULL, /* Re */
- NULL, /* Rs */
- NULL, /* Sc */
- NULL, /* So */
- NULL, /* Sq */
- NULL, /* Sm */
- NULL, /* Sx */
- NULL, /* Sy */
- NULL, /* Tn */
- NULL, /* Ux */
- NULL, /* Xc */
- NULL, /* Xo */
- pmdoc_Fo, /* Fo */
- NULL, /* Fc */
- NULL, /* Oo */
- NULL, /* Oc */
- NULL, /* Bk */
- NULL, /* Ek */
- NULL, /* Bt */
- NULL, /* Hf */
- NULL, /* Fr */
- NULL, /* Ud */
- NULL, /* Lb */
- NULL, /* Lp */
- NULL, /* Lk */
- NULL, /* Mt */
- NULL, /* Brq */
- NULL, /* Bro */
- NULL, /* Brc */
- NULL, /* %C */
- NULL, /* Es */
- NULL, /* En */
- NULL, /* Dx */
- NULL, /* %Q */
- NULL, /* br */
- NULL, /* sp */
- NULL, /* %U */
- NULL, /* Ta */
+static void dbclose(int);
+static void dbadd(struct mpage *, struct mchars *);
+static void dbadd_mlink(const struct mlink *mlink);
+static int dbopen(int);
+static void dbprune(void);
+static void filescan(const char *);
+static void *hash_alloc(size_t, void *);
+static void hash_free(void *, void *);
+static void *hash_calloc(size_t, size_t, void *);
+static void mlink_add(struct mlink *, const struct stat *);
+static void mlink_check(struct mpage *, struct mlink *);
+static void mlink_free(struct mlink *);
+static void mlinks_undupe(struct mpage *);
+static void mpages_free(void);
+static void mpages_merge(struct mchars *, struct mparse *);
+static void names_check(void);
+static void parse_cat(struct mpage *, int);
+static void parse_man(struct mpage *, const struct man_node *);
+static void parse_mdoc(struct mpage *, const struct mdoc_node *);
+static int parse_mdoc_body(struct mpage *, const struct mdoc_node *);
+static int parse_mdoc_head(struct mpage *, const struct mdoc_node *);
+static int parse_mdoc_Fd(struct mpage *, const struct mdoc_node *);
+static int parse_mdoc_Fn(struct mpage *, const struct mdoc_node *);
+static int parse_mdoc_Nd(struct mpage *, const struct mdoc_node *);
+static int parse_mdoc_Nm(struct mpage *, const struct mdoc_node *);
+static int parse_mdoc_Sh(struct mpage *, const struct mdoc_node *);
+static int parse_mdoc_Xr(struct mpage *, const struct mdoc_node *);
+static void putkey(const struct mpage *, char *, uint64_t);
+static void putkeys(const struct mpage *,
+ const char *, size_t, uint64_t);
+static void putmdockey(const struct mpage *,
+ const struct mdoc_node *, uint64_t);
+static void render_key(struct mchars *, struct str *);
+static void say(const char *, const char *, ...);
+static int set_basedir(const char *);
+static int treescan(void);
+static size_t utf8(unsigned int, char [7]);
+
+static char tempfilename[32];
+static char *progname;
+static int nodb; /* no database changes */
+static int mparse_options; /* abort the parse early */
+static int use_all; /* use all found files */
+static int debug; /* print what we're doing */
+static int warnings; /* warn about crap */
+static int write_utf8; /* write UTF-8 output; else ASCII */
+static int exitcode; /* to be returned by main */
+static enum op op; /* operational mode */
+static char basedir[PATH_MAX]; /* current base directory */
+static struct ohash mpages; /* table of distinct manual pages */
+static struct ohash mlinks; /* table of directory entries */
+static struct ohash names; /* table of all names */
+static struct ohash strings; /* table of all strings */
+static sqlite3 *db = NULL; /* current database */
+static sqlite3_stmt *stmts[STMT__MAX]; /* current statements */
+static uint64_t name_mask;
+
+static const struct mdoc_handler mdocs[MDOC_MAX] = {
+ { NULL, 0 }, /* Ap */
+ { NULL, 0 }, /* Dd */
+ { NULL, 0 }, /* Dt */
+ { NULL, 0 }, /* Os */
+ { parse_mdoc_Sh, TYPE_Sh }, /* Sh */
+ { parse_mdoc_head, TYPE_Ss }, /* Ss */
+ { NULL, 0 }, /* Pp */
+ { NULL, 0 }, /* D1 */
+ { NULL, 0 }, /* Dl */
+ { NULL, 0 }, /* Bd */
+ { NULL, 0 }, /* Ed */
+ { NULL, 0 }, /* Bl */
+ { NULL, 0 }, /* El */
+ { NULL, 0 }, /* It */
+ { NULL, 0 }, /* Ad */
+ { NULL, TYPE_An }, /* An */
+ { NULL, TYPE_Ar }, /* Ar */
+ { NULL, TYPE_Cd }, /* Cd */
+ { NULL, TYPE_Cm }, /* Cm */
+ { NULL, TYPE_Dv }, /* Dv */
+ { NULL, TYPE_Er }, /* Er */
+ { NULL, TYPE_Ev }, /* Ev */
+ { NULL, 0 }, /* Ex */
+ { NULL, TYPE_Fa }, /* Fa */
+ { parse_mdoc_Fd, 0 }, /* Fd */
+ { NULL, TYPE_Fl }, /* Fl */
+ { parse_mdoc_Fn, 0 }, /* Fn */
+ { NULL, TYPE_Ft }, /* Ft */
+ { NULL, TYPE_Ic }, /* Ic */
+ { NULL, TYPE_In }, /* In */
+ { NULL, TYPE_Li }, /* Li */
+ { parse_mdoc_Nd, 0 }, /* Nd */
+ { parse_mdoc_Nm, 0 }, /* Nm */
+ { NULL, 0 }, /* Op */
+ { NULL, 0 }, /* Ot */
+ { NULL, TYPE_Pa }, /* Pa */
+ { NULL, 0 }, /* Rv */
+ { NULL, TYPE_St }, /* St */
+ { NULL, TYPE_Va }, /* Va */
+ { parse_mdoc_body, TYPE_Va }, /* Vt */
+ { parse_mdoc_Xr, 0 }, /* Xr */
+ { NULL, 0 }, /* %A */
+ { NULL, 0 }, /* %B */
+ { NULL, 0 }, /* %D */
+ { NULL, 0 }, /* %I */
+ { NULL, 0 }, /* %J */
+ { NULL, 0 }, /* %N */
+ { NULL, 0 }, /* %O */
+ { NULL, 0 }, /* %P */
+ { NULL, 0 }, /* %R */
+ { NULL, 0 }, /* %T */
+ { NULL, 0 }, /* %V */
+ { NULL, 0 }, /* Ac */
+ { NULL, 0 }, /* Ao */
+ { NULL, 0 }, /* Aq */
+ { NULL, TYPE_At }, /* At */
+ { NULL, 0 }, /* Bc */
+ { NULL, 0 }, /* Bf */
+ { NULL, 0 }, /* Bo */
+ { NULL, 0 }, /* Bq */
+ { NULL, TYPE_Bsx }, /* Bsx */
+ { NULL, TYPE_Bx }, /* Bx */
+ { NULL, 0 }, /* Db */
+ { NULL, 0 }, /* Dc */
+ { NULL, 0 }, /* Do */
+ { NULL, 0 }, /* Dq */
+ { NULL, 0 }, /* Ec */
+ { NULL, 0 }, /* Ef */
+ { NULL, TYPE_Em }, /* Em */
+ { NULL, 0 }, /* Eo */
+ { NULL, TYPE_Fx }, /* Fx */
+ { NULL, TYPE_Ms }, /* Ms */
+ { NULL, 0 }, /* No */
+ { NULL, 0 }, /* Ns */
+ { NULL, TYPE_Nx }, /* Nx */
+ { NULL, TYPE_Ox }, /* Ox */
+ { NULL, 0 }, /* Pc */
+ { NULL, 0 }, /* Pf */
+ { NULL, 0 }, /* Po */
+ { NULL, 0 }, /* Pq */
+ { NULL, 0 }, /* Qc */
+ { NULL, 0 }, /* Ql */
+ { NULL, 0 }, /* Qo */
+ { NULL, 0 }, /* Qq */
+ { NULL, 0 }, /* Re */
+ { NULL, 0 }, /* Rs */
+ { NULL, 0 }, /* Sc */
+ { NULL, 0 }, /* So */
+ { NULL, 0 }, /* Sq */
+ { NULL, 0 }, /* Sm */
+ { NULL, 0 }, /* Sx */
+ { NULL, TYPE_Sy }, /* Sy */
+ { NULL, TYPE_Tn }, /* Tn */
+ { NULL, 0 }, /* Ux */
+ { NULL, 0 }, /* Xc */
+ { NULL, 0 }, /* Xo */
+ { parse_mdoc_head, 0 }, /* Fo */
+ { NULL, 0 }, /* Fc */
+ { NULL, 0 }, /* Oo */
+ { NULL, 0 }, /* Oc */
+ { NULL, 0 }, /* Bk */
+ { NULL, 0 }, /* Ek */
+ { NULL, 0 }, /* Bt */
+ { NULL, 0 }, /* Hf */
+ { NULL, 0 }, /* Fr */
+ { NULL, 0 }, /* Ud */
+ { NULL, TYPE_Lb }, /* Lb */
+ { NULL, 0 }, /* Lp */
+ { NULL, TYPE_Lk }, /* Lk */
+ { NULL, TYPE_Mt }, /* Mt */
+ { NULL, 0 }, /* Brq */
+ { NULL, 0 }, /* Bro */
+ { NULL, 0 }, /* Brc */
+ { NULL, 0 }, /* %C */
+ { NULL, 0 }, /* Es */
+ { NULL, 0 }, /* En */
+ { NULL, TYPE_Dx }, /* Dx */
+ { NULL, 0 }, /* %Q */
+ { NULL, 0 }, /* br */
+ { NULL, 0 }, /* sp */
+ { NULL, 0 }, /* %U */
+ { NULL, 0 }, /* Ta */