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