# HG changeset patch # User viric@llimona # Date 1188676181 -7200 # Node ID 01fe372188ac4761139ab6c4af8bb9cf6a8f3798 # Parent 45798398f4c8fe39bc8975d0ec4a1ad60cc64aec Added capabilities to the dictionary finder. diff -r 45798398f4c8 -r 01fe372188ac dictre.h --- a/dictre.h Sat Sep 01 13:04:10 2007 +0200 +++ b/dictre.h Sat Sep 01 21:49:41 2007 +0200 @@ -36,6 +36,8 @@ int indexfd; int indexsize; FILE *defs; + int trim_first_line; + int trim_last_newlines; }; /* write.c */ diff -r 45798398f4c8 -r 01fe372188ac find.c --- a/find.c Sat Sep 01 13:04:10 2007 +0200 +++ b/find.c Sat Sep 01 21:49:41 2007 +0200 @@ -55,6 +55,9 @@ exit(-1); } + d->trim_first_line = 0; + d->trim_last_newlines = 0; + free(filename); } @@ -65,20 +68,62 @@ fclose(d->defs); } +static int trim_first_line(char *def, int len) +{ + int new_line_pos; + int i,j; + for(i=0; i < len; ++i) + { + if (def[i] == '\n') + { + /* Break */ + memmove(def, def + i + 1 /* \n */, + len - i - 1); + def[len-i-1] = 0; + return len-i-1/*\n*/+1/*\0*/; + } + } + return len; +} + +static int trim_last_newlines(char *def, int len) +{ + int new_line_pos; + int i,j; + for(i=len-1; i >= 0; --i) + { + if (def[i] != '\n' && def[i] != '\r') + { + def[i+1] = '\0'; + return i + 1; + } + } + return len; +} + static void fill_def(struct Dict *d, int offset, int length, char * def) { fseek(d->defs, offset, SEEK_SET); fread(def, 1, length, d->defs); + def[length] = 0; + if (d->trim_first_line) + { + length = trim_first_line(def, length + 1/*\0*/) - 1 /*\0*/; + } + if (d->trim_last_newlines) + { + length = trim_last_newlines(def, length+1) - 1; /* math as above*/ + } } -static int pointer_at_end(struct Dict *d, unsigned char *ptr) +static int pointer_at_end(struct Dict *d, const unsigned char *ptr) { if (ptr >= (d->index + d->indexsize)) return 1; return 0; } -static char * skip_until_newline(struct Dict *d, char *from) +static const char * skip_until_newline(struct Dict *d, const char *from) { if (pointer_at_end(d, from)) return 0; @@ -118,17 +163,28 @@ return -1; } -static char * bin_search(struct Dict *d, const char *word) +static const char * search_next(struct Dict *d, const char *word, const char *from) +{ + const char *ret; + ret = skip_until_newline(d, from); + if (compare(from, word) == 0) + return ret; + return 0; +} + +static const char * bin_search(struct Dict *d, const char *word) { int step, pivot; + const char *ret; + const char *test; + int comparision; + int found_once = 0; pivot = d->indexsize / 2; step = d->indexsize / 2; do { - char *test; - int comparision; test = d->index + pivot; test = skip_until_newline(d, test); if (test == 0) @@ -136,11 +192,13 @@ test += 1; /* skip exactly the new line */ comparision = compare(word, test); - if (comparision == 0) + if (comparision <= 0) { - return test + strlen(word) + 1; /* skip word and \n */ - } else if (comparision < 0) - { + if (comparision == 0) + found_once = 1; + /* If == 0, we don't know that it's the FIRST + * match possible in the dictionary. + * We want all possible matches. */ step = step / 2; pivot = pivot - step; } else if (comparision > 0) @@ -149,13 +207,24 @@ pivot = pivot + step; } } while(step > 0); - return 0; + + if (!found_once) + return 0; + + if (comparision == 0) /* last comparision */ + { + ret = skip_until_newline(d, d->index + pivot) + 1; + } else + { + ret = skip_until_newline(d, test) + 1; + } + return ret; } -static int my_get_int(char **pos) +static int my_get_int(const char **pos) { int i; - char *start; + const char *start; int val; start = *pos; @@ -169,16 +238,26 @@ void find_def(struct Dict *d, const char *word, char * def) { int offset, len; - char *pos; + const char *found, *pos; + int wordlen; - pos = bin_search(d, word); /* pos points to the offset already. */ - if (pos == 0) + def[0] = 0; + /* we will get a pointer to the offset for the ints*/ + found = bin_search(d, word); + if (found == 0) + return; + wordlen = strlen(word); + do { - def[0] = 0; - /*fprintf(stderr, "Cannot find %s\n", word);*/ - return; - } - offset = my_get_int(&pos); /* increments pos */ - len = my_get_int(&pos); /* increments pos */ - fill_def(d, offset, len, def); + found += wordlen+1; + pos = found; + offset = my_get_int(&pos); /* increments pos */ + len = my_get_int(&pos); /* increments pos */ + fill_def(d, offset, len, def); + found = search_next(d, word, found); + if (!found) + break; + strcat(def, ", "); + def += strlen(def); + } while(1); }