{ /*************************************************************************** compoptsmodes.pas - Lazarus IDE unit --------------------------------------- Conditional compiler options and build modes. ***************************************************************************/ *************************************************************************** * * * 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 . 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: This unit contains a class to create diffs between compiler options. } unit CompOptsModes; {$mode objfpc}{$H+} {$i ide.inc} interface uses Classes, SysUtils, ExprEval, LazLoggerBase, ProjectIntf, IDEProcs; type { TCompilerDiffTool A tool to collect the difference between two option sets } TCompilerDiffTool = class private FDiff: TStrings; FDiffer: boolean; FPath: string; procedure SetDiff(const AValue: TStrings); procedure SetDiffer(const AValue: boolean); procedure SetPath(const AValue: string); public constructor Create(DiffList: TStrings); procedure AddDiffItem(const PropertyName, Value: string); procedure AddDiffItemUndefined(const PropertyName: string); function AddDiff(const PropertyName: string; const Old, New: string): boolean; function AddDiff(const PropertyName: string; const Old, New: integer): boolean; function AddDiff(const PropertyName: string; const Old, New: boolean): boolean; function AddStringsDiff(const PropertyName: string; const OldList, NewList: TStrings): boolean; function AddPathsDiff(const PropertyName: string; const Old, New: string): boolean; function AddSetDiff(const PropertyName: string; const Old, New: integer; const EnumNames: PString): boolean; property Diff: TStrings read FDiff write SetDiff; property Path: string read FPath write SetPath; property Differ: boolean read FDiffer write SetDiffer; end; implementation { TCompilerDiffTool } procedure TCompilerDiffTool.SetDiff(const AValue: TStrings); begin if Self=nil then exit; if FDiff=AValue then exit; FDiff:=AValue; end; procedure TCompilerDiffTool.SetDiffer(const AValue: boolean); begin if Self=nil then exit; if FDiffer=AValue then exit; FDiffer:=AValue; end; procedure TCompilerDiffTool.SetPath(const AValue: string); begin if Self=nil then exit; if FPath=AValue then exit; FPath:=AValue; // ! config path, not file path. Always /, not PathDelim if (FPath<>'') and (Path[length(Path)]<>'/') then FPath:=FPath+'/'; end; constructor TCompilerDiffTool.Create(DiffList: TStrings); begin FDiff:=DiffList; if Diff<>nil then Diff.Clear; end; procedure TCompilerDiffTool.AddDiffItem(const PropertyName, Value: string); begin if Self=nil then exit; Differ:=true; if Diff<>nil then Diff.Add(Path+PropertyName+'='+Value); end; procedure TCompilerDiffTool.AddDiffItemUndefined(const PropertyName: string); begin if Self=nil then exit; Differ:=true; if Diff<>nil then Diff.Add(Path+PropertyName+' undefined'); end; function TCompilerDiffTool.AddDiff(const PropertyName: string; const Old, New: string): boolean; begin //if Self<>nil then debugln(['TCompilerDiffTool.AddDiff ',PropertyName,'=',Old,',',New]); if Old=New then exit(false); Result:=true; if Self=nil then exit; AddDiffItem(PropertyName,New); end; function TCompilerDiffTool.AddDiff(const PropertyName: string; const Old, New: integer): boolean; begin if Old=New then exit(false); Result:=true; if Self=nil then exit; AddDiffItem(PropertyName,IntToStr(New)); end; function TCompilerDiffTool.AddDiff(const PropertyName: string; const Old, New: boolean): boolean; begin if Old=New then exit(false); Result:=true; if Self=nil then exit; AddDiffItem(PropertyName,dbgs(New)); end; function TCompilerDiffTool.AddStringsDiff(const PropertyName: string; const OldList, NewList: TStrings): boolean; var i: Integer; OldCnt: Integer; NewCnt: Integer; begin OldCnt:=0; if OldList<>nil then OldCnt:=OldList.Count; NewCnt:=0; if NewList<>nil then NewCnt:=NewList.Count; Result:=AddDiff(PropertyName+'/Count',OldCnt,NewCnt); if Result and (Self=nil) then exit; for i:=0 to OldCnt-1 do begin if (i>=NewCnt) then begin Result:=true; if Self=nil then exit; AddDiffItem(PropertyName+'/Item'+IntToStr(i),'deleted='+OldList[i]); end else if (OldList[i]<>NewList[i]) then begin Result:=true; if Self=nil then exit; AddDiffItem(PropertyName+'/Item'+IntToStr(i),NewList[i]); end; end; end; function TCompilerDiffTool.AddPathsDiff(const PropertyName: string; const Old, New: string): boolean; begin if Old=New then exit(false); Result:=true; if Self=nil then exit; AddDiff(PropertyName,Old,New); end; function TCompilerDiffTool.AddSetDiff(const PropertyName: string; const Old, New: integer; const EnumNames: PString): boolean; var i: Integer; Mask: LongInt; s: String; begin if Old=New then exit(false); Result:=true; if Self=nil then exit; Mask := 1; s:=''; for i := 0 to 31 do begin if (New and Mask) <> (Old and Mask) then begin if s<>'' then s:=s+','; if (New and Mask) <> 0 then s:=s+'+' else s:=s+'-'; s:=s+EnumNames[i]; end; Mask := Mask shl 1; end; AddDiffItem(PropertyName,s); end; end.