mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 16:59:45 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			782 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			782 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
{
 | 
						|
    $Id$
 | 
						|
    Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
 | 
						|
 | 
						|
    Implementation of the reading of PPU Files for the symtable
 | 
						|
 | 
						|
    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.
 | 
						|
 ****************************************************************************
 | 
						|
}
 | 
						|
 | 
						|
    const
 | 
						|
{$ifdef FPC}
 | 
						|
       ppubufsize=32768;
 | 
						|
{$ELSE}
 | 
						|
    {$IFDEF USEOVERLAY}
 | 
						|
       ppubufsize=512;
 | 
						|
    {$ELSE}
 | 
						|
       ppubufsize=4096;
 | 
						|
    {$ENDIF}
 | 
						|
{$ENDIF}
 | 
						|
 | 
						|
{$define ORDERSOURCES}
 | 
						|
 | 
						|
{*****************************************************************************
 | 
						|
                                 PPU Writing
 | 
						|
*****************************************************************************}
 | 
						|
 | 
						|
    procedure writebyte(b:byte);
 | 
						|
      begin
 | 
						|
        current_ppu^.putbyte(b);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure writeword(w:word);
 | 
						|
      begin
 | 
						|
        current_ppu^.putword(w);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure writelong(l:longint);
 | 
						|
      begin
 | 
						|
        current_ppu^.putlongint(l);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure writereal(d:bestreal);
 | 
						|
      begin
 | 
						|
        current_ppu^.putreal(d);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure writestring(const s:string);
 | 
						|
      begin
 | 
						|
        current_ppu^.putstring(s);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure writenormalset(var s); {You cannot pass an array[0..31] of byte!}
 | 
						|
      begin
 | 
						|
        current_ppu^.putdata(s,sizeof(tnormalset));
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure writesmallset(var s; size: longint);
 | 
						|
      var
 | 
						|
        tmpl: longint;
 | 
						|
      begin
 | 
						|
        { The minimum size of a set under Delphi isn't 32 bit }
 | 
						|
        { this is only binary compatible with FPC if first element's value of the set is 0 }
 | 
						|
        tmpl:=0; move(s,tmpl,size);
 | 
						|
        current_ppu^.putdata(tmpl,4);
 | 
						|
        {old code: current_ppu^.putdata(s,4);}
 | 
						|
      end;
 | 
						|
 | 
						|
    procedure writeguid(var g: tguid);
 | 
						|
      begin
 | 
						|
        current_ppu^.putdata(g,sizeof(g));
 | 
						|
      end;
 | 
						|
 | 
						|
    { posinfo is not relevant for changes in PPU }
 | 
						|
    procedure writeposinfo(const p:tfileposinfo);
 | 
						|
      var
 | 
						|
        oldcrc : boolean;
 | 
						|
      begin
 | 
						|
        oldcrc:=current_ppu^.do_crc;
 | 
						|
        current_ppu^.do_crc:=false;
 | 
						|
        current_ppu^.putword(p.fileindex);
 | 
						|
        current_ppu^.putlongint(p.line);
 | 
						|
        current_ppu^.putword(p.column);
 | 
						|
        current_ppu^.do_crc:=oldcrc;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure writederef(p : psymtableentry);
 | 
						|
      begin
 | 
						|
        if p=nil then
 | 
						|
         current_ppu^.putbyte(ord(derefnil))
 | 
						|
        else
 | 
						|
         begin
 | 
						|
           { Static symtable ? }
 | 
						|
           if p^.owner^.symtabletype=staticsymtable then
 | 
						|
            begin
 | 
						|
              current_ppu^.putbyte(ord(derefaktstaticindex));
 | 
						|
              current_ppu^.putword(p^.indexnr);
 | 
						|
            end
 | 
						|
           { Local record/object symtable ? }
 | 
						|
           else if (p^.owner=aktrecordsymtable) then
 | 
						|
            begin
 | 
						|
              current_ppu^.putbyte(ord(derefaktrecordindex));
 | 
						|
              current_ppu^.putword(p^.indexnr);
 | 
						|
            end
 | 
						|
           { Local local/para symtable ? }
 | 
						|
           else if (p^.owner=aktlocalsymtable) then
 | 
						|
            begin
 | 
						|
              current_ppu^.putbyte(ord(derefaktlocal));
 | 
						|
              current_ppu^.putword(p^.indexnr);
 | 
						|
            end
 | 
						|
           else
 | 
						|
            begin
 | 
						|
              current_ppu^.putbyte(ord(derefindex));
 | 
						|
              current_ppu^.putword(p^.indexnr);
 | 
						|
           { Current unit symtable ? }
 | 
						|
              repeat
 | 
						|
                if not assigned(p) then
 | 
						|
                 internalerror(556655);
 | 
						|
                case p^.owner^.symtabletype of
 | 
						|
                 { when writing the pseudo PPU file
 | 
						|
                   to get CRC values the globalsymtable is not yet
 | 
						|
                   a unitsymtable PM }
 | 
						|
                  globalsymtable,
 | 
						|
                  unitsymtable :
 | 
						|
                    begin
 | 
						|
                      { check if the unit is available in the uses
 | 
						|
                        clause, else it's an error }
 | 
						|
                      if p^.owner^.unitid=$ffff then
 | 
						|
                       internalerror(55665566);
 | 
						|
                      current_ppu^.putbyte(ord(derefunit));
 | 
						|
                      current_ppu^.putword(p^.owner^.unitid);
 | 
						|
                      break;
 | 
						|
                    end;
 | 
						|
                  staticsymtable :
 | 
						|
                    begin
 | 
						|
                      current_ppu^.putbyte(ord(derefaktstaticindex));
 | 
						|
                      current_ppu^.putword(p^.indexnr);
 | 
						|
                      break;
 | 
						|
                    end;
 | 
						|
                  localsymtable :
 | 
						|
                    begin
 | 
						|
                      p:=p^.owner^.defowner;
 | 
						|
                      current_ppu^.putbyte(ord(dereflocal));
 | 
						|
                      current_ppu^.putword(p^.indexnr);
 | 
						|
                    end;
 | 
						|
                  parasymtable :
 | 
						|
                    begin
 | 
						|
                      p:=p^.owner^.defowner;
 | 
						|
                      current_ppu^.putbyte(ord(derefpara));
 | 
						|
                      current_ppu^.putword(p^.indexnr);
 | 
						|
                    end;
 | 
						|
                  objectsymtable,
 | 
						|
                  recordsymtable :
 | 
						|
                    begin
 | 
						|
                      p:=p^.owner^.defowner;
 | 
						|
                      current_ppu^.putbyte(ord(derefrecord));
 | 
						|
                      current_ppu^.putword(p^.indexnr);
 | 
						|
                    end;
 | 
						|
                  else
 | 
						|
                    internalerror(556656);
 | 
						|
                end;
 | 
						|
              until false;
 | 
						|
            end;
 | 
						|
         end;
 | 
						|
      end;
 | 
						|
 | 
						|
    procedure writedefref(p : pdef);
 | 
						|
      begin
 | 
						|
        writederef(p);
 | 
						|
      end;
 | 
						|
 | 
						|
    procedure writesymref(p : psym);
 | 
						|
      begin
 | 
						|
        writederef(p);
 | 
						|
      end;
 | 
						|
 | 
						|
    procedure writesourcefiles;
 | 
						|
      var
 | 
						|
        hp    : pinputfile;
 | 
						|
{$ifdef ORDERSOURCES}
 | 
						|
        i,j : longint;
 | 
						|
{$endif ORDERSOURCES}
 | 
						|
      begin
 | 
						|
      { second write the used source files }
 | 
						|
        current_ppu^.do_crc:=false;
 | 
						|
        hp:=current_module^.sourcefiles^.files;
 | 
						|
{$ifdef ORDERSOURCES}
 | 
						|
      { write source files directly in good order }
 | 
						|
        j:=0;
 | 
						|
        while assigned(hp) do
 | 
						|
          begin
 | 
						|
            inc(j);
 | 
						|
            hp:=hp^.ref_next;
 | 
						|
          end;
 | 
						|
        while j>0 do
 | 
						|
          begin
 | 
						|
            hp:=current_module^.sourcefiles^.files;
 | 
						|
            for i:=1 to j-1 do
 | 
						|
              hp:=hp^.ref_next;
 | 
						|
            current_ppu^.putstring(hp^.name^);
 | 
						|
            dec(j);
 | 
						|
         end;
 | 
						|
{$else not ORDERSOURCES}
 | 
						|
        while assigned(hp) do
 | 
						|
         begin
 | 
						|
         { only name and extension }
 | 
						|
           current_ppu^.putstring(hp^.name^);
 | 
						|
           hp:=hp^.ref_next;
 | 
						|
         end;
 | 
						|
{$endif ORDERSOURCES}
 | 
						|
        current_ppu^.writeentry(ibsourcefiles);
 | 
						|
        current_ppu^.do_crc:=true;
 | 
						|
      end;
 | 
						|
 | 
						|
    procedure writeusedmacros;
 | 
						|
      var
 | 
						|
        hp    : pmacrosym;
 | 
						|
        i     : longint;
 | 
						|
      begin
 | 
						|
      { second write the used source files }
 | 
						|
        current_ppu^.do_crc:=false;
 | 
						|
        for i:=1 to macros^.symindex^.count do
 | 
						|
         begin
 | 
						|
           hp:=pmacrosym(macros^.symindex^.search(i));
 | 
						|
         { only used or init defined macros are stored }
 | 
						|
           if hp^.is_used or hp^.defined_at_startup then
 | 
						|
             begin
 | 
						|
               current_ppu^.putstring(hp^.name);
 | 
						|
               current_ppu^.putbyte(byte(hp^.defined_at_startup));
 | 
						|
               current_ppu^.putbyte(byte(hp^.is_used));
 | 
						|
             end;
 | 
						|
         end;
 | 
						|
        current_ppu^.writeentry(ibusedmacros);
 | 
						|
        current_ppu^.do_crc:=true;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure writeusedunit;
 | 
						|
      var
 | 
						|
        hp      : pused_unit;
 | 
						|
      begin
 | 
						|
        numberunits;
 | 
						|
        hp:=pused_unit(current_module^.used_units.first);
 | 
						|
        while assigned(hp) do
 | 
						|
         begin
 | 
						|
           { implementation units should not change
 | 
						|
             the CRC PM }
 | 
						|
           current_ppu^.do_crc:=hp^.in_interface;
 | 
						|
           current_ppu^.putstring(hp^.name^);
 | 
						|
           { the checksum should not affect the crc of this unit ! (PFV) }
 | 
						|
           current_ppu^.do_crc:=false;
 | 
						|
           current_ppu^.putlongint(hp^.checksum);
 | 
						|
           current_ppu^.putlongint(hp^.interface_checksum);
 | 
						|
           current_ppu^.putbyte(byte(hp^.in_interface));
 | 
						|
           current_ppu^.do_crc:=true;
 | 
						|
           hp:=pused_unit(hp^.next);
 | 
						|
         end;
 | 
						|
        current_ppu^.do_interface_crc:=true;
 | 
						|
        current_ppu^.writeentry(ibloadunit);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure writelinkcontainer(var p:tlinkcontainer;id:byte;strippath:boolean);
 | 
						|
      var
 | 
						|
        hcontainer : tlinkcontainer;
 | 
						|
        s : string;
 | 
						|
        mask : longint;
 | 
						|
      begin
 | 
						|
        hcontainer.init;
 | 
						|
        while not p.empty do
 | 
						|
         begin
 | 
						|
           s:=p.get(mask);
 | 
						|
           if strippath then
 | 
						|
            current_ppu^.putstring(SplitFileName(s))
 | 
						|
           else
 | 
						|
            current_ppu^.putstring(s);
 | 
						|
           current_ppu^.putlongint(mask);
 | 
						|
           hcontainer.insert(s,mask);
 | 
						|
         end;
 | 
						|
        current_ppu^.writeentry(id);
 | 
						|
        p:=hcontainer;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure writeunitas(const s : string;unittable : punitsymtable;only_crc : boolean);
 | 
						|
      begin
 | 
						|
         Message1(unit_u_ppu_write,s);
 | 
						|
 | 
						|
       { create unit flags }
 | 
						|
         with Current_Module^ do
 | 
						|
          begin
 | 
						|
{$ifdef GDB}
 | 
						|
            if cs_gdb_dbx in aktglobalswitches then
 | 
						|
             flags:=flags or uf_has_dbx;
 | 
						|
{$endif GDB}
 | 
						|
            if target_os.endian=endian_big then
 | 
						|
             flags:=flags or uf_big_endian;
 | 
						|
            if cs_browser in aktmoduleswitches then
 | 
						|
             flags:=flags or uf_has_browser;
 | 
						|
            if cs_local_browser in aktmoduleswitches then
 | 
						|
             flags:=flags or uf_local_browser;
 | 
						|
          end;
 | 
						|
 | 
						|
{$ifdef Test_Double_checksum_write}
 | 
						|
        If only_crc then
 | 
						|
          Assign(CRCFile,s+'.INT')
 | 
						|
        else
 | 
						|
          Assign(CRCFile,s+'.IMP');
 | 
						|
        Rewrite(CRCFile);
 | 
						|
{$endif def Test_Double_checksum_write}
 | 
						|
       { open ppufile }
 | 
						|
         current_ppu:=new(pppufile,init(s));
 | 
						|
         current_ppu^.crc_only:=only_crc;
 | 
						|
         if not current_ppu^.create then
 | 
						|
           Message(unit_f_ppu_cannot_write);
 | 
						|
 | 
						|
{$ifdef Test_Double_checksum}
 | 
						|
         if only_crc then
 | 
						|
           begin
 | 
						|
              new(current_ppu^.crc_test);
 | 
						|
              new(current_ppu^.crc_test2);
 | 
						|
           end
 | 
						|
         else
 | 
						|
           begin
 | 
						|
             current_ppu^.crc_test:=Current_Module^.crc_array;
 | 
						|
             current_ppu^.crc_index:=Current_Module^.crc_size;
 | 
						|
             current_ppu^.crc_test2:=Current_Module^.crc_array2;
 | 
						|
             current_ppu^.crc_index2:=Current_Module^.crc_size2;
 | 
						|
           end;
 | 
						|
{$endif def Test_Double_checksum}
 | 
						|
 | 
						|
         current_ppu^.change_endian:=source_os.endian<>target_os.endian;
 | 
						|
       { write symbols and definitions }
 | 
						|
         unittable^.writeasunit;
 | 
						|
 | 
						|
       { flush to be sure }
 | 
						|
         current_ppu^.flush;
 | 
						|
       { create and write header }
 | 
						|
         current_ppu^.header.size:=current_ppu^.size;
 | 
						|
         current_ppu^.header.checksum:=current_ppu^.crc;
 | 
						|
         current_ppu^.header.interface_checksum:=current_ppu^.interface_crc;
 | 
						|
         current_ppu^.header.compiler:=wordversion;
 | 
						|
         current_ppu^.header.cpu:=word(target_cpu);
 | 
						|
         current_ppu^.header.target:=word(target_info.target);
 | 
						|
         current_ppu^.header.flags:=current_module^.flags;
 | 
						|
         If not only_crc then
 | 
						|
           current_ppu^.writeheader;
 | 
						|
       { save crc in current_module also }
 | 
						|
         current_module^.crc:=current_ppu^.crc;
 | 
						|
         current_module^.interface_crc:=current_ppu^.interface_crc;
 | 
						|
         if only_crc then
 | 
						|
          begin
 | 
						|
{$ifdef Test_Double_checksum}
 | 
						|
            Current_Module^.crc_array:=current_ppu^.crc_test;
 | 
						|
            current_ppu^.crc_test:=nil;
 | 
						|
            Current_Module^.crc_size:=current_ppu^.crc_index2;
 | 
						|
            Current_Module^.crc_array2:=current_ppu^.crc_test2;
 | 
						|
            current_ppu^.crc_test2:=nil;
 | 
						|
            Current_Module^.crc_size2:=current_ppu^.crc_index2;
 | 
						|
{$endif def Test_Double_checksum}
 | 
						|
            closecurrentppu;
 | 
						|
          end;
 | 
						|
{$ifdef Test_Double_checksum_write}
 | 
						|
        close(CRCFile);
 | 
						|
{$endif Test_Double_checksum_write}
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure closecurrentppu;
 | 
						|
      begin
 | 
						|
{$ifdef Test_Double_checksum}
 | 
						|
         if assigned(current_ppu^.crc_test) then
 | 
						|
           dispose(current_ppu^.crc_test);
 | 
						|
         if assigned(current_ppu^.crc_test2) then
 | 
						|
           dispose(current_ppu^.crc_test2);
 | 
						|
{$endif Test_Double_checksum}
 | 
						|
       { close }
 | 
						|
         current_ppu^.close;
 | 
						|
         dispose(current_ppu,done);
 | 
						|
         current_ppu:=nil;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
{*****************************************************************************
 | 
						|
                                 PPU Reading
 | 
						|
*****************************************************************************}
 | 
						|
 | 
						|
    function readbyte:byte;
 | 
						|
      begin
 | 
						|
        readbyte:=current_ppu^.getbyte;
 | 
						|
        if current_ppu^.error then
 | 
						|
         Message(unit_f_ppu_read_error);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    function readword:word;
 | 
						|
      begin
 | 
						|
        readword:=current_ppu^.getword;
 | 
						|
        if current_ppu^.error then
 | 
						|
         Message(unit_f_ppu_read_error);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    function readlong:longint;
 | 
						|
      begin
 | 
						|
        readlong:=current_ppu^.getlongint;
 | 
						|
        if current_ppu^.error then
 | 
						|
         Message(unit_f_ppu_read_error);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    function readreal : bestreal;
 | 
						|
      begin
 | 
						|
        readreal:=current_ppu^.getreal;
 | 
						|
        if current_ppu^.error then
 | 
						|
         Message(unit_f_ppu_read_error);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    function readstring : string;
 | 
						|
      begin
 | 
						|
        readstring:=current_ppu^.getstring;
 | 
						|
        if current_ppu^.error then
 | 
						|
         Message(unit_f_ppu_read_error);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure readnormalset(var s);   {You cannot pass an array [0..31] of byte.}
 | 
						|
      begin
 | 
						|
        current_ppu^.getdata(s,sizeof(tnormalset));
 | 
						|
        if current_ppu^.error then
 | 
						|
         Message(unit_f_ppu_read_error);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure readsmallset(var s;size: longint);
 | 
						|
      var
 | 
						|
        tmpl: longint;
 | 
						|
      begin
 | 
						|
        { The minimum size of a set under Delphi isn't 32 bit }
 | 
						|
        { this is only binary compatible if first element's value of the set is 0 }
 | 
						|
        current_ppu^.getdata(tmpl,4);
 | 
						|
        move(tmpl,s,size);
 | 
						|
        {old code: current_ppu^.getdata(s,4); }
 | 
						|
        if current_ppu^.error then
 | 
						|
         Message(unit_f_ppu_read_error);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure readguid(var g: tguid);
 | 
						|
      begin
 | 
						|
        current_ppu^.getdata(g,sizeof(g));
 | 
						|
        if current_ppu^.error then
 | 
						|
         Message(unit_f_ppu_read_error);
 | 
						|
      end;
 | 
						|
 | 
						|
    procedure readposinfo(var p:tfileposinfo);
 | 
						|
      begin
 | 
						|
        p.fileindex:=current_ppu^.getword;
 | 
						|
        p.line:=current_ppu^.getlongint;
 | 
						|
        p.column:=current_ppu^.getword;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    function readderef : pderef;
 | 
						|
      var
 | 
						|
        hp,p : pderef;
 | 
						|
        b : tdereftype;
 | 
						|
      begin
 | 
						|
        p:=nil;
 | 
						|
        repeat
 | 
						|
          hp:=p;
 | 
						|
          b:=tdereftype(current_ppu^.getbyte);
 | 
						|
          case b of
 | 
						|
            derefnil :
 | 
						|
              break;
 | 
						|
            derefunit,
 | 
						|
            derefaktrecordindex,
 | 
						|
            derefaktlocal,
 | 
						|
            derefaktstaticindex :
 | 
						|
              begin
 | 
						|
                new(p,init(b,current_ppu^.getword));
 | 
						|
                p^.next:=hp;
 | 
						|
                break;
 | 
						|
              end;
 | 
						|
            derefindex,
 | 
						|
            dereflocal,
 | 
						|
            derefpara,
 | 
						|
            derefrecord :
 | 
						|
              begin
 | 
						|
                new(p,init(b,current_ppu^.getword));
 | 
						|
                p^.next:=hp;
 | 
						|
              end;
 | 
						|
          end;
 | 
						|
        until false;
 | 
						|
        readderef:=p;
 | 
						|
      end;
 | 
						|
 | 
						|
    function readdefref : pdef;
 | 
						|
      begin
 | 
						|
        readdefref:=pdef(readderef);
 | 
						|
      end;
 | 
						|
 | 
						|
    function readsymref : psym;
 | 
						|
      begin
 | 
						|
        readsymref:=psym(readderef);
 | 
						|
      end;
 | 
						|
 | 
						|
    procedure readusedmacros;
 | 
						|
      var
 | 
						|
        hs : string;
 | 
						|
        mac : pmacrosym;
 | 
						|
        was_defined_at_startup,
 | 
						|
        was_used : boolean;
 | 
						|
      begin
 | 
						|
        while not current_ppu^.endofentry do
 | 
						|
         begin
 | 
						|
           hs:=current_ppu^.getstring;
 | 
						|
           was_defined_at_startup:=boolean(current_ppu^.getbyte);
 | 
						|
           was_used:=boolean(current_ppu^.getbyte);
 | 
						|
           mac:=pmacrosym(macros^.search(hs));
 | 
						|
           if assigned(mac) then
 | 
						|
             begin
 | 
						|
{$ifndef EXTDEBUG}
 | 
						|
           { if we don't have the sources why tell }
 | 
						|
              if current_module^.sources_avail then
 | 
						|
{$endif ndef EXTDEBUG}
 | 
						|
               if (not was_defined_at_startup) and
 | 
						|
                  was_used and
 | 
						|
                  mac^.defined_at_startup then
 | 
						|
                Message2(unit_h_cond_not_set_in_last_compile,hs,current_module^.mainsource^);
 | 
						|
             end
 | 
						|
           else { not assigned }
 | 
						|
             if was_defined_at_startup and
 | 
						|
                was_used then
 | 
						|
              Message2(unit_h_cond_not_set_in_last_compile,hs,current_module^.mainsource^);
 | 
						|
         end;
 | 
						|
      end;
 | 
						|
 | 
						|
    procedure readsourcefiles;
 | 
						|
      var
 | 
						|
        temp,hs       : string;
 | 
						|
        temp_dir      : string;
 | 
						|
{$ifdef ORDERSOURCES}
 | 
						|
        main_dir      : string;
 | 
						|
{$endif ORDERSOURCES}
 | 
						|
        incfile_found,
 | 
						|
        main_found,
 | 
						|
        is_main       : boolean;
 | 
						|
        ppufiletime,
 | 
						|
        source_time   : longint;
 | 
						|
        hp            : pinputfile;
 | 
						|
      begin
 | 
						|
        ppufiletime:=getnamedfiletime(current_module^.ppufilename^);
 | 
						|
        current_module^.sources_avail:=true;
 | 
						|
{$ifdef ORDERSOURCES}
 | 
						|
        is_main:=true;
 | 
						|
        main_dir:='';
 | 
						|
{$endif ORDERSOURCES}
 | 
						|
        while not current_ppu^.endofentry do
 | 
						|
         begin
 | 
						|
           hs:=current_ppu^.getstring;
 | 
						|
{$ifndef ORDERSOURCES}
 | 
						|
           is_main:=current_ppu^.endofentry;
 | 
						|
{$endif ORDERSOURCES}
 | 
						|
           temp_dir:='';
 | 
						|
           if (current_module^.flags and uf_in_library)<>0 then
 | 
						|
            begin
 | 
						|
              current_module^.sources_avail:=false;
 | 
						|
              temp:=' library';
 | 
						|
            end
 | 
						|
           else if pos('Macro ',hs)=1 then
 | 
						|
            begin
 | 
						|
              { we don't want to find this file }
 | 
						|
              { but there is a problem with file indexing !! }
 | 
						|
              temp:='';
 | 
						|
            end
 | 
						|
           else
 | 
						|
            begin
 | 
						|
              { check the date of the source files }
 | 
						|
              Source_Time:=GetNamedFileTime(current_module^.path^+hs);
 | 
						|
              incfile_found:=false;
 | 
						|
              main_found:=false;
 | 
						|
              if Source_Time<>-1 then
 | 
						|
                hs:=current_module^.path^+hs
 | 
						|
{$ifdef ORDERSOURCES}
 | 
						|
              else if not(is_main) then
 | 
						|
                begin
 | 
						|
                  Source_Time:=GetNamedFileTime(main_dir+hs);
 | 
						|
                  if Source_Time<>-1 then
 | 
						|
                    hs:=main_dir+hs;
 | 
						|
                end
 | 
						|
{$endif def ORDERSOURCES}
 | 
						|
                   ;
 | 
						|
              if (Source_Time=-1) then
 | 
						|
                begin
 | 
						|
                  if is_main then
 | 
						|
                    temp_dir:=unitsearchpath.FindFile(hs,main_found)
 | 
						|
                  else
 | 
						|
                    temp_dir:=includesearchpath.FindFile(hs,incfile_found);
 | 
						|
                  if incfile_found or main_found then
 | 
						|
                   begin
 | 
						|
                     hs:=temp_dir+hs;
 | 
						|
                     Source_Time:=GetNamedFileTime(hs);
 | 
						|
                   end
 | 
						|
                end;
 | 
						|
              if Source_Time=-1 then
 | 
						|
               begin
 | 
						|
                 current_module^.sources_avail:=false;
 | 
						|
                 temp:=' not found';
 | 
						|
               end
 | 
						|
              else
 | 
						|
               begin
 | 
						|
                 if main_found then
 | 
						|
                   main_dir:=temp_dir;
 | 
						|
                 { time newer? But only allow if the file is not searched
 | 
						|
                   in the include path (PFV), else you've problems with
 | 
						|
                   units which use the same includefile names }
 | 
						|
                 if incfile_found then
 | 
						|
                  temp:=' found'
 | 
						|
                 else
 | 
						|
                  begin
 | 
						|
                    temp:=' time '+filetimestring(source_time);
 | 
						|
                    if (source_time>ppufiletime) then
 | 
						|
                     begin
 | 
						|
                       current_module^.do_compile:=true;
 | 
						|
                       current_module^.recompile_reason:=rr_sourcenewer;
 | 
						|
                       temp:=temp+' *'
 | 
						|
                     end;
 | 
						|
                  end;
 | 
						|
               end;
 | 
						|
              new(hp,init(hs));
 | 
						|
              { the indexing is wrong here PM }
 | 
						|
              current_module^.sourcefiles^.register_file(hp);
 | 
						|
            end;
 | 
						|
{$ifdef ORDERSOURCES}
 | 
						|
           if is_main then
 | 
						|
             begin
 | 
						|
               stringdispose(current_module^.mainsource);
 | 
						|
               current_module^.mainsource:=stringdup(hs);
 | 
						|
             end;
 | 
						|
{$endif ORDERSOURCES}
 | 
						|
           Message1(unit_u_ppu_source,hs+temp);
 | 
						|
{$ifdef ORDERSOURCES}
 | 
						|
           is_main:=false;
 | 
						|
{$endif ORDERSOURCES}
 | 
						|
         end;
 | 
						|
{$ifndef ORDERSOURCES}
 | 
						|
      { main source is always the last }
 | 
						|
        stringdispose(current_module^.mainsource);
 | 
						|
        current_module^.mainsource:=stringdup(hs);
 | 
						|
 | 
						|
        { the indexing is corrected here PM }
 | 
						|
        current_module^.sourcefiles^.inverse_register_indexes;
 | 
						|
{$endif ORDERSOURCES}
 | 
						|
      { check if we want to rebuild every unit, only if the sources are
 | 
						|
        available }
 | 
						|
        if do_build and current_module^.sources_avail then
 | 
						|
          begin
 | 
						|
             current_module^.do_compile:=true;
 | 
						|
             current_module^.recompile_reason:=rr_build;
 | 
						|
          end;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure readloadunit;
 | 
						|
      var
 | 
						|
        hs : string;
 | 
						|
        intfchecksum,
 | 
						|
        checksum : longint;
 | 
						|
        in_interface : boolean;
 | 
						|
      begin
 | 
						|
        while not current_ppu^.endofentry do
 | 
						|
         begin
 | 
						|
           hs:=current_ppu^.getstring;
 | 
						|
           checksum:=current_ppu^.getlongint;
 | 
						|
           intfchecksum:=current_ppu^.getlongint;
 | 
						|
           in_interface:=(current_ppu^.getbyte<>0);
 | 
						|
           current_module^.used_units.concat(new(pused_unit,init_to_load(hs,checksum,intfchecksum,in_interface)));
 | 
						|
         end;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure readlinkcontainer(var p:tlinkcontainer);
 | 
						|
      var
 | 
						|
        s : string;
 | 
						|
        m : longint;
 | 
						|
      begin
 | 
						|
        while not current_ppu^.endofentry do
 | 
						|
         begin
 | 
						|
           s:=current_ppu^.getstring;
 | 
						|
           m:=current_ppu^.getlongint;
 | 
						|
           p.insert(s,m);
 | 
						|
         end;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure load_interface;
 | 
						|
      var
 | 
						|
        b : byte;
 | 
						|
        newmodulename : string;
 | 
						|
      begin
 | 
						|
       { read interface part }
 | 
						|
         repeat
 | 
						|
           b:=current_ppu^.readentry;
 | 
						|
           case b of
 | 
						|
             ibmodulename :
 | 
						|
               begin
 | 
						|
                 newmodulename:=current_ppu^.getstring;
 | 
						|
                 if upper(newmodulename)<>current_module^.modulename^ then
 | 
						|
                   Message2(unit_f_unit_name_error,current_module^.realmodulename^,newmodulename);
 | 
						|
                 stringdispose(current_module^.modulename);
 | 
						|
                 stringdispose(current_module^.realmodulename);
 | 
						|
                 current_module^.modulename:=stringdup(upper(newmodulename));
 | 
						|
                 current_module^.realmodulename:=stringdup(newmodulename);
 | 
						|
               end;
 | 
						|
             ibsourcefiles :
 | 
						|
               readsourcefiles;
 | 
						|
             ibusedmacros :
 | 
						|
               readusedmacros;
 | 
						|
             ibloadunit :
 | 
						|
               readloadunit;
 | 
						|
             iblinkunitofiles :
 | 
						|
               readlinkcontainer(current_module^.LinkUnitOFiles);
 | 
						|
             iblinkunitstaticlibs :
 | 
						|
               readlinkcontainer(current_module^.LinkUnitStaticLibs);
 | 
						|
             iblinkunitsharedlibs :
 | 
						|
               readlinkcontainer(current_module^.LinkUnitSharedLibs);
 | 
						|
             iblinkotherofiles :
 | 
						|
               readlinkcontainer(current_module^.LinkotherOFiles);
 | 
						|
             iblinkotherstaticlibs :
 | 
						|
               readlinkcontainer(current_module^.LinkotherStaticLibs);
 | 
						|
             iblinkothersharedlibs :
 | 
						|
               readlinkcontainer(current_module^.LinkotherSharedLibs);
 | 
						|
             ibendinterface :
 | 
						|
               break;
 | 
						|
           else
 | 
						|
             Message1(unit_f_ppu_invalid_entry,tostr(b));
 | 
						|
           end;
 | 
						|
         until false;
 | 
						|
      end;
 | 
						|
 | 
						|
{
 | 
						|
  $Log$
 | 
						|
  Revision 1.7  2000-11-04 14:25:22  florian
 | 
						|
    + merged Attila's changes for interfaces, not tested yet
 | 
						|
 | 
						|
  Revision 1.6  2000/10/31 22:02:52  peter
 | 
						|
    * symtable splitted, no real code changes
 | 
						|
 | 
						|
  Revision 1.5  2000/10/15 07:47:53  peter
 | 
						|
    * unit names and procedure names are stored mixed case
 | 
						|
 | 
						|
  Revision 1.4  2000/09/24 21:33:47  peter
 | 
						|
    * message updates merges
 | 
						|
 | 
						|
  Revision 1.3  2000/09/21 20:56:19  pierre
 | 
						|
   * fix for bugs 1084/1128 (merged)
 | 
						|
 | 
						|
  Revision 1.2  2000/07/13 11:32:49  michael
 | 
						|
  + removed logs
 | 
						|
 | 
						|
} |