1 { /***************************************************************************
2                     compoptsmodes.pas  -  Lazarus IDE unit
3                     ---------------------------------------
4                 Conditional compiler options and build modes.
5 
6  ***************************************************************************/
7 
8  ***************************************************************************
9  *                                                                         *
10  *   This source is free software; you can redistribute it and/or modify   *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  *   This code is distributed in the hope that it will be useful, but      *
16  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
18  *   General Public License for more details.                              *
19  *                                                                         *
20  *   A copy of the GNU General Public License is available on the World    *
21  *   Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also      *
22  *   obtain it by writing to the Free Software Foundation,                 *
23  *   Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA.   *
24  *                                                                         *
25  ***************************************************************************
26 
27   Author: Mattias Gaertner
28 
29   Abstract:
30     This unit contains a class to create diffs between compiler options.
31 }
32 unit CompOptsModes;
33 
34 {$mode objfpc}{$H+}
35 
36 {$i ide.inc}
37 
38 interface
39 
40 uses
41   Classes, SysUtils, LCLProc, ExprEval,
42   IDEProcs, ProjectIntf;
43 
44 type
45 
46   { TCompilerDiffTool
47     A tool to collect the difference between two option sets }
48 
49   TCompilerDiffTool = class
50   private
51     FDiff: TStrings;
52     FDiffer: boolean;
53     FPath: string;
54     procedure SetDiff(const AValue: TStrings);
55     procedure SetDiffer(const AValue: boolean);
56     procedure SetPath(const AValue: string);
57   public
58     constructor Create(DiffList: TStrings);
59     procedure AddDiffItem(const PropertyName, Value: string);
60     procedure AddDiffItemUndefined(const PropertyName: string);
AddDiffnull61     function AddDiff(const PropertyName: string; const Old, New: string): boolean;
AddDiffnull62     function AddDiff(const PropertyName: string; const Old, New: integer): boolean;
AddDiffnull63     function AddDiff(const PropertyName: string; const Old, New: boolean): boolean;
AddStringsDiffnull64     function AddStringsDiff(const PropertyName: string; const OldList, NewList: TStrings): boolean;
AddPathsDiffnull65     function AddPathsDiff(const PropertyName: string; const Old, New: string): boolean;
AddSetDiffnull66     function AddSetDiff(const PropertyName: string; const Old, New: integer;
67                          const EnumNames: PString): boolean;
68     property Diff: TStrings read FDiff write SetDiff;
69     property Path: string read FPath write SetPath;
70     property Differ: boolean read FDiffer write SetDiffer;
71   end;
72 
73 implementation
74 
75 { TCompilerDiffTool }
76 
77 procedure TCompilerDiffTool.SetDiff(const AValue: TStrings);
78 begin
79   if Self=nil then exit;
80   if FDiff=AValue then exit;
81   FDiff:=AValue;
82 end;
83 
84 procedure TCompilerDiffTool.SetDiffer(const AValue: boolean);
85 begin
86   if Self=nil then exit;
87   if FDiffer=AValue then exit;
88   FDiffer:=AValue;
89 end;
90 
91 procedure TCompilerDiffTool.SetPath(const AValue: string);
92 begin
93   if Self=nil then exit;
94   if FPath=AValue then exit;
95   FPath:=AValue;
96   // ! config path, not file path. Always /, not PathDelim
97   if (FPath<>'') and (Path[length(Path)]<>'/') then FPath:=FPath+'/';
98 end;
99 
100 constructor TCompilerDiffTool.Create(DiffList: TStrings);
101 begin
102   FDiff:=DiffList;
103   if Diff<>nil then
104     Diff.Clear;
105 end;
106 
107 procedure TCompilerDiffTool.AddDiffItem(const PropertyName, Value: string);
108 begin
109   if Self=nil then exit;
110   Differ:=true;
111   if Diff<>nil then
112     Diff.Add(Path+PropertyName+'='+Value);
113 end;
114 
115 procedure TCompilerDiffTool.AddDiffItemUndefined(const PropertyName: string);
116 begin
117   if Self=nil then exit;
118   Differ:=true;
119   if Diff<>nil then
120     Diff.Add(Path+PropertyName+' undefined');
121 end;
122 
TCompilerDiffTool.AddDiffnull123 function TCompilerDiffTool.AddDiff(const PropertyName: string; const Old,
124   New: string): boolean;
125 begin
126   //if Self<>nil then debugln(['TCompilerDiffTool.AddDiff ',PropertyName,'=',Old,',',New]);
127   if Old=New then exit(false);
128   Result:=true;
129   if Self=nil then exit;
130   AddDiffItem(PropertyName,New);
131 end;
132 
TCompilerDiffTool.AddDiffnull133 function TCompilerDiffTool.AddDiff(const PropertyName: string; const Old,
134   New: integer): boolean;
135 begin
136   if Old=New then exit(false);
137   Result:=true;
138   if Self=nil then exit;
139   AddDiffItem(PropertyName,IntToStr(New));
140 end;
141 
TCompilerDiffTool.AddDiffnull142 function TCompilerDiffTool.AddDiff(const PropertyName: string; const Old,
143   New: boolean): boolean;
144 begin
145   if Old=New then exit(false);
146   Result:=true;
147   if Self=nil then exit;
148   AddDiffItem(PropertyName,dbgs(New));
149 end;
150 
AddStringsDiffnull151 function TCompilerDiffTool.AddStringsDiff(const PropertyName: string;
152   const OldList, NewList: TStrings): boolean;
153 var
154   i: Integer;
155   OldCnt: Integer;
156   NewCnt: Integer;
157 begin
158   OldCnt:=0;
159   if OldList<>nil then
160     OldCnt:=OldList.Count;
161   NewCnt:=0;
162   if NewList<>nil then
163     NewCnt:=NewList.Count;
164   Result:=AddDiff(PropertyName+'/Count',OldCnt,NewCnt);
165   if Result and (Self=nil) then exit;
166   for i:=0 to OldCnt-1 do begin
167     if (i>=NewCnt) then begin
168       Result:=true;
169       if Self=nil then exit;
170       AddDiffItem(PropertyName+'/Item'+IntToStr(i),'deleted='+OldList[i]);
171     end
172     else if (OldList[i]<>NewList[i]) then begin
173       Result:=true;
174       if Self=nil then exit;
175       AddDiffItem(PropertyName+'/Item'+IntToStr(i),NewList[i]);
176     end;
177   end;
178 end;
179 
AddPathsDiffnull180 function TCompilerDiffTool.AddPathsDiff(const PropertyName: string; const Old,
181   New: string): boolean;
182 begin
183   if Old=New then exit(false);
184   Result:=true;
185   if Self=nil then exit;
186   AddDiff(PropertyName,Old,New);
187 end;
188 
TCompilerDiffTool.AddSetDiffnull189 function TCompilerDiffTool.AddSetDiff(const PropertyName: string; const Old,
190   New: integer; const EnumNames: PString): boolean;
191 var
192   i: Integer;
193   Mask: LongInt;
194   s: String;
195 begin
196   if Old=New then exit(false);
197   Result:=true;
198   if Self=nil then exit;
199   Mask := 1;
200   s:='';
201   for i := 0 to 31 do begin
202     if (New and Mask) <> (Old and Mask) then begin
203       if s<>'' then s:=s+',';
204       if (New and Mask) <> 0 then
205         s:=s+'+'
206       else
207         s:=s+'-';
208       s:=s+EnumNames[i];
209     end;
210     Mask := Mask shl 1;
211   end;
212   AddDiffItem(PropertyName,s);
213 end;
214 
215 end.
216 
217