| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542 | {    This file is part of the Free Pascal run time library.    Copyright (c) 1999-2000 by Florian Klaempfl    member of the Free Pascal development team    See the file COPYING.FPC, included in this distribution,    for details about the copyright.    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. **********************************************************************}  { Read filename handling functions implementation }  {$i fina.inc}    Function FileSearch (Const Name, DirList : String) : String;    Var      I : longint;      Temp : String;    begin      Result:='';      temp:=Dirlist;      repeat        While (Length(Temp)>0) and (Temp[1]=PathSeparator) do          Delete(Temp,1,1);        I:=pos(PathSep,Temp);        If I<>0 then          begin            Result:=Copy (Temp,1,i-1);            system.Delete(Temp,1,I);          end        else          begin            Result:=Temp;            Temp:='';          end;        If (Length(Result)>0) and (result[length(result)]<>DirectorySeparator) then          Result:=Result+DirectorySeparator;        Result:=Result+name;        If not FileExists(Result) Then         Result:='';      until (length(temp)=0) or (length(result)<>0);    end;  {$ifndef OS_FILEISREADONLY}  Function FileIsReadOnly(const FileName: String): Boolean;  begin    Result := (FileGetAttr(FileName) and faReadOnly) <> 0;  end;  {$endif OS_FILEISREADONLY}  {$ifndef OS_FILESETDATEBYNAME}  Function FileSetDate (Const FileName : String;Age : Longint) : Longint;  Var    fd : longint;  begin    fd:=FileOpen(FileName,fmOpenRead);    If (Fd>=0) then      try        Result:=FileSetDate(fd,Age);      finally        FileClose(fd);      end    else      Result:=Fd;  end;  {$endif}  { Read String Handling functions implementation }  {$i sysstr.inc}  { Read date & Time function implementations }  {$i dati.inc}  { Read pchar handling functions implementation }  {$i syspch.inc}  { generic internationalisation code }  {$i sysint.inc}  { MCBS functions }  {$i sysansi.inc}  { wide string functions }  {$i syswide.inc}  { threading stuff }  {$i sysuthrd.inc}  { CPU Specific code }  {$i sysutilp.inc}  { OS utility code }  {$i osutil.inc}    procedure FreeAndNil(var obj);      var        temp: tobject;      begin        temp:=tobject(obj);        pointer(obj):=nil;        temp.free;      end;  { Interfaces support }  {$i sysuintf.inc}    constructor Exception.Create(const msg : string);      begin         inherited create;         fmessage:=msg;      end;    constructor Exception.CreateFmt(const msg : string; const args : array of const);      begin         inherited create;         fmessage:=Format(msg,args);      end;    constructor Exception.CreateRes(ResString: PString);      begin         inherited create;         fmessage:=ResString^;      end;    constructor Exception.CreateResFmt(ResString: PString; const Args: array of const);      begin         inherited create;         fmessage:=Format(ResString^,args);      end;    constructor Exception.CreateHelp(const Msg: string; AHelpContext: Integer);      begin         inherited create;         fmessage:=Msg;         fhelpcontext:=AHelpContext;      end;    constructor Exception.CreateFmtHelp(const Msg: string; const Args: array of const;      AHelpContext: Integer);    begin       inherited create;       fmessage:=Format(Msg,args);       fhelpcontext:=AHelpContext;    end;    constructor Exception.CreateResHelp(ResString: PString; AHelpContext: Integer);    begin       inherited create;       fmessage:=ResString^;       fhelpcontext:=AHelpContext;    end;    constructor Exception.CreateResFmtHelp(ResString: PString; const Args: array of const;      AHelpContext: Integer);    begin       inherited create;       fmessage:=Format(ResString^,args);       fhelpcontext:=AHelpContext;    end;    procedure EHeapMemoryError.FreeInstance;    begin       if AllowFree then        inherited FreeInstance;    end;{$ifopt S+}{$define STACKCHECK_WAS_ON}{$S-}{$endif OPT S }Procedure CatchUnhandledException (Obj : TObject; Addr: Pointer; FrameCount: Longint; Frames: PPointer);[public,alias:'FPC_BREAK_UNHANDLED_EXCEPTION'];Var  Message : String;  i : longint;begin  Writeln(stdout,'An unhandled exception occurred at $',HexStr(Ptrint(Addr),sizeof(PtrInt)*2),' :');  if Obj is exception then   begin     Message:=Exception(Obj).ClassName+' : '+Exception(Obj).Message;     Writeln(stdout,Message);   end  else   Writeln(stdout,'Exception object ',Obj.ClassName,' is not of class Exception.');  Writeln(stdout,BackTraceStrFunc(Addr));  if (FrameCount>0) then    begin      for i:=0 to FrameCount-1 do        Writeln(stdout,BackTraceStrFunc(Frames[i]));    end;  Halt(217);end;Var OutOfMemory : EOutOfMemory;    InValidPointer : EInvalidPointer;Procedure RunErrorToExcept (ErrNo : Longint; Address,Frame : Pointer);Var E : Exception;    S : String;begin  Case Errno of   1,203 : E:=OutOfMemory;   204 : E:=InvalidPointer;   2,3,4,5,6,100,101,102,103,105,106 : { I/O errors }     begin     Case Errno of       2 : S:=SFileNotFound;       3 : S:=SInvalidFileName;       4 : S:=STooManyOpenFiles;       5 : S:=SAccessDenied;       6 : S:=SInvalidFileHandle;       15 : S:=SInvalidDrive;       100 : S:=SEndOfFile;       101 : S:=SDiskFull;       102 : S:=SFileNotAssigned;       103 : S:=SFileNotOpen;       104 : S:=SFileNotOpenForInput;       105 : S:=SFileNotOpenForOutput;       106 : S:=SInvalidInput;     end;     E:=EinOutError.Create (S);     EInoutError(E).ErrorCode:=IOresult; // Clears InOutRes !!     end;  // We don't set abstracterrorhandler, but we do it here.  // Unless the use sets another handler we'll get here anyway...  200 : E:=EDivByZero.Create(SDivByZero);  201 : E:=ERangeError.Create(SRangeError);  205 : E:=EOverflow.Create(SOverflow);  206 : E:=EOverflow.Create(SUnderflow);  207 : E:=EInvalidOp.Create(SInvalidOp);  211 : E:=EAbstractError.Create(SAbstractError);  214 : E:=EBusError.Create(SBusError);  215 : E:=EIntOverflow.Create(SIntOverflow);  216 : E:=EAccessViolation.Create(SAccessViolation);  217 : E:=EPrivilege.Create(SPrivilege);  218 : E:=EControlC.Create(SControlC);  219 : E:=EInvalidCast.Create(SInvalidCast);  220 : E:=EVariantError.Create(SInvalidVarCast);  221 : E:=EVariantError.Create(SInvalidVarOp);  222 : E:=EVariantError.Create(SDispatchError);  223 : E:=EVariantError.Create(SVarArrayCreate);  224 : E:=EVariantError.Create(SVarNotArray);  225 : E:=EVariantError.Create(SVarArrayBounds);  227 : E:=EAssertionFailed.Create(SAssertionFailed);  228 : E:=EExternalException.Create(SExternalException);  229 : E:=EIntfCastError.Create(SIntfCastError);  230 : E:=ESafecallException.Create(SSafecallException);  232 : E:=ENoThreadSupport.Create(SNoThreadSupport);  else   E:=Exception.CreateFmt (SUnKnownRunTimeError,[Errno]);  end;  Raise E at Address,Frame;end;{$IFDEF HAS_OSERROR}Procedure RaiseLastOSError;var  ECode: Cardinal;  E : EOSError;begin  ECode := GetLastOSError;  If (ECode<>0) then    E:=EOSError.CreateFmt(SOSError, [ECode, SysErrorMessage(ECode)])  else    E:=EOSError.Create(SUnkOSError);  E.ErrorCode:=ECode;  Raise E;end;{$else}Procedure RaiseLastOSError;begin  Raise Exception.Create('RaiseLastOSError not implemented on this platform.');end;{$endif}Procedure AssertErrorHandler (Const Msg,FN : ShortString;LineNo:longint; TheAddr : pointer);Var  S : String;begin  If Msg='' then    S:=SAssertionFailed  else    S:=Msg;  Raise EAssertionFailed.Createfmt(SAssertError,[S,Fn,LineNo]); // at Pointer(theAddr);end;{$ifdef STACKCHECK_WAS_ON}{$S+}{$endif}Procedure InitExceptions;{  Must install uncaught exception handler (ExceptProc)  and install exceptions for system exceptions or signals.  (e.g: SIGSEGV -> ESegFault or so.)}begin  ExceptProc:=@CatchUnhandledException;  // Create objects that may have problems when there is no memory.  OutOfMemory:=EOutOfMemory.Create(SOutOfMemory);  OutOfMemory.AllowFree:=false;  InvalidPointer:=EInvalidPointer.Create(SInvalidPointer);  InvalidPointer.AllowFree:=false;  AssertErrorProc:=@AssertErrorHandler;  ErrorProc:=@RunErrorToExcept;  OnShowException:=Nil;end;Procedure DoneExceptions;begin  OutOfMemory.AllowFree:=true;  OutOfMemory.Free;  InValidPointer.AllowFree:=true;  InValidPointer.Free;end;{ Exception handling routines }function ExceptObject: TObject;begin  If RaiseList=Nil then    Result:=Nil  else    Result:=RaiseList^.FObject;end;function ExceptAddr: Pointer;begin  If RaiseList=Nil then    Result:=Nil  else    Result:=RaiseList^.Addr;end;function ExceptFrameCount: Longint;begin  If RaiseList=Nil then    Result:=0  else    Result:=RaiseList^.Framecount;end;function ExceptFrames: PPointer;begin  If RaiseList=Nil then    Result:=Nil  else    Result:=RaiseList^.Frames;end;function ExceptionErrorMessage(ExceptObject: TObject; ExceptAddr: Pointer;                               Buffer: PChar; Size: Integer): Integer;Var  S : AnsiString;  Len : Integer;begin  S:=Format(SExceptionErrorMessage,[ExceptAddr,ExceptObject.ClassName]);  If ExceptObject is Exception then    S:=Format('%s:'#10'%s',[S,Exception(ExceptObject).Message]);  Len:=Length(S);  If S[Len]<>'.' then    begin    S:=S+'.';    Inc(len);    end;  If Len>Size then    Len:=Size;  if Len > 0 then    Move(S[1],Buffer^,Len);  Result:=Len;end;procedure ShowException(ExceptObject: TObject; ExceptAddr: Pointer);// use shortstring. On exception, the heap may be corrupt.Var  Buf : ShortString;begin  SetLength(Buf,ExceptionErrorMessage(ExceptObject,ExceptAddr,@Buf[1],255));  If IsConsole Then    writeln(Buf)  else    If Assigned(OnShowException) Then      OnShowException (Buf);end;procedure Abort;begin  Raise EAbort.Create(SAbortError) at Pointer(Get_Caller_addr(Get_Frame));end;procedure OutOfMemoryError;begin  Raise OutOfMemory;end;{ ---------------------------------------------------------------------    Initialization/Finalization/exit code  ---------------------------------------------------------------------}Type  PPRecord = ^TPRecord;  TPRecord = Record    Func : TTerminateProc;    NextFunc : PPRecord;  end;Const  TPList : PPRecord = Nil;procedure AddTerminateProc(TermProc: TTerminateProc);Var  TPR : PPRecord;begin  New(TPR);  With TPR^ do    begin    NextFunc:=TPList;    Func:=TermProc;    end;  TPList:=TPR;end;function CallTerminateProcs: Boolean;Var  TPR : PPRecord;begin  Result:=True;  TPR:=TPList;  While Result and (TPR<>Nil) do    begin    Result:=TPR^.Func();    TPR:=TPR^.NextFunc;    end;end;{ ---------------------------------------------------------------------    Diskh functions, OS independent.  ---------------------------------------------------------------------}function ForceDirectories(Const Dir: string): Boolean;var  E: EInOutError;  ADir : String;begin  Result:=True;  ADir:=ExcludeTrailingPathDelimiter(Dir);  if (ADir='') then    begin    E:=EInOutError.Create(SCannotCreateEmptyDir);    E.ErrorCode:=3;    Raise E;    end;  if Not DirectoryExists(ADir) then    begin    Result:=ForceDirectories(ExtractFilePath(ADir));    If Result then      CreateDir(ADir);    end;end;Procedure GetRandomBytes(Var Buf; NBytes : Integer);Var  I : Integer;  P : PByte;begin  P:=@Buf;  Randomize;  For I:=0 to NBytes-1 do    P[i]:=Random(256);end;{$IFDEF HASCREATEGUID}Function SysCreateGUID(out GUID : TGUID) : Integer; forward;{$ENDIF}Function CreateGUID(out GUID : TGUID) : Integer;begin  If Assigned(OnCreateGUID) then    Result:=OnCreateGUID(GUID)  else    begin    {$IFDEF HASCREATEGUID}    Result:=SysCreateGUID(GUID);    {$ELSE}    GetRandomBytes(GUID,SizeOf(Guid));    Result:=0;    {$ENDIF}    end;end;
 |