| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 | {    Copyright (c) 1998-2002 by Peter Vreman    This unit handles the compilerhooks for output to external programs    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. ****************************************************************************}unit comphook;{$i fpcdefs.inc}interfaceuses{$IFNDEF USE_FAKE_SYSUTILS}  sysutils,{$ELSE}  fksysutl,{$ENDIF}  globtype,  finput;Const  { Levels }  V_None         = $0;  V_Fatal        = $1;  V_Error        = $2;  V_Normal       = $4; { doesn't show a text like Error: }  V_Warning      = $8;  V_Note         = $10;  V_Hint         = $20;  V_LineInfoMask = $fff;  { From here by default no line info }  V_Info         = $1000;  V_Status       = $2000;  V_Used         = $4000;  V_Tried        = $8000;  V_Conditional  = $10000;  V_Debug        = $20000;  V_Executable   = $40000;  V_TimeStamps   = $80000;  V_LevelMask    = $fffffff;  V_All          = V_LevelMask;  V_Default      = V_Fatal + V_Error + V_Normal;  { Flags }  V_LineInfo     = $10000000;const  { RHIDE expect gcc like error output }  fatalstr      : string[20] = 'Fatal:';  errorstr      : string[20] = 'Error:';  warningstr    : string[20] = 'Warning:';  notestr       : string[20] = 'Note:';  hintstr       : string[20] = 'Hint:';type  PCompilerStatus = ^TCompilerStatus;  TCompilerStatus = record  { Current status }    currentmodule,    currentsourcepath,    currentsource : string;   { filename }    currentline,    currentcolumn : longint;  { current line and column }    currentmodulestate : string[20];  { Total Status }    compiledlines : longint;  { the number of lines which are compiled }    errorcount,               { this field should never be increased directly,                                use Verbose.GenerateError procedure to do this,                                this allows easier error catching using GDB by                                adding a single breakpoint at this procedure }    countWarnings,    countNotes,    countHints    : longint;  { number of found errors/warnings/notes/hints }    codesize,    datasize      : qword;  { program info }    isexe,    ispackage,    islibrary     : boolean;  { Settings for the output }    showmsgnrs    : boolean;    verbosity     : longint;    maxerrorcount : longint;    errorwarning,    errornote,    errorhint,    skip_error,    use_stderr,    use_redir,    use_bugreport,    use_gccoutput,    print_source_path : boolean;  { Redirection support }    redirfile : text;  { Special file for bug report }    reportbugfile : text;  end;type  EControlCAbort=class(Exception)    constructor Create;  end;  ECompilerAbort=class(Exception)    constructor Create;  end;  ECompilerAbortSilent=class(Exception)    constructor Create;  end;var  status : tcompilerstatus;{ Default Functions }Function  def_status:boolean;Function  def_comment(Level:Longint;const s:ansistring):boolean;function  def_internalerror(i:longint):boolean;function  def_CheckVerbosity(v:longint):boolean;procedure def_initsymbolinfo;procedure def_donesymbolinfo;procedure def_extractsymbolinfo;function  def_openinputfile(const filename: TPathStr): tinputfile;Function  def_getnamedfiletime(Const F : TPathStr) : Longint;{ Function redirecting for IDE support }type  tstopprocedure         = procedure(err:longint);  tstatusfunction        = function:boolean;  tcommentfunction       = function(Level:Longint;const s:ansistring):boolean;  tinternalerrorfunction = function(i:longint):boolean;  tcheckverbosityfunction = function(i:longint):boolean;  tinitsymbolinfoproc = procedure;  tdonesymbolinfoproc = procedure;  textractsymbolinfoproc = procedure;  topeninputfilefunc = function(const filename: TPathStr): tinputfile;  tgetnamedfiletimefunc = function(const filename: TPathStr): longint;const  do_status        : tstatusfunction  = @def_status;  do_comment       : tcommentfunction = @def_comment;  do_internalerror : tinternalerrorfunction = @def_internalerror;  do_checkverbosity : tcheckverbosityfunction = @def_checkverbosity;  do_initsymbolinfo : tinitsymbolinfoproc = @def_initsymbolinfo;  do_donesymbolinfo : tdonesymbolinfoproc = @def_donesymbolinfo;  do_extractsymbolinfo : textractsymbolinfoproc = @def_extractsymbolinfo;  needsymbolinfo : boolean =false;  do_openinputfile : topeninputfilefunc = @def_openinputfile;  do_getnamedfiletime : tgetnamedfiletimefunc = @def_getnamedfiletime;implementation  uses   cutils, systems, globals   ;{****************************************************************************                          Helper Routines****************************************************************************}function gccfilename(const s : string) : string;var  i : longint;begin  for i:=1to length(s) do   begin     case s[i] of      '\' : gccfilename[i]:='/'; 'A'..'Z' : if not (tf_files_case_aware in source_info.flags) and               not (tf_files_case_sensitive in source_info.flags) then              gccfilename[i]:=chr(ord(s[i])+32)            else              gccfilename[i]:=s[i];     else      gccfilename[i]:=s[i];     end;   end;  gccfilename[0]:=s[0];end;function tostr(i : longint) : string;var  hs : string;begin  str(i,hs);  tostr:=hs;end;{****************************************************************************                          Stopping the compiler****************************************************************************}constructor EControlCAbort.Create;  begin    inherited Create('Ctrl-C Signaled!');  end;constructor ECompilerAbort.Create;  begin    inherited Create('Compilation Aborted');  end;constructor ECompilerAbortSilent.Create;  begin    inherited Create('Compilation Aborted');  end;{****************************************************************************                         Predefined default Handlers****************************************************************************}function def_status:boolean;var  hstatus : TFPCHeapStatus;begin  def_status:=false; { never stop }{ Status info?, Called every line }  if ((status.verbosity and V_Status)<>0) then   begin     if (status.compiledlines=1) or        (status.currentline mod 100=0) then       begin         if status.currentline>0 then           Write(status.currentline,' ');         hstatus:=GetFPCHeapStatus;         WriteLn(DStr(hstatus.CurrHeapUsed shr 10),'/',DStr(hstatus.CurrHeapSize shr 10),' Kb Used');       end;   end;{$ifdef macos}  Yield;{$endif}end;Function def_comment(Level:Longint;const s:ansistring):boolean;const  rh_errorstr   = 'error:';  rh_warningstr = 'warning:';var  hs : ansistring;  hs2 : ansistring;begin  def_comment:=false; { never stop }  hs:='';  if not(status.use_gccoutput) then    begin      if (status.verbosity and Level)=V_Hint then        hs:=hintstr;      if (status.verbosity and Level)=V_Note then        hs:=notestr;      if (status.verbosity and Level)=V_Warning then        hs:=warningstr;      if (status.verbosity and Level)=V_Error then        hs:=errorstr;      if (status.verbosity and Level)=V_Fatal then        hs:=fatalstr;      if (status.verbosity and Level)=V_Used then        hs:=PadSpace('('+status.currentmodule+')',10);    end  else    begin      if (status.verbosity and Level)=V_Hint then        hs:=rh_warningstr;      if (status.verbosity and Level)=V_Note then        hs:=rh_warningstr;      if (status.verbosity and Level)=V_Warning then        hs:=rh_warningstr;      if (status.verbosity and Level)=V_Error then        hs:=rh_errorstr;      if (status.verbosity and Level)=V_Fatal then        hs:=rh_errorstr;    end;  { Generate line prefix }  if ((Level and V_LineInfo)=V_LineInfo) and     (status.currentsource<>'') and     (status.currentline>0) then   begin     {$ifndef macos}     { Adding the column should not confuse RHIDE,     even if it does not yet use it PM     but only if it is after error or warning !! PM }     if status.currentcolumn>0 then      begin        if status.use_gccoutput then          hs:=gccfilename(status.currentsource)+':'+tostr(status.currentline)+': '+hs+' '+              tostr(status.currentcolumn)+': '+s        else          begin            hs:=status.currentsource+'('+tostr(status.currentline)+              ','+tostr(status.currentcolumn)+') '+hs+' '+s;          end;        if status.print_source_path then          hs:=status.currentsourcepath+hs;      end     else      begin        if status.use_gccoutput then          hs:=gccfilename(status.currentsource)+': '+hs+' '+tostr(status.currentline)+': '+s        else          hs:=status.currentsource+'('+tostr(status.currentline)+') '+hs+' '+s;      end;     {$else}     {MPW style error}     if status.currentcolumn>0 then       hs:='File "'+status.currentsourcepath+status.currentsource+'"; Line '+tostr(status.currentline)+         ' #[' + tostr(status.currentcolumn) + '] ' +hs+' '+s     else       hs:='File "'+status.currentsourcepath+status.currentsource+'"; Line '+tostr(status.currentline)+' # '+hs+' '+s;     {$endif}   end  else   begin     if hs<>'' then      hs:=hs+' '+s     else      hs:=s;   end;  if (status.verbosity and V_TimeStamps)<>0 then    begin      system.str(getrealtime-starttime:0:3,hs2);      hs:='['+hs2+'] '+hs;    end;  { Display line }  if (Level<>V_None) and     ((status.verbosity and (Level and V_LevelMask))=(Level and V_LevelMask)) then   begin     if status.use_stderr then      begin        writeln(stderr,hs);        flush(stderr);      end     else      begin        if status.use_redir then         writeln(status.redirfile,hs)        else         writeln(hs);      end;   end;  { include everything in the bugreport file }  if status.use_bugreport then   begin     Write(status.reportbugfile,hexstr(level,8)+':');     Writeln(status.reportbugfile,hs);   end;end;function def_internalerror(i : longint) : boolean;begin  do_comment(V_Fatal+V_LineInfo,'Internal error '+tostr(i));{$ifdef EXTDEBUG}  { Internalerror() and def_internalerror() do not    have a stackframe }  dump_stack(stdout,get_caller_frame(get_frame));{$endif EXTDEBUG}  def_internalerror:=true;end;function def_CheckVerbosity(v:longint):boolean;begin  result:=status.use_bugreport or          ((v<>V_None) and           ((status.verbosity and (v and V_LevelMask))=(v and V_LevelMask)));end;procedure def_initsymbolinfo;beginend;procedure def_donesymbolinfo;beginend;procedure def_extractsymbolinfo;beginend;function  def_openinputfile(const filename: TPathStr): tinputfile;begin  def_openinputfile:=tdosinputfile.create(filename);end;Function def_GetNamedFileTime (Const F : TPathStr) : Longint;begin  Result:=FileAge(F);end;end.
 |