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