first commit
This commit is contained in:
676
extern/stdcxx/4.2.1/util/aliases.cpp
vendored
Normal file
676
extern/stdcxx/4.2.1/util/aliases.cpp
vendored
Normal file
@@ -0,0 +1,676 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* aliases.cpp
|
||||
*
|
||||
* $Id: aliases.cpp 648752 2008-04-16 17:01:56Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2008 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <rw/_defs.h>
|
||||
|
||||
#ifdef _RWSTD_EDG_ECCP
|
||||
// disable error #450-D: the type "long long" is nonstandard
|
||||
// issued for uses of the type in Linux system headers (e.g.,
|
||||
// pthreadtypes.h)
|
||||
# pragma diag_suppress 450
|
||||
#endif // vanilla EDG eccp demo
|
||||
|
||||
#ifdef __linux__
|
||||
// on Linux define _XOPEN_SOURCE to get CODESET defined in <langinfo.h>
|
||||
# define _XOPEN_SOURCE 500 /* SUS conformance */
|
||||
# include <sys/types.h>
|
||||
#endif // __linux__
|
||||
|
||||
#include "diagnostic.h"
|
||||
|
||||
#include <cassert> // for assert()
|
||||
#include <cerrno> // for errno
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring> // for memcpy(), strlen()
|
||||
#include <clocale> // for setlocale()
|
||||
#include <locale> // for tolower()
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# ifndef _RWSTD_NO_NL_LANGINFO
|
||||
# include <langinfo.h>
|
||||
# endif
|
||||
#endif // _MSC_VER
|
||||
|
||||
#include "aliases.h"
|
||||
|
||||
#if __GNUG__ == 2 && __GNUC_MINOR__ == 96
|
||||
# include <unistd.h> // for close()
|
||||
|
||||
// declare the POSIX (but not ANSI C) function mkstemp()
|
||||
extern "C" int mkstemp (char*) _LIBC_THROWS ();
|
||||
|
||||
#endif // gcc 2.96
|
||||
|
||||
|
||||
struct alias_t
|
||||
{
|
||||
const char* name; // canonical locale name
|
||||
const char* aliases [8]; // known aliases for the name
|
||||
};
|
||||
|
||||
|
||||
// codesets aliases
|
||||
static const alias_t codeset_aliases [] = {
|
||||
{ "ANSI_X3.4-1968", { "ascii", "usascii", "us-ascii", "us_ascii", 0 } },
|
||||
{ "arabic8", { "arabic-8", "arabic_8", 0 } },
|
||||
// chinese-t <=> chinese traditional
|
||||
{ "BIG5", { "big5", "chinese-t", 0 } },
|
||||
{ "BIG5-HKSCS", { "hkbig5", 0 } },
|
||||
{ "CP1251", { 0 } },
|
||||
{ "CP1255", { 0 } },
|
||||
// !ujis is coming from Unix JIS!
|
||||
{ "EUC-JP", { "eucjp", "eucJP", "euc_jp", "euc", "ujis", 0 } },
|
||||
{ "EUC-KR", { "euckr", "eucKR", "euc_kr", 0 } },
|
||||
{ "EUC-TW", { "euctw", "eucTW", "euc_tw", "cns-11643-1992",
|
||||
"cns11643", 0 } },
|
||||
{ "GB18030", { "gb18030", 0 } },
|
||||
// chinese-s <=> chinese simplified
|
||||
{ "GB2312", { "gb2312", "hp15CN", "chinese-s", 0 } },
|
||||
{ "GBK", { "gbk", 0 } },
|
||||
{ "GEORGIAN-PS", { 0 } },
|
||||
{ "greek8", { "greek-8", "greek_8", 0 } },
|
||||
{ "hebrew8", { "hebrew-8", "hebrew_8", 0 } },
|
||||
{ "IS-620", { 0 } },
|
||||
|
||||
{ "ISO-8859-1",
|
||||
{ "ISO-88591", "ISO_8859-1", "ISO8859-1", "iso88591", "iso1", 0 } },
|
||||
{ "ISO-8859-2",
|
||||
{ "ISO-88592", "ISO_8859-2", "ISO8859-2", "iso88592", "iso2", 0 } },
|
||||
{ "ISO-8859-3",
|
||||
{ "ISO-88593", "ISO_8859-3", "ISO8859-3", "iso88593", "iso3", 0 } },
|
||||
{ "ISO-8859-5",
|
||||
{ "ISO-88595", "ISO_8859-5", "ISO8859-5", "iso88595", "iso5", 0 } },
|
||||
{ "ISO-8859-6",
|
||||
{ "ISO-88596", "ISO_8859-6", "ISO8859-6", "iso88596", "iso6", 0 } },
|
||||
{ "ISO-8859-7",
|
||||
{ "ISO-88597", "ISO_8859-7", "ISO8859-7", "iso88597", "iso7",
|
||||
"sun_eu_greek", 0 } },
|
||||
{ "ISO-8859-8",
|
||||
{ "ISO-88598", "ISO_8859-8", "ISO8859-8", "iso88598", "iso8", 0 } },
|
||||
{ "ISO-8859-9",
|
||||
{ "ISO-88599", "ISO_8859-9", "ISO8859-9", "iso88599", "iso9", 0 } },
|
||||
{ "ISO-8859-13",
|
||||
{ "ISO-885913", "ISO_8859-13", "ISO8859-13", "iso885913", "iso13", 0 } },
|
||||
{ "ISO-8859-14",
|
||||
{ "ISO-885914", "ISO_8859-14", "ISO8859-14", "iso885914", "iso14", 0 } },
|
||||
{ "ISO-8859-15",
|
||||
{ "ISO-885915", "ISO_8859-15", "ISO8859-15", "iso885915", "iso15", 0 } },
|
||||
|
||||
{ "KOI8-R", { "koi8r", "koi8_r", 0 } },
|
||||
{ "KOI8-T", { "koi8t", "koi8_t", 0 } },
|
||||
{ "KOI8-U", { "koi8u", "koi8_u", 0 } },
|
||||
{ "PCK", { 0 } },
|
||||
{ "roman8", { "roman-8", "roman_8", 0 } },
|
||||
{ "Shift_JIS", { "shift-jis", "sjis", 0 } },
|
||||
{ "TIS-620", { "tis620", "tis620.2533", 0 } },
|
||||
{ "UTF-8", { "utf8", "utf_8", 0 } },
|
||||
{ 0, { 0 } }
|
||||
};
|
||||
|
||||
// locale names aliases
|
||||
static const alias_t locale_aliases [] = {
|
||||
{ "af_ZA", { "afrikaans", 0 } },
|
||||
{ "ar_AE", { 0 } },
|
||||
{ "ar_BH", { 0 } },
|
||||
{ "ar_DZ", { 0 } },
|
||||
{ "ar_EG", { 0 } },
|
||||
{ "ar_IN", { 0 } },
|
||||
{ "ar_IQ", { 0 } },
|
||||
{ "ar_JO", { 0 } },
|
||||
{ "ar_KW", { 0 } },
|
||||
{ "ar_LB", { 0 } },
|
||||
{ "ar_LY", { 0 } },
|
||||
{ "ar_MA", { 0 } },
|
||||
{ "ar_OM", { 0 } },
|
||||
{ "ar_QA", { 0 } },
|
||||
{ "ar_SA", { 0 } },
|
||||
{ "ar_SD", { 0 } },
|
||||
{ "ar_SY", { 0 } },
|
||||
{ "ar_TN", { 0 } },
|
||||
{ "ar_YE", { 0 } },
|
||||
{ "be_BY", { 0 } },
|
||||
{ "bg_BG", { "bulgarian", 0 } },
|
||||
{ "br_FR", { "br", 0 } },
|
||||
{ "bs_BA", { "bs", 0 } },
|
||||
{ "ca_ES", { 0 } },
|
||||
{ "ca_ES@euro", { 0 } },
|
||||
{ "cs_CZ", { "czech", 0 } },
|
||||
{ "cy_GB", { "cy", 0 } },
|
||||
{ "da_DK", { "danish", 0 } },
|
||||
{ "de_AT", { "austrian", 0 } },
|
||||
{ "de_AT@euro", { 0 } },
|
||||
{ "de_BE", { 0 } },
|
||||
{ "de_BE@euro", { 0 } },
|
||||
{ "de_CH", { 0 } },
|
||||
{ "de_DE", { "deutsch", "german", 0 } },
|
||||
{ "de_DE@euro", { 0 } },
|
||||
{ "de_LU", { 0 } },
|
||||
{ "de_LU@euro", { 0 } },
|
||||
{ "el_GR", { "greek", 0 } },
|
||||
{ "en_AU", { 0 } },
|
||||
{ "en_BW", { 0 } },
|
||||
{ "en_CA", { 0 } },
|
||||
{ "en_DK", { 0 } },
|
||||
{ "en_GB", { 0 } },
|
||||
{ "en_HK", { 0 } },
|
||||
{ "en_IE", { 0 } },
|
||||
{ "en_IE@euro", { 0 } },
|
||||
{ "en_IN", { 0 } },
|
||||
{ "en_NZ", { 0 } },
|
||||
{ "en_PH", { 0 } },
|
||||
{ "en_SG", { 0 } },
|
||||
{ "en_US", { 0 } },
|
||||
{ "en_ZA", { 0 } },
|
||||
{ "en_ZW", { 0 } },
|
||||
{ "es_AR", { 0 } },
|
||||
{ "es_BO", { 0 } },
|
||||
{ "es_CL", { 0 } },
|
||||
{ "es_CO", { 0 } },
|
||||
{ "es_CR", { 0 } },
|
||||
{ "es_DO", { 0 } },
|
||||
{ "es_EC", { 0 } },
|
||||
{ "es_ES", { "spanish", 0 } },
|
||||
{ "es_ES@euro", { 0 } },
|
||||
{ "es_GT", { 0 } },
|
||||
{ "es_HN", { 0 } },
|
||||
{ "es_MX", { 0 } },
|
||||
{ "es_NI", { 0 } },
|
||||
{ "es_PA", { 0 } },
|
||||
{ "es_PE", { 0 } },
|
||||
{ "es_PR", { 0 } },
|
||||
{ "es_PY", { 0 } },
|
||||
{ "es_SV", { 0 } },
|
||||
{ "es_US", { 0 } },
|
||||
{ "es_UY", { 0 } },
|
||||
{ "es_VE", { 0 } },
|
||||
{ "et_EE", { "estonian", 0 } },
|
||||
{ "eu_ES", { 0 } },
|
||||
{ "eu_ES@euro", { 0 } },
|
||||
{ "fa_IR", { "fa", 0 } },
|
||||
{ "fi_FI", { "finnish", 0 } },
|
||||
{ "fi_FI@euro", { "fi", 0 } },
|
||||
{ "fo_FO", { "fo", 0 } },
|
||||
{ "fr_BE", { 0 } },
|
||||
{ "fr_BE@euro", { 0 } },
|
||||
{ "fr_CA", { "canadian", 0 } },
|
||||
{ "fr_CH", { 0 } },
|
||||
{ "fr_FR", { "french", 0 } },
|
||||
{ "fr_FR@euro", { 0 } },
|
||||
{ "fr_LU", { 0 } },
|
||||
{ "fr_LU@euro", { 0 } },
|
||||
{ "ga_IE", { 0 } },
|
||||
{ "ga_IE@euro", { 0 } },
|
||||
{ "gl_ES", { 0 } },
|
||||
{ "gl_ES@euro", { 0 } },
|
||||
{ "gv_GB", { 0 } },
|
||||
{ "he_IL", { "hebrew", 0 } },
|
||||
{ "hi_IN", { 0 } },
|
||||
{ "hr_HR", { "croatian", 0 } },
|
||||
{ "hu_HU", { "hungarian", 0 } },
|
||||
{ "id_ID", { 0 } },
|
||||
{ "is_IS", { 0 } },
|
||||
{ "it_CH", { 0 } },
|
||||
{ "it_IT", { "italian", 0 } },
|
||||
{ "it_IT@euro", { 0 } },
|
||||
{ "iw_IL", { 0 } },
|
||||
{ "ja_JP", { "ja", "japanese", 0 } },
|
||||
{ "ka_GE", { 0 } },
|
||||
{ "kl_GL", { 0 } },
|
||||
{ "ko_KR", { "ko", 0 } },
|
||||
{ "kw_GB", { 0 } },
|
||||
{ "lt_LT", { "lithuanian", 0 } },
|
||||
{ "lv_LV", { "latvian", 0 } },
|
||||
{ "mi_NZ", { 0 } },
|
||||
{ "mk_MK", { "macedonian", 0 } },
|
||||
{ "mr_IN", { 0 } },
|
||||
{ "ms_MY", { 0 } },
|
||||
{ "mt_MT", { 0 } },
|
||||
{ "nl_BE", { 0 } },
|
||||
{ "nl_BE@euro", { 0 } },
|
||||
{ "nl_NL", { "dutch", 0 } },
|
||||
{ "nl_NL@euro", { 0 } },
|
||||
{ "nn_NO", { 0 } },
|
||||
{ "no_NO", { "no", 0 } },
|
||||
{ "oc_FR", { "occitan", 0 } },
|
||||
{ "pl_PL", { "polish", 0 } },
|
||||
{ "pt_BR", { 0 } },
|
||||
{ "pt_PT", { "portuguese", 0 } },
|
||||
{ "pt_PT@euro", { 0 } },
|
||||
{ "ro_RO", { "romanian", 0 } },
|
||||
{ "ru_RU", { "russian", 0 } },
|
||||
{ "ru_UA", { 0 } },
|
||||
{ "sk_SK", { "slovakian", "slovak", 0 } },
|
||||
{ "sl_SI", { "slovenian", "sloven", 0 } },
|
||||
{ "sq_AL", { "albanian", 0 } },
|
||||
{ "sr_YU", { "serbian", 0 } },
|
||||
{ "sr_YU@cyrillic", { 0 } },
|
||||
{ "sv_FI", { 0 } },
|
||||
{ "sv_FI@euro", { 0 } },
|
||||
{ "sv_SE", { 0 } },
|
||||
{ "ta_IN", { 0 } },
|
||||
{ "te_IN", { 0 } },
|
||||
{ "tg_TJ", { 0 } },
|
||||
{ "th_TH", { "thai", 0 } },
|
||||
{ "tl_PH", { 0 } },
|
||||
{ "tr_TR", { "turkish", 0 } },
|
||||
{ "uk_UA", { "ukrainian", 0 } },
|
||||
{ "ur_PK", { 0 } },
|
||||
{ "uz_UZ", { 0 } },
|
||||
{ "vi_VN", { 0 } },
|
||||
{ "yi_US", { 0 } },
|
||||
{ "zh_TW", { "zh", "chinese", 0 } },
|
||||
{ 0, { 0 } }
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
struct codepage_t
|
||||
{
|
||||
const char* name; // standard codeset name
|
||||
unsigned int codepage; // code page number
|
||||
};
|
||||
|
||||
static const codepage_t codepages [] = {
|
||||
{ "ANSI_X3.4-1968", 20127 },
|
||||
{ "BIG5", 950 },
|
||||
{ "GBK", 936 },
|
||||
{ "GB2312", 20936 },
|
||||
{ "ISO-8859-1", 28591 },
|
||||
{ "ISO-8859-2", 28592 },
|
||||
{ "ISO-8859-3", 28593 },
|
||||
{ "ISO-8859-4", 28594 },
|
||||
{ "ISO-8859-5", 28595 },
|
||||
{ "ISO-8859-6", 28596 },
|
||||
{ "ISO-8859-7", 28597 },
|
||||
{ "ISO-8859-8", 28598 },
|
||||
{ "ISO-8859-9", 28599 },
|
||||
{ "ISO-8859-15", 28605 },
|
||||
{ "KOI8-R", 20866 },
|
||||
{ "KOI8-U", 21866 },
|
||||
{ "Shift_JIS", 932 },
|
||||
{ "UTF-8", 65001 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
/****************************************************************************/
|
||||
#ifdef _MSC_VER
|
||||
|
||||
unsigned int get_codepage (const std::string& cname)
|
||||
{
|
||||
for (std::size_t i = 0; codepages [i].name; i++) {
|
||||
if (0 == ci_compare (codepages [i].name, cname.c_str ()))
|
||||
return codepages[i].codepage;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void store_aliases (StringVector& v, const alias_t &a)
|
||||
{
|
||||
v.push_back (a.name);
|
||||
|
||||
for (std::size_t i = 0; a.aliases [i]; i++)
|
||||
v.push_back (a.aliases [i]);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
// case insensitive comparison of initial parts of the strings
|
||||
static int ci_pre_compare (const std::string& s1, const std::string& s2)
|
||||
{
|
||||
std::string::const_iterator it1 = s1.begin ();
|
||||
std::string::const_iterator it2 = s2.begin ();
|
||||
for (; it1 != s1.end () && it2 != s2.end (); it1++, it2++)
|
||||
if ( (std::tolower)(*it1, std::locale ())
|
||||
!= (std::tolower)(*it2, std::locale ()))
|
||||
return (*it1 - *it2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ci_compare (const char *s1, const char *s2)
|
||||
{
|
||||
assert (0 != s1);
|
||||
assert (0 != s2);
|
||||
|
||||
typedef unsigned char UChar;
|
||||
|
||||
for ( ; ; ++s1, ++s2) {
|
||||
if (*s1 != *s2)
|
||||
return UChar (*s1) - UChar (*s2);
|
||||
|
||||
if ('\0' == *s1)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// case insensitive comparison between strings
|
||||
int ci_compare (const std::string& s1, const std::string& s2)
|
||||
{
|
||||
return ci_compare (s1.c_str (), s2.c_str ());
|
||||
}
|
||||
|
||||
|
||||
void get_cname_aliases (const std::string& name,
|
||||
StringVector& aliases)
|
||||
{
|
||||
for (std::size_t i = 0; codeset_aliases [i].name; i++) {
|
||||
if (0 == ci_compare (codeset_aliases [i].name, name.c_str ())) {
|
||||
// store the whole structure data
|
||||
store_aliases (aliases, codeset_aliases [i]);
|
||||
break;
|
||||
}
|
||||
|
||||
// check the entry's aliases as well
|
||||
for (std::size_t j = 0; codeset_aliases [i].aliases [j]; j++) {
|
||||
if (0 == ci_compare (codeset_aliases [i].aliases [j],
|
||||
name.c_str ())) {
|
||||
// store the whole structure data
|
||||
store_aliases (aliases, codeset_aliases [i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aliases.empty ())
|
||||
aliases.push_back (name);
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
||||
void get_lname_aliases (const std::string& name,
|
||||
StringVector& aliases)
|
||||
{
|
||||
for (std::size_t i = 0; locale_aliases [i].name; i++) {
|
||||
if (0 == ci_compare (locale_aliases [i].name, name.c_str ())) {
|
||||
// store the whole structure data
|
||||
store_aliases (aliases, locale_aliases [i]);
|
||||
break;
|
||||
}
|
||||
|
||||
// check the entry's aliases as well
|
||||
for (std::size_t j = 0; locale_aliases [i].aliases [j]; j++) {
|
||||
if (0 == ci_compare (locale_aliases [i].aliases [j],
|
||||
name.c_str ())) {
|
||||
// store the whole structure data
|
||||
store_aliases (aliases, locale_aliases [i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aliases.empty ())
|
||||
aliases.push_back (name);
|
||||
}
|
||||
|
||||
|
||||
void get_same_encoding_C_locale (const std::string &lname,
|
||||
const std::string &cname,
|
||||
StringVector &libc_locales)
|
||||
{
|
||||
// get the aliases for both name and codeset
|
||||
StringVector la;
|
||||
StringVector ca;
|
||||
|
||||
get_lname_aliases (lname, la);
|
||||
get_cname_aliases (cname, ca);
|
||||
|
||||
// find all the installed C library locales that are equivalent
|
||||
// to the locale named by `lname' and that use the encoding given
|
||||
// by `cname'
|
||||
|
||||
char* locname = get_installed_locales ();
|
||||
|
||||
for (; *locname; locname += std::strlen (locname) + 1) {
|
||||
|
||||
bool match_found = false;
|
||||
|
||||
typedef StringVector::iterator Iterator;
|
||||
|
||||
// iterate through the aliases and see if any one of them
|
||||
// starts with the same sequence
|
||||
for (Iterator it = la.begin (); it != la.end (); ++it) {
|
||||
|
||||
if (0 != ci_pre_compare (locname, (*it).c_str ()))
|
||||
continue;
|
||||
|
||||
// this is a good match, test to see if the encodings match
|
||||
if (0 == std::setlocale (LC_CTYPE, locname))
|
||||
continue;
|
||||
|
||||
const char* const cs = nl_langinfo (CODESET);
|
||||
|
||||
// compare the codeset to the aliases
|
||||
for (Iterator it1 = ca.begin (); it1 != ca.end (); ++it1) {
|
||||
if (0 != ci_compare (cs, (*it1).c_str ()))
|
||||
continue;
|
||||
|
||||
// found a match and save it
|
||||
libc_locales.push_back (std::string (locname));
|
||||
match_found = true;
|
||||
}
|
||||
|
||||
if (match_found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string get_C_encoding_locale (const std::string &codeset)
|
||||
{
|
||||
// retrieve the set of aliases for this codeset
|
||||
StringVector ca;
|
||||
get_cname_aliases (codeset, ca);
|
||||
|
||||
// find a C library locale that uses the same encoding
|
||||
char* locname = get_installed_locales ();
|
||||
|
||||
for (; *locname; locname += std::strlen (locname) + 1) {
|
||||
|
||||
// set the C locale and get the codeset name
|
||||
if (0 == std::setlocale (LC_CTYPE, locname))
|
||||
continue;
|
||||
|
||||
#ifdef _RWSTD_OS_HP_UX
|
||||
|
||||
// skip the limited C.utf8 locale
|
||||
if (0 == std::strcmp ("C.utf8", locname))
|
||||
continue;
|
||||
|
||||
#endif // _RWSTD_OS_HPUX
|
||||
|
||||
|
||||
const char* const cs = nl_langinfo (CODESET);
|
||||
|
||||
typedef StringVector::iterator Iterator;
|
||||
|
||||
// compare the name with this codeset's aliases
|
||||
for (Iterator it = ca.begin (); it != ca.end (); ++it)
|
||||
if (0 == ci_compare (cs, (*it).c_str ())) {
|
||||
return locname;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string ();
|
||||
}
|
||||
|
||||
|
||||
// returns a character array consisting of NUL-separated names
|
||||
// of locales intalled on a system; if `loc_cat' is other than
|
||||
// LC_INVALID_CAT, will eliminate names that do not refer to
|
||||
// valid locales (i.e., those for which setlocale(loc_cat,
|
||||
// name) will return 0
|
||||
char* get_installed_locales (int loc_cat /* = LC_INVALID_CAT */)
|
||||
{
|
||||
static char* slocname = 0;
|
||||
|
||||
static std::size_t size = 0; // number of elements in array
|
||||
static std::size_t total_size = 5120; // the size of the array
|
||||
|
||||
// allocate first time through
|
||||
if (!slocname) {
|
||||
slocname = new char [16384];
|
||||
*slocname = '\0';
|
||||
}
|
||||
|
||||
char* locname = slocname;
|
||||
|
||||
// save the current locale setting and set the locale to "C"
|
||||
const char* const save_localename = std::setlocale (LC_ALL, 0);
|
||||
std::setlocale (LC_ALL, "C");
|
||||
|
||||
#if __GNUG__ == 2 && __GNUC_MINOR__ == 96
|
||||
|
||||
// create a temporary file for the output of `locale -a'
|
||||
char fname_buf [L_tmpnam] = "/tmp/tmpfile-XXXXXX";
|
||||
const char *fname = fname_buf;
|
||||
|
||||
// avoid using tmpnam() to prevent the bogus gcc 2.96 warning:
|
||||
// the use of `tmpnam' is dangerous, better use `mkstemp'
|
||||
const int fd = mkstemp (fname_buf);
|
||||
|
||||
if (-1 == fd) {
|
||||
std::perror ("mkstemp() failed");
|
||||
std::abort();
|
||||
}
|
||||
|
||||
close (fd);
|
||||
|
||||
#else // if !defined (gcc 2.96)
|
||||
|
||||
// create a temporary file for the output of `locale -a'
|
||||
char fname_buf [L_tmpnam];
|
||||
const char *fname = std::tmpnam (fname_buf);
|
||||
|
||||
#endif // gcc 2.96
|
||||
|
||||
if (!fname) {
|
||||
std::perror ("tmpnam() failed");
|
||||
std::abort ();
|
||||
}
|
||||
|
||||
// create a shell command and redirect its output into the file
|
||||
|
||||
// cmd must be at least this large:
|
||||
// sizeof ("locale -a | grep \"\" > ") // 22
|
||||
// + strlen (fname) // must be <= L_tmpnam
|
||||
|
||||
char cmd [80 + L_tmpnam];
|
||||
|
||||
std::sprintf (cmd, "LC_ALL=C /usr/bin/locale -a >%s 2>/dev/null", fname);
|
||||
|
||||
const int ret = std::system (cmd);
|
||||
|
||||
if (ret)
|
||||
issue_diag (W_NOTSUP, false, 0, "call to system(\"%s\") failed: %s\n",
|
||||
cmd, std::strerror (errno));
|
||||
|
||||
// open file containing the list of installed locales
|
||||
std::FILE *f = std::fopen (fname, "r");
|
||||
|
||||
if (f) {
|
||||
// even simple locale names can be very long (e.g., on HP-UX,
|
||||
// where a locale name always consists of the names of all
|
||||
// categories, such as "C C C C C C")
|
||||
char last_name [256];
|
||||
*last_name = '\0';
|
||||
|
||||
// if successful, construct a char array with the locales
|
||||
while (std::fgets (cmd, sizeof cmd, f)) {
|
||||
cmd [std::strlen (cmd) - 1] = '\0';
|
||||
|
||||
// if our buffer is full then dynamically allocate a new one
|
||||
if ((size += (std::strlen (cmd) + 1)) > total_size) {
|
||||
total_size += 5120;
|
||||
char* newBuf = new char[total_size];
|
||||
std::memcpy (newBuf, slocname, total_size - 5120);
|
||||
std::free (slocname);
|
||||
slocname = newBuf;
|
||||
locname = slocname + size - std::strlen (cmd) - 1;
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
|
||||
// prevent a hang (OS/libc bug?)
|
||||
std::strcpy (locname, cmd);
|
||||
locname += std::strlen (cmd) + 1;
|
||||
|
||||
#else
|
||||
|
||||
if (loc_cat != int (LC_INVALID_CAT)) {
|
||||
|
||||
// set the C locale to verify that the name is valid
|
||||
const char *name = std::setlocale (loc_cat, cmd);
|
||||
|
||||
// if it is and if the actual locale name different
|
||||
// from the last one, append it to the list
|
||||
if (name && std::strcmp (last_name, name)) {
|
||||
std::strcpy (locname, cmd);
|
||||
locname += std::strlen (cmd) + 1;
|
||||
|
||||
// save the last locale name
|
||||
assert (std::strlen (name) < sizeof last_name);
|
||||
std::strcpy (last_name, name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::strcpy (locname, cmd);
|
||||
locname += std::strlen (cmd) + 1;
|
||||
}
|
||||
|
||||
#endif // _WIN64
|
||||
|
||||
}
|
||||
*locname = '\0';
|
||||
|
||||
}
|
||||
|
||||
// restore the original locale
|
||||
if (save_localename)
|
||||
std::setlocale (LC_ALL, save_localename);
|
||||
|
||||
std::fclose (f);
|
||||
std::remove (fname);
|
||||
return slocname;
|
||||
}
|
||||
|
||||
#endif // _MSC_VER
|
||||
64
extern/stdcxx/4.2.1/util/aliases.h
vendored
Normal file
64
extern/stdcxx/4.2.1/util/aliases.h
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* aliases.h
|
||||
*
|
||||
* $Id: aliases.h 550991 2007-06-26 23:58:07Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 1994-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RWSTD_UTIL_ALIASES_H_INCLUDED
|
||||
#define RWSTD_UTIL_ALIASES_H_INCLUDED
|
||||
|
||||
#include <string> // for string
|
||||
#include <vector> // for vector
|
||||
|
||||
|
||||
// get the codepage for a particular codeset
|
||||
unsigned int get_codepage (const std::string&);
|
||||
|
||||
// case-insensitive comparison of strings
|
||||
int ci_compare (const std::string&, const std::string&);
|
||||
|
||||
|
||||
typedef std::vector<std::string> StringVector;
|
||||
|
||||
// aliases retrieval for locale name and for codeset name
|
||||
void get_cname_aliases (const std::string&, StringVector&);
|
||||
void get_lname_aliases (const std::string&, StringVector&);
|
||||
|
||||
// retrieves the C locale that will be used in getting the internal
|
||||
// encoding for the locale if _RWSTD_NO_ISO_10646_WCHAR_T is defined
|
||||
std::string get_C_encoding_locale (const std::string&);
|
||||
|
||||
// gets the corresponding C locale names
|
||||
void get_same_encoding_C_locale (const std::string&,
|
||||
const std::string&,
|
||||
StringVector&);
|
||||
|
||||
// invalid value (hopefully) different from any LC_XXX constant
|
||||
#define LC_INVALID_CAT 0xdeadbeef
|
||||
|
||||
// retrieves the names of locales that grep the pattern
|
||||
char* get_installed_locales (int = LC_INVALID_CAT);
|
||||
|
||||
#endif // RWSTD_UTIL_ALIASES_H_INCLUDED
|
||||
1083
extern/stdcxx/4.2.1/util/charmap.cpp
vendored
Normal file
1083
extern/stdcxx/4.2.1/util/charmap.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
264
extern/stdcxx/4.2.1/util/charmap.h
vendored
Normal file
264
extern/stdcxx/4.2.1/util/charmap.h
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* charmap.h
|
||||
*
|
||||
* $Id: charmap.h 580483 2007-09-28 20:55:52Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2007 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef _RWSTD_CHARMAP_H_INCLUDED
|
||||
#define _RWSTD_CHARMAP_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#ifndef _RWSTD_NO_ICONV
|
||||
# include <iconv.h>
|
||||
#endif // _RWSTD_NO_ICONV
|
||||
|
||||
|
||||
#include "scanner.h"
|
||||
|
||||
class Charmap
|
||||
{
|
||||
public:
|
||||
static const char* const portable_charset [];
|
||||
|
||||
Charmap(const char* /*corresponding C library locale*/,
|
||||
const char* /*filename*/,
|
||||
bool /*is utf8 encoding?*/,
|
||||
bool /*create_forward_charmaps*/,
|
||||
bool /*create_reverse_charmaps*/,
|
||||
bool /*use UCS4 internally*/);
|
||||
|
||||
// returns the narrow character map which maps a symbolic character
|
||||
// name to its narrow character value
|
||||
const std::map<std::string, unsigned char>& get_n_cmap() const {
|
||||
return n_cmap_;
|
||||
}
|
||||
|
||||
// returns the reverse narrow character map which maps a narrow
|
||||
// character value to its symbolic name
|
||||
const std::map<unsigned char, std::string>& get_rn_cmap() const {
|
||||
return rn_cmap_;
|
||||
}
|
||||
|
||||
// returns the wide character map which maps a symbolic character
|
||||
// name to its wide character value
|
||||
const std::map<std::string, wchar_t>& get_w_cmap() const {
|
||||
return w_cmap_;
|
||||
}
|
||||
|
||||
// returns the reverse wide character map which maps a wide
|
||||
// character value to its symbolic name
|
||||
const std::map<wchar_t, std::string>& get_rw_cmap() const {
|
||||
return rw_cmap_;
|
||||
}
|
||||
|
||||
// returns the multibyte character map which maps a multibyte
|
||||
// character to its corresponding wide character value
|
||||
const std::map<std::string, wchar_t>& get_mb_cmap() const {
|
||||
return mb_cmap_;
|
||||
}
|
||||
|
||||
// returns the reverse multibyte character map which maps a wide
|
||||
// character value to its corresponding multibyte character
|
||||
const std::map<wchar_t, std::string>& get_rmb_cmap() const {
|
||||
return rmb_cmap_;
|
||||
}
|
||||
|
||||
// get the string value map
|
||||
const std::list<std::string>& get_symnames_list() const {
|
||||
return symnames_list_;
|
||||
}
|
||||
|
||||
const std::map <std::string, wchar_t>& get_ucs4_cmap () const {
|
||||
return ucs4_cmap_;
|
||||
}
|
||||
|
||||
const std::map <wchar_t, std::string>& get_rucs4_cmap () const {
|
||||
return rucs4_cmap_;
|
||||
}
|
||||
|
||||
// return the value of mb_cur_max
|
||||
int get_mb_cur_max() const {
|
||||
return mb_cur_max_;
|
||||
}
|
||||
|
||||
// return the name of the codeset
|
||||
const std::string& get_code_set_name () const {
|
||||
return code_set_name_;
|
||||
}
|
||||
|
||||
// return the name of the character map
|
||||
std::string get_charmap_name () const;
|
||||
|
||||
// return the full path to the charmap
|
||||
std::string get_full_charmap_name () const {
|
||||
return charmap_name_;
|
||||
}
|
||||
|
||||
// convert the externally encoded string to the internal encoding
|
||||
bool convert_to_wc (const std::string&, const std::string&, wchar_t&);
|
||||
|
||||
// convert the externally encoded string to UCS
|
||||
bool convert_to_ucs (const std::string&, const std::string&, wchar_t&);
|
||||
|
||||
// convert the externally encoded string to UCS
|
||||
wchar_t convert_sym_to_ucs (const std::string&) const;
|
||||
|
||||
|
||||
// get the number of bytes in a single multi-byte character
|
||||
std::size_t mbcharlen (const std::string&) const;
|
||||
|
||||
// convert the first byte in the multi-byte character to an unsigned char
|
||||
unsigned char convert_char (const char*, const char** = 0) const;
|
||||
|
||||
unsigned char get_largest_nchar () const;
|
||||
|
||||
// increments the wide character value to the next encoded character
|
||||
// in the current codeset; returns the incremented value or -1 on
|
||||
// error
|
||||
wchar_t increment_wchar (wchar_t) const;
|
||||
|
||||
private:
|
||||
|
||||
// processes characters implicitly defined by an ellipsis denoted
|
||||
// by two explicitly defined characters; returns the number of
|
||||
// characters in the range, -1 on error
|
||||
std::size_t process_ellipsis (const Scanner::token_t&, int);
|
||||
|
||||
// process the charmap file making the necessary mappings in the cmaps
|
||||
void process_chars();
|
||||
|
||||
// increment the encoded multi byte character argument
|
||||
bool increment_encoding (std::string&);
|
||||
|
||||
// verify that all the characters in the portable character set
|
||||
// are defined in the character map
|
||||
void verify_portable_charset () const;
|
||||
|
||||
#ifndef _RWSTD_NO_ICONV
|
||||
// open the iconv descriptor to convert to utf8
|
||||
iconv_t open_iconv_to_utf8 () const;
|
||||
#endif // _RWSTD_NO_ICONV
|
||||
|
||||
// convert a human-readable encoding of a character
|
||||
// to its raw multibyte character representation
|
||||
std::string encoding_to_mbchar (const std::string&) const;
|
||||
|
||||
// convert a multi-byte string to a utf8 multi-byte string
|
||||
char* convert_to_utf8 (const char *inbuf, std::size_t inbuf_s,
|
||||
char *outbuf, std::size_t outbuf_s) const;
|
||||
|
||||
#ifndef _RWSTD_NO_ICONV
|
||||
# ifndef _RWSTD_NO_ISO_10646_WCHAR_T
|
||||
|
||||
// open the iconv descriptor to convert from utf8 to the external encoding
|
||||
iconv_t open_iconv_to_ext ();
|
||||
|
||||
# endif // _RWSTD_NO_ISO_10646_WCHAR_T
|
||||
#endif // _RWSTD_NO_ICONV
|
||||
|
||||
// add the symbolic name of a character and the raw multibyte
|
||||
// character corresponding to it to the character maps
|
||||
void add_to_cmaps (const std::string&,
|
||||
const std::string&,
|
||||
bool = false);
|
||||
|
||||
// the scanner used to process the charmap file
|
||||
Scanner scanner_;
|
||||
|
||||
// the name of the codeset
|
||||
std::string code_set_name_;
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
int codepage_;
|
||||
#endif // _MSC_VER
|
||||
|
||||
// n_cmap maps the symbolic name to a narrow character value
|
||||
// rn_cmap does the opposite
|
||||
std::map <std::string, unsigned char> n_cmap_;
|
||||
std::map <unsigned char, std::string> rn_cmap_;
|
||||
|
||||
// mb_cmap maps a multibyte character representation to its
|
||||
// corresponding wide character value
|
||||
// rmb_cmap does the opposite
|
||||
std::map <std::string, wchar_t> mb_cmap_;
|
||||
std::map <wchar_t, std::string> rmb_cmap_;
|
||||
|
||||
typedef std::map <wchar_t, std::string>::const_iterator rmb_cmap_iter;
|
||||
typedef std::map <std::string, wchar_t>::const_iterator mb_cmap_iter;
|
||||
|
||||
// w_cmap maps the symbolic name to a wide character value
|
||||
// rw_cmap does exactly the opposite
|
||||
std::map <std::string, wchar_t> w_cmap_;
|
||||
std::map <wchar_t, std::string> rw_cmap_;
|
||||
|
||||
// ucs4_cmap maps the symbolic name to the UCS4 value for that name
|
||||
std::map <std::string, wchar_t> ucs4_cmap_;
|
||||
std::map <wchar_t, std::string> rucs4_cmap_;
|
||||
|
||||
// the number of bytes in the largest multi-byte value
|
||||
int mb_cur_max_;
|
||||
|
||||
#ifndef _RWSTD_NO_ICONV
|
||||
// the iconv file descriptor that converts to utf8
|
||||
iconv_t ic_to_utf8_;
|
||||
|
||||
// the iconv file descriptor that converts from utf8 to external
|
||||
iconv_t ic_to_ext_;
|
||||
#endif // _RWSTD_NO_ICONV
|
||||
|
||||
// the name of the character map file
|
||||
std::string charmap_name_;
|
||||
|
||||
// the name of the C library locale with same encoding
|
||||
std::string Clocale_;
|
||||
|
||||
unsigned char largest_nchar_;
|
||||
|
||||
// are we in the utf8 encoding?
|
||||
bool in_utf8_;
|
||||
|
||||
// should we create the forward character maps
|
||||
bool forward_maps;
|
||||
|
||||
// should we create the reverse character maps
|
||||
bool reverse_maps;
|
||||
|
||||
// should we use UCS4 as the internal representation
|
||||
bool UCS4_internal_;
|
||||
|
||||
// list of all known symbolic character names
|
||||
std::list<std::string> symnames_list_;
|
||||
|
||||
Scanner::token_t next;
|
||||
};
|
||||
|
||||
|
||||
#endif // _RWSTD_CHARMAP_H_INCLUDED
|
||||
|
||||
767
extern/stdcxx/4.2.1/util/cmdopt.cpp
vendored
Normal file
767
extern/stdcxx/4.2.1/util/cmdopt.cpp
vendored
Normal file
@@ -0,0 +1,767 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* cmdopt.cpp - Definitions of the option parsing subsystem
|
||||
*
|
||||
* $Id: cmdopt.cpp 588734 2007-10-26 18:17:55Z sebor $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* disable Compaq/HP C++ pure libc headers to allow POSIX symbols
|
||||
such as SIGALRM or SIGKILL to be defined.*/
|
||||
#undef __PURE_CNAME
|
||||
|
||||
#include <assert.h> /* for assert() */
|
||||
#include <ctype.h> /* for isspace */
|
||||
#include <errno.h> /* for errno */
|
||||
#include <signal.h> /* for raise, signal, SIG_IGN */
|
||||
#include <stdio.h> /* for *printf, fputs */
|
||||
#include <stdlib.h> /* for exit */
|
||||
#include <string.h> /* for str* */
|
||||
#if !defined (_WIN32) && !defined (_WIN64)
|
||||
# include <unistd.h> /* for sleep */
|
||||
|
||||
# if defined (_XOPEN_UNIX)
|
||||
# include <sys/resource.h> /* for struct rlimit, RLIMIT_CORE, ... */
|
||||
# endif
|
||||
|
||||
#else
|
||||
# include <windows.h> /* for Sleep */
|
||||
#endif /* _WIN{32,64} */
|
||||
|
||||
#include "exec.h"
|
||||
#include "target.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "cmdopt.h"
|
||||
|
||||
const char* exe_name; /**< Alias for process argv [0]. */
|
||||
#if !defined (_WIN32) && !defined (_WIN64)
|
||||
const char escape_code = '\\';
|
||||
const char default_path_sep = '/';
|
||||
const char suffix_sep = '.';
|
||||
const size_t exe_suffix_len = 0;
|
||||
#if defined (_SC_CLK_TCK)
|
||||
const float TICKS_PER_SEC = sysconf (_SC_CLK_TCK);
|
||||
#elif defined (CLK_TCK)
|
||||
const float TICKS_PER_SEC = CLK_TCK;
|
||||
#elif defined (CLOCKS_PER_SEC)
|
||||
const float TICKS_PER_SEC = CLOCKS_PER_SEC;
|
||||
#else
|
||||
# error Unable to determine number of clock ticks in a second.
|
||||
#endif
|
||||
#else
|
||||
const char escape_code = '^';
|
||||
const char default_path_sep = '\\';
|
||||
const char suffix_sep = '.';
|
||||
const size_t exe_suffix_len = 4; /* strlen(".exe") == 4 */
|
||||
const float TICKS_PER_SEC = CLOCKS_PER_SEC;
|
||||
|
||||
# ifndef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0500
|
||||
# endif
|
||||
|
||||
# if _WIN32_WINNT >= 0x0500
|
||||
# define RLIMIT_AS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static const char
|
||||
usage_text[] = {
|
||||
"Usage: %s [OPTIONS] [targets]\n"
|
||||
"\n"
|
||||
" Treats each token in targets as the path to an executable. Each target\n"
|
||||
" enumerated is executed, and the output is processed after termination.\n"
|
||||
" If target prepended by '@' character, target is treated as text file\n"
|
||||
" with list of targets (one target per line).\n"
|
||||
" If the execution takes longer than a certain (configurable) amount of\n"
|
||||
" time, the process is killed.\n"
|
||||
"\n"
|
||||
" -d dir Specify root directory for output reference files.\n"
|
||||
" -h, -? Display usage information and exit.\n"
|
||||
" -t seconds Set timeout before killing target (default is 10\n"
|
||||
" seconds).\n"
|
||||
" -x opts Specify command line options to pass to targets.\n"
|
||||
" -- Terminate option processing and treat all arguments\n"
|
||||
" that follow as targets.\n"
|
||||
" --compat Use compatability mode test output parsing.\n"
|
||||
" --nocompat Use standard test output parsing (default).\n"
|
||||
" --help Display usage information and exit.\n"
|
||||
" --exit=val Exit immediately with the specified return code.\n"
|
||||
" --sleep=sec Sleep for the specified number of seconds.\n"
|
||||
" --signal=sig Send itself the specified signal.\n"
|
||||
" --ignore=sig Ignore the specified signal.\n"
|
||||
" --ulimit=lim Set child process usage limits (see below).\n"
|
||||
" --warn=alias Set compiler log warning pattern (see below).\n"
|
||||
"\n"
|
||||
" All short (single dash) options must be specified seperately.\n"
|
||||
" If a short option takes a value, it may either be provided like\n"
|
||||
" '-sval' or '-s val'.\n"
|
||||
" If a long option take a value, it may either be provided like\n"
|
||||
" '--option=value' or '--option value'.\n"
|
||||
"\n"
|
||||
" --ulimit sets limits on how much of a given resource or resorces\n"
|
||||
" child processes are allowed to utilize. These limits take on two\n"
|
||||
" forms, 'soft' and 'hard' limits. Options are specified in the form\n"
|
||||
" 'resource:limit', where resource is a resource named below, and and\n"
|
||||
" limit is a number, with value specifing the limit for the named\n"
|
||||
" resource. If multiple limits are to be set, they can be specified\n"
|
||||
" either in multiple instances of the --ulimit switch, or by specifying\n"
|
||||
" additional limits in the same call by seperating the pairs with\n"
|
||||
" commas. 'Soft' limits are specified by providing the resource name\n"
|
||||
" in lowercase letters, while 'hard' limits are specified by providing\n"
|
||||
" the resource name in uppercase letters. To set both limits, specify\n"
|
||||
" the resource name in title case.\n"
|
||||
"\n"
|
||||
" --ulimit modes:\n"
|
||||
" core Maximum size of core file, in bytes.\n"
|
||||
" cpu Maximum CPU time, in seconds.\n"
|
||||
" data Maximum data segment size, in bytes.\n"
|
||||
" fsize Maximum size of generated files, in bytes.\n"
|
||||
" nofile Maximum number of open file descriptors.\n"
|
||||
" stack Maximum size of initial thread's stack, in bytes.\n"
|
||||
" as Maximum size of available memory, in bytes.\n"
|
||||
"\n"
|
||||
" Note: Some operating systems lack support for some or all of the\n"
|
||||
" ulimit modes. If a system is unable to limit a given property, a\n"
|
||||
" warning message will be produced.\n"
|
||||
"\n"
|
||||
" --warn set the string used to parse compile and link logs. Rather\n"
|
||||
" than specifying a search string, an alias code is provided,\n"
|
||||
" coresponding to the output of a compiler and linker. Alias codes\n"
|
||||
" are case sensitive.\n"
|
||||
"\n"
|
||||
" --warn modes:\n"
|
||||
" acc HP aCC\n"
|
||||
" cxx Compaq C++\n"
|
||||
" eccp EDG eccp\n"
|
||||
" gcc GNU gcc\n"
|
||||
" icc Intel icc for Linux\n"
|
||||
" mipspro SGI MIPSpro\n"
|
||||
" sunpro Sun C++\n"
|
||||
" vacpp IBM VisualAge C++\n"
|
||||
" xlc IBM XLC++\n"
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Display command line switches for program and terminate.
|
||||
|
||||
@param status status code to exit with.
|
||||
*/
|
||||
static void
|
||||
show_usage (int status)
|
||||
{
|
||||
FILE* const where = status ? stderr : stdout;
|
||||
|
||||
assert (0 != exe_name);
|
||||
|
||||
fprintf (where, usage_text, exe_name);
|
||||
|
||||
exit (status);
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function to read the value for a short option
|
||||
|
||||
@param argv argument array
|
||||
@param idx reference to index for option
|
||||
*/
|
||||
static char*
|
||||
get_short_val (char* const* argv, int* idx)
|
||||
{
|
||||
assert (0 != argv);
|
||||
assert (0 != idx);
|
||||
|
||||
if ('\0' == argv [*idx][2])
|
||||
return argv [++(*idx)];
|
||||
else
|
||||
return argv [*idx] + 2;
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function to read the value for a long option
|
||||
|
||||
@param argv argument array
|
||||
@param idx reference to index for option
|
||||
@param offset length of option name (including leading --)
|
||||
*/
|
||||
static char*
|
||||
get_long_val (char* const* argv, int* idx, unsigned offset)
|
||||
{
|
||||
assert (0 != argv);
|
||||
assert (0 != idx);
|
||||
|
||||
if ('\0' == argv [*idx][offset])
|
||||
return argv [++(*idx)];
|
||||
else if ('=' == argv [*idx][offset])
|
||||
return argv [*idx] + offset + 1;
|
||||
else
|
||||
return (char*)0;
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function to parse a ulimit value string
|
||||
|
||||
@param opts ulimit value string to pares
|
||||
@see child_limits
|
||||
*/
|
||||
static bool
|
||||
parse_limit_opts (const char* opts, struct target_opts* defaults)
|
||||
{
|
||||
static const struct {
|
||||
rw_rlimit** limit;
|
||||
const char* name;
|
||||
const char* caps;
|
||||
const char* mixd;
|
||||
size_t len;
|
||||
} limits[] = {
|
||||
{
|
||||
#ifdef RLIMIT_CORE
|
||||
&defaults->core,
|
||||
#else
|
||||
0,
|
||||
#endif /* RLIMIT_CORE */
|
||||
"core", "CORE", "Core", 4 },
|
||||
{
|
||||
#ifdef RLIMIT_CPU
|
||||
&defaults->cpu,
|
||||
#else
|
||||
0,
|
||||
#endif /* RLIMIT_CPU */
|
||||
"cpu", "CPU", "Cpu", 3 },
|
||||
{
|
||||
#ifdef RLIMIT_DATA
|
||||
&defaults->data,
|
||||
#else
|
||||
0,
|
||||
#endif /* RLIMIT_DATA */
|
||||
"data", "DATA", "Data", 4 },
|
||||
{
|
||||
#ifdef RLIMIT_FSIZE
|
||||
&defaults->fsize,
|
||||
#else
|
||||
0,
|
||||
#endif /* RLIMIT_FSIZE */
|
||||
"fsize", "FSIZE", "Fsize", 5 },
|
||||
{
|
||||
#ifdef RLIMIT_NOFILE
|
||||
&defaults->nofile,
|
||||
#else
|
||||
0,
|
||||
#endif /* RLIMIT_NOFILE */
|
||||
"nofile", "NOFILE", "Nofile", 6 },
|
||||
{
|
||||
#ifdef RLIMIT_STACK
|
||||
&defaults->stack,
|
||||
#else
|
||||
0,
|
||||
#endif /* RLIMIT_STACK */
|
||||
"stack", "STACK", "Stack", 5 },
|
||||
{
|
||||
#ifdef RLIMIT_AS
|
||||
&defaults->as,
|
||||
#else
|
||||
0,
|
||||
#endif /* RLIMIT_AS */
|
||||
"as", "AS", "As", 2 },
|
||||
{ 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
const char* arg = opts;
|
||||
|
||||
assert (0 != opts);
|
||||
|
||||
while (arg && *arg) {
|
||||
|
||||
const size_t arglen = strlen (arg);
|
||||
|
||||
for (size_t i = 0; limits [i].name; ++i) {
|
||||
if ( limits [i].len < arglen
|
||||
&& ( 0 == memcmp (limits [i].name, arg, limits [i].len)
|
||||
|| 0 == memcmp (limits [i].caps, arg, limits [i].len)
|
||||
|| 0 == memcmp (limits [i].mixd, arg, limits [i].len))
|
||||
&& ':' == arg [limits [i].len]) {
|
||||
|
||||
/* determine whether the hard limit and/or the soft limit
|
||||
should be set. */
|
||||
const bool hard = 0 != isupper (arg [0]);
|
||||
const bool soft = 0 != islower (arg [1]);
|
||||
|
||||
arg += limits [i].len + 1;
|
||||
|
||||
if (!isdigit (*arg)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *end;
|
||||
const long lim = strtol (arg, &end, 10);
|
||||
|
||||
arg = end;
|
||||
|
||||
if ('\0' != *arg && ',' != *arg)
|
||||
break;
|
||||
|
||||
if (limits [i].limit) {
|
||||
if (!*limits [i].limit) {
|
||||
(*limits [i].limit) =
|
||||
(rw_rlimit*)RW_MALLOC (sizeof (rw_rlimit));
|
||||
(*limits [i].limit)->rlim_cur = RLIM_SAVED_CUR;
|
||||
(*limits [i].limit)->rlim_max = RLIM_SAVED_MAX;
|
||||
}
|
||||
if (soft)
|
||||
(*limits [i].limit)->rlim_cur = lim;
|
||||
|
||||
if (hard)
|
||||
(*limits [i].limit)->rlim_max = lim;
|
||||
}
|
||||
else
|
||||
warn ("Unable to process %s limit: Not supported\n",
|
||||
limits [i].name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (',' == *arg) {
|
||||
++arg;
|
||||
}
|
||||
else if ('\0' != *arg) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function to parse a warning value string
|
||||
|
||||
@param opts ulimit value string to pares
|
||||
@see child_limits
|
||||
*/
|
||||
static bool
|
||||
parse_warn_opts (const char* arg, struct target_opts* defaults)
|
||||
{
|
||||
static const struct {
|
||||
const char* name;
|
||||
const char* pat;
|
||||
} warn_set [] = {
|
||||
{ "acc", "Warning " },
|
||||
/*
|
||||
{ "cds", "UNKNOWN"},
|
||||
{ "como", "UNKNOWN"},
|
||||
*/
|
||||
{ "cxx", "Warning:"},
|
||||
{ "eccp", "warning:"},
|
||||
{ "gcc", "warning:"},
|
||||
{ "icc", "warning #"},
|
||||
{ "mipspro", "CC: WARNING"},
|
||||
{ "sunpro", "Warning:"},
|
||||
{ "vacpp", ": (W) "},
|
||||
{ "xlc", ": (W) "}, /* xlc and vacpp are synonyms. */
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
assert (0 != arg);
|
||||
assert (0 != defaults);
|
||||
|
||||
for (size_t i = 0; warn_set [i].name; ++i) {
|
||||
if (0 == strcmp (warn_set [i].name, arg)) {
|
||||
|
||||
/* Set both compiler and linker warning string. */
|
||||
defaults->c_warn = warn_set [i].pat;
|
||||
defaults->l_warn = warn_set [i].pat;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function to produce 'Bad argument' error message.
|
||||
|
||||
@param opt name of option encountered
|
||||
@param val invalid value found
|
||||
*/
|
||||
static void
|
||||
bad_value (const char* opt, const char* val)
|
||||
{
|
||||
assert (0 != opt);
|
||||
|
||||
terminate (1, "Bad argument for %s: %s\n", opt, val);
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function to produce 'Missing argument' error message.
|
||||
|
||||
@param opt name of option missing argument
|
||||
*/
|
||||
static void
|
||||
missing_value (const char* opt)
|
||||
{
|
||||
assert (0 != opt);
|
||||
|
||||
terminate (1, "Missing argument for %s\n", opt);
|
||||
}
|
||||
|
||||
/**
|
||||
Helper function to produce 'Unknown option' error message.
|
||||
|
||||
@param opt name of option encountered
|
||||
*/
|
||||
static void
|
||||
bad_option (const char* opt)
|
||||
{
|
||||
assert (0 != opt);
|
||||
|
||||
warn ("Unknown option: %s\n", opt);
|
||||
|
||||
show_usage (1);
|
||||
}
|
||||
|
||||
int
|
||||
eval_options (int argc, char **argv, struct target_opts* defaults,
|
||||
const char** exe_opts)
|
||||
{
|
||||
const char opt_timeout[] = "-t";
|
||||
const char opt_data_dir[] = "-d";
|
||||
const char opt_t_flags[] = "-x";
|
||||
const char opt_compat[] = "--compat";
|
||||
const char opt_exit[] = "--exit";
|
||||
const char opt_help[] = "--help";
|
||||
const char opt_ignore[] = "--ignore";
|
||||
const char opt_nocompat[] = "--nocompat";
|
||||
const char opt_signal[] = "--signal";
|
||||
const char opt_sleep[] = "--sleep";
|
||||
const char opt_ulimit[] = "--ulimit";
|
||||
const char opt_verbose[] = "--verbose";
|
||||
const char opt_warn[] = "--warn";
|
||||
|
||||
int i;
|
||||
|
||||
assert (0 != argv);
|
||||
assert (0 != defaults);
|
||||
|
||||
memset (defaults, 0, sizeof (target_opts));
|
||||
|
||||
/* The chain of preprocesor logic below initializes the defaults->c_warn
|
||||
and defaults->l_warn values.
|
||||
*/
|
||||
#ifdef __GNUG__
|
||||
parse_warn_opts ("Gcc", defaults);
|
||||
#elif defined (__HP_aCC)
|
||||
parse_warn_opts ("Acc", defaults);
|
||||
#elif defined (__IBMCPP__)
|
||||
parse_warn_opts ("Xlc", defaults);
|
||||
#elif defined (__SUNPRO_CC)
|
||||
parse_warn_opts ("Sunpro", defaults);
|
||||
#elif defined (SNI)
|
||||
parse_warn_opts ("Cds", defaults);
|
||||
#elif defined (__APOGEE__) /* EDG variant that doesn't define __EDG__. */
|
||||
parse_warn_opts ("Como", defaults);
|
||||
|
||||
/* The following are EDG variants, that define __EDG__ */
|
||||
#elif defined (__DECCXX)
|
||||
parse_warn_opts ("Cxx", defaults);
|
||||
#elif defined (_SGI_COMPILER_VERSION)
|
||||
parse_warn_opts ("Mipspro", defaults);
|
||||
#elif defined (__INTEL_COMPILER)
|
||||
parse_warn_opts ("Icc", defaults);
|
||||
|
||||
/* So we need to check for __EDG__ after we check for them. */
|
||||
#elif defined (__EDG__)
|
||||
parse_warn_opts ("Eccp", defaults);
|
||||
#endif
|
||||
|
||||
if (1 == argc || '-' != argv [1][0])
|
||||
return 1;
|
||||
|
||||
for (i = 1; i < argc && '-' == argv [i][0]; ++i) {
|
||||
|
||||
/* the name of the option being processed */
|
||||
const char* optname = argv [i];
|
||||
|
||||
/* the option's argument, if any */
|
||||
const char* optarg = 0;
|
||||
|
||||
char* end = 0;
|
||||
|
||||
switch (argv [i][1]) {
|
||||
case '?': /* display help and exit with status of 0 */
|
||||
case 'h':
|
||||
show_usage (0);
|
||||
|
||||
case 'r':
|
||||
++i; /* Ignore -r option (makefile compat) */
|
||||
break;
|
||||
|
||||
case 't': /* executable timeout in seconds */
|
||||
optname = opt_timeout;
|
||||
optarg = get_short_val (argv, &i);
|
||||
if (optarg) {
|
||||
if (!isdigit (*optarg))
|
||||
bad_value (optname, optarg);
|
||||
|
||||
errno = 0;
|
||||
defaults->timeout = strtol (optarg, &end, 10);
|
||||
if (*end || errno)
|
||||
bad_value (optname, optarg);
|
||||
}
|
||||
else
|
||||
missing_value (optname);
|
||||
|
||||
break;
|
||||
|
||||
case 'd': /* directory containing example reference files */
|
||||
optname = opt_data_dir;
|
||||
defaults->data_dir = get_short_val (argv, &i);
|
||||
if (!defaults->data_dir)
|
||||
missing_value (optname);
|
||||
break;
|
||||
|
||||
case 'v': /* enable verbose mode */
|
||||
optname = opt_verbose;
|
||||
++defaults->verbose;
|
||||
break;
|
||||
|
||||
case 'x': /* command line options to pass to targets */
|
||||
optname = opt_t_flags;
|
||||
*exe_opts = get_short_val (argv, &i);
|
||||
if (!*exe_opts)
|
||||
missing_value (optname);
|
||||
break;
|
||||
|
||||
case '-': /* long options */
|
||||
{
|
||||
const size_t arglen = strlen (argv [i]);
|
||||
|
||||
/* abort processing on --, eat token */
|
||||
if ('\0' == argv [i][2])
|
||||
return i+1;
|
||||
|
||||
if ( sizeof opt_compat - 1 == arglen
|
||||
&& !memcmp (opt_compat, argv [i], sizeof opt_compat)) {
|
||||
/* enter compatibility mode */
|
||||
defaults->compat = 1;
|
||||
break;
|
||||
}
|
||||
else if ( sizeof opt_nocompat - 1 == arglen
|
||||
&& !memcmp (opt_nocompat, argv [i], sizeof opt_nocompat)) {
|
||||
/* exit compatibility mode */
|
||||
defaults->compat = 0;
|
||||
break;
|
||||
}
|
||||
else if ( sizeof opt_exit - 1 <= arglen
|
||||
&& !memcmp (opt_exit, argv [i], sizeof opt_exit - 1)) {
|
||||
/* exit immediately with the specified status */
|
||||
optname = opt_exit;
|
||||
optarg = get_long_val (argv, &i, sizeof opt_exit - 1);
|
||||
if (optarg && *optarg) {
|
||||
if (!isdigit (*optarg))
|
||||
bad_value (optname, optarg);
|
||||
|
||||
errno = 0;
|
||||
const long code = strtol (optarg, &end, 10);
|
||||
if ('\0' == *end && !errno)
|
||||
exit (code);
|
||||
}
|
||||
}
|
||||
else if ( sizeof opt_help - 1 == arglen
|
||||
&& !memcmp (opt_help, argv [i], sizeof opt_help - 1)) {
|
||||
/* display help and exit with status of 0 */
|
||||
optname = opt_help;
|
||||
show_usage (0);
|
||||
break;
|
||||
}
|
||||
else if ( sizeof opt_sleep - 1 <= arglen
|
||||
&& !memcmp (opt_sleep, argv [i], sizeof opt_sleep - 1)) {
|
||||
/* sleep for the specified number of seconds */
|
||||
optname = opt_sleep;
|
||||
optarg = get_long_val (argv, &i, sizeof opt_sleep - 1);
|
||||
if (optarg && *optarg) {
|
||||
if (!isdigit (*optarg))
|
||||
bad_value (optname, optarg);
|
||||
|
||||
errno = 0;
|
||||
const long nsec = strtol (optarg, &end, 10);
|
||||
if ('\0' == *end && 0 <= nsec && !errno) {
|
||||
rw_sleep (nsec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( sizeof opt_signal - 1 <= arglen
|
||||
&& !memcmp (opt_signal, argv [i], sizeof opt_signal - 1)) {
|
||||
/* send ourselves the specified signal */
|
||||
optname = opt_signal;
|
||||
optarg = get_long_val (argv, &i, sizeof opt_signal - 1);
|
||||
if (optarg && *optarg) {
|
||||
const int signo = get_signo (optarg);
|
||||
if (0 <= signo) {
|
||||
if (0 > raise (signo))
|
||||
terminate (1, "raise(%s) failed: %s\n",
|
||||
get_signame (signo), strerror (errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( sizeof opt_ignore - 1 <= arglen
|
||||
&& !memcmp (opt_ignore, argv [i], sizeof opt_ignore - 1)) {
|
||||
/* ignore the specified signal */
|
||||
optname = opt_ignore;
|
||||
optarg = get_long_val (argv, &i, sizeof opt_ignore - 1);
|
||||
if (optarg && *optarg) {
|
||||
const int signo = get_signo (optarg);
|
||||
if (0 <= signo) {
|
||||
if (rw_signal (signo, 0 /* SIG_IGN */))
|
||||
terminate (1, "rw_signal(%s, ...) failed: %s\n",
|
||||
get_signame (signo), strerror (errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( sizeof opt_ulimit - 1 <= arglen
|
||||
&& !memcmp (opt_ulimit, argv [i], sizeof opt_ulimit - 1)) {
|
||||
/* set child process resource utilization limits */
|
||||
optname = opt_ulimit;
|
||||
optarg = get_long_val (argv, &i, sizeof opt_ulimit - 1);
|
||||
if (optarg && *optarg) {
|
||||
if (!parse_limit_opts (optarg, defaults)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( sizeof opt_warn - 1 <= arglen
|
||||
&& !memcmp (opt_warn, argv [i], sizeof opt_warn - 1)) {
|
||||
/* set compiler warning mode */
|
||||
optname = opt_warn;
|
||||
optarg = get_long_val (argv, &i, sizeof opt_warn - 1);
|
||||
if (optarg && *optarg) {
|
||||
if (!parse_warn_opts (optarg, defaults)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* fall through */
|
||||
}
|
||||
default:
|
||||
if (optarg) {
|
||||
if (*optarg)
|
||||
bad_value (optname, optarg);
|
||||
else
|
||||
missing_value (optname);
|
||||
}
|
||||
|
||||
if (argv [i])
|
||||
bad_option (argv [i]);
|
||||
else
|
||||
missing_value (optname);
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
char**
|
||||
split_opt_string (const char* opts)
|
||||
{
|
||||
char in_quote = 0;
|
||||
int in_escape = 0;
|
||||
int in_token = 0;
|
||||
const char *pos;
|
||||
char *target, *last;
|
||||
char **table_pos, **argv;
|
||||
size_t optlen;
|
||||
|
||||
assert (0 != opts);
|
||||
|
||||
optlen = strlen (opts);
|
||||
|
||||
if (0 == optlen) {
|
||||
/* Alloc a an index array to hold the program name */
|
||||
argv = (char**)RW_MALLOC (sizeof (char*));
|
||||
|
||||
/* And tie the two together */
|
||||
argv [0] = (char*)0;
|
||||
return argv;
|
||||
}
|
||||
|
||||
table_pos = argv = (char**)RW_MALLOC ((optlen + 3) * sizeof (char*) / 2);
|
||||
/* (strlen (opts)+3)/2 is overkill for the most situations, but it is just
|
||||
large enough to handle the worst case scenario. The worst case is a
|
||||
string similar to 'x y' or 'x y z', requiring array lengths of 4 and 5
|
||||
respectively.
|
||||
*/
|
||||
|
||||
last = target = argv [0] = (char*)RW_MALLOC (optlen + 1);
|
||||
|
||||
/* Transcribe the contents, handling escaping and splitting */
|
||||
for (pos = opts; *pos; ++pos) {
|
||||
if (in_escape) {
|
||||
*(target++) = *pos;
|
||||
in_escape = 0;
|
||||
continue;
|
||||
}
|
||||
if (isspace (*pos)) {
|
||||
if (in_quote) {
|
||||
*(target++) = *pos;
|
||||
}
|
||||
else {
|
||||
if (in_token) {
|
||||
*(target++) = '\0';
|
||||
*(table_pos++) = last;
|
||||
in_token = 0;
|
||||
}
|
||||
last = target;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
in_token = 1;
|
||||
switch (*pos) {
|
||||
case escape_code:
|
||||
in_escape = 1;
|
||||
break;
|
||||
case '"':
|
||||
case '\'':
|
||||
if (*pos == in_quote) {
|
||||
in_quote = 0;
|
||||
break;
|
||||
}
|
||||
else if (0 == in_quote) {
|
||||
in_quote = *pos;
|
||||
break;
|
||||
}
|
||||
/* intentionally falling through (in a quote and quote didn't
|
||||
match opening quote.
|
||||
*/
|
||||
default:
|
||||
*(target++) = *pos;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_token) { /* close and record the final token */
|
||||
*(target++) = '\0';
|
||||
*(table_pos++) = last;
|
||||
}
|
||||
*table_pos = (char*)0;/*And terminate the array*/
|
||||
|
||||
return argv;
|
||||
}
|
||||
80
extern/stdcxx/4.2.1/util/cmdopt.h
vendored
Normal file
80
extern/stdcxx/4.2.1/util/cmdopt.h
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* cmdopt.h - Interface declaration for the option parsing subsystem
|
||||
*
|
||||
* $Id: cmdopt.h 475085 2006-11-15 00:38:06Z sebor $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RW_PARSE_OPTS_H
|
||||
#define RW_PARSE_OPTS_H
|
||||
|
||||
#include "target.h" /* For struct target_opts */
|
||||
|
||||
extern const char* exe_name;
|
||||
extern const char escape_code; /**< Escape character used in paths. */
|
||||
extern const char default_path_sep; /**< Primary path seperator */
|
||||
extern const char suffix_sep; /**< File suffix seperator. */
|
||||
extern const size_t exe_suffix_len; /**< Length of executable suffix. */
|
||||
extern const float TICKS_PER_SEC; /**< Number of clock ticks in a second. */
|
||||
|
||||
/**
|
||||
Parses command line arguments for switches and options.
|
||||
|
||||
@param argc number of command line arguments.
|
||||
@param argv command line arguments.
|
||||
@param defaults target_status structure containing default values.
|
||||
@param exe_opts handle to default child process arguments string
|
||||
@return number of command line arguments parsed.
|
||||
*/
|
||||
int
|
||||
eval_options (int argc, char** argv, struct target_opts* defaults,
|
||||
const char** exe_opts);
|
||||
|
||||
/**
|
||||
Translates opts into an array that can be passed to exec().
|
||||
|
||||
This method malloc ()s two blocks of memory. The first block is the
|
||||
generated argv index array. This is the return value of this method. The
|
||||
second block is the parsed and split string contents the index referenced.
|
||||
This block is stored in element 1 of the return array. It is the
|
||||
responsibility of the calling method to free () both blocks.
|
||||
|
||||
@warning this logic is UTF-8 unsafe
|
||||
@warning I/O redirection command piping isn't supported in the parse logic
|
||||
@param opts option string to split
|
||||
@return the parsed argv array
|
||||
*/
|
||||
char**
|
||||
split_opt_string (const char* opts);
|
||||
|
||||
/**
|
||||
Accessor method for current execution target.
|
||||
|
||||
This function is defined in runall.cpp (not cmdopt.cpp).
|
||||
|
||||
This value is a pointer into argv[0] of the current target.
|
||||
|
||||
@returns (Base) name of current execution target.
|
||||
*/
|
||||
const char* get_target ();
|
||||
|
||||
#endif /* RW_PARSE_OPTS_H */
|
||||
658
extern/stdcxx/4.2.1/util/codecvt.cpp
vendored
Normal file
658
extern/stdcxx/4.2.1/util/codecvt.cpp
vendored
Normal file
@@ -0,0 +1,658 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* codecvt.cpp
|
||||
*
|
||||
* $Id: codecvt.cpp 449092 2006-09-22 21:16:16Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "diagnostic.h" // for issue_diag()
|
||||
#include "def.h" // for Def
|
||||
|
||||
#include "path.h" // for get_pathname()
|
||||
#include "scanner.h" // for scanner
|
||||
|
||||
#include <cassert> // for assert()
|
||||
#include <climits> // for UCHAR_MAX
|
||||
#include <cstring> // for memset()
|
||||
#include <fstream> // for ifstream, ofstream
|
||||
|
||||
|
||||
typedef std::map<std::string, wchar_t>::const_iterator n_cmap_citer2;
|
||||
|
||||
|
||||
std::size_t Def::
|
||||
gen_mbchar_tables (codecvt_offsets_map_t &tab,
|
||||
std::map<std::string, unsigned> &off_map,
|
||||
const std::string &charp /* = "" */,
|
||||
unsigned tabno /* = 0 */)
|
||||
{
|
||||
// upon the first call (but not during subsequent recursive calls)
|
||||
// generate a set of multibyte prefixes from the set of all known
|
||||
// multibyte characters
|
||||
static unsigned ntabs = 0;
|
||||
static std::set<std::string>* pfx_set = 0;
|
||||
|
||||
const n_cmap_citer2 mb_map_end = charmap_.get_mb_cmap ().end ();
|
||||
|
||||
if (0 == pfx_set) {
|
||||
pfx_set = new std::set<std::string>;
|
||||
|
||||
// iterate over the range of valid multibyte characters
|
||||
// obtained from the charmap and generate a complete
|
||||
// subset of non-empty multibyte prefixes from each
|
||||
unsigned off = 0;
|
||||
|
||||
const n_cmap_citer2 mb_map_begin = charmap_.get_mb_cmap ().begin ();
|
||||
|
||||
for (n_cmap_citer2 it = mb_map_begin; it != mb_map_end; ++it, ++off) {
|
||||
|
||||
// insert the ordinal number of each multibyte character
|
||||
// into a map for fast lookup later
|
||||
off_map.insert (std::make_pair (it->first, off));
|
||||
|
||||
// generate non-empty prefixes up to one byte less
|
||||
// in length than the complete multibyte character
|
||||
for (std::string prefix = it->first; 1 < prefix.size (); ) {
|
||||
prefix = prefix.substr (0, prefix.size () - 1);
|
||||
pfx_set->insert (prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// number of valid characters inserted into the tables
|
||||
std::size_t nchars = 0;
|
||||
|
||||
// an array of offsets to the multibyte character or to the next
|
||||
// array containing such offsets (defined recursively for up to
|
||||
// MB_CUR_MAX levels of nesting)
|
||||
codecvt_offset_tab_t* const offsets = new codecvt_offset_tab_t;
|
||||
|
||||
std::string mb_char (charp + '\0');
|
||||
|
||||
for (unsigned i = 0; i <= UCHAR_MAX; ++i) {
|
||||
|
||||
unsigned char cur_char = (unsigned char)i;
|
||||
|
||||
mb_char [mb_char.size () - 1] = char (cur_char);
|
||||
|
||||
if (mb_map_end == charmap_.get_mb_cmap ().find (mb_char)) {
|
||||
// mb_char is not a complete, valid multibyte character
|
||||
// check to see if it's a prefix of one
|
||||
|
||||
if (pfx_set->find (mb_char) == pfx_set->end ()) {
|
||||
// mb_char is not a prefix of a valid multibyte
|
||||
// character, mark it invalide
|
||||
offsets->off [cur_char] = UINT_MAX;
|
||||
}
|
||||
else {
|
||||
// mb_char is a prefix of a valid multibyte character,
|
||||
// set the MSB to denote that it "continues" in the
|
||||
// table at the next higher offset
|
||||
offsets->off [cur_char] = ++ntabs | 0x80000000;
|
||||
|
||||
// generate that table
|
||||
nchars += gen_mbchar_tables (tab, off_map, mb_char, ntabs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// mb_char is a complete, valid miltibyte character
|
||||
// insert its ordinal number (offset) into the array
|
||||
offsets->off [cur_char] = off_map.find (mb_char)->second;
|
||||
++nchars;
|
||||
}
|
||||
}
|
||||
|
||||
// insert the completely populated table into the map
|
||||
tab.insert (std::make_pair (tabno, offsets));
|
||||
|
||||
if (0 == ntabs) {
|
||||
// clean up on return from the topmost (non-recursive) call
|
||||
delete pfx_set;
|
||||
pfx_set = 0;
|
||||
}
|
||||
|
||||
return nchars;
|
||||
}
|
||||
|
||||
|
||||
std::size_t Def::
|
||||
gen_wchar_tables (codecvt_offsets_map_t &tab,
|
||||
const std::string &charp /* = "" */,
|
||||
unsigned int tabno /* = 0 */)
|
||||
{
|
||||
// upon the first call (but not during subsequent recursive calls)
|
||||
// generate a set of multibyte prefixes from the set of all known
|
||||
// multibyte characters
|
||||
static unsigned ntabs = 0;
|
||||
static std::set<std::string> *pfx_set = 0;
|
||||
static std::map<std::string, unsigned> *off_map = 0;
|
||||
static std::map<std::string, std::string> *utf_map = 0;
|
||||
|
||||
if (0 == utf_map) {
|
||||
pfx_set = new std::set<std::string>;
|
||||
off_map = new std::map<std::string, unsigned>;
|
||||
utf_map = new std::map<std::string, std::string>;
|
||||
|
||||
const n_cmap_citer2 first = charmap_.get_mb_cmap ().begin ();
|
||||
const n_cmap_citer2 last = charmap_.get_mb_cmap ().end ();
|
||||
|
||||
unsigned off = 0;
|
||||
|
||||
for (n_cmap_citer2 it = first; it != last; ++it) {
|
||||
|
||||
off_map->insert (std::make_pair (it->first, off));
|
||||
|
||||
off += it->first.size () + 1;
|
||||
|
||||
std::string utf = utf8_encode (it->second);
|
||||
|
||||
utf_map->insert (std::make_pair (utf, it->first));
|
||||
|
||||
while (1 < utf.size ()) {
|
||||
utf = utf.substr (0, utf.size () - 1);
|
||||
pfx_set->insert (utf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
codecvt_offset_tab_t* const offsets = new codecvt_offset_tab_t;
|
||||
|
||||
// number of valid characters inserted into the tables
|
||||
std::size_t nchars = 0;
|
||||
|
||||
std::string mb_char (charp + '\0');
|
||||
|
||||
for (unsigned i = 0; i <= UCHAR_MAX; ++i) {
|
||||
|
||||
unsigned char cur_char = (unsigned char)i;
|
||||
|
||||
mb_char [mb_char.size () - 1] = char (cur_char);
|
||||
|
||||
const wchar_utf8_iter it = utf_map->find (mb_char);
|
||||
if (it == utf_map->end ()) {
|
||||
if (pfx_set->find (mb_char) == pfx_set->end ()) {
|
||||
offsets->off [cur_char] = UINT_MAX;
|
||||
}
|
||||
else {
|
||||
offsets->off [cur_char] = ++ntabs | 0x80000000;
|
||||
|
||||
nchars += gen_wchar_tables (tab, mb_char, ntabs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
offsets->off [cur_char] = off_map->find (it->second)->second;
|
||||
|
||||
++nchars;
|
||||
}
|
||||
}
|
||||
|
||||
tab.insert (std::make_pair (tabno, offsets));
|
||||
|
||||
if (0 == ntabs) {
|
||||
// clean up
|
||||
delete pfx_set;
|
||||
delete utf_map;
|
||||
|
||||
pfx_set = 0;
|
||||
utf_map = 0;
|
||||
}
|
||||
|
||||
return nchars;
|
||||
}
|
||||
|
||||
|
||||
std::size_t Def::
|
||||
gen_utf8_tables (codecvt_offsets_map_t &tab,
|
||||
std::map<std::string, unsigned> &off_map,
|
||||
const std::string &charp /* = "" */,
|
||||
unsigned tabno /* = 0 */)
|
||||
{
|
||||
static unsigned ntabs = 0;
|
||||
static std::set<std::string> *pfx_set = 0;
|
||||
static std::map<std::string, wchar_t> *utf_map = 0;
|
||||
|
||||
if (0 == pfx_set) {
|
||||
pfx_set = new std::set<std::string>;
|
||||
|
||||
const ucs4_cmap_iter first = charmap_.get_ucs4_cmap ().begin ();
|
||||
const ucs4_cmap_iter last = charmap_.get_ucs4_cmap ().end ();
|
||||
|
||||
for (ucs4_cmap_iter it = first; it != last; ++it) {
|
||||
|
||||
for (std::string prefix = utf8_encode (it->second);
|
||||
1 < prefix.size (); ) {
|
||||
prefix = prefix.substr (0, prefix.size () - 1);
|
||||
pfx_set->insert (prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the set of complete utf8 strings in the current character map
|
||||
typedef std::map<std::string, wchar_t>::iterator utf8_map_iter;
|
||||
|
||||
if (0 == utf_map) {
|
||||
utf_map = new std::map<std::string, wchar_t>;
|
||||
|
||||
const ucs4_cmap_iter first = charmap_.get_ucs4_cmap ().begin ();
|
||||
const ucs4_cmap_iter last = charmap_.get_ucs4_cmap ().end ();
|
||||
|
||||
for (ucs4_cmap_iter it = first; it != last; ++it) {
|
||||
const std::string utf = utf8_encode (it->second);
|
||||
utf_map->insert (std::make_pair (utf, it->second));
|
||||
}
|
||||
}
|
||||
|
||||
codecvt_offset_tab_t* const offsets = new codecvt_offset_tab_t;
|
||||
|
||||
// number of valid characters inserted into the tables
|
||||
std::size_t nchars = 0;
|
||||
|
||||
std::string mb_char = charp + '\0';
|
||||
|
||||
for (unsigned int i = 0; i <= UCHAR_MAX; ++i) {
|
||||
|
||||
unsigned char cur_char = (unsigned char)i;
|
||||
|
||||
mb_char [mb_char.size () - 1] = char (cur_char);
|
||||
|
||||
const utf8_map_iter where = utf_map->find (mb_char);
|
||||
|
||||
if (where == utf_map->end ()) {
|
||||
if (pfx_set->find (mb_char) == pfx_set->end ()) {
|
||||
offsets->off [cur_char] = UINT_MAX;
|
||||
}
|
||||
else {
|
||||
offsets->off [cur_char] = ++ntabs | 0x80000000;
|
||||
nchars += gen_utf8_tables (tab, off_map, mb_char, ntabs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// first get the symbolic name
|
||||
std::string str
|
||||
= charmap_.get_rucs4_cmap ().find (where->second)->second;
|
||||
|
||||
// then get the internal encoding of the character
|
||||
const wchar_t int_enc = charmap_.get_w_cmap().find (str)->second;
|
||||
|
||||
// then get the external encoding to use in a lookup in
|
||||
// mb_char_off_map
|
||||
str = charmap_.get_rmb_cmap ().find (int_enc)->second;
|
||||
|
||||
offsets->off [cur_char] = off_map.find (str)->second;
|
||||
|
||||
++nchars;
|
||||
}
|
||||
}
|
||||
|
||||
tab.insert (std::make_pair (tabno, offsets));
|
||||
|
||||
if (0 == ntabs) {
|
||||
// clean up
|
||||
delete pfx_set;
|
||||
delete utf_map;
|
||||
|
||||
pfx_set = 0;
|
||||
utf_map = 0;
|
||||
}
|
||||
return nchars;
|
||||
}
|
||||
|
||||
|
||||
void Def::
|
||||
gen_xlit_data ()
|
||||
{
|
||||
// data offset points to the beginning of the data containing
|
||||
// the narrow strings character encodings
|
||||
unsigned int data_offset = 0;
|
||||
|
||||
// traverse the map and construct the map of offsets
|
||||
xlit_map_t::const_iterator it = xlit_map_.begin ();
|
||||
for (; it != xlit_map_.end (); ++it) {
|
||||
// insert pair(wchar_t value, offset of first string in data block)
|
||||
xlit_data_offset_map_.insert (
|
||||
std::make_pair (it->first,data_offset));
|
||||
|
||||
// advance the data_offset value to the next "first" string
|
||||
std::list<std::string>::const_iterator sit =
|
||||
it->second.begin ();
|
||||
for (; sit != it->second.end (); ++sit) {
|
||||
data_offset += sit->size () + 1;
|
||||
}
|
||||
++data_offset;
|
||||
}
|
||||
|
||||
// create a new table (first), populate it with default values
|
||||
// and insert it in the tables map
|
||||
xlit_offset_table_t table0;
|
||||
unsigned int k;
|
||||
for (k = 0; k < UCHAR_MAX + 1; ++k)
|
||||
table0.offset_table [k] = UINT_MAX;
|
||||
|
||||
// insert it into the map
|
||||
xlit_table_map_.insert (std::make_pair(0, table0));
|
||||
|
||||
const xlit_map_t::const_iterator xlit_map_end = xlit_map_.end ();
|
||||
|
||||
// traverse the map again and build the tables
|
||||
for (it = xlit_map_.begin (); it != xlit_map_end; ++it) {
|
||||
|
||||
// encode the wchar_t value to UTF-8
|
||||
const std::string utf8_rep (utf8_encode (it->first));
|
||||
data_offset = xlit_data_offset_map_.find (it->first)->second;
|
||||
|
||||
// traverse the utf8 representation string and create the
|
||||
// necessary tables and populate the indexes
|
||||
unsigned int table_idx = 0;
|
||||
|
||||
const std::string::const_iterator utf8_rep_end = utf8_rep.end ();
|
||||
std::string::const_iterator string_it = utf8_rep.begin ();
|
||||
|
||||
for (; string_it != utf8_rep_end; ++string_it) {
|
||||
// get the table corresponding to the current index and locate
|
||||
// the value at that index
|
||||
const xlit_table_map_t::iterator res =
|
||||
xlit_table_map_.find (table_idx);
|
||||
|
||||
assert (res != xlit_table_map_.end ());
|
||||
|
||||
// offset in table
|
||||
unsigned char off_idx = (unsigned char)*string_it;
|
||||
|
||||
// res is the iterator pointing to the correct table in the map
|
||||
// check the index and if not populated, create a new table
|
||||
if (res->second.offset_table [off_idx] == UINT_MAX) {
|
||||
|
||||
// if this is the last position in the string, then
|
||||
// fill the table position with the offset of the string data
|
||||
if ((string_it + 1) == utf8_rep.end ()) {
|
||||
xlit_data_offset_map_t::const_iterator data_it =
|
||||
xlit_data_offset_map_.find (it->first);
|
||||
assert (data_it != xlit_data_offset_map_.end ());
|
||||
|
||||
// fill the table position with the found offset
|
||||
res->second.offset_table [off_idx] = data_it->second;
|
||||
continue;
|
||||
}
|
||||
|
||||
// create a new table and append it to the map
|
||||
xlit_offset_table_t table;
|
||||
for (unsigned int i = 0; i < UCHAR_MAX + 1; ++i)
|
||||
table.offset_table [i] = UINT_MAX;
|
||||
|
||||
// insert it into the map
|
||||
unsigned int tmp = xlit_table_map_.size ();
|
||||
xlit_table_map_.insert (std::make_pair(tmp, table));
|
||||
|
||||
// store its index at correct position in current table
|
||||
res->second.offset_table [off_idx] = tmp | 0x80000000;
|
||||
table_idx = tmp;
|
||||
} else {
|
||||
table_idx =
|
||||
res->second.offset_table [off_idx] & 0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Def::
|
||||
write_codecvt (std::string dir_name)
|
||||
{
|
||||
// if it has been already written
|
||||
if (codecvt_written_)
|
||||
return;
|
||||
|
||||
// compose the directory name
|
||||
((dir_name += _RWSTD_PATH_SEP) += "..") += _RWSTD_PATH_SEP;
|
||||
dir_name += charmap_.get_code_set_name ();
|
||||
|
||||
// check to see if the codecvt database already exists and
|
||||
// avoid recreating it if it does (as an optimization)
|
||||
if (std::ifstream (dir_name.c_str ())) {
|
||||
issue_diag (I_OPENWR, false, 0,
|
||||
"%s exists, skipping\n", dir_name.c_str ());
|
||||
return;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// generate multibyte conversion tables
|
||||
issue_diag (I_STAGE, false, 0, "generating multibyte tables\n");
|
||||
|
||||
codecvt_offsets_map_t mbchar_offs;
|
||||
std::map<std::string, unsigned> off_map;
|
||||
const std::size_t n_mbchars = gen_mbchar_tables (mbchar_offs, off_map);
|
||||
|
||||
// generate wchar_t conversion tables
|
||||
issue_diag (I_STAGE, false, 0, "generating wchar_t tables\n");
|
||||
|
||||
codecvt_offsets_map_t wchar_offs;
|
||||
const std::size_t n_wchars = gen_wchar_tables (wchar_offs);
|
||||
|
||||
// generate UTF-8 conversion conversion tables
|
||||
issue_diag (I_STAGE, false, 0, "generating UTF-8 tables\n");
|
||||
|
||||
codecvt_offsets_map_t uchar_offs;
|
||||
const std::size_t n_uchars = gen_utf8_tables (uchar_offs, off_map);
|
||||
|
||||
// not needed beyond this point, clear it out
|
||||
off_map.clear ();
|
||||
|
||||
// generate the transliteration tables and the transliteration data
|
||||
issue_diag (I_STAGE, false, 0, "generating transliteration tables\n");
|
||||
gen_xlit_data ();
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// populate the codecvt structure before writing it out
|
||||
// in binary form to the file (the codecvt database)
|
||||
_RW::__rw_codecvt_t codecvt_out;
|
||||
std::memset (&codecvt_out, 0, sizeof codecvt_out);
|
||||
|
||||
// calculate byte offsets within the structure
|
||||
codecvt_out.n_to_w_tab_off = 0;
|
||||
codecvt_out.w_to_n_tab_off = codecvt_out.n_to_w_tab_off
|
||||
+ mbchar_offs.size () * (UCHAR_MAX + 1) * sizeof (unsigned);
|
||||
|
||||
codecvt_out.utf8_to_ext_tab_off = codecvt_out.w_to_n_tab_off
|
||||
+ wchar_offs.size () * (UCHAR_MAX + 1) * sizeof (unsigned);
|
||||
|
||||
// insert the transliteration tables here
|
||||
codecvt_out.xliteration_off = codecvt_out.utf8_to_ext_tab_off
|
||||
+ uchar_offs.size () * (UCHAR_MAX + 1) * sizeof (unsigned);
|
||||
|
||||
codecvt_out.wchar_off = codecvt_out.xliteration_off
|
||||
+ xlit_table_map_.size () * (UCHAR_MAX + 1) * sizeof (unsigned);
|
||||
|
||||
codecvt_out.codeset_off = codecvt_out.wchar_off
|
||||
+ charmap_.get_mb_cmap ().size () * 2 * sizeof (wchar_t);
|
||||
|
||||
codecvt_out.charmap_off = codecvt_out.codeset_off
|
||||
+ charmap_.get_code_set_name ().size () + 1 /* NUL */;
|
||||
|
||||
const std::size_t mb_offset = codecvt_out.charmap_off
|
||||
+ charmap_.get_charmap_name ().size () + 1 /* NUL */;
|
||||
|
||||
// compute the size of narrow strings map which added to
|
||||
// mb_offset will give the start of the transliteration data
|
||||
std::size_t xlit_data_offset = mb_offset;
|
||||
|
||||
mb_cmap_iter iter;
|
||||
|
||||
for (iter = charmap_.get_mb_cmap ().begin();
|
||||
iter != charmap_.get_mb_cmap().end(); ++iter) {
|
||||
xlit_data_offset += iter->first.size() + 1;
|
||||
}
|
||||
|
||||
// now traverse again the utf8 tables for transliteration data
|
||||
// and recompute the offsets:
|
||||
const xlit_table_map_t::const_iterator xlit_table_map_end =
|
||||
xlit_table_map_.end ();
|
||||
|
||||
xlit_table_map_t::iterator xit = xlit_table_map_.begin ();
|
||||
for (; xit != xlit_table_map_end; ++xit) {
|
||||
for (unsigned int i = 0; i < UCHAR_MAX + 1; ++i) {
|
||||
if (xit->second.offset_table [i] & 0x80000000)
|
||||
continue;
|
||||
// add the offset for xliteration data
|
||||
xit->second.offset_table [i] += xlit_data_offset;
|
||||
}
|
||||
}
|
||||
|
||||
codecvt_out.mb_cur_max = charmap_.get_mb_cur_max();
|
||||
|
||||
issue_diag (I_OPENWR, false, 0, "writing %s\n", dir_name.c_str ());
|
||||
|
||||
// create the stream with exceptions enabled
|
||||
std::ofstream out (dir_name.c_str(), std::ios::binary);
|
||||
out.exceptions (std::ios::failbit | std::ios::badbit);
|
||||
|
||||
// write the codecvt_out structure
|
||||
out.write ((char*)&codecvt_out, sizeof codecvt_out);
|
||||
|
||||
typedef codecvt_offsets_map_t::iterator off_iter_t;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// write out the multibyte to wchar_t tables
|
||||
issue_diag (I_WRITE, false, 0,
|
||||
"writing %lu multibyte tables (%lu characters)\n",
|
||||
mbchar_offs.size (), n_mbchars);
|
||||
|
||||
for (off_iter_t it = mbchar_offs.begin (); it != mbchar_offs.end (); ++it) {
|
||||
for (unsigned i = 0; i <= UCHAR_MAX; ++i) {
|
||||
|
||||
const unsigned off = it->second->off [i];
|
||||
|
||||
out.write ((const char*)&off, sizeof off);
|
||||
}
|
||||
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
// not needed beyond this point, clear it out
|
||||
mbchar_offs.clear ();
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// write out the wchar_t to multibyte conversion tables
|
||||
issue_diag (I_WRITE, false, 0,
|
||||
"writing %lu wchar_t tables (%lu characters)\n",
|
||||
wchar_offs.size (), n_wchars);
|
||||
|
||||
for (off_iter_t it = wchar_offs.begin (); it != wchar_offs.end (); ++it) {
|
||||
for (unsigned i = 0; i <= UCHAR_MAX; ++i) {
|
||||
|
||||
// adjust offsets to multibyte characters (but not those
|
||||
// to other tables or invalid encodings)
|
||||
unsigned off = it->second->off [i];
|
||||
|
||||
if (!(off & 0x80000000))
|
||||
off += mb_offset;
|
||||
|
||||
out.write ((const char*)&off, sizeof off);
|
||||
}
|
||||
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
// not needed beyond this point, clear it out
|
||||
wchar_offs.clear ();
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// write out the UTF-8 to (libc) multibyte tables
|
||||
issue_diag (I_WRITE, false, 0,
|
||||
"writing %lu UTF-8 tables (%lu characters)\n",
|
||||
uchar_offs.size (), n_uchars);
|
||||
|
||||
for (off_iter_t it = uchar_offs.begin (); it != uchar_offs.end (); ++it) {
|
||||
for (unsigned i = 0; i <= UCHAR_MAX; ++i) {
|
||||
|
||||
// adjust offsets to multibyte characters (but not those
|
||||
// to other tables or invalid encodings)
|
||||
unsigned off = it->second->off [i];
|
||||
|
||||
if (!(off & 0x80000000))
|
||||
off += mb_offset;
|
||||
|
||||
out.write ((const char*)&off, sizeof off);
|
||||
}
|
||||
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
// not needed beyond this point, clear it out
|
||||
uchar_offs.clear ();
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// write out the transliteration UTF-8 lookup tables
|
||||
issue_diag (I_WRITE, false, 0,
|
||||
"writing transliteration table (size %lu)\n",
|
||||
xlit_table_map_.size ());
|
||||
|
||||
xit = xlit_table_map_.begin ();
|
||||
for (; xit != xlit_table_map_end; ++xit) {
|
||||
const unsigned int* ptable = &xit->second.offset_table [0];
|
||||
for (unsigned int i = 0; i < UCHAR_MAX + 1; ++i, ++ptable)
|
||||
out.write ((const char*)ptable, sizeof (unsigned int));
|
||||
}
|
||||
|
||||
issue_diag (I_WRITE, false, 0,
|
||||
"writing the UCS table (%lu characters)\n",
|
||||
charmap_.get_mb_cmap ().size ());
|
||||
|
||||
const mb_cmap_iter n_cmap2_end = charmap_.get_mb_cmap ().end ();
|
||||
|
||||
// write the locale-encoded wchar_t and the UCS4 wchar_t
|
||||
for (iter = charmap_.get_mb_cmap ().begin();
|
||||
iter != n_cmap2_end; ++iter) {
|
||||
out.write ((const char*)&iter->second, sizeof (iter->second));
|
||||
out.write ((const char*)& (charmap_.get_ucs4_cmap().find
|
||||
(charmap_.get_rw_cmap().find
|
||||
(iter->second)->second))->second,
|
||||
sizeof (wchar_t));
|
||||
}
|
||||
|
||||
// write the code_set_name string and charmap string
|
||||
out << charmap_.get_code_set_name() << std::ends
|
||||
<< charmap_.get_charmap_name() << std::ends;
|
||||
|
||||
|
||||
// write out the narrow character strings
|
||||
for (iter = charmap_.get_mb_cmap().begin();
|
||||
iter != n_cmap2_end; ++iter) {
|
||||
out.write (iter->first.c_str(), iter->first.size() + 1);
|
||||
}
|
||||
|
||||
issue_diag (I_WRITE, false, 0,
|
||||
"writing transliteration data (size %lu)\n",
|
||||
xlit_map_.size ());
|
||||
|
||||
// write out the transliteration data
|
||||
xlit_map_t::const_iterator xlit_data_it = xlit_map_.begin ();
|
||||
for (; xlit_data_it != xlit_map_.end (); ++xlit_data_it) {
|
||||
std::list<std::string>::const_iterator sit =
|
||||
xlit_data_it->second.begin ();
|
||||
for (; sit != xlit_data_it->second.end (); ++sit) {
|
||||
out.write (sit->c_str (), sit->size () + 1);
|
||||
}
|
||||
out.write ("\0", 1);
|
||||
}
|
||||
}
|
||||
19
extern/stdcxx/4.2.1/util/codeset_aliases
vendored
Normal file
19
extern/stdcxx/4.2.1/util/codeset_aliases
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
iso88591 ISO-88591 ISO_8859-1 ISO8859-1 ISO-8859-1 END
|
||||
iso88592 ISO-88592 ISO_8859-2 ISO8859-2 ISO-8859-2 END
|
||||
iso88595 ISO-88595 ISO_8859-5 ISO8859-5 ISO-8859-5 END
|
||||
iso88596 ISO-88596 ISO_8859-6 ISO8859-6 ISO-8859-6 END
|
||||
iso88597 ISO-88597 ISO_8859-7 ISO8859-7 ISO-8859-7 END
|
||||
iso88598 ISO-88598 ISO_8859-8 ISO8859-8 ISO-8859-8 END
|
||||
iso88599 ISO-88599 ISO_8859-9 ISO8859-9 ISO-8859-9 END
|
||||
iso885915 ISO-885915 ISO_8859-15 ISO_8859-15:1998 ISO8859-15 ISO-8859-15END
|
||||
arabic8 ARABIC END
|
||||
big5 BIG-5 BIG5 END
|
||||
SJIS END
|
||||
eucJP EUC-JP END
|
||||
eucKR EUC-KR END
|
||||
eucTW EUC-TW END
|
||||
greek8 GREEK8 END
|
||||
hebrew8 HEBREW END
|
||||
roman8 ROMAN8 END
|
||||
tis620 TIS-620 TIS620 END
|
||||
utf8 UTF8 UTF-8 END
|
||||
2254
extern/stdcxx/4.2.1/util/collate.cpp
vendored
Normal file
2254
extern/stdcxx/4.2.1/util/collate.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
914
extern/stdcxx/4.2.1/util/ctype.cpp
vendored
Normal file
914
extern/stdcxx/4.2.1/util/ctype.cpp
vendored
Normal file
@@ -0,0 +1,914 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* ctype.cpp
|
||||
*
|
||||
* $Id: ctype.cpp 648752 2008-04-16 17:01:56Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2008 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "def.h" // for Def
|
||||
#include "diagnostic.h" // for issue_diag()
|
||||
#include "loc_exception.h" // for loc_exception
|
||||
#include "path.h" // for get_pathname()
|
||||
#include "scanner.h" // for scanner
|
||||
|
||||
#include <cassert> // for assert()
|
||||
#include <cctype> // for isdigit(), ...
|
||||
#include <cstdio> // for sprintf()
|
||||
#include <cstdlib> // for strtol()
|
||||
#include <cstring> // for memset(), strchr()
|
||||
#include <fstream> // for ofstream
|
||||
#include <locale> // for ctype_base::mask
|
||||
|
||||
|
||||
static const char lc_name[] = "LC_CTYPE";
|
||||
|
||||
|
||||
static wchar_t
|
||||
convert_literal_to_ucs4 (Scanner::token_t& t)
|
||||
{
|
||||
if ( t.name.size() < 4 || t.name [0] != '<' || t.name [1] != 'U') {
|
||||
issue_diag (E_CVT, true, &t,
|
||||
"Symbol could not be converted to UCS-4 value"
|
||||
"(literal form should have been <Uxxxxxxxx>)");
|
||||
}
|
||||
|
||||
long w = std::strtol (t.name.substr (2, t.name.size ()).c_str (),
|
||||
0, 16);
|
||||
if (w > _RWSTD_WCHAR_MAX) {
|
||||
// issue_diag intercepted in process_transliteration_statement
|
||||
// but will render -w switch useless; just throw here
|
||||
throw loc_exception ("symbol could not be converted to UCS-4 "
|
||||
"value (value outside wchar_t range)");
|
||||
}
|
||||
|
||||
return wchar_t (w);
|
||||
}
|
||||
|
||||
|
||||
bool Def::get_n_val (const Scanner::token_t &tok, unsigned char &val)
|
||||
{
|
||||
bool got_val = true;
|
||||
|
||||
n_cmap_iter n_cmap_pos;
|
||||
|
||||
switch (tok.token) {
|
||||
|
||||
case Scanner::tok_sym_name:
|
||||
n_cmap_pos = charmap_.get_n_cmap ().find (tok.name);
|
||||
if (charmap_.get_n_cmap ().end () != n_cmap_pos)
|
||||
val = n_cmap_pos->second;
|
||||
else
|
||||
got_val = false;
|
||||
break;
|
||||
|
||||
case Scanner::tok_char_value:
|
||||
if (charmap_.mbcharlen (tok.name) == 1)
|
||||
val = scanner_.convert_escape (tok.name.c_str ());
|
||||
else
|
||||
got_val = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
val = tok.name [0];
|
||||
}
|
||||
|
||||
return got_val;
|
||||
}
|
||||
|
||||
|
||||
bool Def::get_w_val (const Scanner::token_t &tok, wchar_t &val)
|
||||
{
|
||||
bool got_val = true;
|
||||
|
||||
w_cmap_iter w_cmap_pos;
|
||||
|
||||
switch (tok.token) {
|
||||
|
||||
case Scanner::tok_sym_name:
|
||||
w_cmap_pos = charmap_.get_w_cmap ().find (tok.name);
|
||||
if (charmap_.get_w_cmap ().end () != w_cmap_pos)
|
||||
val = w_cmap_pos->second;
|
||||
else
|
||||
got_val = false;
|
||||
break;
|
||||
|
||||
case Scanner::tok_char_value:
|
||||
return charmap_.convert_to_wc ("", tok.name, val);
|
||||
|
||||
default:
|
||||
val = wchar_t (tok.name [0]);
|
||||
}
|
||||
|
||||
return got_val;
|
||||
}
|
||||
|
||||
|
||||
// process absolute ellipsis
|
||||
std::size_t Def::
|
||||
process_abs_ellipsis (const Scanner::token_t &nextnext,
|
||||
std::ctype_base::mask m)
|
||||
{
|
||||
std::size_t nchars = 0;
|
||||
|
||||
typedef unsigned char UChar;
|
||||
|
||||
// first we need to handle narrow chars if the range is a range
|
||||
// of narrow characters
|
||||
UChar first;
|
||||
UChar last;
|
||||
|
||||
// check to see if the start value is in the narrow map
|
||||
// if it is then we have to add some values to the narrow mask_tab
|
||||
if (get_n_val (next, first) && get_n_val (nextnext, last)) {
|
||||
// both the start value and end value are in the mask table
|
||||
// so add the mask to the narrow table from start value
|
||||
// to end_value. Make sure that start < end
|
||||
if (last < first)
|
||||
issue_diag (E_RANGE, true, &next,
|
||||
"illegal range [%u, %u] in LC_CTYPE definition\n",
|
||||
last, first);
|
||||
|
||||
for (unsigned val = first; val <= last; ++val)
|
||||
ctype_out_.mask_tab [val] |= m;
|
||||
|
||||
nchars += last - first;
|
||||
}
|
||||
|
||||
wchar_t wfirst;
|
||||
wchar_t wlast;
|
||||
|
||||
if (get_w_val (next, wfirst) && get_w_val (nextnext, wlast)) {
|
||||
|
||||
for (wchar_t val = wfirst; val != wlast; ) {
|
||||
|
||||
const mask_iter mask_pos = mask_.find (val);
|
||||
|
||||
if (mask_pos == mask_.end ())
|
||||
mask_.insert (std::make_pair (val, m));
|
||||
else
|
||||
mask_pos->second |= m;
|
||||
|
||||
val = charmap_.increment_wchar (val);
|
||||
|
||||
++nchars;
|
||||
}
|
||||
|
||||
// now add the end_value
|
||||
mask_iter mask_pos = mask_.find (wlast);
|
||||
if(mask_pos == mask_.end ())
|
||||
mask_.insert (std::make_pair (wlast, m));
|
||||
else {
|
||||
mask_pos->second |= m;
|
||||
}
|
||||
}
|
||||
else {
|
||||
warnings_occurred_ =
|
||||
issue_diag (W_RANGE, false,
|
||||
&next, "beginning or endpoint of range "
|
||||
"was not found in the character map; "
|
||||
"ignoring range\n") || warnings_occurred_;
|
||||
}
|
||||
|
||||
next = scanner_.next_token ();
|
||||
|
||||
return nchars;
|
||||
}
|
||||
|
||||
|
||||
// process hexadecimal symbolic ellipsis, decimal symbolic ellipsis,
|
||||
// and double increment hexadecimal symbolic ellipsis
|
||||
std::size_t Def::
|
||||
process_sym_ellipsis (const std::string& start_sym,
|
||||
const std::string& end_sym,
|
||||
Scanner::token_id type,
|
||||
std::ctype_base::mask m)
|
||||
{
|
||||
// number of characters in the range
|
||||
std::size_t nchars = 0;
|
||||
|
||||
// first, get the alphabetic beginning of the sym name
|
||||
std::size_t idx = 0;
|
||||
std::string begin;
|
||||
|
||||
const int base =
|
||||
type == Scanner::tok_hex_ellipsis
|
||||
|| type == Scanner::tok_dbl_ellipsis ? 16 : 10;
|
||||
|
||||
if (16 == base) {
|
||||
// append all characters until the first hex digit
|
||||
while (idx < start_sym.size () && !std::isxdigit (start_sym [idx]))
|
||||
begin += start_sym [idx++];
|
||||
}
|
||||
else {
|
||||
// append all characters until the first decimal digit
|
||||
while (idx < start_sym.size () && !std::isdigit (start_sym [idx]))
|
||||
begin += start_sym [idx++];
|
||||
}
|
||||
|
||||
std::string num_str; // the numeric portion of the sym name
|
||||
|
||||
// get the numeric portion of the sym_name, this is the portion
|
||||
// that will be different for each sym_name within the ellipsis
|
||||
while (idx < start_sym.size () && start_sym [idx] != '>')
|
||||
num_str += start_sym [idx++];
|
||||
|
||||
std::size_t num_len = num_str.size();
|
||||
|
||||
// convert the numeric string to a long
|
||||
|
||||
unsigned long num = std::strtoul (num_str.c_str(), (char**)0, base);
|
||||
|
||||
// now create the symbolic name
|
||||
char next_num [32];
|
||||
std::string sym_name;
|
||||
do {
|
||||
int len;
|
||||
|
||||
if (16 == base) {
|
||||
len = std::sprintf (next_num, "%lX", num++);
|
||||
|
||||
if (type == Scanner::tok_dbl_ellipsis)
|
||||
num++;
|
||||
}
|
||||
else {
|
||||
len = std::sprintf (next_num, "%lu", num++);
|
||||
}
|
||||
|
||||
sym_name = begin;
|
||||
|
||||
sym_name.append (num_len - len, '0');
|
||||
|
||||
sym_name += next_num;
|
||||
sym_name += '>';
|
||||
|
||||
next.name = sym_name;
|
||||
unsigned char n_val;
|
||||
// if the value is <= UCHARMAX then we will add mask to the
|
||||
// mask_tab table
|
||||
if (get_n_val (next, n_val)) {
|
||||
ctype_out_.mask_tab [n_val] |= m;
|
||||
}
|
||||
|
||||
wchar_t w_val;
|
||||
if (get_w_val (next, w_val)) {
|
||||
// add the mask to the mask map
|
||||
mask_iter mask_pos = mask_.find (w_val);
|
||||
if (mask_pos != mask_.end())
|
||||
mask_pos->second |= m;
|
||||
else {
|
||||
mask_.insert (std::make_pair (w_val, m));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if the value is not in the charmap
|
||||
// then we cannot continue (???)
|
||||
|
||||
/*
|
||||
warnings_occurred_ =
|
||||
issue_diag (W_SYM, false,
|
||||
&next, "symbolic name %s "
|
||||
"was not found in the character map; "
|
||||
"ignoring character\n", next.name.c_str())
|
||||
|| warnings_occurred_;
|
||||
*/
|
||||
}
|
||||
|
||||
++nchars;
|
||||
|
||||
} while (sym_name != end_sym);
|
||||
|
||||
next = scanner_.next_token ();
|
||||
|
||||
return nchars;
|
||||
}
|
||||
|
||||
|
||||
// process_mask is called from process_ctype when process_ctype reaches
|
||||
// a mask defintion (ie. upper, lower, digit). It processes each token
|
||||
// until a new line is reached (which designates the end of the mask
|
||||
// definition). If the token is a symbolic name then it looks up the name
|
||||
// in the cmap map to find the value of the character, otherwise it uses
|
||||
// the value of the character and adds the character to the mask map (if
|
||||
// the character is not alreay there) with the current mask.
|
||||
void Def::
|
||||
process_mask (std::ctype_base::mask m, const char *name)
|
||||
{
|
||||
issue_diag (I_STAGE, false, 0, "processing %s class\n", name);
|
||||
|
||||
next = scanner_.next_token ();
|
||||
|
||||
Scanner::token_t nextnext = scanner_.next_token ();
|
||||
|
||||
std::size_t nchars = 0;
|
||||
|
||||
typedef unsigned char UChar;
|
||||
|
||||
for ( ; next.token != Scanner::tok_nl; ) {
|
||||
|
||||
switch (nextnext.token) {
|
||||
|
||||
case Scanner::tok_abs_ellipsis: {
|
||||
|
||||
// if there are ellipses then include all characters
|
||||
// in between the values that surround the ellipsis
|
||||
|
||||
// the next token will be the end of the range
|
||||
nextnext = scanner_.next_token ();
|
||||
nchars += process_abs_ellipsis (nextnext, m);
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_hex_ellipsis:
|
||||
case Scanner::tok_dec_ellipsis:
|
||||
case Scanner::tok_dbl_ellipsis: {
|
||||
|
||||
const Scanner::token_id id = nextnext.token;
|
||||
// the next token will be the end of the range
|
||||
nextnext = scanner_.next_token ();
|
||||
nchars += process_sym_ellipsis (next.name, nextnext.name, id, m);
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_nl:
|
||||
case Scanner::tok_sym_name:
|
||||
case Scanner::tok_char_value: {
|
||||
|
||||
UChar n_val;
|
||||
// if the value is <= UCHARMAX then add this mask
|
||||
// to the mask table
|
||||
if (get_n_val (next, n_val)) {
|
||||
ctype_out_.mask_tab [n_val] |= m;
|
||||
++nchars;
|
||||
}
|
||||
|
||||
wchar_t w_val;
|
||||
if (get_w_val (next, w_val)) {
|
||||
// add the mask to the mask map
|
||||
const mask_iter mask_pos = mask_.find (w_val);
|
||||
if (mask_pos == mask_.end ())
|
||||
mask_.insert (std::make_pair (w_val, m));
|
||||
else {
|
||||
mask_pos->second |= m;
|
||||
}
|
||||
|
||||
++nchars;
|
||||
}
|
||||
else {
|
||||
// if the value is not in the charmap
|
||||
// then we cannot continue (???)
|
||||
/*
|
||||
warnings_occurred_ =
|
||||
issue_diag (W_SYM, false,
|
||||
&next, "symbolic name %s "
|
||||
"was not found in the character map; "
|
||||
"ignoring character\n", next.name.c_str())
|
||||
|| warnings_occurred_;
|
||||
*/
|
||||
}
|
||||
next = nextnext;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
// the ctype category definition contains non-symbolic characters
|
||||
// the actual value of the characters will be used. This is
|
||||
// unportable
|
||||
warnings_occurred_ =
|
||||
issue_diag (W_SYM, false, &next,
|
||||
"non-symbolic character %s found in ctype "
|
||||
"definition.\n", next.name.c_str())
|
||||
|| warnings_occurred_;
|
||||
if (next.name.size () != 1)
|
||||
warnings_occurred_ =
|
||||
issue_diag (W_SYM, false, &next,
|
||||
"non-symbolic character %s in ctype "
|
||||
"definition is longer than one char in "
|
||||
"length. Ignoring character\n",
|
||||
next.name.c_str()) || warnings_occurred_;
|
||||
else {
|
||||
ctype_out_.mask_tab [UChar (next.name [0])] |= m;
|
||||
wchar_t mb_val = wchar_t (UChar (next.name [0]));
|
||||
mask_iter mask_pos = mask_.find (mb_val);
|
||||
if (mask_pos != mask_.end())
|
||||
mask_pos->second |= m;
|
||||
else
|
||||
mask_.insert (std::make_pair (mb_val, m));
|
||||
++nchars;
|
||||
}
|
||||
next = nextnext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if we are not at the newline get the next token
|
||||
if (Scanner::tok_nl != next.token)
|
||||
nextnext = scanner_.next_token ();
|
||||
}
|
||||
|
||||
issue_diag (I_STAGE, false, 0,
|
||||
"done processing %s class (%lu characters)\n",
|
||||
name, nchars);
|
||||
}
|
||||
|
||||
|
||||
// process_upper_lower processes the toupper and tolower ctype categories
|
||||
// These categories consist of pairs of characters in the format '(<a>,<b>)'
|
||||
void Def::
|
||||
process_upper_lower (Scanner::token_id tok)
|
||||
{
|
||||
assert (Scanner::tok_toupper == tok || Scanner::tok_tolower == tok);
|
||||
|
||||
const char* const name =
|
||||
Scanner::tok_toupper == tok ? "upper" : "lower";
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "processing ctype to%s map\n", name);
|
||||
|
||||
std::size_t nchars = 0;
|
||||
|
||||
// process the toupper and tolower ctype categories
|
||||
|
||||
next = scanner_.next_token();
|
||||
for (; next.token != Scanner::tok_nl; ) {
|
||||
|
||||
std::string sym, sym2;
|
||||
|
||||
// seperate the symbolic names in the toupper or tolower pair
|
||||
// and place the result in sym and sym2
|
||||
strip_pair(next.name, sym, sym2);
|
||||
|
||||
// first process toupper or tolower for the narrow characters
|
||||
const n_cmap_iter sym1_pos = charmap_.get_n_cmap().find (sym);
|
||||
const n_cmap_iter sym2_pos = charmap_.get_n_cmap().find (sym2);
|
||||
if ( sym1_pos != charmap_.get_n_cmap().end()
|
||||
&& sym2_pos != charmap_.get_n_cmap().end()) {
|
||||
if (tok == Scanner::tok_toupper)
|
||||
ctype_out_.toupper_tab [sym1_pos->second] = sym2_pos->second;
|
||||
else
|
||||
ctype_out_.tolower_tab [sym1_pos->second] = sym2_pos->second;
|
||||
|
||||
++nchars;
|
||||
}
|
||||
|
||||
// now process toupper or tolower fot the wide characters
|
||||
const w_cmap_iter wsym1_pos = charmap_.get_w_cmap().find (sym);
|
||||
const w_cmap_iter wsym2_pos = charmap_.get_w_cmap().find (sym2);
|
||||
if (wsym1_pos == charmap_.get_w_cmap().end ())
|
||||
warnings_occurred_ =
|
||||
issue_diag (W_SYM, false, &next,
|
||||
"unknown symbol name %s found in "
|
||||
"%s definition\n", sym.c_str (), lc_name)
|
||||
|| warnings_occurred_;
|
||||
else if (wsym2_pos == charmap_.get_w_cmap().end())
|
||||
warnings_occurred_ =
|
||||
issue_diag (W_SYM, false, &next,
|
||||
"unknown symbol name %s found in "
|
||||
"%s definition\n",
|
||||
sym2.c_str (), lc_name)
|
||||
|| warnings_occurred_;
|
||||
else {
|
||||
if (tok == Scanner::tok_toupper)
|
||||
upper_.insert (std::make_pair (wsym1_pos->second,
|
||||
wsym2_pos->second));
|
||||
else
|
||||
lower_.insert (std::make_pair (wsym1_pos->second,
|
||||
wsym2_pos->second));
|
||||
|
||||
++nchars;
|
||||
}
|
||||
next = scanner_.next_token();
|
||||
}
|
||||
|
||||
issue_diag (I_STAGE, false, 0,
|
||||
"done processing to%s map (%lu characters)\n", name, nchars);
|
||||
}
|
||||
|
||||
|
||||
void Def::
|
||||
process_xlit_statement (std::size_t &nchars)
|
||||
{
|
||||
// convert the name we have for a symbolic name
|
||||
std::string sym_s (next.name);
|
||||
wchar_t sym_w;
|
||||
try {
|
||||
sym_w = convert_literal_to_ucs4 (next);
|
||||
}
|
||||
catch (loc_exception&) {
|
||||
scanner_.ignore_line ();
|
||||
return;
|
||||
}
|
||||
catch (...) {
|
||||
throw;
|
||||
}
|
||||
|
||||
// add a new element to the transliteration map
|
||||
std::pair<xlit_map_t::iterator, bool> res =
|
||||
xlit_map_.insert (std::make_pair(sym_w, std::list<std::string>()));
|
||||
if (res.second == false) {
|
||||
scanner_.ignore_line ();
|
||||
return;
|
||||
}
|
||||
|
||||
xlit_map_t::iterator& it = res.first;
|
||||
next = scanner_.next_token ();
|
||||
while (next.token != Scanner::tok_nl) {
|
||||
|
||||
switch (next.token) {
|
||||
case Scanner::tok_sym_name: {
|
||||
// convert this symbol to a string with the external encoding
|
||||
w_cmap_iter w_pos = charmap_.get_w_cmap().find (next.name);
|
||||
if (w_pos != charmap_.get_w_cmap().end()) {
|
||||
it->second.push_back(convert_to_ext(w_pos->second));
|
||||
++nchars;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Scanner::tok_string: {
|
||||
// for empty names there is no processing
|
||||
if (next.name.size () <= 2)
|
||||
break;
|
||||
|
||||
// convert this symbol or string of symbols to a string
|
||||
// with the external encoding
|
||||
|
||||
std::string enc = convert_string (next.name);
|
||||
if (enc.empty())
|
||||
break;
|
||||
it->second.push_back (enc);
|
||||
++nchars;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
issue_diag (W_SYNTAX, false, &next,
|
||||
"ignoring unexpected token in "
|
||||
"transliteration statement\n");
|
||||
break;
|
||||
}
|
||||
|
||||
next = scanner_.next_token ();
|
||||
}
|
||||
|
||||
// if the transliteration statement contained only symbols undefined in
|
||||
// the character map, dump this balast
|
||||
if (it->second.empty ())
|
||||
xlit_map_.erase (it);
|
||||
}
|
||||
|
||||
|
||||
void Def::
|
||||
process_xlit ()
|
||||
{
|
||||
issue_diag (I_STAGE, false, 0, "processing transliteration\n");
|
||||
|
||||
std::size_t nchars = 0;
|
||||
|
||||
// used in processing the include directive
|
||||
int nesting_level = 0;
|
||||
std::list<std::string> file_list;
|
||||
|
||||
while (true) {
|
||||
next = scanner_.next_token ();
|
||||
|
||||
switch (next.token) {
|
||||
case Scanner::tok_include: {
|
||||
|
||||
// extract all file names from the list
|
||||
std::list<std::string> tmp_list;
|
||||
while (next.token != Scanner::tok_nl) {
|
||||
next = scanner_.next_token ();
|
||||
if (next.token == Scanner::tok_string &&
|
||||
next.name.size () > 2)
|
||||
tmp_list.push_back (next.name);
|
||||
}
|
||||
|
||||
// insert this list into the main list - at beginning
|
||||
file_list.insert (file_list.begin (),
|
||||
tmp_list.begin (), tmp_list.end ());
|
||||
|
||||
// get the top of the list
|
||||
std::string fname (file_list.front ());
|
||||
file_list.pop_front ();
|
||||
|
||||
// bump up the nesting level
|
||||
nesting_level++;
|
||||
|
||||
// get the full path for the included file and open it
|
||||
scanner_.open (get_pathname (strip_quotes (fname), next.file));
|
||||
|
||||
// get comment char and escape char;
|
||||
// these informations are stored by the scanner
|
||||
while ((next = scanner_.next_token ()).token
|
||||
!= Scanner::tok_xlit_start );
|
||||
|
||||
break;
|
||||
}
|
||||
case Scanner::tok_sym_name: {
|
||||
process_xlit_statement (nchars);
|
||||
break;
|
||||
}
|
||||
case Scanner::tok_xlit_end: {
|
||||
if (nesting_level == 0)
|
||||
return;
|
||||
|
||||
// decrement nesting level, close opened file
|
||||
nesting_level--;
|
||||
scanner_.close ();
|
||||
|
||||
// check if the list of files is empty or not
|
||||
if (file_list.empty ())
|
||||
break;
|
||||
|
||||
// if not take the following file and open it
|
||||
std::string fname (file_list.front ());
|
||||
file_list.pop_front ();
|
||||
|
||||
// bump up the nesting level
|
||||
nesting_level++;
|
||||
|
||||
// get the full path for the included file and open it
|
||||
scanner_.open (get_pathname (strip_quotes (fname), next.file));
|
||||
|
||||
// get comment char and escape char;
|
||||
// these informations are stored by the scanner
|
||||
while ((next = scanner_.next_token ()).token
|
||||
!= Scanner::tok_xlit_start);
|
||||
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "done processing transliteration "
|
||||
"(%lu tokens, %lu characters)");
|
||||
}
|
||||
|
||||
|
||||
void Def::
|
||||
process_ctype ()
|
||||
{
|
||||
issue_diag (I_STAGE, false, 0, "processing %s section\n", lc_name);
|
||||
|
||||
ctype_def_found_ = true;
|
||||
|
||||
// used in processing the copy/include directive
|
||||
int nesting_level = 0;
|
||||
|
||||
while ((next = scanner_.next_token()).token != Scanner::tok_ctype) {
|
||||
|
||||
switch(next.token) {
|
||||
|
||||
case Scanner::tok_copy: {
|
||||
// when we see the copy directive in the ctype definition we
|
||||
// are going to either create the shared database and create a
|
||||
// symbolic link to it, or we are going to create a symbolic link
|
||||
// to the already existing shared ctype database.
|
||||
|
||||
next = scanner_.next_token();
|
||||
if (next.token != Scanner::tok_string)
|
||||
issue_diag (E_SYNTAX, true, &next,
|
||||
"expected string following \"copy\" directive\n");
|
||||
#ifndef _MSC_VER
|
||||
|
||||
ctype_symlink_ = true;
|
||||
|
||||
// first lets make sure that the ctype database for this
|
||||
// locale hasn't already been generated
|
||||
ctype_filename_ = output_name_;
|
||||
// strip off the last directory
|
||||
ctype_filename_ = ctype_filename_.substr
|
||||
(0, ctype_filename_.rfind
|
||||
(_RWSTD_PATH_SEP, ctype_filename_.length() - 1) + 1);
|
||||
ctype_filename_ += strip_quotes(next.name);
|
||||
ctype_filename_ += ".ctype.";
|
||||
ctype_filename_ += charmap_.get_charmap_name();
|
||||
std::ifstream f (ctype_filename_.c_str(), std::ios::binary);
|
||||
if (f) {
|
||||
// the database exists so simply create a sym link to it
|
||||
ctype_written_ = true;
|
||||
f.close();
|
||||
continue;
|
||||
}
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
// bump up the nesting level
|
||||
nesting_level++;
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "processing copy directive\n");
|
||||
|
||||
// open the file
|
||||
scanner_.open (get_pathname (strip_quotes (next.name), next.file));
|
||||
|
||||
// get comment char and escape char;
|
||||
// these informations are stored by the scanner
|
||||
while ((next = scanner_.next_token ()).token
|
||||
!= Scanner::tok_ctype ){
|
||||
// the LC_IDENTIFICATION section may also have a
|
||||
// LC_CTYPE token that will mess up the parsing
|
||||
if (next.token == Scanner::tok_ident) {
|
||||
while ((next = scanner_.next_token()).token
|
||||
!= Scanner::tok_end );
|
||||
next = scanner_.next_token();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Scanner::tok_nl:
|
||||
break;
|
||||
|
||||
case Scanner::tok_upper:
|
||||
process_mask (std::ctype_base::upper, "upper");
|
||||
break;
|
||||
|
||||
case Scanner::tok_lower:
|
||||
process_mask (std::ctype_base::lower, "lower");
|
||||
break;
|
||||
|
||||
case Scanner::tok_alpha:
|
||||
process_mask (std::ctype_base::alpha, "alpha");
|
||||
break;
|
||||
|
||||
case Scanner::tok_digit:
|
||||
process_mask (std::ctype_base::digit, "digit");
|
||||
break;
|
||||
|
||||
case Scanner::tok_space:
|
||||
process_mask (std::ctype_base::space, "space");
|
||||
break;
|
||||
|
||||
case Scanner::tok_cntrl:
|
||||
process_mask (std::ctype_base::cntrl, "cntrl");
|
||||
break;
|
||||
|
||||
case Scanner::tok_punct:
|
||||
process_mask (std::ctype_base::punct, "punct");
|
||||
break;
|
||||
|
||||
case Scanner::tok_graph:
|
||||
process_mask (std::ctype_base::graph, "graph");
|
||||
break;
|
||||
|
||||
case Scanner::tok_print:
|
||||
process_mask (std::ctype_base::print, "print");
|
||||
break;
|
||||
|
||||
case Scanner::tok_xdigit:
|
||||
process_mask (std::ctype_base::xdigit, "xdigit");
|
||||
break;
|
||||
|
||||
case Scanner::tok_toupper:
|
||||
process_upper_lower (Scanner::tok_toupper);
|
||||
break;
|
||||
|
||||
case Scanner::tok_tolower:
|
||||
process_upper_lower (Scanner::tok_tolower);
|
||||
break;
|
||||
|
||||
case Scanner::tok_blank:
|
||||
scanner_.ignore_line();
|
||||
break;
|
||||
|
||||
case Scanner::tok_xlit_start:
|
||||
process_xlit ();
|
||||
break;
|
||||
|
||||
case Scanner::tok_end:
|
||||
next = scanner_.next_token();
|
||||
if (next.token == Scanner::tok_ctype) {
|
||||
// end of ctype block
|
||||
if (nesting_level == 0)
|
||||
return;
|
||||
|
||||
nesting_level--;
|
||||
scanner_.close ();
|
||||
} else
|
||||
issue_diag (E_SYNTAX, true, &next,
|
||||
"wrong section name in END directive\n");
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// ignore locale specific character classes because the c++
|
||||
// library does not make use of them
|
||||
scanner_.ignore_line();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Def::
|
||||
write_ctype (std::string dir_name)
|
||||
{
|
||||
// dir_name cannot be empty
|
||||
assert (!dir_name.empty());
|
||||
|
||||
if (ctype_filename_.empty ()) {
|
||||
ctype_filename_ = dir_name + _RWSTD_PATH_SEP + lc_name;
|
||||
ctype_symlink_ = false;
|
||||
}
|
||||
|
||||
// if a CTYPE section was not found or ctype info has been already written
|
||||
// in the database
|
||||
if (ctype_def_found_ && !ctype_written_) {
|
||||
|
||||
issue_diag (I_OPENWR, false, 0,
|
||||
"writing %s\n", ctype_filename_.c_str ());
|
||||
|
||||
std::ofstream out (ctype_filename_.c_str(), std::ios::binary);
|
||||
out.exceptions (std::ios::failbit | std::ios::badbit);
|
||||
|
||||
// calculate the offsets for the wchar_t arrays
|
||||
ctype_out_.wtoupper_off = 0;
|
||||
ctype_out_.wtolower_off = ctype_out_.wtoupper_off
|
||||
+ upper_.size() * sizeof (_RW::__rw_upper_elm);
|
||||
ctype_out_.wmask_off = ctype_out_.wtolower_off
|
||||
+ lower_.size() * sizeof (_RW::__rw_lower_elm);
|
||||
ctype_out_.wmask_s = mask_.size();
|
||||
|
||||
// calculate the offsets for the codeset name string and character
|
||||
// map name string
|
||||
ctype_out_.codeset_off = ctype_out_.wmask_off
|
||||
+ mask_.size() * sizeof (_RW::__rw_mask_elm);
|
||||
ctype_out_.charmap_off = ctype_out_.codeset_off
|
||||
+ charmap_.get_code_set_name().size() + 1;
|
||||
|
||||
ctype_out_.mb_cur_max = charmap_.get_mb_cur_max();
|
||||
std::size_t i;
|
||||
|
||||
for (i = 0; i <= UCHAR_MAX; i++) {
|
||||
if(0 == ctype_out_.toupper_tab[i])
|
||||
ctype_out_.toupper_tab[i] = (char)i;
|
||||
if(0 == ctype_out_.tolower_tab[i])
|
||||
ctype_out_.tolower_tab[i] = (char)i;
|
||||
}
|
||||
|
||||
// write the ctype_out structure
|
||||
out.write ((char*)&ctype_out_, sizeof(ctype_out_));
|
||||
|
||||
// print out the wide character arrays
|
||||
for(upper_iter u_pos = upper_.begin(); u_pos != upper_.end(); u_pos++){
|
||||
_RW::__rw_upper_elm elm = {u_pos->first, u_pos->second};
|
||||
out.write((char*)&elm, sizeof(elm));
|
||||
}
|
||||
for(lower_iter l_pos = lower_.begin(); l_pos != lower_.end(); l_pos++){
|
||||
_RW::__rw_lower_elm elm = {l_pos->first, l_pos->second};
|
||||
out.write((char*)&elm, sizeof(elm));
|
||||
}
|
||||
for(mask_iter m_pos = mask_.begin(); m_pos != mask_.end(); m_pos++){
|
||||
_RW::__rw_mask_elm elm = {m_pos->first, m_pos->second};
|
||||
out.write((char*)&elm, sizeof(elm));
|
||||
}
|
||||
|
||||
// write the code_set_name string and charmap string
|
||||
out << charmap_.get_code_set_name() << std::ends
|
||||
<< charmap_.get_charmap_name() << std::ends;
|
||||
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
||||
if (ctype_symlink_) {
|
||||
|
||||
std::string xname (ctype_filename_);
|
||||
if (xname [0] != _RWSTD_PATH_SEP) {
|
||||
xname = std::string ("..");
|
||||
xname += _RWSTD_PATH_SEP;
|
||||
xname += ctype_filename_.substr (
|
||||
ctype_filename_.rfind (_RWSTD_PATH_SEP) + 1,
|
||||
ctype_filename_.size ());
|
||||
}
|
||||
|
||||
std::string sname (lc_name);
|
||||
create_symlink (output_name_, xname, sname);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
}
|
||||
610
extern/stdcxx/4.2.1/util/def.cpp
vendored
Normal file
610
extern/stdcxx/4.2.1/util/def.cpp
vendored
Normal file
@@ -0,0 +1,610 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* def.cpp
|
||||
*
|
||||
* $Id: def.cpp 522614 2007-03-26 20:25:09Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
// #ifndef _RWSTD_NO_PURE_C_HEADERS
|
||||
// # define _RWSTD_NO_PURE_C_HEADERS
|
||||
// #endif // _RWSTD_NO_PURE_C_HEADERS
|
||||
|
||||
// #ifndef _RWSTD_NO_DEPRECATED_C_HEADERS
|
||||
// # define _RWSTD_NO_DEPRECATED_C_HEADERS
|
||||
// #endif // _RWSTD_NO_DEPRECATED_C_HEADERS
|
||||
|
||||
#ifdef __DECCXX
|
||||
# undef __PURE_CNAME
|
||||
#endif // __DECCXX
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <cerrno>
|
||||
#include <climits>
|
||||
#include <clocale>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring> // for memset()
|
||||
|
||||
#include "aliases.h"
|
||||
#include "def.h"
|
||||
#include "diagnostic.h"
|
||||
#include "loc_exception.h"
|
||||
#include "path.h"
|
||||
|
||||
|
||||
#define UTF8_MAX_SIZE 6
|
||||
|
||||
|
||||
// convert_to_ext converts a wchar_t value with some encoding into
|
||||
// a narrow character string in the current locale's encoding
|
||||
std::string Def::convert_to_ext (wchar_t val)
|
||||
{
|
||||
rmb_cmap_iter it;
|
||||
if ((it = charmap_.get_rmb_cmap().find(val))
|
||||
!= charmap_.get_rmb_cmap().end()){
|
||||
return it->second;
|
||||
|
||||
}
|
||||
|
||||
issue_diag (E_CVT2EXT, true, 0,
|
||||
"unable to convert character %d to external "
|
||||
"representation\n", val);
|
||||
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
|
||||
// convert the wchar_t value into a utf8 string
|
||||
std::string Def::utf8_encode (wchar_t wc)
|
||||
{
|
||||
unsigned int wc_int = _RWSTD_STATIC_CAST (unsigned int, wc);
|
||||
|
||||
std::string ret;
|
||||
std::size_t size = 0;
|
||||
char buf[UTF8_MAX_SIZE + 1];
|
||||
char* bufp = buf;
|
||||
|
||||
if (wc_int < 0x80)
|
||||
{
|
||||
size = 1;
|
||||
*bufp++ = wc_int;
|
||||
}
|
||||
else
|
||||
{
|
||||
int b;
|
||||
|
||||
for (b = 2; b < UTF8_MAX_SIZE; b++)
|
||||
if ((wc_int & (~(wchar_t)0 << (5 * b + 1))) == 0)
|
||||
break;
|
||||
size = b;
|
||||
|
||||
*bufp = (unsigned char) (~0xff >> b);
|
||||
--b;
|
||||
do
|
||||
{
|
||||
bufp[b] = 0x80 | (wc_int & 0x3f);
|
||||
wc_int >>= 6;
|
||||
}
|
||||
while (--b > 0);
|
||||
*bufp |= wc_int;
|
||||
}
|
||||
buf[size] = (char)0;
|
||||
for (unsigned int i = 0; i < size; i++)
|
||||
ret += buf[i];
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
void Def::copy_file (const std::string& name, const std::string& outname)
|
||||
{
|
||||
assert (name.size() > 0);
|
||||
assert (outname.size() > 0);
|
||||
|
||||
std::ifstream from (name.c_str(), std::ios::binary);
|
||||
if (!from) {
|
||||
issue_diag (E_OPENRD, true,
|
||||
&next, "unable to open locale database %s\n",
|
||||
name.c_str());
|
||||
}
|
||||
from.exceptions (std::ios::badbit);
|
||||
|
||||
std::ofstream to (outname.c_str(), std::ios::binary);
|
||||
if (!to) {
|
||||
issue_diag (E_OPENWR, true,
|
||||
&next, "unable to create locale database %s\n",
|
||||
outname.c_str());
|
||||
}
|
||||
to.exceptions (std::ios::failbit | std::ios::badbit);
|
||||
|
||||
// copy the file
|
||||
to << from.rdbuf ();
|
||||
}
|
||||
|
||||
|
||||
void Def::copy_category(int category, std::string name)
|
||||
{
|
||||
assert (name.size() > 0);
|
||||
|
||||
// create the name of the file to copy to and call copy_file
|
||||
std::string outname (output_name_);
|
||||
|
||||
makedir (outname.c_str ());
|
||||
|
||||
switch (category) {
|
||||
// append the category name to both 'name' and 'outname'
|
||||
// and call the copy_file routine
|
||||
// the xxx_written variable is set to true so that write_xxx
|
||||
// does not overwrite the file that is written here
|
||||
case LC_CTYPE:
|
||||
(name += _RWSTD_PATH_SEP) += "LC_CTYPE";
|
||||
(outname += _RWSTD_PATH_SEP) += "LC_CTYPE";
|
||||
copy_file (name, outname);
|
||||
ctype_written_ = true;
|
||||
|
||||
break;
|
||||
case LC_COLLATE:
|
||||
(name += _RWSTD_PATH_SEP) += "LC_COLLATE";
|
||||
(outname += _RWSTD_PATH_SEP) += "LC_COLLATE";
|
||||
copy_file(name, outname);
|
||||
collate_written_ = true;
|
||||
|
||||
break;
|
||||
case LC_MONETARY:
|
||||
(name += _RWSTD_PATH_SEP) += "LC_MONETARY";
|
||||
(outname += _RWSTD_PATH_SEP) += "LC_MONETARY";
|
||||
copy_file(name, outname);
|
||||
mon_written_ = true;
|
||||
|
||||
break;
|
||||
|
||||
case LC_NUMERIC:
|
||||
(name += _RWSTD_PATH_SEP) += "LC_NUMERIC";
|
||||
(outname += _RWSTD_PATH_SEP) += "LC_NUMERIC";
|
||||
copy_file(name, outname);
|
||||
num_written_ = true;
|
||||
|
||||
break;
|
||||
case LC_TIME:
|
||||
(name += _RWSTD_PATH_SEP) += "LC_TIME";
|
||||
(outname += _RWSTD_PATH_SEP) += "LC_TIME";
|
||||
copy_file(name, outname);
|
||||
time_written_ = true;
|
||||
|
||||
break;
|
||||
|
||||
#ifdef LC_MESSAGES
|
||||
case LC_MESSAGES:
|
||||
(name += _RWSTD_PATH_SEP) += "LC_MESSAGES";
|
||||
(outname += _RWSTD_PATH_SEP) += "LC_MESSAGES";
|
||||
copy_file(name, outname);
|
||||
messages_written_ = true;
|
||||
break;
|
||||
#endif // LC_MESSAGES
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// strip a pair, which should be in the form '(<sym>,<sym2>)'
|
||||
void Def::strip_pair (const std::string &tok, std::string &sym,
|
||||
std::string &sym2)
|
||||
{
|
||||
std::size_t i = 0;
|
||||
|
||||
if(tok[i] == '(') {
|
||||
if(tok[++i] == '<')
|
||||
while (tok[i] != '>'){
|
||||
if (tok[i] == scanner_.escape_char ())
|
||||
i++;
|
||||
sym.push_back(tok[i++]);
|
||||
}
|
||||
// this push_back is safe because the while loop above ends when
|
||||
// tok[i] == '>'
|
||||
sym.push_back(tok[i++]);
|
||||
if (tok[i++] != ',')
|
||||
issue_diag (E_PAIR, true, &next,
|
||||
"invalid pair %s\n", tok.c_str());
|
||||
if (tok[i] == '<')
|
||||
while (tok[i] != '>'){
|
||||
if (tok[i] == scanner_.escape_char ())
|
||||
sym2.push_back(tok[i++]);
|
||||
if ('\0' != tok[i])
|
||||
sym2.push_back(tok[i++]);
|
||||
else
|
||||
issue_diag (E_PAIR, true, &next,
|
||||
"invalid pair %s\n", tok.c_str());
|
||||
}
|
||||
|
||||
// this push_back is safe because the while loop above ends when
|
||||
// tok[i] == '>'
|
||||
sym2.push_back(tok[i++]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// converts str, which is a string in the following format
|
||||
// "[<sym_name>][char]" including the quotes to a string of characters
|
||||
// str is not a const reference because if the string spans multiple lines
|
||||
// str is modified
|
||||
std::string Def::convert_string (const std::string &str1)
|
||||
{
|
||||
assert (str1[0] == '\"');
|
||||
|
||||
std::string ret;
|
||||
|
||||
std::string sym;
|
||||
// the index starts at 1 so that we ignore the initial '"'
|
||||
int idx = 1;
|
||||
|
||||
const char* str = str1.c_str();
|
||||
while (str[idx] != '\"') {
|
||||
sym.clear();
|
||||
// if we reach the null-terminator before we see an end-quote
|
||||
// then we must have a multi-line string, so get the next token
|
||||
if (str[idx] == '\0') {
|
||||
if((next = scanner_.next_token()).token == Scanner::tok_string)
|
||||
break;
|
||||
str = next.name.c_str();
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
// '<' marks the beginning of a symbolic name
|
||||
// construct the name and look up its value in the cmap
|
||||
if (str[idx] == '<') {
|
||||
while (str [idx] && str [idx] != '>') {
|
||||
if (str[idx] == scanner_.escape_char ())
|
||||
idx++;
|
||||
sym += str[idx++];
|
||||
}
|
||||
|
||||
// this is safe because the while loop ended with *str == '>'
|
||||
if (str [idx])
|
||||
sym += str [idx++];
|
||||
|
||||
w_cmap_iter w_pos = charmap_.get_w_cmap().find (sym);
|
||||
if (w_pos != charmap_.get_w_cmap().end()) {
|
||||
ret += convert_to_ext(w_pos->second);
|
||||
}
|
||||
else {
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
// the definition file contains a sting with non-symbol names.
|
||||
// process each character as it's actual character value.
|
||||
// Locale definitions that use this may not be portable.
|
||||
else {
|
||||
ret += (char)str[idx++];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#ifndef _RWSTD_NO_WCHAR_T
|
||||
// converts a collating element definition to an array of wide characters
|
||||
// (the wide characters the collating element is composed of).
|
||||
|
||||
// this overload deals with collating elements defined through
|
||||
// a sequence of symbolic names, NOT enclosed within quotes.
|
||||
std::wstring
|
||||
Def::convert_wstring (const StringVector& sym_array)
|
||||
{
|
||||
std::wstring ret;
|
||||
StringVector::const_iterator it = sym_array.begin ();
|
||||
while (it != sym_array.end ()) {
|
||||
// lookup the symbol we just constructed
|
||||
w_cmap_iter w_pos = charmap_.get_w_cmap().find (*it);
|
||||
if (w_pos != charmap_.get_w_cmap().end()) {
|
||||
ret += w_pos->second;
|
||||
it++;
|
||||
}
|
||||
else {
|
||||
// we return an empty string if we couldn't find any character
|
||||
// in the character map
|
||||
ret.clear();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// this overload deals with collating elements defined through
|
||||
// a sequence of characters or symbolic names, enclosed within quotes.
|
||||
std::wstring
|
||||
Def::convert_wstring (const token_t& t)
|
||||
{
|
||||
std::wstring ret;
|
||||
std::string sym;
|
||||
|
||||
std::string str1 (t.name);
|
||||
|
||||
int idx = 0;
|
||||
char term = 0;
|
||||
const char* str = str1.c_str();
|
||||
|
||||
// skip first character if quote
|
||||
if (str[idx] == '\"') {
|
||||
term = '\"', idx++;
|
||||
}
|
||||
|
||||
while (str[idx] != term) {
|
||||
sym.clear();
|
||||
|
||||
// '<' marks the beginning of a symbolic name
|
||||
// construct the name and look up its value in the cmap
|
||||
if (str[idx] == '<') {
|
||||
while (str[idx] != '>') {
|
||||
if (str[idx] == scanner_.escape_char ()) {
|
||||
// sym += str[idx++];
|
||||
idx++;
|
||||
}
|
||||
|
||||
if ('\0' != str[idx])
|
||||
sym += str[idx++];
|
||||
else
|
||||
issue_diag (E_SYMEND, true, &t,
|
||||
"end of symbolic name not found\n");
|
||||
}
|
||||
|
||||
// this is safe because the while loop ended with *str == '>'
|
||||
sym += str[idx++];
|
||||
|
||||
// lookup the symbol we just constructed
|
||||
w_cmap_iter w_pos = charmap_.get_w_cmap().find (sym);
|
||||
if (w_pos != charmap_.get_w_cmap().end()) {
|
||||
ret += w_pos->second;
|
||||
}
|
||||
else {
|
||||
// if we can't find a symbol then return an empty string,
|
||||
// most likely this will happen if inside a collating-element
|
||||
// the user uses a character that is not in the current
|
||||
// codeset, in this case the collating element will be ignored
|
||||
ret.clear();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
// the definition file contains a string with non-symbol names.
|
||||
// process each character as it's actual character value.
|
||||
// Locale definitions that use this may not be portable.
|
||||
else
|
||||
ret += (wchar_t)str[idx++];
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
#endif // _RWSTD_NO_WCHAR_T
|
||||
|
||||
|
||||
// automatically fill any categories that depend on other categories
|
||||
void Def::auto_fill ()
|
||||
{
|
||||
|
||||
mask_iter mask_pos;
|
||||
|
||||
for (std::size_t i = 0; i <= UCHAR_MAX; i++) {
|
||||
if ( ctype_out_.mask_tab[i] & std::ctype_base::upper
|
||||
|| ctype_out_.mask_tab[i] & std::ctype_base::lower
|
||||
|| ctype_out_.mask_tab[i] & std::ctype_base::alpha
|
||||
|| ctype_out_.mask_tab[i] & std::ctype_base::digit
|
||||
|| ctype_out_.mask_tab[i] & std::ctype_base::xdigit
|
||||
|| ctype_out_.mask_tab[i] & std::ctype_base::punct)
|
||||
|
||||
ctype_out_.mask_tab[i] |= std::ctype_base::print;
|
||||
|
||||
if ( ctype_out_.mask_tab[i] & std::ctype_base::upper
|
||||
|| ctype_out_.mask_tab[i] & std::ctype_base::lower)
|
||||
|
||||
ctype_out_.mask_tab[i] |= std::ctype_base::alpha;
|
||||
|
||||
if ( ctype_out_.mask_tab[i] & std::ctype_base::upper
|
||||
|| ctype_out_.mask_tab[i] & std::ctype_base::lower
|
||||
|| ctype_out_.mask_tab[i] & std::ctype_base::alpha
|
||||
|| ctype_out_.mask_tab[i] & std::ctype_base::digit
|
||||
|| ctype_out_.mask_tab[i] & std::ctype_base::xdigit
|
||||
|| ctype_out_.mask_tab[i] & std::ctype_base::punct)
|
||||
|
||||
ctype_out_.mask_tab[i] |= std::ctype_base::graph;
|
||||
}
|
||||
|
||||
for (mask_pos = mask_.begin(); mask_pos != mask_.end(); mask_pos++) {
|
||||
// all lower, alpha, digit, xdigit, and punct, and space
|
||||
// characters are automatically print
|
||||
|
||||
if ( mask_pos->second & std::ctype_base::upper
|
||||
|| mask_pos->second & std::ctype_base::lower
|
||||
|| mask_pos->second & std::ctype_base::alpha
|
||||
|| mask_pos->second & std::ctype_base::digit
|
||||
|| mask_pos->second & std::ctype_base::xdigit
|
||||
|| mask_pos->second & std::ctype_base::punct)
|
||||
// || mask_pos->second & std::ctype_base::space)
|
||||
|
||||
mask_pos->second |= std::ctype_base::print;
|
||||
|
||||
// all upper and lower characters are alpha
|
||||
if ( mask_pos->second & std::ctype_base::upper
|
||||
|| mask_pos->second & std::ctype_base::lower)
|
||||
|
||||
mask_pos->second |= std::ctype_base::alpha;
|
||||
|
||||
// all upper, lower, alpha, digit, xdigit, and punct characters
|
||||
// are graph characters
|
||||
if ( mask_pos->second & std::ctype_base::upper
|
||||
|| mask_pos->second & std::ctype_base::lower
|
||||
|| mask_pos->second & std::ctype_base::alpha
|
||||
|| mask_pos->second & std::ctype_base::digit
|
||||
|| mask_pos->second & std::ctype_base::xdigit
|
||||
|| mask_pos->second & std::ctype_base::punct)
|
||||
|
||||
mask_pos->second |= std::ctype_base::graph;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Def::process_input ()
|
||||
{
|
||||
while ((next = scanner_.next_token ()).token != Scanner::tok_end_tokens) {
|
||||
|
||||
switch (next.token) {
|
||||
|
||||
case Scanner::tok_comment:
|
||||
scanner_.ignore_line ();
|
||||
break;
|
||||
|
||||
case Scanner::tok_ctype:
|
||||
process_ctype ();
|
||||
break;
|
||||
|
||||
case Scanner::tok_collate:
|
||||
process_collate ();
|
||||
break;
|
||||
|
||||
case Scanner::tok_monetary:
|
||||
process_monetary ();
|
||||
break;
|
||||
|
||||
case Scanner::tok_numeric:
|
||||
process_numeric ();
|
||||
break;
|
||||
|
||||
case Scanner::tok_time:
|
||||
process_time ();
|
||||
break;
|
||||
|
||||
case Scanner::tok_messages:
|
||||
process_messages ();
|
||||
break;
|
||||
|
||||
case Scanner::tok_nl:
|
||||
break;
|
||||
|
||||
default:
|
||||
scanner_.ignore_line ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto_fill ();
|
||||
}
|
||||
|
||||
|
||||
Def::Def (const char* filename, const char* out_name, Charmap& char_map,
|
||||
bool no_position)
|
||||
: warnings_occurred_ (false),
|
||||
scan_ahead_ (false),
|
||||
next_offset_ (0),
|
||||
output_name_ (out_name),
|
||||
charmap_ (char_map),
|
||||
ctype_written_ (false),
|
||||
codecvt_written_ (false),
|
||||
collate_written_ (false),
|
||||
time_written_ (false),
|
||||
num_written_ (false),
|
||||
mon_written_ (false),
|
||||
messages_written_ (false),
|
||||
ctype_def_found_ (false),
|
||||
collate_def_found_ (false),
|
||||
time_def_found_ (false),
|
||||
num_def_found_ (false),
|
||||
mon_def_found_ (false),
|
||||
messages_def_found_ (false),
|
||||
undefined_keyword_found_ (false),
|
||||
no_position_ (no_position)
|
||||
|
||||
{
|
||||
// make sure ctype_out object is cleared
|
||||
std::memset (&ctype_out_, 0, sizeof (ctype_out_));
|
||||
std::memset (&time_out_, 0, sizeof (time_out_));
|
||||
|
||||
// invalidate format characters by setting each to CHAR_MAX
|
||||
// as specified by the C function localeconv()
|
||||
mon_out_.frac_digits [0] = CHAR_MAX;
|
||||
mon_out_.frac_digits [1] = CHAR_MAX;
|
||||
mon_out_.p_cs_precedes [0] = CHAR_MAX;
|
||||
mon_out_.p_sep_by_space [0] = CHAR_MAX;
|
||||
mon_out_.n_cs_precedes [0] = CHAR_MAX;
|
||||
mon_out_.n_sep_by_space [0] = CHAR_MAX;
|
||||
mon_out_.p_sign_posn [0] = CHAR_MAX;
|
||||
mon_out_.n_sign_posn [0] = CHAR_MAX;
|
||||
|
||||
mon_st_.mon_grouping += CHAR_MAX;
|
||||
|
||||
// invalidate int'l formats
|
||||
mon_out_.p_cs_precedes [1] = CHAR_MAX;
|
||||
mon_out_.p_sep_by_space [1] = CHAR_MAX;
|
||||
mon_out_.n_cs_precedes [1] = CHAR_MAX;
|
||||
mon_out_.n_sep_by_space [1] = CHAR_MAX;
|
||||
mon_out_.p_sign_posn [1] = CHAR_MAX;
|
||||
mon_out_.n_sign_posn [1] = CHAR_MAX;
|
||||
|
||||
num_st_.grouping += CHAR_MAX;
|
||||
|
||||
collate_out_.largest_ce = 1;
|
||||
collate_out_.longest_weight = 1;
|
||||
collate_out_.num_wchars = 0;
|
||||
std::memset (collate_out_.weight_type, 0,
|
||||
sizeof (collate_out_.weight_type));
|
||||
|
||||
// initialize all extensions to 0
|
||||
ctype_out_.ctype_ext_off = 0;
|
||||
num_out_.numeric_ext_off = 0;
|
||||
collate_out_.collate_ext_off = 0;
|
||||
mon_out_.monetary_ext_off = 0;
|
||||
time_out_.time_ext_off = 0;
|
||||
|
||||
// actual processing
|
||||
scanner_.open (filename);
|
||||
}
|
||||
|
||||
|
||||
Def::~Def ()
|
||||
{
|
||||
// free up the memory that was allocated
|
||||
|
||||
coll_map_iter coll_map_pos;
|
||||
for (coll_map_pos = coll_map_.begin();
|
||||
coll_map_pos != coll_map_.end(); coll_map_pos ++) {
|
||||
delete[] (coll_map_pos->second.weights);
|
||||
}
|
||||
|
||||
}
|
||||
615
extern/stdcxx/4.2.1/util/def.h
vendored
Normal file
615
extern/stdcxx/4.2.1/util/def.h
vendored
Normal file
@@ -0,0 +1,615 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* def.h
|
||||
*
|
||||
* $Id: def.h 648752 2008-04-16 17:01:56Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RWSTD_UTIL_DEF_H_INCLUDED
|
||||
#define RWSTD_UTIL_DEF_H_INCLUDED
|
||||
|
||||
#include <list>
|
||||
#include <locale> // for ctype_base
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cassert> // for assert()
|
||||
#include <climits> // for UCHAR_MAX
|
||||
#include <cstddef> // for size_t
|
||||
|
||||
#include <loc/_localedef.h>
|
||||
|
||||
#include "scanner.h"
|
||||
#include "charmap.h"
|
||||
|
||||
|
||||
class Def
|
||||
{
|
||||
public:
|
||||
|
||||
// the constructor takes in a pointer to the character map, the name
|
||||
// of the file that hold the locale definiton, the name of the locale
|
||||
// being created, and the value of mb_cur_max specified in the
|
||||
// charmap file
|
||||
Def(const char* filename,
|
||||
const char* out_name,
|
||||
Charmap& charmap, bool no_position);
|
||||
|
||||
// free up all the dynamically allocated memory
|
||||
~Def ();
|
||||
|
||||
// start point for processing the input files
|
||||
void process_input ();
|
||||
|
||||
// write the LC_CTYPE file to the specified directory
|
||||
void write_ctype(std::string dir_name);
|
||||
|
||||
void write_codecvt(std::string dir_name);
|
||||
|
||||
// write the LC_NUMERIC file to the specified directory
|
||||
void write_numeric(std::string dir_name);
|
||||
|
||||
// write the LC_MONETARY file to the specified directory
|
||||
void write_monetary(std::string dir_name);
|
||||
|
||||
// write the LC_TIME file to the specified directory
|
||||
void write_time(std::string dir_name);
|
||||
|
||||
// write the LC_MESSAGES file to the specified directory
|
||||
void write_messages(std::string dir_name);
|
||||
|
||||
// write the LC_COLLATE file to the specified directory
|
||||
void write_collate(std::string dir_name);
|
||||
|
||||
// dump the collate information
|
||||
void dump_collate ();
|
||||
|
||||
// have warnings occurred
|
||||
bool warnings_occurred_;
|
||||
|
||||
// was the content of the locale definition file scanned ahead
|
||||
bool scan_ahead_;
|
||||
|
||||
typedef Scanner::token_t token_t;
|
||||
typedef std::pair<token_t,token_t> token_pair_t;
|
||||
typedef std::list<token_t> token_list_t;
|
||||
typedef std::pair<token_t,token_list_t> collate_entry_t;
|
||||
typedef std::pair<token_t,token_list_t> collate_elem_t;
|
||||
typedef std::list<collate_entry_t> collate_entry_list_t;
|
||||
struct collate_section_t;
|
||||
|
||||
struct collate_section_t {
|
||||
std::string name;
|
||||
token_list_t order;
|
||||
collate_entry_list_t entries;
|
||||
};
|
||||
|
||||
private:
|
||||
struct ce_info_t;
|
||||
struct collate_info_t;
|
||||
friend struct ce_info_t;
|
||||
friend struct collate_info_t;
|
||||
|
||||
// a struct used to represent the weights for each collating element
|
||||
struct Weights_t {
|
||||
unsigned char size;
|
||||
unsigned int weight[256];
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// collate preprocessing information
|
||||
|
||||
token_list_t script_list_;
|
||||
token_list_t cs_list_;
|
||||
token_list_t sym_list_;
|
||||
std::list<collate_elem_t> ce_list_;
|
||||
std::list<collate_section_t> section_list_;
|
||||
|
||||
// preprocessing for collate section
|
||||
void preprocess_collate ();
|
||||
void preprocess_order ();
|
||||
void preprocess_reorder ();
|
||||
void preprocess_reorder_section ();
|
||||
void preprocess_collation_definitions();
|
||||
|
||||
void process_collation_definition ( bool, collate_entry_t&,
|
||||
unsigned int, unsigned int);
|
||||
unsigned int process_order_stmt (collate_section_t&);
|
||||
|
||||
bool insert_entries (token_t&, collate_entry_list_t&);
|
||||
void remove_entry (collate_entry_t&);
|
||||
void list_collate ();
|
||||
|
||||
// automatically fill any ctype categories that depend upon characters
|
||||
// being defined in other categories
|
||||
void auto_fill ();
|
||||
|
||||
// copy a category from one locale into the current locale
|
||||
void copy_category(int cat, std::string name);
|
||||
|
||||
// copy a file
|
||||
void copy_file(const std::string &name, const std::string &outname);
|
||||
|
||||
// process absolute ellipsis
|
||||
std::size_t process_abs_ellipsis (const Scanner::token_t&,
|
||||
std::ctype_base::mask);
|
||||
|
||||
// process hexadecimal symbolic ellipsis, decimal symbolic ellipsis,
|
||||
// and double increment hexadecimal symbolic ellipsis
|
||||
std::size_t process_sym_ellipsis (const std::string&,
|
||||
const std::string&,
|
||||
Scanner::token_id,
|
||||
std::ctype_base::mask);
|
||||
|
||||
// parse the era string
|
||||
void parse_era (const token_t&);
|
||||
|
||||
// process the ctype category specified by m with the exception of
|
||||
// (e.g. std::ctype_base::upper)
|
||||
void process_mask (std::ctype_base::mask, const char*);
|
||||
|
||||
// process the ctype toupper and tolower definitions
|
||||
void process_upper_lower(Scanner::token_id tok);
|
||||
|
||||
// process the ctype section of the locale definition file
|
||||
void process_ctype();
|
||||
|
||||
// process transliteration information
|
||||
void process_xlit ();
|
||||
|
||||
void process_xlit_statement (std::size_t&);
|
||||
|
||||
// process the collate section of the locale definition file
|
||||
void process_collate ();
|
||||
|
||||
// processing of collating definition statements
|
||||
void process_collate_definition (bool, collate_entry_t&,
|
||||
unsigned int&, unsigned int);
|
||||
|
||||
// helper function for process_collate() that processes the collition
|
||||
// order of the collating elements
|
||||
void process_order (collate_section_t&, unsigned int&);
|
||||
|
||||
// helper function for process_order() that processes the sequence
|
||||
// of weights for each collating element
|
||||
void process_weights(collate_entry_t&);
|
||||
|
||||
// get the next weight
|
||||
bool get_weight (token_t&, Weights_t*, int);
|
||||
|
||||
// add a symbolic name to the collition array
|
||||
void add_to_coll (const wchar_t val,
|
||||
const Weights_t* weight_template,
|
||||
const unsigned int coll_value,
|
||||
const std::vector<bool>& ordinal_weights,
|
||||
bool undefined_value);
|
||||
|
||||
// add missing values when the UNDEFINED keyword is found or at the
|
||||
// end of the collition array if UNDEFINED is not found
|
||||
void add_missing_values (const std::vector<bool> &ordinal_weights,
|
||||
const Weights_t* weights_template,
|
||||
unsigned int &coll_value, bool give_warning);
|
||||
|
||||
// process the monetary section of the locale definition file
|
||||
void process_monetary();
|
||||
|
||||
// create the monetary formats
|
||||
void create_format (char [4], char, char, char, bool);
|
||||
|
||||
// process the numeric section of the locale definition file
|
||||
void process_numeric();
|
||||
|
||||
// extracts and converts an array of strings such as those
|
||||
// representing the names of weekdays in the LC_TIME section
|
||||
Scanner::token_t
|
||||
extract_string_array (std::string*, std::wstring*, std::size_t);
|
||||
|
||||
|
||||
// process the time section of the locale definition file
|
||||
void process_time();
|
||||
|
||||
// process the messages section of the locale definition file
|
||||
void process_messages();
|
||||
|
||||
std::string convert_string (const std::string&);
|
||||
std::wstring convert_wstring (const token_t&);
|
||||
std::wstring convert_wstring (const std::vector<std::string>&);
|
||||
|
||||
void strip_pair(const std::string&, std::string&, std::string&);
|
||||
|
||||
// encode a wchar_t into utf8 encoding
|
||||
std::string utf8_encode (wchar_t ch);
|
||||
|
||||
// convert a utf8 encoded string to the encoding for this locale
|
||||
std::string convert_to_ext (wchar_t val);
|
||||
|
||||
bool get_n_val (const Scanner::token_t&, unsigned char &val);
|
||||
bool get_w_val (const Scanner::token_t&, wchar_t &val);
|
||||
|
||||
// initialize the coll_map with all the characters in the codeset
|
||||
void init_coll_map();
|
||||
|
||||
void gen_n_to_w_coll_tables (const std::string &charp,
|
||||
unsigned int tab_num);
|
||||
|
||||
void gen_w_to_n_coll_tables (const std::string &charp,
|
||||
unsigned int tab_num);
|
||||
|
||||
// the next useable offset for collating elements greater then UCHAR_MAX
|
||||
unsigned int next_offset_;
|
||||
|
||||
Scanner::token_t next;
|
||||
|
||||
// the name of the locale we are creating
|
||||
std::string output_name_;
|
||||
|
||||
// the charmap used to process the character map definition file
|
||||
Charmap& charmap_;
|
||||
|
||||
// the scanner used to process the locale definition file
|
||||
Scanner scanner_;
|
||||
|
||||
bool ctype_symlink_;
|
||||
std::string ctype_filename_;
|
||||
|
||||
|
||||
// maps characters to a mask value
|
||||
std::map<wchar_t, unsigned int> mask_;
|
||||
|
||||
// maps characters to their lower case representation
|
||||
std::map<wchar_t, wchar_t> lower_;
|
||||
|
||||
// maps characters to their upper case representation
|
||||
std::map<wchar_t, wchar_t> upper_;
|
||||
|
||||
typedef std::map<std::string, unsigned int>::iterator mb_char_off_map_iter;
|
||||
|
||||
struct codecvt_offset_tab_t {
|
||||
unsigned int off [UCHAR_MAX + 1];
|
||||
};
|
||||
|
||||
void create_wchar_utf8_table ();
|
||||
std::map<std::string, std::string> wchar_utf8_to_ext_;
|
||||
typedef std::map<std::string, std::string>::iterator wchar_utf8_iter;
|
||||
|
||||
void gen_valid_coll_wchar_set ();
|
||||
|
||||
std::set<std::string> valid_coll_wchar_set_;
|
||||
typedef std::set<std::string>::iterator valid_coll_wchar_set_iter;
|
||||
std::set<std::string> valid_codecvt_wchar_set_;
|
||||
typedef std::set<std::string>::iterator valid_codecvt_wchar_set_iter;
|
||||
|
||||
typedef std::map<unsigned, const codecvt_offset_tab_t*>
|
||||
codecvt_offsets_map_t;
|
||||
|
||||
// generates conversion tables of all valid multibyte characters
|
||||
// from a multibyte character map populated from the character
|
||||
// set description file
|
||||
std::size_t
|
||||
gen_mbchar_tables (codecvt_offsets_map_t&,
|
||||
std::map<std::string, unsigned>&,
|
||||
const std::string& = "",
|
||||
unsigned = 0);
|
||||
|
||||
std::size_t
|
||||
gen_wchar_tables (codecvt_offsets_map_t&,
|
||||
const std::string& = "",
|
||||
unsigned = 0);
|
||||
|
||||
std::size_t
|
||||
gen_utf8_tables (codecvt_offsets_map_t&,
|
||||
std::map<std::string, unsigned>&,
|
||||
const std::string& = "",
|
||||
unsigned = 0);
|
||||
|
||||
std::set<std::string> valid_coll_mb_set_;
|
||||
|
||||
void gen_valid_coll_mb_set();
|
||||
|
||||
// generation of transliteration tables
|
||||
void gen_xlit_data ();
|
||||
|
||||
// specifies if the locale file has already been written such as when
|
||||
// the "copy" directive is used in a locale definition file
|
||||
bool ctype_written_, codecvt_written_, collate_written_, time_written_,
|
||||
num_written_, mon_written_, messages_written_;
|
||||
bool ctype_def_found_, collate_def_found_,
|
||||
time_def_found_, num_def_found_, mon_def_found_, messages_def_found_;
|
||||
|
||||
// specifies if the keyword UNDEFINED is used in the LC_COLLATE definition
|
||||
bool undefined_keyword_found_;
|
||||
|
||||
// no_position_ is set by the "--no_position" command line option
|
||||
// when true forward,postion orders will be treated like forward orders
|
||||
bool no_position_;
|
||||
|
||||
// collate maps
|
||||
|
||||
struct offset_tab_t {
|
||||
int first_offset;
|
||||
unsigned int off[UCHAR_MAX + 1];
|
||||
};
|
||||
|
||||
std::map<unsigned int, offset_tab_t> char_offs_;
|
||||
typedef std::map<unsigned int, offset_tab_t>::iterator char_offs_iter;
|
||||
|
||||
std::map<unsigned int, offset_tab_t> w_to_n_coll_;
|
||||
typedef std::map<unsigned int, offset_tab_t>::iterator w_to_n_coll_iter;
|
||||
|
||||
unsigned int next_tab_num_;
|
||||
unsigned int next_wchar_coll_tab_num_;
|
||||
|
||||
|
||||
struct ce_offset_tab_t {
|
||||
int first_offset;
|
||||
int last_offset;
|
||||
unsigned int off[UCHAR_MAX + 1];
|
||||
};
|
||||
std::map<unsigned int, ce_offset_tab_t> n_ce_offs_;
|
||||
typedef std::map<unsigned int, ce_offset_tab_t>::iterator n_ce_offs_iter;
|
||||
|
||||
std::map<unsigned int, ce_offset_tab_t> w_ce_offs_;
|
||||
typedef std::map<unsigned int, ce_offset_tab_t>::iterator w_ce_offs_iter;
|
||||
|
||||
std::set<std::string> valid_n_ce_set;
|
||||
typedef std::set<std::string>::iterator valid_n_ce_set_iter;
|
||||
|
||||
void gen_n_ce_tables (const std::set<std::string>,
|
||||
unsigned int, unsigned int);
|
||||
unsigned int next_n_ce_tab_num_;
|
||||
void gen_w_ce_tables (const std::set<std::string>,
|
||||
unsigned int, unsigned int);
|
||||
unsigned int next_w_ce_tab_num_;
|
||||
|
||||
std::map<std::string, std::string>ce_sym_map_;
|
||||
std::map<std::string, std::string>ce_wsym_map_;
|
||||
typedef std::map<std::string, std::string>::iterator ce_sym_map_iter;
|
||||
// off_mapr maps an offset value to the symbol name or collating element
|
||||
std::map<unsigned int, std::string> off_mapr_;
|
||||
|
||||
// cs_map_ maps a collating symbol name to a collation value
|
||||
std::map<std::string, unsigned int> cs_map_;
|
||||
typedef std::map<std::string, unsigned int>::iterator cs_map_iter;
|
||||
|
||||
// transliteration information
|
||||
struct xlit_offset_table {
|
||||
unsigned int offset_table [UCHAR_MAX + 1];
|
||||
};
|
||||
typedef struct xlit_offset_table xlit_offset_table_t;
|
||||
typedef std::map<wchar_t,std::list<std::string> > xlit_map_t;
|
||||
typedef std::map<wchar_t, unsigned int> xlit_data_offset_map_t;
|
||||
typedef std::map<unsigned int,xlit_offset_table_t> xlit_table_map_t;
|
||||
xlit_map_t xlit_map_;
|
||||
xlit_data_offset_map_t xlit_data_offset_map_;
|
||||
xlit_table_map_t xlit_table_map_;
|
||||
|
||||
// the collate_info_t struct contains information concerning the collation
|
||||
// of each character
|
||||
struct collate_info_t{
|
||||
unsigned int offset;
|
||||
unsigned int coll_val;
|
||||
unsigned int order;
|
||||
Weights_t *weights;
|
||||
};
|
||||
|
||||
// we need one collate_info_t to hold information about the undefined
|
||||
// characters. All the other characters have collate_info_ts that are
|
||||
// located in the coll_map.
|
||||
collate_info_t undef_char_info_;
|
||||
|
||||
// the ce_info_t strurct contains information concerning the collation
|
||||
// of a collating element.
|
||||
|
||||
struct ce_info_t {
|
||||
unsigned int offset;
|
||||
unsigned int coll_val;
|
||||
unsigned int order;
|
||||
Weights_t *weights;
|
||||
std::wstring ce_wstr;
|
||||
};
|
||||
|
||||
// The coll_map_ contains a mapping from the wide char value to the
|
||||
// collition information about that value.
|
||||
std::map<wchar_t, collate_info_t> coll_map_;
|
||||
typedef std::map<wchar_t, collate_info_t>::iterator coll_map_iter;
|
||||
|
||||
// the ce_map_ contains a mapping from the symbolic collating element
|
||||
// name to the collition information about that element
|
||||
std::map <std::string, ce_info_t> ce_map_;
|
||||
typedef std::map <std::string, ce_info_t>::iterator ce_map_iter;
|
||||
|
||||
// iterator type definitions for the maps
|
||||
typedef std::map<wchar_t, unsigned int>::iterator mask_iter;
|
||||
typedef std::map<wchar_t, wchar_t>::iterator upper_iter;
|
||||
typedef std::map<wchar_t, wchar_t>::iterator lower_iter;
|
||||
typedef std::map< std::string, unsigned char >::const_iterator n_cmap_iter;
|
||||
typedef std::map<std::string, wchar_t>::const_iterator mb_cmap_iter;
|
||||
typedef std::map<wchar_t, std::string>::const_iterator rmb_cmap_iter;
|
||||
typedef std::map<std::string, wchar_t >::const_iterator w_cmap_iter;
|
||||
typedef std::map<wchar_t, std::string >::const_iterator rw_cmap_iter;
|
||||
typedef std::map<unsigned int, std::string>::iterator off_mapr_iter;
|
||||
typedef std::map<std::string, wchar_t>::const_iterator ucs4_cmap_iter;
|
||||
|
||||
typedef std::list<std::string>::const_iterator symnames_list_iter;
|
||||
|
||||
// the structures used to hold the offsets for each locale category
|
||||
// and any non-pointer locale information
|
||||
_RW::__rw_punct_t num_punct_out_;
|
||||
_RW::__rw_ctype_t ctype_out_;
|
||||
_RW::__rw_time_t time_out_;
|
||||
_RW::__rw_collate_t collate_out_;
|
||||
_RW::__rw_mon_t mon_out_;
|
||||
_RW::__rw_num_t num_out_;
|
||||
_RW::__rw_messages_t messages_out_;
|
||||
|
||||
// structures used for internally holding locale information
|
||||
// LC_CTYPE structures
|
||||
|
||||
|
||||
struct ctype_t {
|
||||
struct mask_elm {
|
||||
wchar_t ch; // the wide character value
|
||||
unsigned int mask; // the mask for that character
|
||||
};
|
||||
struct upper_elm {
|
||||
wchar_t lower; // the lower case wide character
|
||||
wchar_t upper; // the upper case wide character
|
||||
};
|
||||
struct lower_elm {
|
||||
wchar_t upper; // the upper case wide character
|
||||
wchar_t lower; // the lower case wide character
|
||||
};
|
||||
|
||||
char max_mb_s; // the max number of bytes in a char
|
||||
upper_elm* wtoupper_tab; // the wide char to_upper table
|
||||
lower_elm* wtolower_tab; // the wide char to_lower table
|
||||
mask_elm* wmask_tab; // the wide char mask_table
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct era_st {
|
||||
std::string name;
|
||||
std::string fmt;
|
||||
std::wstring wname;
|
||||
std::wstring wfmt;
|
||||
_RW::__rw_time_t::era_t era_out;
|
||||
};
|
||||
|
||||
std::list<era_st> era_list_;
|
||||
typedef std::list<era_st>::iterator era_list_iter;
|
||||
|
||||
// LC_COLLATE structure
|
||||
struct collate_t {
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
// LC_MONETARY structure
|
||||
struct mon_t {
|
||||
std::string int_curr_symbol; // narrow char* int_curr_symbol
|
||||
std::string currency_symbol; // narrow char* currency_symbol
|
||||
std::string mon_decimal_point; // narrow char* mon_decimal_point
|
||||
std::string mon_thousands_sep; // narrow char* mon_thoucands_sep
|
||||
std::string mon_grouping; // narrow char* mon_grouping
|
||||
std::string positive_sign; // narrow char* positive_sign
|
||||
std::string negative_sign; // narrow char* negative_sign
|
||||
std::wstring wint_curr_symbol; // wide wchar_t* int_curr_symbol
|
||||
std::wstring wcurrency_symbol; // wide wchar_t* currency_symbol
|
||||
std::wstring wmon_decimal_point; // wide wchar_t* mon_decimal_point
|
||||
std::wstring wmon_thousands_sep; // wide wchar_t* mon_thousands_sep
|
||||
std::wstring wpositive_sign; // wide wchar_t* positive_sign
|
||||
std::wstring wnegative_sign; // wide wchar_t* negative_sign
|
||||
};
|
||||
|
||||
|
||||
|
||||
// LC_NUMERIC structure
|
||||
struct num_t {
|
||||
std::string decimal_point; // narrow char* decimal_point
|
||||
std::string thousands_sep; // narrow char* thousands_sep
|
||||
std::string grouping; // narrow char* grouping
|
||||
std::string truename; // narrow char* truename
|
||||
std::string falsename; // narrow char* falsename
|
||||
|
||||
std::wstring wdecimal_point; // wide wchar_t* decimal_point
|
||||
std::wstring wthousands_sep; // wide wchar_t* thousands_sep
|
||||
std::wstring wtruename; // wide wchar_t* truename
|
||||
std::wstring wfalsename; // wide wchar_t* falsename
|
||||
};
|
||||
|
||||
// list to hold the alternate digits
|
||||
struct alt_digit_t {
|
||||
std::string n_alt_digit;
|
||||
std::wstring w_alt_digit;
|
||||
unsigned int n_offset;
|
||||
unsigned int w_offset;
|
||||
};
|
||||
std::list<alt_digit_t> alt_digits_;
|
||||
typedef std::list<alt_digit_t>::iterator alt_digits_iter;
|
||||
|
||||
// LC_TIME structure
|
||||
struct time_t {
|
||||
std::string abday[7]; // narrow array of abbreviated days
|
||||
std::string day[7]; // narrow array of days
|
||||
std::string abmon[12]; // narrow array of abbreviated months
|
||||
std::string mon[12]; // narrow array of months
|
||||
std::string am_pm[2]; // narrow array of am/pm specifiers
|
||||
std::string d_t_fmt; // narrow date and time format string
|
||||
std::string d_fmt; // narrow date format string
|
||||
std::string t_fmt; // narrow time format string
|
||||
std::string t_fmt_ampm; // narrow time format string with am/pm
|
||||
std::string era_d_t_fmt; // narrow era date and time format string
|
||||
std::string era_d_fmt; // narrow era date format string
|
||||
std::string era_t_fmt; // narrow era time format string
|
||||
|
||||
|
||||
|
||||
std::wstring wabday[7]; // wide array of abbreviated days
|
||||
std::wstring wday[7]; // wide array of days
|
||||
std::wstring wabmon[12]; // wide array of abbreviated months
|
||||
std::wstring wmon[12]; // wide array of months
|
||||
std::wstring wam_pm[2]; // wide array of am/pm specifiers
|
||||
std::wstring wd_t_fmt; // wide date and time format string
|
||||
std::wstring wd_fmt; // wide date format string
|
||||
std::wstring wt_fmt; // wide time format string
|
||||
std::wstring wt_fmt_ampm; // wide time format string with am/pm
|
||||
std::wstring wera_d_t_fmt; // wide era date and time format string
|
||||
std::wstring wera_d_fmt; // wide era date format string
|
||||
std::wstring wera_t_fmt; // wide era time format string
|
||||
} ;
|
||||
|
||||
// LC_MESSAGES structure
|
||||
struct messages_t {
|
||||
std::string yesexpr;
|
||||
std::string noexpr;
|
||||
|
||||
std::wstring wyesexpr;
|
||||
std::wstring wnoexpr;
|
||||
};
|
||||
|
||||
messages_t messages_st_;
|
||||
time_t time_st_;
|
||||
ctype_t ctype_st_;
|
||||
mon_t mon_st_;
|
||||
num_t num_st_;
|
||||
collate_t collate_st_;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline std::string strip_quotes (const std::string& str)
|
||||
{
|
||||
assert (0 != str.size ());
|
||||
assert (str [0] == '\"');
|
||||
|
||||
// return a string from str[1] to the position of the end-quote
|
||||
return std::string (str, 1, str.rfind ('\"') - 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // RWSTD_UTIL_DEF_H_INCLUDED
|
||||
160
extern/stdcxx/4.2.1/util/diagnostic.cpp
vendored
Normal file
160
extern/stdcxx/4.2.1/util/diagnostic.cpp
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* diagnostic.cpp
|
||||
*
|
||||
* $Id: diagnostic.cpp 448754 2006-09-22 00:42:16Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "diagnostic.h"
|
||||
#include "scanner.h" // for Scanner::token_t
|
||||
#include "loc_exception.h"
|
||||
|
||||
#include <cstdarg> // for va_list, ...
|
||||
#include <cstdio> // for puts(), fprintf(), ...
|
||||
#include <set> // for set
|
||||
|
||||
|
||||
// set of disabled warnings
|
||||
static std::set<int> disabled;
|
||||
|
||||
static bool warn = true; // warnings (on by default)
|
||||
static bool info = false; // info messages (off by default)
|
||||
|
||||
|
||||
// write a warning or error message to standard output. If it is a warning
|
||||
// that is issued and that warning has not been disabled then return true.
|
||||
bool issue_diag (int type, bool, const Scanner::token_t *token,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
bool enabled = false;
|
||||
|
||||
if (0 == fmt) {
|
||||
|
||||
// special treatment when format string is 0: a request
|
||||
// to enable or disable this type of diagnostic, e.g.,
|
||||
// in response to a command line option
|
||||
|
||||
if (W_DISABLE == type) {
|
||||
// disable all warnings
|
||||
enabled = warn;
|
||||
warn = false;
|
||||
}
|
||||
else if (I_ENABLE == type) {
|
||||
// enable all informational messages
|
||||
enabled = info;
|
||||
info = true;
|
||||
}
|
||||
else {
|
||||
// disable a specific warning and return its previous
|
||||
// setting (i.e., enabled or disabled)
|
||||
enabled = disabled.find (type) == disabled.end ();
|
||||
disabled.insert (type);
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
const bool is_info = I_FIRST <= type && type <= I_LAST;
|
||||
const bool is_warn = !is_info && W_FIRST <= type && type <= W_LAST;
|
||||
const bool is_error = !is_info && !is_warn;
|
||||
|
||||
if (is_warn && (!warn || disabled.end () != disabled.find (type))) {
|
||||
// warning disabled
|
||||
return enabled;
|
||||
}
|
||||
|
||||
if (is_info && !info) {
|
||||
// info disabled
|
||||
return enabled;
|
||||
}
|
||||
|
||||
// all errors and those warnings that are not disabled
|
||||
// must be issued
|
||||
enabled = true;
|
||||
|
||||
if (token && token->file)
|
||||
std::fprintf (stderr, "%s:%d: ", token->file, token->line);
|
||||
|
||||
if (is_error)
|
||||
std::fprintf (stderr, "Error %-3d: ", type);
|
||||
else if (is_warn)
|
||||
std::fprintf (stderr, "Warning %-3d: ", type);
|
||||
else
|
||||
std::fprintf (stderr, "Note %-3d: ", type);
|
||||
|
||||
// get the variable sized argument and pass it to vfprintf
|
||||
// to be printed
|
||||
std::va_list va;
|
||||
va_start (va, fmt);
|
||||
std::vfprintf (stderr, fmt, va);
|
||||
va_end (va);
|
||||
|
||||
// if the token pointer is non-zero, find the file and line
|
||||
// the token appears on and print it out, followed by a line
|
||||
// underscoring the token that caused the diagnostic with
|
||||
// a string of carets ('^')
|
||||
|
||||
std::FILE* const ftok = token ? std::fopen (token->file, "r") : 0;
|
||||
|
||||
if (ftok) {
|
||||
int i;
|
||||
char line [1024]; // FIXME: handle longer lines
|
||||
|
||||
// advance to the specified line in the file
|
||||
for (i = 0; i < token->line; ++i) {
|
||||
if (0 == std::fgets (line, 1024, ftok)) {
|
||||
*line = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == token->line && '\0' != *line) {
|
||||
std::fputs ("\t\t", stderr);
|
||||
std::fputs (line, stderr);
|
||||
std::fputs ("\t\t", stderr);
|
||||
|
||||
// tok->col is the column number where the first character
|
||||
// in the token begins. Go through the line saving tabs
|
||||
// so that the '^' will line up with the token
|
||||
|
||||
for (i = 0; i < token->column; ++i)
|
||||
std::fputc (line [i] == '\t' ? '\t' : ' ', stderr);
|
||||
|
||||
for (unsigned j = 0; j < token->name.size (); ++j)
|
||||
std::fputc ('^', stderr);
|
||||
|
||||
std::fputc ('\n', stderr);
|
||||
}
|
||||
|
||||
std::fclose (ftok);
|
||||
}
|
||||
|
||||
if (is_error) {
|
||||
// throw an exception if the diagnostic is a hard error
|
||||
throw loc_exception ();
|
||||
}
|
||||
|
||||
// return otherwise (i.e., the diagnostic is not an error)
|
||||
return enabled;
|
||||
}
|
||||
95
extern/stdcxx/4.2.1/util/diagnostic.h
vendored
Normal file
95
extern/stdcxx/4.2.1/util/diagnostic.h
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* diagnostic.h
|
||||
*
|
||||
* $Id: diagnostic.h 448754 2006-09-22 00:42:16Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RWSTD_UTIL_DIAGNOSTIC_H_INCLUDED
|
||||
#define RWSTD_UTIL_DIAGNOSTIC_H_INCLUDED
|
||||
|
||||
#include "scanner.h" // for token_t
|
||||
|
||||
enum {
|
||||
E_FIRST = 100,
|
||||
E_SYMUSED = 101, // symbol used before defined
|
||||
E_OPENRD = 109, // opening a file for reading
|
||||
E_OPENWR = 110, // opening a file for writing
|
||||
E_PAIR = 111, // invalid pair of symbolic characters (<A>,<B>)
|
||||
E_COLNUM = 114, // bad number of collation orders
|
||||
E_CVT2EXT = 123, // convert a character to external representation
|
||||
E_SYMEND = 127, // unterminated symbolic name (missing '>')
|
||||
E_CVT = 136, // error converting a character
|
||||
E_IFMT = 135, // invalid integer format
|
||||
E_MBCHAR = 308, // illegal/incomplete multibyte character
|
||||
E_UCS = 315, // ill-formed or invalid UCS character
|
||||
E_MBTOWC = 310, // mbtowc() error
|
||||
E_RANGE = 311, // invalid range (ellipsis)
|
||||
E_SYNTAX = 312, // bad syntax
|
||||
E_COLORD = 133, // bad collating order
|
||||
E_REORD = 291, // bad reorder-after
|
||||
E_INVAL = 399, // invalid value
|
||||
E_CMDARG = 401, // invalid command line argument
|
||||
E_XARG = 402, // extra command line argument
|
||||
E_NOARG = 403, // missing command line argument
|
||||
E_OPTARG = 404, // missing argument to a command line option
|
||||
E_CALL = 405, // system or libc call failed
|
||||
E_NOTSUP = 712, // feature not supported (hard error)
|
||||
E_LAST = 699,
|
||||
|
||||
W_FIRST = 700,
|
||||
W_DISABLE = 700, // disable all warnings
|
||||
W_COMPAT = 701, // no compatible locale installed
|
||||
W_NOPCS = 702, // PCS character value not defined
|
||||
W_COLSYM = 703, // undefined collating symbol or collating element
|
||||
W_MISSING = 704, // missing value
|
||||
W_REORD = 705, // bad reorder-after
|
||||
W_ICONV = 706, // iconv_open() or iconv() error
|
||||
W_SYM = 707, // unknown symbolic constant
|
||||
W_CHAR = 708, // unknown character (no corresponding symbol)
|
||||
W_CHARMAP = 709, // unknown charmap
|
||||
W_SYNTAX = 709, // recoverable syntax error
|
||||
W_RANGE = 710, // recoverable invalid range
|
||||
W_INVAL = 711, // recoverable invalid value
|
||||
W_CALL = 712, // system or libc call failed
|
||||
W_NOTSUP = 713, // feature not supported (will be ignored)
|
||||
W_LAST = 799,
|
||||
|
||||
I_FIRST = 800,
|
||||
I_ENABLE = 800, // enable all informational messages
|
||||
I_STAGE = 801, // information about stages of processing
|
||||
I_OPENRD = 802, // information about files being opened for reading
|
||||
I_OPENWR = 803, // information about files being opened for writing
|
||||
I_READ = 804, // information about data reads
|
||||
I_WRITE = 805, // information about data writes
|
||||
I_SKIP = 806, // information about skpping an operation
|
||||
I_LAST = 899
|
||||
};
|
||||
|
||||
|
||||
bool issue_diag (int id, bool is_error,
|
||||
const Scanner::token_t* token,
|
||||
const char *fmt, ...);
|
||||
|
||||
#endif // RWSTD_UTIL_DIAGNOSTIC_H_INCLUDED
|
||||
366
extern/stdcxx/4.2.1/util/display.cpp
vendored
Normal file
366
extern/stdcxx/4.2.1/util/display.cpp
vendored
Normal file
@@ -0,0 +1,366 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* display.cpp - Definitions of the result display subsystem
|
||||
*
|
||||
* $Id: display.cpp 648752 2008-04-16 17:01:56Z faridz $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h> /* for fflush(), printf(), puts(), ... */
|
||||
#include <string.h> /* for strchr() */
|
||||
|
||||
#include "cmdopt.h" /* for target_name -should this be moved? */
|
||||
#include "exec.h" /* for get_signame */
|
||||
|
||||
#include "display.h"
|
||||
#include "target.h" /* for target_status */
|
||||
|
||||
|
||||
/**
|
||||
ProcessStatus enum lookup table for 'short' (6 character) strings.
|
||||
*/
|
||||
static const char* const
|
||||
short_st_name [ST_LAST] = {
|
||||
"OK", /*ST_OK*/
|
||||
"COMP", /*ST_COMPILE*/
|
||||
"LINK", /*ST_LINK*/
|
||||
"EXIST", /*ST_EXIST*/
|
||||
"XPERM", /*ST_EXECUTE_FLAG*/
|
||||
"EXEC", /*ST_EXECUTE*/
|
||||
"NOUT", /*ST_NO_OUTPUT*/
|
||||
"OUTPUT", /*ST_NO_REF*/
|
||||
"BREF", /*ST_BAD_REF*/
|
||||
"DIFF", /*ST_BAD_OUTPUT*/
|
||||
"FORMAT", /*ST_FORMAT*/
|
||||
"OFLOW", /*ST_OVERFLOW*/
|
||||
"ERROR", /*ST_SYSTEM_ERROR*/
|
||||
"KILLED", /*ST_KILLED*/
|
||||
"NKILL" /*ST_NOT_KILLED*/
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
ProcessStatus enum lookup table for descriptive strings.
|
||||
*/
|
||||
static const char* const
|
||||
verbose_st_name [ST_LAST] = {
|
||||
"OK", /*ST_OK*/
|
||||
"Program failed to compile.", /*ST_COMPILE*/
|
||||
"Program failed to link.", /*ST_LINK*/
|
||||
"Program executable not found.", /*ST_EXIST*/
|
||||
"Program not executable.", /*ST_EXECUTE_FLAG*/
|
||||
"Program failed to execute.", /*ST_EXECUTE*/
|
||||
"Program generated no output.", /*ST_NO_OUTPUT*/
|
||||
"Program reference output missing.", /*ST_NO_REF*/
|
||||
"Bad reference.", /*ST_BAD_REF*/
|
||||
"Program produced unexpected output.", /*ST_BAD_OUTPUT*/
|
||||
"Program produced output in unexpected format.", /*ST_FORMAT*/
|
||||
"Arithmetic overflow.", /*ST_OVERFLOW*/
|
||||
"System error occurred.", /*ST_SYSTEM_ERROR*/
|
||||
"Process killed after a timeout.", /*ST_KILLED*/
|
||||
"Failed to kill process after a timeout." /*ST_NOT_KILLED*/
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Prints an argv array, quoting elelemnts containing spaces.
|
||||
*/
|
||||
static int
|
||||
print_argv (const char* const argv[], int newline)
|
||||
{
|
||||
assert (0 != argv);
|
||||
|
||||
const char* const* parg = argv;
|
||||
|
||||
int nchars = 0;
|
||||
|
||||
for (parg = argv; *parg; ++parg) {
|
||||
|
||||
const char *fmt = "%s ";
|
||||
|
||||
if (strchr (*parg, ' '))
|
||||
fmt = "\"%s\" ";
|
||||
|
||||
nchars += printf (fmt, *parg);
|
||||
}
|
||||
|
||||
if (newline)
|
||||
puts ("");
|
||||
|
||||
return nchars;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Generates output header, designed for text output and console viewing.
|
||||
*/
|
||||
static void
|
||||
print_header_plain (const char* const argv[])
|
||||
{
|
||||
(void)&argv;
|
||||
|
||||
puts ("NAME STATUS WARN ASSERTS "
|
||||
"FAILED PERCNT USER SYS REAL");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Generates output header in verbose mode.
|
||||
*/
|
||||
static void
|
||||
print_header_verbose (const char* const argv[])
|
||||
{
|
||||
print_argv (argv, 1 /* append newline */);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Generates target name listing, designed for text output and console viewing.
|
||||
*/
|
||||
static void
|
||||
print_target_plain (const struct target_opts *defaults)
|
||||
{
|
||||
const char* const target_name = get_target ();
|
||||
|
||||
assert (0 == defaults->verbose);
|
||||
|
||||
printf ("%-40.40s ", target_name);
|
||||
|
||||
/* flush to prevent killing a signal from not displaying the text */
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Generates target name listing, designed for text output and console viewing.
|
||||
*/
|
||||
static void
|
||||
print_target_verbose (const struct target_opts *defaults)
|
||||
{
|
||||
assert (defaults->verbose);
|
||||
|
||||
printf ("%s ", "Executing \"");
|
||||
print_argv (defaults->argv, 0 /* no newline */);
|
||||
|
||||
/* print stdin, stdout, and stderr redirections */
|
||||
if (defaults->infname && *defaults->infname)
|
||||
printf (" <%s", defaults->infname);
|
||||
|
||||
if (defaults->outfname && *defaults->outfname)
|
||||
printf (" >%s 2>&1", defaults->outfname);
|
||||
|
||||
puts ("\"");
|
||||
|
||||
/* flush to prevent killing a signal from not displaying the text */
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Generates target result listing, designed for text output and console
|
||||
viewing.
|
||||
*/
|
||||
static void print_status_plain (const struct target_status* status)
|
||||
{
|
||||
unsigned valid_timing;
|
||||
assert (0 != status);
|
||||
assert (ST_OK <= status->status && ST_LAST > status->status);
|
||||
|
||||
valid_timing = status->usr_time != (clock_t)-1
|
||||
&& status->sys_time != (clock_t)-1
|
||||
&& ST_NOT_KILLED != status->status;
|
||||
|
||||
if (status->status) /* if status is set, print it */
|
||||
printf ("%6s", short_st_name [status->status]);
|
||||
else if (status->signaled) /* if exit signal is non-zero, print it */
|
||||
printf ("%6s", get_signame (status->exit));
|
||||
else if (status->exit) /* if exit code is non-zero, print it */
|
||||
printf ("%6d", status->exit);
|
||||
else
|
||||
printf (" 0");
|
||||
|
||||
printf (" %4u", status->c_warn + status->l_warn + status->t_warn);
|
||||
|
||||
/* Print assetions, if any registered */
|
||||
if ( (unsigned)-1 != status->assert
|
||||
&& 0 == status->status
|
||||
&& 0 == status->exit) {
|
||||
if (status->assert) {
|
||||
const int percnt = int ( 100.0
|
||||
* (status->assert - status->failed)
|
||||
/ status->assert);
|
||||
printf (" %7u %6u %5d%%", status->assert, status->failed, percnt);
|
||||
}
|
||||
else {
|
||||
printf (" 0 %6u 100%%", status->failed);
|
||||
}
|
||||
}
|
||||
else if (valid_timing || status->wall_time != (clock_t)-1)
|
||||
printf (" ");
|
||||
|
||||
/* Print timings, if available */
|
||||
if (valid_timing)
|
||||
printf (" %7.3f %7.3f", (float)status->usr_time / TICKS_PER_SEC,
|
||||
(float)status->sys_time / TICKS_PER_SEC);
|
||||
else if (status->wall_time != (clock_t)-1)
|
||||
printf (" ");
|
||||
|
||||
if (status->wall_time != (clock_t)-1)
|
||||
printf (" %7.3f\n", (float)status->wall_time / TICKS_PER_SEC);
|
||||
else
|
||||
puts ("");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Generates verbose target result listing.
|
||||
*/
|
||||
static void
|
||||
print_status_verbose (const struct target_status* status)
|
||||
{
|
||||
unsigned valid_timing;
|
||||
|
||||
assert (0 != status);
|
||||
assert (ST_OK <= status->status && ST_LAST > status->status);
|
||||
|
||||
valid_timing = status->usr_time != (clock_t)-1
|
||||
&& status->sys_time != (clock_t)-1
|
||||
&& ST_NOT_KILLED != status->status;
|
||||
|
||||
if (status->status) /* if status is set, print it */
|
||||
printf (" Status: %s\n", verbose_st_name [status->status]);
|
||||
else if (status->signaled) /* if exit signal is non-zero, print it */
|
||||
printf (" Process signalled: %s\n", get_signame (status->exit));
|
||||
else {
|
||||
printf (" Exit status: %6d%s\n"
|
||||
" Compiler warnings: %6u\n"
|
||||
" Linker warnings: %6u\n"
|
||||
" Runtime warnings: %6u\n",
|
||||
status->exit, 0 == status->exit ? " (success)" : "",
|
||||
status->c_warn,
|
||||
status->l_warn,
|
||||
status->t_warn);
|
||||
|
||||
/* Print assetions, if any registered */
|
||||
if ((unsigned)-1 != status->assert && status->assert) {
|
||||
printf (" Failed assertions: %6u\n"
|
||||
" Total assertions: %6u\n",
|
||||
status->failed, status->assert);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print timings, if available */
|
||||
if (valid_timing) {
|
||||
const float wall = (float)status->wall_time / TICKS_PER_SEC;
|
||||
const float user = (float)status->usr_time / TICKS_PER_SEC;
|
||||
const float sys = (float)status->sys_time / TICKS_PER_SEC;
|
||||
|
||||
printf (" Times:\n"
|
||||
" Real %7.3fs\n"
|
||||
" User %7.3fs\n"
|
||||
" Sys %7.3fs\n",
|
||||
wall, user, sys);
|
||||
}
|
||||
|
||||
puts ("");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Placholder output footer function, unneeded for text output and console
|
||||
viewing.
|
||||
*/
|
||||
static void
|
||||
print_footer_plain (int count, const struct target_status *summary)
|
||||
{
|
||||
/* compute cumulative times for all targets */
|
||||
const float wall = (float)summary->wall_time / TICKS_PER_SEC;
|
||||
const float user = (float)summary->usr_time / TICKS_PER_SEC;
|
||||
const float sys = (float)summary->sys_time / TICKS_PER_SEC;
|
||||
|
||||
printf ("PROGRAM SUMMARY:\n"
|
||||
" Programs: %9d\n"
|
||||
" Non-zero exit status: %9d\n"
|
||||
" Signalled: %9d\n"
|
||||
" Compiler warnings: %9u\n"
|
||||
" Linker warnings: %9u\n"
|
||||
" Runtime warnings: %9u\n",
|
||||
count,
|
||||
summary->exit,
|
||||
summary->signaled,
|
||||
summary->c_warn,
|
||||
summary->l_warn,
|
||||
summary->t_warn);
|
||||
|
||||
if ((unsigned)-1 != summary->assert) {
|
||||
/* print assertion counters only when they're valid */
|
||||
printf (" Assertions: %9u\n"
|
||||
" Failed assertions: %9u\n",
|
||||
summary->assert,
|
||||
summary->failed);
|
||||
}
|
||||
|
||||
printf ( " Cumulative times:\n"
|
||||
" Real %7.3fs\n"
|
||||
" User %7.3fs\n"
|
||||
" Sys %7.3fs\n",
|
||||
wall,
|
||||
user,
|
||||
sys);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_footer_verbose (int count, const struct target_status *summary)
|
||||
{
|
||||
print_footer_plain (count, summary);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Sets the output functions referenced.
|
||||
*/
|
||||
void set_output_format (enum OutputFmt format)
|
||||
{
|
||||
if (FMT_VERBOSE == format) {
|
||||
print_header = print_header_verbose;
|
||||
print_target = print_target_verbose;
|
||||
print_status = print_status_verbose;
|
||||
print_footer = print_footer_verbose;
|
||||
}
|
||||
else {
|
||||
/* only two formats implemented */
|
||||
assert (FMT_PLAIN == format);
|
||||
|
||||
print_header = print_header_plain;
|
||||
print_target = print_target_plain;
|
||||
print_status = print_status_plain;
|
||||
print_footer = print_footer_plain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void (*print_header) (const char* const[]) = print_header_plain;
|
||||
void (*print_target) (const struct target_opts*) = print_target_plain;
|
||||
void (*print_status) (const struct target_status*) = print_status_plain;
|
||||
void (*print_footer) (int, const struct target_status*) = print_footer_plain;
|
||||
95
extern/stdcxx/4.2.1/util/display.h
vendored
Normal file
95
extern/stdcxx/4.2.1/util/display.h
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* display.h - Interface declaration for the result display subsystem
|
||||
*
|
||||
* $Id: display.h 580483 2007-09-28 20:55:52Z sebor $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RW_DISPLAY_H
|
||||
#define RW_DISPLAY_H
|
||||
|
||||
#include "target.h" /* For target_opts */
|
||||
|
||||
/**
|
||||
Output format mode enumeration.
|
||||
|
||||
Used to determine the mode used in producing output.
|
||||
*/
|
||||
enum OutputFmt {
|
||||
FMT_PLAIN = 0, /**< plain text output. */
|
||||
FMT_XTERM, /**< xterm colored output. */
|
||||
FMT_VERBOSE, /**< verbose text output. */
|
||||
FMT_INDEP, /**< Non-targeted formated output. */
|
||||
FMT_HTML /**< HTML formated output. */
|
||||
};
|
||||
|
||||
/**
|
||||
Sets the output functions referenced.
|
||||
*/
|
||||
void set_output_format (enum OutputFmt format);
|
||||
|
||||
/**
|
||||
Sets the column order and widths (if applicable) for output.
|
||||
|
||||
@param format custom format string for output.
|
||||
*/
|
||||
extern void (*set_header) (const char* format);
|
||||
|
||||
/**
|
||||
Prints the table preamble formatting, followed by the formatted header row.
|
||||
*/
|
||||
extern void (*print_header) (const char* const argv[]);
|
||||
|
||||
/**
|
||||
Prints the formatted header column for a target row.
|
||||
|
||||
This method uses the target_name global (defined in cmdopt.h), and flushes
|
||||
stdout after printing.
|
||||
|
||||
@see target_name
|
||||
*/
|
||||
extern void (*print_target) (const struct target_opts* options);
|
||||
|
||||
/**
|
||||
Updates the display of a (non-final) status indicator
|
||||
|
||||
This function is only useful for FMT_XTERM.
|
||||
|
||||
@param time 0 > time indicates -signal number, otherwise time remaining
|
||||
*/
|
||||
extern void (*set_progress) (int time);
|
||||
|
||||
/**
|
||||
Prints the formatted results for a target row.
|
||||
|
||||
@param status describes the results of the run
|
||||
*/
|
||||
extern void (*print_status) (const struct target_status* status);
|
||||
|
||||
|
||||
/**
|
||||
Prints the closing formatting for the table.
|
||||
*/
|
||||
extern void (*print_footer) (int count, const struct target_status* status);
|
||||
|
||||
|
||||
#endif /* RW_DISPLAY_H */
|
||||
1239
extern/stdcxx/4.2.1/util/exec.cpp
vendored
Normal file
1239
extern/stdcxx/4.2.1/util/exec.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
84
extern/stdcxx/4.2.1/util/exec.h
vendored
Normal file
84
extern/stdcxx/4.2.1/util/exec.h
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* exec.h - Interface declaration for the child process subsystem
|
||||
*
|
||||
* $Id: exec.h 452253 2006-10-02 23:08:06Z sebor $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RW_EXEC_H
|
||||
#define RW_EXEC_H
|
||||
|
||||
#include "target.h" /* For struct target_opts */
|
||||
|
||||
/**
|
||||
Translates a human understandable signal name into a number usable by kill ().
|
||||
|
||||
This method understands several formats for signal names. They are as follows:
|
||||
- n
|
||||
- SIGFOO
|
||||
- FOO
|
||||
In this list, n denotes a number and FOO denotes a short signal name.
|
||||
|
||||
@param signame a signal name to decode
|
||||
@returns the signal number or -1 if a number couldn't be determined
|
||||
@see signal_names []
|
||||
*/
|
||||
int get_signo (const char* signame);
|
||||
|
||||
/**
|
||||
Translates a signal number into a human understandable name
|
||||
|
||||
@param signo a signal number
|
||||
@returns the human understandable name for the signal (minus the SIG
|
||||
prefix), or "#n" if the the name for the number is unknown to the
|
||||
function, where n is signo
|
||||
@see signal_names []
|
||||
*/
|
||||
const char* get_signame (int signo);
|
||||
|
||||
/**
|
||||
Entry point to the child process (watchdog) subsystem.
|
||||
|
||||
On UNIX systems, this method fork ()s, creating a child process. This
|
||||
child process becomes a process group leader, redirects input and output
|
||||
files, then exec ()s the target specified in argv [0], providing it with
|
||||
argv to use as its argv array. Meanwhile, the parent process calls the
|
||||
wait_for_child method to monitor the child process, passing the return
|
||||
value back to the calling method.
|
||||
|
||||
On Windows, this method creates a process using the windows CreateProcess
|
||||
API call. The startup context for this process is based on the context of
|
||||
the exec utility, but with the standard * file handles redirected. The
|
||||
execution of the process is monitored with the WaitForSingleObject API
|
||||
call. If the process doesn't complete within the allowed timeout, it is
|
||||
then killed. On Windows NT systems, a soft kill of the process (via the
|
||||
GenerateConsoleCtrlEvent API call) are first attempted attempted. The
|
||||
process is then hard killed via the TerminateProcess API call.
|
||||
|
||||
@param exec_name name of the child executable
|
||||
@param argv argv array for child process
|
||||
@return structure describing how the child procees exited
|
||||
@see wait_for_child ()
|
||||
*/
|
||||
void exec_file (const struct target_opts* options, struct target_status* result);
|
||||
|
||||
#endif /* RW_EXEC_H */
|
||||
103
extern/stdcxx/4.2.1/util/gen_list
vendored
Normal file
103
extern/stdcxx/4.2.1/util/gen_list
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
ar_DZ.ara8.src arabic8.cm
|
||||
ar_DZ.utf8.src utf8.cm
|
||||
ar_SA.ara8.src arabic8.cm
|
||||
ar_SA.iso6.src iso88596.cm
|
||||
ar_SA.utf8.src utf8.cm
|
||||
bg_BG.iso5.src iso88595.cm
|
||||
bg_BG.utf8.src utf8.cm
|
||||
cs_CZ.iso2.src iso88592.cm
|
||||
cs_CZ.utf8.src utf8.cm
|
||||
da_DK.iso1.src iso88591.cm
|
||||
da_DK.iso885915.src iso885915.cm
|
||||
da_DK.rom8.src roman8.cm
|
||||
da_DK.utf8.src utf8.cm
|
||||
de_DE.iso1.src iso88591.cm
|
||||
de_DE.iso885915.src iso885915.cm
|
||||
de_DE.rom8.src roman8.cm
|
||||
de_DE.utf8.src utf8.cm
|
||||
el_GR.gre8.src greek8.cm
|
||||
el_GR.iso7.src iso88597.cm
|
||||
el_GR.utf8.src utf8.cm
|
||||
en_GB.iso1.src iso88591.cm
|
||||
en_GB.iso885915.src iso885915.cm
|
||||
en_GB.rom8.src roman8.cm
|
||||
en_GB.utf8.src utf8.cm
|
||||
en_US.iso1.src iso88591.cm
|
||||
en_US.rom8.src roman8.cm
|
||||
en_US.utf8.src utf8.cm
|
||||
es_ES.iso1.src iso88591.cm
|
||||
es_ES.iso885915.src iso885915.cm
|
||||
es_ES.rom8.src roman8.cm
|
||||
es_ES.utf8.src utf8.cm
|
||||
fi_FI.iso1.src iso88591.cm
|
||||
fi_FI.iso885915.src iso885915.cm
|
||||
fi_FI.rom8.src roman8.cm
|
||||
fi_FI.utf8.src utf8.cm
|
||||
fr_CA.iso1.src iso88591.cm
|
||||
fr_CA.iso885915.src iso885915.cm
|
||||
fr_CA.rom8.src roman8.cm
|
||||
fr_CA.utf8.src utf8.cm
|
||||
fr_FR.iso1.src iso88591.cm
|
||||
fr_FR.iso885915.src iso885915.cm
|
||||
fr_FR.rom8.src roman8.cm
|
||||
fr_FR.utf8.src utf8.cm
|
||||
hr_HR.iso2.src iso88592.cm
|
||||
hr_HR.utf8.src utf8.cm
|
||||
hu_HU.iso2.src iso88592.cm
|
||||
hu_HU.utf8.src utf8.cm
|
||||
is_IS.iso1.src iso88591.cm
|
||||
is_IS.iso885915.src iso885915.cm
|
||||
is_IS.rom8.src roman8.cm
|
||||
is_IS.utf8.src utf8.cm
|
||||
it_IT.iso1.src iso88591.cm
|
||||
it_IT.iso885915.src iso885915.cm
|
||||
it_IT.rom8.src roman8.cm
|
||||
it_IT.utf8.src utf8.cm
|
||||
iw_IL.heb8.src hebrew8.cm
|
||||
iw_IL.iso8.src iso88598.cm
|
||||
iw_IL.utf8.src utf8.cm
|
||||
ja_JP.SJIS.src SJIS.cm
|
||||
ja_JP.euc.src eucJP.cm
|
||||
ja_JP.kan8.src kana8.cm
|
||||
ja_JP.utf8.src utf8.cm
|
||||
ko_KR.euc.src eucKR.cm
|
||||
ko_KR.utf8.src utf8.cm
|
||||
nl_NL.iso1.src iso88591.cm
|
||||
nl_NL.iso885915.src iso885915.cm
|
||||
nl_NL.rom8.src roman8.cm
|
||||
nl_NL.utf8.src utf8.cm
|
||||
no_NO.iso1.src iso88591.cm
|
||||
no_NO.iso885915.src iso885915.cm
|
||||
no_NO.rom8.src roman8.cm
|
||||
no_NO.utf8.src utf8.cm
|
||||
pl_PL.iso2.src iso88592.cm
|
||||
pl_PL.utf8.src utf8.cm
|
||||
pt_PT.iso1.src iso88591.cm
|
||||
pt_PT.iso885915.src iso885915.cm
|
||||
pt_PT.rom8.src roman8.cm
|
||||
pt_PT.utf8.src utf8.cm
|
||||
ro_RO.iso2.src iso88592.cm
|
||||
ro_RO.utf8.src utf8.cm
|
||||
ru_RU.iso5.src iso88595.cm
|
||||
ru_RU.utf8.src utf8.cm
|
||||
sk_SK.iso2.src iso88592.cm
|
||||
sk_SK.utf8.src utf8.cm
|
||||
sl_SI.iso2.src iso88592.cm
|
||||
sl_SI.utf8.src utf8.cm
|
||||
sv_SE.iso1.src iso88591.cm
|
||||
sv_SE.iso885915.src iso885915.cm
|
||||
sv_SE.rom8.src roman8.cm
|
||||
sv_SE.utf8.src utf8.cm
|
||||
th_TH.tis.src tis620.cm
|
||||
tr_TR.iso9.src iso88599.cm
|
||||
tr_TR.tuk8.src turkish8.cm
|
||||
tr_TR.utf8.src utf8.cm
|
||||
zh_CN.utf8.src utf8.cm
|
||||
zh_HK.utf8.src utf8.cm
|
||||
zh_TW.big5.src big5.cm
|
||||
zh_TW.ccdc.src ccdc.cm
|
||||
zh_TW.euc.src eucTW.cm
|
||||
zh_TW.utf8.src utf8.cm
|
||||
|
||||
|
||||
|
||||
176
extern/stdcxx/4.2.1/util/gencat.cpp
vendored
Normal file
176
extern/stdcxx/4.2.1/util/gencat.cpp
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* gencat.cpp - Utility for generating message catalogs on Windows
|
||||
*
|
||||
* $Id: gencat.cpp 637080 2008-03-14 12:36:21Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <cstdlib> // for system(), getenv()
|
||||
#include <cstdio> // for printf()
|
||||
#include <cstring> // for strcmp(), strrchr()
|
||||
#include <cstddef> // for size_t
|
||||
#include <cassert> // for assert()
|
||||
|
||||
#include <string>
|
||||
|
||||
static const char
|
||||
usage_text[] = {
|
||||
"Usage: %s OUTPUT-FILE INPUT-FILE\n"
|
||||
"Generate message catalog.\n"
|
||||
"\n"
|
||||
" -?, --help Give this help list\n"
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
# define SLASH '\\'
|
||||
|
||||
// replace file extension in str by new extension ext
|
||||
static void change_ext (std::string& str, const char* ext)
|
||||
{
|
||||
const std::string::size_type npos = std::string::npos;
|
||||
std::string::size_type dot_pos = str.find_last_of ('.');
|
||||
std::string::size_type quote_pos =
|
||||
npos == dot_pos ? str.find_last_of ('\"')
|
||||
: str.find_first_of ('\"', dot_pos);
|
||||
if (npos == quote_pos)
|
||||
quote_pos = str.size ();
|
||||
if (npos == dot_pos)
|
||||
dot_pos = quote_pos;
|
||||
str.replace (dot_pos, quote_pos - dot_pos, ext);
|
||||
}
|
||||
|
||||
#else // !_WIN32
|
||||
# define SLASH '/'
|
||||
#endif // _WIN32
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
const char* exe_name = "gencat";
|
||||
|
||||
if (argv [0]) {
|
||||
if (const char* slash = std::strrchr (argv [0], SLASH))
|
||||
exe_name = slash + 1;
|
||||
else
|
||||
exe_name = argv [0];
|
||||
}
|
||||
|
||||
assert (exe_name);
|
||||
|
||||
if (1 == argc) {
|
||||
std::printf (usage_text, exe_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--argc;
|
||||
|
||||
while (0 != *++argv && 0 < argc-- && '-' == **argv) {
|
||||
|
||||
switch (*++*argv) {
|
||||
|
||||
case '?':
|
||||
std::printf (usage_text, exe_name);
|
||||
return 0;
|
||||
|
||||
case '-':
|
||||
if (0 == std::strcmp (*argv, "-help")) {
|
||||
std::printf (usage_text, exe_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fall through...
|
||||
default:
|
||||
std::printf ("%s: invalid option -%s\n",
|
||||
exe_name, *argv);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (1 > argc) {
|
||||
std::printf ("%s: missing arguments\n Try '%s --help'\n",
|
||||
exe_name, exe_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string cmd;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
# ifndef _WIN64
|
||||
# define PLATFORM "X86"
|
||||
# else // _WIN64
|
||||
# define PLATFORM "X64"
|
||||
# endif // _WIN64
|
||||
|
||||
const char* const env_vars [] = {
|
||||
"VS90COMNTOOLS", "VS80COMNTOOLS",
|
||||
"VS71COMNTOOLS", "VSCOMNTOOLS"
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof (env_vars) / sizeof (*env_vars); ++i) {
|
||||
if (const char* vcvarspath = std::getenv (env_vars [i])) {
|
||||
cmd = vcvarspath;
|
||||
cmd += "vsvars32.bat";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (std::string::npos != cmd.find (' ')) {
|
||||
cmd.insert (cmd.begin (), 1, '\"');
|
||||
cmd.push_back ('\"');
|
||||
}
|
||||
|
||||
const char* const dll_name = argv [0];
|
||||
const char* const rc_name = argv [1];
|
||||
|
||||
std::string res_name (rc_name);
|
||||
change_ext (res_name, ".res");
|
||||
|
||||
if (!cmd.empty ())
|
||||
cmd += " && ";
|
||||
|
||||
cmd += "rc ";
|
||||
cmd += rc_name;
|
||||
cmd += " && link /NOLOGO /DLL /NOENTRY /MACHINE:" PLATFORM " /OUT:";
|
||||
cmd += dll_name;
|
||||
cmd += ' ';
|
||||
cmd += res_name;
|
||||
|
||||
const int ret = std::system (cmd.c_str ());
|
||||
|
||||
std::remove (res_name.c_str ());
|
||||
|
||||
#else // !_WIN32
|
||||
|
||||
const char* const cat_name = argv [0];
|
||||
const char* const msg_name = argv [1];
|
||||
|
||||
cmd = "/usr/bin/gencat ";
|
||||
cmd += cat_name;
|
||||
cmd += ' ';
|
||||
cmd += msg_name;
|
||||
|
||||
const int ret = std::system (cmd.c_str ());
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
return ret;
|
||||
}
|
||||
351
extern/stdcxx/4.2.1/util/iconv.cpp
vendored
Normal file
351
extern/stdcxx/4.2.1/util/iconv.cpp
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* iconv.cpp - Win32 implementation of the POSIX iconv facility
|
||||
*
|
||||
* $Id: iconv.cpp 550991 2007-06-26 23:58:07Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 1994-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#if defined (_WIN32) || defined (_WIN64)
|
||||
|
||||
#include <errno.h>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
typedef int iconv_t;
|
||||
|
||||
iconv_t iconv_open (const char*, const char*);
|
||||
size_t iconv (iconv_t, char**, size_t*, char**, size_t*);
|
||||
int iconv_close (iconv_t);
|
||||
|
||||
|
||||
iconv_t iconv_open (const char *from_code, const char *to_code)
|
||||
{
|
||||
static const struct {
|
||||
int code;
|
||||
const char *name;
|
||||
} pages[] = {
|
||||
{ 37, "EBCDIC-US" },
|
||||
{ 437, "OEM - United States" },
|
||||
{ 500, "IBM EBCDIC - International" },
|
||||
{ 708, "Arabic - ASMO 708" },
|
||||
{ 709, "Arabic - ASMO 449+, BCON V4" },
|
||||
{ 710, "Arabic - Transparent Arabic" },
|
||||
{ 720, "Arabic - Transparent ASMO" },
|
||||
{ 737, "OEM - Greek (formerly 437G)" },
|
||||
{ 775, "OEM - Baltic" },
|
||||
{ 850, "OEM - Multilingual Latin I" },
|
||||
{ 852, "OEM - Latin II" },
|
||||
{ 855, "OEM - Cyrillic (primarily Russian)" },
|
||||
{ 857, "OEM - Turkish" },
|
||||
{ 858, "OEM - Multlingual Latin I + Euro symbol" },
|
||||
{ 860, "OEM - Portuguese" },
|
||||
{ 861, "OEM - Icelandic" },
|
||||
{ 862, "OEM - Hebrew" },
|
||||
{ 863, "OEM - Canadian-French" },
|
||||
{ 864, "OEM - Arabic" },
|
||||
{ 865, "OEM - Nordic" },
|
||||
{ 866, "OEM - Russian" },
|
||||
{ 869, "OEM - Modern Greek" },
|
||||
{ 870, "IBM EBCDIC - Multilingual/ROECE (Latin-2)" },
|
||||
{ 874, "ANSI/OEM - Thai (same as 28605, ISO 8859-15)" },
|
||||
{ 875, "IBM EBCDIC - Modern Greek" },
|
||||
{ 932, "Shift_JIS" },
|
||||
{ 936, "ANSI/OEM - Simplified Chinese (PRC, Singapore)" },
|
||||
{ 949, "ANSI/OEM - Korean (Unified Hangeul Code)" },
|
||||
{ 950, "ANSI/OEM - Traditional Chinese" },
|
||||
{ 1026, "IBM EBCDIC - Turkish (Latin-5)" },
|
||||
{ 1047, "IBM EBCDIC - Latin 1/Open System" },
|
||||
{ 1140, "EBCDIC-CA-FR@EURO" },
|
||||
{ 1141, "EBCDIC-AT-DE@EURO" },
|
||||
{ 1142, "EBCDIC-DK-NO@EURO" },
|
||||
{ 1143, "EBCDIC-FI-SE@EURO" },
|
||||
{ 1144, "EBCDIC-IT@EURO" },
|
||||
{ 1145, "EBCDIC-ES-A@EURO" },
|
||||
{ 1146, "EBCDIC-UK@EURO" },
|
||||
{ 1147, "EBCDIC-FR@EURO" },
|
||||
{ 1148, "IBM EBCDIC - International (500 + Euro symbol)" },
|
||||
{ 1149, "EBCDIC-IS-FRISS@EURO" },
|
||||
{ 1200, "UCS-2-LE" },
|
||||
{ 1201, "UCS-2-BE" },
|
||||
{ 1251, "ANSI - Cyrillic" },
|
||||
{ 1252, "ANSI - Latin I" },
|
||||
{ 1253, "ANSI - Greek" },
|
||||
{ 1254, "ANSI - Turkish" },
|
||||
{ 1255, "ANSI - Hebrew" },
|
||||
{ 1256, "ANSI - Arabic" },
|
||||
{ 1257, "ANSI - Baltic" },
|
||||
{ 1258, "ANSI/OEM - Vietnamese" },
|
||||
{ 1361, "Korean (Johab)" },
|
||||
{ 10000, "MAC - Roman" },
|
||||
{ 10001, "MAC-JP" },
|
||||
{ 10002, "MAC - Traditional Chinese (Big5)" },
|
||||
{ 10003, "MAC-KR" },
|
||||
{ 10004, "MAC-AR" },
|
||||
{ 10005, "MAC - Hebrew" },
|
||||
{ 10006, "MAC - Greek I" },
|
||||
{ 10007, "MAC-CYRILLIC" },
|
||||
{ 10008, "MAC - Simplified Chinese (GB 2312)" },
|
||||
{ 10010, "MAC - Romania" },
|
||||
{ 10017, "MAC - Ukraine" },
|
||||
{ 10021, "MAC - Thai" },
|
||||
{ 10029, "MAC - Latin II" },
|
||||
{ 10079, "MAC - Icelandic" },
|
||||
{ 10081, "MAC - Turkish" },
|
||||
{ 10082, "MAC - Croatia" },
|
||||
{ 12000, "UCS-4-LE" },
|
||||
{ 12001, "UCS-4-BE" },
|
||||
{ 20000, "CNS - Taiwan" },
|
||||
{ 20001, "TCA - Taiwan" },
|
||||
{ 20002, "Eten - Taiwan" },
|
||||
{ 20003, "IBM5550 - Taiwan" },
|
||||
{ 20004, "TeleText - Taiwan" },
|
||||
{ 20005, "Wang - Taiwan" },
|
||||
{ 20105, "IA5 IRV International Alphabet No. 5 (7-bit)" },
|
||||
{ 20106, "IA5 German (7-bit)" },
|
||||
{ 20107, "IA5 Swedish (7-bit)" },
|
||||
{ 20108, "IA5 Norwegian (7-bit)" },
|
||||
{ 20127, "ANSI_X3.4-1968" },
|
||||
{ 20261, "T.61" },
|
||||
{ 20269, "ISO 6937 Non-Spacing Accent" },
|
||||
{ 20273, "EBCDIC-DE" },
|
||||
{ 20277, "EBCDIC-DK-NO" },
|
||||
{ 20278, "EBCDIC-FI-SE" },
|
||||
{ 20280, "EBCDIC-IT" },
|
||||
{ 20284, "EBCDIC-ES-A" },
|
||||
{ 20285, "EBCDIC-UK" },
|
||||
{ 20290, "EBCDIC-JP" },
|
||||
{ 20297, "EBCDIC-FR" },
|
||||
{ 20420, "EBCDIC-AR" },
|
||||
{ 20423, "IBM EBCDIC - Greek" },
|
||||
{ 20424, "IBM EBCDIC - Hebrew" },
|
||||
{ 20833, "EBCDIC-KR" },
|
||||
{ 20838, "IBM EBCDIC - Thai" },
|
||||
{ 20866, "Russian - KOI8-R" },
|
||||
{ 20871, "IBM EBCDIC - Icelandic" },
|
||||
{ 20880, "IBM EBCDIC - Cyrillic (Russian)" },
|
||||
{ 20905, "IBM EBCDIC - Turkish" },
|
||||
{ 20924, "IBM EBCDIC - Latin-1/Open System (1047 + Euro symbol)" },
|
||||
{ 20932, "JIS X 0208-1990 & 0121-1990" },
|
||||
{ 20936, "GB2312" },
|
||||
{ 21025, "IBM EBCDIC - Cyrillic (Serbian, Bulgarian)" },
|
||||
{ 21027, "Extended Alpha Lowercase" },
|
||||
{ 21866, "Ukrainian (KOI8-U)" },
|
||||
{ 28591, "ISO-8859-1" },
|
||||
{ 28592, "ISO-8859-2" },
|
||||
{ 28593, "ISO-8859-3" },
|
||||
{ 28594, "ISO-8859-4" },
|
||||
{ 28595, "ISO-8859-5" },
|
||||
{ 28596, "ISO-8859-6" },
|
||||
{ 28597, "ISO-8859-7" },
|
||||
{ 28598, "ISO-8859-8" },
|
||||
{ 28599, "ISO-8859-95" },
|
||||
{ 28605, "ISO-8859-15" },
|
||||
{ 29001, "Europa 3" },
|
||||
{ 38598, "ISO-8859-8 Hebrew" },
|
||||
{ 50220, "ISO-2022 Japanese with no halfwidth Katakana" },
|
||||
{ 50221, "ISO-2022-JP" },
|
||||
{ 50222, "ISO-2022 Japanese JIS X 0201-1989" },
|
||||
{ 50225, "ISO-2022-KR" },
|
||||
{ 50227, "ISO-2022 Simplified Chinese" },
|
||||
{ 50229, "ISO-2022 Traditional Chinese" },
|
||||
{ 50930, "Japanese (Katakana) Extended" },
|
||||
{ 50931, "US/Canada and Japanese" },
|
||||
{ 50933, "Korean Extended and Korean" },
|
||||
{ 50935, "Simplified Chinese Extended and Simplified Chinese" },
|
||||
{ 50936, "Simplified Chinese" },
|
||||
{ 50937, "US/Canada and Traditional Chinese" },
|
||||
{ 50939, "Japanese (Latin) Extended and Japanese" },
|
||||
{ 51932, "EUC-JP" },
|
||||
{ 51936, "EUC - Simplified Chinese" },
|
||||
{ 51949, "EUC-KR" },
|
||||
{ 51950, "EUC - Traditional Chinese" },
|
||||
{ 52936, "HZ-GB2312 Simplified Chinese" },
|
||||
{ 54936, "Windows XP: GB18030 Simplified Chinese (4 Byte)" },
|
||||
{ 57002, "ISCII Devanagari 57003 ISCII Bengali" },
|
||||
{ 57004, "ISCII Tamil" },
|
||||
{ 57005, "ISCII Telugu" },
|
||||
{ 57006, "ISCII Assamese" },
|
||||
{ 57007, "ISCII Oriya" },
|
||||
{ 57008, "ISCII Kannada" },
|
||||
{ 57009, "ISCII Malayalam" },
|
||||
{ 57010, "ISCII Gujarati" },
|
||||
{ 57011, "ISCII Punjabi" },
|
||||
{ 65000, "UTF-7" },
|
||||
{ 65001, "UTF-8" }
|
||||
};
|
||||
|
||||
iconv_t cd = 0;
|
||||
|
||||
for (size_t i = 0; ; ++i) {
|
||||
|
||||
if (i == sizeof pages / sizeof *pages) {
|
||||
cd = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!strcmp (from_code, pages [i].name)) {
|
||||
cd |= pages [i].code << 16;
|
||||
|
||||
if (cd & 0x0000ffff)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!strcmp (to_code, pages [i].name)) {
|
||||
cd |= pages [i].code & 0xffff;
|
||||
|
||||
if (cd & 0xffff0000)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// validate code pages
|
||||
if ( -1 == cd
|
||||
|| !MultiByteToWideChar (cd & 0x0000ffff, 0, "", 1, 0, 0)
|
||||
|| !MultiByteToWideChar ((cd >> 16) & 0x0000ffff, 0, "", 1, 0, 0)) {
|
||||
// [EINVAL]
|
||||
// The conversion specified by fromcode and tocode
|
||||
// is not supported by the implementation.
|
||||
errno = EINVAL;
|
||||
cd = -1;
|
||||
}
|
||||
|
||||
return cd;
|
||||
}
|
||||
|
||||
|
||||
size_t iconv (iconv_t cd,
|
||||
char **inbuf, size_t *inbytesleft,
|
||||
char **outbuf, size_t *outbytesleft)
|
||||
{
|
||||
const int fromcode = (cd >> 16) & 0x0000ffff;
|
||||
const int tocode = cd & 0x0000ffff;
|
||||
|
||||
if (0x0000ffff == fromcode || 0x0000ffff == tocode) {
|
||||
errno = EBADF;
|
||||
return size_t (-1);
|
||||
}
|
||||
|
||||
wchar_t wbuf [256];
|
||||
|
||||
// allocate a sufficient amount of storage to conver the input
|
||||
// buffer to wide character assuming, pessimistically, that
|
||||
// each byte converts to one wide character
|
||||
wchar_t *pwc = *inbytesleft < sizeof wbuf / sizeof *wbuf ?
|
||||
wbuf : new wchar_t [*inbytesleft];
|
||||
|
||||
// convert the contents of the narrow input buffer to wide characters
|
||||
// `nwout' -- number of wide chars successfully produced by the call
|
||||
const int nwout =
|
||||
MultiByteToWideChar (fromcode, MB_ERR_INVALID_CHARS,
|
||||
*inbuf, int (*inbytesleft),
|
||||
pwc, int (*inbytesleft));
|
||||
|
||||
if (!nwout) {
|
||||
if (pwc != wbuf)
|
||||
delete[] pwc;
|
||||
|
||||
const int error = GetLastError ();
|
||||
errno = ERROR_INSUFFICIENT_BUFFER == error || !error ? E2BIG : EILSEQ;
|
||||
return size_t (-1);
|
||||
}
|
||||
|
||||
// convert the contents of wide character buffer into the narrow
|
||||
// character buffer
|
||||
// `nnout' -- number of narrow chars successfully produced by the
|
||||
// call
|
||||
const int nnout =
|
||||
WideCharToMultiByte (tocode, 0,
|
||||
pwc, nwout,
|
||||
*outbuf, int (*outbytesleft),
|
||||
0, 0);
|
||||
if (!nnout || !*outbytesleft) {
|
||||
if (pwc != wbuf)
|
||||
delete[] pwc;
|
||||
|
||||
const int error = GetLastError ();
|
||||
errno = ERROR_INSUFFICIENT_BUFFER == error || !error ? E2BIG : EILSEQ;
|
||||
return size_t (-1);
|
||||
}
|
||||
|
||||
// compute the number of wide characters consumed by second
|
||||
// conversion
|
||||
// `nwin' -- number of wide chars consumed by the call above
|
||||
const int nwin =
|
||||
MultiByteToWideChar (tocode, 0, *outbuf, nnout, 0, 0);
|
||||
|
||||
if (!nwin) {
|
||||
if (pwc != wbuf)
|
||||
delete[] pwc;
|
||||
|
||||
const int error = GetLastError ();
|
||||
errno = ERROR_INSUFFICIENT_BUFFER == error || !error ? E2BIG : EILSEQ;
|
||||
return size_t (-1);
|
||||
}
|
||||
|
||||
// finally, compute the number of narrow characters in the source
|
||||
// encoding corresponding to the number of narrow characters in
|
||||
// the destrination encoding
|
||||
// `nnin' -- number of narrow chars consumed by the first call
|
||||
const int nnin =
|
||||
WideCharToMultiByte (fromcode, 0, pwc, nwin, 0, 0, 0, 0);
|
||||
if (pwc != wbuf)
|
||||
delete[] pwc;
|
||||
|
||||
if (!nnin) {
|
||||
const int error = GetLastError ();
|
||||
errno = ERROR_INSUFFICIENT_BUFFER == error || !error ? E2BIG : EILSEQ;
|
||||
return size_t (-1);
|
||||
}
|
||||
|
||||
// advance buffers to the first character to convert
|
||||
*inbuf += nnin;
|
||||
*outbuf += nnout;
|
||||
|
||||
// decrement the size of each buffer
|
||||
*inbytesleft -= nnin;
|
||||
*outbytesleft -= nnout;
|
||||
|
||||
if (*inbytesleft) {
|
||||
errno = E2BIG;
|
||||
return size_t (-1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int iconv_close (iconv_t cd)
|
||||
{
|
||||
const int fromcode = (cd >> 16) & 0x0000ffff;
|
||||
const int tocode = cd & 0x0000ffff;
|
||||
|
||||
if (0x0000ffff == fromcode || 0x0000ffff == tocode) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // _WIN{32,64}
|
||||
44
extern/stdcxx/4.2.1/util/loc_exception.h
vendored
Normal file
44
extern/stdcxx/4.2.1/util/loc_exception.h
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* loc_exception.h - exception class used in locale and localedef
|
||||
*
|
||||
* $Id: loc_exception.h 550991 2007-06-26 23:58:07Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 1994-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <exception>
|
||||
|
||||
class loc_exception : public std::exception {
|
||||
public:
|
||||
loc_exception (){}
|
||||
|
||||
loc_exception (const std::string &str) :
|
||||
what_str(str) {
|
||||
}
|
||||
~loc_exception () throw () {}
|
||||
virtual const char* what() const throw() {
|
||||
return what_str.c_str();
|
||||
}
|
||||
private:
|
||||
const std::string what_str;
|
||||
};
|
||||
2987
extern/stdcxx/4.2.1/util/locale.cpp
vendored
Normal file
2987
extern/stdcxx/4.2.1/util/locale.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
84
extern/stdcxx/4.2.1/util/locale_stub.cpp
vendored
Normal file
84
extern/stdcxx/4.2.1/util/locale_stub.cpp
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* locale_stub.cpp
|
||||
*
|
||||
* $Id: locale_stub.cpp 648752 2008-04-16 17:01:56Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <cstdlib> // for size_t, system()
|
||||
#include <cstring> // for strcat(), strlen()
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
// compute the total length of the command line arguments
|
||||
std::size_t arglen = 0;
|
||||
for (int i = 0; i != argc; ++i)
|
||||
arglen += std::strlen (argv [i]);
|
||||
|
||||
// add the length of space separating adjacent pairs
|
||||
arglen += argc;
|
||||
|
||||
// add the length of the option to invoke localeded in locale mode
|
||||
const char argv_1[] = "--locale-mode";
|
||||
arglen += sizeof argv_1;
|
||||
|
||||
const char localedef[] = "localedef";
|
||||
arglen += sizeof localedef;
|
||||
|
||||
// allocate space for the new command line
|
||||
char* const cmdline = new char [arglen];
|
||||
|
||||
// replace the basename of argv[0] with "localedef" keeping the
|
||||
// directory portion, if it's there, followed by the new option
|
||||
// separated by a space
|
||||
std::strcpy (cmdline, argv [0]);
|
||||
char* slash = std::strrchr (cmdline, '/');
|
||||
|
||||
if (0 == slash) {
|
||||
// look for backslash for Windoze
|
||||
slash = std::strrchr (cmdline, '\\');
|
||||
}
|
||||
|
||||
if (slash)
|
||||
std::strcpy (slash + 1, localedef);
|
||||
else
|
||||
std::strcpy (cmdline, localedef);
|
||||
|
||||
std::strcat (cmdline, " ");
|
||||
std::strcat (cmdline, argv_1);
|
||||
|
||||
// copy arguments to the newly allocated buffer
|
||||
for (int i = 1; i != argc; ++i) {
|
||||
std::strcat (cmdline, " ");
|
||||
std::strcat (cmdline, argv [i]);
|
||||
}
|
||||
|
||||
// invoke the localedef utility instructing it to switch
|
||||
// to locale mode
|
||||
const int status = std::system (cmdline);
|
||||
|
||||
// clean up
|
||||
delete[] cmdline;
|
||||
|
||||
return status;
|
||||
}
|
||||
616
extern/stdcxx/4.2.1/util/localedef.cpp
vendored
Normal file
616
extern/stdcxx/4.2.1/util/localedef.cpp
vendored
Normal file
@@ -0,0 +1,616 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* localedef.cpp
|
||||
*
|
||||
* $Id: localedef.cpp 526304 2007-04-06 22:34:41Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "aliases.h"
|
||||
#include "def.h" // for Def
|
||||
#include "diagnostic.h" // for issue_diag()
|
||||
#include "loc_exception.h" // for loc_exception
|
||||
#include "path.h"
|
||||
|
||||
#include <fstream> // for ifstream
|
||||
#include <iostream> // for cerr
|
||||
#include <string> // for string
|
||||
#include <vector> // for vector
|
||||
|
||||
#include <clocale> // for setlocale(), LC_XXX
|
||||
#include <cstdlib> // for atoi()
|
||||
#include <cstring> // for strcmp()
|
||||
|
||||
|
||||
// exit status
|
||||
#define EXIT_OK 0
|
||||
#define EXIT_ERRORS 4
|
||||
|
||||
|
||||
// charmaps holds pointers to the character maps being used to generate
|
||||
// the locales.
|
||||
static std::vector<Charmap*> charmaps;
|
||||
|
||||
|
||||
static void
|
||||
print_help_msg ()
|
||||
{
|
||||
static const char msg[] =
|
||||
"NAME\n"
|
||||
"\tlocaledef - generate a locale environment\n"
|
||||
"\n"
|
||||
"SYNOPSIS\n"
|
||||
"\tlocaledef [-c][-w[###]][-f charmap_file][-i locale_defintion]\n"
|
||||
"\t\tlocale_name\n"
|
||||
"\n"
|
||||
"\tlocaledef -g [-m creation_list]\n"
|
||||
"\t\t[-d output_dir][-r charmap_dir][-s src_dir][--ucs]\n"
|
||||
"\n"
|
||||
"DESCRIPTION\n"
|
||||
"\tThe localedef utility sets up the language environment for the\n"
|
||||
"\tnamed locale. localedef reads a locale definition file from\n"
|
||||
"\tstandard input or from locale_definition file and creates a\n"
|
||||
"\tlocale database with the name specified on the command line.\n"
|
||||
"\n"
|
||||
"OPTIONS\n"
|
||||
"\tThe localedef utility recognizes the following options:\n"
|
||||
"\n"
|
||||
"\t-c\tCreate output irrespective of warnings.\n"
|
||||
"\n"
|
||||
"\t-f charmap_file\n"
|
||||
"\t\tIf the locale definition uses symbolic names use charmap_file.\n"
|
||||
"\n"
|
||||
"\t-i locale_definition\n"
|
||||
"\t\tUse locale_definition as input, instead of standard input\n"
|
||||
"\t\t(default).\n"
|
||||
"\n"
|
||||
"\t-g\tGenerate all the locales listed in the creation list.\n"
|
||||
"\n"
|
||||
"\t--ucs\tUse UCS for the internal (wchar_t) encoding."
|
||||
"\n"
|
||||
"\n\t-m creation_list\n"
|
||||
"\t\tSpecify a file that lists what combinations of charmaps and\n"
|
||||
"\t\tsource files should be used to create a locale.\n"
|
||||
"\n"
|
||||
"\t-r charmap_dir\n"
|
||||
"\t\tSpecify the directory where the character maps are located.\n"
|
||||
"\n"
|
||||
"\t-s src_dir\n"
|
||||
"\t\tSpecify the directory where the source files are located.\n"
|
||||
"\n"
|
||||
"\t-d output_dir\n"
|
||||
"\t\tSpecify the directory where the generated locale database\n"
|
||||
"\t\tfiles should be placed.\n"
|
||||
"\n"
|
||||
"\t-w\tDisable all warning messages.\n"
|
||||
"\n"
|
||||
"\t-w###\n"
|
||||
"\t\tDisable warning number ###.\n"
|
||||
"\n"
|
||||
"\t--notes\tEnable notes (informational messages).\n"
|
||||
"\t-?\n"
|
||||
"\t--help\tPrint out this message.\n";
|
||||
|
||||
std::cout << msg;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
create_locale (std::string std_src,
|
||||
std::string std_cmap,
|
||||
std::string outdir,
|
||||
std::string std_locale,
|
||||
bool force_output, bool use_ucs,
|
||||
bool no_position, bool link_aliases)
|
||||
{
|
||||
// extract the names of the locale and of the codeset
|
||||
std::string lname (std_src);
|
||||
std::string cname (std_cmap);
|
||||
|
||||
if (lname.rfind(_RWSTD_PATH_SEP) != std::string::npos)
|
||||
lname = lname.substr(lname.rfind(_RWSTD_PATH_SEP) + 1, lname.size());
|
||||
|
||||
if (cname.rfind(_RWSTD_PATH_SEP) != std::string::npos)
|
||||
cname = cname.substr(cname.rfind(_RWSTD_PATH_SEP) + 1, cname.size());
|
||||
|
||||
if (lname.find('.') != std::string::npos)
|
||||
lname = lname.substr(0, lname.find('.'));
|
||||
if (cname.find('.') != std::string::npos)
|
||||
cname = cname.substr(0, cname.find('.'));
|
||||
|
||||
// the vector of corresponding C locales
|
||||
StringVector C_locales;
|
||||
#ifndef _MSC_VER
|
||||
get_same_encoding_C_locale (lname, cname, C_locales);
|
||||
#endif // _MSC_VER
|
||||
|
||||
// C library locale using same encoding
|
||||
std::string enc_C_locale;
|
||||
|
||||
#ifdef _RWSTD_NO_ISO_10646_WCHAR_T
|
||||
// the encoding C locale
|
||||
enc_C_locale = get_C_encoding_locale (cname);
|
||||
|
||||
// platforms with locale dependant wchar_t encodings need the current
|
||||
// C locale to be set. If there is no C locale with the same name
|
||||
// or that uses the same encoding as the locale we are creating
|
||||
// issue warning
|
||||
if (enc_C_locale.empty ()) {
|
||||
issue_diag (W_COMPAT, false, 0, "no compatible locale found\n");
|
||||
} else
|
||||
std::setlocale (LC_ALL, enc_C_locale.c_str ());
|
||||
|
||||
#endif // _RWSTD_NO_ISO_10646_WCHAR_T
|
||||
|
||||
// if no charmap is present assume ISO-8859-1
|
||||
if (std_cmap.empty ())
|
||||
std_cmap = "ISO-8859-1";
|
||||
|
||||
// retrieve UTF-8 encoding aliases
|
||||
std::string utf8_cname("UTF-8");
|
||||
StringVector utf8_aliases;
|
||||
get_cname_aliases (utf8_cname, utf8_aliases);
|
||||
|
||||
// is it a UTF-8 encoded locale?
|
||||
bool is_utf8 = false;
|
||||
StringVector::iterator pos = utf8_aliases.begin();
|
||||
for (; pos != utf8_aliases.end (); pos++)
|
||||
if (ci_compare (cname, *pos) == 0) {
|
||||
is_utf8 = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// retrieve the charmap/codeset object
|
||||
Charmap* charmap_p = 0;
|
||||
std::vector <Charmap*>::iterator charmaps_it = charmaps.begin();
|
||||
for (; charmaps_it != charmaps.end(); charmaps_it++){
|
||||
if ((*charmaps_it)->get_full_charmap_name() == std_cmap) {
|
||||
charmap_p = *charmaps_it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if none found, create one and parse the corresponding file
|
||||
if (0 == charmap_p) {
|
||||
|
||||
issue_diag (I_STAGE, false, 0,
|
||||
"processing character set description file %s\n",
|
||||
std_cmap.c_str ());
|
||||
|
||||
charmap_p = new Charmap (enc_C_locale.c_str (),
|
||||
std_cmap.c_str (),
|
||||
is_utf8, true, true, use_ucs);
|
||||
charmaps.push_back (charmap_p);
|
||||
}
|
||||
|
||||
// parse the source definition files
|
||||
bool def_error = false;
|
||||
|
||||
issue_diag (I_STAGE, false, 0,
|
||||
"processing locale definition file %s\n", std_src.c_str ());
|
||||
|
||||
Def def (std_src.c_str (), (outdir + std_locale).c_str (),
|
||||
*charmap_p, no_position);
|
||||
|
||||
try {
|
||||
// try to parse the input files
|
||||
def.process_input ();
|
||||
}
|
||||
catch (...) {
|
||||
def_error = true;
|
||||
}
|
||||
|
||||
// create the locale directory
|
||||
std::string locale_dir (outdir + std_locale);
|
||||
|
||||
makedir (locale_dir.c_str ());
|
||||
|
||||
if (def_error) {
|
||||
// write out the codecvt database and exit if parsing failed
|
||||
def.write_codecvt (locale_dir);
|
||||
throw loc_exception ("abort.");
|
||||
}
|
||||
|
||||
// no output when it hasn't been forced and warnings were present
|
||||
if (!force_output && def.warnings_occurred_) {
|
||||
std::cerr << "Warnings occurred - No output produced\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// and write out the locale categories data
|
||||
issue_diag (I_STAGE, false, 0, "generating LC_CTYPE database\n");
|
||||
def.write_ctype (locale_dir);
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "generating codeset database\n");
|
||||
def.write_codecvt (locale_dir);
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "generating LC_MONETARY database\n");
|
||||
def.write_monetary (locale_dir);
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "generating LC_NUMERIC database\n");
|
||||
def.write_numeric (locale_dir);
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "generating LC_TIME database\n");
|
||||
def.write_time (locale_dir);
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "generating LC_COLLATE database\n");
|
||||
def.write_collate (locale_dir);
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "generating LC_MESSAGES database\n");
|
||||
def.write_messages (locale_dir);
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
// no C library locales equivalents
|
||||
if (C_locales.empty ())
|
||||
return;
|
||||
|
||||
#if !defined (_MSC_VER)
|
||||
|
||||
if (link_aliases == false)
|
||||
return;
|
||||
|
||||
// some corresponding C lib locale names where found for this name
|
||||
StringVector::iterator it = C_locales.begin ();
|
||||
for (; it != C_locales.end (); it++) {
|
||||
// check if the name actually exists
|
||||
if (*it == std_locale)
|
||||
continue;
|
||||
|
||||
// set a symlink with the name of the C lib locale
|
||||
// pointing to our locale database
|
||||
create_symlink (outdir, std_locale, *it);
|
||||
}
|
||||
#endif // _MSC_VER
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generate_locales (const char* map_name, const char* /*alias_name*/,
|
||||
const char* charmap_dir, const char* src_dir,
|
||||
const char* output_dir, bool use_ucs,
|
||||
bool no_position, bool link_aliases)
|
||||
{
|
||||
std::ifstream f (map_name);
|
||||
|
||||
if (!f) {
|
||||
issue_diag (E_OPENRD, true, 0,
|
||||
"the generation list '%s' "
|
||||
"could not be opened\n", map_name);
|
||||
return;
|
||||
}
|
||||
|
||||
while (f) {
|
||||
std::string s1;
|
||||
std::string s2;
|
||||
|
||||
f >> s1 >> s2;
|
||||
if (f) {
|
||||
std::string lname = s1.substr (0, s1.find('.'));
|
||||
std::string cname = s2.substr (0, s2.find('.'));
|
||||
|
||||
// our name for a locale database is <locale>.<codeset>
|
||||
std::string std_locale(lname + "." + cname);
|
||||
|
||||
// create the locale database
|
||||
std::cout << "creating locale " << std_locale << '\n';
|
||||
try {
|
||||
create_locale ((std::string(src_dir) + s1),
|
||||
(std::string(charmap_dir) + s2),
|
||||
std::string (output_dir), std_locale,
|
||||
true, use_ucs, no_position, link_aliases);
|
||||
|
||||
}
|
||||
catch (const std::ios::failure& error) {
|
||||
std::cerr << "I/O exception " << error.what() << '\n';
|
||||
}
|
||||
catch (loc_exception& e) {
|
||||
std::cerr << "Unable to create locale " << std_locale
|
||||
<< " : " << e.what () << '\n';
|
||||
}
|
||||
catch (const std::exception& error) {
|
||||
std::cerr <<"ERROR: " << error.what() << '\n';
|
||||
}
|
||||
catch (...) {
|
||||
std::cerr << "Unable to create locale " << std_locale
|
||||
<< '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct ProgramOptions
|
||||
{
|
||||
const char* program_name;
|
||||
const char* charmap_name;
|
||||
const char* source_name;
|
||||
const char* map_file;
|
||||
const char* alias_file;
|
||||
const char* locale_name;
|
||||
|
||||
std::string charmap_dir;
|
||||
std::string src_dir;
|
||||
std::string output_dir;
|
||||
|
||||
bool gen;
|
||||
bool force_output;
|
||||
bool use_ucs;
|
||||
bool no_position;
|
||||
bool link_aliases;
|
||||
};
|
||||
|
||||
|
||||
static bool
|
||||
process_command_line (ProgramOptions *opts, int argc, char* argv[])
|
||||
{
|
||||
opts->program_name = argv [0];
|
||||
opts->charmap_name = "";
|
||||
opts->source_name = "";
|
||||
opts->map_file = 0;
|
||||
opts->alias_file = 0;
|
||||
opts->locale_name = 0;
|
||||
|
||||
opts->gen = false;
|
||||
opts->force_output = false;
|
||||
opts->use_ucs = false;
|
||||
opts->no_position = false;
|
||||
opts->link_aliases = false;
|
||||
|
||||
int i; // index of command line argument being processed
|
||||
|
||||
for (i = 1; i < argc && '-' == argv [i][0]; ++i) {
|
||||
|
||||
switch (argv [i][1]) {
|
||||
|
||||
case 'f': // set character set description file name
|
||||
if (argv [i + 1])
|
||||
opts->charmap_name = argv [++i];
|
||||
break;
|
||||
|
||||
case 'i': // set locale definition file name
|
||||
if (argv [i + 1])
|
||||
opts->source_name = argv [++i];
|
||||
break;
|
||||
|
||||
case 'c': // create output even if warnings are issued
|
||||
opts->force_output = true;
|
||||
break;
|
||||
|
||||
case 'g': // generate more than one locale database
|
||||
opts->gen = true;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (argv [i + 1])
|
||||
opts->map_file = argv [++i];
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
if (argv [i + 1])
|
||||
opts->alias_file = argv [++i];
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
if (argv [i + 1])
|
||||
opts->charmap_dir = argv [++i];
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (argv [i + 1])
|
||||
opts->src_dir = argv [++i];
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (argv [i + 1])
|
||||
opts->output_dir = argv [++i];
|
||||
break;
|
||||
|
||||
case 'w': // disable one or all warnings
|
||||
if (argv [i][2])
|
||||
issue_diag (std::atoi (argv [i] + 2), false, 0, 0);
|
||||
else
|
||||
issue_diag (W_DISABLE, false, 0, 0);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
print_help_msg ();
|
||||
return false;
|
||||
|
||||
case '-':
|
||||
if (0 == std::strcmp (argv [i] + 2, "help")) {
|
||||
print_help_msg ();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 == std::strcmp (argv [i] + 2, "ucs")) {
|
||||
// --ucs: use UCS as the internal wchar_t encoding
|
||||
opts->use_ucs = true;
|
||||
break;
|
||||
}
|
||||
else if (0 == std::strcmp (argv [i] + 2, "no_position")) {
|
||||
opts->no_position = true;
|
||||
break;
|
||||
}
|
||||
else if (0 == std::strcmp (argv [i] + 2, "aliases")) {
|
||||
opts->link_aliases = true;
|
||||
break;
|
||||
}
|
||||
else if (0 == std::strcmp (argv [i] + 2, "notes")) {
|
||||
// --notes: enable informational messages (notes)
|
||||
issue_diag (I_ENABLE, false, 0, 0);
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
|
||||
default:
|
||||
issue_diag (E_CMDARG, true, 0, "invalid option %s\n", argv [i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->gen) {
|
||||
|
||||
bool errors = false;
|
||||
|
||||
// make sure that all the required options are specified
|
||||
if (0 == opts->map_file) {
|
||||
issue_diag (E_NOARG, true, 0,
|
||||
"option %s requires a string argument\n", "-m");
|
||||
}
|
||||
|
||||
if (opts->charmap_dir.empty ()) {
|
||||
issue_diag (E_NOARG, true, 0,
|
||||
"option %s requires a string argument\n", "-r");
|
||||
}
|
||||
|
||||
if (opts->src_dir.empty ()) {
|
||||
issue_diag (E_NOARG, true, 0,
|
||||
"option %s requires a string argument\n", "-s");
|
||||
}
|
||||
|
||||
if (opts->output_dir.empty ()) {
|
||||
issue_diag (E_NOARG, true, 0,
|
||||
"option %s requires a string argument\n", "-d");
|
||||
}
|
||||
|
||||
// append a slash to the directories if the user didn't
|
||||
if (opts->output_dir [opts->output_dir.size () - 1] != _RWSTD_PATH_SEP)
|
||||
opts->output_dir += _RWSTD_PATH_SEP;
|
||||
|
||||
if (opts->src_dir [opts->src_dir.size () - 1] != _RWSTD_PATH_SEP)
|
||||
opts->src_dir += _RWSTD_PATH_SEP;
|
||||
|
||||
if (opts->charmap_dir [opts->charmap_dir.size () - 1] != _RWSTD_PATH_SEP)
|
||||
opts->charmap_dir += _RWSTD_PATH_SEP;
|
||||
}
|
||||
|
||||
if (0 == argv [i] && !opts->gen) {
|
||||
issue_diag (E_NOARG, true, 0, "missing command line argument\n");
|
||||
}
|
||||
|
||||
opts->locale_name = argv [i];
|
||||
|
||||
if (argv [i + 1]) {
|
||||
issue_diag (E_XARG, true, 0,
|
||||
"extra command line arguments after %s\n", argv [i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int localedef_main (int argc, char *argv[])
|
||||
{
|
||||
ProgramOptions opts;
|
||||
|
||||
if (!process_command_line (&opts, argc, argv))
|
||||
return EXIT_OK;
|
||||
|
||||
if (opts.gen) {
|
||||
// create the locale databases as specified in generation list
|
||||
generate_locales (opts.map_file, opts.alias_file,
|
||||
opts.charmap_dir.c_str (),
|
||||
opts.src_dir.c_str (),
|
||||
opts.output_dir.c_str (),
|
||||
opts.use_ucs,
|
||||
opts.no_position,
|
||||
opts.link_aliases);
|
||||
}
|
||||
else {
|
||||
assert (0 != opts.locale_name);
|
||||
|
||||
// C++ locale name requested
|
||||
std::string std_locale (opts.locale_name);
|
||||
|
||||
// retrieve the output directory if any
|
||||
std::string std_outdir ("");
|
||||
|
||||
if (std_locale.rfind (_RWSTD_PATH_SEP) != std::string::npos) {
|
||||
std_outdir =
|
||||
std_locale.substr (
|
||||
0, std_locale.rfind (_RWSTD_PATH_SEP) + 1);
|
||||
|
||||
std_locale =
|
||||
std_locale.substr (std_locale.rfind (_RWSTD_PATH_SEP) + 1,
|
||||
std_locale.size ());
|
||||
}
|
||||
|
||||
// create the locale database
|
||||
create_locale (opts.source_name, opts.charmap_name,
|
||||
std_outdir, std_locale,
|
||||
opts.force_output, opts.use_ucs,
|
||||
opts.no_position, opts.link_aliases);
|
||||
}
|
||||
|
||||
return EXIT_OK;
|
||||
}
|
||||
|
||||
|
||||
// defined in locale.cpp
|
||||
int locale_main (int, char*[]);
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int exit_status = EXIT_OK;
|
||||
|
||||
try {
|
||||
|
||||
if (1 < argc && 0 == std::strcmp (argv [1], "--locale-mode")) {
|
||||
|
||||
// invoked with the special option ""--locale-mode"
|
||||
// to act like the locale utility
|
||||
|
||||
// remove argv [1] from command line
|
||||
for (int i = 2; argv [i]; ++i)
|
||||
argv [i - 1] = argv [i];
|
||||
|
||||
// NULL-terminate argv
|
||||
argv [argc - 1] = 0;
|
||||
|
||||
exit_status = locale_main (argc - 1, argv);
|
||||
}
|
||||
else {
|
||||
exit_status = localedef_main (argc, argv);
|
||||
}
|
||||
}
|
||||
catch (const std::ios::failure& error) {
|
||||
std::cerr << "Error: I/O exception: " << error.what () << '\n';
|
||||
exit_status = EXIT_ERRORS;
|
||||
}
|
||||
catch (loc_exception&) {
|
||||
exit_status = EXIT_ERRORS;
|
||||
}
|
||||
catch (const std::exception& error) {
|
||||
std::cerr <<"Error: " << error.what () << '\n';
|
||||
exit_status = EXIT_ERRORS;
|
||||
}
|
||||
catch (...) {
|
||||
std::cerr << "Error: unknown exception\n";
|
||||
exit_status = EXIT_ERRORS;
|
||||
}
|
||||
|
||||
return exit_status;
|
||||
}
|
||||
34
extern/stdcxx/4.2.1/util/localedef.h
vendored
Normal file
34
extern/stdcxx/4.2.1/util/localedef.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* localedef.h
|
||||
*
|
||||
* $Id: localedef.h 550991 2007-06-26 23:58:07Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 1994-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RWSTD_UTIL_LOCALEDEF_H_INCLUDED
|
||||
#define RWSTD_UTIL_LOCALEDEF_H_INCLUDED
|
||||
|
||||
// empty
|
||||
|
||||
#endif // RWSTD_UTIL_LOCALEDEF_H_INCLUDED
|
||||
235
extern/stdcxx/4.2.1/util/memchk.cpp
vendored
Normal file
235
extern/stdcxx/4.2.1/util/memchk.cpp
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* memchk.cpp - definitions of memory checking helper functions
|
||||
*
|
||||
* $Id: memchk.cpp 648752 2008-04-16 17:01:56Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2008 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# include <fcntl.h> // for open()
|
||||
# include <unistd.h> // for getpagesize(), write()
|
||||
#else // if MSVC
|
||||
# include <fcntl.h> // for POSIX compatibility APIs
|
||||
# include <io.h> // ditto
|
||||
# include <windows.h> // for all of Win32 junk
|
||||
#endif // MSVC
|
||||
|
||||
#include <errno.h> // for errno, EINTR
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdio.h> // for L_tmpnam, P_tmpdir, tempnam()
|
||||
#include <stdlib.h> // for mkstemp()
|
||||
#include <string.h> // for memchr()
|
||||
|
||||
#include <rw/_defs.h>
|
||||
|
||||
|
||||
#ifndef EINTR
|
||||
# define EINTR 4 /* AIX, HP-UX, IRIX, Linux, SunOS, Tru64 */
|
||||
#endif // EINTR
|
||||
|
||||
|
||||
#if defined (_RWSTD_NO_MKSTEMP) || !defined (_RWSTD_NO_PURE_C_HEADERS)
|
||||
# ifndef _RWSTD_NO_MKSTEMP_IN_LIBC
|
||||
|
||||
extern "C" int mkstemp (char*) _LIBC_THROWS();
|
||||
|
||||
# undef _RWSTD_NO_MKSTEMP
|
||||
# endif // _RWSTD_NO_MKSTEMP_IN_LIBC
|
||||
#endif // _RWSTD_NO_MKSTEMP || !_RWSTD_NO_PURE_C_HEADERS
|
||||
|
||||
|
||||
#ifndef P_tmpdir
|
||||
# ifndef _P_tmpdir
|
||||
# define P_tmpdir "/tmp/"
|
||||
# else
|
||||
# define P_tmpdir _P_tmpdir
|
||||
# endif
|
||||
#endif // P_tmpdir
|
||||
|
||||
|
||||
#if defined (_RWSTD_EDG_ECCP) && !defined (_WIN32)
|
||||
|
||||
extern "C" {
|
||||
|
||||
int getpagesize ();
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // vanilla EDG eccp demo on UNIX
|
||||
|
||||
|
||||
static int page_size ()
|
||||
{
|
||||
static int size = 0;
|
||||
|
||||
if (0 == size) {
|
||||
|
||||
#if defined (_WIN32) || defined (_WIN64)
|
||||
|
||||
SYSTEM_INFO info;
|
||||
|
||||
GetSystemInfo (&info);
|
||||
|
||||
size = int (info.dwPageSize);
|
||||
|
||||
#else // any saner OS
|
||||
|
||||
size = getpagesize ();
|
||||
|
||||
#endif // WIN{32,64}
|
||||
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
size_t memchk (const void *addr, size_t nbytes)
|
||||
{
|
||||
static int fd = -1;
|
||||
|
||||
if (-1 == fd) {
|
||||
|
||||
// writing to /dev/null need not reliably detect invalid
|
||||
// address ranges if the operating system optimizes the
|
||||
// operation away (as SunOS does, for instance)
|
||||
// fd = open ("/dev/null", O_WRONLY);
|
||||
|
||||
#if defined (_WIN32) || defined (_WIN64)
|
||||
|
||||
char* const fname = tempnam (P_tmpdir, ".rwmemchk.tmp");
|
||||
|
||||
if (!fname)
|
||||
return size_t (-1);
|
||||
|
||||
// create a temporary file and have Win32 delete it when
|
||||
// the last file descriptor that refers to it is closed
|
||||
fd = open (fname, O_RDWR | O_CREAT | _O_TEMPORARY, 0666);
|
||||
|
||||
// free storage allocated by tempnam()
|
||||
free (fname);
|
||||
|
||||
if (fd < 0) {
|
||||
// error: unable to check addr
|
||||
return size_t (-1);
|
||||
}
|
||||
|
||||
#else // !_WIN{32,64}
|
||||
|
||||
# define TMP_TEMPLATE P_tmpdir "/rwmemchk-XXXXXX"
|
||||
|
||||
char fname_buf [] = TMP_TEMPLATE;
|
||||
|
||||
fd = mkstemp (fname_buf);
|
||||
|
||||
if (fd < 0) {
|
||||
// error: unable to check addr
|
||||
return size_t (-1);
|
||||
}
|
||||
|
||||
unlink (fname_buf);
|
||||
|
||||
#endif // _WIN{32,64}
|
||||
|
||||
}
|
||||
|
||||
lseek (fd, 0, SEEK_SET);
|
||||
|
||||
size_t size = size_t (-1); // error
|
||||
|
||||
const int errno_save = errno;
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (size_t (-1) == nbytes) {
|
||||
|
||||
// size not specified, check that addr points
|
||||
// to a valid NUL-terminated byte string (NTBS)
|
||||
|
||||
// get the virtual page size
|
||||
static const size_t pgsz = page_size ();
|
||||
|
||||
// compute the positive offset from the closest page boundary
|
||||
const size_t pgoff = size_t (addr) % pgsz;
|
||||
|
||||
// compute the number of bytes from addr to the end of the page
|
||||
nbytes = pgsz - pgoff;
|
||||
|
||||
// go through memory pointed to by `addr' one page
|
||||
// at a time looking for the terminating NUL
|
||||
for (const char *pc = static_cast<const char*>(addr); ; ) {
|
||||
|
||||
// try to write a page of memory (or what's left of it)
|
||||
const size_t nwrote = write (fd, pc, nbytes);
|
||||
|
||||
if (nwrote == nbytes) {
|
||||
|
||||
// on success, look for the NUL character
|
||||
const void* const pnull = memchr (pc, 0, nbytes);
|
||||
|
||||
if (pnull) {
|
||||
|
||||
// return the offset of the NUL character from `addr'
|
||||
size = static_cast<const char*>(pnull)
|
||||
- static_cast<const char*>(addr) + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
pc += nbytes;
|
||||
nbytes = pgsz;
|
||||
}
|
||||
else if (size_t (-1) == nwrote && EINTR == errno) {
|
||||
// retry the interrupted system call
|
||||
errno = 0;
|
||||
}
|
||||
else if (nwrote < nbytes) {
|
||||
// retry after a partial write
|
||||
errno = 0;
|
||||
pc += nwrote;
|
||||
nbytes -= nwrote;
|
||||
}
|
||||
else {
|
||||
// error: `addr' doesn't point to a valid NTBS
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
const size_t nwrote = write (fd, addr, nbytes);
|
||||
|
||||
if (nwrote == nbytes)
|
||||
size = nbytes;
|
||||
}
|
||||
|
||||
errno = errno_save;
|
||||
|
||||
return size_t (size);
|
||||
}
|
||||
|
||||
|
||||
size_t strchk (const char *str)
|
||||
{
|
||||
return memchk (str, size_t (-1));
|
||||
}
|
||||
42
extern/stdcxx/4.2.1/util/memchk.h
vendored
Normal file
42
extern/stdcxx/4.2.1/util/memchk.h
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* memchk.cpp - declarations of memory checking helper functions
|
||||
*
|
||||
* $Id: memchk.h 550991 2007-06-26 23:58:07Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 1994-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RWSTD_MEMCHK_H_INCLUDED
|
||||
#define RWSTD_MEMCHK_H_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
// checks if the first argument points to a readable region of memory
|
||||
// of the given size; returns the size on success, -1 otherwise
|
||||
std::size_t memchk (const void*, std::size_t);
|
||||
|
||||
// checks of the argument points to a valid NUL-terminated character
|
||||
// string; returns the length of the string on success, -1 otherwise
|
||||
std::size_t strchk (const char*);
|
||||
|
||||
#endif // RWSTD_MEMCHK_H_INCLUDED
|
||||
171
extern/stdcxx/4.2.1/util/messages.cpp
vendored
Normal file
171
extern/stdcxx/4.2.1/util/messages.cpp
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* messages.cpp
|
||||
*
|
||||
* $Id: messages.cpp 448754 2006-09-22 00:42:16Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "def.h" // for Def
|
||||
#include "diagnostic.h" // for issue_diag()
|
||||
#include "path.h" // for get_pathname()
|
||||
#include "scanner.h" // for scanner
|
||||
|
||||
#include <cassert> // for assert()
|
||||
#include <fstream> // for ofstream
|
||||
|
||||
|
||||
static const char lc_name[] = "LC_MESSAGES";
|
||||
|
||||
|
||||
void Def::process_messages()
|
||||
{
|
||||
issue_diag (I_STAGE, false, 0, "processing %s section\n", lc_name);
|
||||
|
||||
// nesting level
|
||||
int nesting_level = 0;
|
||||
|
||||
messages_def_found_ = true;
|
||||
|
||||
std::string name;
|
||||
|
||||
while ((next = scanner_.next_token()).token != Scanner::tok_messages) {
|
||||
|
||||
switch(next.token) {
|
||||
|
||||
case Scanner::tok_end:
|
||||
next = scanner_.next_token();
|
||||
if (next.token == Scanner::tok_messages) {
|
||||
// end of numeric block
|
||||
if (nesting_level == 0)
|
||||
return;
|
||||
|
||||
nesting_level--;
|
||||
scanner_.close ();
|
||||
} else
|
||||
issue_diag (E_SYNTAX, true, &next,
|
||||
"wrong section name in END directive\n");
|
||||
|
||||
break;
|
||||
|
||||
case Scanner::tok_copy: {
|
||||
next = scanner_.next_token();
|
||||
if (next.token != Scanner::tok_string)
|
||||
issue_diag (E_SYNTAX, true, &next,
|
||||
"expected string following \"copy\" directive\n");
|
||||
|
||||
// bump up the nesting level
|
||||
nesting_level++;
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "processing copy directive\n");
|
||||
|
||||
// open the file
|
||||
scanner_.open (get_pathname (strip_quotes (next.name), next.file));
|
||||
|
||||
// get comment char and escape char;
|
||||
// these informations are stored by the scanner
|
||||
while ((next = scanner_.next_token ()).token
|
||||
!= Scanner::tok_messages ){
|
||||
// the LC_IDENTIFICATION section may also have a
|
||||
// LC_MESSAGES token that will mess up the parsing
|
||||
if (next.token == Scanner::tok_ident) {
|
||||
while ((next = scanner_.next_token()).token
|
||||
!= Scanner::tok_end );
|
||||
next = scanner_.next_token();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_yesexpr: {
|
||||
next = scanner_.next_token();
|
||||
messages_st_.yesexpr = convert_string (next.name);
|
||||
messages_st_.wyesexpr = convert_wstring (next);
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_noexpr: {
|
||||
next = scanner_.next_token();
|
||||
messages_st_.noexpr = convert_string (next.name);
|
||||
messages_st_.wnoexpr = convert_wstring (next);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Def::write_messages(std::string dir_name)
|
||||
{
|
||||
assert (!dir_name.empty());
|
||||
|
||||
if (messages_written_)
|
||||
return;
|
||||
|
||||
if (!messages_def_found_) {
|
||||
issue_diag (I_SKIP, false, 0,
|
||||
"%s section not found, skipping\n", lc_name);
|
||||
return;
|
||||
}
|
||||
|
||||
(dir_name += _RWSTD_PATH_SEP) += lc_name;
|
||||
|
||||
issue_diag (I_OPENWR, false, 0, "writing %s\n", dir_name.c_str ());
|
||||
|
||||
std::ofstream out (dir_name.c_str(), std::ios::binary);
|
||||
out.exceptions (std::ios::failbit | std::ios::badbit);
|
||||
|
||||
// now calculate the offsets for the wide string representations
|
||||
messages_out_.yesexpr_off[1] = 0;
|
||||
messages_out_.noexpr_off[1] = messages_out_.yesexpr_off[1]
|
||||
+ (messages_st_.wyesexpr.size() + 1) * sizeof (wchar_t) ;
|
||||
|
||||
// now calculate the offsets for the narrow string representations
|
||||
messages_out_.yesexpr_off[0] = messages_out_.noexpr_off[1]
|
||||
+ (messages_st_.wnoexpr.size() + 1) * sizeof (wchar_t);
|
||||
messages_out_.noexpr_off[0] = messages_out_.yesexpr_off[0]
|
||||
+ (messages_st_.yesexpr.size() + 1) * sizeof (char);
|
||||
|
||||
messages_out_.codeset_off = messages_out_.noexpr_off[0]
|
||||
+ (messages_st_.noexpr.size() + 1) * sizeof (char);
|
||||
messages_out_.charmap_off = messages_out_.codeset_off
|
||||
+ (charmap_.get_code_set_name().size() + 1) * sizeof (char);
|
||||
|
||||
// first write out the messages structure
|
||||
out.write ((char*)&messages_out_, sizeof(messages_out_));
|
||||
|
||||
// now write out all the strings
|
||||
out.write ((const char*)messages_st_.wyesexpr.c_str(),
|
||||
(messages_st_.wyesexpr.size() + 1) * sizeof (wchar_t));
|
||||
out.write ((const char*)messages_st_.wnoexpr.c_str(),
|
||||
(messages_st_.wnoexpr.size() + 1) * sizeof (wchar_t));
|
||||
|
||||
out << messages_st_.yesexpr << std::ends;
|
||||
out << messages_st_.noexpr << std::ends;
|
||||
out << charmap_.get_code_set_name() << std::ends;
|
||||
out << charmap_.get_charmap_name() << std::ends;
|
||||
out.close();
|
||||
}
|
||||
570
extern/stdcxx/4.2.1/util/monetary.cpp
vendored
Normal file
570
extern/stdcxx/4.2.1/util/monetary.cpp
vendored
Normal file
@@ -0,0 +1,570 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* monetary.cpp
|
||||
*
|
||||
* $Id: monetary.cpp 480734 2006-11-29 22:22:44Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "def.h" // for Def
|
||||
#include "diagnostic.h" // for issue_diag()
|
||||
#include "path.h" // for get_pathname()
|
||||
#include "scanner.h" // for scanner
|
||||
|
||||
#include <cassert> // for assert()
|
||||
#include <climits> // for CHAR_MAX, CHAR_MIN
|
||||
#include <cstdlib> // for strtol()
|
||||
#include <fstream> // for ofstream
|
||||
#include <locale> // for money_base
|
||||
|
||||
|
||||
static const char lc_name[] = "LC_MONETARY";
|
||||
|
||||
|
||||
void Def::process_monetary ()
|
||||
{
|
||||
issue_diag (I_STAGE, false, 0, "processing %s section\n", lc_name);
|
||||
|
||||
// nesting level
|
||||
int nesting_level = 0;
|
||||
|
||||
mon_def_found_ = true;
|
||||
|
||||
while ((next = scanner_.next_token ()).token != Scanner::tok_monetary) {
|
||||
|
||||
// set to point to the integer represented as an ordinary char
|
||||
// corresponding to p_cs_precedes, p_sep_by_space, p_sign_posn,
|
||||
// or one of the n_ (or int_ versions) of the same
|
||||
char *pcharint = 0;
|
||||
|
||||
typedef unsigned char UChar;
|
||||
long maxval = long (UChar (CHAR_MAX)); // maximum allowed value
|
||||
|
||||
switch (next.token) {
|
||||
|
||||
case Scanner::tok_end:
|
||||
next = scanner_.next_token();
|
||||
if (next.token == Scanner::tok_monetary) {
|
||||
// end of monetary block
|
||||
if (nesting_level == 0)
|
||||
return;
|
||||
|
||||
nesting_level--;
|
||||
scanner_.close ();
|
||||
}
|
||||
else
|
||||
issue_diag (E_SYNTAX, true, &next,
|
||||
"wrong section name in END directive\n");
|
||||
|
||||
break;
|
||||
|
||||
case Scanner::tok_copy: {
|
||||
next = scanner_.next_token();
|
||||
if (next.token != Scanner::tok_string)
|
||||
issue_diag (E_SYNTAX, true, &next,
|
||||
"expected string following \"copy\" directive\n");
|
||||
|
||||
// bump up the nesting level
|
||||
nesting_level++;
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "processing copy directive\n");
|
||||
|
||||
// open the file
|
||||
scanner_.open (get_pathname (strip_quotes (next.name), next.file));
|
||||
|
||||
// get comment char and escape char;
|
||||
// these informations are stored by the scanner
|
||||
while ((next = scanner_.next_token ()).token
|
||||
!= Scanner::tok_monetary ){
|
||||
// the LC_IDENTIFICATION section may also have a
|
||||
// LC_MONETARY token that will mess up the parsing
|
||||
if (next.token == Scanner::tok_ident) {
|
||||
while ((next = scanner_.next_token()).token
|
||||
!= Scanner::tok_end );
|
||||
next = scanner_.next_token();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_int_curr_symbol:
|
||||
next = scanner_.next_token();
|
||||
mon_st_.int_curr_symbol = convert_string (next.name);
|
||||
mon_st_.wint_curr_symbol = convert_wstring (next);
|
||||
break;
|
||||
|
||||
case Scanner::tok_currency_symbol:
|
||||
next = scanner_.next_token();
|
||||
mon_st_.currency_symbol = convert_string (next.name);
|
||||
mon_st_.wcurrency_symbol = convert_wstring (next);
|
||||
break;
|
||||
|
||||
case Scanner::tok_mon_decimal_point:
|
||||
next = scanner_.next_token();
|
||||
mon_st_.mon_decimal_point = convert_string (next.name);
|
||||
mon_st_.wmon_decimal_point = convert_wstring (next);
|
||||
break;
|
||||
|
||||
case Scanner::tok_mon_thousands_sep:
|
||||
next = scanner_.next_token();
|
||||
mon_st_.mon_thousands_sep = convert_string (next.name);
|
||||
mon_st_.wmon_thousands_sep = convert_wstring (next);
|
||||
break;
|
||||
|
||||
case Scanner::tok_mon_grouping:
|
||||
mon_st_.mon_grouping.clear();
|
||||
while ((next = scanner_.next_token()).token != Scanner::tok_nl)
|
||||
mon_st_.mon_grouping += std::strtol (next.name.c_str (), 0, 10);
|
||||
break;
|
||||
|
||||
case Scanner::tok_positive_sign:
|
||||
next = scanner_.next_token();
|
||||
mon_st_.positive_sign = convert_string (next.name);
|
||||
mon_st_.wpositive_sign = convert_wstring (next);
|
||||
break;
|
||||
|
||||
case Scanner::tok_negative_sign:
|
||||
next = scanner_.next_token();
|
||||
mon_st_.negative_sign = convert_string (next.name);
|
||||
mon_st_.wnegative_sign = convert_wstring (next);
|
||||
break;
|
||||
|
||||
case Scanner::tok_frac_digits:
|
||||
pcharint = &mon_out_.frac_digits [0];
|
||||
break;
|
||||
|
||||
case Scanner::tok_int_frac_digits:
|
||||
pcharint = &mon_out_.frac_digits [1 /* int'l */ ];
|
||||
break;
|
||||
|
||||
case Scanner::tok_p_cs_precedes:
|
||||
maxval = 1;
|
||||
pcharint = &mon_out_.p_cs_precedes [0];
|
||||
break;
|
||||
|
||||
case Scanner::tok_p_sep_by_space:
|
||||
maxval = 2;
|
||||
pcharint = &mon_out_.p_sep_by_space [0];
|
||||
break;
|
||||
|
||||
case Scanner::tok_n_cs_precedes:
|
||||
maxval = 1;
|
||||
pcharint = &mon_out_.n_cs_precedes [0];
|
||||
break;
|
||||
|
||||
case Scanner::tok_n_sep_by_space:
|
||||
maxval = 2;
|
||||
pcharint = &mon_out_.n_sep_by_space [0];
|
||||
break;
|
||||
|
||||
case Scanner::tok_p_sign_posn:
|
||||
maxval = 4;
|
||||
pcharint = &mon_out_.p_sign_posn [0];
|
||||
break;
|
||||
|
||||
case Scanner::tok_n_sign_posn:
|
||||
maxval = 4;
|
||||
pcharint = &mon_out_.n_sign_posn [0];
|
||||
break;
|
||||
|
||||
case Scanner::tok_int_p_cs_precedes:
|
||||
maxval = 1;
|
||||
pcharint = &mon_out_.p_cs_precedes [1 /* int'l */ ];
|
||||
break;
|
||||
|
||||
case Scanner::tok_int_p_sep_by_space:
|
||||
maxval = 2;
|
||||
pcharint = &mon_out_.p_sep_by_space [1 /* int'l */ ];
|
||||
break;
|
||||
|
||||
case Scanner::tok_int_n_cs_precedes:
|
||||
maxval = 1;
|
||||
pcharint = &mon_out_.n_cs_precedes [1 /* int'l */ ];
|
||||
break;
|
||||
|
||||
case Scanner::tok_int_n_sep_by_space:
|
||||
maxval = 2;
|
||||
pcharint = &mon_out_.n_sep_by_space [1 /* int'l */ ];
|
||||
break;
|
||||
|
||||
case Scanner::tok_int_p_sign_posn:
|
||||
maxval = 4;
|
||||
pcharint = &mon_out_.p_sign_posn [1 /* int'l */ ];
|
||||
break;
|
||||
|
||||
case Scanner::tok_int_n_sign_posn:
|
||||
maxval = 4;
|
||||
pcharint = &mon_out_.n_sign_posn [1 /* int'l */ ];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (pcharint) {
|
||||
next = scanner_.next_token ();
|
||||
|
||||
char *end = 0;
|
||||
const long val = std::strtol (next.name.c_str (), &end, 10);
|
||||
|
||||
if (next.name.empty () || *end || val < -1 || maxval < val) {
|
||||
// report as errors values outside the permitted range
|
||||
// (-1 indicates an unspecified value for a keyword)
|
||||
issue_diag (E_INVAL, true, &next,
|
||||
"expected integer in [0, %li], got: %s\n",
|
||||
maxval, next.name.c_str ());
|
||||
}
|
||||
else
|
||||
*pcharint = -1 == val ? CHAR_MAX : char (val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Def::create_format (char format [4],
|
||||
char sign_posn,
|
||||
char cs_precedes,
|
||||
char sep_by_space,
|
||||
bool is_positive)
|
||||
{
|
||||
switch (sign_posn) {
|
||||
// the international extension is not defined for this locale
|
||||
case CHAR_MAX:
|
||||
format [0] = CHAR_MAX;
|
||||
format [1] = CHAR_MAX;
|
||||
format [2] = CHAR_MAX;
|
||||
format [3] = CHAR_MAX;
|
||||
return;
|
||||
|
||||
case 0:
|
||||
// if sign_posn is 0 then we change the sign to "()", if sign is
|
||||
// not the empty string then issue a warning
|
||||
if (is_positive) {
|
||||
if (!mon_st_.positive_sign.empty())
|
||||
warnings_occurred_ =
|
||||
issue_diag (W_INVAL, false, 0,
|
||||
"invalid combination of positive_sign "
|
||||
"and p_sign_posn. Ignoring positive_sign")
|
||||
|| warnings_occurred_;
|
||||
mon_st_.positive_sign = "()";
|
||||
}
|
||||
else {
|
||||
if (!mon_st_.negative_sign.empty())
|
||||
warnings_occurred_ =
|
||||
issue_diag (W_INVAL, false, 0,
|
||||
"invalid combination of negative_sign "
|
||||
"and n_sign_posn. Ignoring negative_sign")
|
||||
|| warnings_occurred_;
|
||||
mon_st_.negative_sign = "()";
|
||||
}
|
||||
|
||||
// now construct the format
|
||||
format[0] = std::money_base::sign;
|
||||
if (cs_precedes == 0) {
|
||||
format[1] = std::money_base::value;
|
||||
format[2] = std::money_base::symbol;
|
||||
}
|
||||
else {
|
||||
format[1] = std::money_base::symbol;
|
||||
format[2] = std::money_base::value;
|
||||
}
|
||||
|
||||
break;
|
||||
case 1:
|
||||
format[0] = std::money_base::sign;
|
||||
if (cs_precedes == 0) {
|
||||
format[1] = std::money_base::value;
|
||||
format[2] = std::money_base::symbol;
|
||||
}
|
||||
else {
|
||||
format[1] = std::money_base::symbol;
|
||||
format[2] = std::money_base::value;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (cs_precedes == 0) {
|
||||
format[0] = std::money_base::value;
|
||||
format[1] = std::money_base::symbol;
|
||||
}
|
||||
else {
|
||||
format[0] = std::money_base::symbol;
|
||||
format[1] = std::money_base::value;
|
||||
}
|
||||
format[2] = std::money_base::sign;
|
||||
break;
|
||||
case 3:
|
||||
if (cs_precedes == 0) {
|
||||
format[0] = std::money_base::value;
|
||||
format[1] = std::money_base::sign;
|
||||
format[2] = std::money_base::symbol;
|
||||
}
|
||||
else {
|
||||
format[0] = std::money_base::sign;
|
||||
format[1] = std::money_base::symbol;
|
||||
format[2] = std::money_base::value;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (cs_precedes == 0) {
|
||||
format[0] = std::money_base::value;
|
||||
format[1] = std::money_base::symbol;
|
||||
format[2] = std::money_base::sign;
|
||||
}
|
||||
else {
|
||||
format[0] = std::money_base::symbol;
|
||||
format[1] = std::money_base::sign;
|
||||
format[2] = std::money_base::value;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// now put the space in the appropriate position
|
||||
if (sep_by_space == 0)
|
||||
format[3] = std::money_base::none;
|
||||
else if (sep_by_space == 1) {
|
||||
if (format[0] == std::money_base::value) {
|
||||
format[3] = format[2];
|
||||
format[2] = format[1];
|
||||
format[1] = std::money_base::space;
|
||||
}
|
||||
else if (format[2] == std::money_base::value) {
|
||||
format[3] = format[2];
|
||||
format[2] = std::money_base::space;
|
||||
}
|
||||
else if (format[0] == std::money_base::symbol) {
|
||||
format[3] = format[2];
|
||||
format[2] = format[1];
|
||||
format[1] = std::money_base::space;
|
||||
}
|
||||
else {
|
||||
format[3] = format[2];
|
||||
format[2] = std::money_base::space;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (format[0] == std::money_base::value) {
|
||||
format[3] = format[2];
|
||||
format[2] = std::money_base::space;
|
||||
}
|
||||
else if (format[2] == std::money_base::value) {
|
||||
format[3] = format[2];
|
||||
format[2] = format[1];
|
||||
format[1] = std::money_base::space;
|
||||
}
|
||||
else if (format[0] == std::money_base::symbol) {
|
||||
format[3] = format[2];
|
||||
format[2] = std::money_base::space;
|
||||
}
|
||||
else {
|
||||
format[3] = format[2];
|
||||
format[2] = format[1];
|
||||
format[1] = std::money_base::space;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Def::write_monetary (std::string dir_name)
|
||||
{
|
||||
assert (!dir_name.empty());
|
||||
|
||||
if (mon_written_)
|
||||
return;
|
||||
|
||||
if (!mon_def_found_) {
|
||||
issue_diag (I_SKIP, false, 0,
|
||||
"%s section not found, skipping\n", lc_name);
|
||||
return;
|
||||
}
|
||||
|
||||
// write out all the information in the LC_MONETARY category
|
||||
(dir_name += _RWSTD_PATH_SEP) += lc_name;
|
||||
|
||||
issue_diag (I_OPENWR, false, 0, "writing %s\n", dir_name.c_str ());
|
||||
|
||||
std::ofstream out (dir_name.c_str(), std::ios::binary);
|
||||
out.exceptions (std::ios::failbit | std::ios::badbit);
|
||||
|
||||
_RW::__rw_punct_t punct;
|
||||
|
||||
// calculate the offsets for the mon_punct structure
|
||||
punct.decimal_point_off [1] = 0;
|
||||
|
||||
punct.thousands_sep_off [1] =
|
||||
punct.decimal_point_off [1]
|
||||
+ (mon_st_.wmon_decimal_point.size () + 1) * sizeof (wchar_t);
|
||||
|
||||
punct.decimal_point_off [0] =
|
||||
punct.thousands_sep_off [1]
|
||||
+ (mon_st_.wmon_thousands_sep.size () + 1) * sizeof (wchar_t);
|
||||
|
||||
punct.thousands_sep_off [0] =
|
||||
punct.decimal_point_off [0]
|
||||
+ mon_st_.mon_decimal_point.size () + 1;
|
||||
|
||||
punct.grouping_off =
|
||||
punct.thousands_sep_off [0]
|
||||
+ mon_st_.mon_thousands_sep.size () + 1;
|
||||
|
||||
punct.punct_ext_off =
|
||||
punct.grouping_off
|
||||
+ mon_st_.mon_grouping.size () + 1;
|
||||
|
||||
// compute the alignment requirement of any offset member
|
||||
const std::size_t align = sizeof punct.punct_ext_off;
|
||||
|
||||
// align the offset of the extension struct on the required boundary
|
||||
const std::size_t misalign = punct.punct_ext_off % align;
|
||||
|
||||
// compute the amount of padding between the two structs
|
||||
const std::size_t pad = misalign ? align - misalign : 0;
|
||||
|
||||
punct.punct_ext_off += pad;
|
||||
|
||||
mon_out_.curr_symbol_off [1][1] = 0;
|
||||
|
||||
mon_out_.curr_symbol_off [0][1] =
|
||||
mon_out_.curr_symbol_off [1][1]
|
||||
+ (mon_st_.wint_curr_symbol.size () + 1) * sizeof (wchar_t);
|
||||
|
||||
mon_out_.positive_sign_off [1] =
|
||||
mon_out_.curr_symbol_off [0][1]
|
||||
+ (mon_st_.wcurrency_symbol.size () + 1) * sizeof (wchar_t);
|
||||
|
||||
mon_out_.negative_sign_off [1] =
|
||||
mon_out_.positive_sign_off [1]
|
||||
+ (mon_st_.wpositive_sign.size () + 1) * sizeof (wchar_t);
|
||||
|
||||
|
||||
// calculate all the narrow character string offsets
|
||||
mon_out_.curr_symbol_off [1][0] =
|
||||
mon_out_.negative_sign_off [1]
|
||||
+ (mon_st_.wnegative_sign.size () + 1) * sizeof (wchar_t);
|
||||
|
||||
mon_out_.curr_symbol_off [0][0] =
|
||||
mon_out_.curr_symbol_off [1][0]
|
||||
+ mon_st_.int_curr_symbol.size () + 1;
|
||||
|
||||
mon_out_.positive_sign_off [0] =
|
||||
mon_out_.curr_symbol_off [0][0]
|
||||
+ mon_st_.currency_symbol.size() + 1;
|
||||
|
||||
mon_out_.negative_sign_off [0] =
|
||||
mon_out_.positive_sign_off [0]
|
||||
+ mon_st_.positive_sign.size () + 1;
|
||||
|
||||
mon_out_.codeset_off =
|
||||
mon_out_.negative_sign_off [0]
|
||||
+ mon_st_.negative_sign.size () + 1;
|
||||
|
||||
mon_out_.charmap_off =
|
||||
mon_out_.codeset_off
|
||||
+ charmap_.get_code_set_name ().size () + 1;
|
||||
|
||||
issue_diag (I_WRITE, false, 0,
|
||||
"%s layout:\n"
|
||||
"__rw_punct_t {\n"
|
||||
" decimal_point_off[] = { %u, %u }\n"
|
||||
" thousand_sep_off[] = { %u, %u }\n"
|
||||
" grouping_off = %u\n"
|
||||
" ext_off = %u\n"
|
||||
"}\n__rw_moneypunct_t {\n"
|
||||
" curr_symbol_off[][] = { { %u, %u }, { %u, %u } }\n"
|
||||
" positive_sign_off[] = { %u, %u }\n"
|
||||
" negative_sign_off[] = { %u, %u }\n"
|
||||
" codeset_off = %u\n"
|
||||
" charmap_off = %u\n"
|
||||
"}\n",
|
||||
lc_name,
|
||||
punct.decimal_point_off [0],
|
||||
punct.decimal_point_off [1],
|
||||
punct.thousands_sep_off [0],
|
||||
punct.thousands_sep_off [1],
|
||||
punct.grouping_off,
|
||||
punct.punct_ext_off,
|
||||
mon_out_.curr_symbol_off [0][0],
|
||||
mon_out_.curr_symbol_off [0][1],
|
||||
mon_out_.curr_symbol_off [1][0],
|
||||
mon_out_.curr_symbol_off [1][1],
|
||||
mon_out_.positive_sign_off [0],
|
||||
mon_out_.negative_sign_off [1],
|
||||
mon_out_.codeset_off,
|
||||
mon_out_.charmap_off);
|
||||
|
||||
// construct the pos_format and neg_format
|
||||
create_format (mon_out_.pos_format[0], mon_out_.p_sign_posn[0],
|
||||
mon_out_.p_cs_precedes[0], mon_out_.p_sep_by_space[0],
|
||||
true);
|
||||
|
||||
create_format (mon_out_.neg_format[0], mon_out_.n_sign_posn[0],
|
||||
mon_out_.n_cs_precedes[0], mon_out_.n_sep_by_space[0],
|
||||
false);
|
||||
|
||||
create_format (mon_out_.pos_format[1], mon_out_.p_sign_posn[1],
|
||||
mon_out_.p_cs_precedes[1], mon_out_.p_sep_by_space[1],
|
||||
true);
|
||||
|
||||
create_format (mon_out_.neg_format[1], mon_out_.n_sign_posn[1],
|
||||
mon_out_.n_cs_precedes[1], mon_out_.n_sep_by_space[1],
|
||||
false);
|
||||
|
||||
// write out the mon_punct structure
|
||||
out.write ((char*)&punct, sizeof punct);
|
||||
|
||||
// write out the strings in the punct structure
|
||||
out.write ((const char*)mon_st_.wmon_decimal_point.c_str(),
|
||||
(mon_st_.wmon_decimal_point.size() + 1) * sizeof(wchar_t));
|
||||
out.write ((const char*)mon_st_.wmon_thousands_sep.c_str(),
|
||||
(mon_st_.wmon_thousands_sep.size() + 1) * sizeof(wchar_t));
|
||||
|
||||
out << mon_st_.mon_decimal_point << std::ends
|
||||
<< mon_st_.mon_thousands_sep << std::ends
|
||||
<< mon_st_.mon_grouping << std::ends;
|
||||
|
||||
// pad the structure up to the next alignment boundary
|
||||
out.write ("\0\0\0\0\0\0\0\0", pad);
|
||||
|
||||
// now write out the monetary offset extension struct
|
||||
out.write ((char*)&mon_out_, sizeof (mon_out_));
|
||||
|
||||
// write the wide character strings
|
||||
out.write ((const char*)mon_st_.wint_curr_symbol.c_str(),
|
||||
(mon_st_.wint_curr_symbol.size() + 1) * sizeof(wchar_t));
|
||||
out.write ((const char*)mon_st_.wcurrency_symbol.c_str(),
|
||||
(mon_st_.wcurrency_symbol.size() + 1) * sizeof(wchar_t));
|
||||
out.write ((const char*)mon_st_.wpositive_sign.c_str(),
|
||||
(mon_st_.wpositive_sign.size() + 1) * sizeof(wchar_t));
|
||||
out.write ((const char*)mon_st_.wnegative_sign.c_str(),
|
||||
(mon_st_.wnegative_sign.size() + 1) * sizeof(wchar_t));
|
||||
|
||||
// write the narrow character strings
|
||||
out << mon_st_.int_curr_symbol << std::ends
|
||||
<< mon_st_.currency_symbol << std::ends
|
||||
<< mon_st_.positive_sign << std::ends
|
||||
<< mon_st_.negative_sign << std::ends
|
||||
<< charmap_.get_code_set_name() << std::ends
|
||||
<< charmap_.get_charmap_name() << std::ends;
|
||||
}
|
||||
280
extern/stdcxx/4.2.1/util/numeric.cpp
vendored
Normal file
280
extern/stdcxx/4.2.1/util/numeric.cpp
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* numeric.cpp
|
||||
*
|
||||
* $Id: numeric.cpp 448754 2006-09-22 00:42:16Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "def.h" // for Def
|
||||
#include "diagnostic.h" // for issue_diag()
|
||||
#include "path.h" // for get_pathname()
|
||||
#include "scanner.h" // for scanner
|
||||
|
||||
#include <cassert> // for assert()
|
||||
#include <cstdlib> // for atoi()
|
||||
#include <fstream> // for ofstream
|
||||
|
||||
|
||||
static const char lc_name[] = "LC_NUMERIC";
|
||||
|
||||
|
||||
void Def::process_numeric ()
|
||||
{
|
||||
issue_diag (I_STAGE, false, 0, "processing %s section\n", lc_name);
|
||||
|
||||
// nesting level
|
||||
int nesting_level = 0;
|
||||
|
||||
num_def_found_ = true;
|
||||
|
||||
while ((next = scanner_.next_token()).token != Scanner::tok_numeric) {
|
||||
|
||||
switch (next.token) {
|
||||
|
||||
case Scanner::tok_end:
|
||||
next = scanner_.next_token();
|
||||
if (next.token == Scanner::tok_numeric) {
|
||||
// end of numeric block
|
||||
if (nesting_level == 0)
|
||||
return;
|
||||
|
||||
nesting_level--;
|
||||
scanner_.close ();
|
||||
} else
|
||||
issue_diag (E_SYNTAX, true, &next,
|
||||
"wrong section name in END directive\n");
|
||||
|
||||
break;
|
||||
|
||||
case Scanner::tok_copy: {
|
||||
next = scanner_.next_token();
|
||||
if (next.token != Scanner::tok_string)
|
||||
issue_diag (E_SYNTAX, true, &next,
|
||||
"expected string following \"copy\" directive\n");
|
||||
|
||||
// bump up the nesting level
|
||||
nesting_level++;
|
||||
|
||||
issue_diag (I_STAGE, false, 0, "processing copy directive\n");
|
||||
|
||||
// open the file
|
||||
scanner_.open (get_pathname (strip_quotes (next.name), next.file));
|
||||
|
||||
// get comment char and escape char;
|
||||
// these informations are stored by the scanner
|
||||
while ((next = scanner_.next_token ()).token
|
||||
!= Scanner::tok_numeric ){
|
||||
// the LC_IDENTIFICATION section may also have a
|
||||
// LC_NUMERIC token that will mess up the parsing
|
||||
if (next.token == Scanner::tok_ident) {
|
||||
while ((next = scanner_.next_token()).token
|
||||
!= Scanner::tok_end );
|
||||
next = scanner_.next_token();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_decimal_point:
|
||||
next = scanner_.next_token();
|
||||
num_st_.decimal_point = convert_string (next.name);
|
||||
num_st_.wdecimal_point = convert_wstring (next);
|
||||
break;
|
||||
|
||||
case Scanner::tok_thousands_sep:
|
||||
next = scanner_.next_token();
|
||||
num_st_.thousands_sep = convert_string (next.name);
|
||||
num_st_.wthousands_sep = convert_wstring (next);
|
||||
break;
|
||||
|
||||
case Scanner::tok_grouping:
|
||||
// convert the grouping digits from ascii to integers before
|
||||
// adding them to the grouping string
|
||||
num_st_.grouping.clear();
|
||||
while ((next = scanner_.next_token()).token
|
||||
!= Scanner::tok_nl)
|
||||
num_st_.grouping += std::atoi(next.name.c_str());
|
||||
break;
|
||||
|
||||
case Scanner::tok_truename:
|
||||
next = scanner_.next_token();
|
||||
num_st_.truename = convert_string (next.name);
|
||||
num_st_.wtruename = convert_wstring (next);
|
||||
break;
|
||||
|
||||
case Scanner::tok_falsename:
|
||||
next = scanner_.next_token();
|
||||
num_st_.falsename = convert_string (next.name);
|
||||
num_st_.wfalsename = convert_wstring (next);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Def::write_numeric (std::string dir_name)
|
||||
{
|
||||
assert (!dir_name.empty ());
|
||||
|
||||
if (num_written_)
|
||||
return;
|
||||
|
||||
if (!num_def_found_) {
|
||||
issue_diag (I_SKIP, false, 0,
|
||||
"%s section not found, skipping\n", lc_name);
|
||||
return;
|
||||
}
|
||||
|
||||
(dir_name += _RWSTD_PATH_SEP) += lc_name;
|
||||
|
||||
issue_diag (I_OPENWR, false, 0, "writing %s\n", dir_name.c_str ());
|
||||
|
||||
std::ofstream out (dir_name.c_str (), std::ios::binary);
|
||||
out.exceptions (std::ios::failbit | std::ios::badbit);
|
||||
|
||||
// calculate the offsets of members of the num_punct struct
|
||||
|
||||
// start with wide strings to simplify dealing with their alignment
|
||||
num_punct_out_.decimal_point_off [1] = 0;
|
||||
|
||||
num_punct_out_.thousands_sep_off [1] =
|
||||
num_punct_out_.decimal_point_off [1]
|
||||
+ (num_st_.wdecimal_point.size () + 1) * sizeof (wchar_t);
|
||||
|
||||
num_punct_out_.decimal_point_off [0] =
|
||||
num_punct_out_.thousands_sep_off [1]
|
||||
+ (num_st_.wthousands_sep.size() + 1) * sizeof (wchar_t);
|
||||
|
||||
num_punct_out_.thousands_sep_off [0] =
|
||||
num_punct_out_.decimal_point_off [0]
|
||||
+ num_st_.decimal_point.size () + 1;
|
||||
|
||||
num_punct_out_.grouping_off =
|
||||
num_punct_out_.thousands_sep_off [0]
|
||||
+ num_st_.thousands_sep.size () + 1;
|
||||
|
||||
num_punct_out_.punct_ext_off =
|
||||
num_punct_out_.grouping_off
|
||||
+ num_st_.grouping.size () + 1;
|
||||
|
||||
// compute the alignment requirement of any offset member
|
||||
const std::size_t align = sizeof num_punct_out_.punct_ext_off;
|
||||
|
||||
// align the offset of the extension struct on the required boundary
|
||||
const std::size_t misalign = num_punct_out_.punct_ext_off % align;
|
||||
|
||||
// compute the amount of padding between the two structs
|
||||
const std::size_t pad = misalign ? align - misalign : 0;
|
||||
|
||||
num_punct_out_.punct_ext_off += pad;
|
||||
|
||||
// calculate the offsets of members of the numeric extension struct
|
||||
|
||||
num_out_.truename_off [1] = 0;
|
||||
|
||||
num_out_.falsename_off [1] =
|
||||
num_out_.truename_off [1]
|
||||
+ (num_st_.wtruename.size() + 1) * sizeof (wchar_t);
|
||||
|
||||
num_out_.truename_off [0] =
|
||||
num_out_.falsename_off [1]
|
||||
+ (num_st_.wfalsename.size() + 1) * sizeof (wchar_t);
|
||||
|
||||
num_out_.falsename_off [0] =
|
||||
num_out_.truename_off [0]
|
||||
+ num_st_.truename.size() + 1;
|
||||
|
||||
num_out_.codeset_off =
|
||||
num_out_.falsename_off [0]
|
||||
+ num_st_.falsename.size() + 1;
|
||||
|
||||
num_out_.charmap_off =
|
||||
num_out_.codeset_off
|
||||
+ charmap_.get_code_set_name().size() + 1;
|
||||
|
||||
issue_diag (I_WRITE, false, 0,
|
||||
"%s layout:\n"
|
||||
"__rw_punct_t {\n"
|
||||
" decimal_point_off[] = { %u, %u }\n"
|
||||
" thousand_sep_off[] = { %u, %u }\n"
|
||||
" grouping_off = %u\n"
|
||||
" ext_off = %u\n"
|
||||
"}\n__rw_numpunct_t {\n"
|
||||
" falsename_off[] = { %u, %u }\n"
|
||||
" truename_off[] = { %u, %u }\n"
|
||||
" codeset_off = %u\n"
|
||||
" charmap_off = %u\n"
|
||||
"}\n",
|
||||
lc_name,
|
||||
num_punct_out_.decimal_point_off [0],
|
||||
num_punct_out_.decimal_point_off [1],
|
||||
num_punct_out_.thousands_sep_off [0],
|
||||
num_punct_out_.thousands_sep_off [1],
|
||||
num_punct_out_.grouping_off,
|
||||
num_punct_out_.punct_ext_off,
|
||||
num_out_.falsename_off [0],
|
||||
num_out_.falsename_off [1],
|
||||
num_out_.truename_off [0],
|
||||
num_out_.truename_off [1],
|
||||
num_out_.codeset_off,
|
||||
num_out_.charmap_off);
|
||||
|
||||
// write the num_punct struct
|
||||
out.write ((char*)&num_punct_out_, sizeof (num_punct_out_));
|
||||
|
||||
// write out the strings in the num_punct struct
|
||||
out.write ((const char*)num_st_.wdecimal_point.c_str (),
|
||||
(num_st_.wdecimal_point.size() + 1) * sizeof (wchar_t));
|
||||
out.write ((const char*)num_st_.wthousands_sep.c_str(),
|
||||
(num_st_.wthousands_sep.size() + 1) * sizeof(wchar_t));
|
||||
|
||||
out << num_st_.decimal_point << std::ends
|
||||
<< num_st_.thousands_sep << std::ends
|
||||
<< num_st_.grouping << std::ends;
|
||||
|
||||
// pad the structure up to the next alignment boundary
|
||||
out.write ("\0\0\0\0\0\0\0\0", pad);
|
||||
|
||||
// write the numeric offset extension struct
|
||||
out.write ((char*)&num_out_, sizeof (num_out_));
|
||||
|
||||
// write all the wide character strings
|
||||
out.write ((const char*)num_st_.wtruename.c_str(),
|
||||
(num_st_.wtruename.size() + 1) * sizeof (wchar_t));
|
||||
out.write ((const char*)num_st_.wfalsename.c_str(),
|
||||
(num_st_.wfalsename.size() + 1) * sizeof (wchar_t));
|
||||
|
||||
|
||||
// write the narrow strings and codeset name
|
||||
out << num_st_.truename << std::ends
|
||||
<< num_st_.falsename << std::ends
|
||||
<< charmap_.get_code_set_name() << std::ends
|
||||
<< charmap_.get_charmap_name() << std::ends;
|
||||
|
||||
out.close();
|
||||
}
|
||||
360
extern/stdcxx/4.2.1/util/output.cpp
vendored
Normal file
360
extern/stdcxx/4.2.1/util/output.cpp
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* output.cpp - Definitions of the result parsing subsystem
|
||||
*
|
||||
* $Id: output.cpp 580483 2007-09-28 20:55:52Z sebor $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h> /* for printf, puts, FILE, f* */
|
||||
#include <stdlib.h> /* for exit, free */
|
||||
#include <string.h> /* for str* */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "cmdopt.h"
|
||||
#include "display.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "output.h"
|
||||
|
||||
#ifndef ENOENT
|
||||
# define ENOENT 2
|
||||
#endif /* ENOENT */
|
||||
|
||||
|
||||
/**
|
||||
Parses contents of the open file handle data for test target_name.
|
||||
|
||||
This method reads the data file handle, looking for the output summary from
|
||||
the test driver. The results of this search (and the parsing of this
|
||||
summary, if found) are stored in the status structure.
|
||||
|
||||
@param data pointer to file structure for output file being parsed
|
||||
@param status status object to record results in.
|
||||
*/
|
||||
static void
|
||||
check_test (FILE* data, struct target_status* status)
|
||||
{
|
||||
unsigned r_lvl = 0; /* diagnostic severity level */
|
||||
unsigned r_active = 0; /* number of active diagnostics */
|
||||
unsigned r_total = 0; /* total number of diagnostics */
|
||||
|
||||
int fmt_ok = 0; /* is output format okay? */
|
||||
|
||||
unsigned fsm = 0; /* state */
|
||||
char tok; /* current character */
|
||||
|
||||
const char* const target_name = get_target ();
|
||||
|
||||
assert (0 != target_name);
|
||||
assert (0 != data);
|
||||
assert (0 != status);
|
||||
|
||||
tok = fgetc (data);
|
||||
|
||||
if (feof (data)) {
|
||||
/* target produced no output (regression test?) */
|
||||
status->status = ST_NO_OUTPUT;
|
||||
return;
|
||||
}
|
||||
|
||||
for ( ; fsm < 6 && !feof (data); tok = fgetc (data)) {
|
||||
switch (tok) {
|
||||
case '\n':
|
||||
fsm = 1;
|
||||
break;
|
||||
case '#':
|
||||
fsm = (1 == fsm) ? 2 : 0;
|
||||
break;
|
||||
case ' ':
|
||||
fsm = (2 == fsm) ? 3 : ((4 == fsm) ? 5 : 0);
|
||||
break;
|
||||
case '|':
|
||||
fsm = (3 == fsm) ? 4 : 0;
|
||||
break;
|
||||
case '(':
|
||||
if (5 == fsm) {
|
||||
fseek (data, -6, SEEK_CUR);
|
||||
fsm++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fsm = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!feof (data)) {
|
||||
while (3 == fscanf (data, "# | (S%u) %*s | %u | %u | %*u%% |\n",
|
||||
&r_lvl, &r_active, &r_total)) {
|
||||
if (6 < r_lvl) {
|
||||
/* The 0.new tests produces errors, and are all
|
||||
expected to be active, so invert the total */
|
||||
if (8 == r_lvl && 0 == strcmp (target_name, "0.new"))
|
||||
r_active = r_total-r_active;
|
||||
status->failed += r_active;
|
||||
status->assert += r_total;
|
||||
if ( status->failed < r_active
|
||||
|| status->assert < r_total
|
||||
|| (unsigned int)-1 == status->assert) {
|
||||
status->status = ST_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (1 < r_lvl) {
|
||||
status->t_warn += r_active;
|
||||
if (status->t_warn < r_active) {
|
||||
status->t_warn = (unsigned int)-1;
|
||||
}
|
||||
}
|
||||
fmt_ok = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fmt_ok)
|
||||
status->status = ST_FORMAT;
|
||||
}
|
||||
|
||||
/**
|
||||
Parses contents of the open file handle data for test target_name.
|
||||
|
||||
This method is a reimplementation of check_test (). The difference between
|
||||
this method and check_test () is how it parses the results. This version
|
||||
parses compatability layer output, rather than the test driver output.
|
||||
|
||||
@param data pointer to file structure for output file being parsed
|
||||
@see check_test ()
|
||||
*/
|
||||
static void
|
||||
check_compat_test (FILE* data, struct target_status* status)
|
||||
{
|
||||
int read = 0;
|
||||
unsigned fsm = 0;
|
||||
char tok;
|
||||
|
||||
assert (0 != data);
|
||||
assert (0 != status);
|
||||
|
||||
tok = fgetc (data);
|
||||
|
||||
if (feof (data)) {
|
||||
/* target produced no output (regression test?) */
|
||||
status->status = ST_NO_OUTPUT;
|
||||
return;
|
||||
}
|
||||
|
||||
for ( ; !feof (data); tok = fgetc (data)) {
|
||||
switch (tok) {
|
||||
case '\n':
|
||||
fsm = 1;
|
||||
break;
|
||||
case '#':
|
||||
if (1 == fsm || 2 == fsm)
|
||||
++fsm;
|
||||
else
|
||||
fsm = 0;
|
||||
break;
|
||||
case ' ':
|
||||
if (3 == fsm)
|
||||
++fsm;
|
||||
else
|
||||
fsm = 0;
|
||||
break;
|
||||
case 'W':
|
||||
if (4 == fsm && !feof (data)) /* leading "## W" eaten */
|
||||
read = fscanf (data, "arnings = %u\n## Assertions = %u\n"
|
||||
"## FailedAssertions = %u",
|
||||
&status->t_warn, &status->assert, &status->failed);
|
||||
default:
|
||||
fsm = 0;
|
||||
}
|
||||
}
|
||||
if (3 != read) {
|
||||
status->status = ST_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Arbitrary constant controling static read buffer size.
|
||||
|
||||
@see check_example ()
|
||||
*/
|
||||
#define DELTA_BUF_LEN 64
|
||||
|
||||
/**
|
||||
Parses output file out_name for the example target_name.
|
||||
|
||||
This method tries to compare out_name against a reference output file and
|
||||
reports the result of the comparison. If the comparison fails to result in
|
||||
a match, status->status is set to the appropriate error state. The
|
||||
reference file name is generated by the reference_name function.
|
||||
|
||||
Reference file locations:
|
||||
- [data_dir]/manual/out/[target_name].out
|
||||
- [data_dir]/tutorial/out/[target_name].out
|
||||
|
||||
@todo add logic to handle differing line endings (CR vs LF vs CRLF)
|
||||
|
||||
@param out_name the name of the output file
|
||||
@param fout pointer to file structure for output file being parsed
|
||||
@param status status object to record results in.
|
||||
@see reference_name
|
||||
*/
|
||||
static void
|
||||
check_example (const char* const data_dir, char* const out_name, FILE* fout,
|
||||
struct target_status* status)
|
||||
{
|
||||
struct stat file_info;
|
||||
char* ref_name;
|
||||
|
||||
FILE* fref; /* reference file (expected output) */
|
||||
|
||||
assert (0 != out_name);
|
||||
assert (0 != fout);
|
||||
assert (0 != status);
|
||||
|
||||
/* Mark as an example by setting assertions to -1 */
|
||||
status->assert = (unsigned)-1;
|
||||
|
||||
/* Try data_dir/manual/out/target_name.out */
|
||||
ref_name = reference_name (data_dir, "manual", "out");
|
||||
|
||||
if (0 > stat (ref_name, &file_info)) {
|
||||
if (ENOENT != errno) {
|
||||
warn ("stat (%s) error: %s\n", exe_name, ref_name,
|
||||
strerror (errno));
|
||||
status->status = ST_BAD_REF;
|
||||
free (ref_name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If that doesn't exist, try
|
||||
data_dir/tutorial/out/target_name.out */
|
||||
free (ref_name);
|
||||
ref_name = reference_name (data_dir, "tutorial", "out");
|
||||
|
||||
if (0 > stat (ref_name, &file_info)) {
|
||||
if (ENOENT != errno) {
|
||||
warn ("stat (%s) error: %s\n", exe_name, ref_name,
|
||||
strerror (errno));
|
||||
status->status = ST_BAD_REF;
|
||||
}
|
||||
else
|
||||
status->status = ST_NO_REF;
|
||||
|
||||
free (ref_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fref = fopen (ref_name, "r");
|
||||
|
||||
if (0 == fref) {
|
||||
int cache = errno; /* caching errno, as puts could alter it */
|
||||
if (ENOENT != cache)
|
||||
warn ("Error opening %s: %s\n", ref_name, strerror (cache));
|
||||
status->status = ST_BAD_REF;
|
||||
}
|
||||
else {
|
||||
int match = 1; /* do the two files match? */
|
||||
|
||||
while (!feof (fref) && !feof (fout)) {
|
||||
|
||||
char buf [2][DELTA_BUF_LEN];
|
||||
|
||||
size_t nread [2]; /* bytes read from the output/ref file */
|
||||
|
||||
/* First, read a block from the files into the buffer */
|
||||
nread [0] = fread (buf [0], 1, sizeof buf [0], fout);
|
||||
if (ferror (fout)) {
|
||||
warn ("Error reading %s: %s\n", out_name, strerror (errno));
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
nread [1] = fread (buf [1], 1, sizeof buf [1], fref);
|
||||
if (ferror (fref)) {
|
||||
warn ("Error reading %s: %s\n", ref_name, strerror (errno));
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Then, check if the amount of data read or the state of the
|
||||
files differs
|
||||
*/
|
||||
if (nread [0] != nread [1] || feof (fref) != feof (fout)) {
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Finally, check if the contents of the buffers differ */
|
||||
if (0 != memcmp (buf [0], buf [1], nread [0])) {
|
||||
match = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match)
|
||||
status->status = ST_BAD_OUTPUT;
|
||||
|
||||
fclose (fref);
|
||||
}
|
||||
free (ref_name);
|
||||
}
|
||||
|
||||
void
|
||||
parse_output (const struct target_opts* options, struct target_status* status)
|
||||
{
|
||||
char* out_name;
|
||||
FILE* data;
|
||||
|
||||
assert (0 != status);
|
||||
assert (0 != options->argv [0]);
|
||||
out_name = output_name (options->argv [0]);
|
||||
|
||||
data = fopen (out_name, "r");
|
||||
|
||||
if (0 == data) {
|
||||
if (ENOENT != errno)
|
||||
warn ("Error opening %s: %s\n", out_name, strerror (errno));
|
||||
status->status = ST_NO_OUTPUT;
|
||||
}
|
||||
else {
|
||||
if (0 == options->data_dir || '\0' == *options->data_dir) {
|
||||
/* If there is not an input directory, look at the assertion tags */
|
||||
|
||||
if (!options->compat)
|
||||
check_test (data, status);
|
||||
else
|
||||
check_compat_test (data, status);
|
||||
}
|
||||
else {
|
||||
/* Otherwise, diff against the output file */
|
||||
check_example (options->data_dir, out_name, data, status);
|
||||
}
|
||||
fclose (data);
|
||||
}
|
||||
free (out_name);
|
||||
}
|
||||
45
extern/stdcxx/4.2.1/util/output.h
vendored
Normal file
45
extern/stdcxx/4.2.1/util/output.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* output.h - Interface declaration for the result parsing subsystem
|
||||
*
|
||||
* $Id: output.h 452253 2006-10-02 23:08:06Z sebor $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef OUTPUT_H
|
||||
#define OUTPUT_H
|
||||
|
||||
/**
|
||||
Umbrella (dispatch) function to analyse the (saved) output of target.
|
||||
|
||||
This file opens the saved output for parsing. If this fails,
|
||||
the status structure is updated to reflect this. Otherwise, check_test (),
|
||||
check_compat_test (), or check_example () is called to parse the output
|
||||
file.
|
||||
|
||||
@param target the path to the executable that generated the output file
|
||||
being parsed.
|
||||
@param status status object to record results in.
|
||||
*/
|
||||
void
|
||||
parse_output (const struct target_opts* options, struct target_status* status);
|
||||
|
||||
#endif /* OUTPUT_H */
|
||||
280
extern/stdcxx/4.2.1/util/path.cpp
vendored
Normal file
280
extern/stdcxx/4.2.1/util/path.cpp
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* path.cpp
|
||||
*
|
||||
* $Id: path.cpp 648752 2008-04-16 17:01:56Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 1994-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# ifdef __linux__
|
||||
// for symlink()
|
||||
# ifndef _XOPEN_SOURCE
|
||||
# define _XOPEN_SOURCE
|
||||
# endif
|
||||
# ifndef _XOPEN_SOURCE_EXTENDED
|
||||
# define _XOPEN_SOURCE_EXTENDED
|
||||
# endif
|
||||
# endif // __linux__
|
||||
|
||||
# include <unistd.h> // for getcwd()
|
||||
# include <sys/stat.h> // for struct stat, stat()
|
||||
#else
|
||||
# include <direct.h> // for struct _stat
|
||||
# include <io.h>
|
||||
# include <windows.h> // for _getcwd()
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h> // for struct stat, stat()
|
||||
#endif // _MSC_VER
|
||||
|
||||
|
||||
#include "path.h"
|
||||
|
||||
#include "diagnostic.h" // for issue_diag()
|
||||
|
||||
#include <cassert> // for assert()
|
||||
#include <cerrno> // for ERANGE
|
||||
#include <cstdlib> // for getenv()
|
||||
#include <cstring> // for strerror()
|
||||
#include <string> // for string
|
||||
|
||||
|
||||
static char* get_cwd (char* s, std::size_t l)
|
||||
{
|
||||
#if !defined (_MSC_VER)
|
||||
return getcwd (s, l);
|
||||
#else
|
||||
return _getcwd (s, l);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
||||
void
|
||||
create_symlink (const std::string &dir,
|
||||
const std::string &xname,
|
||||
const std::string &sname)
|
||||
{
|
||||
int ret = 0;
|
||||
char* pret = 0;
|
||||
char buf [1024];
|
||||
|
||||
if (dir.size ()) {
|
||||
pret = get_cwd (buf, 1024);
|
||||
if (pret == 0) {
|
||||
issue_diag (213, true, 0,
|
||||
"could not retrieve current working directory\n") ;
|
||||
}
|
||||
|
||||
ret = chdir (dir.c_str ());
|
||||
if (ret == -1)
|
||||
issue_diag (214, false, 0, "could not change directory to %s\n",
|
||||
dir.c_str ()) ;
|
||||
}
|
||||
|
||||
ret = symlink(xname.c_str(), sname.c_str());
|
||||
|
||||
#ifdef EEXIST
|
||||
|
||||
if (ret == -1 && errno != EEXIST) {
|
||||
issue_diag (215, false, 0,
|
||||
"could not create symbolic link to %s "
|
||||
"locale database (%s)\n",
|
||||
xname.c_str (), std::strerror (errno)) ;
|
||||
}
|
||||
|
||||
#endif // EEXIST
|
||||
|
||||
// go back to previous wd
|
||||
if (dir.size ()) {
|
||||
chdir (pret);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
|
||||
inline int
|
||||
filemode (const char *path)
|
||||
{
|
||||
assert (0 != path);
|
||||
|
||||
struct stat buf;
|
||||
return stat (path, &buf) ? 0 : buf.st_mode;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
get_pathname (const std::string &fname,
|
||||
const std::string &other /* = std::string () */)
|
||||
{
|
||||
// use absolute path as given by fname
|
||||
#if !defined (_MSC_VER)
|
||||
if (fname.size () && _RWSTD_PATH_SEP == fname [0])
|
||||
#else
|
||||
if (fname.size () &&
|
||||
fname [1] && fname [1] == ':' &&
|
||||
fname [2] && fname [2] == _RWSTD_PATH_SEP)
|
||||
#endif
|
||||
return fname;
|
||||
|
||||
std::string pathname;
|
||||
std::string dir_other (
|
||||
other.substr (0,other.rfind (_RWSTD_PATH_SEP) + 1));
|
||||
|
||||
// OR use the path given through "other", be it relative or absolute
|
||||
#if !defined (_MSC_VER)
|
||||
if (other.size () && _RWSTD_PATH_SEP == other [0]) {
|
||||
#else
|
||||
if (other.size () &&
|
||||
other [1] && other [1] == ':' &&
|
||||
other [2] && other [2] == _RWSTD_PATH_SEP) {
|
||||
#endif
|
||||
// other is an absolute path; compose dirname(other) + fname
|
||||
(pathname += dir_other) += fname;
|
||||
|
||||
} else {
|
||||
pathname.resize (1024);
|
||||
|
||||
// other is a relative path; compose cwd() + dirname(other) + fname
|
||||
while (!get_cwd (&pathname [0], pathname.size ())) {
|
||||
if (ERANGE != errno) {
|
||||
issue_diag (213, true, 0,
|
||||
"could not retrieve current working directory\n");
|
||||
return fname;
|
||||
}
|
||||
// buffer too small, reallocate
|
||||
pathname.resize (pathname.size () * 2);
|
||||
}
|
||||
|
||||
pathname.resize (std::strlen (pathname.data ()));
|
||||
|
||||
if (pathname.size() &&
|
||||
pathname [pathname.size () - 1] != _RWSTD_PATH_SEP)
|
||||
pathname += _RWSTD_PATH_SEP;
|
||||
|
||||
(pathname += dir_other) += fname;
|
||||
}
|
||||
|
||||
#if !defined (_MSC_VER)
|
||||
if (S_ISREG (filemode (pathname.c_str ())))
|
||||
#else
|
||||
if (S_IFREG & filemode (pathname.c_str ()))
|
||||
#endif // !defined (_MSC_VER)
|
||||
return pathname;
|
||||
|
||||
|
||||
// use the value of RWSTD_SRC_ROOT
|
||||
const char* const src_root = std::getenv ("RWSTD_SRC_ROOT");
|
||||
if (src_root && *src_root) {
|
||||
// if the environment variable is not empty, append `fname'
|
||||
// to it and see if the file exists and names a regular file
|
||||
// if so, return its pathname
|
||||
pathname = src_root;
|
||||
(((pathname += _RWSTD_PATH_SEP) += "src") += _RWSTD_PATH_SEP) += fname;
|
||||
|
||||
#if !defined (_MSC_VER)
|
||||
if (S_ISREG (filemode (pathname.c_str ())))
|
||||
#else
|
||||
if (S_IFREG & filemode (pathname.c_str ()))
|
||||
#endif // !defined (_MSC_VER)
|
||||
return pathname;
|
||||
}
|
||||
|
||||
// allocate a sufficiently large buffer for the cwd
|
||||
pathname.resize (1024);
|
||||
|
||||
// use current working directory
|
||||
while (!get_cwd (&pathname [0], pathname.size ())) {
|
||||
|
||||
if (ERANGE != errno) {
|
||||
issue_diag (213, true, 0,
|
||||
"could not retrieve current working directory\n");
|
||||
return fname;
|
||||
}
|
||||
|
||||
// buffer too small, reallocate
|
||||
pathname.resize (pathname.size () * 2);
|
||||
}
|
||||
|
||||
// chop off everything past the terminating NUL
|
||||
pathname.resize (std::strlen (pathname.data ()));
|
||||
pathname += fname;
|
||||
|
||||
#if !defined (_MSC_VER)
|
||||
if (S_ISREG (filemode (pathname.c_str ())))
|
||||
#else
|
||||
if (S_IFREG & filemode (pathname.c_str ()))
|
||||
#endif // !defined (_MSC_VER)
|
||||
return pathname;
|
||||
|
||||
return fname;
|
||||
}
|
||||
|
||||
|
||||
int makedir (const char *name)
|
||||
{
|
||||
#if defined (_WIN32) || defined (_WIN64)
|
||||
|
||||
if ( 0 == CreateDirectory (name, NULL)
|
||||
&& GetLastError () != ERROR_ALREADY_EXISTS) {
|
||||
|
||||
LPVOID lpMsgBuf;
|
||||
|
||||
FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||
| FORMAT_MESSAGE_FROM_SYSTEM
|
||||
| FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
0,
|
||||
GetLastError (),
|
||||
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&lpMsgBuf,
|
||||
0,
|
||||
0);
|
||||
|
||||
issue_diag (E_CALL, true, 0, (char*)lpMsgBuf);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else // if !defined (_WIN{32,64})
|
||||
|
||||
if (-1 == mkdir (name, 0755)) {
|
||||
|
||||
# ifdef EEXIST
|
||||
|
||||
if (errno != EEXIST) {
|
||||
issue_diag (E_CALL, true, 0, "failed to create directory %s: %s\n",
|
||||
name, std::strerror (errno));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
# endif // EEXIST
|
||||
|
||||
}
|
||||
|
||||
#endif // _WIN{32,64}
|
||||
|
||||
return 0;
|
||||
}
|
||||
60
extern/stdcxx/4.2.1/util/path.h
vendored
Normal file
60
extern/stdcxx/4.2.1/util/path.h
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* path.h
|
||||
*
|
||||
* $Id: path.h 580483 2007-09-28 20:55:52Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the License); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2007 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RWSTD_PATH_H_INCLUDED
|
||||
#define RWSTD_PATH_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
// creates a directory in the current working directory
|
||||
// returns 0 on success, non-zero value on failure
|
||||
int
|
||||
makedir (const char*);
|
||||
|
||||
|
||||
void
|
||||
create_symlink (const std::string &dir,
|
||||
const std::string &xname,
|
||||
const std::string &sname);
|
||||
|
||||
// returns the pathname of a file `fname' which may be a file name
|
||||
// or an absolute or relative pathname; relative pathnames are searched
|
||||
// for in the following order
|
||||
// 1. if `other' is an absolute pathname, use dirname(other)
|
||||
// 1.1. if `other' is a relative pathname, then use cwd() + dirname(other)
|
||||
// + fname
|
||||
// 2. relative to the ${RWSTD_SRC_ROOT} environment variable, if
|
||||
// it is set and non-empty
|
||||
// 3. relative to the current working directory
|
||||
std::string
|
||||
get_pathname (const std::string &fname,
|
||||
const std::string &other = std::string ());
|
||||
|
||||
|
||||
#endif // RWSTD_PATH_H_INCLUDED
|
||||
619
extern/stdcxx/4.2.1/util/runall.cpp
vendored
Normal file
619
extern/stdcxx/4.2.1/util/runall.cpp
vendored
Normal file
@@ -0,0 +1,619 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* runall.cpp - Core logic for the exec utility
|
||||
*
|
||||
* $Id: runall.cpp 598869 2007-11-28 05:08:25Z sebor $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <assert.h> /* for assert() */
|
||||
#include <errno.h> /* for errno */
|
||||
#include <stdlib.h> /* for exit(), free() */
|
||||
#include <string.h> /* for memcpy(), ... */
|
||||
#include <stdio.h> /* for FILE, fopen(), ... */
|
||||
|
||||
#include <ctype.h> /* for isspace */
|
||||
#include <limits.h> /* for PATH_MAX */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#if !defined (_WIN32) && !defined (_WIN64)
|
||||
# include <sys/wait.h> /* for WIFEXITED(), ... */
|
||||
#endif
|
||||
|
||||
#include "cmdopt.h"
|
||||
#include "display.h"
|
||||
#include "exec.h"
|
||||
#include "output.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "target.h"
|
||||
|
||||
#ifndef ENOENT
|
||||
# define ENOENT 2
|
||||
#endif /* ENOENT */
|
||||
|
||||
#ifndef S_IXUSR
|
||||
# define S_IXUSR 0100
|
||||
#endif /* S_IXUSR */
|
||||
|
||||
#ifndef S_IXGRP
|
||||
# define S_IXGRP 0010
|
||||
#endif /* S_IXGRP */
|
||||
|
||||
#ifndef S_IXOTH
|
||||
# define S_IXOTH 0001
|
||||
#endif /* S_IXOTH */
|
||||
|
||||
#if !defined (PATH_MAX) || PATH_MAX < 128 || 4096 < PATH_MAX
|
||||
// deal with undefined, bogus, or excessive values
|
||||
# undef PATH_MAX
|
||||
# define PATH_MAX 1024
|
||||
#endif
|
||||
|
||||
/**
|
||||
Utility function to rework the argv array
|
||||
|
||||
target is either a 'bare' executable or a 'complex' executable. A bare
|
||||
executable is the path to an executable. A complex executable is the
|
||||
path to the executable, followed by a series of command line arguments.
|
||||
|
||||
If target is a bare executable, the arguments in the returned argv array
|
||||
will be the target followed by the contents of the recieved argv array.
|
||||
|
||||
If target is a complex executable, the arguments in the returned argv
|
||||
array will be target, transformed into an array. If a token in the
|
||||
argument string is '%x' (no quotes), the contents of the provided argv
|
||||
array will be inserted into the return array at that point.
|
||||
|
||||
It is the responsibility of the caller to free() the returned blocks of
|
||||
memory, which were allocated by a call to split_opt_string().
|
||||
|
||||
@todo Figure out an escaping mechanism to allow '%x' to be passed to an
|
||||
executable
|
||||
|
||||
@param target target to generate an argv array for
|
||||
@param argv program wide argv array for child processes
|
||||
@return processed argv array, usable in exec ()
|
||||
*/
|
||||
static char**
|
||||
merge_argv (const char* target, char* const argv [])
|
||||
{
|
||||
size_t tlen;
|
||||
char ** split;
|
||||
unsigned i, arg_count = 0, spl_count = 0, wld_count = 0;
|
||||
|
||||
assert (0 != target);
|
||||
assert (0 != argv);
|
||||
|
||||
tlen = strlen (target);
|
||||
split = split_opt_string (target);
|
||||
|
||||
/* If the split of target only contains a single value, we may have a
|
||||
bare executable name */
|
||||
if (!split [1]) {
|
||||
/* Check if last character in the target is whitespace */
|
||||
if (isspace (target [tlen])) {
|
||||
/* If it is, we've got a complex executable with no arguments.
|
||||
Therfore, return it as is.
|
||||
*/
|
||||
return split;
|
||||
} /* Otherwise, it's a bare executable, so append argv */
|
||||
|
||||
/* Figure out how many arguments we've got in argv*/
|
||||
for (/* none */; argv [arg_count]; ++arg_count);
|
||||
|
||||
/* reallocate memory for copying them, extending the buffer */
|
||||
split = (char**)RW_REALLOC (split, (arg_count + 2) * sizeof (char*));
|
||||
|
||||
/* And copy the pointers */
|
||||
for (i=0; i < arg_count; ++i)
|
||||
split [i+1] = argv [i];
|
||||
|
||||
/* Then terminate the array*/
|
||||
split [++i] = (char*)0;
|
||||
|
||||
return split;
|
||||
} /* Otherwise, it's a complex executable with 1 or more arguments */
|
||||
|
||||
/* Figure out how many instances of '%x' we've got */
|
||||
for (spl_count = 1; split [spl_count]; ++spl_count) {
|
||||
if ('%' == split [spl_count][0] && 'x' == split [spl_count][1]
|
||||
&& '\0' == split [spl_count][2])
|
||||
++wld_count;
|
||||
}
|
||||
|
||||
/* If we don't have any instances of '%x', we have a valid argv array,
|
||||
so return it as it is.
|
||||
*/
|
||||
if (0 == wld_count)
|
||||
return split;
|
||||
|
||||
/* Now we need to determine how large the argv array is */
|
||||
for (/* none */; argv [arg_count]; ++arg_count);
|
||||
|
||||
if (0 == arg_count) {
|
||||
/* We want to shrink the array, removing the '%x' terms*/
|
||||
unsigned found = 0;
|
||||
for (i = 1; i <= spl_count; ++i) {
|
||||
if (split [i] && '%' == split [i][0] && 'x' == split [i][1]
|
||||
&& '\0' == split [i][2])
|
||||
++found;
|
||||
else
|
||||
split [i - found] = split [i];
|
||||
}
|
||||
}
|
||||
else if (1 == arg_count) {
|
||||
/* We need to replace all the %x terms with argv [0] */
|
||||
|
||||
for (i = 1; i < spl_count; ++i) {
|
||||
if ('%' == split [i][0] && 'x' == split [i][1]
|
||||
&& '\0' == split [i][2])
|
||||
split [i] = argv [0];
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* We need to resize the split array to hold the insertion (s) */
|
||||
/* First, we realloc the array */
|
||||
const unsigned new_len = spl_count + (arg_count - 1) * wld_count;
|
||||
split = (char**)RW_REALLOC (split, sizeof (char**) * new_len);
|
||||
|
||||
/* Then we itterate backwards through the split array, transcribing
|
||||
elements as we go. We have to go backwards, so we don't clobber
|
||||
data in the process.
|
||||
*/
|
||||
for (/* none */; wld_count; --spl_count) {
|
||||
if (split [spl_count] && '%' == split [spl_count][0]
|
||||
&& 'x' == split [spl_count][1]
|
||||
&& '\0' == split [spl_count][2]) {
|
||||
--wld_count;
|
||||
for (i = arg_count; i; --i) {
|
||||
split [spl_count + (arg_count - 1) * wld_count + i - 1] =
|
||||
argv [i - 1];
|
||||
}
|
||||
}
|
||||
else
|
||||
split [spl_count + (arg_count - 1) * wld_count] =
|
||||
split [spl_count];
|
||||
}
|
||||
}
|
||||
return split;
|
||||
}
|
||||
|
||||
/**
|
||||
Arbitrary constant controling static read buffer size.
|
||||
|
||||
@see count_warnings
|
||||
*/
|
||||
#define READ_BUF_LEN 64
|
||||
|
||||
/**
|
||||
Compiler/linker output parser.
|
||||
|
||||
This method tries to open the compiler/linker log file, based on the name
|
||||
of a the target file that was generated by the compiler/linker.
|
||||
Upon opening the file, it tries to count the number of warnings present.
|
||||
|
||||
@param target name of target to parse the log for
|
||||
@param counter pointer to the counter to count warnings in.
|
||||
@param match string to match when detecting a warning.
|
||||
*/
|
||||
static
|
||||
void count_warnings (const char* const target, unsigned* counter,
|
||||
const char* const match)
|
||||
{
|
||||
size_t path_len;
|
||||
char* tmp_name;
|
||||
FILE* data;
|
||||
|
||||
assert (0 != target);
|
||||
assert (0 != counter);
|
||||
|
||||
if (0 == match)
|
||||
return; /* Don't have a match string, so don't tally warnings */
|
||||
|
||||
path_len = strlen (target);
|
||||
tmp_name = (char*)RW_MALLOC (path_len + 5);
|
||||
memcpy (tmp_name, target, path_len + 1);
|
||||
strcat (tmp_name,".log");
|
||||
|
||||
data = fopen (tmp_name, "r");
|
||||
if (data) {
|
||||
size_t pos = 0, limit = strlen (match);
|
||||
while (!feof (data)) {
|
||||
char buf [READ_BUF_LEN];
|
||||
size_t nread; /* bytes read */
|
||||
|
||||
/* First, read a block from the file into the buffer */
|
||||
nread = fread (buf, 1, sizeof buf, data);
|
||||
if (ferror (data)) {
|
||||
warn ("Error reading %s: %s\n", tmp_name, strerror (errno));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Then, look for the search string within it. */
|
||||
for (size_t i = 0; i < nread; ++i) {
|
||||
if (buf [i] != match [pos])
|
||||
pos = 0;
|
||||
else if (++pos == limit) {
|
||||
pos = 0;
|
||||
++*counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose (data);
|
||||
}
|
||||
else if (ENOENT != errno)
|
||||
warn ("Error opening %s: %s\n", tmp_name, strerror (errno));
|
||||
|
||||
free (tmp_name);
|
||||
}
|
||||
|
||||
/**
|
||||
Preflight check to ensure that target is something that should be run.
|
||||
|
||||
This method checks to see if target exists and is theoretically executable.
|
||||
If a problem is detected, the condition is recorded in the status structure
|
||||
and 0 is returned. This method also attempts to determine the number of
|
||||
compile and link warnings that occurred, using count_warnings.
|
||||
|
||||
A special case is the situation where the target name ends in .o,
|
||||
indicating that the target only needed to compile, and doesn't need to
|
||||
be run. Processing for this case is currently disabled as it is unused.
|
||||
|
||||
@param target the path to the executable to check
|
||||
@param status status object to record results in.
|
||||
@return 1 if valid target to run, 0 otherwise.
|
||||
*/
|
||||
static int
|
||||
check_target_ok (const char* target, struct target_status* status)
|
||||
{
|
||||
struct stat file_info;
|
||||
int exists = 1;
|
||||
size_t path_len;
|
||||
char* tmp_name;
|
||||
|
||||
assert (0 != target);
|
||||
assert (0 != status);
|
||||
|
||||
path_len = strlen (target);
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Otherwise, check for the .o file on non-windows systems */
|
||||
tmp_name = (char*)RW_MALLOC (path_len + 3);
|
||||
memcpy (tmp_name, target, path_len + 1);
|
||||
strcat (tmp_name,".o");
|
||||
#else
|
||||
/* Or the target\target.obj file on windows systems*/
|
||||
{
|
||||
const char* const target_name = get_target ();
|
||||
size_t target_len = strlen (target_name);
|
||||
size_t tmp_len = path_len + target_len - 2;
|
||||
/* - 2 comes from removing 4 characters (extra .exe) and adding 2
|
||||
characters (\ directory seperator and trailing null) */
|
||||
tmp_name = (char*)RW_MALLOC (tmp_len);
|
||||
memcpy (tmp_name, target, path_len - 4);
|
||||
tmp_name [path_len - 4] = default_path_sep;
|
||||
memcpy (tmp_name + path_len - 3, target_name, target_len);
|
||||
tmp_name [tmp_len - 4] = 'o';
|
||||
tmp_name [tmp_len - 3] = 'b';
|
||||
tmp_name [tmp_len - 2] = 'j';
|
||||
tmp_name [tmp_len - 1] = '\0';
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
count_warnings (target, &status->l_warn, "warning:");
|
||||
count_warnings (tmp_name, &status->c_warn, "warning:");
|
||||
|
||||
if (0 > stat (target, &file_info)) {
|
||||
if (ENOENT != errno) {
|
||||
warn ("Error stating %s: %s\n", target, strerror (errno));
|
||||
status->status = ST_SYSTEM_ERROR;
|
||||
free (tmp_name);
|
||||
return 0;
|
||||
}
|
||||
file_info.st_mode = 0; /* force mode on non-existant file to 0 */
|
||||
exists = 0; /* note that it doesn't exist */
|
||||
}
|
||||
|
||||
if (0 == (file_info.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
|
||||
/* This is roughly equivlent to the -x bash operator.
|
||||
It checks if the file can be run, /not/ if we can run it
|
||||
*/
|
||||
|
||||
#if 0 /* Disable .o target check as unused */
|
||||
/* If target is a .o file, check if it exists */
|
||||
if ('.' == target [path_len-1] && 'o' == target [path_len]) {
|
||||
if (!exists)
|
||||
status->status = ST_COMPILE;
|
||||
free (tmp_name);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the target exists, it doesn't have valid permissions */
|
||||
if (exists) {
|
||||
status->status = ST_EXECUTE_FLAG;
|
||||
free (tmp_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 > stat (tmp_name, &file_info)) {
|
||||
if (ENOENT != errno) {
|
||||
warn ("Error stating %s: %s\n", tmp_name, strerror (errno));
|
||||
status->status = ST_SYSTEM_ERROR;
|
||||
}
|
||||
else
|
||||
status->status = ST_COMPILE;
|
||||
}
|
||||
else {
|
||||
status->status = ST_LINK;
|
||||
}
|
||||
|
||||
free (tmp_name);
|
||||
return 0;
|
||||
}
|
||||
free (tmp_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
(Re)implementation of the POSIX basename function.
|
||||
|
||||
This is a simplistic (re)implementation of the basename function
|
||||
specified in the XSI extension to the IEEE Std 1003.1 (POSIX) standard.
|
||||
|
||||
@warning this method is UTF-8 unsafe
|
||||
@warning this method assumes there are no trailing slashes in the path name
|
||||
@warning this method retuns a pointer referencing a position inside the
|
||||
provided path. As such, the returned string isn't a new string, but rather
|
||||
an alias to the provided string.
|
||||
@param path path name to determine the basename for
|
||||
@return final element in path name
|
||||
*/
|
||||
static const char*
|
||||
rw_basename (const char* path)
|
||||
{
|
||||
const char *pos, *mark;
|
||||
|
||||
assert (0 != path);
|
||||
|
||||
for (mark = pos = path; '\0' != *pos; ++pos)
|
||||
#if !defined (_WIN32) && !defined (_WIN64)
|
||||
mark = (default_path_sep == *pos) ? pos + 1 : mark;
|
||||
#else
|
||||
mark = (default_path_sep == *pos || '/' == *pos) ? pos + 1 : mark;
|
||||
#endif /* _WIN{32,64} */
|
||||
|
||||
return mark;
|
||||
}
|
||||
|
||||
static const char* target_name;
|
||||
|
||||
const char* get_target ()
|
||||
{
|
||||
return target_name;
|
||||
}
|
||||
|
||||
/**
|
||||
High level method to run target, using childargv as arguments.
|
||||
|
||||
This method preflights the execution of target, runs it using the watchdog
|
||||
subsystem, then processes the results from that subsystem.
|
||||
|
||||
@param target path to target executable
|
||||
@param null ((char*)0) terminated array of parameters to be passed to
|
||||
target when it is run
|
||||
@see check_target_ok
|
||||
@see exec_file
|
||||
@see process_results
|
||||
*/
|
||||
static void
|
||||
run_target (struct target_status *summary,
|
||||
const char *target,
|
||||
const struct target_opts *target_template)
|
||||
{
|
||||
struct target_opts options;
|
||||
struct target_status results;
|
||||
|
||||
assert (0 != target);
|
||||
assert (0 != target_template);
|
||||
assert (0 != target_template->argv);
|
||||
|
||||
memcpy (&options, target_template, sizeof options);
|
||||
memset (&results, 0, sizeof results);
|
||||
|
||||
/* create the argv array for this target */
|
||||
options.argv = merge_argv (target, options.argv);
|
||||
|
||||
assert (0 != options.argv);
|
||||
assert (0 != options.argv [0]);
|
||||
|
||||
target_name = rw_basename (options.argv [0]);
|
||||
|
||||
/* create the names of files to redirect stdin and stdout */
|
||||
options.infname = input_name (options.data_dir, target_name);
|
||||
options.outfname = output_name (options.argv [0]);
|
||||
|
||||
print_target (&options);
|
||||
|
||||
if (check_target_ok (options.argv [0], &results)) {
|
||||
exec_file (&options, &results);
|
||||
if (0 == results.exit && 0 == results.signaled)
|
||||
parse_output (&options, &results);
|
||||
}
|
||||
|
||||
print_status (&results);
|
||||
|
||||
if (summary) {
|
||||
/* increment summary counters */
|
||||
if (0 == results.signaled && results.exit)
|
||||
++summary->exit;
|
||||
|
||||
/* add cumulative times (when valid) */
|
||||
if (results.usr_time != (clock_t)-1)
|
||||
summary->usr_time += results.usr_time;
|
||||
|
||||
if (results.sys_time != (clock_t)-1)
|
||||
summary->sys_time += results.sys_time;
|
||||
|
||||
if (results.wall_time != (clock_t)-1)
|
||||
summary->wall_time += results.wall_time;
|
||||
|
||||
summary->signaled += results.signaled;
|
||||
summary->c_warn += results.c_warn;
|
||||
summary->l_warn += results.l_warn;
|
||||
summary->t_warn += results.t_warn;
|
||||
|
||||
if ((unsigned)-1 != results.assert) {
|
||||
/* increment assertion counters only when they're valid */
|
||||
summary->assert += results.assert;
|
||||
summary->failed += results.failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* free data dynamically allocated for this target alone */
|
||||
free (options.argv [0]);
|
||||
free (options.argv);
|
||||
free ((char*)options.infname);
|
||||
free ((char*)options.outfname);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Entry point to the application.
|
||||
|
||||
Passes arguments to the option processing subsystem, then processes all
|
||||
remaing arguments as targets using run_target
|
||||
|
||||
@param argc number of arguments recieved
|
||||
@param argv array of arguments recieved
|
||||
@return 0 upon successfull completeion of execution
|
||||
*/
|
||||
|
||||
int
|
||||
main (int argc, char *argv [])
|
||||
{
|
||||
struct target_opts target_template;
|
||||
const char* exe_opts = "";
|
||||
const char* const* const saved_argv = (const char* const*)argv;
|
||||
|
||||
exe_name = argv [0];
|
||||
|
||||
if (1 < argc && '-' == argv [1][0]) {
|
||||
const int nopts =
|
||||
eval_options (argc, argv, &target_template, &exe_opts);
|
||||
|
||||
if (0 > nopts)
|
||||
return 1;
|
||||
|
||||
argc -= nopts;
|
||||
argv += nopts;
|
||||
}
|
||||
else {
|
||||
/* initialize data members */
|
||||
memset (&target_template, 0, sizeof target_template);
|
||||
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
|
||||
/* set the program output mode */
|
||||
if (target_template.verbose)
|
||||
set_output_format (FMT_VERBOSE);
|
||||
else
|
||||
set_output_format (FMT_PLAIN);
|
||||
|
||||
if (0 < argc) {
|
||||
struct target_status summary;
|
||||
|
||||
int i;
|
||||
|
||||
target_template.argv = split_opt_string (exe_opts);
|
||||
|
||||
assert (0 != target_template.argv);
|
||||
|
||||
/* print out the program's argv array in verbose mode */
|
||||
print_header (target_template.verbose ? saved_argv : 0);
|
||||
|
||||
memset (&summary, 0, sizeof summary);
|
||||
|
||||
/* number of program's executed */
|
||||
int progs_count = 0;
|
||||
|
||||
for (i = 0; i < argc; ++i) {
|
||||
const char* target = argv [i];
|
||||
|
||||
if ('@' == target [0]) {
|
||||
/* read targets from specified file */
|
||||
const char* lst_name = target + 1;
|
||||
FILE* lst = fopen (lst_name, "r");
|
||||
if (0 == lst) {
|
||||
warn ("Error opening %s: %s\n", lst_name, strerror (errno));
|
||||
break;
|
||||
}
|
||||
|
||||
while (!feof (lst)) {
|
||||
char buf [PATH_MAX];
|
||||
target = fgets (buf, sizeof (buf), lst);
|
||||
|
||||
if (ferror (lst)) {
|
||||
warn ("Error reading %s: %s\n", lst_name, strerror (errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if (target) {
|
||||
/* remove terminating newline character if present */
|
||||
assert (buf == target);
|
||||
if (char* pos = strchr (buf, '\n'))
|
||||
*pos = '\0';
|
||||
if (*target) {
|
||||
++progs_count;
|
||||
run_target (&summary, target, &target_template);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose (lst);
|
||||
}
|
||||
else {
|
||||
++progs_count;
|
||||
run_target (&summary, target, &target_template);
|
||||
}
|
||||
}
|
||||
|
||||
print_footer (progs_count, &summary);
|
||||
|
||||
if (target_template.argv [0])
|
||||
free (target_template.argv [0]);
|
||||
free (target_template.argv);
|
||||
}
|
||||
|
||||
free (target_template.core);
|
||||
free (target_template.cpu);
|
||||
free (target_template.data);
|
||||
free (target_template.fsize);
|
||||
free (target_template.nofile);
|
||||
free (target_template.stack);
|
||||
free (target_template.as);
|
||||
|
||||
return 0;
|
||||
}
|
||||
772
extern/stdcxx/4.2.1/util/scanner.cpp
vendored
Normal file
772
extern/stdcxx/4.2.1/util/scanner.cpp
vendored
Normal file
@@ -0,0 +1,772 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* scanner.cpp
|
||||
*
|
||||
* $Id: scanner.cpp 648752 2008-04-16 17:01:56Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "scanner.h"
|
||||
|
||||
#include "diagnostic.h"
|
||||
#include "loc_exception.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cassert> // for assert()
|
||||
#include <climits> // for UCHAR_MAX
|
||||
#include <cstdlib> // for strtol()
|
||||
#include <cstring> // for strcmp()
|
||||
|
||||
|
||||
struct ScannerContext
|
||||
{
|
||||
ScannerContext (const char*, char = '#', char = '\\');
|
||||
|
||||
std::ifstream file; // file stream object
|
||||
std::string filename; // filename
|
||||
|
||||
// comment and escape for current file
|
||||
char comment_char;
|
||||
char escape_char;
|
||||
|
||||
// current line and column for the scanner
|
||||
int line;
|
||||
|
||||
// current line and position within it
|
||||
std::string line_;
|
||||
const char* pos_;
|
||||
|
||||
private:
|
||||
// not defined (not copy constructible or assignable)
|
||||
ScannerContext (const ScannerContext&);
|
||||
void operator= (ScannerContext&);
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
// helpers
|
||||
|
||||
static void normal_path (std::string& s)
|
||||
{
|
||||
std::string::iterator it(s.begin ());
|
||||
|
||||
for (; it != s.end (); it++)
|
||||
if (*it == '/' || *it == '\\') {
|
||||
#if defined (_MSC_VER)
|
||||
*it = '\\';
|
||||
#else
|
||||
*it = '/';
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
// ScannerContext class definitions
|
||||
|
||||
ScannerContext::
|
||||
ScannerContext (const char* name, char cc, char ec)
|
||||
: file (name), filename (name),
|
||||
comment_char (cc), escape_char (ec),
|
||||
line (0) // , column (0)
|
||||
{
|
||||
// update current position
|
||||
pos_ = line_.c_str ();
|
||||
|
||||
if (!file.is_open ())
|
||||
issue_diag (500, true, 0,
|
||||
"%s could not be opened for reading\n", name);
|
||||
|
||||
issue_diag (I_OPENRD, false, 0, "reading %s\n", name);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
// Scanner class definitions
|
||||
|
||||
Scanner::
|
||||
Scanner ()
|
||||
: context_ (0), nlines_ (0), ntokens_ (0), escaped_newline_ (false)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
Scanner::
|
||||
~Scanner()
|
||||
{
|
||||
// empty the stack and destroy the current state
|
||||
delete context_;
|
||||
|
||||
while (!context_stack_.empty ()) {
|
||||
delete context_stack_.top ();
|
||||
context_stack_.pop ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char Scanner::
|
||||
escape_char () const
|
||||
{
|
||||
return context_ ? context_->escape_char : 0;
|
||||
}
|
||||
|
||||
void Scanner::
|
||||
ignore_line ()
|
||||
{
|
||||
while (next_token ().token != tok_nl);
|
||||
}
|
||||
|
||||
|
||||
void Scanner::
|
||||
open (std::string name, char cc, char ec)
|
||||
{
|
||||
normal_path (name);
|
||||
|
||||
if (context_)
|
||||
context_stack_.push (context_);
|
||||
|
||||
try {
|
||||
context_ = new ScannerContext (name.c_str (), cc, ec);
|
||||
}
|
||||
catch (loc_exception&) {
|
||||
context_ = 0;
|
||||
|
||||
if (!context_stack_.empty ()) {
|
||||
context_ = context_stack_.top ();
|
||||
context_stack_.pop ();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
nlines_ = 0;
|
||||
ntokens_ = 0;
|
||||
}
|
||||
|
||||
|
||||
void Scanner::
|
||||
close ()
|
||||
{
|
||||
assert (0 != context_);
|
||||
|
||||
issue_diag (I_OPENRD, false, 0,
|
||||
"%s: %u tokens, %u lines\n",
|
||||
context_->filename.c_str (), ntokens_, nlines_);
|
||||
|
||||
delete context_;
|
||||
|
||||
if (context_stack_.empty ())
|
||||
context_ = 0;
|
||||
else {
|
||||
context_ = context_stack_.top ();
|
||||
context_stack_.pop ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Scanner::token_id Scanner::
|
||||
process_token (const char* name)
|
||||
{
|
||||
assert (0 != name);
|
||||
|
||||
if (*name == context_->escape_char) {
|
||||
switch (name [1]) {
|
||||
case '0': case '1': case '2': case '3':
|
||||
case '4': case '5': case '6': case '7':
|
||||
case 'd':
|
||||
case 'x':
|
||||
// escaped numeric character value
|
||||
return tok_char_value;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return tok_ndef;
|
||||
}
|
||||
|
||||
// look for a predefined token
|
||||
|
||||
static const struct {
|
||||
const char* name;
|
||||
Scanner::token_id token;
|
||||
} tok_map [] = {
|
||||
// elements must be sorted in ascending order
|
||||
{ "CHARMAP", tok_charmap },
|
||||
{ "END", tok_end },
|
||||
{ "IGNORE", tok_ignore },
|
||||
{ "LC_ADDRESS", tok_addr },
|
||||
{ "LC_COLLATE", tok_collate },
|
||||
{ "LC_CTYPE", tok_ctype },
|
||||
{ "LC_IDENTIFICATION", tok_ident },
|
||||
{ "LC_MEASUREMENT", tok_measure },
|
||||
{ "LC_MESSAGES", tok_messages },
|
||||
{ "LC_MONETARY", tok_monetary },
|
||||
{ "LC_NAME", tok_name },
|
||||
{ "LC_NUMERIC", tok_numeric },
|
||||
{ "LC_PAPER", tok_paper },
|
||||
{ "LC_TELEPHONE", tok_phone },
|
||||
{ "LC_TIME", tok_time },
|
||||
{ "UNDEFINED", tok_undefined },
|
||||
{ "WIDTH", tok_width },
|
||||
{ "abday", tok_abday },
|
||||
{ "abmon", tok_abmon },
|
||||
{ "alpha", tok_alpha },
|
||||
{ "alt_digits", tok_alt_digits },
|
||||
{ "am_pm", tok_am_pm },
|
||||
{ "backward", tok_backward },
|
||||
{ "blank", tok_blank },
|
||||
{ "cntrl", tok_cntrl },
|
||||
{ "collating-element", tok_coll_elem },
|
||||
{ "collating-symbol", tok_coll_sym },
|
||||
{ "comment_char", tok_comment_char },
|
||||
{ "copy", tok_copy },
|
||||
{ "currency_symbol", tok_currency_symbol },
|
||||
{ "d_fmt", tok_d_fmt },
|
||||
{ "d_t_fmt", tok_d_t_fmt },
|
||||
{ "day", tok_day },
|
||||
{ "decimal_point", tok_decimal_point },
|
||||
{ "digit", tok_digit },
|
||||
{ "era", tok_era },
|
||||
{ "era_d_fmt", tok_era_d_fmt },
|
||||
{ "era_d_t_fmt", tok_era_d_t_fmt },
|
||||
{ "era_t_fmt", tok_era_t_fmt },
|
||||
{ "escape_char", tok_escape_char },
|
||||
{ "falsename", tok_falsename },
|
||||
{ "forward", tok_forward },
|
||||
{ "frac_digits", tok_frac_digits },
|
||||
{ "from", tok_from },
|
||||
{ "graph", tok_graph },
|
||||
{ "grouping", tok_grouping },
|
||||
{ "include", tok_include },
|
||||
{ "int_curr_symbol", tok_int_curr_symbol },
|
||||
{ "int_frac_digits", tok_int_frac_digits },
|
||||
{ "int_n_cs_precedes", tok_int_n_cs_precedes },
|
||||
{ "int_n_sep_by_space", tok_int_n_sep_by_space },
|
||||
{ "int_n_sign_posn", tok_int_n_sign_posn },
|
||||
{ "int_p_cs_precedes", tok_int_p_cs_precedes },
|
||||
{ "int_p_sep_by_space", tok_int_p_sep_by_space },
|
||||
{ "int_p_sign_posn", tok_int_p_sign_posn },
|
||||
{ "lower", tok_lower },
|
||||
{ "mon", tok_mon },
|
||||
{ "mon_decimal_point", tok_mon_decimal_point },
|
||||
{ "mon_grouping", tok_mon_grouping },
|
||||
{ "mon_thousands_sep", tok_mon_thousands_sep },
|
||||
{ "n_cs_precedes", tok_n_cs_precedes },
|
||||
{ "n_sep_by_space", tok_n_sep_by_space },
|
||||
{ "n_sign_posn", tok_n_sign_posn },
|
||||
{ "negative_sign", tok_negative_sign },
|
||||
{ "noexpr", tok_noexpr },
|
||||
{ "order_end", tok_order_end },
|
||||
{ "order_start", tok_order_start },
|
||||
{ "p_cs_precedes", tok_p_cs_precedes },
|
||||
{ "p_sep_by_space", tok_p_sep_by_space },
|
||||
{ "p_sign_posn", tok_p_sign_posn },
|
||||
{ "position", tok_position },
|
||||
{ "positive_sign", tok_positive_sign },
|
||||
{ "print", tok_print },
|
||||
{ "punct", tok_punct },
|
||||
{ "reorder-after", tok_reorder },
|
||||
{ "reorder-end", tok_reorder_end },
|
||||
{ "reorder-section-after", tok_reorder_section },
|
||||
{ "reorder-section-end", tok_reorder_section_end },
|
||||
{ "script", tok_script },
|
||||
{ "space", tok_space },
|
||||
{ "t_fmt", tok_t_fmt },
|
||||
{ "t_fmt_ampm", tok_t_fmt_ampm },
|
||||
{ "thousands_sep", tok_thousands_sep },
|
||||
{ "tolower", tok_tolower },
|
||||
{ "toupper", tok_toupper },
|
||||
{ "translit_end", tok_xlit_end },
|
||||
{ "translit_start", tok_xlit_start },
|
||||
{ "truename", tok_truename },
|
||||
{ "upper", tok_upper },
|
||||
{ "xdigit", tok_xdigit },
|
||||
{ "yesexpr", tok_yesexpr }
|
||||
};
|
||||
|
||||
int low = 0;
|
||||
int high = sizeof tok_map / sizeof *tok_map - 1;
|
||||
|
||||
// this loop implements a binary search to find 'name' in the
|
||||
// tok_map list and when found returns the token value.
|
||||
while (low <= high) {
|
||||
|
||||
const int cur = (low + high) / 2;
|
||||
|
||||
const int cmp = std::strcmp (name, tok_map [cur].name);
|
||||
if (0 == cmp)
|
||||
return tok_map [cur].token;
|
||||
|
||||
if (cmp < 0)
|
||||
high = cur - 1;
|
||||
else
|
||||
low = cur + 1;
|
||||
}
|
||||
|
||||
return tok_ndef;
|
||||
}
|
||||
|
||||
|
||||
void Scanner::
|
||||
read_line ()
|
||||
{
|
||||
context_->line_.clear ();
|
||||
|
||||
std::getline (context_->file, context_->line_);
|
||||
|
||||
context_->line_ += '\n';
|
||||
|
||||
context_->pos_ = context_->line_.c_str ();
|
||||
|
||||
++context_->line;
|
||||
// context_->column = 0;
|
||||
|
||||
++nlines_;
|
||||
|
||||
assert (context_->line_.size ());
|
||||
}
|
||||
|
||||
|
||||
Scanner::token_t Scanner::
|
||||
next_token ()
|
||||
{
|
||||
assert (0 != context_);
|
||||
assert (context_->file.is_open ());
|
||||
|
||||
// token
|
||||
token_t next_tok;
|
||||
|
||||
next_tok.name = "";
|
||||
next_tok.token = tok_ndef;
|
||||
next_tok.line = 0;
|
||||
next_tok.column = 0;
|
||||
next_tok.file = 0;
|
||||
|
||||
while (true) {
|
||||
|
||||
// store the *current* file name
|
||||
next_tok.file = context_->filename.c_str ();
|
||||
|
||||
// the assert above for eof checks if the caller has lost it;
|
||||
if (context_->file.eof ()) {
|
||||
next_tok.token = tok_end_tokens;
|
||||
return next_tok;
|
||||
}
|
||||
|
||||
// if we exhausted the current line, advance
|
||||
if ( context_->line_.size ()
|
||||
<= std::size_t (context_->pos_ - context_->line_.c_str ())) {
|
||||
read_line ();
|
||||
}
|
||||
|
||||
// line and column for the token start; they are set at each
|
||||
// iteration; the finding of a token breaks and next_tok leaves
|
||||
// this loop having the line/col info
|
||||
next_tok.line = context_->line;
|
||||
next_tok.column = context_->pos_ - context_->line_.c_str ();
|
||||
|
||||
// plug in the pointer to current position
|
||||
const char*& next = context_->pos_;
|
||||
|
||||
if (*next != context_->comment_char)
|
||||
escaped_newline_ = false;
|
||||
|
||||
if (*next == '<') {
|
||||
// beginning of a symbolic name or keyword
|
||||
const char* tok_begin = next++;
|
||||
|
||||
for (; '>' != *next; ++next) {
|
||||
|
||||
// if has an escaped close angular, pass
|
||||
if (*next == context_->escape_char) {
|
||||
|
||||
// append symbol name up to but not including the escape
|
||||
next_tok.name.append (tok_begin, next - tok_begin);
|
||||
|
||||
// advance the next pointer to skip the escape
|
||||
tok_begin = ++next;
|
||||
}
|
||||
else if ('\n' == *next) {
|
||||
// past the end of the line
|
||||
issue_diag (E_SYNTAX, true, &next_tok,
|
||||
" unterminated symbolic name\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
next_tok.name.append (tok_begin, ++next - tok_begin);
|
||||
|
||||
// check the name fetched so far
|
||||
if (next_tok.name == "<code_set_name>") {
|
||||
next_tok.token = tok_code_set_name;
|
||||
}
|
||||
else if ( next_tok.name == "<escape_char>"
|
||||
|| next_tok.name == "<comment_char>") {
|
||||
|
||||
// eat away spaces
|
||||
while (' ' == *next || '\t' == *next) {
|
||||
++next;
|
||||
}
|
||||
|
||||
// test for end of line
|
||||
if (*next == '\n')
|
||||
issue_diag (E_SYNTAX, true, &next_tok,
|
||||
"missing value for %s\n",
|
||||
next_tok.name.c_str ());
|
||||
|
||||
// store character
|
||||
if (next_tok.name == "<escape_char>")
|
||||
context_->escape_char = *next;
|
||||
else
|
||||
context_->comment_char = *next;
|
||||
|
||||
// adjust positions;
|
||||
context_->pos_ =
|
||||
context_->line_.c_str () + context_->line_.size ();
|
||||
|
||||
// set token to a newline
|
||||
next_tok.name = "";
|
||||
next_tok.token = tok_nl;
|
||||
}
|
||||
else if (next_tok.name == "<mb_cur_max>") {
|
||||
next_tok.token = tok_mb_cur_max;
|
||||
}
|
||||
else if (next_tok.name == "<mb_cur_min>") {
|
||||
next_tok.token = tok_mb_cur_min;
|
||||
}
|
||||
else {
|
||||
next_tok.token = tok_sym_name;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (*next == ' ' || *next == '\t' || *next == ';') {
|
||||
// ignore whitespace and separators
|
||||
while (*next == ' ' || *next == '\t' || *next == ';') {
|
||||
++next;
|
||||
}
|
||||
}
|
||||
else if (*next == '\n') {
|
||||
++next;
|
||||
next_tok.token = tok_nl;
|
||||
break;
|
||||
}
|
||||
else if (*next == context_->comment_char) {
|
||||
// start of a comment - check as early as necessary
|
||||
// adjust to end of line
|
||||
context_->pos_ = context_->line_.c_str () + context_->line_.size ();
|
||||
|
||||
if (escaped_newline_)
|
||||
continue;
|
||||
|
||||
next_tok.token = tok_nl;
|
||||
next_tok.name = "\n";
|
||||
break;
|
||||
}
|
||||
else if (*next == '(') {
|
||||
// push open parenthesis
|
||||
next_tok.name.push_back (*next++);
|
||||
|
||||
// start of a grouping
|
||||
while (*next != ')') {
|
||||
// contains a symbolic name
|
||||
if (*next == '<') {
|
||||
// push open angular parenthesis
|
||||
next_tok.name.push_back (*next++);
|
||||
|
||||
while (*next != '\n') {
|
||||
// if has an escaped close angular, pass
|
||||
if (next [0] == context_->escape_char) {
|
||||
next_tok.name.push_back (*next++);
|
||||
next_tok.name.push_back (*next++);
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we have reached the end of the sym name
|
||||
if (*next == '>') {
|
||||
next_tok.name.push_back (*next);
|
||||
break;
|
||||
}
|
||||
|
||||
// still inside the sym name/keyword
|
||||
next_tok.name.push_back (*next++);
|
||||
}
|
||||
|
||||
// check if we have gone past the end of the line
|
||||
if (*next == '\n')
|
||||
issue_diag (E_SYNTAX, true, &next_tok,
|
||||
" unterminated symbolic name");
|
||||
|
||||
++next;
|
||||
}
|
||||
else {
|
||||
// fetch the character
|
||||
next_tok.name.push_back (*next++);
|
||||
}
|
||||
|
||||
if (*next == '\n')
|
||||
issue_diag (E_SYNTAX, true, &next_tok,
|
||||
" unterminated grouping ");
|
||||
}
|
||||
|
||||
next_tok.name.push_back (*next++);
|
||||
next_tok.token = tok_grouping;
|
||||
break;
|
||||
}
|
||||
else if (*next == '.') {
|
||||
// ellipsis (see ISO/IEC TR 14652)
|
||||
int ellipsis_count = 0;
|
||||
// start of an interval
|
||||
while (*next == '.') {
|
||||
next_tok.name.push_back (*next++);
|
||||
++ellipsis_count;
|
||||
}
|
||||
|
||||
switch (ellipsis_count) {
|
||||
case 2: {
|
||||
const char* tmp = next;
|
||||
if (*tmp++ == '(' && *tmp++ == '2' && *tmp++ == ')'
|
||||
&& *tmp++ == '.' && *tmp++ == '.') {
|
||||
// double increment hexadecimal symbolic ellipsis
|
||||
next_tok.token = tok_dbl_ellipsis;
|
||||
next = tmp;
|
||||
}
|
||||
else {
|
||||
// hexadecimal symbolic ellipsis
|
||||
next_tok.token = tok_hex_ellipsis;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
// absolute symbolic ellipsis
|
||||
next_tok.token = tok_abs_ellipsis;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// decimal symbolic ellipsis
|
||||
next_tok.token = tok_dec_ellipsis;
|
||||
break;
|
||||
|
||||
default:
|
||||
issue_diag (E_SYNTAX, true, &next_tok, "illegal ellipsis\n");
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
else if (*next == '\"') {
|
||||
|
||||
// start of a string
|
||||
next_tok.name.push_back (*next++);
|
||||
const char ec = context_->escape_char;
|
||||
|
||||
while (next[0] != '\n') {
|
||||
|
||||
// escaped newline; continue
|
||||
if (next [0] == ec && next [1] == '\n') {
|
||||
read_line ();
|
||||
continue;
|
||||
}
|
||||
|
||||
// escaped quote
|
||||
if (next[0] == ec) {
|
||||
next_tok.name.push_back (*next++);
|
||||
next_tok.name.push_back (*next++);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next [0] == '\"') {
|
||||
next_tok.name.push_back (*next);
|
||||
break;
|
||||
}
|
||||
|
||||
// still inside the string
|
||||
next_tok.name.push_back (*next++);
|
||||
}
|
||||
|
||||
// test for closure
|
||||
if (*next == '\n')
|
||||
issue_diag (E_SYNTAX, true, &next_tok, "unterminated string");
|
||||
|
||||
++next;
|
||||
next_tok.token = tok_string;
|
||||
break;
|
||||
|
||||
}
|
||||
else if (*next == context_->escape_char) {
|
||||
// start of an escape sequence
|
||||
// escaped new line
|
||||
if (next [1] == '\n') {
|
||||
// adjust to end of line
|
||||
context_->pos_ =
|
||||
context_->line_.c_str () + context_->line_.size ();
|
||||
|
||||
escaped_newline_ = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// or
|
||||
while ( *next != ' ' && *next != '\t'
|
||||
&& *next != ';' && *next != '\n') {
|
||||
next_tok.name.push_back (*next++);
|
||||
}
|
||||
|
||||
// retrieve token based on value
|
||||
next_tok.token = process_token (next_tok.name.c_str ());
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// the rest of it
|
||||
for (const char ec = context_->escape_char; ; ) {
|
||||
|
||||
// stop at esc-newline or at first "separator"
|
||||
if ( (next [0] == ec && next [1] == '\n')
|
||||
|| next [0] == ' '
|
||||
|| next [0] == '\t'
|
||||
|| next [0] == '\n'
|
||||
|| next [0] == ';') {
|
||||
// continuation of a line, separators
|
||||
break;
|
||||
}
|
||||
|
||||
// fetch characters
|
||||
next_tok.name.push_back (*next++);
|
||||
}
|
||||
|
||||
// assert length of input
|
||||
assert (next_tok.name.size ());
|
||||
|
||||
// it wasn't a locale definition keyword so call process_token
|
||||
// and add the result to the list
|
||||
next_tok.token = process_token (next_tok.name.c_str ());
|
||||
|
||||
|
||||
// an extra bit of processing since we keep comment and escape
|
||||
// characters in the scanner for a faster processing
|
||||
if ( next_tok.token == tok_escape_char
|
||||
|| next_tok.token == tok_comment_char) {
|
||||
|
||||
// eat away spaces
|
||||
while (' ' == *next || '\t' == *next) {
|
||||
++next;
|
||||
}
|
||||
|
||||
// test for end of line
|
||||
if (*next == '\n')
|
||||
issue_diag (E_SYNTAX, true, &next_tok,
|
||||
"unterminated statement");
|
||||
|
||||
// store character
|
||||
if (next_tok.token == tok_escape_char)
|
||||
context_->escape_char = next [0];
|
||||
else
|
||||
context_->comment_char = next [0];
|
||||
|
||||
// adjust positions;
|
||||
context_->pos_ =
|
||||
context_->line_.c_str () + context_->line_.size ();
|
||||
|
||||
// return the token
|
||||
next_tok.name = "";
|
||||
next_tok.token = tok_nl;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++ntokens_;
|
||||
|
||||
return next_tok;
|
||||
}
|
||||
|
||||
|
||||
unsigned long Scanner::
|
||||
convert_escape (const char *esc,
|
||||
const char **pend /* = 0 */,
|
||||
bool multi /* = false */) const
|
||||
{
|
||||
assert (0 != esc);
|
||||
|
||||
const char escape = escape_char ();
|
||||
|
||||
if (escape != *esc)
|
||||
issue_diag (E_SYNTAX, true, 0,
|
||||
"expected the escape character ('%c'), got \"%s\"\n",
|
||||
escape, esc);
|
||||
|
||||
unsigned long value = 0;
|
||||
|
||||
for (const char *s = esc; ; ) {
|
||||
|
||||
// escaped characters are octal by default
|
||||
const char *basename = "octal";
|
||||
int base = 8;
|
||||
|
||||
switch (*++s) {
|
||||
case 'd': ++s; base = 10; basename = "decimal"; break;
|
||||
case 'x': ++s; base = 16; basename = "hexadecimal"; break;
|
||||
|
||||
case 'o': ++s;
|
||||
case '0': case '1': case '2': case '3':
|
||||
case '4': case '5': case '6': case '7':
|
||||
break;
|
||||
|
||||
default:
|
||||
issue_diag (E_SYNTAX, true, 0,
|
||||
"one of { 'o', 'd', 'x' } expected following "
|
||||
"the escape character: %s\n", esc);
|
||||
}
|
||||
|
||||
char *end = 0;
|
||||
|
||||
const unsigned long byte = std::strtoul (s, &end, base);
|
||||
|
||||
if (pend)
|
||||
*pend = end;
|
||||
|
||||
// cast away constness below to work around an MSVC 7.0 bug:
|
||||
// causing error C2446: '==' : no conversion from 'char ** '
|
||||
// to 'const char ** ' Conversion loses qualifiers
|
||||
if (!multi && _RWSTD_CONST_CAST (char**, pend) == &end && **pend)
|
||||
issue_diag (E_SYNTAX, true, 0,
|
||||
"%s constant expected: %s\n", basename, esc);
|
||||
|
||||
if (UCHAR_MAX < byte)
|
||||
issue_diag (E_INVAL, true, 0,
|
||||
"%s byte value must be in the range [0, %d]: %s\n",
|
||||
basename, int (UCHAR_MAX), esc);
|
||||
|
||||
if (value >> (sizeof (unsigned long) - 1) * CHAR_BIT)
|
||||
issue_diag (E_INVAL, true, 0, "integer overflow: %s\n", esc);
|
||||
|
||||
value = (value << CHAR_BIT) | byte;
|
||||
|
||||
if (**pend != escape || !multi)
|
||||
break;
|
||||
|
||||
s = *pend;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
233
extern/stdcxx/4.2.1/util/scanner.h
vendored
Normal file
233
extern/stdcxx/4.2.1/util/scanner.h
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* scanner.h
|
||||
*
|
||||
* $Id: scanner.h 648752 2008-04-16 17:01:56Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RWSTD_UTIL_SCANNER_H_INCLUDED
|
||||
#define RWSTD_UTIL_SCANNER_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <stack>
|
||||
#include <climits> // for ULONG_MAX
|
||||
|
||||
|
||||
struct ScannerContext;
|
||||
|
||||
|
||||
class Scanner
|
||||
{
|
||||
public:
|
||||
|
||||
// enumeration of all tokens in the character map
|
||||
// and locale definition file
|
||||
enum token_id {
|
||||
tok_code_set_name, // <code_set_name>
|
||||
tok_mb_cur_max, // <mb_cur_max>
|
||||
tok_mb_cur_min, // <mb_cur_min>
|
||||
// sections
|
||||
tok_charmap, // beginning of CHARMAP section
|
||||
tok_collate, // beginning of LC_COLLATE section
|
||||
tok_ctype, // beginning of LC_CTYPE section
|
||||
tok_messages, // beginning of LC_MESSAGES section
|
||||
tok_monetary, // beginning of LC_MONETARY section
|
||||
tok_numeric, // beginning of LC_NUMERIC section
|
||||
tok_time, // beginning of LC_TIME section
|
||||
// ISO/IEC TR 14652 extensions:
|
||||
tok_addr, // beginning of LC_ADDRESS section
|
||||
tok_ident, // beginning of LC_IDENTIFICATION section
|
||||
tok_measure, // beginning of LC_MEASUREMENT section
|
||||
tok_name, // beginning of LC_NAME section
|
||||
tok_paper, // beginning of LC_PAPER section
|
||||
tok_phone, // beginning of LC_TELEPHONE section
|
||||
//
|
||||
tok_end, // END of a section
|
||||
// LC_CTYPE-specific tokens
|
||||
tok_upper, // upper section of LC_CTYPE
|
||||
tok_lower, // lower section of LC_CTYPE
|
||||
tok_digit, // digit section of LC_CTYPE
|
||||
tok_space, // space section of LC_CTYPE
|
||||
tok_alpha, // alpha section of LC_CTYPE
|
||||
tok_graph, // graph section of LC_CTYPE
|
||||
tok_print, // print section of LC_CTYPE
|
||||
tok_cntrl, // cntrl section of LC_CTYPE
|
||||
tok_punct, // punct section of LC_CTYPE
|
||||
tok_xdigit, // xdigit section of LC_CTYPE
|
||||
tok_blank, // blank section of LC_CTYPE
|
||||
tok_tolower, // tolower section of LC_CTYPE
|
||||
tok_toupper, // toupper section of LC_CTYPE
|
||||
// LC_COLLATE-specific tokens
|
||||
tok_script,
|
||||
tok_coll_elem, // collating-element
|
||||
tok_coll_sym, // collating symbol
|
||||
tok_from,
|
||||
tok_xlit_start, // translit_start
|
||||
tok_xlit_end, // translit_end
|
||||
tok_reorder,
|
||||
tok_reorder_end,
|
||||
tok_reorder_section,
|
||||
tok_reorder_section_end,
|
||||
tok_order_start,
|
||||
tok_order_end,
|
||||
tok_forward,
|
||||
tok_backward,
|
||||
tok_position,
|
||||
tok_undefined,
|
||||
//
|
||||
tok_string,
|
||||
tok_ignore,
|
||||
// absolute, hexadecimal, decimal, and double-increment
|
||||
// ellipses (see ISO/IEC TR 14652)
|
||||
tok_abs_ellipsis, // "..."
|
||||
tok_hex_ellipsis, // ".."
|
||||
tok_dec_ellipsis, // "...."
|
||||
tok_dbl_ellipsis, // "..(N).."
|
||||
tok_width,
|
||||
// LC_MONETARY-specific tokens
|
||||
tok_int_curr_symbol,
|
||||
tok_currency_symbol,
|
||||
tok_mon_decimal_point,
|
||||
tok_mon_thousands_sep,
|
||||
tok_mon_grouping,
|
||||
tok_positive_sign,
|
||||
tok_negative_sign,
|
||||
tok_int_frac_digits,
|
||||
tok_frac_digits,
|
||||
tok_p_cs_precedes,
|
||||
tok_p_sep_by_space,
|
||||
tok_n_cs_precedes,
|
||||
tok_n_sep_by_space,
|
||||
tok_p_sign_posn,
|
||||
tok_n_sign_posn,
|
||||
tok_int_p_cs_precedes,
|
||||
tok_int_n_cs_precedes,
|
||||
tok_int_p_sep_by_space,
|
||||
tok_int_n_sep_by_space,
|
||||
tok_int_p_sign_posn,
|
||||
tok_int_n_sign_posn,
|
||||
// LC_NUMERIC-specific tokens
|
||||
tok_decimal_point, // decimal point
|
||||
tok_thousands_sep, // thousands_sep
|
||||
tok_grouping, // grouping
|
||||
tok_truename, // truename (C++ extension)
|
||||
tok_falsename, // falsename (C++ extension)
|
||||
// LC_TIME-specific tokens
|
||||
tok_abday,
|
||||
tok_day,
|
||||
tok_abmon,
|
||||
tok_mon,
|
||||
tok_d_t_fmt,
|
||||
tok_d_fmt,
|
||||
tok_t_fmt,
|
||||
tok_am_pm,
|
||||
tok_t_fmt_ampm,
|
||||
tok_era,
|
||||
tok_era_d_fmt,
|
||||
tok_era_t_fmt,
|
||||
tok_era_d_t_fmt,
|
||||
tok_alt_digits,
|
||||
// LC_MESSAGES-specific tokens
|
||||
tok_yesexpr,
|
||||
tok_noexpr,
|
||||
// LC_ADDRESS-specific tokens
|
||||
// LC_IDENTIFICATION-specific tokens
|
||||
// LC_MEASUREMENT-specific tokens
|
||||
// LC_NAME-specific tokens
|
||||
// LC_PAPER-specific tokens
|
||||
// LC_TELEPHONE-specific tokens
|
||||
// other:
|
||||
tok_sym_name, // symbolic character name
|
||||
tok_char_value, // character value (octal, decimal, or hex)
|
||||
tok_comment, // comment
|
||||
tok_comment_char, // <comment_char>
|
||||
tok_escape_char, // <escape_char>
|
||||
tok_copy, // copy directive
|
||||
tok_include, // include directive
|
||||
tok_nl, // newline
|
||||
tok_ndef, // unknown/undefined token
|
||||
tok_end_tokens // end of input
|
||||
};
|
||||
|
||||
// scanner states
|
||||
// enum {valid, invalid};
|
||||
|
||||
// a structure that represents a token
|
||||
struct token_t {
|
||||
std::string name;
|
||||
token_id token;
|
||||
|
||||
// file position
|
||||
int line;
|
||||
int column;
|
||||
|
||||
// file name pointer
|
||||
const char* file;
|
||||
};
|
||||
|
||||
// realization
|
||||
Scanner ();
|
||||
virtual ~Scanner();
|
||||
|
||||
// public interface
|
||||
token_t next_token ();
|
||||
|
||||
void open (std::string, char = '#', char = '\\');
|
||||
|
||||
void close ();
|
||||
|
||||
char escape_char () const;
|
||||
|
||||
void ignore_line ();
|
||||
|
||||
// converts an octal, decimal, or hexadecimal escape sequence
|
||||
// (or a multibyte sequence of such things) to a numeric value
|
||||
unsigned long
|
||||
convert_escape (const char*, const char** = 0, bool = false) const;
|
||||
|
||||
private:
|
||||
|
||||
Scanner (const Scanner&); // not defined
|
||||
void operator= (const Scanner&); // not defined
|
||||
|
||||
// helper function that identifies a token from a string and
|
||||
// returns a new token_t object
|
||||
token_id process_token (const char* name);
|
||||
|
||||
// read a line from stream
|
||||
void read_line ();
|
||||
|
||||
// current file context and stack of context objects
|
||||
ScannerContext* context_;
|
||||
std::stack<ScannerContext*> context_stack_;
|
||||
|
||||
unsigned nlines_; // number of lines read
|
||||
unsigned ntokens_; // number of tokens read
|
||||
|
||||
// was the last token an escaped newline
|
||||
bool escaped_newline_;
|
||||
};
|
||||
|
||||
|
||||
#endif // RWSTD_UTIL_SCANNER_H_INCLUDED
|
||||
134
extern/stdcxx/4.2.1/util/target.h
vendored
Normal file
134
extern/stdcxx/4.2.1/util/target.h
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* target.h - Struct definitions for target execution and results.
|
||||
*
|
||||
* $Id: target.h 598869 2007-11-28 05:08:25Z sebor $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RW_TARGET_H
|
||||
#define RW_TARGET_H
|
||||
|
||||
#include <time.h> /* for clock_t */
|
||||
|
||||
#if !defined (_WIN32) && !defined (_WIN64)
|
||||
# include <unistd.h> /* For _XOPEN_UNIX */
|
||||
#endif
|
||||
|
||||
#ifdef _XOPEN_UNIX
|
||||
# include <sys/resource.h> /* for struct rlimit */
|
||||
/**
|
||||
Abstraction typedef for struct rlimit using real struct
|
||||
*/
|
||||
typedef struct rlimit rw_rlimit;
|
||||
#else /* _XOPEN_UNIX */
|
||||
/**
|
||||
Placeholder rlim_t for use in rw_rlimit
|
||||
*/
|
||||
typedef unsigned long rw_rlim_t;
|
||||
/**
|
||||
Placeholder struct rlimit to use if _XOPEN_UNIX isn't defined
|
||||
*/
|
||||
struct rw_rlimit {
|
||||
rw_rlim_t rlim_cur;
|
||||
rw_rlim_t rlim_max;
|
||||
};
|
||||
/**
|
||||
Abstraction typedef for struct rlimit using placeholder struct
|
||||
*/
|
||||
typedef struct rw_rlimit rw_rlimit;
|
||||
#endif /* _XOPEN_UNIX */
|
||||
|
||||
#ifndef RLIM_INFINITY
|
||||
# define RLIM_INFINITY -1
|
||||
#endif /* RLIM_INFINITY */
|
||||
|
||||
#ifndef RLIM_SAVED_CUR
|
||||
# define RLIM_SAVED_CUR RLIM_INFINITY
|
||||
#endif /* RLIM_SAVED_CUR */
|
||||
|
||||
#ifndef RLIM_SAVED_MAX
|
||||
# define RLIM_SAVED_MAX RLIM_INFINITY
|
||||
#endif /* RLIM_SAVED_MAX */
|
||||
|
||||
/**
|
||||
Structure encapsulating the options involved in executing a run.
|
||||
*/
|
||||
struct target_opts {
|
||||
char** argv; /**< Target argv array. */
|
||||
unsigned timeout; /**< Allowed time for process execution. */
|
||||
const char* data_dir; /**< Root dir for reference input/output files. */
|
||||
const char* c_warn; /**< Warning flag string when compiling. */
|
||||
const char* l_warn; /**< Warning flag string when linking. */
|
||||
const char* infname; /**< Input file to redirect stdin from. */
|
||||
const char* outfname; /**< Output file to redirect stdout to. */
|
||||
int compat; /**< Test suite compatability mode switch. */
|
||||
int verbose; /**< Verbose mode. */
|
||||
rw_rlimit* core;
|
||||
rw_rlimit* cpu;
|
||||
rw_rlimit* data;
|
||||
rw_rlimit* fsize;
|
||||
rw_rlimit* nofile;
|
||||
rw_rlimit* stack;
|
||||
rw_rlimit* as;
|
||||
};
|
||||
|
||||
/**
|
||||
Status codes to denote result of analysis.
|
||||
*/
|
||||
enum ProcessStatus {
|
||||
ST_OK = 0, /**< Default (OK) status */
|
||||
ST_COMPILE, /**< Target failed to compile */
|
||||
ST_LINK, /**< Target failed to link */
|
||||
ST_EXIST, /**< Target doesn't exist? */
|
||||
ST_EXECUTE_FLAG, /**< Target lacks X flag */
|
||||
ST_EXECUTE, /**< Target failed to execute? */
|
||||
ST_NO_OUTPUT, /**< Target produced no output */
|
||||
ST_NO_REF, /**< No reference file found */
|
||||
ST_BAD_REF, /**< Invalid reference file found */
|
||||
ST_BAD_OUTPUT, /**< Incorrect output found */
|
||||
ST_FORMAT, /**< Incorrectly formatted (test) output found */
|
||||
ST_OVERFLOW, /**< Assertion counter overflow */
|
||||
ST_SYSTEM_ERROR, /**< System error during file system operation */
|
||||
ST_KILLED, /**< Target killed by exec utility */
|
||||
ST_NOT_KILLED, /** Target not killed by exec utility */
|
||||
ST_LAST /**< Array terminator */
|
||||
};
|
||||
|
||||
/**
|
||||
Structure encapsulating the results extracted from a run.
|
||||
*/
|
||||
struct target_status {
|
||||
int exit; /**< exit/signal code for process. */
|
||||
int signaled; /**< 1 if exit is a signal number, 0 denoting exit code
|
||||
otherwise */
|
||||
enum ProcessStatus status; /**< Textual process status. */
|
||||
clock_t usr_time; /**< Elapsed user time spent in execution. */
|
||||
clock_t sys_time; /**< Elapsed system time spent in execution. */
|
||||
clock_t wall_time; /**< Wall clock time spent in execution. */
|
||||
unsigned c_warn; /**< Number of compile warnings. */
|
||||
unsigned l_warn; /**< Number of link warnings. */
|
||||
unsigned t_warn; /**< Number of (test) warnings. */
|
||||
unsigned assert; /**< Number of (test) assertions. */
|
||||
unsigned failed; /**< Number of failed (test) assertions. */
|
||||
};
|
||||
|
||||
#endif /* RW_TARGET_H */
|
||||
635
extern/stdcxx/4.2.1/util/time.cpp
vendored
Normal file
635
extern/stdcxx/4.2.1/util/time.cpp
vendored
Normal file
@@ -0,0 +1,635 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* time.cpp
|
||||
*
|
||||
* $Id: time.cpp 648752 2008-04-16 17:01:56Z faridz $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2008 Rogue Wave Software, Inc.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "def.h" // for Def
|
||||
#include "diagnostic.h" // for issue_diag()
|
||||
#include "path.h" // for get_pathname()
|
||||
#include "scanner.h" // for scanner
|
||||
|
||||
#include <cassert> // for assert()
|
||||
#include <cstdio> // for fscanf()
|
||||
#include <cstring> // for strcmp(), strtok()
|
||||
#include <fstream> // for ofstream
|
||||
|
||||
|
||||
static const char lc_name[] = "LC_TIME";
|
||||
|
||||
|
||||
void Def::
|
||||
parse_era (const token_t& tok)
|
||||
{
|
||||
// to make processing the era a little easier, first convert
|
||||
// the era_str with possible symbolic names to a narrow string
|
||||
// without symbolic names
|
||||
std::string era = convert_string (tok.name);
|
||||
|
||||
if (era.empty ())
|
||||
return;
|
||||
|
||||
// we need to also parse the wide version of this string so that we
|
||||
// may get the wide version of the era name and format
|
||||
const std::wstring wera = convert_wstring (tok);
|
||||
|
||||
char* const erap = _RWSTD_CONST_CAST (char*, era.c_str ());
|
||||
|
||||
const wchar_t* const werap = wera.c_str ();
|
||||
|
||||
// first get the direction
|
||||
char* tokp = std::strtok (erap, ":");
|
||||
const char direction = tokp ? *tokp : '\0';
|
||||
|
||||
era_st tmp_era = era_st ();
|
||||
|
||||
// now get the offset
|
||||
tokp = std::strtok (0, ":");
|
||||
if (0 == tokp)
|
||||
issue_diag (E_SYNTAX, true, &tok,
|
||||
"expected ':' in era definition\n");
|
||||
|
||||
assert (0 != tokp);
|
||||
|
||||
std::sscanf (tokp, "%d", &tmp_era.era_out.offset);
|
||||
if (direction == '-')
|
||||
tmp_era.era_out.offset *= -1;
|
||||
|
||||
// now get the start date
|
||||
tokp = std::strtok (0, ":");
|
||||
if (0 == tokp)
|
||||
issue_diag (E_SYNTAX, true, &tok,
|
||||
"expected ':' in era definition\n");
|
||||
|
||||
assert (0 != tokp);
|
||||
|
||||
unsigned int tmp_mon, tmp_day;
|
||||
std::sscanf (tokp, "%d/%u/%u", &tmp_era.era_out.year[0],
|
||||
&tmp_mon, &tmp_day);
|
||||
// the month is offset by one ot be in the range [0-11]
|
||||
tmp_era.era_out.month[0] = char(tmp_mon - 1);
|
||||
tmp_era.era_out.day[0] = char(tmp_day);
|
||||
|
||||
|
||||
// now get the end date (this may be the beginning or end of time
|
||||
tokp = std::strtok (0, ":");
|
||||
if (0 == tokp)
|
||||
issue_diag (E_SYNTAX, true, &tok,
|
||||
"expected ':' in era definition\n");
|
||||
|
||||
assert (0 != tokp);
|
||||
|
||||
if (std::strcmp (tokp, "-*") == 0) {
|
||||
tmp_era.era_out.year[1] = _RWSTD_INT_MIN;
|
||||
tmp_era.era_out.month[1] = _RWSTD_CHAR_MIN;
|
||||
tmp_era.era_out.day[1] = _RWSTD_CHAR_MIN;
|
||||
}
|
||||
else if (std::strcmp (tokp, "+*") == 0) {
|
||||
tmp_era.era_out.year[1] = _RWSTD_INT_MAX;
|
||||
tmp_era.era_out.month[1] = _RWSTD_CHAR_MAX;
|
||||
tmp_era.era_out.day[1] = _RWSTD_CHAR_MAX;
|
||||
}
|
||||
else {
|
||||
std::sscanf (tokp, "%d/%u/%u", &tmp_era.era_out.year[1],
|
||||
&tmp_mon, &tmp_day);
|
||||
// the month is offset by one to be in the range [0-11]
|
||||
tmp_era.era_out.month[1] = char(tmp_mon - 1);
|
||||
tmp_era.era_out.day[1] = char(tmp_day);
|
||||
|
||||
}
|
||||
// now get the name of the era
|
||||
tokp = std::strtok (0, ":");
|
||||
tmp_era.name = tokp;
|
||||
|
||||
// finally get the format string if one is available
|
||||
tokp = std::strtok (0, ":");
|
||||
if (0 != tokp)
|
||||
tmp_era.fmt = tokp;
|
||||
|
||||
// FIXME: check the values
|
||||
//advance to name of the era inside the wide char string
|
||||
const wchar_t *wtokp = werap;
|
||||
for (int i = 0; i < 4 && *wtokp; i++)
|
||||
while (*wtokp && *(wtokp++) != L':');
|
||||
|
||||
if (*wtokp) {
|
||||
while (*wtokp != L':')
|
||||
tmp_era.wname += *wtokp++;
|
||||
|
||||
// advance past the current ':'
|
||||
wtokp++;
|
||||
}
|
||||
|
||||
if (*wtokp)
|
||||
tmp_era.wfmt = wtokp;
|
||||
|
||||
era_list_.push_back (tmp_era);
|
||||
time_out_.num_eras++;
|
||||
}
|
||||
|
||||
|
||||
Scanner::token_t Def::
|
||||
extract_string_array (std::string *str,
|
||||
std::wstring *wstr,
|
||||
std::size_t nelems)
|
||||
{
|
||||
assert (0 != str);
|
||||
assert (0 != wstr);
|
||||
|
||||
Scanner::token_t tok;
|
||||
|
||||
for (std::size_t i = 0; i != nelems; ++i) {
|
||||
|
||||
tok = scanner_.next_token ();
|
||||
|
||||
if (tok.token != Scanner::tok_string) {
|
||||
issue_diag (W_MISSING, false, &tok, "expected string");
|
||||
break;
|
||||
}
|
||||
|
||||
str [i] = convert_string (tok.name);
|
||||
wstr [i] = convert_wstring (tok);
|
||||
}
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
||||
|
||||
void Def::process_time ()
|
||||
{
|
||||
issue_diag (I_STAGE, false, 0, "processing %s section\n", lc_name);
|
||||
|
||||
// nesting level
|
||||
int nesting_level = 0;
|
||||
|
||||
time_def_found_ = true;
|
||||
|
||||
while ((next = scanner_.next_token ()).token != Scanner::tok_time) {
|
||||
|
||||
switch (next.token) {
|
||||
|
||||
case Scanner::tok_end:
|
||||
next = scanner_.next_token ();
|
||||
if (next.token == Scanner::tok_time) {
|
||||
// end of numeric block
|
||||
if (nesting_level == 0)
|
||||
return;
|
||||
|
||||
--nesting_level;
|
||||
scanner_.close ();
|
||||
}
|
||||
else
|
||||
issue_diag (E_SYNTAX, true, &next,
|
||||
"wrong section name in END directive\n");
|
||||
break;
|
||||
|
||||
case Scanner::tok_copy: {
|
||||
next = scanner_.next_token();
|
||||
if (next.token != Scanner::tok_string)
|
||||
issue_diag (E_SYNTAX, true, &next,
|
||||
"expected string following \"copy\" directive\n");
|
||||
|
||||
// bump up the nesting level
|
||||
++nesting_level;
|
||||
|
||||
// open the file
|
||||
scanner_.open (get_pathname (strip_quotes (next.name), next.file));
|
||||
|
||||
// get comment char and escape char;
|
||||
// these informations are stored by the scanner
|
||||
while ((next = scanner_.next_token ()).token != Scanner::tok_time) {
|
||||
// the LC_IDENTIFICATION section may also have a
|
||||
// LC_TIME token that will mess up the parsing
|
||||
if (next.token == Scanner::tok_ident) {
|
||||
while ((next = scanner_.next_token ()).token
|
||||
!= Scanner::tok_end);
|
||||
next = scanner_.next_token ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_abday: {
|
||||
|
||||
const std::size_t nelems =
|
||||
sizeof time_st_.abday / sizeof *time_st_.abday;
|
||||
|
||||
next = extract_string_array (time_st_.abday,
|
||||
time_st_.wabday,
|
||||
nelems);
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_day: {
|
||||
|
||||
const std::size_t nelems =
|
||||
sizeof time_st_.day / sizeof *time_st_.day;
|
||||
|
||||
next = extract_string_array (time_st_.day,
|
||||
time_st_.wday,
|
||||
nelems);
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_abmon: {
|
||||
|
||||
const std::size_t nelems =
|
||||
sizeof time_st_.abmon / sizeof *time_st_.abmon;
|
||||
|
||||
next = extract_string_array (time_st_.abmon,
|
||||
time_st_.wabmon,
|
||||
nelems);
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_mon: {
|
||||
|
||||
const std::size_t nelems =
|
||||
sizeof time_st_.mon / sizeof *time_st_.mon;
|
||||
|
||||
next = extract_string_array (time_st_.mon,
|
||||
time_st_.wmon,
|
||||
nelems);
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_d_t_fmt:
|
||||
next = scanner_.next_token();
|
||||
time_st_.d_t_fmt = convert_string (next.name);
|
||||
time_st_.wd_t_fmt = convert_wstring (next);
|
||||
break;
|
||||
|
||||
case Scanner::tok_d_fmt:
|
||||
next = scanner_.next_token();
|
||||
time_st_.d_fmt = convert_string (next.name);
|
||||
time_st_.wd_fmt = convert_wstring (next);
|
||||
break;
|
||||
case Scanner::tok_t_fmt:
|
||||
next = scanner_.next_token();
|
||||
time_st_.t_fmt = convert_string (next.name);
|
||||
time_st_.wt_fmt = convert_wstring (next);
|
||||
break;
|
||||
|
||||
case Scanner::tok_am_pm: {
|
||||
const std::size_t nelems =
|
||||
sizeof time_st_.am_pm / sizeof *time_st_.am_pm;
|
||||
|
||||
next = extract_string_array (time_st_.am_pm,
|
||||
time_st_.wam_pm,
|
||||
nelems);
|
||||
break;
|
||||
}
|
||||
|
||||
case Scanner::tok_t_fmt_ampm:
|
||||
next = scanner_.next_token();
|
||||
time_st_.t_fmt_ampm = convert_string (next.name);
|
||||
time_st_.wt_fmt_ampm = convert_wstring (next);
|
||||
break;
|
||||
// The time_get and time_put facets do not make use of eras or
|
||||
// alternate digits, so we will ignore this part of the locale
|
||||
// definition
|
||||
case Scanner::tok_era:
|
||||
while ((next = scanner_.next_token()).token == Scanner::tok_string)
|
||||
parse_era (next);
|
||||
break;
|
||||
case Scanner::tok_era_d_fmt:
|
||||
next = scanner_.next_token();
|
||||
time_st_.era_d_fmt = convert_string (next.name);
|
||||
time_st_.wera_d_fmt = convert_wstring (next);
|
||||
break;
|
||||
case Scanner::tok_era_t_fmt:
|
||||
next = scanner_.next_token();
|
||||
time_st_.era_t_fmt = convert_string (next.name);
|
||||
time_st_.wera_t_fmt = convert_wstring (next);
|
||||
break;
|
||||
case Scanner::tok_era_d_t_fmt:
|
||||
next = scanner_.next_token();
|
||||
time_st_.era_d_t_fmt = convert_string (next.name);
|
||||
time_st_.wera_d_t_fmt = convert_wstring (next);
|
||||
break;
|
||||
case Scanner::tok_alt_digits:
|
||||
while ((next = scanner_.next_token()).token == Scanner::tok_string)
|
||||
{
|
||||
alt_digit_t digit;
|
||||
digit.n_alt_digit = convert_string (next.name);
|
||||
digit.w_alt_digit = convert_wstring (next);
|
||||
digit.n_offset = 0;
|
||||
digit.w_offset = 0;
|
||||
alt_digits_.push_back (digit);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Def::write_time(std::string dir_name)
|
||||
{
|
||||
assert (!dir_name.empty());
|
||||
|
||||
if (time_written_)
|
||||
return;
|
||||
|
||||
if (!time_def_found_) {
|
||||
issue_diag (I_SKIP, false, 0,
|
||||
"%s section not found, skipping\n", lc_name);
|
||||
return;
|
||||
}
|
||||
|
||||
// write out all the information in the LC_TIME category
|
||||
|
||||
(dir_name += _RWSTD_PATH_SEP) += lc_name;
|
||||
|
||||
issue_diag (I_OPENWR, false, 0, "writing %s\n", dir_name.c_str ());
|
||||
|
||||
std::ofstream out (dir_name.c_str(), std::ios::binary);
|
||||
out.exceptions (std::ios::failbit | std::ios::badbit);
|
||||
|
||||
int i;
|
||||
|
||||
time_out_.num_alt_digits = alt_digits_.size();
|
||||
time_out_.era_off = 0;
|
||||
|
||||
time_out_.alt_digits_off = time_out_.era_off +
|
||||
sizeof (_RW::__rw_time_t::era_t) * era_list_.size();
|
||||
|
||||
// now calculate all the offsets for the wide string representations
|
||||
time_out_.abday_off[1][0] = time_out_.alt_digits_off +
|
||||
2 * sizeof (unsigned int) * time_out_.num_alt_digits;
|
||||
|
||||
for (i = 1; i < 7; i++) {
|
||||
time_out_.abday_off[1][i] = time_out_.abday_off[1][i-1]
|
||||
+ (time_st_.wabday[i-1].size() * sizeof (wchar_t))
|
||||
+ sizeof(wchar_t);
|
||||
}
|
||||
|
||||
time_out_.day_off[1][0] = time_out_.abday_off[1][6]
|
||||
+ time_st_.wabday[6].size() * sizeof (wchar_t)
|
||||
+ sizeof (wchar_t);
|
||||
for (i = 1; i < 7; i++) {
|
||||
time_out_.day_off[1][i] = time_out_.day_off[1][i-1]
|
||||
+ time_st_.wday[i-1].size() * sizeof (wchar_t)
|
||||
+ sizeof (wchar_t);
|
||||
}
|
||||
|
||||
time_out_.abmon_off[1][0] = time_out_.day_off[1][6]
|
||||
+ time_st_.wday[6].size() * sizeof (wchar_t) + sizeof (wchar_t);
|
||||
for (i = 1; i < 12; i++) {
|
||||
time_out_.abmon_off[1][i] = time_out_.abmon_off[1][i-1]
|
||||
+ time_st_.wabmon[i-1].size() * sizeof (wchar_t)
|
||||
+ sizeof (wchar_t);
|
||||
}
|
||||
|
||||
time_out_.mon_off[1][0] = time_out_.abmon_off[1][11]
|
||||
+ time_st_.wabmon[11].size() * sizeof (wchar_t)
|
||||
+ sizeof (wchar_t);
|
||||
for (i = 1; i < 12; i++) {
|
||||
time_out_.mon_off[1][i] = time_out_.mon_off[1][i-1]
|
||||
+ time_st_.wmon[i-1].size() * sizeof (wchar_t)
|
||||
+ sizeof (wchar_t);
|
||||
}
|
||||
|
||||
time_out_.am_pm_off[1][0] = time_out_.mon_off[1][11]
|
||||
+ time_st_.wmon[11].size() * sizeof (wchar_t) + sizeof (wchar_t);
|
||||
time_out_.am_pm_off[1][1] = time_out_.am_pm_off[1][0]
|
||||
+ time_st_.wam_pm[0].size() * sizeof (wchar_t) + sizeof (wchar_t);
|
||||
|
||||
time_out_.d_t_fmt_off[1] = time_out_.am_pm_off[1][1]
|
||||
+ time_st_.wam_pm[1].size() * sizeof (wchar_t)
|
||||
+ sizeof (wchar_t);
|
||||
time_out_.d_fmt_off[1] = time_out_.d_t_fmt_off[1]
|
||||
+ time_st_.wd_t_fmt.size() * sizeof (wchar_t) + sizeof (wchar_t);
|
||||
time_out_.t_fmt_off[1] = time_out_.d_fmt_off[1]
|
||||
+ time_st_.wd_fmt.size() * sizeof (wchar_t) + sizeof (wchar_t);
|
||||
time_out_.t_fmt_ampm_off[1] = time_out_.t_fmt_off[1]
|
||||
+ time_st_.wt_fmt.size() * sizeof (wchar_t) + sizeof (wchar_t);
|
||||
|
||||
time_out_.era_d_t_fmt_off[1] = time_out_.t_fmt_ampm_off[1]
|
||||
+ time_st_.wt_fmt_ampm.size() * sizeof (wchar_t)
|
||||
+ sizeof (wchar_t);
|
||||
time_out_.era_d_fmt_off[1] = time_out_.era_d_t_fmt_off[1]
|
||||
+ time_st_.wera_d_t_fmt.size() * sizeof (wchar_t)
|
||||
+ sizeof (wchar_t);
|
||||
time_out_.era_t_fmt_off[1] = time_out_.era_d_fmt_off[1]
|
||||
+ time_st_.wera_d_fmt.size() * sizeof (wchar_t) + sizeof (wchar_t);
|
||||
|
||||
unsigned int next_off = time_out_.era_t_fmt_off[1]
|
||||
+ time_st_.wera_t_fmt.size() * sizeof (wchar_t) + sizeof (wchar_t);
|
||||
era_list_iter era_list_it;
|
||||
for (era_list_it = era_list_.begin(); era_list_it != era_list_.end();
|
||||
era_list_it ++) {
|
||||
era_list_it->era_out.name_off[1] = next_off;
|
||||
next_off += era_list_it->wname.size()
|
||||
* sizeof (wchar_t) + sizeof (wchar_t);
|
||||
era_list_it->era_out.fmt_off[1] = next_off;
|
||||
next_off += era_list_it->wfmt.size()
|
||||
* sizeof (wchar_t) + sizeof (wchar_t);
|
||||
}
|
||||
|
||||
alt_digits_iter alt_digits_it;
|
||||
for (alt_digits_it = alt_digits_.begin();
|
||||
alt_digits_it != alt_digits_.end(); alt_digits_it ++ ){
|
||||
alt_digits_it->w_offset = next_off;
|
||||
next_off += (alt_digits_it->w_alt_digit.size() + 1)
|
||||
* sizeof(wchar_t);
|
||||
}
|
||||
|
||||
time_out_.abday_off[0][0] = next_off;
|
||||
|
||||
for (i = 1; i < 7; i++) {
|
||||
// calculate the offsets for the abreviated days
|
||||
time_out_.abday_off[0][i] = time_out_.abday_off[0][i-1]
|
||||
+ time_st_.abday[i - 1].size() + 1;
|
||||
}
|
||||
|
||||
time_out_.day_off[0][0] = time_out_.abday_off[0][6]
|
||||
+ time_st_.abday[6].size() + 1;
|
||||
for (i = 1; i < 7; i++) {
|
||||
// calculate the offsets for the days
|
||||
time_out_.day_off[0][i] = time_out_.day_off[0][i-1]
|
||||
+ time_st_.day[i-1].size() + 1;
|
||||
}
|
||||
|
||||
time_out_.abmon_off[0][0] = time_out_.day_off[0][6]
|
||||
+ time_st_.day[6].size() + 1;
|
||||
for (i = 1; i < 12; i++) {
|
||||
// calculate the offsets for the abreviated months
|
||||
time_out_.abmon_off[0][i] = time_out_.abmon_off[0][i-1]
|
||||
+ time_st_.abmon[i-1].size() + 1;
|
||||
}
|
||||
|
||||
time_out_.mon_off[0][0] = time_out_.abmon_off[0][11]
|
||||
+ time_st_.abmon[11].size() + 1;
|
||||
for (i = 1; i < 12; i++) {
|
||||
// calculate the offsets for the months
|
||||
time_out_.mon_off[0][i] = time_out_.mon_off[0][i-1]
|
||||
+ time_st_.mon[i-1].size() + 1;
|
||||
}
|
||||
|
||||
// calculate the offsets for am and pm
|
||||
time_out_.am_pm_off[0][0] = time_out_.mon_off[0][11]
|
||||
+ time_st_.mon[11].size() + 1;
|
||||
time_out_.am_pm_off[0][1] = time_out_.am_pm_off[0][0]
|
||||
+ time_st_.am_pm[0].size() + 1;
|
||||
|
||||
time_out_.d_t_fmt_off[0] = time_out_.am_pm_off[0][1]
|
||||
+ time_st_.am_pm[1].size() + 1;
|
||||
time_out_.d_fmt_off[0] = time_out_.d_t_fmt_off[0]
|
||||
+ time_st_.d_t_fmt.size() + 1;
|
||||
time_out_.t_fmt_off[0] = time_out_.d_fmt_off[0]
|
||||
+ time_st_.d_fmt.size() + 1;
|
||||
time_out_.t_fmt_ampm_off[0] = time_out_.t_fmt_off[0]
|
||||
+ time_st_.t_fmt.size() + 1;
|
||||
|
||||
time_out_.era_d_t_fmt_off[0] = time_out_.t_fmt_ampm_off[0]
|
||||
+ time_st_.t_fmt_ampm.size() + 1;
|
||||
time_out_.era_d_fmt_off[0] = time_out_.era_d_t_fmt_off[0]
|
||||
+ time_st_.era_d_t_fmt.size() + 1;
|
||||
time_out_.era_t_fmt_off[0] = time_out_.era_d_fmt_off[0]
|
||||
+ time_st_.era_d_fmt.size() + 1;
|
||||
|
||||
|
||||
|
||||
next_off = time_out_.era_t_fmt_off[0]
|
||||
+ time_st_.era_t_fmt.size() + 1;
|
||||
|
||||
for (era_list_it = era_list_.begin(); era_list_it != era_list_.end();
|
||||
era_list_it ++) {
|
||||
era_list_it->era_out.name_off[0] = next_off;
|
||||
next_off += era_list_it->name.size() + 1;
|
||||
era_list_it->era_out.fmt_off[0] = next_off;
|
||||
next_off += era_list_it->fmt.size() + 1;
|
||||
}
|
||||
|
||||
for (alt_digits_it = alt_digits_.begin();
|
||||
alt_digits_it != alt_digits_.end(); alt_digits_it ++ ){
|
||||
alt_digits_it->n_offset = next_off;
|
||||
next_off += alt_digits_it->n_alt_digit.size() + 1;
|
||||
}
|
||||
|
||||
|
||||
time_out_.codeset_off = next_off;
|
||||
|
||||
time_out_.charmap_off = time_out_.codeset_off
|
||||
+ charmap_.get_code_set_name().size() + 1;
|
||||
|
||||
// write the time struct
|
||||
out.write ((char*)&time_out_, sizeof(time_out_));
|
||||
|
||||
// first write out the era structs
|
||||
for (era_list_it = era_list_.begin(); era_list_it != era_list_.end();
|
||||
era_list_it ++) {
|
||||
out.write ((const char*) &era_list_it->era_out,
|
||||
sizeof (era_list_it->era_out));
|
||||
}
|
||||
|
||||
// next write out the offsets to where the alternate digits are stored
|
||||
for (alt_digits_it = alt_digits_.begin();
|
||||
alt_digits_it != alt_digits_.end(); alt_digits_it ++ ){
|
||||
out.write ((const char*) &alt_digits_it->n_offset,
|
||||
sizeof (alt_digits_it->n_offset));
|
||||
out.write ((const char*) &alt_digits_it->w_offset,
|
||||
sizeof (alt_digits_it->w_offset));
|
||||
}
|
||||
|
||||
// now write out the wchar_t version of LC_TIME
|
||||
for (i = 0; i < 7; i++){
|
||||
out.write ((const char*)time_st_.wabday[i].c_str(),
|
||||
(time_st_.wabday[i].size() + 1) * sizeof (wchar_t));
|
||||
}
|
||||
for (i = 0; i < 7; i++)
|
||||
out.write ((const char*)time_st_.wday[i].c_str(),
|
||||
(time_st_.wday[i].size() + 1) * sizeof (wchar_t));
|
||||
for (i = 0; i < 12; i++)
|
||||
out.write ((const char*)time_st_.wabmon[i].c_str(),
|
||||
(time_st_.wabmon[i].size() + 1) * sizeof (wchar_t));
|
||||
for (i = 0; i < 12; i++)
|
||||
out.write ((const char*)time_st_.wmon[i].c_str(),
|
||||
(time_st_.wmon[i].size() + 1) * sizeof (wchar_t));
|
||||
for (i = 0; i < 2; i++)
|
||||
out.write ((const char*)time_st_.wam_pm[i].c_str(),
|
||||
(time_st_.wam_pm[i].size() + 1) * sizeof (wchar_t));
|
||||
out.write ((const char*)time_st_.wd_t_fmt.c_str(),
|
||||
(time_st_.wd_t_fmt.size() + 1) * sizeof (wchar_t));
|
||||
out.write ((const char*)time_st_.wd_fmt.c_str(),
|
||||
(time_st_.wd_fmt.size() + 1) * sizeof (wchar_t));
|
||||
out.write ((const char*)time_st_.wt_fmt.c_str(),
|
||||
(time_st_.wt_fmt.size() + 1) * sizeof (wchar_t));
|
||||
out.write ((const char*)time_st_.wt_fmt_ampm.c_str(),
|
||||
(time_st_.wt_fmt_ampm.size() + 1) * sizeof (wchar_t));
|
||||
out.write ((const char*)time_st_.wera_d_t_fmt.c_str(),
|
||||
(time_st_.wera_d_t_fmt.size() + 1) * sizeof (wchar_t));
|
||||
out.write ((const char*)time_st_.wera_d_fmt.c_str(),
|
||||
(time_st_.wera_d_fmt.size() + 1) * sizeof (wchar_t));
|
||||
out.write ((const char*)time_st_.wera_t_fmt.c_str(),
|
||||
(time_st_.wera_t_fmt.size() + 1) * sizeof (wchar_t));
|
||||
for (era_list_it = era_list_.begin(); era_list_it != era_list_.end();
|
||||
era_list_it ++) {
|
||||
out.write ((const char*) era_list_it->wname.c_str(),
|
||||
(era_list_it->wname.size() + 1) * sizeof (wchar_t));
|
||||
out.write ((const char*) era_list_it->wfmt.c_str(),
|
||||
(era_list_it->wfmt.size() + 1) * sizeof (wchar_t));
|
||||
}
|
||||
for (alt_digits_it = alt_digits_.begin();
|
||||
alt_digits_it != alt_digits_.end(); alt_digits_it ++ ){
|
||||
out.write ((const char*) alt_digits_it->w_alt_digit.c_str(),
|
||||
(alt_digits_it->w_alt_digit.size() + 1)
|
||||
* sizeof (wchar_t));
|
||||
}
|
||||
|
||||
// write out the char version of LC_TIME
|
||||
for (i = 0; i < 7; i++)
|
||||
out << time_st_.abday[i] << std::ends;
|
||||
for (i = 0; i < 7; i++)
|
||||
out << time_st_.day[i] << std::ends;
|
||||
for (i = 0; i < 12; i++)
|
||||
out << time_st_.abmon[i] << std::ends;
|
||||
for (i = 0; i < 12; i++)
|
||||
out << time_st_.mon[i] << std::ends;
|
||||
for (i = 0; i < 2; i++)
|
||||
out << time_st_.am_pm[i] << std::ends;
|
||||
out << time_st_.d_t_fmt << std::ends;
|
||||
out << time_st_.d_fmt << std::ends;
|
||||
out << time_st_.t_fmt << std::ends;
|
||||
out << time_st_.t_fmt_ampm << std::ends;
|
||||
out << time_st_.era_d_t_fmt << std::ends;
|
||||
out << time_st_.era_d_fmt << std::ends;
|
||||
out << time_st_.era_t_fmt << std::ends;
|
||||
for (era_list_it = era_list_.begin(); era_list_it != era_list_.end();
|
||||
era_list_it ++) {
|
||||
out << era_list_it->name << std::ends;
|
||||
out << era_list_it->fmt << std::ends;
|
||||
}
|
||||
for (alt_digits_it = alt_digits_.begin();
|
||||
alt_digits_it != alt_digits_.end(); alt_digits_it ++ ){
|
||||
out << alt_digits_it->n_alt_digit << std::ends;
|
||||
}
|
||||
|
||||
out << charmap_.get_code_set_name() << std::ends;
|
||||
out << charmap_.get_charmap_name() << std::ends;
|
||||
}
|
||||
315
extern/stdcxx/4.2.1/util/util.cpp
vendored
Normal file
315
extern/stdcxx/4.2.1/util/util.cpp
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* util.cpp - Utility function definitions for the exec utility
|
||||
*
|
||||
* $Id: util.cpp 590510 2007-10-30 23:30:35Z sebor $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <assert.h> /* for assert */
|
||||
#include <errno.h> /* for errno */
|
||||
#include <signal.h> /* for sigaction(), signal() */
|
||||
#include <stdio.h> /* for vfprintf */
|
||||
#include <stdlib.h> /* for exit, malloc */
|
||||
#include <stdarg.h> /* for va_* */
|
||||
#include <string.h> /* for strerror */
|
||||
|
||||
#include <sys/stat.h> /* for stat() */
|
||||
#include <sys/types.h> /* for size_t */
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <unistd.h> /* for sleep() */
|
||||
#else
|
||||
# include <windows.h> /* for Sleep() */
|
||||
#endif /* _WIN{32,64} */
|
||||
|
||||
|
||||
#include "cmdopt.h" /* for exe_name, target_name */
|
||||
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
# define DEV_NULL "NUL:"
|
||||
#else
|
||||
# define DEV_NULL "/dev/null"
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
void
|
||||
warn (const char* const format, ...)
|
||||
{
|
||||
const char* const target_name = get_target ();
|
||||
va_list args;
|
||||
|
||||
assert (0 != format);
|
||||
|
||||
if (target_name)
|
||||
fprintf (stderr, "%s (%s): ", exe_name, target_name);
|
||||
else
|
||||
fprintf (stderr, "%s: ", exe_name);
|
||||
|
||||
va_start (args, format);
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void
|
||||
terminate (const int state, const char* const format, ...)
|
||||
{
|
||||
const char* const target_name = get_target ();
|
||||
va_list args;
|
||||
|
||||
assert (0 != format);
|
||||
assert (0 != state);
|
||||
|
||||
if (target_name)
|
||||
fprintf (stderr, "%s (%s): ", exe_name, target_name);
|
||||
else
|
||||
fprintf (stderr, "%s: ", exe_name);
|
||||
|
||||
va_start (args, format);
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
|
||||
exit (state);
|
||||
}
|
||||
|
||||
void*
|
||||
guarded_malloc (const size_t size, const char* const file, const unsigned line)
|
||||
{
|
||||
void* alloc;
|
||||
|
||||
assert (0 != file);
|
||||
assert (0 < size);
|
||||
|
||||
alloc = malloc (size);
|
||||
|
||||
if (0 == alloc)
|
||||
terminate (1, "malloc (%lu) at line %u of %s failed: %s\n",
|
||||
(unsigned long)size, line, file, strerror (errno));
|
||||
|
||||
return alloc;
|
||||
}
|
||||
|
||||
void*
|
||||
guarded_realloc (void* source, const size_t size, const char* const file,
|
||||
const unsigned line)
|
||||
{
|
||||
void* alloc;
|
||||
|
||||
assert (0 != file);
|
||||
assert (0 < size);
|
||||
|
||||
alloc = realloc (source, size);
|
||||
|
||||
if (0 == alloc)
|
||||
terminate (1, "malloc(%lu) at line %u of %s failed: %s\n",
|
||||
(unsigned long)size, line, file, strerror (errno));
|
||||
|
||||
return alloc;
|
||||
}
|
||||
|
||||
char*
|
||||
reference_name (const char* data_dir, const char* subdir, const char* mode)
|
||||
{
|
||||
size_t root_len, cmp_len, dir_len, mode_len, net_len;
|
||||
char* ref_name;
|
||||
char* tail;
|
||||
const char* const target_name = get_target ();
|
||||
|
||||
assert (0 != target_name);
|
||||
assert (0 != subdir);
|
||||
assert (0 != mode);
|
||||
|
||||
root_len = data_dir ? strlen (data_dir) : 0;
|
||||
cmp_len = strlen (target_name) - exe_suffix_len;
|
||||
dir_len = strlen (subdir);
|
||||
mode_len = strlen (mode);
|
||||
net_len = root_len + cmp_len + dir_len + mode_len * 2 + 5;
|
||||
/* 5 comes from 3 path seperator characters, the suffix seperator
|
||||
character, and the trailing null */
|
||||
tail = ref_name = (char*)RW_MALLOC (net_len);
|
||||
|
||||
memcpy (tail, data_dir, root_len);
|
||||
tail += root_len;
|
||||
*tail++ = default_path_sep;
|
||||
memcpy (tail , subdir, dir_len);
|
||||
tail += dir_len;
|
||||
*tail++ = default_path_sep;
|
||||
memcpy (tail , mode, mode_len);
|
||||
tail += mode_len;
|
||||
*tail++ = default_path_sep;
|
||||
memcpy (tail , target_name, cmp_len);
|
||||
tail += cmp_len;
|
||||
*tail++ = suffix_sep;
|
||||
memcpy (tail , mode, mode_len);
|
||||
tail += mode_len;
|
||||
*tail = '\0';
|
||||
|
||||
return ref_name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Composes the name of an input file, based on target
|
||||
|
||||
Takes a data directory and an executable name, and tries to open an input
|
||||
file based on these variables. If a file is found in neither of two
|
||||
locattions derived from these variables, this method tries to fall back on
|
||||
/dev/null.
|
||||
|
||||
Source file locations:
|
||||
- [data_dir]/manual/in/[target].in
|
||||
- [data_dir]/tutorial/in/[target].in
|
||||
- /dev/null
|
||||
|
||||
@param data_dir the path of the reference data directory
|
||||
@param target the name of executable being run
|
||||
@returns the name of the file
|
||||
*/
|
||||
char*
|
||||
input_name (const char* data_dir, const char* target)
|
||||
{
|
||||
char* fname = 0;
|
||||
int stat_result = 0;
|
||||
struct stat sb;
|
||||
|
||||
assert (0 != target);
|
||||
|
||||
if (data_dir && *data_dir) {
|
||||
|
||||
/* Try data_dir/manual/in/target.in */
|
||||
fname = reference_name (data_dir, "manual", "in");
|
||||
stat_result = stat (fname, &sb);
|
||||
|
||||
if (0 == stat_result)
|
||||
return fname;
|
||||
|
||||
free (fname);
|
||||
|
||||
/* Try data_dir/tutorial/in/target.in */
|
||||
fname = reference_name (data_dir, "tutorial", "in");
|
||||
stat_result = stat (fname, &sb);
|
||||
|
||||
if (0 == stat_result)
|
||||
return fname;
|
||||
|
||||
free (fname);
|
||||
}
|
||||
|
||||
/* If we didn't find a source file, use /dev/null */
|
||||
fname = (char*)RW_MALLOC (sizeof DEV_NULL);
|
||||
strcpy (fname, DEV_NULL);
|
||||
return fname;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
output_name (const char* target)
|
||||
{
|
||||
const char* suffix = "out";
|
||||
const size_t sfx_len = strlen (suffix);
|
||||
const size_t exe_len = strlen (target) - exe_suffix_len;
|
||||
char* const tmp_name = (char*)RW_MALLOC (exe_len + sfx_len + 2);
|
||||
|
||||
memcpy (tmp_name, target, exe_len);
|
||||
*(tmp_name + exe_len) = suffix_sep;
|
||||
memcpy (tmp_name + exe_len + 1, suffix, sfx_len + 1);
|
||||
return tmp_name;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
void
|
||||
rw_sleep (int seconds)
|
||||
{
|
||||
sleep (seconds);
|
||||
}
|
||||
|
||||
|
||||
# ifndef _RWSTD_EDG_ECCP
|
||||
|
||||
# ifdef __cplusplus
|
||||
|
||||
extern "C" {
|
||||
|
||||
# endif /* __cplusplus */
|
||||
|
||||
int
|
||||
rw_signal (int signo, void (*func)(int))
|
||||
{
|
||||
struct sigaction act;
|
||||
memset (&act, 0, sizeof act);
|
||||
|
||||
/* avoid extern "C"/"C++" mismatch due to an HP aCC 6 bug
|
||||
(see STDCXX-291) */
|
||||
if (func)
|
||||
memcpy (&act.sa_handler, &func, sizeof func);
|
||||
else
|
||||
act.sa_handler = 0;
|
||||
|
||||
return 0 > sigaction (signo, &act, 0);
|
||||
}
|
||||
|
||||
# ifdef __cplusplus
|
||||
|
||||
} /* extern "C" */
|
||||
|
||||
# endif /* __cplusplus */
|
||||
|
||||
# else /* if defined (_RWSTD_EDG_ECCP) */
|
||||
|
||||
# ifdef __cplusplus
|
||||
|
||||
extern "C" {
|
||||
|
||||
# endif /* __cplusplus */
|
||||
|
||||
int
|
||||
rw_signal (int signo, void (*func)(int))
|
||||
{
|
||||
return SIG_ERR == signal (signo, func);
|
||||
}
|
||||
|
||||
# ifdef __cplusplus
|
||||
|
||||
} /* extern "C" */
|
||||
|
||||
# endif /* __cplusplus */
|
||||
# endif /* _RWSTD_EDG_ECCP */
|
||||
#else /* if defined (_WIN32) || defined (_WIN64) */
|
||||
|
||||
void
|
||||
rw_sleep (int seconds)
|
||||
{
|
||||
Sleep (seconds * 1000);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rw_signal (int signo, void (*func)(int))
|
||||
{
|
||||
return SIG_ERR == signal (signo, func);
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
148
extern/stdcxx/4.2.1/util/util.h
vendored
Normal file
148
extern/stdcxx/4.2.1/util/util.h
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
/************************************************************************
|
||||
*
|
||||
* util.h - Utility macros / prototypes for the runall utility
|
||||
*
|
||||
* $Id: util.h 588734 2007-10-26 18:17:55Z sebor $
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef RW_UTIL_H
|
||||
#define RW_UTIL_H
|
||||
|
||||
/**
|
||||
Generates a non-terminal error message on stderr.
|
||||
|
||||
@param format printf () format string to display on stderr
|
||||
*/
|
||||
void warn (const char* const format, ...);
|
||||
|
||||
/**
|
||||
Wrapper for exit (), providing a terminal error message on stderr.
|
||||
|
||||
@param state non-zero status code to exit () with
|
||||
@param format printf () format string to display on stderr
|
||||
*/
|
||||
void terminate (const int state, const char* const format, ...);
|
||||
|
||||
/* Note: RW_MALLOC should be used rather than malloc within the runall
|
||||
utility. This macro calls the guarded_malloc function which performs
|
||||
validation on inputs and outputs. guarded_malloc shouldn't be called
|
||||
directly, as it needs file and line information, provided by RW_MALLOC.
|
||||
*/
|
||||
|
||||
#define RW_MALLOC(size) \
|
||||
guarded_malloc(size, __FILE__, __LINE__)
|
||||
/**
|
||||
Wrapper for malloc (), providing return value checking.
|
||||
|
||||
@param size number of bytes of memory to allocate
|
||||
@param file name of file calling method
|
||||
@param line line number in file method was called from
|
||||
@return (non-null) pointer to allocated bock of memory
|
||||
*/
|
||||
void* guarded_malloc (const size_t size, const char* const file,
|
||||
const unsigned line);
|
||||
|
||||
#define RW_REALLOC(source, size) \
|
||||
guarded_realloc(source, size, __FILE__, __LINE__)
|
||||
/**
|
||||
Wrapper for realloc(), providing return value checking.
|
||||
|
||||
@param source pointer to memory block to reallocate
|
||||
@param size number of bytes of memory to allocate
|
||||
@param file name of file calling method
|
||||
@param line line number in file method was called from
|
||||
@return (non-null) pointer to allocated bock of memory
|
||||
*/
|
||||
void* guarded_realloc (void* source, const size_t size,
|
||||
const char* const file, const unsigned line);
|
||||
|
||||
/**
|
||||
Generates the name of a reference (input/output) file.
|
||||
|
||||
This function allocates memory which is to be freed by the caller.
|
||||
|
||||
@param data_dir location of example data directory
|
||||
@param subdir example subdirectory to reference
|
||||
@param mode type of file to generate name for (should be 'in' or 'out')
|
||||
@return translation of 'data_dir/subdir/mode/target_name.mode'
|
||||
*/
|
||||
char* reference_name (const char* data_dir, const char* subdir,
|
||||
const char* mode);
|
||||
|
||||
/**
|
||||
Composes the name of an input file, based on exec_name
|
||||
|
||||
Takes a data directory and an executable name, and tries to open an input
|
||||
file based on these variables. If a file is found in neither of two
|
||||
locattions derived from these variables, this method tries to fall back on
|
||||
/dev/null.
|
||||
|
||||
Source file locations:
|
||||
- [data_dir]/manual/in/[exec_name].in
|
||||
- [data_dir]/tutorial/in/[exec_name].in
|
||||
- /dev/null
|
||||
|
||||
@param data_dir the path of the reference data directory
|
||||
@param exec_name the name of executable being run
|
||||
@returns the name of the file
|
||||
*/
|
||||
char* input_name (const char* data_dir, const char* target);
|
||||
|
||||
|
||||
/**
|
||||
Generates the name of the output file for the executable target.
|
||||
|
||||
This function allocates memory which is to be freed by the caller.
|
||||
|
||||
@param path of target to generate output name for
|
||||
@return translation of 'target.out'
|
||||
*/
|
||||
char* output_name (const char* target);
|
||||
|
||||
|
||||
/**
|
||||
Portability interface to sleep.
|
||||
|
||||
@param seconds the number of seconds to sleep
|
||||
*/
|
||||
void rw_sleep (int seconds);
|
||||
|
||||
|
||||
/**
|
||||
Portability interface to signal or sigaction.
|
||||
|
||||
@param signo signal number
|
||||
@param func signal handler
|
||||
@return 0 on success, -1 otherwise
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int rw_signal (int signo, void (*func)(int));
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* RW_UTIL_H */
|
||||
Reference in New Issue
Block a user