Getopt

September 17, 2019

Here is our version of getopt:

function getopt(defn, msg,     n, i, flag, rest) {

    # collect flag/value pairs in OPTS,
    # remove from ARGV, and return count

    # initialize i, loop runs forever
    for (i = 1; ;) {

        # stop at end of arguments
        if (i == ARGC) { return n+0 }
        if (ARGV[i] == "--") { ARGV[i] = ""; return n+0 }
        if (ARGV[i] == "") { i++; continue }
        if (substr(ARGV[i],1,1) != "-") { return n+0 }

        # found argument; parse flag from rest of string
        flag = substr(ARGV[i],2,1); rest = substr(ARGV[i],3)

        # argument requires an associated value
        if (index(defn, flag ":") > 0) {
            if (rest != "") { # value in same argument as flag
                OPTS[flag] = rest; ARGV[i] = ""; i++; n++ }
            else if (i &2"; exit 1 } }

        # argument has no associated value
        else if (index(defn, flag) > 0) {
            if (rest != "") {
                OPTS[flag] = ""; ARGV[i] = "-" rest; n++ }
            else { OPTS[flag] = ARGV[i] = ""; n++ } }

        # unrecognized flag
        else { print "ERROR: unrecognized flag " flag \
                   ": " msg | "cat 1>&2"; exit 1 } } }

There are a few points of interest here. The for loop initializes i but doesn’t increment it, because sometimes i isn’t incremented the same as other times, and doesn’t test for termination, because there are multiple ways to terminate the loop, some of which require different processing. The idiom print ... | "cat 1>&2" prints a message on stderr; in Gawk you can write directly to /dev/stderr, but that is not possible in other implementations of Nawk (for instance, on HP-UX where I work). The return value n+0 coerces n to numeric in case there are no flags.

You can call getopt in the BEGIN action like this:

BEGIN { msg = "usage: [-befhmn] [-D string]"
        print "There are", getopt("befhmnD:", msg), "options."
        for (flag in OPTS) { print flag, OPTS[flag] } }

Called as awk -f opts.awk -- -b -D hello, that will set two options OPTS["b"] = "" and OPTS["D"] = "hello".

You can run the program at <a href="https://ideone.com/RIk98j"<https://ideone.com/RIk98j.

Pages: 1 2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: