summaryrefslogtreecommitdiffstats
path: root/tools/localize/res_check.cpp
blob: 0fab98a1fc87409ec140c1b64a035c9f43340ce8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "res_check.h"
#include "localize.h"
#include "file_utils.h"
#include "ValuesFile.h"

#include <stdio.h>

static int check_file(const ValuesFile* file);
static int check_value(const SourcePos& pos, const XMLNode* value);
static int scan_for_unguarded_format(const SourcePos& pos, const XMLNode* value, int depth = 0);

int
do_rescheck(const vector<string>& files)
{
    int err;

    Configuration english;
        english.locale = "en_US";

    for (size_t i=0; i<files.size(); i++) {
        const string filename = files[i];
        ValuesFile* valuesFile = get_local_values_file(filename, english, CURRENT_VERSION,
                "0", true);
        if (valuesFile != NULL) {
            err |= check_file(valuesFile);
            delete valuesFile;
        } else {
            err |= 1;
        }
    }

    return err;
}

static int
check_file(const ValuesFile* file)
{
    int err = 0;
    set<StringResource> strings = file->GetStrings();
    for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) {
        XMLNode* value = it->value;
        if (value != NULL) {
            err |= check_value(it->pos, value);
        }
    }
    return err;
}

static bool
contains_percent(const string& str)
{
    const size_t len = str.length();
    for (size_t i=0; i<len; i++) {
        char c = str[i];
        if (c == '%') {
            return true;
        }
    }
    return false;
}

static int
check_value(const SourcePos& pos, const XMLNode* value)
{
    int err = 0;
    err |= scan_for_unguarded_format(pos, value);
    return err;
}

static bool
is_xliff_block(const string& ns, const string& name)
{
    if (ns == XLIFF_XMLNS) {
        return name == "g";
    } else {
        return false;
    }
}

static int
scan_for_unguarded_format(const SourcePos& pos, const string& string)
{
    bool containsPercent = contains_percent(string);
    if (containsPercent) {
        pos.Error("unguarded percent: '%s'\n", string.c_str());
    }
    return 0;
}

static int
scan_for_unguarded_format(const SourcePos& pos, const XMLNode* value, int depth)
{
    if (value->Type() == XMLNode::ELEMENT) {
        int err = 0;
        if (depth == 0 || !is_xliff_block(value->Namespace(), value->Name())) {
            const vector<XMLNode*>& children = value->Children();
            for (size_t i=0; i<children.size(); i++) {
                err |= scan_for_unguarded_format(pos, children[i], depth+1);
            }
        }
        return err;
    } else {
        return scan_for_unguarded_format(pos, value->Text());
    }
}