123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- {
- Copyright (c) 1999-2012 by Peter Vreman, Michael Van Canneyt
- Deletes all files generated for Pascal (*.exe,units,objects,libs)
- This program 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 program 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.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************}
- program Delp;
- {$mode ObjFPC}{$H+}
- uses
- Sysutils,getopts;
- const
- Version = 'Version 1.3';
- Title = 'DelPascal';
- Copyright = 'Copyright (c) 1999-2012 by the Free Pascal Development Team';
- function DStr(l:longint):string;
- var
- TmpStr : string[32];
- i : byte;
- begin
- Str(l,tmpstr);
- i:=Length(TmpStr);
- while (i>3) do
- begin
- i:=i-3;
- if TmpStr[i]<>'-' then
- Insert('.',TmpStr,i+1);
- end;
- DStr:=TmpStr;
- end;
- procedure dosfsplit(path:ansistring;var dir,name,ext:ansistring);
- // implementation of dos.fsplit on top of sysutils routines to avoid
- // path length issues.
- // a lot of old tooling uses fsplit, maybe move this to sysutils?
- begin
- dir:=extractfiledir(dir);
- name:=changefileext(extractfilename(path),'');
- ext:=extractfileext(path);
- if (length(ext)>0) and (ext[1]='.') then
- delete(ext,1,1);
- end;
- function MatchesMask(What, Mask: string): boolean;
- Function CmpStr(const hstr1,hstr2:string):boolean;
- var
- found : boolean;
- i1,i2 : longint;
- begin
- i1:=0;
- i2:=0;
- found:=true;
- while found and (i1<length(hstr1)) and (i2<length(hstr2)) do
- begin
- inc(i2);
- inc(i1);
- case hstr1[i1] of
- '?' :
- found:=true;
- '*' :
- begin
- found:=true;
- if (i1=length(hstr1)) then
- i2:=length(hstr2)
- else
- if (i1<length(hstr1)) and (hstr1[i1+1]<>hstr2[i2]) then
- begin
- if i2<length(hstr2) then
- dec(i1)
- end
- else
- if i2>1 then
- dec(i2);
- end;
- else
- found:=(hstr1[i1]=hstr2[i2]) or (hstr2[i2]='?');
- end;
- end;
- if found then
- begin
- { allow 'p*' matching 'p' }
- if (i1<length(hstr1)) and (hstr1[i1+1]='*') then
- inc(i1);
- found:=(i1>=length(hstr1)) and (i2>=length(hstr2));
- end;
- CmpStr:=found;
- end;
- var
- D1,D2 : ansistring;
- N1,N2 : ansistring;
- E1,E2 : ansistring;
- begin
- {$ifdef Unix}
- DosFSplit(What,D1,N1,E1);
- DosFSplit(Mask,D2,N2,E2);
- {$else}
- DosFSplit(Uppercase(What),D1,N1,E1);
- DosFSplit(Uppercase(Mask),D2,N2,E2);
- {$endif}
- MatchesMask:=CmpStr(N2,N1) and CmpStr(E2,E1);
- end;
- type
- PMaskItem=^TMaskItem;
- TMaskItem=record
- Mask : string[15];
- Files : longint;
- Size : longint;
- Next : PMaskItem;
- end;
- var
- masklist : pmaskitem;
- procedure AddMask(s:string);
- var
- maskitem : PMaskItem;
- i : longint;
- begin
- repeat
- i:=pos(' ',s);
- if i=0 then
- i:=length(s)+1;
- New(maskitem);
- fillchar(maskitem^,sizeof(tmaskitem),0);
- maskitem^.mask:=Copy(s,1,i-1);
- maskitem^.next:=masklist;
- masklist:=maskitem;
- Delete(s,1,i);
- until s='';
- end;
- Var
- quiet : boolean = False;
- Recurse : Boolean = False;
- Verbose : Boolean = False;
- NoDelete : Boolean = False;
- MaxDepth : Integer = 0;
- procedure usage;
- begin
- Writeln('Delp [options] <directory> [<directory2> [<directory3> ...]');
- Writeln('Where options is one of:');
- writeln(' -e Delete executables also (Not on Unix)');
- writeln(' -x ext Add extension to list of extensions to delete (no dot)');
- writeln(' -h Display (this) help message.');
- writeln(' -r Recurse into directories.');
- writeln(' -n Do not actually delete files.');
- writeln(' -m N Maximum depth to recurse into directories (1 based, zero is no max).');
- writeln(' -q Quietly perfoms deleting.');
- writeln(' -v Verbose (print names of deleted files).');
- Halt(1);
- end;
- procedure processoptions;
- Var c : char;
- begin
- quiet:=false;
- Repeat
- C:=Getopt('ehvnqrm:x:');
- Case C of
- 'e' : AddMAsk('*.exe *.so *.dll');
- 'x' : if (optarg<>'') then
- AddMask('*.'+optarg);
- 'h' : Usage;
- 'r' : Recurse:=True;
- 'n' : NoDelete:=True;
- 'm' : MaxDepth:=StrToInt(optarg);
- 'q' : begin
- Quiet:=True;
- verbose:=False;
- end;
- 'v' : Verbose:=True;
- EndOfOptions : ;
- end;
- Until C=EndOfOptions;
- end;
- Procedure DoDir(basedir : string; ALevel : Integer);
- var
- Dir : TSearchrec;
- hp : pmaskitem;
- begin
- if Verbose and not Quiet then
- Writeln('Cleaning directory "',BaseDir,'".');
- if FindFirst(basedir+'*.*',faanyfile,Dir)=0 then
- begin
- repeat
- hp:=masklist;
- while assigned(hp) do
- begin
- if ((Dir.Attr and faDirectory)=0) and MatchesMask(Dir.Name,hp^.mask) then
- begin
- if Verbose then
- Writeln('Deleting "',BaseDir+Dir.Name,'"');
- if not NoDelete then
- DeleteFile(BaseDir+Dir.Name);
- inc(hp^.Files);
- inc(hp^.Size,Dir.Size);
- break;
- end;
- hp:=hp^.next;
- end;
- until FindNext(Dir)<>0;
- FindClose(Dir);
- end;
- if Recurse and ((MaxDepth=0) or (ALevel<=MaxDepth)) then
- if FindFirst(basedir+allfilesmask,faanyfile,Dir)=0 then
- begin
- Repeat
- if ((Dir.Attr and faDirectory)=faDirectory) and Not ((Dir.Name='.') or (Dir.Name='..')) then
- DoDir(IncludeTrailingPathDelimiter(BaseDir+Dir.Name),ALevel+1);
- until FindNext(Dir)<>0;
- FindClose(Dir);
- end;
- end;
- Procedure PrintResults;
- var
- Total : longint;
- found : boolean;
- hp : pmaskitem;
- begin
- { Write Results }
- Total:=0;
- found:=false;
- hp:=masklist;
- while assigned(hp) do
- begin
- if hp^.Files>0 then
- begin
- WriteLn(' - Removed ',hp^.Files:2,' ',hp^.Mask,' (',DStr(hp^.Size)+' Bytes)');
- inc(Total,hp^.Size);
- found:=true;
- end;
- hp:=hp^.next;
- end;
- if not found then
- WriteLn(' - No Redundant Files Found!')
- else
- WriteLn(' - Total ',DStr(Total),' Bytes Freed');
- end;
- var
- basedir : string;
- i : Integer;
- begin
- ProcessOptions;
- I:=OptInd;
- if (OptInd=0) or (OptInd>ParamCount) then
- Usage;
- { Win32 target }
- AddMask('*.ppw *.ow *.aw *.sw');
- AddMask('ppas.bat ppas.sh link.res fpcmaked fpcmade fpcmade.*');
- AddMask('*.tpu *.tpp *.tpw *.tr');
- AddMask('*.dcu *.dcp *.bpl');
- AddMask('*.log *.bak *.~pas *.~pp *.*~');
- AddMask('*.ppu *.o *.a *.s *.or *.compiled');
- AddMask('*.pp1 *.o1 *.a1 *.s1');
- AddMask('*.ppo *.oo *.ao *.so');
- AddMask('*.rst *.rsj');
- { OS/2 target }
- AddMask('*.oo2 *.so2 *.ppo');
- { Amiga target }
- AddMask('*.ppa *.asm');
- if not quiet then
- begin
- writeln(Title+' '+Version);
- writeln(Copyright);
- Writeln;
- end;
- While (I<=ParamCount) do
- begin
- BaseDir:=IncludeTrailingPathDelimiter(Paramstr(I));
- DoDir(Basedir,1);
- Inc(I);
- end;
- if Not Quiet then
- PrintResults;
- end.
|