00001
00002
00003 #define nil 0
00004 #include <sys/types.h>
00005 #include <stdio.h>
00006 #include <ctype.h>
00007 #include <stdlib.h>
00008 #include <string.h>
00009
00010 char DEFAULT[] = "/usr/lib/dict/words";
00011
00012 char *string, *wordlist= DEFAULT;
00013
00014 #define MAXLEN 1024
00015
00016 int dflg= 0, fflg= 0;
00017
00018 void nonascii(char *what)
00019 {
00020 fprintf(stderr, "look: %s contains non-ASCII characters.\n", what);
00021 exit(1);
00022 }
00023
00024 int compare(char *prefix, char *word)
00025 {
00026 char *p= prefix, *w= word;
00027 int cp, cw;
00028
00029 do {
00030 do {
00031 if ((cp= *p++) == 0) return 0;
00032 if (!isascii(cp)) nonascii("prefix string");
00033 } while (dflg && !isspace(cp) && !isalnum(cp));
00034
00035 if (dflg) {
00036 if (isspace(cp)) {
00037 while (isspace(*p)) p++;
00038 cp= ' ';
00039 }
00040 }
00041 if (fflg && isupper(cp)) cp= tolower(cp);
00042
00043 do {
00044 if ((cw= *w++) == 0) return 1;
00045 if (!isascii(cw)) nonascii(wordlist);
00046 } while (dflg && !isspace(cw) && !isalnum(cw));
00047
00048 if (dflg) {
00049 if (isspace(cw)) {
00050 while (isspace(*w)) w++;
00051 cw= ' ';
00052 }
00053 }
00054 if (fflg && isupper(cw)) cw= tolower(cw);
00055 } while (cp == cw);
00056
00057 return cp - cw;
00058 }
00059
00060 char *readword(FILE *f)
00061 {
00062 static char word[MAXLEN + 2];
00063 int n;
00064
00065 if (fgets(word, sizeof(word), f) == nil) {
00066 if (ferror(f)) {
00067 fprintf(stderr, "look: read error on %s",
00068 wordlist);
00069 exit(1);
00070 }
00071 return nil;
00072 }
00073
00074 n= strlen(word);
00075
00076 if (word[n-1] != '\n') {
00077 fprintf(stderr, "look: word from %s is too long\n", wordlist);
00078 exit(1);
00079 }
00080 word[n-1] = 0;
00081
00082 return word;
00083 }
00084
00085 void look(void)
00086 {
00087 off_t low, mid, high;
00088 FILE *f;
00089 char *word;
00090 int c;
00091
00092 if ((f= fopen(wordlist, "r")) == nil) {
00093 fprintf(stderr, "look: Can't open %s\n", wordlist);
00094 exit(1);
00095 }
00096
00097 low= 0;
00098
00099 fseek(f, (off_t) 0, 2);
00100
00101 high= ftell(f);
00102
00103 while (low <= high) {
00104 mid= (low + high) / 2;
00105
00106 fseek(f, mid, 0);
00107
00108 if (mid != 0) readword(f);
00109
00110 if ((word= readword(f)) == nil)
00111 c= -1;
00112 else
00113 c= compare(string, word);
00114
00115 if (c <= 0) high= mid - 1; else low= mid + 1;
00116 }
00117 fseek(f, low, 0);
00118 if (low != 0) readword(f);
00119
00120 c=0;
00121 while (c >= 0 && (word= readword(f)) != nil) {
00122 c= compare(string, word);
00123
00124 if (c == 0) puts(word);
00125 }
00126 }
00127
00128 int main(int argc, char **argv)
00129 {
00130 if (argc == 2) dflg= fflg= 1;
00131
00132 while (argc > 1 && argv[1][0] == '-') {
00133 char *p= argv[1] + 1;
00134
00135 while (*p != 0) {
00136 switch (*p++) {
00137 case 'd': dflg= 1; break;
00138 case 'f': fflg= 1; break;
00139 default:
00140 fprintf(stderr, "look: Bad flag: %c\n", p[-1]);
00141 exit(1);
00142 }
00143 }
00144 argc--;
00145 argv++;
00146 }
00147 if (argc == 3)
00148 wordlist= argv[2];
00149 else
00150 if (argc != 2) {
00151 fprintf(stderr, "Usage: look [-df] string [file]\n");
00152 exit(1);
00153 }
00154 string= argv[1];
00155 look();
00156 exit(0);
00157 }
00158