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