1 #include "res_check.h" 2 #include "localize.h" 3 #include "file_utils.h" 4 #include "ValuesFile.h" 5 6 #include <stdio.h> 7 8 static int check_file(const ValuesFile* file); 9 static int check_value(const SourcePos& pos, const XMLNode* value); 10 static int scan_for_unguarded_format(const SourcePos& pos, const XMLNode* value, int depth = 0); 11 12 int 13 do_rescheck(const vector<string>& files) 14 { 15 int err; 16 17 Configuration english; 18 english.locale = "en_US"; 19 20 for (size_t i=0; i<files.size(); i++) { 21 const string filename = files[i]; 22 ValuesFile* valuesFile = get_local_values_file(filename, english, CURRENT_VERSION, 23 "0", true); 24 if (valuesFile != NULL) { 25 err |= check_file(valuesFile); 26 delete valuesFile; 27 } else { 28 err |= 1; 29 } 30 } 31 32 return err; 33 } 34 35 static int 36 check_file(const ValuesFile* file) 37 { 38 int err = 0; 39 set<StringResource> strings = file->GetStrings(); 40 for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) { 41 XMLNode* value = it->value; 42 if (value != NULL) { 43 err |= check_value(it->pos, value); 44 } 45 } 46 return err; 47 } 48 49 static bool 50 contains_percent(const string& str) 51 { 52 const size_t len = str.length(); 53 for (size_t i=0; i<len; i++) { 54 char c = str[i]; 55 if (c == '%') { 56 return true; 57 } 58 } 59 return false; 60 } 61 62 static int 63 check_value(const SourcePos& pos, const XMLNode* value) 64 { 65 int err = 0; 66 err |= scan_for_unguarded_format(pos, value); 67 return err; 68 } 69 70 static bool 71 is_xliff_block(const string& ns, const string& name) 72 { 73 if (ns == XLIFF_XMLNS) { 74 return name == "g"; 75 } else { 76 return false; 77 } 78 } 79 80 static int 81 scan_for_unguarded_format(const SourcePos& pos, const string& string) 82 { 83 bool containsPercent = contains_percent(string); 84 if (containsPercent) { 85 pos.Error("unguarded percent: '%s'\n", string.c_str()); 86 } 87 return 0; 88 } 89 90 static int 91 scan_for_unguarded_format(const SourcePos& pos, const XMLNode* value, int depth) 92 { 93 if (value->Type() == XMLNode::ELEMENT) { 94 int err = 0; 95 if (depth == 0 || !is_xliff_block(value->Namespace(), value->Name())) { 96 const vector<XMLNode*>& children = value->Children(); 97 for (size_t i=0; i<children.size(); i++) { 98 err |= scan_for_unguarded_format(pos, children[i], depth+1); 99 } 100 } 101 return err; 102 } else { 103 return scan_for_unguarded_format(pos, value->Text()); 104 } 105 } 106 107