xref: /netbsd-src/external/bsd/less/dist/lesstest/display.c (revision e4a6e799a67c2028562d75b4e61407b22434aa36)
1 #include <termcap.h>
2 #include "lesstest.h"
3 
4 extern TermInfo terminfo;
5 
6 // Set the user's terminal to a given attribute and colors.
display_attr_color(Attr attr,Color fg_color,Color bg_color)7 static void display_attr_color(Attr attr, Color fg_color, Color bg_color) {
8 	printf("\33[m");
9 	if (fg_color != NULL_COLOR)
10 		printf("\33[%dm", fg_color);
11 	if (bg_color != NULL_COLOR)
12 		printf("\33[%dm", bg_color);
13 	if (attr & ATTR_UNDERLINE)
14 		printf("%s", terminfo.enter_underline);
15 	if (attr & ATTR_BOLD)
16 		printf("%s", terminfo.enter_bold);
17 	if (attr & ATTR_BLINK)
18 		printf("%s", terminfo.enter_blink);
19 	if (attr & ATTR_STANDOUT)
20 		printf("%s", terminfo.enter_standout);
21 }
22 
hexval(unsigned char ch)23 static int hexval(unsigned char ch) {
24 	if (ch >= '0' && ch <= '9') return ch - '0';
25 	if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
26 	if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
27 	fprintf(stderr, "invalid hex char 0x%x\n", ch);
28 	abort();
29 }
30 
get_hex(unsigned char const ** pp)31 static int get_hex(unsigned char const** pp) {
32 	int v1 = hexval(*(*pp)++);
33 	int v2 = hexval(*(*pp)++);
34 	return (v1 << 4) | v2;
35 }
36 
37 // Display a given screen image on the user's terminal.
display_screen(const byte * img,int imglen,int screen_width,int screen_height)38 void display_screen(const byte* img, int imglen, int screen_width, int screen_height) {
39 	int x = 0;
40 	int y = 0;
41 	int cursor_x = 0;
42 	int cursor_y = 0;
43 	int literal = 0;
44 	Attr curr_attr = 0;
45 	Color curr_fg_color = NULL_COLOR;
46 	Color curr_bg_color = NULL_COLOR;
47 	while (imglen-- > 0) {
48 		wchar ch = load_wchar(&img);
49 		if (!literal) {
50 			switch (ch) {
51 			case '\\':
52 				literal = 1;
53 				continue;
54 			case LTS_CHAR_ATTR:
55 				curr_attr = get_hex(&img);
56 				display_attr_color(curr_attr, curr_fg_color, curr_bg_color);
57 				continue;
58 			case LTS_CHAR_FG_COLOR:
59 				curr_fg_color = get_hex(&img);
60 				display_attr_color(curr_attr, curr_fg_color, curr_bg_color);
61 				continue;
62 			case LTS_CHAR_BG_COLOR:
63 				curr_bg_color = get_hex(&img);
64 				display_attr_color(curr_attr, curr_fg_color, curr_bg_color);
65 				continue;
66 			case LTS_CHAR_CURSOR:
67 				cursor_x = x;
68 				cursor_y = y;
69 				continue;
70 			}
71 		}
72 		literal = 0;
73 		if (ch != 0) {
74 			byte cbuf[UNICODE_MAX_BYTES];
75 			byte* cp = cbuf;
76 			store_wchar(&cp, ch);
77 			fwrite(cbuf, 1, cp-cbuf, stdout);
78 		}
79 		if (++x >= screen_width) {
80 			printf("\n");
81 			x = 0;
82 			if (++y >= screen_height)
83 				break;
84 		}
85 	}
86 	printf("%s", tgoto(terminfo.cursor_move, cursor_x, cursor_y));
87 	fflush(stdout);
88 }
89 
90 // Print a given screen image on stderr.
91 // Unlike display_screen which prints escape sequences to change color etc,
92 // display_screen_debug only prints printable ASCII.
display_screen_debug(const byte * img,int imglen,int screen_width,int screen_height)93 void display_screen_debug(const byte* img, int imglen, int screen_width, int screen_height) {
94 	int x = 0;
95 	int y = 0;
96 	int literal = 0;
97 	while (imglen-- > 0) {
98 		wchar ch = load_wchar(&img);
99 		if (!literal) {
100 			switch (ch) {
101 			case '\\':
102 				literal = 1;
103 				continue;
104 			case LTS_CHAR_ATTR:
105 			case LTS_CHAR_FG_COLOR:
106 			case LTS_CHAR_BG_COLOR:
107 				x -= 3; // don't count LTS_CHAR or following 2 bytes
108 				break;
109 			case LTS_CHAR_CURSOR:
110 				x -= 1; // don't count LTS_CHAR
111 				break;
112 			}
113 		}
114 		literal = 0;
115 		if (is_ascii(ch))
116 			fwrite(&ch, 1, 1, stderr);
117 		else
118 			fprintf(stderr, "<%lx>", (unsigned long) ch);
119 		if (++x >= screen_width) {
120 			fprintf(stderr, "\n");
121 			x = 0;
122 			if (++y >= screen_height)
123 				break;
124 		}
125 	}
126 	fflush(stderr);
127 }
128 
129 // Print a list of strings.
print_strings(const char * title,char * const * strings)130 void print_strings(const char* title, char* const* strings) {
131 	if (1) return; ///
132 	fprintf(stderr, "%s:\n", title);
133 	char* const* s;
134 	for (s = strings; *s != NULL; ++s) {
135 		fprintf(stderr, " ");
136 		const char* p;
137 		for (p = *s; *p != '\0'; ++p) {
138 			if (is_ascii(*p))
139 				fprintf(stderr, "%c", (char) *p);
140 			else
141 				fprintf(stderr, "\\x%04x", *p);
142 		}
143 		fprintf(stderr, "\n");
144 	}
145 	fprintf(stderr, "%s- end\n", title);
146 }
147