(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* *) (* Last modified on Mon Jun 22 17:07:44 PDT 1992 by muller *) (* modified on Mon Jun 8 11:40:56 PDT 1992 by meehan *) UNSAFE MODULE RdUtils; IMPORT Char, Fmt, IOFailure, M3toC, Cerrno, Range, Rd, RTutils, TextF; IMPORT Thread, Uerror; PROCEDURE Find (rd : Rd.T; pattern : TEXT; ignoreCase: BOOLEAN := FALSE; start : CARDINAL := 0; length : CARDINAL := LAST (CARDINAL)): [-1 .. LAST (CARDINAL)] RAISES {Range.Error, Rd.Failure, Thread.Alerted} = BEGIN RETURN FindChars (rd, SUBARRAY (pattern^, 0, NUMBER (pattern^) - 1), (* TextF reveals that there's a null char at the end *) start, length, ignoreCase) END Find; PROCEDURE FindChars ( rd : Rd.T; READONLY pattern: ARRAY OF CHAR; start : CARDINAL := 0; length : CARDINAL := LAST (CARDINAL); ignoreCase: BOOLEAN := FALSE): [-1 .. LAST (CARDINAL)] RAISES {Range.Error, Rd.Failure, Thread.Alerted} = VAR i: CARDINAL; BEGIN WITH end = Range.End (start, length, NUMBER (pattern)) DO IF length = 0 THEN RETURN Rd.Index (rd) ELSE TRY LOOP IF FindChar (rd, pattern [start], ignoreCase) = -1 THEN RETURN -1 ELSE WITH restart = Rd.Index (rd) DO i := start + 1; LOOP IF i = end THEN RETURN restart - 1 ELSE WITH x = Rd.GetChar (rd), y = pattern [i] DO IF x = y OR ignoreCase AND Char.Upper [x] = Char.Upper [y] THEN INC (i) ELSE Rd.Seek (rd, restart); EXIT (* to outer loop *) END (* IF x = y ... *) END (* WITH x ... *) END (* IF i = end ... *) END (* inner LOOP *) END (* WITH restart ... *) END (* IF FindChar ... *) END (* outer LOOP *) EXCEPT | Rd.EndOfFile => RETURN -1 END END END END FindChars; PROCEDURE FindChar (rd: Rd.T; pattern: CHAR; ignoreCase: BOOLEAN := FALSE): [-1 .. LAST (CARDINAL)] RAISES {Rd.Failure, Thread.Alerted} = BEGIN WITH uc = Char.Upper [pattern] DO TRY LOOP WITH c = Rd.GetChar (rd) DO IF c = pattern OR ignoreCase AND Char.Upper [c] = uc THEN RETURN Rd.Index (rd) - 1 END END END EXCEPT | Rd.EndOfFile => RETURN -1 END END END FindChar; PROCEDURE FailureText (f: REFANY): TEXT = BEGIN WITH errno = Cerrno.errno DO TYPECASE f OF | NULL => RETURN "NIL" | IOFailure.T (iof) => RETURN Fmt.F ("%s (errno = %s: %s)", IOFailureKind_names [iof^], Fmt.Int (errno), M3toC.StoT (Uerror.GetFrom_sys_errlist (errno))) | TEXT (t) => RETURN t | REFANY => RETURN "unknown error of type " & RTutils.TypeName (f) END END END FailureText; BEGIN END RdUtils.