cde56abf43f21439b130f8237186ef8c076fef68
[oweals/cde.git] / cde / lib / tt / slib / mp_otype.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 //%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                  
24 //%%  (c) Copyright 1993, 1994 International Business Machines Corp.    
25 //%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                   
26 //%%  (c) Copyright 1993, 1994 Novell, Inc.                             
27 //%%  $TOG: mp_otype.C /main/4 1998/03/20 14:27:39 mgreess $                                                    
28 /*
29  * mp_otype.cc
30  *
31  * Copyright (c) 1990 by Sun Microsystems, Inc.
32  */
33 #include <stdlib.h>
34 #if defined(linux)
35 /*# include <g++/minmax.h>*/
36 #else
37 # include <macros.h>
38 #endif
39 #include "mp/mp_global.h"
40 #include "mp_s_mp.h"
41 #include "mp_otype.h"
42 #include "mp_otype_utils.h"     
43 #include "mp_ce_attrs.h"
44 #include "util/tt_enumname.h"
45 #include "util/tt_iostream.h"
46
47 //
48 // This file contains methods for _Tt_otype objects which embody the
49 // behavior of otype definitions.
50 //
51
52
53 _Tt_otype::
54 _Tt_otype()
55 {
56         _ancestors = new _Tt_string_list();
57         _children = (_Tt_string_list *)0;
58         _inhs = new _Tt_signature_list();
59         _osigs = new _Tt_signature_list();
60         _hsigs = new _Tt_signature_list();
61         visitp = 0;
62         ce_entry = 0;
63 }
64
65
66 bool_t _Tt_otype::
67 xdr(XDR *xdrs)
68 {
69         return(_otid.xdr(xdrs) &&
70                _ancestors.xdr(xdrs) &&
71                _inhs.xdr(xdrs) &&
72                _osigs.xdr(xdrs) &&
73                _hsigs.xdr(xdrs) &&
74                xdr_int(xdrs, &visitp));
75 }
76
77
78 _Tt_otype::
79 _Tt_otype(_Tt_string otid)
80 {
81         _ancestors = new _Tt_string_list();
82         _children = (_Tt_string_list *)0;
83         _inhs = new _Tt_signature_list();
84         _osigs = new _Tt_signature_list();
85         _hsigs = new _Tt_signature_list();
86         _otid = otid;
87         visitp = 0;
88         ce_entry = 0;
89 }
90
91
92 _Tt_otype::
93 ~_Tt_otype()
94 {
95 }
96
97
98 void _Tt_otype::
99 set_otid(_Tt_string otid)
100 {
101         _otid = otid;
102 }
103
104
105 void _Tt_otype::
106 set_ancestors(_Tt_string_list_ptr ancs)
107 {
108         _ancestors = ancs;
109 }
110
111
112 //
113 // Appends an inherited signature to this object if there isn't the
114 // same signature already.
115 //
116 void _Tt_otype::
117 append_inhs(_Tt_signature_ptr sig)
118 {
119         if (_inhs.is_null()) {
120                 _inhs = new _Tt_signature_list();
121                 _inhs->push(sig);
122         } else {
123                 _Tt_signature_list_cursor       sc(_inhs);
124
125                 while (sc.next()) {
126                         if (**sc == *sig) {
127                                 return;
128                         }
129                 }
130                 _inhs->append(sig);
131         }
132 }
133
134
135 //
136 // Appends an observer signature to this object if there isn't the
137 // same signature already.
138 //
139 void _Tt_otype::
140 append_osig(_Tt_signature_ptr sig)
141 {
142         sig->set_pattern_category(TT_OBSERVE);
143
144         if (_osigs.is_null()) {
145                 _osigs = new _Tt_signature_list();
146                 _osigs->push(sig);
147         } else {
148                 _Tt_signature_list_cursor       sc(_osigs);
149
150                 while (sc.next()) {
151                         if (**sc == *sig) {
152                                 return;
153                         }
154                 }
155                 _osigs->append(sig);
156         }
157 }
158
159
160 //
161 // Appends a handler signature to this object if there isn't the same
162 // signature already.
163 //
164 void _Tt_otype::
165 append_hsig(_Tt_signature_ptr sig, Tt_category category)
166 {
167         sig->set_pattern_category(category);
168
169         if (_hsigs.is_null()) {
170                 _hsigs = new _Tt_signature_list();
171                 _hsigs->push(sig);
172         } else {
173                 _Tt_signature_list_cursor       sc(_hsigs);
174
175                 while (sc.next()) {
176                         if (**sc == *sig) {
177                                 return;
178                         }
179                 }
180                 _hsigs->append(sig);
181         }
182 }
183
184
185 //
186 // Appends a list of observer signatures to this object.
187 //
188 void _Tt_otype::
189 append_osigs(_Tt_signature_list_ptr sigs)
190 {
191         _Tt_signature_list_cursor       sc(sigs);
192
193         while (sc.next()) {
194                 sc->set_pattern_category(TT_OBSERVE);
195         }
196         if (_osigs.is_null()) {
197                 _osigs = sigs;
198         } else {
199                 _osigs->append_destructive(sigs);
200         }
201 }
202
203
204 //
205 // Appends a list of handler signature to this object.
206 //
207 void _Tt_otype::
208 append_hsigs(_Tt_signature_list_ptr sigs, Tt_category category)
209 {
210         _Tt_signature_list_cursor       sc(sigs);
211
212         while (sc.next()) {
213                 sc->set_pattern_category(category);
214         }
215         if (_hsigs.is_null()) {
216                 _hsigs = sigs;
217         } else {
218                 _hsigs->append_destructive(sigs);
219         }
220 }
221
222
223 //
224 // Prints out a _Tt_otype object. Note that the format used to print
225 // the object is the format used to represent this object to the
226 // Classing Engine. It is important to preserve this characteristic
227 // for compatibility's sake.
228 //
229 void _Tt_otype::
230 print(const _Tt_ostream &os) const
231 {
232         _Tt_string_list_cursor          anc;
233         FILE *fs = os.theFILE();
234
235         if (_otid.len()) {
236                 fprintf(fs, "\t(\n\t\t(%s,%s,<",
237                         _tt_ce_attr_string(_TYPE_NAME),
238                         _tt_ce_attr_string(_TT_TOOLTALK_OTYPE));
239                 _otid.print(fs);
240                 fputs(">)\n", fs);
241                 fprintf(fs,"\t\t(%s,string,<%s>)\n",
242                         _tt_ce_attr_string(_TT_TOOLTALK_TYPE),
243                         _tt_ce_attr_string(_TT_TOOLTALK_OTYPE));
244                 if (! _ancestors.is_null()) {
245                         anc.reset(_ancestors);
246                         while (anc.next()) {
247                                 fprintf(fs,"\t\t(%s,string,<%s>)\n",
248                                         _tt_ce_attr_string(_TT_PARENT),
249                                         (char *)*anc);
250                         }
251                 }
252                 fprintf(fs,"\t)");
253         }
254 }
255
256
257 //
258 // Returns a list of descendant otypes from this otype.
259 //
260 _Tt_string_list_ptr & _Tt_otype::
261 children()
262 {
263         _Tt_otype_table_cursor c;
264         _Tt_string_list_ptr plist;
265         _Tt_string parname;
266         _Tt_otype_ptr cparent;
267
268         if (!_children.is_null()) {
269                 return _children;
270         }
271         _children = new _Tt_string_list;
272
273         c.reset(_tt_s_mp->otable);
274         while(c.next()) {
275                 plist = c->parents();
276                 if (!plist.is_null() && plist->count()!=0) {
277                         parname = plist->top();
278                         if (! _tt_s_mp->otable->lookup(parname,cparent)) {
279                                 if (cparent->otid() == otid()) {
280                                         _children->append(c->otid());
281                                 }
282                         }
283                 }
284         }
285         return _children;
286 }
287
288
289 _Tt_string_list_ptr & _Tt_otype::
290 parents()
291 {
292         return _ancestors;
293 }
294
295
296 _Tt_signature_list_ptr &_Tt_otype::
297 hsigs()
298 {
299         return _hsigs;
300 }
301
302
303 _Tt_signature_list_ptr &_Tt_otype::
304 osigs()
305 {
306         return _osigs;
307 }
308
309
310 int _Tt_otype::
311 xdr_version_required() const
312 {
313         int version = _Tt_signature::xdr_version_required_( _hsigs );
314 //     return max(version, _Tt_signature::xdr_version_required_( _osigs ));
315         if (version > _Tt_signature::xdr_version_required_( _osigs )) {
316                 return version;
317         } else {
318                 return _Tt_signature::xdr_version_required_( _osigs );
319         }
320 }
321
322 //
323 // Prints out an otype object in source format. This means that the
324 // otype is printed out in such a fashion that the result is parseable
325 // by tt_type_comp and when parsed would reproduce the essential
326 // structure of this object.
327 //
328 void _Tt_otype::
329 pretty_print(const _Tt_ostream &os) const
330 {
331         _Tt_string_list_cursor          anc;
332
333         FILE *fs = os.theFILE();
334
335         fprintf(fs,"otype ");
336         _otid.print(fs);
337         if (! _ancestors.is_null() && _ancestors->count()) {
338                 fprintf(fs," :");
339                 anc.reset(_ancestors);
340                 while (anc.next()) {
341                         fprintf(fs," %s", (char *)*anc);
342                 }
343         }
344         fprintf(fs," {\n");
345         _Tt_signature::pretty_print_( os, _hsigs, TT_HANDLE, 0 );
346         _Tt_signature::pretty_print_( os, _hsigs, TT_HANDLE_PUSH, 0 );
347         _Tt_signature::pretty_print_( os, _hsigs, TT_HANDLE_ROTATE, 0 );
348         _Tt_signature::pretty_print_( os, _osigs, TT_OBSERVE, 0 );
349         fprintf(fs,"};\n");
350 }
351
352
353 // 
354 // Returns the otid of the given _Tt_object which is assumed to be a
355 // _Tt_otype object. This is used by the generic table package to
356 // generate a key for an entry in the table.
357 // 
358 _Tt_string
359 _tt_otype_otid(_Tt_object_ptr &o)
360 {
361         return(((_Tt_otype *)o.c_pointer())->otid());
362 }
363
364
365 // 
366 // Invokes the print method on the given _Tt_object which is assumed to
367 // really point to a _Tt_otype object. This is used by the generic table
368 // and list objects in their print methods.
369 // 
370 void 
371 _tt_otype_print(const _Tt_ostream &os, const _Tt_object *obj)
372 {
373         ((_Tt_otype *)obj)->print(os);
374 }