1# getopt --- do C library getopt(3) function in awk
2#
3# arnold@gnu.org
4# Public domain
5#
6# Initial version: March, 1991
7# Revised: May, 1993
8
9# External variables:
10#    Optind -- index of ARGV for first non-option argument
11#    Optarg -- string value of argument to current option
12#    Opterr -- if non-zero, print our own diagnostic
13#    Optopt -- current option letter
14
15# Returns
16#    -1     at end of options
17#    ?      for unrecognized option
18#    <c>    a character representing the current option
19
20# Private Data
21#    _opti  index in multi-flag option, e.g., -abc
22function getopt(argc, argv, options,    optl, thisopt, i)
23{
24    optl = length(options)
25    if (optl == 0)        # no options given
26        return -1
27
28    if (argv[Optind] == "--") {  # all done
29        Optind++
30        _opti = 0
31        return -1
32    } else if (argv[Optind] !~ /^-[^: \t\n\f\r\v\b]/) {
33        _opti = 0
34        return -1
35    }
36    if (_opti == 0)
37        _opti = 2
38    thisopt = substr(argv[Optind], _opti, 1)
39    Optopt = thisopt
40    i = index(options, thisopt)
41    if (i == 0) {
42        if (Opterr)
43            printf("%c -- invalid option\n",
44                                  thisopt) > "/dev/stderr"
45        if (_opti >= length(argv[Optind])) {
46            Optind++
47            _opti = 0
48        } else
49            _opti++
50        return "?"
51    }
52    if (substr(options, i + 1, 1) == ":") {
53        # get option argument
54        if (length(substr(argv[Optind], _opti + 1)) > 0)
55            Optarg = substr(argv[Optind], _opti + 1)
56        else
57            Optarg = argv[++Optind]
58        _opti = 0
59    } else
60        Optarg = ""
61    if (_opti == 0 || _opti >= length(argv[Optind])) {
62        Optind++
63        _opti = 0
64    } else
65        _opti++
66    return thisopt
67}
68BEGIN {
69    Opterr = 1    # default is to diagnose
70    Optind = 1    # skip ARGV[0]
71
72    # test program
73    if (_getopt_test) {
74        while ((_go_c = getopt(ARGC, ARGV, "ab:cd")) != -1)
75            printf("c = <%c>, optarg = <%s>\n",
76                                       _go_c, Optarg)
77        printf("non-option arguments:\n")
78        for (; Optind < ARGC; Optind++)
79            printf("\tARGV[%d] = <%s>\n",
80                                    Optind, ARGV[Optind])
81    }
82}
83