-----------------------------------------------------------------------
--  util-streams-pipes -- Pipe stream to or from a process
--  Copyright (C) 2011, 2013, 2015, 2016, 2017, 2018, 2019 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.Finalization;

with Util.Processes;

--  == Pipes ==
--  The `Util.Streams.Pipes` package defines a pipe stream to or from a process.
--  It allows to launch an external program while getting the program standard output or
--  providing the program standard input.  The `Pipe_Stream` type represents the input or
--  output stream for the external program.  This is a portable interface that works on
--  Unix and Windows.
--
--  The process is created and launched by the `Open` operation.  The pipe allows
--  to read or write to the process through the `Read` and `Write` operation.
--  It is very close to the *popen* operation provided by the C stdio library.
--  First, create the pipe instance:
--
--    with Util.Streams.Pipes;
--    ...
--       Pipe : aliased Util.Streams.Pipes.Pipe_Stream;
--
--  The pipe instance can be associated with only one process at a time.
--  The process is launched by using the `Open` command and by specifying the command
--  to execute as well as the pipe redirection mode:
--
--  * `READ` to read the process standard output,
--  * `WRITE` to write the process standard input.
--
--  For example to run the `ls -l` command and read its output, we could run it by using:
--
--    Pipe.Open (Command => "ls -l", Mode => Util.Processes.READ);
--
--  The `Pipe_Stream` is not buffered and a buffer can be configured easily by using the
--  `Input_Buffer_Stream` type and connecting the buffer to the pipe so that it reads
--  the pipe to fill the buffer.  The initialization of the buffer is the following:
--
--    with Util.Streams.Buffered;
--    ...
--       Buffer : Util.Streams.Buffered.Input_Buffer_Stream;
--       ...
--       Buffer.Initialize (Input => Pipe'Access, Size => 1024);
--
--  And to read the process output, one can use the following:
--
--     Content : Ada.Strings.Unbounded.Unbounded_String;
--     ...
--     Buffer.Read (Into => Content);
--
--  The pipe object should be closed when reading or writing to it is finished.
--  By closing the pipe, the caller will wait for the termination of the process.
--  The process exit status can be obtained by using the `Get_Exit_Status` function.
--
--     Pipe.Close;
--     if Pipe.Get_Exit_Status /= 0 then
--        Ada.Text_IO.Put_Line ("Command exited with status "
--                              & Integer'Image (Pipe.Get_Exit_Status));
--     end if;
--
--  You will note that the `Pipe_Stream` is a limited type and thus cannot be copied.
--  When leaving the scope of the `Pipe_Stream` instance, the application will wait for
--  the process to terminate.
--
--  Before opening the pipe, it is possible to have some control on the process that
--  will be created to configure:
--
--    * The shell that will be used to launch the process,
--    * The process working directory,
--    * Redirect the process output to a file,
--    * Redirect the process error to a file,
--    * Redirect the process input from a file.
--
--  All these operations must be made before calling the `Open` procedure.
package Util.Streams.Pipes is

   use Util.Processes;

   subtype Pipe_Mode is Util.Processes.Pipe_Mode range READ .. READ_WRITE;

   --  -----------------------
   --  Pipe stream
   --  -----------------------
   --  The Pipe_Stream is an output/input stream that reads or writes
   --  to or from a process.
   type Pipe_Stream is limited new Output_Stream and Input_Stream  with private;

   --  Set the shell executable path to use to launch a command.  The default on Unix is
   --  the /bin/sh command.  Argument splitting is done by the /bin/sh -c command.
   --  When setting an empty shell command, the argument splitting is done by the
   --  <tt>Spawn</tt> procedure.
   procedure Set_Shell (Stream : in out Pipe_Stream;
                        Shell  : in String);

   --  Before launching the process, redirect the input stream of the process
   --  to the specified file.
   --  Raises Invalid_State if the process is running.
   procedure Set_Input_Stream (Stream : in out Pipe_Stream;
                               File   : in String);

   --  Set the output stream of the process.
   --  Raises Invalid_State if the process is running.
   procedure Set_Output_Stream (Stream : in out Pipe_Stream;
                                File   : in String;
                                Append : in Boolean := False);

   --  Set the error stream of the process.
   --  Raises Invalid_State if the process is running.
   procedure Set_Error_Stream (Stream : in out Pipe_Stream;
                               File   : in String;
                               Append : in Boolean := False);

   --  Set the working directory that the process will use once it is created.
   --  The directory must exist or the Invalid_Directory exception will be raised.
   procedure Set_Working_Directory (Stream : in out Pipe_Stream;
                                    Path   : in String);

   --  Closes the given file descriptor in the child process before executing the command.
   procedure Add_Close (Stream : in out Pipe_Stream;
                        Fd     : in Util.Processes.File_Type);

   --  Open a pipe to read or write to an external process.  The pipe is created and the
   --  command is executed with the input and output streams redirected through the pipe.
   procedure Open (Stream  : in out Pipe_Stream;
                   Command : in String;
                   Mode    : in Pipe_Mode := READ);

   --  Close the pipe and wait for the external process to terminate.
   overriding
   procedure Close (Stream : in out Pipe_Stream);

   --  Get the process exit status.
   function Get_Exit_Status (Stream : in Pipe_Stream) return Integer;

   --  Returns True if the process is running.
   function Is_Running (Stream : in Pipe_Stream) return Boolean;

   --  Write the buffer array to the output stream.
   overriding
   procedure Write (Stream : in out Pipe_Stream;
                    Buffer : in Ada.Streams.Stream_Element_Array);

   --  Read into the buffer as many bytes as possible and return in
   --  last the position of the last byte read.
   overriding
   procedure Read (Stream : in out Pipe_Stream;
                   Into   : out Ada.Streams.Stream_Element_Array;
                   Last   : out Ada.Streams.Stream_Element_Offset);

private

   type Pipe_Stream is limited new Ada.Finalization.Limited_Controlled
     and Output_Stream and Input_Stream with record
      Proc   : Util.Processes.Process;
   end record;

   --  Flush the stream and release the buffer.
   overriding
   procedure Finalize (Object : in out Pipe_Stream);

end Util.Streams.Pipes;

-----------------------------------------------------------------------
--  util-streams-pipes -- Pipe stream to or from a process
--  Copyright (C) 2011, 2013, 2015, 2016, 2017, 2018, 2019, 2021 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.Processes;

--  == Pipes ==
--  The `Util.Streams.Pipes` package defines a pipe stream to or from a process.
--  It allows to launch an external program while getting the program standard output or
--  providing the program standard input.  The `Pipe_Stream` type represents the input or
--  output stream for the external program.  This is a portable interface that works on
--  Unix and Windows.
--
--  The process is created and launched by the `Open` operation.  The pipe allows
--  to read or write to the process through the `Read` and `Write` operation.
--  It is very close to the *popen* operation provided by the C stdio library.
--  First, create the pipe instance:
--
--    with Util.Streams.Pipes;
--    ...
--       Pipe : aliased Util.Streams.Pipes.Pipe_Stream;
--
--  The pipe instance can be associated with only one process at a time.
--  The process is launched by using the `Open` command and by specifying the command
--  to execute as well as the pipe redirection mode:
--
--  * `READ` to read the process standard output,
--  * `WRITE` to write the process standard input.
--
--  For example to run the `ls -l` command and read its output, we could run it by using:
--
--    Pipe.Open (Command => "ls -l", Mode => Util.Processes.READ);
--
--  The `Pipe_Stream` is not buffered and a buffer can be configured easily by using the
--  `Input_Buffer_Stream` type and connecting the buffer to the pipe so that it reads
--  the pipe to fill the buffer.  The initialization of the buffer is the following:
--
--    with Util.Streams.Buffered;
--    ...
--       Buffer : Util.Streams.Buffered.Input_Buffer_Stream;
--       ...
--       Buffer.Initialize (Input => Pipe'Access, Size => 1024);
--
--  And to read the process output, one can use the following:
--
--     Content : Ada.Strings.Unbounded.Unbounded_String;
--     ...
--     Buffer.Read (Into => Content);
--
--  The pipe object should be closed when reading or writing to it is finished.
--  By closing the pipe, the caller will wait for the termination of the process.
--  The process exit status can be obtained by using the `Get_Exit_Status` function.
--
--     Pipe.Close;
--     if Pipe.Get_Exit_Status /= 0 then
--        Ada.Text_IO.Put_Line ("Command exited with status "
--                              & Integer'Image (Pipe.Get_Exit_Status));
--     end if;
--
--  You will note that the `Pipe_Stream` is a limited type and thus cannot be copied.
--  When leaving the scope of the `Pipe_Stream` instance, the application will wait for
--  the process to terminate.
--
--  Before opening the pipe, it is possible to have some control on the process that
--  will be created to configure:
--
--    * The shell that will be used to launch the process,
--    * The process working directory,
--    * Redirect the process output to a file,
--    * Redirect the process error to a file,
--    * Redirect the process input from a file.
--
--  All these operations must be made before calling the `Open` procedure.
package Util.Streams.Pipes is

   use Util.Processes;

   subtype Pipe_Mode is Util.Processes.Pipe_Mode range READ .. READ_WRITE;

   --  -----------------------
   --  Pipe stream
   --  -----------------------
   --  The Pipe_Stream is an output/input stream that reads or writes
   --  to or from a process.
   type Pipe_Stream is limited new Output_Stream and Input_Stream with private;

   --  Set the shell executable path to use to launch a command.  The default on Unix is
   --  the /bin/sh command.  Argument splitting is done by the /bin/sh -c command.
   --  When setting an empty shell command, the argument splitting is done by the
   --  <tt>Spawn</tt> procedure.
   procedure Set_Shell (Stream : in out Pipe_Stream;
                        Shell  : in String);

   --  Before launching the process, redirect the input stream of the process
   --  to the specified file.
   --  Raises Invalid_State if the process is running.
   procedure Set_Input_Stream (Stream : in out Pipe_Stream;
                               File   : in String);

   --  Set the output stream of the process.
   --  Raises Invalid_State if the process is running.
   procedure Set_Output_Stream (Stream : in out Pipe_Stream;
                                File   : in String;
                                Append : in Boolean := False);

   --  Set the error stream of the process.
   --  Raises Invalid_State if the process is running.
   procedure Set_Error_Stream (Stream : in out Pipe_Stream;
                               File   : in String;
                               Append : in Boolean := False);

   --  Set the working directory that the process will use once it is created.
   --  The directory must exist or the Invalid_Directory exception will be raised.
   procedure Set_Working_Directory (Stream : in out Pipe_Stream;
                                    Path   : in String);

   --  Closes the given file descriptor in the child process before executing the command.
   procedure Add_Close (Stream : in out Pipe_Stream;
                        Fd     : in Util.Processes.File_Type);

   --  Open a pipe to read or write to an external process.  The pipe is created and the
   --  command is executed with the input and output streams redirected through the pipe.
   procedure Open (Stream  : in out Pipe_Stream;
                   Command : in String;
                   Mode    : in Pipe_Mode := READ);

   --  Close the pipe and wait for the external process to terminate.
   overriding
   procedure Close (Stream : in out Pipe_Stream);

   --  Get the process exit status.
   function Get_Exit_Status (Stream : in Pipe_Stream) return Integer;

   --  Returns True if the process is running.
   function Is_Running (Stream : in Pipe_Stream) return Boolean;

   --  Write the buffer array to the output stream.
   overriding
   procedure Write (Stream : in out Pipe_Stream;
                    Buffer : in Ada.Streams.Stream_Element_Array);

   --  Read into the buffer as many bytes as possible and return in
   --  last the position of the last byte read.
   overriding
   procedure Read (Stream : in out Pipe_Stream;
                   Into   : out Ada.Streams.Stream_Element_Array;
                   Last   : out Ada.Streams.Stream_Element_Offset);

   --  Terminate the process by sending a signal on Unix and exiting the process on Windows.
   --  This operation is not portable and has a different behavior between Unix and Windows.
   --  Its intent is to stop the process.
   procedure Stop (Stream : in out Pipe_Stream;
                   Signal : in Positive := 15);

private

   type Pipe_Stream is limited new Output_Stream and Input_Stream with record
      Proc   : Util.Processes.Process;
   end record;

end Util.Streams.Pipes;

Remove the Ada.Finalization.Limited_Controlled and Finalize Add Stop procedure to stop the process by using some signal


-----------------------------------------------------------------------
--  awa-events -- AWA Events
--  Copyright (C) 2012, 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.
-----------------------------------------------------------------------

package body AWA.Events is

   --  ------------------------------
   --  Set the event type which identifies the event.
   --  ------------------------------
   procedure Set_Event_Kind (Event : in out Module_Event;
                             Kind  : in Event_Index) is
   begin
      Event.Kind := Kind;
   end Set_Event_Kind;

   --  ------------------------------
   --  Get the event type which identifies the event.
   --  ------------------------------
   function Get_Event_Kind (Event : in Module_Event) return Event_Index is
   begin
      return Event.Kind;
   end Get_Event_Kind;

   --  ------------------------------
   --  Set a parameter on the message.
   --  ------------------------------
   procedure Set_Parameter (Event  : in out Module_Event;
                            Name   : in String;
                            Value  : in String) is
   begin
      Event.Props.Include (Name, Util.Beans.Objects.To_Object (Value));
   end Set_Parameter;

   --  ------------------------------
   --  Get the parameter with the given name.
   --  ------------------------------
   function Get_Parameter (Event : in Module_Event;
                           Name  : in String) return String is
      Pos : constant Util.Beans.Objects.Maps.Cursor := Event.Props.Find (Name);
   begin
      if Util.Beans.Objects.Maps.Has_Element (Pos) then
         return Util.Beans.Objects.To_String (Util.Beans.Objects.Maps.Element (Pos));
      else
         return "";
      end if;
   end Get_Parameter;

   --  ------------------------------
   --  Get the value that corresponds to the parameter with the given name.
   --  ------------------------------
   function Get_Value (Event : in Module_Event;
                       Name  : in String) return Util.Beans.Objects.Object is
   begin
      if Event.Props.Contains (Name) then
         return Event.Props.Element (Name);
      else
         return Util.Beans.Objects.Null_Object;
      end if;
   end Get_Value;

   --  ------------------------------
   --  Get the entity identifier associated with the event.
   --  ------------------------------
   function Get_Entity_Identifier (Event : in Module_Event) return ADO.Identifier is
   begin
      return Event.Entity;
   end Get_Entity_Identifier;

   --  ------------------------------
   --  Set the entity identifier associated with the event.
   --  ------------------------------
   procedure Set_Entity_Identifier (Event : in out Module_Event;
                                    Id    : in ADO.Identifier) is
   begin
      Event.Entity := Id;
   end Set_Entity_Identifier;

   --  ------------------------------
   --  Copy the event properties to the map passed in <tt>Into</tt>.
   --  ------------------------------
   procedure Copy (Event : in Module_Event;
                   Into  : in out Util.Beans.Objects.Maps.Map) is
   begin
      Into := Event.Props;
   end Copy;

   --  ------------------------------
   --  Make and return a copy of the event.
   --  ------------------------------
   function Copy (Event : in Module_Event) return Module_Event_Access is
      Result : constant Module_Event_Access := new Module_Event;
   begin
      Result.Kind := Event.Kind;
      Result.Props := Event.Props;
      return Result;
   end Copy;

end AWA.Events;

-----------------------------------------------------------------------
--  awa-events -- AWA Events
--  Copyright (C) 2012, 2015, 2020 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 ADO.Sessions.Entities;
package body AWA.Events is

   --  ------------------------------
   --  Set the event type which identifies the event.
   --  ------------------------------
   procedure Set_Event_Kind (Event : in out Module_Event;
                             Kind  : in Event_Index) is
   begin
      Event.Kind := Kind;
   end Set_Event_Kind;

   --  ------------------------------
   --  Get the event type which identifies the event.
   --  ------------------------------
   function Get_Event_Kind (Event : in Module_Event) return Event_Index is
   begin
      return Event.Kind;
   end Get_Event_Kind;

   --  ------------------------------
   --  Set a parameter on the message.
   --  ------------------------------
   procedure Set_Parameter (Event  : in out Module_Event;
                            Name   : in String;
                            Value  : in String) is
   begin
      Event.Props.Include (Name, Util.Beans.Objects.To_Object (Value));
   end Set_Parameter;

   --  ------------------------------
   --  Get the parameter with the given name.
   --  ------------------------------
   function Get_Parameter (Event : in Module_Event;
                           Name  : in String) return String is
      Pos : constant Util.Beans.Objects.Maps.Cursor := Event.Props.Find (Name);
   begin
      if Util.Beans.Objects.Maps.Has_Element (Pos) then
         return Util.Beans.Objects.To_String (Util.Beans.Objects.Maps.Element (Pos));
      else
         return "";
      end if;
   end Get_Parameter;

   --  ------------------------------
   --  Set the parameters of the message.
   --  ------------------------------
   procedure Set_Parameters (Event      : in out Module_Event;
                             Parameters : in Util.Beans.Objects.Maps.Map) is
   begin
      Event.Props := Parameters;
   end Set_Parameters;

   --  ------------------------------
   --  Get the value that corresponds to the parameter with the given name.
   --  ------------------------------
   function Get_Value (Event : in Module_Event;
                       Name  : in String) return Util.Beans.Objects.Object is
   begin
      if Event.Props.Contains (Name) then
         return Event.Props.Element (Name);
      else
         return Util.Beans.Objects.Null_Object;
      end if;
   end Get_Value;

   --  ------------------------------
   --  Get the entity identifier associated with the event.
   --  ------------------------------
   function Get_Entity_Identifier (Event : in Module_Event) return ADO.Identifier is
   begin
      return Event.Entity;
   end Get_Entity_Identifier;

   --  ------------------------------
   --  Set the entity identifier associated with the event.
   --  ------------------------------
   procedure Set_Entity_Identifier (Event : in out Module_Event;
                                    Id    : in ADO.Identifier) is
   begin
      Event.Entity := Id;
   end Set_Entity_Identifier;

   --  ------------------------------
   --  Set the database entity associated with the event.
   --  ------------------------------
   procedure Set_Entity (Event   : in out Module_Event;
                         Entity  : in ADO.Objects.Object_Ref'Class;
                         Session : in ADO.Sessions.Session'Class) is
      Key : constant ADO.Objects.Object_Key := Entity.Get_Key;
   begin
      Event.Entity := ADO.Objects.Get_Value (Key);
      Event.Entity_Type := ADO.Sessions.Entities.Find_Entity_Type (Session, Key);
   end Set_Entity;

   --  ------------------------------
   --  Copy the event properties to the map passed in <tt>Into</tt>.
   --  ------------------------------
   procedure Copy (Event : in Module_Event;
                   Into  : in out Util.Beans.Objects.Maps.Map) is
   begin
      Into := Event.Props;
   end Copy;

   --  ------------------------------
   --  Make and return a copy of the event.
   --  ------------------------------
   function Copy (Event : in Module_Event) return Module_Event_Access is
      Result : constant Module_Event_Access := new Module_Event;
   begin
      Result.Kind := Event.Kind;
      Result.Props := Event.Props;
      return Result;
   end Copy;

end AWA.Events;

Add Set_Entity and Set_Parameters procedures


-----------------------------------------------------------------------
--  html -- ASF HTML Components
--  Copyright (C) 2009, 2010, 2011, 2012, 2017, 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 Ada.Exceptions;
with Ada.Unchecked_Deallocation;

with EL.Objects;

with ASF.Components.Core;
with ASF.Utils;
package body ASF.Components.Html.Text is

   use EL.Objects;

   TEXT_ATTRIBUTE_NAMES  : Util.Strings.String_Set.Set;

   LABEL_ATTRIBUTE_NAMES : Util.Strings.String_Set.Set;

   --  ------------------------------
   --  Get the local value of the component without evaluating
   --  the associated Value_Expression.
   --  ------------------------------
   overriding
   function Get_Local_Value (UI : in UIOutput) return EL.Objects.Object is
   begin
      return UI.Value;
   end Get_Local_Value;

   --  ------------------------------
   --  Get the value to write on the output.
   --  ------------------------------
   overriding
   function Get_Value (UI    : in UIOutput) return EL.Objects.Object is
   begin
      if not EL.Objects.Is_Null (UI.Value) then
         return UI.Value;
      else
         return UI.Get_Attribute (UI.Get_Context.all, "value");
      end if;
   end Get_Value;

   --  ------------------------------
   --  Set the value to write on the output.
   --  ------------------------------
   overriding
   procedure Set_Value (UI    : in out UIOutput;
                        Value : in EL.Objects.Object) is
   begin
      UI.Value := Value;
   end Set_Value;

   --  ------------------------------
   --  Get the converter that is registered on the component.
   --  ------------------------------
   overriding
   function Get_Converter (UI : in UIOutput)
                           return ASF.Converters.Converter_Access is
   begin
      return UI.Converter;
   end Get_Converter;

   --  ------------------------------
   --  Set the converter to be used on the component.
   --  ------------------------------
   overriding
   procedure Set_Converter (UI        : in out UIOutput;
                            Converter : in ASF.Converters.Converter_Access;
                            Release   : in Boolean := False) is
      use type ASF.Converters.Converter_Access;
      procedure Free is
        new Ada.Unchecked_Deallocation (Object => ASF.Converters.Converter'Class,
                                        Name   => ASF.Converters.Converter_Access);
   begin
      if UI.Release_Converter then
         Free (UI.Converter);
      end if;
      if Converter = null then
         UI.Converter := null;
         UI.Release_Converter := False;
      else
         UI.Converter := Converter.all'Unchecked_Access;
         UI.Release_Converter := Release;
      end if;
   end Set_Converter;

   --  ------------------------------
   --  Get the value of the component and apply the converter on it if there is one.
   --  ------------------------------
   function Get_Formatted_Value (UI      : in UIOutput;
                                 Context : in Faces_Context'Class) return String is
      Value : constant EL.Objects.Object := UIOutput'Class (UI).Get_Value;
   begin
      return UIOutput'Class (UI).Get_Formatted_Value (Value, Context);
   end Get_Formatted_Value;

   --  ------------------------------
   --  Get the converter associated with the component
   --  ------------------------------
   function Get_Converter (UI      : in UIOutput;
                           Context : in Faces_Context'Class)
                           return access ASF.Converters.Converter'Class is
      use type ASF.Converters.Converter_Access;
      Result : ASF.Converters.Converter_Access := UIOutput'Class (UI).Get_Converter;
   begin
      if Result /= null then
         return Result;
      else
         declare
            Name : constant EL.Objects.Object
              := UIOutput'Class (UI).Get_Attribute (Name    => CONVERTER_NAME,
                                                    Context => Context);
         begin
            return Context.Get_Converter (Name);
         end;
      end if;
   end Get_Converter;

   --  ------------------------------
   --  Format the value by appling the To_String converter on it if there is one.
   --  ------------------------------
   function Get_Formatted_Value (UI      : in UIOutput;
                                 Value   : in Util.Beans.Objects.Object;
                                 Context : in Contexts.Faces.Faces_Context'Class) return String is
      use type ASF.Converters.Converter_Access;
   begin
      if UI.Converter /= null then
         return UI.Converter.To_String (Context   => Context,
                                        Component => UI,
                                        Value     => Value);
      else
         declare
            Converter : constant access ASF.Converters.Converter'Class
              := UI.Get_Converter (Context);
         begin
            if Converter /= null then
               return Converter.To_String (Context   => Context,
                                           Component => UI,
                                           Value     => Value);
            elsif not Is_Null (Value) then
               return EL.Objects.To_String (Value);

            else
               return "";
            end if;
         end;
      end if;

      --  If the converter raises an exception, report an error in the logs.
      --  At this stage, we know the value and we can report it in this log message.
      --  We must queue the exception in the context, so this is done later.
   exception
      when E : others =>
         UI.Log_Error ("Error when converting value '{0}': {1}: {2}",
                       Util.Beans.Objects.To_String (Value),
                       Ada.Exceptions.Exception_Name (E),
                       Ada.Exceptions.Exception_Message (E));
         raise;
   end Get_Formatted_Value;

   procedure Write_Output (UI      : in UIOutput;
                           Context : in out Faces_Context'Class;
                           Value   : in String) is
      Writer : constant Response_Writer_Access := Context.Get_Response_Writer;
      Escape : constant Object := UI.Get_Attribute (Context, "escape");
   begin
      Writer.Start_Optional_Element ("span");
      UI.Render_Attributes (Context, TEXT_ATTRIBUTE_NAMES, Writer);
      if Is_Null (Escape) or To_Boolean (Escape) then
         Writer.Write_Text (Value);
      else
         Writer.Write_Raw (Value);
      end if;
      Writer.End_Optional_Element ("span");
   end Write_Output;

   procedure Encode_Begin (UI      : in UIOutput;
                           Context : in out Faces_Context'Class) is
   begin
      if UI.Is_Rendered (Context) then
         UI.Write_Output (Context => Context,
                          Value   => UIOutput'Class (UI).Get_Formatted_Value (Context));

      end if;

      --  Queue any block converter exception that could be raised.
   exception
      when E : others =>
         Context.Queue_Exception (E);
   end Encode_Begin;

   overriding
   procedure Finalize (UI : in out UIOutput) is
   begin
      UI.Set_Converter (null);
      UIHtmlComponent (UI).Finalize;
   end Finalize;

   --  ------------------------------
   --  Label Component
   --  ------------------------------

   procedure Encode_Begin (UI      : in UIOutputLabel;
                           Context : in out Faces_Context'Class) is
      Writer : Response_Writer_Access;
   begin
      if UI.Is_Rendered (Context) then
         Writer := Context.Get_Response_Writer;
         Writer.Start_Element ("label");
         UI.Render_Attributes (Context, LABEL_ATTRIBUTE_NAMES, Writer);
         declare
            Value : Util.Beans.Objects.Object := UI.Get_Attribute (Name    => "for",
                                                                   Context => Context);
         begin
            if not Util.Beans.Objects.Is_Null (Value) then
               Writer.Write_Attribute ("for", Value);
            end if;

            Value := UIOutputLabel'Class (UI).Get_Value;
            if not Util.Beans.Objects.Is_Null (Value) then
               declare
                  S : constant String
                    := UIOutputLabel'Class (UI).Get_Formatted_Value (Value, Context);
               begin
                  if UI.Get_Attribute (Name => "escape", Context => Context, Default => True) then
                     Writer.Write_Text (S);
                  else
                     Writer.Write_Raw (S);
                  end if;
               end;
            end if;

            --  Queue and block any converter exception that could be raised.
         exception
            when E : others =>
               Context.Queue_Exception (E);
         end;
      end if;
   end Encode_Begin;

   procedure Encode_End (UI      : in UIOutputLabel;
                         Context : in out Faces_Context'Class) is
      Writer : Response_Writer_Access;
   begin
      if UI.Is_Rendered (Context) then
         Writer := Context.Get_Response_Writer;
         Writer.End_Element ("label");
      end if;
   end Encode_End;

   --  ------------------------------
   --  OutputFormat Component
   --  ------------------------------
   procedure Encode_Begin (UI      : in UIOutputFormat;
                           Context : in out Faces_Context'Class) is
      use ASF.Components.Core;
      use ASF.Utils;
   begin
      if not UI.Is_Rendered (Context) then
         return;
      end if;

      declare
         Params : constant UIParameter_Access_Array := Get_Parameters (UI);
         Values : ASF.Utils.Object_Array (Params'Range);
         Result : Ada.Strings.Unbounded.Unbounded_String;
         Fmt    : constant String := EL.Objects.To_String (UI.Get_Value);
      begin
         --  Get the values associated with the parameters.
         for I in Params'Range loop
            Values (I) := Params (I).Get_Value (Context);
         end loop;
         Formats.Format (Fmt, Values, Result);
         UI.Write_Output (Context => Context,
                          Value   => To_String (Result));
      end;
   end Encode_Begin;

begin
   Utils.Set_Text_Attributes (TEXT_ATTRIBUTE_NAMES);
   Utils.Set_Text_Attributes (LABEL_ATTRIBUTE_NAMES);
   Utils.Set_Interactive_Attributes (LABEL_ATTRIBUTE_NAMES);
end ASF.Components.Html.Text;

-----------------------------------------------------------------------
--  html -- ASF HTML Components
--  Copyright (C) 2009, 2010, 2011, 2012, 2017, 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 Ada.Exceptions;
with Ada.Unchecked_Deallocation;

with EL.Objects;

with ASF.Components.Core;
with ASF.Utils;
package body ASF.Components.Html.Text is

   use EL.Objects;

   TEXT_ATTRIBUTE_NAMES  : Util.Strings.String_Set.Set;

   LABEL_ATTRIBUTE_NAMES : Util.Strings.String_Set.Set;

   --  ------------------------------
   --  Get the local value of the component without evaluating
   --  the associated Value_Expression.
   --  ------------------------------
   overriding
   function Get_Local_Value (UI : in UIOutput) return EL.Objects.Object is
   begin
      return UI.Value;
   end Get_Local_Value;

   --  ------------------------------
   --  Get the value to write on the output.
   --  ------------------------------
   overriding
   function Get_Value (UI    : in UIOutput) return EL.Objects.Object is
   begin
      if not EL.Objects.Is_Null (UI.Value) then
         return UI.Value;
      else
         return UI.Get_Attribute (UI.Get_Context.all, "value");
      end if;
   end Get_Value;

   --  ------------------------------
   --  Set the value to write on the output.
   --  ------------------------------
   overriding
   procedure Set_Value (UI    : in out UIOutput;
                        Value : in EL.Objects.Object) is
   begin
      UI.Value := Value;
   end Set_Value;

   --  ------------------------------
   --  Get the converter that is registered on the component.
   --  ------------------------------
   overriding
   function Get_Converter (UI : in UIOutput)
                           return ASF.Converters.Converter_Access is
   begin
      return UI.Converter;
   end Get_Converter;

   --  ------------------------------
   --  Set the converter to be used on the component.
   --  ------------------------------
   overriding
   procedure Set_Converter (UI        : in out UIOutput;
                            Converter : in ASF.Converters.Converter_Access;
                            Release   : in Boolean := False) is
      use type ASF.Converters.Converter_Access;
      procedure Free is
        new Ada.Unchecked_Deallocation (Object => ASF.Converters.Converter'Class,
                                        Name   => ASF.Converters.Converter_Access);
   begin
      if UI.Release_Converter then
         Free (UI.Converter);
      end if;
      if Converter = null then
         UI.Converter := null;
         UI.Release_Converter := False;
      else
         UI.Converter := Converter.all'Unchecked_Access;
         UI.Release_Converter := Release;
      end if;
   end Set_Converter;

   --  ------------------------------
   --  Get the value of the component and apply the converter on it if there is one.
   --  ------------------------------
   function Get_Formatted_Value (UI      : in UIOutput;
                                 Context : in Faces_Context'Class) return String is
      Value : constant EL.Objects.Object := UIOutput'Class (UI).Get_Value;
   begin
      return UIOutput'Class (UI).Get_Formatted_Value (Value, Context);
   end Get_Formatted_Value;

   --  ------------------------------
   --  Get the converter associated with the component
   --  ------------------------------
   function Get_Converter (UI      : in UIOutput;
                           Context : in Faces_Context'Class)
                           return access ASF.Converters.Converter'Class is
      use type ASF.Converters.Converter_Access;
      Result : constant ASF.Converters.Converter_Access := UIOutput'Class (UI).Get_Converter;
   begin
      if Result /= null then
         return Result;
      else
         declare
            Name : constant EL.Objects.Object
              := UIOutput'Class (UI).Get_Attribute (Name    => CONVERTER_NAME,
                                                    Context => Context);
         begin
            return Context.Get_Converter (Name);
         end;
      end if;
   end Get_Converter;

   --  ------------------------------
   --  Format the value by appling the To_String converter on it if there is one.
   --  ------------------------------
   function Get_Formatted_Value (UI      : in UIOutput;
                                 Value   : in Util.Beans.Objects.Object;
                                 Context : in Contexts.Faces.Faces_Context'Class) return String is
      use type ASF.Converters.Converter_Access;
   begin
      if UI.Converter /= null then
         return UI.Converter.To_String (Context   => Context,
                                        Component => UI,
                                        Value     => Value);
      else
         declare
            Converter : constant access ASF.Converters.Converter'Class
              := UI.Get_Converter (Context);
         begin
            if Converter /= null then
               return Converter.To_String (Context   => Context,
                                           Component => UI,
                                           Value     => Value);
            elsif not Is_Null (Value) then
               return EL.Objects.To_String (Value);

            else
               return "";
            end if;
         end;
      end if;

      --  If the converter raises an exception, report an error in the logs.
      --  At this stage, we know the value and we can report it in this log message.
      --  We must queue the exception in the context, so this is done later.
   exception
      when E : others =>
         UI.Log_Error ("Error when converting value '{0}': {1}: {2}",
                       Util.Beans.Objects.To_String (Value),
                       Ada.Exceptions.Exception_Name (E),
                       Ada.Exceptions.Exception_Message (E));
         raise;
   end Get_Formatted_Value;

   procedure Write_Output (UI      : in UIOutput;
                           Context : in out Faces_Context'Class;
                           Value   : in String) is
      Writer : constant Response_Writer_Access := Context.Get_Response_Writer;
      Escape : constant Object := UI.Get_Attribute (Context, "escape");
   begin
      Writer.Start_Optional_Element ("span");
      UI.Render_Attributes (Context, TEXT_ATTRIBUTE_NAMES, Writer);
      if Is_Null (Escape) or To_Boolean (Escape) then
         Writer.Write_Text (Value);
      else
         Writer.Write_Raw (Value);
      end if;
      Writer.End_Optional_Element ("span");
   end Write_Output;

   procedure Encode_Begin (UI      : in UIOutput;
                           Context : in out Faces_Context'Class) is
   begin
      if UI.Is_Rendered (Context) then
         UI.Write_Output (Context => Context,
                          Value   => UIOutput'Class (UI).Get_Formatted_Value (Context));

      end if;

      --  Queue any block converter exception that could be raised.
   exception
      when E : others =>
         Context.Queue_Exception (E);
   end Encode_Begin;

   overriding
   procedure Finalize (UI : in out UIOutput) is
   begin
      UI.Set_Converter (null);
      UIHtmlComponent (UI).Finalize;
   end Finalize;

   --  ------------------------------
   --  Label Component
   --  ------------------------------

   procedure Encode_Begin (UI      : in UIOutputLabel;
                           Context : in out Faces_Context'Class) is
      Writer : Response_Writer_Access;
   begin
      if UI.Is_Rendered (Context) then
         Writer := Context.Get_Response_Writer;
         Writer.Start_Element ("label");
         UI.Render_Attributes (Context, LABEL_ATTRIBUTE_NAMES, Writer);
         declare
            Value : Util.Beans.Objects.Object := UI.Get_Attribute (Name    => "for",
                                                                   Context => Context);
         begin
            if not Util.Beans.Objects.Is_Null (Value) then
               Writer.Write_Attribute ("for", Value);
            end if;

            Value := UIOutputLabel'Class (UI).Get_Value;
            if not Util.Beans.Objects.Is_Null (Value) then
               declare
                  S : constant String
                    := UIOutputLabel'Class (UI).Get_Formatted_Value (Value, Context);
               begin
                  if UI.Get_Attribute (Name => "escape", Context => Context, Default => True) then
                     Writer.Write_Text (S);
                  else
                     Writer.Write_Raw (S);
                  end if;
               end;
            end if;

            --  Queue and block any converter exception that could be raised.
         exception
            when E : others =>
               Context.Queue_Exception (E);
         end;
      end if;
   end Encode_Begin;

   procedure Encode_End (UI      : in UIOutputLabel;
                         Context : in out Faces_Context'Class) is
      Writer : Response_Writer_Access;
   begin
      if UI.Is_Rendered (Context) then
         Writer := Context.Get_Response_Writer;
         Writer.End_Element ("label");
      end if;
   end Encode_End;

   --  ------------------------------
   --  OutputFormat Component
   --  ------------------------------
   procedure Encode_Begin (UI      : in UIOutputFormat;
                           Context : in out Faces_Context'Class) is
      use ASF.Components.Core;
      use ASF.Utils;
   begin
      if not UI.Is_Rendered (Context) then
         return;
      end if;

      declare
         Params : constant UIParameter_Access_Array := Get_Parameters (UI);
         Values : ASF.Utils.Object_Array (Params'Range);
         Result : Ada.Strings.Unbounded.Unbounded_String;
         Fmt    : constant String := EL.Objects.To_String (UI.Get_Value);
      begin
         --  Get the values associated with the parameters.
         for I in Params'Range loop
            Values (I) := Params (I).Get_Value (Context);
         end loop;
         Formats.Format (Fmt, Values, Result);
         UI.Write_Output (Context => Context,
                          Value   => To_String (Result));
      end;
   end Encode_Begin;

begin
   Utils.Set_Text_Attributes (TEXT_ATTRIBUTE_NAMES);
   Utils.Set_Text_Attributes (LABEL_ATTRIBUTE_NAMES);
   Utils.Set_Interactive_Attributes (LABEL_ATTRIBUTE_NAMES);
end ASF.Components.Html.Text;

Fix compilation warning

Fix compilation warning


-----------------------------------------------------------------------
--  wiki-parsers-dotclear -- Dotclear parser operations
--  Copyright (C) 2011 - 2022 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 Wiki.Nodes;
with Wiki.Helpers;
with Wiki.Parsers.Common;
package body Wiki.Parsers.Dotclear is

   use Wiki.Helpers;
   use Wiki.Nodes;
   use Wiki.Strings;
   use Wiki.Buffers;

   --  Parse an image.
   --  Example:
   --    ((url|alt text))
   --    ((url|alt text|position))
   --    ((url|alt text|position||description))
   procedure Parse_Image (Parser  : in out Parser_Type;
                          Text    : in out Wiki.Buffers.Buffer_Access;
                          From    : in out Positive);

   procedure Parse_Preformatted (Parser : in out Parser_Type;
                                 Text   : in out Wiki.Buffers.Buffer_Access;
                                 From   : in out Positive);

   procedure Parse_Preformatted (Parser : in out Parser_Type;
                                 Text   : in out Wiki.Buffers.Buffer_Access;
                                 From   : in out Positive) is
      Count : constant Natural := Count_Occurence (Text, From, '/');
   begin
      if Count /= 3 then
         return;
      end if;

      --  Extract the format either 'Ada' or '[Ada]'
      declare
         Pos    : Natural := Count + 1;
         Buffer : Wiki.Buffers.Buffer_Access := Text;
         Space_Count : Natural;
      begin
         Wiki.Strings.Clear (Parser.Preformat_Format);
         Buffers.Skip_Spaces (Buffer, Pos, Space_Count);
         if Buffer /= null and then Pos <= Buffer.Last and then Buffer.Content (Pos) = '[' then
            Next (Buffer, Pos);
            Common.Parse_Token (Buffer, Pos, Parser.Escape_Char, ']', ']',
                                Parser.Preformat_Format);
            if Buffer /= null then
               Next (Buffer, Pos);
            end if;
         else
            Common.Parse_Token (Buffer, Pos, Parser.Escape_Char, CR, LF,
                                Parser.Preformat_Format);
         end if;
         if Buffer /= null then
            Buffers.Skip_Spaces (Buffer, Pos, Space_Count);
         end if;
         Text := Buffer;
         From := Pos;
      end;

      Parser.Preformat_Indent := 0;
      Parser.Preformat_Fence := ' ';
      Parser.Preformat_Fcount := 0;
      Flush_Text (Parser, Trim => Right);
      Pop_Block (Parser);
      Push_Block (Parser, N_PREFORMAT);
   end Parse_Preformatted;

   --  ------------------------------
   --  Parse an image.
   --  Example:
   --    ((url|alt text))
   --    ((url|alt text|position))
   --    ((url|alt text|position||description))
   --  ------------------------------
   procedure Parse_Image (Parser  : in out Parser_Type;
                          Text    : in out Wiki.Buffers.Buffer_Access;
                          From    : in out Positive) is
      procedure Append_Position (Position : in Wiki.Strings.WString);

      procedure Append_Position (Position : in Wiki.Strings.WString) is
      begin
         if Position in "L" | "G" then
            Wiki.Attributes.Append (Parser.Attributes, String '("align"), "left");
         elsif Position in "R" | "D" then
            Wiki.Attributes.Append (Parser.Attributes, String '("align"), "right");
         elsif Position = "C" then
            Wiki.Attributes.Append (Parser.Attributes, String '("align"), "center");
         end if;
      end Append_Position;

      procedure Append_Position is
         new Wiki.Strings.Wide_Wide_Builders.Get (Append_Position);

      Link     : Wiki.Strings.BString (128);
      Alt      : Wiki.Strings.BString (128);
      Position : Wiki.Strings.BString (128);
      Desc     : Wiki.Strings.BString (128);
      Block    : Wiki.Buffers.Buffer_Access := Text;
      Pos      : Positive := From;
   begin
      Next (Block, Pos);
      if Block = null or else Block.Content (Pos) /= '(' then
         Common.Parse_Text (Parser, Text, From);
         return;
      end if;

      Next (Block, Pos);
      if Block = null then
         Common.Parse_Text (Parser, Text, From, Count => 2);
         return;
      end if;

      Common.Parse_Token (Block, Pos, Parser.Escape_Char, '|', ')', Link);
      if Block /= null and then Block.Content (Pos) = '|' then
         Next (Block, Pos);
         if Block /= null then
            Common.Parse_Token (Block, Pos, Parser.Escape_Char, '|', ')', Alt);
         end if;
         if Block /= null and then Block.Content (Pos) = '|' then
            Next (Block, Pos);
            if Block /= null then
               Common.Parse_Token (Block, Pos, Parser.Escape_Char, '|', ')', Position);
            end if;
            if Block /= null and then Block.Content (Pos) = '|' then
               Next (Block, Pos);
               if Block /= null then
                  Common.Parse_Token (Block, Pos, Parser.Escape_Char, '|', ')', Desc);
               end if;
            end if;
         end if;
      end if;

      --  Check for the first ')'.
      if Block /= null and then Block.Content (Pos) = ')' then
         Next (Block, Pos);
      end if;

      --  Check for the second ')', abort the image and emit the '((' if the '))' is missing.
      if Block = null or else Block.Content (Pos) /= ')' then
         Common.Parse_Text (Parser, Text, From, Count => 2);
         return;
      end if;
      Next (Block, Pos);
      Text := Block;
      From := Pos;

      Flush_Text (Parser);
      if not Parser.Context.Is_Hidden then
         Wiki.Attributes.Clear (Parser.Attributes);
         Wiki.Attributes.Append (Parser.Attributes, "src", Link);
         Append_Position (Position);
         Wiki.Attributes.Append (Parser.Attributes, "longdesc", Desc);
         Parser.Context.Filters.Add_Image (Parser.Document,
                                           Strings.To_WString (Alt),
                                           Parser.Attributes);
      end if;
   end Parse_Image;

   procedure Parse_Line (Parser : in out Parser_Type;
                         Text   : in Wiki.Buffers.Buffer_Access) is
      Pos    : Natural := 1;
      C      : Wiki.Strings.WChar;
      Count  : Natural;
      Buffer : Wiki.Buffers.Buffer_Access := Text;
   begin
      if Parser.In_Blockquote then
         Count := Count_Occurence (Buffer, 1, '>');
         if Count = 0 then
            loop
               Pop_Block (Parser);
               exit when Parser.Current_Node = Nodes.N_NONE;
            end loop;
         else
            Buffers.Next (Buffer, Pos, Count);
            Buffers.Skip_Optional_Space (Buffer, Pos);
            if Buffer = null then
               return;
            end if;
            Push_Block (Parser, Nodes.N_BLOCKQUOTE, Count);
         end if;
      end if;

      if Parser.Current_Node = N_PREFORMAT then
         if Parser.Preformat_Fcount = 0 then
            Count := Count_Occurence (Buffer, 1, '/');
            if Count /= 3 then
               Common.Append (Parser.Text, Buffer, 1);
               return;
            end if;
            Pop_Block (Parser);
            return;
         end if;
         if Buffer.Content (Pos) = ' ' then
            Common.Append (Parser.Text, Buffer, Pos + 1);
            return;
         end if;
         Pop_Block (Parser);
      end if;

      if Parser.Current_Node = N_HEADER then
         Pop_Block (Parser);
      end if;

      C := Buffer.Content (Pos);
      if C = '>' then
         Count := Count_Occurence (Buffer, Pos, '>');
         Push_Block (Parser, Nodes.N_BLOCKQUOTE, Count);
         Buffers.Next (Buffer, Pos, Count);
         Buffers.Skip_Optional_Space (Buffer, Pos);
         if Buffer = null then
            return;
         end if;
         C := Buffer.Content (Pos);
      end if;

      case C is
         when CR | LF =>
            Common.Parse_Paragraph (Parser, Buffer, Pos);
            return;

         when '!' =>
            Common.Parse_Header (Parser, Buffer, Pos, '!');
            if Buffer = null then
               return;
            end if;

         when '/' =>
            Parse_Preformatted (Parser, Buffer, Pos);
            if Buffer = null then
               return;
            end if;

         when ' ' =>
            Parser.Preformat_Indent := 1;
            Parser.Preformat_Fence := ' ';
            Parser.Preformat_Fcount := 1;
            Flush_Text (Parser, Trim => Right);
            if Parser.Current_Node /= N_BLOCKQUOTE then
               Pop_Block (Parser);
            end if;
            Push_Block (Parser, N_PREFORMAT);
            Common.Append (Parser.Text, Buffer, Pos + 1);
            return;

         when '-' =>
            Common.Parse_Horizontal_Rule (Parser, Buffer, Pos, '-');
            if Buffer = null then
               return;
            end if;

         when '*' | '#' =>
            Common.Parse_List (Parser, Buffer, Pos);

         when others =>
            if Parser.Current_Node not in N_PARAGRAPH | N_BLOCKQUOTE then
               Pop_List (Parser);
               Push_Block (Parser, N_PARAGRAPH);
            end if;

      end case;

      Main :
      while Buffer /= null loop
         declare
            Last : Natural := Buffer.Last;
         begin
            while Pos <= Last loop
               C := Buffer.Content (Pos);
               case C is
                  when '_' =>
                     Parse_Format_Double (Parser, Buffer, Pos, '_', Wiki.BOLD);
                     exit Main when Buffer = null;

                  when ''' =>
                     Parse_Format_Double (Parser, Buffer, Pos, ''', Wiki.ITALIC);
                     exit Main when Buffer = null;

                  when '-' =>
                     Parse_Format_Double (Parser, Buffer, Pos, '-', Wiki.STRIKEOUT);
                     exit Main when Buffer = null;

                  when '+' =>
                     Parse_Format_Double (Parser, Buffer, Pos, '+', Wiki.INS);
                     exit Main when Buffer = null;

                  when ',' =>
                     Parse_Format_Double (Parser, Buffer, Pos, ',', Wiki.SUBSCRIPT);
                     exit Main when Buffer = null;

                  when '@' =>
                     Parse_Format_Double (Parser, Buffer, Pos, '@', Wiki.CODE);
                     exit Main when Buffer = null;

                  when '^' =>
                     Parse_Format (Parser, Buffer, Pos, '^', Wiki.SUPERSCRIPT);
                     exit Main when Buffer = null;

                  when '{' =>
                     Common.Parse_Quote (Parser, Buffer, Pos, '{');
                     exit Main when Buffer = null;

                  when '(' =>
                     Parse_Image (Parser, Buffer, Pos);
                     exit Main when Buffer = null;

                  when '[' =>
                     Common.Parse_Link (Parser, Buffer, Pos);
                     exit Main when Buffer = null;

                  when '<' =>
                     Common.Parse_Template (Parser, Buffer, Pos, '<');
                     exit Main when Buffer = null;

                  when '%' =>
                     Count := Count_Occurence (Buffer, Pos, '%');
                     if Count >= 3 then
                        Parser.Empty_Line := True;
                        Flush_Text (Parser, Trim => Right);
                        if not Parser.Context.Is_Hidden then
                           Parser.Context.Filters.Add_Node (Parser.Document, Nodes.N_LINE_BREAK);
                        end if;

                        --  Skip 3 '%' characters.
                        for I in 1 .. 3 loop
                           Next (Buffer, Pos);
                        end loop;
                        if Buffer /= null and then Helpers.Is_Newline (Buffer.Content (Pos)) then
                           Next (Buffer, Pos);
                        end if;
                        exit Main when Buffer = null;
                     else
                        Append (Parser.Text, C);
                        Pos := Pos + 1;
                     end if;

                  when CR | LF =>
                     --  if Wiki.Strings.Length (Parser.Text) > 0 then
                        Append (Parser.Text, ' ');
                     --  end if;
                     Pos := Pos + 1;

                  when '\' =>
                     Next (Buffer, Pos);
                     if Buffer = null then
                        Append (Parser.Text, C);
                     else
                        Append (Parser.Text, Buffer.Content (Pos));
                        Pos := Pos + 1;
                        Last := Buffer.Last;
                     end if;

                  when others =>
                     Append (Parser.Text, C);
                     Pos := Pos + 1;

               end case;
            end loop;
         end;
         Buffer := Buffer.Next_Block;
         Pos := 1;
      end loop Main;
   end Parse_Line;

end Wiki.Parsers.Dotclear;

-----------------------------------------------------------------------
--  wiki-parsers-dotclear -- Dotclear parser operations
--  Copyright (C) 2011 - 2022 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 Wiki.Nodes;
with Wiki.Helpers;
with Wiki.Parsers.Common;
package body Wiki.Parsers.Dotclear is

   use Wiki.Helpers;
   use Wiki.Nodes;
   use Wiki.Strings;
   use Wiki.Buffers;

   --  Parse an image.
   --  Example:
   --    ((url|alt text))
   --    ((url|alt text|position))
   --    ((url|alt text|position||description))
   procedure Parse_Image (Parser  : in out Parser_Type;
                          Text    : in out Wiki.Buffers.Buffer_Access;
                          From    : in out Positive);

   procedure Parse_Preformatted (Parser : in out Parser_Type;
                                 Text   : in out Wiki.Buffers.Buffer_Access;
                                 From   : in out Positive);

   procedure Parse_Preformatted (Parser : in out Parser_Type;
                                 Text   : in out Wiki.Buffers.Buffer_Access;
                                 From   : in out Positive) is
      Count : constant Natural := Count_Occurence (Text, From, '/');
   begin
      if Count /= 3 then
         return;
      end if;

      --  Extract the format either 'Ada' or '[Ada]'
      declare
         Pos    : Natural := Count + 1;
         Buffer : Wiki.Buffers.Buffer_Access := Text;
         Space_Count : Natural;
      begin
         Wiki.Strings.Clear (Parser.Preformat_Format);
         Buffers.Skip_Spaces (Buffer, Pos, Space_Count);
         if Buffer /= null and then Pos <= Buffer.Last and then Buffer.Content (Pos) = '[' then
            Next (Buffer, Pos);
            Common.Parse_Token (Buffer, Pos, Parser.Escape_Char, ']', ']',
                                Parser.Preformat_Format);
            if Buffer /= null then
               Next (Buffer, Pos);
            end if;
         else
            Common.Parse_Token (Buffer, Pos, Parser.Escape_Char, CR, LF,
                                Parser.Preformat_Format);
         end if;
         if Buffer /= null then
            Buffers.Skip_Spaces (Buffer, Pos, Space_Count);
         end if;
         Text := Buffer;
         From := Pos;
      end;

      Parser.Preformat_Indent := 0;
      Parser.Preformat_Fence := ' ';
      Parser.Preformat_Fcount := 0;
      Flush_Text (Parser, Trim => Right);
      Pop_Block (Parser);
      Push_Block (Parser, N_PREFORMAT);
   end Parse_Preformatted;

   --  ------------------------------
   --  Parse an image.
   --  Example:
   --    ((url|alt text))
   --    ((url|alt text|position))
   --    ((url|alt text|position||description))
   --  ------------------------------
   procedure Parse_Image (Parser  : in out Parser_Type;
                          Text    : in out Wiki.Buffers.Buffer_Access;
                          From    : in out Positive) is
      procedure Append_Position (Position : in Wiki.Strings.WString);

      procedure Append_Position (Position : in Wiki.Strings.WString) is
      begin
         if Position in "L" | "G" then
            Wiki.Attributes.Append (Parser.Attributes, String '("align"), "left");
         elsif Position in "R" | "D" then
            Wiki.Attributes.Append (Parser.Attributes, String '("align"), "right");
         elsif Position = "C" then
            Wiki.Attributes.Append (Parser.Attributes, String '("align"), "center");
         end if;
      end Append_Position;

      procedure Append_Position is
         new Wiki.Strings.Wide_Wide_Builders.Get (Append_Position);

      Link     : Wiki.Strings.BString (128);
      Alt      : Wiki.Strings.BString (128);
      Position : Wiki.Strings.BString (128);
      Desc     : Wiki.Strings.BString (128);
      Block    : Wiki.Buffers.Buffer_Access := Text;
      Pos      : Positive := From;
   begin
      Next (Block, Pos);
      if Block = null or else Block.Content (Pos) /= '(' then
         Common.Parse_Text (Parser, Text, From);
         return;
      end if;

      Next (Block, Pos);
      if Block = null then
         Common.Parse_Text (Parser, Text, From, Count => 2);
         return;
      end if;

      Common.Parse_Token (Block, Pos, Parser.Escape_Char, '|', ')', Link);
      if Block /= null and then Block.Content (Pos) = '|' then
         Next (Block, Pos);
         if Block /= null then
            Common.Parse_Token (Block, Pos, Parser.Escape_Char, '|', ')', Alt);
         end if;
         if Block /= null and then Block.Content (Pos) = '|' then
            Next (Block, Pos);
            if Block /= null then
               Common.Parse_Token (Block, Pos, Parser.Escape_Char, '|', ')', Position);
            end if;
            if Block /= null and then Block.Content (Pos) = '|' then
               Next (Block, Pos);
               if Block /= null then
                  Common.Parse_Token (Block, Pos, Parser.Escape_Char, '|', ')', Desc);
               end if;
            end if;
         end if;
      end if;

      --  Check for the first ')'.
      if Block /= null and then Block.Content (Pos) = ')' then
         Next (Block, Pos);
      end if;

      --  Check for the second ')', abort the image and emit the '((' if the '))' is missing.
      if Block = null or else Block.Content (Pos) /= ')' then
         Common.Parse_Text (Parser, Text, From, Count => 2);
         return;
      end if;
      Next (Block, Pos);
      Text := Block;
      From := Pos;

      Flush_Text (Parser);
      if not Parser.Context.Is_Hidden then
         Wiki.Attributes.Clear (Parser.Attributes);
         Wiki.Attributes.Append (Parser.Attributes, "src", Link);
         Append_Position (Position);
         Wiki.Attributes.Append (Parser.Attributes, "longdesc", Desc);
         Parser.Context.Filters.Add_Image (Parser.Document,
                                           Strings.To_WString (Alt),
                                           Parser.Attributes);
      end if;
   end Parse_Image;

   procedure Parse_Line (Parser : in out Parser_Type;
                         Text   : in Wiki.Buffers.Buffer_Access) is
      Pos    : Natural := 1;
      C      : Wiki.Strings.WChar;
      Count  : Natural;
      Buffer : Wiki.Buffers.Buffer_Access := Text;
   begin
      if Parser.In_Blockquote then
         Count := Count_Occurence (Buffer, 1, '>');
         if Count = 0 then
            loop
               Pop_Block (Parser);
               exit when Parser.Current_Node = Nodes.N_NONE;
            end loop;
         else
            Buffers.Next (Buffer, Pos, Count);
            Buffers.Skip_Optional_Space (Buffer, Pos);
            if Buffer = null then
               return;
            end if;
            Push_Block (Parser, Nodes.N_BLOCKQUOTE, Count);
         end if;
      end if;

      if Parser.Current_Node = N_PREFORMAT then
         if Parser.Preformat_Fcount = 0 then
            Count := Count_Occurence (Buffer, 1, '/');
            if Count /= 3 then
               Common.Append (Parser.Text, Buffer, 1);
               return;
            end if;
            Pop_Block (Parser);
            return;
         end if;
         if Buffer.Content (Pos) = ' ' then
            Common.Append (Parser.Text, Buffer, Pos + 1);
            return;
         end if;
         Pop_Block (Parser);
      end if;

      if Parser.Current_Node = N_HEADER then
         Pop_Block (Parser);
      end if;

      C := Buffer.Content (Pos);
      if C = '>' then
         Count := Count_Occurence (Buffer, Pos, '>');
         Push_Block (Parser, Nodes.N_BLOCKQUOTE, Count);
         Buffers.Next (Buffer, Pos, Count);
         Buffers.Skip_Optional_Space (Buffer, Pos);
         if Buffer = null then
            return;
         end if;
         C := Buffer.Content (Pos);
      end if;

      case C is
         when CR | LF =>
            Common.Parse_Paragraph (Parser, Buffer, Pos);
            return;

         when '!' =>
            Common.Parse_Header (Parser, Buffer, Pos, '!');
            if Buffer = null then
               return;
            end if;

         when '/' =>
            Parse_Preformatted (Parser, Buffer, Pos);
            if Buffer = null then
               return;
            end if;

         when ' ' =>
            Parser.Preformat_Indent := 1;
            Parser.Preformat_Fence := ' ';
            Parser.Preformat_Fcount := 1;
            Flush_Text (Parser, Trim => Right);
            if Parser.Current_Node /= N_BLOCKQUOTE then
               Pop_Block (Parser);
            end if;
            Push_Block (Parser, N_PREFORMAT);
            Common.Append (Parser.Text, Buffer, Pos + 1);
            return;

         when '-' =>
            Common.Parse_Horizontal_Rule (Parser, Buffer, Pos, '-');
            if Buffer = null then
               return;
            end if;

         when '*' | '#' =>
            Common.Parse_List (Parser, Buffer, Pos);

         when others =>
            if Parser.Current_Node not in N_PARAGRAPH | N_BLOCKQUOTE then
               Pop_List (Parser);
               Push_Block (Parser, N_PARAGRAPH);
            end if;

      end case;

      Main :
      while Buffer /= null loop
         while Pos <= Buffer.Last loop
            C := Buffer.Content (Pos);
            case C is
               when '_' =>
                  Parse_Format_Double (Parser, Buffer, Pos, '_', Wiki.BOLD);
                  exit Main when Buffer = null;

               when ''' =>
                  Parse_Format_Double (Parser, Buffer, Pos, ''', Wiki.ITALIC);
                  exit Main when Buffer = null;

               when '-' =>
                  Parse_Format_Double (Parser, Buffer, Pos, '-', Wiki.STRIKEOUT);
                  exit Main when Buffer = null;

               when '+' =>
                  Parse_Format_Double (Parser, Buffer, Pos, '+', Wiki.INS);
                  exit Main when Buffer = null;

               when ',' =>
                  Parse_Format_Double (Parser, Buffer, Pos, ',', Wiki.SUBSCRIPT);
                  exit Main when Buffer = null;

               when '@' =>
                  Parse_Format_Double (Parser, Buffer, Pos, '@', Wiki.CODE);
                  exit Main when Buffer = null;

               when '^' =>
                  Parse_Format (Parser, Buffer, Pos, '^', Wiki.SUPERSCRIPT);
                  exit Main when Buffer = null;

               when '{' =>
                  Common.Parse_Quote (Parser, Buffer, Pos, '{');
                  exit Main when Buffer = null;

               when '(' =>
                  Parse_Image (Parser, Buffer, Pos);
                  exit Main when Buffer = null;

               when '[' =>
                  Common.Parse_Link (Parser, Buffer, Pos);
                  exit Main when Buffer = null;

               when '<' =>
                  Common.Parse_Template (Parser, Buffer, Pos, '<');
                  exit Main when Buffer = null;

               when '%' =>
                  Count := Count_Occurence (Buffer, Pos, '%');
                  if Count >= 3 then
                     Parser.Empty_Line := True;
                     Flush_Text (Parser, Trim => Right);
                     if not Parser.Context.Is_Hidden then
                        Parser.Context.Filters.Add_Node (Parser.Document, Nodes.N_LINE_BREAK);
                     end if;

                     --  Skip 3 '%' characters.
                     for I in 1 .. 3 loop
                        Next (Buffer, Pos);
                     end loop;
                     if Buffer /= null and then Helpers.Is_Newline (Buffer.Content (Pos)) then
                        Next (Buffer, Pos);
                     end if;
                     exit Main when Buffer = null;
                  else
                     Append (Parser.Text, C);
                     Pos := Pos + 1;
                  end if;

               when CR | LF =>
                  Append (Parser.Text, ' ');
                  Pos := Pos + 1;

               when '\' =>
                  Next (Buffer, Pos);
                  if Buffer = null then
                     Append (Parser.Text, C);
                  else
                     Append (Parser.Text, Buffer.Content (Pos));
                     Pos := Pos + 1;
                  end if;

               when others =>
                  Append (Parser.Text, C);
                  Pos := Pos + 1;

            end case;
         end loop;
         Buffer := Buffer.Next_Block;
         Pos := 1;
      end loop Main;
   end Parse_Line;

end Wiki.Parsers.Dotclear;

Fix Constraint_Error raised when parsing some Dotclear documents


-----------------------------------------------------------------------
--  gen-commands-distrib -- Distrib command for dynamo
--  Copyright (C) 2012 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 GNAT.Command_Line;

with Ada.Text_IO;
package body Gen.Commands.Distrib is

   use GNAT.Command_Line;

   --  ------------------------------
   --  Execute the command with the arguments.
   --  ------------------------------
   procedure Execute (Cmd       : in Command;
                      Generator : in out Gen.Generator.Handler) is
      pragma Unreferenced (Cmd);
   begin
      Generator.Read_Project ("dynamo.xml", True);

      --  Setup the target directory where the distribution is created.
      declare
         Target_Dir : constant String := Get_Argument;
      begin
         if Target_Dir'Length = 0 then
            Generator.Error ("Missing target directory");
            return;
         end if;
         Generator.Set_Result_Directory (Target_Dir);
      end;

      --  Read the package description.
      declare
         Package_File : constant String := Get_Argument;
      begin
         if Package_File'Length > 0 then
            Gen.Generator.Read_Package (Generator, Package_File);
         else
            Gen.Generator.Read_Package (Generator, "package.xml");
         end if;
      end;

      --  Run the generation.
      Gen.Generator.Prepare (Generator);
      Gen.Generator.Generate_All (Generator);
      Gen.Generator.Finish (Generator);
   end Execute;

   --  ------------------------------
   --  Write the help associated with the command.
   --  ------------------------------
   procedure Help (Cmd       : in Command;
                   Generator : in out Gen.Generator.Handler) is
      pragma Unreferenced (Cmd, Generator);
      use Ada.Text_IO;
   begin
      Put_Line ("distrib: Generate the Ada files for the database model or queries");
      Put_Line ("Usage: distrib target-dir [package.xml]");
      New_Line;
      Put_Line ("  Read the XML package description and build the distribution tree");
      Put_Line ("  and create the distribution in the target directory.");
   end Help;

end Gen.Commands.Distrib;

-----------------------------------------------------------------------
--  gen-commands-distrib -- Distrib command for dynamo
--  Copyright (C) 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 GNAT.Command_Line;

with Ada.Text_IO;
package body Gen.Commands.Distrib is

   use GNAT.Command_Line;

   --  ------------------------------
   --  Execute the command with the arguments.
   --  ------------------------------
   procedure Execute (Cmd       : in Command;
                      Generator : in out Gen.Generator.Handler) is
      pragma Unreferenced (Cmd);
   begin
      Generator.Read_Project ("dynamo.xml", True);

      --  Setup the target directory where the distribution is created.
      declare
         Target_Dir : constant String := Get_Argument;
      begin
         if Target_Dir'Length = 0 then
            Generator.Error ("Missing target directory");
            return;
         end if;
         Generator.Set_Result_Directory (Target_Dir);
      end;

      --  Read the package description.
      declare
         Package_File : constant String := Get_Argument;
      begin
         if Package_File'Length > 0 then
            Gen.Generator.Read_Package (Generator, Package_File);
         else
            Gen.Generator.Read_Package (Generator, "package.xml");
         end if;
      end;

      --  Run the generation.
      Gen.Generator.Prepare (Generator);
      Gen.Generator.Generate_All (Generator);
      Gen.Generator.Finish (Generator);
   end Execute;

   --  ------------------------------
   --  Write the help associated with the command.
   --  ------------------------------
   procedure Help (Cmd       : in Command;
                   Generator : in out Gen.Generator.Handler) is
      pragma Unreferenced (Cmd, Generator);
      use Ada.Text_IO;
   begin
      Put_Line ("dist: Build the distribution files to prepare the server installation");
      Put_Line ("Usage: dist target-dir [package.xml]");
      New_Line;
      Put_Line ("  The dist command reads the XML package description to build the"
                & " distribution tree.");
      Put_Line ("  This command is intended to be used after the project is built.  It prepares");
      Put_Line ("  the files for their installation on the target server in a "
                & "production environment.");
      Put_Line ("  The package.xml describes what files are necessary on the server.");
      Put_Line ("  It allows to make transformations such as compressing Javascript, CSS and "
                & "images");
   end Help;

end Gen.Commands.Distrib;

Fix the help documentation for the dist command


-----------------------------------------------------------------------
--  mat-readers-files -- Reader for files
--  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.Streams.Stream_IO;

with Util.Log.Loggers;
with MAT.Readers.Marshaller;
package body MAT.Readers.Streams.Files is

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

   BUFFER_SIZE  : constant Natural := 100 * 1024;

   --  Open the file.
   procedure Open (Reader : in out File_Reader_Type;
                   Path   : in String) is
   begin
      Log.Info ("Reading data stream {0}", Path);

      Reader.Stream.Initialize (Size   => BUFFER_SIZE,
                                Input  => Reader.File'Unchecked_Access,
                                Output => null);
      Reader.File.Open (Mode => Ada.Streams.Stream_IO.In_File,
                        Name => Path);
   end Open;

end MAT.Readers.Streams.Files;

-----------------------------------------------------------------------
--  mat-readers-files -- Reader for files
--  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.Streams.Stream_IO;

with Util.Log.Loggers;
package body MAT.Readers.Streams.Files is

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

   BUFFER_SIZE  : constant Natural := 100 * 1024;

   --  ------------------------------
   --  Open the file.
   --  ------------------------------
   procedure Open (Reader : in out File_Reader_Type;
                   Path   : in String) is
   begin
      Log.Info ("Reading data stream {0}", Path);

      Reader.Stream.Initialize (Size   => BUFFER_SIZE,
                                Input  => Reader.File'Unchecked_Access,
                                Output => null);
      Reader.File.Open (Mode => Ada.Streams.Stream_IO.In_File,
                        Name => Path);
   end Open;

end MAT.Readers.Streams.Files;

Fix compilation warnings

Fix compilation warnings


-----------------------------------------------------------------------
--  ADO Drivers -- Database Drivers
--  Copyright (C) 2010, 2011 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.Log.Loggers;

with Ada.IO_Exceptions;

with ADO.Queries.Loaders;
package body ADO.Drivers is

   use Util.Log;

   Log : constant Loggers.Logger := Loggers.Create ("ADO.Drivers");

   --  Global configuration properties (loaded by Initialize).
   Global_Config : Util.Properties.Manager;

   --  ------------------------------
   --  Initialize the drivers and the library by reading the property file
   --  and configure the runtime with it.
   --  ------------------------------
   procedure Initialize (Config : in String) is
   begin
      Log.Info ("Initialize using property file {0}", Config);

      begin
         Util.Properties.Load_Properties (Global_Config, Config);
      exception
         when Ada.IO_Exceptions.Name_Error =>
            Log.Error ("Configuration file '{0}' does not exist", Config);
      end;

      Initialize (Global_Config);
   end Initialize;

   --  ------------------------------
   --  Initialize the drivers and the library and configure the runtime with the given properties.
   --  ------------------------------
   procedure Initialize (Config : in Util.Properties.Manager'Class) is
   begin
      Global_Config := Util.Properties.Manager (Config);

      --  Configure the XML query loader.
      ADO.Queries.Loaders.Initialize (Global_Config.Get ("ado.queries.paths", ".;db"),
                                      Global_Config.Get ("ado.queries.load", "false") = "true");

      --  Initialize the drivers.
      ADO.Drivers.Initialize;
   end Initialize;

   --  ------------------------------
   --  Get the global configuration property identified by the name.
   --  If the configuration property does not exist, returns the default value.
   --  ------------------------------
   function Get_Config (Name    : in String;
                        Default : in String := "") return String is
   begin
      return Global_Config.Get (Name, Default);
   end Get_Config;

   --  Initialize the drivers which are available.
   procedure Initialize is separate;

end ADO.Drivers;

-----------------------------------------------------------------------
--  ADO Drivers -- Database Drivers
--  Copyright (C) 2010, 2011, 2012, 2013 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.Log.Loggers;

with Ada.IO_Exceptions;
with ADO.Queries.Loaders;
package body ADO.Drivers is

   use Util.Log;

   Log : constant Loggers.Logger := Loggers.Create ("ADO.Drivers");

   --  Global configuration properties (loaded by Initialize).
   Global_Config : Util.Properties.Manager;

   --  ------------------------------
   --  Initialize the drivers and the library by reading the property file
   --  and configure the runtime with it.
   --  ------------------------------
   procedure Initialize (Config : in String) is
   begin
      Log.Info ("Initialize using property file {0}", Config);

      begin
         Util.Properties.Load_Properties (Global_Config, Config);
      exception
         when Ada.IO_Exceptions.Name_Error =>
            Log.Error ("Configuration file '{0}' does not exist", Config);
      end;

      Initialize (Global_Config);
   end Initialize;

   --  ------------------------------
   --  Initialize the drivers and the library and configure the runtime with the given properties.
   --  ------------------------------
   procedure Initialize (Config : in Util.Properties.Manager'Class) is
   begin
      Global_Config := Util.Properties.Manager (Config);

      --  Configure the XML query loader.
      ADO.Queries.Loaders.Initialize (Global_Config.Get ("ado.queries.paths", ".;db"),
                                      Global_Config.Get ("ado.queries.load", "false") = "true");
   end Initialize;

   --  ------------------------------
   --  Get the global configuration property identified by the name.
   --  If the configuration property does not exist, returns the default value.
   --  ------------------------------
   function Get_Config (Name    : in String;
                        Default : in String := "") return String is
   begin
      return Global_Config.Get (Name, Default);
   end Get_Config;

end ADO.Drivers;

Move the initialization in a separate library


-----------------------------------------------------------------------
--  asf-streams -- Print streams for servlets
--  Copyright (C) 2010, 2011, 2012, 2013 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.Streams;
with Ada.Strings.Unbounded;
with Ada.Strings.Wide_Wide_Unbounded;
with Ada.Finalization;

with Util.Streams;
with Util.Streams.Texts;
with EL.Objects;
package ASF.Streams is

--     pragma Preelaborate;

   --  -----------------------
   --  Print stream
   --  -----------------------
   --  The <b>Print_Stream</b> is an output stream which provides helper methods
   --  for writing text streams.
   type Print_Stream is new Ada.Finalization.Limited_Controlled
     and Util.Streams.Output_Stream with private;

   procedure Initialize (Stream : in out Print_Stream;
                         To     : in Util.Streams.Texts.Print_Stream_Access);

   --  Initialize the stream
   procedure Initialize (Stream : in out Print_Stream;
                         To     : in Print_Stream'Class);

   --  Write an integer on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Item   : in Integer);

   --  Write a string on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Item   : in Ada.Strings.Unbounded.Unbounded_String);

   --  Write a string on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Item   : in Ada.Strings.Wide_Wide_Unbounded.Unbounded_Wide_Wide_String);

   --  Write a raw character on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Char   : in Character);

   --  Write a raw string on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Item   : in String);

   --  Write a raw string on the stream.
   procedure Write_Wide (Stream : in out Print_Stream;
                         Item   : in Wide_Wide_String);

   --  Write the object converted into a string on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Item   : in EL.Objects.Object);

   --  Write the buffer array to the output stream.
   procedure Write (Stream : in out Print_Stream;
                    Buffer : in Ada.Streams.Stream_Element_Array);

   --  Flush the buffer by writing on the output stream.
   --  Raises Data_Error if there is no output stream.
   procedure Flush (Stream : in out Print_Stream);

   --  Write into the text stream.
   procedure Write (Stream : in out Print_Stream;
                    Print  : access procedure
                      (Into : in out Util.Streams.Texts.Print_Stream'Class));

   --  Close the text stream.
   overriding
   procedure Close (Stream : in out Print_Stream);

private

   type Print_Stream is new Ada.Finalization.Limited_Controlled
     and Util.Streams.Output_Stream with record
      Target : Util.Streams.Texts.Print_Stream_Access;
   end record;

end ASF.Streams;

-----------------------------------------------------------------------
--  asf-streams -- Print streams for servlets
--  Copyright (C) 2010, 2011, 2012, 2013, 2017 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.Streams;
with Ada.Strings.Unbounded;
with Ada.Strings.Wide_Wide_Unbounded;
with Ada.Finalization;

with Util.Streams;
with Util.Streams.Texts;
with Util.Streams.Buffered;
with EL.Objects;
package ASF.Streams is

   subtype Input_Stream is Util.Streams.Buffered.Buffered_Stream;
   type Input_Stream_Access is access all Input_Stream'Class;

   --  -----------------------
   --  Print stream
   --  -----------------------
   --  The <b>Print_Stream</b> is an output stream which provides helper methods
   --  for writing text streams.
   type Print_Stream is new Ada.Finalization.Limited_Controlled
     and Util.Streams.Output_Stream with private;

   procedure Initialize (Stream : in out Print_Stream;
                         To     : in Util.Streams.Texts.Print_Stream_Access);

   --  Initialize the stream
   procedure Initialize (Stream : in out Print_Stream;
                         To     : in Print_Stream'Class);

   --  Write an integer on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Item   : in Integer);

   --  Write a string on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Item   : in Ada.Strings.Unbounded.Unbounded_String);

   --  Write a string on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Item   : in Ada.Strings.Wide_Wide_Unbounded.Unbounded_Wide_Wide_String);

   --  Write a raw character on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Char   : in Character);

   --  Write a raw string on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Item   : in String);

   --  Write a raw string on the stream.
   procedure Write_Wide (Stream : in out Print_Stream;
                         Item   : in Wide_Wide_String);

   --  Write the object converted into a string on the stream.
   procedure Write (Stream : in out Print_Stream;
                    Item   : in EL.Objects.Object);

   --  Write the buffer array to the output stream.
   procedure Write (Stream : in out Print_Stream;
                    Buffer : in Ada.Streams.Stream_Element_Array);

   --  Flush the buffer by writing on the output stream.
   --  Raises Data_Error if there is no output stream.
   procedure Flush (Stream : in out Print_Stream);

   --  Write into the text stream.
   procedure Write (Stream : in out Print_Stream;
                    Print  : access procedure
                      (Into : in out Util.Streams.Texts.Print_Stream'Class));

   --  Close the text stream.
   overriding
   procedure Close (Stream : in out Print_Stream);

private

   type Print_Stream is new Ada.Finalization.Limited_Controlled
     and Util.Streams.Output_Stream with record
      Target : Util.Streams.Texts.Print_Stream_Access;
   end record;

end ASF.Streams;

Declare the Input_Stream and Input_Stream_Access types