Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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
}