diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..b0ced55 --- /dev/null +++ b/src/main.c @@ -0,0 +1,270 @@ +#include "trans.h" +#include <unistd.h> + +char *sql_database; +char *sql_host; +int sql_port = 3306; +char *sql_password; +char *sql_user; +int debug; +int compile_only; +static int error_count; + +void * +emalloc(size_t size) +{ + void *ptr; + ptr = malloc(size); + if (!ptr) { + fprintf(stderr, "not enough memory\n"); + exit(1); + } + return ptr; +} + +void +efree(void *ptr) +{ + free(ptr); +} + +static RAD_LIST *node_list; + +void +register_node(RAD_LIST *hdr, RAD_LIST *descr) +{ + struct node *node = emalloc(sizeof(*node)); + struct header *prev = NULL; + int i; + + for (i = list_count(hdr)-1; i >= 0; i--) { + struct header *dp = list_item(hdr, i); + if (!dp->pos) { + if (prev) + dp->pos = prev->pos; + else { + fprintf(stderr, + "%s:%d: no POS is set for \"%s\"\n", + file_name, + input_line, + dp->key); + error_count++; + } + } + if (dp->pos) + prev = dp; + } + node->header = hdr; + node->descr = descr; + list_append(node_list, node); +} + + + +static unsigned long dict_index; +static unsigned long article_index; + +static RAD_LIST *antonym_list; +static RAD_LIST *xref_list; + +int +_emit_headers(void *item, void *data) +{ + struct header *hp = item; + char *sound; + + if (debug) + fprintf(stderr, "Emitting %s\n", hp->key); + sound = greek_to_transcription(hp->key); + if (hp->forms) + sql_query("INSERT INTO dict VALUES(%lu,\"%s\",\"%s\",\"%s\",\"%s\")", + dict_index, hp->key, sound, hp->pos, hp->forms); + else + sql_query("INSERT INTO dict (ident,word,sound,pos) VALUES(%lu,\"%s\",\"%s\",\"%s\")", + dict_index, hp->key, sound, hp->pos); + efree(sound); + return 0; +} + +int +insert_antonym(unsigned long dict_index, u_char *value) +{ + unsigned long index; + if (sql_query_n(&index, + "SELECT ident FROM dict WHERE word=\"%s\"", + value) == 0) { + sql_query("REPLACE INTO antonym VALUES (%lu,%lu)", + index, dict_index); + sql_query("REPLACE INTO antonym VALUES (%lu,%lu)", + dict_index, index); + return 0; + } + return 1; +} + +int +insert_xref(unsigned long dict_index, u_char *value) +{ + unsigned long index; + if (sql_query_n(&index, + "SELECT ident FROM dict WHERE word=\"%s\"", + value) == 0) { + sql_query("REPLACE INTO xref VALUES (%lu,%lu)", + index, dict_index); + sql_query("REPLACE INTO xref VALUES (%lu,%lu)", + dict_index, index); + return 0; + } + return 1; +} + +int +_emit_descr(void *item, void *data) +{ + struct descr *descr = item; + unsigned long index; + + switch (descr->type) { + case descr_topic: + if (sql_query_n(&index, + "SELECT ident FROM topic WHERE title=\"%s\"", + descr->value)) { + sql_query("INSERT INTO topic (title) VALUES (\"%s\")", + descr->value); + sql_query_n(&index, "SELECT LAST_INSERT_ID()"); + } + sql_query("INSERT INTO topic_tab VALUES(%lu,%lu)", + index, dict_index); + break; + + case descr_meaning: + sql_query("INSERT INTO articles VALUES (%lu, %lu, \"%s\")", + dict_index, + article_index++, + descr->value); + break; + + case descr_antonym: + if (insert_antonym(dict_index, descr->value)) { + struct xref *p = emalloc(sizeof(*p)); + p->index = dict_index; + p->value = descr->value; + list_append(antonym_list, p); + } + break; + + case descr_xref: + if (insert_xref(dict_index, descr->value)) { + struct xref *p = emalloc(sizeof(*p)); + p->index = dict_index; + p->value = descr->value; + list_append(xref_list, p); + } + break; + } + return 0; +} + +static int +cmp_descr_type(const void *a, const void *b) +{ + const struct descr *da = a, *db = b; + return da->type != db->type; +} + +int +emit_node(void *item, void *data) +{ + struct node *node = item; + article_index = 0; + + list_iterate(node->header, _emit_headers, NULL); + list_iterate(node->descr, _emit_descr, NULL); + + dict_index++; + return 0; +} + +int +_antonym_fixup(void *item, void *data) +{ + struct xref *ant = item; + if (insert_antonym(ant->index, ant->value)) { + fprintf(stderr, "unresolved antonym: %lu - \"%s\"\n", + ant->index, ant->value); + } + return 0; +} + +int +_xref_fixup(void *item, void *data) +{ + struct xref *ant = item; + if (insert_xref(ant->index, ant->value)) { + fprintf(stderr, "unresolved cross reference: %lu - \"%s\"\n", + ant->index, ant->value); + } + return 0; +} + + + +int +main(int argc, char **argv) +{ + int rc; + + while ((rc = getopt(argc, argv, "cd:h:P:p:u:v")) != EOF) { + switch (rc) { + case 'c': + compile_only = 1; + break; + case 'd': + sql_database = optarg; + break; + + case 'h': + sql_host = optarg; + break; + + case 'P': + sql_port = atoi(optarg); + break; + + case 'p': + sql_password = optarg; + break; + + case 'u': + sql_user = optarg; + break; + + case 'v': + debug++; + break; + } + } + + node_list = list_create(); + + if (parse(argv[optind]) || error_count) + return 1; + + if (compile_only) + return 0; + + sql_connect(); + + antonym_list = list_create(); + xref_list = list_create(); + + sql_query_n(&dict_index, + "SELECT ident FROM dict ORDER BY ident DESC LIMIT 1"); + + list_iterate(node_list, emit_node, NULL); + + list_iterate(antonym_list, _antonym_fixup, NULL); + list_iterate(xref_list, _xref_fixup, NULL); + sql_close(); + return 0; +} |