tw.spell.c revision 59243
1/* $Header: /src/pub/tcsh/tw.spell.c,v 3.14 1996/04/26 19:23:27 christos Exp $ */
2/*
3 * tw.spell.c: Spell check words
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
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *	This product includes software developed by the University of
20 *	California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 *    may be used to endorse or promote products derived from this software
23 *    without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37#include "sh.h"
38
39RCSID("$Id: tw.spell.c,v 3.14 1996/04/26 19:23:27 christos Exp $")
40
41#include "tw.h"
42
43/* spell_me : return corrrectly spelled filename.  From K&P spname */
44int
45spell_me(oldname, oldsize, looking, pat, suf)
46    Char   *oldname;
47    int     oldsize, looking;
48    Char   *pat;
49    int     suf;
50{
51    /* The +1 is to fool hp's optimizer */
52    Char    guess[FILSIZ + 1], newname[FILSIZ + 1];
53    register Char *new = newname, *old = oldname;
54    register Char *p, *cp, *ws;
55    bool    foundslash = 0;
56    int     retval;
57
58    for (;;) {
59	while (*old == '/') {	/* skip '/' */
60	    *new++ = *old++;
61	    foundslash = 1;
62	}
63	/* do not try to correct spelling of single letter words */
64	if (*old != '\0' && old[1] == '\0')
65	    *new++ = *old++;
66	*new = '\0';
67	if (*old == '\0') {
68	    retval = (StrQcmp(oldname, newname) != 0);
69	    copyn(oldname, newname, oldsize);	/* shove it back. */
70	    return retval;
71	}
72	p = guess;		/* start at beginning of buf */
73	if (newname[0])		/* add current dir if any */
74	    for (cp = newname; *cp; cp++)
75		if (p < guess + FILSIZ)
76		    *p++ = *cp;
77	ws = p;
78	for (; *old != '/' && *old != '\0'; old++)/* add current file name */
79	    if (p < guess + FILSIZ)
80		*p++ = *old;
81	*p = '\0';		/* terminate it */
82
83	/*
84	 * Don't tell t_search we're looking for cmd if no '/' in the name so
85	 * far but there are later - or it will look for *all* commands
86	 */
87	/* (*should* say "looking for directory" whenever '/' is next...) */
88	retval = t_search(guess, p, SPELL, FILSIZ,
89			  looking == TW_COMMAND && (foundslash || *old != '/') ?
90			  TW_COMMAND : looking, 1, pat, suf);
91	if (retval >= 4 || retval < 0)
92	    return -1;		/* hopeless */
93	for (p = ws; (*new = *p++) != '\0'; new++)
94	    continue;
95    }
96/*NOTREACHED*/
97#ifdef notdef
98    return (0);			/* lint on the vax under mtXinu complains! */
99#endif
100}
101
102#define EQ(s,t)	(StrQcmp(s,t) == 0)
103
104/*
105 * spdist() is taken from Kernighan & Pike,
106 *  _The_UNIX_Programming_Environment_
107 * and adapted somewhat to correspond better to psychological reality.
108 * (Note the changes to the return values)
109 *
110 * According to Pollock and Zamora, CACM April 1984 (V. 27, No. 4),
111 * page 363, the correct order for this is:
112 * OMISSION = TRANSPOSITION > INSERTION > SUBSTITUTION
113 * thus, it was exactly backwards in the old version. -- PWP
114 */
115
116int
117spdist(s, t)
118    register Char *s, *t;
119{
120    for (; (*s & TRIM) == (*t & TRIM); t++, s++)
121	if (*t == '\0')
122	    return 0;		/* exact match */
123    if (*s) {
124	if (*t) {
125	    if (s[1] && t[1] && (*s & TRIM) == (t[1] & TRIM) &&
126		(*t & TRIM) == (s[1] & TRIM) && EQ(s + 2, t + 2))
127		return 1;	/* transposition */
128	    if (EQ(s + 1, t + 1))
129		return 3;	/* 1 char mismatch */
130	}
131	if (EQ(s + 1, t))
132	    return 2;		/* extra character */
133    }
134    if (*t && EQ(s, t + 1))
135	return 1;		/* missing character */
136    return 4;
137}
138
139int
140spdir(extended_name, tilded_dir, item, name)
141    Char   *extended_name;
142    Char   *tilded_dir;
143    Char   *item;
144    Char   *name;
145{
146    Char    path[MAXPATHLEN + 1];
147    Char   *s;
148    Char    oldch;
149
150    if (ISDOT(item) || ISDOTDOT(item))
151	return 0;
152
153    for (s = name; *s != 0 && (*s & TRIM) == (*item & TRIM); s++, item++)
154	continue;
155    if (*s == 0 || s[1] == 0 || *item != 0)
156	return 0;
157
158    (void) Strcpy(path, tilded_dir);
159    oldch = *s;
160    *s = '/';
161    catn(path, name, (int) (sizeof(path) / sizeof(Char)));
162    if (access(short2str(path), F_OK) == 0) {
163	(void) Strcpy(extended_name, name);
164	return 1;
165    }
166    *s = oldch;
167    return 0;
168}
169