| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 | {    This unit is the interface of the compiler which can be used by    external programs to link in the compiler    Copyright (c) 1998-2005 by Florian Klaempfl    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 compiler;{$i fpcdefs.inc}{ some units are implicitly needed by the compiler }{$WARN 5023 off : Unit "$1" not used in $2}interfaceuses{$ifdef GO32V2}  emu387,{$endif GO32V2}{$ifdef WATCOM}  emu387,{$endif WATCOM}{$if defined(unix)}  { system code page stuff for unix }  unixcp,  fpwidestring,{$endif}{$IFNDEF USE_FAKE_SYSUTILS}  sysutils,math,{$ELSE}  fksysutl,{$ENDIF}  verbose,comphook,systems,  cutils,cfileutl,cclasses,globals,options,fmodule,parser,symtable,  assemble,link,dbgbase,import,export,tokens,wpo  { cpu parameter handling }  ,cpupara  { procinfo stuff }  ,cpupi  { cpu codegenerator }  ,cgcpu{$ifndef NOPASS2}  ,cpunode{$endif}  { cpu targets }  ,cputarg{$ifdef llvm}  ,llvmtarg{$endif llvm}  { system information for source system }  { the information about the target os  }  { are pulled in by the t_* units       }{$ifdef amiga}  ,i_amiga{$endif amiga}{$ifdef android}  ,i_android{$endif android}{$ifdef aros}  ,i_aros{$endif}{$ifdef atari}  ,i_atari{$endif atari}{$ifdef beos}  ,i_beos{$endif beos}{$ifdef bsd}{$ifdef darwin}  ,i_darwin{$else darwin}  ,i_bsd{$endif darwin}{$endif bsd}{$ifdef gba}  ,i_gba{$endif gba}{$ifdef go32v2}  ,i_go32v2{$endif go32v2}{$ifdef haiku}  ,i_haiku{$endif haiku}{$ifdef linux}  ,i_linux{$endif linux}{$ifdef macos}  ,i_macos{$endif macos}{$ifdef morphos}  ,i_morph{$endif morphos}{$ifdef nds}  ,i_nds{$endif nds}{$ifdef nwm}  ,i_nwm{$endif nwm}{$ifdef nwl}  ,i_nwl{$endif nwm}{$ifdef os2} {$ifdef emx}  ,i_emx {$else emx}  ,i_os2 {$endif emx}{$endif os2}{$ifdef palmos}  ,i_palmos{$endif palmos}{$ifdef solaris}  ,i_sunos{$endif solaris}{$ifdef sinclairql}  ,i_sinclairql{$endif sinclairql}{$ifdef wdosx}  ,i_wdosx{$endif wdosx}{$ifdef wii}  ,i_wii{$endif wii}{$ifdef windows}  ,i_win{$endif windows}{$ifdef symbian}  ,i_symbian{$endif symbian}{$ifdef nativent}  ,i_nativent{$endif nativent}{$ifdef aix}  ,i_aix{$endif aix}  ,globtype;function Compile(const cmd:TCmdStr):longint;implementationuses  aasmcpu;{$if defined(MEMDEBUG)}  {$define SHOWUSEDMEM}{$endif}var  CompilerInitedAfterArgs,  CompilerInited : boolean;{****************************************************************************                                Compiler****************************************************************************}procedure DoneCompiler;begin  if not CompilerInited then   exit;{ Free compiler if args are read }  if CompilerInitedAfterArgs then   begin     CompilerInitedAfterArgs:=false;     DoneParser;     DoneImport;     DoneExport;     DoneLinker;     DoneAsm;     DoneWpo;   end;{ Free memory for the others }  CompilerInited:=false;  do_doneSymbolInfo;  DoneSymtable;  DoneGlobals;  DoneFileUtils;  donetokens;end;procedure InitCompiler(const cmd:TCmdStr);begin  if CompilerInited then   DoneCompiler;{$if defined(unix)}  { Set default code page for ansistrings on unix-like systems }  DefaultSystemCodePage:=GetSystemCodePage;{$endif}{ inits which need to be done before the arguments are parsed }  InitSystems;  { fileutils depends on source_info so it must be after systems }  InitFileUtils;  { globals depends on source_info so it must be after systems }  InitGlobals;  { verbose depends on exe_path and must be after globals }  InitVerbose;  inittokens;  IniTSymtable; {Must come before read_arguments, to enable macrosymstack}  do_initSymbolInfo;  CompilerInited:=true;{ this is needed here for the IDE  in case of compilation failure  at the previous compile }  set_current_module(nil);{ read the arguments }  read_arguments(cmd);{ inits which depend on arguments }  InitParser;  InitImport;  InitExport;  InitLinker;  InitAsm;  InitWpo;  CompilerInitedAfterArgs:=true;end;function Compile(const cmd:TCmdStr):longint;{$maxfpuregisters 0}  procedure writecmdstrlist(w:longint;l:TCmdStrList);  var    hp : TCmdStrListItem;  begin    hp:=TCmdStrListItem(l.first);    while assigned(hp) do     begin       Message1(w,hp.str);       hp:=TCmdStrListItem(hp.next);     end;  end;var  timestr    : string[20];  linkstr    : string[64];{$ifdef SHOWUSEDMEM}  hstatus : TFPCHeapStatus;{$endif SHOWUSEDMEM}  ExceptionMask : TFPUExceptionMask;  totaltime : real;begin  try    try       ExceptionMask:=GetExceptionMask;       SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide,                         exOverflow, exUnderflow, exPrecision]);       GetLocalTime(startsystime);       starttime := getrealtime(startsystime);       { Initialize the compiler }       InitCompiler(cmd);       { show some info }       Message1(general_t_compilername,FixFileName(system.paramstr(0)));       Message1(general_d_sourceos,source_info.name);       Message1(general_i_targetos,target_info.name);       Message1(general_t_exepath,exepath);       WriteCmdStrList(general_t_unitpath,unitsearchpath);       WriteCmdStrList(general_t_includepath,includesearchpath);       WriteCmdStrList(general_t_librarypath,librarysearchpath);       WriteCmdStrList(general_t_objectpath,objectsearchpath);       WriteCmdStrList(general_t_unitscope,namespacelist);       { Compile the program }  {$ifdef PREPROCWRITE}       if parapreprocess then        parser.preprocess(inputfilepath+inputfilename)       else  {$endif PREPROCWRITE}        parser.compile(inputfilepath+inputfilename);       { Show statistics }       if status.errorcount=0 then        begin          totaltime:=getrealtime-starttime;          if totaltime<0 then            totaltime:=totaltime+3600.0*24.0;          if round(frac(totaltime)*10) >= 10 then            totaltime:=trunc(totaltime) + 1;          timestr:=tostr(trunc(totaltime))+'.'+tostr(round(frac(totaltime)*10));          if status.codesize<>aword(-1) then            linkstr:=', '+tostr(status.codesize)+' ' +MessageStr(general_text_bytes_code)+', '+tostr(status.datasize)+' '+MessageStr(general_text_bytes_data)          else            linkstr:='';          Message3(general_i_abslines_compiled,tostr(status.compiledlines),timestr,linkstr);          if (Status.Verbosity and V_Warning = V_Warning) and                                               (Status.CountWarnings <> 0) then           Message1 (general_i_number_of_warnings, tostr (Status.CountWarnings));          if (Status.Verbosity and V_Hint = V_Hint) and                                                  (Status.CountHints <> 0) then           Message1 (general_i_number_of_hints, tostr (Status.CountHints));          if (Status.Verbosity and V_Note = V_Note) and                                               (Status.CountNotes <> 0) then           Message1 (general_i_number_of_notes, tostr (Status.CountNotes));        end;     finally       { no message possible after this !!    }       DoneCompiler;       SetExceptionMask(ExceptionMask);     end;     DoneVerbose;  except    on EControlCAbort do      begin        try          { in case of 50 errors, this could cause another exception,            suppress this exception          }          Message(general_f_compilation_aborted);        except          on ECompilerAbort do            ;        end;        DoneVerbose;      end;    on ECompilerAbort do      begin        try          { in case of 50 errors, this could cause another exception,            suppress this exception          }          Message(general_f_compilation_aborted);        except          on ECompilerAbort do            ;        end;        DoneVerbose;      end;    on ECompilerAbortSilent do      begin        DoneVerbose;      end;    on EOutOfMemory do      begin        try          Message(general_f_no_memory_left);        except          on ECompilerAbort do            ;        end;        DoneVerbose;      end;    on e : EInOutError do      begin        try          Message1(general_f_ioerror,e.message);        except          on ECompilerAbort do            ;        end;        DoneVerbose;      end;    on e : EOSError do      begin        try          Message1(general_f_oserror,e.message);        except          on ECompilerAbort do            ;        end;        DoneVerbose;      end;    on Exception do      begin        { General catchall, normally not used }        try          { in case of 50 errors, this could cause another exception,            suppress this exception          }          if not exception_raised then            begin              exception_raised:=true;              Message(general_e_exception_raised);            end          else            Message(general_f_compilation_aborted);        except          on ECompilerAbort do            ;        end;        DoneVerbose;        Raise;      end;  end;{$ifdef SHOWUSEDMEM}      hstatus:=GetFPCHeapStatus;      Writeln('Max Memory used/heapsize: ',DStr(hstatus.MaxHeapUsed shr 10),'/',DStr(hstatus.MaxHeapSize shr 10),' Kb');{$endif SHOWUSEDMEM}  { Set the return value if an error has occurred }  if status.errorcount=0 then    result:=0  else    result:=1;end;end.
 |