Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
22.locale.messages.cpp
Go to the documentation of this file.
1
29#include <locale>
30
31#include <rw_driver.h> // for rw_test()
32#include <rw_environ.h> // for rw_putenv()
33#include <rw_file.h> // for rw_nextfd()
34#include <rw_locale.h> // for rw_locales(), rw_create_catalog()
35#include <rw_process.h> // for rw_system()
36
37#include <cstring> // for strlen()
38#include <cstdlib> // for getenv()
39#include <cstdio> // for remove()
40#include <clocale> // for LC_ALL
41
42#include <cwchar> // for mbsinit()
43
44#ifndef _RWSTD_NO_NEW_HEADER
45# if defined (_WIN32)
46# include <io.h> // for _open()
47# include <direct.h> // for getcwd()
48# else
49# include <sys/types.h>
50# include <sys/stat.h>
51# include <unistd.h> // for getcwd()
52# endif
53# include <fcntl.h> // for mode flags for _open
54#endif // _RWSTD_NO_NEW_HEADER
55
56#undef open
57#undef close
58
59#if defined (_MSC_VER)
60# define open(f,m) _open (f, _##m)
61# define close(f) _close (f)
62#else
63# define open(f,m) open (f, m)
64# define close(f) close (f)
65#endif // defined (_MSC_VER)
66
67
69template <class charT>
70struct CodeCvt: std::codecvt<charT, char, std::mbstate_t>
71{
72 typedef std::codecvt<charT, char, std::mbstate_t> Base;
73 typedef typename Base::extern_type extern_type;
74 typedef typename Base::intern_type intern_type;
75 typedef typename Base::state_type state_type;
76 typedef typename Base::result result;
77
78 static bool used_;
79 static bool partial_;
80 static bool noconv_;
81 static bool check_state_;
82
83 static bool valid_state_;
84
85 CodeCvt (std::size_t ref = 1U)
86 : Base (ref) {
88 }
89
90protected:
91
92 // override base class virtual function to make the messages
93 // facet use codecvt<char, char>::in() (the base returns true)
94 bool do_always_noconv () const _THROWS (()) {
95 return false;
96 }
97
98 result
100 const extern_type *from,
101 const extern_type *from_end,
102 const extern_type *&from_next,
103 intern_type *to,
104 intern_type *to_end,
105 intern_type *&to_next) const {
106
107 used_ = true;
108
109#ifndef _RWSTD_NO_MBSINIT
110
111 if (check_state_)
112 valid_state_ = std::mbsinit (&state) != 0;
113
114#else // if (_RWSTD_NO_MBSINIT)
115
116 if (check_state_)
117 valid_state_ = true;
118
119#endif // _RWSTD_NO_MBSINIT
120
121 const result res =
122 Base::do_in (state, from, from_end, from_next,
123 to, to_end, to_next);
124
125 if (partial_)
126 return std::codecvt_base::partial;
127
128 if (noconv_)
129 return std::codecvt_base::noconv;
130
131 return res;
132 }
133};
134
135template <class charT>
137template <class charT>
139template <class charT>
141template <class charT>
143template <class charT>
145
146
148// finds the first named locale other than "C" or "POSIX"; returns
149// a pointer to the name of the locale on success, 0 on failure
150const char*
152{
153 const char *name = rw_locales (LC_ALL, "");
154
155 if (!name)
156 return 0;
157
158 char namebuf [256];
159
160 // get the full name of the "C" locale for comparison with aliases
161 const char* const classic_name =
162 std::strcpy (namebuf, std::setlocale (LC_ALL, "C"));
163
164 do {
165 if (std::strcmp (name, "C") && std::strcmp (name, "POSIX")) {
166
167 // skip over any aliases of the "C" and "POSIX" locales
168 const char* const fullname = std::setlocale (LC_ALL, name);
169 if (std::strcmp (fullname, classic_name)) {
170
171 // skip over the C and POSIX locales
172 _TRY {
173 const std::locale loc (name);
175
176 std::setlocale (LC_ALL, "C");
177 return name;
178 }
179 _CATCH (...) { }
180 }
181 }
182 name += std::strlen (name) + 1;
183
184 } while (*name);
185
186 std::setlocale (LC_ALL, "C");
187
188 return 0;
189}
190
191
193#ifndef _WIN32
194# define CAT_NAME "./rwstdmessages.cat"
195# define MSG_NAME "rwstdmessages.msg"
196#else
197# define CAT_NAME "rwstdmessages.dll"
198# define MSG_NAME "rwstdmessages.rc"
199#endif
200
201#define NLS_CAT_NAME "rwstdmessages"
202
203#define MAX_SETS 5
204#define MAX_MESSAGES 5
205
206
207int msg_id (int set, int id)
208{
209#ifdef _WIN32
210
211 return (set - 1) * 5 + id;
212
213#else
214
215 _RWSTD_UNUSED (set);
216 return id;
217
218#endif
219}
220
221
223static const char* const
224messages [MAX_SETS][MAX_MESSAGES] = {
225 { "First set, first message",
226 "First set, second message",
227 "First set, third message",
228 "First set, fourth message",
229 "First set, fifth message"
230 },
231 { "Second set, first message",
232 "Second set, second message",
233 "Second set, third message",
234 "Second set, fourth message",
235 "Second set, fifth message"
236 },
237 { "Third set, first message",
238 "Third set, second message",
239 "Third set, third message",
240 "Third set, fourth message",
241 "Third set, fifth message"
242 },
243 { "Fourth set, first message",
244 "Fourth set, second message",
245 "Fourth set, third message",
246 "Fourth set, fourth message",
247 "Fourth set, fifth message"
248 },
249 { "Fifth set, first message",
250 "Fifth set, second message",
251 "Fifth set, third message",
252 "Fifth set, fourth message",
253 "Fifth set, fifth message"
254 }
255};
256
257static std::string catalog;
258
259
262template <class charT>
263std::basic_string<charT> widen (std::string message)
264{
265 std::basic_string<charT> result;
266 for (std::size_t i = 0; i < message.length(); i++) {
267 result.push_back ((charT)message[i]);
268 }
269
270 return result;
271}
272
273
275// Test that the message facet exists in the locale and that
276// we can get a reference to it.
277template <class charT>
278void test_has_facet (const char *loc_name, const char *cname)
279{
280 // construct a copy of the named locale or default
281 // when no name is specified
282 const std::locale loc =
283 loc_name ? std::locale (loc_name) : std::locale ();
284
285 typedef std::messages<charT> Messages;
286
287 // verify that the facet exists in the locale
288 bool facet_exists = std::has_facet<Messages>(loc);
289
290 rw_assert (facet_exists, 0, __LINE__,
291 "has_facet<messages<%s> >(locale(%{?}%#s%{;})) == true",
292 cname, 0 != loc_name, loc_name);
293
294 try {
295 // verify that use facet doesn't throw an exception
296 std::use_facet<Messages>(loc);
297 }
298#ifndef _RWSTD_NO_EXCEPTIONS
299
300 catch (std::exception &ex) {
301 rw_assert (0, 0, __LINE__,
302 "use_fact<messages<%s> >(locale(%{?}%#s%{;})) "
303 "unexpectedly threw exception(%#s)",
304 cname, 0 != loc_name, loc_name, ex.what ());
305 }
306 catch (...) {
307 rw_assert (0, 0, __LINE__,
308 "use_fact<messages<%s> >(locale(%{?}%#s%{;})) "
309 "unexpectedly threw an unknown exception",
310 cname, 0 != loc_name, loc_name);
311 }
312
313 typedef std::messages_byname<charT> MessagesByname;
314
315 const bool byname = loc_name
316 && std::strcmp (loc_name, "C") && std::strcmp (loc_name, "POSIX");
317
318 facet_exists = std::has_facet<MessagesByname>(loc);
319
320 rw_assert (byname == facet_exists, 0, __LINE__,
321 "has_fact<messages_byname<%s> >(locale(%{?}%#s%{;})) == %b",
322 cname, 0 != loc_name, loc_name);
323
324 try {
325 // verify that use facet throws an exception only
326 // for the default and "C" locales
327 std::use_facet<MessagesByname>(loc);
328
329 rw_assert (byname, 0, __LINE__,
330 "use_fact<messages_byname<%s> >(locale(%{?}%#s%{;})) "
331 "failed to throw",
332 cname, 0 != loc_name, loc_name);
333 }
334 catch (std::exception &ex) {
335 rw_assert (!byname, 0, __LINE__,
336 "use_fact<messages_byname<%s> >(locale(%{?}%#s%{;})) "
337 "unexpectedly threw exception(%#s)",
338 cname, 0 != loc_name, loc_name, ex.what ());
339 }
340 catch (...) {
341 rw_assert (0, 0, __LINE__,
342 "use_fact<messages<%s> >(locale(%{?}%#s%{;})) "
343 "unexpectedly threw an unknown exception",
344 cname, 0 != loc_name, loc_name);
345 }
346
347#endif // _RWSTD_NO_EXCEPTIONS
348
349}
350
351
353template <class charT>
354std::messages_base::catalog
355open_catalog (const std::messages<charT> &msgs,
356 const char *cat_name, const std::locale &loc,
357 int expect, const char *cname, int line)
358{
359 std::messages_base::catalog cat = -1;
360
361 // expect is set to:
362 // * 0 (or greater) when the caller expects the call to open()
363 // to succeed
364 // * -1 when the caller expects the call to open() to fail
365 // by returning -1
366 // * -2 (or less) when the caller expects the call to open()
367 // to exit by throwing an exception
368 const bool expect_success = expect >= 0;
369 const bool expect_failure = expect == -1;
370 const bool expect_exception = expect < -1;
371
372 const char* const nlspath = std::getenv ("NLSPATH");
373
374 try {
375 // an already closed cat should throw an exception
376 cat = (msgs.open)(cat_name, loc);
377
378 const bool success =
379 (expect_success && -1 < cat) || (expect_failure && cat < 0);
380
381 rw_assert (success, 0, line,
382 "messages<%s>::open(%#s, locale(%#s))"
383 "%{?} > -1%{:}%{?} == -1 %{;}%{;}, got %d"
384 "%{?}; failed to throw an exception%{;}; NLSPATH=%s",
385 cname, cat_name, loc.name ().c_str (),
386 expect_success, expect_failure, cat,
387 expect_exception, nlspath);
388 }
389
390#ifndef _RWSTD_NO_EXCEPTIONS
391
392 catch (std::exception &ex) {
393 rw_assert (expect_exception, 0, line,
394 "messages<%s>::open(%#s, locale(%#s)) unexpectedly "
395 "threw exception(%#s); NLSPATH=%s",
396 cname, cat_name, loc.name ().c_str (), ex.what (), nlspath);
397 }
398 catch (...) {
399 rw_assert (expect_exception, 0, line,
400 "messages<%s>::open(%#s, locale(%#s)) unexpectedly "
401 "threw an unknown exception; NLSPATH=%s",
402 cname, cat_name, loc.name ().c_str (), nlspath);
403 }
404
405#endif // _RWSTD_NO_EXCEPTIONS
406
407 return cat;
408}
409
410
412template <class charT>
413void
414close_catalog (const std::messages<charT> &msgs,
415 std::messages_base::catalog cat,
416 bool expect_exception,
417 const char *cname, int line)
418{
419 try {
420 // an already closed cat should throw an exception
421 (msgs.close)(cat);
422
423 rw_assert (!expect_exception, 0, line,
424 "messages<%s>::close(%d) failed "
425 "to throw an expected exception",
426 cname, cat);
427 }
428
429#ifndef _RWSTD_NO_EXCEPTIONS
430
431 catch (std::exception &ex) {
432 rw_assert (expect_exception, 0, line,
433 "messages<%s>::close(%d) unexpectedly "
434 "threw exception(%#s)",
435 cname, cat, ex.what ());
436 }
437 catch (...) {
438 rw_assert (expect_exception, 0, line,
439 "messages<%s>::close(%d) unexpectedly "
440 "threw an unknown exception",
441 cname, cat);
442 }
443
444#endif // _RWSTD_NO_EXCEPTIONS
445
446}
447
448
450template <class charT>
451void test_open_close (const char *loc_name, const char *cname)
452{
453 int fdcount [2];
454 int next_fd [2];
455
456#ifndef _WIN32
457 next_fd [0] = rw_nextfd (fdcount + 0);
458#else
459 // don't test file descriptor leaking on Win32 to avoid
460 // invalid parameter error
461 // catalog functions not uses file descriptors
462 next_fd [0] = fdcount [0] = 0;
463#endif
464
465 rw_info (0, 0, __LINE__,
466 "std::messages<%s>::open() and close() in locale(#%s)",
467 cname, loc_name);
468
469 // construct a copy of the named locale or default
470 // when no name is specified
471 const std::locale loc =
472 loc_name ? std::locale (loc_name) : std::locale ();
473
474 const std::messages<charT>& msgs =
475 std::use_facet<std::messages<charT> >(loc);
476
477 const std::messages_base::catalog cat =
478 open_catalog (msgs, CAT_NAME, loc, 0, cname, __LINE__);
479
480 // close a (presumably successfully) opened catalog
481 close_catalog (msgs, cat, cat < 0, cname, __LINE__);
482
483 // an already closed cat should throw an exception
484 close_catalog (msgs, cat, true, cname, __LINE__);
485
486 // verify that no file descriptor has leaked
487#ifndef _WIN32
488 next_fd [1] = rw_nextfd (fdcount + 1);
489#else
490 next_fd [1] = fdcount [1] = 0;
491#endif
492
493 rw_assert (next_fd [1] == next_fd [0] && fdcount [0] == fdcount [1],
494 0, __LINE__,
495 "std::messages<%s>::close() leaked %d file descriptor(s) "
496 "(or descriptor mismatch)",
497 cname, fdcount [1] - fdcount [0]);
498}
499
500
502template <class charT>
503void test_get (const char *loc_name,
504 const char* const text[5][5],
505 const char *cname)
506{
507 // construct a copy of the named locale or default
508 // when no name is specified
509 const std::locale loc =
510 loc_name ? std::locale (loc_name) : std::locale ();
511
512 const std::messages<charT>& msgs =
513 std::use_facet<std::messages<charT> > (loc);
514
515 const charT def[] = {
516 'N', 'o', ' ', 'm', 'e', 's', 's', 'a', 'g', 'e', '.', '\0'
517 };
518
519 std::messages_base::catalog cat = -1;
520
521 cat = open_catalog (msgs, CAT_NAME, loc, 0, cname, __LINE__);
522
523 if (cat < 0)
524 return;
525
526 typedef std::char_traits<charT> Traits;
527 typedef std::allocator<charT> Allocator;
528 typedef std::basic_string<charT, Traits, Allocator> String;
529
530 for (int setId = 1; setId <= MAX_SETS; ++setId) {
531
532 for (int msgId = 1; msgId <= MAX_MESSAGES; ++msgId) {
533
534 const int id = msg_id (setId, msgId);
535 const String got = msgs.get (cat, setId, id, def);
536
537 rw_assert (got == widen<charT>(text [setId - 1][msgId - 1]),
538 0, __LINE__,
539 "messages<%s>::get(%d, %d, %d, %{*Ac}) == %#s, "
540 "got %{#*S}",
541 cname, cat, setId, id,
542 int (sizeof *def), def,
543 text [setId - 1][msgId - 1],
544 int (sizeof (charT)), &got);
545 }
546 }
547
548 // bad catalog id
549 const std::messages_base::catalog bad_cat = 777;
550
551 try {
552 // get() will either throw or return `def'
553 // when passed a bad catalog id
554 const String got = msgs.get (bad_cat, 1, 1, def);
555
556 rw_assert (def == got, 0, __LINE__,
557 "messages<%s>::get(%d, 1, 1, %{*Ac}) == %{*Ac}, got %{#*S}",
558 cname, bad_cat, int (sizeof *def), def,
559 int (sizeof *def), def, int (sizeof (charT)), &got);
560 }
561#ifndef _RWSTD_NO_EXCEPTIONS
562
563 catch (std::exception &ex) {
564 rw_assert (true, 0, __LINE__,
565 "messages<%s>::get(%d, 1, 1, %{*Ac}) unexpectedly threw "
566 "exception(%#s)", cname, bad_cat, int (sizeof *def), def,
567 ex.what ());
568 }
569
570#endif // _RWSTD_NO_EXCEPTIONS
571
572 // Bad set id
573#ifndef _WIN32
574 // When we use resource files for the message catalogs
575 // the set ids are ignored.
576 rw_assert (msgs.get (cat, 777, 1, def) == def, 0, __LINE__,
577 "messages<%s>::get(%d, 777, 1, %{#*Ac}) == %{#*Ac}",
578 cname, cat, int (sizeof *def), def, int (sizeof *def), def);
579#endif // _WIN32
580
581 // Bad message id
582 rw_assert (msgs.get (cat, 1, 777, def) == def, 0, __LINE__,
583 "messages<%s>::get(%d, 777, 1) == \"\"", cname);
584
585 close_catalog (msgs, cat, false, cname, __LINE__);
586}
587
588
590template <class charT>
591void test_use_codecvt (const char *cname)
592{
594
595 const std::locale loc (std::locale::classic (), &cvt);
596
597 const charT def[] = {
598 'N', 'o', ' ', 'm', 'e', 's', 's', 'a', 'g', 'e', '.', '\0'
599 };
600
601 const std::messages<charT>& msgs =
602 std::use_facet <std::messages<charT> >(loc);
603
604 cvt.used_ = false;
605
606 std::messages_base::catalog cat = -1;
607
608 cat = open_catalog (msgs, CAT_NAME, loc, 0, cname, __LINE__);
609
610 if (cat < 0)
611 return;
612
613 cvt.check_state_ = true;
614
615 const int msgid = msg_id (1, 1);
616 std::basic_string<charT> got = msgs.get (cat, 1, msgid, def);
617 rw_assert (cvt.used_, 0, __LINE__,
618 "messages<%s>::get(%d, 1, %d, const char_type*) "
619 "uses codecvt<%1$s, char>", cname, cat, msgid);
620
621 rw_assert (cvt.valid_state_, 0, __LINE__,
622 "messages<%s>::get(%d, 1, %d, const char_type*) "
623 "initializes mbstate_t argument", cname, cat, msgid);
624
625 cvt.check_state_ = false;
626 cvt.partial_ = true;
627
628 got = msgs.get (cat, 1, msgid, def);
629 rw_assert (got == def, 0, __LINE__,
630 "messages<%s>::get(%d, 1, %d, %{*Ac}) == %{*Ac}",
631 cname, cat, msgid, int (sizeof *def), def,
632 int (sizeof *def), def);
633
634 cvt.partial_ = false;
635 cvt.noconv_ = true;
636
637 got = msgs.get (cat, 1, msgid, def);
638 rw_assert (got == widen<charT>(std::string(messages[0][0])), 0, __LINE__,
639 "messages<%s>::get(%d, 1, %d, %{*Ac}) == %#s, got %{#*S}",
640 cname, cat, msgid, int (sizeof *def), def,
641 messages [0][0], int (sizeof (charT)), &got);
642
643 cvt.noconv_ = false;
644
645 close_catalog (msgs, cat, false, cname, __LINE__);
646
647 cvt.used_ = false;
648}
649
650
653template <class charT>
654void test_use_nls_path (const char *cname)
655{
656 // get working directory
657 char cwd [2048];
658 cwd [0] = '\0';
659 if (!rw_error (0 != getcwd (cwd, 2048), 0, __LINE__,
660 "getcwd(%#p, %u) failed: %{#m} (%m)", cwd, 2048))
661 return;
662
663 char* const nlspath = new char [std::strlen (cwd) + 512];
664
665 // create NLSPATH string
666 std::sprintf (nlspath, "NLSPATH=%s/%%N.cat", cwd);
667 rw_putenv (nlspath);
668
669 const std::locale loc;
670
671 const std::messages<charT>& msgs =
672 std::use_facet <std::messages<charT> >(loc);
673
674 const std::messages_base::catalog cat =
675 open_catalog (msgs, NLS_CAT_NAME, loc, 0, "char", __LINE__);
676
677 if (-1 < cat)
678 close_catalog (msgs, cat, false, cname, __LINE__);
679
680 delete[] nlspath;
681}
682
683
686template <class charT>
687void stress_test (const char *cname)
688{
689 // NLSPATH must be defined
690 RW_ASSERT (0 != std::getenv ("NLSPATH"));
691
692 char catalog_names [24][24];
693 const std::size_t NCATS = sizeof catalog_names / sizeof *catalog_names;
694
695 std::messages_base::catalog cats [NCATS];
696
697 // detect descriptor leaks
698 const int fd1 = open (__FILE__, O_RDONLY);
699
700 const std::locale loc = std::locale::classic ();
701
702 const std::messages<charT>& msgs =
703 std::use_facet<std::messages<charT> > (loc);
704
705 std::size_t i;
706
707 for (i = 0; i < NCATS; i++) {
708
709 char msg_name [NCATS];
710
711#ifndef _WIN32
712 std::sprintf (msg_name, "rwstdmessages_%d.msg", int (i));
713#else
714 std::sprintf (msg_name, "rwstdmessages_%d.rc", int (i));
715#endif
716
717 rw_create_catalog (msg_name, catalog.c_str ());
718
719 const char* const dot = std::strrchr (msg_name, '.');
720 std::strncpy (catalog_names[i], msg_name, dot - msg_name);
721 *(catalog_names[i] + (dot - msg_name)) = '\0';
722
723 // open each catalog (expect success)
724 cats [i] = open_catalog (msgs, catalog_names [i],
725 loc, 0, cname, __LINE__);
726 }
727
728 // close smallest first and check for descriptor leaks
729 for (i = 0; i < NCATS; ++i) {
730 if (-1 != cats [i])
731 close_catalog (msgs, cats [i], false, cname, __LINE__);
732 }
733
734 int fd2 = open (__FILE__, O_RDONLY);
735 rw_assert (fd2 - fd1 == 1, 0, __LINE__,
736 "messages<%s>::close() leaked %d file descriptors",
737 cname, fd2 - fd1 - 1);
738
739 // open again, close largest first and check for descriptor leaks
740 for (i = 0; i < NCATS; ++i) {
741 cats [i] = open_catalog (msgs, catalog_names [i],
742 loc, 0, cname, __LINE__);
743 }
744
745 for (i = NCATS; i-- > 0; ) {
746 if (-1 != cats [i])
747 close_catalog (msgs, cats [i], false, cname, __LINE__);
748 }
749
750 // close again fd2
751 close (fd2);
752
753 fd2 = open (__FILE__, O_RDONLY);
754 rw_assert (fd2 - fd1 == 1, 0, __LINE__,
755 "messages<%s>::close() leaked %d file descriptors",
756 cname, fd2 - fd1 - 1);
757
758 close (fd1);
759 close (fd2);
760
761 rw_system (SHELL_RM_F "rwstdmessages_*");
762}
763
764
772
773
774template <class charT>
775void test_messages (charT, const char *cname, const char *locname)
776{
777 if (rw_note (0 <= opt_has_facet, 0, __LINE__,
778 "has_facet<messages<%s> > tests disabled", cname)) {
779
780 // exercise has_facet and use_facet in the default locale
781 test_has_facet<charT>(0, cname);
782
783 // exercise has_facet and use_facet in locale("C")
784 test_has_facet<charT>("C", cname);
785
786 // exercise has_facet and use_facet in a named locale
787 test_has_facet<charT>(locname, cname);
788 }
789
790 if (rw_note (0 <= opt_open_close, 0, __LINE__,
791 "messages<%s>::open() and close() tests disabled", cname)) {
792 test_open_close<charT>("C", cname);
793 test_open_close<charT>(locname, cname);
794 }
795
796 if (rw_note (0 <= opt_has_facet, 0, __LINE__,
797 "messages<%s>::get() tests disabled", cname)) {
798 test_get<charT>("C", messages, cname);
799 test_get<charT>(locname, messages, cname);
800 }
801
802 if (rw_note (0 <= opt_has_facet, 0, __LINE__,
803 "messages<%s> codecvt tests disabled", cname))
804 test_use_codecvt<charT>(cname);
805
806 if (rw_note (0 <= opt_nlspath, 0, __LINE__,
807 "messages<%s> NLSPATH tests disabled", cname))
808 test_use_nls_path<charT>(cname);
809
810 if (rw_note (0 <= opt_has_facet, 0, __LINE__,
811 "messages<%s> codecvt tests disabled", cname))
812 stress_test<charT>(cname);
813}
814
815
817static int
818run_test (int, char*[])
819{
820
821#ifdef _RWSTD_OS_AIX
822
823 // must do this so that NLSPATH lookup works correctly for both
824 // the C and POSIX locales.
825 const int p = rw_putenv ("LC__FASTMSG=false");
826 rw_note (!p, 0, __LINE__, "failed to set LC__FASTMSG");
827
828#endif // _RWSTD_OS_AIX
829
830#ifdef _RWSTD_NO_DYNAMIC_CAST
831
832 // if dynamic_cast isn't supported then has_facet() can't
833 // reliably detect if a facet is installed or not.
834 rw_warn (0 != opt_has_facet, 0, __LINE__,
835 "dynamic_cast not supported, disabling has_facet tests");
836
837 opt_has_facet = -1;
838
839#endif // _RWSTD_NO_DYNAMIC_CAST
840
841
842 for (int i = 0; i < MAX_SETS; ++i) {
843 for (int j = 0; j < MAX_MESSAGES; ++j)
844 catalog.append (messages [i][j], std::strlen (messages [i][j]) + 1);
845
846 catalog.append (1, '\0');
847 }
848
849 const char* const locname = find_named_locale ();
850
851 rw_create_catalog (MSG_NAME, catalog.c_str ());
852
853 test_messages (char (), "char", locname);
854
855#ifndef _RWSTD_NO_WCHAR_T
856
857 test_messages (wchar_t (), "wchar_t", locname);
858
859#endif // _RWSTD_NO_WCHAR_T
860
861 std::remove (CAT_NAME);
862
863 return 0;
864}
865
866
867
869int main (int argc, char *argv[])
870{
871 return rw_test (argc, argv, __FILE__,
872 "lib.category.messages",
873 0 /* no comment */,
874 run_test,
875 "|-has_facet~ "
876 "|-open_close~ "
877 "|-get~ "
878 "|-codecvt~ "
879 "|-nlspath~ "
880 "|-stress-test~ ",
883 &opt_get,
887 (void*)0 /* sentinel */);
888}
#define i
Definition 17.names.cpp:126
#define line
Definition 17.names.cpp:490
#define res
Definition 17.names.cpp:531
#define loc
Definition 17.names.cpp:492
#define Allocator
Definition 17.names.cpp:440
#define Traits
Definition 17.names.cpp:556
#define j
Definition 17.names.cpp:127
#define charT
Definition 17.names.cpp:456
#define p
Definition 17.names.cpp:132
volatile int result
std::messages_byname< char > MessagesByname
std::messages< char > Messages
void test_use_nls_path(const char *cname)
int opt_stress_test
#define open(f, m)
const char * find_named_locale()
#define MAX_MESSAGES
void test_use_codecvt(const char *cname)
void test_open_close(const char *loc_name, const char *cname)
#define NLS_CAT_NAME
int opt_has_facet
int msg_id(int set, int id)
int opt_get
void test_has_facet(const char *loc_name, const char *cname)
#define CAT_NAME
void close_catalog(const std::messages< charT > &msgs, std::messages_base::catalog cat, bool expect_exception, const char *cname, int line)
int opt_nlspath
#define MSG_NAME
void test_messages(charT, const char *cname, const char *locname)
std::basic_string< charT > widen(std::string message)
std::messages_base::catalog open_catalog(const std::messages< charT > &msgs, const char *cat_name, const std::locale &loc, int expect, const char *cname, int line)
#define MAX_SETS
void test_get(const char *loc_name, const char *const text[5][5], const char *cname)
void stress_test(const char *cname)
#define close(f)
int opt_codecvt
int opt_open_close
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define main
#define _THROWS()
#define LC_ALL
#define _RWSTD_UNUSED(arg)
Definition _defs.h:972
#define _TRY
Definition _defs.h:850
#define _CATCH(ex)
Definition _defs.h:851
const char * name
Definition codecvt1.cpp:72
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_info(int, const char *, int, const char *,...)
Definition driver.cpp:1681
_TEST_EXPORT int rw_note(int, const char *, int, const char *,...)
Definition driver.cpp:1664
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630
_TEST_EXPORT int rw_error(int, const char *, int, const char *,...)
Definition driver.cpp:1613
_TEST_EXPORT int rw_warn(int, const char *, int, const char *,...)
Definition driver.cpp:1647
_TEST_EXPORT int rw_putenv(const char *, int=-1)
Definition environ.cpp:69
_TEST_EXPORT int rw_nextfd(int *)
Definition file.cpp:478
#define SHELL_RM_F
Definition rw_file.h:57
_TEST_EXPORT char * rw_locales(int=_UNUSED_CAT, const char *=0, bool=true)
Definition locale.cpp:368
_TEST_EXPORT int rw_create_catalog(const char *, const char *)
Definition locale.cpp:920
_TEST_EXPORT int rw_system(const char *,...)
Definition process.cpp:328
#define RW_ASSERT(expr)
std::codecvt< charT, char, std::mbstate_t > Base
Base::intern_type intern_type
static bool check_state_
bool do_always_noconv() const _THROWS(())
Base::extern_type extern_type
static bool valid_state_
CodeCvt(std::size_t ref=1U)
Base::state_type state_type
Base::result result
static bool noconv_
static bool used_
static bool partial_
result do_in(state_type &state, const extern_type *from, const extern_type *from_end, const extern_type *&from_next, intern_type *to, intern_type *to_end, intern_type *&to_next) const