[BACK]Return to terminal.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/Attic/terminal.c between version 1.1 and 1.5

version 1.1, 2009/03/19 16:17:27 version 1.5, 2009/03/21 13:09:29
Line 24 
Line 24 
   
 #include "term.h"  #include "term.h"
   
 static  struct termp     *termp_alloc(enum termenc);  #ifdef __linux__
 static  void              termp_free(struct termp *);  extern  size_t            strlcpy(char *, const char *, size_t);
 static  void              termp_body(struct termp *, struct termpair *,  extern  size_t            strlcat(char *, const char *, size_t);
   #endif
   
   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_meta *,
                                 const struct mdoc_node *);                                  const struct mdoc_node *);
 static  void              termp_head(struct termp *,  static  void              term_head(struct termp *,
                                 const struct mdoc_meta *);                                  const struct mdoc_meta *);
 static  void              termp_foot(struct termp *,  static  void              term_foot(struct termp *,
                                 const struct mdoc_meta *);                                  const struct mdoc_meta *);
 static  void              termp_pword(struct termp *, const char *, int);  static  void              term_pword(struct termp *, const char *, int);
 static  void              termp_pescape(struct termp *,  static  void              term_pescape(struct termp *,
                                 const char *, int *, int);                                  const char *, int *, int);
 static  void              termp_nescape(struct termp *,  static  void              term_nescape(struct termp *,
                                 const char *, size_t);                                  const char *, size_t);
 static  void              termp_chara(struct termp *, char);  static  void              term_chara(struct termp *, char);
 static  void              termp_stringa(struct termp *,  static  void              term_stringa(struct termp *,
                                 const char *, size_t);                                  const char *, size_t);
   static  int               term_isopendelim(const char *, size_t);
   static  int               term_isclosedelim(const char *, size_t);
 static  void              sanity(const struct mdoc_node *); /* XXX */  static  void              sanity(const struct mdoc_node *); /* XXX */
   
   
Line 48  void *
Line 55  void *
 latin1_alloc(void)  latin1_alloc(void)
 {  {
   
         return(termp_alloc(TERMENC_LATIN1));          return(term_alloc(TERMENC_LATIN1));
 }  }
   
   
Line 56  void *
Line 63  void *
 utf8_alloc(void)  utf8_alloc(void)
 {  {
   
         return(termp_alloc(TERMENC_UTF8));          return(term_alloc(TERMENC_UTF8));
 }  }
   
   
Line 64  void *
Line 71  void *
 ascii_alloc(void)  ascii_alloc(void)
 {  {
   
         return(termp_alloc(TERMENC_ASCII));          return(term_alloc(TERMENC_ASCII));
 }  }
   
   
Line 76  terminal_run(void *arg, const struct mdoc *mdoc)
Line 83  terminal_run(void *arg, const struct mdoc *mdoc)
         p = (struct termp *)arg;          p = (struct termp *)arg;
   
         if (NULL == p->symtab)          if (NULL == p->symtab)
                 p->symtab = ascii2htab();                  p->symtab = term_ascii2htab();
   
         termp_head(p, mdoc_meta(mdoc));          term_head(p, mdoc_meta(mdoc));
         termp_body(p, NULL, mdoc_meta(mdoc), mdoc_node(mdoc));          term_body(p, NULL, mdoc_meta(mdoc), mdoc_node(mdoc));
         termp_foot(p, mdoc_meta(mdoc));          term_foot(p, mdoc_meta(mdoc));
   
         return(1);          return(1);
 }  }
