summaryrefslogtreecommitdiff
path: root/tests/expand-test-matrix.sh
blob: 333f403b16bbf04a635b18ffae75e4d51a0031f6 (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
#!/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 $1; do
    parse_test $test
done

echo "# This file is autogenerated by make 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)"