Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / tt / lib / mp / mp_pattern.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_pattern.C /main/5 1999/10/14 18:48:24 mgreess $                                                  
28 /*
29  *
30  * @(#)mp_pattern.C     1.28 30 Jul 1993
31  *
32  * Tool Talk Message Passer (MP) - mp_pattern.cc
33  *
34  * Copyright (c) 1990,1992 by Sun Microsystems, Inc.
35  */
36 #include "api/c/api_spec_map_ref.h"
37 #include "mp/mp_global.h"
38 #include "mp/mp_arg.h"
39 #include "mp/mp_pat_context.h"
40 #include "mp/mp_mp.h"
41 #include "mp/mp_pattern.h"
42 #include "mp/mp_message.h"
43 #include "mp/mp_session.h"
44 #include "mp/mp_xdr_functions.h"
45 #include "util/tt_enumname.h"
46 #include "util/tt_global_env.h"
47 #include "util/tt_port.h"
48
49 //
50 // Base constructor for _Tt_pattern objects. Should be called by all
51 // other _Tt_pattern constructors.
52 //
53 void _Tt_pattern::
54 base_constructor()
55 {
56         server_callback = 0;
57         _category       = TT_CATEGORY_LAST;
58         _classes        = 0;
59         _paradigms      = 0;
60         _reliabilities  = 0;
61         _scopes         = 0;
62         _states         = 0;
63         _files          = new _Tt_string_list();
64         _handler_ptypes = new _Tt_string_list();
65         _handlers       = new _Tt_string_list();
66         _objects        = new _Tt_string_list();
67         _observer_ptypes = new _Tt_string_list();
68         _opnums         = new _Tt_int_rec_list();
69         _ops            = new _Tt_string_list();
70         _args           = new _Tt_arg_list();
71         _contexts       = new _Tt_pat_context_list;
72         _otypes         = new _Tt_string_list();
73         _sender_ptypes  = new _Tt_string_list();
74         _senders        = new _Tt_string_list();
75         _sessions       = new _Tt_string_list();
76         _flags          = 0;
77 }
78
79 _Tt_pattern::
80 ~_Tt_pattern()
81 {
82 }
83
84
85 //
86 // Deletes the given argument from the _files field of this object.
87 //
88 Tt_status _Tt_pattern::
89 del_file(const _Tt_string &f)
90 {
91         _Tt_string_list_cursor  fcursor(_files);
92
93         while (fcursor.next()) {
94                 if (*fcursor == f) {
95                         fcursor.remove();
96                 }
97         }
98         return(TT_OK);
99 }
100
101
102 //
103 // Deletes the given argument from the _sessions field of this object.
104 //
105 Tt_status _Tt_pattern::
106 del_session(const _Tt_string &s)
107 {
108         _Tt_string_list_cursor  scursor(_sessions);
109
110         while (scursor.next()) {
111                 if (*scursor == s) {
112                         scursor.remove();
113                 }
114         }
115         return(TT_OK);
116 }
117
118
119 //
120 // Adds the given object id to the _objects field. Will return
121 // TT_WRN_STALE_OBJID if the oid is a stale object id.
122 //
123 Tt_status _Tt_pattern::
124 add_object(const _Tt_string &oid)
125 {
126         _Tt_api_spec_map_ref spec_map;
127         _Tt_objid_spec_ptr   spec = spec_map.getSpec(oid);
128         Tt_status            status;
129
130         if (spec.is_null()) {
131                 return(TT_ERR_OBJID);
132         }
133
134         switch (spec->getDBResults()) {
135               case TT_DB_OK:
136                 status = TT_OK;
137                 break;
138               case TT_DB_WRN_FORWARD_POINTER:
139                 status = TT_WRN_STALE_OBJID;
140                 break;
141               default:
142                 return(TT_ERR_OBJID);
143         }
144         add_field(oid, _objects);
145
146         return(status);
147 }
148
149
150 // 
151 // Generic function for adding an integer to a _Tt_int_rec_list if it
152 // isn't already there.
153 // 
154 void _Tt_pattern::
155 add_field(int v, _Tt_int_rec_list_ptr &vlist)
156 {
157         _Tt_int_rec_list_cursor c(vlist);
158
159         while (c.next()) {
160                 if (c->val == v) {
161                         return;
162                 }
163         }
164         vlist->push(new _Tt_int_rec((int)v));
165 }
166
167
168 // 
169 // Generic function for adding a string to a _Tt_string_list if it
170 // isn't already there.
171 // 
172 void _Tt_pattern::
173 add_field(const _Tt_string &v, _Tt_string_list_ptr &vlist)
174 {
175         _Tt_string_list_cursor  c(vlist);
176
177         while (c.next()) {
178                 if (*c == v) {
179                         return;
180                 }
181         }
182         vlist->push(v);
183 }
184
185
186 _Tt_pat_context_ptr _Tt_pattern::
187 context(const char *slotname) const
188 {
189         _Tt_pat_context_list_cursor contextC( _contexts );
190         while (contextC.next()) {
191                 if (contextC->slotName() == slotname) {
192                         return *contextC;
193                 }
194         }
195         return 0;
196 }
197
198
199 _Tt_pat_context_ptr _Tt_pattern::
200 context(int i) const
201 {
202         if ((i >= 0) && (i < _contexts->count())) {
203                 return (*_contexts)[ i ];
204         }
205         return 0;
206 }
207
208
209 int _Tt_pattern::
210 contextsCount() const
211 {
212         if (_contexts.is_null()) {
213                 return 0;
214         }
215         return _contexts->count();
216 }
217
218 Tt_status
219 _Tt_pattern::add_netfile(
220         const _Tt_string &filepath,
221         int fallback_2_local_netfile
222 )
223 {
224         _Tt_string abspath;
225         Tt_status  status = TT_OK;
226         int        __scopes = scopes();
227
228         if ((__scopes&(1<<TT_FILE)) || (__scopes&(1<<TT_BOTH))) {
229                 abspath = _Tt_db_file::getNetworkPath(filepath);
230                 if ((abspath.len() == 0) && (! fallback_2_local_netfile)) {
231                         return TT_ERR_FILE;
232                 }
233         }
234         if (abspath.len() == 0) {
235                 abspath = _tt_local_network_path(filepath);
236                 if (abspath.len() == 0) {
237                         return TT_ERR_FILE;
238                 }
239         }
240         return(add_file(abspath));
241 }
242
243
244 //
245 // XDR encodes/decodes a pattern. 
246 //
247 bool_t _Tt_pattern::
248 xdr(XDR *xdrs)
249 {
250         if (! tt_xdr_string(xdrs, &_pattern_id)) {
251                 return(0);
252         }
253         if (! xdr_int(xdrs, (int *)&_category)) {
254                 return(0);
255         }
256         if (! xdr_int(xdrs, (int *)&_classes)) {
257                 return(0);
258         }
259         if (! xdr_int(xdrs, (int *)&_states)) {
260                 return(0);
261         }
262         if (! xdr_int(xdrs, (int *)&_paradigms)) {
263                 return(0);
264         }
265         if (! xdr_int(xdrs, (int *)&_scopes)) {
266                 return(0);
267         }
268         if (! xdr_int(xdrs, (int *)&_reliabilities)) {
269                 return(0);
270         }
271         if (! _files.xdr(xdrs)) {
272                 return(0);
273         }
274         if (! _sessions.xdr(xdrs)) {
275                 return(0);
276         }
277         if (! _ops.xdr(xdrs)) {
278                 return(0);
279         }
280         if (! _opnums.xdr(xdrs)) {
281                 return(0);
282         }
283         if (! _objects.xdr(xdrs)) {
284                 return(0);
285         }
286         if (! _otypes.xdr(xdrs)) {
287                 return(0);
288         }
289         if (! _senders.xdr(xdrs)) {
290                 return(0);
291         }
292         if (! _handlers.xdr(xdrs)) {
293                 return(0);
294         }
295         if (! _sender_ptypes.xdr(xdrs)) {
296                 return(0);
297         }
298         if (! _handler_ptypes.xdr(xdrs)) {
299                 return(0);
300         }
301         if (! _args.xdr(xdrs)) {
302                 return(0);
303         }
304         if (_tt_global->xdr_version() >= TT_CONTEXTS_XDR_VERSION) {
305                 if (! _contexts.xdr(xdrs)) {
306                         return(0);
307                 }
308         }
309
310         return(1);
311 }
312
313
314 //
315 // Function wrapper so that the xdr method for a pattern can be invoked
316 // from the C RPC interface.
317 //
318 bool_t tt_xdr_pattern(XDR *xdrs, _Tt_pattern_ptr *pat)
319 {
320         return((*pat)->xdr(xdrs));
321 }
322
323 // 
324 // methods and functions associated with printing patterns
325 //
326
327 static const char *
328 int_to_class(int r)
329 {
330         return(_tt_enumname((Tt_class)r));
331 }
332
333 static const char *
334 int_to_paradigm(int r)
335 {
336         return(_tt_enumname((Tt_address) r));
337 }
338
339 static const char *
340 int_to_state(int r)
341 {
342         return(_tt_enumname((Tt_state) r));
343 }
344
345 static const char *
346 int_to_scope(int r)
347 {
348         return(_tt_enumname((Tt_scope) r));
349 }
350
351
352 // 
353 // Used to print out a generic list of integers. The given conversion
354 // function ppfn returns an appropiate string to print for each integer.
355 // See all the int_to_* functions above.
356 // 
357 static void
358 print_enum_mask(const _Tt_ostream &os, int start, int end, int mask,
359                 const char *(*ppfn)(int a))
360 {
361         int     i;
362
363         for (i=start;i <= end;i++) {
364                 if (mask&(1<<i)) {
365                         os << (*ppfn)(i) << " ";
366                 }
367         }
368 }
369
370
371 // 
372 // Used by the generic list and table packages to print out elements.
373 // Should not be used otherwise.
374 // 
375 void
376 _tt_int_rec_print(const _Tt_ostream &os, const _Tt_object *obj)
377 {
378         ((_Tt_int_rec *)obj)->print(os);
379 }
380
381
382 // 
383 // Prints out a pattern object. Used for debugging and for printing out
384 // patterns being considered when tracing is turned on. 
385 // 
386 void _Tt_pattern::
387 print(const _Tt_ostream &os) const
388 {
389         os << "id:\t\t";
390         os << _pattern_id << "\n";
391         os << "category:\t" << _tt_enumname(_category) << "\n";
392         if (_classes != 0) {
393                 os << "classes:\t";
394                 print_enum_mask(os,(int)TT_CLASS_UNDEFINED,(int)TT_CLASS_LAST,
395                                 _classes, int_to_class);
396                 os << "\n";
397         }
398         if (_states != 0) {
399                 os << "states:\t\t";
400                 print_enum_mask(os,(int)TT_CREATED, (int)TT_STATE_LAST,
401                                 _states, int_to_state);
402                 os << "\n";
403         }
404         if (_paradigms != 0) {
405                 os << "addresses:\t";
406                 print_enum_mask(os,(int)TT_PROCEDURE,(int)TT_HANDLER,
407                                 _paradigms, int_to_paradigm);
408                 os << "\n";
409         }
410         if (_scopes != 0) {
411                 os << "scopes:\t\t";
412                 print_enum_mask(os,(int)TT_SCOPE_NONE,(int)TT_FILE_IN_SESSION,
413                                 _scopes, int_to_scope);
414                 os << "\n";
415         }
416         if (_files->count()) {
417                 os << "files:\t\t";
418                 _files->print(_tt_string_print, os);
419                 os << "\n";
420         }
421         if (_sessions->count()) {
422                 os << "sessions:\t";
423                 _sessions->print(_tt_string_print, os);
424                 os << "\n";
425         }
426         if (_ops->count()) {
427                 os << "ops:\t\t";
428                 _ops->print(_tt_string_print, os);
429                 os << "\n";
430         }
431         if (_args->count()) {
432                 os << "args:\n";
433                 _Tt_string indent = os.indent();
434                 os.set_indent( indent.cat( "\t" ));
435                 _Tt_arg_list_cursor argC( _args );
436                 while (argC.next()) {   
437                         argC->print( os );
438                 }
439                 os.set_indent( indent );
440         }
441         if (_contexts->count()) {
442                 os << "contexts:\n";
443                 _Tt_string indent = os.indent();
444                 os.set_indent( indent.cat( "\t" ));
445                 _Tt_pat_context_list_cursor contextC( _contexts );
446                 while (contextC.next()) {       
447                         contextC->print( os );
448                 }
449                 os.set_indent( indent );
450         }
451         if (_opnums->count()) {
452                 os << "opnums:\t";
453                 _opnums->print(_tt_int_rec_print, os);
454                 os << "\n";
455         }
456         if (_otypes->count()) {
457                 os << "otypes:\t";
458                 _otypes->print(_tt_string_print, os);
459                 os << "\n";
460         }
461         if (_senders->count()) {
462                 os << "senders:\t";
463                 _senders->print(_tt_string_print, os);
464                 os << "\n";
465         }
466         if (_handlers->count()) {
467                 os << "handlers:\t";
468                 _handlers->print(_tt_string_print, os);
469                 os << "\n";
470         }
471         if (_sender_ptypes->count()) {
472                 os << "sender_ptypes:\t";
473                 _sender_ptypes->print(_tt_string_print, os);
474                 os << "\n";
475         }
476         if (_handler_ptypes->count()) {
477                 os << "handler_ptypes:\t";
478                 _handler_ptypes->print(_tt_string_print, os);
479                 os << "\n";
480         }
481 }