Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / tt / lib / util / tt_iostream.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23
24 //%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                  
25 //%%  (c) Copyright 1993, 1994 International Business Machines Corp.    
26 //%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                   
27 //%%  (c) Copyright 1993, 1994 Novell, Inc.                             
28 //%%  $TOG: tt_iostream.C /main/5 1998/04/03 17:10:03 mgreess $                                                         
29 /*
30  * @(#)tt_iostream.cc   1.4 93/08/15
31  * 
32  * Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
33  */
34
35 #include <string.h>
36 #include <stdarg.h>
37 #include "util/tt_iostream.h"
38 #include "util/tt_enumname.h"
39 #include "mp/mp_message.h"
40 #include "mp/mp_pattern.h"
41
42 _Tt_ostream::_Tt_ostream()
43 {
44         _f = 0;
45         _s = 0;
46         _was_newline = 1;  // so we indent the first line
47 }
48
49 _Tt_ostream::_Tt_ostream(
50         FILE *sink
51 )
52 {
53         _f = 0;
54         _s = 0;
55         _was_newline = 0;
56         *this = sink;
57 }
58
59 _Tt_ostream::_Tt_ostream(
60         _Tt_string &sink
61 )
62 {
63         _f = 0;
64         _s = 0;
65         _was_newline = 0;
66         *this = sink;
67 }
68
69 _Tt_ostream::~_Tt_ostream()
70 {
71 }
72
73 _Tt_ostream &
74 _Tt_ostream::operator =(
75         FILE *sink
76 )
77 {
78         _f = sink;
79         _s = 0;
80         return *this;
81 }
82
83 _Tt_ostream &
84 _Tt_ostream::operator =(
85         _Tt_string &sink
86 )
87 {
88         _f = 0;
89         _s = &sink;
90         return *this;
91 }
92
93 const _Tt_ostream &
94 _Tt_ostream::operator <<(
95         const _Tt_message &m
96 ) const
97 {
98         m.print( *this );
99         return *this;
100 }
101
102 const _Tt_ostream &
103 _Tt_ostream::operator <<(
104         const _Tt_pattern &p
105 ) const
106 {
107         p.print( *this );
108         return *this;
109 }
110
111 const _Tt_ostream &
112 _Tt_ostream::operator <<(
113         const _Tt_string &s
114 ) const
115 {
116         s.print( *this );
117         return *this;
118 }
119
120 const _Tt_ostream &
121 _Tt_ostream::operator <<(
122         Tt_status status
123 ) const
124 {
125         *this << _tt_enumname( status );
126         return *this;
127 }
128
129 const _Tt_ostream &
130 _Tt_ostream::operator <<(
131         Tt_callback_action val
132 ) const
133 {
134         *this << _tt_enumname( val );
135         return *this;
136 }
137
138 const _Tt_ostream &
139 _Tt_ostream::operator <<(
140         void *p
141 ) const
142 {
143         char buf[20];
144         ::sprintf( buf, "0x%p", p );
145         *this << buf;
146         return *this;
147 }
148
149 const _Tt_ostream &
150 _Tt_ostream::operator <<(
151         const char *s
152 ) const
153 {
154         if (s == 0) {
155                 *this << "(null)";
156                 return *this;
157         }
158         //
159         // If no indenting and no newlines...
160         //
161         if ((_indent.len() <= 0) && (strchr( s, '\n' ) == 0)) {
162                 //
163                 // ... just blast the whole string
164                 //
165                 if (_f != 0) {
166                         fputs( s, _f );
167                 }
168                 if (_s != 0) {
169                         *_s = (*_s).cat( s );
170                 }
171                 return *this;
172         }
173
174
175         // XXX - Inefficient.
176         // The string either has a newline in it, or indents is > 0,
177         // so deal with it on a per-character basis.
178         const char *pc = s;
179         while (*pc != '\0') {
180                 *this << *pc;
181                 pc++;
182         }
183         return *this;
184 }
185
186 const _Tt_ostream &
187 _Tt_ostream::operator <<(
188         char c
189 ) const
190 {
191         if (_f != 0) {
192                 if (_indent.len() > 0) {
193                         if (_was_newline == 1) {
194                                 _indent.print( _f );
195                         }
196                 }
197                 fputc( c, _f );
198         }
199         if (_s != 0) {
200                 if (_indent.len() > 0) {
201                         if (_was_newline == 1) {
202                                 *_s = (*_s).cat( _indent );
203                         }
204                 }
205                 *_s = (*_s).cat( c );
206         }
207
208         if (c == '\n') {
209                 ((_Tt_ostream *) this)->_was_newline = 1;
210         } else  {
211                 ((_Tt_ostream *) this)->_was_newline = 0;
212         }
213
214         return *this;
215 }
216
217 const _Tt_ostream &
218 _Tt_ostream::operator <<(
219         int n
220 ) const
221 {
222         char buf[ 20 ];
223         ::sprintf( buf, "%d", n );
224         *this << buf;
225         return *this;
226 }
227
228 #if defined(__osf__) || defined(linux)
229 /* This operator is being added to take care of uid_t and gid_t
230  * for osf */
231 const _Tt_ostream &
232 _Tt_ostream::operator <<(
233         unsigned int n
234 ) const
235 {
236         char buf[ 20 ];
237         ::sprintf( buf, "%u", n );
238         *this << buf;
239         return *this;
240 }
241 #endif
242
243 const _Tt_ostream &
244 _Tt_ostream::operator <<(
245         long n
246 ) const
247 {
248         char buf[ 20 ];
249         ::sprintf( buf, "%ld", n );
250         *this << buf;
251         return *this;
252 }
253
254 const _Tt_ostream &
255 _Tt_ostream::operator <<(
256         unsigned long n
257 ) const
258 {
259         char buf[ 20 ];
260         ::sprintf( buf, "%lu", n );
261         *this << buf;
262         return *this;
263 }
264
265 const _Tt_ostream &
266 _Tt_ostream::print(
267         _Tt_object_printfn print_it,
268         const _Tt_object  *obj
269 ) const
270 {
271         (*print_it)( *this, obj );
272         return *this;
273 }
274
275 int
276 _Tt_ostream::sprintf(
277         unsigned int      maxlen,
278         const char       *format,
279         ...
280 ) const
281 {
282         va_list args;
283         char *buf = (char *)malloc( maxlen + 1 );
284         if (buf == 0) {
285                 return -1;
286         }
287         va_start( args, format );
288         int val = vsprintf( buf, format, args );
289         va_end( args );
290         if (val >= 0) {
291                 *this << buf;
292         }
293         free( buf );
294         return val;
295 }
296
297 void
298 _Tt_ostream::set_indent(
299         const _Tt_string &new_indent
300 ) const
301 {
302         _Tt_ostream *nonconst_this = (_Tt_ostream *)this;
303         nonconst_this->_indent = new_indent;
304 }