|
|
1.1 root 1: /*
2: * Copyright (c) 1987 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1987 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)look.c 4.5 (Berkeley) 10/6/87";
15: #endif not lint
16:
17: #include <sys/types.h>
18: #include <sys/file.h>
19: #include <sys/stat.h>
20: #include <stdio.h>
21: #include <ctype.h>
22:
23: #define EOS '\0'
24: #define MAXLINELEN 250
25: #define YES 1
26:
27: static int fold, dict, len;
28:
29: main(argc, argv)
30: int argc;
31: char **argv;
32: {
33: extern char *optarg;
34: extern int optind;
35: static char *filename = "/usr/dict/words";
36: register off_t bot, mid, top;
37: register int c;
38: struct stat sb;
39: char entry[MAXLINELEN], copy[MAXLINELEN];
40:
41: while ((c = getopt(argc, argv, "df")) != EOF)
42: switch((char)c) {
43: case 'd':
44: dict = YES;
45: break;
46: case 'f':
47: fold = YES;
48: break;
49: case '?':
50: default:
51: usage();
52: }
53: argv += optind;
54: argc -= optind;
55:
56: switch(argc) {
57: case 1: /* if default file, set to dictionary order and folding */
58: dict = fold = YES;
59: break;
60: case 2:
61: filename = argv[1];
62: break;
63: default:
64: usage();
65: }
66:
67: if (!freopen(filename, "r", stdin)) {
68: fprintf(stderr,"look: can't read %s.\n", filename);
69: exit(2);
70: }
71: if (fstat(fileno(stdin), &sb)) {
72: perror("look: fstat");
73: exit(2);
74: }
75:
76: len = strlen(*argv);
77: canon(*argv, *argv);
78: len = strlen(*argv); /* may have changed */
79: if (len > MAXLINELEN - 1) {
80: fputs("look: search string is too long.\n", stderr);
81: exit(2);
82: }
83:
84: for (bot = 0, top = sb.st_size;;) {
85: mid = (top + bot) / 2;
86: (void)fseek(stdin, mid, L_SET);
87:
88: for (++mid; (c = getchar()) != EOF && c != '\n'; ++mid);
89: if (!getline(entry))
90: break;
91: canon(entry, copy);
92: if (strncmp(*argv, copy, len) <= 0) {
93: if (top <= mid)
94: break;
95: top = mid;
96: }
97: else
98: bot = mid;
99: }
100: (void)fseek(stdin, bot, L_SET);
101: while (ftell(stdin) < top) {
102: register int val;
103:
104: if (!getline(entry))
105: exit(0);
106: canon(entry, copy);
107: if (!(val = strncmp(*argv, copy, len))) {
108: puts(entry);
109: break;
110: }
111: if (val < 0)
112: exit(0);
113: }
114: while (getline(entry)) {
115: canon(entry, copy);
116: if (strncmp(*argv, copy, len))
117: break;
118: puts(entry);
119: }
120: exit(0);
121: }
122:
123: /*
124: * getline --
125: * get a line
126: */
127: static
128: getline(buf)
129: register char *buf;
130: {
131: register int c;
132:
133: for (;;) {
134: if ((c = getchar()) == EOF)
135: return(0);
136: if (c == '\n')
137: break;
138: *buf++ = c;
139: }
140: *buf = EOS;
141: return(1);
142: }
143:
144: /*
145: * canon --
146: * create canonical version of word
147: */
148: static
149: canon(src, copy)
150: register char *src, *copy;
151: {
152: register int cnt;
153: register char c;
154:
155: for (cnt = len + 1; (c = *src++) && cnt; --cnt)
156: if (!dict || isalnum(c))
157: *copy++ = fold && isupper(c) ? tolower(c) : c;
158: *copy = EOS;
159: }
160:
161: /*
162: * usage --
163: * print a usage message and die
164: */
165: static
166: usage()
167: {
168: fputs("usage: look [-df] string [file]\n", stderr);
169: exit(1);
170: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.