| #!/usr/bin/env bash |
| |
| function usage() |
| { |
| cat <<EOF >&2 |
| Usage: $0 [options] |
| |
| Options: |
| -h Display help or usage |
| -i <input_config> Input config file |
| -l <variable_list> 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 |
| |