1 #!/bin/sh 2 3 # Search for a definition in the definitions file, expanding it to the recorded 4 # value, recursively expanding any definition references. 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 DEFS="$THISDIR/makesd-defs" 26 27 28 29 # Test for options. 30 31 if [ "$1" = '--original' ] ; then 32 FLAT=$1 33 shift 1 34 else 35 FLAT= 36 fi 37 38 # Obtain the requested definition name. 39 40 DEF=$1 41 42 if [ ! "$DEF" ] || [ "$DEF" = '--help' ] ; then 43 cat 1>&2 <<EOF 44 Usage: $PROGNAME <definition name> 45 46 Search for a definition of the given name in the definitions file: 47 48 $DEFS 49 50 If the definition can be found, the value of the definition is emitted and an 51 exit value of 0 returned. Otherwise, no output is produced and an exit value of 52 1 is returned. 53 EOF 54 exit 1 55 fi 56 57 58 59 # lookup <definition name> 60 # 61 # Search for a definition of the given name in the definitions file. Emit the 62 # full definition, incorporating multiple lines if continuation characters are 63 # present. 64 65 lookup() 66 { 67 local LINENUM 68 69 # Obtain the line number of the matching definition. 70 71 LINENUM=`grep -h -n "^$1\s" "$DEFS" | cut -d: -f1` 72 73 if [ "$LINENUM" ] ; then 74 75 # Read from the definition line. Line continuations are observed. 76 77 tail -n "+$LINENUM" "$DEFS" | if read LINE ; then 78 echo "$LINE" 79 break 80 fi 81 fi 82 } 83 84 # match <string> <pattern> 85 # 86 # Attempt to match pattern in string, emitting the string if successful. 87 88 match() 89 { 90 if `echo "$1" | grep -q "$2"` ; then 91 echo "$1" 92 return 0 93 else 94 return 1 95 fi 96 } 97 98 # defname <prefixed name> 99 # 100 # Return the actual definition name from the given prefixed name. 101 102 defname() 103 { 104 echo "$1" | sed 's/^\$//' 105 } 106 107 # expand <definition name> 108 # 109 # Expand the given definition name to its value, recursively expanding any 110 # definition names found in the value text. 111 112 expand() 113 { 114 local FOUND VALUE 115 116 FOUND= 117 VALUE= 118 119 for WORD in `lookup "$1"`; do 120 if [ ! "$FOUND" ] ; then 121 FOUND=$WORD 122 continue 123 fi 124 125 # Prevent recursive expansion if flat mode is selected. 126 127 if [ ! "$FLAT" ] ; then 128 129 # Identify definition names by looking for a $ prefix. 130 131 DEFNAME=`match "$WORD" '^\\$'` 132 133 # Attempt to expand definition names. 134 135 if [ "$DEFNAME" ] ; then 136 DEFNAME=`defname "$DEFNAME"` 137 EXPANDED=`expand "$DEFNAME"` 138 139 if [ "$EXPANDED" ] ; then 140 WORD=$EXPANDED 141 fi 142 fi 143 fi 144 145 # Incorporate expansions into the final value. 146 147 if [ ! "$VALUE" ] ; then 148 VALUE=$WORD 149 else 150 VALUE="$VALUE $WORD" 151 fi 152 done 153 154 # Show the expanded definition value. 155 156 echo "$VALUE" 157 158 # Return a result value of 0 if successful, 1 otherwise. 159 160 if [ "$VALUE" ] ; then 161 return 0 162 else 163 return 1 164 fi 165 } 166 167 168 169 # Expand the definition and return the result code. 170 171 expand "$DEF" 172 exit $?