summaryrefslogtreecommitdiff
path: root/BUILD/capture_warnings.sh
blob: 3413c4226ee0f3dddc75805fbd3ef0b54178cf17 (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
#!/bin/bash
warn_path=$1
warn_mode=$2 # 'late', 'early' or 'both'
shift 2

warn_file="$warn_path/compile.warnings"
suppress_file="$warn_path/suppress.warnings"

# suppress_warnings:
#
# 1. treat STDIN as sequence of warnings (w) delimited by ^~~~... lines
#
# 2. sanitize each w to matchable m:
#    a. ignore 'In file included from' lines;
#    b. protect BRE chars;
#    c. ignore text coords (NNN:NNN);
#    d. convert multiline to X-delimited single line.
#
# 3. match sanitized m against X-delimited suppress.warnings:
#    if match not found print w to STDOUT.

suppress_warnings()
{
    [ -f "$suppress_file" ] || {
        cat
        return
    }
    [ -z "$suppress_file" ] && {
        cat > /dev/null
        return
    }
    local m w from
    IFS=""
    while read -r l
    do
        w="$w$l"$'\n'

        [[ $l =~ ^"In file included from " ]] && {
            from=1
            continue
        }

        [[ $from && $l =~ ^[[:space:]]+"from " ]] &&
            continue

        unset from

        if [[ $l =~ ^[[:space:]]*~*\^~*$ ]]
        then
            cat "$suppress_file" | tr '\n' 'X' | /bin/grep -Gq "$m" ||
                echo "$w"
            unset m w
        else
            # Protect BRE metacharacters \.[*^$
            l=${l//\\/\\\\}
            l=${l//./\\.}
            l=${l//[/\\[}
            l=${l//-/\\-}
            l=${l//\*/\\*}
            l=${l//^/\\^}
            l=${l//\$/\\\$}
            # replace text coords line:char with BRE wildcard
            [[ $l =~ ^(.*:)[[:digit:]]+:[[:digit:]]+(.*)$ ]] &&
                l=${BASH_REMATCH[1]}[[:digit:]]\\+:[[:digit:]]\\+${BASH_REMATCH[2]}
            m="$m$l"$'X'
        fi
    done
}

exec 3>&1
"$@" 2>&1 1>&3 | suppress_warnings | (
    cmderr=`cat`

    if [[ -n "$cmderr" ]]; then
        if [[ "$cmderr" =~ error: ]]; then
            echo "$cmderr" >&2
            exit
        fi
        [[ "$warn_mode" != "late" ]] &&
            echo "$cmderr" >&2
        [[ "$warn_mode" != "early" && "$cmderr" =~ (warning|note): ]] &&
            echo "$cmderr" >> "$warn_file"
    fi
)

exit ${PIPESTATUS}