ncurses 5.9 - patch 20131110
[ncurses.git] / test / insdelln.c
1 /****************************************************************************
2  * Copyright (c) 2008-2010,2012 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.7 2012/11/18 00:37:58 tom Exp $
30  *
31  * test-driver for deleteln, wdeleteln, insdelln, winsdelln, insertln, winsertln
32  */
33
34 #include <test.priv.h>
35
36 #define SHOW(n) ((n) == ERR ? "ERR" : "OK")
37 #define COLOR_DEFAULT (-1)
38
39 typedef struct {
40     unsigned c;
41     unsigned v;
42     int pair;
43     unsigned attr;
44     int count;
45     int ch;
46     const char *c_msg;
47     const char *v_msg;
48     int y_val;
49     int x_val;
50     int y_beg, x_beg;
51     int y_max, x_max;
52 } STATUS;
53
54 static const char *
55 color_params(unsigned state, int *pair)
56 {
57     /* *INDENT-OFF* */
58     static struct {
59         short pair;
60         short fg, bg;
61         const char *msg;
62     } table[] = {
63         { 0, COLOR_DEFAULT, COLOR_DEFAULT, "default" },
64         { 1, COLOR_RED,     COLOR_BLACK,   "red/black" },
65         { 2, COLOR_WHITE,   COLOR_BLUE,    "white/blue" },
66     };
67     /* *INDENT-ON* */
68
69     static bool first = TRUE;
70     const char *result = 0;
71
72     if (has_colors()) {
73         if (first) {
74             unsigned n;
75
76             start_color();
77             for (n = 0; n < SIZEOF(table); ++n) {
78                 init_pair(table[n].pair, table[n].fg, table[n].bg);
79             }
80         }
81         if (state < SIZEOF(table)) {
82             *pair = table[state].pair;
83             result = table[state].msg;
84         }
85     }
86     return result;
87 }
88
89 static const char *
90 video_params(unsigned state, unsigned *attr)
91 {
92     /* *INDENT-OFF* */
93     static struct {
94         unsigned attr;
95         const char *msg;
96     } table[] = {
97         { A_NORMAL,     "normal" },
98         { A_BOLD,       "bold" },
99         { A_REVERSE,    "reverse" },
100         { A_UNDERLINE,  "underline" },
101         { A_BLINK,      "blink" },
102     };
103     /* *INDENT-ON* */
104
105     const char *result = 0;
106
107     if (state < SIZEOF(table)) {
108         *attr = table[state].attr;
109         result = table[state].msg;
110     }
111     return result;
112 }
113
114 /* fill the window with a test-pattern */
115 static void
116 fill_window(WINDOW *win)
117 {
118     int y, x;
119     int y0 = -1, x0 = -1;
120
121     getyx(win, y, x);
122     wmove(win, 0, 0);
123     while (waddstr(win, "0123456789 abcdefghijklmnopqrstuvwxyz ") != ERR) {
124         int y1, x1;
125         getyx(win, y1, x1);
126         if (y1 == y0 && x1 == x0)
127             break;
128         x0 = x1;
129         y0 = y1;
130     }
131     wmove(win, y, x);
132 }
133
134 static void
135 show_status(WINDOW *win, STATUS * sp)
136 {
137     int y, x;
138
139     getyx(win, y, x);
140     wmove(win, 0, 0);
141     wprintw(win, "Count %d", sp->count);
142     if (sp->v_msg != 0)
143         wprintw(win, " Video %s", sp->v_msg);
144     if (sp->c_msg != 0)
145         wprintw(win, " Color %s", sp->c_msg);
146     wclrtoeol(win);
147     wmove(win, y, x);
148 }
149
150 static void
151 reshow_status(WINDOW *win, STATUS * sp)
152 {
153     fill_window(win);
154     show_status(win, sp);
155 }
156
157 static void
158 do_subwindow(WINDOW *win, STATUS * sp, void func(WINDOW *))
159 {
160     WINDOW *win1 = newwin(sp->y_max - 2, sp->x_max - 2,
161                           sp->y_beg + 1, sp->x_beg + 1);
162
163     if (win1 != 0 && sp->y_max > 4 && sp->x_max > 4) {
164         WINDOW *win2 = derwin(win1, sp->y_max - 4, sp->x_max - 4, 1, 1);
165
166         if (win2 != 0) {
167             box(win1, 0, 0);
168             wrefresh(win1);
169             func(win2);
170
171             delwin(win2);
172         } else {
173             beep();
174         }
175         delwin(win1);
176         touchwin(win);
177     } else {
178         if (win1)
179             delwin(win1);
180         beep();
181     }
182 }
183
184 static void
185 init_status(WINDOW *win, STATUS * sp)
186 {
187     memset(sp, 0, sizeof(*sp));
188     sp->c = 99;
189     sp->v = 99;
190     sp->ch = ' ';
191
192     keypad(win, TRUE);
193     fill_window(win);
194
195     getbegyx(win, sp->y_beg, sp->x_beg);
196     getmaxyx(win, sp->y_max, sp->x_max);
197 }
198
199 static void
200 show_help(WINDOW *win)
201 {
202     static const char *table[] =
203     {
204         "Basic commands:"
205         ,"Use h/j/k/l or arrow keys to move the cursor."
206         ,"Set the count parameter for insert/delete by entering digits 0-9."
207         ,""
208         ,"Other commands:"
209         ,"space toggles through the set of video attributes and colors."
210         ,"t     touches (forces repaint) of the current line."
211         ,"i     calls insertln at the current position with the given count."
212         ,"d     calls deleteln at the window beginning with the given count."
213         ,"I     calls insdelln at the window beginning with the given count."
214         ,"D     calls insdelln at the window beginning with the given -count."
215         ,"f     refills the window with test-pattern using current attributes."
216         ,"w     recur to test windows other than stdscr"
217         ,"q     quit"
218         ,"=     resets count to zero."
219         ,"?     shows this help-window"
220         ,""
221         ,""
222     };
223
224     int y_max, x_max;
225     int row;
226
227     getmaxyx(win, y_max, x_max);
228     for (row = 0; row < (int) SIZEOF(table) && row < y_max; ++row) {
229         MvWPrintw(win, row, 0, "%.*s", x_max, table[row]);
230     }
231     while (wgetch(win) != 'q')
232         beep();
233 }
234
235 static void
236 update_status(WINDOW *win, STATUS * sp)
237 {
238     switch (sp->ch) {
239     case ' ':                   /* next test-iteration */
240         if (has_colors()) {
241             if ((sp->c_msg = color_params(++(sp->c), &(sp->pair))) == 0) {
242                 sp->c_msg = color_params(sp->c = 0, &(sp->pair));
243                 if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) {
244                     sp->v_msg = video_params(sp->v = 0, &(sp->attr));
245                 }
246             }
247         } else {
248             if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) {
249                 sp->v_msg = video_params(sp->v = 0, &(sp->attr));
250             }
251         }
252         sp->count = 0;
253         show_status(win, sp);
254         break;
255     case KEY_LEFT:
256     case 'h':
257         if (sp->x_val > 0)
258             wmove(win, sp->y_val, --(sp->x_val));
259         break;
260     case KEY_DOWN:
261     case 'j':
262         if (sp->y_val < sp->y_max)
263             wmove(win, ++(sp->y_val), sp->x_val);
264         break;
265     case KEY_UP:
266     case 'k':
267         if (sp->y_val > 0)
268             wmove(win, --(sp->y_val), sp->x_val);
269         break;
270     case KEY_RIGHT:
271     case 'l':
272         if (sp->x_val < sp->x_max)
273             wmove(win, sp->y_val, ++(sp->x_val));
274         break;
275     case 't':
276         touchline(win, sp->y_val, 1);
277         break;
278     case '=':
279         sp->count = 0;
280         show_status(win, sp);
281         break;
282     case '?':
283         do_subwindow(win, sp, show_help);
284         break;
285     default:
286         if (isdigit(sp->ch)) {
287             sp->count = (sp->count * 10) + (sp->ch - '0');
288             show_status(win, sp);
289         } else {
290             beep();
291         }
292         break;
293     }
294 }
295
296 static void
297 test_winsdelln(WINDOW *win)
298 {
299     STATUS st;
300     int n;
301
302     init_status(win, &st);
303
304     do {
305         (void) wattrset(win, (int) (st.attr | (attr_t) COLOR_PAIR(st.pair)));
306         switch (st.ch) {
307         case 'i':
308             for (n = 0; n < st.count; ++n)
309                 winsertln(win);
310             break;
311         case 'd':
312             for (n = 0; n < st.count; ++n)
313                 wdeleteln(win);
314             break;
315         case 'I':
316             winsdelln(win, st.count);
317             break;
318         case 'D':
319             winsdelln(win, -st.count);
320             break;
321         case 'f':
322             fill_window(win);
323             reshow_status(win, &st);
324             break;
325         case 'w':
326             do_subwindow(win, &st, test_winsdelln);
327             break;
328         case 'q':
329             return;
330         default:
331             update_status(win, &st);
332             break;
333         }
334     } while ((st.ch = wgetch(win)) != ERR);
335 }
336
337 static void
338 test_insdelln(void)
339 {
340     STATUS st;
341     int n;
342
343     init_status(stdscr, &st);
344
345     do {
346         (void) attrset(st.attr | (attr_t) COLOR_PAIR(st.pair));
347         switch (st.ch) {
348         case 'i':
349             for (n = 0; n < st.count; ++n)
350                 insertln();
351             break;
352         case 'd':
353             for (n = 0; n < st.count; ++n)
354                 deleteln();
355             break;
356         case 'I':
357             insdelln(st.count);
358             break;
359         case 'D':
360             insdelln(-st.count);
361             break;
362         case 'f':
363             fill_window(stdscr);
364             reshow_status(stdscr, &st);
365             break;
366         case 'w':
367             do_subwindow(stdscr, &st, test_winsdelln);
368             break;
369         case 'q':
370             return;
371         default:
372             update_status(stdscr, &st);
373             break;
374         }
375     } while ((st.ch = getch()) != ERR);
376 }
377
378 int
379 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
380 {
381     initscr();
382     cbreak();
383     noecho();
384
385     test_insdelln();
386     endwin();
387
388     ExitProgram(EXIT_SUCCESS);
389 }