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

Diff for /mandoc/term.c between version 1.264 and 1.267

version 1.264, 2017/06/04 22:44:15 version 1.267, 2017/06/07 20:01:19
Line 32 
Line 32 
 #include "main.h"  #include "main.h"
   
 static  size_t           cond_width(const struct termp *, int, int *);  static  size_t           cond_width(const struct termp *, int, int *);
 static  void             adjbuf(struct termp *p, size_t);  static  void             adjbuf(struct termp_col *, size_t);
 static  void             bufferc(struct termp *, char);  static  void             bufferc(struct termp *, char);
 static  void             encode(struct termp *, const char *, size_t);  static  void             encode(struct termp *, const char *, size_t);
 static  void             encode1(struct termp *, int);  static  void             encode1(struct termp *, int);
Line 42  static void   endline(struct termp *);
Line 42  static void   endline(struct termp *);
 void  void
 term_free(struct termp *p)  term_free(struct termp *p)
 {  {
           for (p->tcol = p->tcols; p->tcol < p->tcols + p->maxtcol; p->tcol++)
         free(p->buf);                  free(p->tcol->buf);
           free(p->tcols);
         free(p->fontq);          free(p->fontq);
         free(p);          free(p);
 }  }
Line 94  term_end(struct termp *p)
Line 95  term_end(struct termp *p)
 void  void
 term_flushln(struct termp *p)  term_flushln(struct termp *p)
 {  {
         size_t           i;     /* current input position in p->buf */  
         int              ntab;  /* number of tabs to prepend */  
         size_t           vis;   /* current visual position on output */          size_t           vis;   /* current visual position on output */
         size_t           vbl;   /* number of blanks to prepend to output */          size_t           vbl;   /* number of blanks to prepend to output */
         size_t           vend;  /* end of word visual position on output */          size_t           vend;  /* end of word visual position on output */
         size_t           bp;    /* visual right border position */          size_t           bp;    /* visual right border position */
         size_t           dv;    /* temporary for visual pos calculations */          size_t           dv;    /* temporary for visual pos calculations */
         size_t           j;     /* temporary loop index for p->buf */          size_t           j;     /* temporary loop index for p->tcol->buf */
         size_t           jhy;   /* last hyph before overflow w/r/t j */          size_t           jhy;   /* last hyph before overflow w/r/t j */
         size_t           maxvis; /* output position of visible boundary */          size_t           maxvis; /* output position of visible boundary */
           int              ntab;  /* number of tabs to prepend */
   
         vbl = (p->flags & TERMP_NOPAD) || p->offset < p->viscol ? 0 :          vbl = (p->flags & TERMP_NOPAD) || p->tcol->offset < p->viscol ?
             p->offset - p->viscol;              0 : p->tcol->offset - p->viscol;
         if (p->minbl && vbl < p->minbl)          if (p->minbl && vbl < p->minbl)
                 vbl = p->minbl;                  vbl = p->minbl;
         maxvis = p->rmargin > p->viscol + vbl ?          maxvis = p->tcol->rmargin > p->viscol + vbl ?
             p->rmargin - p->viscol - vbl : 0;              p->tcol->rmargin - p->viscol - vbl : 0;
         bp = !(p->flags & TERMP_NOBREAK) ? maxvis :          bp = !(p->flags & TERMP_NOBREAK) ? maxvis :
             p->maxrmargin > p->viscol + vbl ?              p->maxrmargin > p->viscol + vbl ?
             p->maxrmargin - p->viscol - vbl : 0;              p->maxrmargin - p->viscol - vbl : 0;
         vis = vend = 0;          vis = vend = 0;
         i = 0;  
   
         while (i < p->col) {          if (p->lasttcol == 0)
                   p->tcol->col = 0;
           while (p->tcol->col < p->lastcol) {
   
                 /*                  /*
                  * Handle literal tab characters: collapse all                   * Handle literal tab characters: collapse all
                  * subsequent tabs into a single huge set of spaces.                   * subsequent tabs into a single huge set of spaces.
                  */                   */
   
                 ntab = 0;                  ntab = 0;
                 while (i < p->col && p->buf[i] == '\t') {                  while (p->tcol->col < p->lastcol &&
                       p->tcol->buf[p->tcol->col] == '\t') {
                         vend = term_tab_next(vis);                          vend = term_tab_next(vis);
                         vbl += vend - vis;                          vbl += vend - vis;
                         vis = vend;                          vis = vend;
                         ntab++;                          ntab++;
                         i++;                          p->tcol->col++;
                 }                  }
   
                 /*                  /*
Line 138  term_flushln(struct termp *p)
Line 142  term_flushln(struct termp *p)
                  * space is printed according to regular spacing rules).                   * space is printed according to regular spacing rules).
                  */                   */
   
                 for (j = i, jhy = 0; j < p->col; j++) {                  jhy = 0;
                         if (' ' == p->buf[j] || '\t' == p->buf[j])                  for (j = p->tcol->col; j < p->lastcol; j++) {
                           if (p->tcol->buf[j] == ' ' || p->tcol->buf[j] == '\t')
                                 break;                                  break;
   
                         /* Back over the last printed character. */                          /* Back over the last printed character. */
                         if (8 == p->buf[j]) {                          if (p->tcol->buf[j] == '\b') {
                                 assert(j);                                  assert(j);
                                 vend -= (*p->width)(p, p->buf[j - 1]);                                  vend -= (*p->width)(p, p->tcol->buf[j - 1]);
                                 continue;                                  continue;
                         }                          }
   
                         /* Regular word. */                          /* Regular word. */
                         /* Break at the hyphen point if we overrun. */                          /* Break at the hyphen point if we overrun. */
                         if (vend > vis && vend < bp &&                          if (vend > vis && vend < bp &&
                             (ASCII_HYPH == p->buf[j] ||                              (p->tcol->buf[j] == ASCII_HYPH||
                              ASCII_BREAK == p->buf[j]))                               p->tcol->buf[j] == ASCII_BREAK))
                                 jhy = j;                                  jhy = j;
   
                         /*                          /*
                          * Hyphenation now decided, put back a real                           * Hyphenation now decided, put back a real
                          * hyphen such that we get the correct width.                           * hyphen such that we get the correct width.
                          */                           */
                         if (ASCII_HYPH == p->buf[j])                          if (p->tcol->buf[j] == ASCII_HYPH)
                                 p->buf[j] = '-';                                  p->tcol->buf[j] = '-';
   
                         vend += (*p->width)(p, p->buf[j]);                          vend += (*p->width)(p, p->tcol->buf[j]);
                 }                  }
   
                 /*                  /*
                  * Find out whether we would exceed the right margin.                   * Find out whether we would exceed the right margin.
                  * If so, break to the next line.                   * If so, break to the next line.
                  */                   */
                 if (vend > bp && 0 == jhy && vis > 0 &&  
                   if (vend > bp && jhy == 0 && vis > 0 &&
                     (p->flags & TERMP_BRNEVER) == 0) {                      (p->flags & TERMP_BRNEVER) == 0) {
                         vend -= vis;                          if (p->lasttcol)
                                   return;
   
                         endline(p);                          endline(p);
                           vend -= vis;
   
                         /* Use pending tabs on the new line. */                          /* Use pending tabs on the new line. */
   
Line 184  term_flushln(struct termp *p)
Line 193  term_flushln(struct termp *p)
                         /* Re-establish indentation. */                          /* Re-establish indentation. */
   
                         if (p->flags & TERMP_BRIND)                          if (p->flags & TERMP_BRIND)
                                 vbl += p->rmargin;                                  vbl += p->tcol->rmargin;
                         else                          else
                                 vbl += p->offset;                                  vbl += p->tcol->offset;
                         maxvis = p->rmargin > vbl ? p->rmargin - vbl : 0;                          maxvis = p->tcol->rmargin > vbl ?
                               p->tcol->rmargin - vbl : 0;
                         bp = !(p->flags & TERMP_NOBREAK) ? maxvis :                          bp = !(p->flags & TERMP_NOBREAK) ? maxvis :
                             p->maxrmargin > vbl ?  p->maxrmargin - vbl : 0;                              p->maxrmargin > vbl ?  p->maxrmargin - vbl : 0;
                 }                  }
   
                 /* Write out the [remaining] word. */                  /*
                 for ( ; i < p->col; i++) {                   * Write out the rest of the word.
                         if (vend > bp && jhy > 0 && i > jhy)                   */
   
                   for ( ; p->tcol->col < p->lastcol; p->tcol->col++) {
                           if (vend > bp && jhy > 0 && p->tcol->col > jhy)
                                 break;                                  break;
                         if ('\t' == p->buf[i])                          if (p->tcol->buf[p->tcol->col] == '\t')
                                 break;                                  break;
                         if (' ' == p->buf[i]) {                          if (p->tcol->buf[p->tcol->col] == ' ') {
                                 j = i;                                  j = p->tcol->col;
                                 while (i < p->col && ' ' == p->buf[i])                                  while (p->tcol->col < p->lastcol &&
                                         i++;                                      p->tcol->buf[p->tcol->col] == ' ')
                                 dv = (i - j) * (*p->width)(p, ' ');                                          p->tcol->col++;
                                   dv = (p->tcol->col - j) * (*p->width)(p, ' ');
                                 vbl += dv;                                  vbl += dv;
                                 vend += dv;                                  vend += dv;
                                 break;                                  break;
                         }                          }
                         if (ASCII_NBRSP == p->buf[i]) {                          if (p->tcol->buf[p->tcol->col] == ASCII_NBRSP) {
                                 vbl += (*p->width)(p, ' ');                                  vbl += (*p->width)(p, ' ');
                                 continue;                                  continue;
                         }                          }
                         if (ASCII_BREAK == p->buf[i])                          if (p->tcol->buf[p->tcol->col] == ASCII_BREAK)
                                 continue;                                  continue;
   
                         /*                          /*
Line 225  term_flushln(struct termp *p)
Line 239  term_flushln(struct termp *p)
                                 vbl = 0;                                  vbl = 0;
                         }                          }
   
                         (*p->letter)(p, p->buf[i]);                          (*p->letter)(p, p->tcol->buf[p->tcol->col]);
                         if (8 == p->buf[i])                          if (p->tcol->buf[p->tcol->col] == '\b')
                                 p->viscol -= (*p->width)(p, p->buf[i-1]);                                  p->viscol -= (*p->width)(p,
                                       p->tcol->buf[p->tcol->col - 1]);
                         else                          else
                                 p->viscol += (*p->width)(p, p->buf[i]);                                  p->viscol += (*p->width)(p,
                                       p->tcol->buf[p->tcol->col]);
                 }                  }
                 vis = vend;                  vis = vend;
         }          }
Line 238  term_flushln(struct termp *p)
Line 254  term_flushln(struct termp *p)
          * If there was trailing white space, it was not printed;           * If there was trailing white space, it was not printed;
          * so reset the cursor position accordingly.           * so reset the cursor position accordingly.
          */           */
   
         if (vis > vbl)          if (vis > vbl)
                 vis -= vbl;                  vis -= vbl;
         else          else
                 vis = 0;                  vis = 0;
   
         p->col = 0;          p->col = p->lastcol = 0;
         p->minbl = p->trailspace;          p->minbl = p->trailspace;
         p->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE | TERMP_NOPAD);          p->flags &= ~(TERMP_BACKAFTER | TERMP_BACKBEFORE | TERMP_NOPAD);
   
         /* Trailing whitespace is significant in some columns. */          /* Trailing whitespace is significant in some columns. */
   
         if (vis && vbl && (TERMP_BRTRSP & p->flags))          if (vis && vbl && (TERMP_BRTRSP & p->flags))
                 vis += vbl;                  vis += vbl;
   
Line 287  term_newln(struct termp *p)
Line 305  term_newln(struct termp *p)
 {  {
   
         p->flags |= TERMP_NOSPACE;          p->flags |= TERMP_NOSPACE;
         if (p->col || p->viscol)          if (p->lastcol || p->viscol)
                 term_flushln(p);                  term_flushln(p);
 }  }
   
Line 472  term_word(struct termp *p, const char *word)
Line 490  term_word(struct termp *p, const char *word)
                         else {                          else {
                                 uc += p->col;                                  uc += p->col;
                                 p->col = 0;                                  p->col = 0;
                                 if (p->offset > (size_t)(-uc)) {                                  if (p->tcol->offset > (size_t)(-uc)) {
                                         p->ti += uc;                                          p->ti += uc;
                                         p->offset += uc;                                          p->tcol->offset += uc;
                                 } else {                                  } else {
                                         p->ti -= p->offset;                                          p->ti -= p->tcol->offset;
                                         p->offset = 0;                                          p->tcol->offset = 0;
                                 }                                  }
                         }                          }
                         continue;                          continue;
Line 486  term_word(struct termp *p, const char *word)
Line 504  term_word(struct termp *p, const char *word)
                                 continue;                                  continue;
                         uc = term_hspan(p, &su) / 24;                          uc = term_hspan(p, &su) / 24;
                         if (uc <= 0) {                          if (uc <= 0) {
                                 if (p->rmargin <= p->offset)                                  if (p->tcol->rmargin <= p->tcol->offset)
                                         continue;                                          continue;
                                 lsz = p->rmargin - p->offset;                                  lsz = p->tcol->rmargin - p->tcol->offset;
                         } else                          } else
                                 lsz = uc;                                  lsz = uc;
                         while (sz &&                          while (sz &&
Line 556  term_word(struct termp *p, const char *word)
Line 574  term_word(struct termp *p, const char *word)
                                 }                                  }
                         }                          }
                         /* Trim trailing backspace/blank pair. */                          /* Trim trailing backspace/blank pair. */
                         if (p->col > 2 &&                          if (p->lastcol > 2 &&
                             (p->buf[p->col - 1] == ' ' ||                              (p->tcol->buf[p->lastcol - 1] == ' ' ||
                              p->buf[p->col - 1] == '\t'))                               p->tcol->buf[p->lastcol - 1] == '\t'))
                                 p->col -= 2;                                  p->lastcol -= 2;
                           if (p->col > p->lastcol)
                                   p->col = p->lastcol;
                         continue;                          continue;
                 default:                  default:
                         continue;                          continue;
Line 584  term_word(struct termp *p, const char *word)
Line 604  term_word(struct termp *p, const char *word)
 }  }
   
 static void  static void
 adjbuf(struct termp *p, size_t sz)  adjbuf(struct termp_col *c, size_t sz)
 {  {
           if (c->maxcols == 0)
         if (0 == p->maxcols)                  c->maxcols = 1024;
                 p->maxcols = 1024;          while (c->maxcols <= sz)
         while (sz >= p->maxcols)                  c->maxcols <<= 2;
                 p->maxcols <<= 2;          c->buf = mandoc_reallocarray(c->buf, c->maxcols, sizeof(*c->buf));
   
         p->buf = mandoc_reallocarray(p->buf, p->maxcols, sizeof(int));  
 }  }
   
 static void  static void
