=================================================================== RCS file: /cvs/texi2mdoc/main.c,v retrieving revision 1.66 retrieving revision 1.68 diff -u -p -r1.66 -r1.68 --- texi2mdoc/main.c 2015/03/11 12:51:41 1.66 +++ texi2mdoc/main.c 2015/03/12 10:44:34 1.68 @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.66 2015/03/11 12:51:41 kristaps Exp $ */ +/* $Id: main.c,v 1.68 2015/03/12 10:44:34 kristaps Exp $ */ /* * Copyright (c) 2015 Kristaps Dzonsons * @@ -76,7 +76,6 @@ static void donode(struct texi *, enum texicmd, size_t static void doprintindex(struct texi *, enum texicmd, size_t *); static void doquotation(struct texi *, enum texicmd, size_t *); static void dotable(struct texi *, enum texicmd, size_t *); -static void dotop(struct texi *, enum texicmd, size_t *); static void dosecoffs(struct texi *, enum texicmd, size_t *); static void dosection(struct texi *, enum texicmd, size_t *); static void dosp(struct texi *, enum texicmd, size_t *); @@ -135,6 +134,10 @@ static const struct texitok __texitoks[TEXICMD__MAX] = { dodefindex, "defindex", 8 }, /* TEXICMD_DEFINDEX */ { dodefn, "defmac", 6 }, /* TEXICMD_DEFMAC */ { dodefn, "defmacx", 7 }, /* TEXICMD_DEFMACX */ + { dodefn, "defop", 5 }, /* TEXICMD_DEFOP */ + { dodefn, "defopx", 6 }, /* TEXICMD_DEFOPX */ + { dodefn, "defopt", 6 }, /* TEXICMD_DEFOPT */ + { dodefn, "defoptx", 7 }, /* TEXICMD_DEFOPTX */ { dodefn, "deftp", 5 }, /* TEXICMD_DEFTP */ { dodefn, "deftpx", 6 }, /* TEXICMD_DEFTPX */ { dodefn, "deftypefn", 9 }, /* TEXICMD_DEFTYPEFN */ @@ -153,7 +156,7 @@ static const struct texitok __texitoks[TEXICMD__MAX] = { dodefn, "defvarx", 7 }, /* TEXICMD_DEFVARX */ { dodefn, "defvr", 5 }, /* TEXICMD_DEFVR */ { dodefn, "defvrx", 6 }, /* TEXICMD_DEFVRX */ - { domenu, "detailmenu", 10 }, /* TEXICMD_DETAILMENU */ + { doignblock, "detailmenu", 10 }, /* TEXICMD_DETAILMENU */ { doinline, "dfn", 3 }, /* TEXICMD_DFN */ { dosymbol, "DH", 2 }, /* TEXICMD_DH */ { dosymbol, "dh", 2 }, /* TEXICMD_DHSMALL */ @@ -326,7 +329,7 @@ static const struct texitok __texitoks[TEXICMD__MAX] = { doignline, "title", 5 }, /* TEXICMD_TITLE */ { dobracket, "titlefont", 9 }, /* TEXICMD_TITLEFONT */ { doignblock, "titlepage", 9 }, /* TEXICMD_TITLEPAGE */ - { dotop, "top", 3 }, /* TEXICMD_TOP */ + { dosection, "top", 3 }, /* TEXICMD_TOP */ { doindex, "tpindex", 7 }, /* TEXICMD_TPINDEX */ { doaccent, "u", 1 }, /* TEXICMD_U */ { doaccent, "ubaraccent", 10 }, /* TEXICMD_UBARACCENT */ @@ -394,6 +397,8 @@ dodefn(struct texi *p, enum texicmd cmd, size_t *pos) switch (cmd) { case (TEXICMD_DEFFN): case (TEXICMD_DEFMAC): + case (TEXICMD_DEFOP): + case (TEXICMD_DEFOPT): case (TEXICMD_DEFTP): case (TEXICMD_DEFTYPEFN): case (TEXICMD_DEFTYPEFUN): @@ -430,6 +435,10 @@ dodefn(struct texi *p, enum texicmd cmd, size_t *pos) case (TEXICMD_DEFMACX): texiputchars(p, "Macro"); break; + case (TEXICMD_DEFOPT): + case (TEXICMD_DEFOPTX): + texiputchars(p, "User Option"); + break; case (TEXICMD_DEFTYPEVAR): case (TEXICMD_DEFTYPEVARX): case (TEXICMD_DEFVAR): @@ -472,6 +481,8 @@ dodefn(struct texi *p, enum texicmd cmd, size_t *pos) teximacroclose(p); teximacro(p, "Fc"); break; + case (TEXICMD_DEFOP): + case (TEXICMD_DEFOPX): case (TEXICMD_DEFTYPEFUN): case (TEXICMD_DEFTYPEFUNX): case (TEXICMD_DEFTYPEFN): @@ -501,6 +512,8 @@ dodefn(struct texi *p, enum texicmd cmd, size_t *pos) /* Spin. */ ; teximacroclose(p); break; + case (TEXICMD_DEFOPT): + case (TEXICMD_DEFOPTX): case (TEXICMD_DEFVAR): case (TEXICMD_DEFVARX): case (TEXICMD_DEFVR): @@ -532,6 +545,8 @@ dodefn(struct texi *p, enum texicmd cmd, size_t *pos) switch (peekcmd(p, *pos)) { case (TEXICMD_DEFFNX): case (TEXICMD_DEFMACX): + case (TEXICMD_DEFOPX): + case (TEXICMD_DEFOPTX): case (TEXICMD_DEFTPX): case (TEXICMD_DEFTYPEFNX): case (TEXICMD_DEFTYPEFUNX): @@ -663,7 +678,7 @@ doignblock(struct texi *p, enum texicmd cmd, size_t *p "@%s", texitoks[cmd].tok); assert(ssz < sizeof(start)); esz = snprintf(end, sizeof(end), - "@end %s\n", texitoks[cmd].tok); + "@end %s", texitoks[cmd].tok); assert(esz < sizeof(end)); stack = 1; @@ -847,16 +862,25 @@ docopying(struct texi *p, enum texicmd cmd, size_t *po } term = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, end, endsz); - if (NULL == term) { - texiwarn(p, "unterminated \"%s\"", texitoks[cmd].tok); - endpos = BUFSZ(p); - } else + if (NULL == term) + texierr(p, "unterminated \"%s\"", texitoks[cmd].tok); + else endpos = *pos + (size_t)(term - &BUF(p)[*pos]); - assert(endpos <= BUFSZ(p)); + if (endpos == *pos) { + advanceeoln(p, pos, 1); + return; + } + + assert(endpos < BUFSZ(p) && endpos > *pos); assert('\n' == BUF(p)[*pos]); advance(p, pos); + if (*pos == BUFSZ(p)) { + texiwarn(p, "unterminated \"%s\"", texitoks[cmd].tok); + return; + } + p->copying = malloc(endpos - *pos + 1); p->copyingsz = endpos - *pos; memcpy(p->copying, &BUF(p)[*pos], p->copyingsz); @@ -1477,8 +1501,9 @@ doquotation(struct texi *p, enum texicmd cmd, size_t * static int indexcmp(const void *p1, const void *p2) { + const struct texiterm *t1 = p1, *t2 = p2; - return(strcasecmp(*(const char **)p1, *(const char **)p2)); + return(strcasecmp(t1->term, t2->term)); } static void @@ -1487,6 +1512,7 @@ doprintindex(struct texi *p, enum texicmd cmd, size_t size_t i, j, start, end, len; #if HAVE_INDEX char *cp; + char buf[PATH_MAX]; #endif while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) @@ -1522,26 +1548,38 @@ doprintindex(struct texi *p, enum texicmd cmd, size_t /* Alphabetically sort our indices. */ qsort(p->indexs[i].index, - p->indexs[i].indexsz, sizeof(char *), indexcmp); + p->indexs[i].indexsz, + sizeof(struct texiterm), indexcmp); texivspace(p); teximacro(p, "Bl -tag -width Ds -compact"); for (j = 0; j < p->indexs[i].indexsz; j++) { teximacroopen(p, "It"); #if HAVE_INDEX - teximacroopen(p, "Lkx"); - texiputchars(p, "\"idx"); - texiputchars(p, p->indexs[i].name); - cp = p->indexs[i].index[j]; - while ('\n' != *cp) { - assert('\0' != *cp); - texiputchar(p, *cp++); + if (NULL == p->chapters) { + teximacroopen(p, "Lkx"); + texiputchars(p, "\"idx"); + texiputchars(p, p->indexs[i].name); + cp = p->indexs[i].index[j].term; + while ('\n' != *cp) + texiputchar(p, *cp++); + texiputchars(p, "\" \""); + p->literal++; + } else { + teximacroopen(p, "Xr"); + snprintf(buf, sizeof(buf), "%s-%zd 7 \"idx", + p->chapters, p->indexs[i].index[j].chapter); + texiputchars(p, buf); + texiputchars(p, p->indexs[i].name); + cp = p->indexs[i].index[j].term; + while ('\n' != *cp) + texiputchar(p, *cp++); + texiputchars(p, "\" \""); + p->literal++; } - texiputchars(p, "\" \""); - p->literal++; #endif - texisplice(p, p->indexs[i].index[j], - strlen(p->indexs[i].index[j]), *pos); + texisplice(p, p->indexs[i].index[j].term, + strlen(p->indexs[i].index[j].term), *pos); parseeoln(p, pos); #if HAVE_INDEX p->literal--; @@ -1559,30 +1597,55 @@ static void donode(struct texi *p, enum texicmd cmd, size_t *pos) { int sv = p->seenvs; + char fname[PATH_MAX]; + size_t end, start; - if (NULL != p->chapters) { - advanceeoln(p, pos, 1); - return; - } + if (0 == p->nodesz++) + p->ign--; -#if HAVE_INDEX - p->seenvs = -1; - teximacroopen(p, "Ix"); - texiputchars(p, "node"); + /* Grab our node name. */ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) advance(p, pos); + start = *pos; while (*pos < BUFSZ(p)) { if (BUF(p)[*pos] == ',') break; else if (BUF(p)[*pos] == '\n') break; - texiputchar(p, BUF(p)[*pos]); advance(p, pos); } - teximacroclose(p); -#endif + if (*pos == BUFSZ(p)) { + texiwarn(p, "unexpected EOF"); + return; + } + end = *pos; advanceeoln(p, pos, 1); - p->seenvs = sv; + + if (NULL != p->chapters) + teximdocclose(p, 0); + + /* Cache our node name. */ + p->nodecur = texicache(p, &BUF(p)[start], end - start); + + if (NULL != p->chapters) { + snprintf(fname, sizeof(fname), + "%s-%zd.7", p->chapters, p->nodecur); + p->outfile = fopen(fname, "w"); + if (NULL == p->outfile) + texiabort(p, fname); + teximdocopen(p, pos); + } else if (p->nodesz > 1) { + /* Otherwise, mark our index. */ + p->seenvs = -1; +#if HAVE_INDEX + teximacroopen(p, "Ix"); + texiputchars(p, "node"); + texiputchars(p, p->nodecache[p->nodecur].name); + teximacroclose(p); +#endif + p->seenvs = sv; + } else + teximdocopen(p, pos); } /* @@ -1593,13 +1656,12 @@ donode(struct texi *p, enum texicmd cmd, size_t *pos) static void domenu(struct texi *p, enum texicmd cmd, size_t *pos) { - size_t start, end, sv; + size_t nodename, entryname; + size_t nodenameend, entrynameend, i; + ssize_t ppos, lastppos; + char buf[PATH_MAX]; + enum texicmd tcmd; - if (NULL != p->chapters) { - doignblock(p, cmd, pos); - return; - } - advanceeoln(p, pos, 1); /* @@ -1618,6 +1680,7 @@ domenu(struct texi *p, enum texicmd cmd, size_t *pos) break; } + lastppos = -1; texivspace(p); teximacro(p, "Bl -tag -width Ds -compact"); while (*pos < BUFSZ(p)) { @@ -1633,9 +1696,13 @@ domenu(struct texi *p, enum texicmd cmd, size_t *pos) while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) advance(p, pos); if ('*' != BUF(p)[*pos]) { - if (TEXICMD_END == peeklinecmd(p, *pos)) + tcmd = peeklinecmd(p, *pos); + if (TEXICMD_END == tcmd) break; - parseeoln(p, pos); + else if (TEXICMD_COMMENT == tcmd) + advanceeoln(p, pos, 1); + else + parseeoln(p, pos); continue; } @@ -1643,23 +1710,21 @@ domenu(struct texi *p, enum texicmd cmd, size_t *pos) advance(p, pos); while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) advance(p, pos); - start = sv = *pos; + entryname = *pos; while (*pos < BUFSZ(p) && ':' != BUF(p)[*pos]) advance(p, pos); - end = *pos; + entrynameend = *pos; advance(p, pos); + p->seenvs = 0; + teximacroopen(p, "It"); if (*pos == BUFSZ(p)) { texiwarn(p, "bad menu syntax"); break; } else if (':' != BUF(p)[*pos]) { while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) advance(p, pos); - teximacroopen(p, "It"); -#ifdef HAVE_INDEX - teximacroopen(p, "Lkx"); - texiputchars(p, "\"node"); -#endif + nodename = *pos; while (*pos < BUFSZ(p)) { switch (BUF(p)[*pos]) { case ('\t'): @@ -1677,38 +1742,53 @@ domenu(struct texi *p, enum texicmd cmd, size_t *pos) } /* FALLTHROUGH */ default: - texiputchar(p, BUF(p)[*pos]); advance(p, pos); continue; } advance(p, pos); break; } -#ifdef HAVE_INDEX - texiputchars(p, "\" \""); - for (start = sv; start < end; start++) - texiputchar(p, BUF(p)[start]); - texiputchar(p, '"'); -#endif + nodenameend = *pos; } else { advance(p, pos); - p->seenvs = 0; - teximacroopen(p, "It"); + nodename = entryname; + nodenameend = entrynameend; + } + ppos = texicache(p, &BUF(p)[nodename], + nodenameend - nodename); + if (-1 != lastppos) + p->nodecache[lastppos].next = ppos; + p->nodecache[ppos].prev = lastppos; + p->nodecache[ppos].up = p->nodecur; + lastppos = ppos; #ifdef HAVE_INDEX + if (NULL == p->chapters) { teximacroopen(p, "Lkx"); texiputchars(p, "\"node"); - for (start = sv; start < end; start++) - texiputchar(p, BUF(p)[start]); + for (i = nodename; i < nodenameend; i++) + texiputchar(p, BUF(p)[i]); texiputchars(p, "\" \""); -#endif - for (start = sv; start < end; start++) - texiputchar(p, BUF(p)[start]); -#ifdef HAVE_INDEX - texiputchar(p, '"'); -#endif + for (i = entryname; i < entrynameend; i++) + texiputchar(p, BUF(p)[i]); + texiputchars(p, "\""); + teximacroclose(p); + } else { + snprintf(buf, sizeof(buf), + "%s-%zd 7 ", p->chapters, ppos); + teximacroopen(p, "Xr"); + texiputchars(p, buf); + texiputchars(p, "\"node"); + for (i = nodename; i < nodenameend; i++) + texiputchar(p, BUF(p)[i]); + texiputchars(p, "\" \""); + for (i = entryname; i < entrynameend; i++) + texiputchar(p, BUF(p)[i]); + texiputchars(p, "\""); + teximacroclose(p); } -#ifdef HAVE_INDEX - teximacroclose(p); +#else + for (i = entryname; i < entrynameend; i++) + texiputchar(p, BUF(p)[i]); #endif teximacroclose(p); } @@ -1914,11 +1994,6 @@ dosection(struct texi *p, enum texicmd cmd, size_t *po else texivspace(p); - if (0 == sec && NULL != p->chapters) { - teximdocclose(p, 0); - teximdocopen(p, pos); - } - teximacroopen(p, sects[sec]); parseeoln(p, pos); teximacroclose(p); @@ -1927,18 +2002,6 @@ dosection(struct texi *p, enum texicmd cmd, size_t *po p->seenvs = -1; else texivspace(p); -} - -static void -dotop(struct texi *p, enum texicmd cmd, size_t *pos) -{ - - if (--p->ign) - texierr(p, "@top command while ignoring"); - - if (NULL == p->chapters) - teximdocopen(p, pos); - dosection(p, cmd, pos); } static void