-----------------------------------------------------------------------
--  views.nodes.jsf -- JSF Core Tag Library
--  Copyright (C) 2010, 2011, 2012, 2013, 2014 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with ASF.Views.Nodes;
with ASF.Contexts.Facelets;
with ASF.Validators;

--  The ASF.Views.Nodes.Jsf package implements various JSF Core Tag
--  components which alter the component tree but don't need to create
--  new UI components in the usual way.  The following components are supported:
--
--  <f:attribute name='...' value='...'/>
--  <f:converter converterId='...'/>
--  <f:validateXXX .../>
--  <f:facet name='...'>...</f:facet>
--
--  The f:attribute, f:converter and f:validateXXX tags don't create any
--  component.  The f:facet creates components that are inserted as a facet component
--  in the component tree.
package ASF.Views.Nodes.Jsf is

   --  ------------------------------
   --  Converter Tag
   --  ------------------------------
   --  The Converter_Tag_Node is created in the facelet tree when
   --  the <f:converter> element is found.  When building the component tree,
   --  we have to find the Converter object and attach it to the
   --  parent component.  The parent component must implement the Value_Holder
   --  interface.
   type Converter_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Converter_Tag_Node_Access is access all Converter_Tag_Node'Class;

   --  Create the Converter Tag
   function Create_Converter_Tag_Node (Binding    : in Binding_Access;
                                       Line       : in Views.Line_Info;
                                       Parent     : in Views.Nodes.Tag_Node_Access;
                                       Attributes : in Views.Nodes.Tag_Attribute_Array_Access)
                                       return Views.Nodes.Tag_Node_Access;

   --  Build the component tree from the tag node and attach it as
   --  the last child of the given parent.  Calls recursively the
   --  method to create children.  Get the specified converter and
   --  add it to the parent component.  This operation does not create any
   --  new UIComponent.
   overriding
   procedure Build_Components (Node    : access Converter_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

   --  ------------------------------
   --  Convert Date Time Tag
   --  ------------------------------
   --  The Convert_Date_Time_Tag_Node is created in the facelet tree when
   --  the <f:converterDateTime> element is found.  When building the component tree,
   --  we have to find the Converter object and attach it to the
   --  parent component.  The parent component must implement the Value_Holder
   --  interface.
   type Convert_Date_Time_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Convert_Date_Time_Tag_Node_Access is access all Convert_Date_Time_Tag_Node'Class;

   --  Create the Converter Tag
   function Create_Convert_Date_Time_Tag_Node (Binding    : in Binding_Access;
                                               Line       : in Views.Line_Info;
                                               Parent     : in Views.Nodes.Tag_Node_Access;
                                               Attributes : in Nodes.Tag_Attribute_Array_Access)
                                               return Views.Nodes.Tag_Node_Access;

   --  Build the component tree from the tag node and attach it as
   --  the last child of the given parent.  Calls recursively the
   --  method to create children.  Get the specified converter and
   --  add it to the parent component.  This operation does not create any
   --  new UIComponent.
   overriding
   procedure Build_Components (Node    : access Convert_Date_Time_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

   --  ------------------------------
   --  Validator Tag
   --  ------------------------------
   --  The Validator_Tag_Node is created in the facelet tree when
   --  the <f:validateXXX> element is found.  When building the component tree,
   --  we have to find the Validator object and attach it to the
   --  parent component.  The parent component must implement the Editable_Value_Holder
   --  interface.
   type Validator_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Validator_Tag_Node_Access is access all Validator_Tag_Node'Class;

   --  Create the Validator Tag
   function Create_Validator_Tag_Node (Binding    : in Binding_Access;
                                       Line       : in Views.Line_Info;
                                       Parent     : in Views.Nodes.Tag_Node_Access;
                                       Attributes : in Views.Nodes.Tag_Attribute_Array_Access)
                                       return Views.Nodes.Tag_Node_Access;

   --  Get the validator instance that corresponds to the validator tag.
   --  Returns in Validator the instance if it exists and indicate
   --  in Shared whether it must be freed or not when the component is deleted.
   procedure Get_Validator (Node      : in Validator_Tag_Node;
                            Context   : in out Contexts.Facelets.Facelet_Context'Class;
                            Validator : out Validators.Validator_Access;
                            Shared    : out Boolean);

   --  Get the specified validator and add it to the parent component.
   --  This operation does not create any new UIComponent.
   overriding
   procedure Build_Components (Node    : access Validator_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

   --  ------------------------------
   --  Range Validator Tag
   --  ------------------------------
   --  The Range_Validator_Tag_Node is created in the facelet tree when
   --  the <f:validateLongRange> element is found.
   --  The parent component must implement the Editable_Value_Holder
   --  interface.
   type Range_Validator_Tag_Node is new Validator_Tag_Node with private;
   type Range_Validator_Tag_Node_Access is access all Range_Validator_Tag_Node'Class;

   --  Create the Range_Validator Tag
   function Create_Range_Validator_Tag_Node (Binding    : in Binding_Access;
                                             Line       : in Views.Line_Info;
                                             Parent     : in Views.Nodes.Tag_Node_Access;
                                             Attributes : in Nodes.Tag_Attribute_Array_Access)
                                             return Views.Nodes.Tag_Node_Access;

   --  Get the validator instance that corresponds to the range validator.
   --  Returns in Validator the validator instance if it exists and indicate
   --  in Shared whether it must be freed or not when the component is deleted.
   overriding
   procedure Get_Validator (Node      : in Range_Validator_Tag_Node;
                            Context   : in out Contexts.Facelets.Facelet_Context'Class;
                            Validator : out Validators.Validator_Access;
                            Shared    : out Boolean);

   --  ------------------------------
   --  Length Validator Tag
   --  ------------------------------
   --  The Length_Validator_Tag_Node is created in the facelet tree when
   --  the <f:validateLength> element is found.  When building the component tree,
   --  we have to find the Validator object and attach it to the
   --  parent component.  The parent component must implement the Editable_Value_Holder
   --  interface.
   type Length_Validator_Tag_Node is new Validator_Tag_Node with private;
   type Length_Validator_Tag_Node_Access is access all Length_Validator_Tag_Node'Class;

   --  Create the Length_Validator Tag.  Verifies that the XML node defines
   --  the minimum or the maximum or both attributes.
   function Create_Length_Validator_Tag_Node (Binding    : in Binding_Access;
                                              Line       : in Views.Line_Info;
                                              Parent     : in Views.Nodes.Tag_Node_Access;
                                              Attributes : in Nodes.Tag_Attribute_Array_Access)
                                              return Views.Nodes.Tag_Node_Access;

   --  Get the validator instance that corresponds to the validator tag.
   --  Returns in Validator the instance if it exists and indicate
   --  in Shared whether it must be freed or not when the component is deleted.
   overriding
   procedure Get_Validator (Node      : in Length_Validator_Tag_Node;
                            Context   : in out Contexts.Facelets.Facelet_Context'Class;
                            Validator : out Validators.Validator_Access;
                            Shared    : out Boolean);

   --  ------------------------------
   --  Attribute Tag
   --  ------------------------------
   --  The Attribute_Tag_Node is created in the facelet tree when
   --  the <f:attribute> element is found.  When building the component tree,
   --  an attribute is added to the parent component.
   type Attribute_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Attribute_Tag_Node_Access is access all Attribute_Tag_Node'Class;

   --  Create the Attribute Tag
   function Create_Attribute_Tag_Node (Binding    : in Binding_Access;
                                       Line       : in Views.Line_Info;
                                       Parent     : in Views.Nodes.Tag_Node_Access;
                                       Attributes : in Views.Nodes.Tag_Attribute_Array_Access)
                                       return Views.Nodes.Tag_Node_Access;

   --  Build the component tree from the tag node and attach it as
   --  the last child of the given parent.  Calls recursively the
   --  method to create children.
   --  Adds the attribute to the component node.
   --  This operation does not create any new UIComponent.
   overriding
   procedure Build_Components (Node    : access Attribute_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

   --  ------------------------------
   --  Facet Tag
   --  ------------------------------
   --  The Facet_Tag_Node is created in the facelet tree when
   --  the <f:facet> element is found.  After building the component tree,
   --  we have to add the component as a facet element of the parent component.
   --
   type Facet_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Facet_Tag_Node_Access is access all Facet_Tag_Node'Class;

   --  Create the Facet Tag
   function Create_Facet_Tag_Node (Binding    : in Binding_Access;
                                   Line       : in Views.Line_Info;
                                   Parent     : in Views.Nodes.Tag_Node_Access;
                                   Attributes : in Views.Nodes.Tag_Attribute_Array_Access)
                                   return Views.Nodes.Tag_Node_Access;

   --  Build the component tree from the tag node and attach it as
   --  the facet component of the given parent.  Calls recursively the
   --  method to create children.
   overriding
   procedure Build_Components (Node    : access Facet_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

   --  ------------------------------
   --  Metadata Tag
   --  ------------------------------
   --  The Metadata_Tag_Node is created in the facelet tree when
   --  the <f:metadata> element is found.  This special component is inserted as a special
   --  facet component on the UIView parent component.
   type Metadata_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Metadata_Tag_Node_Access is access all Metadata_Tag_Node'Class;

   --  Create the Metadata Tag
   function Create_Metadata_Tag_Node (Binding    : in Binding_Access;
                                      Line       : in Views.Line_Info;
                                      Parent     : in Views.Nodes.Tag_Node_Access;
                                      Attributes : in Views.Nodes.Tag_Attribute_Array_Access)
                                      return Views.Nodes.Tag_Node_Access;

   --  Build the component tree from the tag node and attach it as a metadata information
   --  facet for the UIView parent component.
   overriding
   procedure Build_Components (Node    : access Metadata_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

   --  The elaboration check is disabled on the Create_XXX operation because they
   --  are referenced by the Components.Core.Factory to define a static UI binding.
   --  This reference triggers the implicit Elaborate_All for the Nodes.JSF package.
   --  At the end, we obtain a circular dependency that cannot be resolved.
   --  It is safe to suppress the elaboration check because these Create_XXX operation
   --  are not invoked before the application is initialized and a view is rendered.
   pragma Suppress (Elaboration_Check, On => Create_Attribute_Tag_Node);
   pragma Suppress (Elaboration_Check, On => Create_Converter_Tag_Node);
   pragma Suppress (Elaboration_Check, On => Create_Convert_Date_Time_Tag_Node);
   pragma Suppress (Elaboration_Check, On => Create_Facet_Tag_Node);
   pragma Suppress (Elaboration_Check, On => Create_Metadata_Tag_Node);
   pragma Suppress (Elaboration_Check, On => Create_Length_Validator_Tag_Node);
   pragma Suppress (Elaboration_Check, On => Create_Range_Validator_Tag_Node);
   pragma Suppress (Elaboration_Check, On => Create_Validator_Tag_Node);

private

   type Converter_Tag_Node is new Views.Nodes.Tag_Node with record
      Converter : EL.Objects.Object;
   end record;

   type Convert_Date_Time_Tag_Node is new Views.Nodes.Tag_Node with record
      Date_Style : Tag_Attribute_Access;
      Time_Style : Tag_Attribute_Access;
      Locale     : Tag_Attribute_Access;
      Pattern    : Tag_Attribute_Access;
      Format     : Tag_Attribute_Access;
   end record;

   type Validator_Tag_Node is new Views.Nodes.Tag_Node with record
      Validator : EL.Objects.Object;
   end record;

   type Length_Validator_Tag_Node is new Validator_Tag_Node with record
      Minimum : Tag_Attribute_Access;
      Maximum : Tag_Attribute_Access;
   end record;

   type Range_Validator_Tag_Node is new Validator_Tag_Node with record
      Minimum : Tag_Attribute_Access;
      Maximum : Tag_Attribute_Access;
   end record;

   type Attribute_Tag_Node is new Views.Nodes.Tag_Node with record
      Attr       : aliased Tag_Attribute;
      Attr_Name  : Tag_Attribute_Access;
      Value      : Tag_Attribute_Access;
   end record;

   type Facet_Tag_Node is new Views.Nodes.Tag_Node with record
      Facet_Name : Tag_Attribute_Access;
   end record;

   type Metadata_Tag_Node is new Views.Nodes.Tag_Node with null record;

end ASF.Views.Nodes.Jsf;

-----------------------------------------------------------------------
--  views.nodes.jsf -- JSF Core Tag Library
--  Copyright (C) 2010, 2011, 2012, 2013, 2014, 2018 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with ASF.Contexts.Facelets;
with ASF.Validators;

--  The ASF.Views.Nodes.Jsf package implements various JSF Core Tag
--  components which alter the component tree but don't need to create
--  new UI components in the usual way.  The following components are supported:
--
--  <f:attribute name='...' value='...'/>
--  <f:converter converterId='...'/>
--  <f:validateXXX .../>
--  <f:facet name='...'>...</f:facet>
--
--  The f:attribute, f:converter and f:validateXXX tags don't create any
--  component.  The f:facet creates components that are inserted as a facet component
--  in the component tree.
package ASF.Views.Nodes.Jsf is

   --  ------------------------------
   --  Converter Tag
   --  ------------------------------
   --  The Converter_Tag_Node is created in the facelet tree when
   --  the <f:converter> element is found.  When building the component tree,
   --  we have to find the Converter object and attach it to the
   --  parent component.  The parent component must implement the Value_Holder
   --  interface.
   type Converter_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Converter_Tag_Node_Access is access all Converter_Tag_Node'Class;

   --  Create the Converter Tag
   function Create_Converter_Tag_Node (Binding    : in Binding_Type;
                                       Line       : in Views.Line_Info;
                                       Parent     : in Views.Nodes.Tag_Node_Access;
                                       Attributes : in Views.Nodes.Tag_Attribute_Array_Access)
                                       return Views.Nodes.Tag_Node_Access;

   --  Build the component tree from the tag node and attach it as
   --  the last child of the given parent.  Calls recursively the
   --  method to create children.  Get the specified converter and
   --  add it to the parent component.  This operation does not create any
   --  new UIComponent.
   overriding
   procedure Build_Components (Node    : access Converter_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

   --  ------------------------------
   --  Convert Date Time Tag
   --  ------------------------------
   --  The Convert_Date_Time_Tag_Node is created in the facelet tree when
   --  the <f:converterDateTime> element is found.  When building the component tree,
   --  we have to find the Converter object and attach it to the
   --  parent component.  The parent component must implement the Value_Holder
   --  interface.
   type Convert_Date_Time_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Convert_Date_Time_Tag_Node_Access is access all Convert_Date_Time_Tag_Node'Class;

   --  Create the Converter Tag
   function Create_Convert_Date_Time_Tag_Node (Binding    : in Binding_Type;
                                               Line       : in Views.Line_Info;
                                               Parent     : in Views.Nodes.Tag_Node_Access;
                                               Attributes : in Nodes.Tag_Attribute_Array_Access)
                                               return Views.Nodes.Tag_Node_Access;

   --  Build the component tree from the tag node and attach it as
   --  the last child of the given parent.  Calls recursively the
   --  method to create children.  Get the specified converter and
   --  add it to the parent component.  This operation does not create any
   --  new UIComponent.
   overriding
   procedure Build_Components (Node    : access Convert_Date_Time_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

   --  ------------------------------
   --  Validator Tag
   --  ------------------------------
   --  The Validator_Tag_Node is created in the facelet tree when
   --  the <f:validateXXX> element is found.  When building the component tree,
   --  we have to find the Validator object and attach it to the
   --  parent component.  The parent component must implement the Editable_Value_Holder
   --  interface.
   type Validator_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Validator_Tag_Node_Access is access all Validator_Tag_Node'Class;

   --  Create the Validator Tag
   function Create_Validator_Tag_Node (Binding    : in Binding_Type;
                                       Line       : in Views.Line_Info;
                                       Parent     : in Views.Nodes.Tag_Node_Access;
                                       Attributes : in Views.Nodes.Tag_Attribute_Array_Access)
                                       return Views.Nodes.Tag_Node_Access;

   --  Get the validator instance that corresponds to the validator tag.
   --  Returns in Validator the instance if it exists and indicate
   --  in Shared whether it must be freed or not when the component is deleted.
   procedure Get_Validator (Node      : in Validator_Tag_Node;
                            Context   : in out Contexts.Facelets.Facelet_Context'Class;
                            Validator : out Validators.Validator_Access;
                            Shared    : out Boolean);

   --  Get the specified validator and add it to the parent component.
   --  This operation does not create any new UIComponent.
   overriding
   procedure Build_Components (Node    : access Validator_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

   --  ------------------------------
   --  Range Validator Tag
   --  ------------------------------
   --  The Range_Validator_Tag_Node is created in the facelet tree when
   --  the <f:validateLongRange> element is found.
   --  The parent component must implement the Editable_Value_Holder
   --  interface.
   type Range_Validator_Tag_Node is new Validator_Tag_Node with private;
   type Range_Validator_Tag_Node_Access is access all Range_Validator_Tag_Node'Class;

   --  Create the Range_Validator Tag
   function Create_Range_Validator_Tag_Node (Binding    : in Binding_Type;
                                             Line       : in Views.Line_Info;
                                             Parent     : in Views.Nodes.Tag_Node_Access;
                                             Attributes : in Nodes.Tag_Attribute_Array_Access)
                                             return Views.Nodes.Tag_Node_Access;

   --  Get the validator instance that corresponds to the range validator.
   --  Returns in Validator the validator instance if it exists and indicate
   --  in Shared whether it must be freed or not when the component is deleted.
   overriding
   procedure Get_Validator (Node      : in Range_Validator_Tag_Node;
                            Context   : in out Contexts.Facelets.Facelet_Context'Class;
                            Validator : out Validators.Validator_Access;
                            Shared    : out Boolean);

   --  ------------------------------
   --  Length Validator Tag
   --  ------------------------------
   --  The Length_Validator_Tag_Node is created in the facelet tree when
   --  the <f:validateLength> element is found.  When building the component tree,
   --  we have to find the Validator object and attach it to the
   --  parent component.  The parent component must implement the Editable_Value_Holder
   --  interface.
   type Length_Validator_Tag_Node is new Validator_Tag_Node with private;
   type Length_Validator_Tag_Node_Access is access all Length_Validator_Tag_Node'Class;

   --  Create the Length_Validator Tag.  Verifies that the XML node defines
   --  the minimum or the maximum or both attributes.
   function Create_Length_Validator_Tag_Node (Binding    : in Binding_Type;
                                              Line       : in Views.Line_Info;
                                              Parent     : in Views.Nodes.Tag_Node_Access;
                                              Attributes : in Nodes.Tag_Attribute_Array_Access)
                                              return Views.Nodes.Tag_Node_Access;

   --  Get the validator instance that corresponds to the validator tag.
   --  Returns in Validator the instance if it exists and indicate
   --  in Shared whether it must be freed or not when the component is deleted.
   overriding
   procedure Get_Validator (Node      : in Length_Validator_Tag_Node;
                            Context   : in out Contexts.Facelets.Facelet_Context'Class;
                            Validator : out Validators.Validator_Access;
                            Shared    : out Boolean);

   --  ------------------------------
   --  Attribute Tag
   --  ------------------------------
   --  The Attribute_Tag_Node is created in the facelet tree when
   --  the <f:attribute> element is found.  When building the component tree,
   --  an attribute is added to the parent component.
   type Attribute_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Attribute_Tag_Node_Access is access all Attribute_Tag_Node'Class;

   --  Create the Attribute Tag
   function Create_Attribute_Tag_Node (Binding    : in Binding_Type;
                                       Line       : in Views.Line_Info;
                                       Parent     : in Views.Nodes.Tag_Node_Access;
                                       Attributes : in Views.Nodes.Tag_Attribute_Array_Access)
                                       return Views.Nodes.Tag_Node_Access;

   --  Build the component tree from the tag node and attach it as
   --  the last child of the given parent.  Calls recursively the
   --  method to create children.
   --  Adds the attribute to the component node.
   --  This operation does not create any new UIComponent.
   overriding
   procedure Build_Components (Node    : access Attribute_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

   --  ------------------------------
   --  Facet Tag
   --  ------------------------------
   --  The Facet_Tag_Node is created in the facelet tree when
   --  the <f:facet> element is found.  After building the component tree,
   --  we have to add the component as a facet element of the parent component.
   --
   type Facet_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Facet_Tag_Node_Access is access all Facet_Tag_Node'Class;

   --  Create the Facet Tag
   function Create_Facet_Tag_Node (Binding    : in Binding_Type;
                                   Line       : in Views.Line_Info;
                                   Parent     : in Views.Nodes.Tag_Node_Access;
                                   Attributes : in Views.Nodes.Tag_Attribute_Array_Access)
                                   return Views.Nodes.Tag_Node_Access;

   --  Build the component tree from the tag node and attach it as
   --  the facet component of the given parent.  Calls recursively the
   --  method to create children.
   overriding
   procedure Build_Components (Node    : access Facet_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

   --  ------------------------------
   --  Metadata Tag
   --  ------------------------------
   --  The Metadata_Tag_Node is created in the facelet tree when
   --  the <f:metadata> element is found.  This special component is inserted as a special
   --  facet component on the UIView parent component.
   type Metadata_Tag_Node is new Views.Nodes.Tag_Node with private;
   type Metadata_Tag_Node_Access is access all Metadata_Tag_Node'Class;

   --  Create the Metadata Tag
   function Create_Metadata_Tag_Node (Binding    : in Binding_Type;
                                      Line       : in Views.Line_Info;
                                      Parent     : in Views.Nodes.Tag_Node_Access;
                                      Attributes : in Views.Nodes.Tag_Attribute_Array_Access)
                                      return Views.Nodes.Tag_Node_Access;

   --  Build the component tree from the tag node and attach it as a metadata information
   --  facet for the UIView parent component.
   overriding
   procedure Build_Components (Node    : access Metadata_Tag_Node;
                               Parent  : in UIComponent_Access;
                               Context : in out Contexts.Facelets.Facelet_Context'Class);

private

   type Converter_Tag_Node is new Views.Nodes.Tag_Node with record
      Converter : EL.Objects.Object;
   end record;

   type Convert_Date_Time_Tag_Node is new Views.Nodes.Tag_Node with record
      Date_Style : Tag_Attribute_Access;
      Time_Style : Tag_Attribute_Access;
      Locale     : Tag_Attribute_Access;
      Pattern    : Tag_Attribute_Access;
      Format     : Tag_Attribute_Access;
   end record;

   type Validator_Tag_Node is new Views.Nodes.Tag_Node with record
      Validator : EL.Objects.Object;
   end record;

   type Length_Validator_Tag_Node is new Validator_Tag_Node with record
      Minimum : Tag_Attribute_Access;
      Maximum : Tag_Attribute_Access;
   end record;

   type Range_Validator_Tag_Node is new Validator_Tag_Node with record
      Minimum : Tag_Attribute_Access;
      Maximum : Tag_Attribute_Access;
   end record;

   type Attribute_Tag_Node is new Views.Nodes.Tag_Node with record
      Attr       : aliased Tag_Attribute;
      Attr_Name  : Tag_Attribute_Access;
      Value      : Tag_Attribute_Access;
   end record;

   type Facet_Tag_Node is new Views.Nodes.Tag_Node with record
      Facet_Name : Tag_Attribute_Access;
   end record;

   type Metadata_Tag_Node is new Views.Nodes.Tag_Node with null record;

end ASF.Views.Nodes.Jsf;

Use Binding_Type instead of Binding_Access


-----------------------------------------------------------------------
--  mat-formats - Format various types for the console or GUI interface
--  Copyright (C) 2015 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with MAT.Types;
package MAT.Formats is

   --  Format the address into a string.
   function Addr (Value : in MAT.Types.Target_Addr) return String;

end MAT.Formats;

-----------------------------------------------------------------------
--  mat-formats - Format various types for the console or GUI interface
--  Copyright (C) 2015 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

with MAT.Types;
package MAT.Formats is

   --  Format the address into a string.
   function Addr (Value : in MAT.Types.Target_Addr) return String;

   --  Format the size into a string.
   function Size (Value : in MAT.Types.Target_Size) return String;

end MAT.Formats;

Declare the Size function

Declare the Size function


-----------------------------------------------------------------------
--  awa-setup -- Setup and installation
--  Copyright (C) 2016 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Text_IO;
with Ada.IO_Exceptions;
with Ada.Directories;
with Util.Files;
with Util.Log.Loggers;
with Util.Strings;
with ASF.Events.Faces.Actions;
with ASF.Applications.Main.Configs;
with AWA.Applications;
package body AWA.Setup.Applications is

   Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("AWA.Setup.Applications");

   package Save_Binding is
     new ASF.Events.Faces.Actions.Action_Method.Bind (Bean   => Application,
                                                      Method => Save,
                                                      Name   => "save");

   package Finish_Binding is
     new ASF.Events.Faces.Actions.Action_Method.Bind (Bean   => Application,
                                                      Method => Finish,
                                                      Name   => "finish");
   package Configure_Binding is
     new ASF.Events.Faces.Actions.Action_Method.Bind (Bean   => Application,
                                                      Method => Configure_Database,
                                                      Name   => "configure_database");

   Binding_Array : aliased constant Util.Beans.Methods.Method_Binding_Array
     := (Save_Binding.Proxy'Access,
         Finish_Binding.Proxy'Access,
         Configure_Binding.Proxy'Access);

   --  ------------------------------
   --  Get the value identified by the name.
   --  ------------------------------
   function Get_Value (From : in Application;
                       Name : in String) return Util.Beans.Objects.Object is
   begin
      if Name = "database_name" then
         return Util.Beans.Objects.To_Object (From.Database.Get_Database);
      elsif Name = "database_server" then
         return Util.Beans.Objects.To_Object (From.Database.Get_Server);
      elsif Name = "database_port" then
         return Util.Beans.Objects.To_Object (From.Database.Get_Port);
      elsif Name = "database_user" then
         return Util.Beans.Objects.To_Object (From.Database.Get_Property ("user"));
      elsif Name = "database_password" then
         return Util.Beans.Objects.To_Object (From.Database.Get_Property ("password"));
      end if;
      if From.Changed.Exists (Name) then
         return Util.Beans.Objects.To_Object (String '(From.Changed.Get (Name)));
      end if;
      declare
         Param : constant String := From.Config.Get (Name);
      begin
         return Util.Beans.Objects.To_Object (Param);
      end;

   exception
      when others =>
         return Util.Beans.Objects.Null_Object;
   end Get_Value;

   --  ------------------------------
   --  Set the value identified by the name.
   --  ------------------------------
   procedure Set_Value (From  : in out Application;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object) is
   begin
      if Name = "database_name" then
         From.Database.Set_Database (Util.Beans.Objects.To_String (Value));
      elsif Name = "database_server" then
         From.Database.Set_Server (Util.Beans.Objects.To_String (Value));
      elsif Name = "database_port" then
         From.Database.Set_Port (Util.Beans.Objects.To_Integer (Value));
      elsif Name = "database_user" then
         From.Database.Set_Property ("user", Util.Beans.Objects.To_String (Value));
      elsif Name = "database_password" then
         From.Database.Set_Property ("password", Util.Beans.Objects.To_String (Value));
      elsif Name = "callback_url" then
         From.Changed.Set (Name, Util.Beans.Objects.To_String (Value));
         From.Changed.Set ("facebook.callback_url",
                           Util.Beans.Objects.To_String (Value) & "#{contextPath}/auth/verify");
         From.Changed.Set ("google-plus.callback_url",
                           Util.Beans.Objects.To_String (Value) & "#{contextPath}/auth/verify");
      else
         From.Changed.Set (Name, Util.Beans.Objects.To_String (Value));
      end if;
   end Set_Value;

   --  ------------------------------
   --  Get the database connection string to be used by the application.
   --  ------------------------------
   function Get_Database_URL (From : in Application) return String is
      use Ada.Strings.Unbounded;

      Result : Ada.Strings.Unbounded.Unbounded_String;
   begin
      Append (Result, "mysql://");
      Append (Result, From.Database.Get_Server);
      if From.Database.Get_Port /= 0 then
         Append (Result, ":");
         Append (Result, Util.Strings.Image (From.Database.Get_Port));
      end if;
      Append (Result, "/");
      Append (Result, From.Database.Get_Database);
      if From.Database.Get_Property ("user") /= "" then
         Append (Result, "?user=");
         Append (Result, From.Database.Get_Property ("user"));
         if From.Database.Get_Property ("password") /= "" then
            Append (Result, "&password=");
            Append (Result, From.Database.Get_Property ("password"));
         end if;
      end if;
      return To_String (Result);
   end Get_Database_URL;

   --  Configure the database.
   procedure Configure_Database (From    : in out Application;
                                 Outcome : in out Ada.Strings.Unbounded.Unbounded_String) is
   begin
      Log.Info ("Configure database");
   end Configure_Database;

   --  ------------------------------
   --  Save the configuration.
   --  ------------------------------
   procedure Save (From    : in out Application;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String) is
      Path     : constant String := Ada.Strings.Unbounded.To_String (From.Path);
      New_File : constant String := Path & ".tmp";
      Output   : Ada.Text_IO.File_Type;

      procedure Read_Property (Line : in String) is
         Pos : constant Natural := Util.Strings.Index (Line, '=');
      begin
         if Pos = 0 or else not From.Changed.Exists (Line (Line'First .. Pos - 1)) then
            Ada.Text_IO.Put_Line (Output, Line);
            return;
         end if;
         Ada.Text_IO.Put (Output, Line (Line'First .. Pos));
         Ada.Text_IO.Put_Line (Output, From.Changed.Get (Line (Line'First .. Pos - 1)));
      end Read_Property;

   begin
      Log.Info ("Saving configuration file {0}", Path);

      From.Changed.Set ("database", From.Get_Database_URL);
      Ada.Text_IO.Create (File => Output, Name => New_File);
      Util.Files.Read_File (Path, Read_Property'Access);
      Ada.Text_IO.Close (Output);
      Ada.Directories.Delete_File (Path);
      Ada.Directories.Rename (Old_Name => New_File,
                              New_Name => Path);
   end Save;

   --  Finish the setup and exit the setup.
   procedure Finish (From    : in out Application;
                     Outcome : in out Ada.Strings.Unbounded.Unbounded_String) is
   begin
      Log.Info ("Finish configuration");
      From.Done := True;
   end Finish;

   --  ------------------------------
   --  This bean provides some methods that can be used in a Method_Expression
   --  ------------------------------
   overriding
   function Get_Method_Bindings (From : in Application)
                                 return Util.Beans.Methods.Method_Binding_Array_Access is
   begin
      return Binding_Array'Access;
   end Get_Method_Bindings;

   --  ------------------------------
   --  Enter in the application setup
   --  ------------------------------
   procedure Setup (App    : in out Application;
                    Config : in String;
                    Server : in out ASF.Server.Container'Class) is
   begin
      Log.Info ("Entering configuration for {0}", Config);
      App.Path := Ada.Strings.Unbounded.To_Unbounded_String (Config);
      begin
         App.Config.Load_Properties (Config);
         Util.Log.Loggers.Initialize (Config);

      exception
         when Ada.IO_Exceptions.Name_Error =>
            Log.Error ("Cannot read application configuration file: {0}", Config);
      end;
      App.Initialize (App.Config, App.Factory);
      App.Set_Global ("contextPath", App.Config.Get ("contextPath"));
      App.Set_Global ("setup",
                      Util.Beans.Objects.To_Object (App'Unchecked_Access,
                        Util.Beans.Objects.STATIC));
      App.Add_Servlet (Name   => "faces",
                       Server => App.Faces'Unchecked_Access);
      App.Add_Servlet (Name   => "files",
                       Server => App.Files'Unchecked_Access);
      App.Add_Mapping (Pattern => "*.html",
                       Name    => "faces");
      App.Add_Mapping (Pattern => "*.css",
                       Name    => "files");
      App.Add_Mapping (Pattern => "*.js",
                       Name    => "files");

      declare
         Paths : constant String := App.Get_Config (AWA.Applications.P_Module_Dir.P);
         Path  : constant String := Util.Files.Find_File_Path ("setup.xml", Paths);
      begin
         ASF.Applications.Main.Configs.Read_Configuration (App, Path);

      exception
         when Ada.IO_Exceptions.Name_Error =>
            Log.Error ("Setup configuration file '{0}' does not exist", Path);
      end;

      declare
         URL : constant String := App.Config.Get ("google-plus.callback_url", "");
         Pos : Natural := Util.Strings.Index (URL, '#');
      begin
         if Pos > 0 then
            App.Changed.Set ("callback_url", URL (URL'First .. Pos - 1));
         end if;
      end;
      App.Database.Set_Connection (App.Config.Get ("database", "mysql://localhost:3306/db"));
      Server.Register_Application (App.Config.Get ("contextPath"), App'Unchecked_Access);
      while not App.Done loop
         delay 5.0;
      end loop;
      Server.Remove_Application (App'Unchecked_Access);
   end Setup;

end AWA.Setup.Applications;

-----------------------------------------------------------------------
--  awa-setup -- Setup and installation
--  Copyright (C) 2016 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Text_IO;
with Ada.IO_Exceptions;
with Ada.Directories;
with Util.Files;
with Util.Log.Loggers;
with Util.Strings;
with ASF.Events.Faces.Actions;
with ASF.Applications.Main.Configs;
with AWA.Applications;
package body AWA.Setup.Applications is

   Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("AWA.Setup.Applications");

   package Save_Binding is
     new ASF.Events.Faces.Actions.Action_Method.Bind (Bean   => Application,
                                                      Method => Save,
                                                      Name   => "save");

   package Finish_Binding is
     new ASF.Events.Faces.Actions.Action_Method.Bind (Bean   => Application,
                                                      Method => Finish,
                                                      Name   => "finish");
   package Configure_Binding is
     new ASF.Events.Faces.Actions.Action_Method.Bind (Bean   => Application,
                                                      Method => Configure_Database,
                                                      Name   => "configure_database");

   Binding_Array : aliased constant Util.Beans.Methods.Method_Binding_Array
     := (Save_Binding.Proxy'Access,
         Finish_Binding.Proxy'Access,
         Configure_Binding.Proxy'Access);

   overriding
   procedure Do_Get (Server   : in Redirect_Servlet;
                     Request  : in out ASF.Requests.Request'Class;
                     Response : in out ASF.Responses.Response'Class) is
      Context_Path : constant String := Request.Get_Context_Path;
   begin
      Response.Send_Redirect (Context_Path & "/setup/install.html");
   end Do_Get;

   --  ------------------------------
   --  Get the value identified by the name.
   --  ------------------------------
   function Get_Value (From : in Application;
                       Name : in String) return Util.Beans.Objects.Object is
   begin
      if Name = "database_name" then
         return Util.Beans.Objects.To_Object (From.Database.Get_Database);
      elsif Name = "database_server" then
         return Util.Beans.Objects.To_Object (From.Database.Get_Server);
      elsif Name = "database_port" then
         return Util.Beans.Objects.To_Object (From.Database.Get_Port);
      elsif Name = "database_user" then
         return Util.Beans.Objects.To_Object (From.Database.Get_Property ("user"));
      elsif Name = "database_password" then
         return Util.Beans.Objects.To_Object (From.Database.Get_Property ("password"));
      elsif Name = "database_driver" then
         return Util.Beans.Objects.To_Object (String '("sqlite"));
      end if;
      if From.Changed.Exists (Name) then
         return Util.Beans.Objects.To_Object (String '(From.Changed.Get (Name)));
      end if;
      declare
         Param : constant String := From.Config.Get (Name);
      begin
         return Util.Beans.Objects.To_Object (Param);
      end;

   exception
      when others =>
         return Util.Beans.Objects.Null_Object;
   end Get_Value;

   --  ------------------------------
   --  Set the value identified by the name.
   --  ------------------------------
   procedure Set_Value (From  : in out Application;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object) is
   begin
      if Name = "database_name" then
         From.Database.Set_Database (Util.Beans.Objects.To_String (Value));
      elsif Name = "database_server" then
         From.Database.Set_Server (Util.Beans.Objects.To_String (Value));
      elsif Name = "database_port" then
         From.Database.Set_Port (Util.Beans.Objects.To_Integer (Value));
      elsif Name = "database_user" then
         From.Database.Set_Property ("user", Util.Beans.Objects.To_String (Value));
      elsif Name = "database_password" then
         From.Database.Set_Property ("password", Util.Beans.Objects.To_String (Value));
      elsif Name = "callback_url" then
         From.Changed.Set (Name, Util.Beans.Objects.To_String (Value));
         From.Changed.Set ("facebook.callback_url",
                           Util.Beans.Objects.To_String (Value) & "#{contextPath}/auth/verify");
         From.Changed.Set ("google-plus.callback_url",
                           Util.Beans.Objects.To_String (Value) & "#{contextPath}/auth/verify");
      else
         From.Changed.Set (Name, Util.Beans.Objects.To_String (Value));
      end if;
   end Set_Value;

   --  ------------------------------
   --  Get the database connection string to be used by the application.
   --  ------------------------------
   function Get_Database_URL (From : in Application) return String is
      use Ada.Strings.Unbounded;

      Result : Ada.Strings.Unbounded.Unbounded_String;
   begin
      Append (Result, "mysql://");
      Append (Result, From.Database.Get_Server);
      if From.Database.Get_Port /= 0 then
         Append (Result, ":");
         Append (Result, Util.Strings.Image (From.Database.Get_Port));
      end if;
      Append (Result, "/");
      Append (Result, From.Database.Get_Database);
      if From.Database.Get_Property ("user") /= "" then
         Append (Result, "?user=");
         Append (Result, From.Database.Get_Property ("user"));
         if From.Database.Get_Property ("password") /= "" then
            Append (Result, "&password=");
            Append (Result, From.Database.Get_Property ("password"));
         end if;
      end if;
      return To_String (Result);
   end Get_Database_URL;

   --  Configure the database.
   procedure Configure_Database (From    : in out Application;
                                 Outcome : in out Ada.Strings.Unbounded.Unbounded_String) is
   begin
      Log.Info ("Configure database");
      --  dynamo create-database db sqlite:///atlas.db
   end Configure_Database;

   --  ------------------------------
   --  Save the configuration.
   --  ------------------------------
   procedure Save (From    : in out Application;
                   Outcome : in out Ada.Strings.Unbounded.Unbounded_String) is
      Path     : constant String := Ada.Strings.Unbounded.To_String (From.Path);
      New_File : constant String := Path & ".tmp";
      Output   : Ada.Text_IO.File_Type;

      procedure Read_Property (Line : in String) is
         Pos : constant Natural := Util.Strings.Index (Line, '=');
      begin
         if Pos = 0 or else not From.Changed.Exists (Line (Line'First .. Pos - 1)) then
            Ada.Text_IO.Put_Line (Output, Line);
            return;
         end if;
         Ada.Text_IO.Put (Output, Line (Line'First .. Pos));
         Ada.Text_IO.Put_Line (Output, From.Changed.Get (Line (Line'First .. Pos - 1)));
      end Read_Property;

   begin
      Log.Info ("Saving configuration file {0}", Path);

      From.Changed.Set ("database", From.Get_Database_URL);
      Ada.Text_IO.Create (File => Output, Name => New_File);
      Util.Files.Read_File (Path, Read_Property'Access);
      Ada.Text_IO.Close (Output);
      Ada.Directories.Delete_File (Path);
      Ada.Directories.Rename (Old_Name => New_File,
                              New_Name => Path);
   end Save;

   --  Finish the setup and exit the setup.
   procedure Finish (From    : in out Application;
                     Outcome : in out Ada.Strings.Unbounded.Unbounded_String) is
   begin
      Log.Info ("Finish configuration");
      From.Done := True;
   end Finish;

   --  ------------------------------
   --  This bean provides some methods that can be used in a Method_Expression
   --  ------------------------------
   overriding
   function Get_Method_Bindings (From : in Application)
                                 return Util.Beans.Methods.Method_Binding_Array_Access is
   begin
      return Binding_Array'Access;
   end Get_Method_Bindings;

   --  ------------------------------
   --  Enter in the application setup
   --  ------------------------------
   procedure Setup (App    : in out Application;
                    Config : in String;
                    Server : in out ASF.Server.Container'Class) is
   begin
      Log.Info ("Entering configuration for {0}", Config);
      App.Path := Ada.Strings.Unbounded.To_Unbounded_String (Config);
      begin
         App.Config.Load_Properties (Config);
         Util.Log.Loggers.Initialize (Config);

      exception
         when Ada.IO_Exceptions.Name_Error =>
            Log.Error ("Cannot read application configuration file: {0}", Config);
      end;
      App.Initialize (App.Config, App.Factory);
      App.Set_Error_Page (ASF.Responses.SC_NOT_FOUND, "/setup/install.html");
      App.Set_Global ("contextPath", App.Config.Get ("contextPath"));
      App.Set_Global ("setup",
                      Util.Beans.Objects.To_Object (App'Unchecked_Access,
                        Util.Beans.Objects.STATIC));
      App.Add_Servlet (Name   => "redirect",
                       Server => App.Redirect'Unchecked_Access);
      App.Add_Servlet (Name   => "faces",
                       Server => App.Faces'Unchecked_Access);
      App.Add_Servlet (Name   => "files",
                       Server => App.Files'Unchecked_Access);
      App.Add_Mapping (Pattern => "*.html",
                       Name    => "redirect");
      App.Add_Mapping (Pattern => "/setup/*.html",
                       Name    => "faces");
      App.Add_Mapping (Pattern => "*.css",
                       Name    => "files");
      App.Add_Mapping (Pattern => "*.js",
                       Name    => "files");

      declare
         Paths : constant String := App.Get_Config (AWA.Applications.P_Module_Dir.P);
         Path  : constant String := Util.Files.Find_File_Path ("setup.xml", Paths);
      begin
         ASF.Applications.Main.Configs.Read_Configuration (App, Path);

      exception
         when Ada.IO_Exceptions.Name_Error =>
            Log.Error ("Setup configuration file '{0}' does not exist", Path);
      end;

      declare
         URL : constant String := App.Config.Get ("google-plus.callback_url", "");
         Pos : Natural := Util.Strings.Index (URL, '#');
      begin
         if Pos > 0 then
            App.Changed.Set ("callback_url", URL (URL'First .. Pos - 1));
         end if;
      end;
      App.Database.Set_Connection (App.Config.Get ("database", "mysql://localhost:3306/db"));
      Server.Register_Application (App.Config.Get ("contextPath"), App'Unchecked_Access);
      while not App.Done loop
         delay 5.0;
      end loop;
      Server.Remove_Application (App'Unchecked_Access);
   end Setup;

end AWA.Setup.Applications;

Implement the Do_Get procedure to redirect to the installation page Initialize the URL mapping to redirect to the installation page for any URL


-----------------------------------------------------------------------
--  mat-interp -- Command interpreter
--  Copyright (C) 2014 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Util.Strings;
with Util.Log.Loggers;

with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;
with Ada.IO_Exceptions;
with Ada.Text_IO;
with Ada.Strings.Unbounded;

with MAT.Types;
with MAT.Readers.Files;
with MAT.Memory.Tools;
with MAT.Memory.Targets;
with MAT.Symbols.Targets;
with MAT.Frames;
with MAT.Frames.Print;
package body MAT.Commands is

   --  The logger
   Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("MAT.Commands");

   package Command_Map is
     new Ada.Containers.Indefinite_Hashed_Maps (Key_Type        => String,
                                                Element_Type    => Command_Handler,
                                                Equivalent_Keys => "=",
                                                Hash            => Ada.Strings.Hash);

   Commands : Command_Map.Map;

   --  ------------------------------
   --  Sizes command.
   --  Collect statistics about the used memory slots and report the different slot
   --  sizes with count.
   --  ------------------------------
   procedure Slot_Command (Target : in out MAT.Targets.Target_Type'Class;
                           Args   : in String) is
      Slots : MAT.Memory.Allocation_Map;
      Iter  : MAT.Memory.Allocation_Cursor;

      procedure Print (Addr : in MAT.Types.Target_Addr;
                       Slot : in MAT.Memory.Allocation) is
         use type MAT.Frames.Frame_Type;
         Backtrace : MAT.Frames.Frame_Table := MAT.Frames.Backtrace (Slot.Frame);

         Name : Ada.Strings.Unbounded.Unbounded_String;
         Func : Ada.Strings.Unbounded.Unbounded_String;
         Line : Natural;
      begin
         Ada.Text_IO.Put (MAT.Types.Hex_Image (Addr));
         Ada.Text_IO.Set_Col (14);
         Ada.Text_IO.Put (MAT.Types.Target_Size'Image (Slot.Size));
         Ada.Text_IO.Set_Col (30);
         Ada.Text_IO.Put (MAT.Types.Target_Thread_Ref'Image (Slot.Thread));
         Ada.Text_IO.Set_Col (50);
         Ada.Text_IO.Put (MAT.Types.Target_Tick_Ref'Image (Slot.Time));
         Ada.Text_IO.New_Line;
         for I in Backtrace'Range loop
            Ada.Text_IO.Put ("   ");
            Ada.Text_IO.Put (Natural'Image (I));
            Ada.Text_IO.Put ("   ");
            Ada.Text_IO.Put (MAT.Types.Hex_Image (Backtrace (I)));
            MAT.Symbols.Targets.Find_Nearest_Line (Symbols => Target.Symbols,
                                                   Addr    => Backtrace (I),
                                                   Name    => Name,
                                                   Func    => Func,
                                                   Line    => Line);
            Ada.Text_IO.Put ("   ");
            Ada.Text_IO.Put (Ada.Strings.Unbounded.To_String (Func));
            Ada.Text_IO.Put (" ");
            Ada.Text_IO.Put (Ada.Strings.Unbounded.To_String (Name));
            if Line /= 0 then
               Ada.Text_IO.Put (":");
               Ada.Text_IO.Put (Util.Strings.Image (Line));
            end if;
            Ada.Text_IO.New_Line;
         end loop;
      end Print;

   begin
      Target.Memory.Find (From => MAT.Types.Target_Addr'First,
                          To   => MAT.Types.Target_Addr'Last,
                          Into => Slots);
      Iter := Slots.First;
      while MAT.Memory.Allocation_Maps.Has_Element (Iter) loop
         MAT.Memory.Allocation_Maps.Query_Element (Iter, Print'Access);
         MAT.Memory.Allocation_Maps.Next (Iter);
      end loop;
   end Slot_Command;

   --  ------------------------------
   --  Sizes command.
   --  Collect statistics about the used memory slots and report the different slot
   --  sizes with count.
   --  ------------------------------
   procedure Sizes_Command (Target : in out MAT.Targets.Target_Type'Class;
                            Args   : in String) is
      Sizes : MAT.Memory.Tools.Size_Info_Map;
      Iter  : MAT.Memory.Tools.Size_Info_Cursor;
   begin
      MAT.Memory.Targets.Size_Information (Memory => Target.Memory,
                                           Sizes  => Sizes);
      Iter := Sizes.First;
      while MAT.Memory.Tools.Size_Info_Maps.Has_Element (Iter) loop
         declare
            use type MAT.Types.Target_Size;

            Size  : MAT.Types.Target_Size := MAT.Memory.Tools.Size_Info_Maps.Key (Iter);
            Info  : MAT.Memory.Tools.Size_Info_Type := MAT.Memory.Tools.Size_Info_Maps.Element (Iter);
            Total : MAT.Types.Target_Size := Size * MAT.Types.Target_Size (Info.Count);
         begin
            Ada.Text_IO.Put (MAT.Types.Target_Size'Image (Size));
            Ada.Text_IO.Set_Col (20);
            Ada.Text_IO.Put (Natural'Image (Info.Count));
            Ada.Text_IO.Set_Col (30);
            Ada.Text_IO.Put_Line (MAT.Types.Target_Size'Image (Total));
         end;
         MAT.Memory.Tools.Size_Info_Maps.Next (Iter);
      end loop;
   end Sizes_Command;

   --  ------------------------------
   --  Symbol command.
   --  Load the symbols from the binary file.
   --  ------------------------------
   procedure Symbol_Command (Target : in out MAT.Targets.Target_Type'Class;
                             Args   : in String) is
   begin
      MAT.Symbols.Targets.Open (Target.Symbols, Args);
   end Symbol_Command;

   --  ------------------------------
   --  Exit command.
   --  ------------------------------
   procedure Exit_Command (Target : in out MAT.Targets.Target_Type'Class;
                           Args   : in String) is
   begin
      raise Stop_Interp;
   end Exit_Command;

   --  ------------------------------
   --  Open a MAT file and read the events.
   --  ------------------------------
   procedure Open_Command (Target : in out MAT.Targets.Target_Type'Class;
                           Args   : in String) is
      Reader : MAT.Readers.Files.File_Reader_Type;
   begin
      Target.Initialize (Reader);
      Reader.Open (Args);
      Reader.Read_All;

   exception
      when E : Ada.IO_Exceptions.Name_Error =>
         Log.Error ("Cannot open {0}", Args);
   end Open_Command;

   function Get_Command (Line : in String) return String is
      Pos : Natural := Util.Strings.Index (Line, ' ');
   begin
      if Pos <= 0 then
         return Line;
      else
         return Line (Line'First .. Pos - 1);
      end if;
   end Get_Command;

   --  ------------------------------
   --  Execute the command given in the line.
   --  ------------------------------
   procedure Execute (Target : in out MAT.Targets.Target_Type'Class;
                      Line   : in String) is
      Command : constant String := Get_Command (Line);
      Index   : constant Natural := Util.Strings.Index (Line, ' ');
      Pos     : constant Command_Map.Cursor := Commands.Find (Command);
   begin
      if Command_Map.Has_Element (Pos) then
         Command_Map.Element (Pos) (Target, Line (Index + 1 .. Line'Last));
      elsif Command'Length > 0 then
         Ada.Text_IO.Put_Line ("Command '" & Command & "' not found");
      end if;
   end Execute;

begin
   Commands.Insert ("exit", Exit_Command'Access);
   Commands.Insert ("quit", Exit_Command'Access);
   Commands.Insert ("open", Open_Command'Access);
   Commands.Insert ("sizes", Sizes_Command'Access);
   Commands.Insert ("symbol", Symbol_Command'Access);
   Commands.Insert ("slots", Slot_Command'Access);
end MAT.Commands;

-----------------------------------------------------------------------
--  mat-interp -- Command interpreter
--  Copyright (C) 2014 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Util.Strings;
with Util.Log.Loggers;

with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Hash;
with Ada.IO_Exceptions;
with Ada.Text_IO;
with Ada.Strings.Unbounded;

with MAT.Types;
with MAT.Readers.Files;
with MAT.Memory.Tools;
with MAT.Memory.Targets;
with MAT.Symbols.Targets;
with MAT.Frames;
with MAT.Frames.Print;
with MAT.Consoles;
package body MAT.Commands is

   --  The logger
   Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("MAT.Commands");

   package Command_Map is
     new Ada.Containers.Indefinite_Hashed_Maps (Key_Type        => String,
                                                Element_Type    => Command_Handler,
                                                Equivalent_Keys => "=",
                                                Hash            => Ada.Strings.Hash);

   Commands : Command_Map.Map;

   --  ------------------------------
   --  Sizes command.
   --  Collect statistics about the used memory slots and report the different slot
   --  sizes with count.
   --  ------------------------------
   procedure Slot_Command (Target : in out MAT.Targets.Target_Type'Class;
                           Args   : in String) is
      Slots : MAT.Memory.Allocation_Map;
      Iter  : MAT.Memory.Allocation_Cursor;

      procedure Print (Addr : in MAT.Types.Target_Addr;
                       Slot : in MAT.Memory.Allocation) is
         use type MAT.Frames.Frame_Type;
         Backtrace : MAT.Frames.Frame_Table := MAT.Frames.Backtrace (Slot.Frame);

         Name : Ada.Strings.Unbounded.Unbounded_String;
         Func : Ada.Strings.Unbounded.Unbounded_String;
         Line : Natural;
      begin
         Ada.Text_IO.Put (MAT.Types.Hex_Image (Addr));
         Ada.Text_IO.Set_Col (14);
         Ada.Text_IO.Put (MAT.Types.Target_Size'Image (Slot.Size));
         Ada.Text_IO.Set_Col (30);
         Ada.Text_IO.Put (MAT.Types.Target_Thread_Ref'Image (Slot.Thread));
         Ada.Text_IO.Set_Col (50);
         Ada.Text_IO.Put (MAT.Types.Target_Tick_Ref'Image (Slot.Time));
         Ada.Text_IO.New_Line;
         for I in Backtrace'Range loop
            Ada.Text_IO.Put ("   ");
            Ada.Text_IO.Put (Natural'Image (I));
            Ada.Text_IO.Put ("   ");
            Ada.Text_IO.Put (MAT.Types.Hex_Image (Backtrace (I)));
            MAT.Symbols.Targets.Find_Nearest_Line (Symbols => Target.Symbols,
                                                   Addr    => Backtrace (I),
                                                   Name    => Name,
                                                   Func    => Func,
                                                   Line    => Line);
            Ada.Text_IO.Put ("   ");
            Ada.Text_IO.Put (Ada.Strings.Unbounded.To_String (Func));
            Ada.Text_IO.Put (" ");
            Ada.Text_IO.Put (Ada.Strings.Unbounded.To_String (Name));
            if Line /= 0 then
               Ada.Text_IO.Put (":");
               Ada.Text_IO.Put (Util.Strings.Image (Line));
            end if;
            Ada.Text_IO.New_Line;
         end loop;
      end Print;

   begin
      Target.Memory.Find (From => MAT.Types.Target_Addr'First,
                          To   => MAT.Types.Target_Addr'Last,
                          Into => Slots);
      Iter := Slots.First;
      while MAT.Memory.Allocation_Maps.Has_Element (Iter) loop
         MAT.Memory.Allocation_Maps.Query_Element (Iter, Print'Access);
         MAT.Memory.Allocation_Maps.Next (Iter);
      end loop;
   end Slot_Command;

   --  ------------------------------
   --  Sizes command.
   --  Collect statistics about the used memory slots and report the different slot
   --  sizes with count.
   --  ------------------------------
   procedure Sizes_Command (Target : in out MAT.Targets.Target_Type'Class;
                            Args   : in String) is
      Sizes   : MAT.Memory.Tools.Size_Info_Map;
      Iter    : MAT.Memory.Tools.Size_Info_Cursor;
      Console : constant MAT.Consoles.Console_Access := Target.Console;
   begin
      Console.Start_Title;
      Console.Print_Title (MAT.Consoles.F_SIZE, "Slot size", 25);
      Console.Print_Title (MAT.Consoles.F_COUNT, "Count", 15);
      Console.Print_Title (MAT.Consoles.F_TOTAL_SIZE, "Total size", 15);
      Console.End_Title;

      MAT.Memory.Targets.Size_Information (Memory => Target.Memory,
                                           Sizes  => Sizes);
      Iter := Sizes.First;
      while MAT.Memory.Tools.Size_Info_Maps.Has_Element (Iter) loop
         declare
            use type MAT.Types.Target_Size;

            Size  : MAT.Types.Target_Size := MAT.Memory.Tools.Size_Info_Maps.Key (Iter);
            Info  : MAT.Memory.Tools.Size_Info_Type := MAT.Memory.Tools.Size_Info_Maps.Element (Iter);
            Total : MAT.Types.Target_Size := Size * MAT.Types.Target_Size (Info.Count);
         begin
            Console.Start_Row;
            Console.Print_Size (MAT.Consoles.F_SIZE, Size);
            Console.Print_Field (MAT.Consoles.F_COUNT, Info.Count);
            Console.Print_Field (MAT.Consoles.F_TOTAL_SIZE, Total);
            Console.End_Row;
         end;
         MAT.Memory.Tools.Size_Info_Maps.Next (Iter);
      end loop;
   end Sizes_Command;

   --  ------------------------------
   --  Symbol command.
   --  Load the symbols from the binary file.
   --  ------------------------------
   procedure Symbol_Command (Target : in out MAT.Targets.Target_Type'Class;
                             Args   : in String) is
   begin
      MAT.Symbols.Targets.Open (Target.Symbols, Args);
   end Symbol_Command;

   --  ------------------------------
   --  Exit command.
   --  ------------------------------
   procedure Exit_Command (Target : in out MAT.Targets.Target_Type'Class;
                           Args   : in String) is
   begin
      raise Stop_Interp;
   end Exit_Command;

   --  ------------------------------
   --  Open a MAT file and read the events.
   --  ------------------------------
   procedure Open_Command (Target : in out MAT.Targets.Target_Type'Class;
                           Args   : in String) is
      Reader : MAT.Readers.Files.File_Reader_Type;
   begin
      Target.Initialize (Reader);
      Reader.Open (Args);
      Reader.Read_All;

   exception
      when E : Ada.IO_Exceptions.Name_Error =>
         Log.Error ("Cannot open {0}", Args);
   end Open_Command;

   function Get_Command (Line : in String) return String is
      Pos : Natural := Util.Strings.Index (Line, ' ');
   begin
      if Pos <= 0 then
         return Line;
      else
         return Line (Line'First .. Pos - 1);
      end if;
   end Get_Command;

   --  ------------------------------
   --  Execute the command given in the line.
   --  ------------------------------
   procedure Execute (Target : in out MAT.Targets.Target_Type'Class;
                      Line   : in String) is
      Command : constant String := Get_Command (Line);
      Index   : constant Natural := Util.Strings.Index (Line, ' ');
      Pos     : constant Command_Map.Cursor := Commands.Find (Command);
   begin
      if Command_Map.Has_Element (Pos) then
         Command_Map.Element (Pos) (Target, Line (Index + 1 .. Line'Last));
      elsif Command'Length > 0 then
         Ada.Text_IO.Put_Line ("Command '" & Command & "' not found");
      end if;
   end Execute;

begin
   Commands.Insert ("exit", Exit_Command'Access);
   Commands.Insert ("quit", Exit_Command'Access);
   Commands.Insert ("open", Open_Command'Access);
   Commands.Insert ("sizes", Sizes_Command'Access);
   Commands.Insert ("symbol", Symbol_Command'Access);
   Commands.Insert ("slots", Slot_Command'Access);
end MAT.Commands;

Use the console operation to print the size of memory slots


-----------------------------------------------------------------------
--  mat-consoles - Console interface
--  Copyright (C) 2014 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Strings.Unbounded;

with MAT.Types;
package MAT.Consoles is

   type Field_Type is (F_ADDR,
                       F_SIZE,
                       F_TOTAL_SIZE,
                       F_MIN_SIZE,
                       F_MAX_SIZE,
                       F_MIN_ADDR,
                       F_MAX_ADDR,
                       F_THREAD,
                       F_COUNT,
                       F_FILE_NAME,
                       F_FUNCTION_NAME,
                       F_LINE_NUMBER,
                       F_ID,
                       F_OLD_ADDR,
                       F_TIME,
                       F_EVENT,
                       F_FRAME_ID,
                       F_FRAME_ADDR);

   type Notice_Type is (N_PID_INFO,
                        N_DURATION,
                        N_PATH_INFO);

   type Justify_Type is (J_LEFT,           --  Justify left   |item    |
                         J_RIGHT,          --  Justify right  |    item|
                         J_CENTER,         --  Justify center |  item  |
                         J_RIGHT_NO_FILL   --  Justify right  |item|
                        );

   type Console_Type is abstract tagged limited private;
   type Console_Access is access all Console_Type'Class;

   --  Report an error message.
   procedure Error (Console : in out Console_Type;
                    Message : in String) is abstract;

   --  Report a notice message.
   procedure Notice (Console : in out Console_Type;
                     Kind    : in Notice_Type;
                     Message : in String) is abstract;

   --  Print the field value for the given field.
   procedure Print_Field (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Value   : in String;
                          Justify : in Justify_Type := J_LEFT) is abstract;

   --  Print the title for the given field.
   procedure Print_Title (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Title   : in String) is abstract;

   --  Start a new title in a report.
   procedure Start_Title (Console : in out Console_Type) is abstract;

   --  Finish a new title in a report.
   procedure End_Title (Console : in out Console_Type) is abstract;

   --  Start a new row in a report.
   procedure Start_Row (Console : in out Console_Type) is abstract;

   --  Finish a new row in a report.
   procedure End_Row (Console : in out Console_Type) is abstract;

   --  Print the title for the given field and setup the associated field size.
   procedure Print_Title (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Title   : in String;
                          Length  : in Positive);

   --  Format the address and print it for the given field.
   procedure Print_Field (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Addr    : in MAT.Types.Target_Addr);

   --  Format the size and print it for the given field.
   procedure Print_Size (Console : in out Console_Type;
                         Field   : in Field_Type;
                         Size    : in MAT.Types.Target_Size);

   --  Format the thread information and print it for the given field.
   procedure Print_Thread (Console : in out Console_Type;
                           Field   : in Field_Type;
                           Thread  : in MAT.Types.Target_Thread_Ref);

   --  Format the time tick as a duration and print it for the given field.
   procedure Print_Duration (Console  : in out Console_Type;
                             Field    : in Field_Type;
                             Duration : in MAT.Types.Target_Tick_Ref);

   --  Format the integer and print it for the given field.
   procedure Print_Field (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Value   : in Integer;
                          Justify : in Justify_Type := J_LEFT);

   --  Format the integer and print it for the given field.
   procedure Print_Field (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Value   : in Ada.Strings.Unbounded.Unbounded_String;
                          Justify : in Justify_Type := J_LEFT);

private

   type Field_Size_Array is array (Field_Type) of Natural;

   type Field_List_Array is array (1 .. Field_Type'Pos (Field_Type'Last)) of Field_Type;

   type Console_Type is abstract tagged limited record
      Sizes       : Field_Size_Array := (others => 1);
      Cols        : Field_Size_Array := (others => 1);
      Fields      : Field_List_Array;
      Field_Count : Natural := 0;
   end record;

end MAT.Consoles;

-----------------------------------------------------------------------
--  mat-consoles - Console interface
--  Copyright (C) 2014, 2015 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Strings.Unbounded;

with MAT.Types;
package MAT.Consoles is

   type Field_Type is (F_ADDR,
                       F_SIZE,
                       F_TOTAL_SIZE,
                       F_MIN_SIZE,
                       F_MAX_SIZE,
                       F_MIN_ADDR,
                       F_MAX_ADDR,
                       F_THREAD,
                       F_COUNT,
                       F_FILE_NAME,
                       F_FUNCTION_NAME,
                       F_LINE_NUMBER,
                       F_ID,
                       F_OLD_ADDR,
                       F_TIME,
                       F_EVENT,
                       F_FRAME_ID,
                       F_FRAME_ADDR);

   type Notice_Type is (N_HELP,
                        N_PID_INFO,
                        N_DURATION,
                        N_PATH_INFO);

   type Justify_Type is (J_LEFT,           --  Justify left   |item    |
                         J_RIGHT,          --  Justify right  |    item|
                         J_CENTER,         --  Justify center |  item  |
                         J_RIGHT_NO_FILL   --  Justify right  |item|
                        );

   type Console_Type is abstract tagged limited private;
   type Console_Access is access all Console_Type'Class;

   --  Report an error message.
   procedure Error (Console : in out Console_Type;
                    Message : in String) is abstract;

   --  Report a notice message.
   procedure Notice (Console : in out Console_Type;
                     Kind    : in Notice_Type;
                     Message : in String) is abstract;

   --  Print the field value for the given field.
   procedure Print_Field (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Value   : in String;
                          Justify : in Justify_Type := J_LEFT) is abstract;

   --  Print the title for the given field.
   procedure Print_Title (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Title   : in String) is abstract;

   --  Start a new title in a report.
   procedure Start_Title (Console : in out Console_Type) is abstract;

   --  Finish a new title in a report.
   procedure End_Title (Console : in out Console_Type) is abstract;

   --  Start a new row in a report.
   procedure Start_Row (Console : in out Console_Type) is abstract;

   --  Finish a new row in a report.
   procedure End_Row (Console : in out Console_Type) is abstract;

   --  Print the title for the given field and setup the associated field size.
   procedure Print_Title (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Title   : in String;
                          Length  : in Positive);

   --  Format the address and print it for the given field.
   procedure Print_Field (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Addr    : in MAT.Types.Target_Addr);

   --  Format the size and print it for the given field.
   procedure Print_Size (Console : in out Console_Type;
                         Field   : in Field_Type;
                         Size    : in MAT.Types.Target_Size);

   --  Format the thread information and print it for the given field.
   procedure Print_Thread (Console : in out Console_Type;
                           Field   : in Field_Type;
                           Thread  : in MAT.Types.Target_Thread_Ref);

   --  Format the time tick as a duration and print it for the given field.
   procedure Print_Duration (Console  : in out Console_Type;
                             Field    : in Field_Type;
                             Duration : in MAT.Types.Target_Tick_Ref);

   --  Format the integer and print it for the given field.
   procedure Print_Field (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Value   : in Integer;
                          Justify : in Justify_Type := J_LEFT);

   --  Format the integer and print it for the given field.
   procedure Print_Field (Console : in out Console_Type;
                          Field   : in Field_Type;
                          Value   : in Ada.Strings.Unbounded.Unbounded_String;
                          Justify : in Justify_Type := J_LEFT);

private

   type Field_Size_Array is array (Field_Type) of Natural;

   type Field_List_Array is array (1 .. Field_Type'Pos (Field_Type'Last)) of Field_Type;

   type Console_Type is abstract tagged limited record
      Sizes       : Field_Size_Array := (others => 1);
      Cols        : Field_Size_Array := (others => 1);
      Fields      : Field_List_Array;
      Field_Count : Natural := 0;
   end record;

end MAT.Consoles;

Define the N_HELP notice type

Define the N_HELP notice type


--  Generated by utildgen.c from system includes
with Interfaces.C;
package Util.Systems.Constants is

   pragma Pure;

   --  Flags used when opening a file with open/creat.
   O_RDONLY                      : constant Interfaces.C.int := 8#000000#;
   O_WRONLY                      : constant Interfaces.C.int := 8#000001#;
   O_RDWR                        : constant Interfaces.C.int := 8#000002#;
   O_CREAT                       : constant Interfaces.C.int := 8#001000#;
   O_EXCL                        : constant Interfaces.C.int := 8#004000#;
   O_TRUNC                       : constant Interfaces.C.int := 8#002000#;
   O_APPEND                      : constant Interfaces.C.int := 8#000010#;
   O_CLOEXEC                     : constant Interfaces.C.int := 8#20000000#;
   O_SYNC                        : constant Interfaces.C.int := 8#000200#;
   O_DIRECT                      : constant Interfaces.C.int := 8#2000000#;
   O_NONBLOCK                    : constant Interfaces.C.int := 8#000004#;

   --  Flags used by fcntl
   F_SETFL                       : constant Interfaces.C.int := 4;
   F_GETFL                       : constant Interfaces.C.int := 3;
   FD_CLOEXEC                    : constant Interfaces.C.int := 1;

   --  Flags used by dlopen
   RTLD_LAZY                     : constant Interfaces.C.int := 8#000001#;
   RTLD_NOW                      : constant Interfaces.C.int := 8#000002#;
   RTLD_NOLOAD                   : constant Interfaces.C.int := 8#020000#;
   RTLD_DEEPBIND                 : constant Interfaces.C.int := 8#000000#;
   RTLD_GLOBAL                   : constant Interfaces.C.int := 8#000400#;
   RTLD_LOCAL                    : constant Interfaces.C.int := 8#001000#;
   RTLD_NODELETE                 : constant Interfaces.C.int := 8#010000#;

   DLL_OPTIONS : constant String := "";

end Util.Systems.Constants;

--  Generated by utildgen.c from system includes
with Interfaces.C;
package Util.Systems.Constants is

   pragma Pure;

   --  Flags used when opening a file with open/creat.
   O_RDONLY                      : constant Interfaces.C.int := 8#000000#;
   O_WRONLY                      : constant Interfaces.C.int := 8#000001#;
   O_RDWR                        : constant Interfaces.C.int := 8#000002#;
   O_CREAT                       : constant Interfaces.C.int := 8#001000#;
   O_EXCL                        : constant Interfaces.C.int := 8#004000#;
   O_TRUNC                       : constant Interfaces.C.int := 8#002000#;
   O_APPEND                      : constant Interfaces.C.int := 8#000010#;
   O_CLOEXEC                     : constant Interfaces.C.int := 8#20000000#;
   O_SYNC                        : constant Interfaces.C.int := 8#000200#;
   O_DIRECT                      : constant Interfaces.C.int := 8#2000000#;
   O_NONBLOCK                    : constant Interfaces.C.int := 8#000004#;

   --  Flags used by fcntl
   F_SETFL                       : constant Interfaces.C.int := 4;
   F_GETFL                       : constant Interfaces.C.int := 3;
   FD_CLOEXEC                    : constant Interfaces.C.int := 1;

   --  Flags used by dlopen
   RTLD_LAZY                     : constant Interfaces.C.int := 8#000001#;
   RTLD_NOW                      : constant Interfaces.C.int := 8#000002#;
   RTLD_NOLOAD                   : constant Interfaces.C.int := 8#020000#;
   RTLD_DEEPBIND                 : constant Interfaces.C.int := 8#000000#;
   RTLD_GLOBAL                   : constant Interfaces.C.int := 8#000400#;
   RTLD_LOCAL                    : constant Interfaces.C.int := 8#001000#;
   RTLD_NODELETE                 : constant Interfaces.C.int := 8#010000#;

   DLL_OPTIONS   : constant String := "";
   SYMBOL_PREFIX : constant String := "";

end Util.Systems.Constants;

Declare SYMBOL_PREFIX

Declare SYMBOL_PREFIX