1 /**
2  * D header file for POSIX's <locale.h>.
3  *
4  * See_Also:  https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/locale.h.html
5  * Copyright: D Language Foundation, 2019
6  * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  * Authors:   Mathias 'Geod24' Lang
8  * Standards: The Open Group Base Specifications Issue 7, 2018 edition
9  * Source:    $(DRUNTIMESRC core/sys/posix/_locale.d)
10  */
11 module core.sys.posix.locale;
12 
13 version (Posix):
14 extern(C):
15 nothrow:
16 @nogc:
17 
18 version (OSX)
19     version = Darwin;
20 else version (iOS)
21     version = Darwin;
22 else version (TVOS)
23     version = Darwin;
24 else version (WatchOS)
25     version = Darwin;
26 
27 version (Darwin)
28     version = DarwinBSDLocale;
29 version (FreeBSD)
30     version = DarwinBSDLocale;
31 version (NetBSD)
32     version = DarwinBSDLocale;
33 version (DragonFlyBSD)
34     version = DarwinBSDLocale;
35 
36 version (CRuntime_Glibc)
37     version = GNULinuxLocale;
38 version (CRuntime_Bionic)
39     version = GNULinuxLocale;
40 version (CRuntime_UClibc)
41     version = GNULinuxLocale;
42 
43 version (DarwinBSDLocale)
44 {
45     ///
46     struct lconv
47     {
48         char*   decimal_point;
49         char*   thousands_sep;
50         char*   grouping;
51         char*   int_curr_symbol;
52         char*   currency_symbol;
53         char*   mon_decimal_point;
54         char*   mon_thousands_sep;
55         char*   mon_grouping;
56         char*   positive_sign;
57         char*   negative_sign;
58         char    int_frac_digits;
59         char    frac_digits;
60         char    p_cs_precedes;
61         char    p_sep_by_space;
62         char    n_cs_precedes;
63         char    n_sep_by_space;
64         char    p_sign_posn;
65         char    n_sign_posn;
66         char    int_p_cs_precedes;
67         char    int_n_cs_precedes;
68         char    int_p_sep_by_space;
69         char    int_n_sep_by_space;
70         char    int_p_sign_posn;
71         char    int_n_sign_posn;
72     }
73 
74     ///
75     enum
76     {
77         LC_ALL      = 0,
78         LC_COLLATE  = 1,
79         LC_CTYPE    = 2,
80         LC_MESSAGES = 6,
81         LC_MONETARY = 3,
82         LC_NUMERIC  = 4,
83         LC_TIME     = 5,
84     }
85 
86     private struct _xlocale;
87 
88     ///
89     alias locale_t = _xlocale*;
90 
91     version (NetBSD)
92         enum LC_ALL_MASK = (cast(int)~0);
93     else
94         enum LC_ALL_MASK = (
95             LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK |
96             LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK);
97 
98 
99     ///
100     enum
101     {
102         LC_COLLATE_MASK  = (1 << 0),
103         LC_CTYPE_MASK    = (1 << 1),
104         LC_MESSAGES_MASK = (1 << 2),
105         LC_MONETARY_MASK = (1 << 3),
106         LC_NUMERIC_MASK  = (1 << 4),
107         LC_TIME_MASK     = (1 << 5),
108     }
109 
110     ///
111     enum LC_GLOBAL_LOCALE = (cast(locale_t)-1);
112 
113     /// Duplicate existing locale
114     locale_t duplocale(locale_t locale);
115     /// Free an allocated locale
116     void     freelocale(locale_t locale);
117     /// Natural language formatting for C
118     lconv*   localeconv();
119     /// Create a new locale
120     locale_t newlocale(int mask, const char* locale, locale_t base);
121     /// Set the C library's notion of natural language formatting style
122     char*    setlocale(int category, const char* locale);
123     /// Set the per-thread locale
124     locale_t uselocale (locale_t locale);
125 }
126 else version (GNULinuxLocale)
127 {
128     ///
129     struct lconv
130     {
131         char*   decimal_point;
132         char*   thousands_sep;
133         char*   grouping;
134         char*   int_curr_symbol;
135         char*   currency_symbol;
136         char*   mon_decimal_point;
137         char*   mon_thousands_sep;
138         char*   mon_grouping;
139         char*   positive_sign;
140         char*   negative_sign;
141         char    int_frac_digits;
142         char    frac_digits;
143         char    p_cs_precedes;
144         char    p_sep_by_space;
145         char    n_cs_precedes;
146         char    n_sep_by_space;
147         char    p_sign_posn;
148         char    n_sign_posn;
149         char    int_p_cs_precedes;
150         char    int_p_sep_by_space;
151         char    int_n_cs_precedes;
152         char    int_n_sep_by_space;
153         char    int_p_sign_posn;
154         char    int_n_sign_posn;
155     }
156 
157     ///
158     enum
159     {
160         LC_ALL      = 6,
161         LC_COLLATE  = 3,
162         LC_CTYPE    = 0,
163         LC_MESSAGES = 5,
164         LC_MONETARY = 4,
165         LC_NUMERIC  = 1,
166         LC_TIME     = 2,
167 
168         // Linux-specific
169         LC_PAPER          =  7,
170         LC_NAME           =  8,
171         LC_ADDRESS        =  9,
172         LC_TELEPHONE      = 10,
173         LC_MEASUREMENT    = 11,
174         LC_IDENTIFICATION = 12,
175     }
176 
177     ///
178     enum
179     {
180         LC_ALL_MASK = (LC_CTYPE_MASK | LC_NUMERIC_MASK | LC_TIME_MASK |
181                        LC_COLLATE_MASK | LC_MONETARY_MASK | LC_MESSAGES_MASK |
182                        LC_PAPER_MASK | LC_NAME_MASK | LC_ADDRESS_MASK |
183                        LC_TELEPHONE_MASK | LC_MEASUREMENT_MASK |
184                        LC_IDENTIFICATION_MASK),
185 
186         LC_COLLATE_MASK  = (1 << LC_COLLATE),
187         LC_CTYPE_MASK    = (1 << LC_CTYPE),
188         LC_MESSAGES_MASK = (1 << LC_MESSAGES),
189         LC_MONETARY_MASK = (1 << LC_MONETARY),
190         LC_NUMERIC_MASK  = (1 << LC_NUMERIC),
191         LC_TIME_MASK     = (1 << LC_TIME),
192 
193         // Linux specific
194         LC_PAPER_MASK          = (1 << LC_PAPER),
195         LC_NAME_MASK           = (1 << LC_NAME),
196         LC_ADDRESS_MASK        = (1 << LC_ADDRESS),
197         LC_TELEPHONE_MASK      = (1 << LC_TELEPHONE),
198         LC_MEASUREMENT_MASK    = (1 << LC_MEASUREMENT),
199         LC_IDENTIFICATION_MASK = (1 << LC_IDENTIFICATION),
200     }
201 
202     private struct __locale_struct;
203 
204     ///
205     alias locale_t = __locale_struct*;
206 
207     ///
208     enum LC_GLOBAL_LOCALE = (cast(locale_t)-1);
209 
210     /// Duplicate existing locale
211     locale_t duplocale(locale_t locale);
212     /// Free an allocated locale
213     void     freelocale(locale_t locale);
214     /// Natural language formatting for C
215     lconv*   localeconv();
216     /// Create a new locale
217     locale_t newlocale(int mask, const char* locale, locale_t base);
218     /// Set the C library's notion of natural language formatting style
219     char*    setlocale(int category, const char* locale);
220     /// Set the per-thread locale
221     locale_t uselocale (locale_t locale);
222 }
223 else version (CRuntime_Musl)
224 {
225     ///
226     struct lconv
227     {
228         char*   decimal_point;
229         char*   thousands_sep;
230         char*   grouping;
231         char*   int_curr_symbol;
232         char*   currency_symbol;
233         char*   mon_decimal_point;
234         char*   mon_thousands_sep;
235         char*   mon_grouping;
236         char*   positive_sign;
237         char*   negative_sign;
238         char    int_frac_digits;
239         char    frac_digits;
240         char    p_cs_precedes;
241         char    p_sep_by_space;
242         char    n_cs_precedes;
243         char    n_sep_by_space;
244         char    p_sign_posn;
245         char    n_sign_posn;
246         char    int_p_cs_precedes;
247         char    int_p_sep_by_space;
248         char    int_n_cs_precedes;
249         char    int_n_sep_by_space;
250         char    int_p_sign_posn;
251         char    int_n_sign_posn;
252     }
253 
254     ///
255     enum
256     {
257         LC_CTYPE    = 0,
258         LC_NUMERIC  = 1,
259         LC_TIME     = 2,
260         LC_COLLATE  = 3,
261         LC_MONETARY = 4,
262         LC_MESSAGES = 5,
263         LC_ALL      = 6,
264     }
265 
266     ///
267     enum
268     {
269         LC_CTYPE_MASK    = (1 << LC_CTYPE),
270         LC_NUMERIC_MASK  = (1 << LC_NUMERIC),
271         LC_TIME_MASK     = (1 << LC_TIME),
272         LC_COLLATE_MASK  = (1 << LC_COLLATE),
273         LC_MONETARY_MASK = (1 << LC_MONETARY),
274         LC_MESSAGES_MASK = (1 << LC_MESSAGES),
275         LC_ALL_MASK      = 0x7fffffff,
276     }
277 
278     private struct __locale_struct;
279 
280     ///
281     alias locale_t = __locale_struct*;
282 
283     ///
284     enum LC_GLOBAL_LOCALE = (cast(locale_t)-1);
285 
286     /// Duplicate existing locale
287     locale_t duplocale(locale_t locale);
288     /// Free an allocated locale
289     void     freelocale(locale_t locale);
290     /// Natural language formatting for C
291     lconv*   localeconv();
292     /// Create a new locale
293     locale_t newlocale(int mask, const char* locale, locale_t base);
294     /// Set the C library's notion of natural language formatting style
295     char*    setlocale(int category, const char* locale);
296     /// Set the per-thread locale
297     locale_t uselocale (locale_t locale);
298 }
299 else version (OpenBSD)
300 {
301     ///
302     struct lconv
303     {
304         char*   decimal_point;
305         char*   thousands_sep;
306         char*   grouping;
307         char*   int_curr_symbol;
308         char*   currency_symbol;
309         char*   mon_decimal_point;
310         char*   mon_thousands_sep;
311         char*   mon_grouping;
312         char*   positive_sign;
313         char*   negative_sign;
314         char    int_frac_digits;
315         char    frac_digits;
316         char    p_cs_precedes;
317         char    p_sep_by_space;
318         char    n_cs_precedes;
319         char    n_sep_by_space;
320         char    p_sign_posn;
321         char    n_sign_posn;
322         char    int_p_cs_precedes;
323         char    int_n_cs_precedes;
324         char    int_p_sep_by_space;
325         char    int_n_sep_by_space;
326         char    int_p_sign_posn;
327         char    int_n_sign_posn;
328     }
329 
330     ///
331     enum
332     {
333         LC_ALL      = 0,
334         LC_COLLATE  = 1,
335         LC_CTYPE    = 2,
336         LC_MONETARY = 3,
337         LC_NUMERIC  = 4,
338         LC_TIME     = 5,
339         LC_MESSAGES = 6,
340     }
341     private enum _LC_LAST = 7;
342 
343     ///
344     enum
345     {
346         LC_COLLATE_MASK  = (1 << LC_COLLATE),
347         LC_CTYPE_MASK    = (1 << LC_CTYPE),
348         LC_MONETARY_MASK = (1 << LC_MONETARY),
349         LC_NUMERIC_MASK  = (1 << LC_NUMERIC),
350         LC_TIME_MASK     = (1 << LC_TIME),
351         LC_MESSAGES_MASK = (1 << LC_MESSAGES),
352         LC_ALL_MASK      = ((1 << _LC_LAST) - 2),
353     }
354 
355     ///
356     alias locale_t = void*;
357 
358     ///
359     enum LC_GLOBAL_LOCALE = (cast(locale_t)-1);
360 
361     /// Duplicate existing locale
362     locale_t duplocale(locale_t locale);
363     /// Free an allocated locale
364     void     freelocale(locale_t locale);
365     /// Natural language formatting for C
366     lconv*   localeconv();
367     /// Create a new locale
368     locale_t newlocale(int mask, const char* locale, locale_t base);
369     /// Set the C library's notion of natural language formatting style
370     char*    setlocale(int category, const char* locale);
371     /// Set the per-thread locale
372     locale_t uselocale (locale_t locale);
373 }
374 else version (Solaris)
375 {
376     ///
377     struct lconv
378     {
379         char*   decimal_point;
380         char*   thousands_sep;
381         char*   grouping;
382         char*   int_curr_symbol;
383         char*   currency_symbol;
384         char*   mon_decimal_point;
385         char*   mon_thousands_sep;
386         char*   mon_grouping;
387         char*   positive_sign;
388         char*   negative_sign;
389         char    int_frac_digits;
390         char    frac_digits;
391         char    p_cs_precedes;
392         char    p_sep_by_space;
393         char    n_cs_precedes;
394         char    n_sep_by_space;
395         char    p_sign_posn;
396         char    n_sign_posn;
397         char    int_p_cs_precedes;
398         char    int_n_cs_precedes;
399         char    int_p_sep_by_space;
400         char    int_n_sep_by_space;
401         char    int_p_sign_posn;
402         char    int_n_sign_posn;
403     }
404 
405     ///
406     enum
407     {
408         LC_CTYPE    = 0,
409         LC_NUMERIC  = 1,
410         LC_TIME     = 2,
411         LC_COLLATE  = 3,
412         LC_MONETARY = 4,
413         LC_MESSAGES = 5,
414         LC_ALL      = 6,
415     }
416 
417     ///
418     enum
419     {
420         LC_CTYPE_MASK    = (1 << LC_CTYPE),
421         LC_NUMERIC_MASK  = (1 << LC_NUMERIC),
422         LC_TIME_MASK     = (1 << LC_TIME),
423         LC_COLLATE_MASK  = (1 << LC_COLLATE),
424         LC_MONETARY_MASK = (1 << LC_MONETARY),
425         LC_MESSAGES_MASK = (1 << LC_MESSAGES),
426         LC_ALL_MASK      = 0x3f,
427     }
428 
429     private struct _LC_locale_t;
430 
431     ///
432     alias locale_t = _LC_locale_t**;
433 
434     ///
435     enum LC_GLOBAL_LOCALE = (cast(locale_t)-1);
436 
437     /// Duplicate existing locale
438     locale_t duplocale(locale_t locale);
439     /// Free an allocated locale
440     void     freelocale(locale_t locale);
441     /// Natural language formatting for C
442     lconv*   localeconv();
443     /// Create a new locale
444     locale_t newlocale(int mask, const char* locale, locale_t base);
445     /// Set the C library's notion of natural language formatting style
446     char*    setlocale(int category, const char* locale);
447     /// Set the per-thread locale
448     locale_t uselocale (locale_t locale);
449 }
450 else
451     static assert(false, "unimplemented platform");