1 /* This file is part of GNU Dico.
2    Copyright (C) 1998-2020 Sergey Poznyakoff
3 
4    GNU Dico is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8 
9    GNU Dico is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with GNU Dico.  If not, see <http://www.gnu.org/licenses/>. */
16 
17 #include <dicod.h>
18 
19 int
dicod_database_init(dicod_database_t * db)20 dicod_database_init(dicod_database_t *db)
21 {
22     dicod_module_instance_t *inst = db->instance;
23 
24     if (inst->module->dico_capabilities & DICO_CAPA_NODB) {
25 	dico_log(L_ERR, 0, _("cannot initialize database `%s': "
26 			     "module `%s' does not support databases"),
27 		 db->command, inst->ident);
28 	return 1;
29     }
30 
31     if (inst->module->dico_capabilities & DICO_CAPA_INIT_EXT) {
32 	db->mod_handle = inst->module->dico_init_db_ext(db->name,
33 							db->argc,
34 							db->argv,
35 							db->extra);
36     } else {
37 	if (db->extra) {
38 	    dico_log(L_ERR, 0, _("cannot initialize database `%s': "
39 				 "module `%s' does not support extended initialization"),
40 		     db->command, inst->ident);
41 	    return 1;
42 	}
43 
44 	db->mod_handle = inst->module->dico_init_db(db->name,
45 						    db->argc,
46 						    db->argv);
47     }
48     if (!db->mod_handle) {
49 	dico_log(L_ERR, 0, _("cannot initialize database `%s'"), db->command);
50 	return 1;
51     }
52     return 0;
53 }
54 
55 int
dicod_database_open(dicod_database_t * db)56 dicod_database_open(dicod_database_t *db)
57 {
58     dicod_module_instance_t *inst = db->instance;
59 
60     if (inst->module->dico_open) {
61 	if (inst->module->dico_open(db->mod_handle)) {
62 	    dico_log(L_ERR, 0, _("cannot open database `%s'"), db->command);
63 	    return 1;
64 	}
65     }
66 
67     if (!db->mime_headers
68 	&& inst->module->dico_version > 2
69 	&& inst->module->dico_db_mime_header) {
70 	char *str = inst->module->dico_db_mime_header(db->mod_handle);
71 	if (str) {
72 	    if (dico_header_parse(&db->mime_headers, str)) {
73 		dico_log(L_WARN, errno,
74 			 "database %s: can't parse mime headers \"%s\"",
75 			 db->name,
76 			 str);
77 	    }
78 	    free(str);
79 	}
80     }
81 
82     return 0;
83 }
84 
85 int
dicod_database_close(dicod_database_t * db)86 dicod_database_close(dicod_database_t *db)
87 {
88     int rc = 0;
89 
90     if (db->mod_handle) {
91 	dicod_module_instance_t *inst = db->instance;
92 	if (inst->module->dico_close)
93 	    rc = inst->module->dico_close(db->mod_handle);
94     }
95     return rc;
96 }
97 
98 int
dicod_database_deinit(dicod_database_t * db)99 dicod_database_deinit(dicod_database_t *db)
100 {
101     int rc = 0;
102 
103     if (db->mod_handle) {
104 	dicod_module_instance_t *inst = db->instance;
105 	if (inst->module->dico_free_db) {
106 	    rc = inst->module->dico_free_db(db->mod_handle);
107 	    db->mod_handle = NULL;
108 	}
109     }
110     return rc;
111 }
112 
113 char *
dicod_database_get_descr(dicod_database_t * db)114 dicod_database_get_descr(dicod_database_t *db)
115 {
116     if (db->descr)
117 	return db->descr;
118     else {
119 	dicod_module_instance_t *inst = db->instance;
120 	if (inst->module->dico_db_descr)
121 	    return inst->module->dico_db_descr(db->mod_handle);
122     }
123     return NULL;
124 }
125 
126 void
dicod_database_free_descr(dicod_database_t * db,char * descr)127 dicod_database_free_descr(dicod_database_t *db, char *descr)
128 {
129     if (descr && descr != db->descr)
130 	free(descr);
131 }
132 
133 char *
dicod_database_get_info(dicod_database_t * db)134 dicod_database_get_info(dicod_database_t *db)
135 {
136     if (db->info)
137 	return db->info;
138     else {
139 	dicod_module_instance_t *inst = db->instance;
140 	if (inst->module->dico_db_info)
141 	    return inst->module->dico_db_info(db->mod_handle);
142     }
143     return NULL;
144 }
145 
146 void
dicod_database_free_info(dicod_database_t * db,char * info)147 dicod_database_free_info(dicod_database_t *db, char *info)
148 {
149     if (info && info != db->info)
150 	free(info);
151 }
152 
153 void
dicod_database_get_languages(dicod_database_t * db,dico_list_t dlist[])154 dicod_database_get_languages(dicod_database_t *db, dico_list_t dlist[])
155 {
156     if (!(db->flags & DICO_DBF_LANG)) {
157 	dicod_module_instance_t *inst = db->instance;
158 	if (inst->module->dico_db_lang) {
159 	    /* FIXME: Return code? */
160 	    inst->module->dico_db_lang(db->mod_handle, db->langlist);
161 	    if (db->langlist[0] || db->langlist[1]) {
162 		if (!db->langlist[0])
163 		    db->langlist[0] = dicod_langlist_copy(db->langlist[1]);
164 		else if (!db->langlist[1])
165 		    db->langlist[1] = dicod_langlist_copy(db->langlist[0]);
166 	    }
167 	    if (dicod_any_lang_list_p(db->langlist[0]))
168 		dico_list_destroy(&db->langlist[0]);
169 	    if (dicod_any_lang_list_p(db->langlist[1]))
170 		dico_list_destroy(&db->langlist[1]);
171 	}
172 	db->flags |= DICO_DBF_LANG;
173     }
174     dlist[0] = db->langlist[0];
175     dlist[1] = db->langlist[1];
176 }
177 
178 dicod_db_result_t *
dicod_database_match(dicod_database_t * db,const dico_strategy_t strat,const char * word)179 dicod_database_match(dicod_database_t *db, const dico_strategy_t strat,
180 		     const char *word)
181 {
182     struct dico_database_module *mod = db->instance->module;
183     dico_result_t res = mod->dico_match(db->mod_handle, strat, word);
184     return dicod_db_result_alloc(db, res);
185 }
186 
187 dicod_db_result_t *
dicod_database_define(dicod_database_t * db,const char * word)188 dicod_database_define(dicod_database_t *db, const char *word)
189 {
190     struct dico_database_module *mod = db->instance->module;
191     dico_result_t res = mod->dico_define(db->mod_handle, word);
192     return dicod_db_result_alloc(db, res);
193 }
194 
195 int
dicod_database_flags(dicod_database_t const * db)196 dicod_database_flags(dicod_database_t const *db)
197 {
198     struct dico_database_module *mod = db->instance->module;
199     if (mod->dico_version > 2 && mod->dico_db_flags)
200 	return mod->dico_db_flags(db->mod_handle) & DICO_DBF_MASK;
201     return DICO_DBF_DEFAULT;
202 }
203 
204