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
19FILE *dfile;
20char *filenam  = "/usr/share/lib/dict/words";
21
22int fold;
23int dict;
24int tab;
25#define WORDSIZE 257
26char entry[WORDSIZE];
27char word[WORDSIZE];
28char key[WORDSIZE];
29
30int	compare(char *, char *);
31void	canon(char *, char *);
32int	getword(char *);
33
34int
35main(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
143int
144compare(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
155int
156getword(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
175void
176canon(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