Home | History | Annotate | Line # | Download | only in sh
mkoptions.sh revision 1.5.14.1
      1       1.1     kre #! /bin/sh
      2       1.1     kre 
      3  1.5.14.1  martin # $NetBSD: mkoptions.sh,v 1.5.14.1 2025/10/01 15:21:11 martin 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.5.14.1  martin 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.5.14.1  martin case $- in
     22  1.5.14.1  martin *x*)
     23  1.5.14.1  martin 	E_FILE=$(${MKTEMP:-mktemp} "${TMPDIR:-/tmp}/MKO.E.$$.XXXXXX") || exit 1
     24  1.5.14.1  martin 	O_FILE=$(${MKTEMP:-mktemp} "${TMPDIR:-/tmp}/MKO.O.$$.XXXXXX") || {
     25  1.5.14.1  martin 		rm -f "${E_FILE}"
     26  1.5.14.1  martin 		exit 1
     27  1.5.14.1  martin 	}
     28  1.5.14.1  martin 	;;
     29  1.5.14.1  martin *)
     30  1.5.14.1  martin 	E_FILE=$(${MKTEMP:-mktemp}) || exit 1
     31  1.5.14.1  martin 	O_FILE=$(${MKTEMP:-mktemp}) || { rm -f "${E_FILE}"; exit 1; }
     32  1.5.14.1  martin 	trap 'rm -f "${E_FILE}" "${O_FILE}"' EXIT
     33  1.5.14.1  martin 	;;
     34  1.5.14.1  martin 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.5.14.1  martin 	-e '/^[ 	]*;/d'		|
     56  1.5.14.1  martin 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.5.14.1  martin 	+)	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