summaryrefslogtreecommitdiff
path: root/tests/expand-test-matrix.sh
blob: 4965fa6a029705dcef311ca8cdf8068a2ef0c043 (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/bin/bash

# This script expands test-matrix expressions into indiviual featuressets
#
# The basic element is a feature, which is just a name:
#  "a" == enable feature a
#
# A featureset is a comma separated list of features:
#  "a,b,c"  == enable feature a, b and c
#
# A test-matrix is a list of featuresets to test and are specified by
# separating featuresets by '+':
#  "a,b+a,c+e" == featuresets "a,b", "a,c" and "e"
#
# At any point in the expression where a feature is expected you can
# instead specify an entire test-matrix by enclosing a sub-expression
# in brackets. The result is the combinatorial combination of the
# sub-test-matrix with the current featureset.
#
# For example:
#
#  "a,{b+c}" == "a,b+a,c"
# or:
#  "a,b,{c,d+e,f}" == "a,b,c,d+a,b,e,f"
#
# This can happen multiple times in an optionset which will fully expand all
# instances:
# "a,{b+c},{d+e}" == "a,{b+c},d+a,{b+c},e" == "a,b,d+a,c,d+a,{b+c},e" == "a,b,d+a,c,d+a,b,e+a,c,e"
#
#
# The common way to use this is to either list all the options to instance the test for each case:
#  foo+bar+gazonk
# Or to create all combination of features:
#  {foo+nofoo},{bar+nobar}

tokens=(  )
current_token=""

function next_token {
    if [ ${#tokens[@]} -eq 0 ]; then
        current_token="$"
    else
        current_token=${tokens[0]}
        tokens=("${tokens[@]:1}")
    fi
}

parse_res=""
function parse {
    local res=(  )
    local cur=(  )
    while true; do
        next_token
        local t=$current_token
        if [ $t == "}" -o $t == "$" ]; then
            break;
        elif [ $t == "{" ]; then
            parse
            local sub=$parse_res
            if [ ${#cur} -eq 0 ]; then
               cur=( ${sub[@]} )
            else
                local sub_res=( )
                for left in "${cur[@]}"; do
                    for right in $sub; do
                        sub_res+=("$left,$right")
                    done
                done
                cur=( ${sub_res[@]} )
            fi
        elif [ $t == "+" ]; then
            res+=( "${cur[@]}" )
            cur=( )
        else # ,t
            if [ ${#cur} -eq 0 ]; then
                cur=( $t )
            else
                for i in "${!cur[@]}"; do
                    cur[$i]="${cur[$i]:+${cur[$i]},}$t"
                done
            fi
        fi
    done
    if [ ${#cur} -ne 0 ]; then
        res+=( "${cur[@]}" )
    fi

    parse_res="${res[@]}"
}

tests=""
dist_tests=""
extra_dist_tests=""
function parse_test {
    if [[ $1 =~ ^(.*).sh\{(.*)\}$ ]]; then
        tokens=( $(awk -v RS='[{}+,]' '{if ($0 != "" && $0 != "\n") print $0; if (RT != "" && RT != ",") print RT}' <<< "${BASH_REMATCH[2]}") )
        parse
        for r in $parse_res; do
            tests="$tests ${BASH_REMATCH[1]}@$r.wrap"
        done
        extra_dist_tests="$extra_dist_tests ${BASH_REMATCH[1]}.sh"
    else
        dist_tests="$dist_tests $1"
    fi
}

for test in $2; do
    parse_test $test
done

if [ "$1" = "--automake" ]; then
    echo "# This file is autogenerated by ./tests/update-test-matrix, don't edit"
    echo "TEST_MATRIX= \\"
    for f in $tests; do
        echo "	${f} \\"
    done
    echo "	\$(NULL)"
    echo "TEST_MATRIX_DIST= \\"
    for f in $dist_tests; do
        echo "	${f} \\"
    done
    echo "	\$(NULL)"
    echo "TEST_MATRIX_EXTRA_DIST= \\"
    for f in $extra_dist_tests; do
        echo "	${f} \\"
    done
    echo "	\$(NULL)"
elif [ "$1" = "--meson" ]; then
    echo "# This file is autogenerated by ./tests/update-test-matrix, don't edit"
    for f in $tests $dist_tests; do
        f="${f#tests/}"
        case "$f" in
            (*@*)
                s="${f%%@*}.sh"
                ;;
            (*)
                s="$f"
                ;;
        esac
        echo "wrapped_tests += {'name' : '$f', 'script' : '$s'}"
    done
fi