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