1// -*- C++ -*-
2//===--------------------- support/ibm/xlocale.h -------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_SUPPORT_IBM_XLOCALE_H
12#define _LIBCPP_SUPPORT_IBM_XLOCALE_H
13
14#if defined(_AIX)
15#include "cstdlib"
16
17#ifdef __cplusplus
18extern "C" {
19#endif
20
21#if !defined(_AIX71)
22// AIX 7.1 and higher has these definitions.  Definitions and stubs
23// are provied here as a temporary workaround on AIX 6.1.
24
25#define LC_COLLATE_MASK         1
26#define LC_CTYPE_MASK           2
27#define LC_MESSAGES_MASK        4
28#define LC_MONETARY_MASK        8
29#define LC_NUMERIC_MASK         16
30#define LC_TIME_MASK            32
31#define LC_ALL_MASK             (LC_COLLATE_MASK | LC_CTYPE_MASK | \
32                                 LC_MESSAGES_MASK | LC_MONETARY_MASK |\
33                                 LC_NUMERIC_MASK | LC_TIME_MASK)
34
35typedef void* locale_t;
36
37// The following are stubs.  They are not supported on AIX 6.1.
38static inline
39locale_t newlocale(int category_mask, const char *locale, locale_t base)
40{
41  _LC_locale_t *newloc, *loc;
42  if ((loc = (_LC_locale_t *)__xopen_locale(locale)) == NULL)
43  {
44    errno = EINVAL;
45    return (locale_t)0;
46  }
47  if ((newloc = (_LC_locale_t *)calloc(1, sizeof(_LC_locale_t))) == NULL)
48  {
49    errno = ENOMEM;
50    return (locale_t)0;
51  }
52  if (!base)
53    base = (_LC_locale_t *)__xopen_locale("C");
54  memcpy(newloc, base, sizeof (_LC_locale_t));
55  if (category_mask & LC_COLLATE_MASK)
56    newloc->lc_collate = loc->lc_collate;
57  if (category_mask & LC_CTYPE_MASK)
58    newloc->lc_ctype = loc->lc_ctype;
59  //if (category_mask & LC_MESSAGES_MASK)
60  //  newloc->lc_messages = loc->lc_messages;
61  if (category_mask & LC_MONETARY_MASK)
62    newloc->lc_monetary = loc->lc_monetary;
63  if (category_mask & LC_TIME_MASK)
64    newloc->lc_time = loc->lc_time;
65  if (category_mask & LC_NUMERIC_MASK)
66    newloc->lc_numeric = loc->lc_numeric;
67  return (locale_t)newloc;
68}
69static inline
70void freelocale(locale_t locobj)
71{
72  free(locobj);
73}
74static inline
75locale_t uselocale(locale_t newloc)
76{
77  return (locale_t)0;
78}
79
80static inline
81int isalnum_l(int c, locale_t locale)
82{
83  return __xisalnum(locale, c);
84}
85static inline
86int isalpha_l(int c, locale_t locale)
87{
88  return __xisalpha(locale, c);
89}
90static inline
91int isblank_l(int c, locale_t locale)
92{
93  return __xisblank(locale, c);
94}
95static inline
96int iscntrl_l(int c, locale_t locale)
97{
98  return __xiscntrl(locale, c);
99}
100static inline
101int isdigit_l(int c, locale_t locale)
102{
103  return __xisdigit(locale, c);
104}
105static inline
106int isgraph_l(int c, locale_t locale)
107{
108  return __xisgraph(locale, c);
109}
110static inline
111int islower_l(int c, locale_t locale)
112{
113  return __xislower(locale, c);
114}
115static inline
116int isprint_l(int c, locale_t locale)
117{
118  return __xisprint(locale, c);
119}
120
121static inline
122int ispunct_l(int c, locale_t locale)
123{
124  return __xispunct(locale, c);
125}
126static inline
127int isspace_l(int c, locale_t locale)
128{
129  return __xisspace(locale, c);
130}
131static inline
132int isupper_l(int c, locale_t locale)
133{
134  return __xisupper(locale, c);
135}
136
137static inline
138int isxdigit_l(int c, locale_t locale)
139{
140  return __xisxdigit(locale, c);
141}
142
143static inline
144int iswalnum_l(wchar_t wc, locale_t locale)
145{
146  return __xiswalnum(locale, wc);
147}
148
149static inline
150int iswalpha_l(wchar_t wc, locale_t locale)
151{
152  return __xiswalpha(locale, wc);
153}
154
155static inline
156int iswblank_l(wchar_t wc, locale_t locale)
157{
158  return __xiswblank(locale, wc);
159}
160
161static inline
162int iswcntrl_l(wchar_t wc, locale_t locale)
163{
164  return __xiswcntrl(locale, wc);
165}
166
167static inline
168int iswdigit_l(wchar_t wc, locale_t locale)
169{
170  return __xiswdigit(locale, wc);
171}
172
173static inline
174int iswgraph_l(wchar_t wc, locale_t locale)
175{
176  return __xiswgraph(locale, wc);
177}
178
179static inline
180int iswlower_l(wchar_t wc, locale_t locale)
181{
182  return __xiswlower(locale, wc);
183}
184
185static inline
186int iswprint_l(wchar_t wc, locale_t locale)
187{
188  return __xiswprint(locale, wc);
189}
190
191static inline
192int iswpunct_l(wchar_t wc, locale_t locale)
193{
194  return __xiswpunct(locale, wc);
195}
196
197static inline
198int iswspace_l(wchar_t wc, locale_t locale)
199{
200  return __xiswspace(locale, wc);
201}
202
203static inline
204int iswupper_l(wchar_t wc, locale_t locale)
205{
206  return __xiswupper(locale, wc);
207}
208
209static inline
210int iswxdigit_l(wchar_t wc, locale_t locale)
211{
212  return __xiswxdigit(locale, wc);
213}
214
215static inline
216int iswctype_l(wint_t wc, wctype_t desc, locale_t locale)
217{
218  return __xiswctype(locale, wc, desc);
219}
220
221static inline
222int toupper_l(int c, locale_t locale)
223{
224  return __xtoupper(locale, c);
225}
226static inline
227int tolower_l(int c, locale_t locale)
228{
229  return __xtolower(locale, c);
230}
231static inline
232wint_t towupper_l(wint_t wc, locale_t locale)
233{
234  return __xtowupper(locale, wc);
235}
236static inline
237wint_t towlower_l(wint_t wc, locale_t locale)
238{
239  return __xtowlower(locale, wc);
240}
241
242static inline
243int strcoll_l(const char *__s1, const char *__s2, locale_t locale)
244{
245  return __xstrcoll(locale, __s1, __s2);
246}
247static inline
248int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t locale)
249{
250  return __xwcscoll(locale, __s1, __s2);
251}
252static inline
253size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t locale)
254{
255  return __xstrxfrm(locale, __s1, __s2, __n);
256}
257
258static inline
259size_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n,
260    locale_t locale)
261{
262  return __xwcsxfrm(locale, __ws1, __ws2, __n);
263}
264#endif // !defined(_AIX71)
265
266// strftime_l() is defined by POSIX. However, AIX 7.1 does not have it
267// implemented yet.
268static inline
269size_t strftime_l(char *__s, size_t __size, const char *__fmt,
270                  const struct tm *__tm, locale_t locale) {
271  return __xstrftime(locale, __s, __size, __fmt, __tm);
272}
273
274// The following are not POSIX routines.  These are quick-and-dirty hacks
275// to make things pretend to work
276static inline
277long long strtoll_l(const char *__nptr, char **__endptr,
278    int __base, locale_t locale) {
279  return strtoll(__nptr, __endptr, __base);
280}
281static inline
282long strtol_l(const char *__nptr, char **__endptr,
283    int __base, locale_t locale) {
284  return strtol(__nptr, __endptr, __base);
285}
286static inline
287long double strtold_l(const char *__nptr, char **__endptr,
288    locale_t locale) {
289  return strtold(__nptr, __endptr);
290}
291static inline
292unsigned long long strtoull_l(const char *__nptr, char **__endptr,
293    int __base, locale_t locale) {
294  return strtoull(__nptr, __endptr, __base);
295}
296static inline
297unsigned long strtoul_l(const char *__nptr, char **__endptr,
298    int __base, locale_t locale) {
299  return strtoul(__nptr, __endptr, __base);
300}
301
302static inline
303int vasprintf(char **strp, const char *fmt, va_list ap)
304{
305  const size_t buff_size = 256;
306  int str_size;
307  if ((*strp = (char *)malloc(buff_size)) == NULL)
308  {
309    return -1;
310  }
311  if ((str_size = vsnprintf(*strp, buff_size, fmt,  ap)) >= buff_size)
312  {
313    if ((*strp = (char *)realloc(*strp, str_size + 1)) == NULL)
314    {
315      return -1;
316    }
317    str_size = vsnprintf(*strp, str_size + 1, fmt,  ap);
318  }
319  return str_size;
320}
321
322#ifdef __cplusplus
323}
324#endif
325#endif // defined(_AIX)
326#endif // _LIBCPP_SUPPORT_IBM_XLOCALE_H
327