[BACK]Return to ul.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ul

Diff for /src/usr.bin/ul/ul.c between version 1.19 and 1.20

version 1.19, 2015/10/10 16:15:03 version 1.20, 2016/01/18 17:34:26
Line 32 
Line 32 
   
 #include <curses.h>  #include <curses.h>
 #include <err.h>  #include <err.h>
   #include <errno.h>
   #include <locale.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <term.h>  #include <term.h>
 #include <unistd.h>  #include <unistd.h>
   #include <wchar.h>
   
 #define IESC    '\033'  #define IESC    L'\033'
 #define SO      '\016'  #define SO      L'\016'
 #define SI      '\017'  #define SI      L'\017'
 #define HFWD    '9'  #define HFWD    '9'
 #define HREV    '8'  #define HREV    '8'
 #define FREV    '7'  #define FREV    '7'
Line 60 
Line 63 
   
 struct  CHAR    {  struct  CHAR    {
         char    c_mode;          char    c_mode;
         char    c_char;          wchar_t c_char;
           int     c_width;
           int     c_pos;
 } ;  } ;
   
 struct  CHAR    obuf[MAXBUF];  struct  CHAR    obuf[MAXBUF];
Line 78 
Line 83 
 void    fwd(void);  void    fwd(void);
 void    flushln(void);  void    flushln(void);
 void    msetmode(int);  void    msetmode(int);
 void    outc(int);  void    outc(wchar_t, int);
 void    overstrike(void);  void    overstrike(void);
 void    iattr(void);  void    iattr(void);
   
Line 98 
Line 103 
         FILE *f;          FILE *f;
         char termcap[1024];          char termcap[1024];
   
           setlocale(LC_CTYPE, "");
   
         if (pledge("stdio rpath tty", NULL) == -1)          if (pledge("stdio rpath tty", NULL) == -1)
                 err(1, "pledge");                  err(1, "pledge");
   
