Home | History | Annotate | Line # | Download | only in sh
mkoptions.sh revision 1.2
      1 #! /bin/sh
      2 
      3 # $NetBSD: mkoptions.sh,v 1.2 2017/05/28 14:14:22 kre Exp $
      4 
      5 #
      6 # It would be more sensible to generate 2 .h files, one which
      7 # is for everyone to use, defines the "variables" and (perhaps) generates
      8 # the externs (though they could just be explicit in options.h)
      9 # and one just for options.c which generates the initialisation.
     10 #
     11 # But then I'd have to deal with making the Makefile handle that properly...
     12 # (this is simpler there, and it just means a bit more sh compile time.)
     13 
     14 set -f
     15 IFS=' 	'	# blank, tab (no newline)
     16 
     17 IF="$1"
     18 OF="${3+$3/}$2"
     19 
     20 E_FILE=$(${MKTEMP:-mktemp} -t MKO.E.$$)
     21 O_FILE=$(${MKTEMP:-mktemp} -t MKO.O.$$)
     22 trap 'rm -f "${E_FILE}" "${O_FILE}"' EXIT
     23 
     24 exec 5> "${E_FILE}"
     25 exec 6> "${O_FILE}"
     26 
     27 {
     28 	printf '/*\n * File automatically generated by %s.\n' "$0"
     29 	printf ' * Do not edit, do not add to cvs.\n'
     30 	printf ' */\n\n'
     31 
     32 	printf '#ifdef DEFINE_OPTIONS\n'
     33 	printf 'struct optent optlist[] = {\n'
     34 } >"${OF}"
     35 
     36 FIRST=true
     37 
     38 ${SED:-sed} <"${IF}"			\
     39 	-e '/^$/d'			\
     40 	-e '/^#/d'			\
     41 	-e '/^[ 	]*\//d'		\
     42 	-e '/^[ 	]*\*/d'		\
     43 	-e '/^[ 	]*;/d'			|
     44 sort -k2,2f -k2,2r < "${IF}"			|
     45 while read line
     46 do
     47 	# Look for comments in various styles, and ignore them
     48 	# (these should generally be already removed by sed above)
     49 
     50 	case "${line}" in
     51 	'')	continue;;
     52 	/*)	continue;;
     53 	\**)	continue;;
     54 	\;*)	continue;;
     55 	\#*)	continue;;
     56 	esac
     57 
     58 	case "${line}" in
     59 	*'#if'*)
     60 		COND="${line#*#}"
     61 		COND="#${COND%%#*}"
     62 		;;
     63 	*)
     64 		COND=
     65 		;;
     66 	esac
     67 	set -- ${line%%[ 	]#*}
     68 
     69 	var="$1" name="$2"
     70 
     71 	case "${var}" in
     72 	('' | [!A-Za-z_]* | *[!A-Za-z0-9_]*)
     73 		printf >&2 "Bad var name: '%s'\\n" "${var}"
     74 		# exit 1
     75 		continue	# just ignore it for now
     76 	esac
     77 
     78 	case "${name}" in
     79 	?) 	set -- ${var} '' $name $3 $4; name= ;;
     80 	esac
     81 
     82 	chr="$3" set="$4" dflt="$5"
     83 
     84 	case "${chr}" in
     85 	-)	chr= set= dflt="$4";;
     86 	''|?)	;;
     87 	*)	printf >&2 'flag "%s": Not a character\n' "${chr}"; continue;;
     88 	esac
     89 
     90 	# options must have some kind of name, or they are useless...
     91 	test -z "${name}${chr}" && continue
     92 
     93 	case "${set}" in
     94 	-)	set= ;;
     95 	[01] | [Oo][Nn] | [Oo][Ff][Ff])	dflt="${set}"; set= ;;
     96 	''|?)	;;
     97 	*)	printf >&2 'set "%s": Not a character\n' "${set}"; continue;;
     98 	esac
     99 
    100 	case "${dflt}" in
    101 	'')		;;
    102 	[Oo][Nn])	dflt=1;;
    103 	[Oo][Ff][Ff])	dflt=0;;
    104 	[01])		;;
    105 	*)	printf >&2 'default "%s" invalid, use 0 off 1 on\n'; continue;;
    106 	esac
    107 
    108 	# validation complete, now to generate output
    109 
    110 	if [ -n "${COND}" ]
    111 	then
    112 		printf '%s\n' "${COND}" >&4
    113 		printf '%s\n' "${COND}" >&5
    114 		printf '%s\n' "${COND}" >&6
    115 	fi
    116 
    117 	printf '\t_SH_OPT_%s,\n' "${var}" >&5
    118 
    119 	if [ -n "${name}" ]
    120 	then
    121 		printf '    { "%s", ' "${name}"	>&4
    122 	else
    123 		printf '    { 0, '		>&4
    124 	fi
    125 
    126 	if [ -n "${chr}" ]
    127 	then
    128 		printf "'%s', " "${chr}"	>&4
    129 	else
    130 		chr=
    131 		printf '0, '			>&4
    132 	fi
    133 
    134 	if [ -n "${set}" ]
    135 	then
    136 		printf "'%s', 0, " "${set}"	>&4
    137 	else
    138 		printf '0, 0, '			>&4
    139 	fi
    140 
    141 	if [ -n "${dflt}" ]
    142 	then
    143 		printf '%s },\n' "${dflt}"	>&4
    144 	else
    145 		printf '0 },\n'			>&4
    146 	fi
    147 
    148 	printf '#define %s\toptlist[_SH_OPT_%s].val\n' "${var}" "${var}" >&6
    149 
    150 	if [ -n "${COND}" ]
    151 	then
    152 		printf '#endif\n' >&4
    153 		printf '#endif\n' >&5
    154 		printf '#endif\n' >&6
    155 	fi
    156 
    157 	test -z "${chr}" && continue
    158 
    159 	printf '%s _SH_OPT_%s %s\n' "${chr}" "${var}" "${COND}"
    160 
    161 done 4>>"${OF}" | sort -t' ' -k1,1f -k1,1r | while read chr index COND
    162 do
    163 	if $FIRST
    164 	then
    165 		printf '    { 0, 0, 0, 0, 0 }\n};\n'
    166 		printf '#endif\n\n'
    167 
    168 		printf 'enum shell_opt_names {\n'
    169 		cat "${E_FILE}"
    170 		printf '};\n\n'
    171 
    172 		printf '#ifdef DEFINE_OPTIONS\n'
    173 		printf 'const unsigned char optorder[] = {\n'
    174 		FIRST=false
    175 	fi
    176 	[ -n "${COND}" ] && printf '%s\n' "${COND}"
    177 	printf '\t%s,\n' "${index}"
    178 	[ -n "${COND}" ] && printf '#endif\n'
    179 
    180 done >>"${OF}"
    181 
    182 {
    183 	printf '};\n\n'
    184 	printf '#define NOPTS (sizeof optlist / sizeof optlist[0] - 1)\n'
    185 	printf 'int sizeof_optlist = sizeof optlist;\n\n'
    186 	printf	\
    187 	   'const int option_flags = (sizeof optorder / sizeof optorder[0]);\n'
    188 	printf '\n#else\n\n'
    189 	printf 'extern struct optent optlist[];\n'
    190 	printf 'extern int sizeof_optlist;\n'
    191 	printf 'extern const unsigned char optorder[];\n'
    192 	printf 'extern const int option_flags;\n'
    193 	printf '\n#endif\n\n'
    194 
    195 	cat "${O_FILE}"
    196 } >> "${OF}"
    197 
    198 exit 0
    199