rc-list - mailing list for the rc(1) shell
 help / color / mirror / Atom feed
* Re: shift, for, return values and getopts
@ 1991-09-30 14:08 Byron Rakitzis
  0 siblings, 0 replies; 2+ messages in thread
From: Byron Rakitzis @ 1991-09-30 14:08 UTC (permalink / raw)
  To: malte, rc

ouch, that is a bug in the shell. unfortunately, when you do

	for (i in $var)

$var's value does not get copied into a temporary space if $var is
overwritten in the body of the loop. Nothing gets re-evaluated,
but there are pointers pointing into outer space in a loop like
that.

The fix is not difficult, but spans three source files (I just
fixed the bug).

I don't know how the list feels about this, but there are maybe 2
or 3 bugs in rc-1.2 that I've heard of so far. I don't know how
important it is to release patches, etc. etc., seeing as I've never
done this sort of thing before. I was hoping that rc-1.2 would be
definitive, i.e., any further changes to the shell would be just
bug fixes. How do I go about scheduling fixes like that?



^ permalink raw reply	[flat|nested] 2+ messages in thread

* shift, for, return values and getopts
@ 1991-09-30 13:10 malte
  0 siblings, 0 replies; 2+ messages in thread
From: malte @ 1991-09-30 13:10 UTC (permalink / raw)
  To: rc

If I define shift like this
	fn shift {
		n=1
		if(~ $1 [1-9]* ) { n=$1; builtin shift }
		for( i in $* ){
			*=$$i; builtin shift $n; $i=$*
		}
	}

it doesn't work because $* gets evaluated in every loop, so $* changes
its value while executing. Is there a reason for this? I'd expected
that  for( i in $* ) is evaluated only once to avoid using a temporary
variable, like 
	fn shift {
		n=1
		if(~ $1 [1-9]* ) { n=$1; builtin shift }
		args=$* { for( i in $args ){
				*=$$i; builtin shift $n; $i=$*
			}
		}
	}
wich does work.

Now something different: I think it is most useful to have status set
to the return codes of a backquote substitution, e.g.
	x=`{/bin/false}
	echo $status
should give you "1".
If this breaks something (what could it be?), I'd propose to allow
something like
	x=`{ /bin/false; return $status}	# status=(1)
or even
	x=`{ ls | /bin/false; exit $status}	# status=(0 1)
At the moment, I'm busy writing a rc equivalent to sh's read and it would
simplify things alot.

---
And now my solution for getopts (not getopt, consult your man pages)

fn getopts {
	if( ~ $#* 0 1 2 ){ return 1 }	# no more arguments to process

	# building a list of possible options
	OPTSTRING=`` ($ifs ':') { echo $^1 | sed '1s|.|& |g' };
	OPTSTRING='-'^$OPTSTRING;

	# possible options are "--", "-o" "-oxx" "-o xx"
	switch($^3){
		# if $^3 is "--" force abortion of getopts
		case --   ; return 1
		# $^3 an option like "-o", possibly with argument
		case -?   ; OPTARG=($^3 $^4)
			    OPTIND=2
		# $^3 an option with argument "-oxx"
		case -??* ; OPTARG=(`{echo $^3 | sed '1s|\(..\)\(.*\)|\1 \2|'})
			    OPTIND=1
		# not a switch, assume no more arguments
		case *    ; return 1
	}
	# check if option is in the list of legal options
	if( ~ $OPTARG(1) $OPTSTRING ){
		# set the varaible which contains the option
		$2=`` ($ifs '-') { echo $OPTARG(1) }
		# check if option demands an argument
		if( ~ $^1 *$$^2:* ){
			OPTARG=$OPTARG(2)	# should be "shift OPTARG"
			if( ~ $#OPTARG 0 ){
				echo 'too few arguments to -'$$2 >[2=1]
				exit 1
			}
		} else {
			OPTARG=() OPTIND=1
		}
	} else {
		echo invalid argument $OPTARG(1) >[2=1]
		OPTARG='-?'
		# at this point the return code could be set to 1,
		# if this meets with the behaviour of your sh.
		# SunOS returns 0.
	}
	return 0
}
This meets the syntax and sematics of sh getopts with one exception each:
In contrary to sh, the $* parameter is not optional.
It is neccesary to call "shift $OPTIND" after each call to getopts, in
contrary to sh getopts, where it suffices to shift after the last call to
getopts:
(rc)	while( getopts 'st:ri:ng' opt $* ){
		switch( $opt ){
			case t ; text=$OPTARG;
			case ...
		}
		shift $OPTIND
	}

(sh)	while getopts 'st:ri:ng' opt
	do
		case $opt in
			...
		esac
	done
	shift `expr $OPTIND - 1`

Suggestions and improvements are highly welcome!


_______________________________________________________________________________
malte@techfak.uni-bielefeld.de

send mail reply to:	Universitaet Bielefeld, Technische Fakultaet
		z. Hd. Malte Uhl
		Postfach 8640
		4800 Bielefeld 1



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1991-09-30 14:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1991-09-30 14:08 shift, for, return values and getopts Byron Rakitzis
  -- strict thread matches above, loose matches on Subject: below --
1991-09-30 13:10 malte

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).