mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-10-31 15:21:26 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			207 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
| {
 | |
|  ***************************************************************************
 | |
|  *                                                                         *
 | |
|  *   This source is free software; you can redistribute it and/or modify   *
 | |
|  *   it under the terms of the GNU General Public License as published by  *
 | |
|  *   the Free Software Foundation; either version 2 of the License, or     *
 | |
|  *   (at your option) any later version.                                   *
 | |
|  *                                                                         *
 | |
|  *   This code is distributed in the hope that it will be useful, but      *
 | |
|  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 | |
|  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 | |
|  *   General Public License for more details.                              *
 | |
|  *                                                                         *
 | |
|  *   A copy of the GNU General Public License is available on the World    *
 | |
|  *   Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also      *
 | |
|  *   obtain it by writing to the Free Software Foundation,                 *
 | |
|  *   Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA.   *
 | |
|  *                                                                         *
 | |
|  ***************************************************************************
 | |
| 
 | |
|   Author: Mattias Gaertner
 | |
| 
 | |
|   Abstract:
 | |
|     Functions and classes to build dependency graphs for groups of pascal units.
 | |
| }
 | |
| unit CTUnitGroupGraph;
 | |
| 
 | |
| {$mode objfpc}{$H+}
 | |
| 
 | |
| interface
 | |
| 
 | |
| uses
 | |
|   Classes, SysUtils, Laz_AVL_Tree, CTUnitGraph;
 | |
| 
 | |
| type
 | |
|   TUGGroup = class;
 | |
|   TUGGroups = class;
 | |
| 
 | |
|   { TUGGroupUnit }
 | |
| 
 | |
|   TUGGroupUnit = class(TUGUnit)
 | |
|   public
 | |
|     Group: TUGGroup;
 | |
|   end;
 | |
| 
 | |
|   TUGGroup = class
 | |
|   private
 | |
|     FBaseDir: string;
 | |
|     FGroups: TUGGroups;
 | |
|     FName: string;
 | |
|     FUnits: TAVLTree;
 | |
|     procedure SetName(AValue: string);
 | |
|   public
 | |
|     constructor Create(aName: string; TheGroups: TUGGroups);
 | |
|     destructor Destroy; override;
 | |
|     procedure Clear;
 | |
|     procedure AddUnit(anUnit: TUGGroupUnit);
 | |
|     procedure RemoveUnit(anUnit: TUGGroupUnit);
 | |
|     property Name: string read FName write SetName;
 | |
|     property BaseDir: string read FBaseDir write FBaseDir;
 | |
|     property Groups: TUGGroups read FGroups;
 | |
|     property Units: TAVLTree read FUnits; // tree of TUGGroupUnit sorted for Filename
 | |
|   end;
 | |
| 
 | |
|   { TUGGroups }
 | |
| 
 | |
|   TUGGroups = class
 | |
|   private
 | |
|     fClearing: boolean;
 | |
|     FGroups: TAVLTree;
 | |
|   public
 | |
|     constructor Create(Graph: TUsesGraph);
 | |
|     destructor Destroy; override;
 | |
|     procedure Clear;
 | |
|     function GetGroup(Name: string; CreateIfNotExists: boolean): TUGGroup;
 | |
|     property Groups: TAVLTree read FGroups; // tree of TUGGroup sorted for Name
 | |
|   end;
 | |
| 
 | |
| function CompareUGGroupNames(UGGroup1, UGGroup2: Pointer): integer;
 | |
| function CompareNameAndUGGroup(NameAnsistring, UGGroup: Pointer): integer;
 | |
| 
 | |
| implementation
 | |
| 
 | |
| function CompareUGGroupNames(UGGroup1, UGGroup2: Pointer): integer;
 | |
| var
 | |
|   Group1: TUGGroup absolute UGGroup1;
 | |
|   Group2: TUGGroup absolute UGGroup2;
 | |
| begin
 | |
|   Result:=SysUtils.CompareText(Group1.Name,Group2.Name);
 | |
| end;
 | |
| 
 | |
| function CompareNameAndUGGroup(NameAnsistring, UGGroup: Pointer): integer;
 | |
| var
 | |
|   Group: TUGGroup absolute UGGroup;
 | |
|   Name: String;
 | |
| begin
 | |
|   Name:=AnsiString(NameAnsistring);
 | |
|   Result:=SysUtils.CompareText(Name,Group.Name);
 | |
| end;
 | |
| 
 | |
| { TUGGroups }
 | |
| 
 | |
