MODULE Permanence;
IMPORT AGRS,Names,Library,Parser,Texts,Directories,Grammars;
CONST
PathDelimiter= '\';
MaxPathLength= 200;
TYPE
Term= AGRS.Term;
FilePrimitive= POINTER TO FilePrimitiveDesc;
FilePrimitiveDesc= RECORD(AGRS.SubTermDesc)
END;
FolderPrimitive= POINTER TO RECORD(FilePrimitiveDesc)
END;
VAR
folderRoot, directoryName, extensionName: AGRS.Name;
environmentName*: AGRS.Name;
directory: AGRS.Class;
dirTerm, currentFolder: AGRS.Term;
i,length: INTEGER;
(*
PROCEDURE Position(t: AGRS.Var; VAR file: Files.File; VAR startPos,endPos: LONGINT);
PROCEDURE Replace(t: AGRS.Var; file: File.File; startPos,endPos: LONGINT; VAR replacement: ARRAY OF CHAR);
PROCEDURE WriteText*(t: AGRS.Var; VAR definition: ARRAY OF CHAR);
PROCEDURE ReadBuffer*(t: AGRS.Var; VAR definition: ARRAY OF CHAR; startPos: LONGINT);
PROCEDURE ReadText*(t: AGRS.Var): CharPtr;
PROCEDURE WriteTerm*(t: AGRS.Var; definition: AGRS.Term);
PROCEDURE WriteDefinition*(t: AGRS.Var);
PROCEDURE Definition*(t: AGRS.Var): AGRS.Term;
PROCEDURE WriteHandler;
VAR
path: AGRS.SubTerm;
BEGIN
path:= AGRS.EnvironmentPath(directoryName);
WriteDefinition(path);
RETURN Library.doneName
END WriteHandler;
*)
PROCEDURE CorrectExtension(VAR filename: ARRAY OF CHAR): BOOLEAN;
VAR
extension: AGRS.Term;
suffix: Names.CharPtr;
pos1,pos2: INTEGER;
BEGIN
extension:= extensionName.Value();
WITH extension: Library.String DO
suffix:= extension.value;
pos1:= 0;
pos2:= 0;
WHILE filename[pos1]#0X DO
INC(pos1);
END;
WHILE suffix[pos2]#0X DO
INC(pos2);
END;
ASSERT(pos2>3);
WHILE (filename[pos1]=suffix[pos2]) & (pos1>0) & (pos2>0) DO
DEC(pos1);
DEC(pos2);
END;
IF (pos2=0) & (filename[pos1]=suffix[pos2]) THEN
filename[pos1]:= 0X;
RETURN TRUE
END;
END;
RETURN FALSE
END CorrectExtension;
PROCEDURE GetPath(pathTerm: Term; VAR pathString: ARRAY OF CHAR);
VAR
i,length: INTEGER;
dir: Names.CharPtr;
PROCEDURE WritePath(t: Term);
VAR
t2: Term;
BEGIN
t2:= t;
WITH t2: FilePrimitive DO
WritePath(t2.indirection);
WritePath(t2.query);
ELSE
dir:= Names.NameSpelling(t(AGRS.Name));
i:= 0;
WHILE dir[i]#0X DO
pathString[length]:= dir[i];
INC(length);
INC(i);
END;
pathString[length]:= PathDelimiter;
INC(length);
END;
END WritePath;
BEGIN
length:= 0;
WritePath(pathTerm);
pathString[length-1]:= 0X;
END GetPath;
PROCEDURE InitFile(dir: Directories.Directory; filename: ARRAY OF CHAR;
isDir: BOOLEAN; VAR cont: BOOLEAN);
VAR
def: AGRS.Name;
newTerm1: FolderPrimitive;
newTerm: FilePrimitive;
BEGIN
cont:= TRUE;
IF isDir THEN
IF filename[0]='.' THEN
RETURN
END;
NEW(newTerm1);
newTerm:= newTerm1;
ELSE
IF ~CorrectExtension(filename) THEN
RETURN
END;
NEW(newTerm);
END;
def:= Names.FindPublicNameNoCase(filename);
IF def=NIL THEN
Names.AddArgument(def,filename);
END;
newTerm.Init(currentFolder);
newTerm.InitQuery(def);
directory.AddProperty(def,newTerm);
END InitFile;
PROCEDURE InitFiles(t: AGRS.Term): AGRS.Term;
VAR
path: ARRAY MaxPathLength OF CHAR;
BEGIN
currentFolder:= t;
NEW(directory);
directory.Init(folderRoot);
directory.AddProperty(directoryName,t);
GetPath(t,path);
Directories.Enumerate(Directories.This(path),InitFile);
RETURN directory
END InitFiles;
PROCEDURE RefreshFolder(dir,value: AGRS.Term);
BEGIN
IF dir IS FolderPrimitive THEN
dir:= dir(FolderPrimitive).query;
END;
dir.indirection(AGRS.Class).
AddProperty(AGRS.lastResult(AGRS.Name),value);
END RefreshFolder;
PROCEDURE (t: FolderPrimitive) Reduce*;
VAR
newDir: Term;
BEGIN
newDir:= InitFiles(t);
RefreshFolder(t.indirection,newDir);
t.query(AGRS.Name).Assign(newDir);
newDir.Reduce;
t.query(AGRS.Name).Restore;
END Reduce;
PROCEDURE (t: FilePrimitive) Reduce*;
VAR
f: Texts.Text;
i,j: INTEGER;
strPtr: Names.CharPtr;
filename: ARRAY MaxPathLength OF CHAR;
result: AGRS.Term;
BEGIN
GetPath(t,filename);
j:= 0;
WHILE filename[j]#0X DO
INC(j);
END;
(*
strPtr:= Names.NameSpelling(AGRS.lastResult(AGRS.Name));
i:= 0;
WHILE strPtr[i]#0X DO
filename[j]:= strPtr[i];
INC(i);
INC(j);
END;
*)
result:= extensionName.Value();
WITH result: Library.String DO
strPtr:= result.value;
i:= 0;
WHILE strPtr[i]#0X DO
filename[j]:= strPtr[i];
INC(i);
INC(j);
END;
END;
filename[j]:= 0X;
NEW(f);
Texts.Open(f,filename);
Grammars.sentenceName.Assign(Library.SubText(f,0,f.len));
result:= Grammars.parseName.Value();
Grammars.sentenceName.Restore();
RefreshFolder(t.indirection,result);
result.Reduce;
END Reduce;
BEGIN
Names.AddArgument(folderRoot, 'FolderClass');
Names.AddArgument(directoryName, 'Directory');
Names.AddArgument(extensionName, 'FileExtension');
Names.AddArgument(environmentName, 'Env');
extensionName.Init(Library.NewString(Names.NewStringCopy('.ATG')));
environmentName.Init(InitFiles(environmentName));
END Permanence.