1 /*
2 LibRCC - language configuration: supported charsets and engines, various
3 options
4
5 Copyright (C) 2005-2008 Suren A. Chilingaryan <csa@dside.dyndns.org>
6
7 This library is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License version 2.1 or later
9 as published by the Free Software Foundation.
10
11 This library is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23
24 #include <string.h>
25 #ifdef HAVE_STRINGS_H
26 # include <strings.h>
27 #endif /* HAVE_STRINGS_H */
28
29 #include "../config.h"
30
31 #include "internal.h"
32 #include "rccconfig.h"
33 #include "rcclocale.h"
34 #include "rcclist.h"
35 #include "lng.h"
36
rccConfigGetLanguage(rcc_language_config config)37 rcc_language_id rccConfigGetLanguage(rcc_language_config config) {
38 unsigned long i;
39 rcc_language_ptr *llist;
40
41 if (!config) return (rcc_language_id)-1;
42
43 llist = rccGetLanguageList(config->ctx);
44 for (i=0;llist[i];i++)
45 if (llist[i] == config->language) return (rcc_language_id)i;
46
47 return (rcc_language_id)-1;
48 }
49
rccConfigGetLanguagePointer(rcc_language_config config)50 rcc_language_ptr rccConfigGetLanguagePointer(rcc_language_config config) {
51 if (!config) return NULL;
52
53 return config->language;
54 }
55
rccConfigGetLanguageName(rcc_language_config config)56 const char *rccConfigGetLanguageName(rcc_language_config config) {
57 if ((!config)||(!config->language)) return NULL;
58
59 return config->language->sn;
60 }
61
rccConfigGetCharsetNumber(rcc_language_config config)62 int rccConfigGetCharsetNumber(rcc_language_config config) {
63 int i;
64 rcc_charset *charsets;
65
66 if ((!config)||(!config->language)) return 0;
67
68 charsets = config->language->charsets;
69
70 for (i=0;charsets[i];i++);
71
72 return i;
73 }
74
rccConfigGetClassCharsetNumber(rcc_language_config config,rcc_class_id class_id)75 int rccConfigGetClassCharsetNumber(rcc_language_config config, rcc_class_id class_id) {
76 int sum, i;
77 rcc_charset *charsets;
78
79 if ((!config)||(!config->language)) return 0;
80 if ((class_id<0)||(class_id>=config->ctx->n_classes)) return 0;
81
82 sum = rccConfigGetCharsetNumber(config);
83
84 charsets = config->ctx->iclass[class_id].additional;
85 if (charsets) {
86 for (i=0;charsets[i];i++)
87 if (rccConfigGetCharsetByName(config, charsets[i]) == (rcc_language_id)-1) sum++;
88 }
89
90 return sum;
91 }
92
rccConfigGetEngineNumber(rcc_language_config config)93 int rccConfigGetEngineNumber(rcc_language_config config) {
94 int i;
95 rcc_engine_ptr *engines;
96
97 if ((!config)||(!config->language)) return 0;
98 engines = config->language->engines;
99 for (i=0;engines[i];i++);
100 return i;
101 }
102
103
rccConfigGetEnginePointer(rcc_language_config config,rcc_engine_id engine_id)104 rcc_engine_ptr rccConfigGetEnginePointer(rcc_language_config config, rcc_engine_id engine_id) {
105 if ((!config)||(!config->language)) return NULL;
106 if (engine_id == (rcc_engine_id)-1) return NULL;
107 if (engine_id>=rccConfigGetEngineNumber(config)) return NULL;
108
109 return config->language->engines[engine_id];
110 }
111
rccConfigCheckEnginePointer(rcc_language_config config,rcc_engine_id engine_id)112 rcc_engine_ptr rccConfigCheckEnginePointer(rcc_language_config config, rcc_engine_id engine_id) {
113 rcc_engine_ptr engine;
114
115 engine = rccConfigGetEnginePointer(config, engine_id);
116 if ((engine)||(engine->func)) return engine;
117 return NULL;
118 }
119
rccConfigGetCurrentEnginePointer(rcc_language_config config)120 rcc_engine_ptr rccConfigGetCurrentEnginePointer(rcc_language_config config) {
121 rcc_engine_id engine_id;
122
123 engine_id = rccConfigGetCurrentEngine(config);
124 if (engine_id == (rcc_engine_id)-1) return NULL;
125
126 return rccConfigGetEnginePointer(config, engine_id);
127 }
128
rccConfigCheckCurrentEnginePointer(rcc_language_config config)129 rcc_engine_ptr rccConfigCheckCurrentEnginePointer(rcc_language_config config) {
130 rcc_engine_ptr engine;
131
132 engine = rccConfigGetCurrentEnginePointer(config);
133 if ((engine)||(engine->func)) return engine;
134 return NULL;
135 }
136
137
rccConfigGetEngineName(rcc_language_config config,rcc_engine_id engine_id)138 const char *rccConfigGetEngineName(rcc_language_config config, rcc_engine_id engine_id) {
139 rcc_engine_ptr engine;
140
141 if (!engine_id) return rcc_disabled_engine_sn;
142 if ((!config)||(!config->language)) return NULL;
143
144 if (engine_id == (rcc_engine_id)-1) return rcc_engine_nonconfigured;
145
146 engine = rccConfigGetEnginePointer(config, engine_id);
147 if (!engine) return NULL;
148
149 return engine->title;
150 }
151
rccConfigGetCharsetName(rcc_language_config config,rcc_charset_id charset_id)152 const char *rccConfigGetCharsetName(rcc_language_config config, rcc_charset_id charset_id) {
153 if (!charset_id) return rcc_default_charset;
154
155 if ((!config)||(!config->language)) return NULL;
156 if (charset_id>=rccConfigGetCharsetNumber(config)) return NULL;
157
158 return config->language->charsets[charset_id];
159 }
160
rccConfigGetClassCharsetName(rcc_language_config config,rcc_class_id class_id,rcc_charset_id charset_id)161 const char *rccConfigGetClassCharsetName(rcc_language_config config, rcc_class_id class_id, rcc_charset_id charset_id) {
162 unsigned int i, pos;
163 rcc_charset *charsets;
164
165 if (!charset_id) return rcc_default_charset;
166
167 if ((!config)||(!config->language)) return NULL;
168 if ((class_id<0)||(class_id>=config->ctx->n_classes)) return NULL;
169
170 pos = rccConfigGetCharsetNumber(config);
171 if (charset_id < pos) return rccConfigGetCharsetName(config, charset_id);
172
173 charset_id -= pos;
174
175 charsets = config->ctx->iclass[class_id].additional;
176 if (!charsets) return NULL;
177
178 for (i=0;charsets[i];i++)
179 if (rccConfigGetCharsetByName(config, charsets[i]) == (rcc_language_id)-1) {
180 if (!charset_id) break;
181 charset_id--;
182 }
183
184 return charsets[i];
185 }
186
rccConfigGetAutoCharsetName(rcc_language_config config,rcc_autocharset_id charset_id)187 const char *rccConfigGetAutoCharsetName(rcc_language_config config, rcc_autocharset_id charset_id) {
188 unsigned int i;
189 rcc_engine_id engine_id;
190 rcc_charset *charsets;
191 rcc_engine_ptr *engines;
192
193 if ((!config)||(!config->language)) return NULL;
194 engine_id = rccConfigGetCurrentEngine(config);
195 if (engine_id == (rcc_engine_id)-1) return NULL;
196
197 engines = config->language->engines;
198 charsets = engines[engine_id]->charsets;
199
200 for (i=0;charsets[i];i++);
201 if (charset_id>=i) return NULL;
202
203 return charsets[charset_id];
204 }
205
206
rccConfigGetEngineByName(rcc_language_config config,const char * name)207 rcc_engine_id rccConfigGetEngineByName(rcc_language_config config, const char *name) {
208 unsigned int i;
209 rcc_engine **engines;
210
211 if ((!config)||(!config->language)||(!name)) return (rcc_engine_id)-1;
212
213 engines = config->language->engines;
214 for (i=0;engines[i];i++)
215 if (!strcasecmp(engines[i]->title,name)) return (rcc_engine_id)i;
216
217 return (rcc_engine_id)-1;
218 }
219
rccConfigGetCharsetByName(rcc_language_config config,const char * name)220 rcc_charset_id rccConfigGetCharsetByName(rcc_language_config config, const char *name) {
221 unsigned int i;
222 rcc_charset *charsets;
223
224 if ((!config)||(!config->language)||(!name)) return (rcc_charset_id)-1;
225
226 charsets = config->language->charsets;
227 for (i=0;charsets[i];i++)
228 if (!strcasecmp(charsets[i],name)) return (rcc_charset_id)i;
229
230 return (rcc_charset_id)-1;
231 }
232
rccConfigGetClassCharsetByName(rcc_language_config config,rcc_class_id class_id,const char * name)233 rcc_charset_id rccConfigGetClassCharsetByName(rcc_language_config config, rcc_class_id class_id, const char *name) {
234 unsigned int pos, i = 0;
235 rcc_charset_id charset_id;
236 rcc_charset *charsets;
237
238 if ((!config)||(!config->language)||(!name)) return (rcc_charset_id)-1;
239 if ((class_id<0)||(class_id>=config->ctx->n_classes)) return (rcc_charset_id)-1;
240
241 charset_id = rccConfigGetCharsetByName(config, name);
242 if (charset_id != (rcc_charset_id)-1) return charset_id;
243
244 pos = rccConfigGetCharsetNumber(config);
245
246 charsets = config->ctx->iclass[class_id].additional;
247 if (!charsets) return (rcc_charset_id)-1;
248
249 for (i=0;charsets[i];i++)
250 if (rccConfigGetCharsetByName(config, charsets[i]) == (rcc_language_id)-1) {
251 if (!strcasecmp(charsets[i], name)) return pos;
252 pos++;
253 }
254
255 return (rcc_charset_id)-1;
256 }
257
rccConfigGetAutoCharsetByName(rcc_language_config config,const char * name)258 rcc_autocharset_id rccConfigGetAutoCharsetByName(rcc_language_config config, const char *name) {
259 unsigned int i;
260 rcc_engine_id engine_id;
261 rcc_charset *charsets;
262 rcc_engine_ptr *engines;
263
264 if ((!config)||(!config->language)||(!name)) return (rcc_autocharset_id)-1;
265
266 engine_id = rccConfigGetCurrentEngine(config);
267 if (engine_id == (rcc_engine_id)-1) return (rcc_autocharset_id)-1;
268
269 engines = config->language->engines;
270 charsets = engines[engine_id]->charsets;
271
272 for (i=0;charsets[i];i++)
273 if (!strcasecmp(charsets[i],name)) return (rcc_autocharset_id)i;
274
275 return (rcc_autocharset_id)-1;
276 }
277
rccConfigIsDisabledCharset(rcc_language_config config,rcc_class_id class_id,rcc_charset_id charset_id)278 int rccConfigIsDisabledCharset(rcc_language_config config, rcc_class_id class_id, rcc_charset_id charset_id) {
279 rcc_charset charset;
280
281 if ((!config)||(!config->language)) return (rcc_autocharset_id)-1;
282
283 charset = rccConfigGetClassCharsetName(config, class_id, charset_id);
284 if (!charset) return -1;
285
286 return rccIsDisabledCharsetName(config->ctx, class_id, charset);
287 }
288
rccConfigInit(rcc_language_config config,rcc_context ctx)289 int rccConfigInit(rcc_language_config config, rcc_context ctx) {
290 int err;
291 unsigned int i;
292 rcc_charset_id *charsets;
293 rcc_charset_id *dcharsets;
294 rcc_iconv *iconv_to;
295 rcc_mutex mutex;
296
297 if ((!ctx)||(!config)) return -1;
298
299 charsets = (rcc_charset_id*)malloc((ctx->max_classes)*sizeof(rcc_charset_id));
300 dcharsets = (rcc_charset_id*)malloc((ctx->max_classes)*sizeof(rcc_charset_id));
301 iconv_to = (rcc_iconv*)malloc((ctx->max_classes)*sizeof(rcc_iconv));
302 mutex = rccMutexCreate();
303 if ((!charsets)||(!dcharsets)||(!iconv_to)||(!mutex)) {
304 if (mutex) rccMutexFree(mutex);
305 if (dcharsets) free(dcharsets);
306 if (charsets) free(charsets);
307 if (iconv_to) free(iconv_to);
308 return -1;
309 }
310
311 err = rccEngineInitContext(&config->engine_ctx, config);
312 if (err) {
313 if (mutex) rccMutexFree(mutex);
314 if (dcharsets) free(dcharsets);
315 if (charsets) free(charsets);
316 if (iconv_to) free(iconv_to);
317 return -1;
318 }
319
320 for (i=0;i<ctx->max_classes;i++) {
321 dcharsets[i] = 0;
322 charsets[i] = 0;
323 iconv_to[i] = NULL;
324 }
325
326 config->fsiconv = NULL;
327 config->trans = NULL;
328 config->entrans = NULL;
329
330 config->ctx = ctx;
331 config->language = NULL;
332 config->charset = charsets;
333 config->engine = -1;
334 config->default_charset = dcharsets;
335 config->configured = 0;
336 config->speller = NULL;
337 config->mutex = mutex;
338
339 config->iconv_to = iconv_to;
340 config->configure = 1;
341
342 return 0;
343 }
344
rccConfigFreeIConv(rcc_language_config config)345 void rccConfigFreeIConv(rcc_language_config config) {
346 unsigned int i;
347
348 if ((!config)||(!config->charset)) return;
349
350 if (config->fsiconv) {
351 rccIConvClose(config->fsiconv);
352 config->fsiconv = NULL;
353 }
354
355 for (i=0;i<config->ctx->n_classes;i++) {
356 if (config->iconv_to[i]) {
357 rccIConvClose(config->iconv_to[i]);
358 config->iconv_to[i] = NULL;
359 }
360 }
361 }
362
rccConfigClear(rcc_language_config config)363 void rccConfigClear(rcc_language_config config) {
364 if ((config)&&(config->charset)) {
365 rccEngineFreeContext(&config->engine_ctx);
366 rccConfigFreeIConv(config);
367 if (config->trans) {
368 rccTranslateClose(config->trans);
369 config->trans = NULL;
370 }
371 if (config->entrans) {
372 rccTranslateClose(config->entrans);
373 config->entrans = NULL;
374 }
375 if (config->iconv_to) {
376 free(config->iconv_to);
377 config->iconv_to = NULL;
378 }
379 if (config->charset) {
380 free(config->charset);
381 config->charset = NULL;
382 }
383 if (config->default_charset) {
384 free(config->default_charset);
385 config->default_charset = NULL;
386 }
387 if (config->speller) {
388 rccSpellerFree(config->speller);
389 config->speller = NULL;
390 }
391 if (config->mutex) {
392 rccMutexFree(config->mutex);
393 config->mutex = NULL;
394 }
395 }
396 }
397
rccGetConfigPointer(rcc_context ctx,rcc_language_id language_id,rcc_language_id * r_language_id)398 static rcc_language_config rccGetConfigPointer(rcc_context ctx, rcc_language_id language_id, rcc_language_id *r_language_id) {
399
400 language_id = rccGetRealLanguage(ctx, language_id);
401 if (!strcasecmp(ctx->languages[language_id]->sn, rcc_disabled_language_sn)) return NULL;
402 if (r_language_id) *r_language_id = language_id;
403
404 return ctx->configs + language_id;
405 }
406
rccCheckConfig(rcc_context ctx,rcc_language_id language_id)407 rcc_language_config rccCheckConfig(rcc_context ctx, rcc_language_id language_id) {
408 rcc_language_config config;
409
410 config = rccGetConfigPointer(ctx, language_id, NULL);
411 if ((config)&&(!config->charset)) return NULL;
412
413 return config;
414 }
415
416
rccGetUsableConfig(rcc_context ctx,rcc_language_id language_id)417 rcc_language_config rccGetUsableConfig(rcc_context ctx, rcc_language_id language_id) {
418 rcc_language_config config;
419
420 config = rccGetConfigPointer(ctx, language_id, &language_id);
421 if (config) {
422 if (!rccCheckLanguageUsability(ctx, language_id)) return NULL;
423 if ((!config->charset)&&(rccConfigInit(config, ctx))) return NULL;
424 config->language = ctx->languages[language_id];
425 }
426
427 return config;
428 }
429
rccGetConfig(rcc_context ctx,rcc_language_id language_id)430 rcc_language_config rccGetConfig(rcc_context ctx, rcc_language_id language_id) {
431 rcc_language_config config;
432
433 config = rccGetConfigPointer(ctx, language_id, &language_id);
434 if (config) {
435 if ((!config->charset)&&(rccConfigInit(config, ctx))) return NULL;
436 config->language = ctx->languages[language_id];
437 }
438
439 return config;
440 }
441
rccGetConfigByName(rcc_context ctx,const char * name)442 rcc_language_config rccGetConfigByName(rcc_context ctx, const char *name) {
443 rcc_language_id language_id;
444
445 language_id = rccGetLanguageByName(ctx, name);
446 if (language_id == (rcc_language_id)-1) return NULL;
447
448 return rccGetConfig(ctx, language_id);
449 }
450
rccGetCurrentConfig(rcc_context ctx)451 rcc_language_config rccGetCurrentConfig(rcc_context ctx) {
452 rcc_language_id language_id;
453
454 language_id = rccGetCurrentLanguage(ctx);
455 if (language_id == (rcc_language_id)-1) return NULL;
456
457 return rccGetConfig(ctx, language_id);
458 }
459
rccConfigGetSpeller(rcc_language_config config)460 rcc_speller rccConfigGetSpeller(rcc_language_config config) {
461 unsigned int i;
462 rcc_speller speller;
463 rcc_language_config pconfig;
464 rcc_language_id *parents;
465 rcc_language_id language_id;
466 if (!config) return NULL;
467
468 rccMutexLock(config->mutex);
469 if (!config->speller) {
470 config->speller = rccSpellerCreate(config->language->sn);
471
472 if (config->speller) language_id = rccConfigGetLanguage(config);
473 else language_id = (rcc_language_id)-1;
474 if (language_id != (rcc_language_id)-1) parents = ((rcc_language_internal*)config->language)->parents;
475 else parents = NULL;
476
477 if (parents) {
478 for (i = 0; parents[i]!=(rcc_language_id)-1; i++) {
479 pconfig = rccGetConfig(config->ctx, parents[i]);
480 if (pconfig) {
481 speller = rccConfigGetSpeller(pconfig);
482 rccSpellerAddParrent(config->speller, speller);
483 }
484 }
485 }
486 }
487 rccMutexUnLock(config->mutex);
488
489 return config->speller;
490 }
491
rccConfigGetTranslator(rcc_language_config config,rcc_language_id to)492 rcc_translate rccConfigGetTranslator(rcc_language_config config, rcc_language_id to) {
493 rcc_option_value timeout;
494 rcc_option_value offline;
495
496 if (!config) return NULL;
497
498 rccMutexLock(config->mutex);
499 if ((config->trans)&&(config->translang != to)) {
500 rccTranslateClose(config->trans);
501 config->trans = NULL;
502 }
503
504 if (!config->trans) {
505 config->trans = rccTranslateOpen(config->language->sn, rccGetLanguageName(config->ctx, to));
506 if (config->trans) {
507 config->translang = to;
508 timeout = rccGetOption(config->ctx, RCC_OPTION_TIMEOUT);
509 if (timeout) rccTranslateSetTimeout(config->trans, timeout);
510
511 offline = rccGetOption(config->ctx, RCC_OPTION_OFFLINE);
512 if (offline) rccTranslateAllowOfflineMode(config->trans);
513 }
514 }
515 rccMutexUnLock(config->mutex);
516
517 return config->trans;
518 }
519
rccConfigGetEnglishTranslator(rcc_language_config config)520 rcc_translate rccConfigGetEnglishTranslator(rcc_language_config config) {
521 rcc_option_value timeout;
522
523 if (!config) return NULL;
524
525 rccMutexLock(config->mutex);
526 if (!config->entrans) {
527 config->entrans = rccTranslateOpen(config->language->sn, rcc_english_language_sn);
528 if (config->entrans) {
529 timeout = rccGetOption(config->ctx, RCC_OPTION_TIMEOUT);
530 if (timeout) rccTranslateSetTimeout(config->entrans, timeout);
531 }
532 }
533 rccMutexUnLock(config->mutex);
534
535 return config->entrans;
536 }
537
rccConfigGetSelectedEngine(rcc_language_config config)538 rcc_engine_id rccConfigGetSelectedEngine(rcc_language_config config) {
539 if (!config) return (rcc_engine_id)-1;
540
541 return config->engine;
542 }
543
rccConfigGetSelectedEngineName(rcc_language_config config)544 const char *rccConfigGetSelectedEngineName(rcc_language_config config) {
545 rcc_engine_id engine_id;
546
547 engine_id = rccConfigGetSelectedEngine(config);
548 if (engine_id == (rcc_engine_id)-1) return rcc_engine_nonconfigured;
549 if (!config->language) return NULL;
550
551 return rccConfigGetEngineName(config, engine_id);
552 }
553
rccConfigGetCurrentEngine(rcc_language_config config)554 rcc_engine_id rccConfigGetCurrentEngine(rcc_language_config config) {
555 rcc_engine **enginelist;
556 rcc_engine_id engine_id;
557
558 if (!config) return (rcc_engine_id)-1;
559
560 engine_id = rccConfigGetSelectedEngine(config);
561 if (engine_id != (rcc_engine_id)-1) return engine_id;
562
563 if (!config->language) return (rcc_engine_id)-1;
564 else enginelist = config->language->engines;
565
566 if (enginelist[0]) {
567 if (enginelist[1]) return (rcc_engine_id)1;
568 return (rcc_engine_id)0;
569 }
570 return (rcc_engine_id)-1;
571 }
572
rccConfigGetCurrentEngineName(rcc_language_config config)573 const char *rccConfigGetCurrentEngineName(rcc_language_config config) {
574 rcc_engine_id engine_id;
575
576 engine_id = rccConfigGetCurrentEngine(config);
577 if ((engine_id == (rcc_engine_id)-1)||(!config->language)) return NULL;
578
579 return rccConfigGetEngineName(config, engine_id);
580 }
581
rccConfigGetSelectedCharset(rcc_language_config config,rcc_class_id class_id)582 rcc_charset_id rccConfigGetSelectedCharset(rcc_language_config config, rcc_class_id class_id) {
583 if ((!config)||(!config->ctx)||(class_id<0)||(class_id>=config->ctx->n_classes)) return (rcc_charset_id)-1;
584
585 return config->charset[class_id];
586 }
587
rccConfigGetSelectedCharsetName(rcc_language_config config,rcc_class_id class_id)588 const char *rccConfigGetSelectedCharsetName(rcc_language_config config, rcc_class_id class_id) {
589 rcc_charset_id charset_id;
590
591 charset_id = rccConfigGetSelectedCharset(config, class_id);
592 if ((charset_id == (rcc_charset_id)-1)||(!config->language)) return NULL;
593
594 return rccConfigGetClassCharsetName(config, class_id, charset_id);
595 }
596
rccConfigGetCurrentCharset(rcc_language_config config,rcc_class_id class_id)597 rcc_charset_id rccConfigGetCurrentCharset(rcc_language_config config, rcc_class_id class_id) {
598 rcc_language_config enconfig;
599 unsigned int i, max;
600 rcc_charset_id charset_id;
601 rcc_charset_id all_charset_id = (rcc_language_id)-1;
602 const char *charset;
603
604 rcc_class_default_charset *defcharset;
605 const char *lang;
606
607 // rcc_language *language;
608 rcc_class_ptr *classes;
609
610 rcc_class *cl;
611
612 const char *defvalue;
613
614 if ((!config)||(!config->ctx)||(class_id<0)||(class_id>=config->ctx->n_classes)) return -1;
615
616 charset_id = config->charset[class_id];
617 if (charset_id) return charset_id;
618
619 enconfig = rccGetConfigByName(config->ctx, rcc_english_language_sn);
620 if ((enconfig)&&(enconfig!=config)) {
621 charset_id = enconfig->charset[class_id];
622 if (charset_id) {
623 charset = rccConfigGetClassCharsetName(enconfig, class_id, charset_id);
624 if ((charset)&&(rccIsUnicode(charset))) return charset_id;
625 }
626 }
627
628 if (!config->language) return (rcc_charset_id)-1;
629 // else language = config->language;
630
631 classes = config->ctx->classes;
632
633 cl = classes[class_id];
634 defvalue = cl->defvalue;
635 if (defvalue) {
636 for (i=0;classes[i];i++) {
637 if (!strcmp(classes[i]->name, defvalue))
638 return rccConfigGetCurrentCharset(config, i);
639 }
640 }
641
642 if (config->default_charset[class_id]) return config->default_charset[class_id];
643
644 if (cl->defvalue) {
645 charset_id = rccConfigGetLocaleClassCharset(config, class_id, defvalue);
646 if ((charset_id != 0)&&(charset_id != (rcc_charset_id)-1)) {
647 if (!rccConfigIsDisabledCharset(config, class_id, charset_id)) {
648 config->default_charset[class_id] = charset_id;
649 return charset_id;
650 }
651 }
652 }
653
654 if (cl->defvalue) {
655 charset_id = rccConfigGetClassCharsetByName(config, class_id, defvalue);
656 if ((charset_id != 0)&&(charset_id != (rcc_charset_id)-1)) {
657 if (!rccConfigIsDisabledCharset(config, class_id, charset_id)) {
658 config->default_charset[class_id] = charset_id;
659 return charset_id;
660 }
661 }
662 }
663
664 defcharset = cl->defcharset;
665 if (defcharset) {
666 lang = config->language->sn;
667
668 for (i = 0; cl->defcharset[i].lang; i++) {
669 if (!strcasecmp(lang, defcharset[i].lang)) {
670 charset_id = rccConfigGetClassCharsetByName(config, class_id, defcharset[i].charset);
671 if ((charset_id != 0)&&(charset_id != (rcc_charset_id)-1)) {
672 if (!rccConfigIsDisabledCharset(config, class_id, charset_id)) {
673 config->default_charset[class_id] = charset_id;
674 return charset_id;
675 } else {
676 all_charset_id = (rcc_charset_id)-1;
677 break;
678 }
679 } else {
680 all_charset_id = (rcc_charset_id)-1;
681 break;
682 }
683 } else if (!strcasecmp(rcc_default_all, defcharset[i].lang)) {
684 charset_id = rccConfigGetClassCharsetByName(config, class_id, defcharset[i].charset);
685 if ((charset_id != 0)&&(charset_id != (rcc_charset_id)-1)) {
686 all_charset_id = charset_id;
687 }
688 }
689 }
690
691 if (all_charset_id != (rcc_language_id)-1) {
692 if (!rccConfigIsDisabledCharset(config, class_id, all_charset_id)) {
693 config->default_charset[class_id] = all_charset_id;
694 return all_charset_id;
695 }
696 }
697 }
698
699 charset_id = rccConfigGetLocaleClassCharset(config, class_id, config->ctx->locale_variable);
700 if ((charset_id != 0)&&(charset_id != (rcc_charset_id)-1)) {
701 if (!rccConfigIsDisabledCharset(config, class_id, charset_id)) {
702 config->default_charset[class_id] = charset_id;
703 return charset_id;
704 }
705 }
706
707 max = rccConfigGetClassCharsetNumber(config, class_id);
708 for (i = 1; i< max; i++)
709 if (!rccConfigIsDisabledCharset(config, class_id, (rcc_charset_id)i)) {
710 return (rcc_charset_id)i;
711 }
712
713 return (rcc_charset_id)-1;
714 }
715
rccConfigGetCurrentCharsetName(rcc_language_config config,rcc_class_id class_id)716 const char *rccConfigGetCurrentCharsetName(rcc_language_config config, rcc_class_id class_id) {
717 rcc_charset_id charset_id;
718
719 charset_id = rccConfigGetCurrentCharset(config, class_id);
720 if ((charset_id == (rcc_charset_id)-1)||(!config->language)) return NULL;
721
722 return rccConfigGetClassCharsetName(config, class_id, charset_id);
723 }
724
725
rccConfigSetEngine(rcc_language_config config,rcc_engine_id engine_id)726 int rccConfigSetEngine(rcc_language_config config, rcc_engine_id engine_id) {
727 unsigned int i;
728
729 if ((!config)||(!config->language)) return -1;
730
731 if (engine_id != (rcc_engine_id)-1) {
732 for (i=0;config->language->engines[i];i++);
733 if (engine_id >= i) return -1;
734 }
735
736 if (config->engine != engine_id) {
737 rccMutexLock(config->mutex);
738 if (config->ctx->current_config == config) config->ctx->configure = 1;
739 config->configure = 1;
740 config->engine = engine_id;
741 rccMutexUnLock(config->mutex);
742 }
743
744 config->configured = 1;
745
746 return 0;
747 }
748
rccConfigSetEngineByName(rcc_language_config config,const char * name)749 int rccConfigSetEngineByName(rcc_language_config config, const char *name) {
750 rcc_engine_id engine_id;
751
752 if (!config) return -1;
753
754 if ((!name)||(!strcasecmp(name,rcc_engine_nonconfigured)))
755 return rccConfigSetEngine(config, (rcc_engine_id)-1);
756
757 engine_id = rccConfigGetEngineByName(config, name);
758 if (engine_id == (rcc_engine_id)-1) return -1;
759
760 return rccConfigSetEngine(config, engine_id);
761 }
762
rccConfigSetCharset(rcc_language_config config,rcc_class_id class_id,rcc_charset_id charset_id)763 int rccConfigSetCharset(rcc_language_config config, rcc_class_id class_id, rcc_charset_id charset_id) {
764 if ((!config)||(!config->language)||(class_id < 0)||(class_id >= config->ctx->n_classes)) return -1;
765
766 if (charset_id >= rccConfigGetClassCharsetNumber(config, class_id)) return -1;
767 if (rccConfigIsDisabledCharset(config, class_id, charset_id)) return -1;
768
769 if (config->charset[class_id] != charset_id) {
770 if (config->ctx->classes[class_id]->flags&RCC_CLASS_FLAG_CONST) return -1;
771
772 rccMutexLock(config->mutex);
773 if (config->ctx->current_config == config) config->ctx->configure = 1;
774 config->configure = 1;
775 config->charset[class_id] = charset_id;
776 rccMutexUnLock(config->mutex);
777 }
778
779 config->configured = 1;
780
781 return 0;
782 }
783
rccConfigSetCharsetByName(rcc_language_config config,rcc_class_id class_id,const char * name)784 int rccConfigSetCharsetByName(rcc_language_config config, rcc_class_id class_id, const char *name) {
785 rcc_charset_id charset_id;
786
787 charset_id = rccConfigGetClassCharsetByName(config, class_id, name);
788 if (charset_id == (rcc_charset_id)-1) return -1;
789
790 return rccConfigSetCharset(config, class_id, charset_id);
791 }
792
rccConfigGetLocaleCharset(rcc_language_config config,const char * locale_variable)793 rcc_charset_id rccConfigGetLocaleCharset(rcc_language_config config, const char *locale_variable) {
794 const char *lv;
795 rcc_language_id language_id;
796 char lang[RCC_MAX_CHARSET_CHARS+1];
797 char stmp[RCC_MAX_CHARSET_CHARS+1];
798
799 if ((!config)||(!config->language)) return (rcc_charset_id)-1;
800
801 lv = locale_variable?locale_variable:config->ctx->locale_variable;
802
803 language_id = rccGetLanguageByName(config->ctx, config->language->sn);
804 if (language_id != (rcc_language_id)-1) {
805 if (!rccLocaleGetCharset(stmp, lv, RCC_MAX_CHARSET_CHARS)) {
806 if (rccIsUnicode(stmp))
807 return rccConfigGetCharsetByName(config, stmp);
808 if ((!rccLocaleGetLanguage(lang, lv, RCC_MAX_CHARSET_CHARS))&&(!strcmp(config->language->sn, lang)))
809 return rccConfigGetCharsetByName(config, stmp);
810 }
811 }
812
813 return (rcc_charset_id)-1;
814 }
815
rccConfigGetLocaleClassCharset(rcc_language_config config,rcc_class_id class_id,const char * locale_variable)816 rcc_charset_id rccConfigGetLocaleClassCharset(rcc_language_config config, rcc_class_id class_id, const char *locale_variable) {
817 const char *lv;
818 rcc_language_id language_id;
819 char lang[RCC_MAX_CHARSET_CHARS+1];
820 char stmp[RCC_MAX_CHARSET_CHARS+1];
821
822 if ((!config)||(!config->language)) return (rcc_charset_id)-1;
823
824 lv = locale_variable?locale_variable:config->ctx->locale_variable;
825
826 language_id = rccGetLanguageByName(config->ctx, config->language->sn);
827 if (language_id != (rcc_language_id)-1) {
828 if (!rccLocaleGetCharset(stmp, lv, RCC_MAX_CHARSET_CHARS)) {
829 if (rccIsUnicode(stmp))
830 return rccConfigGetClassCharsetByName(config, class_id, stmp);
831 if ((!rccLocaleGetLanguage(lang, lv, RCC_MAX_CHARSET_CHARS))&&(!strcmp(config->language->sn, lang)))
832 return rccConfigGetClassCharsetByName(config, class_id, stmp);
833 }
834 }
835
836 return (rcc_charset_id)-1;
837 }
838
839
rccConfigConfigure(rcc_language_config config)840 int rccConfigConfigure(rcc_language_config config) {
841 int err;
842 rcc_context ctx;
843 const char *charset;
844 unsigned int i;
845
846 if (!config) return -1;
847 if (!config->configure) return 0;
848
849 rccMutexLock(config->mutex);
850
851 ctx = config->ctx;
852
853 rccConfigFreeIConv(config);
854 for (i=0;i<ctx->n_classes;i++) {
855 charset = rccConfigGetCurrentCharsetName(config, (rcc_class_id)i);
856 if ((!charset)||(rccIsUTF8(charset))) continue;
857 config->iconv_to[i] = rccIConvOpen(charset, "UTF-8");
858 }
859
860 err = rccEngineConfigure(&config->engine_ctx);
861 if (!err) config->configure = 0;
862
863 rccMutexUnLock(config->mutex);
864
865
866 return err;
867 }
868
869
870 /*
871 rcc_option_value options[RCC_MAX_OPTIONS];
872
873 int rccConfigInit(rcc_language_config config, rcc_context ctx) {
874 for (i=0;i<RCC_MAX_OPTIONS;i++)
875 config->options[i] = 0;
876 }
877
878 rcc_option_value rccConfigGetOption(rcc_language_config config, rcc_option option) {
879 if ((!config)||(option<0)||(option>=RCC_MAX_OPTIONS)) return -1;
880
881 return config->options[option];
882 }
883
884 int rccConfigSetOption(rcc_language_config config, rcc_option option, rcc_option_value value) {
885 if ((!config)||(option>=RCC_MAX_OPTIONS)) return -1;
886 if (config->options[option] != value) {
887 if (config->ctx->current_config == config) config->ctx->configure = 1;
888 config->options[option]=value;
889 }
890
891 return 0;
892 }
893
894 rcc_option_value rccConfigGetOption(rcc_language_config config, rcc_option option);
895 int rccConfigSetOption(rcc_language_config config, rcc_option option, rcc_option_value value);
896 #define rccGetOption(ctx, option) rccConfigGetOption(ctx->current_config, option)
897 #define rccSetOption(ctx,option,value) rccConfigSetOption(ctx->current_config, option, value)
898 */
899