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