💾 Archived View for runjimmyrunrunyoufuckerrun.com › src › d.c captured on 2021-12-17 at 13:26:06.
View Raw
More Information
-=-=-=-=-=-=-
#include <u.h>
#include <libc.h>
#include <bio.h>
/*
Simple dictionary tool.
A dictionary consists of two files in $home/lib/dict:
• dictname:
flat file with entries separated by lines like:
⇒headwordkey
• dictname.idx:
a sorted file of lines like:
headword offset length
There is a separate tool to create an index:
dictidx dictname | sort | uniq > dictname.idx
Usage: d [dictname] headword
prints all entries with keys exactly matching headword
prints nearest match if headword not found
potential additions but too lazy:
• zipped dictionaries?? or just chmod +t them...
• line folding
• context/browsing
Biobuf *index, *dictionary, *output;
char *word;
enum{
PATHLEN = 128,
BUFLEN = 8192
};
vlong
getvlong(char delim){
vlong x;
char *str;
str = Brdstr(index, delim, 1);
if(str == nil)
sysfatal("getvlong: could not read string");
x = atoll(str);
free(str);
return x;
}
int
checkhw(int *ip, int guess)
{
char *hw;
hw = Brdstr(index, '\t', 1);
if(hw == nil)
return 0;
*ip = strcmp(hw, word);
if(guess && *ip > 0)
sysfatal("nearest match: %s", hw);
free(hw);
return 1;
}
vlong
findfirst(void)
{
vlong min, mid, max;
int c;
min = 0;
max = Bseek(index, 0, 2);
for(;;){
Bseek(index, min + (max - min) / 2, 0);
Brdline(index, '\n');
mid = Boffset(index);
if(mid == max || !checkhw(&c, 0))
break;
if(c < 0)
min = mid;
else
max = mid;
}
Bseek(index, min, 0);
for(;;){
if(!checkhw(&c, 1))
sysfatal("could not find %s", word);
if(c == 0)
break;
Brdline(index, '\n');
min = Boffset(index);
}
return min;
}
void
main(int argc, char **argv)
{
char dict[PATHLEN], idx[PATHLEN], buf[BUFLEN];
int c;
vlong off, len;
sprint(dict, "%s/lib/dict/oed", getenv("home"));
ARGBEGIN {
} ARGEND;
switch(argc){
case 2:
sprint(dict, "%s/lib/dict/%s", getenv("home"), *argv++);
case 1:
word = *argv;
if(*word == '\0')
sysfatal("empty search key");
break;
default:
sysfatal("Usage: %s [dict] headword\n", argv0);
}
sprint(idx, "%s.idx", dict);
index = Bopen(idx, OREAD);
if(index == nil) sysfatal("Bopen: %r");
dictionary = Bopen(dict, OREAD);
if(dictionary == nil) sysfatal("Bopen: %r");
output = Bfdopen(1, OWRITE);
if(output == nil) sysfatal("Bfdopen: %r");
Bseek(index, findfirst(), 0);
for(;;){
if(!checkhw(&c, 0) || c != 0)
break;
off = getvlong('\t');
len = getvlong('\n');
Bseek(dictionary, off, 0);
for(; len > BUFLEN; len -= BUFLEN){
Bread(dictionary, buf, BUFLEN);
Bwrite(output, buf, BUFLEN);
}
Bread(dictionary, buf, len);
Bwrite(output, buf, len);
Bputc(output, '\n');
}
exits(nil);
}