version 1.20, 2011/07/12 10:03:02 |
version 1.21, 2011/07/12 15:26:35 |
|
|
#define MANDOC_IDX "mandoc.index" |
#define MANDOC_IDX "mandoc.index" |
#define MANDOC_BUFSZ BUFSIZ |
#define MANDOC_BUFSZ BUFSIZ |
#define MANDOC_FLAGS O_CREAT|O_TRUNC|O_RDWR |
#define MANDOC_FLAGS O_CREAT|O_TRUNC|O_RDWR |
|
#define MANDOC_SLOP 1024 |
|
|
/* Bit-fields. See makewhatis.1. */ |
/* Bit-fields. See makewhatis.1. */ |
|
|
Line 93 static void buf_appendb(struct buf *, |
|
Line 94 static void buf_appendb(struct buf *, |
|
static void dbt_put(DB *, const char *, DBT *, DBT *); |
static void dbt_put(DB *, const char *, DBT *, DBT *); |
static void hash_put(DB *, const struct buf *, int); |
static void hash_put(DB *, const struct buf *, int); |
static void hash_reset(DB **); |
static void hash_reset(DB **); |
static void op_delete(const char *, int, DB *, |
|
const char *, DB *, const char *); |
|
static int pman_node(MAN_ARGS); |
static int pman_node(MAN_ARGS); |
static void pmdoc_node(MDOC_ARGS); |
static void pmdoc_node(MDOC_ARGS); |
static void pmdoc_An(MDOC_ARGS); |
static void pmdoc_An(MDOC_ARGS); |
Line 248 main(int argc, char *argv[]) |
|
Line 247 main(int argc, char *argv[]) |
|
struct mparse *mp; /* parse sequence */ |
struct mparse *mp; /* parse sequence */ |
struct mdoc *mdoc; /* resulting mdoc */ |
struct mdoc *mdoc; /* resulting mdoc */ |
struct man *man; /* resulting man */ |
struct man *man; /* resulting man */ |
enum op op; |
enum op op; /* current operation */ |
char *fn; /* current file being parsed */ |
char *fn; /* current file being parsed */ |
const char *msec, /* manual section */ |
const char *msec, /* manual section */ |
*mtitle, /* manual title */ |
*mtitle, /* manual title */ |
Line 257 main(int argc, char *argv[]) |
|
Line 256 main(int argc, char *argv[]) |
|
char ibuf[MAXPATHLEN], /* index fname */ |
char ibuf[MAXPATHLEN], /* index fname */ |
fbuf[MAXPATHLEN], /* btree fname */ |
fbuf[MAXPATHLEN], /* btree fname */ |
vbuf[8]; /* stringified record number */ |
vbuf[8]; /* stringified record number */ |
int ch, seq, verb, i; |
int ch, seq, sseq, verb, i; |
DB *idx, /* index database */ |
DB *idx, /* index database */ |
*db, /* keyword database */ |
*db, /* keyword database */ |
*hash; /* temporary keyword hashtable */ |
*hash; /* temporary keyword hashtable */ |
DBT key, val; |
DBT key, val; |
enum mandoclevel ec; |
enum mandoclevel ec; /* exit status */ |
size_t sv; |
size_t sv; |
BTREEINFO info; /* btree configuration */ |
BTREEINFO info; /* btree configuration */ |
recno_t rec, /* current record number */ |
recno_t rec, |
maxrec; |
maxrec; /* supremum of all records */ |
recno_t *recs; |
recno_t *recs; /* buffer of empty records */ |
size_t recsz; |
size_t recsz, /* buffer size of recs */ |
|
reccur; /* valid number of recs */ |
struct buf buf, /* keyword buffer */ |
struct buf buf, /* keyword buffer */ |
dbuf; /* description buffer */ |
dbuf; /* description buffer */ |
extern int optind; |
extern int optind; |
Line 286 main(int argc, char *argv[]) |
|
Line 286 main(int argc, char *argv[]) |
|
mp = NULL; |
mp = NULL; |
hash = NULL; |
hash = NULL; |
recs = NULL; |
recs = NULL; |
recsz = 0; |
recsz = reccur = 0; |
maxrec = 0; |
maxrec = 0; |
op = OP_NEW; |
op = OP_NEW; |
ec = MANDOCLEVEL_SYSERR; |
ec = MANDOCLEVEL_SYSERR; |
Line 359 main(int argc, char *argv[]) |
|
Line 359 main(int argc, char *argv[]) |
|
|
|
/* |
/* |
* If we're going to delete or update a database, remove the |
* If we're going to delete or update a database, remove the |
* entries now. This doesn't actually remove them; it only sets |
* entries now (both the index and all keywords pointing to it). |
* their record value lengths to zero. |
* This doesn't actually remove them: it only sets their record |
|
* value lengths to zero. |
|
* While doing so, add the empty records to a list we'll access |
|
* later in re-adding entries to the database. |
*/ |
*/ |
|
|
if (OP_DELETE == op || OP_UPDATE == op) |
if (OP_DELETE == op || OP_UPDATE == op) { |
for (i = 0; i < argc; i++) |
|
op_delete(argv[i], verb, idx, ibuf, db, fbuf); |
|
|
|
if (OP_DELETE == op) { |
|
ec = MANDOCLEVEL_OK; |
|
goto out; |
|
} |
|
|
|
/* |
|
* Compile a list of all available "empty" records to use. This |
|
* keeps the size of the database small. |
|
*/ |
|
|
|
if (OP_UPDATE == op) { |
|
i = 0; |
|
seq = R_FIRST; |
seq = R_FIRST; |
while (0 == (ch = (*idx->seq)(idx, &key, &val, seq))) { |
while (0 == (ch = (*idx->seq)(idx, &key, &val, seq))) { |
seq = R_NEXT; |
seq = R_NEXT; |
maxrec = *(recno_t *)key.data; |
maxrec = *(recno_t *)key.data; |
if (val.size > 0) |
if (0 == val.size && OP_UPDATE == op) { |
|
if (reccur >= recsz) { |
|
recsz += MANDOC_SLOP; |
|
recs = mandoc_realloc |
|
(recs, recsz * sizeof(recno_t)); |
|
} |
|
recs[(int)reccur] = maxrec; |
|
reccur++; |
continue; |
continue; |
if ((size_t)i >= recsz) { |
|
recsz += 1024; |
|
recs = mandoc_realloc |
|
(recs, recsz * sizeof(recno_t)); |
|
} |
} |
recs[i++] = maxrec; |
|
|
fn = (char *)val.data; |
|
for (i = 0; i < argc; i++) |
|
if (0 == strcmp(fn, argv[i])) |
|
break; |
|
|
|
if (i == argc) |
|
continue; |
|
|
|
sseq = R_FIRST; |
|
while (0 == (ch = (*db->seq)(db, &key, &val, sseq))) { |
|
sseq = R_NEXT; |
|
assert(8 == val.size); |
|
if (maxrec != *(recno_t *)(val.data + 4)) |
|
continue; |
|
if (verb > 1) |
|
printf("%s: Deleted keyword: %s\n", |
|
fn, (char *)key.data); |
|
ch = (*db->del)(db, &key, R_CURSOR); |
|
if (ch < 0) |
|
break; |
|
} |
|
if (ch < 0) { |
|
perror(fbuf); |
|
exit((int)MANDOCLEVEL_SYSERR); |
|
} |
|
|
|
if (verb) |
|
printf("%s: Deleted index\n", fn); |
|
|
|
val.size = 0; |
|
ch = (*idx->put)(idx, &key, &val, R_CURSOR); |
|
if (ch < 0) { |
|
perror(ibuf); |
|
exit((int)MANDOCLEVEL_SYSERR); |
|
} |
|
|
|
if (OP_UPDATE == op) { |
|
if (reccur >= recsz) { |
|
recsz += MANDOC_SLOP; |
|
recs = mandoc_realloc |
|
(recs, recsz * sizeof(recno_t)); |
|
} |
|
recs[(int)reccur] = maxrec; |
|
reccur++; |
|
} |
} |
} |
if (ch < 0) { |
|
perror(ibuf); |
|
exit((int)MANDOCLEVEL_SYSERR); |
|
} |
|
recsz = (size_t)i; |
|
maxrec++; |
maxrec++; |
assert(recsz < maxrec); |
} |
} |
|
|
|
|
if (OP_DELETE == op) { |
|
ec = MANDOCLEVEL_OK; |
|
goto out; |
|
} |
|
|
/* |
/* |
* Add records to the database. |
* Add records to the database. |
* Try parsing each manual given on the command line. |
* Try parsing each manual given on the command line. |
Line 418 main(int argc, char *argv[]) |
|
Line 453 main(int argc, char *argv[]) |
|
for (rec = 0, i = 0; i < argc; i++) { |
for (rec = 0, i = 0; i < argc; i++) { |
fn = argv[i]; |
fn = argv[i]; |
if (OP_UPDATE == op) { |
if (OP_UPDATE == op) { |
if (recsz > 0) { |
if (reccur > 0) { |
--recsz; |
--reccur; |
rec = recs[(int)recsz]; |
rec = recs[(int)reccur]; |
} else if (maxrec > 0) { |
} else if (maxrec > 0) { |
rec = maxrec; |
rec = maxrec; |
maxrec = 0; |
maxrec = 0; |
Line 491 main(int argc, char *argv[]) |
|
Line 526 main(int argc, char *argv[]) |
|
val.data = vbuf; |
val.data = vbuf; |
|
|
if (verb > 1) |
if (verb > 1) |
printf("Indexed: %s, %s, 0x%x\n", |
printf("%s: Added keyword: %s, 0x%x\n", |
fn, (char *)key.data, |
fn, (char *)key.data, |
*(int *)val.data); |
*(int *)val.data); |
dbt_put(db, fbuf, &key, &val); |
dbt_put(db, fbuf, &key, &val); |
Line 516 main(int argc, char *argv[]) |
|
Line 551 main(int argc, char *argv[]) |
|
val.size = dbuf.len; |
val.size = dbuf.len; |
|
|
if (verb > 0) |
if (verb > 0) |
printf("Indexed: %s\n", fn); |
printf("%s: Added index\n", fn); |
|
|
dbt_put(idx, ibuf, &key, &val); |
dbt_put(idx, ibuf, &key, &val); |
} |
} |
|
|
free(recs); |
free(recs); |
|
|
return((int)ec); |
return((int)ec); |
} |
|
|
|
static void |
|
op_delete(const char *fn, int verb, DB *idx, |
|
const char *ibuf, DB *db, const char *fbuf) |
|
{ |
|
int ch; |
|
DBT key, val; |
|
recno_t rec; |
|
unsigned int seq, sseq; |
|
|
|
seq = R_FIRST; |
|
while (0 == (ch = (*idx->seq)(idx, &key, &val, seq))) { |
|
seq = R_NEXT; |
|
if (0 == val.size) |
|
continue; |
|
if (strcmp((char *)val.data, fn)) |
|
continue; |
|
|
|
rec = *(recno_t *)key.data; |
|
|
|
sseq = R_FIRST; |
|
while (0 == (ch = (*db->seq)(db, &key, &val, sseq))) { |
|
sseq = R_NEXT; |
|
assert(8 == val.size); |
|
if (rec != *(recno_t *)(val.data + 4)) |
|
continue; |
|
if (verb > 1) |
|
printf("Deleted: %s, %s\n", |
|
fn, (char *)key.data); |
|
ch = (*db->del)(db, &key, R_CURSOR); |
|
if (ch < 0) |
|
break; |
|
} |
|
if (ch < 0) { |
|
perror(fbuf); |
|
exit((int)MANDOCLEVEL_SYSERR); |
|
} |
|
|
|
val.size = 0; |
|
if (verb) |
|
printf("Deleted: %s\n", fn); |
|
ch = (*idx->put) |
|
(idx, &key, &val, R_CURSOR); |
|
if (ch < 0) |
|
break; |
|
} |
|
if (ch < 0) { |
|
perror(ibuf); |
|
exit((int)MANDOCLEVEL_SYSERR); |
|
} |
|
} |
} |
|
|
/* |
/* |