home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Programming / fpc / compiler / files.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-09-24  |  26.6 KB  |  894 lines

  1. {
  2.     $Id: files.pas,v 1.1.1.1 1998/03/25 11:18:12 root Exp $
  3.     Copyright (c) 1996-98 by Florian Klaempfl
  4.  
  5.     This unit implements an extended file management and the first loading
  6.     and searching of the modules (ppufiles)
  7.  
  8.     This program is free software; you can redistribute it and/or modify
  9.     it under the terms of the GNU General Public License as published by
  10.     the Free Software Foundation; either version 2 of the License, or
  11.     (at your option) any later version.
  12.  
  13.     This program is distributed in the hope that it will be useful,
  14.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.     GNU General Public License for more details.
  17.  
  18.     You should have received a copy of the GNU General Public License
  19.     along with this program; if not, write to the Free Software
  20.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22.  ****************************************************************************
  23. }
  24. unit files;
  25.  
  26.   interface
  27.  
  28.     uses
  29.        cobjects,globals;
  30.  
  31.     const
  32. {$ifdef FPC}
  33.        maxunits = 1024;
  34. {$else}
  35.        maxunits = 128;
  36. {$endif}
  37.  
  38.     type
  39.        pextfile = ^textfile;
  40.  
  41.        { this isn't a text file, this is t-ext-file }
  42.        { which means a extended file                }
  43.        { this files can be handled by a file        }
  44.        { manager                                    }
  45.        textfile = object(tbufferedfile)
  46.           path,name,ext : pstring;
  47.           { this is because there is a name conflict }
  48.           { with the older next from tinputstack     }
  49.           _next : pextfile;
  50.           { 65000 input files for a unit should be enough !! }
  51.           ref_index : word;
  52.  
  53.           { p must be the complete path (with ending \ (or / for unix ...) }
  54.           constructor init(const p,n,e : string);
  55.           destructor done;virtual;
  56.        end;
  57.  
  58.        pinputfile = ^tinputfile;
  59.  
  60.        tinputfile = object(textfile)
  61.           filenotatend : boolean;
  62.           line_no : longint;
  63.           { second counter for unimportant tokens }
  64.           line_count : longint;
  65.           { next input file in the stack of input files }
  66.           next : pinputfile;
  67.           { to handle the browser refs }
  68.           ref_count : longint;
  69.  
  70.           constructor init(const p,n,e : string);
  71.           { writes the file name and line number to t }
  72.           procedure write_file_line(var t : text);
  73.           function get_file_line : string;
  74.        end;
  75.  
  76.        pfilemanager = ^tfilemanager;
  77.  
  78.        tfilemanager = object
  79.           files : pextfile;
  80.           last_ref_index : word;
  81.           constructor init;
  82.           destructor done;
  83.           procedure close_all;
  84.           procedure register_file(f : pextfile);
  85.        end;
  86.  
  87.        pimported_procedure = ^timported_procedure;
  88.  
  89.        timported_procedure = object(tlinkedlist_item)
  90.           ordnr : word;
  91.           name,func : pstring;
  92.           { should be plabel, but this gaves problems with circular units }
  93.           lab : pointer;
  94.           constructor init(const n,s : string;o : word);
  95.           destructor done;virtual;
  96.        end;
  97.  
  98.        pimportlist = ^timportlist;
  99.  
  100.        timportlist = object(tlinkedlist_item)
  101.           dllname : pstring;
  102.           imported_procedures : plinkedlist;
  103.           constructor init(const n : string);
  104.           destructor done;virtual;
  105.        end;
  106.  
  107.     type
  108.        pmodule = ^tmodule;
  109.        pused_unit = ^tused_unit;
  110.  
  111.        tused_unit = object(tlinkedlist_item)
  112.           u : pmodule;
  113.           in_uses, in_interface, is_stab_written : boolean;
  114.           unitid : word;
  115.           constructor init(_u : pmodule;f : byte);
  116.           destructor done;virtual;
  117.        end;
  118.  
  119.        tunitmap = array[0..maxunits-1] of pointer;
  120.        punitmap = ^tunitmap;
  121.  
  122.        tmodule = object(tlinkedlist_item)
  123.  
  124.           { the PPU file }
  125.           ppufile : pextfile;
  126.           { used for global switches - in_main section after uses clause }
  127.           { then TRUE else false.                                        }
  128.           in_main : boolean;
  129.           { mapping of all used units }
  130.           map : punitmap;
  131.           { local unit counter }
  132.           unitcount : word;
  133.           { this is a pointer because symtable uses this unit }
  134.           { it should be psymtable                            }
  135.           symtable : pointer;
  136.  
  137.           { PPU version, handle different versions }
  138.           ppuversion : longint;
  139.  
  140.           { check sum written to the file }
  141.           crc : longint;
  142.  
  143.           { flags }
  144.           flags : byte;
  145.  
  146.           {Set if the module imports from DLL's.}
  147.           uses_imports:boolean;
  148.  
  149.           imports : plinkedlist;
  150.  
  151.           { how to write this file }
  152.           output_format : tof;
  153.  
  154.           { for interpenetrated units }
  155.           in_implementation,
  156.           compiled,
  157.           do_assemble,
  158.           do_compile,              { true, if it's needed to compile the sources }
  159.           sources_avail : boolean; { true, if all sources are reachable }
  160.  
  161.           { only used, if the module is compiled by this compiler call }
  162.           sourcefiles : tfilemanager;
  163.           linklibfiles,
  164.           linkofiles  : tstringcontainer;
  165.           used_units  : tlinkedlist;
  166.           current_inputfile : pinputfile;
  167.  
  168.           unitname,               { name of the (unit) module }
  169.           objfilename,            { fullname of the objectfile }
  170.           asmfilename,            { fullname of the assemblerfile }
  171.           ppufilename,            { fullname of the ppufile }
  172.           mainsource   : pstring; { name of the main sourcefile }
  173.  
  174.           constructor init(const s:string;is_unit:boolean);
  175.           { this is to be called only when compiling again }
  176.           destructor special_done;virtual;
  177.  
  178.           function load_ppu(const unit_path,n,ext : string):boolean;
  179.           procedure search_unit(const n : string);
  180.        end;
  181.  
  182.     const
  183.        main_module : pmodule = nil;
  184.        current_module : pmodule = nil;
  185.  
  186.     var
  187.        loaded_units : tlinkedlist;
  188.  
  189.     type
  190.        tunitheader = array[0..19] of char;
  191.  
  192.     const
  193.                                    {                compiler version }
  194.                                    {             format      |       }
  195.                                    { signature    |          |       }
  196.                                    {  |           |          |       }
  197.                                    { /-------\   /-------\  /----\   }
  198.        unitheader : tunitheader  = ('P','P','U','0','1','3',#0,#99,
  199.                                      #0,#0,#0,#0,#0,#0,#255,#255,
  200.                                    { |   | \---------/ \-------/    }
  201.                                    { |   |    |             |        }
  202.                                    { |   |    check sum     |        }
  203.                                    { |   \--flags        unused      }
  204.                                    { target system                   }
  205.                                     #0,#0,#0,#0);
  206.                                    {\---------/                      }
  207.                                    {  |                              }
  208.                                    {  start of machine language      }
  209.  
  210.     const
  211.        ibloadunit = 1;
  212.        iborddef = 2;
  213.        ibpointerdef = 3;
  214.        ibtypesym = 4;
  215.        ibarraydef = 5;
  216.        ibprocdef = 6;
  217.        ibprocsym = 7;
  218.        iblinkofile = 8;
  219.        ibstringdef = 9;
  220.        ibvarsym = 10;
  221.        ibconstsym = 11;
  222.        ibinitunit = 12;
  223.        ibaufzaehlsym = 13;
  224.        ibtypedconstsym = 14;
  225.        ibrecorddef = 15;
  226.        ibfiledef = 16;
  227.        ibformaldef = 17;
  228.        ibobjectdef = 18;
  229.        ibenumdef = 19;
  230.        ibsetdef = 20;
  231.        ibprocvardef = 21;
  232.        ibsourcefile = 22;
  233.        ibdbxcount = 23;
  234.        ibfloatdef = 24;
  235.        ibref = 25;
  236.        ibextsymref = 26;
  237.        ibextdefref = 27;
  238.        ibabsolutesym = 28;
  239.        ibclassrefdef = 29;
  240.        ibpropertysym = 30;
  241.        iblibraries = 31;
  242.        iblongstringdef = 32;
  243.        ibansistringdef = 33;
  244.        ibend = 255;
  245.  
  246.        { unit flags }
  247.        uf_init = 1;
  248.        uf_uses_dbx = 2;
  249.        uf_uses_browser = 4;
  250.        uf_in_library = 8;
  251.        uf_shared_library = 16;
  252.        uf_big_endian = 32;
  253.  
  254.   implementation
  255.  
  256.   uses
  257.     dos,verbose,systems;
  258.  
  259.  
  260. {****************************************************************************
  261.                                   TFILE
  262.  ****************************************************************************}
  263.  
  264.     constructor textfile.init(const p,n,e : string);
  265.  
  266.       begin
  267. {$ifdef FPC}
  268.          inherited init(p+n+e,65536);
  269. {$else}
  270.          inherited init(p+n+e,10000);
  271. {$endif}
  272.          path:=stringdup(p);
  273.          name:=stringdup(n);
  274.          ext:=stringdup(e);
  275.       end;
  276.  
  277.     destructor textfile.done;
  278.  
  279.       begin
  280.          inherited done;
  281.       end;
  282.  
  283. {****************************************************************************
  284.                                   TINPUTFILE
  285.  ****************************************************************************}
  286.  
  287.     constructor tinputfile.init(const p,n,e : string);
  288.  
  289.       begin
  290.          inherited init(p,n,e);
  291.          filenotatend:=true;
  292.          line_no:=1;
  293.          line_count:=0;
  294.          next:=nil;
  295.       end;
  296.  
  297.     procedure tinputfile.write_file_line(var t : text);
  298.  
  299.       begin
  300.          write(t,get_file_line);
  301.       end;
  302.  
  303.     function tinputfile.get_file_line : string;
  304.  
  305.       begin
  306. {$ifdef USE_RHIDE}
  307.         get_file_line:=lowercase(name^+ext^)+':'+tostr(line_no)+':'
  308. {$else  USE_RHIDE}
  309.         get_file_line:=name^+ext^+'('+tostr(line_no)+')'
  310. {$endif USE_RHIDE}
  311.       end;
  312.  
  313. {****************************************************************************
  314.                                 TFILEMANAGER
  315.  ****************************************************************************}
  316.  
  317.     constructor tfilemanager.init;
  318.  
  319.       begin
  320.          files:=nil;
  321.          last_ref_index:=0;
  322.       end;
  323.  
  324.     destructor tfilemanager.done;
  325.  
  326.       var
  327.          hp : pextfile;
  328.  
  329.       begin
  330.          hp:=files;
  331.          while assigned(hp) do
  332.            begin
  333.               files:=files^._next;
  334.               dispose(hp,done);
  335.               hp:=files;
  336.            end;
  337.       end;
  338.  
  339.     procedure tfilemanager.close_all;
  340.  
  341.       begin
  342.       end;
  343.  
  344.     procedure tfilemanager.register_file(f : pextfile);
  345.  
  346.       begin
  347.          inc(last_ref_index);
  348.          f^._next:=files;
  349.          f^.ref_index:=last_ref_index;
  350.          files:=f;
  351.       end;
  352.  
  353. {****************************************************************************
  354.                            Imports stuff
  355.  ****************************************************************************}
  356.  
  357.  
  358.     constructor timported_procedure.init(const n,s : string;o : word);
  359.  
  360.       begin
  361.          inherited init;
  362.          func:=stringdup(n);
  363.          name:=stringdup(s);
  364.          ordnr:=o;
  365.          lab:=nil;
  366.       end;
  367.  
  368.     destructor timported_procedure.done;
  369.  
  370.       begin
  371.          stringdispose(name);
  372.          inherited done;
  373.       end;
  374.  
  375.     constructor timportlist.init(const n : string);
  376.  
  377.       begin
  378.          inherited init;
  379.          dllname:=stringdup(n);
  380.          imported_procedures:=new(plinkedlist,init);
  381.       end;
  382.  
  383.     destructor timportlist.done;
  384.  
  385.       begin
  386.          dispose(imported_procedures,done);
  387.          stringdispose(dllname);
  388.       end;
  389.  
  390. {****************************************************************************
  391.                                   TMODULE
  392.  ****************************************************************************}
  393.  
  394. {$I-}
  395.  
  396.     function tmodule.load_ppu(const unit_path,n,ext : string):boolean;
  397.     var
  398.          header  : tunitheader;
  399.          count   : longint;
  400.          temp,hs : string;
  401.          b       : byte;
  402.          code    : word;
  403.          objfiletime,
  404.          ppufiletime,
  405.          asmfiletime,
  406.          source_time : longint;
  407. {$ifdef UseBrowser}
  408.          hp : pextfile;
  409.          _d : dirstr;
  410.          _n : namestr;
  411.          _e : extstr;
  412. {$endif UseBrowser}
  413.  
  414.     begin
  415.       load_ppu:=false;
  416.  
  417.       Message1(unit_u_ppu_loading,ppufilename^);
  418.       ppufile:=new(pextfile,init(unit_path,n,ext));
  419.       ppufile^.reset;
  420.       ppufile^.flush;
  421.  
  422.       {Get ppufile time}
  423.       ppufiletime:=getnamedfiletime(ppufilename^);
  424.       Message1(unit_d_ppu_time,filetimestring(ppufiletime));
  425.  
  426.       { load the header }
  427.       ppufile^.read_data(header,sizeof(header),count);
  428.       if count<>sizeof(header) then
  429.        begin
  430.          ppufile^.done;
  431.          Message(unit_d_ppu_file_too_short);
  432.          exit;
  433.        end;
  434.  
  435.       { check for a valid PPU file }
  436.       if (header[0]<>'P') or (header[1]<>'P') or (header[2]<>'U') then
  437.        begin
  438.          ppufile^.done;
  439.          Message(unit_d_ppu_invalid_header);
  440.          exit;
  441.        end;
  442.  
  443.       { load ppu version }
  444.       val(header[3]+header[4]+header[5],ppuversion,code);
  445.       if ppuversion<>13 then
  446.        begin
  447.          ppufile^.done;
  448.          Message1(unit_d_ppu_invalid_version,tostr(ppuversion));
  449.          exit;
  450.        end;
  451.  
  452.       flags:=byte(header[9]);
  453.       Message1(unit_d_ppu_flags,tostr(flags));
  454.  
  455.       crc:=plongint(@header[10])^;
  456.       Message1(unit_d_ppu_crc,tostr(crc));
  457.  
  458.     { search source files there is at least one source file }
  459.       do_compile:=false;
  460.       sources_avail:=true;
  461.       ppufile^.read_data(b,1,count);
  462.       while b<>ibend do
  463.        begin
  464.          ppufile^.read_data(hs[0],1,count);
  465.          ppufile^.read_data(hs[1],ord(hs[0]),count);
  466.          if (flags and uf_in_library)<>0 then
  467.           begin
  468.             sources_avail:=false;
  469.             temp:=' library';
  470.           end
  471.          else
  472.           begin
  473.             { check the date of the source files }
  474.             Source_Time:=GetNamedFileTime(unit_path+hs);
  475.             if Source_Time=-1 then
  476.              begin
  477.                sources_avail:=false;
  478.                temp:=' not found';
  479.              end
  480.             else
  481.              begin
  482.                temp:=' time '+filetimestring(source_time);
  483.                if (source_time>ppufiletime) then
  484.                 begin
  485.                   do_compile:=true;
  486.                   temp:=temp+' *'
  487.                 end;
  488.              end;
  489.           end;
  490.          Message1(unit_t_ppu_source,unit_path+hs+temp);
  491. {$ifdef UseBrowser}
  492.          fsplit(unit_path+hs,_d,_n,_e);
  493.          new(hp,init(_d,_n,_e));
  494.          { the indexing should match what is done in writeasunit }
  495.          sourcefiles.register_file(hp);
  496. {$endif UseBrowser}
  497.          ppufile^.read_data(b,1,count);
  498.        end;
  499.     { main source is always the last }
  500.       stringdispose(mainsource);
  501.       mainsource:=stringdup(ppufile^.path^+hs);
  502.  
  503.     { check the object and assembler file if not a library }
  504.       if (flags and uf_in_library)=0 then
  505.        begin
  506.        { the objectfile should be newer than the ppu file }
  507.          objfiletime:=getnamedfiletime(objfilename^);
  508.          if (ppufiletime<0) or (objfiletime<0) or (ppufiletime>objfiletime) then
  509.           begin
  510.           { check if assembler file is older than ppu file }
  511.             asmfileTime:=GetNamedFileTime(asmfilename^);
  512.             if (asmfiletime<0) or (ppufiletime>asmfiletime) then
  513.              begin
  514.                Message(unit_d_obj_and_asm_are_older_than_ppu);
  515.                do_compile:=true;
  516.              end
  517.             else
  518.              begin
  519.                Message(unit_d_obj_is_older_than_asm);
  520.                do_assemble:=true;
  521.              end;
  522.           end;
  523.        end;
  524.       load_ppu:=true;
  525.     end;
  526.  
  527.     procedure tmodule.search_unit(const n : string);
  528.       var
  529.          ext       : string[8];
  530.          singlepathstring,
  531.          Path,
  532.          filename  : string;
  533.          found     : boolean;
  534.          start,pos : longint;
  535.  
  536.          Function UnitExists(const ext:string):boolean;
  537.          begin
  538.            Message1(unit_t_unitsearch,Singlepathstring+filename+ext);
  539.            UnitExists:=FileExists(Singlepathstring+FileName+ext);
  540.          end;
  541.  
  542.          Procedure SetFileNames;
  543.          begin
  544.            stringdispose(mainsource);
  545.            stringdispose(objfilename);
  546.            stringdispose(asmfilename);
  547.            stringdispose(ppufilename);
  548.            mainsource:=stringdup(SinglePathString+FileName+ext);
  549.            objfilename:=stringdup(SinglePathString+FileName+target_info.objext);
  550.            asmfilename:=stringdup(SinglePathString+FileName+target_info.asmext);
  551.            ppufilename:=stringdup(SinglePathString+FileName+target_info.unitext);
  552.          end;
  553.  
  554.  
  555.        begin
  556.          start:=1;
  557.          filename:=FixFileName(n);
  558.          path:=UnitSearchPath;
  559.          Found:=false;
  560.          repeat
  561.          {Create current path to check}
  562.            pos:=system.pos(';',path);
  563.            if pos=0 then
  564.             pos:=length(path)+1;
  565.            singlepathstring:=FixPath(copy(path,start,pos-start));
  566.            delete(path,start,pos-start+1);
  567.          { Check for PPL file }
  568.            if not (cs_link_static in aktswitches) then
  569.             begin
  570.               Found:=UnitExists(target_info.libext);
  571.               if Found then
  572.                Begin
  573.                  SetFileNames;
  574.                  Found:=Load_PPU(singlepathstring,filename,target_info.libext);
  575.                End;
  576.  
  577.              end;
  578.          { Check for PPU file }
  579.            if not (cs_link_dynamic in aktswitches) and not Found then
  580.             begin
  581.               Found:=UnitExists(target_info.unitext);
  582.               if Found then
  583.                Begin
  584.                  SetFileNames;
  585.                  Found:=Load_PPU(singlepathstring,filename,target_info.unitext);
  586.                End;
  587.  
  588.             end;
  589.          { Check for Sources }
  590.            if not Found then
  591.             begin
  592.               ppufile:=nil;
  593.               do_compile:=true;
  594.             {Check for .pp file}
  595.               Found:=UnitExists(target_info.sourceext);
  596.               if Found then
  597.                Ext:=target_info.sourceext
  598.               else
  599.                begin
  600.                {Check for .pas}
  601.                  Found:=UnitExists(target_info.pasext);
  602.                  if Found then
  603.                   Ext:=target_info.pasext;
  604.                end;
  605.               if Found then
  606.                begin
  607.                  sources_avail:=true;
  608.                {Load Filenames when found}
  609.                  SetFilenames;
  610.                end
  611.               else
  612.                begin
  613.                  sources_avail:=false;
  614.                  stringdispose(mainsource);
  615.                end;
  616.             end;
  617.          until Found or (path='');
  618.       end;
  619.  
  620.     constructor tmodule.init(const s:string;is_unit:boolean);
  621.       var
  622.         p:dirstr;
  623.         n:namestr;
  624.         e:extstr;
  625.       begin
  626.          FSplit(s,p,n,e);
  627.          n:=Upper(n);
  628.          unitname:=stringdup(n);
  629.          objfilename:=nil;
  630.          asmfilename:=nil;
  631.          ppufilename:=nil;
  632.          mainsource:=stringdup(s);
  633.          used_units.init;
  634.          sourcefiles.init;
  635.          linkofiles.init;
  636.          linklibfiles.init;
  637.          ppufile:=nil;
  638.          current_inputfile:=nil;
  639.          map:=nil;
  640.          symtable:=nil;
  641.          flags:=0;
  642.          unitcount:=1;
  643.          do_assemble:=false;
  644.          do_compile:=false;
  645.          sources_avail:=true;
  646.          compiled:=false;
  647.          in_implementation:=false;
  648.          in_main:=false;
  649.          uses_imports:=false;
  650.          imports:=new(plinkedlist,init);
  651.          output_format:=commandline_output_format;
  652.        { search the PPU file if it is an unit }
  653.          if is_unit then
  654.           search_unit(unitname^);
  655.       end;
  656.  
  657.     destructor tmodule.special_done;
  658.  
  659.       begin
  660.          if assigned(map) then dispose(map);
  661.          { cannot remove that because it is linked
  662.          in the global chain of used_objects
  663.          used_units.done; }
  664.          sourcefiles.done;
  665.          linkofiles.done;
  666.          linklibfiles.done;
  667.          if assigned(ppufile) then
  668.           dispose(ppufile,done);
  669.          if assigned(imports) then
  670.            dispose(imports,done);
  671.          inherited done;
  672.       end;
  673.  
  674. {****************************************************************************
  675.                               TUSED_UNIT
  676.  ****************************************************************************}
  677.  
  678.  
  679.     constructor tused_unit.init(_u : pmodule;f : byte);
  680.  
  681.       begin
  682.          u:=_u;
  683.          in_interface:=false;
  684.          in_uses:=false;
  685.          is_stab_written:=false;
  686.          unitid:=f;
  687.       end;
  688.  
  689.     destructor tused_unit.done;
  690.  
  691.       begin
  692.          inherited done;
  693.       end;
  694. {$I+}
  695.  
  696. end.
  697. {
  698.   $Log: files.pas,v $
  699.   Revision 1.1.1.1  1998/03/25 11:18:12  root
  700.   * Restored version
  701.  
  702.   Revision 1.37  1998/03/13 22:45:58  florian
  703.     * small bug fixes applied
  704.  
  705.   Revision 1.36  1998/03/11 22:22:52  florian
  706.     * Fixed circular unit uses, when the units are not in the current dir (from Peter)
  707.     * -i shows correct info, not <lf> anymore (from Peter)
  708.     * linking with shared libs works again (from Peter)
  709.  
  710.   Revision 1.35  1998/03/10 16:27:38  pierre
  711.     * better line info in stabs debug
  712.     * symtabletype and lexlevel separated into two fields of tsymtable
  713.     + ifdef MAKELIB for direct library output, not complete
  714.     + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  715.       working
  716.     + ifdef TESTFUNCRET for setting func result in underfunction, not
  717.       working
  718.  
  719.   Revision 1.34  1998/03/10 01:17:18  peter
  720.     * all files have the same header
  721.     * messages are fully implemented, EXTDEBUG uses Comment()
  722.     + AG... files for the Assembler generation
  723.  
  724.   Revision 1.33  1998/03/04 17:33:44  michael
  725.   + Changed ifdef FPK to ifdef FPC
  726.  
  727.   Revision 1.32  1998/03/04 01:35:03  peter
  728.     * messages for unit-handling and assembler/linker
  729.     * the compiler compiles without -dGDB, but doesn't work yet
  730.     + -vh for Hint
  731.  
  732.   Revision 1.31  1998/02/28 14:43:47  florian
  733.     * final implemenation of win32 imports
  734.     * extended tai_align to allow 8 and 16 byte aligns
  735.  
  736.   Revision 1.30  1998/02/28 09:30:57  florian
  737.     + writing of win32 import section added
  738.  
  739.   Revision 1.29  1998/02/28 00:20:23  florian
  740.     * more changes to get import libs for Win32 working
  741.  
  742.   Revision 1.28  1998/02/26 11:57:06  daniel
  743.   * New assembler optimizations commented out, because of bugs.
  744.   * Use of dir-/name- and extstr.
  745.  
  746.   Revision 1.27  1998/02/24 14:20:51  peter
  747.     + tstringcontainer.empty
  748.     * ld -T option restored for linux
  749.     * libraries are placed before the objectfiles in a .PPU file
  750.     * removed 'uses link' from files.pas
  751.  
  752.   Revision 1.26  1998/02/24 10:29:13  peter
  753.     * -a works again
  754.  
  755.   Revision 1.25  1998/02/24 00:19:09  peter
  756.     * makefile works again (btw. linux does like any char after a \ )
  757.     * removed circular unit with assemble and files
  758.     * fixed a sigsegv in pexpr
  759.     * pmodule init unit/program is the almost the same, merged them
  760.  
  761.   Revision 1.24  1998/02/22 23:03:17  peter
  762.     * renamed msource->mainsource and name->unitname
  763.     * optimized filename handling, filename is not seperate anymore with
  764.       path+name+ext, this saves stackspace and a lot of fsplit()'s
  765.     * recompiling of some units in libraries fixed
  766.     * shared libraries are working again
  767.     + $LINKLIB <lib> to support automatic linking to libraries
  768.     + libraries are saved/read from the ppufile, also allows more libraries
  769.       per ppufile
  770.  
  771.   Revision 1.23  1998/02/17 21:20:48  peter
  772.     + Script unit
  773.     + __EXIT is called again to exit a program
  774.     - target_info.link/assembler calls
  775.     * linking works again for dos
  776.     * optimized a few filehandling functions
  777.     * fixed stabs generation for procedures
  778.  
  779.   Revision 1.22  1998/02/16 12:51:30  michael
  780.   + Implemented linker object
  781.  
  782.   Revision 1.21  1998/02/13 10:34:58  daniel
  783.   * Made Motorola version compilable.
  784.   * Fixed optimizer
  785.  
  786.   Revision 1.20  1998/02/12 11:50:04  daniel
  787.   Yes! Finally! After three retries, my patch!
  788.  
  789.   Changes:
  790.  
  791.   Complete rewrite of psub.pas.
  792.   Added support for DLL's.
  793.   Compiler requires less memory.
  794.   Platform units for each platform.
  795.  
  796.   Revision 1.19  1998/02/06 23:08:33  florian
  797.     + endian to targetinfo and sourceinfo added
  798.     + endian independed writing of ppu file (reading missed), a PPU file
  799.       is written with the target endian
  800.  
  801.   Revision 1.18  1998/02/02 13:13:27  pierre
  802.     * line_count transfered to tinputfile, to avoid crosscounting
  803.  
  804.   Revision 1.17  1998/01/30 17:31:20  pierre
  805.     * bug of cyclic symtablestack fixed
  806.  
  807.   Revision 1.16  1998/01/26 18:51:18  peter
  808.     * ForceSlash() changed to FixPath() which also removes a trailing './'
  809.  
  810.   Revision 1.15  1998/01/23 17:12:11  pierre
  811.     * added some improvements for as and ld :
  812.       - doserror and dosexitcode treated separately
  813.       - PATH searched if doserror=2
  814.     + start of long and ansi string (far from complete)
  815.       in conditionnal UseLongString and UseAnsiString
  816.     * options.pas cleaned (some variables shifted to globals)gl
  817.  
  818.   Revision 1.14  1998/01/22 08:57:54  peter
  819.     + added target_info.pasext and target_info.libext
  820.  
  821.   Revision 1.13  1998/01/21 00:11:35  peter
  822.     * files in a ppl will now not recompile
  823.     * better info about source files of a ppu, a * after the time will
  824.       indicate that the file is changed
  825.  
  826.   Revision 1.12  1998/01/20 13:16:29  michael
  827.   + Added flag for static/shared libs.
  828.  
  829.   Revision 1.11  1998/01/17 01:57:32  michael
  830.   + Start of shared library support. First working version.
  831.  
  832.   Revision 1.10  1998/01/16 12:52:09  michael
  833.   + Path treatment and file searching should now be more or less in their
  834.     definite form:
  835.     - Using now modified AddPathToList everywhere.
  836.     - File Searching mechanism is uniform for all files.
  837.     - Include path is working now !!
  838.     All fixes by Peter Vreman. Tested with remake3 target.
  839.  
  840.   Revision 1.9  1998/01/16 00:00:54  michael
  841.   + Better and more modular searching and loading of units.
  842.     - searching in tmodule.search_unit.
  843.     - initial Loading in tmpodule.load_ppu.
  844.     - tmodule.init now calls search_unit.
  845.   * Case sensitivity problem of unix hopefully solved now forever.
  846.     (All from Peter Vreman, checked with remake3)
  847.  
  848.   Revision 1.8  1998/01/15 13:07:46  michael
  849.   + added library treating stuff
  850.  
  851.   Revision 1.7  1998/01/15 12:01:19  michael
  852.   * Linux prints now that actual name of the file being loaded.
  853.  
  854.   Revision 1.6  1998/01/13 23:39:26  michael
  855.   * changed mechanism to look for unit file.
  856.   + added iblibraries constant to implement shared libraries.
  857.  
  858.   Revision 1.5  1998/01/13 23:05:51  florian
  859.     + unit format 013 (change of options size, see symtable.pas log)
  860.  
  861.   Revision 1.4  1998/01/13 17:13:06  michael
  862.   * File time handling and file searching is now done in an OS-independent way,
  863.     using the new file treating functions in globals.pas.
  864.  
  865.   Revision 1.3  1998/01/07 00:16:49  michael
  866.   Restored released version (plus fixes) as current
  867.  
  868.   Revision 1.2  1997/11/28 18:14:31  pierre
  869.    working version with several bug fixes
  870.  
  871.   Revision 1.1.1.1  1997/11/27 08:32:56  michael
  872.   FPC Compiler CVS start
  873.  
  874.  
  875.   Pre-CVS log:
  876.  
  877.   CEC  Carl-Eric Codere
  878.   FK   Florian Klaempfl
  879.   +    feature added
  880.   -    removed
  881.   *    bug fixed or changed
  882.  
  883.   History (started with version 0.9.0):
  884.        2th december 1996:
  885.          + unit started  (FK)
  886.       22th december 1996:
  887.          + tinputfile added  (FK)
  888.       7th september 1997:
  889.          + moved main_module and current_module to const section
  890.            line ~319 and ~416: in_main initialized - added in_main
  891.            field to tmodule object  (CEC)
  892.  
  893. }
  894.