Home | History | Annotate | Download | only in localize
      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