/* * Rewind scope. If a code "er" != MANDOCERR_MAX has been provided, it * will be used if an explicit block scope is being closed out. */ int man_unscope(struct man *man, const struct man_node *to, enum mandocerr er) { struct man_node *n; assert(to); man->next = MAN_NEXT_SIBLING; /* LINTED */ while (man->last != to) { /* * Save the parent here, because we may delete the * man->last node in the post-validation phase and reset * it to man->last->parent, causing a step in the closing * out to be lost. */ n = man->last->parent; rew_warn(man, man->last, er); if ( ! man_valid_post(man)) return(0); man->last = n; assert(man->last); } rew_warn(man, man->last, er); if ( ! man_valid_post(man)) return(0); return(1); }
static int man_node_append(struct man *man, struct man_node *p) { assert(man->last); assert(man->first); assert(MAN_ROOT != p->type); switch (man->next) { case (MAN_NEXT_SIBLING): man->last->next = p; p->prev = man->last; p->parent = man->last->parent; break; case (MAN_NEXT_CHILD): man->last->child = p; p->parent = man->last; break; default: abort(); /* NOTREACHED */ } assert(p->parent); p->parent->nchild++; if ( ! man_valid_pre(man, p)) return(0); switch (p->type) { case (MAN_HEAD): assert(MAN_BLOCK == p->parent->type); p->parent->head = p; break; case (MAN_TAIL): assert(MAN_BLOCK == p->parent->type); p->parent->tail = p; break; case (MAN_BODY): assert(MAN_BLOCK == p->parent->type); p->parent->body = p; break; default: break; } man->last = p; switch (p->type) { case (MAN_TBL): /* FALLTHROUGH */ case (MAN_TEXT): if ( ! man_valid_post(man)) return(0); break; default: break; } return(1); }
static int man_node_append(struct man *man, struct man_node *p) { assert(man->last); assert(man->first); assert(MAN_ROOT != p->type); switch (man->next) { case MAN_NEXT_SIBLING: man->last->next = p; p->prev = man->last; p->parent = man->last->parent; break; case MAN_NEXT_CHILD: man->last->child = p; p->parent = man->last; break; default: abort(); /* NOTREACHED */ } assert(p->parent); p->parent->nchild++; switch (p->type) { case MAN_BLOCK: if (p->tok == MAN_SH || p->tok == MAN_SS) man->flags &= ~MAN_LITERAL; break; case MAN_HEAD: assert(MAN_BLOCK == p->parent->type); p->parent->head = p; break; case MAN_TAIL: assert(MAN_BLOCK == p->parent->type); p->parent->tail = p; break; case MAN_BODY: assert(MAN_BLOCK == p->parent->type); p->parent->body = p; break; default: break; } man->last = p; switch (p->type) { case MAN_TBL: /* FALLTHROUGH */ case MAN_TEXT: if ( ! man_valid_post(man)) return(0); break; default: break; } return(1); }
/* ARGSUSED */ int in_line_eoln(MACRO_PROT_ARGS) { int la; char *p; struct man_node *n; if ( ! man_elem_alloc(man, line, ppos, tok)) return(0); n = man->last; for (;;) { la = *pos; if ( ! man_args(man, line, pos, buf, &p)) break; if ( ! man_word_alloc(man, line, la, p)) return(0); } /* * Append MAN_EOS in case the last snipped argument * ends with a dot, e.g. `.IR syslog (3).' */ if (n != man->last && mandoc_eos(man->last->string, strlen(man->last->string))) man->last->flags |= MAN_EOS; /* * If no arguments are specified and this is MAN_SCOPED (i.e., * next-line scoped), then set our mode to indicate that we're * waiting for terms to load into our context. */ if (n == man->last && MAN_SCOPED & man_macros[tok].flags) { assert( ! (MAN_NSCOPED & man_macros[tok].flags)); man->flags |= MAN_ELINE; return(1); } /* Set ignorable context, if applicable. */ if (MAN_NSCOPED & man_macros[tok].flags) { assert( ! (MAN_SCOPED & man_macros[tok].flags)); man->flags |= MAN_ILINE; } assert(MAN_ROOT != man->last->type); man->next = MAN_NEXT_SIBLING; /* * Rewind our element scope. Note that when TH is pruned, we'll * be back at the root, so make sure that we don't clobber as * its sibling. */ for ( ; man->last; man->last = man->last->parent) { if (man->last == n) break; if (man->last->type == MAN_ROOT) break; if ( ! man_valid_post(man)) return(0); } assert(man->last); /* * Same here regarding whether we're back at the root. */ if (man->last->type != MAN_ROOT && ! man_valid_post(man)) return(0); return(1); }