## vim: filetype=makoada

   <%
      scn_var_type = capi.get_name('project_scenario_variable')
      scn_var_ptr = capi.get_name('project_scenario_variable_ptr')
      scn_var_array = capi.get_name('project_scenario_variable_array')
   %>

   function Scenario_Vars_Count
     (Scenario_Vars : System.Address)
      return Natural;
   --  Return the number of scenario variables in the Scenario_Vars C-style
   --  array. This counts the number of entries before the first NULL entry.

   -------------------------
   -- Scenario_Vars_Count --
   -------------------------

   function Scenario_Vars_Count
     (Scenario_Vars : System.Address)
      return Natural
   is
      Result : Natural := 1;
      SV     : ${scn_var_array} (Positive)
         with Import => True,
              Address => Scenario_Vars;
   begin
      loop
         exit when SV (Result).Name = Null_Ptr;
         Result := Result + 1;
      end loop;
      return Result - 1;
   end Scenario_Vars_Count;

   function ${capi.get_name('create_project_unit_provider')}
     (Project_File  : chars_ptr;
      Scenario_Vars : System.Address)
      return ${unit_provider_type}
   is
      PF      : constant String := Value (Project_File);

      Project : Project_Tree_Access := new Project_Tree;
      Env     : Project_Environment_Access;

      Result  : Unit_Provider_Access;
   begin
      Initialize (Env);
      if Scenario_Vars /= System.Null_Address then
         declare
            Vars : ${scn_var_array} (1 .. Scenario_Vars_Count (Scenario_Vars))
               with Import  => True,
                    Address => Scenario_Vars;
         begin
            for V of Vars loop
               Change_Environment (Env.all, Value (V.Name), Value (V.Value));
            end loop;
         end;
      end if;

      begin
         Load (Project.all, Create (+PF), Env);
      exception
         when Invalid_Project =>
            Free (Env);
            Free (Project);
            return ${unit_provider_type} (System.Null_Address);
      end;

      Result :=
         new Project_Unit_Provider_Type'(Create (Project, Env, True));
      return Wrap (Result);
   end;

   function ${capi.get_name('create_auto_provider')}
     (Input_Files : System.Address;
      Charset     : chars_ptr)
      return ${unit_provider_type}
   is
      use GNATCOLL.VFS;

      type C_String_Array is array (Positive) of chars_ptr
         with Convention => C;

      Files_Count       : Natural := 0;
      Input_Files_Array : C_String_Array with
         Import  => True,
         Address => Input_Files;

      Actual_Charset : constant String :=
        (if Charset = Null_Ptr then Default_Charset else Value (Charset));
   begin
      while Input_Files_Array (Files_Count + 1) /= Null_Ptr loop
         Files_Count := Files_Count + 1;
      end loop;

      declare
         --  Allocate the array of filenames on the heap, as it may be too
         --  large for the stack.

         Files  : File_Array_Access := new File_Array (1 .. Files_Count);
         Result : Unit_Provider_Access;
      begin
         for I in Files'Range loop
            Files (I) := Create (+Value (Input_Files_Array (I)));
         end loop;

         Result := Create_Auto_Provider (Files.all, Actual_Charset);
         Unchecked_Free (Files);
         return Wrap (Result);
      end;
   end;