Line 90  void
Line 97  void
 terminal_free(void *arg)  terminal_free(void *arg)
 {  {
   
         termp_free((struct termp *)arg);          term_free((struct termp *)arg);
 }  }
   
   
 static void  static void
 termp_free(struct termp *p)  term_free(struct termp *p)
 {  {
   
         if (p->buf)          if (p->buf)
                 free(p->buf);                  free(p->buf);
         if (TERMENC_ASCII == p->enc && p->symtab)          if (TERMENC_ASCII == p->enc && p->symtab)
                 asciifree(p->symtab);                  term_asciifree(p->symtab);
   
         free(p);          free(p);
 }  }
   
   
 static struct termp *  static struct termp *
 termp_alloc(enum termenc enc)  term_alloc(enum termenc enc)
 {  {
         struct termp *p;          struct termp *p;
   
Line 121  termp_alloc(enum termenc enc)
Line 128  termp_alloc(enum termenc enc)
 }  }
   
   
   static int
   term_isclosedelim(const char *p, size_t 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, size_t 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   * 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   * that should be followed by a newline, regardless of whether it's
Line 156  termp_alloc(enum termenc enc)
Line 219  termp_alloc(enum termenc enc)
  *  possible).   *  possible).
  */   */
 void  void
 flushln(struct termp *p)  term_flushln(struct termp *p)
 {  {
         int              i, j;          int              i, j;
         size_t           vsz, vis, maxvis, mmax, bp;          size_t           vsz, vis, maxvis, mmax, bp;
Line 217  flushln(struct termp *p)
Line 280  flushln(struct termp *p)
                                 for (j = 0; j < (int)p->offset; j++)                                  for (j = 0; j < (int)p->offset; j++)
                                         putchar(' ');                                          putchar(' ');
                                 vis = 0;                                  vis = 0;
                         } else if (vis + vsz > bp)                          }
                                 warnx("word breaks right margin");                  } else if (vis && vis + vsz > bp) {
                           putchar('\n');
                         /* TODO: hyphenate. */                          for (j = 0; j < (int)p->rmargin; j++)
                                   putchar(' ');
                 } else {                          vis = p->rmargin - p->offset;
                         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. */  
                 }                  }
   
                 /*                  /*
Line 289  flushln(struct termp *p)
Line 343  flushln(struct termp *p)
  * assertion.   * assertion.
  */   */
 void  void
 newln(struct termp *p)  term_newln(struct termp *p)
 {  {
   
         p->flags |= TERMP_NOSPACE;          p->flags |= TERMP_NOSPACE;
Line 297  newln(struct termp *p)
Line 351  newln(struct termp *p)
                 p->flags &= ~TERMP_NOLPAD;                  p->flags &= ~TERMP_NOLPAD;
                 return;                  return;
         }          }
         flushln(p);          term_flushln(p);
         p->flags &= ~TERMP_NOLPAD;          p->flags &= ~TERMP_NOLPAD;
 }  }
   
Line 309  newln(struct termp *p)
Line 363  newln(struct termp *p)
  * assertion.   * assertion.
  */   */
 void  void
 vspace(struct termp *p)  term_vspace(struct termp *p)
 {  {
   
         newln(p);          term_newln(p);
         putchar('\n');          putchar('\n');
 }  }
   
