~ubuntu-branches/debian/sid/adabrowse/sid

« back to all changes in this revision

Viewing changes to util-pipes.ads

  • Committer: Bazaar Package Importer
  • Author(s): Ludovic Brenta
  • Date: 2004-02-14 13:22:40 UTC
  • Revision ID: james.westby@ubuntu.com-20040214132240-cqumhiq1677pkvzo
Tags: upstream-4.0.2
ImportĀ upstreamĀ versionĀ 4.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
-------------------------------------------------------------------------------
 
2
--
 
3
--  <STRONG>Copyright &copy; 2001, 2002 by Thomas Wolf.</STRONG>
 
4
--  <BLOCKQUOTE>
 
5
--    This piece of software is free software; you can redistribute it and/or
 
6
--    modify it under the terms of the  GNU General Public License as published
 
7
--    by the Free Software  Foundation; either version 2, or (at your option)
 
8
--    any later version. This software is distributed in the hope that it will
 
9
--    be useful, but <EM>without any warranty</EM>; without even the implied
 
10
--    warranty of <EM>merchantability or fitness for a particular purpose.</EM>
 
11
--    See the GNU General Public License for  more details. You should have
 
12
--    received a copy of the GNU General Public License with this distribution,
 
13
--    see file "<A HREF="GPL.txt">GPL.txt</A>". If not, write to the Free
 
14
--    Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 
15
--    USA.
 
16
--  </BLOCKQUOTE>
 
17
--  <BLOCKQUOTE>
 
18
--    As a special exception from the GPL, if other files instantiate generics
 
19
--    from this unit, or you link this unit with other files to produce an
 
20
--    executable, this unit does not by itself cause the resulting executable
 
21
--    to be covered by the GPL. This exception does not however invalidate any
 
22
--    other reasons why the executable file might be covered by the GPL.
 
23
--  </BLOCKQUOTE>
 
24
--
 
25
--  <AUTHOR>
 
26
--    Thomas Wolf  (TW) <E_MAIL>
 
27
--  </AUTHOR>
 
28
--
 
29
--  <PURPOSE>
 
30
--    This is a thick binding to the @popen@ and @pclose@ routines available
 
31
--    on both Unix and Win32. It gives a convenient way to execute an external
 
32
--    program and pass it some input, or read its output.
 
33
--  </PURPOSE>
 
34
--
 
35
--  <TASKING>
 
36
--    Neither task- not abortion-safe. All operations here should be
 
37
--    considered <EM>potentially blocking</EM>.
 
38
--  </TASKING>
 
39
--
 
40
--  <NO_STORAGE>
 
41
--
 
42
--  <HISTORY>
 
43
--    26-APR-2002   TW  Initial version.
 
44
--    29-APR-2002   TW  Added auto-close feature.
 
45
--  </HISTORY>
 
46
-------------------------------------------------------------------------------
 
47
 
 
48
pragma License (Modified_GPL);
 
49
 
 
50
with Ada.Finalization;
 
51
with Ada.IO_Exceptions;
 
52
with Ada.Streams;
 
53
 
 
54
with Interfaces.C.Strings;
 
55
 
 
56
package Util.Pipes is
 
57
 
 
58
   type Stream_Mode is (In_Stream, Out_Stream);
 
59
   --  Used in @Open@ to specify the type of the stream.
 
60
 
 
61
   type Pipe_Stream is new Ada.Streams.Root_Stream_Type with private;
 
62
   --  I have found no indication whatsoever about the type of the underlying
 
63
   --  C stream (binary or text mode?). Although you <EM>can</EM> write and
 
64
   --  read binary data to and from a @Pipe_Stream@, it's probably prudent to
 
65
   --  consider these streams as <EM>text-only</EM>, because they set up pipes
 
66
   --  to or from an external processes stdin or stdout handles, which are
 
67
   --  defined by the ISO C standard as text streams.
 
68
 
 
69
   Name_Error : exception renames Ada.IO_Exceptions.Name_Error;
 
70
   --  Raised by @Open@ if the command cannot be executed.
 
71
 
 
72
   Use_Error  : exception renames Ada.IO_Exceptions.Use_Error;
 
73
   --  Raised by any stream operation if the stream is not open (and by @Open@,
 
74
   --  if it already is open).
 
75
 
 
76
   Mode_Error : exception renames Ada.IO_Exceptions.Mode_Error;
 
77
   --  Stream operations on the returned stream may raise @Mode_Error@ if
 
78
   --  writing on an @In_Stream@ or reading from an @Out_Stream@ is attempted.
 
79
 
 
80
   End_Error  : exception renames Ada.IO_Exceptions.End_Error;
 
81
   --  Stream operations on an @In_Stream@ will raise @End_Error@ if EOF is
 
82
   --  encountered.
 
83
 
 
84
   Device_Error : exception renames Ada.IO_Exceptions.Device_Error;
 
85
   --  Raised by the @Put@ or @Get@ operations (and also by @Write@ and
 
86
   --  @Read@) if the underlying system operations indicate any reading or
 
87
   --  writing error.
 
88
 
 
89
   procedure Open
 
90
     (Stream  : in out Pipe_Stream;
 
91
      Command : in     String;
 
92
      Mode    : in     Stream_Mode;
 
93
      Close   : in     Boolean := True;
 
94
      Std_In  : in     String  := "");
 
95
   --  Executes @Command@, which may contain arguments, setting it up such that
 
96
   --  the executed command's stdin comes from the returned stream if @Mode@
 
97
   --  is @Out_Stream@, or the command's stdout can be read from that stream
 
98
   --  if @Mode@ is @In_Stream@. Note that "in" and "out" are from the caller's
 
99
   --  perspective.
 
100
   --
 
