ncurses 5.9 - patch 20120616
[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.6 2012/06/09 20:29:33 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         beep();
179     }
180 }
181
182 static void
183 init_status(WINDOW *win, STATUS * sp)
184 {
185     memset(sp, 0, sizeof(*sp));
186     sp->c = 99;
187     sp->v = 99;
188     sp->ch = ' ';
189
190     keypad(win, TRUE);
191     fill_window(win);
192
193     getbegyx(win, sp->y_beg, sp->x_beg);
194     getmaxyx(win, sp->y_max, sp->x_max);
195 }
196
197 static void
198 show_help(WINDOW *win)
199 {
200     static const char *table[] =
201     {
202         "Basic commands:"
203         ,"Use h/j/k/l or arrow keys to move the cursor."
204         ,"Set the count parameter for insert/delete by entering digits 0-9."
205         ,""
206         ,"Other commands:"
207         ,"space toggles through the set of video attributes and colors."
208         ,"t     touches (forces repaint) of the current line."
209         ,"i     calls insertln at the current position with the given count."
210         ,"d     calls deleteln at the window beginning with the given count."
211         ,"I     calls insdelln at the window beginning with the given count."
212         ,"D     calls insdelln at the window beginning with the given -count."
213         ,"f     refills the window with test-pattern using current attributes."
214         ,"w     recur to test windows other than stdscr"
215         ,"q     quit"
216         ,"=     resets count to zero."
217         ,"?     shows this help-window"
218         ,""
219         ,""
220     };
221
222     int y_max, x_max;
223     int row;
224
225     getmaxyx(win, y_max, x_max);
226     for (row = 0; row < (int) SIZEOF(table) && row < y_max; ++row) {
227         MvWPrintw(win, row, 0, "%.*s", x_max, table[row]);
228     }
229     while (wgetch(win) != 'q')
230         beep();
231 }
232
233 static void
234 update_status(WINDOW *win, STATUS * sp)
235 {
236     switch (sp->ch) {
237     case ' ':                   /* next test-iteration */
238         if (has_colors()) {
239             if ((sp->c_msg = color_params(++(sp->c), &(sp->pair))) == 0) {
240                 sp->c_msg = color_params(sp->c = 0, &(sp->pair));
241                 if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) {
242                     sp->v_msg = video_params(sp->v = 0, &(sp->attr));
243                 }
244             }
245         } else {
246             if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) {
247                 sp->v_msg = video_params(sp->v = 0, &(sp->attr));
248             }
249         }
250         sp->count = 0;
251         show_status(win, sp);
252         break;
253     case KEY_LEFT:
254     case 'h':
255         if (sp->x_val > 0)
256             wmove(win, sp->y_val, --(sp->x_val));
257         break;
258     case KEY_DOWN:
259     case 'j':
260         if (sp->y_val < sp->y_max)
261             wmove(win, ++(sp->y_val), sp->x_val);
262         break;
263     case KEY_UP:
264     case 'k':
265         if (sp->y_val > 0)
266             wmove(win, --(sp->y_val), sp->x_val);
267         break;
268     case KEY_RIGHT:
269     case 'l':
270         if (sp->x_val < sp->x_max)
271             wmove(win, sp->y_val, ++(sp->x_val));
272         break;
273     case 't':
274         touchline(win, sp->y_val, 1);
275         break;
276     case '=':
277         sp->count = 0;
278         show_status(win, sp);
279         break;
280     case '?':
281         do_subwindow(win, sp, show_help);
282         break;
283     default:
284         if (isdigit(sp->ch)) {
285             sp->count = (sp->count * 10) + (sp->ch - '0');
286             show_status(win, sp);
287         } else {
288             beep();
289         }
290         break;
291     }
292 }
293
294 static void
295 test_winsdelln(WINDOW *win)
296 {
297     STATUS st;
298     int n;
299
300     init_status(win, &st);
301
302     do {
303         (void) wattrset(win, (int) (st.attr | (attr_t) COLOR_PAIR(st.pair)));
304         switch (st.ch) {
305         case 'i':
306             for (n = 0; n < st.count; ++n)
307                 winsertln(win);
308             break;
309         case 'd':
310             for (n = 0; n < st.count; ++n)
311                 wdeleteln(win);
312             break;
313         case 'I':
314             winsdelln(win, st.count);
315             break;
316         case 'D':
317             winsdelln(win, -st.count);
318             break;
319         case 'f':
320             fill_window(win);
321             reshow_status(win, &st);
322             break;
323         case 'w':
324             do_subwindow(win, &st, test_winsdelln);
325             break;
326         case 'q':
327             return;
328         default:
329             update_status(win, &st);
330             break;
331         }
332     } while ((st.ch = wgetch(win)) != ERR);
333 }
334
335 static void
336 test_insdelln(void)
337 {
338     STATUS st;
339     int n;
340
341     init_status(stdscr, &st);
342
343     do {
344         (void) attrset(st.attr | (attr_t) COLOR_PAIR(st.pair));
345         switch (st.ch) {
346         case 'i':
347             for (n = 0; n < st.count; ++n)
348                 insertln();
349             break;
350         case 'd':
351             for (n = 0; n < st.count; ++n)
352                 deleteln();
353             break;
354         case 'I':
355             insdelln(st.count);
356             break;
357         case 'D':
358             insdelln(-st.count);
359             break;
360         case 'f':
361             fill_window(stdscr);
362             reshow_status(stdscr, &st);
363             break;
364         case 'w':
365             do_subwindow(stdscr, &st, test_winsdelln);
366             break;
367         case 'q':
368             return;
369         default:
370             update_status(stdscr, &st);
371             break;
372         }
373     } while ((st.ch = getch()) != ERR);
374 }
375
376 int
377 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
378 {
379     initscr();
380     cbreak();
381     noecho();
382
383     test_insdelln();
384     endwin();
385
386     ExitProgram(EXIT_SUCCESS);
387 }