172 lines
5.8 KiB
C++
172 lines
5.8 KiB
C++
/***************************************************************************
|
|
*
|
|
* 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();
|
|
}
|