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