const type: striFile is sub null_file struct
var string: content is "";
var integer: position is 1;
end struct;
type_implements_interface(striFile, file);
const func file: openStriFile (in string: content) is func
result
var file: newFile is STD_NULL;
local
var striFile: new_striFile is striFile.value;
begin
new_striFile.content := content;
newFile := toInterface(new_striFile);
end func;
const func file: openStriFile is func
result
var file: newFile is STD_NULL;
local
var striFile: new_striFile is striFile.value;
begin
newFile := toInterface(new_striFile);
end func;
const proc: write (inout striFile: outStriFile, in string: stri) is func
begin
if outStriFile.position = succ(length(outStriFile.content)) then
outStriFile.content &:= stri;
elsif outStriFile.position <= length(outStriFile.content) then
if pred(outStriFile.position) <= length(outStriFile.content) - length(stri) then
outStriFile.content @:= [outStriFile.position] stri;
else
outStriFile.content := outStriFile.content[.. pred(outStriFile.position)];
outStriFile.content &:= stri;
end if;
elsif outStriFile.position > length(outStriFile.content) then
outStriFile.content &:=
"\0;" mult pred(outStriFile.position - length(outStriFile.content)) &
stri;
end if;
outStriFile.position +:= length(stri);
end func;
const proc: moveLeft (inout striFile: outStriFile, in string: stri) is func
begin
if outStriFile.position > length(stri) then
outStriFile.position -:= length(stri);
else
outStriFile.position := 1;
end if;
end func;
const func char: getc (inout striFile: inStriFile) is func
result
var char: charRead is ' ';
begin
if inStriFile.position <= length(inStriFile.content) then
charRead := inStriFile.content[inStriFile.position];
incr(inStriFile.position);
else
charRead := EOF;
end if;
end func;
const func string: gets (inout striFile: inStriFile, in integer: maxLength) is func
result
var string: striRead is "";
begin
if maxLength <= 0 then
if maxLength <> 0 then
raise RANGE_ERROR;
end if;
elsif maxLength <= succ(length(inStriFile.content) - inStriFile.position) then
striRead := inStriFile.content[inStriFile.position fixLen maxLength];
inStriFile.position +:= maxLength;
else
striRead := inStriFile.content[inStriFile.position ..];
inStriFile.position := succ(length(inStriFile.content));
end if;
end func;
const func string: getTerminatedString (inout striFile: inStriFile,
in char: terminator) is func
result
var string: stri is "";
local
var integer: terminatorPos is 0;
begin
terminatorPos := pos(inStriFile.content, terminator, inStriFile.position);
if terminatorPos <> 0 then
stri := inStriFile.content[inStriFile.position .. pred(terminatorPos)];
inStriFile.position := succ(terminatorPos);
inStriFile.bufferChar := terminator;
else
stri := inStriFile.content[inStriFile.position ..];
inStriFile.position := succ(length(inStriFile.content));
inStriFile.bufferChar := EOF;
end if;
end func;
const func string: getwd (inout striFile: inStriFile) is func
result
var string: stri is "";
local
const set of char: space_or_tab is {' ', '\t'};
const set of char: space_tab_or_nl is {' ', '\t', '\n'};
var integer: wordStartPos is 0;
var integer: wordEndPos is 0;
begin
wordStartPos := inStriFile.position;
while wordStartPos <= length(inStriFile.content) and
inStriFile.content[wordStartPos] in space_or_tab do
incr(wordStartPos);
end while;
if wordStartPos > length(inStriFile.content) then
inStriFile.position := wordStartPos;
inStriFile.bufferChar := EOF;
else
wordEndPos := succ(wordStartPos);
while wordEndPos <= length(inStriFile.content) and
inStriFile.content[wordEndPos] not in space_tab_or_nl do
incr(wordEndPos);
end while;
if wordEndPos <= length(inStriFile.content) then
if inStriFile.content[wordEndPos] = '\n' and
inStriFile.content[pred(wordEndPos)] = '\r' then
stri := inStriFile.content[wordStartPos .. wordEndPos - 2];
else
stri := inStriFile.content[wordStartPos .. pred(wordEndPos)];
end if;
inStriFile.position := succ(wordEndPos);
inStriFile.bufferChar := inStriFile.content[wordEndPos];
else
stri := inStriFile.content[wordStartPos ..];
inStriFile.position := succ(length(inStriFile.content));
inStriFile.bufferChar := EOF;
end if;
end if;
end func;
const func string: getln (inout striFile: inStriFile) is func
result
var string: stri is "";
local
var integer: newlinePos is 0;
begin
newlinePos := pos(inStriFile.content, '\n', inStriFile.position);
if newlinePos <> 0 then
if newlinePos >= 2 and
inStriFile.content[pred(newlinePos)] = '\r' then
stri := inStriFile.content[inStriFile.position .. newlinePos - 2];
else
stri := inStriFile.content[inStriFile.position .. pred(newlinePos)];
end if;
inStriFile.position := succ(newlinePos);
inStriFile.bufferChar := '\n';
else
stri := inStriFile.content[inStriFile.position ..];
inStriFile.position := succ(length(inStriFile.content));
inStriFile.bufferChar := EOF;
end if;
end func;
const func boolean: eof (in striFile: inStriFile) is
return inStriFile.position > length(inStriFile.content);
const func boolean: hasNext (in striFile: inStriFile) is
return inStriFile.position <= length(inStriFile.content);
const func integer: length (in striFile: aStriFile) is
return length(aStriFile.content);
const proc: truncate (inout striFile: aStriFile, in integer: length) is func
begin
if length < 0 then
raise RANGE_ERROR;
elsif length(aStriFile.content) > length then
aStriFile.content := aStriFile.content[.. length];
elsif length(aStriFile.content) < length then
aStriFile.content := aStriFile.content &
"\0;" mult (length - length(aStriFile.content));
end if;
end func;
const boolean: seekable (in striFile: aFile) is TRUE;
const proc: seek (inout striFile: aStriFile, in integer: position) is func
begin
if position <= 0 then
raise RANGE_ERROR;
else
aStriFile.position := position;
end if;
end func;
const func integer: tell (in striFile: aStriFile) is
return aStriFile.position;