MODULE DswOpts; IMPORT Kernel; TYPE String* = POINTER TO ARRAY OF CHAR; VAR optMode: BOOLEAN; args: POINTER TO ARRAY OF String; argn-, argi-: INTEGER; str-: String; PROCEDURE IsOpt (ch: CHAR): BOOLEAN; BEGIN RETURN (CAP(ch) >= "A") & (CAP(ch) <= "Z") OR (ch >= "0") & (ch <= "9") END IsOpt; PROCEDURE Reset*; BEGIN argn := 1; argi := 0; str := NIL; optMode := FALSE; END Reset; PROCEDURE GetStr; VAR ch: CHAR; i, beg, len: INTEGER; BEGIN str := NIL; IF argn < LEN(args) THEN beg := argi; REPEAT ch := args[argn, argi]; INC(argi) UNTIL ch = 0X; len := argi - beg; NEW(str, len + 1); FOR i := 0 TO len - 1 DO str[i] := args[argn, beg + i] (* zero not copied *) END; INC(argn); argi := 0; optMode := FALSE END END GetStr; PROCEDURE GetOpt* (IN optstring: ARRAY OF CHAR): CHAR; VAR opt, ch: CHAR; i: INTEGER; BEGIN str := NIL; IF argn >= LEN(args) THEN opt := 0X; optMode := FALSE (* eof *) ELSIF optMode & IsOpt(args[argn, argi]) OR (args[argn, argi] = "-") & IsOpt(args[argn, argi + 1]) THEN IF ~optMode THEN optMode := TRUE; INC(argi) END; opt := args[argn, argi]; INC(argi); i := 0; IF args[argn, argi] = 0X THEN INC(argn); argi := 0; optMode := FALSE END; REPEAT ch := optstring[i]; INC(i); IF ch = ":" THEN ch := optstring[i]; INC(i) END UNTIL (ch = opt) OR (ch = 0X); IF ch = opt THEN IF optstring[i] = ":" THEN GetStr; IF str = NIL THEN NEW(str, 2); str[0] := opt; opt := ":" (* missing param *) END END ELSE NEW(str, 2); str[0] := opt; opt := "?" (* unknown option *) END ELSE GetStr; opt := "$" (* string *) END; RETURN opt END GetOpt; PROCEDURE Init; VAR i: INTEGER; BEGIN NEW(args, Kernel.argc); FOR i := 0 TO Kernel.argc - 1 DO NEW(args[i], LEN(Kernel.argv[i]$) + 1); args[i]^ := Kernel.argv[i]$ END; Reset END Init; BEGIN Init END DswOpts.