=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/mdoc.c,v retrieving revision 1.45 retrieving revision 1.46 diff -c -r1.45 -r1.46 *** src/usr.bin/mandoc/mdoc.c 2010/05/08 01:57:33 1.45 --- src/usr.bin/mandoc/mdoc.c 2010/05/14 01:54:37 1.46 *************** *** 1,4 **** ! /* $Id: mdoc.c,v 1.45 2010/05/08 01:57:33 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * --- 1,4 ---- ! /* $Id: mdoc.c,v 1.46 2010/05/14 01:54:37 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * *************** *** 150,158 **** static int mdoc_ptext(struct mdoc *, int, char *); static int mdoc_pmacro(struct mdoc *, int, char *); static int macrowarn(struct mdoc *, int, const char *); - static int pstring(struct mdoc *, int, int, - const char *, size_t); const struct mdoc_node * mdoc_node(const struct mdoc *m) { --- 150,157 ---- static int mdoc_ptext(struct mdoc *, int, char *); static int mdoc_pmacro(struct mdoc *, int, char *); static int macrowarn(struct mdoc *, int, const char *); + const struct mdoc_node * mdoc_node(const struct mdoc *m) { *************** *** 345,359 **** mdoc_macro(struct mdoc *m, enum mdoct tok, int ln, int pp, int *pos, char *buf) { - assert(tok < MDOC_MAX); ! /* ! * If we're in the prologue, deny "body" macros. Similarly, if ! * we're in the body, deny prologue calls. ! */ if (MDOC_PROLOGUE & mdoc_macros[tok].flags && MDOC_PBODY & m->flags) return(mdoc_perr(m, ln, pp, EPROLBODY)); if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) && ! (MDOC_PBODY & m->flags)) { if ( ! mdoc_pwarn(m, ln, pp, EBODYPROL)) --- 344,359 ---- mdoc_macro(struct mdoc *m, enum mdoct tok, int ln, int pp, int *pos, char *buf) { assert(tok < MDOC_MAX); ! ! /* If we're in the body, deny prologue calls. */ ! if (MDOC_PROLOGUE & mdoc_macros[tok].flags && MDOC_PBODY & m->flags) return(mdoc_perr(m, ln, pp, EPROLBODY)); + + /* If we're in the prologue, deny "body" macros. */ + if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) && ! (MDOC_PBODY & m->flags)) { if ( ! mdoc_pwarn(m, ln, pp, EBODYPROL)) *************** *** 530,542 **** } ! static int ! pstring(struct mdoc *m, int line, int pos, const char *p, size_t len) { struct mdoc_node *n; ! size_t sv; ! n = node_alloc(m, line, pos, -1, MDOC_TEXT); n->string = mandoc_malloc(len + 1); sv = strlcpy(n->string, p, len + 1); --- 530,544 ---- } ! int ! mdoc_word_alloc(struct mdoc *m, int line, int pos, const char *p) { struct mdoc_node *n; ! size_t sv, len; ! len = strlen(p); ! ! n = node_alloc(m, line, pos, MDOC_MAX, MDOC_TEXT); n->string = mandoc_malloc(len + 1); sv = strlcpy(n->string, p, len + 1); *************** *** 545,563 **** if ( ! node_append(m, n)) return(0); m->next = MDOC_NEXT_SIBLING; return(1); } - int - mdoc_word_alloc(struct mdoc *m, int line, int pos, const char *p) - { - - return(pstring(m, line, pos, p, strlen(p))); - } - - void mdoc_node_free(struct mdoc_node *p) { --- 547,558 ---- if ( ! node_append(m, n)) return(0); + m->next = MDOC_NEXT_SIBLING; return(1); } void mdoc_node_free(struct mdoc_node *p) { *************** *** 628,713 **** static int mdoc_ptext(struct mdoc *m, int line, char *buf) { ! int i, j; ! char sv; /* Ignore bogus comments. */ if ('\\' == buf[0] && '.' == buf[1] && '\"' == buf[2]) return(mdoc_pwarn(m, line, 0, EBADCOMMENT)); if (SEC_NONE == m->lastnamed) return(mdoc_perr(m, line, 0, ETEXTPROL)); - - /* - * If in literal mode, then pass the buffer directly to the - * back-end, as it should be preserved as a single term. - */ if (MDOC_LITERAL & m->flags) return(mdoc_word_alloc(m, line, 0, buf)); ! /* Disallow blank/white-space lines in non-literal mode. */ for (i = 0; ' ' == buf[i]; i++) ! /* Skip leading whitespace. */ ; if ('\0' == buf[i]) { if ( ! mdoc_pwarn(m, line, 0, ENOBLANK)) return(0); /* ! * Assume that a `Pp' should be inserted in the case of ! * a blank line. Technically, blank lines aren't ! * allowed, but enough manuals assume this behaviour ! * that we want to work around it. */ if ( ! mdoc_elem_alloc(m, line, 0, MDOC_Pp, NULL)) return(0); m->next = MDOC_NEXT_SIBLING; return(1); } ! /* ! * Break apart a free-form line into tokens. Spaces are ! * stripped out of the input. */ ! for (j = i; buf[i]; i++) { ! if (' ' != buf[i]) ! continue; ! /* Escaped whitespace. */ ! if (i && ' ' == buf[i] && '\\' == buf[i - 1]) ! continue; ! ! sv = buf[i]; ! buf[i++] = '\0'; ! ! if ( ! pstring(m, line, j, &buf[j], (size_t)(i - j))) ! return(0); ! ! /* Trailing whitespace? Check at overwritten byte. */ ! ! if (' ' == sv && '\0' == buf[i]) if ( ! mdoc_pwarn(m, line, i - 1, ETAILWS)) return(0); ! for ( ; ' ' == buf[i]; i++) ! /* Skip trailing whitespace. */ ; ! j = i; ! /* Trailing whitespace? */ ! ! if (' ' == buf[i - 1] && '\0' == buf[i]) ! if ( ! mdoc_pwarn(m, line, i - 1, ETAILWS)) ! return(0); ! ! if ('\0' == buf[i]) ! break; } ! if (j != i && ! pstring(m, line, j, &buf[j], (size_t)(i - j))) return(0); /* --- 623,690 ---- static int mdoc_ptext(struct mdoc *m, int line, char *buf) { ! int i; /* Ignore bogus comments. */ if ('\\' == buf[0] && '.' == buf[1] && '\"' == buf[2]) return(mdoc_pwarn(m, line, 0, EBADCOMMENT)); + /* No text before an initial macro. */ + if (SEC_NONE == m->lastnamed) return(mdoc_perr(m, line, 0, ETEXTPROL)); + /* Literal just gets pulled in as-is. */ + if (MDOC_LITERAL & m->flags) return(mdoc_word_alloc(m, line, 0, buf)); ! /* Check for a blank line, which may also consist of spaces. */ for (i = 0; ' ' == buf[i]; i++) ! /* Skip to first non-space. */ ; if ('\0' == buf[i]) { if ( ! mdoc_pwarn(m, line, 0, ENOBLANK)) return(0); + /* ! * Insert a `Pp' in the case of a blank line. Technically, ! * blank lines aren't allowed, but enough manuals assume this ! * behaviour that we want to work around it. */ if ( ! mdoc_elem_alloc(m, line, 0, MDOC_Pp, NULL)) return(0); + m->next = MDOC_NEXT_SIBLING; return(1); } ! /* ! * Warn if the last un-escaped character is whitespace. Then ! * strip away the remaining spaces (tabs stay!). */ ! i = (int)strlen(buf); ! assert(i); ! if (' ' == buf[i - 1] || '\t' == buf[i - 1]) { ! if (i > 1 && '\\' != buf[i - 2]) if ( ! mdoc_pwarn(m, line, i - 1, ETAILWS)) return(0); ! for (--i; i && ' ' == buf[i]; i--) ! /* Spin back to non-space. */ ; ! /* Jump ahead of escaped whitespace. */ ! i += '\\' == buf[i] ? 2 : 1; ! buf[i] = '\0'; } ! /* Allocate the whole word. */ ! if ( ! mdoc_word_alloc(m, line, 0, buf)) return(0); /* *************** *** 725,737 **** } - static int macrowarn(struct mdoc *m, int ln, const char *buf) { if ( ! (MDOC_IGN_MACRO & m->pflags)) ! return(mdoc_verr(m, ln, 0, ! "unknown macro: %s%s", buf, strlen(buf) > 3 ? "..." : "")); return(mdoc_vwarn(m, ln, 0, "unknown macro: %s%s", buf, strlen(buf) > 3 ? "..." : "")); --- 702,712 ---- } static int macrowarn(struct mdoc *m, int ln, const char *buf) { if ( ! (MDOC_IGN_MACRO & m->pflags)) ! return(mdoc_verr(m, ln, 0, "unknown macro: %s%s", buf, strlen(buf) > 3 ? "..." : "")); return(mdoc_vwarn(m, ln, 0, "unknown macro: %s%s", buf, strlen(buf) > 3 ? "..." : "")); *************** *** 745,752 **** int mdoc_pmacro(struct mdoc *m, int ln, char *buf) { ! int i, j, c; ! char mac[5]; struct mdoc_node *n; char *t; --- 720,728 ---- int mdoc_pmacro(struct mdoc *m, int ln, char *buf) { ! enum mdoct tok; ! int i, j; ! char mac[5]; struct mdoc_node *n; char *t; *************** *** 790,796 **** return(1); } ! if (MDOC_MAX == (c = mdoc_hash_find(mac))) { if ( ! macrowarn(m, ln, mac)) goto err; return(1); --- 766,772 ---- return(1); } ! if (MDOC_MAX == (tok = mdoc_hash_find(mac))) { if ( ! macrowarn(m, ln, mac)) goto err; return(1); *************** *** 801,807 **** while (buf[i] && ' ' == buf[i]) i++; ! /* Trailing whitespace? */ if ('\0' == buf[i] && ' ' == buf[i - 1]) if ( ! mdoc_pwarn(m, ln, i - 1, ETAILWS)) --- 777,786 ---- while (buf[i] && ' ' == buf[i]) i++; ! /* ! * Trailing whitespace. Note that tabs are allowed to be passed ! * into the parser as "text", so we only warn about spaces here. ! */ if ('\0' == buf[i] && ' ' == buf[i - 1]) if ( ! mdoc_pwarn(m, ln, i - 1, ETAILWS)) *************** *** 811,817 **** * Begin recursive parse sequence. Since we're at the start of * the line, we don't need to do callable/parseable checks. */ ! if ( ! mdoc_macro(m, c, ln, 1, &i, buf)) goto err; /* --- 790,796 ---- * Begin recursive parse sequence. Since we're at the start of * the line, we don't need to do callable/parseable checks. */ ! if ( ! mdoc_macro(m, tok, ln, 1, &i, buf)) goto err; /*