1 /*
2   LibRCC - base module for language manipulations
3 
4   Copyright (C) 2005-2008 Suren A. Chilingaryan <csa@dside.dyndns.org>
5 
6   This library is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License version 2.1 or later
8   as published by the Free Software Foundation.
9 
10   This library is distributed in the hope that it will be useful, but WITHOUT
11   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
13   for more details.
14 
15   You should have received a copy of the GNU Lesser General Public License
16   along with this program; if not, write to the Free Software Foundation, Inc.,
17   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 #include <stdio.h>
21 #include <string.h>
22 #ifdef HAVE_STRINGS_H
23 # include <strings.h>
24 #endif /* HAVE_STRINGS_H */
25 
26 #include "internal.h"
27 #include "rccconfig.h"
28 #include "rcclocale.h"
29 
rccGetLanguageNumber(rcc_context ctx)30 int rccGetLanguageNumber(rcc_context ctx) {
31     if (!ctx) {
32 	if (rcc_default_ctx) ctx = rcc_default_ctx;
33 	else return 0;
34     }
35 
36     return ctx->n_languages;
37 }
38 
rccGetClassNumber(rcc_context ctx)39 int rccGetClassNumber(rcc_context ctx) {
40     if (!ctx) {
41 	if (rcc_default_ctx) ctx = rcc_default_ctx;
42 	else return 0;
43     }
44 
45     return ctx->n_classes;
46 }
47 
rccGetLanguagePointer(rcc_context ctx,rcc_language_id language_id)48 rcc_language_ptr rccGetLanguagePointer(rcc_context ctx, rcc_language_id language_id) {
49     if (!ctx) {
50 	if (rcc_default_ctx) ctx = rcc_default_ctx;
51 	else return NULL;
52     }
53     if (language_id>=ctx->n_languages) return NULL;
54     return ctx->languages[language_id];
55 }
56 
rccGetLanguageName(rcc_context ctx,rcc_language_id language_id)57 const char *rccGetLanguageName(rcc_context ctx, rcc_language_id language_id) {
58     rcc_language_ptr language;
59     language = rccGetLanguagePointer(ctx, language_id);
60     if (!language) return NULL;
61     return language->sn;
62 }
63 
rccGetLanguageByName(rcc_context ctx,const char * name)64 rcc_language_id rccGetLanguageByName(rcc_context ctx, const char *name) {
65     unsigned int i;
66 
67     if (!ctx) {
68 	if (rcc_default_ctx) ctx = rcc_default_ctx;
69 	else return (rcc_language_id)-1;
70     }
71     if (!name) return (rcc_language_id)-1;
72 
73     for (i=0;ctx->languages[i];i++)
74 	if (!strcasecmp(ctx->languages[i]->sn, name)) return (rcc_language_id)i;
75 
76     return (rcc_language_id)-1;
77 }
78 
rccCheckLanguageUsability(rcc_context ctx,rcc_language_id language_id)79 int rccCheckLanguageUsability(rcc_context ctx, rcc_language_id language_id) {
80     rcc_language_config config;
81     rcc_option_value clo;
82     rcc_engine_ptr *engines;
83     rcc_charset *charsets;
84 
85     if (!ctx) {
86 	if (rcc_default_ctx) ctx = rcc_default_ctx;
87 	else return 0;
88     }
89     if (language_id>=ctx->n_languages) return 0;
90 
91     language_id = rccGetRealLanguage(ctx, language_id);
92 
93     clo = rccGetOption(ctx, RCC_OPTION_CONFIGURED_LANGUAGES_ONLY);
94     if (clo) {
95 	config = rccCheckConfig(ctx, (rcc_language_id)language_id);
96 	if ((!config)||(!config->configured)) {
97 	    charsets = ctx->languages[language_id]->charsets;
98 	    if ((charsets[0])&&(charsets[1])&&(charsets[2])) {
99 		if (clo == 1) {
100 		    engines = ctx->languages[language_id]->engines;
101 		    if ((!engines[0])||(!engines[1])) return 0;
102 		} else return 0;
103 	    }
104 	}
105     }
106     return 1;
107 }
108 
109 
rccGetDefaultLanguage(rcc_context ctx)110 static rcc_language_id rccGetDefaultLanguage(rcc_context ctx) {
111     unsigned int i;
112     char stmp[RCC_MAX_LANGUAGE_CHARS+1];
113 
114     if (ctx->default_language) return ctx->default_language;
115 
116     if (!rccLocaleGetLanguage(stmp, ctx->locale_variable, RCC_MAX_LANGUAGE_CHARS)) {
117     	for (i=0;ctx->languages[i];i++) {
118 	    if (!strcmp(ctx->languages[i]->sn, stmp)) {
119 		if (!rccCheckLanguageUsability(ctx, (rcc_language_id)i)) break;
120 		ctx->default_language = (rcc_language_id)i;
121 		return (rcc_language_id)i;
122 	    }
123 	}
124     }
125 
126     if (ctx->n_languages>1) return (rcc_language_id)1;
127     return (rcc_language_id)-1;
128 }
129 
rccGetRealLanguage(rcc_context ctx,rcc_language_id language_id)130 rcc_language_id rccGetRealLanguage(rcc_context ctx, rcc_language_id language_id) {
131     if (!ctx) {
132 	if (rcc_default_ctx) ctx = rcc_default_ctx;
133 	else return (rcc_language_id)-1;
134     }
135     if (language_id>=ctx->n_languages) return (rcc_language_id)-1;
136 
137     if (language_id) return language_id;
138     return rccGetDefaultLanguage(ctx);
139 }
140 
rccGetRealLanguageName(rcc_context ctx,rcc_language_id language_id)141 const char *rccGetRealLanguageName(rcc_context ctx, rcc_language_id language_id) {
142     language_id = rccGetRealLanguage(ctx, language_id);
143     if (language_id == (rcc_language_id)-1) return NULL;
144 
145     return rccGetLanguageName(ctx, language_id);
146 }
147 
rccGetSelectedLanguage(rcc_context ctx)148 rcc_language_id rccGetSelectedLanguage(rcc_context ctx) {
149     if (!ctx) {
150 	if (rcc_default_ctx) ctx = rcc_default_ctx;
151 	else return (rcc_language_id)-1;
152     }
153 
154     return ctx->current_language;
155 }
156 
rccGetSelectedLanguageName(rcc_context ctx)157 const char *rccGetSelectedLanguageName(rcc_context ctx) {
158     rcc_language_id language_id;
159 
160     language_id = rccGetSelectedLanguage(ctx);
161     if (language_id == (rcc_language_id)-1) return NULL;
162 
163     return rccGetLanguageName(ctx, language_id);
164 }
165 
rccGetCurrentLanguage(rcc_context ctx)166 rcc_language_id rccGetCurrentLanguage(rcc_context ctx) {
167     if (!ctx) {
168 	if (rcc_default_ctx) ctx = rcc_default_ctx;
169 	else return (rcc_language_id)-1;
170     }
171 
172     return rccGetRealLanguage(ctx, ctx->current_language);
173 }
174 
rccGetCurrentLanguageName(rcc_context ctx)175 const char *rccGetCurrentLanguageName(rcc_context ctx) {
176     rcc_language_id language_id;
177 
178     language_id = rccGetCurrentLanguage(ctx);
179     if (language_id == (rcc_language_id)-1) return NULL;
180 
181     return rccGetLanguageName(ctx, language_id);
182 }
183 
184 
rccSetLanguage(rcc_context ctx,rcc_language_id language_id)185 int rccSetLanguage(rcc_context ctx, rcc_language_id language_id) {
186     rcc_language_config config;
187 
188     if (!ctx) {
189 	if (rcc_default_ctx) ctx = rcc_default_ctx;
190 	else return -1;
191     }
192 
193     if (language_id >= ctx->n_languages) return -1;
194     if ((!ctx->languages[language_id]->engines[0])||(!ctx->languages[language_id]->charsets[0])) return -2;
195 
196     if (ctx->current_language != language_id) {
197 	config = rccGetConfig(ctx, language_id);
198 	// NULL is Okey (Off), if (!config) return -1;
199 
200 	rccMutexLock(ctx->mutex);
201 	ctx->configure = 1;
202 	ctx->current_language = language_id;
203 	ctx->current_config = config;
204 	rccMutexUnLock(ctx->mutex);
205     }
206 
207     return 0;
208 }
209 
rccSetLanguageByName(rcc_context ctx,const char * name)210 int rccSetLanguageByName(rcc_context ctx, const char *name) {
211     rcc_language_id language_id;
212 
213     language_id = rccGetLanguageByName(ctx, name);
214     if (language_id == (rcc_language_id)-1) return -1;
215 
216     return rccSetLanguage(ctx, language_id);
217 }
218