diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2004-02-13 14:21:02 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2004-02-13 14:21:02 +0000 |
commit | cf6bfb57a877b35ffae958c2baa11fc4bebd93e5 (patch) | |
tree | 93f0d7b92a513a4b02bb6111675235fa5a8301d4 /src | |
parent | eb7a03ba9271bf0956686e9e3ecad5b511b1d637 (diff) | |
download | ellinika-cf6bfb57a877b35ffae958c2baa11fc4bebd93e5.tar.gz ellinika-cf6bfb57a877b35ffae958c2baa11fc4bebd93e5.tar.bz2 |
Initial revision
git-svn-id: file:///home/puszcza/svnroot/ellinika/trunk@2 941c8c0f-9102-463b-b60b-cd22ce0e6858
Diffstat (limited to 'src')
-rw-r--r-- | src/.gdbinit | 1 | ||||
-rw-r--r-- | src/Makefile | 20 | ||||
-rw-r--r-- | src/emit.c | 109 | ||||
-rw-r--r-- | src/gram.y | 181 | ||||
-rw-r--r-- | src/input.l | 54 | ||||
-rw-r--r-- | src/list.c | 317 | ||||
-rw-r--r-- | src/list.h | 48 | ||||
-rw-r--r-- | src/main.c | 270 | ||||
-rw-r--r-- | src/mem.h | 2 | ||||
-rw-r--r-- | src/sql.c | 107 | ||||
-rw-r--r-- | src/trans.h | 49 | ||||
-rw-r--r-- | src/xcript.c | 137 |
12 files changed, 1295 insertions, 0 deletions
diff --git a/src/.gdbinit b/src/.gdbinit new file mode 100644 index 0000000..9f53896 --- /dev/null +++ b/src/.gdbinit @@ -0,0 +1 @@ +set args -v -d ellinika ../data/dict.1 diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..cfd269d --- /dev/null +++ b/src/Makefile @@ -0,0 +1,20 @@ +CFLAGS=-ggdb -I. + +trans: y.tab.o lex.yy.o main.c list.o sql.o xcript.o + cc -otrans -ggdb main.c y.tab.o lex.yy.o list.o sql.o xcript.o -ll -L/usr/local/lib/mysql -lmysqlclient + +y.tab.c y.tab.h: gram.y + yacc -vtd gram.y + +lex.yy.c: input.l + lex input.l + +lex.yy.o: lex.yy.c y.tab.h trans.h + +y.tab.o: trans.h + +list.o: list.c list.h + +sql.o: sql.c trans.h + +xcript.o: xcript.c trans.h
\ No newline at end of file diff --git a/src/emit.c b/src/emit.c new file mode 100644 index 0000000..ff99700 --- /dev/null +++ b/src/emit.c @@ -0,0 +1,109 @@ +#include "trans.h" +#include <unistd.h> + +static unsigned long dict_index; +static unsigned long article_index; + +static RAD_LIST *antonym_list; + +int +_emit_headers(void *item, void *data) +{ + struct header *hp = item; + if (hp->forms) + sql_query("INSERT INTO dict VALUES(%lu,'%s','%s','%s')", + dict_index, hp->key, hp->pos, hp->forms); + else + sql_query("INSERT INTO dict (ident,word,pos) VALUES(%lu,'%s','%s')", + dict_index, hp->key, hp->pos); + return 0; +} + +static int +_antonym_cmp(const void *item, const void *data) +{ + const struct antonym *a = item, *b = data; + return !(a->index == b->index && strcmp(a->value, b->value) == 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 +_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 antonym *p = emalloc(sizeof(*p)); + p->index = dict_index; + p->value = descr->value; + list_append(antonym_list, p); + } + } + 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; +} + +void +emit_node(RAD_LIST *hdr, RAD_LIST *descr) +{ + article_index = 0; + + list_iterate(hdr, _emit_headers, NULL); + list_iterate(descr, _emit_descr, NULL); + + dict_index++; +} + +int +_antonym_fixup(void *item, void *data) +{ + struct antonym *ant = item; + if (insert_antonym(ant->index, ant->value)) { + fprintf(stderr, "unhandled antonym: %lu - \"%s\"\n", + ant->index, ant->value); + } + return 0; +} diff --git a/src/gram.y b/src/gram.y new file mode 100644 index 0000000..c065bcf --- /dev/null +++ b/src/gram.y @@ -0,0 +1,181 @@ +%{ +#include "trans.h" +#define obstack_chunk_alloc malloc +#define obstack_chunk_free free +#include <obstack.h> + +struct obstack stk; + +struct descr *make_descr(enum descr_type type, u_char *value); + +%} + +%token NODE POS END MEANING ALIAS ANT TOPIC FORMS XREF +%token <string> STRING + +%type <string> string pos forms +%type <header> nodehdr alias +%type <descr> descr +%type <list> aliases descrlist header + +%union { + u_char *string; + struct header *header; + struct descr *descr; + RAD_LIST *list; +}; + + +%% + +input : list + ; + +list : node + | list node + ; + +node : header descrlist end + { + register_node($1, $2); + } + ; + +end : END + ; + +header : nodehdr + { + $$ = list_create(); + list_append($$, $1); + } + | nodehdr aliases + { + list_prepend($2, $1); + $$ = $2; + } + ; + +nodehdr : NODE string pos forms + { + $$ = emalloc(sizeof(*$$)); + $$->key = $2; + $$->pos = $3; + $$->forms = $4; + } + ; + +pos : /* empty */ + { + $$ = NULL; + } + | POS string + { + $$ = $2; + } + ; + +forms : /* empty */ + { + $$ = NULL; + } + | FORMS string + { + $$ = $2; + } + ; + +aliases : alias + { + $$ = list_create(); + list_append($$, $1); + } + | aliases alias + { + list_append($1, $2); + $$ = $1; + } + ; + +alias : ALIAS string pos forms + { + $$ = emalloc(sizeof(*$$)); + $$->key = $2; + $$->pos = $3; + $$->forms = $4; + } + ; + +descrlist: descr + { + $$ = list_create(); + list_append($$, $1); + } + | descrlist descr + { + list_append($1, $2); + $$ = $1; + } + ; + +descr : TOPIC string + { + $$ = make_descr(descr_topic, $2); + } + | MEANING string + { + $$ = make_descr(descr_meaning, $2); + } + | ANT string + { + $$ = make_descr(descr_antonym, $2); + } + | XREF string + { + $$ = make_descr(descr_xref, $2); + } + ; + +string : mstring + { + obstack_1grow(&stk, 0); + $$ = obstack_finish(&stk); + } + ; + +mstring : STRING + { + obstack_grow(&stk, $1, strlen($1)); + } + | mstring STRING + { + obstack_1grow(&stk, '\n'); + obstack_grow(&stk, $2, strlen($2)); + } + ; + +%% + +yyerror(char *s) +{ + fprintf (stderr, "%s:%d: %s\n", + file_name, input_line, s); +} + +int +parse(char *name) +{ + if (name) + open_input(name); + obstack_init(&stk); + return yyparse(); +} + +struct descr * +make_descr(enum descr_type type, u_char *value) +{ + struct descr *p = emalloc(sizeof(*p)); + p->type = type; + p->value = value; + return p; +} diff --git a/src/input.l b/src/input.l new file mode 100644 index 0000000..542c897 --- /dev/null +++ b/src/input.l @@ -0,0 +1,54 @@ +%{ +#include "trans.h" +#include "y.tab.h" + +char *file_name = "<stdin>"; +int input_line = 1; + +#define isws(c) ((c)==' ' || (c)=='\t') +%} + +MWS [ \t]* +WS [ \t]+ +%% +#.*\n input_line++; +^[nN][oO][dD][eE] return NODE; +^[pP][oO][sS] return POS; +^[eE][nN][dD] return END; +^[mM][eE][aA][nN][iI][nN][gG] return MEANING; +^[aA][lL][iI][aA][sS] return ALIAS; +^[aA][nN][tT] return ANT; +^[tT][oO][pP][iI][cC] return TOPIC; +^[fF][oO][rR][mM][sS] return FORMS; +^[xX][rR][eE][fF] return XREF; +\n input_line++; +{WS}[^\n]+\n { + char *p, *q; + + for (p = yytext + yyleng - 1; p > yytext && isspace(*p); p--) + ; + p[1] = 0; + input_line++; + yylval.string = yytext+1; + return STRING; +} +. { fprintf (stderr, "%s:%d: stray character %c\n", + file_name, input_line, yytext[0]); + exit(1); } + +%% + +void +open_input(char *name) +{ + yyin = fopen(name, "r"); + if (!yyin) { + fprintf (stderr, "cannot open "); + perror (name); + exit (1); + } + file_name = name; +} + + + diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000..5d25a74 --- /dev/null +++ b/src/list.c @@ -0,0 +1,317 @@ +/* This file is part of GNU Radius. + Copyright (C) 2003 Free Software Foundation + + GNU Radius is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GNU Radius is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Radius; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <sys/types.h> +#include <stdlib.h> +#include <mem.h> +#include <list.h> + +struct list_entry { + struct list_entry *next; + void *data; +}; + +struct list { + size_t count; + struct list_entry *head, *tail; + struct iterator *itr; +}; + +struct iterator { + struct iterator *next; + RAD_LIST *list; + struct list_entry *cur; + int advanced; +}; + +struct list * +list_create() +{ + struct list *p = emalloc(sizeof(*p)); + p->head = p->tail = NULL; + p->itr = NULL; + return p; +} + +void +list_destroy(struct list **plist, list_iterator_t user_free, void *data) +{ + struct list_entry *p; + + if (!*plist) + return; + + p = (*plist)->head; + while (p) { + struct list_entry *next = p->next; + if (user_free) + user_free(p->data, data); + efree(p); + p = next; + } + efree(*plist); + *plist = NULL; +} + +void * +iterator_current(ITERATOR *ip) +{ + if (!ip) + return NULL; + return ip->cur ? ip->cur->data : NULL; +} + +ITERATOR * +iterator_create(RAD_LIST *list) +{ + ITERATOR *itr; + + if (!list) + return NULL; + itr = emalloc(sizeof(*itr)); + itr->list = list; + itr->cur = NULL; + itr->next = list->itr; + itr->advanced = 0; + list->itr = itr; + return itr; +} + +void +iterator_destroy(ITERATOR **ip) +{ + ITERATOR *itr, *prev; + + if (!ip || !*ip) + return; + for (itr = (*ip)->list->itr, prev = NULL; + itr; + prev = itr, itr = itr->next) + if (*ip == itr) + break; + if (itr) { + if (prev) + prev->next = itr->next; + else + itr->list->itr = itr->next; + efree(itr); + *ip = NULL; + } + +} + +void * +iterator_first(ITERATOR *ip) +{ + if (!ip) + return NULL; + ip->cur = ip->list->head; + ip->advanced = 0; + return iterator_current(ip); +} + +void * +iterator_next(ITERATOR *ip) +{ + if (!ip || !ip->cur) + return NULL; + if (!ip->advanced) + ip->cur = ip->cur->next; + ip->advanced = 0; + return iterator_current(ip); +} + +static void +_iterator_advance(ITERATOR *ip, struct list_entry *e) +{ + for (; ip; ip = ip->next) { + if (ip->cur == e) { + ip->cur = e->next; + ip->advanced++; + } + } +} + +void * +list_item(struct list *list, size_t n) +{ + struct list_entry *p; + if (n >= list->count) + return NULL; + for (p = list->head; n > 0 && p; p = p->next, n--) + ; + return p->data; +} + +size_t +list_count(struct list *list) +{ + if (!list) + return 0; + return list->count; +} + +void +list_concat(struct list *a, struct list *b) +{ + if (a->tail) + a->tail->next = b->head; + else + a->head = b->head; + a->tail = b->tail; + a->count += b->count; + + b->count = 0; + b->head = b->tail = NULL; +} + +void +list_append(struct list *list, void *data) +{ + struct list_entry *ep; + + if (!list) + return; + ep = emalloc(sizeof(*ep)); + ep->next = NULL; + ep->data = data; + if (list->tail) + list->tail->next = ep; + else + list->head = ep; + list->tail = ep; + list->count++; +} + +void +list_prepend(struct list *list, void *data) +{ + struct list_entry *ep; + + if (!list) + return; + ep = emalloc(sizeof(*ep)); + ep->data = data; + ep->next = list->head; + list->head = ep; + if (!list->tail) + list->tail = list->head; + list->count++; +} + +static int +cmp_ptr(const void *a, const void *b) +{ + return a != b; +} + +void * +list_remove(struct list *list, void *data, list_comp_t cmp) +{ + struct list_entry *p, *prev; + + if (!list) + return NULL; + if (!list->head) + return NULL; + if (!cmp) + cmp = cmp_ptr; + for (p = list->head, prev = NULL; p; prev = p, p = p->next) + if (cmp(p->data, data) == 0) + break; + + if (!p) + return 0; + _iterator_advance(list->itr, p); + if (p == list->head) { + list->head = list->head->next; + if (!list->head) + list->tail = NULL; + } else + prev->next = p->next; + + if (p == list->tail) + list->tail = prev; + + efree(p); + list->count--; + + return data; +} + +void +list_iterate(struct list *list, list_iterator_t func, void *data) +{ + ITERATOR *itr; + void *p; + + if (!list) + return; + itr = iterator_create(list); + if (!itr) + return; + for (p = iterator_first(itr); p; p = iterator_next(itr)) { + if (func(p, data)) + break; + } + iterator_destroy(&itr); +} + +void * +list_locate(struct list *list, void *data, list_comp_t cmp) +{ + struct list_entry *cur; + if (!list) + return NULL; + if (!cmp) + cmp = cmp_ptr; + for (cur = list->head; cur; cur = cur->next) + if (cmp(cur->data, data) == 0) + break; + return cur ? cur->data : NULL; +} + +int +list_insert_sorted(struct list *list, void *data, list_comp_t cmp) +{ + struct list_entry *cur, *prev; + + if (!list) + return -1; + if (!cmp) + return -1; + + for (cur = list->head, prev = NULL; cur; prev = cur, cur = cur->next) + if (cmp(cur->data, data) > 0) + break; + + if (!prev) { + list_prepend(list, data); + } else if (!cur) { + list_append(list, data); + } else { + struct list_entry *ep = emalloc(sizeof(*ep)); + ep->data = data; + ep->next = cur; + prev->next = ep; + } + return 0; +} + diff --git a/src/list.h b/src/list.h new file mode 100644 index 0000000..ee79cd1 --- /dev/null +++ b/src/list.h @@ -0,0 +1,48 @@ +/* This file is part of GNU Radius + Copyright (C) 2003 Free Software Foundation, Inc. + + Written by Sergey Poznyakoff + + GNU Radius is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GNU Radius is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Radius; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef LIST_H +#define LIST_H + +typedef struct list RAD_LIST; +typedef struct iterator ITERATOR; + +typedef int (*list_iterator_t)(void *item, void *data); +typedef int (*list_comp_t)(const void *, const void *); + +RAD_LIST *list_create(); +void list_destroy(RAD_LIST **list, list_iterator_t free, void *data); +void list_iterate(RAD_LIST *list, list_iterator_t itr, void *data); +void *list_item(RAD_LIST *list, size_t n); +size_t list_count(RAD_LIST *list); +void list_append(RAD_LIST *list, void *data); +void list_prepend(RAD_LIST *list, void *data); +int list_insert_sorted(struct list *list, void *data, list_comp_t cmp); +void *list_locate(RAD_LIST *list, void *data, list_comp_t cmp); +void *list_remove(RAD_LIST *list, void *data, list_comp_t cmp); + +void *iterator_current(ITERATOR *ip); +ITERATOR *iterator_create(RAD_LIST *list); +void iterator_destroy(ITERATOR **ip); +void *iterator_first(ITERATOR *ip); +void *iterator_next(ITERATOR *ip); + + +#endif + 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; +} diff --git a/src/mem.h b/src/mem.h new file mode 100644 index 0000000..644ec19 --- /dev/null +++ b/src/mem.h @@ -0,0 +1,2 @@ +extern void *emalloc(size_t size); +extern void efree(void *ptr); diff --git a/src/sql.c b/src/sql.c new file mode 100644 index 0000000..4b1a02b --- /dev/null +++ b/src/sql.c @@ -0,0 +1,107 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <mysql/mysql.h> +#include "trans.h" + +MYSQL mysql; +MYSQL_RES *result; + +void +sql_connect() +{ + if (!mysql_real_connect(&mysql, + sql_host, sql_user, + sql_password, sql_database, sql_port, + NULL, 0)) { + fprintf(stderr, + "cannot connect to MySQL server: %s\n", + mysql_error(&mysql)); + exit(1); + } + +} + +void +sql_close() +{ + mysql_close(&mysql); +} + +int +va_sql_query(char *fmt, va_list ap) +{ + char *buf = NULL; + int rc; + + if (result) { + mysql_free_result(result); + result = NULL; + } + + vasprintf(&buf, fmt, ap); + if (debug) + fprintf(stderr, "Executing query: %s\n", buf); + rc = mysql_query(&mysql, buf); + if (rc) { + fprintf(stderr, "MySQL Error: %s\n", mysql_error(&mysql)); + if (!debug) + fprintf(stderr, "The failed query was: %s\n", buf); + } else { + result = mysql_store_result(&mysql); + if (result) { + if (debug) + fprintf(stderr, "Query returned %lu rows\n", + mysql_num_rows(result)); + } else { + if (mysql_field_count(&mysql) == 0) { + /* query does not return data */ + if (debug) + fprintf(stderr, + "Query affected %lu rows\n", + mysql_affected_rows(&mysql)); + } else { + fprintf(stderr, + "MySQL Error: %s\n", + mysql_error(&mysql)); + if (!debug) + fprintf(stderr, + "The failed query was: %s\n", + buf); + rc = 1; + } + } + } + + free(buf); + return rc; +} + +int +sql_query(char *fmt, ...) +{ + va_list ap; + int rc; + va_start(ap, fmt); + rc = va_sql_query(fmt, ap); + va_end(ap); + return rc; +} + +int +sql_query_n(unsigned long *pret, char *fmt, ...) +{ + va_list ap; + int rc; + va_start(ap, fmt); + rc = va_sql_query(fmt, ap); + va_end(ap); + if (rc == 0) { + MYSQL_ROW row = mysql_fetch_row(result); + if (row) + *pret = strtoul (row[0], NULL, 0); + else + rc = 1; + } + return rc; +} diff --git a/src/trans.h b/src/trans.h new file mode 100644 index 0000000..4b6b35a --- /dev/null +++ b/src/trans.h @@ -0,0 +1,49 @@ +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include "list.h" +#include "mem.h" + +extern char *file_name; +extern int input_line; + +struct header { + u_char *key; + char *pos; + u_char *forms; +}; + +struct node { + RAD_LIST *header; + RAD_LIST *descr; +}; + +enum descr_type { + descr_topic, + descr_meaning, + descr_antonym, + descr_xref +}; + +struct descr { + enum descr_type type; + u_char *value; +}; + +struct xref { + unsigned long index; + u_char *value; +}; + +void open_input(char *name); +int sql_query(char *fmt, ...); +int sql_query_n(unsigned long *pret, char *fmt, ...); + +extern char *sql_database; +extern char *sql_host; +extern int sql_port; +extern char *sql_password; +extern char *sql_user; +extern int debug; + diff --git a/src/xcript.c b/src/xcript.c new file mode 100644 index 0000000..1c9234f --- /dev/null +++ b/src/xcript.c @@ -0,0 +1,137 @@ +#include "trans.h" + +struct xcript_tab { + char *in; + char *out; +}; + + +struct xcript_tab xcript_tab[] = { + { "μπ", "b" }, + { "γγ", "g" }, + { "γκ", "g" }, + { "γχ", "g" }, + { "ντ", "d" }, + { "αι", "e" }, + { "αί", "e" }, + { "αυ", "au"}, + { "αύ", "au"}, + { "ου", "ou"}, + { "ού", "ou"}, + { "ευ", "eu"}, + { "εύ", "eu"}, + { "οι", "i" }, + { "ει", "i" }, + { "εί", "i" }, + { "υι", "i" }, + + { "α", "a" }, + { "Α", "a" }, + { "Ά", "a" }, + { "ά", "a" }, + { "β", "b" }, + { "Β", "b" }, + { "γ", "g" }, + { "Γ", "g" }, + { "δ", "d" }, + { "Δ", "d" }, + { "ε", "e" }, + { "Ε", "e" }, + { "Έ", "e" }, + { "έ", "e" }, + { "ζ", "z" }, + { "Ζ", "z" }, + { "η", "i" }, + { "Η", "i" }, + { "Ή", "i" }, + { "ή", "i" }, + { "θ", "t" }, + { "Θ", "t" }, + { "ι", "i" }, + { "Ι", "i" }, + { "Ί", "i" }, + { "ί", "i" }, + { "κ", "k" }, + { "Κ", "k" }, |