]> git.cameronkatri.com Git - mandoc.git/blobdiff - term.c
Have mandoc-db accumulate manual page descriptions (`Nd' in -mdoc parlance)
[mandoc.git] / term.c
diff --git a/term.c b/term.c
index ba54c31d2a794877db1167511d0590fcf41db48b..12722b97373d82dc5f4c1508d26039a0dfc0a1e3 100644 (file)
--- a/term.c
+++ b/term.c
@@ -1,7 +1,7 @@
-/*     $Id: term.c,v 1.176 2011/01/04 13:14:26 kristaps Exp $ */
+/*     $Id: term.c,v 1.184 2011/04/09 15:29:40 kristaps Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2011 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
 #include <string.h>
 
 #include "mandoc.h"
-#include "chars.h"
 #include "out.h"
 #include "term.h"
 #include "main.h"
 
-static void              spec(struct termp *, enum roffdeco,
-                               const char *, size_t);
+static void              spec(struct termp *, const char *, size_t);
 static void              res(struct termp *, const char *, size_t);
 static void              bufferc(struct termp *, char);
 static void              adjbuf(struct termp *p, size_t);
@@ -80,12 +78,7 @@ term_alloc(enum termenc enc)
 {
        struct termp    *p;
 
-       p = calloc(1, sizeof(struct termp));
-       if (NULL == p) {
-               perror(NULL);
-               exit((int)MANDOCLEVEL_SYSERR);
-       }
-
+       p = mandoc_calloc(1, sizeof(struct termp));
        p->enc = enc;
        return(p);
 }
@@ -353,7 +346,18 @@ term_vspace(struct termp *p)
 
 
 static void
-spec(struct termp *p, enum roffdeco d, const char *word, size_t len)
+numbered(struct termp *p, const char *word, size_t len)
+{
+       const char      *rhs;
+
+       rhs = chars_num2char(word, len);
+       if (rhs) 
+               encode(p, rhs, 1);
+}
+
+
+static void
+spec(struct termp *p, const char *word, size_t len)
 {
        const char      *rhs;
        size_t           sz;
@@ -361,7 +365,7 @@ spec(struct termp *p, enum roffdeco d, const char *word, size_t len)
        rhs = chars_spec2str(p->symtab, word, len, &sz);
        if (rhs) 
                encode(p, rhs, sz);
-       else if (DECO_SSPECIAL == d)
+       else if (1 == len)
                encode(p, word, len);
 }
 
@@ -451,35 +455,10 @@ term_fontpop(struct termp *p)
 void
 term_word(struct termp *p, const char *word)
 {
-       const char      *sv, *seq;
+       const char      *seq;
+       int              sz;
        size_t           ssz;
-       enum roffdeco    deco;
-
-       sv = word;
-
-       if (word[0] && '\0' == word[1])
-               switch (word[0]) {
-               case('.'):
-                       /* FALLTHROUGH */
-               case(','):
-                       /* FALLTHROUGH */
-               case(';'):
-                       /* FALLTHROUGH */
-               case(':'):
-                       /* FALLTHROUGH */
-               case('?'):
-                       /* FALLTHROUGH */
-               case('!'):
-                       /* FALLTHROUGH */
-               case(')'):
-                       /* FALLTHROUGH */
-               case(']'):
-                       if ( ! (TERMP_IGNDELIM & p->flags))
-                               p->flags |= TERMP_NOSPACE;
-                       break;
-               default:
-                       break;
-               }
+       enum mandoc_esc  esc;
 
        if ( ! (TERMP_NOSPACE & p->flags)) {
                if ( ! (TERMP_KEEP & p->flags)) {
@@ -499,60 +478,49 @@ term_word(struct termp *p, const char *word)
 
        p->flags &= ~(TERMP_SENTENCE | TERMP_IGNDELIM);
 
-       while (*word) {
+       while ('\0' != *word) {
                if ((ssz = strcspn(word, "\\")) > 0)
                        encode(p, word, ssz);
 
-               word += ssz;
+               word += (int)ssz;
                if ('\\' != *word)
                        continue;
 
-               seq = ++word;
-               word += a2roffdeco(&deco, &seq, &ssz);
+               word++;
+               esc = mandoc_escape(&word, &seq, &sz);
+               if (ESCAPE_ERROR == esc)
+                       break;
 
-               switch (deco) {
-               case (DECO_RESERVED):
-                       res(p, seq, ssz);
+               switch (esc) {
+               case (ESCAPE_NUMBERED):
+                       numbered(p, seq, sz);
+                       break;
+               case (ESCAPE_PREDEF):
+                       res(p, seq, sz);
                        break;
-               case (DECO_SPECIAL):
-                       /* FALLTHROUGH */
-               case (DECO_SSPECIAL):
-                       spec(p, deco, seq, ssz);
+               case (ESCAPE_SPECIAL):
+                       spec(p, seq, sz);
                        break;
-               case (DECO_BOLD):
+               case (ESCAPE_FONTBOLD):
                        term_fontrepl(p, TERMFONT_BOLD);
                        break;
-               case (DECO_ITALIC):
+               case (ESCAPE_FONTITALIC):
                        term_fontrepl(p, TERMFONT_UNDER);
                        break;
-               case (DECO_ROMAN):
+               case (ESCAPE_FONTROMAN):
                        term_fontrepl(p, TERMFONT_NONE);
                        break;
-               case (DECO_PREVIOUS):
+               case (ESCAPE_FONTPREV):
                        term_fontlast(p);
                        break;
-               default:
-                       break;
-               }
-
-               if (DECO_NOSPACE == deco && '\0' == *word)
-                       p->flags |= TERMP_NOSPACE;
-       }
-
-       /* 
-        * Note that we don't process the pipe: the parser sees it as
-        * punctuation, but we don't in terms of typography.
-        */
-       if (sv[0] && '\0' == sv[1])
-               switch (sv[0]) {
-               case('('):
-                       /* FALLTHROUGH */
-               case('['):
-                       p->flags |= TERMP_NOSPACE;
+               case (ESCAPE_NOSPACE):
+                       if ('\0' == *word)
+                               p->flags |= TERMP_NOSPACE;
                        break;
                default:
                        break;
                }
+       }
 }
 
 
@@ -565,11 +533,7 @@ adjbuf(struct termp *p, size_t sz)
        while (sz >= p->maxcols)
                p->maxcols <<= 2;
 
-       p->buf = realloc(p->buf, p->maxcols);
-       if (NULL == p->buf) {
-               perror(NULL);
-               exit((int)MANDOCLEVEL_SYSERR);
-       }
+       p->buf = mandoc_realloc(p->buf, p->maxcols);
 }
 
 
@@ -637,33 +601,36 @@ term_len(const struct termp *p, size_t sz)
 size_t
 term_strlen(const struct termp *p, const char *cp)
 {
-       size_t           sz, ssz, rsz, i;
-       enum roffdeco    d;
+       size_t           sz, rsz, i;
+       int              ssz;
+       enum mandoc_esc  esc;
        const char      *seq, *rhs;
 
-       for (sz = 0; '\0' != *cp; )
-               /*
-                * Account for escaped sequences within string length
-                * calculations.  This follows the logic in term_word()
-                * as we must calculate the width of produced strings.
-                */
-               if ('\\' == *cp) {
-                       seq = ++cp;
-                       cp += a2roffdeco(&d, &seq, &ssz);
+       /*
+        * Account for escaped sequences within string length
+        * calculations.  This follows the logic in term_word() as we
+        * must calculate the width of produced strings.
+        */
 
-                       switch (d) {
-                       case (DECO_RESERVED):
+       sz = 0;
+       while ('\0' != *cp)
+               switch (*cp) {
+               case ('\\'):
+                       ++cp;
+                       esc = mandoc_escape(&cp, &seq, &ssz);
+                       if (ESCAPE_ERROR == esc)
+                               return(sz);
+
+                       switch (esc) {
+                       case (ESCAPE_PREDEF):
                                rhs = chars_res2str
                                        (p->symtab, seq, ssz, &rsz);
                                break;
-                       case (DECO_SPECIAL):
-                               /* FALLTHROUGH */
-                       case (DECO_SSPECIAL):
+                       case (ESCAPE_SPECIAL):
                                rhs = chars_spec2str
                                        (p->symtab, seq, ssz, &rsz);
 
-                               /* Allow for one-char escapes. */
-                               if (DECO_SSPECIAL != d || rhs)
+                               if (ssz != 1 || rhs)
                                        break;
 
                                rhs = seq;
@@ -674,17 +641,24 @@ term_strlen(const struct termp *p, const char *cp)
                                break;
                        }
 
-                       if (rhs)
-                               for (i = 0; i < rsz; i++)
-                                       sz += (*p->width)(p, *rhs++);
-               } else if (ASCII_NBRSP == *cp) {
+                       if (NULL == rhs)
+                               break;
+
+                       for (i = 0; i < rsz; i++)
+                               sz += (*p->width)(p, *rhs++);
+                       break;
+               case (ASCII_NBRSP):
                        sz += (*p->width)(p, ' ');
                        cp++;
-               } else if (ASCII_HYPH == *cp) {
+                       break;
+               case (ASCII_HYPH):
                        sz += (*p->width)(p, '-');
                        cp++;
-               } else
+                       break;
+               default:
                        sz += (*p->width)(p, *cp++);
+                       break;
+               }
 
        return(sz);
 }