blob: 52ccfb620f9b3ef58d497cbbabf55dabba0bdf29 [file] [log] [blame]
Steve Kondikae271bc2015-11-15 02:50:53 +01001/****************************************************************************
micky3879b9f5e72025-07-08 18:04:53 -04002 * Copyright 2019-2020,2022 Thomas E. Dickey *
3 * Copyright 2008-2014,2017 Free Software Foundation, Inc. *
Steve Kondikae271bc2015-11-15 02:50:53 +01004 * *
5 * Permission is hereby granted, free of charge, to any person obtaining a *
6 * copy of this software and associated documentation files (the *
7 * "Software"), to deal in the Software without restriction, including *
8 * without limitation the rights to use, copy, modify, merge, publish, *
9 * distribute, distribute with modifications, sublicense, and/or sell *
10 * copies of the Software, and to permit persons to whom the Software is *
11 * furnished to do so, subject to the following conditions: *
12 * *
13 * The above copyright notice and this permission notice shall be included *
14 * in all copies or substantial portions of the Software. *
15 * *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
19 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23 * *
24 * Except as contained in this notice, the name(s) of the above copyright *
25 * holders shall not be used in advertising or otherwise to promote the *
26 * sale, use or other dealings in this Software without prior written *
27 * authorization. *
28 ****************************************************************************/
29/*
micky3879b9f5e72025-07-08 18:04:53 -040030 * $Id: insdelln.c,v 1.15 2022/12/10 23:31:31 tom Exp $
Steve Kondikae271bc2015-11-15 02:50:53 +010031 *
32 * test-driver for deleteln, wdeleteln, insdelln, winsdelln, insertln, winsertln
33 */
34
35#include <test.priv.h>
36
micky3879b9f5e72025-07-08 18:04:53 -040037#if HAVE_WINSDELLN
38
39#include <popup_msg.h>
40
Steve Kondikae271bc2015-11-15 02:50:53 +010041#define SHOW(n) ((n) == ERR ? "ERR" : "OK")
42#define COLOR_DEFAULT (-1)
43
44typedef struct {
45 unsigned c;
46 unsigned v;
47 int pair;
48 unsigned attr;
49 int count;
50 int ch;
51 const char *c_msg;
52 const char *v_msg;
53 int y_val;
54 int x_val;
55 int y_beg, x_beg;
56 int y_max, x_max;
57} STATUS;
58
59static const char *
60color_params(unsigned state, int *pair)
61{
62 /* *INDENT-OFF* */
63 static struct {
64 short pair;
65 short fg, bg;
66 const char *msg;
67 } table[] = {
68 { 0, COLOR_DEFAULT, COLOR_DEFAULT, "default" },
69 { 1, COLOR_RED, COLOR_BLACK, "red/black" },
70 { 2, COLOR_WHITE, COLOR_BLUE, "white/blue" },
71 };
72 /* *INDENT-ON* */
73
Steve Kondikae271bc2015-11-15 02:50:53 +010074 const char *result = 0;
75
76 if (has_colors()) {
micky3879b9f5e72025-07-08 18:04:53 -040077 static bool first = TRUE;
Steve Kondikae271bc2015-11-15 02:50:53 +010078 if (first) {
79 unsigned n;
80
81 start_color();
82 for (n = 0; n < SIZEOF(table); ++n) {
83 init_pair(table[n].pair, table[n].fg, table[n].bg);
84 }
85 }
86 if (state < SIZEOF(table)) {
87 *pair = table[state].pair;
88 result = table[state].msg;
89 }
90 }
91 return result;
92}
93
94static const char *
95video_params(unsigned state, unsigned *attr)
96{
97 /* *INDENT-OFF* */
98 static struct {
99 unsigned attr;
100 const char *msg;
101 } table[] = {
102 { A_NORMAL, "normal" },
103 { A_BOLD, "bold" },
104 { A_REVERSE, "reverse" },
105 { A_UNDERLINE, "underline" },
106 { A_BLINK, "blink" },
107 };
108 /* *INDENT-ON* */
109
110 const char *result = 0;
111
112 if (state < SIZEOF(table)) {
113 *attr = table[state].attr;
114 result = table[state].msg;
115 }
116 return result;
117}
118
119/* fill the window with a test-pattern */
120static void
121fill_window(WINDOW *win)
122{
123 int y, x;
124 int y0 = -1, x0 = -1;
125
126 getyx(win, y, x);
127 wmove(win, 0, 0);
128 while (waddstr(win, "0123456789 abcdefghijklmnopqrstuvwxyz ") != ERR) {
129 int y1, x1;
130 getyx(win, y1, x1);
131 if (y1 == y0 && x1 == x0)
132 break;
133 x0 = x1;
134 y0 = y1;
135 }
136 wmove(win, y, x);
137}
138
139static void
140show_status(WINDOW *win, STATUS * sp)
141{
142 int y, x;
143
144 getyx(win, y, x);
145 wmove(win, 0, 0);
146 wprintw(win, "Count %d", sp->count);
147 if (sp->v_msg != 0)
148 wprintw(win, " Video %s", sp->v_msg);
149 if (sp->c_msg != 0)
150 wprintw(win, " Color %s", sp->c_msg);
151 wclrtoeol(win);
152 wmove(win, y, x);
153}
154
155static void
156reshow_status(WINDOW *win, STATUS * sp)
157{
158 fill_window(win);
159 show_status(win, sp);
160}
161
162static void
163do_subwindow(WINDOW *win, STATUS * sp, void func(WINDOW *))
164{
165 WINDOW *win1 = newwin(sp->y_max - 2, sp->x_max - 2,
166 sp->y_beg + 1, sp->x_beg + 1);
167
168 if (win1 != 0 && sp->y_max > 4 && sp->x_max > 4) {
169 WINDOW *win2 = derwin(win1, sp->y_max - 4, sp->x_max - 4, 1, 1);
170
171 if (win2 != 0) {
172 box(win1, 0, 0);
173 wrefresh(win1);
174 func(win2);
175
176 delwin(win2);
177 } else {
178 beep();
179 }
180 delwin(win1);
181 touchwin(win);
182 } else {
183 if (win1)
184 delwin(win1);
185 beep();
186 }
187}
188
189static void
190init_status(WINDOW *win, STATUS * sp)
191{
192 memset(sp, 0, sizeof(*sp));
193 sp->c = 99;
194 sp->v = 99;
195 sp->ch = ' ';
196
197 keypad(win, TRUE);
198 fill_window(win);
199
200 getbegyx(win, sp->y_beg, sp->x_beg);
201 getmaxyx(win, sp->y_max, sp->x_max);
202}
203
204static void
205show_help(WINDOW *win)
206{
207 static const char *table[] =
208 {
209 "Basic commands:"
210 ,"Use h/j/k/l or arrow keys to move the cursor."
211 ,"Set the count parameter for insert/delete by entering digits 0-9."
212 ,""
213 ,"Other commands:"
214 ,"space toggles through the set of video attributes and colors."
215 ,"t touches (forces repaint) of the current line."
216 ,"i calls insertln at the current position with the given count."
217 ,"d calls deleteln at the window beginning with the given count."
218 ,"I calls insdelln at the window beginning with the given count."
219 ,"D calls insdelln at the window beginning with the given -count."
220 ,"f refills the window with test-pattern using current attributes."
221 ,"w recur to test windows other than stdscr"
222 ,"q quit"
223 ,"= resets count to zero."
224 ,"? shows this help-window"
micky3879b9f5e72025-07-08 18:04:53 -0400225 ,0
Steve Kondikae271bc2015-11-15 02:50:53 +0100226 };
227
micky3879b9f5e72025-07-08 18:04:53 -0400228 popup_msg(win, table);
Steve Kondikae271bc2015-11-15 02:50:53 +0100229}
230
231static void
232update_status(WINDOW *win, STATUS * sp)
233{
234 switch (sp->ch) {
235 case ' ': /* next test-iteration */
236 if (has_colors()) {
237 if ((sp->c_msg = color_params(++(sp->c), &(sp->pair))) == 0) {
238 sp->c_msg = color_params(sp->c = 0, &(sp->pair));
239 if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) {
240 sp->v_msg = video_params(sp->v = 0, &(sp->attr));
241 }
242 }
243 } else {
244 if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) {
245 sp->v_msg = video_params(sp->v = 0, &(sp->attr));
246 }
247 }
248 sp->count = 0;
249 show_status(win, sp);
250 break;
251 case KEY_LEFT:
252 case 'h':
253 if (sp->x_val > 0)
254 wmove(win, sp->y_val, --(sp->x_val));
255 break;
256 case KEY_DOWN:
257 case 'j':
258 if (sp->y_val < sp->y_max)
259 wmove(win, ++(sp->y_val), sp->x_val);
260 break;
261 case KEY_UP:
262 case 'k':
263 if (sp->y_val > 0)
264 wmove(win, --(sp->y_val), sp->x_val);
265 break;
266 case KEY_RIGHT:
267 case 'l':
268 if (sp->x_val < sp->x_max)
269 wmove(win, sp->y_val, ++(sp->x_val));
270 break;
271 case 't':
272 touchline(win, sp->y_val, 1);
273 break;
274 case '=':
275 sp->count = 0;
276 show_status(win, sp);
277 break;
micky3879b9f5e72025-07-08 18:04:53 -0400278 case HELP_KEY_1:
279 show_help(win);
Steve Kondikae271bc2015-11-15 02:50:53 +0100280 break;
281 default:
282 if (isdigit(sp->ch)) {
283 sp->count = (sp->count * 10) + (sp->ch - '0');
284 show_status(win, sp);
285 } else {
286 beep();
287 }
288 break;
289 }
290}
291
292static void
293test_winsdelln(WINDOW *win)
294{
295 STATUS st;
296 int n;
297
298 init_status(win, &st);
299
300 do {
301 (void) wattrset(win, AttrArg(COLOR_PAIR(st.pair), st.attr));
302 switch (st.ch) {
303 case 'i':
304 for (n = 0; n < st.count; ++n)
305 winsertln(win);
306 break;
307 case 'd':
308 for (n = 0; n < st.count; ++n)
309 wdeleteln(win);
310 break;
311 case 'I':
312 winsdelln(win, st.count);
313 break;
314 case 'D':
315 winsdelln(win, -st.count);
316 break;
317 case 'f':
318 fill_window(win);
319 reshow_status(win, &st);
320 break;
321 case 'w':
322 do_subwindow(win, &st, test_winsdelln);
323 break;
324 case 'q':
325 return;
326 default:
327 update_status(win, &st);
328 break;
329 }
330 } while ((st.ch = wgetch(win)) != ERR);
331}
332
333static void
334test_insdelln(void)
335{
336 STATUS st;
337 int n;
338
339 init_status(stdscr, &st);
340
341 do {
342 (void) attrset(AttrArg(COLOR_PAIR(st.pair), st.attr));
343 switch (st.ch) {
344 case 'i':
345 for (n = 0; n < st.count; ++n)
346 insertln();
347 break;
348 case 'd':
349 for (n = 0; n < st.count; ++n)
350 deleteln();
351 break;
352 case 'I':
353 insdelln(st.count);
354 break;
355 case 'D':
356 insdelln(-st.count);
357 break;
358 case 'f':
359 fill_window(stdscr);
360 reshow_status(stdscr, &st);
361 break;
362 case 'w':
363 do_subwindow(stdscr, &st, test_winsdelln);
364 break;
365 case 'q':
366 return;
367 default:
368 update_status(stdscr, &st);
369 break;
370 }
371 } while ((st.ch = getch()) != ERR);
372}
373
micky3879b9f5e72025-07-08 18:04:53 -0400374static void
375usage(int ok)
Steve Kondikae271bc2015-11-15 02:50:53 +0100376{
micky3879b9f5e72025-07-08 18:04:53 -0400377 static const char *msg[] =
378 {
379 "Usage: insdelln [options]"
380 ,""
381 ,USAGE_COMMON
382 };
383 size_t n;
384
385 for (n = 0; n < SIZEOF(msg); n++)
386 fprintf(stderr, "%s\n", msg[n]);
387
388 ExitProgram(ok ? EXIT_SUCCESS : EXIT_FAILURE);
389}
390/* *INDENT-OFF* */
391VERSION_COMMON()
392/* *INDENT-ON* */
393
394int
395main(int argc, char *argv[])
396{
397 int ch;
398
399 while ((ch = getopt(argc, argv, OPTS_COMMON)) != -1) {
400 switch (ch) {
401 case OPTS_VERSION:
402 show_version(argv);
403 ExitProgram(EXIT_SUCCESS);
404 default:
405 usage(ch == OPTS_USAGE);
406 /* NOTREACHED */
407 }
408 }
409 if (optind < argc)
410 usage(FALSE);
411
Steve Kondikae271bc2015-11-15 02:50:53 +0100412 initscr();
413 cbreak();
414 noecho();
415
416 test_insdelln();
417 endwin();
418
419 ExitProgram(EXIT_SUCCESS);
420}
micky3879b9f5e72025-07-08 18:04:53 -0400421
422#else
423int
424main(void)
425{
426 printf("This program requires the curses winsdelln function\n");
427 ExitProgram(EXIT_FAILURE);
428}
429#endif