• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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