Commit: b8ad9e19bad361b8e95ee1dfc928c2e9e63e31e4
Parent: 310e995a718b5ea7c6c722f7318f85764127b94f
Author: Randy Palamar
Date: Wed, 15 Nov 2023 06:46:27 -0700
associate ents and nents with their dictionaries
This reduces some amount of boilerplate and will make future
modifications easier.
Diffstat:
M | config.def.h | | | 13 | +++++-------- |
M | jdict.c | | | 127 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
2 files changed, 63 insertions(+), 77 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -11,12 +11,9 @@ static char *repl_prompt = "\033[32;1m入力:\033[0m ";
static char *repl_quit = "\n\033[36m(=^ᆺ^)ノ バイバイ~\033[0m";
/* default yomidicts to search */
-static struct Dict {
- const char *rom;
- const char *name;
-} default_dict_map[] = {
- /* folder name display name */
- {"daijirin", "【三省堂 スーパー大辞林】"},
- {"daijisen", "【大辞泉】"},
- {"koujien", "【広辞苑】"},
+Dict default_dict_map[] = {
+ /* folder name display name */
+ {.rom = "daijirin", .name = "【三省堂 スーパー大辞林】"},
+ {.rom = "daijisen", .name = "【大辞泉】"},
+ {.rom = "koujien", .name = "【広辞苑】"},
};
diff --git a/jdict.c b/jdict.c
@@ -14,8 +14,6 @@
#include "util.h"
#include "yomidict.h"
-#include "config.h"
-
#define YOMI_STRIDE_GUESS 10000UL
#define YOMI_TOKS_PER_ENT 10
#define YOMI_TOK_DELTA (YOMI_TOKS_PER_ENT * 100)
@@ -29,6 +27,13 @@ typedef struct {
size_t ndefs;
} DictEnt;
+typedef struct {
+ const char *rom;
+ const char *name;
+ DictEnt *ents;
+ size_t nents;
+} Dict;
+
struct par_thread_arg {
DictEnt *ents;
size_t len, nents;
@@ -36,6 +41,8 @@ struct par_thread_arg {
int start, end;
};
+#include "config.h"
+
char *argv0;
static void
@@ -87,32 +94,33 @@ merge_ents(DictEnt *a, DictEnt *b)
a->ndefs = nlen;
}
-static DictEnt *
-dedup(DictEnt *ents, size_t *nents)
+static int
+dedup(Dict *d)
{
size_t i, j, len = 0;
- DictEnt *dents = xreallocarray(NULL, *nents, sizeof(DictEnt));
+ DictEnt *dents = xreallocarray(NULL, d->nents, sizeof(DictEnt));
- for (i = 0; i < *nents - 1; i = j) {
- for (j = i+1; j < *nents && !entcmp(&ents[i], &ents[j]); j++) {
- merge_ents(&ents[i], &ents[j]);
+ for (i = 0; i < d->nents - 1; i = j) {
+ for (j = i+1; j < d->nents && !entcmp(&d->ents[i], &d->ents[j]); j++) {
+ merge_ents(&d->ents[i], &d->ents[j]);
/* don't leak memory after merging */
- free(ents[j].term);
- free(ents[j].defs);
+ free(d->ents[j].term);
+ free(d->ents[j].defs);
}
- memcpy(&dents[len++], &ents[i], sizeof(DictEnt));
+ memcpy(&dents[len++], &d->ents[i], sizeof(DictEnt));
}
/* move last ent if it wasn't a duplicate */
- if (i + 1 < *nents)
- memcpy(&dents[len++], &ents[i+1], sizeof(DictEnt));
+ if (i + 1 < d->nents)
+ memcpy(&dents[len++], &d->ents[i+1], sizeof(DictEnt));
/* all entries were copied to dents so old ents can be freed.
* the term and defs ptrs shouldn't be removed since they still
* point to their respective data. the duplicates were freed above
*/
- free(ents);
- *nents = len;
- return xreallocarray(dents, *nents, sizeof(DictEnt));
+ free(d->ents);
+ d->nents = len;
+ d->ents = xreallocarray(dents, d->nents, sizeof(DictEnt));
+ return 1;
}
static size_t
@@ -296,59 +304,48 @@ parallel_parse_term_banks(DictEnt *ents, size_t len, const char *pre,
return nents;
}
-static DictEnt *
-make_dict(struct Dict *dict, size_t *nlen)
+static int
+make_dict(Dict *d)
{
char path[PATH_MAX - 20], tbank[PATH_MAX];
- size_t nbanks, nents = 0, lents = 0;
- DictEnt *ents = NULL;
+ size_t nbanks, lents = 0;
+ d->ents = NULL;
- snprintf(path, LEN(path), "%s/%s", prefix, dict->rom);
+ snprintf(path, LEN(path), "%s/%s", prefix, d->rom);
if ((nbanks = count_term_banks(path)) == 0) {
fprintf(stderr, "no term banks found: %s\n", path);
- return NULL;
+ return 0;
}
/* parse first bank to get a guess for the total number of entries */
snprintf(tbank, LEN(tbank), "%s/term_bank_%d.json", path, 1);
do {
lents += YOMI_STRIDE_GUESS;
- ents = xreallocarray(ents, lents, sizeof(DictEnt));
- nents = parse_term_bank(ents, lents, tbank);
- } while (nents == 0);
+ d->ents = xreallocarray(d->ents, lents, sizeof(DictEnt));
+ d->nents = parse_term_bank(d->ents, lents, tbank);
+ } while (d->nents == 0);
/* alloc enough memory for all ents */
- if ((size_t)-1 / nbanks < nents)
- die("dict has too many entries: %s\n", dict->rom);
- lents = nents * nbanks;
- ents = xreallocarray(ents, lents, sizeof(DictEnt));
+ if ((size_t)-1 / nbanks < d->nents)
+ die("dict has too many entries: %s\n", d->rom);
+ lents = d->nents * nbanks;
+ d->ents = xreallocarray(d->ents, lents, sizeof(DictEnt));
- nents += parallel_parse_term_banks(&ents[nents], lents - nents,
+ d->nents += parallel_parse_term_banks(&d->ents[d->nents], lents - d->nents,
path, nbanks, 2);
- qsort(ents, nents, sizeof(DictEnt), entcmp);
- ents = dedup(ents, &nents);
- *nlen = nents;
-
- return ents;
+ qsort(d->ents, d->nents, sizeof(DictEnt), entcmp);
+ return dedup(d);
}
-static DictEnt **
-make_dicts(struct Dict *dicts, size_t ndicts, size_t *nents)
+static int
+make_dicts(Dict *dicts, size_t ndicts)
{
- DictEnt **ents;
- size_t i;
-
- ents = xreallocarray(NULL, ndicts, sizeof(DictEnt *));
-
- for (i = 0; i < ndicts; i++) {
- ents[i] = make_dict(&dicts[i], &nents[i]);
- if (ents[i] == NULL)
+ for (size_t i = 0; i < ndicts; i++)
+ if (!make_dict(&dicts[i]))
die("make_dict(%s): returned NULL\n", dicts[i].rom);
- }
-
- return ents;
+ return 1;
}
static DictEnt *
@@ -380,11 +377,9 @@ print_ent(DictEnt *ent)
}
static void
-find_and_print(const char *term, DictEnt *ents, size_t nents)
+find_and_print(const char *term, Dict *d)
{
- DictEnt *ent;
-
- ent = find_ent(term, ents, nents);
+ DictEnt *ent = find_ent(term, d->ents, d->nents);
if (ent)
print_ent(ent);
else
@@ -392,13 +387,11 @@ find_and_print(const char *term, DictEnt *ents, size_t nents)
}
static void
-find_and_print_defs(struct Dict *dict, char **terms, size_t nterms)
+find_and_print_defs(Dict *dict, char **terms, size_t nterms)
{
- size_t i, nents = 0;
- DictEnt *ents;
+ size_t i;
- ents = *make_dicts(dict, 1, &nents);
- if (!ents) {
+ if (!make_dict(dict)) {
fputs("failed to allocate dict: ", stdout);
puts(dict->rom);
return;
@@ -406,20 +399,18 @@ find_and_print_defs(struct Dict *dict, char **terms, size_t nterms)
puts(dict->name);
for (i = 0; i < nterms; i++)
- find_and_print(terms[i], ents, nents);
+ find_and_print(terms[i], dict);
- free_ents(ents, nents);
+ free_ents(dict->ents, dict->nents);
}
static void
-repl(struct Dict *dicts, size_t ndicts)
+repl(Dict *dicts, size_t ndicts)
{
- DictEnt **ents;
char buf[BUFLEN];
- size_t i, *nents;
+ size_t i;
- nents = xreallocarray(NULL, ndicts, sizeof(size_t));
- ents = make_dicts(dicts, ndicts, nents);
+ make_dicts(dicts, ndicts);
for (;;) {
fputs(repl_prompt, stdout);
@@ -428,22 +419,20 @@ repl(struct Dict *dicts, size_t ndicts)
break;
for (i = 0; i < ndicts; i++) {
puts(dicts[i].name);
- find_and_print(trim(buf), ents[i], nents[i]);
+ find_and_print(trim(buf), &dicts[i]);
}
}
puts(repl_quit);
for (i = 0; i < ndicts; i++)
- free_ents(ents[i], nents[i]);
- free(ents);
- free(nents);
+ free_ents(dicts[i].ents, dicts[i].nents);
}
int
main(int argc, char *argv[])
{
char **terms = NULL, *t;
- struct Dict *dicts = NULL;
+ Dict *dicts = NULL;
size_t i, ndicts = 0, nterms = 0;
int iflag = 0;