first commit

This commit is contained in:
Jose Caban
2025-06-07 11:34:38 -04:00
commit 0eb2d7c07d
4708 changed files with 1500614 additions and 0 deletions

676
extern/stdcxx/4.2.1/util/aliases.cpp vendored Normal file
View 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
View 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

File diff suppressed because it is too large Load Diff

264
extern/stdcxx/4.2.1/util/charmap.h vendored Normal file
View 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
View 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
View 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
View 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);
}
}

View 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

File diff suppressed because it is too large Load Diff

914
extern/stdcxx/4.2.1/util/ctype.cpp vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

84
extern/stdcxx/4.2.1/util/exec.h vendored Normal file
View 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
View 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
View 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
View 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}

View 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

File diff suppressed because it is too large Load Diff

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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 */