Browse Source

Add support for parsing required packages.

pkgutil.pas:
  + new function add_package to add a package to the list of available packages with the possibility to check for duplicates
  * load_packages: also load all required packages
pmodules.pas, proc_package:
  * create the tpcppackage instance earlier (and use the module name as read from the source file as package name)
  * clear the list of packages in case the user passed any using -FPxxx
  * parse the "requires" section like a list of units and add each full identifier as a package to load
  * before parsing the "contains" section load all packages, so that all units can be correctly resolved

git-svn-id: branches/svenbarth/packages@29042 -
svenbarth 10 years ago
parent
commit
be6a1c719c
2 changed files with 58 additions and 3 deletions
  1. 22 0
      compiler/pkgutil.pas
  2. 36 3
      compiler/pmodules.pas

+ 22 - 0
compiler/pkgutil.pas

@@ -33,6 +33,7 @@ interface
   Function RewritePPU(const PPUFn,PPLFn:String):Boolean;
   procedure export_unit(u:tmodule);
   procedure load_packages;
+  procedure add_package(const name:string;ignoreduplicates:boolean);
 
 implementation
 
@@ -422,6 +423,27 @@ implementation
     end;
 
 
+  procedure add_package(const name:string;ignoreduplicates:boolean);
+    var
+      entry : ppackageentry;
+      i : longint;
+    begin
+      for i:=0 to packagelist.count-1 do
+        begin
+          if packagelist.nameofindex(i)=name then
+            begin
+              if not ignoreduplicates then
+                Message1(package_e_duplicate_package,name);
+              exit;
+            end;
+        end;
+      new(entry);
+      entry^.package:=nil;
+      entry^.realpkgname:=name;
+      packagelist.add(name,entry);
+    end;
+
+
   procedure createimportlibfromexternals(pkg:tpackage);
     type
       tcacheentry=record

+ 36 - 3
compiler/pmodules.pas

@@ -1380,6 +1380,7 @@ type
          current_module.setmodulename(module_name);
          current_module.ispackage:=true;
          exportlib.preparelib(module_name);
+         pkg:=tpcppackage.create(module_name);
 
          if tf_library_needs_pic in target_info.flags then
            include(current_settings.moduleswitches,cs_create_pic);
@@ -1402,11 +1403,42 @@ type
          { of the program                                             }
          current_module.localsymtable:=tstaticsymtable.create(current_module.modulename^,current_module.moduleid);
 
-         {Load the units used by the program we compile.}
-         if token=_REQUIRES then
+         { ensure that no packages are picked up from the options }
+         packagelist.clear;
+
+         {Read the packages used by the package we compile.}
+         if (token=_ID) and (idtoken=_REQUIRES) then
            begin
+             { consume _REQUIRES word }
+             consume(_ID);
+             while true do
+               begin
+                 if token=_ID then
+                   begin
+                     module_name:=orgpattern;
+                     consume(_ID);
+                     while token=_POINT do
+                       begin
+                         consume(_POINT);
+                         module_name:=module_name+'.'+orgpattern;
+                         consume(_ID);
+                       end;
+                     add_package(module_name,false);
+                   end
+                 else
+                   consume(_ID);
+                 if token=_COMMA then
+                   consume(_COMMA)
+                 else
+                   break;
+               end;
+             consume(_SEMICOLON);
            end;
 
+         { now load all packages, so that we can determine whether a unit is
+           already provided by one of the loaded packages }
+         load_packages;
+
          {Load the units used by the program we compile.}
          if (token=_ID) and (idtoken=_CONTAINS) then
            begin
@@ -1495,6 +1527,7 @@ type
            begin
              Message1(unit_f_errors_in_unit,tostr(Errorcount));
              status.skip_error:=true;
+             pkg.free;
              exit;
            end;
 
@@ -1564,6 +1597,7 @@ type
           begin
             Message1(unit_f_errors_in_unit,tostr(Errorcount));
             status.skip_error:=true;
+            pkg.free;
             exit;
           end;
 
@@ -1571,7 +1605,6 @@ type
            begin
              { add all contained units to the package }
              { TODO : handle implicitly imported units }
-             pkg:=tpcppackage.create(current_module.modulename^);
              uu:=tused_unit(current_module.used_units.first);
              while assigned(uu) do
                begin