Line 602  bufferc(struct termp *p, char c)
Line 620  bufferc(struct termp *p, char c)
                 (*p->letter)(p, c);                  (*p->letter)(p, c);
                 return;                  return;
         }          }
         if (p->col + 1 >= p->maxcols)          if (p->col + 1 >= p->tcol->maxcols)
                 adjbuf(p, p->col + 1);                  adjbuf(p->tcol, p->col + 1);
         p->buf[p->col++] = c;          if (p->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
                   p->tcol->buf[p->col] = c;
           if (p->lastcol < ++p->col)
                   p->lastcol = p->col;
 }  }
   
 /*  /*
Line 622  encode1(struct termp *p, int c)
Line 643  encode1(struct termp *p, int c)
                 return;                  return;
         }          }
   
         if (p->col + 7 >= p->maxcols)          if (p->col + 7 >= p->tcol->maxcols)
                 adjbuf(p, p->col + 7);                  adjbuf(p->tcol, p->col + 7);
   
         f = (c == ASCII_HYPH || c > 127 || isgraph(c)) ?          f = (c == ASCII_HYPH || c > 127 || isgraph(c)) ?
             p->fontq[p->fonti] : TERMFONT_NONE;              p->fontq[p->fonti] : TERMFONT_NONE;
   
         if (p->flags & TERMP_BACKBEFORE) {          if (p->flags & TERMP_BACKBEFORE) {
                 if (p->buf[p->col - 1] == ' ' || p->buf[p->col - 1] == '\t')                  if (p->tcol->buf[p->col - 1] == ' ' ||
                       p->tcol->buf[p->col - 1] == '\t')
                         p->col--;                          p->col--;
                 else                  else
                         p->buf[p->col++] = 8;                          p->tcol->buf[p->col++] = '\b';
                 p->flags &= ~TERMP_BACKBEFORE;                  p->flags &= ~TERMP_BACKBEFORE;
         }          }
         if (TERMFONT_UNDER == f || TERMFONT_BI == f) {          if (f == TERMFONT_UNDER || f == TERMFONT_BI) {
                 p->buf[p->col++] = '_';                  p->tcol->buf[p->col++] = '_';
                 p->buf[p->col++] = 8;                  p->tcol->buf[p->col++] = '\b';
         }          }
         if (TERMFONT_BOLD == f || TERMFONT_BI == f) {          if (f == TERMFONT_BOLD || f == TERMFONT_BI) {
                 if (ASCII_HYPH == c)                  if (c == ASCII_HYPH)
                         p->buf[p->col++] = '-';                          p->tcol->buf[p->col++] = '-';
                 else                  else
                         p->buf[p->col++] = c;                          p->tcol->buf[p->col++] = c;
                 p->buf[p->col++] = 8;                  p->tcol->buf[p->col++] = '\b';
         }          }
         p->buf[p->col++] = c;          if (p->lastcol <= p->col || (c != ' ' && c != ASCII_NBRSP))
                   p->tcol->buf[p->col] = c;
           if (p->lastcol < ++p->col)
                   p->lastcol = p->col;
         if (p->flags & TERMP_BACKAFTER) {          if (p->flags & TERMP_BACKAFTER) {
                 p->flags |= TERMP_BACKBEFORE;                  p->flags |= TERMP_BACKBEFORE;
                 p->flags &= ~TERMP_BACKAFTER;                  p->flags &= ~TERMP_BACKAFTER;
Line 664  encode(struct termp *p, const char *word, size_t sz)
Line 689  encode(struct termp *p, const char *word, size_t sz)
                 return;                  return;
         }          }
   
         if (p->col + 2 + (sz * 5) >= p->maxcols)          if (p->col + 2 + (sz * 5) >= p->tcol->maxcols)
                 adjbuf(p, p->col + 2 + (sz * 5));                  adjbuf(p->tcol, p->col + 2 + (sz * 5));
   
         for (i = 0; i < sz; i++) {          for (i = 0; i < sz; i++) {
                 if (ASCII_HYPH == word[i] ||                  if (ASCII_HYPH == word[i] ||
                     isgraph((unsigned char)word[i]))                      isgraph((unsigned char)word[i]))
                         encode1(p, word[i]);                          encode1(p, word[i]);
                 else {                  else {
                         p->buf[p->col++] = word[i];                          if (p->lastcol <= p->col ||
                               (word[i] != ' ' && word[i] != ASCII_NBRSP))
                                   p->tcol->buf[p->col] = word[i];
                           p->col++;
   
                         /*                          /*
                          * Postpone the effect of \z while handling                           * Postpone the effect of \z while handling
Line 686  encode(struct termp *p, const char *word, size_t sz)
Line 714  encode(struct termp *p, const char *word, size_t sz)
                         }                          }
                 }                  }
         }          }
           if (p->lastcol < p->col)
                   p->lastcol = p->col;
 }  }
   
 void  void

Legend:
Removed from v.1.264  
changed lines
  Added in v.1.267

CVSweb