blob: 304ec44b56820b20da6ebfdbafa1860d2a57cffd [file] [log] [blame]
/***************************************************************************
*
* messages.cpp
*
* $Id$
*
***************************************************************************
*
* 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();
}