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