=================================================================== RCS file: /cvs/mandoc/mandocdb.c,v retrieving revision 1.170 retrieving revision 1.175 diff -u -p -r1.170 -r1.175 --- mandoc/mandocdb.c 2014/11/26 21:40:17 1.170 +++ mandoc/mandocdb.c 2014/12/04 21:48:48 1.175 @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.170 2014/11/26 21:40:17 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.175 2014/12/04 21:48:48 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze @@ -104,6 +104,7 @@ struct mpage { char *desc; /* description from file content */ struct mlink *mlinks; /* singly linked list */ int form; /* format from file content */ + int name_head_done; }; struct mlink { @@ -124,11 +125,13 @@ enum stmt { STMT_INSERT_PAGE, /* insert mpage */ STMT_INSERT_LINK, /* insert mlink */ STMT_INSERT_NAME, /* insert name */ + STMT_SELECT_NAME, /* retrieve existing name flags */ STMT_INSERT_KEY, /* insert parsed key */ STMT__MAX }; -typedef int (*mdoc_fp)(struct mpage *, const struct mdoc_node *); +typedef int (*mdoc_fp)(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); struct mdoc_handler { mdoc_fp fp; /* optional handler */ @@ -153,16 +156,28 @@ 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 parse_man(struct mpage *, const struct man_meta *, + const struct man_node *); +static void parse_mdoc(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_body(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_head(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Fd(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Fn(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Fo(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Nd(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Nm(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Sh(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Xr(struct mpage *, const struct mdoc_meta *, + 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); @@ -290,7 +305,7 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = { { NULL, 0 }, /* Ux */ { NULL, 0 }, /* Xc */ { NULL, 0 }, /* Xo */ - { parse_mdoc_head, 0 }, /* Fo */ + { parse_mdoc_Fo, 0 }, /* Fo */ { NULL, 0 }, /* Fc */ { NULL, 0 }, /* Oo */ { NULL, 0 }, /* Oc */ @@ -1093,13 +1108,13 @@ mpages_merge(struct mchars *mc, struct mparse *mp) str_info.free = hash_free; str_info.key_offset = offsetof(struct str, key); - if (0 == nodb) + if ( ! nodb) SQL_EXEC("BEGIN TRANSACTION"); mpage = ohash_first(&mpages, &pslot); - while (NULL != mpage) { + while (mpage != NULL) { mlinks_undupe(mpage); - if (NULL == mpage->mlinks) { + if (mpage->mlinks == NULL) { mpage = ohash_next(&mpages, &pslot); continue; } @@ -1123,17 +1138,23 @@ mpages_merge(struct mchars *mc, struct mparse *mp) * source code, unless it is already known to be * formatted. Fall back to formatted mode. */ - if (FORM_CAT != mpage->mlinks->dform || - FORM_CAT != mpage->mlinks->fform) { + if (mpage->mlinks->dform != FORM_CAT || + mpage->mlinks->fform != FORM_CAT) { lvl = mparse_readfd(mp, fd, mpage->mlinks->file); if (lvl < MANDOCLEVEL_FATAL) mparse_result(mp, &mdoc, &man, &sodest); } - if (NULL != sodest) { + if (sodest != NULL) { mlink_dest = ohash_find(&mlinks, ohash_qlookup(&mlinks, sodest)); - if (NULL != mlink_dest) { + if (mlink_dest == NULL) { + mandoc_asprintf(&cp, "%s.gz", sodest); + mlink_dest = ohash_find(&mlinks, + ohash_qlookup(&mlinks, cp)); + free(cp); + } + if (mlink_dest != NULL) { /* The .so target exists. */ @@ -1154,7 +1175,7 @@ mpages_merge(struct mchars *mc, struct mparse *mp) if (mpage_dest->pageid) dbadd_mlink_name(mlink); - if (NULL == mlink->next) + if (mlink->next == NULL) break; mlink = mlink->next; } @@ -1166,17 +1187,17 @@ mpages_merge(struct mchars *mc, struct mparse *mp) mpage->mlinks = NULL; } goto nextpage; - } else if (NULL != mdoc) { + } else if (mdoc != NULL) { mpage->form = FORM_SRC; mpage->sec = mdoc_meta(mdoc)->msec; mpage->sec = mandoc_strdup( - NULL == mpage->sec ? "" : mpage->sec); + mpage->sec == NULL ? "" : mpage->sec); mpage->arch = mdoc_meta(mdoc)->arch; mpage->arch = mandoc_strdup( - NULL == mpage->arch ? "" : mpage->arch); + mpage->arch == NULL ? "" : mpage->arch); mpage->title = mandoc_strdup(mdoc_meta(mdoc)->title); - } else if (NULL != man) { + } else if (man != NULL) { mpage->form = FORM_SRC; mpage->sec = mandoc_strdup(man_meta(man)->msec); @@ -1193,8 +1214,6 @@ mpages_merge(struct mchars *mc, struct mparse *mp) mpage->title = mandoc_strdup(mpage->mlinks->name); } - if (mpage->mlinks->gzip) - mpage->form |= FORM_GZ; putkey(mpage, mpage->sec, TYPE_sec); if (*mpage->arch != '\0') putkey(mpage, mpage->arch, TYPE_arch); @@ -1209,16 +1228,14 @@ mpages_merge(struct mchars *mc, struct mparse *mp) putkey(mpage, mlink->name, NAME_FILE); } - assert(NULL == mpage->desc); - if (NULL != mdoc) { - if (NULL != (cp = mdoc_meta(mdoc)->name)) - putkey(mpage, cp, NAME_HEAD); - parse_mdoc(mpage, mdoc_node(mdoc)); - } else if (NULL != man) - parse_man(mpage, man_node(man)); + assert(mpage->desc == NULL); + if (mdoc != NULL) + parse_mdoc(mpage, mdoc_meta(mdoc), mdoc_node(mdoc)); + else if (man != NULL) + parse_man(mpage, man_meta(man), man_node(man)); else parse_cat(mpage, fd); - if (NULL == mpage->desc) + if (mpage->desc == NULL) mpage->desc = mandoc_strdup(mpage->mlinks->name); if (warnings && !use_all) @@ -1423,7 +1440,8 @@ putmdockey(const struct mpage *mpage, } static void -parse_man(struct mpage *mpage, const struct man_node *n) +parse_man(struct mpage *mpage, const struct man_meta *meta, + const struct man_node *n) { const struct man_node *head, *body; char *start, *title; @@ -1489,6 +1507,11 @@ parse_man(struct mpage *mpage, const struct man_node * break; putkey(mpage, start, NAME_TITLE); + if ( ! (mpage->name_head_done || + strcasecmp(start, meta->title))) { + putkey(mpage, start, NAME_HEAD); + mpage->name_head_done = 1; + } if (' ' == byte) { start += sz + 1; @@ -1503,6 +1526,11 @@ parse_man(struct mpage *mpage, const struct man_node * if (start == title) { putkey(mpage, start, NAME_TITLE); + if ( ! (mpage->name_head_done || + strcasecmp(start, meta->title))) { + putkey(mpage, start, NAME_HEAD); + mpage->name_head_done = 1; + } free(title); return; } @@ -1533,12 +1561,13 @@ parse_man(struct mpage *mpage, const struct man_node * for (n = n->child; n; n = n->next) { if (NULL != mpage->desc) break; - parse_man(mpage, n); + parse_man(mpage, meta, n); } } static void -parse_mdoc(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { assert(NULL != n); @@ -1554,7 +1583,7 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_node /* FALLTHROUGH */ case MDOC_TAIL: if (NULL != mdocs[n->tok].fp) - if (0 == (*mdocs[n->tok].fp)(mpage, n)) + if (0 == (*mdocs[n->tok].fp)(mpage, meta, n)) break; if (mdocs[n->tok].mask) putmdockey(mpage, n->child, @@ -1565,12 +1594,13 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_node continue; } if (NULL != n->child) - parse_mdoc(mpage, n); + parse_mdoc(mpage, meta, n); } } static int -parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { const char *start, *end; size_t sz; @@ -1613,7 +1643,8 @@ parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_n } static int -parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { char *cp; @@ -1634,6 +1665,8 @@ parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_n cp++; putkey(mpage, cp, TYPE_Fn); + if (n->sec == SEC_SYNOPSIS) + putkey(mpage, cp, NAME_SYN); if (n->string < cp) putkeys(mpage, n->string, cp - n->string, TYPE_Ft); @@ -1646,8 +1679,20 @@ parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_n } static int -parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_Fo(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { + + putmdockey(mpage, n->child, TYPE_Fn); + if (n->sec == SEC_SYNOPSIS) + putmdockey(mpage, n->child, NAME_SYN); + return(0); +} + +static int +parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) +{ char *cp; if (NULL == (n = n->child)) @@ -1665,7 +1710,8 @@ parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_n } static int -parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { if (MDOC_BODY == n->type) @@ -1674,32 +1720,46 @@ parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_n } static int -parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { if (SEC_NAME == n->sec) putmdockey(mpage, n->child, NAME_TITLE); - else if (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type) - putmdockey(mpage, n->child, NAME_SYN); + else if (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type) { + if (n->child == NULL) + putkey(mpage, meta->name, NAME_SYN); + else + putmdockey(mpage, n->child, NAME_SYN); + } + if ( ! (mpage->name_head_done || + n->child == NULL || n->child->string == NULL || + strcasecmp(n->child->string, meta->title))) { + putkey(mpage, n->child->string, NAME_HEAD); + mpage->name_head_done = 1; + } return(0); } static int -parse_mdoc_Sh(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_Sh(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { return(SEC_CUSTOM == n->sec && MDOC_HEAD == n->type); } static int -parse_mdoc_head(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_head(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { return(MDOC_HEAD == n->type); } static int -parse_mdoc_body(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_body(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { return(MDOC_BODY == n->type); @@ -1730,7 +1790,7 @@ putkeys(const struct mpage *mpage, name_mask &= ~NAME_FIRST; if (debug > 1) say(mpage->mlinks->file, - "Adding name %*s", sz, cp); + "Adding name %*s, bits=%d", sz, cp, v); } else { htab = &strings; if (debug > 1) @@ -1947,12 +2007,21 @@ dbadd_mlink(const struct mlink *mlink) static void dbadd_mlink_name(const struct mlink *mlink) { + uint64_t bits; size_t i; dbadd_mlink(mlink); i = 1; - SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, NAME_FILE & NAME_MASK); + SQL_BIND_INT64(stmts[STMT_SELECT_NAME], i, mlink->mpage->pageid); + bits = NAME_FILE & NAME_MASK; + if (sqlite3_step(stmts[STMT_SELECT_NAME]) == SQLITE_ROW) { + bits |= sqlite3_column_int64(stmts[STMT_SELECT_NAME], 0); + sqlite3_reset(stmts[STMT_SELECT_NAME]); + } + + i = 1; + SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, bits); SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, mlink->name); SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mlink->mpage->pageid); SQL_STEP(stmts[STMT_INSERT_NAME]); @@ -2265,7 +2334,8 @@ create_tables: " \"bits\" INTEGER NOT NULL,\n" " \"name\" TEXT NOT NULL,\n" " \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) " - "ON DELETE CASCADE\n" + "ON DELETE CASCADE,\n" + " UNIQUE (\"name\", \"pageid\") ON CONFLICT REPLACE\n" ");\n" "\n" "CREATE TABLE \"keys\" (\n" @@ -2303,6 +2373,8 @@ prepare_statements: sql = "INSERT INTO mlinks " "(sec,arch,name,pageid) VALUES (?,?,?,?)"; sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_LINK], NULL); + sql = "SELECT bits FROM names where pageid = ?"; + sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_SELECT_NAME], NULL); sql = "INSERT INTO names " "(bits,name,pageid) VALUES (?,?,?)"; sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_NAME], NULL);