Line 154 
Line 161 
 void  void
 mfilter(FILE *f)  mfilter(FILE *f)
 {  {
         int c;          struct CHAR     *cp;
           wint_t           c;
           int              skip_bs, w, wt;
   
         while ((c = getc(f)) != EOF && col < MAXBUF) switch(c) {          col = 1;
         case '\b':          skip_bs = 0;
                 if (col > 0)          while (col < MAXBUF) {
                         col--;                  switch (c = fgetwc(f)) {
                 continue;                  case WEOF:
         case '\t':                          /* Discard invalid bytes. */
                 col = (col+8) & ~07;                          if (ferror(f)) {
                 if (col > maxcol)                                  if (errno != EILSEQ)
                         maxcol = col;                                          err(1, NULL);
                 continue;                                  clearerr(f);
         case '\r':                                  break;
                 col = 0;  
                 continue;  
         case SO:  
                 mode |= ALTSET;  
                 continue;  
         case SI:  
                 mode &= ~ALTSET;  
                 continue;  
         case IESC:  
                 switch (c = getc(f)) {  
                 case HREV:  
                         if (halfpos == 0) {  
                                 mode |= SUPERSC;  
                                 halfpos--;  
                         } else if (halfpos > 0) {  
                                 mode &= ~SUBSC;  
                                 halfpos--;  
                         } else {  
                                 halfpos = 0;  
                                 reverse();  
                         }                          }
   
                           /* End of file. */
                           if (maxcol)
                                   flushln();
                           return;
   
                   case L'\b':
                           /*
                            * Back up one character position, not one
                            * display column, but ignore a second
                            * backspace after a double-width character.
                            */
                           if (skip_bs > 0)
                                   skip_bs--;
                           else if (col > 1)
                                   if (obuf[--col].c_width > 1)
                                           skip_bs = obuf[col].c_width - 1;
                         continue;                          continue;
                 case HFWD:  
                         if (halfpos == 0) {                  case L'\t':
                                 mode |= SUBSC;                          /* Calculate the target position. */
                                 halfpos++;                          wt = (obuf[col - 1].c_pos + 8) & ~7;
                         } else if (halfpos < 0) {  
                                 mode &= ~SUPERSC;                          /* Advance past known positions. */
                                 halfpos++;                          while ((w = obuf[col].c_pos) > 0 && w <= wt)
                         } else {                                  col++;
                                 halfpos = 0;  
                                 fwd();                          /* Advance beyond the end. */
                           if (w == 0) {
                                   w = obuf[col - 1].c_pos;
                                   while (w < wt) {
                                           obuf[col].c_width = 1;
                                           obuf[col++].c_pos = ++w;
                                   }
                         }                          }
                         continue;                          if (col > maxcol)
                 case FREV:                                  maxcol = col;
                         reverse();                          break;
                         continue;  
                   case L'\r':
                           col = 1;
                           break;
   
                   case SO:
                           mode |= ALTSET;
                           break;
   
                   case SI:
                           mode &= ~ALTSET;
                           break;
   
                   case IESC:
                           switch (c = fgetwc(f)) {
                           case HREV:
                                   if (halfpos == 0) {
                                           mode |= SUPERSC;
                                           halfpos--;
                                   } else if (halfpos > 0) {
                                           mode &= ~SUBSC;
                                           halfpos--;
                                   } else {
                                           halfpos = 0;
                                           reverse();
                                   }
                                   break;
                           case HFWD:
                                   if (halfpos == 0) {
                                           mode |= SUBSC;
                                           halfpos++;
                                   } else if (halfpos < 0) {
                                           mode &= ~SUPERSC;
                                           halfpos++;
                                   } else {
                                           halfpos = 0;
                                           fwd();
                                   }
                                   break;
                           case FREV:
                                   reverse();
                                   break;
                           default:
                                   errx(1, "0%o: unknown escape sequence", c);
                           }
                           break;
   
                   case L'_':
                           if (obuf[col].c_char == L'\0') {
                                   obuf[col].c_char = L'_';
                                   obuf[col].c_width = 1;
                           } else
                                   obuf[col].c_mode |= UNDERL | mode;
                           /* FALLTHROUGH */
   
                   case L' ':
                           if (obuf[col].c_pos == 0) {
                                   obuf[col].c_width = 1;
                                   obuf[col].c_pos = obuf[col - 1].c_pos + 1;
                           }
                           col++;
                           if (col > maxcol)
                                   maxcol = col;
                           break;
   
                   case L'\n':
                           flushln();
                           break;
   
                   case L'\f':
                           flushln();
                           putwchar(L'\f');
                           break;
   
                 default:                  default:
                         errx(1, "0%o: unknown escape sequence", c);                          /* Discard valid, but non-printable characters. */
                         /* NOTREACHED */                          if ((w = wcwidth(c)) == -1)
                 }                                  break;
                 continue;  
   
         case '_':                          if (obuf[col].c_char == L'\0') {
                 if (obuf[col].c_char)                                  obuf[col].c_char = c;
                         obuf[col].c_mode |= UNDERL | mode;                                  obuf[col].c_mode = mode;
                 else                                  obuf[col].c_width = w;
                         obuf[col].c_char = '_';                                  obuf[col].c_pos = obuf[col - 1].c_pos + w;
                 /* FALLTHROUGH */                          } else if (obuf[col].c_char == L'_') {
         case ' ':                                  obuf[col].c_char = c;
                 col++;                                  obuf[col].c_mode |= UNDERL|mode;
                 if (col > maxcol)                                  obuf[col].c_width = w;
                         maxcol = col;                                  obuf[col].c_pos = obuf[col - 1].c_pos + w;
                 continue;                                  for (cp = obuf + col; cp[1].c_pos > 0; cp++)
         case '\n':                                          cp[1].c_pos = cp[0].c_pos +
                 flushln();                                              cp[1].c_width;
                 continue;                          } else if (obuf[col].c_char == c)
         case '\f':                                  obuf[col].c_mode |= BOLD|mode;
                 flushln();                          else
                 putchar('\f');                                  obuf[col].c_mode = mode;
                 continue;                          col++;
         default:                          if (col > maxcol)
                 if (c < ' ')    /* non printing */                                  maxcol = col;
                         continue;                          break;
                 if (obuf[col].c_char == '\0') {                  }
                         obuf[col].c_char = c;                  skip_bs = 0;
                         obuf[col].c_mode = mode;  
                 } else if (obuf[col].c_char == '_') {  
                         obuf[col].c_char = c;  
                         obuf[col].c_mode |= UNDERL|mode;  
                 } else if (obuf[col].c_char == c)  
                         obuf[col].c_mode |= BOLD|mode;  
                 else  
                         obuf[col].c_mode = mode;  
                 col++;  
                 if (col > maxcol)  
                         maxcol = col;  
                 continue;  
         }          }
         if (maxcol)  
                 flushln();  
 }  }
   
 void  void
Line 257 
Line 327 
         int hadmodes = 0;          int hadmodes = 0;
   
         lastmode = NORMAL;          lastmode = NORMAL;
         for (i=0; i < maxcol; i++) {          for (i = 1; i < maxcol; i++) {
                 if (obuf[i].c_mode != lastmode) {                  if (obuf[i].c_mode != lastmode) {
                         hadmodes++;                          hadmodes = 1;
                         msetmode(obuf[i].c_mode);                          msetmode(obuf[i].c_mode);
                         lastmode = obuf[i].c_mode;                          lastmode = obuf[i].c_mode;
                 }                  }
                 if (obuf[i].c_char == '\0') {                  if (obuf[i].c_char == L'\0') {
                         if (upln)                          if (upln)
                                 PRINT(CURS_RIGHT);                                  PRINT(CURS_RIGHT);
                         else                          else
                                 outc(' ');                                  outc(L' ', 1);
                 } else                  } else
                         outc(obuf[i].c_char);                          outc(obuf[i].c_char, obuf[i].c_width);
         }          }
         if (lastmode != NORMAL) {          if (lastmode != NORMAL)
                 msetmode(0);                  msetmode(0);
         }  
         if (must_overstrike && hadmodes)          if (must_overstrike && hadmodes)
                 overstrike();                  overstrike();
         putchar('\n');          putwchar(L'\n');
         if (iflag && hadmodes)          if (iflag && hadmodes)
                 iattr();                  iattr();
         (void)fflush(stdout);          (void)fflush(stdout);
