diff --git a/components/codetools/examples/runcfgscript.lpr b/components/codetools/examples/runcfgscript.lpr index 2d05a94f17..b2444fe8d3 100644 --- a/components/codetools/examples/runcfgscript.lpr +++ b/components/codetools/examples/runcfgscript.lpr @@ -21,401 +21,41 @@ Author: Mattias Gaertner Abstract: - Write all duplicate ppu files and all duplicate unit source files. + Demo for automatic indentation. } -program runcfgscript; +program RunCfgScript; {$mode objfpc}{$H+} uses - Classes, SysUtils, CustApp, AVL_Tree, CodeToolManager, DefineTemplates, - CodeToolsConfig, FileProcs, CodeToolsStructs; + Classes, SysUtils, DefineTemplates, CodeToolsConfig, FileProcs, + CodeToolsStructs, CodeToolManager, CodeCache, CodeBeautifier, + CodeToolsCfgScript; -const - ConfigFilename = 'codetools.config'; -type - - { TTestFPCSourceUnitRules } - - TTestFPCSourceUnitRules = class(TCustomApplication) - private - FCheckUnitName: string; - protected - procedure DoRun; override; - public - constructor Create(TheOwner: TComponent); override; - destructor Destroy; override; - procedure WriteHelp; virtual; - procedure Error(Msg: string; DoWriteHelp: Boolean); - procedure WriteCompilerInfo(ConfigCache: TFPCTargetConfigCache); - procedure WriteDuplicatesInPPUPath(ConfigCache: TFPCTargetConfigCache); - procedure WriteMissingPPUSources(UnitSet: TFPCUnitSetCache); - procedure WriteDuplicateSources(UnitSet: TFPCUnitSetCache); - procedure WriteUnitReport(UnitSet: TFPCUnitSetCache; const AnUnitName: string); - property CheckUnitName: string read FCheckUnitName write FCheckUnitName; - end; - -{ TMyApplication } - -procedure TTestFPCSourceUnitRules.DoRun; var - ErrorMsg: String; - CompilerFilename: String; - TargetOS: String; - TargetCPU: String; - FPCSrcDir: String; - UnitSet: TFPCUnitSetCache; - ConfigCache: TFPCTargetConfigCache; - Options: TCodeToolsOptions; + Code: TCodeBuffer; + Filename: String; + Src: String; + Engine: TCTConfigScriptEngine; begin - // quick check parameters - ErrorMsg:=CheckOptions('hc:T:P:F:u:','help compiler: targetos: targetcpu: fpcsrcdir: checkunit:'); - if ErrorMsg<>'' then begin - ShowException(Exception.Create(ErrorMsg)); - Terminate; - Exit; - end; + if Paramcount>0 then begin + if Paramcount<>1 then begin + writeln('Usage: '+ParamStrUTF8(0)+' filename line column'); + exit; + end; + Filename:=ExpandFileNameUTF8(ParamStrUTF8(1)); - // parse parameters - if HasOption('h','help') then begin - WriteHelp; - Halt; - end; - - if not HasOption('F','fpcsrcdir') then - Error('fpc source directory missing',true); - - if HasOption('c','compiler') then begin - CompilerFilename:=GetOptionValue('c','compiler'); - CompilerFilename:=CleanAndExpandFilename(CompilerFilename); + // load the example unit + Code:=CodeToolBoss.LoadFile(Filename,false,false); + if Code=nil then + raise Exception.Create('unable to read '+Filename); + Src:=Code.Source; end else begin - CompilerFilename:=GetDefaultCompilerFilename; - CompilerFilename:=SearchFileInPath(CompilerFilename,'', - GetEnvironmentVariable('PATH'), PathSeparator,ctsfcDefault); - end; - TargetOS:=GetOptionValue('T','targetos'); - TargetCPU:=GetOptionValue('P','targetcpu'); - FPCSrcDir:=GetOptionValue('F','fpcsrcdir'); - FPCSrcDir:=CleanAndExpandDirectory(FPCSrcDir); - CheckUnitName:=GetOptionValue('u','checkunit'); - - if not FileExistsUTF8(CompilerFilename) then - Error('compiler file not found: '+CompilerFilename,false); - if not DirPathExists(FPCSrcDir) then - Error('FPC source directory not found: '+FPCSrcDir,false); - - Options:=TCodeToolsOptions.Create; - Options.InitWithEnvironmentVariables; - if FileExistsUTF8(ConfigFilename) then - Options.LoadFromFile(ConfigFilename); - Options.FPCPath:=CompilerFilename; - Options.FPCOptions:=''; - Options.TargetOS:=TargetOS; - Options.TargetProcessor:=TargetCPU; - Options.FPCSrcDir:=FPCSrcDir; - - CodeToolBoss.Init(Options); - - UnitSet:=CodeToolBoss.FPCDefinesCache.FindUnitSet(CompilerFilename, - TargetOS,TargetCPU,'',FPCSrcDir,true); - UnitSet.Init; - - Options.SaveToFile(ConfigFilename); - Options.Free; - - ConfigCache:=UnitSet.GetConfigCache(false); - writeln('FPCSrcDir=',UnitSet.FPCSourceDirectory); - WriteCompilerInfo(ConfigCache); - WriteDuplicatesInPPUPath(ConfigCache); - WriteMissingPPUSources(UnitSet); - WriteDuplicateSources(UnitSet); - if CheckUnitName<>'' then - WriteUnitReport(UnitSet,CheckUnitName); - - // stop program loop - Terminate; -end; - -constructor TTestFPCSourceUnitRules.Create(TheOwner: TComponent); -begin - inherited Create(TheOwner); - StopOnException:=True; -end; - -destructor TTestFPCSourceUnitRules.Destroy; -begin - inherited Destroy; -end; - -procedure TTestFPCSourceUnitRules.WriteHelp; -begin - writeln('Usage: ',ExeName,' -h'); - writeln; - writeln(' -c , --compiler='); - writeln(' Default is to use environment variable PP.'); - writeln(' If this is not set, search for '+GetDefaultCompilerFilename); - writeln; - writeln(' -T , --targetos='); - writeln(' Default is to use environment variable FPCTARGET.'); - writeln(' If this is not set, use the default of the compiler.'); - writeln; - writeln(' -P , --targetcpu='); - writeln(' Default is to use environment variable FPCTARGETCPU.'); - writeln(' If this is not set, use the default of the compiler.'); - writeln; - writeln(' -F , --fpcsrcdir='); - writeln(' Default is to use environment variable FPCDIR.'); - writeln(' There is no default.'); - writeln; - writeln(' -u , --checkunit='); - writeln(' Write a detailed report about this unit.'); -end; - -procedure TTestFPCSourceUnitRules.Error(Msg: string; DoWriteHelp: Boolean); -begin - writeln('Error: ',Msg); - if DoWriteHelp then begin - writeln; - WriteHelp; - end; - Halt; -end; - -procedure TTestFPCSourceUnitRules.WriteCompilerInfo( - ConfigCache: TFPCTargetConfigCache); -var - i: Integer; - CfgFile: TFPCConfigFileState; -begin - writeln('Compiler=',ConfigCache.Compiler); - writeln('TargetOS=',ConfigCache.TargetOS); - writeln('TargetCPU=',ConfigCache.TargetCPU); - writeln('Options=',ConfigCache.CompilerOptions); - writeln('RealCompiler=',ConfigCache.RealCompiler); - writeln('RealTargetOS=',ConfigCache.RealTargetOS); - writeln('RealTargetCPU=',ConfigCache.RealTargetCPU); - writeln('RealCompilerInPATH=',ConfigCache.RealCompilerInPath); - if ConfigCache.ConfigFiles<>nil then begin - for i:=0 to ConfigCache.ConfigFiles.Count-1 do begin - CfgFile:=ConfigCache.ConfigFiles[i]; - writeln('Config=',CfgFile.Filename,' Exists=',CfgFile.FileExists); - end; - end; -end; - -procedure TTestFPCSourceUnitRules.WriteDuplicatesInPPUPath( - ConfigCache: TFPCTargetConfigCache); -var - i: Integer; - Directory: String; - FileInfo: TSearchRec; - ShortFilename: String; - Filename: String; - Ext: String; - LowerUnitname: String; - SearchPaths: TStrings; - IsSource: Boolean; - IsPPU: Boolean; - SourceFiles: TStringList; - Units: TStringToStringTree; - Item: PStringToStringTreeItem; - Node: TAVLTreeNode; -begin - SearchPaths:=ConfigCache.UnitPaths; - if SearchPaths=nil then exit; - SourceFiles:=TStringList.Create; - Units:=TStringToStringTree.Create(false); - for i:=SearchPaths.Count-1 downto 0 do begin - Directory:=CleanAndExpandDirectory(SearchPaths[i]); - if FindFirstUTF8(Directory+FileMask,faAnyFile,FileInfo)=0 then begin - repeat - ShortFilename:=FileInfo.Name; - if (ShortFilename='') or (ShortFilename='.') or (ShortFilename='..') then - continue; - Filename:=Directory+ShortFilename; - Ext:=LowerCase(ExtractFileExt(ShortFilename)); - IsSource:=(Ext='.pas') or (Ext='.pp') or (Ext='.p'); - IsPPU:=(Ext='.ppu'); - if IsSource then - SourceFiles.Add(Filename); - if IsSource or IsPPU then begin - LowerUnitname:=lowercase(ExtractFileNameOnly(Filename)); - if Units.Contains(LowerUnitname) then - Units[LowerUnitname]:=Units[LowerUnitname]+';'+Filename - else - Units[LowerUnitname]:=Filename; - end; - until FindNextUTF8(FileInfo)<>0; - end; - FindCloseUTF8(FileInfo); - end; - if SourceFiles.Count<>0 then begin - // source files in PPU search path - writeln; - writeln('WARNING: source files found in PPU search paths:'); - writeln(SourceFiles.Text); - writeln; - end; - Node:=Units.Tree.FindLowest; - i:=0; - while Node<>nil do begin - Item:=PStringToStringTreeItem(Node.Data); - Filename:=Item^.Value; - if System.Pos(';',Filename)>0 then begin - // duplicate units - if i=0 then writeln; - inc(i); - writeln('HINT: duplicate unit in PPU path: '+Filename); - end; - Node:=Units.Tree.FindSuccessor(Node); - end; - if i>0 then writeln; - Units.Free; - SourceFiles.Free; -end; - -procedure TTestFPCSourceUnitRules.WriteMissingPPUSources( - UnitSet: TFPCUnitSetCache); -var - UnitToSrc: TStringToStringTree; - Node: TAVLTreeNode; - Item: PStringToStringTreeItem; - ConfigCache: TFPCTargetConfigCache; - aUnitName: String; - Cnt: Integer; - Filename: String; - SourceCache: TFPCSourceCache; - i: Integer; - SrcRules: TFPCSourceRules; - aTree: TStringToStringTree; -begin - UnitToSrc:=UnitSet.GetUnitToSourceTree(false); - ConfigCache:=UnitSet.GetConfigCache(false); - SourceCache:=UnitSet.GetSourceCache(false); - if ConfigCache.Units<>nil then begin - Cnt:=0; - Node:=ConfigCache.Units.Tree.FindLowest; - while Node<>nil do begin - Item:=PStringToStringTreeItem(Node.Data); - aUnitName:=Item^.Name; - Filename:=Item^.Value; - if CompareFileExt(Filename,'ppu',false)=0 then begin - // a ppu in the PPU search path - if UnitToSrc[aUnitName]='' then begin - inc(Cnt); - if Cnt=1 then writeln; - writeln('WARNING: no source found for PPU file: '+Filename); - for i:=0 to SourceCache.Files.Count-1 do begin - if SysUtils.CompareText(ExtractFileNameOnly(SourceCache.Files[i]),aUnitName)=0 - then begin - writeln(' Candidate: ',SourceCache.Files[i]); - SrcRules:=UnitSet.GetSourceRules(false); - aTree:=GatherUnitsInFPCSources(SourceCache.Files, - ConfigCache.RealTargetOS,ConfigCache.RealTargetCPU,nil, - SrcRules,aUnitName); - aTree.Free; - end; - end; - end; - end; - Node:=ConfigCache.Units.Tree.FindSuccessor(Node); - end; - if Cnt>0 then writeln; - end; -end; - -procedure TTestFPCSourceUnitRules.WriteDuplicateSources( - UnitSet: TFPCUnitSetCache); -var - SrcDuplicates: TStringToStringTree; - Node: TAVLTreeNode; - Cnt: Integer; - Item: PStringToStringTreeItem; - aUnitName: String; - Files: String; - Units: TStringToStringTree; - PPUFile: string; -begin - SrcDuplicates:=UnitSet.GetSourceDuplicates(false); - if SrcDuplicates=nil then exit; - Units:=UnitSet.GetConfigCache(false).Units; - - // first list all duplicates with a ppu file (important) - if Units<>nil then begin - Cnt:=0; - Node:=SrcDuplicates.Tree.FindLowest; - while Node<>nil do begin - Item:=PStringToStringTreeItem(Node.Data); - aUnitName:=Item^.Name; - Files:=Item^.Value; - PPUFile:=Units[aUnitName]; - if CompareFileExt(PPUFile,'ppu',false)=0 then begin - if Cnt=0 then writeln; - inc(Cnt); - writeln('WARNING: duplicate source file for ppu ',aUnitName,' files=',Files); - end; - Node:=SrcDuplicates.Tree.FindSuccessor(Node); - end; - if Cnt>0 then writeln; + Src:='if (TargetOS=''win32'') then Result:=3'; end; - // then list all duplicates without a ppu file (unimportant) - Cnt:=0; - Node:=SrcDuplicates.Tree.FindLowest; - while Node<>nil do begin - Item:=PStringToStringTreeItem(Node.Data); - aUnitName:=Item^.Name; - Files:=Item^.Value; - if (Units=nil) or (Units[aUnitName]='') then begin - if Cnt=0 then writeln; - inc(Cnt); - writeln('HINT: duplicate source files: unit=',aUnitName,' files=',Files); - end; - Node:=SrcDuplicates.Tree.FindSuccessor(Node); - end; - if Cnt>0 then writeln; -end; + Engine:=TCTConfigScriptEngine.Create; -procedure TTestFPCSourceUnitRules.WriteUnitReport(UnitSet: TFPCUnitSetCache; - const AnUnitName: string); -var - ConfigCache: TFPCTargetConfigCache; - PPUFile: String; - SourceCache: TFPCSourceCache; - aTree: TStringToStringTree; - SrcRules: TFPCSourceRules; -begin - writeln; - writeln('Unit report for ',AnUnitName); - ConfigCache:=UnitSet.GetConfigCache(false); - - // in ppu search path - PPUFile:=''; - if ConfigCache.Units<>nil then - PPUFile:=ConfigCache.Units[AnUnitName]; - if PPUFile='' then - writeln(' WARNING: ',AnUnitName,' is not in PPU search path') - else if CompareFileExt(PPUFile,'ppu',false)=0 then - writeln(' WARNING: fpc ppu search path has a source and not a ppu for ',AnUnitName,': ',PPUFile) - else - writeln(' in PPU search path: ',PPUFile); - - SourceCache:=UnitSet.GetSourceCache(false); - SrcRules:=UnitSet.GetSourceRules(false); - if SourceCache.Files<>nil then begin - aTree:=GatherUnitsInFPCSources(SourceCache.Files, - ConfigCache.RealTargetOS,ConfigCache.RealTargetCPU,nil, - SrcRules,AnUnitName); - aTree.Free; - end; -end; - -var - Application: TTestFPCSourceUnitRules; -begin - Application:=TTestFPCSourceUnitRules.Create(nil); - Application.Title:='TestFPCSrcUnitRules'; - Application.Run; - Application.Free; + Engine.Free; end.