1#include "res_check.h" 2#include "localize.h" 3#include "file_utils.h" 4#include "ValuesFile.h" 5 6#include <stdio.h> 7 8static int check_file(const ValuesFile* file); 9static int check_value(const SourcePos& pos, const XMLNode* value); 10static int scan_for_unguarded_format(const SourcePos& pos, const XMLNode* value, int depth = 0); 11 12int 13do_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 35static int 36check_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 49static bool 50contains_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 62static int 63check_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 70static bool 71is_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 80static int 81scan_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 90static int 91scan_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