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 */
11module core.sys.posix.locale;
12
13version (Posix):
14extern(C):
15@system:
16nothrow:
17@nogc:
18
19version (OSX)
20    version = Darwin;
21else version (iOS)
22    version = Darwin;
23else version (TVOS)
24    version = Darwin;
25else version (WatchOS)
26    version = Darwin;
27
28version (Darwin)
29    version = DarwinBSDLocale;
30version (FreeBSD)
31    version = DarwinBSDLocale;
32version (NetBSD)
33    version = DarwinBSDLocale;
34version (DragonFlyBSD)
35    version = DarwinBSDLocale;
36
37version (CRuntime_Glibc)
38    version = GNULinuxLocale;
39version (CRuntime_Bionic)
40    version = GNULinuxLocale;
41version (CRuntime_UClibc)
42    version = GNULinuxLocale;
43
44version (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}
127else 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}
224else 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}
300else 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}
375else 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}
451else
452    static assert(false, "unimplemented platform");
453