remakesd

Annotated makesd-expand-def

21:eeb7bcd53897
2019-06-10 Paul Boddie Switched to a more structured system definition format. Eliminated partition summaries since the expanded definitions together with the filtering of definitions make such summaries largely redundant.
paul@0 1
#!/bin/sh
paul@0 2
paul@21 3
# Search for a definition in the definitions file, expanding it recursively to
paul@21 4
# provide a complete description.
paul@15 5
#
paul@15 6
# Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
paul@15 7
#
paul@15 8
# This program is free software; you can redistribute it and/or modify it under
paul@15 9
# the terms of the GNU General Public License as published by the Free Software
paul@15 10
# Foundation; either version 3 of the License, or (at your option) any later
paul@15 11
# version.
paul@15 12
#
paul@15 13
# This program is distributed in the hope that it will be useful, but WITHOUT
paul@15 14
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@15 15
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@15 16
# details.
paul@15 17
#
paul@15 18
# You should have received a copy of the GNU General Public License along with
paul@15 19
# this program.  If not, see <http://www.gnu.org/licenses/>.
paul@15 20
paul@0 21
paul@0 22
PROGNAME=`basename "$0"`
paul@0 23
THISDIR=`dirname "$0"`
paul@0 24
paul@21 25
COMMON="$THISDIR/makesd-common"
paul@14 26
DEFS="$THISDIR/makesd-defs"
paul@0 27
paul@21 28
. "$COMMON"
paul@21 29
paul@0 30
paul@0 31
paul@21 32
# lookup <definition>
paul@0 33
#
paul@21 34
# Search for the given definition in the definitions file. Emit the full
paul@21 35
# definition.
paul@0 36
paul@0 37
lookup()
paul@0 38
{
paul@0 39
    local LINENUM
paul@0 40
paul@0 41
    # Obtain the line number of the matching definition.
paul@0 42
paul@21 43
    LINENUM=`search "^$1$" "$DEFS"`
paul@0 44
paul@0 45
    if [ "$LINENUM" ] ; then
paul@0 46
paul@21 47
        # Read from the definition until a blank line or the end of file is
paul@21 48
        # encountered. Line continuations are observed.
paul@21 49
paul@21 50
        tail -n "+$(($LINENUM + 1))" "$DEFS" | while read LINE ; do
paul@21 51
paul@21 52
            # Detect end of definition.
paul@0 53
paul@21 54
            if [ ! "$LINE" ] ; then
paul@21 55
                break
paul@21 56
            fi
paul@21 57
paul@21 58
            # Show definition lines.
paul@21 59
paul@0 60
            echo "$LINE"
paul@21 61
        done
paul@0 62
    fi
paul@0 63
}
paul@0 64
paul@21 65
# consolidate
paul@0 66
#
paul@21 67
# Eliminate duplicate properties, preserving only the final definition.
paul@21 68
paul@21 69
consolidate()
paul@21 70
{
paul@21 71
    sort -k1,1 -t: -s | show_last
paul@21 72
}
paul@21 73
paul@21 74
show_last()
paul@21 75
{
paul@21 76
    local FIELD LAST LASTLINE
paul@21 77
paul@21 78
    LAST=
paul@21 79
    LASTLINE=
paul@21 80
paul@21 81
    while read LINE ; do
paul@21 82
paul@21 83
        # Inspect the property details.
paul@0 84
paul@21 85
        FIELD=`get_field "$LINE"`
paul@21 86
paul@21 87
        # With a differing property from any previous one, emit the previous
paul@21 88
        # one.
paul@21 89
paul@21 90
        if [ "$LAST" ] && [ "$FIELD" != "$LAST" ] ; then
paul@21 91
            echo "$LASTLINE"
paul@21 92
        fi
paul@21 93
paul@21 94
        # Retain this property definition for possible future emission.
paul@21 95
paul@21 96
        LAST=$FIELD
paul@21 97
        LASTLINE=$LINE
paul@21 98
    done
paul@21 99
paul@21 100
    # Emit any remaining line, also indicating whether any lines were processed.
paul@21 101
paul@21 102
    if [ "$LASTLINE" ] ; then
paul@21 103
        echo "$LASTLINE"
paul@0 104
        return 0
paul@0 105
    else
paul@0 106
        return 1
paul@0 107
    fi
paul@0 108
}
paul@0 109
paul@21 110
# expand <definition>
paul@0 111
#
paul@0 112
# Expand the given definition name to its value, recursively expanding any
paul@0 113
# definition names found in the value text.
paul@0 114
paul@0 115
expand()
paul@0 116
{
paul@21 117
    local TYPE
paul@21 118
paul@21 119
    TYPE=`echo "$1" | cut -d' ' -f1`
paul@0 120
paul@21 121
    # Look up the definition and read each line.
paul@21 122
paul@21 123
    lookup "$1" | expand_def "$TYPE"
paul@21 124
}
paul@0 125
paul@21 126
expand_def()
paul@21 127
{
paul@21 128
    local FIELD LINE RESULT TYPE VALUE
paul@0 129
paul@21 130
    RESULT=1
paul@0 131
paul@21 132
    while read LINE ; do
paul@21 133
        RESULT=0
paul@0 134
paul@21 135
        # Inspect the line and find any references to other definitions.
paul@0 136
paul@21 137
        FIELD=`get_field "$LINE"`
paul@21 138
        VALUE=`get_value "$LINE"`
paul@21 139
paul@21 140
        # Merge definitions that are adapted.
paul@0 141
paul@21 142
        if [ "$FIELD" = 'adapts' ] ; then
paul@21 143
            expand "$TYPE $VALUE"
paul@21 144
paul@21 145
        # Aggregate system components such as partitions and regions.
paul@0 146
paul@21 147
        elif [ "$TYPE" = 'system' ] && (
paul@21 148
           [ "$FIELD" = 'partition' ] || [ "$FIELD" = 'region' ] ) ; then
paul@21 149
paul@21 150
            # Declare regions and partitions in the output.
paul@0 151
paul@21 152
            echo "$FIELD"
paul@21 153
            expand "$FIELD $VALUE" | consolidate
paul@21 154
            echo
paul@0 155
paul@21 156
        # Otherwise, emit properties of the definition.
paul@21 157
paul@0 158
        else
paul@21 159
            echo "$LINE"
paul@0 160
        fi
paul@0 161
    done
paul@0 162
paul@21 163
    return $RESULT
paul@0 164
}
paul@0 165
paul@0 166
paul@0 167
paul@21 168
# Obtain the requested system name.
paul@21 169
paul@21 170
if [ ! "$1" ] || [ "$1" = '--help' ] ; then
paul@21 171
    cat 1>&2 <<EOF
paul@21 172
Usage: $PROGNAME <system>
paul@21 173
       $PROGNAME -a | --all | --defs
paul@21 174
paul@21 175
Search for a definition of the given system in the definitions file:
paul@21 176
paul@21 177
$DEFS
paul@21 178
paul@21 179
If the definition can be found, the value of the definition is emitted and an
paul@21 180
exit value of 0 returned. Otherwise, no output is produced and an exit value of
paul@21 181
1 is returned.
paul@21 182
paul@21 183
$(show_definitions_description)
paul@21 184
EOF
paul@21 185
    exit 1
paul@21 186
fi
paul@21 187
paul@21 188
# Show definitions if requested.
paul@21 189
paul@21 190
if [ "$1" = '-a' ] || [ "$1" = '--all' ] || [ "$1" = '--defs' ] ; then
paul@21 191
    grep '^system' "$DEFS" | sed 's/^system //' | sort
paul@21 192
    exit 0
paul@21 193
fi
paul@21 194
paul@0 195
# Expand the definition and return the result code.
paul@0 196
paul@21 197
DEF=$1
paul@21 198
paul@21 199
expand "system $DEF"
paul@0 200
exit $?