summaryrefslogtreecommitdiffstats
path: root/tools/localize/xmb.cpp
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:31:44 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:31:44 -0800
commit9066cfe9886ac131c34d59ed0e2d287b0e3c0087 (patch)
treed88beb88001f2482911e3d28e43833b50e4b4e97 /tools/localize/xmb.cpp
parentd83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (diff)
downloadframeworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.zip
frameworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.tar.gz
frameworks_base-9066cfe9886ac131c34d59ed0e2d287b0e3c0087.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'tools/localize/xmb.cpp')
-rw-r--r--tools/localize/xmb.cpp181
1 files changed, 181 insertions, 0 deletions
diff --git a/tools/localize/xmb.cpp b/tools/localize/xmb.cpp
new file mode 100644
index 0000000..236705f
--- /dev/null
+++ b/tools/localize/xmb.cpp
@@ -0,0 +1,181 @@
+#include "xmb.h"
+
+#include "file_utils.h"
+#include "localize.h"
+#include "ValuesFile.h"
+#include "XMLHandler.h"
+#include "XLIFFFile.h"
+
+#include <map>
+
+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;
+}
+