-- () Copyright International Business Machines Corporation 23 January 
-- 1990.  All Rights Reserved. 
--  
-- See the file USERAGREEMENT distributed with this software for full 
-- terms and conditions of use. 
-- Author: William Silverman
-- SCCS Info: @(#)extract_options.pp	1.1 9/12/91


-- Requires environment to be the root!environ variable, prefix
-- to be an initialized charstring, argv to be an initialized
-- charstringlist, and the following declaration:
--
--  options: annotations;
--
--  Extracted options are added to options, and residual character strings
--  are left in argv.

-- following is required as a workaround for an AIX bug on the Rios
#define addspace(x,y) x y

#define AREF(elt,t,i) elt in t where (B(I(addspace(position of,elt)) = i))

    -- Pick out command line options
    new options;
    block declare
	prefixsize : integer;
	option: annotation;
	optnames: charstringList;
	name: charstring;
	value: charstring;
	empty: empty;
	caseDiff: integer;
      begin
	prefixsize <- I(size of S(prefix));
		-- for case conversions...
	caseDiff <- I(I(convert of C('a')) - I(convert of C('A')));
	-- get all arg strings that begin with a hyphen
	extract optnames from word in argv 
	   where (B(C(AREF(tmp,word,ZERO)) = C('-')));
	-- incorporate all of the environmental variables, prefixed by "+"
	for e in environment[] inspect
	    name <- S(S("+") | e.variable);
	    if B(e.value = S("")) then
		insert name into optnames;
	      else 
		insert S(name | S(S("=") | e.value)) into optnames;
	      end if;
	  end for;
    
	-- Turn each word into an option in the options table.  If the word
	-- begins  "+" | prefix  it is a relevant environmental variable,
	-- and the effective word follows that prefix.  If the effective
	-- word contains an embedded equal sign ('='), the portion before
	-- the equal sign becomes the option name, and the following
	-- portion becomes the option value (a charstring)
	for optname in optnames[] inspect
	    new option;
	    new option.name;
	    block begin
		inspect c in optname where (B(c = C('='))) begin
		    -- break up name and value
		    name <- S(every of c1 in optname
		       where (B(I(position of c1) < I(position of c))));
		    value <- S(every of c1 in optname 
		       where (B(I(position of c1) > I(position of c))));
		    wrap value as option.thing;	
		  end inspect;
	      on (NotFound)
		-- no equal sign... value is empty
		name := optname;
		wrap empty as option.thing;
	      end block;
	    -- Convert option name to lower case
	    for c in name where (B(I(position of c) > ZERO)) inspect
		if  B(B(c >= C('A')) and B(c <= C('Z'))) then
		    insert C(convert of I(I(convert of c) + caseDiff))
			       into option.name;
		  else
		    insert C(copy of c) into option.name;
		  end if;
	      end for;
	    -- Finished forming this option
	    block begin
		if B(exists of c in name where(B(B(I(position of c) = ZERO)
				   and B(c = C('+')))))
		  then
		    -- its an environmental variable - check it for relevance!
		    if B(S(every of c in option.name
				   where(B(I(position of c) < prefixsize))) =
			       prefix)
		      then
			-- strip prefix from effective name
			option.name <- S(every of c in option.name
			   where(B(I(position of c) >= prefixsize)));
		      else
			exit notprefix;
		      end if;
		  end if;
		insert option into options;
	      on (DuplicateKey)
		-- ignore - command line overrides environment
	      on exit (notprefix)
		-- discard irrelevant environment variables
	      end block;
	  end for;
      end block;
