with Ada.Text_IO;             use Ada.Text_IO;
with Ada.Characters.Latin_1;  use Ada.Characters;

package body Parser is

   File : File_Type;


   procedure Initialize (File : in String) is
   begin
      Open (Parser.File, Mode => In_File, Name => File);
   end;


   type Info_Type is record
      First, Last : Positive;
   end record;


   procedure Get_Info
     (Info  :    out Info_Type;
      Line  : in     String;
      First : in out Positive;
      Last  : in     Positive) is

      pragma Assert (First <= Last);

   begin

      Info.First := First;

      loop

         Info.Last := First;

         First := First + 1;

         exit when First > Last or else Line (First) = Latin_1.HT;

      end loop;

      while First <= Last and then Line (First) = Latin_1.HT loop

         First := First + 1;

      end loop;

   end Get_Info;


   procedure Iterate (Process : not null access
                        procedure (Student : String;
                                   Advisor : String;
                                   Place   : String;
                                   Date    : String)) is

      Line : String (1 .. 133);
      Last : Natural;

      Index : Positive;

      Student, Advisor, Place, Date : Info_Type;

   begin

      loop

         loop

            if End_Of_File (File) then
               Reset (File);
               return;
            end if;

            Get_Line (File, Line, Last);
            pragma Assert (Last < Line'Last);

            if Last >= Line'First
              and then Line (Line'First) /= '#'
            then
               exit;
            end if;

         end loop;

         Index := 1;

         Get_Info (Student, Line, Index, Last);
         Get_Info (Advisor, Line, Index, Last);
         Get_Info (Place, Line, Index, Last);
         Get_Info (Date, Line, Index, Last);

         if Line (Advisor.First .. Advisor.Last) = "?" then
            Advisor := (First => Index, Last => Index + 2);
            Line (Advisor.First .. Advisor.Last) := "---";
         end if;

         Process
           (Student => Line (Student.First .. Student.Last),
            Advisor => Line (Advisor.First .. Advisor.Last),
            Place   => Line (Place.First .. Place.Last),
            Date    => Line (Date.First .. Date.Last));

      end loop;

   end Iterate;


end Parser;

