Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/ul/ul.c
Show First 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | static const char | ||||
*ENTER_DIM, *ENTER_BOLD, *ENTER_REVERSE, *UNDER_CHAR, *EXIT_ATTRIBUTES; | *ENTER_DIM, *ENTER_BOLD, *ENTER_REVERSE, *UNDER_CHAR, *EXIT_ATTRIBUTES; | ||||
struct CHAR { | struct CHAR { | ||||
char c_mode; | char c_mode; | ||||
wchar_t c_char; | wchar_t c_char; | ||||
int c_width; /* width or -1 if multi-column char. filler */ | int c_width; /* width or -1 if multi-column char. filler */ | ||||
} ; | } ; | ||||
static struct CHAR obuf[MAXBUF]; | static struct CHAR sobuf[MAXBUF]; /* static output buffer */ | ||||
static struct CHAR *obuf = sobuf; | |||||
static int buflen = MAXBUF; | |||||
static int col, maxcol; | static int col, maxcol; | ||||
static int mode; | static int mode; | ||||
static int halfpos; | static int halfpos; | ||||
static int upln; | static int upln; | ||||
static int iflag; | static int iflag; | ||||
static void usage(void); | static void usage(void); | ||||
static void setnewmode(int); | static void setnewmode(int); | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | if (optind == argc) | ||||
filter(stdin); | filter(stdin); | ||||
else for (; optind<argc; optind++) { | else for (; optind<argc; optind++) { | ||||
f = fopen(argv[optind],"r"); | f = fopen(argv[optind],"r"); | ||||
if (f == NULL) | if (f == NULL) | ||||
err(1, "%s", argv[optind]); | err(1, "%s", argv[optind]); | ||||
else | else | ||||
filter(f); | filter(f); | ||||
} | } | ||||
if (obuf != sobuf) { | |||||
free(obuf); | |||||
} | |||||
exit(0); | exit(0); | ||||
} | } | ||||
static void | static void | ||||
usage(void) | usage(void) | ||||
{ | { | ||||
fprintf(stderr, "usage: ul [-i] [-t terminal] [file ...]\n"); | fprintf(stderr, "usage: ul [-i] [-t terminal] [file ...]\n"); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
static void | static void | ||||
filter(FILE *f) | filter(FILE *f) | ||||
{ | { | ||||
wint_t c; | wint_t c; | ||||
int i, w; | int i, w; | ||||
int copy; | |||||
while ((c = getwc(f)) != WEOF && col < MAXBUF) switch(c) { | copy = 0; | ||||
while ((c = getwc(f)) != WEOF) { | |||||
if (col == buflen) { | |||||
if (obuf == sobuf) { | |||||
obuf = NULL; | |||||
copy = 1; | |||||
} | |||||
obuf = realloc(obuf, sizeof(*obuf) * 2 * buflen); | |||||
if (obuf == NULL) { | |||||
obuf = sobuf; | |||||
break; | |||||
} else if (copy) { | |||||
memcpy(obuf, sobuf, sizeof(*obuf) * buflen); | |||||
copy = 0; | |||||
} | |||||
bzero((char *)(obuf + buflen), sizeof(*obuf) * buflen); | |||||
buflen *= 2; | |||||
} | |||||
switch(c) { | |||||
case '\b': | case '\b': | ||||
if (col > 0) | if (col > 0) | ||||
col--; | col--; | ||||
continue; | continue; | ||||
case '\t': | case '\t': | ||||
col = (col+8) & ~07; | col = (col+8) & ~07; | ||||
if (col > maxcol) | if (col > maxcol) | ||||
maxcol = col; | maxcol = col; | ||||
continue; | continue; | ||||
case '\r': | case '\r': | ||||
col = 0; | col = 0; | ||||
continue; | continue; | ||||
case SO: | case SO: | ||||
mode |= ALTSET; | mode |= ALTSET; | ||||
continue; | continue; | ||||
case SI: | case SI: | ||||
mode &= ~ALTSET; | mode &= ~ALTSET; | ||||
continue; | continue; | ||||
case IESC: | case IESC: | ||||
switch (c = getwc(f)) { | switch (c = getwc(f)) { | ||||
case HREV: | case HREV: | ||||
if (halfpos == 0) { | if (halfpos == 0) { | ||||
mode |= SUPERSC; | mode |= SUPERSC; | ||||
halfpos--; | halfpos--; | ||||
} else if (halfpos > 0) { | } else if (halfpos > 0) { | ||||
mode &= ~SUBSC; | mode &= ~SUBSC; | ||||
halfpos--; | halfpos--; | ||||
} else { | } else { | ||||
halfpos = 0; | halfpos = 0; | ||||
reverse(); | reverse(); | ||||
} | } | ||||
continue; | continue; | ||||
case HFWD: | case HFWD: | ||||
if (halfpos == 0) { | if (halfpos == 0) { | ||||
mode |= SUBSC; | mode |= SUBSC; | ||||
halfpos++; | halfpos++; | ||||
} else if (halfpos < 0) { | } else if (halfpos < 0) { | ||||
mode &= ~SUPERSC; | mode &= ~SUPERSC; | ||||
halfpos++; | halfpos++; | ||||
} else { | } else { | ||||
halfpos = 0; | halfpos = 0; | ||||
fwd(); | fwd(); | ||||
} | } | ||||
continue; | continue; | ||||
case FREV: | case FREV: | ||||
reverse(); | reverse(); | ||||
continue; | continue; | ||||
default: | default: | ||||
errx(1, "unknown escape sequence in input: %o, %o", IESC, c); | errx(1, "unknown escape sequence in input: %o, %o", IESC, c); | ||||
} | } | ||||
continue; | continue; | ||||
case '_': | case '_': | ||||
if (obuf[col].c_char || obuf[col].c_width < 0) { | if (obuf[col].c_char || obuf[col].c_width < 0) { | ||||
while (col > 0 && obuf[col].c_width < 0) | while (col > 0 && obuf[col].c_width < 0) | ||||
col--; | col--; | ||||
w = obuf[col].c_width; | w = obuf[col].c_width; | ||||
for (i = 0; i < w; i++) | for (i = 0; i < w; i++) | ||||
obuf[col++].c_mode |= UNDERL | mode; | obuf[col++].c_mode |= UNDERL | mode; | ||||
if (col > maxcol) | if (col > maxcol) | ||||
maxcol = col; | maxcol = col; | ||||
continue; | continue; | ||||
} | } | ||||
obuf[col].c_char = '_'; | obuf[col].c_char = '_'; | ||||
obuf[col].c_width = 1; | obuf[col].c_width = 1; | ||||
/* FALLTHROUGH */ | /* FALLTHROUGH */ | ||||
case ' ': | case ' ': | ||||
col++; | col++; | ||||
if (col > maxcol) | if (col > maxcol) | ||||
maxcol = col; | maxcol = col; | ||||
continue; | continue; | ||||
case '\n': | case '\n': | ||||
flushln(); | flushln(); | ||||
continue; | continue; | ||||
case '\f': | case '\f': | ||||
flushln(); | flushln(); | ||||
putwchar('\f'); | putwchar('\f'); | ||||
continue; | continue; | ||||
default: | default: | ||||
if ((w = wcwidth(c)) <= 0) /* non printing */ | if ((w = wcwidth(c)) <= 0) /* non printing */ | ||||
continue; | continue; | ||||
if (obuf[col].c_char == '\0') { | if (obuf[col].c_char == '\0') { | ||||
obuf[col].c_char = c; | obuf[col].c_char = c; | ||||
for (i = 0; i < w; i++) | for (i = 0; i < w; i++) | ||||
obuf[col + i].c_mode = mode; | obuf[col + i].c_mode = mode; | ||||
obuf[col].c_width = w; | obuf[col].c_width = w; | ||||
for (i = 1; i < w; i++) | for (i = 1; i < w; i++) | ||||
obuf[col + i].c_width = -1; | obuf[col + i].c_width = -1; | ||||
} else if (obuf[col].c_char == '_') { | } else if (obuf[col].c_char == '_') { | ||||
obuf[col].c_char = c; | obuf[col].c_char = c; | ||||
for (i = 0; i < w; i++) | for (i = 0; i < w; i++) | ||||
obuf[col + i].c_mode |= UNDERL|mode; | obuf[col + i].c_mode |= UNDERL|mode; | ||||
obuf[col].c_width = w; | obuf[col].c_width = w; | ||||
for (i = 1; i < w; i++) | for (i = 1; i < w; i++) | ||||
obuf[col + i].c_width = -1; | obuf[col + i].c_width = -1; | ||||
} else if ((wint_t)obuf[col].c_char == c) { | } else if ((wint_t)obuf[col].c_char == c) { | ||||
for (i = 0; i < w; i++) | for (i = 0; i < w; i++) | ||||
obuf[col + i].c_mode |= BOLD|mode; | obuf[col + i].c_mode |= BOLD|mode; | ||||
} else { | } else { | ||||
w = obuf[col].c_width; | w = obuf[col].c_width; | ||||
for (i = 0; i < w; i++) | for (i = 0; i < w; i++) | ||||
obuf[col + i].c_mode = mode; | obuf[col + i].c_mode = mode; | ||||
} | } | ||||
col += w; | col += w; | ||||
if (col > maxcol) | if (col > maxcol) | ||||
maxcol = col; | maxcol = col; | ||||
continue; | continue; | ||||
} | } | ||||
} | |||||
if (ferror(f)) | if (ferror(f)) | ||||
err(1, NULL); | err(1, NULL); | ||||
if (maxcol) | if (maxcol) | ||||
flushln(); | flushln(); | ||||
} | } | ||||
static void | static void | ||||
flushln(void) | flushln(void) | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | for (cp=lbuf; *cp; cp++) | ||||
putwchar(*cp); | putwchar(*cp); | ||||
putwchar('\n'); | putwchar('\n'); | ||||
} | } | ||||
static void | static void | ||||
initbuf(void) | initbuf(void) | ||||
{ | { | ||||
bzero((char *)obuf, sizeof (obuf)); /* depends on NORMAL == 0 */ | bzero((char *)obuf, buflen * sizeof(*obuf)); /* depends on NORMAL == 0 */ | ||||
col = 0; | col = 0; | ||||
maxcol = 0; | maxcol = 0; | ||||
mode &= ALTSET; | mode &= ALTSET; | ||||
} | } | ||||
static void | static void | ||||
fwd(void) | fwd(void) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 145 Lines • Show Last 20 Lines |