=================================================================== RCS file: /cvs/mandoc/mandocdb.c,v retrieving revision 1.94 retrieving revision 1.98 diff -u -p -r1.94 -r1.98 --- mandoc/mandocdb.c 2014/01/02 20:24:39 1.94 +++ mandoc/mandocdb.c 2014/01/05 03:06:43 1.98 @@ -1,7 +1,7 @@ -/* $Id: mandocdb.c,v 1.94 2014/01/02 20:24:39 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.98 2014/01/05 03:06:43 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons - * Copyright (c) 2011, 2012, 2013 Ingo Schwarze + * Copyright (c) 2011, 2012, 2013, 2014 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 @@ -82,10 +82,10 @@ enum form { }; struct str { - char *utf8; /* key in UTF-8 form */ + char *rendered; /* key in UTF-8 or ASCII form */ const struct mpage *mpage; /* if set, the owning parse */ uint64_t mask; /* bitmask in sequence */ - char key[]; /* the string itself */ + char key[]; /* may contain escape sequences */ }; struct inodev { @@ -165,17 +165,18 @@ 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 void utf8key(struct mchars *, struct str *); static char *progname; static int use_all; /* use all found files */ static int nodb; /* no database changes */ static int verb; /* 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 */ @@ -351,7 +352,7 @@ main(int argc, char *argv[]) path_arg = NULL; op = OP_DEFAULT; - while (-1 != (ch = getopt(argc, argv, "aC:d:ntu:vW"))) + while (-1 != (ch = getopt(argc, argv, "aC:d:nT:tu:vW"))) switch (ch) { case ('a'): use_all = 1; @@ -369,6 +370,14 @@ main(int argc, char *argv[]) case ('n'): nodb = 1; break; + case ('T'): + if (strcmp(optarg, "utf8")) { + fprintf(stderr, "-T%s: Unsupported " + "output format\n", optarg); + goto usage; + } + write_utf8 = 1; + break; case ('t'): CHECKOP(op, ch); dup2(STDOUT_FILENO, STDERR_FILENO); @@ -490,9 +499,9 @@ out: ohash_delete(&mlinks); return(exitcode); usage: - fprintf(stderr, "usage: %s [-anvW] [-C file]\n" - " %s [-anvW] dir ...\n" - " %s [-nvW] -d dir [file ...]\n" + fprintf(stderr, "usage: %s [-anvW] [-C file] [-Tutf8]\n" + " %s [-anvW] [-Tutf8] dir ...\n" + " %s [-nvW] [-Tutf8] -d dir [file ...]\n" " %s [-nvW] -u dir [file ...]\n" " %s -t file ...\n", progname, progname, progname, @@ -1015,9 +1024,19 @@ mpages_merge(struct mchars *mc, struct mparse *mp, int mpage->title = mandoc_strdup(mpage->mlinks->name); } + putkey(mpage, mpage->sec, TYPE_sec); + putkey(mpage, '\0' == *mpage->arch ? + "any" : mpage->arch, TYPE_arch); - for (mlink = mpage->mlinks; mlink; mlink = mlink->next) + for (mlink = mpage->mlinks; mlink; mlink = mlink->next) { + if ('\0' != *mlink->dsec) + putkey(mpage, mlink->dsec, TYPE_sec); + if ('\0' != *mlink->fsec) + putkey(mpage, mlink->fsec, TYPE_sec); + putkey(mpage, '\0' == *mlink->arch ? + "any" : mlink->arch, TYPE_arch); putkey(mpage, mlink->name, TYPE_Nm); + } if (warnings && !use_all) { match = 0; @@ -1653,11 +1672,11 @@ utf8(unsigned int cp, char out[7]) } /* - * Store the UTF-8 version of a key, or alias the pointer if the key has - * no UTF-8 transcription marks in it. + * Store the rendered version of a key, or alias the pointer + * if the key contains no escape sequences. */ static void -utf8key(struct mchars *mc, struct str *key) +render_key(struct mchars *mc, struct str *key) { size_t sz, bsz, pos; char utfbuf[7], res[5]; @@ -1666,7 +1685,7 @@ utf8key(struct mchars *mc, struct str *key) int len, u; enum mandoc_esc esc; - assert(NULL == key->utf8); + assert(NULL == key->rendered); res[0] = '\\'; res[1] = '\t'; @@ -1682,7 +1701,7 @@ utf8key(struct mchars *mc, struct str *key) * pointer as ourselvse and get out of here. */ if (strcspn(val, res) == bsz) { - key->utf8 = key->key; + key->rendered = key->key; return; } @@ -1722,44 +1741,53 @@ utf8key(struct mchars *mc, struct str *key) * Parse the escape sequence and see if it's a * predefined character or special character. */ + esc = mandoc_escape ((const char **)&val, &seq, &len); if (ESCAPE_ERROR == esc) break; - if (ESCAPE_SPECIAL != esc) continue; - if (0 == (u = mchars_spec2cp(mc, seq, len))) - continue; /* - * If we have a Unicode codepoint, try to convert that - * to a UTF-8 byte string. + * Render the special character + * as either UTF-8 or ASCII. */ - cpp = utfbuf; - if (0 == (sz = utf8(u, utfbuf))) - continue; + if (write_utf8) { + if (0 == (u = mchars_spec2cp(mc, seq, len))) + continue; + cpp = utfbuf; + if (0 == (sz = utf8(u, utfbuf))) + continue; + sz = strlen(cpp); + } else { + cpp = mchars_spec2str(mc, seq, len, &sz); + if (NULL == cpp) + continue; + if (ASCII_NBRSP == *cpp) { + cpp = " "; + sz = 1; + } + } + /* Copy the rendered glyph into the stream. */ - sz = strlen(cpp); bsz += sz; - buf = mandoc_realloc(buf, bsz); - memcpy(&buf[pos], cpp, sz); pos += sz; } buf[pos] = '\0'; - key->utf8 = buf; + key->rendered = buf; } /* * Flush the current page's terms (and their bits) into the database. * Wrap the entire set of additions in a transaction to make sqlite be a * little faster. - * Also, UTF-8-encode the description at the last possible moment. + * Also, handle escape sequences at the last possible moment. */ static void dbindex(const struct mpage *mpage, struct mchars *mc) @@ -1782,9 +1810,9 @@ dbindex(const struct mpage *mpage, struct mchars *mc) key = ohash_find(&strings, ohash_qlookup(&strings, mpage->desc)); assert(NULL != key); - if (NULL == key->utf8) - utf8key(mc, key); - desc = key->utf8; + if (NULL == key->rendered) + render_key(mc, key); + desc = key->rendered; } SQL_EXEC("BEGIN TRANSACTION"); @@ -1818,16 +1846,16 @@ dbindex(const struct mpage *mpage, struct mchars *mc) for (key = ohash_first(&strings, &slot); NULL != key; key = ohash_next(&strings, &slot)) { assert(key->mpage == mpage); - if (NULL == key->utf8) - utf8key(mc, key); + if (NULL == key->rendered) + render_key(mc, key); i = 1; SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, key->mask); - SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->utf8); + SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->rendered); SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, recno); SQL_STEP(stmts[STMT_INSERT_KEY]); sqlite3_reset(stmts[STMT_INSERT_KEY]); - if (key->utf8 != key->key) - free(key->utf8); + if (key->rendered != key->key) + free(key->rendered); free(key); }