xia_1.4.0_b16bb5ce/src/mckae-xml-xpath-locations.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
-------------------------------------------------------------------------------
--                                                                           --
--            XPATH IN ADA Copyright (C) 2003, McKae Technologies            --
--     XPATH IN ADA Copyright (C) 2021, Simon Wright <simon@pushface.org>    --
--                                                                           --
--  XPath in  Ada (XIA) is  free software;  you can redistribute  it and/or  --
--  modify it under terms of the GNU General Public License as published by  --
--  the Free Software Foundation; either version 3, or (at your option) any  --
--  later version.  GNAT is distributed in the hope that it will be useful,  --
--  but  WITHOUT  ANY  WARRANTY;  without  even  the  implied  warranty  of  --
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                     --
--                                                                           --
--  As  a special  exception under  Section  7 of  GPL version  3, you  are  --
--  granted  additional permissions  described in  the GCC  Runtime Library  --
--  Exception, version 3.1, as published by the Free Software Foundation.    --
--                                                                           --
--  You should have received a copy of the GNU General Public License and a  --
--  copy of the GCC Runtime Library  Exception along with this program; see  --
--  the  files  COPYING3 and  COPYING.RUNTIME  respectively.   If not,  see  --
--  <http://www.gnu.org/licenses/>.                                          --
--                                                                           --
--  XIA is maintained at https://github.com/simonjwright/xia                 --
--                                                                           --
-------------------------------------------------------------------------------

with Unchecked_Deallocation;

with Ada.Text_IO;

package body Mckae.XML.XPath.Locations is

   use McKae.XML.XPath;

   Parsing_Path : Location_Paths;

   Accumulating_Predicate : Boolean := False;

   function "-" (L : Ada.Strings.Unbounded.Unbounded_String) return String
     renames Ada.Strings.Unbounded.To_String;

   --  In Ada2020, we could just use Object'Image.
   function Image (Object : Node_Test_Specification) return String
   is
   begin
      return "test: " & Object.Node_Test'Image
        & ", name: " & (-Object.Name)
        & (if Object.Node_Test = QName_Node_Test
           then ", prefix: " & (-Object.Prefix)
           else "");
   end Image;

   --  In Ada2020, we could just use Object'Image.
   function Image (Object : Location_Steps) return String
   is
   begin
      return "step:"
        & " axis: " & Object.Axis'Image
        & ", " & Image (Object.Node_Test)
        & ", output: " & Object.Output_Step'Image;
      --  predicates TBD
   end Image;

   --  In Ada2020, we could just use Object'Image.
   function Image (Object : Location_Paths) return String
   is
      function List
        (Component : Location_Steps_Management.Cursor) return String
      is
         use Location_Steps_Management;
      begin
         return (if Component = No_Element
                 then ""
                 else ASCII.LF & " " & Image (Element (Component))
                    & List (Next (Component)));
      end List;
      use type Ada.Containers.Count_Type;
   begin
      return "path ("
        & (if Object.Absolute then "absolute" else "relative")
        & ")"
        & List (Object.Path.First);
   end Image;

   procedure Add (Location_Step : in Location_Steps)
   is
      pragma Debug
        (Ada.Text_IO.Put_Line ("adding " & Image (Location_Step)));
      pragma Assert (Location_Step.Node_Test.Node_Test /= No_Node_Test);
      Step : Location_Steps := Location_Step;
   begin
      if not Step.Location_Predicates.Is_Empty then
         pragma Debug
           (Ada.Text_IO.Put_Line ("! suppressing predicates"));
         Step.Location_Predicates.Clear;
      end if;
      if Accumulating_Predicate
      then
         null;
         pragma Debug
           (Ada.Text_IO.Put_Line (".. skipping"));
      else
         Parsing_Path.Path.Append (Step);
      end if;
   end Add;

   procedure Add_Predicate (Predicate : Xpath_Model.Parseable_Ptr)
   is
      pragma Assert (Accumulating_Predicate);
   begin
      pragma Debug (Ada.Text_IO.Put_Line ("adding predicate"));
      declare
         procedure Add_Predicates (Element : in out Location_Steps) is
         begin
            Element.Location_Predicates.Append (Predicate);
         end Add_Predicates;
      begin
         Parsing_Path.Path.Update_Element
           (Position => Parsing_Path.Path.Last,
            Process => Add_Predicates'Access);
      end;
      pragma Debug
        (Ada.Text_IO.Put_Line
           ("updated predicates: " & Image (Parsing_Path.Path.Last_Element)));
   end Add_Predicate;

   procedure Begin_Predicate is
   begin
      pragma Debug (Ada.Text_IO.Put_Line ("beginning predicate acumulation"));
      pragma Assert (not Accumulating_Predicate);
      Accumulating_Predicate := True;
   end Begin_Predicate;

   procedure End_Predicate
   is
      use type Ada.Containers.Count_Type;
   begin
      pragma Debug (Ada.Text_IO.Put_Line ("ending predicate accumulation"));
      pragma Assert (Accumulating_Predicate);
      Accumulating_Predicate := False;
   end End_Predicate;

   procedure Free (Location_Path : in out Location_Paths) is
      Step : Location_Steps;
   begin
      for Step of Location_Path.Path loop
         Predicates.Release (Step.Location_Predicates);
      end loop;
      Location_Path.Path.Clear;
   end Free;

   function Get_Path return Location_Paths
   is
   begin
      return Parsing_Path;
   end Get_Path;

   procedure Reset_For_Parsing
   is
   begin
      Parsing_Path := (Absolute => False,
                       Path     => <>);
   end Reset_For_Parsing;

end Mckae.XML.XPath.Locations;