mirror of
https://github.com/vishapoberon/compiler.git
synced 2026-10-10 00:27:23 +00:00
182 lines
4.2 KiB
Modula-2
182 lines
4.2 KiB
Modula-2
(* oo2c 1.x command-line arguments represented as a read-only channel. *)
|
|
MODULE oocProgramArgs;
|
|
|
|
IMPORT
|
|
Host := oocProgramArgsHost, Channel0 := oocChannel,
|
|
CharClass := oocCharClass, Time := oocTime, Msg := oocMsg;
|
|
|
|
CONST
|
|
done* = Channel0.done;
|
|
outOfRange* = Channel0.outOfRange;
|
|
readAfterEnd* = Channel0.readAfterEnd;
|
|
channelClosed* = Channel0.channelClosed;
|
|
noWriteAccess* = Channel0.noWriteAccess;
|
|
noModTime* = Channel0.noModTime;
|
|
|
|
TYPE
|
|
Channel* = POINTER TO ChannelDesc;
|
|
ChannelDesc = RECORD
|
|
(Channel0.ChannelDesc)
|
|
END;
|
|
|
|
Reader = POINTER TO ReaderDesc;
|
|
ReaderDesc = RECORD
|
|
(Channel0.ReaderDesc)
|
|
argument, offset, position: LONGINT
|
|
END;
|
|
|
|
ErrorContext = POINTER TO ErrorContextDesc;
|
|
ErrorContextDesc* = RECORD
|
|
(Channel0.ErrorContextDesc)
|
|
END;
|
|
|
|
VAR
|
|
args-: Channel;
|
|
errorContext: ErrorContext;
|
|
|
|
PROCEDURE GetError(code: Msg.Code): Msg.Msg;
|
|
BEGIN
|
|
RETURN Msg.New(errorContext, code)
|
|
END GetError;
|
|
|
|
PROCEDURE (r: Reader) Pos* (): LONGINT;
|
|
BEGIN
|
|
RETURN r.position
|
|
END Pos;
|
|
|
|
PROCEDURE (r: Reader) Available* (): LONGINT;
|
|
VAR available: LONGINT;
|
|
BEGIN
|
|
IF ~r.base.open THEN RETURN -1 END;
|
|
available := r.base.Length()-r.position;
|
|
IF available > 0 THEN RETURN available ELSE RETURN 0 END
|
|
END Available;
|
|
|
|
PROCEDURE (r: Reader) SetPos* (newPos: LONGINT);
|
|
VAR argument, length, remaining: LONGINT;
|
|
BEGIN
|
|
IF r.res = done THEN
|
|
IF newPos < 0 THEN
|
|
r.res := GetError(outOfRange)
|
|
ELSIF ~r.base.open THEN
|
|
r.res := GetError(channelClosed)
|
|
ELSE
|
|
argument := 0;
|
|
remaining := newPos;
|
|
WHILE (argument < Host.Count()) & (remaining > Host.Length(argument)) DO
|
|
DEC(remaining, Host.Length(argument)+1);
|
|
INC(argument)
|
|
END;
|
|
IF argument = Host.Count() THEN
|
|
r.offset := 0
|
|
ELSE
|
|
length := Host.Length(argument);
|
|
IF remaining > length THEN remaining := length END;
|
|
r.offset := remaining
|
|
END;
|
|
r.argument := argument;
|
|
r.position := newPos
|
|
END
|
|
END
|
|
END SetPos;
|
|
|
|
PROCEDURE (r: Reader) ReadByte* (VAR x: Host.Byte);
|
|
VAR length: LONGINT;
|
|
BEGIN
|
|
r.bytesRead := 0;
|
|
IF r.res = done THEN
|
|
IF ~r.base.open THEN
|
|
r.res := GetError(channelClosed)
|
|
ELSIF r.argument >= Host.Count() THEN
|
|
r.res := GetError(readAfterEnd)
|
|
ELSE
|
|
length := Host.Length(r.argument);
|
|
IF r.offset = length THEN
|
|
x := CharClass.eol;
|
|
INC(r.argument);
|
|
r.offset := 0
|
|
ELSE
|
|
Host.Get(r.argument, r.offset, x);
|
|
IF Host.IsEol(x) THEN x := " " END;
|
|
INC(r.offset)
|
|
END;
|
|
INC(r.position);
|
|
r.bytesRead := 1
|
|
END
|
|
END
|
|
END ReadByte;
|
|
|
|
PROCEDURE (r: Reader) ReadBytes* (VAR x: ARRAY OF Host.Byte; start, n: LONGINT);
|
|
VAR count: LONGINT;
|
|
BEGIN
|
|
ASSERT((n >= 0) & (start >= 0) & (start+n <= LEN(x)));
|
|
count := 0;
|
|
WHILE (count < n) & (r.res = done) DO
|
|
r.ReadByte(x[start+count]);
|
|
IF r.res = done THEN INC(count) END
|
|
END;
|
|
r.bytesRead := count
|
|
END ReadBytes;
|
|
|
|
PROCEDURE (ch: Channel) Length* (): LONGINT;
|
|
VAR argument, length: LONGINT;
|
|
BEGIN
|
|
argument := 0;
|
|
length := 0;
|
|
WHILE argument < Host.Count() DO
|
|
INC(length, Host.Length(argument)+1);
|
|
INC(argument)
|
|
END;
|
|
RETURN length
|
|
END Length;
|
|
|
|
PROCEDURE (ch: Channel) ArgNumber* (): LONGINT;
|
|
BEGIN
|
|
IF Host.Count() > 0 THEN RETURN Host.Count()-1 ELSE RETURN 0 END
|
|
END ArgNumber;
|
|
|
|
PROCEDURE (ch: Channel) GetModTime* (VAR mtime: Time.TimeStamp);
|
|
BEGIN
|
|
ch.res := GetError(noModTime)
|
|
END GetModTime;
|
|
|
|
PROCEDURE (ch: Channel) NewReader* (): Channel0.Reader;
|
|
VAR r: Reader;
|
|
BEGIN
|
|
IF ch.open THEN
|
|
NEW(r);
|
|
r.base := ch;
|
|
r.res := done;
|
|
r.bytesRead := 0;
|
|
r.positionable := TRUE;
|
|
r.argument := 0;
|
|
r.offset := 0;
|
|
r.position := 0;
|
|
ch.res := done;
|
|
RETURN r
|
|
ELSE
|
|
ch.res := GetError(channelClosed);
|
|
RETURN NIL
|
|
END
|
|
END NewReader;
|
|
|
|
PROCEDURE (ch: Channel) Flush*;
|
|
BEGIN
|
|
IF ch.open THEN ch.res := done ELSE ch.res := GetError(channelClosed) END
|
|
END Flush;
|
|
|
|
PROCEDURE (ch: Channel) Close*;
|
|
BEGIN
|
|
ch.open := FALSE;
|
|
ch.res := done
|
|
END Close;
|
|
|
|
BEGIN
|
|
NEW(errorContext);
|
|
Msg.InitContext(errorContext, "OOC:Core:ProgramArgs");
|
|
NEW(args);
|
|
args.res := done;
|
|
args.readable := TRUE;
|
|
args.writable := FALSE;
|
|
args.open := TRUE
|
|
END oocProgramArgs.
|