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
do_rescheck(const vector<string> & files)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
check_file(const ValuesFile * file)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
contains_percent(const string & str)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
check_value(const SourcePos & pos,const XMLNode * value)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
is_xliff_block(const string & ns,const string & name)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
scan_for_unguarded_format(const SourcePos & pos,const string & string)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
scan_for_unguarded_format(const SourcePos & pos,const XMLNode * value,int depth)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