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