#!/usr/bin/env bash function usage() { cat <&2 Usage: $0 [options] Options: -h Display help or usage -i Input config file -l List of variables in the array (Optional) EOF exit 1; } # Command line options CONFIG_FILE="" VAR_LIST="" while getopts "hi:l:" o; do case "${o}" in h) usage ;; i) CONFIG_FILE=${OPTARG} ;; l) VAR_LIST=${OPTARG} ;; *) usage ;; esac done shift $((OPTIND-1)) if [ -z "${CONFIG_FILE}" ]; then echo "Must specify input config file" usage fi if [ ! -f "${CONFIG_FILE}" ]; then echo "The input config file should be a present" 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. awk -v"CONFIG_FILE=${CONFIG_FILE}" -v "SCRIPT_NAME=`basename $0`" -v"VARLIST=${VAR_LIST}" ' function array_length(a) { result = 0 for (i in a) result++ return result } function get_fields(start, end) { result = $start; 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