Line 324  vspace(struct termp *p)
Line 378  vspace(struct termp *p)
  * the word and put it verbatim into the output buffer.   * the word and put it verbatim into the output buffer.
  */   */
 void  void
 word(struct termp *p, const char *word)  term_word(struct termp *p, const char *word)
 {  {
         int              i, j, len;          int              i, j, len;
   
           len = (int)strlen(word);
   
         if (p->flags & TERMP_LITERAL) {          if (p->flags & TERMP_LITERAL) {
                 termp_pword(p, word, (int)strlen(word));                  term_pword(p, word, len);
                 return;                  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 */          /* LINTED */
         for (j = i = 0; i < len; i++) {          for (j = i = 0; i < len; i++) {
                 if (' ' != word[i]) {                  if (' ' != word[i]) {
Line 358  word(struct termp *p, const char *word)
Line 405  word(struct termp *p, const char *word)
                 if (0 == j)                  if (0 == j)
                         continue;                          continue;
                 assert(i >= j);                  assert(i >= j);
                 termp_pword(p, &word[i - j], j);                  term_pword(p, &word[i - j], j);
                 j = 0;                  j = 0;
         }          }
         if (j > 0) {          if (j > 0) {
                 assert(i >= j);                  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   * This is the main function for printing out nodes.  It's constituted
  * of PRE and POST functions, which correspond to prefix and infix   * of PRE and POST functions, which correspond to prefix and infix
  * processing.  The termpair structure allows data to persist between   * processing.  The termpair structure allows data to persist between
  * prefix and postfix invocations.   * prefix and postfix invocations.
  */   */
 static void  void
 termp_body(struct termp *p, struct termpair *ppair,  term_node(struct termp *p, struct termpair *ppair,
                 const struct mdoc_meta *meta,                  const struct mdoc_meta *meta,
                 const struct mdoc_node *node)                  const struct mdoc_node *node)
 {  {
Line 400  termp_body(struct termp *p, struct termpair *ppair,
Line 459  termp_body(struct termp *p, struct termpair *ppair,
                         if ( ! (*termacts[node->tok].pre)(p, &pair, meta, node))                          if ( ! (*termacts[node->tok].pre)(p, &pair, meta, node))
                                 dochild = 0;                                  dochild = 0;
         } else /* MDOC_TEXT == node->type */          } else /* MDOC_TEXT == node->type */
                 word(p, node->string);                  term_word(p, node->string);
   
         /* Children. */          /* Children. */
   
Line 408  termp_body(struct termp *p, struct termpair *ppair,
Line 467  termp_body(struct termp *p, struct termpair *ppair,
                 p->flags |= pair.flag;                  p->flags |= pair.flag;
   
         if (dochild && node->child)          if (dochild && node->child)
                 termp_body(p, &pair, meta, node->child);                  term_body(p, &pair, meta, node->child);
   
         if (TERMPAIR_FLAG & pair.type)          if (TERMPAIR_FLAG & pair.type)
                 p->flags &= ~pair.flag;                  p->flags &= ~pair.flag;
Line 418  termp_body(struct termp *p, struct termpair *ppair,
Line 477  termp_body(struct termp *p, struct termpair *ppair,
         if (MDOC_TEXT != node->type)          if (MDOC_TEXT != node->type)
                 if (termacts[node->tok].post)                  if (termacts[node->tok].post)
                         (*termacts[node->tok].post)(p, &pair, meta, node);                          (*termacts[node->tok].post)(p, &pair, meta, node);
   
         /* Siblings. */  
   
         if (node->next)  
                 termp_body(p, ppair, meta, node->next);  
 }  }
   
   
 static void  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;          struct tm       *tm;
         char            *buf, *os;          char            *buf, *os;
Line 455  termp_foot(struct termp *p, const struct mdoc_meta *me
Line 509  termp_foot(struct termp *p, const struct mdoc_meta *me
          * OS                                            MDOCDATE           * OS                                            MDOCDATE
          */           */
   
         vspace(p);          term_vspace(p);
   
         p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;          p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
         p->rmargin = p->maxrmargin - strlen(buf);          p->rmargin = p->maxrmargin - strlen(buf);
         p->offset = 0;          p->offset = 0;
   
         word(p, os);          term_word(p, os);
         flushln(p);          term_flushln(p);
   
         p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;          p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
         p->offset = p->rmargin;          p->offset = p->rmargin;
         p->rmargin = p->maxrmargin;          p->rmargin = p->maxrmargin;
         p->flags &= ~TERMP_NOBREAK;          p->flags &= ~TERMP_NOBREAK;
   
         word(p, buf);          term_word(p, buf);
         flushln(p);          term_flushln(p);
   
         free(buf);          free(buf);
         free(os);          free(os);
Line 478  termp_foot(struct termp *p, const struct mdoc_meta *me
Line 532  termp_foot(struct termp *p, const struct mdoc_meta *me
   
   
 static void  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;          char            *buf, *title;
   
Line 519  termp_head(struct termp *p, const struct mdoc_meta *me
Line 573  termp_head(struct termp *p, const struct mdoc_meta *me
         p->rmargin = (p->maxrmargin - strlen(buf)) / 2;          p->rmargin = (p->maxrmargin - strlen(buf)) / 2;
         p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;          p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
   
         word(p, title);          term_word(p, title);
         flushln(p);          term_flushln(p);
   
         p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;          p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
         p->offset = p->rmargin;          p->offset = p->rmargin;
         p->rmargin = p->maxrmargin - strlen(title);          p->rmargin = p->maxrmargin - strlen(title);
   
         word(p, buf);          term_word(p, buf);
         flushln(p);          term_flushln(p);
   
         p->offset = p->rmargin;          p->offset = p->rmargin;
         p->rmargin = p->maxrmargin;          p->rmargin = p->maxrmargin;
         p->flags &= ~TERMP_NOBREAK;          p->flags &= ~TERMP_NOBREAK;
         p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;          p->flags |= TERMP_NOLPAD | TERMP_NOSPACE;
   
         word(p, title);          term_word(p, title);
         flushln(p);          term_flushln(p);
   
         p->rmargin = p->maxrmargin;          p->rmargin = p->maxrmargin;
         p->offset = 0;          p->offset = 0;
Line 552  termp_head(struct termp *p, const struct mdoc_meta *me
Line 606  termp_head(struct termp *p, const struct mdoc_meta *me
  * output buffer by way of the symbol table.   * output buffer by way of the symbol table.
  */   */
 static void  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;          const char      *rhs;
         size_t           sz;          size_t           sz;
   
         if (NULL == (rhs = a2ascii(p->symtab, word, len, &sz)))          if (NULL == (rhs = term_a2ascii(p->symtab, word, len, &sz)))
                 return;                  return;
         termp_stringa(p, rhs, sz);          term_stringa(p, rhs, sz);
 }  }
   
   
Line 569  termp_nescape(struct termp *p, const char *word, size_
Line 623  termp_nescape(struct termp *p, const char *word, size_
  * the escape sequence (we assert upon badly-formed escape sequences).   * the escape sequence (we assert upon badly-formed escape sequences).
  */   */
 static void  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;          int              j;
   
Line 581  termp_pescape(struct termp *p, const char *word, int *
Line 635  termp_pescape(struct termp *p, const char *word, int *
                 if (*i + 1 >= len)                  if (*i + 1 >= len)
                         return;                          return;
   
                 termp_nescape(p, &word[*i], 2);                  term_nescape(p, &word[*i], 2);
                 (*i)++;                  (*i)++;
                 return;                  return;
   
Line 596  termp_pescape(struct termp *p, const char *word, int *
Line 650  termp_pescape(struct termp *p, const char *word, int *
                         if (*i + 1 >= len)                          if (*i + 1 >= len)
                                 return;                                  return;
   
                         termp_nescape(p, &word[*i], 2);                          term_nescape(p, &word[*i], 2);
                         (*i)++;                          (*i)++;
                         return;                          return;
                 case ('['):                  case ('['):
                         break;                          break;
                 default:                  default:
                         termp_nescape(p, &word[*i], 1);                          term_nescape(p, &word[*i], 1);
                         return;                          return;
                 }                  }
   
         } else if ('[' != word[*i]) {          } else if ('[' != word[*i]) {
                 termp_nescape(p, &word[*i], 1);                  term_nescape(p, &word[*i], 1);
                 return;                  return;
         }          }
   
Line 618  termp_pescape(struct termp *p, const char *word, int *
Line 672  termp_pescape(struct termp *p, const char *word, int *
         if (0 == word[*i])          if (0 == word[*i])
                 return;                  return;
   
         termp_nescape(p, &word[*i - j], (size_t)j);          term_nescape(p, &word[*i - j], (size_t)j);
 }  }
   
   
Line 628  termp_pescape(struct termp *p, const char *word, int *
Line 682  termp_pescape(struct termp *p, const char *word, int *
  * handles word styling.   * handles word styling.
  */   */
 static void  static void
 termp_pword(struct termp *p, const char *word, int len)  term_pword(struct termp *p, const char *word, int len)
 {  {
         int              i;          int              i;
   
         if ( ! (TERMP_NOSPACE & p->flags) &&          if (term_isclosedelim(word, len))
                         ! (TERMP_LITERAL & p->flags))                  if ( ! (TERMP_IGNDELIM & p->flags))
                 termp_chara(p, ' ');                          p->flags |= TERMP_NOSPACE;
   
           if ( ! (TERMP_NOSPACE & p->flags))
                   term_chara(p, ' ');
   
         if ( ! (p->flags & TERMP_NONOSPACE))          if ( ! (p->flags & TERMP_NONOSPACE))
                 p->flags &= ~TERMP_NOSPACE;                  p->flags &= ~TERMP_NOSPACE;
   
Line 646  termp_pword(struct termp *p, const char *word, int len
Line 703  termp_pword(struct termp *p, const char *word, int len
   
         for (i = 0; i < len; i++) {          for (i = 0; i < len; i++) {
                 if ('\\' == word[i]) {                  if ('\\' == word[i]) {
                         termp_pescape(p, word, &i, len);                          term_pescape(p, word, &i, len);
                         continue;                          continue;
                 }                  }
   
                 if (TERMP_STYLE & p->flags) {                  if (TERMP_STYLE & p->flags) {
                         if (TERMP_BOLD & p->flags) {                          if (TERMP_BOLD & p->flags) {
                                 termp_chara(p, word[i]);                                  term_chara(p, word[i]);
                                 termp_chara(p, 8);                                  term_chara(p, 8);
                         }                          }
                         if (TERMP_UNDER & p->flags) {                          if (TERMP_UNDER & p->flags) {
                                 termp_chara(p, '_');                                  term_chara(p, '_');
                                 termp_chara(p, 8);                                  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 by a factor of two (if the buffer is less than that) or the
  * buffer's size.   * buffer's size.
  */   */
 static void  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;          size_t           s;
   
Line 701  termp_stringa(struct termp *p, const char *c, size_t s
Line 761  termp_stringa(struct termp *p, const char *c, size_t s
  * size.   * size.
  */   */
 static void  static void
 termp_chara(struct termp *p, char c)  term_chara(struct termp *p, char c)
 {  {
         size_t           s;          size_t           s;
   

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.5

CVSweb