diff --git a/scripts/carray.sh b/scripts/carray.sh index a2b05d31..2580fac9 100755 --- a/scripts/carray.sh +++ b/scripts/carray.sh @@ -45,42 +45,108 @@ if [ ! -f "${CONFIG_FILE}" ]; then usage fi -TYPE_HEADER=$(awk '{ if ($1 == "HEADER:") { printf $2; exit 0; } }' "${CONFIG_FILE}") -if [ -z "${TYPE_HEADER}" ]; then - echo "Must specify HEADER: in input config file" - usage -fi +# use single awk script to run conversion, but leave in .sh file as awk is +# bad for getopt, and leaves the original script name alone. -TYPE_NAME=$(awk '{ if ($1 == "TYPE:") { printf $2; for (i=3; i<=NF; i++) printf " %s", $i; exit 0; } }' "${CONFIG_FILE}") -if [ -z "${TYPE_NAME}" ]; then - echo "Must specify TYPE: in input config file" - usage -fi +awk -v"CONFIG_FILE=${CONFIG_FILE}" -v "SCRIPT_NAME=`basename $0`" -v"VARLIST=${VAR_LIST}" ' +function array_length(a) +{ + result = 0 -ARRAY_NAME=$(awk '{ if ($1 == "NAME:") { printf $2; exit 0; } }' "${CONFIG_FILE}") -if [ -z "${ARRAY_NAME}" ]; then - echo "Must specify NAME: in input config file" - usage -fi + for (i in a) + result++ -MEMBER_NAME=$(awk '{ if ($1 == "MEMBER-NAME:") { printf $2; exit 0; } }' "${CONFIG_FILE}") -MEMBER_TYPE=$(awk '{ if ($1 == "MEMBER-TYPE:") { printf $2; for (i=3; i<=NF; i++) printf " %s", $i; exit 0; } }' "${CONFIG_FILE}") -if [ -n "${MEMBER_NAME}" ] && [ -z "${MEMBER_TYPE}" ]; then - echo "Must specify MEMBER-TYPE: when using MEMBER-NAME:" - usage -fi + return result +} -printf "// Generated with $(basename $0) from $(basename ${CONFIG_FILE})\n" -printf "#include <%s>\n\n" "${TYPE_HEADER}" +function get_fields(start, end) +{ + result = $start; -for VAR in ${VAR_LIST}; do - printf "extern %s %s;\n" "${TYPE_NAME}" "${VAR}" -done -printf "\n" + for (nr = start+1; nr <= end; nr++) { + result = result " " $nr + } + return result; +} + +BEGIN { + split(VARLIST,VAR_LIST," ") +} + +# process items from the config file + +/^HEADER:/ { TYPE_HEADER = $2 } +/^TYPE:/ { TYPE_NAME = get_fields(2, NF); } +/^NAME:/ { ARRAY_NAME = $2} +/^MEMBER-NAME:/ { MEMBER_NAME = $2 } +/^MEMBER-TYPE:/ { MEMBER_TYPE = get_fields(2, NF); } + +# code to dump the generated .c file once config file is processed + +END { + # enable for debug + if (length(ENVIRON["CARRAY_DEBUG"]) > 0) { + print "ARRAY_NAME " ARRAY_NAME > "/dev/stderr" + print "TYPE_HEADER " TYPE_HEADER > "/dev/stderr" + print "TYPE_NAME " TYPE_NAME > "/dev/stderr" + + print "VAR_LIST length is " array_length(VAR_LIST) > "/dev/stderr" + for (v in VAR_LIST) { + print "VAR_LIST " v " = " VAR_LIST[v] > "/dev/stderr" + } + } + + if (array_length(VAR_LIST) == 0) { + print "Warning; no VAR list on command line" > "/dev/stderr" + } + + if (length(ARRAY_NAME) == 0) { + print "Must specify NAME: in input config file" > "/dev/stderr" + exit 1 + } + + if (length(TYPE_NAME) == 0) { + print "Must specify TYPE: in input config file" > "/dev/stderr" + exit 1 + } + + if (length(TYPE_HEADER) == 0) { + print "Must specify HEADER: in input config file" > "/dev/stderr" + exit 1 + } + + if (length(MEMBER_NAME) > 0 && length(MEMBER_TYPE) == 0) { + print "Must specify MEMBER-TYPE: when using MEMBER-NAME:" > "/dev/stderr" + exit 1 + } + + printf "// Generated with %s from %s\n", SCRIPT_NAME, CONFIG_FILE + printf "// DO NOT EDIT THIS FILE DIRECTLY\n" + printf "\n" + printf("#include <%s>\n\n", TYPE_HEADER) + + for (v in VAR_LIST) { + printf("extern %s %s;\n", TYPE_NAME, VAR_LIST[v]) + } + print "" + + if (length(MEMBER_TYPE) > 0) { + TYPE_NAME = MEMBER_TYPE; + } + + if (length(MEMBER_NAME) > 0) { + VAR_SUFFIX = "." MEMBER_NAME; + } else { + VAR_SUFFIX = "" + } + + printf("%s *const %s[] = {\n", TYPE_NAME, ARRAY_NAME) + for (v in VAR_LIST) { + printf("\t&%s%s,\n", VAR_LIST[v], VAR_SUFFIX) + } + printf("\tNULL\n"); + + printf("};\n"); +} +' < ${CONFIG_FILE} || usage -printf "%s *const %s[] = {\n" "${MEMBER_TYPE:-${TYPE_NAME}}" "${ARRAY_NAME}" -for VAR in ${VAR_LIST}; do - printf "\t&%s,\n" "${VAR}${MEMBER_NAME:+.}${MEMBER_NAME}" -done - printf "\tNULL\n" -printf "};\n"