Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

getopt.macro

8 views
Skip to first unread message

Jonathan Scott Duff

unread,
Mar 27, 2003, 2:29:24 PM3/27/03
to perl6-i...@perl.org
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

Benjamin Goldberg

unread,
Mar 27, 2003, 8:53:33 PM3/27/03
to perl6-i...@perl.org
Jonathan Scott Duff wrote:
>
> 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,
[snip]

> # 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)

Wouldn't it be more flexible to write it as:

.macro getopt(str, args_in, argout_index, argout_hash)

, so that the user can fully specify where args get read from, and what
gets clobbered?

> save S0 # Current command line arg
> save S1 # option char
> save S2 # scratch string

AFAIK, a single "pushs" op is faster than three "save S<N>" ops.

--
$a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
);{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6
]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}

0 new messages