#!/usr/bin/nawk -f
#
#   Ultra-4FT device architecture definition enquiry program
#
#   This nawk(1) script queries the device architecture database
#   ($CMSHOME/etc/u4ftloc.data).
#
#   @(#)u4ftloc_get_parameter	1.2	98/05/27
#

BEGIN   	{
		    init();
		    parse_argv();
		    reset_argv();
		    clear_line();
		}

/^[ \t]*#/	{
		    debug("Comment line: " $0);
		    next;
		}

/^$/    	{
		    debug("End paragraph: " $0);
		    if (match_line())
			show_line();
		    clear_line();
		    next;
		}

		{
		    parse_line();
		    next;
		}

END     	{
		    debug("End file: " $0);
		    if (match_line())
			show_line();
		}

function init()
{
    #
    # initialise global constants
    #
    DATAFILE = "u4ftloc.data";
    DATADIR = ENVIRON["CMSHOME"];
    if (DATADIR != "")
        DATAFILE = DATADIR "/etc/" DATAFILE;
    FLAG="^\\+[fcd]";
    ID="[a-zA-Z_][a-zA-Z_0-9]*";
}

function usage()
{
    name=ARGV[0];
    sub(".*/", "", $name);
    printf "Usage: %s [selector ...] [query ...]", name > "/dev/fd/2";
    exit 255;
}

function parse_argv()
{
    if (ARGC < 2)
	usage();

    for (i = 1; i < ARGC; ++i)
    {
        arg = ARGV[i];
        if (match(arg, "^" ID "=") > 0)
        {
            name = substr(arg, RSTART, RLENGTH-1);
            value = substr(arg, RLENGTH+1);
            selector[name] = value;
            debug("\tselector[" name "]=" selector[name]);
        }
        else if (match(arg, "^" ID "\\?$") > 0)
        {
            name = substr(arg, RSTART, RLENGTH-1);
            format[name] = 2;
            query[++n_queries] = name;
            debug("\tquery[" n_queries "]=" name  \
                  " (format " format[name] ")");
        }
        else if (match(arg, "^" ID "$") > 0)
        {
            name = arg;
            format[name] = 0;
            query[++n_queries] = name;
            debug("\tquery[" n_queries "]=" name  \
                  " (format " format[name] ")");
        }
        else if (arg == "*?")
        {
            wild = 2;
            debug("\twildcard, format " wild);
        }
        else if (arg == "*")
        {
            wild = 1;
            debug("\twildcard, format " wild);
        }
        else if (arg != "")
            whinge("invalid argument \"%s\"", arg);

        # zap each argument once it's been processed, to
        # make sure nawk doesn't interpret it as a filename
        delete ARGV[i];
    }
}

function reset_argv()
{
    ARGV[1] = DATAFILE;
    FS = OFS = "\t";
    RS = ORS = "\n";
}

function clear_line()
{
    debug("");
    for (name in line)
        delete line[name];
    fields = 1;
}

function parse_line()
{
    debug("Input line: " $0);

    for (i = 1; i <= NF; ++i)
    {
        debug("\tField " i ": " $i);
        sub("^[ \t]+", "", $i);
        if ($i != "")
#       {
#           if (substr($i, 1, length(FIELD[fields])) != FIELD[fields])
#               $i = FIELD[fields] $i;
            fields += 1;
#       }
    }

    debug("Named line: " $0);

    for (i = 1; i <= NF; ++i)
    {
        if (match($i, "^" ID "=") > 0)
        {
            value = substr($i, RLENGTH+1);
            $i = substr($i, RSTART, RLENGTH-1);
            line[$i] = value;
            debug("\tline[" $i "]=" line[$i]);
        }
        else if ($i != "")
        {
            debug("\tline " NR ", field " i " of " NF ": \"" $i "\"");
            whinge("invalid data at line %d of input", NR);
        }
    }
}

function match_line()
{
    if (fields == 1)
    {
        debug("No match (no fields)");
        return 0;
    }
    for (name in selector)
        if (line[name] != selector[name])
        {
            debug("No match (" name ")");
            return 0;
        }
    debug("Match!");
    return 1;
}

function show_line()
{
    for (i = 1; i <= n_queries; ++i)
    {
        name = query[i];
        show(name, line[name], i, format[name]);
        delete line[name];
    }
    if (wild > 0)
        for (i = 1; i <= NF; ++i)
            if (line[$i])
                show($i, line[$i], i, wild);
    printf "%s", ORS;
}

function show(name, value, fieldno, format)
{
    #
    #   Display one field of a selected record
    #
    if (fieldno > 1)
        printf "%s", OFS;
    if (format > 1)
        printf "%s=%s", name, value
    else
        printf "%s", value;
}

function debug(msg)
{
#   print msg;
}

function whinge(fmt, arg1, arg2, arg3, arg4)
{
    printf "%s: " fmt "\n", ARGV[0], arg1, arg2, arg3, arg4 > "/dev/fd/2";
    exit 255;
}
