=================================================================== RCS file: /cvs/mandoc/demandoc.c,v retrieving revision 1.4 retrieving revision 1.15 diff -u -p -r1.4 -r1.15 --- mandoc/demandoc.c 2011/09/01 20:55:50 1.4 +++ mandoc/demandoc.c 2015/02/10 08:05:30 1.15 @@ -1,4 +1,4 @@ -/* $Id: demandoc.c,v 1.4 2011/09/01 20:55:50 kristaps Exp $ */ +/* $Id: demandoc.c,v 1.15 2015/02/10 08:05:30 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * @@ -14,10 +14,10 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif +#include + #include #include #include @@ -43,11 +43,13 @@ int main(int argc, char *argv[]) { struct mparse *mp; - int ch, i, list; + struct mchars *mchars; + int ch, fd, i, list; extern int optind; - progname = strrchr(argv[0], '/'); - if (progname == NULL) + if (argc < 1) + progname = "demandoc"; + else if ((progname = strrchr(argv[0], '/')) == NULL) progname = argv[0]; else ++progname; @@ -76,18 +78,24 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - mp = mparse_alloc(MPARSE_AUTO, MANDOCLEVEL_FATAL, NULL, NULL); + mchars = mchars_alloc(); + mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, mchars, NULL); assert(mp); - if (0 == argc) + if (argc < 1) pmandoc(mp, STDIN_FILENO, "", list); for (i = 0; i < argc; i++) { mparse_reset(mp); - pmandoc(mp, -1, argv[i], list); + if (mparse_open(mp, &fd, argv[i]) != MANDOCLEVEL_OK) { + perror(argv[i]); + continue; + } + pmandoc(mp, fd, argv[i], list); } mparse_free(mp); + mchars_free(mchars); return((int)MANDOCLEVEL_OK); } @@ -105,23 +113,20 @@ pmandoc(struct mparse *mp, int fd, const char *fn, int struct man *man; int line, col; - if (mparse_readfd(mp, fd, fn) >= MANDOCLEVEL_FATAL) { - fprintf(stderr, "%s: Parse failure\n", fn); - return; - } - - mparse_result(mp, &mdoc, &man); + mparse_readfd(mp, fd, fn); + mparse_result(mp, &mdoc, &man, NULL); line = 1; col = 0; - if (mdoc) + if (mdoc) pmdoc(mdoc_node(mdoc), &line, &col, list); else if (man) pman(man_node(man), &line, &col, list); else return; - putchar('\n'); + if ( ! list) + putchar('\n'); } /* @@ -131,13 +136,71 @@ static void pstring(const char *p, int col, int *colp, int list) { enum mandoc_esc esc; + const char *start, *end; + int emit; + /* + * Print as many column spaces til we achieve parity with the + * input document. + */ + +again: + if (list && '\0' != *p) { + while (isspace((unsigned char)*p)) + p++; + + while ('\'' == *p || '(' == *p || '"' == *p) + p++; + + emit = isalpha((unsigned char)p[0]) && + isalpha((unsigned char)p[1]); + + for (start = p; '\0' != *p; p++) + if ('\\' == *p) { + p++; + esc = mandoc_escape(&p, NULL, NULL); + if (ESCAPE_ERROR == esc) + return; + emit = 0; + } else if (isspace((unsigned char)*p)) + break; + + end = p - 1; + + while (end > start) + if ('.' == *end || ',' == *end || + '\'' == *end || '"' == *end || + ')' == *end || '!' == *end || + '?' == *end || ':' == *end || + ';' == *end) + end--; + else + break; + + if (emit && end - start >= 1) { + for ( ; start <= end; start++) + if (ASCII_HYPH == *start) + putchar('-'); + else + putchar((unsigned char)*start); + putchar('\n'); + } + + if (isspace((unsigned char)*p)) + goto again; + + return; + } + while (*colp < col) { putchar(' '); (*colp)++; } - while ('\0' != *p) + /* + * Print the input word, skipping any special characters. + */ + while ('\0' != *p) if ('\\' == *p) { p++; esc = mandoc_escape(&p, NULL, NULL); @@ -153,6 +216,14 @@ static void pline(int line, int *linep, int *col, int list) { + if (list) + return; + + /* + * Print out as many lines as needed to reach parity with the + * original input. + */ + while (*linep < line) { putchar('\n'); (*linep)++; @@ -170,7 +241,7 @@ pmdoc(const struct mdoc_node *p, int *line, int *col, pline(p->line, line, col, list); if (MDOC_TEXT == p->type) pstring(p->string, p->pos, col, list); - if (p->child) + if (p->child) pmdoc(p->child, line, col, list); } } @@ -184,7 +255,7 @@ pman(const struct man_node *p, int *line, int *col, in pline(p->line, line, col, list); if (MAN_TEXT == p->type) pstring(p->string, p->pos, col, list); - if (p->child) + if (p->child) pman(p->child, line, col, list); } }