aboutsummaryrefslogtreecommitdiff
path: root/contrib/ncurses/test/view.c
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2000-07-03 09:24:12 +0000
committerPeter Wemm <peter@FreeBSD.org>2000-07-03 09:24:12 +0000
commit15589c42fa2774d2f8ee650f4f31eb8d3a861316 (patch)
tree27e79485df3c9195e6fe58960df47f675f41f1e9 /contrib/ncurses/test/view.c
parent6b9085fd58b7602b14be0cd2059285baa764a7ee (diff)
downloadsrc-15589c42fa2774d2f8ee650f4f31eb8d3a861316.tar.gz
src-15589c42fa2774d2f8ee650f4f31eb8d3a861316.zip
Import the most recent ncurses 5.1 prerelease (20000701).
Mostly this is intended to resolve the trace() badness once and for all. Obtained from: ftp://dickey.his.com/ncurses/
Notes
Notes: svn path=/vendor/ncurses/dist/; revision=62449
Diffstat (limited to 'contrib/ncurses/test/view.c')
-rw-r--r--contrib/ncurses/test/view.c271
1 files changed, 178 insertions, 93 deletions
diff --git a/contrib/ncurses/test/view.c b/contrib/ncurses/test/view.c
index 8381dc8898c4..f4c2f067234d 100644
--- a/contrib/ncurses/test/view.c
+++ b/contrib/ncurses/test/view.c
@@ -5,7 +5,8 @@
* to test the scrolling code in ncurses.
*
* modified by Thomas Dickey <dickey@clark.net> July 1995 to demonstrate
- * the use of 'resizeterm()'.
+ * the use of 'resizeterm()', and May 2000 to illustrate wide-character
+ * handling.
*
* Takes a filename argument. It's a simple file-viewer with various
* scroll-up and scroll-down commands.
@@ -22,7 +23,7 @@
* scroll operation worked, and the refresh() code only had to do a
* partial repaint.
*
- * $Id: view.c,v 1.27 1998/08/22 18:33:41 tom Exp $
+ * $Id: view.c,v 1.29 2000/05/21 01:43:03 tom Exp $
*/
#include <test.priv.h>
@@ -52,7 +53,7 @@
static RETSIGTYPE finish(int sig) GCC_NORETURN;
static void show_all(void);
-#if defined(SIGWINCH) && defined(TIOCGWINSZ) && defined(NCURSES_VERSION)
+#if defined(SIGWINCH) && defined(TIOCGWINSZ) && defined(HAVE_RESIZETERM)
#define CAN_RESIZE 1
#else
#define CAN_RESIZE 0
@@ -60,33 +61,23 @@ static void show_all(void);
#if CAN_RESIZE
static RETSIGTYPE adjust(int sig);
-static int interrupted;
+static int interrupted;
#endif
-static int waiting;
-static int shift;
+static int waiting;
+static int shift;
+static int utf8_mode = FALSE;
-static char *fname;
-static char **lines;
-static char **lptr;
+static char *fname;
+static chtype **lines;
+static chtype **lptr;
-#if !HAVE_STRDUP
-#define strdup my_strdup
-static char *strdup (char *s)
+static void
+usage(void)
{
- char *p;
-
- p = malloc(strlen(s)+1);
- if (p)
- strcpy(p,s);
- return(p);
-}
-#endif /* not HAVE_STRDUP */
-
-static void usage(void)
-{
- static const char *msg[] = {
- "Usage: view [options] file"
+ static const char *msg[] =
+ {
+ "Usage: view [options] file"
,""
,"Options:"
," -n NUM specify maximum number of lines (default 1000)"
@@ -97,27 +88,117 @@ static void usage(void)
," -t trace screen updates"
," -T NUM specify trace mask"
#endif
+ ," -u translate UTF-8 data"
};
size_t n;
for (n = 0; n < SIZEOF(msg); n++)
fprintf(stderr, "%s\n", msg[n]);
- exit (EXIT_FAILURE);
+ exit(EXIT_FAILURE);
+}
+
+static int
+ch_len(chtype * src)
+{
+ int result = 0;
+ while (*src++)
+ result++;
+ return result;
+}
+
+/*
+ * Allocate a string into an array of chtype's. If UTF-8 mode is
+ * active, translate the string accordingly.
+ */
+static chtype *
+ch_dup(char *src)
+{
+ unsigned len = strlen(src);
+ chtype *dst = typeMalloc(chtype, len + 1);
+ unsigned j, k;
+ unsigned utf_count = 0;
+ unsigned utf_char = 0;
+
+#define UCS_REPL 0xfffd
+
+ for (j = k = 0; j < len; j++) {
+ if (utf8_mode) {
+ unsigned c = src[j] & 0xff;
+ /* Combine UTF-8 into Unicode */
+ if (c < 0x80) {
+ /* We received an ASCII character */
+ if (utf_count > 0)
+ dst[k++] = UCS_REPL; /* prev. sequence incomplete */
+ dst[k++] = c;
+ utf_count = 0;
+ } else if (c < 0xc0) {
+ /* We received a continuation byte */
+ if (utf_count < 1) {
+ dst[k++] = UCS_REPL; /* ... unexpectedly */
+ } else {
+ if (!utf_char && !((c & 0x7f) >> (7 - utf_count))) {
+ utf_char = UCS_REPL;
+ }
+ /* characters outside UCS-2 become UCS_REPL */
+ if (utf_char > 0x03ff) {
+ /* value would be >0xffff */
+ utf_char = UCS_REPL;
+ } else {
+ utf_char <<= 6;
+ utf_char |= (c & 0x3f);
+ }
+ utf_count--;
+ if (utf_count == 0)
+ dst[k++] = utf_char;
+ }
+ } else {
+ /* We received a sequence start byte */
+ if (utf_count > 0)
+ dst[k++] = UCS_REPL; /* prev. sequence incomplete */
+ if (c < 0xe0) {
+ utf_count = 1;
+ utf_char = (c & 0x1f);
+ if (!(c & 0x1e))
+ utf_char = UCS_REPL; /* overlong sequence */
+ } else if (c < 0xf0) {
+ utf_count = 2;
+ utf_char = (c & 0x0f);
+ } else if (c < 0xf8) {
+ utf_count = 3;
+ utf_char = (c & 0x07);
+ } else if (c < 0xfc) {
+ utf_count = 4;
+ utf_char = (c & 0x03);
+ } else if (c < 0xfe) {
+ utf_count = 5;
+ utf_char = (c & 0x01);
+ } else {
+ dst[k++] = UCS_REPL;
+ utf_count = 0;
+ }
+ }
+ } else {
+ dst[k++] = src[j];
+ }
+ }
+ dst[k] = 0;
+ return dst;
}
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
-int MAXLINES = 1000;
-FILE *fp;
-char buf[BUFSIZ];
-int i;
-char **olptr;
-int done = FALSE;
-int length = 0;
+ int MAXLINES = 1000;
+ FILE *fp;
+ char buf[BUFSIZ];
+ int i;
+ chtype **olptr;
+ int done = FALSE;
+ int length = 0;
#if CAN_RESIZE
-bool use_resize = TRUE;
+ bool use_resize = TRUE;
#endif
- while ((i = getopt(argc, argv, "n:rtT:")) != EOF) {
+ while ((i = getopt(argc, argv, "n:rtT:u")) != EOF) {
switch (i) {
case 'n':
if ((MAXLINES = atoi(optarg)) < 1)
@@ -136,6 +217,9 @@ bool use_resize = TRUE;
trace(TRACE_CALLS);
break;
#endif
+ case 'u':
+ utf8_mode = TRUE;
+ break;
default:
usage();
}
@@ -143,7 +227,7 @@ bool use_resize = TRUE;
if (optind + 1 != argc)
usage();
- if ((lines = (char **)calloc(MAXLINES+2, sizeof(*lines))) == 0)
+ if ((lines = typeMalloc(chtype *, MAXLINES + 2)) == 0)
usage();
fname = argv[optind];
@@ -152,16 +236,16 @@ bool use_resize = TRUE;
return EXIT_FAILURE;
}
- (void) signal(SIGINT, finish); /* arrange interrupts to terminate */
+ (void) signal(SIGINT, finish); /* arrange interrupts to terminate */
#if CAN_RESIZE
if (use_resize)
- (void) signal(SIGWINCH, adjust); /* arrange interrupts to resize */
+ (void) signal(SIGWINCH, adjust); /* arrange interrupts to resize */
#endif
/* slurp the file */
for (lptr = &lines[0]; (lptr - lines) < MAXLINES; lptr++) {
char temp[BUFSIZ], *s, *d;
- int col;
+ int col;
if (fgets(buf, sizeof(buf), fp) == 0)
break;
@@ -173,9 +257,9 @@ bool use_resize = TRUE;
break;
} else if (*d == '\t') {
col = (col | 7) + 1;
- while ((d-temp) != col)
+ while ((d - temp) != col)
*d++ = ' ';
- } else if (isprint(*d)) {
+ } else if (isprint(*d) || utf8_mode) {
col++;
d++;
} else {
@@ -184,17 +268,17 @@ bool use_resize = TRUE;
col = (d - temp);
}
}
- *lptr = strdup(temp);
+ *lptr = ch_dup(temp);
}
(void) fclose(fp);
length = lptr - lines;
- (void) initscr(); /* initialize the curses library */
- keypad(stdscr, TRUE); /* enable keyboard mapping */
- (void) nonl(); /* tell curses not to do NL->CR/NL on output */
- (void) cbreak(); /* take input chars one at a time, no wait for \n */
- (void) noecho(); /* don't echo input */
- idlok(stdscr, TRUE); /* allow use of insert/delete line */
+ (void) initscr(); /* initialize the curses library */
+ keypad(stdscr, TRUE); /* enable keyboard mapping */
+ (void) nonl(); /* tell curses not to do NL->CR/NL on output */
+ (void) cbreak(); /* take input chars one at a time, no wait for \n */
+ (void) noecho(); /* don't echo input */
+ idlok(stdscr, TRUE); /* allow use of insert/delete line */
lptr = lines;
while (!done) {
@@ -205,7 +289,7 @@ bool use_resize = TRUE;
got_number = FALSE;
n = 0;
- for (;;) {
+ for (;;) {
#if CAN_RESIZE
if (interrupted)
adjust(0);
@@ -215,20 +299,19 @@ bool use_resize = TRUE;
waiting = FALSE;
if ((c < 127) && isdigit(c)) {
if (!got_number) {
- mvprintw(0,0, "Count: ");
+ mvprintw(0, 0, "Count: ");
clrtoeol();
}
addch(c);
n = 10 * n + (c - '0');
got_number = TRUE;
- }
- else
+ } else
break;
}
if (!got_number && n == 0)
n = 1;
- switch(c) {
+ switch (c) {
case KEY_DOWN:
case 'n':
olptr = lptr;
@@ -282,7 +365,7 @@ bool use_resize = TRUE;
break;
#ifdef KEY_RESIZE
- case KEY_RESIZE: /* ignore this; ncurses will repaint */
+ case KEY_RESIZE: /* ignore this; ncurses will repaint */
break;
#endif
#if CAN_RESIZE
@@ -297,7 +380,8 @@ bool use_resize = TRUE;
finish(0); /* we're done */
}
-static RETSIGTYPE finish(int sig)
+static RETSIGTYPE
+finish(int sig)
{
endwin();
exit(sig != 0 ? EXIT_FAILURE : EXIT_SUCCESS);
@@ -309,54 +393,55 @@ static RETSIGTYPE finish(int sig)
* Linux. The 'wrefresh(curscr)' is needed to force the refresh to start from
* the top of the screen -- some xterms mangle the bitmap while resizing.
*/
-static RETSIGTYPE adjust(int sig)
+static RETSIGTYPE
+adjust(int sig)
{
- if (waiting || sig == 0) {
+ if (waiting || sig == 0) {
struct winsize size;
- if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) {
- resizeterm(size.ws_row, size.ws_col);
- wrefresh(curscr); /* Linux needs this */
- show_all();
- }
- interrupted = FALSE;
- } else {
- interrupted = TRUE;
+ if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) {
+ resizeterm(size.ws_row, size.ws_col);
+ wrefresh(curscr); /* Linux needs this */
+ show_all();
}
- (void) signal(SIGWINCH, adjust); /* some systems need this */
+ interrupted = FALSE;
+ } else {
+ interrupted = TRUE;
+ }
+ (void) signal(SIGWINCH, adjust); /* some systems need this */
}
-#endif /* CAN_RESIZE */
+#endif /* CAN_RESIZE */
-static void show_all(void)
+static void
+show_all(void)
{
- int i;
- char temp[BUFSIZ];
- char *s;
+ int i;
+ char temp[BUFSIZ];
+ chtype *s;
#if CAN_RESIZE
- sprintf(temp, "(%3dx%3d) col %d ", LINES, COLS, shift);
- i = strlen(temp);
- sprintf(temp+i, "view %.*s", (int)(sizeof(temp)-7-i), fname);
+ sprintf(temp, "(%3dx%3d) col %d ", LINES, COLS, shift);
+ i = strlen(temp);
+ sprintf(temp + i, "view %.*s", (int) (sizeof(temp) - 7 - i), fname);
#else
- sprintf(temp, "view %.*s", (int)sizeof(temp)-7, fname);
+ sprintf(temp, "view %.*s", (int) sizeof(temp) - 7, fname);
#endif
- move(0,0);
- printw("%.*s", COLS, temp);
+ move(0, 0);
+ printw("%.*s", COLS, temp);
+ clrtoeol();
+
+ scrollok(stdscr, FALSE); /* prevent screen from moving */
+ for (i = 1; i < LINES; i++) {
+ move(i, 0);
+ printw("%3d:", (lptr + i - lines));
clrtoeol();
-
- scrollok(stdscr, FALSE); /* prevent screen from moving */
- for (i = 1; i < LINES; i++) {
- move(i, 0);
- if ((s = lptr[i-1]) != 0 && (int)strlen(s) > shift)
- printw("%3ld:%.*s", (long) (lptr+i-lines), COLS-4, s + shift);
- else
- printw("%3ld:", (long) (lptr+i-lines));
- clrtoeol();
+ if ((s = lptr[i - 1]) != 0) {
+ int len = ch_len(s);
+ if (len > shift)
+ addchstr(s + shift);
}
- setscrreg(1, LINES-1);
- scrollok(stdscr, TRUE);
- refresh();
+ }
+ setscrreg(1, LINES - 1);
+ scrollok(stdscr, TRUE);
+ refresh();
}
-
-/* view.c ends here */
-