------------------------------------------------------------------------------
--                                                                          --
--                           ASIStint COMPONENTS                            --
--                                                                          --
--                       A S I S T I N T . T A B L E                        --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--            Copyright (c) 1997, Free Software Foundation, Inc.            --
--                                                                          --
-- ASIStint is free software; you can redistribute  it  and/or  modify  it  --
-- under terms of the GNU General Public License  as published by the  Free --
-- Software Foundation;  either version 2,  or  (at your option)  any later --
-- version.  ASIStint  is distributed  in the hope  that it will be useful, --
-- but  WITHOUT  ANY  WARRANTY;  without even the implied warranty of  MER- --
-- CHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General --
-- Public License for more details.  You should have received a copy of the --
-- GNU General Public License  distributed with ASIStint; see file COPYING. --
-- If not, write to the  Free  Software  Foundation,  59 Temple Place Suite --
-- 330, Boston, MA 02111-1307, USA.                                         --
--                                                                          --
-- ASIStint  was  originally  developed  by  the  ASIS-for-GNAT team at the --
-- Software Engineering  Laboratory  of  the  Swiss  Federal  Institute  of --
-- Technology (LGL-EPFL) in Lausanne, Switzerland, in cooperation with  the --
-- Scientific  Research  Computer  Center  of Moscow State University (SRCC --
-- MSU), Russia.                                                            --
--                                                                          --
-- This work was supported by a  grant  from  the  Swiss  National  Science --
-- Foundation, no 7SUPJ048247, funding a project entitled  "Development  of --
-- ASIS for GNAT with industry quality".                                    --
------------------------------------------------------------------------------

with ASIStint.Common; use ASIStint.Common;

with 
ASIStint.String_Handling;

--DBP with ASIStint.Text_IO;
--DBP      use ASIStint.Text_IO;

with Ada.Strings;
     use Ada.Strings;
with Ada.Strings.Wide_Fixed;
     use Ada.Strings.Wide_Fixed;

package body ASIStint.Table is

------------------------------------------------------------------------------
-- This package provides handling of ASIStint language variable tables
------------------------------------------------------------------------------


  function  Get_Var_Idx (T: Var_Table; N: Wide_String) return Natural is
  -- Scans for the variable index in table T. Returns 0 if fails.

    Name: Var_Name;

  begin
    Move(N, Name, Right);
    ASIStint.String_Handling.To_Upper(Name);
--DBP    ATIPut_Line ("Searching var. '" & Name & "'");
    for i in 1 .. T.Free-1 loop
      if T.Table.All(i).Name = Name then
        return i;
      end if;
    end loop;
    return 0;
  end Get_Var_Idx;


  function  Get_Var    (T: Var_Table; N: Wide_String) return Var_Info is
  -- Scans for the variable in table T. Returns Var_Unknown if fails.

    Idx: Integer:= Get_Var_Idx (T, N);

  begin
    if Idx = 0
      then
        return Var_Unknown;
      else
        return T.Table(Idx);
    end if;
  end Get_Var;


  function Get_Var_Value ( VI : Var_Info) return Query_Result is
    QR: Query_Result(VI.Vtype);
  begin
    case VI.VType is

      when Par_Absent    => null;
      when Par_String    => QR.S := String_Ptr(VI.SValue);
      when Par_Boolean      => QR.B := Boolean'Val(VI.IValue);
      when Par_CUnit     => QR.C := ATICUnit(VI.IValue);
      when Par_CUnitList => QR.CL:= ATICUnitList(VI.IValue);
      when Par_Element   => QR.E := ATIElem(VI.IValue);
      when Par_ElemList  => QR.EL:= ATIElemList(VI.IValue);
      when Par_Context | Par_Integer
                         => QR.I := VI.IValue;
      when Par_Span      => QR.Sp:= ATISpan(VI.IValue);

      when others => Error(ERR_BADPARAM);
    end case;
    return QR;
  exception
    when others =>
      Error(ERR_INTERNAL,"Get_Var_Value");
  end Get_Var_Value;


  function Store_Var_Value ( QR: Query_Result ) return Var_Info is
    VI : Var_Info;
  begin
    VI.VType := QR.RType;
    case QR.RType is

      when Par_String    => VI.SValue := String_Ptr(QR.S);
      when Par_Boolean   => VI.IValue := Boolean'Pos(QR.B);
      when Par_CUnit     => ATICUnit(0) := QR.C;
                            VI.IValue := 0;
      when Par_CUnitList => ATICUnitList(0) := QR.CL;
                            VI.IValue := 0;
      when Par_Element   => ATIElem(0) := QR.E;
                            VI.IValue := 0;
      when Par_ElemList  => ATIElemList(0) := QR.EL;
                            VI.IValue := 0;
      when Par_Context | Par_Integer
                         => VI.IValue := QR.I;
      when Par_Span      => ATISpan(0) := QR.Sp;
                            VI.IValue := 0;

      when others => Error(ERR_BADPARAM);
    end case;
    return VI;
  exception
    when others =>
      Error(ERR_INTERNAL,"Store_Var_Value");
  end Store_Var_Value;


  procedure Modify_Var (T: in out Var_Table; V: Var_Info) is
  -- Adds/changes variable
    Idx: Integer:= Get_Var_Idx (T, V.Name);
    VT: V_TablePtr;
    VName : Var_Name := V.Name;
  begin
    
ASIStint.String_Handling.To_Upper(VName);
    if Idx = 0
      then
        if T.Free>T.Max then
          -- Increase length of var. table
          T.Max := T.Max + MAX_VARIABLES;
          VT := new V_Table(1..T.Max);
          for i in 1..T.Free-1 loop
            VT(i) := T.Table(i);
          end loop;
          T.Table := VT;
        end if;
        T.Table(T.Free) := V;
        T.Table(T.Free).Name := VName;
        T.Free := T.Free + 1;
      else
        T.Table(Idx) := V;
        T.Table(Idx).Name := VName;
    end if;

--DBP    ATIPut_Line
--DBP      ("Added var. '" & V.Name & "', Free now is "
--DBP            & Natural'Wide_Image(T.Free), 0);
  end Modify_Var;


end ASIStint.Table;