Return-Path: Delivered-To: apmail-incubator-stdcxx-commits-archive@www.apache.org Received: (qmail 94117 invoked from network); 22 Sep 2006 00:42:56 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 22 Sep 2006 00:42:56 -0000 Received: (qmail 67350 invoked by uid 500); 22 Sep 2006 00:42:56 -0000 Delivered-To: apmail-incubator-stdcxx-commits-archive@incubator.apache.org Received: (qmail 67329 invoked by uid 500); 22 Sep 2006 00:42:56 -0000 Mailing-List: contact stdcxx-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-commits@incubator.apache.org Received: (qmail 67318 invoked by uid 99); 22 Sep 2006 00:42:55 -0000 Received: from idunn.apache.osuosl.org (HELO idunn.apache.osuosl.org) (140.211.166.84) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 21 Sep 2006 17:42:55 -0700 Authentication-Results: idunn.apache.osuosl.org smtp.mail=sebor@apache.org; spf=permerror X-ASF-Spam-Status: No, hits=-9.4 required=5.0 tests=ALL_TRUSTED,NO_REAL_NAME Received-SPF: error (idunn.apache.osuosl.org: domain apache.org from 140.211.166.113 cause and error) Received: from [140.211.166.113] ([140.211.166.113:59075] helo=eris.apache.org) by idunn.apache.osuosl.org (ecelerity 2.1.1.8 r(12930)) with ESMTP id 3E/72-06791-A7133154 for ; Thu, 21 Sep 2006 17:42:35 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id 485DB1A9827; Thu, 21 Sep 2006 17:42:19 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r448754 [5/6] - /incubator/stdcxx/trunk/util/ Date: Fri, 22 Sep 2006 00:42:17 -0000 To: stdcxx-commits@incubator.apache.org From: sebor@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20060922004219.485DB1A9827@eris.apache.org> X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Modified: incubator/stdcxx/trunk/util/locale.cpp URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/locale.cpp?view=diff&rev=448754&r1=448753&r2=448754 ============================================================================== --- incubator/stdcxx/trunk/util/locale.cpp (original) +++ incubator/stdcxx/trunk/util/locale.cpp Thu Sep 21 17:42:16 2006 @@ -26,7 +26,7 @@ * **************************************************************************/ -#if defined(__linux__) && !defined (_XOPEN_SOURCE) +#if defined (__linux__) && !defined (_XOPEN_SOURCE) // on Linux define _XOPEN_SOURCE to get CODESET defined in # define _XOPEN_SOURCE 500 /* Single UNIX conformance */ #endif // __linux__ @@ -35,27 +35,27 @@ #include _RWSTD_SYS_TYPES_H #ifndef _MSC_VER -# include -# include // for close () +# include // for mmap() +# include // for close () # include # include #else -# include // for open() +# include // for open() # include #endif // _MSC_VER -#include +#include // for INT_MAX, INT_MIN #include #include #include -#include -#include -#include +#include // for map +#include // for vector +#include // for cerr, cout #include -#include +#include // for fstream -#include +// #include #include #include #include @@ -70,41 +70,72 @@ #include "memchk.h" #include "diagnostic.h" +/**************************************************************************/ -bool print_cat_names = false; -bool print_keywords = false; +#ifndef LC_MESSAGES +# ifdef _RWSTD_LC_MESSAGES +# define LC_MESSAGES _RWSTD_LC_MESSAGES +# else +# define LC_MESSAGES -1 +# endif // _RWSTD_LC_MESSAGES +#endif // LC_MESSAGES + + +// set to true in response to the "-c" command line option requesting +// locale to print the name of each section before printing out its +// contents +static bool print_sect_names = false; + +// set to true in response to the "-k" command line option requesting +// locale to print the name of each keyword before printing out its +// value +static bool print_keywords = false; // set to true in response to the "-h" command line option requesting // locale to try to use character names from the original charmap used // to create the locale (if possible) -bool decode = false; +static bool decode = false; -bool is_utf8 = true; -bool POSIX_output = true; - -const _RW::__rw_codecvt_t* codecvt_st = 0; -const _RW::__rw_collate_t* collate_st = 0; -const _RW::__rw_ctype_t* ctype_st = 0; -const _RW::__rw_time_t* time_st = 0; -const _RW::__rw_num_t* num_st = 0; -const _RW::__rw_mon_t* mon_st = 0; -const _RW::__rw_punct_t* num_punct_st = 0; -const _RW::__rw_punct_t* mon_punct_st = 0; -const _RW::__rw_messages_t* messages_st = 0; - -Charmap *collate_charmap = 0; -Charmap *ctype_charmap = 0; -Charmap *time_charmap = 0; -Charmap *num_charmap = 0; -Charmap *mon_charmap = 0; -Charmap *messages_charmap = 0; - -const char* current_locales[8]; -bool is_env_set[8]; +// set to false in response to the "-l" command line option requesting +// locale to produce output suitable for processing by the localedef +// utility +static bool posix_output = true; + +// set to true in response to the "-p" command line option requesting +// locale to produce output using the symbols from the POSIX Portable +// Character Set +static bool use_pcs = false; + +static bool is_utf8 = true; + + +static const _RW::__rw_codecvt_t* codecvt_st = 0; +static const _RW::__rw_collate_t* collate_st = 0; +static const _RW::__rw_ctype_t* ctype_st = 0; +static const _RW::__rw_time_t* time_st = 0; +static const _RW::__rw_num_t* num_st = 0; +static const _RW::__rw_mon_t* mon_st = 0; +static const _RW::__rw_punct_t* num_punct_st = 0; +static const _RW::__rw_punct_t* mon_punct_st = 0; +static const _RW::__rw_messages_t* messages_st = 0; + + +static const char sect_charmap[] = "CHARMAP"; +static const char sect_lc_all[] = "LC_ALL"; +static const char sect_lc_collate[] = "LC_COLLATE"; +static const char sect_lc_ctype[] = "LC_CTYPE"; +static const char sect_lc_messages[] = "LC_MESSAGES"; +static const char sect_lc_monetary[] = "LC_MONETARY"; +static const char sect_lc_numeric[] = "LC_NUMERIC"; +static const char sect_lc_time[] = "LC_TIME"; // length of the largest string you want printed #define MAX_LINE_LEN 50 +// for convenience +typedef unsigned char UChar; + +/**************************************************************************/ int validate (const void *addr, std::size_t nbytes) { @@ -113,7 +144,7 @@ if (nbytes != size) { if (size) issue_diag (E_INVAL, true, 0, - "invalid size at %p: %u, expected %u\n", + "invalid size at address %p: %u, expected %u\n", addr, size, nbytes); else issue_diag (E_INVAL, true, 0, @@ -153,10 +184,16 @@ // silently use the hardcoded 'POSIX' locale const void* -initialize_struct (const std::string &loc_path_root, - const char *all_val, const char *lang_val, - const char *cat_name, const char *codeset_name) +init_struct (const std::string &loc_path_root, + const char *cat_name, const char *codeset_name) { + // check to see if the LC_ALL or LC_LANG environment variable + // was set, if LC_LANG was not set it defaults to "C" + static const char* const all_val = std::getenv ("LC_ALL"); + static const char* lang_val = std::getenv ("LANG"); + if (0 == lang_val) + lang_val = "C"; + // if LC_ALL is set, use that value for this locale // otherwise, find out what the environment value is for this category // is and if it is not set use the value in LC_LANG @@ -230,14 +267,12 @@ template const FacetData* -initialize (const std::string &loc_path_root, - const char *all_val, const char *lang_val, - const char *cat_name, const char *codeset_name, - FacetData*) +init_section (const std::string &loc_path_root, + const char *cat_name, const char *codeset_name, + FacetData*) { const void* const ptr = - initialize_struct (loc_path_root, all_val, lang_val, - cat_name, codeset_name); + init_struct (loc_path_root, cat_name, codeset_name); if (ptr && 0 == validate (ptr, sizeof (FacetData))) return static_cast(ptr); @@ -246,7 +281,8 @@ } -void initialize_structs () +static void +init_sections () { std::string loc_path_root; @@ -257,63 +293,49 @@ loc_path_root = root ? root : "."; loc_path_root += _RWSTD_PATH_SEP; - // check to see if the LC_ALL or LC_LANG environment was set. - // if LC_LANG was not set it defaults to "C" - const char* const all_val = std::getenv ("LC_ALL"); - const char* lang_val = std::getenv ("LANG"); - if (0 == lang_val) - lang_val = "C"; - // points to the name of the codeset used by all non-empty // locale categories, otherwise 0 - const char *codeset_name = 0; + const char *codeset = 0; - // points to the name of the LC_XXX environment variable - // that refers to the collate category whose codeset is - // described by codeset_name; the value of the variable - // is used to determine the location of the codeset - // conversion database file, e.g., when the environment - // variable RWSTD_LOCALE_ROOT is not defined and locale - // is invoked like so: - // LC_CTYPE=/foo/bar/somelocale locale --charmap - const char *lc_cat_envvar = 0; + // points to the name of the LC_XXX environment variable that refers + // to the collate category whose codeset is described by codeset; + // the value of the variable is used to determine the location of + // the codeset conversion database file, e.g., when the environment + // variable RWSTD_LOCALE_ROOT is not defined and locale is invoked + // like so: + // LC_CTYPE=/foo/bar/somelocale locale --charmap + const char *section = 0; // initialize collate_st - collate_st = initialize (loc_path_root, - all_val, lang_val, - "LC_COLLATE", 0, - (_RW::__rw_collate_t*)0); + collate_st = init_section (loc_path_root, sect_lc_collate, 0, + (_RW::__rw_collate_t*)0); if (collate_st) { validate (collate_st->codeset_name ()); - codeset_name = collate_st->codeset_name (); - lc_cat_envvar = "LC_COLLATE"; + codeset = collate_st->codeset_name (); + section = sect_lc_collate; } // initialize ctype_st - ctype_st = initialize (loc_path_root, - all_val, lang_val, - "LC_CTYPE", 0, + ctype_st = init_section (loc_path_root, sect_lc_ctype, 0, (_RW::__rw_ctype_t*)0); if (ctype_st) { validate (ctype_st->codeset_name ()); - if (codeset_name) { - if (std::strcmp (codeset_name, ctype_st->codeset_name ())) - codeset_name = 0; + if (codeset) { + if (std::strcmp (codeset, ctype_st->codeset_name ())) + codeset = 0; } else { - codeset_name = ctype_st->codeset_name (); - lc_cat_envvar = "LC_CTYPE"; + codeset = ctype_st->codeset_name (); + section = sect_lc_ctype; } } // initialize mon_st - mon_punct_st = initialize (loc_path_root, - all_val, lang_val, - "LC_MONETARY", 0, + mon_punct_st = init_section (loc_path_root, sect_lc_monetary, 0, (_RW::__rw_punct_t*)0); if (0 != mon_punct_st) { @@ -325,20 +347,18 @@ if (mon_st) { validate (mon_st->codeset_name ()); - if (codeset_name) { - if (std::strcmp (codeset_name, mon_st->codeset_name ())) - codeset_name = 0; + if (codeset) { + if (std::strcmp (codeset, mon_st->codeset_name ())) + codeset = 0; } else { - codeset_name = mon_st->codeset_name (); - lc_cat_envvar = "LC_MONETARY"; + codeset = mon_st->codeset_name (); + section = sect_lc_monetary; } } // initialize num_st - num_punct_st = initialize (loc_path_root, - all_val, lang_val, - "LC_NUMERIC", 0, + num_punct_st = init_section (loc_path_root, sect_lc_numeric, 0, (_RW::__rw_punct_t*)0); if (0 != num_punct_st) { num_st = _RWSTD_STATIC_CAST (const _RW::__rw_num_t*, @@ -349,90 +369,210 @@ if (num_st) { validate (num_st->codeset_name ()); - if (codeset_name) { - if (std::strcmp (codeset_name, num_st->codeset_name ())) - codeset_name = 0; + if (codeset) { + if (std::strcmp (codeset, num_st->codeset_name ())) + codeset = 0; } else { - codeset_name = num_st->codeset_name (); - lc_cat_envvar = "LC_NUMERIC"; + codeset = num_st->codeset_name (); + section = sect_lc_numeric; } } // initialize time_st - time_st = initialize (loc_path_root, - all_val, lang_val, - "LC_TIME", 0, - (_RW::__rw_time_t*)0); + time_st = init_section (loc_path_root, sect_lc_time, 0, + (_RW::__rw_time_t*)0); if (time_st) { validate (time_st->codeset_name ()); - if (codeset_name) { - if (std::strcmp (codeset_name, time_st->codeset_name ())) - codeset_name = 0; + if (codeset) { + if (std::strcmp (codeset, time_st->codeset_name ())) + codeset = 0; } else { - codeset_name = time_st->codeset_name (); - lc_cat_envvar = "LC_TIME"; + codeset = time_st->codeset_name (); + section = sect_lc_time; } } // initialize messages_st - messages_st = initialize (loc_path_root, - all_val, lang_val, - "LC_MESSAGES", 0, + messages_st = init_section (loc_path_root, sect_lc_messages, 0, (_RW::__rw_messages_t*)0); if (messages_st) { validate (messages_st->codeset_name ()); - if (codeset_name) { - if (std::strcmp (codeset_name, messages_st->codeset_name ())) - codeset_name = 0; + if (codeset) { + if (std::strcmp (codeset, messages_st->codeset_name ())) + codeset = 0; } else { - codeset_name = messages_st->codeset_name (); - lc_cat_envvar = "LC_MESSAGES"; + codeset = messages_st->codeset_name (); + section = sect_lc_messages; } } - if (codeset_name) { - + if (codeset) { // initialize codecvt_st - codecvt_st = initialize (loc_path_root, - all_val, lang_val, - lc_cat_envvar, - codeset_name, - (_RW::__rw_codecvt_t*)0); + codecvt_st = init_section (loc_path_root, section, codeset, + (_RW::__rw_codecvt_t*)0); + } +} + + +static const char* +set_locale (int lc_cat, const char *locname, const std::string &charmap_name) +{ +#ifndef _MSC_VER + + assert (0 != locname); + + locname = std::setlocale (lc_cat, locname); + + if (locname) + return locname; + + std::string encoding (charmap_name.substr (0, charmap_name.rfind ('.'))); + + std::vector aliases; + get_cname_aliases (encoding, aliases); + + std::vector::iterator pos; + + for (pos = aliases.begin(); !is_utf8 && pos != aliases.end(); pos++) + if (*pos == "utf8") + is_utf8 = true; + + const char* names = get_installed_locales (); + + for (; *names; names += std::strlen (names) + 1) { + + if (0 != std::setlocale (LC_CTYPE, names)) { + + const char* const codeset = nl_langinfo (CODESET); + + for (pos = aliases.begin (); pos != aliases.end (); ++pos) + if (codeset == *pos) + return names; + } } + +#endif // _MSC_VER + + return 0; } -Charmap* get_charmap (const char* name) +/**************************************************************************/ + +static const Charmap* +get_charmap (int lc_cat) { - if (ctype_charmap && ctype_charmap->get_charmap_name () == name) - return ctype_charmap; + if (!decode) + return 0; + + static const char* const lang = std::getenv ("LANG"); + static const char* const lc_all = std::getenv (sect_lc_all); + static const char* const lc_collate = std::getenv (sect_lc_collate); + static const char* const lc_ctype = std::getenv (sect_lc_ctype); + static const char* const lc_messages = std::getenv (sect_lc_messages); + static const char* const lc_monetary = std::getenv (sect_lc_monetary); + static const char* const lc_numeric = std::getenv (sect_lc_numeric); + static const char* const lc_time = std::getenv (sect_lc_time); + + static const Charmap* cmaps [6]; + static bool cmaps_tried [sizeof cmaps / sizeof *cmaps]; + + const char* charmap = 0; + const char* locale = 0; + + const Charmap** cmap = 0; + + switch (lc_cat) { + + case LC_COLLATE: + charmap = collate_st ? collate_st->charmap_name () : ""; + locale = lc_collate; + cmap = cmaps + 0; + break; + + case LC_CTYPE: + charmap = ctype_st ? ctype_st->charmap_name () : ""; + locale = lc_ctype; + cmap = cmaps + 1; + break; + + case LC_MESSAGES: + charmap = messages_st ? messages_st->charmap_name () : ""; + locale = lc_messages; + cmap = cmaps + 2; + break; + + case LC_MONETARY: + charmap = mon_st ? mon_st->charmap_name () : ""; + locale = lc_monetary; + cmap = cmaps + 3; + break; - if (collate_charmap && collate_charmap->get_charmap_name () == name) - return collate_charmap; + case LC_NUMERIC: + charmap = num_st ? num_st->charmap_name () : ""; + locale = lc_numeric; + cmap = cmaps + 4; + break; + + case LC_TIME: + charmap = time_st ? time_st->charmap_name () : ""; + locale = lc_time; + cmap = cmaps + 5; + break; + + default: assert (!"bad LC_XXX constant"); + } + + assert (0 != cmap); + assert (0 != charmap); + + if (*cmap && (*cmap)->get_charmap_name () == charmap) + return *cmap; + + if (cmaps_tried [cmap - cmaps]) + return *cmap; - if (time_charmap && time_charmap->get_charmap_name () == name) - return time_charmap; + cmaps_tried [cmap - cmaps] = true; - if (mon_charmap && mon_charmap->get_charmap_name () == name) - return mon_charmap; + // LC_ALL overrides any other LC_XXX setting + if (lc_all && *lc_all) + locale = lc_all; - if (num_charmap && num_charmap->get_charmap_name () == name) - return num_charmap; + // when neither LC_ALL or LC_XX is specified fall back on LANG + if (0 == locale) + locale = lang ? lang : "POSIX"; + + set_locale (lc_cat, locale, charmap); // look for the charmap directory - const char* const src_root = std::getenv ("RWSTD_SRC_ROOT"); - if (0 != src_root) { + static const char* const src_root = std::getenv ("RWSTD_SRC_ROOT"); + + if (0 == src_root) { + static int warning_issued = 0; + if (0 == warning_issued++) + issue_diag (W_CHARMAP, false, 0, "RWSTD_SRC_ROOT not set\n"); + } + else if ('\0' == *charmap) { + static int warning_issued = 0; + if (0 == warning_issued++) + issue_diag (W_CHARMAP, false, 0, "no charmap name\n"); + } + else { std::string charmap_path = src_root; - charmap_path = charmap_path + "/charmaps/" + name; + + charmap_path += _RWSTD_PATH_SEP; + charmap_path += "charmaps"; + charmap_path += _RWSTD_PATH_SEP; + charmap_path += charmap; // search for a C library locale that uses the same encoding - std::string std_encoding (name); + std::string std_encoding (charmap); # if !defined(_MSC_VER) std::string C_locale (get_C_encoding_locale (std_encoding)); @@ -440,125 +580,203 @@ std::string C_locale (""); # endif - return new Charmap (C_locale.c_str (), charmap_path.c_str(), - 0 == std::strcmp ("utf8.cm", name), - false, true, false); + *cmap = new Charmap (C_locale.c_str (), charmap_path.c_str(), + 0 == std::strcmp ("utf8.cm", charmap), + false, true, false); } - issue_diag (503, true, 0, "RWSTD_SRC_ROOT not set, giving up\n"); - return 0; + return cmap ? *cmap : 0; } -std::string create_str (const char* str, const wchar_t* w_str, - Charmap* charmap) +static std::string +escape_value (unsigned val, bool always = false) { - assert (0 != str); - - typedef std::map ::const_iterator rn_cmap_iter; - typedef std::map ::const_iterator rw_cmap_iter; + // set of printable ASCII characters + static const char printable [] = { + // ................ + // 0123456789abcdef + /* 0. */ " " + /* 1. */ " " + /* 2. */ " ! #$%''()*+,-./" + /* 3. */ "0123456789: <=>?" + /* 4. */ "@ABCDEFGHIJKLMNO" + /* 5. */ "PQRSTUVWXYZ[ ]^_" + /* 6. */ "`abcdefghijklmno" + /* 7. */ "pqrstuvwxyz{|}~ " + }; - if (0 == charmap) - return str; + static const char hexdigit[] = "0123456789abcdef"; std::string ret; - if (0 == ctype_st || ctype_st->mb_cur_max == 1) { - // if we were given a charmap file we will look up each character in - // the charmap to get the symbolic name associated with the value - while (*str != '\0'){ - rn_cmap_iter ch_pos = charmap->get_rn_cmap().find - ((unsigned char)*str); - if (ch_pos != charmap->get_rn_cmap().end()) { - ret += ch_pos->second; - } - str++; - } + + if ( (UChar (';') == val || UChar ('"') == val || UChar ('\\') == val) + && !always) { + ret += '\\'; + ret += char (val); + } + else if ( use_pcs && val <= UChar ('~') + && Charmap::portable_charset [val]) { + // use symbols from the Portable Character Set + ret += Charmap::portable_charset [val]; + } + else if (val < sizeof printable - 1 && ' ' != printable [val] && !always) { + // represent non-space printable characters as themselves + ret += printable [val]; + } + else if (UChar (' ') == val && !always) { + // represent space as itself unless always escaping + ret += ' '; } else { - while (*w_str != '\0') { - rw_cmap_iter ch_wpos = charmap->get_rw_cmap().find (*w_str); - if (ch_wpos != charmap->get_rw_cmap().end()) { - ret += ch_wpos->second; - } - w_str++; - } + // non-printable character or escaping requested + + char buf [40]; + char *pbuf = buf; + + if (0xffU < val) + *pbuf++ = '"'; + + const unsigned mask = 0xffU << (sizeof mask - 1) * 8; + + while (val && 0 == (val & mask)) + val <<= 8; + + do { + *pbuf++ = '\\'; + *pbuf++ = 'x'; + *pbuf++ = hexdigit [val >> (sizeof val * 8 - 4)]; + val <<= 4; + *pbuf++ = hexdigit [val >> (sizeof val * 8 - 4)]; + } while (val <<= 4); + + if ('"' == *buf) + *pbuf++ = '"'; + + *pbuf = '\0'; + + ret = buf; } + return ret; } -std::string create_str (wchar_t ch, Charmap* charmap) + +static std::string +create_str (const char* str, const wchar_t* wstr, const Charmap *charmap) { - typedef std::map ::const_iterator rw_cmap_iter; + if (0 == str) + str = ""; std::string ret; - if (charmap) { - rw_cmap_iter ch_pos = charmap->get_rw_cmap().find (ch); - if (ch_pos != charmap->get_rw_cmap().end()) - ret += ch_pos->second; - else { - issue_diag (501, true, 0, "%d character in locale database " - "could not be found in character map file\n", ch); - } + if (0 == charmap) { + + // when no character map is provided format non-printable + // characters using escape sequences + for (; *str; ++str) + ret += escape_value (UChar (*str)); + + return ret; + } + + typedef std::map ::const_iterator rn_cmap_iter; + typedef std::map ::const_iterator rw_cmap_iter; + + if (0 == ctype_st || 1 == ctype_st->mb_cur_max) { + // look up each character in the character map and (try + // to) get the symbolic name associated with each, falling + // back on ordinary formatting using escape sequences when + // the character is not found in the map + + const rn_cmap_iter end = charmap->get_rn_cmap ().end (); + + for (; *str != '\0'; ++str) { + const UChar uc = UChar (*str); + const rn_cmap_iter it = charmap->get_rn_cmap ().find (uc); + + ret += (it == end) ? escape_value (uc) : it->second; + } } else { - ret += (unsigned char)ch; + const rw_cmap_iter end = charmap->get_rw_cmap ().end (); + + if (0 == wstr) + wstr = L""; + + for ( ; *wstr != '\0'; ++wstr) { + + const unsigned uc = unsigned (*wstr); + + const rw_cmap_iter it = charmap->get_rw_cmap ().find (uc); + + ret += (it == end) ? escape_value (uc) : it->second; + } } - return ret; + return ret; } -std::string create_keyword (const char* str) + +// formats a character in human readable form +static std::string +create_str (unsigned ch, const Charmap *charmap) { - std::string keyword_str = str; - if (POSIX_output) - keyword_str += '='; - else - keyword_str += ' '; + typedef std::map ::const_iterator rw_cmap_iter; - return (print_keywords ? keyword_str : ""); -} + std::string ret; -const char* set_locale (const std::string& charmap_name) -{ -#ifndef _MSC_VER - std::string encoding (charmap_name.substr (0, charmap_name.rfind ('.'))); + if (charmap) { + // look up character in the reverse wide character map + const rw_cmap_iter ch_pos = charmap->get_rw_cmap ().find (ch); - std::vectoraliases; - get_cname_aliases (encoding, aliases); + if (ch_pos == charmap->get_rw_cmap ().end ()) { + // issue a warning when not found and format it below + issue_diag (W_CHAR, true, 0, "wide character L'\\%x' " + "not found in character map\n", ch); + } + else + return ch_pos->second; + } - std::vector::iterator pos; + return escape_value (ch); +} - for (pos = aliases.begin(); !is_utf8 && pos != aliases.end(); pos++) - if (*pos == "utf8") - is_utf8 = true; - const char* names = get_installed_locales (); +static void +print_section (const char* name, bool end = false) +{ + assert (0 != name); - for (; *names; names += std::strlen (names) + 1) { + if (print_sect_names) + std::cout << (end ? "END " : "") << name << '\n'; +} - if (0 != std::setlocale (LC_CTYPE, names)) { - std::string codeset = nl_langinfo(CODESET); - for (pos = aliases.begin(); pos != aliases.end(); pos++) - if (codeset == *pos) - return names; - } - } -#endif // _MSC_VER - return 0; +static void +print_keyword (const char* str) +{ + assert (0 != str); + + if (print_keywords) + std::cout << str << (posix_output ? '=' : ' '); } +/**************************************************************************/ // place holder for function that prints the "C" locale LC_COLLATE category -void print_c_lc_collate () +static void +print_c_lc_collate () { assert (0); } -wchar_t get_wchar_from_offset(unsigned int offset, - const unsigned int* wchar_map, - unsigned int num_wchars) { +/**************************************************************************/ + +static wchar_t +get_wchar_from_offset(unsigned int offset, + const unsigned int* wchar_map, + unsigned int num_wchars) { unsigned int beg = 0; unsigned int end = num_wchars; while (beg <= end) { @@ -575,9 +793,10 @@ } -void print_weight (const unsigned int* weightp, - unsigned int num_weights, - unsigned int longest_weight) +static void +print_weight (const unsigned int* weightp, + unsigned int num_weights, + unsigned int longest_weight) { // FIXME: ignore the order of the element ++weightp; @@ -589,26 +808,8 @@ if (*weightp != UINT_MAX) { if (0 == *weightp) std::cout << "IGNORE;"; - else if (*weightp <= UCHAR_MAX) { - std::cout << "\\d" << *weightp << ';'; - } - else { - std::cout << '"'; - - unsigned wt = *weightp; - - for (unsigned inx = sizeof wt; wt && inx--; ) { - - const unsigned byte = - (wt >> CHAR_BIT * inx) & UCHAR_MAX; - - wt &= ~(wt << (CHAR_BIT * inx)); - - if (byte || wt) - std::cout << "\\d" << byte; - } - std::cout << "\";"; - } + else + std::cout << escape_value (*weightp, true) << ';'; } } } @@ -617,12 +818,13 @@ } -void write_coll_info (const std::string &ch, unsigned int idx, - unsigned int tab_num) +static void +write_coll_info (const std::string &ch, unsigned int idx, + unsigned int tab_num) { - typedef unsigned char UChar; - if (collate_st->num_elms > 1) { + const Charmap* const cmap = get_charmap (LC_COLLATE); + typedef std::map ::const_iterator n_cmap2_iter; const unsigned int* tab = collate_st->get_n_tab (tab_num); unsigned int first = collate_st->get_first_char_in_n_tab(tab_num); @@ -637,12 +839,12 @@ } else { // we found the offset to the weight - if (collate_charmap) { + if (cmap) { // first we need to print the symbolic name n_cmap2_iter n_cmap2_it = - collate_charmap->get_n_cmap2().find(new_ch); - if (n_cmap2_it != collate_charmap->get_n_cmap2().end()) - std::cout << collate_charmap->get_rw_cmap().find( + cmap->get_mb_cmap().find(new_ch); + if (n_cmap2_it != cmap->get_mb_cmap().end()) + std::cout << cmap->get_rw_cmap().find( n_cmap2_it->second)->second; else ; @@ -668,52 +870,71 @@ } } -void print_ce_info (unsigned int tab_num, const std::string& mb_str, - std::map &ce_map) { - static unsigned int ce_num = 0; - const unsigned int *tab = collate_st->get_n_ce_tab (tab_num); - unsigned char first = collate_st->get_first_char_in_n_ce_tab (tab_num); - unsigned char last = collate_st->get_last_char_in_n_ce_tab (tab_num); - std::string cur_mb; - for (unsigned int i = first; i <= last; i++) { - cur_mb = mb_str; - cur_mb += (unsigned char) i; - if (tab[i-first] != UINT_MAX) { - if (tab[i-first] & 0x80000000) { + +static void +print_ce_info (unsigned tab_num, + const std::string &mb_str, + std::map &ce_map) +{ + static unsigned ce_num = 0; + + const unsigned* const tab = collate_st->get_n_ce_tab (tab_num); + + const unsigned first = collate_st->get_first_char_in_n_ce_tab (tab_num); + const unsigned last = collate_st->get_last_char_in_n_ce_tab (tab_num); + + std::string mbchar; + + const Charmap* const cmap = get_charmap (LC_COLLATE); + + for (unsigned i = first; i <= last; ++i) { + + mbchar = mb_str; + mbchar += UChar (i); + + const unsigned elem = tab [i - first]; + + if (elem != UINT_MAX) { + + if (elem & 0x80000000) { // it's an offset to another table. recursively call // print_ce_info with the new table number. - print_ce_info (tab[i-first] &~ 0x80000000, cur_mb, ce_map); + print_ce_info (elem &~ 0x80000000, mbchar, ce_map); } else { // we found the end of the collating element - // now we need to do a lookup in the narrow character maps to - // find the symbolic names for the characters that make up - // this collating element. + // now we need to do a lookup in the narrow character maps + // and find the symbolic names for the characters that make + // up this collating element // sym is sized at 13 because there will never be more then // 99,999 collating elements - char sym[13]; + char sym [13]; std::sprintf (sym, "", ce_num++); - ce_map.insert (std::make_pair (sym, tab[i-first])); + ce_map.insert (std::make_pair (sym, elem)); std::cout << "collating-element " << sym << " from \""; - if (0 == collate_charmap) - std::cout << cur_mb << "\"\n"; + if (0 == cmap) + std::cout << mbchar << "\"\n"; else { - unsigned int first_char = 0; - std::map::const_iterator it; - for (unsigned int j = 1; j <= cur_mb.size(); j++) { - if ((it = collate_charmap->get_n_cmap2().find - (cur_mb.substr (first_char, j))) - != collate_charmap->get_n_cmap2().end()) { - std::cout << (collate_charmap->get_rw_cmap().find + const std::map &cm = + cmap->get_mb_cmap (); + + unsigned ch = 0; + + for (unsigned j = 1; j <= mbchar.size (); ++j) { + const std::map::const_iterator + it = cm.find (mbchar.substr (ch, j)); + + if (it != cm.end ()) { + std::cout << (cmap->get_rw_cmap ().find (it->second))->second; - first_char = j; + ch = j; } - } + std::cout << "\"\n"; } } @@ -722,26 +943,40 @@ } -void print_lc_collate () +static int +print_lc_collate (const char *section, int) { - if (print_cat_names) - std::cout << "LC_COLLATE\n"; + print_section (section); - if (0 == collate_st) { - //print_c_lc_collate(); - } - else { - // if the collate_charmap has not been initialized then initialize it - if (0 == collate_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[1])) - set_locale (collate_st->charmap_name()); -#endif // _MSC_VER - collate_charmap = get_charmap (collate_st->charmap_name()); + if (collate_st) { + + if (decode) { + + // print out internal collate_st data + std::cout << "# collate data:" + << "\n# codeset: \"" + << collate_st->codeset_name () + << "\"\n# charmap: \"" + << collate_st->charmap_name () + << "\"\n# codeset_off: " + << collate_st->codeset_off + << "\n# charmap_off: " + << collate_st->charmap_off + << "\n# elm_size: " + << collate_st->elm_size + << "\n# num_elms: " + << collate_st->num_elms + << "\n# num_wchars: " + << collate_st->num_wchars + << "\n# longest_weight: " + << int (collate_st->longest_weight) + << "\n# num_weights: " + << int (collate_st->num_weights) + << "\n# largest_ce: " + << int (collate_st->largest_ce) + << '\n'; } + std::map ce_map; typedef std::map::iterator ce_map_iter; @@ -772,7 +1007,7 @@ "in collate definition\n"); } if (i == collate_st->num_weights - 1) - std::cout << std::endl; + std::cout << '\n'; else std::cout << ';'; } @@ -782,291 +1017,381 @@ // first print out the collating elements - for (ce_map_iter ce_map_it = ce_map.begin(); - ce_map_it != ce_map.end(); ce_map_it++) { - std::cout << ce_map_it->first << " "; - print_weight (collate_st->get_weight (ce_map_it->second), + for (ce_map_iter it = ce_map.begin (); it != ce_map.end (); ++it) { + std::cout << it->first << " "; + + print_weight (collate_st->get_weight (it->second), collate_st->num_weights, collate_st->longest_weight); } - std::string ch; - write_coll_info (ch, 0, 0); + write_coll_info ("", 0, 0); + if (collate_st->undefined_optimization) { std::cout << "UNDEFINED "; - print_weight (collate_st->get_weight (collate_st->undefined_weight_idx), - collate_st->num_weights, collate_st->longest_weight); + + const unsigned idx = collate_st->undefined_weight_idx; + + print_weight (collate_st->get_weight (idx), + collate_st->num_weights, + collate_st->longest_weight); } std::cout << "\norder_end\n"; } - if (print_cat_names) - std::cout << "END LC_COLLATE\n"; + print_section (section, true); + return 0; } -// print_mask takes in a ctype_base::mask value and prints all the +/**************************************************************************/ + +// print_mask takes in a ctype_base::mask value and prints all the // characters in that mask category. If a charmap was given on the // command line then it will look up the symbolic name and print that instead -void print_mask(std::ctype_base::mask m, bool print_cat) +static int +print_mask (const char *section, int mask) { std::string out; - if (print_cat) - std::cout << "LC_CTYPE\n"; - switch (m){ - case std::ctype_base::upper: - std::cout << create_keyword("upper"); - break; - case std::ctype_base::lower: - std::cout << create_keyword("lower"); - break; - case std::ctype_base::space: - std::cout << create_keyword("space"); - break; - case std::ctype_base::print: - std::cout << create_keyword("print"); - break; - case std::ctype_base::alpha: - std::cout << create_keyword("alpha"); - break; - case std::ctype_base::cntrl: - std::cout << create_keyword("cntrl"); - break; - case std::ctype_base::punct: - std::cout << create_keyword("punct"); - break; - case std::ctype_base::graph: - std::cout << create_keyword("graph"); - break; - case std::ctype_base::digit: - std::cout << create_keyword("digit"); - break; - case std::ctype_base::xdigit: - std::cout << create_keyword("xdigit"); - break; - default: - break; + if (section) + print_section (section); + + const char *keyword = 0; + + switch (mask) { + case std::ctype_base::upper: keyword = "upper"; break; + case std::ctype_base::lower: keyword = "lower"; break; + case std::ctype_base::space: keyword = "space"; break; + case std::ctype_base::print: keyword = "print"; break; + case std::ctype_base::alpha: keyword = "alpha"; break; + case std::ctype_base::cntrl: keyword = "cntrl"; break; + case std::ctype_base::punct: keyword = "punct"; break; + case std::ctype_base::graph: keyword = "graph"; break; + case std::ctype_base::digit: keyword = "digit"; break; + case std::ctype_base::xdigit: keyword = "xdigit"; break; + default: break; } + + if (keyword) + print_keyword (keyword); + + int nchars = 0; + if (0 != ctype_st) { - // if the ctype_charmap has not been initialized then initialize it - if (0 == ctype_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[0])) - set_locale (ctype_st->charmap_name()); -#endif // _MSC_VER - ctype_charmap = get_charmap (ctype_st->charmap_name()); - } + const Charmap* const cmap = get_charmap (LC_CTYPE); + // go through the entire mask_table and print out each - // character that has this mask value. - for (size_t k = 0; k < ctype_st->wmask_s; k++) { - if (ctype_st->wmask_tab(k).mask & m) { - out += create_str (ctype_st->wmask_tab(k).ch, ctype_charmap); - for (size_t j = k + 1; j < ctype_st->wmask_s; j++) - if (ctype_st->wmask_tab(j).mask & m) { - if (out.size() >= MAX_LINE_LEN && !POSIX_output) - out += ";\\"; - else + // character that has the specified mask, counting the + // matching characters in the process + // avoid printing masks without a keyword while still + // counting such characters +#if 1 + for (std::size_t i = 0; i != ctype_st->wmask_s; ++i) { + + if (ctype_st->wmask_tab (i).mask & mask) { + + ++nchars; + + if (keyword) { + std::cout << create_str (ctype_st->wmask_tab (i).ch, cmap); + + if (i + 1 < ctype_st->wmask_s) + std::cout << ';'; + } + } + } +#else + for (std::size_t k = 0; k < ctype_st->wmask_s; ++k) { + + if (ctype_st->wmask_tab (k).mask & mask) { + + if (keyword) + out += create_str (ctype_st->wmask_tab (k).ch, cmap); + + ++nchars; + + for (std::size_t j = k + 1; j < ctype_st->wmask_s; ++j) { + + if (ctype_st->wmask_tab (j).mask & mask) { + + if (keyword) { out += ';'; + + if (out.size () >= MAX_LINE_LEN && !posix_output) + out += '\\'; + } + break; } + } } - if (out.size() > MAX_LINE_LEN && !POSIX_output) { - std::cout << out << '\n'; - out.clear(); + if (keyword && MAX_LINE_LEN < out.size () && !posix_output) { + std::cout << out << '\n'; + out.clear (); } } + std::cout << out; +#endif + } - std::cout << '\n'; + if (keyword) + std::cout << '\n'; + + return nchars; } -void print_toupper (bool print_cat) +static int +print_toupper (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_CTYPE\n"; + print_section (sect_lc_ctype); - std::cout << create_keyword ("toupper"); + print_keyword (keyword); std::string out; + + // number of characters in the maps + int nchars = 0; + if (0 != ctype_st) { - // if the ctype_charmap has not been initialized then initialize it - if (0 == ctype_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[0])) - set_locale (ctype_st->charmap_name()); -#endif // _MSC_VER - ctype_charmap = get_charmap (ctype_st->charmap_name()); - } - // print out each pair in the toupper table. - // the wide char table is used because it contains all characters - for (size_t j = 0; j < ctype_st->wtoupper_s(); j++) { - out = out + "(" + create_str (ctype_st->wtoupper_tab(j).lower, - ctype_charmap) - + "," + create_str (ctype_st->wtoupper_tab(j).upper, - ctype_charmap) + ")"; - if (j != ctype_st->wtoupper_s() - 1) { - if (out.size() >= MAX_LINE_LEN && !POSIX_output) - out += ";\\"; + + const Charmap* const cmap = get_charmap (LC_CTYPE); + + const std::size_t count = ctype_st->wtoupper_s (); + + nchars += count; + + // print out each pair in the toupper table. + // the wide char table is used because it contains all characters + for (std::size_t j = 0; j < count; ++j) { + out += '('; + out += create_str (ctype_st->wtoupper_tab (j).lower, cmap); + out += ','; + out += create_str (ctype_st->wtoupper_tab (j).upper, cmap); + out += ')'; + + if (j != count - 1) { + if (out.size () >= MAX_LINE_LEN && !posix_output) + out += ";\\"; else out += ';'; } - if (out.size() > MAX_LINE_LEN && !POSIX_output) { + + if (out.size () > MAX_LINE_LEN && !posix_output) { std::cout << out << '\n'; - out.clear(); + out.clear (); } } + std::cout << out; } std::cout << '\n'; + + return nchars; } -void print_tolower (bool print_cat) +static int +print_tolower (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_CTYPE\n"; + print_section (sect_lc_ctype); - std::cout << create_keyword ("tolower"); + print_keyword (keyword); std::string out; + // number of characters in the maps + int nchars = 0; + if (0 != ctype_st) { - // if the ctype_charmap has not been initialized then initialize it - if (0 == ctype_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[0])) - set_locale (ctype_st->charmap_name()); -#endif // _MSC_VER - ctype_charmap = get_charmap (ctype_st->charmap_name()); - } - for (size_t j = 0; j < ctype_st->wtolower_s(); j++) { - out = out + "(" + create_str (ctype_st->wtolower_tab(j).upper, - ctype_charmap) - + "," + create_str (ctype_st->wtolower_tab(j).lower, - ctype_charmap) + ")"; - if (j != ctype_st->wtolower_s() - 1) { - if (out.size() >= MAX_LINE_LEN && !POSIX_output) + const Charmap* const cmap = get_charmap (LC_CTYPE); + + const std::size_t count = ctype_st->wtolower_s (); + + nchars += count; + + for (std::size_t j = 0; j < count; ++j) { + out += '('; + out += create_str (ctype_st->wtolower_tab (j).upper, cmap); + out += ','; + out += create_str (ctype_st->wtolower_tab (j).lower, cmap); + out += ')'; + + if (j != count - 1) { + if (out.size () >= MAX_LINE_LEN && !posix_output) out += ";\\"; else out += ';'; } - if (out.size() > MAX_LINE_LEN && !POSIX_output) { + if (out.size () > MAX_LINE_LEN && !posix_output) { std::cout << out << '\n'; - out.clear(); + out.clear (); } } std::cout << out; } std::cout << '\n'; + + return nchars; } -void print_lc_ctype () +static int +print_lc_ctype (const char *section, int) { - if (print_cat_names) - std::cout << "LC_CTYPE\n"; + print_section (section); - print_mask (std::ctype_base::upper, false); - print_mask (std::ctype_base::lower, false); - print_mask (std::ctype_base::space, false); - print_mask (std::ctype_base::print, false); - print_mask (std::ctype_base::cntrl, false); - print_mask (std::ctype_base::alpha, false); - print_mask (std::ctype_base::digit, false); - print_mask (std::ctype_base::punct, false); - print_mask (std::ctype_base::graph, false); - print_mask (std::ctype_base::xdigit, false); - print_toupper (false); - print_tolower (false); + if (0 != ctype_st && decode) { + + // print out internal ctype_st data + std::cout << "# ctype data:" + << "\n# codeset: \"" + << ctype_st->codeset_name () + << "\"\n# charmap: \"" + << ctype_st->charmap_name () + << "\"\n# codeset_off: " + << ctype_st->codeset_off + << "\n# charmap_off: " + << ctype_st->charmap_off + << "\n# wmask_s: " + << ctype_st->wmask_s + << "\n# wtoupper_off: " + << ctype_st->wtoupper_off + << "\n# wtolower_off: " + << ctype_st->wtolower_off + << "\n# wmask_off: " + << ctype_st->wmask_off + << "\n# ctype_ext_off: " + << ctype_st->ctype_ext_off + << "\n# mb_cur_max: " + << unsigned (ctype_st->mb_cur_max) + << '\n'; + } - if (print_cat_names) - std::cout << "END LC_CTYPE\n"; + const std::size_t nupper = print_mask (0, std::ctype_base::upper); + const std::size_t nlower = print_mask (0, std::ctype_base::lower); + const std::size_t nspace = print_mask (0, std::ctype_base::space); + const std::size_t nprint = print_mask (0, std::ctype_base::print); + const std::size_t ncntrl = print_mask (0, std::ctype_base::cntrl); + const std::size_t nalpha = print_mask (0, std::ctype_base::alpha); + const std::size_t ndigit = print_mask (0, std::ctype_base::digit); + const std::size_t npunct = print_mask (0, std::ctype_base::punct); + const std::size_t ngraph = print_mask (0, std::ctype_base::graph); + const std::size_t nxdigit = print_mask (0, std::ctype_base::xdigit); + + const int all_masks = + std::ctype_base::upper | std::ctype_base::lower + | std::ctype_base::space | std::ctype_base::print + | std::ctype_base::cntrl | std::ctype_base::alpha + | std::ctype_base::digit | std::ctype_base::punct + | std::ctype_base::graph | std::ctype_base::xdigit; + + // count the number of all characters in all tables + const std::size_t nall = print_mask (0, -1); + + // count the number of characters whose mask is other than + // any of those specified (probably mistakes) + const std::size_t nother = print_mask (0, ~all_masks); + + const std::size_t ntoupper = print_toupper ("toupper", 0); + const std::size_t ntolower = print_tolower ("tolower", 0); + + if (0 != ctype_st && decode) { + std::cout << "\n# ctype stats:" + << "\n# total characters: " << nall + << "\n# upper characters: " << nupper + << "\n# lower characters: " << nlower + << "\n# space characters: " << nspace + << "\n# print characters: " << nprint + << "\n# cntrl characters: " << ncntrl + << "\n# alpha characters: " << nalpha + << "\n# digit characters: " << ndigit + << "\n# punct characters: " << npunct + << "\n# graph characters: " << ngraph + << "\n# xdigit characters: " << nxdigit + << "\n# unclassified: " << nother + << "\n# tolower pairs: " << ntolower + << "\n# toupper pairs: " << ntoupper + << "\n"; + } + + print_section (section, true); + + return 0; } +/**************************************************************************/ -void print_decimal_point (bool print_cat) +static int +print_decimal_point (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_NUMERIC\n"; - std::cout << create_keyword ("decimal_point"); + print_section (sect_lc_numeric); + + print_keyword (keyword); + if (0 == num_st) - std::cout << "\"" << create_str(".", 0, 0) << "\"\n"; + std::cout << '"' << create_str (".", 0, 0) << "\"\n"; else { - // if the num_charmap has not been initialized then initialize it - if (0 == num_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[4])) - set_locale (num_st->charmap_name()); -#endif // _MSC_VER - num_charmap = get_charmap (num_st->charmap_name()); - } - std::cout << "\"" - << create_str (_RWSTD_STATIC_CAST (const char*, - num_punct_st->decimal_point (0)), - _RWSTD_STATIC_CAST (const wchar_t*, - num_punct_st->decimal_point (1)), - num_charmap) - << "\"\n"; + const char* const dp = + _RWSTD_STATIC_CAST (const char*, num_punct_st->decimal_point (0)); + + const wchar_t* const wdp = + _RWSTD_STATIC_CAST(const wchar_t*, num_punct_st->decimal_point (1)); + + const Charmap* const cmap = get_charmap (LC_NUMERIC); + + std::cout << '"' << create_str (dp, wdp, cmap) << "\"\n"; } + return 0; } -void print_thousands_sep (bool print_cat) + + +static int +print_thousands_sep (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_NUMERIC\n"; - std::cout << create_keyword ("thousands_sep"); + print_section (sect_lc_numeric); + + print_keyword (keyword); + if (0 == num_st) std::cout << "\"\"\n"; else { - // if the num_charmap has not been initialized then initialize it - if (0 == num_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[4])) - set_locale (num_st->charmap_name()); -#endif // _MSC_VER - num_charmap = get_charmap (num_st->charmap_name()); - } + const char* const ts = + _RWSTD_STATIC_CAST (const char*, num_punct_st->thousands_sep (0)); - std::cout << "\"" - << create_str (_RWSTD_STATIC_CAST - (const char*, - num_punct_st->thousands_sep(false)), - _RWSTD_STATIC_CAST - (const wchar_t*, - num_punct_st->thousands_sep(true)), - num_charmap) - << "\"\n"; + const wchar_t* const wts = + _RWSTD_STATIC_CAST(const wchar_t*, num_punct_st->thousands_sep (1)); + + const Charmap* const cmap = get_charmap (LC_NUMERIC); + + std::cout << '"' << create_str (ts, wts, cmap) << "\"\n"; } + + return 0; } -void print_grouping (bool print_cat) + +static int +print_grouping (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_NUMERIC\n"; - std::cout << create_keyword ("grouping"); + print_section (sect_lc_numeric); + + print_keyword (keyword); + if (0 == num_st) std::cout << "-1\n"; else { @@ -1079,137 +1404,155 @@ std::cout << (int)((const char*)num_punct_st->grouping())[i] << '\n'; } + + return 0; } -void print_lc_numeric () + + +static int +print_lc_numeric (const char *section, int) { - if (print_cat_names) - std::cout << "LC_NUMERIC\n"; + print_section (section); + + if (0 != num_st && decode) { - print_decimal_point (false); - print_thousands_sep (false); - print_grouping (false); + // print out internal numeric_st data + std::cout << "# numeric data:" + << "\n# codeset: \"" + << num_st->codeset_name () + << "\"\n# charmap: \"" + << num_st->charmap_name () + << "\"\n# codeset_off: " + << num_st->codeset_off + << "\n# charmap_off: " + << num_st->charmap_off + << '\n'; + } - if (print_cat_names) - std::cout << "END LC_NUMERIC\n"; + // keywords follow the established order on popular platforms + print_decimal_point ("decimal_point", 0); + print_thousands_sep ("thousands_sep", 0); + print_grouping ("grouping", 0); + print_section (section, true); + + return 0; } -void print_int_curr_symbol (bool print_cat) +/**************************************************************************/ + +static int +print_int_curr_symbol (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("int_curr_symbol"); + print_section (sect_lc_monetary); + + print_keyword (keyword); + if (0 == mon_st) std::cout << "\"\"\n"; else { - // if the mon_charmap has not been initialized then initialize it - if (0 == mon_charmap && decode) - mon_charmap = get_charmap (mon_st->charmap_name()); - std::cout << "\"" << create_str (_RWSTD_STATIC_CAST (const char*, - mon_st->curr_symbol (1, 0)), - _RWSTD_STATIC_CAST (const wchar_t*, - mon_st->curr_symbol (1, 1)), - mon_charmap) - << "\"\n"; + const char* const cs = + _RWSTD_STATIC_CAST (const char*, mon_st->curr_symbol (1, 0)); + + const wchar_t* const wcs = + _RWSTD_STATIC_CAST (const wchar_t*, mon_st->curr_symbol (1, 1)); + + const Charmap* const cmap = get_charmap (LC_MONETARY); + + std::cout << '"' << create_str (cs, wcs, cmap) << "\"\n"; } + + return 0; } -void print_currency_symbol (bool print_cat) + +static int +print_currency_symbol (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("currency_symbol"); + print_section (sect_lc_monetary); + + print_keyword (keyword); + if (0 == mon_st) std::cout << "\"\"\n"; else { - // if the mon_charmap has not been initialized then initialize it - if (0 == mon_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encodin -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[3])) - set_locale (mon_st->charmap_name()); -#endif // _MSC_VER - mon_charmap = get_charmap (mon_st->charmap_name()); - } + const char* const cs = + _RWSTD_STATIC_CAST (const char*, mon_st->curr_symbol (0, 1)); - std::cout << "\"" << create_str (_RWSTD_STATIC_CAST (const char*, - mon_st->curr_symbol (0, 0)), - _RWSTD_STATIC_CAST (const wchar_t*, - mon_st->curr_symbol (0, 1)), - mon_charmap) - << "\"\n"; + const wchar_t* const wcs = + _RWSTD_STATIC_CAST (const wchar_t*, mon_st->curr_symbol (0, 1)); + + const Charmap* const cmap = get_charmap (LC_MONETARY); + + std::cout << '"' << create_str (cs, wcs, cmap) << "\"\n"; } + + return 0; } -void print_mon_decimal_point (bool print_cat) + +static int +print_mon_decimal_point (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("mon_decimal_point"); + print_section (sect_lc_monetary); + + print_keyword (keyword); + if (0 == mon_st) std::cout << "\"\"\n"; else { - // if the mon_charmap has not been initialized then initialize it - if (0 == mon_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[3])) - set_locale (mon_st->charmap_name()); -#endif // _MSC_VER - mon_charmap = get_charmap (mon_st->charmap_name()); - } + const char* const dp = + _RWSTD_STATIC_CAST (const char*, mon_punct_st->decimal_point (0)); - std::cout << "\"" - << create_str (_RWSTD_STATIC_CAST (const char*, - mon_punct_st->decimal_point (0)), - _RWSTD_STATIC_CAST (const wchar_t*, - mon_punct_st->decimal_point (1)), - mon_charmap) - << "\"\n"; + const wchar_t* const wdp = + _RWSTD_STATIC_CAST(const wchar_t*, mon_punct_st->decimal_point (1)); + + const Charmap* const cmap = get_charmap (LC_MONETARY); + + std::cout << '"' << create_str (dp, wdp, cmap) << "\"\n"; } + + return 0; } -void print_mon_thousands_sep (bool print_cat) + +static int +print_mon_thousands_sep (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("mon_thousands_sep"); + print_section (sect_lc_monetary); + + print_keyword (keyword); + if (0 == mon_st) std::cout << "\"\"\n"; else { - // if the mon_charmap has not been initialized then initialize it - if (0 == mon_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[3])) - set_locale (mon_st->charmap_name()); -#endif // _MSC_VER - mon_charmap = get_charmap (mon_st->charmap_name()); - } + const char* const ts = + _RWSTD_STATIC_CAST (const char*, mon_punct_st->thousands_sep (0)); - std::cout << "\"" - << create_str (_RWSTD_STATIC_CAST - (const char*, - mon_punct_st->thousands_sep(false)), - _RWSTD_STATIC_CAST - (const wchar_t*, - mon_punct_st->thousands_sep(true)), - mon_charmap) - << "\"\n"; + const wchar_t* const wts = + _RWSTD_STATIC_CAST(const wchar_t*, mon_punct_st->thousands_sep (1)); + + const Charmap* const cmap = get_charmap (LC_MONETARY); + + std::cout << '"' << create_str (ts, wts, cmap) << "\"\n"; } + + return 0; } -void print_mon_grouping (bool print_cat) + +static int +print_mon_grouping (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("mon_grouping"); + print_section (sect_lc_monetary); + + print_keyword (keyword); + if (0 == mon_st) std::cout << "-1\n"; else { @@ -1221,582 +1564,427 @@ std::cout << (int)((const char*)mon_punct_st->grouping())[i] << '\n'; } + + return 0; } -void print_positive_sign (bool print_cat) + +static int +print_positive_sign (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("positive_sign"); + print_section (sect_lc_monetary); + + print_keyword (keyword); + if (0 == mon_st) std::cout << "\"\"\n"; else { - // if the mon_charmap has not been initialized then initialize it - if (0 == mon_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[3])) - set_locale (mon_st->charmap_name()); -#endif // _MSC_VER - mon_charmap = get_charmap (mon_st->charmap_name()); - } + const char* const ps = + _RWSTD_STATIC_CAST (const char*, mon_st->positive_sign (0)); - std::cout << "\"" << create_str (_RWSTD_STATIC_CAST (const char*, - mon_st->positive_sign (0)), - _RWSTD_STATIC_CAST (const wchar_t*, - mon_st->positive_sign (1)), - mon_charmap) - << "\"\n"; + const wchar_t* const wps = + _RWSTD_STATIC_CAST (const wchar_t*, mon_st->positive_sign (1)); + + const Charmap* const cmap = get_charmap (LC_MONETARY); + + std::cout << '"' << create_str (ps, wps, cmap) << "\"\n"; } + + return 0; } -void print_negative_sign (bool print_cat) + +static int +print_negative_sign (const char *keyword, int print_cat) { if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("negative_sign"); + print_section (sect_lc_monetary); + + print_keyword (keyword); + if (0 == mon_st) std::cout << "\"\"\n"; else { - // if the mon_charmap has not been initialized then initialize it - if (0 == mon_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[3])) - set_locale (mon_st->charmap_name()); -#endif // _MSC_VER - mon_charmap = get_charmap (mon_st->charmap_name()); - } + const char* const ns = + _RWSTD_STATIC_CAST (const char*, mon_st->negative_sign (0)); - std::cout << "\"" << create_str (_RWSTD_STATIC_CAST (const char*, - mon_st->negative_sign (0)), - _RWSTD_STATIC_CAST (const wchar_t*, - mon_st->negative_sign (1)), - mon_charmap) - << "\"\n"; + const wchar_t* const wns = + _RWSTD_STATIC_CAST (const wchar_t*, mon_st->negative_sign (1)); + + const Charmap* const cmap = get_charmap (LC_MONETARY); + + std::cout << '"' << create_str (ns, wns, cmap) << "\"\n"; } + return 0; } -void print_int_frac_digits (bool print_cat) + +static void +print_int (const char *keyword, int val, int print_cat) { if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("int_frac_digits"); + print_section (sect_lc_monetary); - signed char c = 0; + print_keyword (keyword); - if (0 == mon_st) - c = -1; - else - c = mon_st->frac_digits [1]; - - std::cout << int(c) << '\n'; + std::cout << val << '\n'; } -void print_frac_digits (bool print_cat) -{ - if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("frac_digits"); - signed char c = 0; +static int +print_int_frac_digits (const char *keyword, int print_cat) +{ + print_int (keyword, mon_st ? mon_st->frac_digits [1] : -1, print_cat); - if (0 == mon_st) - c = -1; - else - c = int(mon_st->frac_digits [0]); + return 0; - std::cout << int(c) << '\n'; } -void print_p_cs_precedes (bool print_cat) -{ - if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("p_cs_precedes"); - - signed char c = 0; - if (0 == mon_st) - c = -1; - else - c = int(mon_st->p_cs_precedes [0]); +static int +print_frac_digits (const char *keyword, int print_cat) +{ + print_int (keyword, mon_st ? mon_st->frac_digits [0] : -1, print_cat); - std::cout << int(c) << '\n'; + return 0; } -void print_n_sep_by_space (bool print_cat) + +static int +print_p_cs_precedes (const char *keyword, int print_cat) { - if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("n_sep_by_space"); + print_int (keyword, mon_st ? mon_st->p_cs_precedes [0] : -1, print_cat); - signed char c = 0; + return 0; +} - if (0 == mon_st) - c = -1; - else - c = int(mon_st->n_sep_by_space [0]); - std::cout << int(c) << '\n'; +static int +print_n_sep_by_space (const char *keyword, int print_cat) +{ + print_int (keyword, mon_st ? mon_st->n_sep_by_space [0] : -1, print_cat); + + return 0; } -void print_p_sep_by_space (bool print_cat) + +static int +print_p_sep_by_space (const char *keyword, int print_cat) { - if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("p_sep_by_space"); + print_int (keyword, mon_st ? mon_st->p_sep_by_space [0] : -1, print_cat); - signed char c = 0; + return 0; +} - if (0 == mon_st) - c = -1; - else - c = int(mon_st->p_sep_by_space [0]); - std::cout << int(c) << '\n'; +static int +print_n_cs_precedes (const char *keyword, int print_cat) +{ + print_int (keyword, mon_st ? mon_st->n_cs_precedes [0] : -1, print_cat); + + return 0; } -void print_n_cs_precedes (bool print_cat) + +static int +print_p_sign_posn (const char *keyword, int print_cat) { - if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("n_cs_precedes"); + print_int (keyword, mon_st ? mon_st->p_sign_posn [0] : -1, print_cat); - signed char c = 0; + return 0; +} - if (0 == mon_st) - c = -1; - else - c = int(mon_st->n_cs_precedes [0]); - std::cout << int(c) << '\n'; +static int +print_n_sign_posn (const char *keyword, int print_cat) +{ + print_int (keyword, mon_st ? mon_st->n_sign_posn [0] : -1, print_cat); + + return 0; } -void print_p_sign_posn (bool print_cat) + +static int +print_int_p_cs_precedes (const char *keyword, int print_cat) { - if (print_cat) - std::cout << "LC_MONETARY\n"; + print_int (keyword, mon_st ? mon_st->p_cs_precedes [1] : -1, print_cat); + + return 0; +} - signed char c = 0; - std::cout << create_keyword ("p_sign_posn"); - if (0 == mon_st) - c = -1; - else - c = int(mon_st->p_sign_posn [0]); +static int +print_int_n_sep_by_space (const char *keyword, int print_cat) +{ + print_int (keyword, mon_st ? mon_st->n_sep_by_space [1] : -1, print_cat); - std::cout << int(c) << '\n'; + return 0; } -void print_n_sign_posn (bool print_cat) + +static int +print_int_p_sep_by_space (const char *keyword, int print_cat) { - if (print_cat) - std::cout << "LC_MONETARY\n"; + print_int (keyword, mon_st ? mon_st->p_sep_by_space [1] : -1, print_cat); - signed char c = 0; + return 0; +} - std::cout << create_keyword ("n_sign_posn"); - if (0 == mon_st) - c = -1; - else - c = int(mon_st->n_sign_posn [0]); - std::cout << int(c) << '\n'; +static int +print_int_n_cs_precedes (const char *keyword, int print_cat) +{ + print_int (keyword, mon_st ? mon_st->n_cs_precedes [1] : -1, print_cat); + + return 0; } -void print_int_p_cs_precedes (bool print_cat) + +static int +print_int_p_sign_posn (const char *keyword, int print_cat) { - if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("int_p_cs_precedes"); + print_int (keyword, mon_st ? mon_st->p_sign_posn [1] : -1, print_cat); - signed char c = 0; + return 0; +} - if (0 == mon_st) - c = -1; - else - c = int(mon_st->p_cs_precedes [1]); - std::cout << int(c) << '\n'; +static int +print_int_n_sign_posn (const char *keyword, int print_cat) +{ + print_int (keyword, mon_st ? mon_st->n_sign_posn [1] : -1, print_cat); + + return 0; } -void print_int_n_sep_by_space (bool print_cat) + +static int +print_lc_monetary (const char *section, int) { - if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("int_n_sep_by_space"); + print_section (section); - signed char c = 0; + if (mon_st && decode) { - if (0 == mon_st) - c = -1; - else - c = int(mon_st->n_sep_by_space [1]); + // print out internal monetary_st data + std::cout << "# monetary data:" + << "\n# codeset: \"" + << mon_st->codeset_name () + << "\"\n# charmap: \"" + << mon_st->charmap_name () + << "\"\n# codeset_off: " + << mon_st->codeset_off + << "\n# charmap_off: " + << mon_st->charmap_off + << '\n'; + } + + // keywords follow the established order on popular platforms + print_int_curr_symbol ("int_curr_symbol", 0); + print_currency_symbol ("currency_symbol", 0); + print_mon_decimal_point ("mon_decimal_point", 0); + print_mon_thousands_sep ("mon_thousands_sep", 0); + print_mon_grouping ("mon_grouping", 0); + print_positive_sign ("positive_sign", 0); + print_negative_sign ("negative_sign", 0); + + print_int_frac_digits ("int_frac_digits", 0); + print_frac_digits ("frac_digits", 0); + + print_p_cs_precedes ("p_cs_precedes", 0); + print_p_sep_by_space ("p_sep_by_space", 0); + print_n_cs_precedes ("n_cs_precedes", 0); + print_n_sep_by_space ("n_sep_by_space", 0); + print_p_sign_posn ("p_sign_posn", 0); + print_n_sign_posn ("n_sign_posn", 0); + + print_int_p_cs_precedes ("int_p_cs_precedes", 0); + print_int_p_sep_by_space ("int_p_sep_by_space", 0); + print_int_n_cs_precedes ("int_n_cs_precedes", 0); + print_int_n_sep_by_space ("int_n_sep_by_space", 0); + print_int_p_sign_posn ("int_p_sign_posn", 0); + print_int_n_sign_posn ("int_n_sign_posn", 0); + + print_section (section, true); - std::cout << int(c) << '\n'; + return 0; } -void print_int_p_sep_by_space (bool print_cat) +/**************************************************************************/ + +static void +print_time_keyword (const char *keyword, int print_cat, + const void *vstr, const void *vwstr) { if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("int_p_sep_by_space"); + print_section (sect_lc_monetary); - signed char c = 0; + if (keyword) + print_keyword (keyword); - if (0 == mon_st) - c = -1; - else - c = int(mon_st->p_sep_by_space [1]); + const Charmap* const cmap = get_charmap (LC_TIME); - std::cout << int(c) << '\n'; + const char* const str = _RWSTD_STATIC_CAST (const char*, vstr); + const wchar_t* const wstr = _RWSTD_STATIC_CAST (const wchar_t*, vwstr); + + std::cout << '"' << create_str (str, wstr, cmap) << "\""; } -void print_int_n_cs_precedes (bool print_cat) + +static int +print_abday (const char *keyword, int print_cat) { - if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("int_n_cs_precedes"); + static const char str[][4] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; - signed char c = 0; + for (std::size_t i = 0; ; ) { - if (0 == mon_st) - c = -1; - else - c = int(mon_st->n_cs_precedes [1]); + print_time_keyword (keyword, print_cat, + time_st ? time_st->abday (i, 0) : str [i], + time_st ? time_st->abday (i, 1) : 0); - std::cout << int(c) << '\n'; -} + keyword = 0; + print_cat = 0; -void print_int_p_sign_posn (bool print_cat) -{ - if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("int_p_sign_posn"); + if (sizeof str / sizeof *str == ++i) + break; - signed char c = 0; + std::cout << ';'; + } - if (0 == mon_st) - c = -1; - else - c = int(mon_st->p_sign_posn [1]); + std::cout << '\n'; - std::cout << int(c) << '\n'; + return 0; } -void print_int_n_sign_posn (bool print_cat) + +static int +print_day (const char *keyword, int print_cat) { - if (print_cat) - std::cout << "LC_MONETARY\n"; - std::cout << create_keyword ("int_n_sign_posn"); + static const char str[][10] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; - signed char c = 0; + for (std::size_t i = 0; ; ) { - if (0 == mon_st) - c = -1; - else - c = int(mon_st->n_sign_posn [1]); - - std::cout << int(c) << '\n'; -} - -void print_lc_monetary () -{ - if (print_cat_names) - std::cout << "LC_MONETARY\n"; - - print_int_curr_symbol (false); - print_currency_symbol (false); - print_mon_decimal_point (false); - print_mon_thousands_sep (false); - print_mon_grouping (false); - print_positive_sign (false); - print_negative_sign (false); - print_int_frac_digits (false); - print_frac_digits (false); - print_p_cs_precedes (false); - print_p_sep_by_space (false); - print_n_cs_precedes (false); - print_n_sep_by_space (false); - print_p_sign_posn (false); - print_n_sign_posn (false); - print_int_p_cs_precedes (false); - print_int_p_sep_by_space (false); - print_int_n_cs_precedes (false); - print_int_n_sep_by_space (false); - print_int_p_sign_posn (false); - print_int_n_sign_posn (false); + print_time_keyword (keyword, print_cat, + time_st ? time_st->day (i, 0) : str [i], + time_st ? time_st->day (i, 1) : 0); + keyword = 0; + print_cat = 0; - if (print_cat_names) - std::cout << "END LC_MONETARY\n"; -} + if (sizeof str / sizeof *str == ++i) + break; -void print_abday (bool print_cat) -{ - if (print_cat) - std::cout << "LC_TIME\n"; - std::cout << create_keyword ("abday"); - if (0 == time_st) - std::cout << "\"" << create_str ("Sun", 0, 0) << "\";" - << "\"" << create_str ("Mon", 0, 0) << "\";" - << "\"" << create_str ("Tue", 0, 0) << "\";\\\n" - << "\"" << create_str ("Wed", 0, 0) << "\";" - << "\"" << create_str ("Thu", 0, 0) << "\";" - << "\"" << create_str ("Fri", 0, 0) << "\";" - << "\"" << create_str ("Sat", 0, 0) << "\"\n"; - else { - // if the time_charmap has not been initialized then initialize it - if (0 == time_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[2])) - set_locale (time_st->charmap_name()); -#endif // _MSC_VER - time_charmap = get_charmap (time_st->charmap_name()); - } - for (unsigned int i = 0; i <= 6; i++) { - std::cout << "\"" - << create_str (_RWSTD_STATIC_CAST - (const char*, time_st->abday (i, 0)), - _RWSTD_STATIC_CAST - (const wchar_t*, time_st->abday (i, 1)), - time_charmap); - if (i != 6) - std::cout << "\";"; - else - std::cout << "\"\n"; - } + std::cout << ';'; } + std::cout << '\n'; + + return 0; } -void print_day (bool print_cat) + +static int +print_abmon (const char *keyword, int print_cat) { - if (print_cat) - std::cout << "LC_TIME\n"; - std::cout << create_keyword ("day"); - if (0 == time_st) - std::cout << "\"" << create_str ("Sunday", 0, 0) << "\";" - << "\"" << create_str ("Monday", 0, 0) << "\";" - << "\"" << create_str ("Tuesday", 0, 0) << "\";\\\n" - << "\"" << create_str ("Wednesday", 0, 0) << "\";" - << "\"" << create_str ("Thursday", 0, 0) << "\";" - << "\"" << create_str ("Friday", 0, 0) << "\";" - << "\"" << create_str ("Saturday", 0, 0) << "\"\n"; + static const char str[][4] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; - else { - // if the time_charmap has not been initialized then initialize it - if (0 == time_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[2])) - set_locale (time_st->charmap_name()); -#endif // _MSC_VER - time_charmap = get_charmap (time_st->charmap_name()); - } - for (unsigned int i = 0; i <= 6; i++) { - std::cout << "\"" - << create_str (_RWSTD_STATIC_CAST - (const char*, time_st->day (i, 0)), - _RWSTD_STATIC_CAST - (const wchar_t*, time_st->day (i, 1)), - time_charmap); - if (i != 6) - std::cout << "\";"; - else - std::cout << "\"\n"; - } - } -} + for (std::size_t i = 0; ; ) { + print_time_keyword (keyword, print_cat, + time_st ? time_st->abmon (i, 0) : str [i], + time_st ? time_st->abmon (i, 1) : 0); -void print_abmon (bool print_cat) -{ - if (print_cat) - std::cout << "LC_TIME\n"; - std::cout << create_keyword ("abmon"); - if (0 == time_st) { - std::cout << "\"" << create_str ("Jan", 0, 0) << "\";" - << "\"" << create_str ("Feb", 0, 0) << "\";" - << "\"" << create_str ("Mar", 0, 0) << "\";"; - if (!POSIX_output) - std::cout << "\\\n"; - std::cout << "\"" << create_str ("Apr", 0, 0) << "\";" - << "\"" << create_str ("May", 0, 0) << "\";" - << "\"" << create_str ("Jun", 0, 0) << "\";"; - if (!POSIX_output) - std::cout << "\\\n"; - std::cout << "\"" << create_str ("Jul", 0, 0) << "\";" - << "\"" << create_str ("Aug", 0, 0) << "\";" - << "\"" << create_str ("Sep", 0, 0) << "\";"; - if (!POSIX_output) - std::cout << "\\\n"; - std::cout << "\"" << create_str ("Oct", 0, 0) << "\";" - << "\"" << create_str ("Nov", 0, 0) << "\";" - << "\"" << create_str ("Dec", 0, 0) << "\"\n"; - } - else { - // if the time_charmap has not been initialized then initialize it - if (0 == time_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[2])) - set_locale (time_st->charmap_name()); -#endif // _MSC_VER - time_charmap = get_charmap (time_st->charmap_name()); - } + keyword = 0; + print_cat = 0; - for (unsigned int i = 0; i <= 11; i++) { - std::cout << "\"" - << create_str (_RWSTD_STATIC_CAST - (const char*, time_st->abmon (i, 0)), - _RWSTD_STATIC_CAST - (const wchar_t*, time_st->abmon (i, 1)), - time_charmap); - if (i != 11) - std::cout << "\";"; - else - std::cout << "\"\n"; + if (sizeof str / sizeof *str == ++i) + break; - if (!(i % 2) && !POSIX_output) - std::cout << "\\\n" ; - } + std::cout << ';'; } + + std::cout << '\n'; + + return 0; } -void print_mon (bool print_cat) + +static int +print_mon (const char *keyword, int print_cat) { - if (print_cat) - std::cout << "LC_TIME\n"; - std::cout << create_keyword ("mon"); - if (0 == time_st) { - std::cout << "\"" << create_str ("January", 0, 0) << "\";" - << "\"" << create_str ("February", 0, 0) << "\";" - << "\"" << create_str ("March", 0, 0) << "\";"; - if (!POSIX_output) - std::cout << "\\\n"; - std::cout << "\"" << create_str ("April", 0, 0) << "\";" - << "\"" << create_str ("May", 0, 0) << "\";" - << "\"" << create_str ("June", 0, 0) << "\";"; - if (!POSIX_output) - std::cout << "\\\n"; - std::cout << "\"" << create_str ("July", 0, 0) << "\";" - << "\"" << create_str ("August", 0, 0) << "\";" - << "\"" << create_str ("September", 0, 0) << "\";"; - if (!POSIX_output) - std::cout << "\\\n"; - std::cout << "\"" << create_str ("October", 0, 0) << "\";" - << "\"" << create_str ("November", 0, 0) << "\";" - << "\"" << create_str ("December", 0, 0) << "\"\n"; - } - else { - // if the time_charmap has not been initialized then initialize it - if (0 == time_charmap && decode) { - // try to set the locale to the locale we are dumping - // if we can't then try to set the locale to any locale - // that uses the same encoding -#ifndef _MSC_VER - if (0 == std::setlocale (LC_CTYPE, current_locales[2])) - set_locale (time_st->charmap_name()); -#endif // MSC_VER - time_charmap = get_charmap (time_st->charmap_name()); - } + static const char str[][10] = { + "January", "February", "March", "April", "May", "June" + "July", "August", "September", "October", "November", "December" + }; - for (unsigned int i = 0; i <= 11; i++) { - std::cout << "\"" - << create_str (_RWSTD_STATIC_CAST - (const char*, time_st->mon (i, 0)), - _RWSTD_STATIC_CAST - (const wchar_t*, time_st->mon (i, 1)), - time_charmap); - if (i != 11) - std::cout << "\";"; - else - std::cout << "\"\n"; + for (std::size_t i = 0; ; ) { - if (!(i % 2) && !POSIX_output) - std::cout << "\\\n" ; - } + print_time_keyword (keyword, print_cat, [... 1502 lines stripped ...]