1 /*
2 Copyright (c) 2002-2007 Perry Rapp
3 "The MIT license"
4 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7 */
8 /*=============================================================
9 * codesets.c -- Manage the various codesets we work with
10 * Created: 2002/11 by Perry Rapp
11 *==============================================================*/
12
13
14 #include "llstdlib.h"
15 #include "codesets.h"
16 #include "gedcom.h"
17 #include "lloptions.h"
18 #include "zstr.h"
19 #include "arch.h"
20
21 #ifdef HAVE_LANGINFO_CODESET
22 # include <langinfo.h>
23 #else
24 # include "langinfz.h"
25 #endif
26
27
28
29 /*********************************************
30 * global/exported variables
31 *********************************************/
32
33 /* internal codeset of current database */
34 BOOLEAN uu8=0; /* flag if internal codeset is UTF-8 */
35 BOOLEAN gui8=0; /* flag if display output encoding is UTF-8 */
36 STRING int_codeset=0; /* internal codeset */
37
38 STRING editor_codeset_out=0; /* output to editor */
39 STRING editor_codeset_in=0; /* input from editor */
40 STRING gedcom_codeset_out=0; /* output GEDCOM files */
41 STRING gedcom_codeset_in=0; /* default for reading GEDCOM files */
42 STRING gui_codeset_in=0; /* reading characters from GUI */
43 STRING gui_codeset_out=0; /* writing characters to GUI */
44 STRING report_codeset_out=0; /* default for report output */
45 STRING report_codeset_in=0; /* default for input from reports */
46
47
48 /*********************************************
49 * external/imported variables
50 *********************************************/
51
52 /*********************************************
53 * local function prototypes
54 *********************************************/
55
56 /* alphabetical */
57 static void set_codeset_pair(CNSTRING base, CNSTRING defval, STRING *pcsout, STRING *pcsin);
58
59 /*********************************************
60 * local variables
61 *********************************************/
62 static STRING defcodeset=0;
63
64 /*********************************************
65 * local & exported function definitions
66 * body of module
67 *********************************************/
68
69 /*=================================================
70 * init_codesets -- initialize all codeset variables
71 * config file needs to have been loaded at this point
72 * Created: 2002/11/27 (Perry Rapp)
73 *===============================================*/
74 void
init_codesets(void)75 init_codesets (void)
76 {
77 STRING e=0;
78 #if defined(WIN32) && !defined(__CYGWIN__)
79 /*
80 The Win32 case is special because we care about both Windows & Console
81 codepages, at least when running in console mode.
82 */
83 char wincs[32];
84 int n = w_get_codepage();
85 sprintf(wincs, "CP%d", n);
86 strupdate(&defcodeset, wincs);
87 #else
88 STRING defval = nl_langinfo (CODESET);
89 /* nl_langinfo giving 0 on linux glibc-2.2.4-19.3 (Perry, 2002-12-01) */
90 if (!defval)
91 defval="";
92 defval = norm_charmap(defval);
93 if (!defval || !defval[0])
94 defval = "ASCII";
95 strupdate(&defcodeset, defval);
96 /*
97 We are using Markus Kuhn's emulator for systems without nl_langinfo
98 see arch/langinfo.c
99 An alternative would be to use localcharset.c, but it isn't as easy
100 to use; you have to configure config.aliases. Anyway, I have no idea
101 if anyone needs this.
102 */
103 #endif
104
105 /* internal */
106 /*
107 internal codeset is not handled here, becauase it must be checked
108 only in the database local options. It is handled in
109 update_db_options() in init.c.
110 */
111
112 /* GuiCodesetOut */
113 e = getlloptstr("GuiCodesetOut", "");
114 if (!e[0])
115 e = getlloptstr("GuiCodeset", "");
116 if (!e[0]) {
117 #ifdef WIN32
118 char temp[32];
119 int cs = (w_get_has_console() ? w_get_oemout_codepage() : w_get_codepage());
120 sprintf(temp, "CP%d", cs);
121 e = temp;
122 #else
123 e = defcodeset;
124 #endif
125 }
126 strupdate(&gui_codeset_out, e);
127 /* Now set the global variable gui8, which tells
128 us if the display output encoding is UTF-8, for
129 purposes of string length truncation */
130 gui8 = is_codeset_utf8(gui_codeset_out);
131
132 /* GuiCodesetIn */
133 e = getlloptstr("GuiCodesetIn", "");
134 if (!e[0])
135 e = getlloptstr("GuiCodeset", "");
136 if (!e[0]) {
137 #ifdef WIN32
138 char temp[32];
139 int cs = (w_get_has_console() ? w_get_oemin_codepage() : w_get_codepage());
140 sprintf(temp, "CP%d", cs);
141 e = temp;
142 #else
143 e = defcodeset;
144 #endif
145 }
146 strupdate(&gui_codeset_in, e);
147
148 /* remaining codesets are all straightforward */
149 set_codeset_pair("GedcomCodeset", defcodeset, &gedcom_codeset_out, &gedcom_codeset_in);
150 set_codeset_pair("EditorCodeset", defcodeset, &editor_codeset_out, &editor_codeset_in);
151 set_codeset_pair("ReportCodeset", defcodeset, &report_codeset_out, &report_codeset_in);
152
153 }
154 /*=================================================
155 * set_codeset_pair -- Initialize a pair of codesets
156 * eg, GedcomCodesetOut & GedcomCodesetIn
157 * Created: 2002/11/28 (Perry Rapp)
158 *===============================================*/
159 static void
set_codeset_pair(CNSTRING base,CNSTRING defval,STRING * pcsout,STRING * pcsin)160 set_codeset_pair (CNSTRING base, CNSTRING defval, STRING *pcsout, STRING *pcsin)
161 {
162 ZSTR zstr = zs_news(base);
163 CNSTRING e;
164 zs_apps(zstr, "Out");
165 e = getlloptstr(zs_str(zstr), "");
166 if (!e[0])
167 e = getlloptstr(base, "");
168 if (!e[0])
169 e = defval;
170 strupdate(pcsout, e);
171
172 zs_sets(zstr, base);
173 zs_apps(zstr, "In");
174 e = getlloptstr(zs_str(zstr), "");
175 if (!e[0])
176 e = getlloptstr(base, "");
177 if (!e[0])
178 e = defval;
179 strupdate(pcsin, e);
180 zs_free(&zstr);
181 }
182 /*=================================================
183 * term_codesets -- free all codeset variables
184 * Created: 2002/11/27 (Perry Rapp)
185 *===============================================*/
186 void
term_codesets(void)187 term_codesets (void)
188 {
189 strfree(&editor_codeset_out);
190 strfree(&editor_codeset_in);
191 strfree(&gedcom_codeset_out);
192 strfree(&gedcom_codeset_in);
193 strfree(&gui_codeset_out);
194 strfree(&gui_codeset_in);
195 strfree(&report_codeset_out);
196 strfree(&report_codeset_in);
197 }
198 /*=================================================
199 * get_defcodeset -- Return user's default codeset
200 *===============================================*/
201 CNSTRING
get_defcodeset(void)202 get_defcodeset (void)
203 {
204 return defcodeset;
205 }
206