I'm fiddling around with parrot and created a getopt macro (inspired by
the arg processing in Leon Brocard's uniq.pasm :-).  This is my first
attempt at something semi-useful in parrot.

Anyway, here it is and looking for comments,

-Scott


---->8---->8 ---->8 ---->8-----
# getopt.macro
#
# Scans P0 for options. The options to scan for are given in str and
# those options found are placed in P15 (as a PerlHash). Unknown options
# are silently ignored. The scan stops at the first argument that
# doesn't start with a '-' or when the special argument "--" is seen (or
# when we've run out of command line).
#
# Options mayn't be grouped, i.e., -a -b -c may NOT be written as -abc
#
# Like the standard getopt routine, a colon after a letter in the option
# string signifies that the option takes an argument.
#
# When using the same option multiple times, only the last is
# saved in the PerlHash
#
# Typical usage might look something like this:
#
#       .include 'getopt.macro'
#       .getopt("ab:")
#       exists I1, P15["a"]
#       exists I2, P15["b"]
#
#       print "a = "
#       print I1
#       print "\n"
#       print "b = "
#       set S0, ""
#       unless I2, NOB
#       set S0, P15["b"]
#NOB:
#       print S0
#       print "\n"
#
#       set I0, I15             # first non-option arg
#LOOP:                          # output the non-option args
#       set S0, P0[I0]
#       print S0
#       print " "
#       inc I0
#       le I0, I2, LOOP
#
#       print "\n"
#       end
#
#
# Note:  Both P15 and I15 are clobbered by this routine. P15 will be a
#        PerlHash containing the options and their values and I15 will
#        contain the index of the first non-option arguement on the
#        comamnd line.


.macro getopt (str)
        save S0                 # Current command line arg
        save S1                 # option char
        save S2                 # scratch string
        save I1                 # length of command line
        save I2                 # scratch int

        set I1, P0              # get length of command line
        lt I1, 2, .$noargs      # There aren't any args
        
        new P15, .PerlHash      # create a place to store the options

        set I15, 0
.local $l0:                             # loop over command line
        inc I15
        eq I15, I1, .$argsdone          # no more args
        set S0, P0[I15]                 # S0 is the command line arg
        eq S0, "--", .$argsdone         # -- signifies end of options
        substr S1, S0, 0, 1             # get first char
        ne S1, "-", .$argsdone          # no -, then we're done

        substr S1, S0, 1, 1             # S1 holds the option char
        index I2, .str, S1
        lt I2, 0, .$l0                  # option not found, ignore
        set P15[S1], ""                 # rare case 
        inc I2
        substr S2, .str, I2, 1          # need a parameter?
        ne S2, ":", .$l0                # nope, get next option

        length I2, S0                   # get the length of the arg
        sub I2, I2, 2                   # subtract 2 for the - and option char
        eq I2, 0, .$getnextarg          # no more chars in arg?
        substr S0, S0, 2, I2
        set P15[S1], S0
        branch .$l0

.local $getnextarg:                     # grab the next arg from the cmd line
        inc I15
        set S0, P0[I15]
        set P15[S1], S0
        branch .$l0

.local $argsdone:
        set I1, P15
        eq I1, 0, .$done                # no, we didn't really find any

        ne S0, "--", .$done             
.local $noargs:
        inc I15

.local $done:                           # put things back
        restore I2
        restore I1
        restore S2
        restore S1
        restore S0
.endm

Reply via email to