1/* $Header: /src/pub/tcsh/sh.file.c,v 3.28 2005/01/05 16:06:13 christos Exp $ */ |
2/* 3 * sh.file.c: File completion for csh. This file is not used in tcsh. 4 */ 5/*- 6 * Copyright (c) 1980, 1991 The Regents of the University of California. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without --- 18 unchanged lines hidden (view full) --- 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33#include "sh.h" 34#include "ed.h" 35 |
36RCSID("$Id: sh.file.c,v 3.28 2005/01/05 16:06:13 christos Exp $") |
37 38#if defined(FILEC) && defined(TIOCSTI) 39 40/* 41 * Tenex style file name recognition, .. and more. 42 * History: 43 * Author: Ken Greer, Sept. 1975, CMU. 44 * Finally got around to adding to the Cshell., Ken Greer, Dec. 1981. --- 14 unchanged lines hidden (view full) --- 59 LIST, RECOGNIZE 60} COMMAND; 61 62static void setup_tty __P((int)); 63static void back_to_col_1 __P((void)); 64static void pushback __P((Char *)); 65static void catn __P((Char *, Char *, int)); 66static void copyn __P((Char *, Char *, int)); |
67static int filetype __P((Char *, Char *)); 68static void print_by_column __P((Char *, Char *[], size_t)); |
69static Char *tilde __P((Char *, Char *)); 70static void retype __P((void)); 71static void beep __P((void)); 72static void print_recognized_stuff __P((Char *)); 73static void extract_dir_and_name __P((Char *, Char *, Char *)); 74static Char *getitem __P((DIR *, int)); 75static void free_items __P((Char **, size_t)); 76static int tsearch __P((Char *, COMMAND, int)); 77static int compare __P((const ptr_t, const ptr_t)); |
78static int recognize __P((Char *, Char *, int, size_t)); |
79static int is_prefix __P((Char *, Char *)); 80static int is_suffix __P((Char *, Char *)); 81static int ignored __P((Char *)); 82 83 84/* 85 * Put this here so the binary can be patched with adb to enable file 86 * completion by default. Filec controls completion, nobeep controls 87 * ringing the terminal bell on incomplete expansions. 88 */ |
89int filec = 0; |
90 91static void 92setup_tty(on) 93 int on; 94{ 95#ifdef TERMIO 96# ifdef POSIX 97 struct termios tchars; --- 123 unchanged lines hidden (view full) --- 221/* 222 * Push string contents back into tty queue 223 */ 224static void 225pushback(string) 226 Char *string; 227{ 228 Char *p; |
229#ifdef TERMIO 230# ifdef POSIX 231 struct termios tty, tty_normal; 232# else 233 struct termio tty, tty_normal; 234# endif /* POSIX */ 235#else 236 struct sgttyb tty, tty_normal; --- 14 unchanged lines hidden (view full) --- 251 tty_normal = tty; 252 tty.c_lflag &= ~(ECHOKE | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOCTL); 253# ifdef POSIX 254 (void) tcsetattr(SHOUT, TCSANOW, &tty); 255# else 256 (void) ioctl(SHOUT, TCSETAW, (ioctl_t) &tty); 257# endif /* POSIX */ 258 |
259 for (p = string; *p != '\0'; p++) { 260 char buf[MB_LEN_MAX]; 261 size_t i, len; 262 263 len = one_wctomb(buf, *p & CHAR); 264 for (i = 0; i < len; i++) 265 (void) ioctl(SHOUT, TIOCSTI, (ioctl_t) &buf[i]); 266 } |
267# ifdef POSIX 268 (void) tcsetattr(SHOUT, TCSANOW, &tty_normal); 269# else 270 (void) ioctl(SHOUT, TCSETAW, (ioctl_t) &tty_normal); 271# endif /* POSIX */ 272#else 273 (void) ioctl(SHOUT, TIOCGETP, (ioctl_t) & tty); 274 tty_normal = tty; --- 40 unchanged lines hidden (view full) --- 315 int count; 316{ 317 while (--count >= 0) 318 if ((*des++ = *src++) == 0) 319 return; 320 *des = '\0'; 321} 322 |
323static int |
324filetype(dir, file) 325 Char *dir, *file; 326{ 327 Char path[MAXPATHLEN]; 328 struct stat statb; 329 330 catn(Strcpy(path, dir), file, sizeof(path) / sizeof(Char)); 331 if (lstat(short2str(path), &statb) == 0) { --- 22 unchanged lines hidden (view full) --- 354static struct winsize win; 355 356/* 357 * Print sorted down columns 358 */ 359static void 360print_by_column(dir, items, count) 361 Char *dir, *items[]; |
362 size_t count; |
363{ |
364 size_t i; 365 int rows, r, c, maxwidth = 0, columns; |
366 367 if (ioctl(SHOUT, TIOCGWINSZ, (ioctl_t) & win) < 0 || win.ws_col == 0) 368 win.ws_col = 80; 369 for (i = 0; i < count; i++) 370 maxwidth = maxwidth > (r = Strlen(items[i])) ? maxwidth : r; 371 maxwidth += 2; /* for the file tag and space */ 372 columns = win.ws_col / maxwidth; 373 if (columns == 0) --- 143 unchanged lines hidden (view full) --- 517 copyn(name, path, MAXNAMLEN); 518 dir[0] = '\0'; 519 } 520 else { 521 copyn(name, ++p, MAXNAMLEN); 522 copyn(dir, path, p - path); 523 } 524} |
525 |
526static Char * 527getitem(dir_fd, looking_for_lognames) 528 DIR *dir_fd; 529 int looking_for_lognames; 530{ 531 struct passwd *pw; 532 struct dirent *dirp; 533 534 if (looking_for_lognames) { |
535#ifndef HAVE_GETPWENT |
536 return (NULL); 537#else 538 if ((pw = getpwent()) == NULL) 539 return (NULL); 540 return (str2short(pw->pw_name)); 541#endif /* atp vmsposix */ 542 } 543 if ((dirp = readdir(dir_fd)) != NULL) --- 34 unchanged lines hidden (view full) --- 578 */ 579static int 580tsearch(word, command, max_word_length) 581 Char *word; 582 int max_word_length; 583 COMMAND command; 584{ 585 DIR *dir_fd; |
586 int ignoring = TRUE, nignored = 0; |
587 int name_length, looking_for_lognames; 588 Char tilded_dir[MAXPATHLEN + 1], dir[MAXPATHLEN + 1]; 589 Char name[MAXNAMLEN + 1], extended_name[MAXNAMLEN + 1]; 590 Char *item; 591 Char **items = NULL; |
592 size_t numitems = 0, maxitems = 0; |
593 594 looking_for_lognames = (*word == '~') && (Strchr(word, '/') == NULL); 595 if (looking_for_lognames) { |
596#ifdef HAVE_GETPWENT |
597 (void) setpwent(); |
598#endif |
599 copyn(name, &word[1], MAXNAMLEN); /* name sans ~ */ 600 dir_fd = NULL; 601 } 602 else { 603 extract_dir_and_name(word, dir, name); 604 if (tilde(tilded_dir, dir) == 0) 605 return (0); 606 dir_fd = opendir(*tilded_dir ? short2str(tilded_dir) : "."); --- 31 unchanged lines hidden (view full) --- 638 else if (recognize(extended_name, 639 item, name_length, ++numitems)) 640 break; 641 } 642 } 643 if (ignoring && numitems == 0 && nignored > 0) { 644 ignoring = FALSE; 645 nignored = 0; |
646 if (looking_for_lognames) { 647#ifdef HAVE_GETPWENT |
648 (void) setpwent(); 649#endif /* atp vmsposix */ |
650 } else |
651 rewinddir(dir_fd); 652 goto again; 653 } 654 |
655 if (looking_for_lognames) { 656#ifndef HAVE_GETPWENT |
657 (void) endpwent(); |
658#endif 659 } else |
660 (void) closedir(dir_fd); 661 if (numitems == 0) 662 return (0); 663 if (command == RECOGNIZE) { 664 if (looking_for_lognames) 665 copyn(word, STRtilde, 1); 666 else 667 /* put back dir part */ 668 copyn(word, dir, max_word_length); 669 /* add extended name */ 670 catn(word, extended_name, max_word_length); 671 return (numitems); 672 } 673 else { /* LIST */ |
674 qsort((ptr_t) items, numitems, sizeof(items[0]), |
675 (int (*) __P((const void *, const void *))) compare); 676 print_by_column(looking_for_lognames ? NULL : tilded_dir, 677 items, numitems); 678 if (items != NULL) 679 FREE_ITEMS(items, numitems); 680 } 681 return (0); 682} 683 684 685static int 686compare(p, q) 687 const ptr_t p, q; 688{ |
689#ifdef WIDE_STRINGS 690 errno = 0; 691 692 return (wcscoll(*(Char **) p, *(Char **) q)); |
693#else |
694 char *p1, *q1; 695 int res; 696 697 p1 = strsave(short2str(*(Char **) p)); 698 q1 = strsave(short2str(*(Char **) q)); 699# if defined(NLS) && !defined(NOSTRCOLL) 700 errno = 0; /* strcoll sets errno, another brain-damage */ 701 res = strcoll(p1, q1); 702# else 703 res = strcmp(p1, q1); 704# endif /* NLS && !NOSTRCOLL */ 705 xfree (p1); 706 xfree (q1); 707 return res; 708#endif /* not WIDE_STRINGS */ |
709} 710 711/* 712 * Object: extend what user typed up to an ambiguity. 713 * Algorithm: 714 * On first match, copy full item (assume it'll be the only match) 715 * On subsequent matches, shorten extended_name to the first 716 * Character mismatch between extended_name and item. 717 * If we shorten it back to the prefix length, stop searching. 718 */ 719static int 720recognize(extended_name, item, name_length, numitems) 721 Char *extended_name, *item; |
722 int name_length; 723 size_t numitems; |
724{ 725 if (numitems == 1) /* 1st match */ 726 copyn(extended_name, item, MAXNAMLEN); 727 else { /* 2nd & subsequent matches */ 728 Char *x, *ent; 729 int len = 0; 730 731 x = extended_name; --- 42 unchanged lines hidden (view full) --- 774} 775 776int 777tenex(inputline, inputline_size) 778 Char *inputline; 779 int inputline_size; 780{ 781 int numitems, num_read; |
782 char tinputline[BUFSIZE + 1]; |
783 784 785 setup_tty(ON); 786 787 while ((num_read = read(SHIN, tinputline, BUFSIZE)) > 0) { |
788 static Char delims[] = {' ', '\'', '"', '\t', ';', '&', '<', 789 '>', '(', ')', '|', '^', '%', '\0'}; 790 Char *str_end, *word_start, last_Char, should_retype; 791 int space_left; 792 COMMAND command; 793 |
794 tinputline[num_read] = 0; 795 Strcpy(inputline, str2short(tinputline)); 796 num_read = Strlen(inputline); |
797 last_Char = inputline[num_read - 1] & ASCII; 798 799 if (last_Char == '\n' || num_read == inputline_size) 800 break; 801 command = (last_Char == ESC) ? RECOGNIZE : LIST; 802 if (command == LIST) 803 xputchar('\n'); 804 str_end = &inputline[num_read]; --- 57 unchanged lines hidden --- |