summaryrefslogtreecommitdiff
path: root/lib/getopts.rb
blob: 490523b8788cd9abd1d8f319bcfb487b948a7ee4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#
#               getopts.rb - 
#                       $Release Version: $
#                       $Revision$
#                       $Date$
#                       by Yasuo OHBA(SHL Japan Inc. Technology Dept.)
#
# --
# this is obsolete; use getoptlong
#
# 2000-03-21
# modified by Minero Aoki <aamine@dp.u-netsurf.ne.jp>
#

$RCS_ID=%q$Header$


def getopts( single_opts, *options )
  single_opts_exp = (single_opts && !single_opts.empty?) ?
                        /[#{single_opts}]/ : nil
  single_colon_exp = nil
  single_colon = nil
  opt = arg = val = nil
  boolopts = {}
  valopts = {}
  argv = ARGV
  newargv = []

  #
  # set default
  #
  if single_opts then
    single_opts.each_byte do |byte|
      boolopts[ byte.chr ] = false
  end
end
  unless options.empty? then
    single_colon = ''

    options.each do |opt|
      m = /\A([^:]+):(.*)\z/.match( opt )
      if m then
        valopts[ m[1] ] = m[2].empty? ? 0 : m[2]
      else
        boolopts[ opt ] = false
end
  end
    valopts.each do |opt, dflt|
      if opt.size == 1 then
        single_colon << opt
end
  end

    if single_colon.empty? then
      single_colon = single_colon_exp = nil
      else
      single_colon_exp = /[#{single_colon}]/
    end
  end
  
  #
  # scan
  #
  c = 0
  arg = argv.shift
  while arg do
    case arg
    when /\A--?\z/                      # xinit -- -bpp 24
      newargv.concat argv
      break

    when /\A--(.*)/
      opt = $1
      if valopts.key? opt  then         # imclean --src +trash
        return nil if argv.empty?
        valopts[ opt ] = argv.shift
      elsif boolopts.key? opt then      # ruby --verbose
        boolopts[ opt ] = true
      else
              return nil
            end
      c += 1

    when /\A-(.+)/
      arg = $1
      0.upto( arg.size - 1 ) do |idx|
        opt = arg[idx, 1]
        if single_opts and single_opts_exp === opt then
          boolopts[ opt ] = true        # ruby -h
          c += 1

        elsif single_colon and single_colon_exp === opt then
          val = arg[ (idx+1)..-1 ]
          if val.empty? then            # ruby -e 'p $:'
            return nil if argv.empty?
            valopts[ opt ] = argv.shift
          else                          # cc -ohello ...
            valopts[ opt ] = val
      end
          c += 1

          break
          else
          return nil
          end
        end

    else                                # ruby test.rb
      newargv.push arg
      end

    arg = argv.shift
    end
    
  #
  # set
  #
  boolopts.each do |opt, val|
    eval "$OPT_#{opt} = val"
    end
  valopts.each do |opt, val|
    eval "$OPT_#{opt} = #{val == 0 ? 'nil' : 'val'}"
  end
  argv.replace newargv

  c
end