with Ada.Text_IO;
with Ada.Exceptions;
with GNAT.Command_Line;
with String_Pkg;
with Ayacc_File_Names;
with Output_File;
package body Options is

   use String_Pkg;
   use Ada.Text_Io;

   -- SCCS_ID : constant String := "@(#) options.ada, Version 1.2";
   -- Rcs_ID : constant String := "$Header: options.a,v 0.1 86/04/01 15:08:15 ada Exp $";

   Verbose_Option        : Boolean := False;
   Interface_To_C_Option : Boolean := False;
   Summary_Option        : Boolean := False;
   Loud_Option           : Boolean := False;

   Copyright : constant String :=
     "@(#) Copyright (c) 1990 Regents of the University of California.";
   Copyright2 : constant String := "All rights reserved.";

   procedure Put_Help_Message is
   begin
      Put_Line (Standard_Error, "ayacc version 1.4.1");
      Put_Line (Standard_Error, Copyright);
      Put_Line (Standard_Error, Copyright2);
      New_Line (Standard_Error);
      Put_Line
        (Standard_Error,
         "Usage: ayacc [-CDPcdlrsv] [-D dir] [-e ext] [-n size] [-S skeleton] grammar");
      Put_Line
        (Standard_Error,
         "-c          Specifies the generation of a 'C' Lex interface.");
      Put_Line
        (Standard_Error,
         "-d          Specifies the production of debugging output");
      Put_Line
        (Standard_Error,
         "-D dir      Write the generated files to the directory specified");
      Put_Line
        (Standard_Error,
         "-P          Generate private package for the parser");
      Put_Line
        (Standard_Error, "-l          Loud option to tell what's going on");
      Put_Line
        (Standard_Error,
         "-k          Keep the token case as written in the grammar");
      Put_Line
        (Standard_Error,
         "-n size     Defines the size of the value and state stack (8192)");
      Put_Line (Standard_Error, "-r          Generate error recovery");
      Put_Line
        (Standard_Error,
         "-s          Specifies the printing of statistics about the parser");
      Put_Line
        (Standard_Error,
         "-v          Produce readable report of states generated by the parser");
      Put_Line
        (Standard_Error,
         "-e ext      Defines the extension to be used for the generated file");
      Put_Line
        (Standard_Error,
         "-C          Disable generation of yyclearin procedure");
      Put_Line
        (Standard_Error,
         "-E          Disable generation of yyerrok procedure");
      Put_Line
        (Standard_Error,
         "-S skeleton Specifies the skeleton to use");
      New_Line (Standard_Error);
   end Put_Help_Message;

   -- Get the program arguments and setup the options.
   procedure Get_Arguments is
      Extension : String_Type := Create (".ada");
      Directory : String_Type;
   begin
      loop
         case Gnat.Command_Line.Getopt ("c d C E D: k l P s v r e: n: S:") is
            when Ascii.Nul =>
               exit;

            when 'c' =>
               Interface_To_C_Option := True;

            when 'd' =>
               Debug_Option := True;

            when 'D' =>
               Directory := Create (Gnat.Command_Line.Parameter);

            when 'k' =>
               Keep_Token_Case_Option := True;

            when 'l' =>
               Loud_Option := True;

            when 's' =>
               Summary_Option := True;

            when 'v' =>
               Verbose_Option := True;

            when 'P' =>
               Private_Option := True;

            when 'r' =>
               Error_Recovery_Extension_Option := True;

            when 'e' =>
               Extension := Create (Gnat.Command_Line.Parameter);

            when 'E' =>
               Disable_Yyerrok := True;

            when 'C' =>
               Disable_Yyclearin := True;

            when 'n' =>
               begin
                  Default_Stack_Size :=
                    Natural'Value (Gnat.Command_Line.Parameter);

               exception
                  when Constraint_Error =>
                     Put_Help_Message;
                     Put_Line
                       (Standard_Error,
                        "Invalid size: " & Gnat.Command_Line.Parameter);
                     raise Illegal_Option;
               end;

            when 'S' =>
               begin
                  Output_file.Open_Skeleton (Gnat.Command_Line.Parameter);

               exception
                  when others =>
                     Put_Help_Message;
                     Put_Line
                       (Standard_Error,
                        "Invalid skeleton: " & Gnat.Command_Line.Parameter);
                     raise Illegal_Option;
               end;

            when others =>
               Put_Help_Message;
               raise Illegal_Option;

         end case;
      end loop;

      declare
         Name : constant String := Gnat.Command_Line.Get_Argument;
      begin
         if Name = "" then
            Put_Help_Message;
            raise Illegal_Option;
         end if;
         Ayacc_File_Names.Set_File_Names
           (Name, Value (Extension), Value (Directory));
      end;

   exception
      when E : Gnat.Command_Line.Invalid_Switch =>
         Put_Help_Message;
         Put_Line
           (Standard_Error,
            "Invalid option: " & Ada.Exceptions.Exception_Message (E));
         raise Illegal_Option;

   end Get_Arguments;

   function Verbose return Boolean is
   begin
      return Verbose_Option;
   end Verbose;

   function Debug return Boolean is
   begin
      return Debug_Option;
   end Debug;

   function Interface_To_C return Boolean is
   begin
      return Interface_To_C_Option;
   end Interface_To_C;

   function Summary return Boolean is
   begin
      return Summary_Option;
   end Summary;

   function Package_Private return Boolean is
   begin
      return Private_Option;
   end Package_Private;

   function Loud return Boolean is
   begin
      return Loud_Option;
   end Loud;

   -- UMASS CODES :
   function Error_Recovery_Extension return Boolean is
   begin
      return Error_Recovery_Extension_Option;
   end Error_Recovery_Extension;
   -- END OF UMASS CODES.

   -- Returns the stack size that the parser must use.
   function Ayacc_Stack_Size return String is
   begin
      return Natural'Image (Default_Stack_Size);
   end Ayacc_Stack_Size;

   --  Skip generation of yyerrok
   function Skip_Yyerrok return Boolean is
   begin
      return Disable_Yyerrok;
   end Skip_Yyerrok;

   --  Skip generation of yyclearin
   function Skip_Yyclearin return Boolean is
   begin
      return Disable_Yyclearin;
   end Skip_Yyclearin;

   --  Keep the token case
   function Keep_Token_Case return Boolean is
   begin
      return Keep_Token_Case_Option;
   end Keep_Token_Case;

end Options;
