tin  2.6.1
About: TIN is a threaded NNTP and spool based UseNet newsreader.
  Fossies Dox: tin-2.6.1.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

getline.c
Go to the documentation of this file.
1/*
2 * Project : tin - a Usenet reader
3 * Module : getline.c
4 * Author : Chris Thewalt & Iain Lea
5 * Created : 1991-11-09
6 * Updated : 2021-02-23
7 * Notes : emacs style line editing input package.
8 * Copyright : (c) Copyright 1991-99 by Chris Thewalt & Iain Lea
9 * Permission to use, copy, modify, and distribute this
10 * software for any purpose and without fee is hereby
11 * granted, provided that the above copyright notices
12 * appear in all copies and that both the copyright
13 * notice and this permission notice appear in supporting
14 * documentation. This software is provided "as is" without
15 * express or implied warranty.
16 */
17
18#ifndef TIN_H
19# include "tin.h"
20#endif /* !TIN_H */
21#ifndef TCURSES_H
22# include "tcurses.h"
23#endif /* !TCURSES_H */
24
25#define BUF_SIZE 1024
26#define TAB_SIZE 4
27
28#define CTRL_A '\001'
29#define CTRL_B '\002'
30#define CTRL_D '\004'
31#define CTRL_E '\005'
32#define CTRL_F '\006'
33#define CTRL_H '\010'
34#define CTRL_K '\013'
35#define CTRL_L '\014'
36#define CTRL_R '\022'
37#define CTRL_N '\016'
38#define CTRL_P '\020'
39#define CTRL_U '\025'
40#define CTRL_W '\027'
41#define TAB '\t'
42#define DEL '\177'
43
44#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
45 static wchar_t gl_buf[BUF_SIZE]; /* wide-character input buffer */
46 static char buf[BUF_SIZE];
47#else
48 static char gl_buf[BUF_SIZE]; /* input buffer */
49#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
50static const char *gl_prompt; /* to save the prompt string */
51static int gl_width = 0; /* net size available for input */
52static int gl_pos, gl_cnt = 0; /* position and size of input */
54
55/*
56 * local prototypes
57 */
58#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
59 static void gl_addwchar(wint_t wc);
60 static int gl_tab(wchar_t *wbuf, int offset, int *loc);
61#else
62 static void gl_addchar(int c);
63 static int gl_tab(char *buf, int offset, int *loc);
64#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
65static void gl_del(int loc);
66static void gl_fixup(int change, int cursor);
67static void gl_newline(int w);
68static void gl_kill(void);
69static void gl_kill_back_word(void);
70static void hist_add(int w);
71static void hist_next(int w);
72static void hist_prev(int w);
73
74#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
75 static int (*gl_in_hook) (wchar_t *) = 0;
76 static int (*gl_out_hook) (wchar_t *) = 0;
77 static int (*gl_tab_hook) (wchar_t *, int, int *) = gl_tab;
78#else
79 static int (*gl_in_hook) (char *) = 0;
80 static int (*gl_out_hook) (char *) = 0;
81 static int (*gl_tab_hook) (char *, int, int *) = gl_tab;
82#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
83
84char *
86 const char *prompt,
87 int number_only, /* 1=positive numbers only, 2=negative too */
88 const char *str,
89 int max_chars,
90 t_bool passwd,
91 int which_hist)
92{
93 int c, i, loc, tmp, gl_max;
94 char *tprompt;
95#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
96 wint_t wc;
97#else
98 char *buf = gl_buf;
99#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
100
102
103 is_passwd = passwd;
104
106 if (prompt == NULL)
107 prompt = "";
108
109 tprompt = strunc(prompt, cCOLS - 6);
110
111 gl_buf[0] = 0; /* used as end of input indicator */
112 gl_fixup(-1, 0); /* this resets gl_fixup */
113 gl_width = cCOLS - MIN(cCOLS - 6, strwidth(tprompt));
114 gl_prompt = tprompt;
115 gl_pos = gl_cnt = 0;
116
117 if (max_chars == 0) {
118 if (number_only)
119 gl_max = 10;
120 else
121 gl_max = BUF_SIZE;
122 } else
123 gl_max = max_chars;
124
125 my_fputs(tprompt, stdout);
126 cursoron();
127 my_flush();
128
129 if (gl_in_hook) {
130 loc = gl_in_hook(gl_buf);
131 if (loc >= 0)
132 gl_fixup(0, BUF_SIZE);
133 }
134
135 if (!cmd_line && gl_max == BUF_SIZE)
136 CleartoEOLN();
137
138#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
139 if (str != NULL) {
140 wchar_t *wbuf;
141
142 if ((wbuf = char2wchar_t(str)) != NULL) {
143 for (i = 0; wbuf[i]; i++)
144 gl_addwchar((wint_t) wbuf[i]);
145 free(wbuf);
146 }
147 }
148
149 while ((wc = ReadWch()) != WEOF) {
150 if ((gl_cnt < gl_max) && iswprint(wc)) {
151 if (number_only) {
152 if (iswdigit(wc)) {
153 gl_addwchar(wc);
154 /* Minus */
155 } else if (number_only == 2 && gl_pos == 0 && wc == (wint_t) '-') {
156 gl_addwchar(wc);
157 } else {
158 ring_bell();
159 }
160 } else
161 gl_addwchar(wc);
162 } else {
163 c = (int) wc;
164 switch (wc) {
165#else
166 if (str != NULL) {
167 for (i = 0; str[i]; i++)
168 gl_addchar(str[i]);
169 }
170
171 while ((c = ReadCh()) != EOF) {
172 c &= 0xff;
173 if ((gl_cnt < gl_max) && my_isprint(c)) {
174 if (number_only) {
175 if (isdigit(c)) {
176 gl_addchar(c);
177 /* Minus */
178 } else if (number_only == 2 && gl_pos == 0 && c == '-') {
179 gl_addchar(c);
180 } else {
181 ring_bell();
182 }
183 } else
184 gl_addchar(c);
185 } else {
186 switch (c) {
187#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
188 case ESC: /* abort */
189#ifdef HAVE_KEY_PREFIX
190 case KEY_PREFIX:
191#endif /* HAVE_KEY_PREFIX */
192 switch (get_arrow_key(c)) {
193 case KEYMAP_UP:
194 case KEYMAP_PAGE_UP:
195 hist_prev(which_hist);
196 break;
197
198 case KEYMAP_PAGE_DOWN:
199 case KEYMAP_DOWN:
200 hist_next(which_hist);
201 break;
202
203 case KEYMAP_RIGHT:
204 gl_fixup(-1, gl_pos + 1);
205 break;
206
207 case KEYMAP_LEFT:
208 gl_fixup(-1, gl_pos - 1);
209 break;
210
211 case KEYMAP_HOME:
212 gl_fixup(-1, 0);
213 break;
214
215 case KEYMAP_END:
216 gl_fixup(-1, gl_cnt);
217 break;
218
219 case KEYMAP_DEL:
220 gl_del(0);
221 break;
222
223 case KEYMAP_INS:
224#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
225 gl_addwchar((wint_t) ' ');
226#else
227 gl_addchar(' ');
228#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
229 break;
230
231 default:
233 free(tprompt);
234 return NULL;
235 }
236 break;
237
238 case '\n': /* newline */
239 case '\r':
240 gl_newline(which_hist);
241#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
242 wcstombs(buf, gl_buf, BUF_SIZE - 1);
243#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
245 free(tprompt);
246 return buf;
247
248 case CTRL_A:
249 gl_fixup(-1, 0);
250 break;
251
252 case CTRL_B:
253 gl_fixup(-1, gl_pos - 1);
254 break;
255
256 case CTRL_D:
257 if (gl_cnt == 0) {
258 gl_buf[0] = 0;
259 my_fputc('\n', stdout);
260#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
261 wcstombs(buf, gl_buf, BUF_SIZE - 1);
262#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
264 free(tprompt);
265 return buf;
266 } else
267 gl_del(0);
268 break;
269
270 case CTRL_E:
271 gl_fixup(-1, gl_cnt);
272 break;
273
274 case CTRL_F:
275 gl_fixup(-1, gl_pos + 1);
276 break;
277
278 case CTRL_H:
279 case DEL:
280 gl_del(-1);
281 break;
282
283 case TAB:
284 if (gl_tab_hook) {
285 tmp = gl_pos;
286 loc = gl_tab_hook(gl_buf, (int) strlen(gl_prompt), &tmp);
287 if (loc >= 0 || tmp != gl_pos)
288 gl_fixup(loc, tmp);
289 }
290 break;
291
292 case CTRL_W:
294 break;
295
296 case CTRL_U:
297 gl_fixup(-1, 0);
298 /* FALLTHROUGH */
299 case CTRL_K:
300 gl_kill();
301 break;
302
303 case CTRL_L:
304 case CTRL_R:
305 gl_redraw();
306 break;
307
308 case CTRL_N:
309 hist_next(which_hist);
310 break;
311
312 case CTRL_P:
313 hist_prev(which_hist);
314 break;
315
316 default:
317 ring_bell();
318 break;
319 }
320 }
321 }
322#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
323 wcstombs(buf, gl_buf, BUF_SIZE - 1);
324#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
326 free(tprompt);
327 return buf;
328}
329
330
331/*
332 * adds the character c to the input buffer at current location if
333 * the character is in the allowed template of characters
334 */
335static void
336#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
337gl_addwchar(
338 wint_t wc)
339#else
341 int c)
342#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
343{
344 int i;
345
346 /*
347 * Crashing is always the worst solution IMHO. So as a quick hack,
348 * ignore characters silently, if buffer is full. To allow a final
349 * newline, leave space for one more character. Just a hack too.
350 * This was the original code:
351 *
352 if (gl_cnt >= BUF_SIZE - 1) {
353 error_message(2, "tin_getline: input buffer overflow");
354 giveup();
355 }
356 */
357 if (gl_cnt >= BUF_SIZE - 2)
358 return;
359
360 for (i = gl_cnt; i >= gl_pos; i--)
361 gl_buf[i + 1] = gl_buf[i];
362
363#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
364 gl_buf[gl_pos] = (wchar_t) wc;
365#else
366 gl_buf[gl_pos] = c;
367#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
368 gl_fixup(gl_pos, gl_pos + 1);
369}
370
371
372/*
373 * Cleans up entire line before returning to caller. A \n is appended.
374 * If line longer than screen, we redraw starting at beginning
375 */
376static void
378 int w)
379{
380 int change = gl_cnt;
381 int len = gl_cnt;
382 int loc = gl_width - 5; /* shifts line back to start position */
383
384 if (gl_cnt >= BUF_SIZE - 1) {
385 /*
386 * Like above: avoid crashing if possible. gl_addchar() now
387 * leaves one space left for the newline, so this part of the
388 * code should never be reached. A proper implementation is
389 * desirable though.
390 */
391 error_message(2, "tin_getline: input buffer overflow");
392 free(tin_progname);
393 giveup();
394 }
395 hist_add(w); /* only adds if nonblank */
396 if (gl_out_hook) {
397 change = gl_out_hook(gl_buf);
398#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
399 len = (int) wcslen(gl_buf);
400#else
401 len = (int) strlen(gl_buf);
402#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
403 }
404 if (loc > len)
405 loc = len;
406 gl_fixup(change, loc); /* must do this before appending \n */
407#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
408 gl_buf[len] = (wchar_t) '\0';
409#else
410 gl_buf[len] = '\0';
411#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
412}
413
414
415/*
416 * Delete a character. The loc variable can be:
417 * -1 : delete character to left of cursor
418 * 0 : delete character under cursor
419 */
420static void
422 int loc)
423{
424 int i;
425
426 if ((loc == -1 && gl_pos > 0) || (loc == 0 && gl_pos < gl_cnt)) {
427 for (i = gl_pos + loc; i < gl_cnt; i++)
428 gl_buf[i] = gl_buf[i + 1];
429 gl_fixup(gl_pos + loc, gl_pos + loc);
430 } else
431 ring_bell();
432}
433
434
435/*
436 * delete from current position to the end of line
437 */
438static void
440 void)
441{
442 if (gl_pos < gl_cnt) {
443#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
444 gl_buf[gl_pos] = (wchar_t) '\0';
445#else
446 gl_buf[gl_pos] = '\0';
447#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
449 } else
450 ring_bell();
451}
452
453
454/*
455 * delete from the start of current or last word to current position
456 */
457static void
459 void)
460{
461 int i, j, cur;
462
463#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
464 /* delete spaces */
465 for (i = gl_pos - 1; i >= 0 && iswspace((wint_t) gl_buf[i]); --i)
466 ;
467
468 /* delete not alnum characters but graph characters */
469 for (; i >= 0 && iswgraph((wint_t) gl_buf[i]) && !iswalnum((wint_t) gl_buf[i]); --i)
470 ;
471
472 /* delete all graph characters except '/' */
473 for (; i >= 0 && gl_buf[i] != (wchar_t) '/' && iswgraph((wint_t) gl_buf[i]); --i)
474 ;
475#else
476 /* delete spaces */
477 for (i = gl_pos - 1; i >= 0 && isspace((int) gl_buf[i]); --i)
478 ;
479
480 /* delete not alnum characters but graph characters */
481 for (; i >= 0 && isgraph((int) gl_buf[i]) && !isalnum((int) gl_buf[i]); --i)
482 ;
483
484 /* delete all graph characters except '/' */
485 for (; i >= 0 && gl_buf[i] != '/' && isgraph((int) gl_buf[i]); --i)
486 ;
487#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
488
489 i++;
490 if (i != gl_pos) {
491 j = i;
492 cur = gl_pos;
493 gl_fixup(-1, i);
494
495 while (gl_buf[cur])
496 gl_buf[j++] = gl_buf[cur++];
497#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
498 gl_buf[j] = (wchar_t) '\0';
499#else
500 gl_buf[j] = '\0';
501#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
502 gl_fixup(i, i);
503 } else
504 ring_bell();
505}
506
507
508/*
509 * emit a newline, reset and redraw prompt and current input line
510 */
511void
513 void)
514{
516 my_fputs(gl_prompt, stdout);
517 gl_pos = 0;
518 gl_fixup(0, BUF_SIZE);
519 cursoron();
520}
521
522
523/*
524 * This function is used both for redrawing when input changes or for
525 * moving within the input line. The parameters are:
526 * change : the index of the start of changes in the input buffer,
527 * with -1 indicating no changes.
528 * cursor : the desired location of the cursor after the call.
529 * A value of BUF_SIZE can be used to indicate the cursor
530 * should move just past the end of the input line.
531 */
532static void
534 int change,
535 int cursor)
536{
537 static int gl_shift; /* index of first on screen character */
538 static int off_right; /* true if more text right of screen */
539 static int off_left; /* true if more text left of screen */
540 int left = 0, right = -1; /* bounds for redraw */
541 int pad; /* how much to erase at end of line */
542 int backup; /* how far to backup before fixing */
543 int new_shift; /* value of shift based on cursor */
544 int extra; /* adjusts when shift (scroll) happens */
545 int i;
546 /* FIXME: there are some small problems if SCROLL >= gl_width - 2 */
547 int SCROLL = MIN(30, gl_width - 3);
548
549 if (change == -1 && cursor == 0 && gl_buf[0] == 0) { /* reset */
550 gl_shift = off_right = off_left = 0;
551 return;
552 }
553 pad = (off_right) ? gl_width - 1 : gl_cnt - gl_shift; /* old length */
554 backup = gl_pos - gl_shift;
555 if (change >= 0) {
556#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
557 gl_cnt = (int) wcslen(gl_buf);
558#else
559 gl_cnt = (int) strlen(gl_buf);
560#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
561 if (change > gl_cnt)
562 change = gl_cnt;
563 }
564 if (cursor > gl_cnt) {
565 if (cursor != BUF_SIZE) /* BUF_SIZE means end of line */
566 ring_bell();
567 cursor = gl_cnt;
568 }
569 if (cursor < 0) {
570 ring_bell();
571 cursor = 0;
572 }
573 if (!is_passwd) {
574 if (off_right || (off_left && (cursor < gl_shift + gl_width - SCROLL / 2)))
575 extra = 2; /* shift the scrolling boundary */
576 else
577 extra = 0;
578 new_shift = cursor + extra + SCROLL - gl_width;
579 if (new_shift > 0) {
580 new_shift /= SCROLL;
581 new_shift *= SCROLL;
582 } else
583 new_shift = 0;
584 if (new_shift != gl_shift) { /* scroll occurs */
585 gl_shift = new_shift;
586 off_left = (gl_shift) ? 1 : 0;
587 off_right = (gl_cnt > gl_shift + gl_width - 1) ? 1 : 0;
588 left = gl_shift;
589 right = (off_right) ? gl_shift + gl_width - 2 : gl_cnt;
590 } else if (change >= 0) { /* no scroll, but text changed */
591 if (change < gl_shift + off_left)
592 left = gl_shift;
593 else {
594 left = change;
595 backup = gl_pos - change;
596 }
597 off_right = (gl_cnt > gl_shift + gl_width - 1) ? 1 : 0;
598 right = (off_right) ? gl_shift + gl_width - 2 : gl_cnt;
599 }
600 pad -= (off_right ? gl_width - 1 : gl_cnt - gl_shift);
601 pad = (pad < 0) ? 0 : pad;
602 if (left <= right) { /* clean up screen */
603 for (i = 0; i < backup; i++)
604 my_fputc('\b', stdout);
605 if (left == gl_shift && off_left) {
606 my_fputc('$', stdout);
607 left++;
608 }
609 for (i = left; i < right; i++) {
610#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
611 my_fputwc((wint_t) gl_buf[i], stdout);
612#else
613 my_fputc(gl_buf[i], stdout);
614#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
615 }
616 if (off_right) {
617 my_fputc('$', stdout);
618 gl_pos = right + 1;
619 } else {
620 for (i = 0; i < pad; i++) /* erase remains of prev line */
621 my_fputc(' ', stdout);
622 gl_pos = right + pad;
623 }
624 }
625 i = gl_pos - cursor; /* move to final cursor location */
626 if (i > 0) {
627 while (i--)
628 my_fputc('\b', stdout);
629 } else {
630 for (i = gl_pos; i < cursor; i++) {
631#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
632 my_fputwc((wint_t) gl_buf[i], stdout);
633#else
634 my_fputc(gl_buf[i], stdout);
635#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
636 }
637 }
638 my_flush();
639 }
640 gl_pos = cursor;
641}
642
643
644/*
645 * default tab handler, acts like tabstops every TAB_SIZE cols
646 */
647static int
649#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
650 wchar_t *wbuf,
651#else
652 char *buf,
653#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
654 int offset,
655 int *loc)
656{
657 int i, count, len;
658
659#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
660 len = (int) wcslen(wbuf);
661 count = TAB_SIZE - (offset + *loc) % TAB_SIZE;
662 for (i = len; i >= *loc; i--)
663 wbuf[i + count] = wbuf[i];
664 for (i = 0; i < count; i++)
665 wbuf[*loc + i] = (wchar_t) ' ';
666#else
667 len = (int) strlen(buf);
668 count = TAB_SIZE - (offset + *loc) % TAB_SIZE;
669 for (i = len; i >= *loc; i--)
670 buf[i + count] = buf[i];
671 for (i = 0; i < count; i++)
672 buf[*loc + i] = ' ';
673#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
674 i = *loc;
675 *loc = i + count;
676 return i;
677}
678
679
680static void
682 int w)
683{
684 char *p;
685 char *tmp;
686
687 if (w == HIST_NONE)
688 return;
689
690#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
691 if ((tmp = wchar_t2char(gl_buf)) == NULL)
692 return;
693#else
694 tmp = my_strdup(gl_buf);
695#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
696
697 p = tmp;
698 while (*p == ' ' || *p == '\t') /* only save nonblank line */
699 p++;
700
701 if (*p) {
702 input_history[w][hist_last[w]] = tmp;
703 hist_last[w] = (hist_last[w] + 1) % HIST_SIZE;
704 FreeAndNull(input_history[w][hist_last[w]]); /* erase next location */
705 } else /* we didn't need tmp, so free it */
706 free(tmp);
707
708 hist_pos[w] = hist_last[w];
709}
710
711
712/*
713 * loads previous hist entry into input buffer, sticks on first
714 */
715static void
717 int w)
718{
719 int next;
720#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
721 size_t size;
722#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
723
724 if (w == HIST_NONE)
725 return;
726
727 next = (hist_pos[w] - 1 + HIST_SIZE) % HIST_SIZE;
728 if (next != hist_last[w]) {
729 if (input_history[w][next]) {
730 hist_pos[w] = next;
731#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
732 if ((size = mbstowcs(gl_buf, input_history[w][hist_pos[w]], BUF_SIZE - 1)) == (size_t) -1)
733 size = 0;
734 gl_buf[size] = (wchar_t) '\0';
735#else
736 strcpy(gl_buf, input_history[w][hist_pos[w]]);
737#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
738 } else
739 ring_bell();
740 } else
741 ring_bell();
742
743 if (gl_in_hook)
745 gl_fixup(0, BUF_SIZE);
746}
747
748
749/*
750 * loads next hist entry into input buffer, clears on last
751 */
752static void
754 int w)
755{
756 if (w == HIST_NONE)
757 return;
758
759 if (hist_pos[w] != hist_last[w]) {
760 hist_pos[w] = (hist_pos[w] + 1) % HIST_SIZE;
761 if (input_history[w][hist_pos[w]]) {
762#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
763 size_t size;
764
765 if ((size = mbstowcs(gl_buf, input_history[w][hist_pos[w]], BUF_SIZE - 1)) == (size_t) -1)
766 size = 0;
767 gl_buf[size] = (wchar_t) '\0';
768#else
769 strcpy(gl_buf, input_history[w][hist_pos[w]]);
770#endif /* MULTIBYTE_ABLE && !NO_LOCALE */
771 } else
772 gl_buf[0] = 0;
773 } else
774 ring_bell();
775
776 if (gl_in_hook)
778 gl_fixup(0, BUF_SIZE);
779}
unsigned t_bool
Definition: bool.h:77
int input_context
Definition: signal.c:106
int hist_pos[HIST_URL+1]
Definition: init.c:120
char * input_history[HIST_URL+1][15+1]
Definition: init.c:169
t_bool cmd_line
Definition: init.c:129
#define HIST_SIZE
Definition: extern.h:1581
int cCOLS
Definition: curses.c:53
char * tin_progname
Definition: init.c:105
int hist_last[HIST_URL+1]
Definition: init.c:119
#define HIST_NONE
Definition: extern.h:1580
static int gl_pos
Definition: getline.c:52
#define CTRL_E
Definition: getline.c:31
void gl_redraw(void)
Definition: getline.c:512
static int gl_width
Definition: getline.c:51
#define CTRL_W
Definition: getline.c:40
static int(* gl_out_hook)(char *)=0
Definition: getline.c:80
static t_bool is_passwd
Definition: getline.c:53
char * tin_getline(const char *prompt, int number_only, const char *str, int max_chars, t_bool passwd, int which_hist)
Definition: getline.c:85
static void hist_next(int w)
Definition: getline.c:753
#define CTRL_B
Definition: getline.c:29
#define CTRL_D
Definition: getline.c:30
static int(* gl_in_hook)(char *)=0
Definition: getline.c:79
static int gl_tab(char *buf, int offset, int *loc)
Definition: getline.c:648
#define CTRL_F
Definition: getline.c:32
static void gl_addchar(int c)
Definition: getline.c:340
static void gl_kill_back_word(void)
Definition: getline.c:458
#define CTRL_H
Definition: getline.c:33
#define CTRL_U
Definition: getline.c:39
#define BUF_SIZE
Definition: getline.c:25
static void gl_newline(int w)
Definition: getline.c:377
#define CTRL_K
Definition: getline.c:34
#define CTRL_P
Definition: getline.c:38
static void gl_del(int loc)
Definition: getline.c:421
#define TAB_SIZE
Definition: getline.c:26
static const char * gl_prompt
Definition: getline.c:50
#define CTRL_L
Definition: getline.c:35
static int gl_cnt
Definition: getline.c:52
static void hist_prev(int w)
Definition: getline.c:716
#define CTRL_N
Definition: getline.c:37
#define CTRL_R
Definition: getline.c:36
static char gl_buf[1024]
Definition: getline.c:48
static void hist_add(int w)
Definition: getline.c:681
#define DEL
Definition: getline.c:42
static void gl_kill(void)
Definition: getline.c:439
#define TAB
Definition: getline.c:41
#define CTRL_A
Definition: getline.c:28
static void gl_fixup(int change, int cursor)
Definition: getline.c:533
static int(* gl_tab_hook)(char *, int, int *)
Definition: getline.c:81
#define ESC
Definition: keymap.h:140
static char buf[16]
Definition: langinfo.c:50
int ReadCh(void)
Definition: curses.c:1110
void error_message(unsigned int sdelay, const char *fmt,...)
Definition: screen.c:224
void ring_bell(void)
Definition: screen.c:480
char * my_strdup(const char *str)
Definition: string.c:139
void set_xclick_off(void)
Definition: curses.c:703
void clear_message(void)
Definition: screen.c:283
int strwidth(const char *str)
Definition: string.c:1050
void cursoron(void)
Definition: curses.c:712
int my_isprint(int c)
Definition: misc.c:978
char * strunc(const char *message, int len)
Definition: string.c:1076
void CleartoEOLN(void)
Definition: curses.c:458
_Noreturn void giveup(void)
Definition: main.c:1058
int get_arrow_key(int prech)
Definition: curses.c:961
static int offset
Definition: read.c:62
#define my_flush()
Definition: tcurses.h:177
#define my_fputs(str, stream)
Definition: tcurses.h:159
#define my_fputc(ch, stream)
Definition: tcurses.h:158
@ cNone
Definition: tin.h:108
@ cGetline
Definition: tin.h:108
#define KEYMAP_END
Definition: tin.h:1084
#define KEYMAP_RIGHT
Definition: tin.h:1080
#define MIN(a, b)
Definition: tin.h:811
#define KEYMAP_UP
Definition: tin.h:1077
#define KEYMAP_LEFT
Definition: tin.h:1079
#define EOF
Definition: tin.h:2516
#define KEYMAP_PAGE_DOWN
Definition: tin.h:1082
#define KEYMAP_PAGE_UP
Definition: tin.h:1081
#define FreeAndNull(p)
Definition: tin.h:2253
#define KEYMAP_DOWN
Definition: tin.h:1078
#define KEYMAP_INS
Definition: tin.h:1086
#define KEYMAP_DEL
Definition: tin.h:1085
#define KEYMAP_HOME
Definition: tin.h:1083