2 This file is part of the software library CADLIB written by Conrad Ziesler
3 Copyright 2003, Conrad Ziesler, all rights reserved.
5 *************************
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* list_search.c, container supporting mulitple sorted searches
26 #include "list_search.h"
28 void list_search_init(list_search_t
*lp
, int size
, int mode
)
30 list_init(&(lp
->list
),size
,mode
);
31 list_init(&(lp
->psearch
),sizeof(list_psearch_t
),LIST_DEFMODE
);
35 void list_search_empty(list_search_t
*lp
)
39 list_empty(&(lp
->list
));
40 list_iterate(&(lp
->psearch
),i
,p
)
42 if(p
->isearchdata
!=NULL
)free(p
->isearchdata
);
44 list_empty(&(lp
->list
));
49 int list_search_addrule(list_search_t
*lp
, int (*cmpf
)(const void *user
, const void *a
, const void *b
),void *user
)
57 return list_add(&(lp
->psearch
),&t
);
60 int list_search_findnext(list_search_iterator_t
*sip
)
67 if(sip
->sp
==NULL
)return -1;
68 if(sip
->last_id
<0)return -1;
69 if(id
>=sip
->sp
->list
.q
)return -1; /* last one, can't be any more */
70 psp
=list_data(&(sip
->sp
->psearch
),sip
->which
);
71 if(psp
==NULL
)return -1;
72 if(!psp
->is_sorted
)return -1;
73 if(psp
->len
!=sip
->sp
->list
.q
) return -1;
75 pa
=list_data(&(sip
->sp
->list
),psp
->isearchdata
[sip
->last_id
]);
76 pb
=list_data(&(sip
->sp
->list
),psp
->isearchdata
[id
]);
77 if((pa
!=NULL
) && (pb
!=NULL
))
78 if( psp
->cmpf(psp
->user
,pa
,pb
)==0) /* yes we match previous */
81 return psp
->isearchdata
[id
];
89 static list_t
*debug_cmpf_list
=NULL
;
90 static int (*debug_psp_cmpf
)(const void *user
,const void *a
, const void *b
);
91 static void *debug_user
;
93 int debug_cmpf(const void *a
, const void *b
)
95 const int *ap
=a
,*bp
=b
;
96 return debug_psp_cmpf(debug_user
,list_vdata(debug_cmpf_list
,ap
[0]),list_vdata(debug_cmpf_list
,bp
[0]));
99 void list_search_qsort_debug (list_search_t
*lsp
, list_psearch_t
*psp
)
101 debug_cmpf_list
=&(lsp
->list
);
102 debug_psp_cmpf
=psp
->cmpf
;
103 debug_user
=psp
->user
;
104 qsort(psp
->isearchdata
,psp
->len
,sizeof(int),debug_cmpf
);
108 int list_search_find(list_search_t
*lp
, int which
, void *key
, list_search_iterator_t
*sip
)
112 char *list_base
=lp
->list
.d
;
113 int base_size
=lp
->list
.s
;
114 int base_qty
=lp
->list
.q
;
124 if(base_size
==0)return -1;
125 if(base_qty
<=0)return -1;
128 psp
=list_data(&(lp
->psearch
),which
);
131 if(psp
->len
!=base_qty
)psp
->is_sorted
=0; /* guard against changes */
135 if(psp
->isearchdata
!=NULL
)free(psp
->isearchdata
);
136 psp
->isearchdata
=malloc(sizeof(int)*base_qty
);
137 assert(psp
->isearchdata
!=NULL
);
139 for(i
=0;i
<base_qty
;i
++) psp
->isearchdata
[i
]=i
;
140 list_search_qsort_debug(lp
,psp
);
145 base
=psp
->isearchdata
;
149 if(base
==NULL
)return -1;
154 res
= psp
->cmpf(psp
->user
, key
, (void *)(list_base
+ (base_size
*base
[idx
])));
160 if(l
>=base_qty
) return -1;
162 res
= psp
->cmpf(psp
->user
, key
, (void *)(list_base
+ (base_size
*base
[l
])));
164 { if(sip
!=NULL
)sip
->last_id
=l
; return base
[l
]; }
170 void list_search_resort(list_search_t
*lp
)
174 list_iterate(&(lp
->psearch
),i
,ps
)
178 if(ps
->isearchdata
!=NULL
)free(ps
->isearchdata
);