#include "cache.h"#include "string-list.h"/* if there is no exact match, point to the index where the entry could be * inserted */staticintget_entry_index(conststructstring_list*list,constchar*string,int*exact_match){intleft=-1,right=list->nr;while(left+1<right){intmiddle=(left+right)/2;intcompare=strcmp(string,list->items[middle].string);if(compare<0)right=middle;elseif(compare>0)left=middle;else{*exact_match=1;returnmiddle;}}*exact_match=0;returnright;}/* returns -1-index if already exists */staticintadd_entry(intinsert_at,structstring_list*list,constchar*string){intexact_match=0;intindex=insert_at!=-1?insert_at:get_entry_index(list,string,&exact_match);if(exact_match)return-1-index;if(list->nr+1>=list->alloc){list->alloc+=32;list->items=xrealloc(list->items,list->alloc*sizeof(structstring_list_item));}if(index<list->nr)memmove(list->items+index+1,list->items+index,(list->nr-index)*sizeof(structstring_list_item));list->items[index].string=list->strdup_strings?xstrdup(string):(char*)string;list->items[index].util=NULL;list->nr++;returnindex;}structstring_list_item*string_list_insert(structstring_list*list,constchar*string){returnstring_list_insert_at_index(list,-1,string);}structstring_list_item*string_list_insert_at_index(structstring_list*list,intinsert_at,constchar*string){intindex=add_entry(insert_at,list,string);if(index<0)index=-1-index;returnlist->items+index;}intstring_list_has_string(conststructstring_list*list,constchar*string){intexact_match;get_entry_index(list,string,&exact_match);returnexact_match;}intstring_list_find_insert_index(conststructstring_list*list,constchar*string,intnegative_existing_index){intexact_match;intindex=get_entry_index(list,string,&exact_match);if(exact_match)index=-1-(negative_existing_index?index:0);returnindex;}structstring_list_item*string_list_lookup(structstring_list*list,constchar*string){intexact_match,i=get_entry_index(list,string,&exact_match);if(!exact_match)returnNULL;returnlist->items+i;}intfor_each_string_list(structstring_list*list,string_list_each_func_tfn,void*cb_data){inti,ret=0;for(i=0;i<list->nr;i++)if((ret=fn(&list->items[i],cb_data)))break;returnret;}voidstring_list_clear(structstring_list*list,intfree_util){if(list->items){inti;if(list->strdup_strings){for(i=0;i<list->nr;i++)free(list->items[i].string);}if(free_util){for(i=0;i<list->nr;i++)free(list->items[i].util);}free(list->items);}list->items=NULL;list->nr=list->alloc=0;}voidstring_list_clear_func(structstring_list*list,string_list_clear_func_tclearfunc){if(list->items){inti;if(clearfunc){for(i=0;i<list->nr;i++)clearfunc(list->items[i].util,list->items[i].string);}if(list->strdup_strings){for(i=0;i<list->nr;i++)free(list->items[i].string);}free(list->items);}list->items=NULL;list->nr=list->alloc=0;}voidprint_string_list(conststructstring_list*p,constchar*text){inti;if(text)printf("%s\n",text);for(i=0;i<p->nr;i++)printf("%s:%p\n",p->items[i].string,p->items[i].util);}structstring_list_item*string_list_append(structstring_list*list,constchar*string){ALLOC_GROW(list->items,list->nr+1,list->alloc);list->items[list->nr].string=list->strdup_strings?xstrdup(string):(char*)string;returnlist->items+list->nr++;}staticintcmp_items(constvoid*a,constvoid*b){conststructstring_list_item*one=a;conststructstring_list_item*two=b;returnstrcmp(one->string,two->string);}voidsort_string_list(structstring_list*list){qsort(list->items,list->nr,sizeof(*list->items),cmp_items);}structstring_list_item*unsorted_string_list_lookup(structstring_list*list,constchar*string){inti;for(i=0;i<list->nr;i++)if(!strcmp(string,list->items[i].string))returnlist->items+i;returnNULL;}intunsorted_string_list_has_string(structstring_list*list,constchar*string){returnunsorted_string_list_lookup(list,string)!=NULL;}