Home | History | Annotate | Line # | Download | only in sh
      1 #! /bin/sh
      2 #	$NetBSD: mkinit.sh,v 1.10 2018/12/05 09:20:18 kre Exp $
      3 
      4 # Copyright (c) 2003 The NetBSD Foundation, Inc.
      5 # All rights reserved.
      6 #
      7 # This code is derived from software contributed to The NetBSD Foundation
      8 # by David Laight.
      9 #
     10 # Redistribution and use in source and binary forms, with or without
     11 # modification, are permitted provided that the following conditions
     12 # are met:
     13 # 1. Redistributions of source code must retain the above copyright
     14 #    notice, this list of conditions and the following disclaimer.
     15 # 2. Redistributions in binary form must reproduce the above copyright
     16 #    notice, this list of conditions and the following disclaimer in the
     17 #    documentation and/or other materials provided with the distribution.
     18 #
     19 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22 # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29 # POSSIBILITY OF SUCH DAMAGE.
     30 
     31 srcs="$*"
     32 
     33 # use of echo in this script is broken
     34 
     35 # some echo versions will expand \n in the args, which breaks C
     36 # Note: this script is a HOST_PROG ... it must run in the
     37 # build host's environment, with its shell.
     38 
     39 # Fortunately, use of echo here is also trivially simplistic,
     40 # we can easily replace all uses with ...
     41 
     42 echo()
     43 {
     44 	printf '%s\n' "$1"
     45 }
     46 
     47 # CAUTION: for anyone modifying this script.... use printf
     48 # rather than echo to output anything at all... then
     49 # you will avoid being bitten by the simplicity of this function.
     50 # This was done this way rather than wholesale replacement
     51 # to avoid unnecessary code churn.
     52 
     53 
     54 nl='
     55 '
     56 openparen='('
     57 
     58 # shells have bugs (including older NetBSD sh) in how \ is
     59 # used in pattern matching.   So work out what the shell
     60 # running this script expects.   We could also just use a
     61 # literal \ in the pattern, which would need to be quoted
     62 # of course, but then we'd run into a whole host of potential
     63 # other shell bugs (both with the quoting in the pattern, and
     64 # with the matching that follows if that works as inended).
     65 # Far easier, and more reliable, is to just work out what works,
     66 # and then use it, which more or less mandates using a variable...
     67 backslash='\\'
     68 var='abc\'			# dummy test case.
     69 if [ "$var" = "${var%$backslash}" ]
     70 then
     71 	# buggy sh, try the broken way
     72 	backslash='\'
     73 	if [ "$var" = "${var%$backslash}" ]
     74 	then
     75 		printf >&2 "$0: %s\n" 'No pattern match with \ (broken shell)'
     76 		exit 1
     77 	fi
     78 fi
     79 # We know we can detect the presence of a trailing \, which is all we need.
     80 # Now to confirm we will not generate false matches.
     81 var='abc'
     82 if [ "$var" != "${var%$backslash}" ]
     83 then
     84 	printf >&2 "$0: %s\n" 'Bogus pattern match with \ (broken shell)'
     85 	exit 1
     86 fi
     87 unset var
     88 
     89 includes=' "shell.h" "mystring.h" "init.h" '
     90 defines=
     91 decles=
     92 event_init=
     93 event_reset=
     94 event_shellproc=
     95 
     96 for src in $srcs; do
     97 	exec <$src
     98 	decnl="$nl"
     99 	while IFS=; read -r line; do
    100 		[ "$line" = x ]
    101 		case "$line " in
    102 		INIT["{ 	"]* ) event=init;;
    103 		RESET["{ 	"]* ) event=reset;;
    104 		SHELLPROC["{ 	"]* ) event=shellproc;;
    105 		INCLUDE[\ \	]* )
    106 			IFS=' 	'
    107 			set -- $line
    108 			# ignore duplicates
    109 			[ "${includes}" != "${includes% $2 *}" ] && continue
    110 			includes="$includes$2 "
    111 			continue
    112 			;;
    113 		MKINIT\  )
    114 			# struct declaration
    115 			decles="$decles$nl"
    116 			while
    117 				read -r line
    118 				decles="${decles}${line}${nl}"
    119 				[ "$line" != "};" ]
    120 			do
    121 				:
    122 			done
    123 			decnl="$nl"
    124 			continue
    125 			;;
    126 		MKINIT["{ 	"]* )
    127 			# strip initialiser
    128 			def=${line#MKINIT}
    129 			comment="${def#*;}"
    130 			def="${def%;$comment}"
    131 			def="${def%%=*}"
    132 			def="${def% }"
    133 			decles="${decles}${decnl}extern${def};${comment}${nl}"
    134 			decnl=
    135 			continue
    136 			;;
    137 		\#define[\ \	]* )
    138 			IFS=' 	'
    139 			set -- $line
    140 			# Ignore those with arguments
    141 			[ "$2" = "${2##*$openparen}" ] || continue
    142 			# and multiline definitions
    143 			[ "$line" = "${line%$backslash}" ] || continue
    144 			defines="${defines}#undef	$2${nl}${line}${nl}"
    145 			continue
    146 			;;
    147 		* ) continue;;
    148 		esac
    149 		# code for events
    150 		ev="${nl}	/* from $src: */${nl}	{${nl}"
    151 		# Indent the text by an extra <tab>
    152 		while
    153 			read -r line
    154 			[ "$line" != "}" ]
    155 		do
    156 			case "$line" in
    157 			('')	;;
    158 			('#'*)	;;
    159 			(*)	line="	$line";;
    160 			esac
    161 			ev="${ev}${line}${nl}"
    162 		done
    163 		ev="${ev}	}${nl}"
    164 		eval event_$event=\"\$event_$event\$ev\"
    165 	done
    166 done
    167 
    168 exec >init.c.tmp
    169 
    170 echo "/*"
    171 echo " * This file was generated by the mkinit program."
    172 echo " */"
    173 echo
    174 
    175 IFS=' '
    176 for f in $includes; do
    177 	echo "#include $f"
    178 done
    179 
    180 echo
    181 echo
    182 echo
    183 echo "$defines"
    184 echo
    185 echo "$decles"
    186 echo
    187 echo
    188 echo "/*"
    189 echo " * Initialization code."
    190 echo " */"
    191 echo
    192 echo "void"
    193 echo "init(void)"
    194 echo "{"
    195 echo "${event_init}"
    196 echo "}"
    197 echo
    198 echo
    199 echo
    200 echo "/*"
    201 echo " * This routine is called when an error or an interrupt occurs in an"
    202 echo " * interactive shell and control is returned to the main command loop."
    203 echo " */"
    204 echo
    205 echo "void"
    206 echo "reset(void)"
    207 echo "{"
    208 echo "${event_reset}"
    209 echo "}"
    210 echo
    211 echo
    212 echo
    213 echo "/*"
    214 echo " * This routine is called to initialize the shell to run a shell procedure."
    215 echo " */"
    216 echo
    217 echo "void"
    218 echo "initshellproc(void)"
    219 echo "{"
    220 echo "${event_shellproc}"
    221 echo "}"
    222 
    223 exec >&-
    224 mv init.c.tmp init.c
    225