1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2000-2011, AdaCore --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
30 ------------------------------------------------------------------------------
34 with Ada
.Strings
.Unbounded
;
35 with Ada
.Strings
.Fixed
;
36 with Ada
.Strings
.Maps
;
37 with Ada
.Unchecked_Deallocation
;
39 with GNAT
.Directory_Operations
;
40 with GNAT
.Dynamic_Tables
;
43 package body GNAT
.AWK
is
46 use Ada
.Strings
.Unbounded
;
48 -----------------------
49 -- Local subprograms --
50 -----------------------
52 -- The following two subprograms provide a functional interface to the
53 -- two special session variables, that are manipulated explicitly by
54 -- Finalize, but must be declared after Finalize to prevent static
55 -- elaboration warnings.
57 function Get_Def
return Session_Data_Access
;
66 type Mode
is abstract tagged null record;
67 -- This is the main type which is declared abstract. This type must be
68 -- derived for each split style.
70 type Mode_Access
is access Mode
'Class;
72 procedure Current_Line
(S
: Mode
; Session
: Session_Type
)
74 -- Split current line of Session using split mode S
76 ------------------------
77 -- Split on separator --
78 ------------------------
80 type Separator
(Size
: Positive) is new Mode
with record
81 Separators
: String (1 .. Size
);
84 procedure Current_Line
86 Session
: Session_Type
);
92 type Column
(Size
: Positive) is new Mode
with record
93 Columns
: Widths_Set
(1 .. Size
);
96 procedure Current_Line
(S
: Column
; Session
: Session_Type
);
100 procedure Free
is new Unchecked_Deallocation
101 (Split
.Mode
'Class, Split
.Mode_Access
);
107 type AWK_File
is access String;
109 package File_Table
is
110 new Dynamic_Tables
(AWK_File
, Natural, 1, 5, 50);
111 -- List of file names associated with a Session
113 procedure Free
is new Unchecked_Deallocation
(String, AWK_File
);
119 type Field_Slice
is record
123 -- This is a field slice (First .. Last) in session's current line
125 package Field_Table
is
126 new Dynamic_Tables
(Field_Slice
, Natural, 1, 10, 100);
127 -- List of fields for the current line
133 -- Define all patterns style: exact string, regular expression, boolean
138 type Pattern
is abstract tagged null record;
139 -- This is the main type which is declared abstract. This type must be
140 -- derived for each patterns style.
142 type Pattern_Access
is access Pattern
'Class;
146 Session
: Session_Type
) return Boolean
148 -- Returns True if P match for the current session and False otherwise
150 procedure Release
(P
: in out Pattern
);
151 -- Release memory used by the pattern structure
153 --------------------------
154 -- Exact string pattern --
155 --------------------------
157 type String_Pattern
is new Pattern
with record
158 Str
: Unbounded_String
;
164 Session
: Session_Type
) return Boolean;
166 --------------------------------
167 -- Regular expression pattern --
168 --------------------------------
170 type Pattern_Matcher_Access
is access Regpat
.Pattern_Matcher
;
172 type Regexp_Pattern
is new Pattern
with record
173 Regx
: Pattern_Matcher_Access
;
179 Session
: Session_Type
) return Boolean;
181 procedure Release
(P
: in out Regexp_Pattern
);
183 ------------------------------
184 -- Boolean function pattern --
185 ------------------------------
187 type Callback_Pattern
is new Pattern
with record
188 Pattern
: Pattern_Callback
;
192 (P
: Callback_Pattern
;
193 Session
: Session_Type
) return Boolean;
197 procedure Free
is new Unchecked_Deallocation
198 (Patterns
.Pattern
'Class, Patterns
.Pattern_Access
);
204 -- Define all action style : simple call, call with matches
208 type Action
is abstract tagged null record;
209 -- This is the main type which is declared abstract. This type must be
210 -- derived for each action style.
212 type Action_Access
is access Action
'Class;
216 Session
: Session_Type
) is abstract;
217 -- Call action A as required
223 type Simple_Action
is new Action
with record
224 Proc
: Action_Callback
;
229 Session
: Session_Type
);
231 -------------------------
232 -- Action with matches --
233 -------------------------
235 type Match_Action
is new Action
with record
236 Proc
: Match_Action_Callback
;
241 Session
: Session_Type
);
245 procedure Free
is new Unchecked_Deallocation
246 (Actions
.Action
'Class, Actions
.Action_Access
);
248 --------------------------
249 -- Pattern/Action table --
250 --------------------------
252 type Pattern_Action
is record
253 Pattern
: Patterns
.Pattern_Access
; -- If Pattern is True
254 Action
: Actions
.Action_Access
; -- Action will be called
257 package Pattern_Action_Table
is
258 new Dynamic_Tables
(Pattern_Action
, Natural, 1, 5, 50);
264 type Session_Data
is record
265 Current_File
: Text_IO
.File_Type
;
266 Current_Line
: Unbounded_String
;
267 Separators
: Split
.Mode_Access
;
268 Files
: File_Table
.Instance
;
269 File_Index
: Natural := 0;
270 Fields
: Field_Table
.Instance
;
271 Filters
: Pattern_Action_Table
.Instance
;
274 Matches
: Regpat
.Match_Array
(0 .. 100);
275 -- Latest matches for the regexp pattern
279 new Unchecked_Deallocation
(Session_Data
, Session_Data_Access
);
285 procedure Finalize
(Session
: in out Session_Type
) is
287 -- We release the session data only if it is not the default session
289 if Session
.Data
/= Get_Def
then
290 -- Release separators
292 Free
(Session
.Data
.Separators
);
296 -- Since we have closed the current session, set it to point now to
297 -- the default session.
307 procedure Initialize
(Session
: in out Session_Type
) is
309 Session
.Data
:= new Session_Data
;
311 -- Initialize separators
313 Session
.Data
.Separators
:=
314 new Split
.Separator
'(Default_Separators'Length, Default_Separators);
316 -- Initialize all tables
318 File_Table.Init (Session.Data.Files);
319 Field_Table.Init (Session.Data.Fields);
320 Pattern_Action_Table.Init (Session.Data.Filters);
323 -----------------------
324 -- Session Variables --
325 -----------------------
327 Def_Session : Session_Type;
328 Cur_Session : Session_Type;
330 ----------------------
331 -- Private Services --
332 ----------------------
334 function Always_True return Boolean;
335 -- A function that always returns True
337 function Apply_Filters
338 (Session : Session_Type) return Boolean;
339 -- Apply any filters for which the Pattern is True for Session. It returns
340 -- True if a least one filters has been applied (i.e. associated action
341 -- callback has been called).
343 procedure Open_Next_File
344 (Session : Session_Type);
345 pragma Inline (Open_Next_File);
346 -- Open next file for Session closing current file if needed. It raises
347 -- End_Error if there is no more file in the table.
349 procedure Raise_With_Info
350 (E : Exceptions.Exception_Id;
352 Session : Session_Type);
353 pragma No_Return (Raise_With_Info);
354 -- Raises exception E with the message prepended with the current line
355 -- number and the filename if possible.
357 procedure Read_Line (Session : Session_Type);
358 -- Read a line for the Session and set Current_Line
360 procedure Split_Line (Session : Session_Type);
361 -- Split session's Current_Line according to the session separators and
362 -- set the Fields table. This procedure can be called at any time.
364 ----------------------
365 -- Private Packages --
366 ----------------------
372 package body Actions is
380 Session : Session_Type)
382 pragma Unreferenced (Session);
393 Session : Session_Type)
396 A.Proc (Session.Data.Matches);
405 package body Patterns is
413 Session : Session_Type) return Boolean
416 return P.Str = Field (P.Rank, Session);
425 Session : Session_Type) return Boolean
427 use type Regpat.Match_Location;
430 (P.Regx.all, Field (P.Rank, Session), Session.Data.Matches);
431 return Session.Data.Matches (0) /= Regpat.No_Match;
439 (P : Callback_Pattern;
440 Session : Session_Type) return Boolean
442 pragma Unreferenced (Session);
444 return P.Pattern.all;
451 procedure Release (P : in out Pattern) is
452 pragma Unreferenced (P);
461 procedure Release (P : in out Regexp_Pattern) is
462 procedure Free is new Unchecked_Deallocation
463 (Regpat.Pattern_Matcher, Pattern_Matcher_Access);
474 package body Split is
482 procedure Current_Line (S : Separator; Session : Session_Type) is
483 Line : constant String := To_String (Session.Data.Current_Line);
484 Fields : Field_Table.Instance renames Session.Data.Fields;
485 Seps : constant Maps.Character_Set := Maps.To_Set (S.Separators);
491 -- First field start here
495 -- Record the first field start position which is the first character
498 Field_Table.Increment_Last (Fields);
499 Fields.Table (Field_Table.Last (Fields)).First := Start;
502 -- Look for next separator
505 (Source => Line (Start .. Line'Last),
510 Fields.Table (Field_Table.Last (Fields)).Last := Stop - 1;
512 -- If separators are set to the default (space and tab) we skip
513 -- all spaces and tabs following current field.
515 if S.Separators = Default_Separators then
517 (Line (Stop + 1 .. Line'Last),
518 Maps.To_Set (Default_Separators),
530 -- Record in the field table the start of this new field
532 Field_Table.Increment_Last (Fields);
533 Fields.Table (Field_Table.Last (Fields)).First := Start;
537 Fields.Table (Field_Table.Last (Fields)).Last := Line'Last;
544 procedure Current_Line (S : Column; Session : Session_Type) is
545 Line : constant String := To_String (Session.Data.Current_Line);
546 Fields : Field_Table.Instance renames Session.Data.Fields;
547 Start : Positive := Line'First;
550 -- Record the first field start position which is the first character
553 for C in 1 .. S.Columns'Length loop
555 Field_Table.Increment_Last (Fields);
557 Fields.Table (Field_Table.Last (Fields)).First := Start;
559 Start := Start + S.Columns (C);
561 Fields.Table (Field_Table.Last (Fields)).Last := Start - 1;
565 -- If there is some remaining character on the line, add them in a
568 if Start - 1 < Line'Length then
570 Field_Table.Increment_Last (Fields);
572 Fields.Table (Field_Table.Last (Fields)).First := Start;
574 Fields.Table (Field_Table.Last (Fields)).Last := Line'Last;
586 Session : Session_Type)
588 Files : File_Table.Instance renames Session.Data.Files;
591 if OS_Lib.Is_Regular_File (Filename) then
592 File_Table.Increment_Last (Files);
593 Files.Table (File_Table.Last (Files)) := new String'(Filename
);
596 (File_Error
'Identity,
597 "File " & Filename
& " not found.",
607 Add_File
(Filename
, Cur_Session
);
617 Number_Of_Files_Added
: out Natural;
618 Session
: Session_Type
)
620 use Directory_Operations
;
623 Filename
: String (1 .. 200);
627 Number_Of_Files_Added
:= 0;
629 Open
(Dir
, Directory
);
632 Read
(Dir
, Filename
, Last
);
635 Add_File
(Filename
(1 .. Last
), Session
);
636 Number_Of_Files_Added
:= Number_Of_Files_Added
+ 1;
644 (File_Error
'Identity,
645 "Error scanning directory " & Directory
646 & " for files " & Filenames
& '.',
653 Number_Of_Files_Added
: out Natural)
657 Add_Files
(Directory
, Filenames
, Number_Of_Files_Added
, Cur_Session
);
664 function Always_True
return Boolean is
673 function Apply_Filters
674 (Session
: Session_Type
) return Boolean
676 Filters
: Pattern_Action_Table
.Instance
renames Session
.Data
.Filters
;
677 Results
: Boolean := False;
680 -- Iterate through the filters table, if pattern match call action
682 for F
in 1 .. Pattern_Action_Table
.Last
(Filters
) loop
683 if Patterns
.Match
(Filters
.Table
(F
).Pattern
.all, Session
) then
685 Actions
.Call
(Filters
.Table
(F
).Action
.all, Session
);
696 procedure Close
(Session
: Session_Type
) is
697 Filters
: Pattern_Action_Table
.Instance
renames Session
.Data
.Filters
;
698 Files
: File_Table
.Instance
renames Session
.Data
.Files
;
701 -- Close current file if needed
703 if Text_IO
.Is_Open
(Session
.Data
.Current_File
) then
704 Text_IO
.Close
(Session
.Data
.Current_File
);
707 -- Release Filters table
709 for F
in 1 .. Pattern_Action_Table
.Last
(Filters
) loop
710 Patterns
.Release
(Filters
.Table
(F
).Pattern
.all);
711 Free
(Filters
.Table
(F
).Pattern
);
712 Free
(Filters
.Table
(F
).Action
);
715 for F
in 1 .. File_Table
.Last
(Files
) loop
716 Free
(Files
.Table
(F
));
719 File_Table
.Set_Last
(Session
.Data
.Files
, 0);
720 Field_Table
.Set_Last
(Session
.Data
.Fields
, 0);
721 Pattern_Action_Table
.Set_Last
(Session
.Data
.Filters
, 0);
723 Session
.Data
.NR
:= 0;
724 Session
.Data
.FNR
:= 0;
725 Session
.Data
.File_Index
:= 0;
726 Session
.Data
.Current_Line
:= Null_Unbounded_String
;
729 ---------------------
730 -- Current_Session --
731 ---------------------
733 function Current_Session
return not null access Session_Type
is
735 return Cur_Session
.Self
;
738 ---------------------
739 -- Default_Session --
740 ---------------------
742 function Default_Session
return not null access Session_Type
is
744 return Def_Session
.Self
;
751 function Discrete_Field
753 Session
: Session_Type
) return Discrete
756 return Discrete
'Value (Field
(Rank
, Session
));
759 function Discrete_Field_Current_Session
760 (Rank
: Count
) return Discrete
is
761 function Do_It
is new Discrete_Field
(Discrete
);
763 return Do_It
(Rank
, Cur_Session
);
764 end Discrete_Field_Current_Session
;
771 (Session
: Session_Type
) return Boolean
774 return Session
.Data
.File_Index
= File_Table
.Last
(Session
.Data
.Files
)
775 and then End_Of_File
(Session
);
782 return End_Of_Data
(Cur_Session
);
790 (Session
: Session_Type
) return Boolean
793 return Text_IO
.End_Of_File
(Session
.Data
.Current_File
);
800 return End_Of_File
(Cur_Session
);
809 Session
: Session_Type
) return String
811 Fields
: Field_Table
.Instance
renames Session
.Data
.Fields
;
814 if Rank
> Number_Of_Fields
(Session
) then
816 (Field_Error
'Identity,
817 "Field number" & Count
'Image (Rank
) & " does not exist.",
822 -- Returns the whole line, this is what $0 does under Session_Type
824 return To_String
(Session
.Data
.Current_Line
);
827 return Slice
(Session
.Data
.Current_Line
,
828 Fields
.Table
(Positive (Rank
)).First
,
829 Fields
.Table
(Positive (Rank
)).Last
);
834 (Rank
: Count
) return String
837 return Field
(Rank
, Cur_Session
);
842 Session
: Session_Type
) return Integer
845 return Integer'Value (Field
(Rank
, Session
));
848 when Constraint_Error
=>
850 (Field_Error
'Identity,
851 "Field number" & Count
'Image (Rank
)
852 & " cannot be converted to an integer.",
857 (Rank
: Count
) return Integer
860 return Field
(Rank
, Cur_Session
);
865 Session
: Session_Type
) return Float
868 return Float'Value (Field
(Rank
, Session
));
871 when Constraint_Error
=>
873 (Field_Error
'Identity,
874 "Field number" & Count
'Image (Rank
)
875 & " cannot be converted to a float.",
880 (Rank
: Count
) return Float
883 return Field
(Rank
, Cur_Session
);
891 (Session
: Session_Type
) return String
893 Files
: File_Table
.Instance
renames Session
.Data
.Files
;
896 if Session
.Data
.File_Index
= 0 then
899 return Files
.Table
(Session
.Data
.File_Index
).all;
907 return File
(Cur_Session
);
914 procedure For_Every_Line
915 (Separators
: String := Use_Current
;
916 Filename
: String := Use_Current
;
917 Callbacks
: Callback_Mode
:= None
;
918 Session
: Session_Type
)
923 Open
(Separators
, Filename
, Session
);
925 while not End_Of_Data
(Session
) loop
927 Split_Line
(Session
);
929 if Callbacks
in Only
.. Pass_Through
then
932 pragma Unreferenced
(Discard
);
934 Discard
:= Apply_Filters
(Session
);
938 if Callbacks
/= Only
then
948 procedure For_Every_Line_Current_Session
949 (Separators
: String := Use_Current
;
950 Filename
: String := Use_Current
;
951 Callbacks
: Callback_Mode
:= None
)
953 procedure Do_It
is new For_Every_Line
(Action
);
955 Do_It
(Separators
, Filename
, Callbacks
, Cur_Session
);
956 end For_Every_Line_Current_Session
;
963 (Callbacks
: Callback_Mode
:= None
;
964 Session
: Session_Type
)
966 Filter_Active
: Boolean;
969 if not Text_IO
.Is_Open
(Session
.Data
.Current_File
) then
975 Split_Line
(Session
);
983 Filter_Active
:= Apply_Filters
(Session
);
984 exit when not Filter_Active
;
987 Filter_Active
:= Apply_Filters
(Session
);
995 (Callbacks
: Callback_Mode
:= None
)
998 Get_Line
(Callbacks
, Cur_Session
);
1001 ----------------------
1002 -- Number_Of_Fields --
1003 ----------------------
1005 function Number_Of_Fields
1006 (Session
: Session_Type
) return Count
1009 return Count
(Field_Table
.Last
(Session
.Data
.Fields
));
1010 end Number_Of_Fields
;
1012 function Number_Of_Fields
1016 return Number_Of_Fields
(Cur_Session
);
1017 end Number_Of_Fields
;
1019 --------------------------
1020 -- Number_Of_File_Lines --
1021 --------------------------
1023 function Number_Of_File_Lines
1024 (Session
: Session_Type
) return Count
1027 return Count
(Session
.Data
.FNR
);
1028 end Number_Of_File_Lines
;
1030 function Number_Of_File_Lines
1034 return Number_Of_File_Lines
(Cur_Session
);
1035 end Number_Of_File_Lines
;
1037 ---------------------
1038 -- Number_Of_Files --
1039 ---------------------
1041 function Number_Of_Files
1042 (Session
: Session_Type
) return Natural
1044 Files
: File_Table
.Instance
renames Session
.Data
.Files
;
1046 return File_Table
.Last
(Files
);
1047 end Number_Of_Files
;
1049 function Number_Of_Files
1053 return Number_Of_Files
(Cur_Session
);
1054 end Number_Of_Files
;
1056 ---------------------
1057 -- Number_Of_Lines --
1058 ---------------------
1060 function Number_Of_Lines
1061 (Session
: Session_Type
) return Count
1064 return Count
(Session
.Data
.NR
);
1065 end Number_Of_Lines
;
1067 function Number_Of_Lines
1071 return Number_Of_Lines
(Cur_Session
);
1072 end Number_Of_Lines
;
1079 (Separators
: String := Use_Current
;
1080 Filename
: String := Use_Current
;
1081 Session
: Session_Type
)
1084 if Text_IO
.Is_Open
(Session
.Data
.Current_File
) then
1085 raise Session_Error
;
1088 if Filename
/= Use_Current
then
1089 File_Table
.Init
(Session
.Data
.Files
);
1090 Add_File
(Filename
, Session
);
1093 if Separators
/= Use_Current
then
1094 Set_Field_Separators
(Separators
, Session
);
1097 Open_Next_File
(Session
);
1105 (Separators
: String := Use_Current
;
1106 Filename
: String := Use_Current
)
1109 Open
(Separators
, Filename
, Cur_Session
);
1112 --------------------
1113 -- Open_Next_File --
1114 --------------------
1116 procedure Open_Next_File
1117 (Session
: Session_Type
)
1119 Files
: File_Table
.Instance
renames Session
.Data
.Files
;
1122 if Text_IO
.Is_Open
(Session
.Data
.Current_File
) then
1123 Text_IO
.Close
(Session
.Data
.Current_File
);
1126 Session
.Data
.File_Index
:= Session
.Data
.File_Index
+ 1;
1128 -- If there are no mores file in the table, raise End_Error
1130 if Session
.Data
.File_Index
> File_Table
.Last
(Files
) then
1135 (File
=> Session
.Data
.Current_File
,
1136 Name
=> Files
.Table
(Session
.Data
.File_Index
).all,
1137 Mode
=> Text_IO
.In_File
);
1145 (Separators
: String := Use_Current
;
1146 Filename
: String := Use_Current
;
1147 Session
: Session_Type
)
1149 Filter_Active
: Boolean;
1150 pragma Unreferenced
(Filter_Active
);
1153 Open
(Separators
, Filename
, Session
);
1155 while not End_Of_Data
(Session
) loop
1156 Get_Line
(None
, Session
);
1157 Filter_Active
:= Apply_Filters
(Session
);
1164 (Separators
: String := Use_Current
;
1165 Filename
: String := Use_Current
)
1168 Parse
(Separators
, Filename
, Cur_Session
);
1171 ---------------------
1172 -- Raise_With_Info --
1173 ---------------------
1175 procedure Raise_With_Info
1176 (E
: Exceptions
.Exception_Id
;
1178 Session
: Session_Type
)
1180 function Filename
return String;
1181 -- Returns current filename and "??" if this information is not
1184 function Line
return String;
1185 -- Returns current line number without the leading space
1191 function Filename
return String is
1192 File
: constant String := AWK
.File
(Session
);
1205 function Line
return String is
1206 L
: constant String := Natural'Image (Session
.Data
.FNR
);
1208 return L
(2 .. L
'Last);
1211 -- Start of processing for Raise_With_Info
1214 Exceptions
.Raise_Exception
1216 '[' & Filename
& ':' & Line
& "] " & Message
);
1217 raise Constraint_Error
; -- to please GNAT as this is a No_Return proc
1218 end Raise_With_Info
;
1224 procedure Read_Line
(Session
: Session_Type
) is
1226 function Read_Line
return String;
1227 -- Read a line in the current file. This implementation is recursive
1228 -- and does not have a limitation on the line length.
1230 NR
: Natural renames Session
.Data
.NR
;
1231 FNR
: Natural renames Session
.Data
.FNR
;
1237 function Read_Line
return String is
1238 Buffer
: String (1 .. 1_024
);
1242 Text_IO
.Get_Line
(Session
.Data
.Current_File
, Buffer
, Last
);
1244 if Last
= Buffer
'Last then
1245 return Buffer
& Read_Line
;
1247 return Buffer
(1 .. Last
);
1251 -- Start of processing for Read_Line
1254 if End_Of_File
(Session
) then
1255 Open_Next_File
(Session
);
1259 Session
.Data
.Current_Line
:= To_Unbounded_String
(Read_Line
);
1272 Action
: Action_Callback
;
1273 Session
: Session_Type
)
1275 Filters
: Pattern_Action_Table
.Instance
renames Session
.Data
.Filters
;
1276 U_Pattern
: constant Unbounded_String
:= To_Unbounded_String
(Pattern
);
1279 Pattern_Action_Table
.Increment_Last
(Filters
);
1281 Filters
.Table
(Pattern_Action_Table
.Last
(Filters
)) :=
1282 (Pattern
=> new Patterns
.String_Pattern
'(U_Pattern, Field),
1283 Action => new Actions.Simple_Action'(Proc
=> Action
));
1289 Action
: Action_Callback
)
1292 Register
(Field
, Pattern
, Action
, Cur_Session
);
1297 Pattern
: GNAT
.Regpat
.Pattern_Matcher
;
1298 Action
: Action_Callback
;
1299 Session
: Session_Type
)
1301 Filters
: Pattern_Action_Table
.Instance
renames Session
.Data
.Filters
;
1303 A_Pattern
: constant Patterns
.Pattern_Matcher_Access
:=
1304 new Regpat
.Pattern_Matcher
'(Pattern);
1306 Pattern_Action_Table.Increment_Last (Filters);
1308 Filters.Table (Pattern_Action_Table.Last (Filters)) :=
1309 (Pattern => new Patterns.Regexp_Pattern'(A_Pattern
, Field
),
1310 Action
=> new Actions
.Simple_Action
'(Proc => Action));
1315 Pattern : GNAT.Regpat.Pattern_Matcher;
1316 Action : Action_Callback)
1319 Register (Field, Pattern, Action, Cur_Session);
1324 Pattern : GNAT.Regpat.Pattern_Matcher;
1325 Action : Match_Action_Callback;
1326 Session : Session_Type)
1328 Filters : Pattern_Action_Table.Instance renames Session.Data.Filters;
1330 A_Pattern : constant Patterns.Pattern_Matcher_Access :=
1331 new Regpat.Pattern_Matcher'(Pattern
);
1333 Pattern_Action_Table
.Increment_Last
(Filters
);
1335 Filters
.Table
(Pattern_Action_Table
.Last
(Filters
)) :=
1336 (Pattern
=> new Patterns
.Regexp_Pattern
'(A_Pattern, Field),
1337 Action => new Actions.Match_Action'(Proc
=> Action
));
1342 Pattern
: GNAT
.Regpat
.Pattern_Matcher
;
1343 Action
: Match_Action_Callback
)
1346 Register
(Field
, Pattern
, Action
, Cur_Session
);
1350 (Pattern
: Pattern_Callback
;
1351 Action
: Action_Callback
;
1352 Session
: Session_Type
)
1354 Filters
: Pattern_Action_Table
.Instance
renames Session
.Data
.Filters
;
1357 Pattern_Action_Table
.Increment_Last
(Filters
);
1359 Filters
.Table
(Pattern_Action_Table
.Last
(Filters
)) :=
1360 (Pattern
=> new Patterns
.Callback_Pattern
'(Pattern => Pattern),
1361 Action => new Actions.Simple_Action'(Proc
=> Action
));
1365 (Pattern
: Pattern_Callback
;
1366 Action
: Action_Callback
)
1369 Register
(Pattern
, Action
, Cur_Session
);
1373 (Action
: Action_Callback
;
1374 Session
: Session_Type
)
1377 Register
(Always_True
'Access, Action
, Session
);
1381 (Action
: Action_Callback
)
1384 Register
(Action
, Cur_Session
);
1391 procedure Set_Current
(Session
: Session_Type
) is
1393 Cur_Session
.Data
:= Session
.Data
;
1396 --------------------------
1397 -- Set_Field_Separators --
1398 --------------------------
1400 procedure Set_Field_Separators
1401 (Separators
: String := Default_Separators
;
1402 Session
: Session_Type
)
1405 Free
(Session
.Data
.Separators
);
1407 Session
.Data
.Separators
:=
1408 new Split
.Separator
'(Separators'Length, Separators);
1410 -- If there is a current line read, split it according to the new
1413 if Session.Data.Current_Line /= Null_Unbounded_String then
1414 Split_Line (Session);
1416 end Set_Field_Separators;
1418 procedure Set_Field_Separators
1419 (Separators : String := Default_Separators)
1422 Set_Field_Separators (Separators, Cur_Session);
1423 end Set_Field_Separators;
1425 ----------------------
1426 -- Set_Field_Widths --
1427 ----------------------
1429 procedure Set_Field_Widths
1430 (Field_Widths : Widths_Set;
1431 Session : Session_Type)
1434 Free (Session.Data.Separators);
1436 Session.Data.Separators :=
1437 new Split.Column'(Field_Widths
'Length, Field_Widths
);
1439 -- If there is a current line read, split it according to
1440 -- the new separators.
1442 if Session
.Data
.Current_Line
/= Null_Unbounded_String
then
1443 Split_Line
(Session
);
1445 end Set_Field_Widths
;
1447 procedure Set_Field_Widths
1448 (Field_Widths
: Widths_Set
)
1451 Set_Field_Widths
(Field_Widths
, Cur_Session
);
1452 end Set_Field_Widths
;
1458 procedure Split_Line
(Session
: Session_Type
) is
1459 Fields
: Field_Table
.Instance
renames Session
.Data
.Fields
;
1461 Field_Table
.Init
(Fields
);
1462 Split
.Current_Line
(Session
.Data
.Separators
.all, Session
);
1469 function Get_Def
return Session_Data_Access
is
1471 return Def_Session
.Data
;
1478 procedure Set_Cur
is
1480 Cur_Session
.Data
:= Def_Session
.Data
;
1484 -- We have declared two sessions but both should share the same data.
1485 -- The current session must point to the default session as its initial
1486 -- value. So first we release the session data then we set current
1487 -- session data to point to default session data.
1489 Free
(Cur_Session
.Data
);
1490 Cur_Session
.Data
:= Def_Session
.Data
;