1 -----------------------------------------------------------------------------
2 -- GNAT COMPILER COMPONENTS --
4 -- G N A T . R E W R I T E _ D A T A --
8 -- Copyright (C) 2014, Free Software Foundation, Inc. --
10 -- GNAT is free software; you can redistribute it and/or modify it under --
11 -- terms of the GNU General Public License as published by the Free Soft- --
12 -- ware Foundation; either version 3, or (at your option) any later ver- --
13 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
14 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
15 -- or FITNESS FOR A PARTICULAR PURPOSE. --
17 -- As a special exception under Section 7 of GPL version 3, you are granted --
18 -- additional permissions described in the GCC Runtime Library Exception, --
19 -- version 3.1, as published by the Free Software Foundation. --
21 -- You should have received a copy of the GNU General Public License and --
22 -- a copy of the GCC Runtime Library Exception along with this program; --
23 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
24 -- <http://www.gnu.org/licenses/>. --
26 -- GNAT was originally developed by the GNAT team at New York University. --
27 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 ------------------------------------------------------------------------------
31 with Ada
.Unchecked_Conversion
;
33 package body GNAT
.Rewrite_Data
is
37 subtype SEO
is Stream_Element_Offset
;
41 Data
: Stream_Element_Array
;
42 Output
: not null access procedure (Data
: Stream_Element_Array
));
43 -- Do the actual output. This ensures that we properly send the data
44 -- through linked rewrite buffers if any.
51 (Pattern
, Value
: String;
52 Size
: Stream_Element_Offset
:= 1_024
) return Buffer
55 subtype SP
is String (1 .. Pattern
'Length);
56 subtype SEAP
is Stream_Element_Array
(1 .. Pattern
'Length);
58 subtype SV
is String (1 .. Value
'Length);
59 subtype SEAV
is Stream_Element_Array
(1 .. Value
'Length);
61 function To_SEAP
is new Unchecked_Conversion
(SP
, SEAP
);
62 function To_SEAV
is new Unchecked_Conversion
(SV
, SEAV
);
65 -- Return result (can't be smaller than pattern)
68 (SEO
'Max (Size
, SEO
(Pattern
'Length)),
72 B
.Pattern
:= To_SEAP
(Pattern
);
73 B
.Value
:= To_SEAV
(Value
);
85 Data
: Stream_Element_Array
;
86 Output
: not null access procedure (Data
: Stream_Element_Array
))
92 Write
(B
.Next
.all, Data
, Output
);
102 Output
: not null access procedure (Data
: Stream_Element_Array
))
105 -- Flush output buffer
108 Do_Output
(B
, B
.Buffer
(1 .. B
.Pos_B
), Output
);
111 -- Flush current buffer
114 Do_Output
(B
, B
.Current
(1 .. B
.Pos_C
), Output
);
117 -- Flush linked buffer if any
119 if B
.Next
/= null then
120 Flush
(B
.Next
.all, Output
);
130 procedure Link
(From
: in out Buffer
; To
: Buffer_Ref
) is
139 procedure Reset
(B
: in out Buffer
) is
144 if B
.Next
/= null then
155 Input
: not null access procedure
156 (Buffer
: out Stream_Element_Array
;
157 Last
: out Stream_Element_Offset
);
158 Output
: not null access procedure (Data
: Stream_Element_Array
))
160 Buffer
: Stream_Element_Array
(1 .. B
.Size
);
161 Last
: Stream_Element_Offset
;
165 Input
(Buffer
, Last
);
166 exit Rewrite_All
when Last
= 0;
167 Write
(B
, Buffer
(1 .. Last
), Output
);
168 end loop Rewrite_All
;
177 function Size
(B
: Buffer
) return Natural is
179 return Natural (B
.Pos_B
+ B
.Pos_C
);
188 Data
: Stream_Element_Array
;
189 Output
: not null access procedure (Data
: Stream_Element_Array
))
191 procedure Need_Space
(Size
: Stream_Element_Offset
);
192 pragma Inline
(Need_Space
);
198 procedure Need_Space
(Size
: Stream_Element_Offset
) is
200 if B
.Pos_B
+ Size
> B
.Size
then
201 Do_Output
(B
, B
.Buffer
(1 .. B
.Pos_B
), Output
);
206 -- Start of processing for Write
209 if B
.Size_Pattern
= 0 then
210 Do_Output
(B
, Data
, Output
);
213 for K
in Data
'Range loop
214 if Data
(K
) = B
.Pattern
(B
.Pos_C
+ 1) then
216 -- Store possible start of a match
218 B
.Pos_C
:= B
.Pos_C
+ 1;
219 B
.Current
(B
.Pos_C
) := Data
(K
);
222 -- Not part of pattern, if a start of a match was found,
226 Need_Space
(B
.Pos_C
);
228 B
.Buffer
(B
.Pos_B
+ 1 .. B
.Pos_B
+ B
.Pos_C
) :=
229 B
.Current
(1 .. B
.Pos_C
);
230 B
.Pos_B
:= B
.Pos_B
+ B
.Pos_C
;
235 B
.Pos_B
:= B
.Pos_B
+ 1;
236 B
.Buffer
(B
.Pos_B
) := Data
(K
);
239 if B
.Pos_C
= B
.Size_Pattern
then
241 -- The pattern is found
243 Need_Space
(B
.Size_Value
);
245 B
.Buffer
(B
.Pos_B
+ 1 .. B
.Pos_B
+ B
.Size_Value
) := B
.Value
;
247 B
.Pos_B
:= B
.Pos_B
+ B
.Size_Value
;
253 end GNAT
.Rewrite_Data
;