diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 54b6cfa9a9e5b861a9930af873580d6dc20f773c (patch) | |
tree | 35051494d2af230dce54d6b31c6af8fc24091316 /tools/localize/xmb.cpp | |
download | frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.zip frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.gz frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.bz2 |
Initial Contribution
Diffstat (limited to 'tools/localize/xmb.cpp')
-rw-r--r-- | tools/localize/xmb.cpp | 181 |
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; +} + |