📄 umakedoc.pas
字号:
12: begin
Desc.Name := 'FilterIdentifiersByName';
Desc.Category := 'Generation.Filter';
Desc.Description := 'Comma-separared list of names of identifiers to be excluded from the documentation, syntax per entry: "[File.][RecordType.]Identifier"';
Desc.DataType := otString;
Desc.DefaultValue.StrData := '';
end;
else
Assert(Index >= GetOptionCount); //invalid index!
raise EInvalidOption.Create('Invalid index for option supplied!');
end;
end;
{Gets the value of an option. Call ~[link GetOptionDescription] to get the type
and the meaning of the option.
~param Index index of the option to get the value of
~result the value of the option
~see GetOptionCount
~see GetOptionDescription
~see SetOption }
function TMakeDoc.GetOption(Index: Cardinal): TOptionValue;
{Returns the filter by name for identifiers as a linear, comma-separated
string.
~result the filter by name for identifiers }
function GetIdentifierNameFilter: String;
var i :Integer; //counter through the list of names
Entry :String; //each name of an identifier
List :TStringList; //sub-list with paths of identifiers
j :Integer; //counter through sub-list
begin
Result := ''; //nothing filtered so far
for i := 0 to FFilterIdentifierByName.Count - 1 do //for each name
begin
Entry := FFilterIdentifierByName[i]; //get the name
List := TStringList(FFilterIdentifierByName.Objects[i]); //get the sub-list
if not assigned(List) then //no sub-list?
begin
if i <> 0 then //if not at the beginning
Result := Result + ', '; //add the separator
Result := Result + Entry; //add simple name of an identifier
end
else
begin
Entry := '.' + Entry; //prepend separator to the path
for j := 0 to List.Count - 1 do //for each path
begin
if (i <> 0) or (j <> 0) then //if not at the beginning
Result := Result + ', '; //add the separator
Result := Result + List[j] + Entry; //add the path and name
end;
end; //else not assigned(List)
end; //for i := 0 to FFilterIdentifierByName.Count - 1
end;
begin
case Index of //depending on index of option
0: Result.StrData := FDestPath; //get the value
1: Result.StrData := FProjectName;
2: Result.BoolData := FAutoLaunchDocumentation;
3: Result.BoolData := FNoPrivateOnlyInterface;
4: Result.SetData := SetToOption(FIgnoredPortabilityIssues,
SizeOf(FIgnoredPortabilityIssues));
5: Result.SetData := SetToOption(FFilterIdentifiersByScope,
SizeOf(FFilterIdentifiersByScope));
6: Result.SetData := SetToOption(FFilterMembersByScope,
SizeOf(FFilterMembersByScope),
Ord(Low(TMemberScope)));
7: Result.SetData := SetToOption(FFilterIdentifiersByKind,
SizeOf(FFilterIdentifiersByKind));
8: Result.SetData := SetToOption(FFilterClassesByKind,
SizeOf(FFilterClassesByKind));
9: Result.SetData := SetToOption(FFilterFunctionsByKind,
SizeOf(FFilterFunctionsByKind));
10: Result.SetData := SetToOption(FFilterMembersByKind,
SizeOf(FFilterMembersByKind));
11: Result.StrData := FFilterFilesByName.CommaText;
12: Result.StrData := GetIdentifierNameFilter;
else
Assert(Index >= GetOptionCount); //invalid index!
raise EInvalidOption.Create('Invalid index for option supplied!');
end;
end;
{Sets the value of an option. Call ~[link GetOptionDescription] to get the type
and the meaning of the option.
~param Index index of the option to set the value
~param Value the new value of the option
~see GetOptionCount
~see GetOptionDescription
~see GetOption }
procedure TMakeDoc.SetOption(Index: Cardinal; const Value: TOptionValue);
{Adds the entries of the comma-separated text to the list.
~param Text the text with entries separated by commas
~param List the list to add the entries to }
procedure SeparateByComma(Text: String; List: TStrings);
var Index :Integer; //index of next separator in the text
Entry :String; //each entry in the text
begin
while Text <> '' do //for each entry
begin
Index := pos(',', Text); //get separator
if Index = 0 then //last entry?
begin
Entry := Text; //get the entry
Text := ''; //finished
end
else
begin
Entry := Copy(Text, 1, Index - 1); //extract the entry
Delete(Text, 1, Index); //and remove it
end;
Entry := Trim(Entry);
if (Entry <> '') and (pos(' ', Entry) = 0) then //a valid entry?
List.Append(Entry); //append it to the list
end;
end;
{Sets the filter to exclude files by their names.
~param Text the text containing the comma-separated names of the files to
exclude }
procedure SetFileNameFilter(const Text: String);
begin
FFilterFilesByName.Clear; //clear old list
SeparateByComma(Text, FFilterFilesByName); //and set the list
end;
{Sets the filter to exclude identifiers by their names.
~param Text the text containing the comma-separated names of the identifiers
to exclude }
procedure SetIdentifierNameFilter(const Text: String);
var i :Integer; //counter through the lists
List :TStringList; //list for specified entries in Text
Entry :String; //each entry
NameIndex :Integer; //index before start of name in entry
IdentName :String; //the name of the identifiers
Index :Integer; //index of the name in the list
PathsList :TStringList; //sub-list with paths of identifiers
begin
for i := 0 to FFilterIdentifierByName.Count - 1 do //clear old sub-lists
FFilterIdentifierByName.Objects[i].Free;
FFilterIdentifierByName.Clear; //clear old list
List := TStringList.Create; //create list for entries in the Text
try
// List.Sorted := True;
// List.Duplicates := dupIgnore;
SeparateByComma(Text, List); //and read the entries
for i := 0 to List.Count - 1 do //for each new entry
begin
Entry := List[i]; //get the entry
NameIndex := LastPos('.', Entry); //contains path to the identifier?
if NameIndex = 0 then //no?
IdentName := Entry //just use the name
else
begin //split name and path
IdentName := Copy(Entry, NameIndex + 1, High(Length(Entry)));
Delete(Entry, NameIndex, High(Length(Entry)));
end;
//the name is already in the list?
if FFilterIdentifierByName.Find(IdentName, Index) then
begin //get the paths
PathsList := TStringList(FFilterIdentifierByName.Objects[Index]);
//if no sub-list then all paths will be filtered anyway
if assigned(PathsList) then //has sub-list with paths?
if NameIndex <> 0 then //this entry has a path?
PathsList.Append(Entry) //add it (if not in it)
else
begin //filter by name, ignore paths
FFilterIdentifierByName.Objects[Index] := nil; //remove all paths
PathsList.Free; //and free the list
end;
end //if FFilterIdentifierByName.Find
else
begin
Index := FFilterIdentifierByName.Add(IdentName); //add the name
if NameIndex <> 0 then //has a path?
begin
PathsList := TStringList.Create; //create list for paths
try
PathsList.Sorted := True; //sort for faster access
PathsList.Duplicates := dupIgnore;
FFilterIdentifierByName.Objects[Index] := PathsList; //set paths
except
PathsList.Free;
raise;
end;
PathsList.Append(Entry); //and add the path
end;
end; //else FFilterIdentifierByName.Find
end; //for i := 0 to List.Count - 1
finally
List.Free; //free list with entries
end;
end;
begin
case Index of //depending on index of option
0: DestPath := Value.StrData; //set the value
1: ProjectName := Value.StrData;
2: FAutoLaunchDocumentation := Value.BoolData;
3: FNoPrivateOnlyInterface := Value.BoolData;
4: OptionToSet(Value.SetData, FIgnoredPortabilityIssues,
SizeOf(FIgnoredPortabilityIssues));
5: OptionToSet(Value.SetData, FFilterIdentifiersByScope,
SizeOf(FFilterIdentifiersByScope));
6: OptionToSet(Value.SetData, FFilterMembersByScope,
SizeOf(FFilterMembersByScope),
Ord(Low(TMemberScope)));
7: OptionToSet(Value.SetData, FFilterIdentifiersByKind,
SizeOf(FFilterIdentifiersByKind));
8: OptionToSet(Value.SetData, FFilterClassesByKind,
SizeOf(FFilterClassesByKind));
9: OptionToSet(Value.SetData, FFilterFunctionsByKind,
SizeOf(FFilterFunctionsByKind));
10: OptionToSet(Value.SetData, FFilterMembersByKind,
SizeOf(FFilterMembersByKind));
11: SetFileNameFilter(Value.StrData);
12: SetIdentifierNameFilter(Value.StrData);
else
Assert(Index >= GetOptionCount); //invalid index!
raise EInvalidOption.Create('Invalid index for option supplied!');
end;
end;
{Returns an object to edit the options of the generator. The object must not be
freed.
~result an object to edit the options of the generator }
function TMakeDoc.GetOptions: TOptionWrapper;
begin
if not Assigned(FOptionAccessor) then //accessor does not exist yet?
FOptionAccessor := TGeneratorOptionWrapper.Create(Self); //create it
Result := FOptionAccessor; //return the wrapper
end;
{Returns a list of wrappers for all options of the generator and all used
objects.
~result a list of wrappers for all options }
function TMakeDoc.GetAllOptions: TOptionWrapperList;
begin
SetLength(Result, 20); //create lists with wrappers of all options
AddOptionWrappers(Result); //and let them be added
end;
{Adds all wrappers for all options of the different objects to the list.
~param List the list to add all option wrappers to }
procedure TMakeDoc.AddOptionWrappers(const List: TOptionWrapperList);
var index :Integer; //counter through the list
{Searches the next free entry in the list. }
procedure NextFreeEntry;
begin
//find next free entry
while Assigned(List[index]) and (index < Length(List)) do
Inc(index);
if index = Length(List) then
raise ERangeError.Create('No free entry in list for option wrapper!');
end;
begin
index := 0; //start search at the beginning
NextFreeEntry; //search a free entry
List[index] := GetOptions; //add options of generator
if Assigned(FExtractor) then //has an extractor?
begin
NextFreeEntry; //search a free entry
List[index] := FExtractor.GetOptions; //add options of extractor
end;
end;
{Registers a list of messages.
~param Descriptions the list of descriptions of messages to add
~param MayAlreadyBeRegistered if the list may already be registered
~result the ID of the list of messages }
function TMakeDoc.RegisterMessages(Descriptions: TMessageDescriptions;
MayAlreadyBeRegistered: Boolean = False):
TMessageID;
{$IFOPT C+}
var i :TMessageID; //counter through messages
{$ENDIF}
begin
Assert(Assigned(Descriptions));
Result := 0; //search a free entry
while (Result < Length(FMessageDescriptions)) and
Assigned(FMessageDescriptions[Result]) and
(FMessageDescriptions[Result] <> Descriptions) do
Inc(Result);
Assert(MayAlreadyBeRegistered or (Result = Length(FMessageDescriptions)) or
(FMessageDescriptions[Result] <> Descriptions));
{$IFOPT C+}
if not MayAlreadyBeRegistered then //must not be registered yet?
begin
i := Result + 1; //check whether it is
while (i < Length(FMessageDescriptions)) and
(FMessageDescriptions[i] <> Descriptions) do
Inc(i);
Assert(i >= Length(FMessageDescriptions)); //not registered yet?
end;
{$ENDIF}
if Result = Length(FMessageDescriptions) then //not found?
SetLength(FMessageDescriptions, Result + 1); //add an entry
FMessageDescriptions[Result] := Descriptions; //register the index
Inc(Result);
end;
{Registers all registered message to the other generator. The messages can be
mapped to the new IDs by assigning them the ID in the returned array, i.e. :
~[code Msg.MessageID := Map~[[Msg.MessageID~[]]. Only used to re-register the
messages used when generating a diagram.
~param OtherGenerator the generator to register all message to
~result an array mapping the message IDs of this generator to the message IDs
in the other generator }
function TMakeDoc.RegisterAllMessagesTo(OtherGenerator: TMakeDoc):
TMessageDescriptionMap;
var i :TMessageID; //counter through all registered messages
begin
SetLength(Result, Length(FMessageDescriptions) + 1);
Result[0] := -1;
//register all message IDs with the other generator
for i := Low(FMessageDescriptions) to High(FMessageDescriptions) do
if Assigned(FMessageDescriptions[i]) then //valid messages?
Result[i + 1] := OtherGenerator.RegisterMessages(FMessageDescriptions[i],
True)
else
Result[i + 1] := -1;
end;
{Unregisters a list of messages.
~param Messages the previously registered ID of a list of messages to
unregister; 0 is ignored }
procedure TMakeDoc.UnRegisterMessages(Messages: TMessageID);
begin
Assert(Messages >= 0);
Assert(Messages <= Length(FMessageDescriptions));
if Messages <> 0 then
FMessageDescriptions[Messages - 1] := nil; //unregister the index
end;
{Adds the message.
~param Message the message }
procedure TMakeDoc.AddMessage(Message: TGeneratorMessage);
var AddToList :Boolean; //whether the message should be added to the list
begin
Assert(Message.MessageID > 0);
Assert(Message.MessageID <= Length(FMessageDescriptions));
AddToList := True; //by default add the message to the list
// todo here: check if message is filtered
if Assigned(FOnMessage) then //event handler assigned?
FOnMessage(Message, Self, AddToList); //call it
if AddToList then //message should still be added to the list?
FMessages.Add(Message); //add th
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -