xref: /illumos-gate/usr/src/cmd/look/look.c (revision 2889ec41c05e9ffe1890b529b3111354da325aeb)
1 /*
2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
7 /*	  All Rights Reserved  	*/
8 
9 /*
10  * Copyright (c) 1980 Regents of the University of California.
11  * All rights reserved. The Berkeley software License Agreement
12  * specifies the terms and conditions for redistribution.
13  */
14 
15 #pragma ident	"%Z%%M%	%I%	%E% SMI"
16 
17 #include <stdio.h>
18 #include <ctype.h>
19 #include <string.h>
20 
21 FILE *dfile;
22 char *filenam  = "/usr/share/lib/dict/words";
23 
24 int fold;
25 int dict;
26 int tab;
27 #define WORDSIZE 257
28 char entry[WORDSIZE];
29 char word[WORDSIZE];
30 char key[WORDSIZE];
31 
32 int	compare(char *, char *);
33 void	canon(char *, char *);
34 int	getword(char *);
35 
36 int
37 main(int argc, char **argv)
38 {
39 	int c;
40 	long top,bot,mid;
41 	char *wstring, *ptr;
42 
43 	while(argc>=2 && *argv[1]=='-') {
44 		for(;;) {
45 			switch(*++argv[1]) {
46 			case 'd':
47 				dict++;
48 				continue;
49 			case 'f':
50 				fold++;
51 				continue;
52 			case 't':
53 				tab = argv[1][1];
54 				if(tab)
55 					++argv[1];
56 				continue;
57 			case 0:
58 				break;
59 			default:
60 				continue;
61 			}
62 			break;
63 		}
64 		argc --;
65 		argv++;
66 	}
67 	if(argc<=1)
68 		return (1);
69 	if(argc==2) {
70 		fold++;
71 		dict++;
72 	} else
73 		filenam = argv[2];
74 	dfile = fopen(filenam,"r");
75 	if(dfile==NULL) {
76 		fprintf(stderr,"look: can't open %s\n",filenam);
77 		exit(2);
78 	}
79 	wstring = strdup(argv[1]);
80 	if (tab != NULL) {
81 		if ((ptr = strchr(wstring, tab)) != NULL) {
82 			*++ptr = '\0';
83 		}
84 	}
85 	canon(wstring,key);
86 	bot = 0;
87 	fseek(dfile,0L,2);
88 	top = ftell(dfile);
89 	for(;;) {
90 		mid = (top+bot)/2;
91 		fseek(dfile,mid,0);
92 		do {
93 			c = getc(dfile);
94 			mid++;
95 		} while(c!=EOF && c!='\n');
96 		if(!getword(entry))
97 			break;
98 		canon(entry,word);
99 		switch(compare(key,word)) {
100 		case -2:
101 		case -1:
102 		case 0:
103 			if(top<=mid)
104 				break;
105 			top = mid;
106 			continue;
107 		case 1:
108 		case 2:
109 			bot = mid;
110 			continue;
111 		}
112 		break;
113 	}
114 	fseek(dfile,bot,0);
115 	while(ftell(dfile)<top) {
116 		if(!getword(entry))
117 			return (0);
118 		canon(entry,word);
119 		switch(compare(key,word)) {
120 		case -2:
121 			return (0);
122 		case -1:
123 		case 0:
124 			puts(entry);
125 			break;
126 		case 1:
127 		case 2:
128 			continue;
129 		}
130 		break;
131 	}
132 	while(getword(entry)) {
133 		canon(entry,word);
134 		switch(compare(key,word)) {
135 		case -1:
136 		case 0:
137 			puts(entry);
138 			continue;
139 		}
140 		break;
141 	}
142 	return (0);
143 }
144 
145 int
146 compare(char *s, char *t)
147 {
148 	for(;*s==*t;s++,t++)
149 		if(*s==0)
150 			return(0);
151 	return(*s==0? -1:
152 		*t==0? 1:
153 		*s<*t? -2:
154 		2);
155 }
156 
157 int
158 getword(char *w)
159 {
160 	int c;
161 	int avail = WORDSIZE - 1;
162 
163 	while(avail--) {
164 		c = getc(dfile);
165 		if(c==EOF)
166 			return(0);
167 		if(c=='\n')
168 			break;
169 		*w++ = c;
170 	}
171 	while (c != '\n')
172 		c = getc(dfile);
173 	*w = 0;
174 	return(1);
175 }
176 
177 void
178 canon(char *old, char *new)
179 {
180 	int c;
181 	int avail = WORDSIZE - 1;
182 
183 	for(;;) {
184 		*new = c = *old++;
185 		if(c==0) {
186 			*new = 0;
187 			break;
188 		}
189 		if(dict) {
190 			if(!isalnum(c))
191 				continue;
192 		}
193 		if(fold) {
194 			if(isupper(c))
195 				*new += 'a' - 'A';
196 		}
197 		new++;
198 		avail--;
199 		if (avail <= 0) {
200 			*new = 0;
201 			break;
202 		}
203 	}
204 }
205