예제 #1
0
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] = unsigned (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] = unsigned (messages_out_.noexpr_off[1] 
        + (messages_st_.wnoexpr.size() + 1) * sizeof (wchar_t));
    messages_out_.noexpr_off[0] = unsigned (messages_out_.yesexpr_off[0] 
        + (messages_st_.yesexpr.size() + 1) * sizeof (char));

    messages_out_.codeset_off = unsigned (messages_out_.noexpr_off[0] 
        + (messages_st_.noexpr.size() + 1) * sizeof (char));
    messages_out_.charmap_off = unsigned (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();
}
예제 #2
0
파일: time.cpp 프로젝트: Quna/mspdev
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;
}
예제 #3
0
파일: localedef.cpp 프로젝트: Quna/mspdev
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';
            }
        }
    } 
}
예제 #4
0
파일: ctype.cpp 프로젝트: Flameeyes/stdcxx
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);
}
예제 #5
0
파일: ctype.cpp 프로젝트: Flameeyes/stdcxx
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"); 
#if !defined (_WIN32) && !defined (__CYGWIN__)

            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  // !_WIN32 && !__CYGWIN__

            // 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;

        }
    }
}
예제 #6
0
파일: ctype.cpp 프로젝트: Flameeyes/stdcxx
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)");
}
예제 #7
0
파일: ctype.cpp 프로젝트: Flameeyes/stdcxx
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);
}
예제 #8
0
파일: ctype.cpp 프로젝트: Flameeyes/stdcxx
// 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);
}
예제 #9
0
파일: ctype.cpp 프로젝트: Flameeyes/stdcxx
// 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);
}
예제 #10
0
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;
        }
    }
}
예제 #11
0
파일: time.cpp 프로젝트: Quna/mspdev
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++;
}
예제 #12
0
파일: time.cpp 프로젝트: Quna/mspdev
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;
}
예제 #13
0
파일: time.cpp 프로젝트: Quna/mspdev
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;
        }

    }
}
예제 #14
0
파일: localedef.cpp 프로젝트: Quna/mspdev
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;
}
예제 #15
0
파일: localedef.cpp 프로젝트: Quna/mspdev
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
}
예제 #16
0
파일: ctype.cpp 프로젝트: Flameeyes/stdcxx
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 = unsigned (ctype_out_.wtoupper_off 
            + upper_.size() * sizeof (_RW::__rw_upper_elm));
        ctype_out_.wmask_off = unsigned (ctype_out_.wtolower_off
            + lower_.size() * sizeof (_RW::__rw_lower_elm));
        ctype_out_.wmask_s = unsigned (mask_.size());

        // calculate the offsets for the codeset name string and character
        // map name string
        ctype_out_.codeset_off = unsigned (ctype_out_.wmask_off
            + mask_.size() * sizeof (_RW::__rw_mask_elm));
        ctype_out_.charmap_off = unsigned (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;
    
    }

#if !defined (_WIN32) && !defined (__CYGWIN__)
    
    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  // !_WIN32 && !__CYGWIN__

}
예제 #17
0
파일: aliases.cpp 프로젝트: Quna/mspdev
// 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;
}
예제 #18
0
파일: ctype.cpp 프로젝트: Flameeyes/stdcxx
// 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;
}