/////////////////////////////////////////////////////////// // CodeFromLCL // // Модуль с кусочками кода, выдранными из LCL // // Copyright (C) 1999-2000 Free Pascal development team // // Распространяется на условиях // // LGPL v2.1 // // // // www.gipatgroup.org // /////////////////////////////////////////////////////////// //К работе над данным файлом приложили руки, ноги.... короче аффтары: // 1) Free Pascal development team // 2) Sagrer (sagrer@yandex.ru) //Included code from LCL's FileUtil, SysUtils modules. //////////////////////////////////////////////////////////////////////// unit CodeFromLCL; {$IFDEF FPC} {$mode objfpc} {$ENDIF FPC} {$H+} interface uses Windows, SysUtils, StrUtils; const AllDirectoryEntriesMask = '*'; Type TGetAppNameEvent = Function : String; TGetTempDirEvent = Function (Global : Boolean) : String; TGetTempFileEvent = Function (Const Dir,Prefix : String) : String; Var OnGetApplicationName : TGetAppNameEvent; OnGetTempDir : TGetTempDirEvent; OnGetTempFile : TGetTempFileEvent; //Функции SysUtils из LCL Function GetTempDir(Global : Boolean) : String; overload; Function GetTempDir : String; overload; Function GetEnvironmentVariable(Const EnvVar : String) : String; //Функции FileUtil из LCL function ChompPathDelim(const Path: string): string; function AppendPathDelim(const Path: string): string; function GetAllFilesMask: string; function TrimFilename(const AFilename: string): string; function CleanAndExpandFilename(const Filename: string): string; function CleanAndExpandDirectory(const Filename: string): string; function DeleteDirectory(const DirectoryName: string; OnlyChilds: boolean): boolean; implementation ///////////////////////////////////////////////// // Функции SysUtils из LCL // ///////////////////////////////////////////////// Function GetEnvironmentVariable(Const EnvVar : String) : String; var s : string; i : longint; hp,p : pchar; begin Result:=''; p:=GetEnvironmentStrings; hp:=p; while hp^<>#0 do begin s:=strpas(hp); i:=pos('=',s); if uppercase(copy(s,1,i-1))=uppercase(envvar) then begin Result:=copy(s,i+1,length(s)-i); break; end; { next string entry} hp:=hp+strlen(hp)+1; end; FreeEnvironmentStrings(p); end; {$ifndef HAS_TEMPDIR} Function GetTempDir(Global : Boolean) : String; overload; begin If Assigned(OnGetTempDir) then Result:=OnGetTempDir(Global) else begin Result:=GetEnvironmentVariable('TEMP'); If (Result='') Then Result:=GetEnvironmentVariable('TMP'); end; if (Result<>'') then Result:=IncludeTrailingPathDelimiter(Result); end; {$endif} Function GetTempDir : String; overload; begin Result:=GetTempDir(True); end; ///////////////////////////////////////////////// // Функции FileUtil из LCL // ///////////////////////////////////////////////// {------------------------------------------------------------------------------ function ChompPathDelim(const Path: string): string; ------------------------------------------------------------------------------} function ChompPathDelim(const Path: string): string; begin if (Path<>'') and (Path[length(Path)]=PathDelim) then Result:=LeftStr(Path,length(Path)-1) else Result:=Path; end; {------------------------------------------------------------------------------ function AppendPathDelim(const Path: string): string; ------------------------------------------------------------------------------} function AppendPathDelim(const Path: string): string; begin if (Path<>'') and (Path[length(Path)]<>PathDelim) then Result:=Path+PathDelim else Result:=Path; end; {------------------------------------------------------------------------------ function TrimFilename(const AFilename: string): string; ------------------------------------------------------------------------------} function TrimFilename(const AFilename: string): string; // trim double path delims, heading and trailing spaces // and special dirs . and .. function FilenameIsTrimmed(const TheFilename: string): boolean; var l: Integer; i: Integer; begin Result:=false; if TheFilename='' then begin Result:=true; exit; end; // check heading spaces if TheFilename[1]=' ' then exit; // check trailing spaces l:=length(TheFilename); if TheFilename[l]=' ' then exit; i:=1; while i<=l do begin case TheFilename[i] of PathDelim: // check for double path delimiter if (i1)) then exit; // check for .. directories if (i=1) and (AFilename[l]=' ') do dec(l); // skip heading spaces while (SrcPos<=l) and (AFilename[SrcPos]=' ') do inc(SrcPos); // trim double path delims and special dirs . and .. while (SrcPos<=l) do begin c:=AFilename[SrcPos]; // check for double path delims if (c=PathDelim) then begin inc(SrcPos); {$IFDEF WINDOWS} if (DestPos>2) {$ELSE} if (DestPos>1) {$ENDIF} and (Result[DestPos-1]=PathDelim) then begin // skip second PathDelim continue; end; Result[DestPos]:=c; inc(DestPos); continue; end; // check for special dirs . and .. if (c='.') then begin if (SrcPos skip inc(SrcPos,2); continue; end else if (AFilename[SrcPos+1]='.') and (SrcPos+1=l) or (AFilename[SrcPos+2]=PathDelim) then begin // special dir .. // 1. .. -> keep // 2. /.. -> skip .., keep / // 3. C:.. -> keep // 4. C:\.. -> skip .., keep C:\ // 5. \\.. -> skip .., keep \\ // 6. xxx../.. -> keep // 7. xxxdir$Macro/.. -> keep // 8. xxxdir/.. -> trim dir and skip .. if DestPos=1 then begin // 1. .. -> keep end else if (DestPos=2) and (Result[1]=PathDelim) then begin // 2. /.. -> skip .., keep / inc(SrcPos,2); continue; {$IFDEF WINDOWS} end else if (DestPos=3) and (Result[2]=':') and (Result[1] in ['a'..'z','A'..'Z']) then begin // 3. C:.. -> keep end else if (DestPos=4) and (Result[2]=':') and (Result[3]=PathDelim) and (Result[1] in ['a'..'z','A'..'Z']) then begin // 4. C:\.. -> skip .., keep C:\ inc(SrcPos,2); continue; end else if (DestPos=3) and (Result[1]=PathDelim) and (Result[2]=PathDelim) then begin // 5. \\.. -> skip .., keep \\ inc(SrcPos,2); continue; {$ENDIF} end else if (DestPos>1) and (Result[DestPos-1]=PathDelim) then begin if (DestPos>3) and (Result[DestPos-2]='.') and (Result[DestPos-3]='.') and ((DestPos=4) or (Result[DestPos-4]=PathDelim)) then begin // 6. ../.. -> keep end else begin // 7. xxxdir/.. -> trim dir and skip .. DirStart:=DestPos-2; while (DirStart>1) and (Result[DirStart-1]<>PathDelim) do dec(DirStart); MacroPos:=DirStart; while MacroPos keep break; end; inc(MacroPos); end; if MacroPos=DestPos then begin DestPos:=DirStart; inc(SrcPos,2); continue; end; end; end; end; end else begin // special dir . at end of filename if DestPos=1 then begin Result:='.'; exit; end else begin // skip break; end; end; end; // copy directory repeat Result[DestPos]:=c; inc(DestPos); inc(SrcPos); if (SrcPos>l) then break; c:=AFilename[SrcPos]; if c=PathDelim then break; until false; end; // trim result if DestPos<=length(AFilename) then SetLength(Result,DestPos-1); end; {------------------------------------------------------------------------------ function CleanAndExpandFilename(const Filename: string): string; ------------------------------------------------------------------------------} function CleanAndExpandFilename(const Filename: string): string; begin Result:=ExpandFilename(TrimFileName(Filename)); end; {------------------------------------------------------------------------------ function CleanAndExpandDirectory(const Filename: string): string; ------------------------------------------------------------------------------} function CleanAndExpandDirectory(const Filename: string): string; begin Result:=AppendPathDelim(CleanAndExpandFilename(Filename)); end; function GetAllFilesMask: string; begin {$IFDEF WINDOWS} Result:='*.*'; {$ELSE} Result:='*'; {$ENDIF} end; {------------------------------------------------------------------------------ function DeleteDirectory(const DirectoryName: string; OnlyChilds: boolean): boolean; ------------------------------------------------------------------------------} function DeleteDirectory(const DirectoryName: string; OnlyChilds: boolean): boolean; var FileInfo: TSearchRec; CurSrcDir: String; CurFilename: String; begin Result:=false; CurSrcDir:=CleanAndExpandDirectory(DirectoryName); if SysUtils.FindFirst(CurSrcDir+GetAllFilesMask,faAnyFile,FileInfo)=0 then begin repeat // check if special file if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='') then continue; CurFilename:=CurSrcDir+FileInfo.Name; if (FileInfo.Attr and faDirectory)>0 then begin if not DeleteDirectory(CurFilename,false) then exit; end else begin if not DeleteFile(CurFilename) then exit; end; until SysUtils.FindNext(FileInfo)<>0; end; SysUtils.FindClose(FileInfo); if (not OnlyChilds) and (not RemoveDir(DirectoryName)) then exit; Result:=true; end; end.