bdb087c930
Otherwise printf is undeclared. These files worked with earlier versions of gcc because either cstdio or stdio.h was being included by some other header file. But this was not guaranteed behavior, so with GCC 4.4 there are errors. The fix is backwards compatible with earlier versions of GCC. This change includes either <cstdio> or <stdio.h> whichever looks more appropriate given the other headers included by the given source file. Note, I'm using "GCC" to mean Gnu Compile Collection, as this problem is specific to C++ source files. (Presumably a C++-specific header file changed to no longer include cstdio.)
183 lines
4.7 KiB
C++
183 lines
4.7 KiB
C++
#include "xmb.h"
|
|
|
|
#include "file_utils.h"
|
|
#include "localize.h"
|
|
#include "ValuesFile.h"
|
|
#include "XMLHandler.h"
|
|
#include "XLIFFFile.h"
|
|
|
|
#include <map>
|
|
#include <cstdio>
|
|
|
|
using namespace std;
|
|
|
|
const char *const NS_MAP[] = {
|
|
"xml", XMLNS_XMLNS,
|
|
NULL, NULL
|
|
};
|
|
|
|
set<string> g_tags;
|
|
|
|
static string
|
|
strip_newlines(const string& str)
|
|
{
|
|
string res;
|
|
const size_t N = str.length();
|
|
for (size_t i=0; i<N; i++) {
|
|
char c = str[i];
|
|
if (c != '\n' && c != '\r') {
|
|
res += c;
|
|
} else {
|
|
res += ' ';
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
static int
|
|
rename_id_attribute(XMLNode* node)
|
|
{
|
|
vector<XMLAttribute>& attrs = node->EditAttributes();
|
|
const size_t I = attrs.size();
|
|
for (size_t i=0; i<I; i++) {
|
|
XMLAttribute attr = attrs[i];
|
|
if (attr.name == "id") {
|
|
attr.name = "name";
|
|
attrs.erase(attrs.begin()+i);
|
|
attrs.push_back(attr);
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
convert_xliff_to_ph(XMLNode* node, int* phID)
|
|
{
|
|
int err = 0;
|
|
if (node->Type() == XMLNode::ELEMENT) {
|
|
if (node->Namespace() == XLIFF_XMLNS) {
|
|
g_tags.insert(node->Name());
|
|
node->SetName("", "ph");
|
|
|
|
err = rename_id_attribute(node);
|
|
if (err != 0) {
|
|
char name[30];
|
|
(*phID)++;
|
|
sprintf(name, "id-%d", *phID);
|
|
node->EditAttributes().push_back(XMLAttribute("", "name", name));
|
|
err = 0;
|
|
}
|
|
}
|
|
vector<XMLNode*>& children = node->EditChildren();
|
|
const size_t I = children.size();
|
|
for (size_t i=0; i<I; i++) {
|
|
err |= convert_xliff_to_ph(children[i], phID);
|
|
}
|
|
}
|
|
return err;
|
|
}
|
|
|
|
XMLNode*
|
|
resource_to_xmb_msg(const StringResource& res)
|
|
{
|
|
// the msg element
|
|
vector<XMLAttribute> attrs;
|
|
string name = res.pos.file;
|
|
name += ":";
|
|
name += res.TypedID();
|
|
attrs.push_back(XMLAttribute("", "name", name));
|
|
attrs.push_back(XMLAttribute("", "desc", strip_newlines(res.comment)));
|
|
attrs.push_back(XMLAttribute(XMLNS_XMLNS, "space", "preserve"));
|
|
XMLNode* msg = XMLNode::NewElement(res.pos, "", "msg", attrs, XMLNode::EXACT);
|
|
|
|
// the contents are in xliff/html, convert it to xliff
|
|
int err = 0;
|
|
XMLNode* value = res.value;
|
|
string tag = value->Name();
|
|
int phID = 0;
|
|
for (vector<XMLNode*>::const_iterator it=value->Children().begin();
|
|
it!=value->Children().end(); it++) {
|
|
err |= convert_html_to_xliff(*it, tag, msg, &phID);
|
|
}
|
|
|
|
if (err != 0) {
|
|
return NULL;
|
|
}
|
|
|
|
// and then convert that to xmb
|
|
for (vector<XMLNode*>::iterator it=msg->EditChildren().begin();
|
|
it!=msg->EditChildren().end(); it++) {
|
|
err |= convert_xliff_to_ph(*it, &phID);
|
|
}
|
|
|
|
if (err == 0) {
|
|
return msg;
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
int
|
|
do_xlb_export(const string& outfile, const vector<string>& resFiles)
|
|
{
|
|
int err = 0;
|
|
|
|
size_t totalFileCount = resFiles.size();
|
|
|
|
Configuration english;
|
|
english.locale = "en_US";
|
|
|
|
set<StringResource> allResources;
|
|
|
|
const size_t J = resFiles.size();
|
|
for (size_t j=0; j<J; j++) {
|
|
string resFile = resFiles[j];
|
|
|
|
ValuesFile* valuesFile = get_local_values_file(resFile, english, CURRENT_VERSION, "", true);
|
|
if (valuesFile != NULL) {
|
|
set<StringResource> resources = valuesFile->GetStrings();
|
|
allResources.insert(resources.begin(), resources.end());
|
|
} else {
|
|
fprintf(stderr, "error reading file %s\n", resFile.c_str());
|
|
}
|
|
|
|
delete valuesFile;
|
|
}
|
|
|
|
// Construct the XLB xml
|
|
vector<XMLAttribute> attrs;
|
|
attrs.push_back(XMLAttribute("", "locale", "en"));
|
|
XMLNode* localizationbundle = XMLNode::NewElement(GENERATED_POS, "", "localizationbundle",
|
|
attrs, XMLNode::PRETTY);
|
|
|
|
for (set<StringResource>::iterator it=allResources.begin(); it!=allResources.end(); it++) {
|
|
XMLNode* msg = resource_to_xmb_msg(*it);
|
|
if (msg) {
|
|
localizationbundle->EditChildren().push_back(msg);
|
|
} else {
|
|
err = 1;
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
for (set<string>::iterator it=g_tags.begin(); it!=g_tags.end(); it++) {
|
|
printf("tag: %s\n", it->c_str());
|
|
}
|
|
printf("err=%d\n", err);
|
|
#endif
|
|
if (err == 0) {
|
|
FILE* f = fopen(outfile.c_str(), "wb");
|
|
if (f == NULL) {
|
|
fprintf(stderr, "can't open outputfile: %s\n", outfile.c_str());
|
|
return 1;
|
|
}
|
|
fprintf(f, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
|
fprintf(f, "%s\n", localizationbundle->ToString(NS_MAP).c_str());
|
|
fclose(f);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|