2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
25 * $XConsortium: trav.c /main/3 1995/11/06 18:41:30 rswiston $
27 * @(#)trav.c 3.41 14 Feb 1994 cde_app_builder/src/libABobj
29 * RESTRICTED CONFIDENTIAL INFORMATION:
31 * The information in this document is subject to special
32 * restrictions in a confidential disclosure agreement between
33 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
34 * document outside HP, IBM, Sun, USL, SCO, or Univel without
35 * Sun's specific written approval. This document and all copies
36 * and derivative works thereof must be returned or destroyed at
39 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
45 * traversal.c - traversals of object trees
53 static int travP_find_first(ABTraversal trav);
54 static int travP_find_next(ABTraversal trav);
55 static int travP_find_next_parents_first(ABTraversal trav);
56 static int travP_find_first_for_parents(ABTraversal trav);
57 static int travP_find_next_for_parents(ABTraversal trav);
58 static BOOL travP_qualifies(ABTraversal trav);
59 static int travP_verify_type(ABTraversal travType, BOOL warn);
60 static ABObj find_first_item(ABObj obj);
61 static ABObj find_first_child_of_type(ABObj obj,
62 ABTraversal trav, AB_OBJECT_TYPE type);
63 static ABObj find_first_action(ABObj, ABTraversal);
64 static ABObj find_first_sibling_child(ABObj obj, ABTraversal trav);
65 static ABObj find_next_sibling_child(ABObj obj, ABTraversal trav);
66 static ABObj find_first_ancestor_sibling_child(ABObj obj, ABTraversal trav);
71 ABTraversal trav, ABObj root, unsigned travType,
72 ABObjTestFunc testFunc)
75 trav->travType= travType;
77 trav->testFunc= testFunc;
79 travP_verify_type(trav, TRUE);
85 travP_close(ABTraversal trav)
88 trav->travType= AB_TRAV_UNDEF;
93 * Restarts the traversal from the beginning. With a safe traversal,
94 * the list of objects is not recalculated.
97 travP_reset(ABTraversal trav)
106 * Hint: travP_goto(trav, -1) is equivalent to travP_reset(trav).
109 travP_goto(ABTraversal trav, int node_num)
114 for (i= 0; i <= node_num; ++i)
124 * Effects: gets the next object in the traversal
125 * Modifies: checks/sets done flag
128 travP_next(ABTraversal trav)
130 BOOL found_next= FALSE;
136 else if (trav->curObj == NULL)
138 /* starting a new traversal */
139 travP_find_first(trav);
140 found_next= ((trav->curObj == NULL) || travP_qualifies(trav));
145 travP_find_next(trav);
146 if ( (trav->curObj == NULL)
147 || (travP_qualifies(trav)) )
151 } /* while !found_next */
153 if (trav->curObj == NULL)
163 * ASSUMES: rootObj is not NULL
167 travP_find_first(ABTraversal trav)
169 #define rootObj (trav->rootObj)
170 #define curObj (trav->curObj)
173 switch (travP_get_qualifier(trav))
175 case AB_TRAV_ACTIONS_FOR_OBJ:
176 curObj= find_first_action(rootObj, trav);
179 case AB_TRAV_CHILDREN:
180 case AB_TRAV_SALIENT_CHILDREN:
181 case AB_TRAV_SALIENT_UI_CHILDREN:
182 curObj= travP_obj_first_child(rootObj, trav);
185 case AB_TRAV_COMP_SUBOBJS:
186 if (obj_is_root(rootObj))
192 case AB_TRAV_ITEMS_FOR_OBJ:
193 curObj= find_first_item(rootObj);
196 case AB_TRAV_MODULES:
197 curObj= obj_is_module(rootObj)?
200 find_first_child_of_type(rootObj, trav, AB_TYPE_MODULE);
203 case AB_TRAV_PARENTS:
204 travP_find_first_for_parents(trav);
207 case AB_TRAV_SIBLINGS:
209 ABObj prevSibling= NULL;
211 while ((prevSibling= travP_obj_prev_sibling(curObj, trav)) != NULL)
230 * Assumes: - traversal is not "done"
231 * - curObj is not NULL
234 travP_find_next(ABTraversal trav)
236 #define curObj (trav->curObj)
237 switch (travP_get_qualifier(trav))
240 * Types that return only a set of siblings
242 case AB_TRAV_ACTIONS_FOR_OBJ:
243 case AB_TRAV_CHILDREN:
244 case AB_TRAV_ITEMS_FOR_OBJ:
245 case AB_TRAV_MODULES:
246 case AB_TRAV_SALIENT_CHILDREN:
247 case AB_TRAV_SALIENT_UI_CHILDREN:
248 case AB_TRAV_SIBLINGS:
249 curObj= travP_obj_next_sibling(curObj, trav);
253 * Types that return parents
255 case AB_TRAV_PARENTS:
256 travP_find_next_for_parents(trav);
260 * Traversals that return an entire tree
263 travP_find_next_parents_first(trav);
269 } /* travP_find_next */
273 travP_find_first_for_parents(ABTraversal trav)
275 #define curObj (trav->curObj)
278 if (travP_is_parents_first(trav))
280 curObj= travP_obj_parent(trav->rootObj, trav);
283 while ((parent= travP_obj_parent(curObj, trav)) != NULL)
291 curObj= travP_obj_parent(trav->rootObj, trav);
300 travP_find_next_for_parents(ABTraversal trav)
302 #define curObj (trav->curObj)
304 if (travP_is_parents_first(trav))
306 curObj= travP_obj_first_child(curObj, trav);
307 if (curObj == trav->rootObj)
314 curObj= travP_obj_parent(curObj, trav);
321 /*****************************************************************
323 ** PARENTS_FIRST TRAVERSAL **
325 ******************************************************************/
329 * Assumes: traversal is open and not done
332 travP_find_next_parents_first(ABTraversal trav)
334 ABObj curObj= trav->curObj;
337 if (curObj == trav->rootObj)
339 curObj= travP_obj_first_child(curObj, trav);
343 if ((tmpObj= travP_obj_next_sibling(curObj, trav)) != NULL)
349 tmpObj= find_first_sibling_child(curObj, trav);
352 tmpObj= find_first_ancestor_sibling_child(curObj, trav);
358 trav->curObj= curObj;
364 find_first_item(ABObj obj)
366 ABObj compRoot= obj_get_root(obj);
370 for (child= obj->first_child; child != NULL; child= child->next_sibling)
372 if (obj_get_root(child) == compRoot)
374 /* it's a subobj - look at its children */
375 item= find_first_item(child);
383 if (obj_is_item(child))
396 * Finds the first sibling (from "left" to "right") of the object
397 * that has a child. Returns the first child of that sibling.
400 find_first_sibling_child(ABObj obj, ABTraversal trav)
404 ABObj prevSibling= NULL;
405 ABObj firstChild= NULL;
407 while ((prevSibling= travP_obj_prev_sibling(sibling, trav)) != NULL)
409 sibling= prevSibling;
412 if ((firstChild= travP_obj_first_child(sibling, trav)) != NULL)
418 child= find_next_sibling_child(sibling, trav);
425 * Finds the next sibling of the object that has a child.
426 * Returns the first child of that sibling.
429 find_next_sibling_child(ABObj obj, ABTraversal trav)
431 ABObj sibling= travP_obj_next_sibling(obj, trav);
433 ABObj firstChild= NULL;
435 while ( (sibling != NULL)
436 && ((firstChild= travP_obj_first_child(sibling, trav)) == NULL) )
438 sibling= travP_obj_next_sibling(sibling, trav);
450 * Finds the first ancestor that has a sibling to its "right"
451 * that has a child. Returns the child.
454 find_first_ancestor_sibling_child(ABObj obj, ABTraversal trav)
456 ABObj ancestor= travP_obj_parent(obj, trav);
459 for (; ((ancestor != NULL) && (ancestor != trav->rootObj));
460 ancestor= travP_obj_parent(ancestor, trav))
462 child= find_next_sibling_child(ancestor, trav);
474 * Check the new current object to see if it qualifies for the traversal.
476 * Assumes: trav->curObj is not null
479 travP_qualifies(ABTraversal trav)
481 register ABObj curObj = trav->curObj;
482 register BOOL qualifies= TRUE;
484 if (obj_has_impl_flags(curObj, ObjFlagDestroyed))
490 switch (travP_get_qualifier(trav))
492 case AB_TRAV_ACTIONS:
493 case AB_TRAV_ACTIONS_FOR_OBJ:
494 qualifies= obj_is_action(curObj);
497 case AB_TRAV_COMP_SUBOBJS:
498 qualifies = (obj_get_root(curObj) == trav->rootObj);
502 qualifies= (curObj->type == AB_TYPE_FILE);
506 qualifies= obj_is_group(curObj);
510 case AB_TRAV_ITEMS_FOR_OBJ:
511 qualifies= obj_is_item(curObj);
515 qualifies= obj_is_menu(curObj);
518 case AB_TRAV_MODULES:
519 qualifies= obj_is_module(curObj);
522 case AB_TRAV_SALIENT:
523 case AB_TRAV_SALIENT_CHILDREN:
524 qualifies= obj_is_salient(curObj);
527 case AB_TRAV_SALIENT_UI:
528 case AB_TRAV_SALIENT_UI_CHILDREN:
529 qualifies= obj_is_salient_ui(curObj);
533 qualifies= obj_is_ui(curObj);
536 case AB_TRAV_WINDOWS:
537 qualifies= obj_is_window(curObj);
541 if ((qualifies) && (trav->testFunc != NULL))
543 qualifies = trav->testFunc(curObj);
548 } /* travP_qualifies */
552 * Verifies that the traversal type is valid, and changes
556 travP_verify_type(ABTraversal trav, BOOL warn)
559 unsigned travQualifier= travP_get_qualifier(trav);
563 switch (travQualifier)
565 case AB_TRAV_ACTIONS:
566 case AB_TRAV_ACTIONS_FOR_OBJ:
568 case AB_TRAV_CHILDREN:
569 case AB_TRAV_COMP_SUBOBJS:
573 case AB_TRAV_ITEMS_FOR_OBJ:
574 case AB_TRAV_MODULES:
576 case AB_TRAV_SALIENT:
577 case AB_TRAV_SALIENT_CHILDREN:
578 case AB_TRAV_SALIENT_UI:
579 case AB_TRAV_SALIENT_UI_CHILDREN:
580 case AB_TRAV_SIBLINGS:
582 case AB_TRAV_WINDOWS:
588 case AB_TRAV_PARENTS:
589 if (travP_is_parents_first(trav) && debugging())
593 "AB_TRAV_PARENTS - Ignoring unsupported modifier "
594 "AB_TRAV_MOD_PARENTS_FIRST.");
595 trav->travType &= ~AB_TRAV_MOD_PARENTS_FIRST;
602 sprintf(errMsg, "WARNING: travType %d unknown - "
603 "Using AB_TRAV_ALL.",
606 travQualifier= AB_TRAV_ALL;
607 trav->travType &= TRAV_MODIFIER_MASK;
608 trav->travType |= travQualifier;
612 if (warn && ((*errMsg) != 0))
614 fprintf(stderr, "%s\n", errMsg);
622 * If parent is NULL, returns NULL.
625 find_first_child_of_type(ABObj parent, ABTraversal trav, AB_OBJECT_TYPE type)
633 for (child= travP_obj_first_child(parent, trav);
634 child != NULL; child= travP_obj_next_sibling(child, trav))
636 if (child->type == type)
646 find_first_action(ABObj obj, ABTraversal trav)
648 obj= find_first_child_of_type(obj, trav, AB_TYPE_ACTION_LIST);
651 obj= find_first_child_of_type(obj, trav, AB_TYPE_ACTION);