diff options
Diffstat (limited to 'awklib/eg')
-rw-r--r-- | awklib/eg/lib/getopt.awk | 94 |
1 files changed, 61 insertions, 33 deletions
diff --git a/awklib/eg/lib/getopt.awk b/awklib/eg/lib/getopt.awk index 6b1f4c50..69944f3f 100644 --- a/awklib/eg/lib/getopt.awk +++ b/awklib/eg/lib/getopt.awk @@ -1,9 +1,11 @@ # getopt.awk --- Do C library getopt(3) function in awk +# Also supports long options. # # Arnold Robbins, arnold@skeeve.com, Public Domain # # Initial version: March, 1991 # Revised: May, 1993 +# Long options added by Greg Minshall, January 2020 # External variables: # Optind -- index in ARGV of first nonoption argument @@ -14,14 +16,14 @@ # Returns: # -1 at end of options # "?" for unrecognized option -# <c> a character representing the current option +# <s> a string representing the current option # Private Data: # _opti -- index in multiflag option, e.g., -abc -function getopt(argc, argv, options, thisopt, i) +function getopt(argc, argv, options, longopts, thisopt, i, j) { - if (length(options) == 0) # no options given - return -1 + if (length(options) == 0 && length(longopts) == 0) + return -1 # no options given if (argv[Optind] == "--") { # all done Optind++ @@ -31,36 +33,61 @@ function getopt(argc, argv, options, thisopt, i) _opti = 0 return -1 } - if (_opti == 0) - _opti = 2 - thisopt = substr(argv[Optind], _opti, 1) - Optopt = thisopt - i = index(options, thisopt) - if (i == 0) { - if (Opterr) - printf("%c -- invalid option\n", thisopt) > "/dev/stderr" - if (_opti >= length(argv[Optind])) { + if (argv[Optind] !~ /^--/) { # if this is a short option + if (_opti == 0) + _opti = 2 + thisopt = substr(argv[Optind], _opti, 1) + Optopt = thisopt + i = index(options, thisopt) + if (i == 0) { + if (Opterr) + printf("%c -- invalid option\n", thisopt) > "/dev/stderr" + if (_opti >= length(argv[Optind])) { + Optind++ + _opti = 0 + } else + _opti++ + return "?" + } + if (substr(options, i + 1, 1) == ":") { + # get option argument + if (length(substr(argv[Optind], _opti + 1)) > 0) + Optarg = substr(argv[Optind], _opti + 1) + else + Optarg = argv[++Optind] + _opti = 0 + } else + Optarg = "" + if (_opti == 0 || _opti >= length(argv[Optind])) { Optind++ _opti = 0 } else _opti++ - return "?" - } - if (substr(options, i + 1, 1) == ":") { - # get option argument - if (length(substr(argv[Optind], _opti + 1)) > 0) - Optarg = substr(argv[Optind], _opti + 1) + return thisopt + } else { + j = index(argv[Optind], "=") + if (j > 0) + thisopt = substr(argv[Optind], 3, j - 3) else - Optarg = argv[++Optind] - _opti = 0 - } else - Optarg = "" - if (_opti == 0 || _opti >= length(argv[Optind])) { + thisopt = substr(argv[Optind], 3) + Optopt = thisopt + i = match(longopts, "(^|,)" thisopt "($|[,:])") + if (i == 0) { + if (Opterr) + printf("%s -- invalid option\n", thisopt) > "/dev/stderr" + Optind++ + return "?" + } + if (substr(longopts, i+1+length(thisopt), 1) == ":") { + if (j > 0) + Optarg = substr(argv[Optind], j + 1) + else + Optarg = argv[++Optind] + } else + Optarg = "" Optind++ - _opti = 0 - } else - _opti++ - return thisopt + return thisopt + } } BEGIN { Opterr = 1 # default is to diagnose @@ -68,12 +95,13 @@ BEGIN { # test program if (_getopt_test) { - while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1) - printf("c = <%c>, Optarg = <%s>\n", - _go_c, Optarg) + _myshortopts = "ab:cd" + _mylongopts = "longa,longb:,otherc,otherd" + + while ((_go_c = getopt(ARGC, ARGV, _myshortopts, _mylongopts)) != -1) + printf("c = <%s>, Optarg = <%s>\n", _go_c, Optarg) printf("non-option arguments:\n") for (; Optind < ARGC; Optind++) - printf("\tARGV[%d] = <%s>\n", - Optind, ARGV[Optind]) + printf("\tARGV[%d] = <%s>\n", Optind, ARGV[Optind]) } } |