perm filename SPLIT.SAI[LIB,AIL] blob sn#408154 filedate 1979-01-09 generic text, type T, neo UTF8
ENTRY SPLIT!SWITCHES;
BEGIN "SPLIT"
DEFINE LIBRARY!ENTRY = TRUE;
REQUIRE "STD.HDR" SOURCE!FILE;
INTERNAL PROCEDURE split!switches(STRING switch!text;
	REFERENCE STRING ARRAY switch!names, switch!values);
BEGIN
! This procedure takes a string of switches (usually from SWITCH.INI via
DEFAULT!SWITCHES, and matches the switch names with the strings in switch!names
and inserts the value associated with the switch in switch!values in the
corresponding location.  If no switch value is included, "/" is stored in
switch!values, and if the switch name is prefixed by "NO", ":" is stored there;

INTEGER break!tab1, break!tab2, low!bound, up!bound, brchar, match!index;
STRING this!switch;
BOOLEAN PROCEDURE match!it(STRING this!switch;
	REFERENCE INTEGER match!index);
! this procedure tries to find a match between this!switch and some element
of switch!names. if successful, it returns TRUE with the index in match!index;
! switch!names must be all uppercase;
   BEGIN "match!it"
   BOOLEAN already!found;
   INTEGER i;
   already!found ← FALSE;
   FOR i ← low!bound STEP 1 UNTIL up!bound DO
      BEGIN "each element"
      ! the switch is deemed to match the array element if the length of
	 the switch is LEQ that of the array element and the switch matches
	 the initial segment of the array element;
      IF LENGTH(this!switch) LEQ LENGTH(switch!names[i]) AND
	    EQU(this!switch,switch!names[i][1 TO LENGTH(this!switch)]) THEN
	 IF already!found THEN
	    USERERR(0, 1, "split!switches ambiguous switch")
	 ELSE
	    BEGIN
	    already!found ← TRUE;
	    match!index ← i
	    END
      END "each element";
   RETURN(already!found)
   END "match!it";

!  first make sure the input is of the right form and get the array bounds;
IF ARRINFO(switch!names, -1) NEQ -1 THEN  ! must be 1-dimensional string array;
   BEGIN
   USERERR(0, 1, "split!switches parameter error 1");
   RETURN
   END;
IF ARRINFO(switch!values, -1) NEQ -1 THEN
   BEGIN
   USERERR(0, 1, "split!switches parameter error 2");
   RETURN
   END;
low!bound ← ARRINFO(switch!names, 1);
IF low!bound < ARRINFO(switch!values, 1) THEN  ! if for some reason
	switch!values is bigger than switch!names, that's o.k.,
	but not vice versa;
   BEGIN
   USERERR(0, 1, "split!switches parameter error 3");
   RETURN
   END;
up!bound ← ARRINFO(switch!names, 2);
IF up!bound > ARRINFO(switch!values, 2) THEN
   BEGIN
   USERERR(0, 1, "split!switches parameter error 4");
   RETURN
   END;
brchar ← LOP(switch!text);  ! default!switches leaves the initial /;
IF brchar NEQ "/" THEN
   BEGIN
   USERERR(0, 1, "split!switches parameter error 5");
   RETURN
   END;
break!tab1 ← GETBREAK;
break!tab2 ← GETBREAK;
SETBREAK(break!tab1, ":/", " ", "IS");  ! this picks up switch names
	(ignoring spaces);
SETBREAK(break!tab2, "/", NULL, "IS");  ! allow spaces in switch values;
WHILE switch!text NEQ NULL DO
   BEGIN "main loop"
   this!switch ← UPPERCASE(SCAN(switch!text, break!tab1, brchar));
   IF match!it(this!switch, match!index) THEN  
      switch!values[match!index] ←  ! insert value if there is one;
		 IF brchar = ":" THEN
		    TRIM(SCAN(switch!text, break!tab2, brchar))
		 ELSE "/"
   ELSE  ! maybe it's a case of NOswitch;
      IF LOP(this!switch) = "N" AND LOP(this!switch) = "O" AND
	    match!it(this!switch, match!index) THEN
	 switch!values[match!index] ← ":"
      ELSE USERERR(0, 1, "unidentifiable switch split!switches") 
   END "main loop"
END;
END "SPLIT"