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