blob: 458788a5ff9fc0fe97ca480e64619522490b0346 [file] [log] [blame]
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +05301/****************************************************************************
2 * Copyright (c) 2002-2006,2007 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: inserts.c,v 1.18 2007/07/21 17:41:55 tom Exp $
30 *
31 * Demonstrate the winsstr() and winsch functions.
32 * Thomas Dickey - 2002/10/19
33 */
34
35#include <test.priv.h>
36
37#if HAVE_WINSSTR
38
39#define InsNStr insnstr
40#define InsStr insstr
41#define MvInsNStr mvinsnstr
42#define MvInsStr mvinsstr
43#define MvWInsNStr mvwinsnstr
44#define MvWInsStr mvwinsstr
45#define WInsNStr winsnstr
46#define WInsStr winsstr
47
48#define InsCh insch
49#define MvInsCh mvinsch
50#define MvWInsCh mvwinsch
51#define WInsCh winsch
52
53#define MY_TABSIZE 8
54
55typedef enum {
56 oDefault = 0,
57 oMove = 1,
58 oWindow = 2,
59 oMoveWindow = 3
60} Options;
61
62static bool m_opt = FALSE;
63static bool w_opt = FALSE;
64static int n_opt = -1;
65
66static void
67legend(WINDOW *win, int level, Options state, char *buffer, int length)
68{
69 NCURSES_CONST char *showstate;
70
71 switch (state) {
72 default:
73 case oDefault:
74 showstate = "";
75 break;
76 case oMove:
77 showstate = " (mvXXX)";
78 break;
79 case oWindow:
80 showstate = " (winXXX)";
81 break;
82 case oMoveWindow:
83 showstate = " (mvwinXXX)";
84 break;
85 }
86
87 wmove(win, 0, 0);
88 wprintw(win,
89 "The Strings/Chars displays should match. Enter any characters, except:\n");
90 wprintw(win,
91 "down-arrow or ^N to repeat on next line, 'w' for inner window, 'q' to exit.\n");
92 wclrtoeol(win);
93 wprintw(win, "Level %d,%s inserted %d characters <%s>", level,
94 showstate, length, buffer);
95}
96
97static int
98ColOf(char *buffer, int length, int margin)
99{
100 int n;
101 int result;
102
103 for (n = 0, result = margin + 1; n < length; ++n) {
104 int ch = UChar(buffer[n]);
105 switch (ch) {
106 case '\n':
107 /* actually newline should clear the remainder of the line
108 * and move to the next line - but that seems a little awkward
109 * in this example.
110 */
111 case '\r':
112 result = 0;
113 break;
114 case '\b':
115 if (result > 0)
116 --result;
117 break;
118 case '\t':
119 result += (MY_TABSIZE - (result % MY_TABSIZE));
120 break;
121 case '\177':
122 result += 2;
123 break;
124 default:
125 ++result;
126 if (ch < 32)
127 ++result;
128 break;
129 }
130 }
131 return result;
132}
133
134#define LEN(n) ((length - (n) > n_opt) ? n_opt : (length - (n)))
135static void
136test_inserts(int level)
137{
138 static bool first = TRUE;
139
140 int ch;
141 int limit;
142 int row = 1;
143 int col;
144 int row2, col2;
145 int length;
146 char buffer[BUFSIZ];
147 WINDOW *look = 0;
148 WINDOW *work = 0;
149 WINDOW *show = 0;
150 int margin = (2 * MY_TABSIZE) - 1;
151 Options option = (Options) ((unsigned) (m_opt
152 ? oMove
153 : oDefault)
154 | (unsigned) ((w_opt || (level > 0))
155 ? oWindow
156 : oDefault));
157
158 if (first) {
159 static char cmd[80];
160 setlocale(LC_ALL, "");
161
162 putenv(strcpy(cmd, "TABSIZE=8"));
163
164 initscr();
165 (void) cbreak(); /* take input chars one at a time, no wait for \n */
166 (void) noecho(); /* don't echo input */
167 keypad(stdscr, TRUE);
168 }
169
170 limit = LINES - 5;
171 if (level > 0) {
172 look = newwin(limit, COLS - (2 * (level - 1)), 0, level - 1);
173 work = newwin(limit - 2, COLS - (2 * level), 1, level);
174 show = newwin(4, COLS, limit + 1, 0);
175 box(look, 0, 0);
176 wnoutrefresh(look);
177 limit -= 2;
178 } else {
179 work = stdscr;
180 show = derwin(stdscr, 4, COLS, limit + 1, 0);
181 }
182 keypad(work, TRUE);
183
184 for (col = margin + 1; col < COLS; col += MY_TABSIZE)
185 mvwvline(work, row, col, '.', limit - 2);
186
187 mvwvline(work, row, margin, ACS_VLINE, limit - 2);
188 mvwvline(work, row, margin + 1, ACS_VLINE, limit - 2);
189 limit /= 2;
190
191 mvwaddstr(work, 1, 2, "String");
192 mvwaddstr(work, limit + 1, 2, "Chars");
193 wnoutrefresh(work);
194
195 buffer[length = 0] = '\0';
196 legend(show, level, option, buffer, length);
197 wnoutrefresh(show);
198
199 doupdate();
200
201 /*
202 * Show the characters inserted in color, to distinguish from those that
203 * are shifted.
204 */
205 if (has_colors()) {
206 start_color();
207 init_pair(1, COLOR_WHITE, COLOR_BLUE);
208 wbkgdset(work, COLOR_PAIR(1) | ' ');
209 }
210
211 while ((ch = wgetch(work)) != 'q') {
212 if (ch == ERR) {
213 beep();
214 break;
215 }
216 wmove(work, row, margin + 1);
217 switch (ch) {
218 case 'w':
219 test_inserts(level + 1);
220
221 touchwin(look);
222 touchwin(work);
223 touchwin(show);
224
225 wnoutrefresh(look);
226 wnoutrefresh(work);
227 wnoutrefresh(show);
228
229 doupdate();
230 break;
231 case CTRL('N'):
232 case KEY_DOWN:
233 if (row < limit) {
234 ++row;
235 /* put the whole string in, all at once */
236 col2 = margin + 1;
237 switch (option) {
238 case oDefault:
239 if (n_opt > 1) {
240 for (col = 0; col < length; col += n_opt) {
241 col2 = ColOf(buffer, col, margin);
242 if (move(row, col2) != ERR) {
243 InsNStr(buffer + col, LEN(col));
244 }
245 }
246 } else {
247 if (move(row, col2) != ERR) {
248 InsStr(buffer);
249 }
250 }
251 break;
252 case oMove:
253 if (n_opt > 1) {
254 for (col = 0; col < length; col += n_opt) {
255 col2 = ColOf(buffer, col, margin);
256 MvInsNStr(row, col2, buffer + col, LEN(col));
257 }
258 } else {
259 MvInsStr(row, col2, buffer);
260 }
261 break;
262 case oWindow:
263 if (n_opt > 1) {
264 for (col = 0; col < length; col += n_opt) {
265 col2 = ColOf(buffer, col, margin);
266 if (wmove(work, row, col2) != ERR) {
267 WInsNStr(work, buffer + col, LEN(col));
268 }
269 }
270 } else {
271 if (wmove(work, row, col2) != ERR) {
272 WInsStr(work, buffer);
273 }
274 }
275 break;
276 case oMoveWindow:
277 if (n_opt > 1) {
278 for (col = 0; col < length; col += n_opt) {
279 col2 = ColOf(buffer, col, margin);
280 MvWInsNStr(work, row, col2, buffer + col, LEN(col));
281 }
282 } else {
283 MvWInsStr(work, row, col2, buffer);
284 }
285 break;
286 }
287
288 /* do the corresponding single-character insertion */
289 row2 = limit + row;
290 for (col = 0; col < length; ++col) {
291 col2 = ColOf(buffer, col, margin);
292 switch (option) {
293 case oDefault:
294 if (move(row2, col2) != ERR) {
295 InsCh(UChar(buffer[col]));
296 }
297 break;
298 case oMove:
299 MvInsCh(row2, col2, UChar(buffer[col]));
300 break;
301 case oWindow:
302 if (wmove(work, row2, col2) != ERR) {
303 WInsCh(work, UChar(buffer[col]));
304 }
305 break;
306 case oMoveWindow:
307 MvWInsCh(work, row2, col2, UChar(buffer[col]));
308 break;
309 }
310 }
311 } else {
312 beep();
313 }
314 break;
315 case KEY_BACKSPACE:
316 ch = '\b';
317 /* FALLTHRU */
318 default:
319 if (ch <= 0 || ch > 255) {
320 beep();
321 break;
322 }
323 buffer[length++] = ch;
324 buffer[length] = '\0';
325
326 /* put the string in, one character at a time */
327 col = ColOf(buffer, length - 1, margin);
328 switch (option) {
329 case oDefault:
330 if (move(row, col) != ERR) {
331 InsStr(buffer + length - 1);
332 }
333 break;
334 case oMove:
335 MvInsStr(row, col, buffer + length - 1);
336 break;
337 case oWindow:
338 if (wmove(work, row, col) != ERR) {
339 WInsStr(work, buffer + length - 1);
340 }
341 break;
342 case oMoveWindow:
343 MvWInsStr(work, row, col, buffer + length - 1);
344 break;
345 }
346
347 /* do the corresponding single-character insertion */
348 switch (option) {
349 case oDefault:
350 if (move(limit + row, col) != ERR) {
351 InsCh(UChar(ch));
352 }
353 break;
354 case oMove:
355 MvInsCh(limit + row, col, UChar(ch));
356 break;
357 case oWindow:
358 if (wmove(work, limit + row, col) != ERR) {
359 WInsCh(work, UChar(ch));
360 }
361 break;
362 case oMoveWindow:
363 MvWInsCh(work, limit + row, col, UChar(ch));
364 break;
365 }
366
367 wnoutrefresh(work);
368
369 legend(show, level, option, buffer, length);
370 wnoutrefresh(show);
371
372 doupdate();
373 break;
374 }
375 }
376 if (level > 0) {
377 delwin(show);
378 delwin(work);
379 delwin(look);
380 }
381}
382
383static void
384usage(void)
385{
386 static const char *tbl[] =
387 {
388 "Usage: inserts [options]"
389 ,""
390 ,"Options:"
391 ," -n NUM limit string-inserts to NUM bytes on ^N replay"
392 ," -m perform wmove/move separately from insert-functions"
393 ," -w use window-parameter even when stdscr would be implied"
394 };
395 unsigned n;
396 for (n = 0; n < SIZEOF(tbl); ++n)
397 fprintf(stderr, "%s\n", tbl[n]);
398 ExitProgram(EXIT_FAILURE);
399}
400
401int
402main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
403{
404 int ch;
405
406 setlocale(LC_ALL, "");
407
408 while ((ch = getopt(argc, argv, "mn:w")) != -1) {
409 switch (ch) {
410 case 'm':
411 m_opt = TRUE;
412 break;
413 case 'n':
414 n_opt = atoi(optarg);
415 if (n_opt == 0)
416 n_opt = -1;
417 break;
418 case 'w':
419 w_opt = TRUE;
420 break;
421 default:
422 usage();
423 break;
424 }
425 }
426 if (optind < argc)
427 usage();
428
429 test_inserts(0);
430 endwin();
431 ExitProgram(EXIT_SUCCESS);
432}
433#else
434int
435main(void)
436{
437 printf("This program requires the winsstr function\n");
438 ExitProgram(EXIT_FAILURE);
439}
440#endif /* HAVE_WINSSTR */