<> <> <> DIRECTORY Arpa, ArpaNameSupport, Ascii USING [Digit], IO USING [PutFR], Rope USING [Cat, Equal, Fetch, InlineFetch, IsEmpty, Length, ROPE, Substr]; ArpaNameSupportImpl: CEDAR PROGRAM IMPORTS Ascii, IO, Rope EXPORTS ArpaNameSupport = BEGIN ROPE: TYPE = Rope.ROPE; AddressInList: PUBLIC PROC [addresses: LIST OF Arpa.Address, address: Arpa.Address] RETURNS [yes: BOOL] = { FOR list: LIST OF Arpa.Address _ addresses, list.rest UNTIL list = NIL DO IF list.first = address THEN RETURN [TRUE]; ENDLOOP; RETURN[FALSE]; }; CountAddresses: PUBLIC PROC [addresses: LIST OF Arpa.Address] RETURNS [count: INT_0] = { FOR list: LIST OF Arpa.Address _ addresses, list.rest UNTIL list = NIL DO count _ count +1; ENDLOOP; }; AppendUniqueAddress: PUBLIC PROC [address: Arpa.Address, addresses: LIST OF Arpa.Address _ NIL] RETURNS [new: LIST OF Arpa.Address] = { IF addresses = NIL THEN RETURN[LIST[address]]; new _ addresses; DO IF addresses.first = address THEN RETURN; IF addresses.rest = NIL THEN { addresses.rest _ LIST[address]; RETURN; }; addresses _ addresses.rest; ENDLOOP; }; AppendUniqueRope: PUBLIC PROC [ropes: LIST OF ROPE, name: ROPE] RETURNS [new: LIST OF ROPE] = { IF ropes = NIL THEN RETURN[LIST[name]]; new _ ropes; DO IF Rope.Equal[ropes.first, name, FALSE] THEN RETURN; IF ropes.rest = NIL THEN { ropes.rest _ LIST[name]; RETURN; }; ropes _ ropes.rest; ENDLOOP; }; AddressToRope: PUBLIC PROC [address: Arpa.Address, brackets: BOOL _ TRUE] RETURNS [rope: Rope.ROPE] = { rope _ IO.PutFR["%g.%g.%g.%g", [cardinal[address.a]], [cardinal[address.b]], [cardinal[address.c]], [cardinal[address.d]]]; IF brackets THEN rope _ Rope.Cat["[", rope, "]"]; }; IsAddressRope: PUBLIC PROC [rope: ROPE] RETURNS [BOOL] = { firstChar: CHAR; length: INT _ Rope.Length[rope]; IF Rope.IsEmpty[rope] THEN RETURN[FALSE]; firstChar _ Rope.Fetch[rope, 0]; IF length > 2 AND (firstChar = '[ OR Ascii.Digit[firstChar]) THEN RETURN[TRUE]; RETURN[FALSE];}; AddressRopeToQueryRope: PUBLIC PROC [addrRope: ROPE] RETURNS [queryRope: ROPE] = { addr: Arpa.Address _ RopeToAddress[addrRope]; IF ~IsAddressRope[addrRope] THEN RETURN[NIL]; addr _ RopeToAddress[addrRope]; IF addr = Arpa.nullAddress THEN RETURN[NIL]; queryRope _ AddressToQueryRope[addr]; }; AddressToQueryRope: PUBLIC PROC [addr: Arpa.Address] RETURNS [queryRope: ROPE] = { queryRope _ IO.PutFR["%G.%G.%G.%G.IN-ADDR.ARPA", [integer[addr.d]], [integer[addr.c]], [integer[addr.b]], [integer[addr.a]]]; }; StripBrackets: PUBLIC PROC [inRope: ROPE] RETURNS [outRope: ROPE] = { firstChar: CHAR; length: INT _ Rope.Length[inRope]; IF Rope.IsEmpty[inRope] THEN RETURN[NIL]; firstChar _ Rope.Fetch[inRope, 0]; IF length > 2 AND firstChar = '[ THEN outRope _ Rope.Substr[inRope, 1, length-2] ELSE outRope _ inRope; }; RopeToAddress: PUBLIC PROC [rope: ROPE] RETURNS [address: Arpa.Address_Arpa.nullAddress] = { len: CARDINAL; i: CARDINAL _ 0; AtEnd: PROC RETURNS [BOOL] ~ INLINE { RETURN [i >= len] }; GetChar: PROC RETURNS [c: CHAR] ~ INLINE { c _ Rope.InlineFetch[rope, i]; i _ i + 1 }; Skip: PROC [c: CHAR] ~ INLINE { IF (i < len) AND (Rope.InlineFetch[rope, i] = c) THEN i _ i + 1 }; AToI: PROC RETURNS [n: CARDINAL _ 0] ~ { DO c: CHAR; IF AtEnd[] THEN RETURN; IF NOT Ascii.Digit[c _ GetChar[]] THEN RETURN; n _ n * 10 + (c - '0); ENDLOOP; }; IF rope = NIL THEN RETURN[Arpa.nullAddress]; len _ Rope.Length[rope]; Skip['[]; IF AtEnd[] THEN RETURN[Arpa.nullAddress]; address.a _ AToI[]; Skip['.]; IF AtEnd[] THEN RETURN[Arpa.nullAddress]; address.b _ AToI[]; Skip['.]; IF AtEnd[] THEN RETURN[Arpa.nullAddress]; address.c _ AToI[]; Skip['.]; IF AtEnd[] THEN RETURN[Arpa.nullAddress]; address.d _ AToI[]; RETURN[address]; }; Tailed: PUBLIC PROC [body, tail: ROPE] RETURNS [match: BOOL] = { bodyLength: INT = Rope.Length[body]; tailLength: INT = Rope.Length[tail]; back: ROPE; IF bodyLength <= tailLength THEN RETURN[FALSE]; back _ Rope.Substr[body, bodyLength-tailLength, tailLength]; IF ~Rope.Equal[back, tail, FALSE] THEN RETURN[FALSE]; RETURN[TRUE]; }; StripTail: PUBLIC PROC [body, tail: ROPE] RETURNS [new: ROPE] = { bodyLength: INT = body.Length[]; tailLength: INT = tail.Length[]; RETURN[Rope.Substr[body, 0, bodyLength - tailLength]]}; END.