ncurses 5.7 - patch 20090530
[ncurses.git] / test / insdelln.c
1 /****************************************************************************
2  * Copyright (c) 2008 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.1 2008/12/20 22:06:52 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         int pair;
60         int 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
120     getyx(win, y, x);
121     wmove(win, 1, 0);
122     while (waddstr(win, "0123456789 abcdefghijklmnopqrstuvwxyz ") != ERR) {
123     }
124     wmove(win, y, x);
125 }
126
127 static void
128 show_status(WINDOW *win, STATUS * sp)
129 {
130     int y, x;
131
132     getyx(win, y, x);
133     wmove(win, 0, 0);
134     wprintw(win, "Count %d", sp->count);
135     if (sp->v_msg != 0)
136         wprintw(win, " Video %s", sp->v_msg);
137     if (sp->c_msg != 0)
138         wprintw(win, " Color %s", sp->c_msg);
139     wclrtoeol(win);
140     wmove(win, y, x);
141 }
142
143 static void
144 reshow_status(WINDOW *win, STATUS * sp)
145 {
146     fill_window(win);
147     show_status(win, sp);
148 }
149
150 static void
151 do_subwindow(WINDOW *win, STATUS * sp, void func(WINDOW *))
152 {
153     WINDOW *win1 = newwin(sp->y_max - 2, sp->x_max - 2,
154                           sp->y_beg + 1, sp->x_beg + 1);
155
156     if (win1 != 0 && sp->y_max > 4 && sp->x_max > 4) {
157         WINDOW *win2 = derwin(win1, sp->y_max - 4, sp->x_max - 4, 1, 1);
158
159         if (win2 != 0) {
160             box(win1, 0, 0);
161             wrefresh(win1);
162             func(win2);
163
164             delwin(win2);
165         } else {
166             beep();
167         }
168         delwin(win1);
169         touchwin(win);
170     } else {
171         beep();
172     }
173 }
174
175 static void
176 init_status(WINDOW *win, STATUS * sp)
177 {
178     memset(sp, 0, sizeof(*sp));
179     sp->c = 99;
180     sp->v = 99;
181     sp->ch = ' ';
182
183     keypad(win, TRUE);
184     fill_window(win);
185
186     getbegyx(win, sp->y_beg, sp->x_beg);
187     getmaxyx(win, sp->y_max, sp->x_max);
188 }
189
190 static void
191 show_help(WINDOW *win)
192 {
193     static const char *table[] =
194     {
195         "Basic commands:"
196         ,"Use h/j/k/l or arrow keys to move the cursor."
197         ,"Set the count parameter for insert/delete by entering digits 0-9."
198         ,""
199         ,"Other commands:"
200         ,"space toggles through the set of video attributes and colors."
201         ,"t     touches (forces repaint) of the current line."
202         ,"i     calls insertln at the current position with the given count."
203         ,"d     calls deleteln at the window beginning with the given count."
204         ,"I     calls insdelln at the window beginning with the given count."
205         ,"D     calls insdelln at the window beginning with the given -count."
206         ,"f     refills the window with test-pattern using current attributes."
207         ,"w     recur to test windows other than stdscr"
208         ,"q     quit"
209         ,"=     resets count to zero."
210         ,"?     shows this help-window"
211         ,""
212         ,""
213     };
214
215     int y_max, x_max;
216     int row;
217
218     getmaxyx(win, y_max, x_max);
219     for (row = 0; row < (int) SIZEOF(table) && row < y_max; ++row) {
220         mvwprintw(win, row, 0, "%.*s", x_max, table[row]);
221     }
222     while (wgetch(win) != 'q')
223         beep();
224 }
225
226 static void
227 update_status(WINDOW *win, STATUS * sp)
228 {
229     switch (sp->ch) {
230     case ' ':                   /* next test-iteration */
231         if (has_colors()) {
232             if ((sp->c_msg = color_params(++(sp->c), &(sp->pair))) == 0) {
233                 sp->c_msg = color_params(sp->c = 0, &(sp->pair));
234                 if ((sp->v_msg = video_params(++(sp->v), &(sp->attr))) == 0) {
235                     sp->v_msg = video_params(sp->v = 0, &(sp->attr));
236                 }
237             }
238         } else {
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         sp->count = 0;
244         show_status(win, sp);
245         break;
246     case KEY_LEFT:
247     case 'h':
248         if (sp->x_val > 0)
249             wmove(win, sp->y_val, --(sp->x_val));
250         break;
251     case KEY_DOWN:
252     case 'j':
253         if (sp->y_val < sp->y_max)
254             wmove(win, ++(sp->y_val), sp->x_val);
255         break;
256     case KEY_UP:
257     case 'k':
258         if (sp->y_val > 0)
259             wmove(win, --(sp->y_val), sp->x_val);
260         break;
261     case KEY_RIGHT:
262     case 'l':
263         if (sp->x_val < sp->x_max)
264             wmove(win, sp->y_val, ++(sp->x_val));
265         break;
266     case 't':
267         touchline(win, sp->y_val, 1);
268         break;
269     case '=':
270         sp->count = 0;
271         show_status(win, sp);
272         break;
273     case '?':
274         do_subwindow(win, sp, show_help);
275         break;
276     default:
277         if (isdigit(sp->ch)) {
278             sp->count = (sp->count * 10) + (sp->ch - '0');
279             show_status(win, sp);
280         } else {
281             beep();
282         }
283         break;
284     }
285 }
286
287 static void
288 test_winsdelln(WINDOW *win)
289 {
290     STATUS st;
291     int n;
292
293     init_status(win, &st);
294
295     do {
296         wattrset(win, st.attr | COLOR_PAIR(st.pair));
297         switch (st.ch) {
298         case 'i':
299             for (n = 0; n < st.count; ++n)
300                 winsertln(win);
301             break;
302         case 'd':
303             for (n = 0; n < st.count; ++n)
304                 wdeleteln(win);
305             break;
306         case 'I':
307             winsdelln(win, st.count);
308             break;
309         case 'D':
310             winsdelln(win, -st.count);
311             break;
312         case 'f':
313             fill_window(win);
314             reshow_status(win, &st);
315             break;
316         case 'w':
317             do_subwindow(win, &st, test_winsdelln);
318             break;
319         case 'q':
320             return;
321         default:
322             update_status(win, &st);
323             break;
324         }
325     } while ((st.ch = wgetch(win)) != ERR);
326 }
327
328 static void
329 test_insdelln(void)
330 {
331     STATUS st;
332     int n;
333
334     init_status(stdscr, &st);
335
336     do {
337         attrset(st.attr | COLOR_PAIR(st.pair));
338         switch (st.ch) {
339         case 'i':
340             for (n = 0; n < st.count; ++n)
341                 insertln();
342             break;
343         case 'd':
344             for (n = 0; n < st.count; ++n)
345                 deleteln();
346             break;
347         case 'I':
348             insdelln(st.count);
349             break;
350         case 'D':
351             insdelln(-st.count);
352             break;
353         case 'f':
354             fill_window(stdscr);
355             reshow_status(stdscr, &st);
356             break;
357         case 'w':
358             do_subwindow(stdscr, &st, test_winsdelln);
359             break;
360         case 'q':
361             return;
362         default:
363             update_status(stdscr, &st);
364             break;
365         }
366     } while ((st.ch = getch()) != ERR);
367 }
368
369 int
370 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
371 {
372     initscr();
373     cbreak();
374     noecho();
375
376     test_insdelln();
377     endwin();
378
379     ExitProgram(EXIT_SUCCESS);
380 }