xref: /minix3/minix/commands/look/look.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc /*	look 1.3 - Find lines in a sorted list.		Author: Kees J. Bot
2*433d6423SLionel Sambuc  */
3*433d6423SLionel Sambuc #define nil 0
4*433d6423SLionel Sambuc #include <sys/types.h>
5*433d6423SLionel Sambuc #include <stdio.h>
6*433d6423SLionel Sambuc #include <ctype.h>
7*433d6423SLionel Sambuc #include <stdlib.h>
8*433d6423SLionel Sambuc #include <string.h>
9*433d6423SLionel Sambuc 
10*433d6423SLionel Sambuc char DEFAULT[] = "/usr/lib/dict/words";
11*433d6423SLionel Sambuc 
12*433d6423SLionel Sambuc char *string, *wordlist= DEFAULT;
13*433d6423SLionel Sambuc 
14*433d6423SLionel Sambuc #define MAXLEN	1024	/* Maximum word length. */
15*433d6423SLionel Sambuc 
16*433d6423SLionel Sambuc int dflg= 0, fflg= 0;
17*433d6423SLionel Sambuc 
nonascii(char * what)18*433d6423SLionel Sambuc void nonascii(char *what)
19*433d6423SLionel Sambuc {
20*433d6423SLionel Sambuc 	fprintf(stderr, "look: %s contains non-ASCII characters.\n", what);
21*433d6423SLionel Sambuc 	exit(1);
22*433d6423SLionel Sambuc }
23*433d6423SLionel Sambuc 
compare(char * prefix,char * word)24*433d6423SLionel Sambuc int compare(char *prefix, char *word)
25*433d6423SLionel Sambuc {
26*433d6423SLionel Sambuc 	char *p= prefix, *w= word;
27*433d6423SLionel Sambuc 	int cp, cw;
28*433d6423SLionel Sambuc 
29*433d6423SLionel Sambuc 	do {
30*433d6423SLionel Sambuc 		do {
31*433d6423SLionel Sambuc 			if ((cp= *p++) == 0) return 0;
32*433d6423SLionel Sambuc 			if (!isascii(cp)) nonascii("prefix string");
33*433d6423SLionel Sambuc 		} while (dflg && !isspace(cp) && !isalnum(cp));
34*433d6423SLionel Sambuc 
35*433d6423SLionel Sambuc 		if (dflg) {
36*433d6423SLionel Sambuc 			if (isspace(cp)) {
37*433d6423SLionel Sambuc 				while (isspace(*p)) p++;
38*433d6423SLionel Sambuc 				cp= ' ';
39*433d6423SLionel Sambuc 			}
40*433d6423SLionel Sambuc 		}
41*433d6423SLionel Sambuc 		if (fflg && isupper(cp)) cp= tolower(cp);
42*433d6423SLionel Sambuc 
43*433d6423SLionel Sambuc 		do {
44*433d6423SLionel Sambuc 			if ((cw= *w++) == 0) return 1;
45*433d6423SLionel Sambuc 			if (!isascii(cw)) nonascii(wordlist);
46*433d6423SLionel Sambuc 		} while (dflg && !isspace(cw) && !isalnum(cw));
47*433d6423SLionel Sambuc 
48*433d6423SLionel Sambuc 		if (dflg) {
49*433d6423SLionel Sambuc 			if (isspace(cw)) {
50*433d6423SLionel Sambuc 				while (isspace(*w)) w++;
51*433d6423SLionel Sambuc 				cw= ' ';
52*433d6423SLionel Sambuc 			}
53*433d6423SLionel Sambuc 		}
54*433d6423SLionel Sambuc 		if (fflg && isupper(cw)) cw= tolower(cw);
55*433d6423SLionel Sambuc 	} while (cp == cw);
56*433d6423SLionel Sambuc 
57*433d6423SLionel Sambuc 	return cp - cw;
58*433d6423SLionel Sambuc }
59*433d6423SLionel Sambuc 
readword(FILE * f)60*433d6423SLionel Sambuc char *readword(FILE *f)
61*433d6423SLionel Sambuc {
62*433d6423SLionel Sambuc 	static char word[MAXLEN + 2];
63*433d6423SLionel Sambuc 	int n;
64*433d6423SLionel Sambuc 
65*433d6423SLionel Sambuc 	if (fgets(word, sizeof(word), f) == nil) {
66*433d6423SLionel Sambuc 		if (ferror(f)) {
67*433d6423SLionel Sambuc 			fprintf(stderr, "look: read error on %s",
68*433d6423SLionel Sambuc 				wordlist);
69*433d6423SLionel Sambuc 			exit(1);
70*433d6423SLionel Sambuc 		}
71*433d6423SLionel Sambuc 		return nil;
72*433d6423SLionel Sambuc 	}
73*433d6423SLionel Sambuc 
74*433d6423SLionel Sambuc 	n= strlen(word);
75*433d6423SLionel Sambuc 
76*433d6423SLionel Sambuc 	if (word[n-1] != '\n') {
77*433d6423SLionel Sambuc 		fprintf(stderr, "look: word from %s is too long\n", wordlist);
78*433d6423SLionel Sambuc 		exit(1);
79*433d6423SLionel Sambuc 	}
80*433d6423SLionel Sambuc 	word[n-1] = 0;
81*433d6423SLionel Sambuc 
82*433d6423SLionel Sambuc 	return word;
83*433d6423SLionel Sambuc }
84*433d6423SLionel Sambuc 
look(void)85*433d6423SLionel Sambuc void look(void)
86*433d6423SLionel Sambuc {
87*433d6423SLionel Sambuc 	off_t low, mid, high;
88*433d6423SLionel Sambuc 	FILE *f;
89*433d6423SLionel Sambuc 	char *word;
90*433d6423SLionel Sambuc 	int c;
91*433d6423SLionel Sambuc 
92*433d6423SLionel Sambuc 	if ((f= fopen(wordlist, "r")) == nil) {
93*433d6423SLionel Sambuc 		fprintf(stderr, "look: Can't open %s\n", wordlist);
94*433d6423SLionel Sambuc 		exit(1);
95*433d6423SLionel Sambuc 	}
96*433d6423SLionel Sambuc 
97*433d6423SLionel Sambuc 	low= 0;
98*433d6423SLionel Sambuc 
99*433d6423SLionel Sambuc 	fseek(f, (off_t) 0, 2);
100*433d6423SLionel Sambuc 
101*433d6423SLionel Sambuc 	high= ftell(f);
102*433d6423SLionel Sambuc 
103*433d6423SLionel Sambuc 	while (low <= high) {
104*433d6423SLionel Sambuc 		mid= (low + high) / 2;
105*433d6423SLionel Sambuc 
106*433d6423SLionel Sambuc 		fseek(f, mid, 0);
107*433d6423SLionel Sambuc 
108*433d6423SLionel Sambuc 		if (mid != 0) readword(f);
109*433d6423SLionel Sambuc 
110*433d6423SLionel Sambuc 		if ((word= readword(f)) == nil)
111*433d6423SLionel Sambuc 			c= -1;
112*433d6423SLionel Sambuc 		else
113*433d6423SLionel Sambuc 			c= compare(string, word);
114*433d6423SLionel Sambuc 
115*433d6423SLionel Sambuc 		if (c <= 0) high= mid - 1; else low= mid + 1;
116*433d6423SLionel Sambuc 	}
117*433d6423SLionel Sambuc 	fseek(f, low, 0);
118*433d6423SLionel Sambuc 	if (low != 0) readword(f);
119*433d6423SLionel Sambuc 
120*433d6423SLionel Sambuc 	c=0;
121*433d6423SLionel Sambuc 	while (c >= 0 && (word= readword(f)) != nil) {
122*433d6423SLionel Sambuc 		c= compare(string, word);
123*433d6423SLionel Sambuc 
124*433d6423SLionel Sambuc 		if (c == 0) puts(word);
125*433d6423SLionel Sambuc 	}
126*433d6423SLionel Sambuc }
127*433d6423SLionel Sambuc 
main(int argc,char ** argv)128*433d6423SLionel Sambuc int main(int argc, char **argv)
129*433d6423SLionel Sambuc {
130*433d6423SLionel Sambuc 	if (argc == 2) dflg= fflg= 1;
131*433d6423SLionel Sambuc 
132*433d6423SLionel Sambuc 	while (argc > 1 && argv[1][0] == '-') {
133*433d6423SLionel Sambuc 		char *p= argv[1] + 1;
134*433d6423SLionel Sambuc 
135*433d6423SLionel Sambuc 		while (*p != 0) {
136*433d6423SLionel Sambuc 			switch (*p++) {
137*433d6423SLionel Sambuc 			case 'd':	dflg= 1; break;
138*433d6423SLionel Sambuc 			case 'f':	fflg= 1; break;
139*433d6423SLionel Sambuc 			default:
140*433d6423SLionel Sambuc 				fprintf(stderr, "look: Bad flag: %c\n", p[-1]);
141*433d6423SLionel Sambuc 				exit(1);
142*433d6423SLionel Sambuc 			}
143*433d6423SLionel Sambuc 		}
144*433d6423SLionel Sambuc 		argc--;
145*433d6423SLionel Sambuc 		argv++;
146*433d6423SLionel Sambuc 	}
147*433d6423SLionel Sambuc 	if (argc == 3)
148*433d6423SLionel Sambuc 		wordlist= argv[2];
149*433d6423SLionel Sambuc 	else
150*433d6423SLionel Sambuc 	if (argc != 2) {
151*433d6423SLionel Sambuc 		fprintf(stderr, "Usage: look [-df] string [file]\n");
152*433d6423SLionel Sambuc 		exit(1);
153*433d6423SLionel Sambuc 	}
154*433d6423SLionel Sambuc 	string= argv[1];
155*433d6423SLionel Sambuc 	look();
156*433d6423SLionel Sambuc 	exit(0);
157*433d6423SLionel Sambuc }
158*433d6423SLionel Sambuc /* Kees J. Bot 24-5-89. */
159