1 /* This file is part of Dico.
2 Copyright (C) 2008-2020 Sergey Poznyakoff
3
4 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 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 Dico. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <dicod.h>
18
19 dico_list_t dicod_lang_lazy_prefs;
20 dico_list_t dicod_lang_prefs[2];
21
22 static int
cmp_string_ci(const void * a,const void * b,void * closure)23 cmp_string_ci(const void *a, const void *b, void *closure)
24 {
25 return c_strcasecmp(a, b);
26 }
27
28 int
dicod_lang_check(dico_list_t list[2])29 dicod_lang_check(dico_list_t list[2])
30 {
31 if (!list[0] && !list[1])
32 return 1;
33
34 if (dicod_lang_lazy_prefs) {
35 if (list[0] && dico_list_intersect_p(dicod_lang_lazy_prefs, list[0],
36 cmp_string_ci, NULL))
37 return 1;
38 if (list[1] && dico_list_intersect_p(dicod_lang_lazy_prefs, list[1],
39 cmp_string_ci, NULL))
40 return 1;
41 return 0;
42 }
43
44 if (dicod_lang_prefs[0] && list[0]
45 && !dico_list_intersect_p(dicod_lang_prefs[0], list[0],
46 cmp_string_ci, NULL))
47 return 0;
48 if (dicod_lang_prefs[1] && list[1]
49 && !dico_list_intersect_p(dicod_lang_prefs[1], list[1],
50 cmp_string_ci, NULL))
51 return 0;
52 return 1;
53 }
54
55 void
dicod_lang(dico_stream_t str,int argc,char ** argv)56 dicod_lang(dico_stream_t str, int argc, char **argv)
57 {
58 dico_list_destroy(&dicod_lang_lazy_prefs);
59 dico_list_destroy(&dicod_lang_prefs[0]);
60 dico_list_destroy(&dicod_lang_prefs[1]);
61 if (argc > 2) {
62 int n = 0;
63 int i;
64
65 for (i = 2; i < argc; i++) {
66 if (n == 0 && strcmp(argv[i], ":") == 0)
67 n = 1;
68 else {
69 if (!dicod_lang_prefs[n]) {
70 dicod_lang_prefs[n] = xdico_list_create();
71 dico_list_set_free_item(dicod_lang_prefs[n],
72 dicod_free_item, NULL);
73 }
74 xdico_list_append(dicod_lang_prefs[n], xstrdup(argv[i]));
75 }
76 }
77 if (n == 0) {
78 dicod_lang_lazy_prefs = dicod_lang_prefs[0];
79 dicod_lang_prefs[0] = NULL;
80 }
81 }
82 check_db_visibility();
83 stream_writez(str, "250 ok - set language preferences\n");
84 }
85
86 static int
_display_pref(void * item,void * data)87 _display_pref(void *item, void *data)
88 {
89 dico_stream_t str = data;
90 stream_writez(str, " ");
91 stream_writez(str, item);
92 return 0;
93 }
94
95 static void
show_lang_lists(dico_stream_t str,dico_list_t list[2])96 show_lang_lists(dico_stream_t str, dico_list_t list[2])
97 {
98 dico_list_iterate(list[0], _display_pref, str);
99 dico_stream_write(str, " :", 2);
100 dico_list_iterate(list[1], _display_pref, str);
101 dico_stream_write(str, "\n", 1);
102 }
103
104 void
dicod_show_lang_pref(dico_stream_t str,int argc,char ** argv)105 dicod_show_lang_pref(dico_stream_t str, int argc, char **argv)
106 {
107 stream_writez(str, "280");
108 if (dicod_lang_lazy_prefs) {
109 dico_list_iterate(dicod_lang_lazy_prefs, _display_pref, str);
110 dico_stream_write(str, "\n", 1);
111 } else
112 show_lang_lists(str, dicod_lang_prefs);
113 }
114
115 void
dicod_show_lang_info(dico_stream_t str,int argc,char ** argv)116 dicod_show_lang_info(dico_stream_t str, int argc, char **argv)
117 {
118 dicod_database_t *db = find_database(argv[3]);
119 if (!db) {
120 stream_writez(str,
121 "550 invalid database, use SHOW DB for a list\n");
122 } else {
123 dico_list_t langlist[2];
124
125 dicod_database_get_languages(db, langlist);
126 stream_writez(str, "280");
127 show_lang_lists(str, langlist);
128 }
129 }
130
131 static int
_show_database_lang(void * item,void * data)132 _show_database_lang(void *item, void *data)
133 {
134 dicod_database_t *db = item;
135 dico_stream_t str = data;
136 dico_list_t langlist[2];
137 dicod_database_get_languages(db, langlist);
138 stream_printf(str, "%s", db->name);
139 show_lang_lists(str, langlist);
140 return 0;
141 }
142
143 void
dicod_show_lang_db(dico_stream_t str,int argc,char ** argv)144 dicod_show_lang_db(dico_stream_t str, int argc, char **argv)
145 {
146 size_t count = database_count();
147 if (count == 0)
148 stream_printf(str, "554 No databases present\n");
149 else {
150 dico_stream_t ostr;
151
152 stream_printf(str, "110 %lu databases present\n",
153 (unsigned long) count);
154 ostr = dicod_ostream_create(str, NULL);
155 database_iterate(_show_database_lang, ostr);
156 dico_stream_close(ostr);
157 dico_stream_destroy(&ostr);
158 stream_writez(str, ".\n");
159 stream_writez(str, "250 ok\n");
160 }
161 }
162
163 void
register_lang(void)164 register_lang(void)
165 {
166 static struct dicod_command cmd[] = {
167 { "OPTION LANG", 2, DICOD_MAXPARAM_INF, "[list]",
168 "define language preferences",
169 dicod_lang },
170 { "SHOW LANG DB", 3, 3, NULL,
171 "show databases with their language preferences",
172 dicod_show_lang_db },
173 { "SHOW LANG DATABASES", 3, 3, NULL,
174 "show databases with their language preferences",
175 dicod_show_lang_db },
176 { "SHOW LANG INFO", 4, 4, "database",
177 "show language preferences of a database",
178 dicod_show_lang_info },
179 { "SHOW LANG PREF", 3, 3, NULL,
180 "show server language preferences",
181 dicod_show_lang_pref },
182 { NULL }
183 };
184 dicod_capa_register("lang", cmd, NULL, NULL);
185 }
186