1 /*
2 Copyright (C) 2015-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5 
6 /*
7 	WARNING: This file was generated by the dkct program (see
8 	http://dktools.sourceforge.net/ for details).
9 	Changes you make here will be lost if dkct is run again!
10 	You should modify the original source and run dkct on it.
11 	Original source: dk4loc.ctr
12 */
13 
14 /**	@file dk4loc.c The dk4loc module.
15 */
16 
17 
18 #include "dk4conf.h"
19 #include <libdk4c/dk4loc.h>
20 
21 #ifndef STDLIB_H_INCLUDED
22 #include <stdlib.h>
23 #define	STDLIB_H_INCLUDED 1
24 #endif
25 
26 #if DK4_HAVE_STRING_H
27 #ifndef STRING_H_INCLUDED
28 #include <string.h>
29 #define STRING_H_INCLUDED 1
30 #endif
31 #endif
32 
33 #if DK4_HAVE_CTYPE_H
34 #ifndef CTYPE_H_INCLUDED
35 #include <ctype.h>
36 #define	CTYPE_H_INCLUDED 1
37 #endif
38 #endif
39 
40 #ifndef DK4ENC_H_INCLUDED
41 #include <libdk4c/dk4enc.h>
42 #endif
43 
44 #ifndef DK4STR8_H_INCLUDED
45 #include <libdk4base/dk4str8.h>
46 #endif
47 
48 #if DK4_ON_WINDOWS
49 
50 #ifndef DK4WREG8_H_INCLUDED
51 #include <libdk4c/dk4wreg8.h>
52 #endif
53 #ifndef DK4WREGC_H_INCLUDED
54 #include <libdk4c/dk4wregc.h>
55 #endif
56 
57 #endif
58 
59 #if	DK4_HAVE_ASSERT_H
60 #ifndef	ASSERT_H_INCLUDED
61 #include <assert.h>
62 #define	ASSERT_H_INCLUDED 1
63 #endif
64 #endif
65 
66 
67 
68 
69 
70 /**	Keywords used by the module.
71 */
72 static const char * const dk4loc_mod_kw_8[] = {
73 /* 0 */
74 "LANG",
75 
76 /* 1 */
77 "utf8",
78 
79 /* 2 */
80 "UTF-8",
81 
82 /* 3 */
83 "Control Panel\\International",
84 
85 /* 4 */
86 "LocaleName",
87 
88 /* 5 */
89 "sLanguage",
90 
91 NULL
92 
93 };
94 
95 
96 
97 static
98 int
dk4loc_use_default(dkChar * lptr,size_t szl,dk4_er_t * erp)99 dk4loc_use_default(dkChar *lptr, size_t szl, dk4_er_t *erp)
100 {
101   int		 back = 0;
102   if ((NULL != lptr) && (2 < szl)) {
103     lptr[0] = dkT('e');
104     lptr[1] = dkT('n');
105     lptr[2] = dkT('\0');
106     back = 1;
107   } else {
108     dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
109   }
110   return back;
111 }
112 
113 
114 int
dk4loc_get_settings(dkChar * lang,size_t szlang,dkChar * reg,size_t szreg,int * enc,dk4_er_t * erp)115 dk4loc_get_settings(
116   dkChar	*lang,
117   size_t	 szlang,
118   dkChar	*reg,
119   size_t	 szreg,
120   int		*enc,
121   dk4_er_t	*erp
122 )
123 {
124 #if DK4_ON_WINDOWS
125   char		 buf[64];	/* Buffer to process getenv result */
126   void		*kptr;		/* Registry key pointer */
127   dkChar	*pd;		/* Copy string */
128   char		*p3;		/* Region */
129   char		*p4;		/* Copy string */
130   size_t	 sz;		/* String length */
131   int		 res;		/* Result from RegQueryValueEx() */
132   int		 expand	= 0;	/* Flag: Expansion necessary. */
133 #else
134   char		 buf[64];	/* Buffer to process getenv result */
135   dkChar	*pd;		/* Copy string */
136   char		*p1;		/* Result from getenv */
137   char		*p2;		/* Encoding */
138   char		*p3;		/* Region */
139   char		*p4;		/* Copy string */
140   size_t	 sz;		/* String length */
141 #endif
142   int		 back	=	0;
143 
144 #if	DK4_USE_ASSERT
145   assert(NULL != lang);
146   assert(NULL != reg);
147   assert(NULL != enc);
148   assert(0 < szlang);
149   assert(0 < szreg);
150 #endif
151   if ((NULL != lang) && (0 < szlang)) { *lang = dkT('\0'); }
152   if ((NULL != reg ) && (0 < szreg )) { *reg = dkT('\0'); }
153   if (NULL != enc) {
154 #if DK4_ON_WINDOWS
155     *enc = DK4_ENCODING_WIN1252;
156 #else
157     *enc = DK4_ENCODING_PLAIN;
158 #endif
159   }
160   if ((NULL != lang) && (NULL != reg) && (NULL != enc)) {
161     if ((0 < szlang) && (0 < szreg)) {
162 #if DK4_ON_WINDOWS
163 #if DK4_CHAR_SIZE > 1
164       *enc = DK4_ENCODING_UTF16;
165 #else
166       *enc = DK4_ENCODING_WIN1252;
167 #endif
168       kptr = dk4wreg_open_key_c8(DK4_WREGKEY_HKCU, dk4loc_mod_kw_8[3], 0, erp);
169       if (NULL != kptr) {
170         res = dk4wreg_get_string_c8(
171 	  kptr, dk4loc_mod_kw_8[4], buf, sizeof(buf), &expand, erp
172 	);
173 	if (0 != res) {
174 	  p3 = dk4str8_chr(buf, '-');
175 	  if (NULL != p3) { *(p3++) = '\0'; }
176 	  dk4str8_normalize(buf, NULL);
177 	  if (NULL != p3) { dk4str8_normalize(p3, NULL); }
178 	  sz = dk4str8_len(buf);
179 	  if (0 < sz) {
180 	    if (szlang > sz) {
181 	      /* strcpy(lang, buf); */
182 	      pd = lang; p4 = buf;
183 	      while('\0' != *p4) {
184 		*(pd++) = (dkChar)dk4str8_tolower(*(p4++));
185 	      }
186 	      *pd = dkT('\0');
187 	      back = 1;
188 	      sz = dk4str8_len(p3);
189 	      if (0 < sz) {
190 	        if (szreg > sz) {
191 		  /* strcpy(reg, p3); */
192 		  pd = reg; p4 = p3;
193 		  while('\0' != *p4) {
194 #if 0
195 		    *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
196 #endif
197 		    *(pd++) = (dkChar)dk4str8_tolower(*(p4++));
198 		  }
199 		  *pd = dkT('\0');
200 		} else {
201 		  dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
202 		  back = 0;
203 		}
204 	      }
205 	    } else {
206 	      dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
207 	    }
208 	  } else {
209 	    back = dk4loc_use_default(lang, szlang, erp);
210 	  }
211 	} else {
212 	  res = dk4wreg_get_string_c8(
213 	    kptr, dk4loc_mod_kw_8[5], buf, sizeof(buf), &expand, erp
214 	  );
215 	  if (0 != res) {
216 	    dk4str8_normalize(buf, NULL);
217 	    sz = dk4str8_len(buf);
218 	    if (2 < sz) { buf[2] = '\0'; }
219 	    sz = dk4str8_len(buf);
220 	    if (0 < sz) {
221 	      if (szlang > sz) {
222 	        pd = lang; p4 = buf;
223 		while ('\0' != *p4) {
224 		  *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
225 		}
226 		*pd = dkT('\0');
227 		back = 1;
228 	      } else {
229 	        dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
230 	      }
231 	    } else {
232 	      back = dk4loc_use_default(lang, szlang, erp);
233 	    }
234 	  } else {
235 	    back = dk4loc_use_default(lang, szlang, erp);
236 	  }
237 	}
238         dk4wreg_close_key(kptr);
239       } else {
240         back = dk4loc_use_default(lang, szlang, erp);
241       }
242 #else
243       p1 = getenv(dk4loc_mod_kw_8[0]);
244       if (NULL != p1) {
245         if (sizeof(buf) > dk4str8_len(p1)) {
246 	  dk4str8_cpy_s(buf, sizeof(buf), p1, NULL);
247 	  p2 = dk4str8_chr(buf, '.');
248 	  if (NULL != p2) {
249 	    *(p2++) = '\0';
250 	  }
251 	  p3 = dk4str8_chr(buf, '_');
252 	  if (NULL != p3) {
253 	    *(p3++) = '\0';
254 	  }
255 	  dk4str8_normalize(buf, NULL);
256 	  if (NULL != p2) { dk4str8_normalize(p2, NULL); }
257 	  if (NULL != p3) { dk4str8_normalize(p3, NULL); }
258 	  sz = dk4str8_len(buf);
259 	  if (0 < sz) {
260 	    if (szlang > sz) {
261 	      /* strcpy(lang, buf); */
262 	      pd = lang; p4 = buf;
263 	      while('\0' != *p4) {
264 	        *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
265 	      }
266 	      *pd = dkT('\0');
267 	      back = 1;
268 	      if (NULL != p3) {
269 	        sz = dk4str8_len(p3);
270 	        if (0 < sz) {
271 		  if (szreg > sz) {
272 		    /* strcpy(reg, p3); */
273 		    pd = reg; p4 = p3;
274 		    while('\0' != *p4) {
275 		      *(pd++) = (dkChar)(tolower((unsigned char)(*(p4++))));
276 		    }
277 		    *pd = dkT('\0');
278 		  } else {
279 		    dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
280 		    back = 0;
281 		  }
282 		}
283 	      }
284 #if DK4_CHAR_SIZE > 1
285 #if DK4_CHAR_SIZE > 2
286 
287 	      *enc = DK4_ENCODING_32;
288 #else
289 
290 	      *enc = DK4_ENCODING_UTF16;
291 #endif
292 #else
293 
294 	      *enc = DK4_ENCODING_PLAIN;
295 	      if (NULL != p2) {
296 	        if (0 == dk4str8_casecmp(p2, dk4loc_mod_kw_8[1])) {
297 		  *enc = DK4_ENCODING_UTF8;
298 		} else {
299 		  if (0 == dk4str8_casecmp(p2, dk4loc_mod_kw_8[2])) {
300 		    *enc = DK4_ENCODING_UTF8;
301 		  }
302 		}
303 	      }
304 #endif
305 	    } else {
306 	      dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
307 	    }
308 	  } else {
309 	    back = dk4loc_use_default(lang, szlang, erp);
310 	  }
311 	} else {
312 	  dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
313 	}
314       } else {
315         back = dk4loc_use_default(lang, szlang, erp);
316       }
317 #endif
318     } else {
319       dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
320     }
321   } else {
322     dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
323   }
324   return back;
325 }
326 
327