📄 ujaddstate.pas
字号:
raise Exception.CreateFmtHelp('Constant "%s" has a type, constants for conditional compiling have to be true, untyped constants!',
[Ident.Name], 0);
Ident := Ident.Clone; //create a copy
try
Ident.InFile := nil; //don't keep a reference
Ident.EffectiveFile := nil; //to the parser
Ident.EffectiveForwardFile := nil;
List.AddIdent(Ident); //add the constant
except
Ident.Free;
raise;
end;
end;
finally
Data.Free; //free the file and parser
end;
end; //if Text <> ''
end;
var S :String; //general string to read from ini file
c :Char; //counter through the compiler options
PreOpts :TCompilerOptions; //compiler options before parsing CFG
PostOpts :TPostOptions; //compiler options after parsing CFG
begin
//read list of files to parse and to exclude and to parse only if used
ReadFileListFromIni(Ini, 'ToParse', FFilesToParse, True);
ReadFileListFromIni(Ini, 'NotToParse', FFilesToExclude, True);
ReadFileListFromIni(Ini, 'Libs', FFilesOfLibrary, True);
//read the additional search paths
ReadFileListFromIni(Ini, 'SearchPaths', FDefines.PostSearchPath, False);
//read compiler options to set
S := Ini.ReadString('PreDefines', 'PreOptions', '');
PreOpts := FDefines.PreOptions;
c := Low(PreOpts);
while (c <= High(PreOpts)) and (S <> '') do //and parse them
begin
if S[1] in ['0', '1'] then
PreOpts[c] := S[1] = '1'; //set each single one
Delete(S, 1, 1);
inc(c);
end;
FDefines.PreOptions := PreOpts; //set the options
//read defined compiler symbols
FDefines.PreDefines.CommaText := Ini.ReadString('PreDefines',
'PreDefines', '');
//read if .cfg/.conf files should be parsed
FDefines.AutoParse := Ini.ReadBool('PreDefines', 'AutoParse', True);
//read compiler options to set after the .cfg/.conf files have been parsed
S := Ini.ReadString('PreDefines', 'PostOptions', '');
PostOpts := FDefines.PostOptions;
c := low(PostOpts);
while (c <= high(PostOpts)) and (S <> '') do //parse them
begin
if S[1] in ['0', '1', '2'] then
PostOpts[c] := TPostOption(ord(S[1]) - ord('0')); //set each single one
Delete(S, 1, 1);
inc(c);
end;
FDefines.PostOptions := PostOpts; //set the options
//read compiler symbols to (un)define after parsing the .cfg/.conf files
FDefines.PostDefines.CommaText := Ini.ReadString('PreDefines',
'PostDefines', '');
FDefines.PostUnDefines.CommaText := Ini.ReadString('PreDefines',
'PostUnDefines', '');
FDefines.PostUnitAliasesAsString := Ini.ReadString('PreDefines',
'PostUnitAliases', '');
//read the declaration of all constants for conditional compiling
ReadConstants(FDefines.ConditionalCompilingConstants);
end;
{Saves the DelphiDoc project to an ini file.
~param Ini the ini file to save the DelphiDoc project to }
procedure TJADDState.SaveProject(Ini: TCustomIniFile);
{Writes the list of constants for conditional compiling.
~param List the list of constants to write }
procedure WriteConstants(List: TIdentifierList);
var ConstFormat :TTextFormat; //format for declaration of constants
i :Integer; //counter through the list
begin
Ini.EraseSection('CondCompilingConstants'); //clear the section and
//write the number of entries
Ini.WriteInteger('CondCompilingConstants', 'Count', List.Count);
if not List.IsEmpty then //some constants defined?
begin
ConstFormat := TTextFormat.Create; //create object to get declaration
try
for i := List.Count - 1 downto 0 do //write each constant
Ini.WriteString('CondCompilingConstants', 'Constant' + IntToStr(i),
List[i].GetDescriptionString(ConstFormat, nil));
finally
ConstFormat.Free; //free declaration
end;
end;
end;
var S :String; //a general string to write the options
c :Char; //counter through the compiler options
begin
//write the lists of files
WriteFileListToIni(Ini, 'ToParse', FFilesToParse, True);
WriteFileListToIni(Ini, 'NotToParse', FFilesToExclude, True);
WriteFileListToIni(Ini, 'Libs', FFilesOfLibrary, True);
//write the additional search paths
WriteFileListToIni(Ini, 'SearchPaths', FDefines.PostSearchPath, False);
//write compiler options to set
SetLength(S, ord(high(FDefines.PreOptions)) -
ord(low(FDefines.PreOptions)) + 1);
for c := low(FDefines.PreOptions) to high(FDefines.PreOptions) do
S[ord(c) - ord(low(FDefines.PreOptions)) + 1] :=
char(ord(FDefines.PreOptions[c]) + ord('0'));
Ini.WriteString('PreDefines', 'PreOptions', S);
//write defined compiler symbols
Ini.WriteString('PreDefines', 'PreDefines', FDefines.PreDefines.CommaText);
//write if .cfg/.conf files should be parsed
Ini.WriteBool('PreDefines', 'AutoParse', FDefines.AutoParse);
//write compiler options to set after the .cfg/.conf files have been parsed
SetLength(S, ord(high(FDefines.PostOptions)) -
ord(low(FDefines.PostOptions)) + 1);
for c := low(FDefines.PostOptions) to high(FDefines.PostOptions) do
S[ord(c) - ord(low(FDefines.PostOptions)) + 1] :=
char(ord(FDefines.PostOptions[c]) + ord('0'));
Ini.WriteString('PreDefines', 'PostOptions', S);
//write compiler symbols to (un)define after parsing the .cfg/.conf files
Ini.WriteString('PreDefines', 'PostDefines',
FDefines.PostDefines.CommaText);
Ini.WriteString('PreDefines', 'PostUnDefines',
FDefines.PostUnDefines.CommaText);
Ini.WriteString('PreDefines', 'PostUnitAliases',
FDefines.PostUnitAliasesAsString);
//write the declaration of all constants for conditional compiling
WriteConstants(FDefines.ConditionalCompilingConstants);
end;
{Loads a project to generate help about a GUI from the ini file.
~param Ini the ini of a DelphiDoc project to load }
procedure TJADDState.LoadGUIProject(Ini: TCustomIniFile);
{Reads an child-entries of the specified entry from the ini file.
~param Root the entry whose children should be read
~param Prefix the prefix for the entries of the children
~param Prefixes list of currently loading prefixes, to detect "recursion" }
procedure ReadEntry(Root: TGUIMainIndexEntry; const Prefix: String;
Prefixes: TStrings);
var i :Integer; //counter through the child entries
Value :String;
Separat :Integer; //index of separator in child value
Part :String; //a single value of a child entry
LinkKind :TGUIMainIndexLinkKind; //kind of the links of the entries
Link :String; //the target of the link
Entry :TGUIMainIndexEntry; //each new child entry
begin
//read number of child entries, and read each one
for i := 1 to Ini.ReadInteger(MainIndexIniSection, Prefix + 'Count', -1) do
begin
//read the values of the entry
Value := Ini.ReadString(MainIndexIniSection, Prefix + IntToStr(i), '');
if Value <> '' then //entry found?
begin
Separat := pos(',', Value); //extract first value, the link
Link := Copy(Value, 1, Separat - 1);
Delete(Value, 1, Separat);
if Link = '' then //empty link
LinkKind := gmilkNone //ok, just some text, no link
else
begin
Separat := pos(' ', Link); //extract kind of link
Part := Copy(Link, 1, Separat - 1);
LinkKind := High(LinkKind); //search specified kind
while (LinkKind > Low(LinkKind)) and
(CompareText(GUIHelpIniLinkKinds[LinkKind], Part) <> 0) do
Dec(LinkKind);
if LinkKind <> gmilkNone then //valid kind found?
Delete(Link, 1, Separat); //remove kind from the link
end; //Link = ''
Separat := pos(',', Value); //extract prefix of children
Part := Copy(Value, 1, Separat - 1);
Delete(Value, 1, Separat);
Entry := TGUIMainIndexEntry.Create; //create entry for the child
try
Entry.LinkKind := LinkKind; //set the link
Entry.LinkTarget := Link;
Entry.Text := Value; //and the text
Root.AppendEntry(Entry); //add the new child entry
except
Entry.Free;
raise;
end;
if Part <> '' then //has child entries?
begin
if Prefixes.IndexOf(Part) <> -1 then
raise Exception.CreateFmt('Invalid alternative content for main index, recursion in prefixes for sub-entries detected with "%s"!',
[Part]);
Prefixes.Append(Part); //add the prefix to the list
ReadEntry(Entry, Part, Prefixes); //read sub-entries, too
Assert(Prefixes[Prefixes.Count - 1] = Part);
Prefixes.Delete(Prefixes.Count - 1); //remove prefix again
end;
end; //if Value <> ''
end; //for i := 1 to Ini.ReadInteger('Count')
end;
var i :Integer; //counter through old content of main index
Prefixes :TStringList; //list of prefixes while reading entries
begin
//read the list of files
ReadFileListFromIni(Ini, 'GUILogFiles', FGUIHelpLogFiles, True);
//free old content of main index
for i := FGenerate.GUIMainIndexRoot.SubTopicCount - 1 downto 0 do
FGenerate.GUIMainIndexRoot.SubTopics[i].Free;
Prefixes := TStringList.Create; //create list for prefixes
try
ReadEntry(FGenerate.GUIMainIndexRoot, '', Prefixes); //read the new content
finally
Prefixes.Free;
end;
end;
{Saves the project to generate help about a GUI to an ini file.
~param Ini the ini file to save the DelphiDoc project to }
procedure TJADDState.SaveGUIProject(Ini: TCustomIniFile);
{Writes all children of the node to the ini file.
~param Root the entry whose children should be written
~param Prefix the prefix for the values of the children }
procedure WriteEntry(Root: TGUIMainIndexEntry; const Prefix: String);
{Replaces each comma with "%44" in the text.
~param Text the text to replace all commas in
~result the text without commads }
function ReplaceComma(const Text: String): String;
var i :Integer; //index of commas in the text
begin
Result := Text;
i := pos(',', Result); //search a comma
while i <> 0 do //a(nother) comma in it?
begin
Result[i] := '%'; //replace it with "%44"
Insert('44', Result, i + 1);
i := pos(',', Result); //search again for a comma
end;
end;
var i :Integer; //counter through all child entries
Entry :TGUIMainIndexEntry; //each child entry
Value :String; //value of the child entry
begin
//write number of child entries
Ini.WriteInteger(MainIndexIniSection, Prefix + 'Count', Root.SubTopicCount);
for i := 0 to Root.SubTopicCount - 1 do //for each child entry
begin
Entry := Root.SubTopics[i]; //get it
Value := GUIHelpIniLinkKinds[Entry.LinkKind]; //add its link
if Entry.LinkKind <> gmilkNone then
Value := Value + ' ' + ReplaceComma(Entry.LinkTarget);
Value := Value + ','; //a separator
if Entry.SubTopicCount <> 0 then //has itself child entries?
Value := Value + Prefix + IntToStr(i + 1) + '.'; //write their prefix
Value := Value + ',' + Entry.Text; //append its text
//write the value of the entry
Ini.WriteString(MainIndexIniSection, Prefix + IntToStr(i + 1), Value);
if Entry.SubTopicCount <> 0 then //has itself child entries?
//write them with their prefix
WriteEntry(Entry, Prefix + IntToStr(i + 1) + '.');
end;
end;
begin
//write the list of files
WriteFileListToIni(Ini, 'GUILogFiles', FGUIHelpLogFiles, True);
Ini.EraseSection(MainIndexIniSection); //clear the section of the main index
WriteEntry(FGenerate.GUIMainIndexRoot, ''); //and write the current content
end;
{Loads already parsed data from the file.
~param FileName the name of the file to load parsed data from
~result the kind of errors/warnings occured while reading the parse data }
function TJADDState.ReadDataFromFile(FileName: String): TParsedDataReadErrors;
begin
ClearFileList; //free current list for the files
FFileList := USaveParsed.ReadDataFromFile(FileName, Result); //read the data
FCompletelyParsed := True; //data must have been complete
FileListChanged; //notify
end;
{Writes the parsed data to a file.
~param FileName the name of the file to save the parsed data to }
procedure TJADDState.WriteDataToFile(FileName: String);
begin
Assert(FCompletelyParsed);
Assert(assigned(FFileList));
USaveParsed.WriteDataToFile(FileName, FFileList); //write data to the file
end;
{Marks the current data to be kept, so it is not freed when parsing again. }
procedure TJADDState.KeepCurrentData;
begin
assert(assigned(FFileList) and FCompletelyParsed);
assert(FKeptParsedData.IndexOf(FFileList) = -1);
FKeptParsedData.Add(FFileList); //keep the parsed data
end;
{Gets the index of the current data in the list of kept data.
~result the index of the current data in the list of kept data,
or -1 when not kept }
function TJADDState.CurrentDataKeptIndex: Integer;
begin
Result := FKeptParsedData.IndexOf(FFileList);
end;
{Selects parsed data from the list of kept parsed data.
~param Index the index in the list of kept data }
procedure TJADDState.SelectParsedData(Index: Integer);
begin
assert((Index >= 0) and (Index < FKeptParsedData.Count));
//parsed data available and not kept?
if assigned(FFileList) and (FKeptParsedData.IndexOf(FFileList) = -1) then
try
FFileList.Free; //free the parsed data
finally
FFileList := nil;
end;
FFileList := FKeptParsedData[Index]; //get the parsed data
FCompletelyParsed := True; //it is complete
FileListChanged; //notify
end;
{Marks the parsed data in the list to not longer keep it.
~param Index the index in the list of kept data }
procedure TJADDState.DoNotKeepParsedData(Index: Integer);
begin
assert((Index >= 0) and (Index < FKeptParsedData.Count));
if FKeptParsedData[Index] <> FFileList then //not the current data?
TFileList(FKeptParsedData[Index]).Free; //free the data
FKeptParsedData.Delete(Index); //unmark the data
end;
{Returns parsed data from the list of kept parsed data.
~param Index the index in the list of kept data
~result the kept parsed data }
function TJADDState.GetKeptData(Index: Integer): TFileList;
begin
assert((Index >= 0) and (Index < FKeptParsedData.Count));
Result := FKeptParsedData[Index];
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -