--- 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);
}