blob: 2580fac97d7bbca71f591ab5c020bf4fa5fb3b2e [file] [log] [blame]
#!/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