Package: GNAT.AWK |
with Ada.Finalization;
with GNAT.Regpat;
G N A T . A W K
S p e c
$Revision: 1.10 $
Copyright (C) 2000 Ada Core Technologies, Inc.
GNAT is free software; you can redistribute it and/or modify it under terms of the GNU General Public License as published by the Free Soft- ware Foundation; either version 2, or (at your option) any later ver- sion. GNAT is distributed in the hope that it will be useful, but WITH- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License distributed with GNAT; see file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate generics from this unit, or you link this unit with other files to produce an executable, this unit does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU Public License.
GNAT is maintained by Ada Core Technologies Inc (http://www.gnat.com).
This is an AWK-like unit. It provides an easy interface for parsing one or more files containing formatted data. The file can be viewed seen as a database where each record is a line and a field is a data element in this line. In this implementation an AWK record is a line. This means that a record cannot span multiple lines. The operating procedure is to read files line by line, with each line being presented to the user of the package. The interface provides services to access specific fields in the line. Thus it is possible to control actions takn on a line based on values of some fields. This can be achieved directly or by registering callbacks triggered on programmed conditions.
The state of an AWK run is recorded in an object of type session. The following is the procedure for using a session to control an AWK run:
1) Specify which session is to be used. It is possible to use the default session or to create a new one by declaring an object of type Session_Type. For example:
Computers : Session_Type;
2) Specify how to cut a line into fields. There are two modes: using character fields separators or column width. This is done by using Set_Fields_Separators or Set_Fields_Width. For example by:
AWK.Set_Field_Separators (";,", Computers);
or by using iterators' Separators parameter.
3) Specify which files to parse. This is done with Add_File/Add_Files services, or by using the iterators' Filename parameter. For example:
AWK.Add_File ("myfile.db", Computers);
4) Run the AWK session using one of the provided iterators.
Parse This is the most automated iterator. You can gain control on the session only by registering one or more callbacks (see Register).
Get_Line/End_Of_Data This is a manual iterator to be used with a loop. You have complete control on the session. You can use callbacks but this is not required.
For_Every_Line This provides a mixture of manual/automated iterator action.
Examples of these three approaches appear below
There is many ways to use this package. The following discussion shows three approaches, using the three iterator forms, to using this package. All examples will use the following file (computer.db):
Pluton;Windows-NT;Pentium III Mars;Linux;Pentium Pro Venus;Solaris;Sparc Saturn;OS/2;i486 Jupiter;MacOS;PPC
1) Using Parse iterator
Here the first step is to register some action associated to a pattern and then to call the Parse iterator (this is the simplest way to use this unit). The default session is used here. For example to output the second field (the OS) of computer "Saturn".
procedure Action is begin Put_Line (AWK.Field (2)); end Action;
begin AWK.Register (1, "Saturn", Action'Access); AWK.Parse (";", "computer.db");
2) Using the Get_Line/End_Of_Data iterator
Here you have full control. For example to do the same as above but using a specific session, you could write:
Computer_File : Session_Type;
begin AWK.Set_Current (Computer_File); AWK.Open (Separators => ";", Filename => "computer.db");
-- Display Saturn OS
while not AWK.End_Of_File loop AWK.Get_Line;
if AWK.Field (1) = "Saturn" then Put_Line (AWK.Field (2)); end if; end loop;
AWK.Close (Computer_File);
3) Using For_Every_Line iterator
In this case you use a provided iterator and you pass the procedure that must be called for each record. You could code the previous example could be coded as follows (using the iterator quick interface but without using the current session):
Computer_File : Session_Type;
procedure Action (Quit : in out Boolean) is begin if AWK.Field (1, Computer_File) = "Saturn" then Put_Line (AWK.Field (2, Computer_File)); end if; end Action;
procedure Look_For_Saturn is new AWK.For_Every_Line (Action);
begin Look_For_Saturn (Separators => ";", Filename => "computer.db", Session => Computer_File);
Integer_Text_IO.Put (Integer (AWK.NR (Session => Computer_File))); Put_Line (" line(s) have been processed.");
You can also use a regular expression for the pattern. Let us output the computer name for all computer for which the OS has a character O in its name.
Regexp : String := ".*O.*";
Matcher : Regpat.Pattern_Matcher := Regpat.Compile (Regexp);
procedure Action is begin Text_IO.Put_Line (AWK.Field (2)); end Action;
begin AWK.Register (2, Matcher, Action'Unrestricted_Access); AWK.Parse (";", "computer.db");
Header | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Generated on 2002-07-04 at 12:43:22 by AdaBrowse 2.12 using configuration file std.cfg. |