static void pmandoc(struct mparse *mp, int fd, const char *fn, int list) { struct roff_man *man; int line, col; mparse_readfd(mp, fd, fn); close(fd); mparse_result(mp, &man, NULL); line = 1; col = 0; if (man == NULL) return; if (man->macroset == MACROSET_MDOC) { mdoc_validate(man); pmdoc(man->first->child, &line, &col, list); } else { man_validate(man); pman(man->first->child, &line, &col, list); } if ( ! list) putchar('\n'); }
static void format(const struct req *req, const char *file) { struct manoutput conf; struct mparse *mp; struct roff_man *man; void *vp; int fd; int usepath; if (-1 == (fd = open(file, O_RDONLY, 0))) { puts("<P>You specified an invalid manual file.</P>"); return; } mchars_alloc(); mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, req->q.manpath); mparse_readfd(mp, fd, file); close(fd); memset(&conf, 0, sizeof(conf)); conf.fragment = 1; usepath = strcmp(req->q.manpath, req->p[0]); mandoc_asprintf(&conf.man, "%s?query=%%N&sec=%%S%s%s%s%s", scriptname, req->q.arch ? "&arch=" : "", req->q.arch ? req->q.arch : "", usepath ? "&manpath=" : "", usepath ? req->q.manpath : ""); mparse_result(mp, &man, NULL); if (man == NULL) { fprintf(stderr, "fatal mandoc error: %s/%s\n", req->q.manpath, file); pg_error_internal(); mparse_free(mp); mchars_free(); return; } vp = html_alloc(&conf); if (man->macroset == MACROSET_MDOC) { mdoc_validate(man); html_mdoc(vp, man); } else { man_validate(man); html_man(vp, man); } html_free(vp); mparse_free(mp); mchars_free(); free(conf.man); }
/* Validate the subtree rooted at man->last. */ void man_validate(struct roff_man *man) { struct roff_node *n; const v_check *cp; /* * Translate obsolete macros such that later code * does not need to look for them. */ n = man->last; switch (n->tok) { case MAN_LP: case MAN_P: n->tok = MAN_PP; break; default: break; } /* * Iterate over all children, recursing into each one * in turn, depth-first. */ man->last = man->last->child; while (man->last != NULL) { man_validate(man); if (man->last == n) man->last = man->last->child; else man->last = man->last->next; } /* Finally validate the macro itself. */ man->last = n; man->next = ROFF_NEXT_SIBLING; switch (n->type) { case ROFFT_TEXT: check_text(man, n); break; case ROFFT_ROOT: check_root(man, n); break; case ROFFT_COMMENT: case ROFFT_EQN: case ROFFT_TBL: break; default: if (n->tok < ROFF_MAX) { roff_validate(man); break; } assert(n->tok >= MAN_TH && n->tok < MAN_MAX); cp = man_valids + (n->tok - MAN_TH); if (*cp) (*cp)(man, n); if (man->last == n) n->flags |= NODE_VALID; break; } }