http://www.adaconcept.com/programs/elaboracio/rendezett_parancssori_parameterek.adb
with Ada.Command_Line;                                                                                                 -- FONTOS!!! A csomag specifikaciojaban talalhato Preelaborate pragma miatt hasznalhatjuk az Elemek tomb deklaraciojaban a csomag Argument_Count fuggvenye altal visszaadott erteket.
with Ada.Text_IO;                                                                                                      -- FONTOS!!! A csomag specifikaciojaban Elaborate_Body pragma talalhato ez teszi lehetove, hogy elaboracios idoben hasznaljuk az Ada.Text_IO muveleteit a Rendezett_Parancssori_Parameterek csomagban.

package body Rendezett_Parancssori_Parameterek is


   type Rendezendo_Elemek_Tomb_Tipus is array(Positive range <>) of Positive;


   function Alapertelmezett_Ertekek(A_Tomb_Hossza : Natural) return Rendezendo_Elemek_Tomb_Tipus;


   -- ha  [*] -ot ide tesszuk, a program lefordul, de elaboracios hibat kapunk! (hiszen a hivatkozott fuggveny torzse meg nem ismert ezen a ponton) Ne hidd le, probald ki! :)


   function Alapertelmezett_Ertekek(A_Tomb_Hossza : Natural) return Rendezendo_Elemek_Tomb_Tipus is
      Vissza : Rendezendo_Elemek_Tomb_Tipus(1 .. A_Tomb_Hossza);
   begin
      for i in Vissza'Range loop
         Vissza(i):=i;
      end loop;
      return Vissza;
   end Alapertelmezett_Ertekek;


   -- figyeljuk meg, mennyire fontos szerepet jatszik a tomb indexelese
   Elemek : Rendezendo_Elemek_Tomb_Tipus := Alapertelmezett_Ertekek(Ada.Command_Line.Argument_Count);                  -- [*]


   function Parameterek_Szama return Natural is
   begin
      return Ada.Command_Line.Argument_Count;
   end Parameterek_Szama;


   function Parameter (Hanyadik : Positive) return String is
   begin
      return Ada.Command_Line.Argument(Elemek(Hanyadik));                                                              -- (a rendezes tulajdonkeppen nem mas, mint egy indexhalmazbol indexhalmazba kepezo bijekcio, ahol az eredmenyt kompoziciokent adjuk meg... ez a gondolat kesobb meg hasznos lehet :))
   end Parameter;


   subtype T is Rendezendo_Elemek_Tomb_Tipus;                                                                          -- a rovidebb irasmod erdekeben atnevezzuk a Rendezendo_Elemek_Tomb_Tipus -t


   generic
      S1 : T;                                                                                                          --| a ket rendezendo reszsorozat
      S2 : T;                                                                                                          --|
      S  : in out T;                                                                                                   -- az osszefesules eredmenye (figyeljuk meg a parameter modjat)
   package Osszefesul is
      -- ide most szandekosan nem irunk semmit :)
   end Osszefesul;


   package body Osszefesul is

      -- Emlekezzunk a ketvaltozos-egyerteku elemenkenti feldolgozasra!
      function Osszefesul( l : T; m : T) return T is                                                                   -- a rovidebb irasmod erdekeben nem hasznalunk beszedes elnevezeseket (ezzel nem veszitunk a program olvashatosagabol)
      begin

         while l'Length /= 0 and m'Length /= 0 loop

            if Ada.Command_Line.Argument(l(l'First)) < Ada.Command_Line.Argument(m(m'First)) then

               return l(l'First) & Osszefesul(l(l'First + 1 .. l'Last), m(m'First .. m'Last));

            elsif Ada.Command_Line.Argument(l(l'First)) > Ada.Command_Line.Argument(m(m'First)) then

               return m(m'First) & Osszefesul(l(l'First .. l'Last), m(m'First + 1 .. m'Last));

            else

               return m(m'First) & l(l'First) & Osszefesul(l(l'First + 1 .. l'Last), m(m'First + 1 .. m'Last));

            end if;

         end loop;

         return l & m;

      end Osszefesul;

   begin
      S := Osszefesul(S1, S2);
   end Osszefesul;


   generic
      S : in out T;                                                                                                    -- figyeljuk meg a parameter modjat
   package Osszefesuleses_Rendezes is
      -- a csomag specifikaciojat uresen hagyjuk
   end Osszefesuleses_Rendezes;


   function Rendez(l : T) return T;                                                                                    -- nem lehet mindig elkerulni a warningokat!... FONOTS: ha ide, ennek a sornak a helyere masoljuk a fuggveny torzset, van olyan fordito, ami a fuggvenyben levo Osszefesuleses_Rendezes peldanyositasokat mar nem hajtja vegre, es igy hibas eredmenyt ad a program!


   package body Osszefesuleses_Rendezes is                                                                             -- figyeljuk meg a csomag torzse es a tartalmazo csomag kozotti fuggosegeket
   begin
      -- ezek a csomag torzsenek utasitasai
      if S'length > 1 then
         S := Rendez(S);                                                                                               -- warning
      end if;
   end Osszefesuleses_Rendezes;


   function Rendez(l : T) return T is                                                                                  -- a rovidebb irasmod erdekeben nem hasznalunk beszedes elnevezeseket (ezzel nem veszitunk a program olvashatosagabol)

      E : T := l(l'First .. l'First + (l'Length / 2) - 1);  -- eleje
      V : T := l(l'First + (l'Length / 2) .. l'Last);       -- vege

      package A_Tomb_Elso_Felenek_Rendezeset_Vegzo_Csomag    is new Osszefesuleses_Rendezes(E);                        --| figyeljuk meg, hogy magukra a csomagokra nem hivatkozunk a kesobbiekben, csak az altaluk megvaltoztatott parametereket hasznaljuk majd fel :)
      package A_Tomb_Masodik_Felenek_Rendezeset_Vegzo_Csomag is new Osszefesuleses_Rendezes(V);                        --|

   begin

      declare
         O : T(1..l'Length);                                -- az osszefesules eredmenye
         package Osszefesules is new Osszefesul(E, V, O);
      begin
         return O;
      end;

   end Rendez;


   package A_Rendezest_Vegzo_Csomag is new Osszefesuleses_Rendezes(Elemek);                                            -- figyeljuk meg, hogy magara a csomagra nem hivatkozunk a kesobbiekben, csak az altala megvaltoztatott parametert hasznaljuk majd fel :)


begin

   Ada.Text_IO.Put_Line("A Rendezett_Parancssori_Parameterek nevu csomag elaboracioja veget ert.");

   for i in 1 .. Parameterek_Szama loop
      Ada.Text_IO.Put_Line(Parameter(i));
   end loop;

end Rendezett_Parancssori_Parameterek;