# getopt
BEGIN { msg = "usage: [-befhmn] [-D string]"
print "There are", getopt("befhmnD:", msg), "options."
for (flag in OPTS) { print flag, OPTS[flag] } }
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 < ARGC) { # value in next argument
OPTS[flag] = ARGV[i+1]; ARGV[i] = ARGV[i+1] = ""
i += 2; n++ }
else { print "ERROR: " flag " flag requires value " \
": " msg
| "cat 1>&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 } } }
IyBnZXRvcHQKCkJFR0lOIHsgbXNnID0gInVzYWdlOiBbLWJlZmhtbl0gWy1EIHN0cmluZ10iCiAgICAgICAgcHJpbnQgIlRoZXJlIGFyZSIsIGdldG9wdCgiYmVmaG1uRDoiLCBtc2cpLCAib3B0aW9ucy4iCiAgICAgICAgZm9yIChmbGFnIGluIE9QVFMpIHsgcHJpbnQgZmxhZywgT1BUU1tmbGFnXSB9IH0KCmZ1bmN0aW9uIGdldG9wdChkZWZuLCBtc2csICAgICBuLCBpLCBmbGFnLCByZXN0KSB7CgogICAgIyBjb2xsZWN0IGZsYWcvdmFsdWUgcGFpcnMgaW4gT1BUUywKICAgICMgcmVtb3ZlIGZyb20gQVJHViwgYW5kIHJldHVybiBjb3VudAoKICAgICMgaW5pdGlhbGl6ZSBpLCBsb29wIHJ1bnMgZm9yZXZlcgogICAgZm9yIChpID0gMTsgOykgewoKICAgICAgICAjIHN0b3AgYXQgZW5kIG9mIGFyZ3VtZW50cwogICAgICAgIGlmIChpID09IEFSR0MpIHsgcmV0dXJuIG4rMCB9CiAgICAgICAgaWYgKEFSR1ZbaV0gPT0gIi0tIikgeyBBUkdWW2ldID0gIiI7IHJldHVybiBuKzAgfQogICAgICAgIGlmIChBUkdWW2ldID09ICIiKSB7IGkrKzsgY29udGludWUgfQogICAgICAgIGlmIChzdWJzdHIoQVJHVltpXSwxLDEpICE9ICItIikgeyByZXR1cm4gbiswIH0KCiAgICAgICAgIyBmb3VuZCBhcmd1bWVudDsgcGFyc2UgZmxhZyBmcm9tIHJlc3Qgb2Ygc3RyaW5nCiAgICAgICAgZmxhZyA9IHN1YnN0cihBUkdWW2ldLDIsMSk7IHJlc3QgPSBzdWJzdHIoQVJHVltpXSwzKQoKICAgICAgICAjIGFyZ3VtZW50IHJlcXVpcmVzIGFuIGFzc29jaWF0ZWQgdmFsdWUKICAgICAgICBpZiAoaW5kZXgoZGVmbiwgZmxhZyAiOiIpID4gMCkgewogICAgICAgICAgICBpZiAocmVzdCAhPSAiIikgeyAjIHZhbHVlIGluIHNhbWUgYXJndW1lbnQgYXMgZmxhZwogICAgICAgICAgICAgICAgT1BUU1tmbGFnXSA9IHJlc3Q7IEFSR1ZbaV0gPSAiIjsgaSsrOyBuKysgfQogICAgICAgICAgICBlbHNlIGlmIChpIDwgQVJHQykgeyAjIHZhbHVlIGluIG5leHQgYXJndW1lbnQKICAgICAgICAgICAgICAgIE9QVFNbZmxhZ10gPSBBUkdWW2krMV07IEFSR1ZbaV0gPSBBUkdWW2krMV0gPSAiIgogICAgICAgICAgICAgICAgaSArPSAyOyBuKysgfQogICAgICAgICAgICBlbHNlIHsgcHJpbnQgIkVSUk9SOiAiIGZsYWcgIiBmbGFnIHJlcXVpcmVzIHZhbHVlICIgXAogICAgICAgICAgICAgICAgICAgIjogIiBtc2cgfCAiY2F0IDE+JjIiOyBleGl0IDEgfSB9CgogICAgICAgICMgYXJndW1lbnQgaGFzIG5vIGFzc29jaWF0ZWQgdmFsdWUKICAgICAgICBlbHNlIGlmIChpbmRleChkZWZuLCBmbGFnKSA+IDApIHsKICAgICAgICAgICAgaWYgKHJlc3QgIT0gIiIpIHsKICAgICAgICAgICAgICAgIE9QVFNbZmxhZ10gPSAiIjsgQVJHVltpXSA9ICItIiByZXN0OyBuKysgfQogICAgICAgICAgICBlbHNlIHsgT1BUU1tmbGFnXSA9IEFSR1ZbaV0gPSAiIjsgbisrIH0gfQoKICAgICAgICAjIHVucmVjb2duaXplZCBmbGFnCiAgICAgICAgZWxzZSB7IHByaW50ICJFUlJPUjogdW5yZWNvZ25pemVkIGZsYWcgIiBmbGFnIFwKICAgICAgICAgICAgICAgICAgICI6ICIgbXNnIHwgImNhdCAxPiYyIjsgZXhpdCAxIH0gfSB9