/* ARGSUSED */ static enum rofferr roff_ds(ROFF_ARGS) { char *name, *string; /* * A symbol is named by the first word following the macro * invocation up to a space. Its value is anything after the * name's trailing whitespace and optional double-quote. Thus, * * [.ds foo "bar " ] * * will have `bar " ' as its value. */ string = *bufp + pos; name = roff_getname(r, &string, ln, pos); if ('\0' == *name) return(ROFF_IGN); /* Read past initial double-quote. */ if ('"' == *string) string++; /* The rest is the value. */ roff_setstr(r, name, string, 0); return(ROFF_IGN); }
/* ARGSUSED */ static enum rofferr roff_block_sub(ROFF_ARGS) { enum rofft t; int i, j; /* * First check whether a custom macro exists at this level. If * it does, then check against it. This is some of groff's * stranger behaviours. If we encountered a custom end-scope * tag and that tag also happens to be a "real" macro, then we * need to try interpreting it again as a real macro. If it's * not, then return ignore. Else continue. */ if (r->last->end) { for (i = pos, j = 0; r->last->end[j]; j++, i++) if ((*bufp)[i] != r->last->end[j]) break; if ('\0' == r->last->end[j] && ('\0' == (*bufp)[i] || ' ' == (*bufp)[i] || '\t' == (*bufp)[i])) { roffnode_pop(r); roffnode_cleanscope(r); while (' ' == (*bufp)[i] || '\t' == (*bufp)[i]) i++; pos = i; if (ROFF_MAX != roff_parse(r, *bufp, &pos)) return(ROFF_RERUN); return(ROFF_IGN); } } /* * If we have no custom end-query or lookup failed, then try * pulling it out of the hashtable. */ t = roff_parse(r, *bufp, &pos); /* * Macros other than block-end are only significant * in `de' blocks; elsewhere, simply throw them away. */ if (ROFF_cblock != t) { if (ROFF_de == tok) roff_setstr(r, r->last->name, *bufp + ppos, 1); return(ROFF_IGN); } assert(roffs[t].proc); return((*roffs[t].proc)(r, t, bufp, szp, ln, ppos, pos, offs)); }
/* ARGSUSED */ static enum rofferr roff_block_text(ROFF_ARGS) { if (ROFF_de == tok) roff_setstr(r, r->last->name, *bufp + pos, 1); return(ROFF_IGN); }
/* ARGSUSED */ static enum rofferr roff_TH(ROFF_ARGS) { const char *const *cp; if (MPARSE_MDOC != r->parsetype) for (cp = __man_reserved; *cp; cp++) roff_setstr(r, *cp, NULL, 0); return(ROFF_CONT); }
void roff_reset(struct roff *r) { int i; roff_free1(r); r->control = 0; for (i = 0; i < PREDEFS_MAX; i++) roff_setstr(r, predefs[i].name, predefs[i].str, 0); }
void roff_reset(struct roff *r) { int i; roff_free1(r); r->control = 0; memset(&r->regs, 0, sizeof(struct reg) * REG__MAX); for (i = 0; i < PREDEFS_MAX; i++) roff_setstr(r, predefs[i].name, predefs[i].str, 0); }
void roff_reset(struct roff *r) { int i; roff_free1(r); memset(&r->regs, 0, sizeof(r->regs)); memset(&r->nr, 0, sizeof(r->nr)); for (i = 0; i < PREDEFS_MAX; i++) roff_setstr(r, predefs[i].name, predefs[i].str, 0); }
/* ARGSUSED */ static enum rofferr roff_rm(ROFF_ARGS) { const char *name; char *cp; cp = *bufp + pos; while ('\0' != *cp) { name = roff_getname(r, &cp, ln, (int)(cp - *bufp)); if ('\0' != *name) roff_setstr(r, name, NULL, 0); } return(ROFF_IGN); }
struct roff * roff_alloc(struct mparse *parse) { struct roff *r; int i; r = mandoc_calloc(1, sizeof(struct roff)); r->parse = parse; r->rstackpos = -1; roffhash_init(); for (i = 0; i < PREDEFS_MAX; i++) roff_setstr(r, predefs[i].name, predefs[i].str, 0); return(r); }
/* ARGSUSED */ static enum rofferr roff_block(ROFF_ARGS) { int sv; size_t sz; char *name; name = NULL; if (ROFF_ig != tok) { if ('\0' == (*bufp)[pos]) { mandoc_msg(MANDOCERR_NOARGS, r->parse, ln, ppos, NULL); return(ROFF_IGN); } /* * Re-write `de1', since we don't really care about * groff's strange compatibility mode, into `de'. */ if (ROFF_de1 == tok) tok = ROFF_de; if (ROFF_de == tok) name = *bufp + pos; else mandoc_msg(MANDOCERR_REQUEST, r->parse, ln, ppos, roffs[tok].name); while ((*bufp)[pos] && ! isspace((unsigned char)(*bufp)[pos])) pos++; while (isspace((unsigned char)(*bufp)[pos])) (*bufp)[pos++] = '\0'; } roffnode_push(r, tok, name, ln, ppos); /* * At the beginning of a `de' macro, clear the existing string * with the same name, if there is one. New content will be * added from roff_block_text() in multiline mode. */ if (ROFF_de == tok) roff_setstr(r, name, "", 0); if ('\0' == (*bufp)[pos]) return(ROFF_IGN); /* If present, process the custom end-of-line marker. */ sv = pos; while ((*bufp)[pos] && ! isspace((unsigned char)(*bufp)[pos])) pos++; /* * Note: groff does NOT like escape characters in the input. * Instead of detecting this, we're just going to let it fly and * to hell with it. */ assert(pos > sv); sz = (size_t)(pos - sv); if (1 == sz && '.' == (*bufp)[sv]) return(ROFF_IGN); r->last->end = mandoc_malloc(sz + 1); memcpy(r->last->end, *bufp + sv, sz); r->last->end[(int)sz] = '\0'; if ((*bufp)[pos]) mandoc_msg(MANDOCERR_ARGSLOST, r->parse, ln, pos, NULL); return(ROFF_IGN); }