Line 292 
Line 361 
 void  void
 overstrike(void)  overstrike(void)
 {  {
         int i;          wchar_t wc;
         char *buf, *cp;          int i, j, needspace;
         int hadbold = 0;  
   
         if ((buf = malloc(maxcol + 1)) == NULL)          putwchar(L'\r');
                 err(1, NULL);          needspace = 0;
         cp = buf;          for (i = 1; i < maxcol; i++) {
                   if (obuf[i].c_mode != UNDERL && obuf[i].c_mode != BOLD) {
                           needspace += obuf[i].c_width;
                           continue;
                   }
                   while (needspace > 0) {
                           putwchar(L' ');
                           needspace--;
                   }
                   if (obuf[i].c_mode == BOLD)
                           putwchar(obuf[i].c_char);
                   else
                           for (j = 0; j < obuf[i].c_width; j++)
                                   putwchar(L'_');
           }
   }
   
         /* Set up overstrike buffer */  void
         for (i = 0; i < maxcol; i++)  iattr(void)
   {
           int i, j, needspace;
           char c;
   
           needspace = 0;
           for (i = 1; i < maxcol; i++) {
                 switch (obuf[i].c_mode) {                  switch (obuf[i].c_mode) {
                 case NORMAL:                  case NORMAL:
                 default:                          needspace += obuf[i].c_width;
                         *cp++ = ' ';                          continue;
                   case ALTSET:
                           c = 'g';
                         break;                          break;
                   case SUPERSC:
                           c = '^';
                           break;
                   case SUBSC:
                           c = 'v';
                           break;
                 case UNDERL:                  case UNDERL:
                         *cp++ = '_';                          c = '_';
                         break;                          break;
                 case BOLD:                  case BOLD:
                         *cp++ = obuf[i].c_char;                          c = '!';
                         hadbold=1;  
                         break;                          break;
                   default:
                           c = 'X';
                           break;
                 }                  }
         putchar('\r');                  while (needspace > 0) {
         while (cp > buf && *(cp - 1) == ' ')                          putwchar(L' ');
                 cp--;                          needspace--;
         *cp = '\0';                  }
         for (cp = buf; *cp != '\0'; cp++)                  for (j = 0; j < obuf[i].c_width; j++)
                 putchar(*cp);                          putwchar(c);
         if (hadbold) {  
                 putchar('\r');  
                 for (cp = buf; *cp != '\0'; cp++)  
                         putchar(*cp=='_' ? ' ' : *cp);  
                 putchar('\r');  
                 for (cp = buf; *cp != '\0'; cp++)  
                         putchar(*cp=='_' ? ' ' : *cp);  
         }          }
         free(buf);          putwchar(L'\n');
 }  }
   
 void  void
 iattr(void)  
 {  
         int i;  
         char *buf, *cp;  
   
         if ((buf = malloc(maxcol + 1)) == NULL)  
                 err(1, NULL);  
         cp = buf;  
   
         for (i=0; i < maxcol; i++)  
                 switch (obuf[i].c_mode) {  
                 case NORMAL:    *cp++ = ' '; break;  
                 case ALTSET:    *cp++ = 'g'; break;  
                 case SUPERSC:   *cp++ = '^'; break;  
                 case SUBSC:     *cp++ = 'v'; break;  
                 case UNDERL:    *cp++ = '_'; break;  
                 case BOLD:      *cp++ = '!'; break;  
                 default:        *cp++ = 'X'; break;  
                 }  
         while (cp > buf && *(cp - 1) == ' ')  
                 cp--;  
         *cp = '\0';  
         for (cp = buf; *cp != '\0'; cp++)  
                 putchar(*cp);  
         free(buf);  
         putchar('\n');  
 }  
   
 void  
 initbuf(void)  initbuf(void)
 {  {
         bzero(obuf, sizeof (obuf));     /* depends on NORMAL == 0 */          bzero(obuf, sizeof (obuf));     /* depends on NORMAL == 0 */
         col = 0;          col = 1;
         maxcol = 0;          maxcol = 0;
         mode &= ALTSET;          mode &= ALTSET;
 }  }
Line 448 
Line 511 
 int  int
 outchar(int c)  outchar(int c)
 {  {
         putchar(c & 0177);          return (putwchar(c) != WEOF ? c : EOF);
         return (0);  
 }  }
   
 static int curmode = 0;  static int curmode = 0;
   
 void  void
 outc(int c)  outc(wchar_t c, int width)
 {  {
         putchar(c);          int i;
   
           putwchar(c);
         if (must_use_uc && (curmode&UNDERL)) {          if (must_use_uc && (curmode&UNDERL)) {
                 PRINT(CURS_LEFT);                  for (i = 0; i < width; i++)
                 PRINT(UNDER_CHAR);                          PRINT(CURS_LEFT);
                   for (i = 0; i < width; i++)
                           PRINT(UNDER_CHAR);
         }          }
 }  }
   

Legend:
Removed from v.1.19  
changed lines
  Added in v.1.20