| constructor TUGGroups.Create(Graph: TUsesGraph);
 | |
| begin
 | |
|   if (not Graph.UnitClass.InheritsFrom(TUGGroup))
 | |
|   and ((Graph.FilesTree.Count>0) or (Graph.QueuedFilesTree.Count>0)
 | |
|      or (Graph.TargetFilesTree.Count>0))
 | |
|   then
 | |
|     raise Exception.Create('TUGGroups.Create You must create TUGGroups before adding units');
 | |
|   FGroups:=TAVLTree.Create(@CompareUGGroupNames);
 | |
|   Graph.UnitClass:=TUGGroupUnit;
 | |
| end;
 | |
| 
 | |
| destructor TUGGroups.Destroy;
 | |
| begin
 | |
|   Clear;
 | |
|   FreeAndNil(FGroups);
 | |
|   inherited Destroy;
 | |
| end;
 | |
| 
 | |
| procedure TUGGroups.Clear;
 | |
| begin
 | |
|   if FGroups=nil then exit;
 | |
|   fClearing:=true;
 | |
|   try
 | |
|     FGroups.FreeAndClear;
 | |
|   finally
 | |
|     fClearing:=false;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| function TUGGroups.GetGroup(Name: string; CreateIfNotExists: boolean): TUGGroup;
 | |
| var
 | |
|   Node: TAVLTreeNode;
 | |
| begin
 | |
|   Node:=FGroups.FindKey(Pointer(Name),@CompareNameAndUGGroup);
 | |
|   if Node<>nil then begin
 | |
|     Result:=TUGGroup(Node.Data);
 | |
|   end else if CreateIfNotExists then begin
 | |
|     Result:=TUGGroup.Create(Name,Self);
 | |
|     FGroups.Add(Result);
 | |
|   end else
 | |
|    Result:=nil;
 | |
| end;
 | |
| 
 | |
| { TUGGroup }
 | |
| 
 | |
| procedure TUGGroup.SetName(AValue: string);
 | |
| begin
 | |
|   if FName=AValue then Exit;
 | |
|   if Groups.GetGroup(AValue,false)<>nil then
 | |
|     raise Exception.Create('TUGGroup.SetName name already exists');
 | |
|   Groups.fGroups.Remove(Self);
 | |
|   FName:=AValue;
 | |
|   Groups.fGroups.Add(Self);
 | |
| end;
 | |
| 
 | |
| constructor TUGGroup.Create(aName: string; TheGroups: TUGGroups);
 | |
| begin
 | |
|   FName:=aName;
 | |
|   FGroups:=TheGroups;
 | |
|   FUnits:=TAVLTree.Create(@CompareUGUnitFilenames);
 | |
| end;
 | |
| 
 | |
| destructor TUGGroup.Destroy;
 | |
| begin
 | |
|   Clear;
 | |
|   if not Groups.fClearing then
 | |
|     Groups.FGroups.Remove(Self);
 | |
|   fGroups:=nil;
 | |
|   FreeAndNil(FUnits);
 | |
|   inherited Destroy;
 | |
| end;
 | |
| 
 | |
| procedure TUGGroup.Clear;
 | |
| var
 | |
|   Node: TAVLTreeNode;
 | |
| begin
 | |
|   Node:=FUnits.FindLowest;
 | |
|   while Node<>nil do begin
 | |
|     TUGGroupUnit(Node.Data).Group:=nil;
 | |
|     Node:=FUnits.FindSuccessor(Node);
 | |
|   end;
 | |
|   FUnits.Clear;
 | |
| end;
 | |
| 
 | |
| procedure TUGGroup.AddUnit(anUnit: TUGGroupUnit);
 | |
| begin
 | |
|   if anUnit.Group<>nil then begin
 | |
|     anUnit.Group.FUnits.Remove(anUnit);
 | |
|     anUnit.Group:=nil;
 | |
|   end;
 | |
|   FUnits.Add(anUnit);
 | |
|   anUnit.Group:=Self;
 | |
| end;
 | |
| 
 | |
| procedure TUGGroup.RemoveUnit(anUnit: TUGGroupUnit);
 | |
| begin
 | |
|   if (anUnit.Group<>nil) and (anUnit.Group<>Self) then
 | |
|     raise Exception.Create('TUGGroup.RemoveUnit inconsistency');
 | |
|   FUnits.Remove(anUnit);
 | |
|   anUnit.Group:=nil;
 | |
| end;
 | |
| 
 | |
| end.
 | |
| 
 | 
