Home | History | Annotate | Line # | Download | only in sh
mkoptions.sh revision 1.1
      1 #! /bin/sh
      2 
      3 # $NetBSD: mkoptions.sh,v 1.1 2017/05/28 00:38:01 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 {
     21 	printf '/*\n * File automatically generated by %s.\n' "$0"
     22 	printf ' * Do not edit, do not add to cvs.\n'
     23 	printf ' */\n\n'
     24 
     25 	printf '#ifdef DEFINE_OPTIONS\n'
     26 	printf '#define DEF_OPT(a,b,c,d,e) { a, b, c, d, e },\n'
     27 	printf 'struct optent optlist[] = {\n'
     28 	printf '#else\n'
     29 	printf '#define DEF_OPT(a,b,c,d,e)\n'
     30 	printf '#endif\n\n'
     31 } >"${OF}"
     32 
     33 FIRST=true
     34 I=0
     35 
     36 while read line
     37 do
     38 	# Look for comments in various styles, and ignore them
     39 	# preprocessor statements are simply output verbatim
     40 	# but use them only first or last. one #ifdef/#endif at end is OK
     41 
     42 	case "${line}" in
     43 	'')	continue;;
     44 	/*)	continue;;
     45 	\**)	continue;;
     46 	\;*)	continue;;
     47 	\#*)	printf '%s\n\n' "${line}" >&4; continue;;
     48 	esac
     49 
     50 	set -- ${line%%[ 	]#*}
     51 
     52 	var="$1" name="$2"
     53 
     54 	case "${var}" in
     55 	('' | [!A-Za-z_]* | *[!A-Za-z0-9_]*)
     56 		printf >&2 "Bad var name: '%s'\\n" "${var}"
     57 		# exit 1
     58 		continue	# just ignore it for now
     59 	esac
     60 
     61 	case "${name}" in
     62 #	=)	name=${var};;		# probably not a good idea
     63 	?) 	set -- ${var} '' $name $3 $4; name= ;;
     64 	esac
     65 
     66 	chr="$3" set="$4" dflt="$5"
     67 
     68 	case "${chr}" in
     69 	-)	chr= set= dflt="$4";;
     70 	''|?)	;;
     71 	*)	printf >&2 'flag "%s": Not a character\n' "${chr}"; continue;;
     72 	esac
     73 
     74 	# options must have some kind of name, or they are useless...
     75 	test -z "${name}${chr}" && continue
     76 
     77 	case "${set}" in
     78 	-)	set= ;;
     79 	[01])	dflt="${set}"; set= ;;
     80 	''|?)	;;
     81 	*)	printf >&2 'set "%s": Not a character\n' "${set}"; continue;;
     82 	esac
     83 
     84 
     85 	if [ -n "${name}" ]
     86 	then
     87 		printf '    DEF_OPT("%s", ' "${name}" >&4
     88 	else
     89 		printf '    DEF_OPT(0, ' >&4
     90 	fi
     91 
     92 	if [ -n "${chr}" ]
     93 	then
     94 		printf "'%s', " "${chr}" >&4
     95 	else
     96 		printf '0, ' >&4
     97 	fi
     98 
     99 	if [ -n "${set}" ]
    100 	then
    101 		printf "'%s', 0, " "${set}" >&4
    102 	else
    103 		printf '0, 0, ' >&4
    104 	fi
    105 
    106 	if [ -n "${dflt}" ]
    107 	then
    108 		printf '%s )\n' "${dflt}" >&4
    109 	else
    110 		printf '0 )\n' >&4
    111 	fi
    112 
    113 	printf '#define	%s	optlist[%d].val\n\n' "${var}" "${I}" >&4
    114 	I=$((I + 1))
    115 
    116 	test -z "${chr}" && continue
    117 
    118 	printf '%s %d\n' "${chr}" $((I - 1))
    119 
    120 done < "$IF" 4>>"${OF}" | sort -t' ' -k1,1f -k1,1r | while read chr index
    121 do
    122 	if $FIRST
    123 	then
    124 		printf '#ifdef DEFINE_OPTIONS\n'
    125 		printf '    { 0, 0, 0, 0, 0 }\n};\n\n'
    126 		printf 'const unsigned char optorder[] = {\n'
    127 		FIRST=false
    128 	fi
    129 	printf '\t%s,\n' "${index}"
    130 
    131 done >>"${OF}"
    132 
    133 {
    134 	printf '};\n\n'
    135 	printf '#define NOPTS (sizeof optlist / sizeof optlist[0] - 1)\n'
    136 	printf 'int sizeof_optlist = sizeof optlist;\n\n'
    137 	printf	\
    138 	   'const int option_flags = (sizeof optorder / sizeof optorder[0]);\n'
    139 	printf '\n#else\n\n'
    140 	printf 'extern struct optent optlist[];\n'
    141 	printf 'extern int sizeof_optlist;\n'
    142 	printf 'extern const unsigned char optorder[];\n'
    143 	printf 'extern const int option_flags;\n'
    144 	printf '\n#endif\n'
    145 } >> "${OF}"
    146 
    147 exit 0
    148