ReactOS 0.4.15-dev-7961-gdcf9eb0
getline.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 1991, 1992, 1993 by Chris Thewalt (thewalt@ce.berkeley.edu)
3 *
4 * Permission to use, copy, modify, and distribute this software
5 * for any purpose and without fee is hereby granted, provided
6 * that the above copyright notices appear in all copies and that both the
7 * copyright notice and this permission notice appear in supporting
8 * documentation. This software is provided "as is" without express or
9 * implied warranty.
10 *
11 * Thanks to the following people who have provided enhancements and fixes:
12 * Ron Ueberschaer, Christoph Keller, Scott Schwartz, Steven List,
13 * DaviD W. Sanderson, Goran Bostrom, Michael Gleason, Glenn Kasten,
14 * Edin Hodzic, Eric J Bivona, Kai Uwe Rommel, Danny Quah, Ulrich Betzler
15 */
16
17/*
18 * Note: This version has been updated by Mike Gleason <mgleason@ncftp.com>
19 */
20
21static const char copyright[] = "getline: Copyright (C) 1991, 1992, 1993, Chris Thewalt";
22
23# include <windows.h>
24# include <sys/types.h>
25# include <sys/stat.h>
26# include <errno.h>
27# include <conio.h>
28# include <io.h>
29# include <fcntl.h>
30// # define strcasecmp stricmp
31// # define strncasecmp strnicmp
32# define sleep(a) Sleep(a * 1000)
33# ifndef S_ISREG
34# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
35# define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
36# endif
37# ifndef open
38# define open _open
39# define write _write
40# define read _read
41# define close _close
42# define lseek _lseek
43# define stat _stat
44# define lstat _stat
45# define fstat _fstat
46# define dup _dup
47# define utime _utime
48# define utimbuf _utimbuf
49# endif
50# ifndef unlink
51# define unlink remove
52# endif
53# define NO_SIGNALS 1
54# define LOCAL_PATH_DELIM '\\'
55# define LOCAL_PATH_DELIM_STR "\\"
56# define LOCAL_PATH_ALTDELIM '/'
57# define IsLocalPathDelim(c) ((c == LOCAL_PATH_DELIM) || (c == LOCAL_PATH_ALTDELIM))
58# define UNC_PATH_PREFIX "\\\\"
59# define IsUNCPrefixed(s) (IsLocalPathDelim(s[0]) && IsLocalPathDelim(s[1]))
60# define __windows__ 1
61
62/********************* C library headers ********************************/
63
64#include <stdio.h>
65#include <string.h>
66#ifdef HAVE_STRINGS_H
67# include <strings.h>
68#endif
69#include <stdlib.h>
70#include <ctype.h>
71#include <signal.h>
72
73#define _getline_c_ 1
74#include "getline.h"
75
76static int gl_tab(char *buf, int offset, int *loc, size_t bufsize);
77
78/******************** external interface *********************************/
79
83size_t gl_strlen(const char *s) { return strlen(s); }
85int gl_filename_quoting_desired = -1; /* default to unspecified */
86const char *gl_filename_quote_characters = " \t*?<>|;&()[]$`";
89char gl_buf[GL_BUF_SIZE]; /* input buffer */
90
91/******************** internal interface *********************************/
92
93
94static int gl_init_done = -1; /* terminal mode flag */
95static int gl_termw = 80; /* actual terminal width */
96static int gl_termh = 24; /* actual terminal height */
97static int gl_scroll = 27; /* width of EOL scrolling region */
98static int gl_width = 0; /* net size available for input */
99static int gl_extent = 0; /* how far to redraw, 0 means all */
100static int gl_overwrite = 0; /* overwrite mode */
101static int gl_pos = 0, gl_cnt = 0; /* position and size of input */
102static char gl_killbuf[GL_BUF_SIZE]=""; /* killed text */
103static const char *gl_prompt; /* to save the prompt string */
104static char gl_intrc = 0; /* keyboard SIGINT char */
105static char gl_quitc = 0; /* keyboard SIGQUIT char */
106// static char gl_suspc = 0; /* keyboard SIGTSTP char */
107// static char gl_dsuspc = 0; /* delayed SIGTSTP char */
108static int gl_search_mode = 0; /* search mode flag */
109static char **gl_matchlist = 0;
110static char *gl_home_dir = NULL;
111static int gl_vi_preferred = -1;
112static int gl_vi_mode = 0;
113static int gl_result = GL_OK;
114
115static void gl_init(void); /* prepare to edit a line */
116static void gl_cleanup(void); /* to undo gl_init */
117static void gl_char_init(void); /* get ready for no echo input */
118static void gl_char_cleanup(void); /* undo gl_char_init */
119 /* returns printable prompt width */
120
121static void gl_addchar(int c); /* install specified char */
122static void gl_del(int loc, int); /* del, either left (-1) or cur (0) */
123static void gl_error(const char *const buf); /* write error msg and die */
124static void gl_fixup(const char *prompt, int change, int cursor); /* fixup state variables and screen */
125static int gl_getc(void); /* read one char from terminal */
126static int gl_getcx(int); /* read one char from terminal, if available before timeout */
127static void gl_kill(int pos); /* delete to EOL */
128static void gl_newline(void); /* handle \n or \r */
129static void gl_putc(int c); /* write one char to terminal */
130static void gl_puts(const char *const buf); /* write a line to terminal */
131static void gl_redraw(void); /* issue \n and redraw all */
132static void gl_transpose(void); /* transpose two chars */
133static void gl_yank(void); /* yank killed text */
134static void gl_word(int direction); /* move a word */
135static void gl_killword(int direction);
136
137static void hist_init(void); /* initializes hist pointers */
138static char *hist_next(void); /* return ptr to next item */
139static char *hist_prev(void); /* return ptr to prev item */
140static char *hist_save(char *p); /* makes copy of a string, without NL */
141
142static void search_addchar(int c); /* increment search string */
143static void search_term(void); /* reset with current contents */
144static void search_back(int new_search); /* look back for current string */
145static void search_forw(int new_search); /* look forw for current string */
146static void gl_beep(void); /* try to play a system beep sound */
147
148static int gl_do_tab_completion(char *buf, int *loc, size_t bufsize, int tabtab);
149
150/************************ nonportable part *********************************/
151
152#ifdef MSDOS
153#include <bios.h>
154#endif
155
156static void
157gl_char_init(void) /* turn off input echo */
158{
159#ifdef __unix__
160# ifdef HAVE_TERMIOS_H /* Use POSIX */
161 if (tcgetattr(0, &old_termios) == 0) {
162 gl_intrc = old_termios.c_cc[VINTR];
163 gl_quitc = old_termios.c_cc[VQUIT];
164# ifdef VSUSP
165 gl_suspc = old_termios.c_cc[VSUSP];
166# endif
167# ifdef VDSUSP
168 gl_dsuspc = old_termios.c_cc[VDSUSP];
169# endif
170 }
171 new_termios = old_termios;
172 new_termios.c_iflag &= ~(BRKINT|ISTRIP|IXON|IXOFF);
173 new_termios.c_iflag |= (IGNBRK|IGNPAR);
174 new_termios.c_lflag &= ~(ICANON|ISIG|IEXTEN|ECHO);
175 new_termios.c_cc[VMIN] = 1;
176 new_termios.c_cc[VTIME] = 0;
177 tcsetattr(0, TCSANOW, &new_termios);
178# elif defined(TIOCSETN) /* BSD */
179 if (ioctl(0, TIOCGETC, &tch) == 0) {
180 gl_intrc = tch.t_intrc;
181 gl_quitc = tch.t_quitc;
182 }
183 ioctl(0, TIOCGLTC, &ltch);
184 gl_suspc = ltch.t_suspc;
185 gl_dsuspc = ltch.t_dsuspc;
186 ioctl(0, TIOCGETP, &old_tty);
187 new_tty = old_tty;
188 new_tty.sg_flags |= RAW;
189 new_tty.sg_flags &= ~ECHO;
190 ioctl(0, TIOCSETN, &new_tty);
191# else /* SYSV */
192 if (ioctl(0, TCGETA, &old_termio) == 0) {
193 gl_intrc = old_termio.c_cc[VINTR];
194 gl_quitc = old_termio.c_cc[VQUIT];
195 }
196 new_termio = old_termio;
197 new_termio.c_iflag &= ~(BRKINT|ISTRIP|IXON|IXOFF);
198 new_termio.c_iflag |= (IGNBRK|IGNPAR);
199 new_termio.c_lflag &= ~(ICANON|ISIG|ECHO);
200 new_termio.c_cc[VMIN] = 1;
201 new_termio.c_cc[VTIME] = 0;
202 ioctl(0, TCSETA, &new_termio);
203# endif
204#endif /* __unix__ */
205}
206
207static void
208gl_char_cleanup(void) /* undo effects of gl_char_init */
209{
210#ifdef __unix__
211# ifdef HAVE_TERMIOS_H
212 tcsetattr(0, TCSANOW, &old_termios);
213# elif defined(TIOCSETN) /* BSD */
214 ioctl(0, TIOCSETN, &old_tty);
215# else /* SYSV */
216 ioctl(0, TCSETA, &old_termio);
217# endif
218#endif /* __unix__ */
219}
220
221
222
223int
225{
226 return (gl_result);
227} /* gl_get_result */
228
229
230
231
232#if defined(MSDOS) || defined(__windows__)
233
234#define K_UP 0x48
235#define K_DOWN 0x50
236#define K_LEFT 0x4B
237#define K_RIGHT 0x4D
238#define K_DELETE 0x53
239#define K_INSERT 0x52
240#define K_HOME 0x47
241#define K_END 0x4F
242#define K_PGUP 0x49
243#define K_PGDN 0x51
244
245int pc_keymap(int c)
246{
247 switch (c) {
248 case K_UP:
249 case K_PGUP:
250 c = 16; /* up -> ^P */
251 break;
252 case K_DOWN:
253 case K_PGDN:
254 c = 14; /* down -> ^N */
255 break;
256 case K_LEFT:
257 c = 2; /* left -> ^B */
258 break;
259 case K_RIGHT:
260 c = 6; /* right -> ^F */
261 break;
262 case K_END:
263 c = 5; /* end -> ^E */
264 break;
265 case K_HOME:
266 c = 1; /* home -> ^A */
267 break;
268 case K_INSERT:
269 c = 15; /* insert -> ^O */
270 break;
271 case K_DELETE:
272 c = 4; /* del -> ^D */
273 break;
274 default:
275 c = 0; /* make it garbage */
276 }
277 return c;
278}
279#endif /* defined(MSDOS) || defined(__windows__) */
280
281static int
283/* get a character without echoing it to screen */
284{
285 int c;
286#ifdef __unix__
287 char ch;
288#endif
289
290#ifdef __unix__
291 ch = '\0';
292 while ((c = (int) read(0, &ch, 1)) == -1) {
293 if (errno != EINTR)
294 break;
295 }
296 if (c != (-1))
297 c = (int) ch;
298#endif /* __unix__ */
299#ifdef MSDOS
300 c = _bios_keybrd(_NKEYBRD_READ);
301 if ((c & 0377) == 224) {
302 c = pc_keymap((c >> 8) & 0377);
303 } else {
304 c &= 0377;
305 }
306#endif /* MSDOS */
307#ifdef __windows__
308 c = (int) _getch();
309 if ((c == 0) || (c == 0xE0)) {
310 /* Read key code */
311 c = (int) _getch();
312 c = pc_keymap(c);
313 } else if (c == '\r') {
314 /* Note: we only get \r from the console,
315 * and not a matching \n.
316 */
317 c = '\n';
318 }
319#endif
320 return c;
321}
322
323
324
325#ifdef __unix__
326
327static int
328gl_getcx(int tlen)
329/* Get a character without echoing it to screen, timing out
330 * after tlen tenths of a second.
331 */
332{
333 int c, result;
334 char ch;
335 fd_set ss;
336 struct timeval tv;
337
338 for (errno = 0;;) {
339 FD_ZERO(&ss);
340 FD_SET(0, &ss); /* set STDIN_FILENO */
341 tv.tv_sec = tlen / 10;
342 tv.tv_usec = (tlen % 10) * 100000L;
343 result = select(1, &ss, NULL, NULL, &tv);
344 if (result == 1) {
345 /* ready */
346 break;
347 } else if (result == 0) {
349 return (-2);
350 } else if (errno != EINTR) {
351 return (-1);
352 }
353 }
354
355 for (errno = 0;;) {
356 c = (int) read(0, &ch, 1);
357 if (c == 1)
358 return ((int) ch);
359 if (errno != EINTR)
360 break;
361 }
362
363 return (-1);
364} /* gl_getcx */
365
366#endif /* __unix__ */
367
368
369
370
371#ifdef __windows__
372
373static int
374gl_getcx(int tlen)
375{
376 int i, c;
377
378 c = (-2);
379 tlen -= 2; /* Adjust for 200ms overhead */
380 if (tlen < 1)
381 tlen = 1;
382 for (i=0; i<tlen; i++) {
383 if (_kbhit()) {
384 c = (int) _getch();
385 if ((c == 0) || (c == 0xE0)) {
386 /* Read key code */
387 c = (int) _getch();
388 c = pc_keymap(c);
389 break;
390 }
391 }
392 (void) SleepEx((DWORD) (tlen * 100), FALSE);
393 }
394 return (c);
395} /* gl_getcx */
396
397#endif /* __windows__ */
398
399
400
401
402static void
404{
405 char ch = (char) (unsigned char) c;
406
407 write(1, &ch, 1);
408 if (ch == '\n') {
409 ch = '\r';
410 write(1, &ch, 1); /* RAW mode needs '\r', does not hurt */
411 }
412}
413
414/******************** fairly portable part *********************************/
415
416static void
417gl_puts(const char *const buf)
418{
419 int len;
420
421 if (buf) {
422 len = (int) strlen(buf);
423 write(1, buf, len);
424 }
425}
426
427static void
428gl_error(const char *const buf)
429{
430 int len = (int) strlen(buf);
431
432 gl_cleanup();
433 write(2, buf, len);
434 exit(1);
435}
436
437static void
439/* set up variables and terminal */
440{
441 const char *cp;
442 int w;
443
444 if (gl_init_done < 0) { /* -1 only on startup */
445 cp = (const char *) getenv("COLUMNS");
446 if (cp != NULL) {
447 w = atoi(cp);
448 if (w > 20)
449 gl_setwidth(w);
450 }
451 cp = (const char *) getenv("ROWS");
452 if (cp != NULL) {
453 w = atoi(cp);
454 if (w > 10)
456 }
457 hist_init();
458 }
459 if (_isatty(0) == 0 || _isatty(1) == 0)
460 gl_error("\n*** Error: getline(): not interactive, use stdio.\n");
461 gl_char_init();
462 gl_init_done = 1;
463}
464
465static void
467/* undo effects of gl_init, as necessary */
468{
469 if (gl_init_done > 0)
471 gl_init_done = 0;
472#ifdef __windows__
473 Sleep(40);
475#endif
476}
477
478
479static void
481{
482 FILE *fp;
483 char path[256];
484
485 /* If the user has a ~/.inputrc file,
486 * check it to see if it has a line like
487 * "set editing-mode vi". If it does,
488 * we know that the user wants vi
489 * emulation rather than emacs. If the
490 * file doesn't exist, it's no big
491 * deal since we can also check the
492 * $EDITOR environment variable.
493 */
495 if (gl_home_dir == NULL)
496 return;
497
498#ifdef HAVE_SNPRINTF
499 snprintf(path, sizeof(path), "%s/%s", gl_home_dir, ".inputrc");
500#else
501 if (sizeof(path) >= (strlen(gl_home_dir) + strlen("/.inputrc")))
502 return;
503
504 sprintf(path, "%s%s", gl_home_dir, "/.inputrc");
505#endif
506
507 fp = fopen(
508 path,
509#if defined(__windows__) || defined(MSDOS)
510 "rt"
511#else
512 "r"
513#endif
514 );
515
516 if (fp == NULL)
517 return;
518
519 while (fgets(path, sizeof(path) - 1, fp) != NULL) {
520 if ((strstr(path, "editing-mode") != NULL) && (strstr(path, "vi") != NULL)) {
521 gl_vi_preferred = 1;
522 break;
523 }
524 }
525
526 (void) fclose(fp);
527} /* gl_check_inputrc_for_vi */
528
529
530
531void
533{
534 if (w > 250)
535 w = 250;
536 if (w > 20) {
537 gl_termw = w;
538 gl_scroll = w / 3;
539 } else {
540 gl_error("\n*** Error: minimum screen width is 21\n");
541 }
542} /* gl_setwidth */
543
544
545
546void
548{
549 if (w > 10) {
550 gl_termh = w;
551 } else {
552 gl_error("\n*** Error: minimum screen height is 10\n");
553 }
554} /* gl_setheight */
555
556
557
558
559char *
560getline(char *prompt)
561{
562 int c, loc, tmp, lastch;
563 int vi_count, count;
564 int vi_delete;
565 char vi_countbuf[32];
566 char *cp;
567
568#ifdef __unix__
569 int sig;
570#endif
571
572 /* We'll change the result code only if something happens later. */
574
575 /* Even if it appears that "vi" is preferred, we
576 * don't start in gl_vi_mode. They need to hit
577 * ESC to go into vi command mode.
578 */
579 gl_vi_mode = 0;
580 vi_count = 0;
581 vi_delete = 0;
582 if (gl_vi_preferred < 0) {
583 gl_vi_preferred = 0;
584 cp = (char *) getenv("EDITOR");
585 if (cp != NULL)
586 gl_vi_preferred = (strstr(cp, "vi") != NULL);
587 if (gl_vi_preferred == 0)
589 }
590
591 gl_init();
592 gl_prompt = (prompt)? prompt : "";
593 gl_buf[0] = 0;
594 if (gl_in_hook)
597 lastch = 0;
598
599#ifdef __windows__
601#endif
602
603 while ((c = gl_getc()) != (-1)) {
604 gl_extent = 0; /* reset to full extent */
605 /* Note: \n may or may not be considered printable */
606 if ((c != '\t') && ((isprint(c) != 0) || ((c & 0x80) != 0))) {
607 if (gl_vi_mode > 0) {
608 /* "vi" emulation -- far from perfect,
609 * but reasonably functional.
610 */
611vi:
612 for (count = 0; ; ) {
613 if (isdigit(c)) {
614 if (vi_countbuf[sizeof(vi_countbuf) - 2] == '\0')
615 vi_countbuf[strlen(vi_countbuf)] = (char) c;
616 } else if (vi_countbuf[0] != '\0') {
617 vi_count = atoi(vi_countbuf);
618 memset(vi_countbuf, 0, sizeof(vi_countbuf));
619 }
620 switch (c) {
621 case 'b':
622 gl_word(-1);
623 break;
624 case 'w':
625 if (vi_delete) {
626 gl_killword(1);
627 } else {
628 gl_word(1);
629 }
630 break;
631 case 'h': /* left */
632 if (vi_delete) {
633 if (gl_pos > 0) {
634 gl_fixup(gl_prompt, -1, gl_pos-1);
635 gl_del(0, 1);
636 }
637 } else {
638 gl_fixup(gl_prompt, -1, gl_pos-1);
639 }
640 break;
641 case ' ':
642 case 'l': /* right */
643 if (vi_delete) {
644 gl_del(0, 1);
645 } else {
646 gl_fixup(gl_prompt, -1, gl_pos+1);
647 }
648 break;
649 case 'k': /* up */
651 if (gl_in_hook)
654 break;
655 case 'j': /* down */
657 if (gl_in_hook)
660 break;
661 case 'd':
662 if (vi_delete == 1) {
663 gl_kill(0);
664 vi_count = 1;
665 vi_delete = 0;
666 gl_vi_mode = 0;
667 goto vi_break;
668 }
669 vi_delete = 1;
670 goto vi_break;
671 case '^': /* start of line */
672 if (vi_delete) {
673 vi_count = gl_pos;
674 gl_fixup(gl_prompt, -1, 0);
675 for (c = 0; c < vi_count; c++) {
676 if (gl_cnt > 0)
677 gl_del(0, 0);
678 }
679 vi_count = 1;
680 vi_delete = 0;
681 } else {
682 gl_fixup(gl_prompt, -1, 0);
683 }
684 break;
685 case '$': /* end of line */
686 if (vi_delete) {
688 } else {
689 loc = (int) strlen(gl_buf);
690 if (loc > 1)
691 loc--;
692 gl_fixup(gl_prompt, -1, loc);
693 }
694 break;
695 case 'p': /* paste after */
696 gl_fixup(gl_prompt, -1, gl_pos+1);
697 gl_yank();
698 break;
699 case 'P': /* paste before */
700 gl_yank();
701 break;
702 case 'r': /* replace character */
703 gl_buf[gl_pos] = (char) gl_getc();
705 vi_count = 1;
706 break;
707 case 'R':
708 gl_overwrite = 1;
709 gl_vi_mode = 0;
710 break;
711 case 'i':
712 case 'I':
713 gl_overwrite = 0;
714 gl_vi_mode = 0;
715 break;
716 case 'o':
717 case 'O':
718 case 'a':
719 case 'A':
720 gl_overwrite = 0;
721 gl_fixup(gl_prompt, -1, gl_pos+1);
722 gl_vi_mode = 0;
723 break;
724 }
725 count++;
726 if (count >= vi_count)
727 break;
728 }
729 vi_count = 1;
730 vi_delete = 0;
731vi_break:
732 continue;
733 } else if (gl_search_mode) {
735 } else {
736 gl_addchar(c);
737 }
738 } else {
739 if (gl_search_mode) {
740 if (c == '\033' || c == '\016' || c == '\020') {
741 search_term();
742 c = 0; /* ignore the character */
743 } else if (c == '\010' || c == '\177') {
744 search_addchar(-1); /* unwind search string */
745 c = 0;
746 } else if (c != '\022' && c != '\023') {
747 search_term(); /* terminate and handle char */
748 }
749 }
750 switch (c) {
751 case '\n': case '\r': /* newline */
752 gl_newline();
753 gl_cleanup();
754 return gl_buf;
755 case '\001': gl_fixup(gl_prompt, -1, 0); /* ^A */
756 break;
757 case '\002': gl_fixup(gl_prompt, -1, gl_pos-1); /* ^B */
758 break;
759 case '\004': /* ^D */
760 if (gl_cnt == 0) {
761 gl_buf[0] = 0;
762 gl_cleanup();
763 gl_putc('\n');
765 return gl_buf;
766 } else {
767 gl_del(0, 1);
768 }
769 break;
770 case '\005': gl_fixup(gl_prompt, -1, gl_cnt); /* ^E */
771 break;
772 case '\006': gl_fixup(gl_prompt, -1, gl_pos+1); /* ^F */
773 break;
774 case '\010': case '\177': gl_del(-1, 0); /* ^H and DEL */
775 break;
776 case '\t': /* TAB */
777 if (gl_completion_proc) {
778 tmp = gl_pos;
779 gl_buf[sizeof(gl_buf) - 1] = '\0';
780 loc = gl_do_tab_completion(gl_buf, &tmp, sizeof(gl_buf), (lastch == '\t'));
781 gl_buf[sizeof(gl_buf) - 1] = '\0';
782 if (loc >= 0 || tmp != gl_pos)
783 gl_fixup(gl_prompt, /* loc */ -2, tmp);
784 if (lastch == '\t') {
785 c = 0;
786 lastch = 0;
787 }
788 } else if (gl_tab_hook) {
789 tmp = gl_pos;
790 gl_buf[sizeof(gl_buf) - 1] = '\0';
791 loc = gl_tab_hook(gl_buf, (int) gl_strlen(gl_prompt), &tmp, sizeof(gl_buf));
792 gl_buf[sizeof(gl_buf) - 1] = '\0';
793 if (loc >= 0 || tmp != gl_pos)
794 gl_fixup(gl_prompt, loc, tmp);
795 }
796 break;
797 case '\013': gl_kill(gl_pos); /* ^K */
798 break;
799 case '\014': gl_redraw(); /* ^L */
800 break;
801 case '\016': /* ^N */
803 if (gl_in_hook)
806 break;
807 case '\017': gl_overwrite = !gl_overwrite; /* ^O */
808 break;
809 case '\020': /* ^P */
811 if (gl_in_hook)
814 break;
815 case '\022': search_back(1); /* ^R */
816 break;
817 case '\023': search_forw(1); /* ^S */
818 break;
819 case '\024': gl_transpose(); /* ^T */
820 break;
821 case '\025': gl_kill(0); /* ^U */
822 break;
823 case '\027': gl_killword(-1); /* ^W */
824 break;
825 case '\031': gl_yank(); /* ^Y */
826 break;
827 case '\033': /* ansi arrow keys */
828 c = gl_getcx(3);
829 if ((c == '[') || (c == 'O')) {
830ansi:
831 switch(c = gl_getc()) {
832 case 'A': /* up */
834 if (gl_in_hook)
837 break;
838 case 'B': /* down */
840 if (gl_in_hook)
843 break;
844 case 'C':
845 gl_fixup(gl_prompt, -1, gl_pos+1); /* right */
846 break;
847 case 'D':
848 gl_fixup(gl_prompt, -1, gl_pos-1); /* left */
849 break;
850 case '0':
851 case '1':
852 goto ansi;
853 default: gl_beep(); /* who knows */
854 break;
855 }
856 } else if ((gl_vi_preferred == 0) && ((c == 'f') || (c == 'F'))) {
857 gl_word(1);
858 } else if ((gl_vi_preferred == 0) && ((c == 'b') || (c == 'B'))) {
859 gl_word(-1);
860 } else if (c != (-1)) {
861 /* enter vi command mode */
862#if defined(__windows__) || defined(MSDOS)
863 if (gl_vi_preferred == 0) {
864 /* On Windows, ESC acts like a line kill,
865 * so don't use vi mode unless they prefer
866 * vi mode.
867 */
868 gl_kill(0);
869 } else
870#endif
871 if (gl_vi_mode == 0) {
872 gl_vi_mode = 1;
873 vi_count = 1;
874 vi_delete = 0;
875 memset(vi_countbuf, 0, sizeof(vi_countbuf));
876 if (gl_pos > 0)
877 gl_fixup(gl_prompt, -2, gl_pos-1); /* left 1 char */
878 /* Don't bother if the line is empty and we don't
879 * know for sure if the user wants vi mode.
880 */
881 if ((gl_cnt > 0) || (gl_vi_preferred == 1)) {
882 /* We still have to use the char read! */
883 goto vi;
884 }
885 gl_vi_mode = 0;
886 } else {
887 gl_beep();
888 }
889 }
890 break;
891 default: /* check for a terminal signal */
892 if (c > 0) { /* ignore 0 (reset above) */
893 if (c == gl_intrc) {
895 gl_buf[0] = 0;
896 gl_cleanup();
897#ifdef SIGINT
898 raise(SIGINT);
899 gl_init();
900 gl_redraw();
901#endif
902 return gl_buf;
903 }
904
905 if (c == gl_quitc) {
907 gl_buf[0] = 0;
908 gl_cleanup();
909#ifdef SIGQUIT
910 raise(SIGQUIT);
911 gl_init();
912 gl_redraw();
913#endif
914 return gl_buf;
915 }
916
917#ifdef __unix__
918 if (c == gl_suspc || c == gl_dsuspc) {
919#ifdef SIGTSTP
921 gl_buf[0] = 0;
922 gl_cleanup();
923 sig = SIGTSTP;
924 kill(0, sig);
925 gl_init();
926 gl_redraw();
927 return gl_buf;
928#endif
929 }
930#endif /* __unix__ */
931 }
932 if (c > 0)
933 gl_beep();
934 break;
935 }
936 }
937 if (c > 0)
938 lastch = c;
939 }
940 gl_buf[0] = 0;
941 gl_cleanup();
942 return gl_buf;
943}
944
945static void
947
948/* adds the character c to the input buffer at current location */
949{
950 int i;
951
952 if (gl_cnt >= GL_BUF_SIZE - 1)
953 gl_error("\n*** Error: getline(): input buffer overflow\n");
954 if (gl_overwrite == 0 || gl_pos == gl_cnt) {
955 for (i=gl_cnt; i >= gl_pos; i--)
956 gl_buf[i+1] = gl_buf[i];
957 gl_buf[gl_pos] = (char) c;
959 } else {
960 gl_buf[gl_pos] = (char) c;
961 gl_extent = 1;
963 }
964}
965
966static void
968/* adds the kill buffer to the input buffer at current location */
969{
970 int i, len;
971
973 if (len > 0) {
974 if (gl_overwrite == 0) {
975 if (gl_cnt + len >= GL_BUF_SIZE - 1)
976 gl_error("\n*** Error: getline(): input buffer overflow\n");
977 for (i=gl_cnt; i >= gl_pos; i--)
978 gl_buf[i+len] = gl_buf[i];
979 for (i=0; i < len; i++)
982 } else {
983 if (gl_pos + len > gl_cnt) {
984 if (gl_pos + len >= GL_BUF_SIZE - 1)
985 gl_error("\n*** Error: getline(): input buffer overflow\n");
986 gl_buf[gl_pos + len] = 0;
987 }
988 for (i=0; i < len; i++)
990 gl_extent = len;
992 }
993 } else
994 gl_beep();
995}
996
997static void
999/* switch character under cursor and to left of cursor */
1000{
1001 int c;
1002
1003 if (gl_pos > 0 && gl_cnt > gl_pos) {
1004 c = gl_buf[gl_pos-1];
1005 gl_buf[gl_pos-1] = gl_buf[gl_pos];
1006 gl_buf[gl_pos] = (char) c;
1007 gl_extent = 2;
1009 } else
1010 gl_beep();
1011}
1012
1013static void
1015/*
1016 * Cleans up entire line before returning to caller. A \n is appended.
1017 * If line longer than screen, we redraw starting at beginning
1018 */
1019{
1020 int change = gl_cnt;
1021 int len = gl_cnt;
1022 int loc = gl_width - 5; /* shifts line back to start position */
1023
1024 if (gl_cnt >= GL_BUF_SIZE - 1)
1025 gl_error("\n*** Error: getline(): input buffer overflow\n");
1026 if (gl_out_hook) {
1027 change = gl_out_hook(gl_buf);
1028 len = (int) strlen(gl_buf);
1029 }
1030 if (loc > len)
1031 loc = len;
1032 gl_fixup(gl_prompt, change, loc); /* must do this before appending \n */
1033 gl_buf[len] = '\n';
1034 gl_buf[len+1] = '\0';
1035 gl_putc('\n');
1036}
1037
1038static void
1039gl_del(int loc, int killsave)
1040
1041/*
1042 * Delete a character. The loc variable can be:
1043 * -1 : delete character to left of cursor
1044 * 0 : delete character under cursor
1045 */
1046{
1047 int i, j;
1048
1049 if ((loc == -1 && gl_pos > 0) || (loc == 0 && gl_pos < gl_cnt)) {
1050 for (j=0, i=gl_pos+loc; i < gl_cnt; i++) {
1051 if ((j == 0) && (killsave != 0) && (gl_vi_mode != 0)) {
1052 gl_killbuf[0] = gl_buf[i];
1053 gl_killbuf[1] = '\0';
1054 j = 1;
1055 }
1056 gl_buf[i] = gl_buf[i+1];
1057 }
1058 gl_fixup(gl_prompt, gl_pos+loc, gl_pos+loc);
1059 } else
1060 gl_beep();
1061}
1062
1063static void
1065
1066/* delete from pos to the end of line */
1067{
1068 if (pos < gl_cnt) {
1070 gl_buf[pos] = '\0';
1072 } else
1073 gl_beep();
1074}
1075
1076static void
1077gl_killword(int direction)
1078{
1079 int pos = gl_pos;
1080 int startpos = gl_pos;
1081 int tmp;
1082 int i;
1083
1084 if (direction > 0) { /* forward */
1085 while (!isspace(gl_buf[pos]) && pos < gl_cnt)
1086 pos++;
1087 while (isspace(gl_buf[pos]) && pos < gl_cnt)
1088 pos++;
1089 } else { /* backward */
1090 if (pos > 0)
1091 pos--;
1092 while (isspace(gl_buf[pos]) && pos > 0)
1093 pos--;
1094 while (!isspace(gl_buf[pos]) && pos > 0)
1095 pos--;
1096 if (pos < gl_cnt && isspace(gl_buf[pos])) /* move onto word */
1097 pos++;
1098 }
1099 if (pos < startpos) {
1100 tmp = pos;
1101 pos = startpos;
1102 startpos = tmp;
1103 }
1104 memcpy(gl_killbuf, gl_buf + startpos, (size_t) (pos - startpos));
1105 gl_killbuf[pos - startpos] = '\0';
1106 if (isspace(gl_killbuf[pos - startpos - 1]))
1107 gl_killbuf[pos - startpos - 1] = '\0';
1108 gl_fixup(gl_prompt, -1, startpos);
1109 for (i=0, tmp=pos - startpos; i<tmp; i++)
1110 gl_del(0, 0);
1111} /* gl_killword */
1112
1113static void
1114gl_word(int direction)
1115
1116/* move forward or backword one word */
1117{
1118 int pos = gl_pos;
1119
1120 if (direction > 0) { /* forward */
1121 while (!isspace(gl_buf[pos]) && pos < gl_cnt)
1122 pos++;
1123 while (isspace(gl_buf[pos]) && pos < gl_cnt)
1124 pos++;
1125 } else { /* backword */
1126 if (pos > 0)
1127 pos--;
1128 while (isspace(gl_buf[pos]) && pos > 0)
1129 pos--;
1130 while (!isspace(gl_buf[pos]) && pos > 0)
1131 pos--;
1132 if (pos < gl_cnt && isspace(gl_buf[pos])) /* move onto word */
1133 pos++;
1134 }
1135 gl_fixup(gl_prompt, -1, pos);
1136}
1137
1138static void
1140/* emit a newline, reset and redraw prompt and current input line */
1141{
1142 if (gl_init_done > 0) {
1143 gl_putc('\n');
1145 }
1146}
1147
1148static void
1149gl_fixup(const char *prompt, int change, int cursor)
1150
1151
1152/*
1153 * This function is used both for redrawing when input changes or for
1154 * moving within the input line. The parameters are:
1155 * prompt: compared to last_prompt[] for changes;
1156 * change : the index of the start of changes in the input buffer,
1157 * with -1 indicating no changes, -2 indicating we're on
1158 * a new line, redraw everything.
1159 * cursor : the desired location of the cursor after the call.
1160 * A value of GL_BUF_SIZE can be used to indicate the cursor should
1161 * move just past the end of the input line.
1162 */
1163{
1164 static int gl_shift; /* index of first on screen character */
1165 static int off_right; /* true if more text right of screen */
1166 static int off_left; /* true if more text left of screen */
1167 static char last_prompt[80] = "";
1168 int left = 0, right = -1; /* bounds for redraw */
1169 int pad; /* how much to erase at end of line */
1170 int backup; /* how far to backup before fixing */
1171 int new_shift; /* value of shift based on cursor */
1172 int extra; /* adjusts when shift (scroll) happens */
1173 int i;
1174 int new_right = -1; /* alternate right bound, using gl_extent */
1175 int l1, l2;
1176
1177 if (change == -2) { /* reset */
1178 gl_pos = gl_cnt = gl_shift = off_right = off_left = 0;
1179 gl_putc('\r');
1180 gl_puts(prompt);
1181 strcpy(last_prompt, prompt);
1182 change = 0;
1183 gl_width = gl_termw - (int) gl_strlen(prompt);
1184 } else if (strcmp(prompt, last_prompt) != 0) {
1185 l1 = (int) gl_strlen(last_prompt);
1186 l2 = (int) gl_strlen(prompt);
1187 gl_cnt = gl_cnt + l1 - l2;
1188 strcpy(last_prompt, prompt);
1189 gl_putc('\r');
1190 gl_puts(prompt);
1191 gl_pos = gl_shift;
1192 gl_width = gl_termw - l2;
1193 change = 0;
1194 }
1195 pad = (off_right)? gl_width - 1 : gl_cnt - gl_shift; /* old length */
1196 backup = gl_pos - gl_shift;
1197 if (change >= 0) {
1198 gl_cnt = (int) strlen(gl_buf);
1199 if (change > gl_cnt)
1200 change = gl_cnt;
1201 }
1202 if (cursor > gl_cnt) {
1203 if (cursor != GL_BUF_SIZE) { /* GL_BUF_SIZE means end of line */
1205 gl_beep();
1206 }
1207 }
1208 cursor = gl_cnt;
1209 }
1210 if (cursor < 0) {
1211 gl_beep();
1212 cursor = 0;
1213 }
1214 if (off_right || (off_left && cursor < gl_shift + gl_width - gl_scroll / 2))
1215 extra = 2; /* shift the scrolling boundary */
1216 else
1217 extra = 0;
1218 new_shift = cursor + extra + gl_scroll - gl_width;
1219 if (new_shift > 0) {
1220 new_shift /= gl_scroll;
1221 new_shift *= gl_scroll;
1222 } else
1223 new_shift = 0;
1224 if (new_shift != gl_shift) { /* scroll occurs */
1225 gl_shift = new_shift;
1226 off_left = (gl_shift)? 1 : 0;
1227 off_right = (gl_cnt > gl_shift + gl_width - 1)? 1 : 0;
1228 left = gl_shift;
1229 new_right = right = (off_right)? gl_shift + gl_width - 2 : gl_cnt;
1230 } else if (change >= 0) { /* no scroll, but text changed */
1231 if (change < gl_shift + off_left) {
1232 left = gl_shift;
1233 } else {
1234 left = change;
1235 backup = gl_pos - change;
1236 }
1237 off_right = (gl_cnt > gl_shift + gl_width - 1)? 1 : 0;
1238 right = (off_right)? gl_shift + gl_width - 2 : gl_cnt;
1239 new_right = (gl_extent && (right > left + gl_extent))?
1240 left + gl_extent : right;
1241 }
1242 pad -= (off_right)? gl_width - 1 : gl_cnt - gl_shift;
1243 pad = (pad < 0)? 0 : pad;
1244 if (left <= right) { /* clean up screen */
1245 for (i=0; i < backup; i++)
1246 gl_putc('\b');
1247 if (left == gl_shift && off_left) {
1248 gl_putc('$');
1249 left++;
1250 }
1251 for (i=left; i < new_right; i++)
1252 gl_putc(gl_buf[i]);
1253 gl_pos = new_right;
1254 if (off_right && new_right == right) {
1255 gl_putc('$');
1256 gl_pos++;
1257 } else {
1258 for (i=0; i < pad; i++) /* erase remains of prev line */
1259 gl_putc(' ');
1260 gl_pos += pad;
1261 }
1262 }
1263 i = gl_pos - cursor; /* move to final cursor location */
1264 if (i > 0) {
1265 while (i--)
1266 gl_putc('\b');
1267 } else {
1268 for (i=gl_pos; i < cursor; i++)
1269 gl_putc(gl_buf[i]);
1270 }
1271 gl_pos = cursor;
1272}
1273
1274static int
1275gl_tab(char *buf, int offset, int *loc, size_t bufsize)
1276/* default tab handler, acts like tabstops every 8 cols */
1277{
1278 int i, count, len;
1279
1280 len = (int) strlen(buf);
1281 count = 8 - (offset + *loc) % 8;
1282 for (i=len; i >= *loc; i--)
1283 if (i+count < (int) bufsize)
1284 buf[i+count] = buf[i];
1285 for (i=0; i < count; i++)
1286 if (*loc+i < (int) bufsize)
1287 buf[*loc+i] = ' ';
1288 i = *loc;
1289 *loc = i + count;
1290 return i;
1291}
1292
1293/******************* History stuff **************************************/
1294
1295#ifndef HIST_SIZE
1296#define HIST_SIZE 100
1297#endif
1298
1299static int hist_pos = 0, hist_last = 0;
1300static char *hist_buf[HIST_SIZE];
1301static char hist_empty_elem[2] = "";
1302
1303static void
1305{
1306 int i;
1307
1309 for (i=1; i < HIST_SIZE; i++)
1310 hist_buf[i] = (char *)0;
1311}
1312
1313void
1315{
1316 static char *prev = 0;
1317 char *p = buf;
1318 int len;
1319
1320 /* in case we call gl_histadd() before we call getline() */
1321 if (gl_init_done < 0) { /* -1 only on startup */
1322 hist_init();
1323 gl_init_done = 0;
1324 }
1325 while (*p == ' ' || *p == '\t' || *p == '\n')
1326 p++;
1327 if (*p) {
1328 len = (int) strlen(buf);
1329 if (strchr(p, '\n')) /* previously line already has NL stripped */
1330 len--;
1331 if ((prev == 0) || ((int) strlen(prev) != len) ||
1332 strncmp(prev, buf, (size_t) len) != 0) {
1334 prev = hist_buf[hist_last];
1335 hist_last = (hist_last + 1) % HIST_SIZE;
1338 }
1340 }
1341 }
1343}
1344
1345static char *
1347/* loads previous hist entry into input buffer, sticks on first */
1348{
1349 char *p = 0;
1350 int next = (hist_pos - 1 + HIST_SIZE) % HIST_SIZE;
1351
1352 if (hist_buf[hist_pos] != 0 && next != hist_last) {
1353 hist_pos = next;
1354 p = hist_buf[hist_pos];
1355 }
1356 if (p == 0) {
1358 gl_beep();
1359 }
1360 return p;
1361}
1362
1363static char *
1365/* loads next hist entry into input buffer, clears on last */
1366{
1367 char *p = 0;
1368
1369 if (hist_pos != hist_last) {
1370 hist_pos = (hist_pos+1) % HIST_SIZE;
1371 p = hist_buf[hist_pos];
1372 }
1373 if (p == 0) {
1375 gl_beep();
1376 }
1377 return p;
1378}
1379
1380static char *
1382
1383/* makes a copy of the string */
1384{
1385 char *s = 0;
1386 size_t len = strlen(p);
1387 char *nl = strpbrk(p, "\n\r");
1388
1389 if (nl) {
1390 if ((s = (char *) malloc(len)) != 0) {
1391 strncpy(s, p, len-1);
1392 s[len-1] = 0;
1393 }
1394 } else {
1395 if ((s = (char *) malloc(len+1)) != 0) {
1396 strcpy(s, p);
1397 }
1398 }
1399 if (s == 0)
1400 gl_error("\n*** Error: hist_save() failed on malloc\n");
1401 return s;
1402}
1403
1404
1405
1406
1407void
1408gl_histsavefile(const char *const path)
1409{
1410 FILE *fp;
1411 const char *p;
1412 int i, j;
1413
1414 fp = fopen(path,
1415#if defined(__windows__) || defined(MSDOS)
1416 "wt"
1417#else
1418 "w"
1419#endif
1420 );
1421 if (fp != NULL) {
1422 for (i=2; i<HIST_SIZE; i++) {
1423 j = (hist_pos+i) % HIST_SIZE;
1424 p = hist_buf[j];
1425 if ((p == NULL) || (*p == '\0'))
1426 continue;
1427 fprintf(fp, "%s\n", p);
1428 }
1429 fclose(fp);
1430 }
1431} /* gl_histsavefile */
1432
1433
1434
1435
1436void
1437gl_histloadfile(const char *const path)
1438{
1439 FILE *fp;
1440 char line[256];
1441
1442 fp = fopen(path,
1443#if defined(__windows__) || defined(MSDOS)
1444 "rt"
1445#else
1446 "r"
1447#endif
1448 );
1449 if (fp != NULL) {
1450 memset(line, 0, sizeof(line));
1451 while (fgets(line, sizeof(line) - 2, fp) != NULL) {
1453 }
1454 fclose(fp);
1455 }
1456} /* gl_histloadfile */
1457
1458
1459
1460
1461/******************* Search stuff **************************************/
1462
1463static char search_prompt[101]; /* prompt includes search string */
1464static char search_string[100];
1465static int search_pos = 0; /* current location in search_string */
1466static int search_forw_flg = 0; /* search direction flag */
1467static int search_last = 0; /* last match found */
1468
1469static void
1471{
1472 if (c == 0) {
1473 search_pos = 0;
1474 search_string[0] = 0;
1475 search_prompt[0] = '?';
1476 search_prompt[1] = ' ';
1477 search_prompt[2] = 0;
1478 } else if (c > 0) {
1480 search_string[search_pos+1] = (char) 0;
1482 search_prompt[search_pos+1] = (char) '?';
1483 search_prompt[search_pos+2] = (char) ' ';
1484 search_prompt[search_pos+3] = (char) 0;
1485 search_pos++;
1486 } else {
1487 if (search_pos > 0) {
1488 search_pos--;
1490 search_prompt[search_pos] = (char) '?';
1491 search_prompt[search_pos+1] = (char) ' ';
1492 search_prompt[search_pos+2] = (char) 0;
1493 } else {
1494 gl_beep();
1496 }
1497 }
1498}
1499
1500static void
1502{
1503 char *loc;
1504
1506 if (c < 0) {
1507 if (search_pos > 0) {
1509 } else {
1510 gl_buf[0] = 0;
1512 }
1514 }
1515 if ((loc = strstr(gl_buf, search_string)) != 0) {
1516 gl_fixup(search_prompt, 0, (int) (loc - gl_buf));
1517 } else if (search_pos > 0) {
1518 if (search_forw_flg) {
1519 search_forw(0);
1520 } else {
1521 search_back(0);
1522 }
1523 } else {
1524 gl_fixup(search_prompt, 0, 0);
1525 }
1526}
1527
1528static void
1530{
1531 gl_search_mode = 0;
1532 if (gl_buf[0] == 0) /* not found, reset hist list */
1534 if (gl_in_hook)
1537}
1538
1539static void
1540search_back(int new_search)
1541{
1542 int found = 0;
1543 char *p, *loc;
1544
1545 search_forw_flg = 0;
1546 if (gl_search_mode == 0) {
1548 search_update(0);
1549 gl_search_mode = 1;
1550 gl_buf[0] = 0;
1551 gl_fixup(search_prompt, 0, 0);
1552 } else if (search_pos > 0) {
1553 while (!found) {
1554 p = hist_prev();
1555 if (*p == 0) { /* not found, done looking */
1556 gl_buf[0] = 0;
1557 gl_fixup(search_prompt, 0, 0);
1558 found = 1;
1559 } else if ((loc = strstr(p, search_string)) != 0) {
1560 strcpy(gl_buf, p);
1561 gl_fixup(search_prompt, 0, (int) (loc - p));
1562 if (new_search)
1564 found = 1;
1565 }
1566 }
1567
1568 } else {
1569 gl_beep();
1570 }
1571}
1572
1573static void
1574search_forw(int new_search)
1575{
1576 int found = 0;
1577 char *p, *loc;
1578
1579 search_forw_flg = 1;
1580 if (gl_search_mode == 0) {
1582 search_update(0);
1583 gl_search_mode = 1;
1584 gl_buf[0] = 0;
1585 gl_fixup(search_prompt, 0, 0);
1586 } else if (search_pos > 0) {
1587 while (!found) {
1588 p = hist_next();
1589 if (*p == 0) { /* not found, done looking */
1590 gl_buf[0] = 0;
1591 gl_fixup(search_prompt, 0, 0);
1592 found = 1;
1593 } else if ((loc = strstr(p, search_string)) != 0) {
1594 strcpy(gl_buf, p);
1595 gl_fixup(search_prompt, 0, (int) (loc - p));
1596 if (new_search)
1598 found = 1;
1599 }
1600 }
1601 } else {
1602 gl_beep();
1603 }
1604}
1605
1606
1607static void
1609{
1610#ifdef __windows__
1612#else
1613 gl_putc('\007');
1614#endif
1615} /* gl_beep */
1616
1617
1618
1619static int
1620gl_display_matches_sort_proc(const void *a, const void *b)
1621{
1622 return (strcasecmp(
1623 * ((const char **) a),
1624 * ((const char **) b)
1625 ));
1626} /* gl_display_matches_sort_proc */
1627
1628
1629
1630static void
1632{
1633 char buf[256];
1634 char buf2[256];
1635 size_t ilen, imaxlen;
1636 int i, j, k, l;
1637 int glen, allmatch;
1638 int nmax, ncol, colw, nrow;
1639 char *cp1, *cp2, *lim, *itemp;
1640
1641 gl_putc('\n');
1642 if (nused == 0) {
1643 gl_beep();
1644 gl_puts(" (no matches)");
1645 gl_putc('\n');
1646 } else {
1647 qsort(gl_matchlist, (size_t) nused, sizeof(char *), gl_display_matches_sort_proc);
1648
1649 /* Find the greatest amount that matches. */
1650 for (glen = 0; ; glen++) {
1651 allmatch = 1;
1652 for (i=1; i<nused; i++) {
1653 if (gl_matchlist[0][glen] != gl_matchlist[i][glen]) {
1654 allmatch = 0;
1655 break;
1656 }
1657 }
1658 if (allmatch == 0)
1659 break;
1660 }
1661
1662 while (glen > 0) {
1663 if (!isalnum(gl_matchlist[0][glen - 1]))
1664 break;
1665 --glen;
1666 }
1667
1668 nmax = nused;
1669 imaxlen = strlen(gl_matchlist[0]);
1670 for (i=1; i<nused; i++) {
1671 ilen = strlen(gl_matchlist[i]);
1672 if (ilen > imaxlen)
1673 imaxlen = ilen;
1674 }
1675
1676 /* Subtract amount we'll skip for each item. */
1677 imaxlen -= glen;
1678
1679 ncol = (gl_termw - 8) / ((int) imaxlen + 2);
1680 if (ncol < 1)
1681 ncol = 1;
1682
1683 colw = (gl_termw - 8) / ncol;
1684 nrow = nmax / ncol;
1685 if ((nused % ncol) != 0)
1686 nrow++;
1687
1688 if (nrow > (gl_termh - 4)) {
1689 nrow = gl_termh - 4;
1690 nmax = ncol * nrow;
1691 }
1692
1693 for (i=0; i<(int) sizeof(buf2); i++)
1694 buf2[i] = ' ';
1695
1696 for (j=0; j<nrow; j++) {
1697 (void) memcpy(buf, buf2, sizeof(buf));
1698 for (i=0, k=j, l=4; i<ncol; i++, k += nrow, l += colw) {
1699 if (k >= nmax)
1700 continue;
1701 itemp = gl_matchlist[k] + glen;
1702 cp1 = buf + l;
1703 lim = cp1 + (int) strlen(itemp);
1704 if (lim > (buf + sizeof(buf) - 1))
1705 continue;
1706 cp2 = itemp;
1707 while (cp1 < lim)
1708 *cp1++ = *cp2++;
1709 }
1710 for (cp1 = buf + sizeof(buf); *--cp1 == ' '; )
1711 ;
1712 ++cp1;
1713 *cp1 = '\0';
1714 gl_puts(buf);
1715 gl_putc('\n');
1716 }
1717
1718 if (nused > nmax) {
1719 (void) sprintf(buf, " ... %d others omitted ...", (nused - nmax));
1720 gl_puts(buf);
1721 gl_putc('\n');
1722 }
1723 }
1725} /* gl_display_matches */
1726
1727
1728
1729
1730static int
1731gl_do_tab_completion(char *buf, int *loc, size_t bufsize, int tabtab)
1732{
1733 char *startp;
1734 size_t startoff, amt;
1735 int c;
1736 int qmode;
1737 char *qstart;
1738 char *lastspacestart;
1739 char *cp;
1740 int ntoalloc, nused, nprocused, nalloced, i;
1741 char **newgl_matchlist;
1742 char *strtoadd, *strtoadd1;
1743 int addquotes;
1744 size_t llen, mlen, glen;
1745 int allmatch;
1746 char *curposp;
1747 size_t lenaftercursor;
1748 char *matchpfx;
1749 int wasateol;
1750 char ellipsessave[4];
1751
1752 /* Zero out the rest of the buffer, so we can move stuff around
1753 * and know we'll still be NUL-terminated.
1754 */
1755 llen = strlen(buf);
1756 memset(buf + llen, 0, bufsize - llen);
1757 bufsize -= 4; /* leave room for a NUL, space, and two quotes. */
1758 curposp = buf + *loc;
1759 wasateol = (*curposp == '\0');
1760 lenaftercursor = llen - (curposp - buf);
1762 memcpy(ellipsessave, curposp, (size_t) 4);
1763 memcpy(curposp, "... ", (size_t) 4);
1765 memcpy(curposp, ellipsessave, (size_t) 4);
1766 }
1767
1768 qmode = 0;
1769 qstart = NULL;
1770 lastspacestart = NULL;
1771 matchpfx = NULL;
1772
1773 cp = buf;
1774 while (cp < curposp) {
1775 c = (int) *cp++;
1776 if (c == '\0')
1777 break;
1778 if ((c == '"') || (c == '\'')) {
1779 if (qmode == c) {
1780 /* closing quote; end it. */
1781 qstart = NULL;
1782 qmode = 0;
1783 } else if (qmode != 0) {
1784 /* just treat it as a regular char. */
1785 } else {
1786 /* start new quote group. */
1787 qmode = c;
1788 qstart = cp - 1;
1789 }
1790 } else if ((isspace(c)) && (qmode == 0)) {
1791 /* found a non-quoted space. */
1792 lastspacestart = cp - 1;
1793 } else {
1794 /* regular char */
1795 }
1796 }
1797
1798 if (qstart != NULL)
1799 startp = qstart + 1;
1800 else if (lastspacestart != NULL)
1801 startp = lastspacestart + 1;
1802 else
1803 startp = buf;
1804
1805 cp = startp;
1806 mlen = (curposp - cp);
1807
1808 matchpfx = (char *) malloc(mlen + 1);
1809 memcpy(matchpfx, cp, mlen);
1810 matchpfx[mlen] = '\0';
1811
1812#define GL_COMPLETE_VECTOR_BLOCK_SIZE 64
1813
1814 nused = 0;
1816 newgl_matchlist = (char **) malloc((size_t) (sizeof(char *) * (ntoalloc + 1)));
1817 if (newgl_matchlist == NULL) {
1818 free(matchpfx);
1819 gl_beep();
1820 return 0;
1821 }
1822 gl_matchlist = newgl_matchlist;
1823 nalloced = ntoalloc;
1824 for (i=nused; i<=nalloced; i++)
1825 gl_matchlist[i] = NULL;
1826
1828 for (nprocused = 0;; nprocused++) {
1829 if (nused == nalloced) {
1831 newgl_matchlist = (char **) realloc((char *) gl_matchlist, (size_t) (sizeof(char *) * (ntoalloc + 1)));
1832 if (newgl_matchlist == NULL) {
1833 /* not enough memory to expand list -- abort */
1834 for (i=0; i<nused; i++)
1838 gl_beep();
1839 free(matchpfx);
1840 return 0;
1841 }
1842 gl_matchlist = newgl_matchlist;
1843 nalloced = ntoalloc;
1844 for (i=nused; i<=nalloced; i++)
1845 gl_matchlist[i] = NULL;
1846 }
1847 cp = gl_completion_proc(matchpfx, nprocused);
1848 if (cp == NULL)
1849 break;
1850 if ((cp[0] == '.') && ((cp[1] == '\0') || ((cp[1] == '.') && (cp[2] == '\0'))))
1851 continue; /* Skip . and .. */
1852 gl_matchlist[nused++] = cp;
1853 }
1854
1857 gl_puts(" ");
1858 }
1859
1860 /* We now have an array strings, whose last element is NULL. */
1861 strtoadd = NULL;
1862 strtoadd1 = NULL;
1863 amt = 0;
1864
1866
1867 if (nused == 1) {
1868 /* Exactly one match. */
1869 strtoadd = gl_matchlist[0];
1870 } else if (tabtab != 0) {
1871 /* TAB-TAB: print all matches */
1872 gl_display_matches(nused);
1873 } else if ((nused > 1) && (mlen > 0)) {
1874 /* Find the greatest amount that matches. */
1875 for (glen = strlen(matchpfx); ; glen++) {
1876 allmatch = 1;
1877 for (i=1; i<nused; i++) {
1878 if (gl_matchlist[0][glen] != gl_matchlist[i][glen]) {
1879 allmatch = 0;
1880 break;
1881 }
1882 }
1883 if (allmatch == 0)
1884 break;
1885 }
1886 strtoadd1 = (char *) malloc(glen + 1);
1887 if (strtoadd1 != NULL) {
1888 memcpy(strtoadd1, gl_matchlist[0], glen);
1889 strtoadd1[glen] = '\0';
1890 strtoadd = strtoadd1;
1891 }
1892 }
1893
1894 if (strtoadd != NULL) {
1895 if ((qmode == 0) && (addquotes != 0)) {
1896 if (strpbrk(strtoadd, gl_filename_quote_characters) != NULL) {
1897 qmode = (strchr(strtoadd, '"') == NULL) ? '"' : '\'';
1898 memmove(curposp + 1, curposp, lenaftercursor + 1 /* NUL */);
1899 curposp++;
1900 *startp++ = (char) qmode;
1901 }
1902 }
1903 startoff = (size_t) (startp - buf);
1904 amt = strlen(strtoadd);
1905 if ((amt + startoff + lenaftercursor) >= bufsize)
1906 amt = bufsize - (amt + startoff + lenaftercursor);
1907 memmove(curposp + amt - mlen, curposp, lenaftercursor + 1 /* NUL */);
1908 curposp += amt - mlen;
1909 memcpy(startp, strtoadd, amt);
1910 if (nused == 1) {
1911 /* Exact match. */
1912 if (qmode != 0) {
1913 /* Finish the quoting. */
1914 memmove(curposp + 1, curposp, lenaftercursor + 1 /* NUL */);
1915 curposp++;
1916 buf[amt + startoff] = (char) qmode;
1917 amt++;
1918 }
1919 memmove(curposp + 1, curposp, lenaftercursor + 1 /* NUL */);
1920 curposp++;
1921 buf[amt + startoff] = (char) gl_completion_exact_match_extra_char;
1922 amt++;
1923 } else if ((!wasateol) && (!isspace(*curposp))) {
1924 /* Not a full match, but insert a
1925 * space for better readability.
1926 */
1927 memmove(curposp + 1, curposp, lenaftercursor + 1 /* NUL */);
1928 curposp++;
1929 buf[amt + startoff] = ' ';
1930 }
1931 *loc = (int) (startoff + amt);
1932
1933 if (strtoadd1 != NULL)
1934 free(strtoadd1);
1935 }
1936
1937 /* Don't need this any more. */
1938 for (i=0; i<nused; i++)
1942 free(matchpfx);
1943
1944 return 0;
1945} /* gl_do_tab_completion */
1946
1947
1948
1949
1950void
1952{
1953 if (proc == NULL)
1954 proc = gl_local_filename_completion_proc; /* default proc */
1956} /* gl_tab_completion */
1957
1958
1959
1960
1961#ifndef _StrFindLocalPathDelim
1962static char *
1963_StrRFindLocalPathDelim(const char *src) /* TODO: optimize */
1964{
1965 const char *last;
1966 int c;
1967
1968 last = NULL;
1969 for (;;) {
1970 c = *src++;
1971 if (c == '\0')
1972 break;
1973 if (IsLocalPathDelim(c))
1974 last = src - 1;
1975 }
1976
1977 return ((char *) last);
1978} /* StrRFindLocalPathDelim */
1979#endif /* Windows */
1980
1981
1982
1983
1984void
1985gl_set_home_dir(const char *homedir)
1986{
1987 size_t len;
1988#ifdef __windows__
1989 const char *homedrive, *homepath;
1990 char wdir[64];
1991#else
1992 struct passwd *pw;
1993 char *cp;
1994#endif
1995
1996 if (gl_home_dir != NULL) {
1998 gl_home_dir = NULL;
1999 }
2000
2001 if (homedir == NULL) {
2002#ifdef __windows__
2003 homedrive = getenv("HOMEDRIVE");
2004 homepath = getenv("HOMEPATH");
2005 if ((homedrive != NULL) && (homepath != NULL)) {
2006 len = strlen(homedrive) + strlen(homepath) + 1;
2007 gl_home_dir = (char *) malloc(len);
2008 if (gl_home_dir != NULL) {
2009 strcpy(gl_home_dir, homedrive);
2010 strcat(gl_home_dir, homepath);
2011 return;
2012 }
2013 }
2014
2015 wdir[0] = '\0';
2016 if (GetWindowsDirectory(wdir, sizeof(wdir) - 1) < 1)
2017 (void) strncpy(wdir, ".", sizeof(wdir));
2018 else if (wdir[1] == ':') {
2019 wdir[2] = '\\';
2020 wdir[3] = '\0';
2021 }
2022 homedir = wdir;
2023#else
2024 cp = (char *) getlogin();
2025 if (cp == NULL) {
2026 cp = (char *) getenv("LOGNAME");
2027 if (cp == NULL)
2028 cp = (char *) getenv("USER");
2029 }
2030 pw = NULL;
2031 if (cp != NULL)
2032 pw = getpwnam(cp);
2033 if (pw == NULL)
2034 pw = getpwuid(getuid());
2035 if (pw == NULL)
2036 return; /* hell with it */
2037 homedir = pw->pw_dir;
2038#endif
2039 }
2040
2041 len = strlen(homedir) + /* NUL */ 1;
2042 gl_home_dir = (char *) malloc(len);
2043 if (gl_home_dir != NULL) {
2044 memcpy(gl_home_dir, homedir, len);
2045 }
2046} /* gl_set_home_dir */
2047
2048
2049
2050
2051char *gl_getpass(const char *const prompt, char *const pass, int dsize)
2052{
2053#ifdef __unix__
2054 char *cp;
2055 int c;
2056
2057 memset(pass, 0, (size_t) sizeof(dsize));
2058 dsize--;
2059 gl_init();
2060
2061 /* Display the prompt first. */
2062 if ((prompt != NULL) && (prompt[0] != '\0'))
2063 gl_puts(prompt);
2064
2065 cp = pass;
2066 while ((c = gl_getc()) != (-1)) {
2067 if ((c == '\r') || (c == '\n'))
2068 break;
2069 if ((c == '\010') || (c == '\177')) {
2070 /* ^H and DEL */
2071 if (cp > pass) {
2072 *--cp = '\0';
2073 gl_putc('\010');
2074 gl_putc(' ');
2075 gl_putc('\010');
2076 }
2077 } else if (cp < (pass + dsize)) {
2078 gl_putc('*');
2079 *cp++ = c;
2080 }
2081 }
2082 *cp = '\0';
2083 gl_putc('\n');
2084 gl_cleanup();
2085 return (pass);
2086#else
2087#ifdef __windows__
2088 char *cp;
2089 int c;
2090
2092 ZeroMemory(pass, (DWORD) sizeof(dsize));
2093 dsize--;
2094
2095 if ((prompt != NULL) && (prompt[0] != '\0'))
2096 _cputs(prompt);
2097
2098 for (cp = pass;;) {
2099 c = (int) _getch();
2100 if ((c == '\r') || (c == '\n'))
2101 break;
2102 if ((c == '\010') || (c == '\177')) {
2103 /* ^H and DEL */
2104 if (cp > pass) {
2105 *--cp = '\0';
2106 _putch('\010');
2107 _putch(' ');
2108 _putch('\010');
2109 }
2110 } else if (cp < (pass + dsize)) {
2111 _putch('*');
2112 *cp++ = c;
2113 }
2114 }
2115 _putch('\r');
2116 _putch('\n');
2117 Sleep(40);
2119
2120 *cp = '\0';
2121 return (pass);
2122#endif /* __windows__ */
2123#endif /* ! __unix__ */
2124} /* gl_getpass */
2125
2126
2127
2128
2129#ifdef __unix__
2130
2131char *
2133{
2134 static DIR *dir = NULL;
2135 static int filepfxoffset;
2136 static size_t filepfxlen;
2137
2138 const char *filepfx;
2139 struct dirent *dent;
2140 char *cp;
2141 const char *dirtoopen, *name;
2142 char *dirtoopen1;
2143 size_t len, len2;
2144 struct stat st;
2145
2146 if (idx == 0) {
2147 if (dir != NULL) {
2148 /* shouldn't get here! */
2149 closedir(dir);
2150 dir = NULL;
2151 }
2152 }
2153
2154 if (dir == NULL) {
2155 dirtoopen1 = NULL;
2157 if (cp == start) {
2158 dirtoopen = LOCAL_PATH_DELIM_STR; /* root dir */
2159 filepfxoffset = 1;
2160 } else if (cp == NULL) {
2161 dirtoopen = ".";
2162 filepfxoffset = 0;
2163 } else {
2164 len = strlen(start) + 1;
2165 dirtoopen1 = (char *) malloc(len);
2166 if (dirtoopen1 == NULL)
2167 return NULL;
2168 memcpy(dirtoopen1, start, len);
2169 len = (cp - start);
2170 dirtoopen1[len] = '\0';
2171 dirtoopen = dirtoopen1;
2172 filepfxoffset = (int) ((cp + 1) - start);
2173 }
2174
2175 if (strcmp(dirtoopen, "~") == 0) {
2176 if (gl_home_dir == NULL)
2178 if (gl_home_dir == NULL)
2179 return (NULL);
2180 dirtoopen = gl_home_dir;
2181 }
2182
2183 dir = opendir(dirtoopen);
2184 if (dirtoopen1 != NULL)
2185 free(dirtoopen1);
2186
2187 filepfx = start + filepfxoffset;
2188 filepfxlen = strlen(filepfx);
2189 }
2190
2191 if (dir != NULL) {
2192 /* assumes "start" is same for each iteration. */
2193 filepfx = start + filepfxoffset;
2194
2195 for (;;) {
2196 dent = readdir(dir);
2197 if (dent == NULL) {
2198 /* no more items */
2199 closedir(dir);
2200 dir = NULL;
2201
2202 if (idx == 1) {
2203 /* There was exactly one match.
2204 * In this special case, we
2205 * want to append a / instead
2206 * of a space.
2207 */
2208 cp = gl_matchlist[0];
2209 if ((cp[0] == '~') && ((cp[1] == '\0') || (IsLocalPathDelim(cp[1])))) {
2210 len = strlen(cp + 1) + /* NUL */ 1;
2211 len2 = strlen(gl_home_dir);
2212 if (IsLocalPathDelim(gl_home_dir[len2 - 1]))
2213 len2--;
2214 cp = (char *) realloc(gl_matchlist[0], len + len2);
2215 if (cp == NULL) {
2216 cp = gl_matchlist[0];
2217 } else {
2218 memmove(cp + len2, cp + 1, len);
2219 memcpy(cp, gl_home_dir, len2);
2220 gl_matchlist[0] = cp;
2221 }
2222 }
2223 if ((lstat(cp, &st) == 0) && (S_ISDIR(st.st_mode)))
2225 }
2226 return NULL;
2227 }
2228
2229 name = dent->d_name;
2230 if ((name[0] == '.') && ((name[1] == '\0') || ((name[1] == '.') && (name[2] == '\0'))))
2231 continue; /* Skip . and .. */
2232
2233 if ((filepfxlen == 0) || (strncmp(name, filepfx, filepfxlen) == 0)) {
2234 /* match */
2235 len = strlen(name);
2236 cp = (char *) malloc(filepfxoffset + len + 1 /* spare */ + 1 /* NUL */);
2237 *cp = '\0';
2238 if (filepfxoffset > 0)
2239 memcpy(cp, start, (size_t) filepfxoffset);
2240 memcpy(cp + filepfxoffset, name, len + 1);
2241 return (cp);
2242 }
2243 }
2244 }
2245
2246 return NULL;
2247} /* gl_local_filename_completion_proc */
2248
2249#endif /* __unix__ */
2250
2251
2252
2253
2254
2255#ifdef __windows__
2256
2257char *
2259{
2260 static HANDLE searchHandle = NULL;
2261 static int filepfxoffset;
2262 static size_t filepfxlen;
2263
2264 WIN32_FIND_DATA ffd;
2265 DWORD dwErr;
2266 char *cp, *c2, ch;
2267 const char *filepfx;
2268 const char *dirtoopen, *name;
2269 char *dirtoopen1, *dirtoopen2;
2270 size_t len, len2;
2271
2272 if (idx == 0) {
2273 if (searchHandle != NULL) {
2274 /* shouldn't get here! */
2275 FindClose(searchHandle);
2276 searchHandle = NULL;
2277 }
2278 }
2279
2280
2281 if (searchHandle == NULL) {
2282 dirtoopen1 = NULL;
2283 dirtoopen2 = NULL;
2285 if (cp == start) {
2286 dirtoopen = LOCAL_PATH_DELIM_STR; /* root dir */
2287 filepfxoffset = 1;
2288 } else if (cp == NULL) {
2289 dirtoopen = ".";
2290 filepfxoffset = 0;
2291 } else {
2292 len = strlen(start) + 1;
2293 dirtoopen1 = (char *) malloc(len);
2294 if (dirtoopen1 == NULL)
2295 return NULL;
2296 memcpy(dirtoopen1, start, len);
2297 len = (cp - start);
2298 dirtoopen1[len] = '\0';
2299 dirtoopen = dirtoopen1;
2300 filepfxoffset = (int) ((cp + 1) - start);
2301 }
2302
2303 if (strcmp(dirtoopen, "~") == 0) {
2304 if (gl_home_dir == NULL)
2306 if (gl_home_dir == NULL)
2307 return (NULL);
2308 dirtoopen = gl_home_dir;
2309 }
2310
2311 len = strlen(dirtoopen);
2312 dirtoopen2 = (char *) malloc(len + 8);
2313 if (dirtoopen2 == NULL) {
2314 if (dirtoopen1 != NULL)
2315 free(dirtoopen1);
2316 return NULL;
2317 }
2318
2319 memcpy(dirtoopen2, dirtoopen, len + 1);
2320 if (dirtoopen2[len - 1] == LOCAL_PATH_DELIM)
2321 memcpy(dirtoopen2 + len, "*.*", (size_t) 4);
2322 else
2323 memcpy(dirtoopen2 + len, "\\*.*", (size_t) 5);
2324
2325 /* "Open" the directory. */
2326 memset(&ffd, 0, sizeof(ffd));
2327 searchHandle = FindFirstFile(dirtoopen2, &ffd);
2328
2329 free(dirtoopen2);
2330 if (dirtoopen1 != NULL)
2331 free(dirtoopen1);
2332
2333 if (searchHandle == INVALID_HANDLE_VALUE) {
2334 return NULL;
2335 }
2336
2337 filepfx = start + filepfxoffset;
2338 filepfxlen = strlen(filepfx);
2339 } else {
2340 /* assumes "start" is same for each iteration. */
2341 filepfx = start + filepfxoffset;
2342 goto next;
2343 }
2344
2345 for (;;) {
2346
2347 name = ffd.cFileName;
2348 if ((name[0] == '.') && ((name[1] == '\0') || ((name[1] == '.') && (name[2] == '\0'))))
2349 goto next; /* Skip . and .. */
2350
2351 if ((filepfxlen == 0) || (_strnicmp(name, filepfx, filepfxlen) == 0)) {
2352 /* match */
2353 len = strlen(name);
2354 cp = (char *) malloc(filepfxoffset + len + 4 /* spare */ + 1 /* NUL */);
2355 *cp = '\0';
2356 if (filepfxoffset > 0)
2357 memcpy(cp, start, filepfxoffset);
2358 memcpy(cp + filepfxoffset, name, len + 1);
2359 if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
2360 /* Embed file type with name. */
2361 c2 = cp + filepfxoffset + len + 1;
2362 *c2++ = '\0';
2363 *c2++ = 'd';
2364 *c2 = '\0';
2365 } else {
2366 c2 = cp + filepfxoffset + len + 1;
2367 *c2++ = '\0';
2368 *c2++ = '-';
2369 *c2 = '\0';
2370 }
2371 return (cp);
2372 }
2373
2374next:
2375 if (!FindNextFile(searchHandle, &ffd)) {
2376 dwErr = GetLastError();
2377 if (dwErr != ERROR_NO_MORE_FILES) {
2378 FindClose(searchHandle);
2379 searchHandle = NULL;
2380 return NULL;
2381 }
2382
2383 /* no more items */
2384 FindClose(searchHandle);
2385 searchHandle = NULL;
2386
2387 if (idx == 1) {
2388 /* There was exactly one match.
2389 * In this special case, we
2390 * want to append a \ instead
2391 * of a space.
2392 */
2393 cp = gl_matchlist[0];
2394 ch = (char) cp[strlen(cp) + 2];
2395 if (ch == (char) 'd')
2397
2398 if ((cp[0] == '~') && ((cp[1] == '\0') || (IsLocalPathDelim(cp[1])))) {
2399 len = strlen(cp + 1) + /* NUL */ 1;
2400 len2 = strlen(gl_home_dir);
2401 if (IsLocalPathDelim(gl_home_dir[len2 - 1]))
2402 len2--;
2403 cp = (char *) realloc(gl_matchlist[0], len + len2 + 4);
2404 if (cp == NULL) {
2405 cp = gl_matchlist[0];
2406 } else {
2407 memmove(cp + len2, cp + 1, len);
2408 memcpy(cp, gl_home_dir, len2);
2409 c2 = cp + len + len2;
2410 *c2++ = '\0';
2411 *c2++ = ch;
2412 *c2 = '\0';
2413 gl_matchlist[0] = cp;
2414 }
2415 }
2416 }
2417 break;
2418 }
2419 }
2420 return (NULL);
2421} /* gl_local_filename_completion_proc */
2422
2423#endif /* __windows__ */
#define isspace(c)
Definition: acclib.h:69
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define EINTR
Definition: acclib.h:80
#define isdigit(c)
Definition: acclib.h:68
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define isprint(c)
Definition: acclib.h:73
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * strpbrk(const char *String, const char *Delimiters)
Definition: utclib.c:302
unsigned int dir
Definition: maze.c:112
static long backup()
Definition: maze.c:403
uid_t getuid()
Definition: uid.c:27
char * getlogin(void)
DWORD dwErr
Definition: service.c:36
BOOL WINAPI FlushConsoleInputBuffer(IN HANDLE hConsoleInput)
Definition: console.c:220
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
r l[0]
Definition: byte_order.h:168
int __cdecl raise(int _SigNum)
Definition: signal.c:71
#define SIGINT
Definition: signal.h:23
#define SIGQUIT
Definition: signal.h:24
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned char
Definition: typeof.h:29
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
#define ETIMEDOUT
Definition: errno.h:121
__kernel_size_t size_t
Definition: linux.h:237
#define strcasecmp
Definition: fake.h:9
unsigned long DWORD
Definition: ntddk_ex.h:95
#define RAW(x)
Definition: genincdata.c:42
int gl_ellipses_during_completion
Definition: getline.c:87
static int gl_pos
Definition: getline.c:101
static char search_string[100]
Definition: getline.c:1464
#define K_LEFT
Definition: getline.c:236
static char * hist_prev(void)
Definition: getline.c:1346
#define LOCAL_PATH_DELIM
Definition: getline.c:54
void gl_tab_completion(gl_tab_completion_proc proc)
Definition: getline.c:1951
static int search_last
Definition: getline.c:1467
static int gl_getc(void)
Definition: getline.c:282
static int gl_width
Definition: getline.c:98
static void gl_check_inputrc_for_vi(void)
Definition: getline.c:480
static int gl_result
Definition: getline.c:113
static const char copyright[]
Definition: getline.c:21
int gl_completion_exact_match_extra_char
Definition: getline.c:88
static int gl_search_mode
Definition: getline.c:108
gl_tab_completion_proc gl_completion_proc
Definition: getline.c:84
static void gl_error(const char *const buf)
Definition: getline.c:428
static char gl_intrc
Definition: getline.c:104
static int gl_scroll
Definition: getline.c:97
static int gl_tab(char *buf, int offset, int *loc, size_t bufsize)
Definition: getline.c:1275
static char gl_killbuf[GL_BUF_SIZE]
Definition: getline.c:102
static void search_forw(int new_search)
Definition: getline.c:1574
#define K_HOME
Definition: getline.c:240
void gl_setwidth(int w)
Definition: getline.c:532
static char * hist_next(void)
Definition: getline.c:1364
static int gl_termw
Definition: getline.c:95
#define K_RIGHT
Definition: getline.c:237
static void search_back(int new_search)
Definition: getline.c:1540
static char hist_empty_elem[2]
Definition: getline.c:1301
static void gl_yank(void)
Definition: getline.c:967
static int gl_init_done
Definition: getline.c:94
static int hist_pos
Definition: getline.c:1299
int pc_keymap(int c)
Definition: getline.c:245
static int gl_do_tab_completion(char *buf, int *loc, size_t bufsize, int tabtab)
Definition: getline.c:1731
static char ** gl_matchlist
Definition: getline.c:109
static void gl_addchar(int c)
Definition: getline.c:946
static void gl_newline(void)
Definition: getline.c:1014
void gl_histsavefile(const char *const path)
Definition: getline.c:1408
static void gl_del(int loc, int)
Definition: getline.c:1039
static int search_pos
Definition: getline.c:1465
static void gl_init(void)
Definition: getline.c:438
#define K_PGDN
Definition: getline.c:243
#define read
Definition: getline.c:40
static void gl_puts(const char *const buf)
Definition: getline.c:417
#define S_ISDIR(m)
Definition: getline.c:35
void gl_histadd(char *buf)
Definition: getline.c:1314
static int search_forw_flg
Definition: getline.c:1466
static int gl_getcx(int)
Definition: getline.c:374
static int gl_extent
Definition: getline.c:99
#define HIST_SIZE
Definition: getline.c:1296
char * gl_getpass(const char *const prompt, char *const pass, int dsize)
Definition: getline.c:2051
int gl_get_result(void)
Definition: getline.c:224
#define GL_COMPLETE_VECTOR_BLOCK_SIZE
static void gl_char_cleanup(void)
Definition: getline.c:208
static void gl_word(int direction)
Definition: getline.c:1114
#define K_DOWN
Definition: getline.c:235
static void gl_char_init(void)
Definition: getline.c:157
static int gl_overwrite
Definition: getline.c:100
static void gl_cleanup(void)
Definition: getline.c:466
static int gl_vi_mode
Definition: getline.c:112
static char * _StrRFindLocalPathDelim(const char *src)
Definition: getline.c:1963
static void gl_fixup(const char *prompt, int change, int cursor)
Definition: getline.c:1149
char * gl_local_filename_completion_proc(const char *start, int idx)
Definition: getline.c:2258
gl_in_hook_proc gl_in_hook
Definition: getline.c:80
static char * hist_buf[HIST_SIZE]
Definition: getline.c:1300
static void gl_display_matches(int nused)
Definition: getline.c:1631
static void search_addchar(int c)
Definition: getline.c:1501
static void gl_killword(int direction)
Definition: getline.c:1077
const char * gl_filename_quote_characters
Definition: getline.c:86
#define K_DELETE
Definition: getline.c:238
static const char * gl_prompt
Definition: getline.c:103
static void gl_beep(void)
Definition: getline.c:1608
#define __windows__
Definition: getline.c:60
#define K_END
Definition: getline.c:241
static char search_prompt[101]
Definition: getline.c:1463
static int gl_cnt
Definition: getline.c:101
void gl_set_home_dir(const char *homedir)
Definition: getline.c:1985
#define write
Definition: getline.c:39
void gl_setheight(int w)
Definition: getline.c:547
gl_out_hook_proc gl_out_hook
Definition: getline.c:81
#define K_INSERT
Definition: getline.c:239
static int gl_vi_preferred
Definition: getline.c:111
static void search_update(int c)
Definition: getline.c:1470
#define IsLocalPathDelim(c)
Definition: getline.c:57
gl_tab_hook_proc gl_tab_hook
Definition: getline.c:82
char gl_buf[GL_BUF_SIZE]
Definition: getline.c:89
static int hist_last
Definition: getline.c:1299
static void gl_kill(int pos)
Definition: getline.c:1064
static void search_term(void)
Definition: getline.c:1529
int gl_filename_quoting_desired
Definition: getline.c:85
static char * hist_save(char *p)
Definition: getline.c:1381
static char gl_quitc
Definition: getline.c:105
static void gl_redraw(void)
Definition: getline.c:1139
static void gl_transpose(void)
Definition: getline.c:998
#define K_PGUP
Definition: getline.c:242
#define lstat
Definition: getline.c:44
#define K_UP
Definition: getline.c:234
static int gl_display_matches_sort_proc(const void *a, const void *b)
Definition: getline.c:1620
static char * gl_home_dir
Definition: getline.c:110
void gl_histloadfile(const char *const path)
Definition: getline.c:1437
static int gl_termh
Definition: getline.c:96
static void hist_init(void)
Definition: getline.c:1304
#define LOCAL_PATH_DELIM_STR
Definition: getline.c:55
static void gl_putc(int c)
Definition: getline.c:403
int(* gl_in_hook_proc)(char *)
Definition: getline.h:16
int(* gl_tab_hook_proc)(char *, int, int *, size_t)
Definition: getline.h:18
gl_strlen_proc gl_strlen
#define GL_OK
Definition: getline.h:11
#define GL_INTERRUPT
Definition: getline.h:13
char *(* gl_tab_completion_proc)(const char *, int)
Definition: getline.h:20
#define GL_BUF_SIZE
Definition: getline.h:8
#define GL_EOF
Definition: getline.h:12
int(* gl_out_hook_proc)(char *)
Definition: getline.h:17
GLuint start
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLdouble GLdouble right
Definition: glext.h:10859
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLint left
Definition: glext.h:7726
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLuint64EXT * result
Definition: glext.h:11304
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define ss
Definition: i386-dis.c:441
const char cursor[]
Definition: icontest.c:13
@ extra
Definition: id3.c:95
_Check_return_ _CRTIMP int __cdecl isalnum(_In_ int _C)
int __cdecl closedir(DIR *)
DIR *__cdecl opendir(const char *)
struct dirent *__cdecl readdir(DIR *)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
#define c
Definition: ke_i.h:80
POINT cp
Definition: magnifier.c:59
struct msdos_volume_info vi
Definition: mkdosfs.c:440
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static UINT UINT last
Definition: font.c:45
int __cdecl _cputs(const char *)
Definition: cputs.c:8
int k
Definition: mpi.c:3369
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
static HANDLE proc()
Definition: pdb.c:34
static unsigned __int64 next
Definition: rand_nt.c:6
#define getline
Definition: schily.h:567
_CRTIMP int __cdecl _putch(_In_ int _Ch)
_CRTIMP int __cdecl _kbhit(void)
Definition: kbhit.c:21
#define errno
Definition: errno.h:18
_Check_return_ _CRTIMP int __cdecl _isatty(_In_ int _FileHandle)
#define exit(n)
Definition: config.h:202
#define memset(x, y, z)
Definition: compat.h:39
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
int _getch()
Definition: getch.c:16
Definition: dirent.h:40
Definition: fatfs.h:198
char * d_name
Definition: dirent.h:29
Definition: winsock.h:66
Definition: parser.c:49
Definition: name.c:39
Definition: stat.h:55
DWORD WINAPI SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:802
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define ECHO
Definition: telnetd.h:34
pass
Definition: typegen.h:25
#define GetWindowsDirectory
Definition: winbase.h:3857
#define ZeroMemory
Definition: winbase.h:1712
#define STD_INPUT_HANDLE
Definition: winbase.h:267
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FindNextFile
Definition: winbase.h:3788
#define FindFirstFile
Definition: winbase.h:3782
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89
#define ioctl
Definition: wintirpc.h:60
#define snprintf
Definition: wintirpc.h:48
BOOL WINAPI MessageBeep(_In_ UINT uType)
#define MB_OK
Definition: winuser.h:790