101
   --  If <CODE>Close = True</CODE>, the stream is closed automatically when
 
102
   --  the stream object disappears. Note that this may involve waiting until
 
103
   --  the external command terminates. @Out_Stream@s always are closed
 
104
   --  automatically.
 
105
   --
 
106
   --  Raises @Name_Error@ if the @Command@ cannot be executed, or @Use_Error@
 
107
   --  if the stream is already open.
 
108
   --
 
109
   --  Note that an <EM>output filter</EM> is created using a stream of mode
 
110
   --  @Out_Stream@. The external process will share its stdout with the
 
111
   --  calling application, so you should carefully flush your stdout before
 
112
   --  opening such a pipe, otherwise, output may become garbled and mixed up.
 
113
   --  The same applies to an <EM>input filter</EM>: it shares its stdin with
 
114
   --  the calling application! Unfortunately, one cannot flush an input stream
 
115
   --  (that would be a meaningless operation anyway), so be careful!
 
116
   --
 
117
   --  One way to avoid such problems is using the @Std_In@ parameter. If it
 
118
   --  is not the empty string, the command's stdin is redirected to come
 
119
   --  from the given filename (which had better be valid). In other words,
 
120
   --  the command actually executed is <CODE>Command & " <" & Std_In</CODE>.
 
121
   --  If this feature is used, the caller is responsible for removing the
 
122
   --  file, if that is desired.
 
123
 
 
124
   procedure Close
 
125
     (Stream    : in out Pipe_Stream;
 
126
      Exit_Code :    out Integer);
 
127
   --  Closes a stream obtained through @Open@. Raises @Use_Error@ if the
 
128
   --  stream has not been opened.
 
129
   --
 
130
   --  An @Out_Stream@ <EM>must</EM> be closed, otherwise your program might
 
131
   --  not terminate. therefore, @Pipe_Stream@s are controlled, and any
 
132
   --  @Out_Stream@ is closed automatically when the stream object disappears.
 
133
   --
 
134
   --  An @In_Stream@ is only closed automatically if it has been opened with
 
135
   --  <CODE>Close = True</CODE>, because closing such a stream may involve
 
136
   --  waiting until the external command has terminated.
 
137
   --
 
138
   --  Note: this is a blocking call: it waits until the executed command
 
139
   --  has terminated, and then returns that commands exit code.
 
140
 
 
141
   function Is_Open
 
142
     (Stream : in Pipe_Stream)
 
143
     return Boolean;
 
144
   --  Returns @True@ if the @Stream@ is open, and @False@ otherwise.
 
145
 
 
146
   function End_Of_Stream
 
147
     (Stream : in Pipe_Stream)
 
148
     return Boolean;
 
149
   --  Raises @Mode_Error@ if the @Stream@ is an @Out_Stream@. Otherwise,
 
150
   --  returns @True@ if the @In_Stream@s end has been reached and @False@
 
151
   --  otherwise.
 
152
 
 
153
   procedure Put
 
154
     (Stream : in Pipe_Stream;
 
155
      Text   : in String);
 
156
   --  Same semantics as @Ada.Text_IO.Put@.
 
157
 
 
158
   procedure Put
 
159
     (Stream : in Pipe_Stream;
 
160
      Ch     : in Character);
 
161
   --  Same semantics as @Put@ for a string.
 
162
 
 
163
   procedure Put_Line
 
164
     (Stream : in Pipe_Stream;
 
165
      Text   : in String);
 
166
   --  Same semantics as @Ada.Text_IO.Put_Line@.
 
167
 
 
168
   procedure Get
 
169
     (Stream : in     Pipe_Stream;
 
170
      Ch     :    out Character);
 
171
   --  Same semantics as @Ada.Text_IO.Get@.
 
172
 
 
173
   procedure Get
 
174
     (Stream : in     Pipe_Stream;
 
175
      Buffer :    out String);
 
176
   --  Same semantics as @Ada.Text_IO.Get@.
 
177
 
 
178
   procedure Get_Line
 
179
     (Stream : in     Pipe_Stream;
 
180
      Buffer :    out String;
 
181
      Last   :    out Natural);
 
182
   --  Same semantics as @Ada.Text_IO.Get_Line@.
 
183
 
 
184
   function Get_Line
 
185
     (Stream : in Pipe_Stream)
 
186
     return String;
 
187
   --  As @Ada.Text_IO.Get_Line@, but always returns a full line.
 
188
 
 
189
private
 
190
 
 
191
   type C_File_Ptr is new Interfaces.C.Strings.chars_ptr;
 
192
 
 
193
   Null_Ptr : constant C_File_Ptr :=
 
194
     C_File_Ptr (Interfaces.C.Strings.Null_Ptr);
 
195
 
 
196
   type Closer (Stream : access Pipe_Stream) is
 
197
     new Ada.Finalization.Limited_Controlled with null record;
 
198
 
 
199
   procedure Finalize (C : in out Closer);
 
200
 
 
201
   type Pipe_Stream is new Ada.Streams.Root_Stream_Type with
 
202
      record
 
203
         F        : C_File_Ptr := Null_Ptr;
 
204
         Mode     : Stream_Mode;
 
205
         Close_It : Boolean    := True;
 
206
         Clean_Up : Closer (Pipe_Stream'Access);
 
207
      end record;
 
208
 
 
209
   procedure Read
 
210
     (Stream : in out Pipe_Stream;
 
211
      Item   :    out Ada.Streams.Stream_Element_Array;
 
212
      Last   :    out Ada.Streams.Stream_Element_Offset);
 
213
 
 
214
   procedure Write
 
215
     (Stream : in out Pipe_Stream;
 
216
      Item   : in     Ada.Streams.Stream_Element_Array);
 
217
 
 
218
end Util.Pipes;