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:: 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++; }
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::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; } } }