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