=================================================================== RCS file: /cvs/mandoc/Attic/terminal.c,v retrieving revision 1.2 retrieving revision 1.6 diff -u -p -r1.2 -r1.6 --- mandoc/Attic/terminal.c 2009/03/19 16:40:49 1.2 +++ mandoc/Attic/terminal.c 2009/03/22 19:10:48 1.6 @@ -1,4 +1,4 @@ -/* $Id: terminal.c,v 1.2 2009/03/19 16:40:49 kristaps Exp $ */ +/* $Id: terminal.c,v 1.6 2009/03/22 19:10:48 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -29,23 +29,25 @@ extern size_t strlcpy(char *, const char *, size_t) extern size_t strlcat(char *, const char *, size_t); #endif -static struct termp *termp_alloc(enum termenc); -static void termp_free(struct termp *); -static void termp_body(struct termp *, struct termpair *, +static struct termp *term_alloc(enum termenc); +static void term_free(struct termp *); +static void term_body(struct termp *, struct termpair *, const struct mdoc_meta *, const struct mdoc_node *); -static void termp_head(struct termp *, +static void term_head(struct termp *, const struct mdoc_meta *); -static void termp_foot(struct termp *, +static void term_foot(struct termp *, const struct mdoc_meta *); -static void termp_pword(struct termp *, const char *, int); -static void termp_pescape(struct termp *, +static void term_pword(struct termp *, const char *, int); +static void term_pescape(struct termp *, const char *, int *, int); -static void termp_nescape(struct termp *, +static void term_nescape(struct termp *, const char *, size_t); -static void termp_chara(struct termp *, char); -static void termp_stringa(struct termp *, +static void term_chara(struct termp *, char); +static void term_stringa(struct termp *, const char *, size_t); +static int term_isopendelim(const char *, int); +static int term_isclosedelim(const char *, int); static void sanity(const struct mdoc_node *); /* XXX */ @@ -53,7 +55,7 @@ void * latin1_alloc(void) { - return(termp_alloc(TERMENC_LATIN1)); + return(term_alloc(TERMENC_LATIN1)); } @@ -61,7 +63,7 @@ void * utf8_alloc(void) { - return(termp_alloc(TERMENC_UTF8)); + return(term_alloc(TERMENC_UTF8)); } @@ -69,7 +71,7 @@ void * ascii_alloc(void) { - return(termp_alloc(TERMENC_ASCII)); + return(term_alloc(TERMENC_ASCII)); } @@ -81,11 +83,11 @@ terminal_run(void *arg, const struct mdoc *mdoc) p = (struct termp *)arg; if (NULL == p->symtab) - p->symtab = ascii2htab(); + p->symtab = term_ascii2htab(); - termp_head(p, mdoc_meta(mdoc)); - termp_body(p, NULL, mdoc_meta(mdoc), mdoc_node(mdoc)); - termp_foot(p, mdoc_meta(mdoc)); + term_head(p, mdoc_meta(mdoc)); + term_body(p, NULL, mdoc_meta(mdoc), mdoc_node(mdoc)); + term_foot(p, mdoc_meta(mdoc)); return(1); } @@ -95,25 +97,25 @@ void terminal_free(void *arg) { - termp_free((struct termp *)arg); + term_free((struct termp *)arg); } static void -termp_free(struct termp *p) +term_free(struct termp *p) { if (p->buf) free(p->buf); if (TERMENC_ASCII == p->enc && p->symtab) - asciifree(p->symtab); + term_asciifree(p->symtab); free(p); } static struct termp * -termp_alloc(enum termenc enc) +term_alloc(enum termenc enc) { struct termp *p; @@ -126,6 +128,62 @@ termp_alloc(enum termenc enc) } +static int +term_isclosedelim(const char *p, int len) +{ + + if (1 != len) + return(0); + + switch (*p) { + case('.'): + /* FALLTHROUGH */ + case(','): + /* FALLTHROUGH */ + case(';'): + /* FALLTHROUGH */ + case(':'): + /* FALLTHROUGH */ + case('?'): + /* FALLTHROUGH */ + case('!'): + /* FALLTHROUGH */ + case(')'): + /* FALLTHROUGH */ + case(']'): + /* FALLTHROUGH */ + case('}'): + return(1); + default: + break; + } + + return(0); +} + + +static int +term_isopendelim(const char *p, int len) +{ + + if (1 != len) + return(0); + + switch (*p) { + case('('): + /* FALLTHROUGH */ + case('['): + /* FALLTHROUGH */ + case('{'): + return(1); + default: + break; + } + + return(0); +} + + /* * Flush a line of text. A "line" is loosely defined as being something * that should be followed by a newline, regardless of whether it's @@ -161,7 +219,7 @@ termp_alloc(enum termenc enc) * possible). */ void -flushln(struct termp *p) +term_flushln(struct termp *p) { int i, j; size_t vsz, vis, maxvis, mmax, bp; @@ -222,21 +280,12 @@ flushln(struct termp *p) for (j = 0; j < (int)p->offset; j++) putchar(' '); vis = 0; - } else if (vis + vsz > bp) - warnx("word breaks right margin"); - - /* TODO: hyphenate. */ - - } else { - if (vis && vis + vsz > bp) { - putchar('\n'); - for (j = 0; j < (int)p->rmargin; j++) - putchar(' '); - vis = p->rmargin - p->offset; - } else if (vis + vsz > bp) - warnx("word breaks right margin"); - - /* TODO: hyphenate. */ + } + } else if (vis && vis + vsz > bp) { + putchar('\n'); + for (j = 0; j < (int)p->rmargin; j++) + putchar(' '); + vis = p->rmargin - p->offset; } /* @@ -294,7 +343,7 @@ flushln(struct termp *p) * assertion. */ void -newln(struct termp *p) +term_newln(struct termp *p) { p->flags |= TERMP_NOSPACE; @@ -302,7 +351,7 @@ newln(struct termp *p) p->flags &= ~TERMP_NOLPAD; return; } - flushln(p); + term_flushln(p); p->flags &= ~TERMP_NOLPAD; } @@ -314,10 +363,10 @@ newln(struct termp *p) * assertion. */ void -vspace(struct termp *p) +term_vspace(struct termp *p) { - newln(p); + term_newln(p); putchar('\n'); } @@ -329,24 +378,17 @@ vspace(struct termp *p) * the word and put it verbatim into the output buffer. */ void -word(struct termp *p, const char *word) +term_word(struct termp *p, const char *word) { int i, j, len; + len = (int)strlen(word); + if (p->flags & TERMP_LITERAL) { - termp_pword(p, word, (int)strlen(word)); + term_pword(p, word, len); return; } - if (0 == (len = (int)strlen(word))) - errx(1, "blank line not in literal context"); - - if (mdoc_isdelim(word)) { - if ( ! (p->flags & TERMP_IGNDELIM)) - p->flags |= TERMP_NOSPACE; - p->flags &= ~TERMP_IGNDELIM; - } - /* LINTED */ for (j = i = 0; i < len; i++) { if (' ' != word[i]) { @@ -363,24 +405,36 @@ word(struct termp *p, const char *word) if (0 == j) continue; assert(i >= j); - termp_pword(p, &word[i - j], j); + term_pword(p, &word[i - j], j); j = 0; } if (j > 0) { assert(i >= j); - termp_pword(p, &word[i - j], j); + term_pword(p, &word[i - j], j); } } +static void +term_body(struct termp *p, struct termpair *ppair, + const struct mdoc_meta *meta, + const struct mdoc_node *node) +{ + + term_node(p, ppair, meta, node); + if (node->next) + term_body(p, ppair, meta, node->next); +} + + /* * This is the main function for printing out nodes. It's constituted * of PRE and POST functions, which correspond to prefix and infix * processing. The termpair structure allows data to persist between * prefix and postfix invocations. */ -static void -termp_body(struct termp *p, struct termpair *ppair, +void +term_node(struct termp *p, struct termpair *ppair, const struct mdoc_meta *meta, const struct mdoc_node *node) { @@ -405,7 +459,7 @@ termp_body(struct termp *p, struct termpair *ppair, if ( ! (*termacts[node->tok].pre)(p, &pair, meta, node)) dochild = 0; } else /* MDOC_TEXT == node->type */ - word(p, node->string); + term_word(p, node->string); /* Children. */ @@ -413,7 +467,7 @@ termp_body(struct termp *p, struct termpair *ppair, p->flags |= pair.flag; if (dochild && node->child) - termp_body(p, &pair, meta, node->child); + term_body(p, &pair, meta, node->child); if (TERMPAIR_FLAG & pair.type) p->flags &= ~pair.flag; @@ -423,16 +477,11 @@ termp_body(struct termp *p, struct termpair *ppair, if (MDOC_TEXT != node->type) if (termacts[node->tok].post) (*termacts[node->tok].post)(p, &pair, meta, node); - - /* Siblings. */ - - if (node->next) - termp_body(p, ppair, meta, node->next); } static void -termp_foot(struct termp *p, const struct mdoc_meta *meta) +term_foot(struct termp *p, const struct mdoc_meta *meta) { struct tm *tm; char *buf, *os; @@ -460,22 +509,22 @@ termp_foot(struct termp *p, const struct mdoc_meta *me * OS MDOCDATE */ - vspace(p); + term_vspace(p); p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; p->rmargin = p->maxrmargin - strlen(buf); p->offset = 0; - word(p, os); - flushln(p); + term_word(p, os); + term_flushln(p); p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin; p->flags &= ~TERMP_NOBREAK; - word(p, buf); - flushln(p); + term_word(p, buf); + term_flushln(p); free(buf); free(os); @@ -483,7 +532,7 @@ termp_foot(struct termp *p, const struct mdoc_meta *me static void -termp_head(struct termp *p, const struct mdoc_meta *meta) +term_head(struct termp *p, const struct mdoc_meta *meta) { char *buf, *title; @@ -524,23 +573,23 @@ termp_head(struct termp *p, const struct mdoc_meta *me p->rmargin = (p->maxrmargin - strlen(buf)) / 2; p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; - word(p, title); - flushln(p); + term_word(p, title); + term_flushln(p); p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; p->offset = p->rmargin; p->rmargin = p->maxrmargin - strlen(title); - word(p, buf); - flushln(p); + term_word(p, buf); + term_flushln(p); p->offset = p->rmargin; p->rmargin = p->maxrmargin; p->flags &= ~TERMP_NOBREAK; p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; - word(p, title); - flushln(p); + term_word(p, title); + term_flushln(p); p->rmargin = p->maxrmargin; p->offset = 0; @@ -557,14 +606,14 @@ termp_head(struct termp *p, const struct mdoc_meta *me * output buffer by way of the symbol table. */ static void -termp_nescape(struct termp *p, const char *word, size_t len) +term_nescape(struct termp *p, const char *word, size_t len) { const char *rhs; size_t sz; - if (NULL == (rhs = a2ascii(p->symtab, word, len, &sz))) + if (NULL == (rhs = term_a2ascii(p->symtab, word, len, &sz))) return; - termp_stringa(p, rhs, sz); + term_stringa(p, rhs, sz); } @@ -574,7 +623,7 @@ termp_nescape(struct termp *p, const char *word, size_ * the escape sequence (we assert upon badly-formed escape sequences). */ static void -termp_pescape(struct termp *p, const char *word, int *i, int len) +term_pescape(struct termp *p, const char *word, int *i, int len) { int j; @@ -586,7 +635,7 @@ termp_pescape(struct termp *p, const char *word, int * if (*i + 1 >= len) return; - termp_nescape(p, &word[*i], 2); + term_nescape(p, &word[*i], 2); (*i)++; return; @@ -601,18 +650,18 @@ termp_pescape(struct termp *p, const char *word, int * if (*i + 1 >= len) return; - termp_nescape(p, &word[*i], 2); + term_nescape(p, &word[*i], 2); (*i)++; return; case ('['): break; default: - termp_nescape(p, &word[*i], 1); + term_nescape(p, &word[*i], 1); return; } } else if ('[' != word[*i]) { - termp_nescape(p, &word[*i], 1); + term_nescape(p, &word[*i], 1); return; } @@ -623,7 +672,7 @@ termp_pescape(struct termp *p, const char *word, int * if (0 == word[*i]) return; - termp_nescape(p, &word[*i - j], (size_t)j); + term_nescape(p, &word[*i - j], (size_t)j); } @@ -633,14 +682,17 @@ termp_pescape(struct termp *p, const char *word, int * * handles word styling. */ static void -termp_pword(struct termp *p, const char *word, int len) +term_pword(struct termp *p, const char *word, int len) { int i; - if ( ! (TERMP_NOSPACE & p->flags) && - ! (TERMP_LITERAL & p->flags)) - termp_chara(p, ' '); + if (term_isclosedelim(word, len)) + if ( ! (TERMP_IGNDELIM & p->flags)) + p->flags |= TERMP_NOSPACE; + if ( ! (TERMP_NOSPACE & p->flags)) + term_chara(p, ' '); + if ( ! (p->flags & TERMP_NONOSPACE)) p->flags &= ~TERMP_NOSPACE; @@ -651,33 +703,36 @@ termp_pword(struct termp *p, const char *word, int len for (i = 0; i < len; i++) { if ('\\' == word[i]) { - termp_pescape(p, word, &i, len); + term_pescape(p, word, &i, len); continue; } if (TERMP_STYLE & p->flags) { if (TERMP_BOLD & p->flags) { - termp_chara(p, word[i]); - termp_chara(p, 8); + term_chara(p, word[i]); + term_chara(p, 8); } if (TERMP_UNDER & p->flags) { - termp_chara(p, '_'); - termp_chara(p, 8); + term_chara(p, '_'); + term_chara(p, 8); } } - termp_chara(p, word[i]); + term_chara(p, word[i]); } + + if (term_isopendelim(word, len)) + p->flags |= TERMP_NOSPACE; } /* - * Like termp_chara() but for arbitrary-length buffers. Resize the + * Like term_chara() but for arbitrary-length buffers. Resize the * buffer by a factor of two (if the buffer is less than that) or the * buffer's size. */ static void -termp_stringa(struct termp *p, const char *c, size_t sz) +term_stringa(struct termp *p, const char *c, size_t sz) { size_t s; @@ -706,7 +761,7 @@ termp_stringa(struct termp *p, const char *c, size_t s * size. */ static void -termp_chara(struct termp *p, char c) +term_chara(struct termp *p, char c) { size_t s;