Print this page
Fixes for wcstok.
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/head/iso/wchar_iso.h
+++ new/usr/src/head/iso/wchar_iso.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 28 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
29 29 */
30 30
31 31 /*
32 32 * An application should not include this header directly. Instead it
33 33 * should be included only through the inclusion of other Sun headers.
34 34 *
35 35 * The contents of this header is limited to identifiers specified in the
36 36 * C Standard. Any new identifiers specified in future amendments to the
37 37 * C Standard must be placed in this header. If these new identifiers
38 38 * are required to also be in the C++ Standard "std" namespace, then for
39 39 * anything other than macro definitions, corresponding "using" directives
40 40 * must also be added to <wchar.h>.
41 41 */
42 42
43 43 #ifndef _ISO_WCHAR_ISO_H
44 44 #define _ISO_WCHAR_ISO_H
45 45
46 46 #include <sys/feature_tests.h>
47 47 #include <stdio_tag.h>
48 48 #include <wchar_impl.h>
49 49 #include <iso/time_iso.h>
50 50
51 51 #if (defined(__cplusplus) && (__cplusplus - 0 < 54321L)) || \
52 52 (!defined(__cplusplus) && !defined(_STRICT_STDC)) || \
53 53 defined(__EXTENSIONS__)
54 54 #include <stdio.h>
55 55 #endif /* (defined(__cplusplus) && (__cplusplus - 0 < 54321L)) ... */
56 56
57 57 #if !defined(_STRICT_STDC) || defined(__EXTENSIONS__)
58 58 #include <ctype.h>
59 59 #include <stddef.h>
60 60 #endif /* !defined(_STRICT_STDC) || defined(__EXTENSIONS__) */
61 61
62 62 #include <sys/va_list.h>
63 63
64 64 #ifdef __cplusplus
65 65 extern "C" {
66 66 #endif
67 67
68 68 #if __cplusplus >= 199711L
69 69 namespace std {
70 70 #endif
71 71
72 72 /*
73 73 * wchar_t is a built-in type in standard C++ and as such is not
74 74 * defined here when using standard C++. However, the GNU compiler
75 75 * fixincludes utility nonetheless creates its own version of this
76 76 * header for use by gcc and g++. In that version it adds a redundant
77 77 * guard for __cplusplus. To avoid the creation of a gcc/g++ specific
78 78 * header we need to include the following magic comment:
79 79 *
80 80 * we must use the C++ compiler's type
81 81 *
82 82 * The above comment should not be removed or changed until GNU
83 83 * gcc/fixinc/inclhack.def is updated to bypass this header.
84 84 */
85 85 #if !defined(__cplusplus) || (__cplusplus < 199711L && !defined(__GNUG__))
86 86 #ifndef _WCHAR_T
87 87 #define _WCHAR_T
88 88 #if defined(_LP64)
89 89 typedef int wchar_t;
90 90 #else
91 91 typedef long wchar_t;
92 92 #endif
93 93 #endif /* !_WCHAR_T */
94 94 #endif /* !defined(__cplusplus) ... */
95 95
96 96 #if !defined(_WINT_T) || __cplusplus >= 199711L
97 97 #define _WINT_T
98 98 #if defined(_LP64)
99 99 typedef int wint_t;
100 100 #else
101 101 typedef long wint_t;
102 102 #endif
103 103 #endif /* !defined(_WINT_T) || __cplusplus >= 199711L */
104 104
105 105 #if !defined(_SIZE_T) || __cplusplus >= 199711L
106 106 #define _SIZE_T
107 107 #if defined(_LP64) || defined(_I32LPx)
108 108 typedef unsigned long size_t; /* size of something in bytes */
109 109 #else
110 110 typedef unsigned int size_t; /* (historical version) */
111 111 #endif
112 112 #endif /* !defined(_SIZE_T) || __cplusplus >= 199711L */
113 113
114 114 #ifndef NULL
115 115 #if defined(_LP64)
116 116 #define NULL 0L
117 117 #else
118 118 #define NULL 0
119 119 #endif
120 120 #endif /* !NULL */
121 121
122 122 #ifndef WEOF
123 123 #if __cplusplus >= 199711L
124 124 #define WEOF ((std::wint_t)(-1))
125 125 #else
126 126 #define WEOF ((wint_t)(-1))
127 127 #endif
128 128 #endif /* WEOF */
129 129
130 130 /* not XPG4 and not XPG4v2 */
131 131 #if !defined(_XPG4) || defined(_XPG5)
132 132 #ifndef WCHAR_MAX
133 133 #define WCHAR_MAX 2147483647
134 134 #endif
135 135 #ifndef WCHAR_MIN
136 136 #define WCHAR_MIN (-2147483647-1)
137 137 #endif
138 138 #endif /* not XPG4 and not XPG4v2 */
139 139
140 140 #if !defined(_MBSTATE_T) || __cplusplus >= 199711L
141 141 #define _MBSTATE_T
142 142 typedef __mbstate_t mbstate_t;
143 143 #endif /* _MBSTATE_T */
144 144
145 145 #if defined(_XPG4) && !defined(_FILEDEFED) || __cplusplus >= 199711L
146 146 #define _FILEDEFED
147 147 typedef __FILE FILE;
148 148 #endif
149 149
150 150 #if !defined(_LP64) && !defined(_LONGLONG_TYPE)
151 151
152 152 #ifdef __PRAGMA_REDEFINE_EXTNAME
153 153 #pragma redefine_extname fwprintf _fwprintf_c89
154 154 #pragma redefine_extname swprintf _swprintf_c89
155 155 #pragma redefine_extname vfwprintf _vfwprintf_c89
156 156 #pragma redefine_extname vswprintf _vswprintf_c89
157 157 #pragma redefine_extname vwprintf _vwprintf_c89
158 158 #pragma redefine_extname wprintf _wprintf_c89
159 159 #pragma redefine_extname fwscanf _fwscanf_c89
160 160 #pragma redefine_extname swscanf _swscanf_c89
161 161 #pragma redefine_extname wscanf _wscanf_c89
162 162 #else
163 163 #define fwprintf _fwprintf_c89
164 164 #define swprintf _swprintf_c89
165 165 #define vfwprintf _vfwprintf_c89
166 166 #define vswprintf _vswprintf_c89
167 167 #define vwprintf _vwprintf_c89
168 168 #define wprintf _wprintf_c89
169 169 #define fwscanf _fwscanf_c89
170 170 #define swscanf _swscanf_c89
171 171 #define wscanf _wscanf_c89
172 172 #endif
173 173
174 174 #endif /* !defined(_LP64) && !defined(_LONGLONG_TYPE) */
175 175
176 176 #if (!defined(_MSE_INT_H))
177 177 /* not XPG4 and not XPG4v2 */
178 178 #if !defined(_XPG4) || defined(_XPG5)
179 179 #ifdef __PRAGMA_REDEFINE_EXTNAME
180 180 #pragma redefine_extname fgetwc __fgetwc_xpg5
181 181 #pragma redefine_extname getwc __getwc_xpg5
182 182 #pragma redefine_extname getwchar __getwchar_xpg5
183 183 #pragma redefine_extname fputwc __fputwc_xpg5
184 184 #pragma redefine_extname putwc __putwc_xpg5
185 185 #pragma redefine_extname putwchar __putwchar_xpg5
186 186 #pragma redefine_extname fgetws __fgetws_xpg5
187 187 #pragma redefine_extname fputws __fputws_xpg5
188 188 #pragma redefine_extname ungetwc __ungetwc_xpg5
189 189 #else /* __PRAGMA_REDEFINE_EXTNAME */
190 190 #ifdef __STDC__
191 191 extern wint_t __fgetwc_xpg5(__FILE *);
192 192 extern wint_t __getwc_xpg5(__FILE *);
193 193 extern wint_t __getwchar_xpg5(void);
194 194 extern wint_t __fputwc_xpg5(wint_t, __FILE *);
195 195 extern wint_t __putwc_xpg5(wint_t, __FILE *);
196 196 extern wint_t __putwchar_xpg5(wint_t);
197 197 extern wchar_t *__fgetws_xpg5(wchar_t *_RESTRICT_KYWD, int,
198 198 __FILE *_RESTRICT_KYWD);
199 199 extern int __fputws_xpg5(const wchar_t *_RESTRICT_KYWD, __FILE *_RESTRICT_KYWD);
200 200 extern wint_t __ungetwc_xpg5(wint_t, __FILE *);
201 201 #else
202 202 extern wint_t __fgetwc_xpg5();
203 203 extern wint_t __getwc_xpg5();
204 204 extern wint_t __getwchar_xpg5();
205 205 extern wint_t __fputwc_xpg5();
206 206 extern wint_t __putwc_xpg5();
207 207 extern wint_t __putwchar_xpg5();
208 208 extern wchar_t *__fgetws_xpg5();
209 209 extern int __fputws_xpg5();
210 210 extern wint_t __ungetwc_xpg5();
211 211 #endif /* __STDC__ */
212 212 #define fgetwc __fgetwc_xpg5
213 213 #define getwc __getwc_xpg5
214 214 #define getwchar __getwchar_xpg5
215 215 #define fputwc __fputwc_xpg5
216 216 #define putwc __putwc_xpg5
217 217 #define putwchar __putwchar_xpg5
218 218 #define fgetws __fgetws_xpg5
219 219 #define fputws __fputws_xpg5
220 220 #define ungetwc __ungetwc_xpg5
221 221 #endif /* __PRAGMA_REDEFINE_EXTNAME */
222 222 #endif /* not XPG4 and not XPG4v2 */
223 223 #endif /* defined(_MSE_INT_H) */
224 224
225 225 #ifdef __STDC__
226 226
227 227 extern wint_t fgetwc(__FILE *);
228 228 extern wchar_t *fgetws(wchar_t *_RESTRICT_KYWD, int, __FILE *_RESTRICT_KYWD);
229 229 extern wint_t fputwc(wint_t, __FILE *);
230 230 extern int fputws(const wchar_t *_RESTRICT_KYWD, __FILE *_RESTRICT_KYWD);
231 231 extern wint_t ungetwc(wint_t, __FILE *);
232 232 extern wint_t getwc(__FILE *);
233 233 extern wint_t getwchar(void);
234 234 extern wint_t putwc(wint_t, __FILE *);
235 235 extern wint_t putwchar(wint_t);
236 236 extern double wcstod(const wchar_t *_RESTRICT_KYWD, wchar_t **_RESTRICT_KYWD);
237 237 extern long wcstol(const wchar_t *_RESTRICT_KYWD, wchar_t **_RESTRICT_KYWD,
238 238 int);
239 239 extern unsigned long wcstoul(const wchar_t *_RESTRICT_KYWD,
240 240 wchar_t **_RESTRICT_KYWD, int);
241 241 extern wchar_t *wcscat(wchar_t *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD);
242 242 extern int wcscmp(const wchar_t *, const wchar_t *);
243 243 extern int wcscoll(const wchar_t *, const wchar_t *);
244 244 extern wchar_t *wcscpy(wchar_t *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD);
245 245 extern size_t wcscspn(const wchar_t *, const wchar_t *);
246 246 extern size_t wcslen(const wchar_t *);
247 247 extern wchar_t *wcsncat(wchar_t *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
248 248 size_t);
249 249 extern int wcsncmp(const wchar_t *, const wchar_t *, size_t);
250 250 extern wchar_t *wcsncpy(wchar_t *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
251 251 size_t);
252 252 extern size_t wcsspn(const wchar_t *, const wchar_t *);
253 253 extern size_t wcsxfrm(wchar_t *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
254 254 size_t);
255 255 #if __cplusplus >= 199711L
256 256 extern const wchar_t *wcschr(const wchar_t *, wchar_t);
257 257 extern "C++" {
258 258 inline wchar_t *wcschr(wchar_t *__ws, wchar_t __wc) {
259 259 return (wchar_t *)wcschr((const wchar_t *)__ws, __wc);
260 260 }
261 261 }
262 262 extern const wchar_t *wcspbrk(const wchar_t *, const wchar_t *);
263 263 extern "C++" {
264 264 inline wchar_t *wcspbrk(wchar_t *__ws1, const wchar_t *__ws2) {
265 265 return (wchar_t *)wcspbrk((const wchar_t *)__ws1, __ws2);
266 266 }
267 267 }
268 268 extern const wchar_t *wcsrchr(const wchar_t *, wchar_t);
269 269 extern "C++" {
270 270 inline wchar_t *wcsrchr(wchar_t *__ws, wchar_t __wc) {
271 271 return (wchar_t *)wcsrchr((const wchar_t *)__ws, __wc);
↓ open down ↓ |
271 lines elided |
↑ open up ↑ |
272 272 }
273 273 }
274 274 #else /* __cplusplus >= 199711L */
275 275 extern wchar_t *wcschr(const wchar_t *, wchar_t);
276 276 extern wchar_t *wcspbrk(const wchar_t *, const wchar_t *);
277 277 extern wchar_t *wcsrchr(const wchar_t *, wchar_t);
278 278 #endif /* __cplusplus >= 199711L */
279 279
280 280 #if (!defined(_MSE_INT_H))
281 281 #if defined(_XPG4) && !defined(_XPG5) /* XPG4 or XPG4v2 */
282 -extern wchar_t *wcstok(wchar_t *, const wchar_t *);
282 +extern wchar_t *wcstok(wchar_t *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD);
283 283 extern size_t wcsftime(wchar_t *, size_t, const char *, const struct tm *);
284 284 #else /* XPG4 or XPG4v2 */
285 285 #ifdef __PRAGMA_REDEFINE_EXTNAME
286 286 #pragma redefine_extname wcstok __wcstok_xpg5
287 287 #pragma redefine_extname wcsftime __wcsftime_xpg5
288 288 extern wchar_t *wcstok(wchar_t *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
289 289 wchar_t **_RESTRICT_KYWD);
290 290 extern size_t wcsftime(wchar_t *_RESTRICT_KYWD, size_t,
291 291 const wchar_t *_RESTRICT_KYWD, const struct tm *_RESTRICT_KYWD);
292 292 #else /* __PRAGMA_REDEFINE_EXTNAME */
293 293 extern wchar_t *__wcstok_xpg5(wchar_t *_RESTRICT_KYWD,
294 294 const wchar_t *_RESTRICT_KYWD, wchar_t **_RESTRICT_KYWD);
295 295 extern size_t __wcsftime_xpg5(wchar_t *_RESTRICT_KYWD, size_t,
296 296 const wchar_t *_RESTRICT_KYWD, const struct tm *_RESTRICT_KYWD);
297 297 #define wcstok __wcstok_xpg5
298 298 #define wcsftime __wcsftime_xpg5
299 299 #endif /* __PRAGMA_REDEFINE_EXTNAME */
300 300 #endif /* XPG4 or XPG4v2 */
301 301 #endif /* !defined(_MSE_INT_H) */
302 302
303 303 /* not XPG4 and not XPG4v2 */
304 304 #if !defined(_XPG4) || defined(_XPG5)
305 305 extern wint_t btowc(int);
306 306 extern int fwprintf(__FILE *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
307 307 ...);
308 308 extern int fwscanf(__FILE *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
309 309 ...);
310 310 extern int fwide(__FILE *, int);
311 311 extern int mbsinit(const mbstate_t *);
312 312 extern size_t mbrlen(const char *_RESTRICT_KYWD, size_t,
313 313 mbstate_t *_RESTRICT_KYWD);
314 314 extern size_t mbrtowc(wchar_t *_RESTRICT_KYWD, const char *_RESTRICT_KYWD,
315 315 size_t, mbstate_t *_RESTRICT_KYWD);
316 316 extern size_t mbsrtowcs(wchar_t *_RESTRICT_KYWD, const char **_RESTRICT_KYWD,
317 317 size_t, mbstate_t *_RESTRICT_KYWD);
318 318 extern int swprintf(wchar_t *_RESTRICT_KYWD, size_t,
319 319 const wchar_t *_RESTRICT_KYWD, ...);
320 320 extern int swscanf(const wchar_t *_RESTRICT_KYWD,
321 321 const wchar_t *_RESTRICT_KYWD, ...);
322 322 extern int vfwprintf(__FILE *_RESTRICT_KYWD, const wchar_t *_RESTRICT_KYWD,
323 323 __va_list);
324 324 extern int vwprintf(const wchar_t *_RESTRICT_KYWD, __va_list);
325 325 extern int vswprintf(wchar_t *_RESTRICT_KYWD, size_t,
326 326 const wchar_t *_RESTRICT_KYWD, __va_list);
327 327 extern size_t wcrtomb(char *_RESTRICT_KYWD, wchar_t,
328 328 mbstate_t *_RESTRICT_KYWD);
329 329 extern size_t wcsrtombs(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD,
330 330 size_t, mbstate_t *_RESTRICT_KYWD);
331 331 #if defined(_XPG7) || !defined(_STRICT_SYMBOLS)
332 332 extern size_t wcsnrtombs(char *_RESTRICT_KYWD, const wchar_t **_RESTRICT_KYWD,
333 333 size_t, size_t, mbstate_t *_RESTRICT_KYWD);
334 334 #endif
335 335 extern int wctob(wint_t);
336 336 extern int wmemcmp(const wchar_t *, const wchar_t *, size_t);
337 337 extern wchar_t *wmemcpy(wchar_t *_RESTRICT_KYWD,
338 338 const wchar_t *_RESTRICT_KYWD, size_t);
339 339 extern wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t);
340 340 extern wchar_t *wmemset(wchar_t *, wchar_t, size_t);
341 341 extern int wprintf(const wchar_t *_RESTRICT_KYWD, ...);
342 342 extern int wscanf(const wchar_t *_RESTRICT_KYWD, ...);
343 343 #if __cplusplus >= 199711L
344 344 extern const wchar_t *wcsstr(const wchar_t *, const wchar_t *);
345 345 extern "C++" {
346 346 inline wchar_t *wcsstr(wchar_t *__ws1, const wchar_t *__ws2) {
347 347 return (wchar_t *)wcsstr((const wchar_t *)__ws1, __ws2);
348 348 }
349 349 }
350 350 extern const wchar_t *wmemchr(const wchar_t *, wchar_t, size_t);
351 351 extern "C++" {
352 352 inline wchar_t *wmemchr(wchar_t *__ws, wchar_t __wc, size_t __n) {
353 353 return (wchar_t *)wmemchr((const wchar_t *)__ws, __wc, __n);
354 354 }
355 355 }
356 356 #else /* __cplusplus >= 199711L */
357 357 extern wchar_t *wcsstr(const wchar_t *_RESTRICT_KYWD,
358 358 const wchar_t *_RESTRICT_KYWD);
359 359 extern wchar_t *wmemchr(const wchar_t *, wchar_t, size_t);
360 360 #endif /* __cplusplus >= 199711L */
361 361 #endif /* not XPG4 and not XPG4v2 */
362 362
363 363 #else /* __STDC__ */
364 364
365 365 extern wint_t fgetwc();
366 366 extern wchar_t *fgetws();
367 367 extern wint_t fputwc();
368 368 extern int fputws();
369 369 extern wint_t ungetwc();
370 370 extern wint_t getwc();
371 371 extern wint_t getwchar();
372 372 extern wint_t putwc();
373 373 extern wint_t putwchar();
374 374 extern wint_t ungetwc();
375 375 extern double wcstod();
376 376 extern long wcstol();
377 377 extern unsigned long wcstoul();
378 378 extern wchar_t *wcscat();
379 379 extern wchar_t *wcschr();
380 380 extern int wcscmp();
381 381 extern int wcscoll();
382 382 extern wchar_t *wcscpy();
383 383 extern size_t wcscspn();
384 384 extern size_t wcslen();
385 385 extern wchar_t *wcsncat();
386 386 extern int wcsncmp();
387 387 extern wchar_t *wcsncpy();
388 388 extern wchar_t *wcspbrk();
389 389 extern wchar_t *wcsrchr();
390 390 extern size_t wcsspn();
391 391 extern size_t wcsxfrm();
392 392
393 393 #if (!defined(_MSE_INT_H))
394 394 #if defined(_XPG4) && !defined(_XPG5) /* XPG4 or XPG4v2 */
395 395 extern wchar_t *wcstok();
396 396 extern size_t wcsftime();
397 397 #else /* XPG4 or XPG4v2 */
398 398 #ifdef __PRAGMA_REDEFINE_EXTNAME
399 399 #pragma redefine_extname wcstok __wcstok_xpg5
400 400 #pragma redefine_extname wcsftime __wcsftime_xpg5
401 401 extern wchar_t *wcstok();
402 402 extern size_t wcsftime();
403 403 #else /* __PRAGMA_REDEFINE_EXTNAME */
404 404 extern wchar_t *__wcstok_xpg5();
405 405 extern size_t __wcsftime_xpg5();
406 406 #define wcstok __wcstok_xpg5
407 407 #define wcsftime __wcsftime_xpg5
408 408 #endif /* __PRAGMA_REDEFINE_EXTNAME */
409 409 #endif /* XPG4 or XPG4v2 */
410 410 #endif /* defined(_MSE_INT_H) */
411 411
412 412 /* not XPG4 and not XPG4v2 */
413 413 #if (!defined(_XPG4) && !defined(_XPG4_2) || defined(_XPG5))
414 414 extern wint_t btowc();
415 415 extern int fwprintf();
416 416 extern int fwscanf();
417 417 extern int fwide();
418 418 extern int mbsinit();
419 419 extern size_t mbrlen();
420 420 extern size_t mbrtowc();
421 421 extern size_t mbsrtowcs();
422 422 extern int swprintf();
423 423 extern int swscanf();
424 424 extern int vfwprintf();
425 425 extern int vwprintf();
426 426 extern int vswprintf();
427 427 extern size_t wcrtomb();
428 428 extern size_t wcsrtombs();
429 429 #if defined(_XPG7) || !defined(_STRICT_SYMBOLS)
430 430 extern size_t wcsnrtombs();
431 431 #endif
432 432
433 433 extern wchar_t *wcsstr();
434 434 extern int wctob();
435 435 extern wchar_t *wmemchr();
436 436 extern int wmemcmp();
437 437 extern wchar_t *wmemcpy();
438 438 extern wchar_t *wmemmove();
439 439 extern wchar_t *wmemset();
440 440 extern int wprintf();
441 441 extern int wscanf();
442 442 #endif /* not XPG4 and not XPG4v2 */
443 443
444 444 #endif /* __STDC__ */
445 445
446 446 #if __cplusplus >= 199711L
447 447 }
448 448 #endif /* end of namespace std */
449 449
450 450 #ifdef __cplusplus
451 451 }
452 452 #endif
453 453
454 454 #endif /* _ISO_WCHAR_ISO_H */
↓ open down ↓ |
162 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX