Collaboration diagram for Linked Lists:
![]() |
Files | |
file | list.c |
Support routines for linked lists. | |
Data Structures | |
struct | bu_list |
Defines | |
#define | BU_LIST_HEAD_MAGIC 0x01016580 |
#define | BU_LIST_NULL ((struct bu_list *)0) |
#define | BU_LIST_CLOSE(hp) |
#define | BU_LIST_INSERT(old, new) |
#define | BU_LIST_APPEND(old, new) |
#define | BU_LIST_DEQUEUE(cur) |
#define | BU_LIST_DQ(cur) |
#define | BU_LIST_DQ_T(cur, type) |
#define | BU_LIST_DEQUEUE_T(cur, type) |
#define | BU_LIST_PUSH(hp, p) BU_LIST_APPEND(hp, (struct bu_list *)(p)) |
#define | BU_LIST_POP(structure, hp, p) |
#define | BU_LIST_POP_T(hp, type) (type *)bu_list_pop( hp ) |
#define | BU_LIST_INSERT_LIST(dest_hp, src_hp) |
#define | BU_LIST_APPEND_LIST(dest_hp, src_hp) |
#define | BU_LIST_IS_EMPTY(hp) ((hp)->forw == (hp)) |
#define | BU_LIST_NON_EMPTY(hp) ((hp)->forw != (hp)) |
#define | BU_LIST_NON_EMPTY_P(p, structure, hp) (((p)=(struct structure *)((hp)->forw)) != (struct structure *)(hp)) |
#define | BU_LIST_IS_CLEAR(hp) |
#define | BU_LIST_UNINITIALIZED(hp) ((hp)->forw == BU_LIST_NULL) |
#define | BU_LIST_IS_INITIALIZED(hp) ((hp)->forw != BU_LIST_NULL) |
#define | BU_LIST_INIT(hp) |
#define | BU_LIST_MAGIC_SET(hp, val) {(hp)->magic = (val);} |
#define | BU_LIST_MAGIC_OK(hp, val) ((hp)->magic == (val)) |
#define | BU_LIST_MAGIC_WRONG(hp, val) ((hp)->magic != (val)) |
#define | BU_LIST_LAST(structure, hp) ((struct structure *)((hp)->back)) |
#define | BU_LIST_BACK(structure, hp) ((struct structure *)((hp)->back)) |
#define | BU_LIST_PREV(structure, hp) ((struct structure *)((hp)->back)) |
#define | BU_LIST_FIRST(structure, hp) ((struct structure *)((hp)->forw)) |
#define | BU_LIST_FORW(structure, hp) ((struct structure *)((hp)->forw)) |
#define | BU_LIST_NEXT(structure, hp) ((struct structure *)((hp)->forw)) |
#define | BU_LIST_IS_HEAD(p, hp) (((struct bu_list *)(p)) == (hp)) |
#define | BU_LIST_NOT_HEAD(p, hp) (((struct bu_list *)(p)) != (hp)) |
#define | BU_CK_LIST_HEAD(_p) BU_CKMAG( (_p), BU_LIST_HEAD_MAGIC, "bu_list") |
#define | BU_LIST_PREV_IS_HEAD(p, hp) (((struct bu_list *)(p))->back == (hp)) |
#define | BU_LIST_PREV_NOT_HEAD(p, hp) (((struct bu_list *)(p))->back != (hp)) |
#define | BU_LIST_NEXT_IS_HEAD(p, hp) (((struct bu_list *)(p))->forw == (hp)) |
#define | BU_LIST_NEXT_NOT_HEAD(p, hp) (((struct bu_list *)(p))->forw != (hp)) |
#define | BU_LIST_EACH(hp, p, type) |
#define | BU_LIST_REVEACH(hp, p, type) |
#define | BU_LIST_TAIL(hp, start, p, type) |
#define | BU_LIST_FOR(p, structure, hp) |
#define | BU_LIST_FOR_BACKWARDS(p, structure, hp) |
#define | BU_LIST_FOR_CIRC(p, structure, hp) |
#define | BU_LIST_FOR2(p1, p2, structure, hp1, hp2) |
#define | BU_LIST_WHILE(p, structure, hp) (((p)=(struct structure *)((hp)->forw)) != (struct structure *)(hp)) |
#define | BU_LIST_FIRST_MAGIC(hp) ((hp)->forw->magic) |
#define | BU_LIST_LAST_MAGIC(hp) ((hp)->back->magic) |
#define | BU_LIST_PNEXT(structure, p) ((struct structure *)(((struct bu_list *)(p))->forw)) |
#define | BU_LIST_PLAST(structure, p) ((struct structure *)(((struct bu_list *)(p))->back)) |
#define | BU_LIST_PNEXT_PNEXT(structure, p) ((struct structure *)(((struct bu_list *)(p))->forw->forw)) |
#define | BU_LIST_PNEXT_PLAST(structure, p) ((struct structure *)(((struct bu_list *)(p))->forw->back)) |
#define | BU_LIST_PLAST_PNEXT(structure, p) ((struct structure *)(((struct bu_list *)(p))->back->forw)) |
#define | BU_LIST_PLAST_PLAST(structure, p) ((struct structure *)(((struct bu_list *)(p))->back->back)) |
#define | BU_LIST_PNEXT_CIRC(structure, p) |
#define | BU_LIST_PPREV_CIRC(structure, p) |
#define | BU_LIST_MAIN_PTR(_type, _ptr2, _name2) ((struct _type *)(((char *)(_ptr2)) - offsetof(struct _type, _name2.magic))) |
Typedefs | |
typedef bu_list | bu_list_t |
Functions | |
bu_list * | bu_list_new () |
bu_list * | bu_list_pop (struct bu_list *hp) |
int | bu_list_len (const struct bu_list *hd) |
void | bu_list_reverse (struct bu_list *hd) |
void | bu_list_free (struct bu_list *hd) |
void | bu_list_parallel_append (struct bu_list *headp, struct bu_list *itemp) |
bu_list * | bu_list_parallel_dequeue (struct bu_list *headp) |
void | bu_ck_list (const struct bu_list *hd, const char *str) |
void | bu_ck_list_magic (const struct bu_list *hd, const char *str, const long magic) |
int | bu_list_len (register const struct bu_list *hd) |
void | bu_list_reverse (register struct bu_list *hd) |
void | bu_ck_list_magic (const struct bu_list *hd, const char *str, const long int magic) |
bu_list * | bu_list_dequeue_next (struct bu_list *hp, struct bu_list *p) |
Doubly-linked list support
These macros assume that all user-provided structures will have a "struct bu_list" as their first element (often named "l" [ell]). Thus, a pointer to the bu_list struct is a "pun" for the user-provided structure as well, and the pointers can be converted back and forth safely with type casts.
Furthermore, the head of the linked list could be a full instance of the user-provided structure (although the storage-conscious programmer could make the head just an bu_list structure, with careful type casting). This results in a doubly-linked circular list, with the head having the same shape as all the list members. The application is free to make use of this symmetry and store data values in the head, or the extra storage in the head can be ignored.
Where a macro expects an argument "p", it should be a pointer to a user-provided structure.
Where a macro expects an argument "hp", it should be a pointer to a "struct bu_list" located in the list head, e.g., &(head.l).
Where a macro expects an argument "old", "new", or "cur", it should be a pointer to the "struct bu_list" located either in a user-provided structure, e.g. &((p)->l), or for the case of "old" it may also be in the list head, e.g. BU_LIST_INSERT( &(head.l), &((p)->l) );
Dequeueing the head of a list is a valid and well defined operation which should be performed with caution. Unless a pointer to some other element of the list is retained by the application, the rest of the linked list can no longer be referred to.
The "magic" field of the list header _must_ be set to the constant BU_LIST_HEAD_MAGIC, but the "magic" field of all list members should be established by user code, to identify the type of structure that the bu_list structure is embedded in. It is permissible for one list to contain an arbitrarily mixed set of user "magic" numbers, as long as the head is properly marked.
There is a dual set of terminology used in some of the macros: FIRST / LAST from the point of view of the list head NEXT / PREV from the point of view of a list member forw / back the actual pointer names
|
Definition at line 526 of file bu.h. Referenced by bu_ck_list(), bu_ck_list_magic(), bu_identify_magic(), get_solidbitv(), nmg_index_of_struct(), nmg_klu(), and nmg_vvu(). |
|
Definition at line 527 of file bu.h. Referenced by bu_bitv_free(), bu_realloc(), and rt_nmg_idisk(). |
|
Value: { \ assert( (hp) != NULL ); \ if( (hp) == NULL ) \ return; \ assert( BU_LIST_IS_EMPTY( (hp) ) ); \ bu_list_free( (hp) ); \ bu_free( (char *)(hp), "bu_list head" ); \ } |
|
|
|
|
Value: {\ (cur)->forw->back = (cur)->back; \ (cur)->back->forw = (cur)->forw; } |
|
Value: (\ (cur)->forw->back = (cur)->back, \ (cur)->back->forw = (cur)->forw, \ (type *)(cur) ) |
|
Value: (\ (cur)->forw->back = (cur)->back, \ (cur)->back->forw = (cur)->forw, \ (cur)->forw = (cur)->back = BU_LIST_NULL, \ (type *)(cur) ) |
|
|
|
Value: { \ if (BU_LIST_NON_EMPTY(hp)) \ { \ (p) = ((struct structure *)((hp)->forw)); \ BU_LIST_DEQUEUE((struct bu_list *)(p)); \ } \ else \ (p) = (struct structure *) 0; \ } Definition at line 602 of file bu.h. Referenced by bu_list_pop(). |
|
|
|
Value: if( BU_LIST_NON_EMPTY(src_hp) ) { \ register struct bu_list *_first = (src_hp)->forw; \ register struct bu_list *_last = (src_hp)->back; \ (dest_hp)->forw->back = _last; \ _last->forw = (dest_hp)->forw; \ (dest_hp)->forw = _first; \ _first->back = (dest_hp); \ (src_hp)->forw = (src_hp)->back = (src_hp); \ } BU_LIST_INSERT_LIST places src_hd elements at head of dest_hd list, BU_LIST_APPEND_LIST places src_hd elements at end of dest_hd list. Definition at line 624 of file bu.h. Referenced by bu_list_reverse(), eval_etree(), and eval_op(). |
|
Value: if( BU_LIST_NON_EMPTY(src_hp) ) {\ register struct bu_list *_first = (src_hp)->forw; \ register struct bu_list *_last = (src_hp)->back; \ _first->back = (dest_hp)->back; \ (dest_hp)->back->forw = _first; \ (dest_hp)->back = _last; \ _last->forw = (dest_hp); \ (src_hp)->forw = (src_hp)->back = (src_hp); \ } Definition at line 635 of file bu.h. Referenced by dgo_drawH_part2(), dgo_invent_solid(), nmg_merge_models(), rt_dsp_shot(), and subdivide_bezier(). |
|
Test if a doubly linked list is empty, given head pointer Definition at line 647 of file bu.h. Referenced by bu_flog(), bu_log(), bu_putchar(), dgo_autoview(), dgo_cvt_vlblock_to_solids(), dgo_get_autoview_cmd(), eval_op(), get_solidbitv(), make_near_list(), nmg_isect_ray_model(), nmg_keu(), nmg_kfu(), nmg_kill_snakes(), nmg_klu(), nmg_kr(), nmg_ks(), nmg_kvu(), nmg_ml(), nmg_move_lu_between_fus(), nmg_movevu(), nmg_mv_eu_between_shells(), nmg_mv_fu_between_shells(), nmg_mv_lu_between_shells(), nmg_mv_shell_to_region(), nmg_radial_sorted_list_insert(), nmg_ray_segs(), nmg_sanitize_s_lv(), nmg_shell_a(), nmg_shell_manifolds(), nmg_simplify_face(), nmg_simplify_shell_edges(), rt_dsp_shot(), rt_ebm_dda(), rt_nmg_tess(), rt_pipe_plot(), rt_pipe_prep(), rt_pipe_tess(), rt_plot_solid(), rt_plot_vlblock(), rt_shootray(), rt_shootray_bundle(), rt_vlblock_free(), rt_vol_shot(), show_seg(), and wdb_do_paren(). |
|
|
|
|
Value: ((hp)->magic == 0 && \ (hp)->forw == BU_LIST_NULL && \ (hp)->back == BU_LIST_NULL) |
|
Definition at line 656 of file bu.h. Referenced by bn_vlblock_init(), bn_vlist_cleanup(), bu_open_mapped_file(), dgo_E_cmd(), nmg_class_ray_vs_shell(), rt_cell_n_on_ray(), rt_cut_clean(), rt_get_seg(), Rt_Init(), rt_init_resource(), rt_shootray(), and rt_shootray_bundle(). |
|
Definition at line 657 of file bu.h. Referenced by rt_clean_resource(), and rt_free_rti(). |
|
|
Definition at line 661 of file bu.h. Referenced by bu_realloc(), isect_ray_lseg(), isect_ray_planar_face(), and nmg_flatten_face(). |
|
|
|
Definition at line 663 of file bu.h. Referenced by bu_free(), bu_realloc(), and rt_shootray(). |
|
Definition at line 668 of file bu.h. Referenced by dgo_drawH_part2(), dgo_invent_solid(), nmg_dup_loop(), nmg_edge_collapse(), nmg_extrude_cleanup(), rt_ebm_dda(), rt_extrude_plot(), rt_pipe_shot(), rt_pipe_tcladjust(), rt_process_uplot_value(), rt_tgc_tnurb(), and rt_vol_shot(). |
|
|
|
Definition at line 672 of file bu.h. Referenced by bu_cmdhist_history(), nmg_radial_sorted_list_insert(), nmg_shell_coplanar_face_merge(), nmg_simplify_face(), nmg_simplify_shell(), rt_pipe_hitsort(), tesselate_pipe_end(), wdb_do_inter(), wdb_do_paren(), and wdb_do_union_subtr(). |
|
|
|
|
|
Definition at line 682 of file bu.h. Referenced by bu_cmdhist_next(), dgo_get_eyemodel_cmd(), eliminate_overlaps(), nmg_fix_overlapping_loops(), nmg_shell_coplanar_face_merge(), promote_ints(), rt_pipe_hitsort(), rt_pipe_plot(), rt_pipe_prep(), rt_pipe_tess(), and wdb_which_cmd(). |
|
|
|
|
|
|
|
Definition at line 695 of file bu.h. Referenced by nmg_shell_coplanar_face_merge(). |
|
Definition at line 697 of file bu.h. Referenced by nmg_to_arb(), nmg_to_tgc(), rt_nmg_tess(), and rt_pipe_hitsort(). |
|
Value: for( (p)=(type *)BU_LIST_FIRST(bu_list,hp); \ BU_LIST_NOT_HEAD(p,hp); \ (p)=(type *)BU_LIST_PNEXT(bu_list,p) ) \ |
|
Value: for( (p)=(type *)BU_LIST_LAST(bu_list,hp); \ BU_LIST_NOT_HEAD(p,hp); \ (p)=(type *)BU_LIST_PREV(bu_list,((struct bu_list *)(p))) ) \ |
|
Value: for( (p)=(type *)start ; \ BU_LIST_NOT_HEAD(p,hp); \ (p)=(type *)BU_LIST_PNEXT(bu_list,(p)) ) |
|
|
Value: (p)=BU_LIST_LAST(structure,hp); \ BU_LIST_NOT_HEAD(p,hp); \ (p)=BU_LIST_PLAST(structure,p) Definition at line 726 of file bu.h. Referenced by nmg_radial_sorted_list_insert(), and rt_nmg_tclget(). |
|
Value: (p)=BU_LIST_PNEXT_CIRC(structure,hp); \ (p) != (hp); \ (p)=BU_LIST_PNEXT_CIRC(structure,p) Definition at line 735 of file bu.h. Referenced by nmg_radial_check_parity(), and nmg_radial_mark_flips(). |
|
Value: (p1)=BU_LIST_FIRST(structure,hp1), \ (p2)=BU_LIST_FIRST(structure,hp2); \ BU_LIST_NOT_HEAD((struct bu_list *)(p1),(hp1)) && \ BU_LIST_NOT_HEAD((struct bu_list *)(p2),(hp2)); \ (p1)=BU_LIST_NEXT(structure,(struct bu_list *)(p1)), \ (p2)=BU_LIST_NEXT(structure,(struct bu_list *)(p2)) Definition at line 747 of file bu.h. Referenced by nmg_extrude_face(). |
|
Innards for a while() loop that constantly picks off the first element. Useful mostly for a loop that will dequeue every list element, e.g.: while( BU_LIST_WHILE(p, structure, hp) ) { Definition at line 763 of file bu.h. Referenced by bn_vlist_cleanup(), bu_list_free(), bu_list_reverse(), bu_rb_free(), classify_seg(), eval_op(), nmg_class_ray_vs_shell(), nmg_eu_radial_check(), nmg_radial_join_eu_NEW(), nmg_radial_merge_lists(), nmg_s_radial_harmonize(), nmg_triangulate_fu(), rt_clean(), rt_clean_resource(), rt_metaball_ifree(), rt_nurb_bezier(), rt_nurb_free(), rt_nurb_intersect(), rt_pipe_hitsort(), rt_pipe_ifree(), rt_pipe_shot(), rt_process_casec(), rt_seg_planeclip(), shoot_and_plot(), and wdb_free_tokens(). |
|
|
|
|
Return pointer to next (or previous) element, which may be the head Definition at line 771 of file bu.h. Referenced by bu_cmdhist_next(), bu_observer_free(), dgo_zap_cmd(), eliminate_overlaps(), eval_op(), make_near_list(), nmg_break_crossed_loops(), nmg_class_shells(), nmg_classify_lu_lu(), nmg_do_radial_flips(), nmg_eusplit(), nmg_extrude_cleanup(), nmg_find_pt_in_shell(), nmg_fix_overlapping_loops(), nmg_js(), nmg_jv(), nmg_kill_cracks(), nmg_kill_non_common_cracks(), nmg_kill_snakes(), nmg_kill_zero_length_edgeuses(), nmg_pr_lu(), nmg_pr_lu_briefly(), nmg_radial_mark_cracks(), nmg_rm_redundancies(), nmg_sanitize_fu(), nmg_sanitize_s_lv(), nmg_shell_a(), nmg_simplify_loop(), nmg_simplify_shell_edges(), nmg_split_loops_handler(), nmg_triangulate_fu(), nmg_vlblock_lu(), promote_ints(), rt_ebm_tess(), and rt_nmg_tess(). |
|
Definition at line 773 of file bu.h. Referenced by bu_cmdhist_prev(), bu_delete_hook(), bu_log_delete_hook(), make_near_list(), nmg_extrude_cleanup(), nmg_sanitize_s_lv(), nmg_simplify_loop(), and promote_ints(). |
|
Return pointer two links away, which may include the head Definition at line 777 of file bu.h. Referenced by nmg_class_shells(), nmg_find_pt_in_shell(), and nmg_sanitize_s_lv(). |
|
Definition at line 779 of file bu.h. Referenced by nmg_ck_fu(), nmg_vlu(), nmg_vregion(), and nmg_vvu(). |
|
Definition at line 781 of file bu.h. Referenced by nmg_ck_fu(). |
|
|
|
|
Value: ((BU_LIST_LAST_MAGIC((struct bu_list *)(p)) == BU_LIST_HEAD_MAGIC) ? \ BU_LIST_PLAST_PLAST(structure,(struct bu_list *)(p)) : \ BU_LIST_PLAST(structure,p) ) Definition at line 793 of file bu.h. Referenced by nmg_assess_eu(), nmg_assess_vu(), nmg_break_all_es_on_v(), nmg_ck_eu(), nmg_class_pt_euvu(), nmg_classify_lu_lu(), nmg_do_radial_flips(), nmg_do_radial_join(), nmg_face_state_transition(), nmg_find_eu_leftvec(), nmg_find_first_last_use_of_v_in_fu(), nmg_find_isect_faces(), nmg_insert_vu_if_on_edge(), nmg_join_2loops(), nmg_join_2singvu_loops(), nmg_join_singvu_loop(), nmg_kill_accordions(), nmg_kill_anti_loops(), nmg_kill_cracks(), nmg_kill_cracks_at_vertex(), nmg_move_edge_thru_pt(), nmg_offset_eu_vert(), nmg_radial_implement_decisions(), nmg_radial_mark_flips(), nmg_radial_verify_pointers(), nmg_veu(), and nmg_vu_angle_measure(). |
|
Support for membership on multiple linked lists. When a structure of type '_type' contains more than one bu_list structure within it (such as the NMG edgeuse), this macro can be used to convert a pointer '_ptr2' to a "midway" bu_list structure (an element called '_name2' in structure '_type') back into a pointer to the overall enclosing structure. Examples: eu = BU_LIST_MAIN_PTR( edgeuse, midway, l2 ); eu1 = BU_LIST_MAIN_PTR(edgeuse, BU_LIST_FIRST(bu_list, &eg1->eu_hd2), l2); Files using BU_LIST_MAIN_PTR will need to include stddef.h Definition at line 813 of file bu.h. Referenced by nmg_ck_eg_verts(), nmg_common_v_2eg(), nmg_edgeuse_with_eg_tabulate(), nmg_index_of_struct(), nmg_jeg(), nmg_model_edge_g_fuse(), nmg_veg(), and rt_find_identical_solid(). |
|
|
|
B U _ L I S T _ N E W Creates and initializes a bu_list head structure Definition at line 57 of file list.c. References BU_GETSTRUCT, and BU_LIST_INIT. |
|
B U _ L I S T _ P O P Returns the results of BU_LIST_POP Definition at line 73 of file list.c. References BU_LIST_POP. |
|
Referenced by nmg_insure_radial_list_is_increasing(), nmg_pl_hitmiss_list(), nmg_pr_eg(), nmg_unbreak_edge(), and nmg_unbreak_handler(). |
|
Referenced by nmg_insure_radial_list_is_increasing(). |
|
B U _ L I S T _ F R E E Given a list of structures allocated with bu_malloc() enrolled on a bu_list head, walk the list and free the structures. This routine can only be used when the structures have no interior pointers. Definition at line 130 of file list.c. References bu_free(), BU_LIST_DEQUEUE, and BU_LIST_WHILE. Here is the call graph for this function: ![]() |
|
B U _ L I S T _ P A R A L L E L _ A P P E N D Simple parallel-safe routine for appending a data structure to the end of a bu_list doubly-linked list.
Definition at line 150 of file list.c. References BU_LIST_INSERT, BU_SEM_LISTS, bu_semaphore_acquire(), and bu_semaphore_release(). Here is the call graph for this function: ![]() |
|
B U _ L I S T _ P A R A L L E L _ D E Q U E U E Simple parallel-safe routine for dequeueing one data structure from the head of a bu_list doubly-linked list. If the list is empty, wait until some other thread puts something on the list.
Definition at line 170 of file list.c. References BU_LIST_DEQUEUE, BU_LIST_FIRST, BU_LIST_NOT_HEAD, BU_SEM_LISTS, bu_semaphore_acquire(), and bu_semaphore_release(). Here is the call graph for this function: ![]() |
|
B U _ C K _ L I S T Generic bu_list doubly-linked list checker. Definition at line 198 of file list.c. References back, bu_bomb(), BU_LIST_HEAD_MAGIC, bu_log(), forw, and magic. Here is the call graph for this function: ![]() |
|
|
|
B U _ L I S T _ L E N Returns the number of elements on a bu_list brand linked list. Definition at line 88 of file list.c. References BU_LIST_FOR. |
|
B U _ L I S T _ R E V E R S E Reverses the order of elements in a bu_list linked list. Definition at line 105 of file list.c. References BU_CK_LIST_HEAD, BU_LIST_APPEND, BU_LIST_DEQUEUE, BU_LIST_INIT, BU_LIST_INSERT_LIST, and BU_LIST_WHILE. |
|
B U _ C K _ L I S T _ M A G I C bu_list doubly-linked list checker which checks the magic number for all elements in the linked list Definition at line 242 of file list.c. References back, bu_bomb(), bu_identify_magic(), BU_LIST_HEAD_MAGIC, bu_log(), forw, and magic. Here is the call graph for this function: ![]() |
|
Definition at line 297 of file list.c. References BU_LIST_DEQUEUE, and BU_LIST_NEXT. |