| #include "res_check.h" |
| #include "localize.h" |
| #include "file_utils.h" |
| #include "ValuesFile.h" |
| |
| #include <stdio.h> |
| |
| static int check_file(const ValuesFile* file); |
| static int check_value(const SourcePos& pos, const XMLNode* value); |
| static int scan_for_unguarded_format(const SourcePos& pos, const XMLNode* value, int depth = 0); |
| |
| int |
| do_rescheck(const vector<string>& files) |
| { |
| int err; |
| |
| Configuration english; |
| english.locale = "en_US"; |
| |
| for (size_t i=0; i<files.size(); i++) { |
| const string filename = files[i]; |
| ValuesFile* valuesFile = get_local_values_file(filename, english, CURRENT_VERSION, |
| "0", true); |
| if (valuesFile != NULL) { |
| err |= check_file(valuesFile); |
| delete valuesFile; |
| } else { |
| err |= 1; |
| } |
| } |
| |
| return err; |
| } |
| |
| static int |
| check_file(const ValuesFile* file) |
| { |
| int err = 0; |
| set<StringResource> strings = file->GetStrings(); |
| for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) { |
| XMLNode* value = it->value; |
| if (value != NULL) { |
| err |= check_value(it->pos, value); |
| } |
| } |
| return err; |
| } |
| |
| static bool |
| contains_percent(const string& str) |
| { |
| const size_t len = str.length(); |
| for (size_t i=0; i<len; i++) { |
| char c = str[i]; |
| if (c == '%') { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| static int |
| check_value(const SourcePos& pos, const XMLNode* value) |
| { |
| int err = 0; |
| err |= scan_for_unguarded_format(pos, value); |
| return err; |
| } |
| |
| static bool |
| is_xliff_block(const string& ns, const string& name) |
| { |
| if (ns == XLIFF_XMLNS) { |
| return name == "g"; |
| } else { |
| return false; |
| } |
| } |
| |
| static int |
| scan_for_unguarded_format(const SourcePos& pos, const string& string) |
| { |
| bool containsPercent = contains_percent(string); |
| if (containsPercent) { |
| pos.Error("unguarded percent: '%s'\n", string.c_str()); |
| } |
| return 0; |
| } |
| |
| static int |
| scan_for_unguarded_format(const SourcePos& pos, const XMLNode* value, int depth) |
| { |
| if (value->Type() == XMLNode::ELEMENT) { |
| int err = 0; |
| if (depth == 0 || !is_xliff_block(value->Namespace(), value->Name())) { |
| const vector<XMLNode*>& children = value->Children(); |
| for (size_t i=0; i<children.size(); i++) { |
| err |= scan_for_unguarded_format(pos, children[i], depth+1); |
| } |
| } |
| return err; |
| } else { |
| return scan_for_unguarded_format(pos, value->Text()); |
| } |
| } |
| |