diff options
Diffstat (limited to 'navit/search.c')
-rw-r--r-- | navit/search.c | 1784 |
1 files changed, 846 insertions, 938 deletions
diff --git a/navit/search.c b/navit/search.c index 139feef58..c875f56b1 100644 --- a/navit/search.c +++ b/navit/search.c @@ -48,46 +48,42 @@ static void search_list_street_destroy(struct search_list_street *this_); static void search_list_house_number_destroy(struct search_list_house_number *this_); struct search_list_level { - struct mapset *ms; - struct search_list_common *parent; - struct attr *attr; - int partial; - int selected; - struct mapset_search *search; - GHashTable *hash; - GList *list,*curr,*last; + struct mapset *ms; + struct search_list_common *parent; + struct attr *attr; + int partial; + int selected; + struct mapset_search *search; + GHashTable *hash; + GList *list,*curr,*last; }; struct search_list { - struct mapset *ms; - struct item *item; - int level; - struct search_list_level levels[4]; - struct search_list_result result; - struct search_list_result last_result; - int last_result_valid; - char *postal; - struct house_number_interpolation inter; - int use_address_results; - GList *address_results,*address_results_pos; + struct mapset *ms; + struct item *item; + int level; + struct search_list_level levels[4]; + struct search_list_result result; + struct search_list_result last_result; + int last_result_valid; + char *postal; + struct house_number_interpolation inter; + int use_address_results; + GList *address_results,*address_results_pos; }; -static guint -search_item_hash_hash(gconstpointer key) -{ - const struct item *itm=key; - gconstpointer hashkey=(gconstpointer)GINT_TO_POINTER(itm->id_hi^itm->id_lo); - return g_direct_hash(hashkey); +static guint search_item_hash_hash(gconstpointer key) { + const struct item *itm=key; + gconstpointer hashkey=(gconstpointer)GINT_TO_POINTER(itm->id_hi^itm->id_lo); + return g_direct_hash(hashkey); } -static gboolean -search_item_hash_equal(gconstpointer a, gconstpointer b) -{ - const struct item *itm_a=a; - const struct item *itm_b=b; - if (item_is_equal_id(*itm_a, *itm_b)) - return TRUE; - return FALSE; +static gboolean search_item_hash_equal(gconstpointer a, gconstpointer b) { + const struct item *itm_a=a; + const struct item *itm_b=b; + if (item_is_equal_id(*itm_a, *itm_b)) + return TRUE; + return FALSE; } /** @@ -97,14 +93,13 @@ search_item_hash_equal(gconstpointer a, gconstpointer b) * @returns new search_list */ struct search_list * -search_list_new(struct mapset *ms) -{ - struct search_list *ret; +search_list_new(struct mapset *ms) { + struct search_list *ret; - ret=g_new0(struct search_list, 1); - ret->ms=ms; + ret=g_new0(struct search_list, 1); + ret->ms=ms; - return ret; + return ret; } static void search_list_search_free(struct search_list *sl, int level); @@ -114,226 +109,210 @@ static void search_list_search_free(struct search_list *sl, int level); * @param attr_type attribute value * @return corresponding search list level (country=0, town=1, ...) */ -int -search_list_level(enum attr_type attr_type) -{ - switch(attr_type) { - case attr_country_all: - case attr_country_id: - case attr_country_iso2: - case attr_country_iso3: - case attr_country_car: - case attr_country_name: - return 0; - case attr_town_postal: - return 1; - case attr_town_name: - case attr_district_name: - case attr_town_or_district_name: - return 1; - case attr_street_name: - return 2; - case attr_house_number: - return 3; - case attr_postal: - return -1; - default: - dbg(lvl_error,"unknown search '%s'\n",attr_to_name(attr_type)); - return -1; - } -} - -static char * -search_fix_spaces(char *str) -{ - int i; - int len=strlen(str); - char c,*s,*d,*ret=g_strdup(str); - - for (i = 0 ; i < len ; i++) { - if (ret[i] == ',' || ret[i] == ',' || ret[i] == '/') - ret[i]=' '; - } - s=ret; - d=ret; - len=0; - do { - c=*s++; - if (c != ' ' || len != 0) { - *d++=c; - len++; - } - while (c == ' ' && *s == ' ') - s++; - if (c == ' ' && *s == '\0') { - d--; - len--; - } - } while (c); - return ret; +int search_list_level(enum attr_type attr_type) { + switch(attr_type) { + case attr_country_all: + case attr_country_id: + case attr_country_iso2: + case attr_country_iso3: + case attr_country_car: + case attr_country_name: + return 0; + case attr_town_postal: + return 1; + case attr_town_name: + case attr_district_name: + case attr_town_or_district_name: + return 1; + case attr_street_name: + return 2; + case attr_house_number: + return 3; + case attr_postal: + return -1; + default: + dbg(lvl_error,"unknown search '%s'",attr_to_name(attr_type)); + return -1; + } +} + +static char *search_fix_spaces(char *str) { + int i; + int len=strlen(str); + char c,*s,*d,*ret=g_strdup(str); + + for (i = 0 ; i < len ; i++) { + if (ret[i] == ',' || ret[i] == ',' || ret[i] == '/') + ret[i]=' '; + } + s=ret; + d=ret; + len=0; + do { + c=*s++; + if (c != ' ' || len != 0) { + *d++=c; + len++; + } + while (c == ' ' && *s == ' ') + s++; + if (c == ' ' && *s == '\0') { + d--; + len--; + } + } while (c); + return ret; } struct phrase { - char *start; - char *end; - int wordcount; + char *start; + char *end; + int wordcount; }; -static GList * -search_split_phrases(char *str) -{ - char *s,*d; - int wordcount=0; - GList *ret=NULL; - s=str; - do { - d=s; - wordcount=0; - do { - d++; - if (*d == ' ' || *d == '\0') { - struct phrase *phrase=g_new(struct phrase, 1); - phrase->start=s; - phrase->end=d; - phrase->wordcount=++wordcount; - ret=g_list_append(ret, phrase); - } - } while (*d != '\0'); - do { - s++; - if (*s == ' ') { - s++; - break; - } - } while (*s != '\0'); - } while (*s != '\0'); - return ret; -} - -static char * -search_phrase_str(struct phrase *p) -{ - int len=p->end-p->start; - char *ret=g_malloc(len+1); - strncpy(ret, p->start, len); - ret[len]='\0'; - return ret; -} - -static int -search_phrase_used(struct phrase *p, GList *used_phrases) -{ - while (used_phrases) { - struct phrase *pu=used_phrases->data; - dbg(lvl_debug,"'%s'-'%s' vs '%s'-'%s'\n",p->start,p->end,pu->start,pu->end); - if (p->start < pu->end && p->end > pu->start) - return 1; - dbg(lvl_debug,"unused\n"); - used_phrases=g_list_next(used_phrases); - } - return 0; -} - -static gint -search_by_address_compare(gconstpointer a, gconstpointer b) -{ - const struct search_list_result *slra=a; - const struct search_list_result *slrb=b; - return slrb->id-slra->id; -} - - -static GList * -search_by_address_attr(GList *results, struct search_list *sl, GList *phrases, GList *exclude, enum attr_type attr_type, int wordcount) -{ - GList *tmp=phrases; - struct attr attr; - attr.type=attr_type; - while (tmp) { - if (!search_phrase_used(tmp->data, exclude)) { - struct phrase *p=tmp->data; - int count=0,wordcount_all=wordcount+p->wordcount; - struct search_list_result *slr; - attr.u.str=search_phrase_str(p); - dbg(lvl_debug,"%s phrase '%s'\n",attr_to_name(attr_type),attr.u.str); - search_list_search(sl, &attr, 0); - while ((slr=search_list_get_result(sl))) { - if (attr_type != attr_country_all) { - struct search_list_result *slrd=search_list_result_dup(slr); - slrd->id=wordcount_all; - results=g_list_insert_sorted(results, slrd, search_by_address_compare); - } - count++; - } - dbg(lvl_debug,"%d results wordcount %d\n",count,wordcount_all); - if (count) { - GList *used=g_list_prepend(g_list_copy(exclude), tmp->data); - enum attr_type new_attr_type=attr_none; - switch (attr_type) { - case attr_country_all: - new_attr_type=attr_town_or_district_name; - break; - case attr_town_or_district_name: - new_attr_type=attr_street_name; - break; - case attr_street_name: - new_attr_type=attr_house_number; - break; - default: - break; - } - if (new_attr_type != attr_none) - results=search_by_address_attr(results, sl, phrases, used, new_attr_type, wordcount_all); - g_list_free(used); - } - g_free(attr.u.str); - } - tmp=g_list_next(tmp); - } - return results; -} - -static void -search_by_address(struct search_list *this_, char *addr) -{ - char *str=search_fix_spaces(addr); - GList *tmp,*phrases=search_split_phrases(str); - struct search_list *sl=search_list_new(this_->ms); - this_->address_results=search_by_address_attr(NULL, sl, phrases, NULL, attr_country_all, 0); - this_->address_results_pos=this_->address_results; - search_list_destroy(sl); - tmp=phrases; - while (tmp) { - g_free(tmp->data); - tmp=g_list_next(tmp); - } - g_list_free(phrases); - // TODO: Looks like we should g_free(str) here. But this is - // currently dead code, so no way to test it. -} - -static void -search_address_results_free(struct search_list *this_) -{ - GList *tmp; - tmp=this_->address_results; - while (tmp) { - struct search_list_result *slr=tmp->data; - if (slr->country) - search_list_country_destroy(slr->country); - if (slr->town) - search_list_town_destroy(slr->town); - if (slr->street) - search_list_street_destroy(slr->street); - if (slr->house_number) - search_list_house_number_destroy(slr->house_number); - if (slr->c) - g_free(slr->c); - g_free(slr); - tmp=g_list_next(tmp); - } - g_list_free(this_->address_results); - this_->address_results=this_->address_results_pos=NULL; +static GList *search_split_phrases(char *str) { + char *s,*d; + int wordcount=0; + GList *ret=NULL; + s=str; + do { + d=s; + wordcount=0; + do { + d++; + if (*d == ' ' || *d == '\0') { + struct phrase *phrase=g_new(struct phrase, 1); + phrase->start=s; + phrase->end=d; + phrase->wordcount=++wordcount; + ret=g_list_append(ret, phrase); + } + } while (*d != '\0'); + do { + s++; + if (*s == ' ') { + s++; + break; + } + } while (*s != '\0'); + } while (*s != '\0'); + return ret; +} + +static char *search_phrase_str(struct phrase *p) { + int len=p->end-p->start; + char *ret=g_malloc(len+1); + strncpy(ret, p->start, len); + ret[len]='\0'; + return ret; +} + +static int search_phrase_used(struct phrase *p, GList *used_phrases) { + while (used_phrases) { + struct phrase *pu=used_phrases->data; + dbg(lvl_debug,"'%s'-'%s' vs '%s'-'%s'",p->start,p->end,pu->start,pu->end); + if (p->start < pu->end && p->end > pu->start) + return 1; + dbg(lvl_debug,"unused"); + used_phrases=g_list_next(used_phrases); + } + return 0; +} + +static gint search_by_address_compare(gconstpointer a, gconstpointer b) { + const struct search_list_result *slra=a; + const struct search_list_result *slrb=b; + return slrb->id-slra->id; +} + + +static GList *search_by_address_attr(GList *results, struct search_list *sl, GList *phrases, GList *exclude, + enum attr_type attr_type, + int wordcount) { + GList *tmp=phrases; + struct attr attr; + attr.type=attr_type; + while (tmp) { + if (!search_phrase_used(tmp->data, exclude)) { + struct phrase *p=tmp->data; + int count=0,wordcount_all=wordcount+p->wordcount; + struct search_list_result *slr; + attr.u.str=search_phrase_str(p); + dbg(lvl_debug,"%s phrase '%s'",attr_to_name(attr_type),attr.u.str); + search_list_search(sl, &attr, 0); + while ((slr=search_list_get_result(sl))) { + if (attr_type != attr_country_all) { + struct search_list_result *slrd=search_list_result_dup(slr); + slrd->id=wordcount_all; + results=g_list_insert_sorted(results, slrd, search_by_address_compare); + } + count++; + } + dbg(lvl_debug,"%d results wordcount %d",count,wordcount_all); + if (count) { + GList *used=g_list_prepend(g_list_copy(exclude), tmp->data); + enum attr_type new_attr_type=attr_none; + switch (attr_type) { + case attr_country_all: + new_attr_type=attr_town_or_district_name; + break; + case attr_town_or_district_name: + new_attr_type=attr_street_name; + break; + case attr_street_name: + new_attr_type=attr_house_number; + break; + default: + break; + } + if (new_attr_type != attr_none) + results=search_by_address_attr(results, sl, phrases, used, new_attr_type, wordcount_all); + g_list_free(used); + } + g_free(attr.u.str); + } + tmp=g_list_next(tmp); + } + return results; +} + +static void search_by_address(struct search_list *this_, char *addr) { + char *str=search_fix_spaces(addr); + GList *tmp,*phrases=search_split_phrases(str); + struct search_list *sl=search_list_new(this_->ms); + this_->address_results=search_by_address_attr(NULL, sl, phrases, NULL, attr_country_all, 0); + this_->address_results_pos=this_->address_results; + search_list_destroy(sl); + tmp=phrases; + while (tmp) { + g_free(tmp->data); + tmp=g_list_next(tmp); + } + g_list_free(phrases); + // TODO: Looks like we should g_free(str) here. But this is + // currently dead code, so no way to test it. +} + +static void search_address_results_free(struct search_list *this_) { + GList *tmp; + tmp=this_->address_results; + while (tmp) { + struct search_list_result *slr=tmp->data; + if (slr->country) + search_list_country_destroy(slr->country); + if (slr->town) + search_list_town_destroy(slr->town); + if (slr->street) + search_list_street_destroy(slr->street); + if (slr->house_number) + search_list_house_number_destroy(slr->house_number); + if (slr->c) + g_free(slr->c); + g_free(slr); + tmp=g_list_next(tmp); + } + g_list_free(this_->address_results); + this_->address_results=this_->address_results_pos=NULL; } /** @@ -343,499 +322,450 @@ search_address_results_free(struct search_list *this_) * @param search_attr attributes to use for the search * @param partial do partial search? (1=yes,0=no) */ -void -search_list_search(struct search_list *this_, struct attr *search_attr, int partial) -{ - struct search_list_level *le; - int level; - dbg(lvl_info,"Starting search for '=%s' of type %s\n", search_attr->u.str, attr_to_name(search_attr->type)); - search_address_results_free(this_); - if (search_attr->type == attr_address) { - search_by_address(this_, search_attr->u.str); - this_->use_address_results=1; - return; - } - this_->use_address_results=0; - level=search_list_level(search_attr->type); - this_->item=NULL; - house_number_interpolation_clear_all(&this_->inter); - if (level != -1) { - this_->result.id=0; - this_->level=level; - le=&this_->levels[level]; - search_list_search_free(this_, level); - le->attr=attr_dup(search_attr); - le->partial=partial; - if (level > 0) { - le=&this_->levels[level-1]; - le->curr=le->list; - } - } else if (search_attr->type == attr_postal) { - g_free(this_->postal); - this_->postal=g_strdup(search_attr->u.str); - } +void search_list_search(struct search_list *this_, struct attr *search_attr, int partial) { + struct search_list_level *le; + int level; + dbg(lvl_info,"Starting search for '=%s' of type %s", search_attr->u.str, attr_to_name(search_attr->type)); + search_address_results_free(this_); + if (search_attr->type == attr_address) { + search_by_address(this_, search_attr->u.str); + this_->use_address_results=1; + return; + } + this_->use_address_results=0; + level=search_list_level(search_attr->type); + this_->item=NULL; + house_number_interpolation_clear_all(&this_->inter); + if (level != -1) { + this_->result.id=0; + this_->level=level; + le=&this_->levels[level]; + search_list_search_free(this_, level); + le->attr=attr_dup(search_attr); + le->partial=partial; + if (level > 0) { + le=&this_->levels[level-1]; + le->curr=le->list; + } + } else if (search_attr->type == attr_postal) { + g_free(this_->postal); + this_->postal=g_strdup(search_attr->u.str); + } } struct search_list_common * -search_list_select(struct search_list *this_, enum attr_type attr_type, int id, int mode) -{ - int level; - int num; - struct search_list_level *le; - struct search_list_common *slc; - GList *curr; - - level = search_list_level(attr_type); - if (level < 0) - return NULL; - le=&this_->levels[level]; - curr=le->list; - if (mode > 0 || !id) - le->selected=mode; - //dbg(lvl_debug,"enter level=%d %d %d %p\n", level, id, mode, curr); - num = 0; - while (curr) { - num++; - if (! id || num == id) { - slc=curr->data; - slc->selected=mode; - if (id) { - le->last=curr; - //dbg(lvl_debug,"found\n"); - return slc; - } - } - curr=g_list_next(curr); - } - //dbg(lvl_debug,"not found\n"); - return NULL; -} - -static void -search_list_common_addattr(struct attr* attr,struct search_list_common *common) -{ - - common->attrs=attr_generic_prepend_attr(common->attrs,attr); - switch(attr->type) { - case attr_town_name: - common->town_name=common->attrs[0]->u.str; - break; - case attr_county_name: - common->county_name=common->attrs[0]->u.str; - break; - case attr_district_name: - common->district_name=common->attrs[0]->u.str; - break; - case attr_postal: - common->postal=common->attrs[0]->u.str; - break; - case attr_town_postal: - if(!common->postal) - common->postal=common->attrs[0]->u.str; - break; - case attr_postal_mask: - common->postal_mask=common->attrs[0]->u.str; - break; - default: - break; - } -} - -static void -search_list_common_new(struct item *item, struct search_list_common *common) -{ - struct attr attr; - int i; - enum attr_type common_attrs[]={ - attr_state_name, - attr_county_name, - attr_municipality_name, - attr_town_name, - attr_district_name, - attr_postal, - attr_town_postal, - attr_postal_mask, - attr_none - }; - - common->town_name=NULL; - common->district_name=NULL; - common->county_name=NULL; - common->postal=NULL; - common->postal_mask=NULL; - common->attrs=NULL; - - for(i=0;common_attrs[i];i++) { - if (item_attr_get(item, common_attrs[i], &attr)) { - struct attr at; - at.type=attr.type; - at.u.str=map_convert_string(item->map, attr.u.str); - search_list_common_addattr(&at,common); - map_convert_free(at.u.str); - } - } -} - -static void -search_list_common_dup(struct search_list_common *src, struct search_list_common *dst) -{ - int i; - - if(dst->attrs) { - for(i=0;dst->attrs[i];i++) - search_list_common_addattr(src->attrs[i],dst); - } - - if (src->c) { - dst->c=g_new(struct pcoord, 1); - *dst->c=*src->c; - } else - dst->c=NULL; -} - -static void -search_list_common_destroy(struct search_list_common *common) -{ - g_free(common->c); - attr_list_free(common->attrs); - - common->town_name=NULL; - common->district_name=NULL; - common->county_name=NULL; - common->postal=NULL; - common->postal_mask=NULL; - common->c=NULL; - common->attrs=NULL; -} - -static struct search_list_country * -search_list_country_new(struct item *item) -{ - struct search_list_country *ret=g_new0(struct search_list_country, 1); - struct attr attr; - - ret->common.item=ret->common.unique=*item; - if (item_attr_get(item, attr_country_car, &attr)) - ret->car=g_strdup(attr.u.str); - if (item_attr_get(item, attr_country_iso2, &attr)) { +search_list_select(struct search_list *this_, enum attr_type attr_type, int id, int mode) { + int level; + int num; + struct search_list_level *le; + struct search_list_common *slc; + GList *curr; + + level = search_list_level(attr_type); + if (level < 0) + return NULL; + le=&this_->levels[level]; + curr=le->list; + if (mode > 0 || !id) + le->selected=mode; + //dbg(lvl_debug,"enter level=%d %d %d %p", level, id, mode, curr); + num = 0; + while (curr) { + num++; + if (! id || num == id) { + slc=curr->data; + slc->selected=mode; + if (id) { + le->last=curr; + //dbg(lvl_debug,"found"); + return slc; + } + } + curr=g_list_next(curr); + } + //dbg(lvl_debug,"not found"); + return NULL; +} + +static void search_list_common_addattr(struct attr* attr,struct search_list_common *common) { + + common->attrs=attr_generic_prepend_attr(common->attrs,attr); + switch(attr->type) { + case attr_town_name: + common->town_name=common->attrs[0]->u.str; + break; + case attr_county_name: + common->county_name=common->attrs[0]->u.str; + break; + case attr_district_name: + common->district_name=common->attrs[0]->u.str; + break; + case attr_postal: + common->postal=common->attrs[0]->u.str; + break; + case attr_town_postal: + if(!common->postal) + common->postal=common->attrs[0]->u.str; + break; + case attr_postal_mask: + common->postal_mask=common->attrs[0]->u.str; + break; + default: + break; + } +} + +static void search_list_common_new(struct item *item, struct search_list_common *common) { + struct attr attr; + int i; + enum attr_type common_attrs[]= { + attr_state_name, + attr_county_name, + attr_municipality_name, + attr_town_name, + attr_district_name, + attr_postal, + attr_town_postal, + attr_postal_mask, + attr_none + }; + + common->town_name=NULL; + common->district_name=NULL; + common->county_name=NULL; + common->postal=NULL; + common->postal_mask=NULL; + common->attrs=NULL; + + for(i=0; common_attrs[i]; i++) { + if (item_attr_get(item, common_attrs[i], &attr)) { + struct attr at; + at.type=attr.type; + at.u.str=map_convert_string(item->map, attr.u.str); + search_list_common_addattr(&at,common); + map_convert_free(at.u.str); + } + } +} + +static void search_list_common_dup(struct search_list_common *src, struct search_list_common *dst) { + int i; + + if(dst->attrs) { + for(i=0; dst->attrs[i]; i++) + search_list_common_addattr(src->attrs[i],dst); + } + + if (src->c) { + dst->c=g_new(struct pcoord, 1); + *dst->c=*src->c; + } else + dst->c=NULL; +} + +static void search_list_common_destroy(struct search_list_common *common) { + g_free(common->c); + attr_list_free(common->attrs); + + common->town_name=NULL; + common->district_name=NULL; + common->county_name=NULL; + common->postal=NULL; + common->postal_mask=NULL; + common->c=NULL; + common->attrs=NULL; +} + +static struct search_list_country *search_list_country_new(struct item *item) { + struct search_list_country *ret=g_new0(struct search_list_country, 1); + struct attr attr; + + ret->common.item=ret->common.unique=*item; + if (item_attr_get(item, attr_country_car, &attr)) + ret->car=g_strdup(attr.u.str); + if (item_attr_get(item, attr_country_iso2, &attr)) { #ifdef HAVE_API_ANDROID - ret->iso2=g_malloc(strlen(attr.u.str)+1); - strtolower(ret->iso2, attr.u.str); + ret->iso2=g_malloc(strlen(attr.u.str)+1); + strtolower(ret->iso2, attr.u.str); #else - ret->iso2=g_strdup(attr.u.str); + ret->iso2=g_strdup(attr.u.str); #endif - ret->flag=g_strdup_printf("country_%s", ret->iso2); - } - if (item_attr_get(item, attr_country_iso3, &attr)) - ret->iso3=g_strdup(attr.u.str); - if (item_attr_get(item, attr_country_name, &attr)) - ret->name=g_strdup(attr.u.str); - return ret; -} - -static struct search_list_country * -search_list_country_dup(struct search_list_country *this_) -{ - struct search_list_country *ret=g_new(struct search_list_country, 1); - ret->car=g_strdup(this_->car); - ret->iso2=g_strdup(this_->iso2); - ret->iso3=g_strdup(this_->iso3); - ret->flag=g_strdup(this_->flag); - ret->name=g_strdup(this_->name); - return ret; -} - -static void -search_list_country_destroy(struct search_list_country *this_) -{ - g_free(this_->car); - g_free(this_->iso2); - g_free(this_->iso3); - g_free(this_->flag); - g_free(this_->name); - g_free(this_); -} - -static struct search_list_town * -search_list_town_new(struct item *item) -{ - struct search_list_town *ret=g_new0(struct search_list_town, 1); - struct attr attr; - struct coord c; - - ret->itemt=*item; - ret->common.item=ret->common.unique=*item; - if (item_attr_get(item, attr_town_streets_item, &attr)) { - dbg(lvl_debug,"town_assoc 0x%x 0x%x\n", attr.u.item->id_hi, attr.u.item->id_lo); - ret->common.unique=*attr.u.item; - } - search_list_common_new(item, &ret->common); - if (item_attr_get(item, attr_county_name, &attr)) - ret->county=map_convert_string(item->map,attr.u.str); - else - ret->county=NULL; - if (item_coord_get(item, &c, 1)) { - ret->common.c=g_new(struct pcoord, 1); - ret->common.c->x=c.x; - ret->common.c->y=c.y; - ret->common.c->pro = map_projection(item->map); - } - return ret; -} - -static struct search_list_town * -search_list_town_dup(struct search_list_town *this_) -{ - struct search_list_town *ret=g_new0(struct search_list_town, 1); - ret->county=map_convert_dup(this_->county); - search_list_common_dup(&this_->common, &ret->common); - return ret; -} - -static void -search_list_town_destroy(struct search_list_town *this_) -{ - map_convert_free(this_->county); - search_list_common_destroy(&this_->common); - g_free(this_); -} - - -static struct search_list_street * -search_list_street_new(struct item *item) -{ - struct search_list_street *ret=g_new0(struct search_list_street, 1); - struct attr attr; - struct coord p[1024]; - struct coord c; - int count; - - ret->common.item=ret->common.unique=*item; - if (item_attr_get(item, attr_street_name, &attr)) - ret->name=map_convert_string(item->map, attr.u.str); - else - ret->name=NULL; - search_list_common_new(item, &ret->common); - count=item_coord_get(item, p, sizeof(p)/sizeof(*p)); - if (count) { - geom_line_middle(p,count,&c); - ret->common.c=g_new(struct pcoord, 1); - ret->common.c->x=c.x; - ret->common.c->y=c.y; - ret->common.c->pro = map_projection(item->map); - } - return ret; -} - -static struct search_list_street * -search_list_street_dup(struct search_list_street *this_) -{ - struct search_list_street *ret=g_new0(struct search_list_street, 1); - ret->name=map_convert_dup(this_->name); - search_list_common_dup(&this_->common, &ret->common); - return ret; -} - -static void -search_list_street_destroy(struct search_list_street *this_) -{ - map_convert_free(this_->name); - search_list_common_destroy(&this_->common); - g_free(this_); -} - -static struct search_list_house_number * -search_list_house_number_new(struct item *item, struct house_number_interpolation *inter, char *inter_match, int inter_partial) -{ - struct search_list_house_number *ret=g_new0(struct search_list_house_number, 1); - struct attr attr; - char *house_number=NULL; - - ret->common.item=ret->common.unique=*item; - if (item_attr_get(item, attr_house_number, &attr)) { - house_number=attr.u.str; - } else { - ret->house_number_interpolation=1; - memset(&ret->common.unique, 0, sizeof(ret->common.unique)); - house_number=search_next_interpolated_house_number(item, inter, inter_match, inter_partial); - } - if (!house_number) { - g_free(ret); - return NULL; - } - ret->house_number=map_convert_string(item->map, house_number); - search_list_common_new(item, &ret->common); - ret->common.c=search_house_number_coordinate(item, ret->house_number_interpolation?inter:NULL); - return ret; -} - -static struct search_list_house_number * -search_list_house_number_dup(struct search_list_house_number *this_) -{ - struct search_list_house_number *ret=g_new0(struct search_list_house_number, 1); - ret->house_number=map_convert_dup(this_->house_number); - search_list_common_dup(&this_->common, &ret->common); - return ret; -} - -static void -search_list_house_number_destroy(struct search_list_house_number *this_) -{ - map_convert_free(this_->house_number); - search_list_common_destroy(&this_->common); - g_free(this_); -} - -static void -search_list_result_destroy(int level, void *p) -{ - switch (level) { - case 0: - search_list_country_destroy(p); - break; - case 1: - search_list_town_destroy(p); - break; - case 2: - search_list_street_destroy(p); - break; - case 3: - search_list_house_number_destroy(p); - break; - } -} - -static struct search_list_result * -search_list_result_dup(struct search_list_result *slr) -{ - struct search_list_result *ret=g_new0(struct search_list_result, 1); - ret->id=slr->id; - if (slr->c) { - ret->c=g_new(struct pcoord, 1); - *ret->c=*slr->c; - } - if (slr->country) - ret->country=search_list_country_dup(slr->country); - if (slr->town) - ret->town=search_list_town_dup(slr->town); - if (slr->street) - ret->street=search_list_street_dup(slr->street); - if (slr->house_number) - ret->house_number=search_list_house_number_dup(slr->house_number); - return ret; -} - -static void -search_list_search_free(struct search_list *sl, int level) -{ - struct search_list_level *le=&sl->levels[level]; - GList *next,*curr; - if (le->search) - { - mapset_search_destroy(le->search); - le->search=NULL; - } + ret->flag=g_strdup_printf("country_%s", ret->iso2); + } + if (item_attr_get(item, attr_country_iso3, &attr)) + ret->iso3=g_strdup(attr.u.str); + if (item_attr_get(item, attr_country_name, &attr)) + ret->name=g_strdup(attr.u.str); + return ret; +} + +static struct search_list_country *search_list_country_dup(struct search_list_country *this_) { + struct search_list_country *ret=g_new(struct search_list_country, 1); + ret->car=g_strdup(this_->car); + ret->iso2=g_strdup(this_->iso2); + ret->iso3=g_strdup(this_->iso3); + ret->flag=g_strdup(this_->flag); + ret->name=g_strdup(this_->name); + return ret; +} + +static void search_list_country_destroy(struct search_list_country *this_) { + g_free(this_->car); + g_free(this_->iso2); + g_free(this_->iso3); + g_free(this_->flag); + g_free(this_->name); + g_free(this_); +} + +static struct search_list_town *search_list_town_new(struct item *item) { + struct search_list_town *ret=g_new0(struct search_list_town, 1); + struct attr attr; + struct coord c; + + ret->itemt=*item; + ret->common.item=ret->common.unique=*item; + if (item_attr_get(item, attr_town_streets_item, &attr)) { + dbg(lvl_debug,"town_assoc 0x%x 0x%x", attr.u.item->id_hi, attr.u.item->id_lo); + ret->common.unique=*attr.u.item; + } + search_list_common_new(item, &ret->common); + if (item_attr_get(item, attr_county_name, &attr)) + ret->county=map_convert_string(item->map,attr.u.str); + else + ret->county=NULL; + if (item_coord_get(item, &c, 1)) { + ret->common.c=g_new(struct pcoord, 1); + ret->common.c->x=c.x; + ret->common.c->y=c.y; + ret->common.c->pro = map_projection(item->map); + } + return ret; +} + +static struct search_list_town *search_list_town_dup(struct search_list_town *this_) { + struct search_list_town *ret=g_new0(struct search_list_town, 1); + ret->county=map_convert_dup(this_->county); + search_list_common_dup(&this_->common, &ret->common); + return ret; +} + +static void search_list_town_destroy(struct search_list_town *this_) { + map_convert_free(this_->county); + search_list_common_destroy(&this_->common); + g_free(this_); +} + + +static struct search_list_street *search_list_street_new(struct item *item) { + struct search_list_street *ret=g_new0(struct search_list_street, 1); + struct attr attr; + struct coord p[1024]; + struct coord c; + int count; + + ret->common.item=ret->common.unique=*item; + if (item_attr_get(item, attr_street_name, &attr)) + ret->name=map_convert_string(item->map, attr.u.str); + else + ret->name=NULL; + search_list_common_new(item, &ret->common); + count=item_coord_get(item, p, sizeof(p)/sizeof(*p)); + if (count) { + geom_line_middle(p,count,&c); + ret->common.c=g_new(struct pcoord, 1); + ret->common.c->x=c.x; + ret->common.c->y=c.y; + ret->common.c->pro = map_projection(item->map); + } + return ret; +} + +static struct search_list_street *search_list_street_dup(struct search_list_street *this_) { + struct search_list_street *ret=g_new0(struct search_list_street, 1); + ret->name=map_convert_dup(this_->name); + search_list_common_dup(&this_->common, &ret->common); + return ret; +} + +static void search_list_street_destroy(struct search_list_street *this_) { + map_convert_free(this_->name); + search_list_common_destroy(&this_->common); + g_free(this_); +} + +static struct search_list_house_number *search_list_house_number_new(struct item *item, + struct house_number_interpolation *inter, char *inter_match, + int inter_partial) { + struct search_list_house_number *ret=g_new0(struct search_list_house_number, 1); + struct attr attr; + char *house_number=NULL; + + ret->common.item=ret->common.unique=*item; + if (item_attr_get(item, attr_house_number, &attr)) { + house_number=attr.u.str; + } else { + ret->house_number_interpolation=1; + memset(&ret->common.unique, 0, sizeof(ret->common.unique)); + house_number=search_next_interpolated_house_number(item, inter, inter_match, inter_partial); + } + if (!house_number) { + g_free(ret); + return NULL; + } + ret->house_number=map_convert_string(item->map, house_number); + search_list_common_new(item, &ret->common); + ret->common.c=search_house_number_coordinate(item, ret->house_number_interpolation?inter:NULL); + return ret; +} + +static struct search_list_house_number *search_list_house_number_dup(struct search_list_house_number *this_) { + struct search_list_house_number *ret=g_new0(struct search_list_house_number, 1); + ret->house_number=map_convert_dup(this_->house_number); + search_list_common_dup(&this_->common, &ret->common); + return ret; +} + +static void search_list_house_number_destroy(struct search_list_house_number *this_) { + map_convert_free(this_->house_number); + search_list_common_destroy(&this_->common); + g_free(this_); +} + +static void search_list_result_destroy(int level, void *p) { + switch (level) { + case 0: + search_list_country_destroy(p); + break; + case 1: + search_list_town_destroy(p); + break; + case 2: + search_list_street_destroy(p); + break; + case 3: + search_list_house_number_destroy(p); + break; + } +} + +static struct search_list_result *search_list_result_dup(struct search_list_result *slr) { + struct search_list_result *ret=g_new0(struct search_list_result, 1); + ret->id=slr->id; + if (slr->c) { + ret->c=g_new(struct pcoord, 1); + *ret->c=*slr->c; + } + if (slr->country) + ret->country=search_list_country_dup(slr->country); + if (slr->town) + ret->town=search_list_town_dup(slr->town); + if (slr->street) + ret->street=search_list_street_dup(slr->street); + if (slr->house_number) + ret->house_number=search_list_house_number_dup(slr->house_number); + return ret; +} + +static void search_list_search_free(struct search_list *sl, int level) { + struct search_list_level *le=&sl->levels[level]; + GList *next,*curr; + if (le->search) { + mapset_search_destroy(le->search); + le->search=NULL; + } #if 0 /* FIXME */ - if (le->hash) { - g_hash_table_destroy(le->hash); - le->hash=NULL; - } + if (le->hash) { + g_hash_table_destroy(le->hash); + le->hash=NULL; + } #endif - curr=le->list; - while (curr) - { - search_list_result_destroy(level, curr->data); - next=g_list_next(curr); - curr=next; - } - attr_free(le->attr); - g_list_free(le->list); - le->list=NULL; - le->curr=NULL; - le->last=NULL; -} - -char * -search_postal_merge(char *mask, char *new) -{ - int i; - char *ret=NULL; - dbg(lvl_debug,"enter %s %s\n", mask, new); - if (!new) - return NULL; - if (!mask) - return g_strdup(new); - i=0; - while (mask[i] && new[i]) { - if (mask[i] != '.' && mask[i] != new[i]) - break; - i++; - - } - if (mask[i]) { - ret=g_strdup(mask); - while (mask[i]) - ret[i++]='.'; - } - dbg(lvl_debug,"merged %s with %s as %s\n", mask, new, ret); - return ret; -} - -char * -search_postal_merge_replace(char *mask, char *new) -{ - char *ret=search_postal_merge(mask, new); - if (!ret) - return mask; - g_free(mask); - return ret; -} - - -static int -postal_match(char *postal, char *mask) -{ - for (;;) { - if ((*postal != *mask) && (*mask != '.')) - return 0; - if (!*postal) { - if (!*mask) - return 1; - else - return 0; - } - postal++; - mask++; - } -} - -static int -search_add_result(struct search_list_level *le, struct search_list_common *slc) -{ - struct search_list_common *slo; - char *merged; - int unique=0; - if (slc->unique.type || slc->unique.id_hi || slc->unique.id_lo) - unique=1; - if (unique) - slo=g_hash_table_lookup(le->hash, &slc->unique); - else - slo=NULL; - if (!slo) { - if (unique) - g_hash_table_insert(le->hash, &slc->unique, slc); - if (slc->postal && !slc->postal_mask) { - slc->postal_mask=g_strdup(slc->postal); - } - le->list=g_list_append(le->list, slc); - return 1; - } - merged=search_postal_merge(slo->postal_mask, slc->postal); - if (merged) { - g_free(slo->postal_mask); - slo->postal_mask=merged; - } - return 0; + curr=le->list; + while (curr) { + search_list_result_destroy(level, curr->data); + next=g_list_next(curr); + curr=next; + } + attr_free(le->attr); + g_list_free(le->list); + le->list=NULL; + le->curr=NULL; + le->last=NULL; +} + +char *search_postal_merge(char *mask, char *new) { + int i; + char *ret=NULL; + dbg(lvl_debug,"enter %s %s", mask, new); + if (!new) + return NULL; + if (!mask) + return g_strdup(new); + i=0; + while (mask[i] && new[i]) { + if (mask[i] != '.' && mask[i] != new[i]) + break; + i++; + + } + if (mask[i]) { + ret=g_strdup(mask); + while (mask[i]) + ret[i++]='.'; + } + dbg(lvl_debug,"merged %s with %s as %s", mask, new, ret); + return ret; +} + +char *search_postal_merge_replace(char *mask, char *new) { + char *ret=search_postal_merge(mask, new); + if (!ret) + return mask; + g_free(mask); + return ret; +} + + +static int postal_match(char *postal, char *mask) { + for (;;) { + if ((*postal != *mask) && (*mask != '.')) + return 0; + if (!*postal) { + if (!*mask) + return 1; + else + return 0; + } + postal++; + mask++; + } +} + +static int search_add_result(struct search_list_level *le, struct search_list_common *slc) { + struct search_list_common *slo; + char *merged; + int unique=0; + if (slc->unique.type || slc->unique.id_hi || slc->unique.id_lo) + unique=1; + if (unique) + slo=g_hash_table_lookup(le->hash, &slc->unique); + else + slo=NULL; + if (!slo) { + if (unique) + g_hash_table_insert(le->hash, &slc->unique, slc); + if (slc->postal && !slc->postal_mask) { + slc->postal_mask=g_strdup(slc->postal); + } + le->list=g_list_append(le->list, slc); + return 1; + } + merged=search_postal_merge(slo->postal_mask, slc->postal); + if (merged) { + g_free(slo->postal_mask); + slo->postal_mask=merged; + } + return 0; } /** @@ -845,206 +775,184 @@ search_add_result(struct search_list_level *le, struct search_list_common *slc) * @return next result */ struct search_list_result * -search_list_get_result(struct search_list *this_) -{ - struct search_list_level *le,*leu; - int level=this_->level; - struct attr attr2; - int has_street_name=0; - - if (this_->use_address_results) { - struct search_list_result *ret=NULL; - if (this_->address_results_pos) { - ret=this_->address_results_pos->data; - this_->address_results_pos=g_list_next(this_->address_results_pos); - } - return ret; - } - - //dbg(lvl_debug,"enter\n"); - le=&this_->levels[level]; - //dbg(lvl_debug,"le=%p\n", le); - for (;;) - { - //dbg(lvl_debug,"le->search=%p\n", le->search); - if (! le->search) - { - //dbg(lvl_debug,"partial=%d level=%d\n", le->partial, level); - if (! level) - le->parent=NULL; - else - { - leu=&this_->levels[level-1]; - //dbg(lvl_debug,"leu->curr=%p\n", leu->curr); - for (;;) - { - //dbg(lvl_debug,"*********########"); - - struct search_list_common *slc; - if (! leu->curr) - { - return NULL; - } - le->parent=leu->curr->data; - leu->last=leu->curr; - leu->curr=g_list_next(leu->curr); - slc=(struct search_list_common *)(le->parent); - if (!slc) - break; - if (slc->selected == leu->selected) - break; - } - } - if (le->parent) - { - //dbg(lvl_debug,"mapset_search_new with item(%d,%d)\n", le->parent->item.id_hi, le->parent->item.id_lo); - } - //dbg(lvl_debug,"############## attr=%s\n", attr_to_name(le->attr->type)); - le->search=mapset_search_new(this_->ms, &le->parent->item, le->attr, le->partial); - le->hash=g_hash_table_new(search_item_hash_hash, search_item_hash_equal); - } - //dbg(lvl_debug,"le->search=%p\n", le->search); - if (!this_->item) - { - //dbg(lvl_debug,"sssss 1"); - this_->item=mapset_search_get_item(le->search); - //dbg(lvl_debug,"sssss 1 %p\n",this_->item); - } - if (this_->item) - { - void *p=NULL; - //dbg(lvl_debug,"id_hi=%d id_lo=%d\n", this_->item->id_hi, this_->item->id_lo); - if (this_->postal) - { - struct attr postal; - if (item_attr_get(this_->item, attr_postal_mask, &postal)) { - if (!postal_match(this_->postal, postal.u.str)) - continue; - } else if (item_attr_get(this_->item, attr_postal, &postal)) { - if (strcmp(this_->postal, postal.u.str)) - continue; - } - } - this_->result.country=NULL; - this_->result.town=NULL; - this_->result.street=NULL; - this_->result.c=NULL; - //dbg(lvl_debug,"case x LEVEL start %d\n",level); - switch (level) - { - case 0: - //dbg(lvl_debug,"case 0 COUNTRY"); - p=search_list_country_new(this_->item); - this_->result.country=p; - this_->result.country->common.parent=NULL; - this_->result.town=NULL; - this_->result.street=NULL; - this_->result.house_number=NULL; - this_->item=NULL; - break; - case 1: - //dbg(lvl_debug,"case 1 TOWN"); - p=search_list_town_new(this_->item); - this_->result.town=p; - this_->result.town->common.parent=this_->levels[0].last->data; - this_->result.country=this_->result.town->common.parent; - this_->result.c=this_->result.town->common.c; - this_->result.street=NULL; - this_->result.house_number=NULL; - this_->item=NULL; - break; - case 2: - //dbg(lvl_debug,"case 2 STREET"); - p=search_list_street_new(this_->item); - this_->result.street=p; - this_->result.street->common.parent=this_->levels[1].last->data; - this_->result.town=this_->result.street->common.parent; - this_->result.country=this_->result.town->common.parent; - this_->result.c=this_->result.street->common.c; - this_->result.house_number=NULL; - this_->item=NULL; - break; - case 3: - dbg(lvl_debug,"case 3 HOUSENUMBER\n"); - has_street_name=0; - - // if this housenumber has a streetname tag, set the name now - if (item_attr_get(this_->item, attr_street_name, &attr2)) - { - dbg(lvl_debug,"streetname: %s\n",attr2.u.str); - has_street_name=1; - } - - p=search_list_house_number_new(this_->item, &this_->inter, le->attr->u.str, le->partial); - if (!p) - { - house_number_interpolation_clear_all(&this_->inter); - this_->item=NULL; - continue; - } - - this_->result.house_number=p; - if (!this_->result.house_number->house_number_interpolation) - { - this_->item=NULL; - } else { - dbg(lvl_debug,"interpolation!\n"); - } - - if(le->parent && has_street_name) { - struct search_list_street *street=this_->levels[level-1].last->data; - if(navit_utf8_strcasecmp(street->name, attr2.u.str)) { - search_list_house_number_destroy(p); - //this_->item=NULL; - continue; - } - } - - - this_->result.house_number->common.parent=this_->levels[2].last->data; - this_->result.street=this_->result.house_number->common.parent; - this_->result.town=this_->result.street->common.parent; - this_->result.country=this_->result.town->common.parent; - this_->result.c=this_->result.house_number->common.c; +search_list_get_result(struct search_list *this_) { + struct search_list_level *le,*leu; + int level=this_->level; + struct attr attr2; + int has_street_name=0; + + if (this_->use_address_results) { + struct search_list_result *ret=NULL; + if (this_->address_results_pos) { + ret=this_->address_results_pos->data; + this_->address_results_pos=g_list_next(this_->address_results_pos); + } + return ret; + } + + //dbg(lvl_debug,"enter"); + le=&this_->levels[level]; + //dbg(lvl_debug,"le=%p", le); + for (;;) { + //dbg(lvl_debug,"le->search=%p", le->search); + if (! le->search) { + //dbg(lvl_debug,"partial=%d level=%d", le->partial, level); + if (! level) + le->parent=NULL; + else { + leu=&this_->levels[level-1]; + //dbg(lvl_debug,"leu->curr=%p", leu->curr); + for (;;) { + //dbg(lvl_debug,"*********########"); + + struct search_list_common *slc; + if (! leu->curr) { + return NULL; + } + le->parent=leu->curr->data; + leu->last=leu->curr; + leu->curr=g_list_next(leu->curr); + slc=(struct search_list_common *)(le->parent); + if (!slc) + break; + if (slc->selected == leu->selected) + break; + } + } + if (le->parent) { + //dbg(lvl_debug,"mapset_search_new with item(%d,%d)", le->parent->item.id_hi, le->parent->item.id_lo); + } + //dbg(lvl_debug,"############## attr=%s", attr_to_name(le->attr->type)); + le->search=mapset_search_new(this_->ms, &le->parent->item, le->attr, le->partial); + le->hash=g_hash_table_new(search_item_hash_hash, search_item_hash_equal); + } + //dbg(lvl_debug,"le->search=%p", le->search); + if (!this_->item) { + //dbg(lvl_debug,"sssss 1"); + this_->item=mapset_search_get_item(le->search); + //dbg(lvl_debug,"sssss 1 %p",this_->item); + } + if (this_->item) { + void *p=NULL; + //dbg(lvl_debug,"id_hi=%d id_lo=%d", this_->item->id_hi, this_->item->id_lo); + if (this_->postal) { + struct attr postal; + if (item_attr_get(this_->item, attr_postal_mask, &postal)) { + if (!postal_match(this_->postal, postal.u.str)) + continue; + } else if (item_attr_get(this_->item, attr_postal, &postal)) { + if (strcmp(this_->postal, postal.u.str)) + continue; + } + } + this_->result.country=NULL; + this_->result.town=NULL; + this_->result.street=NULL; + this_->result.c=NULL; + //dbg(lvl_debug,"case x LEVEL start %d",level); + switch (level) { + case 0: + //dbg(lvl_debug,"case 0 COUNTRY"); + p=search_list_country_new(this_->item); + this_->result.country=p; + this_->result.country->common.parent=NULL; + this_->result.town=NULL; + this_->result.street=NULL; + this_->result.house_number=NULL; + this_->item=NULL; + break; + case 1: + //dbg(lvl_debug,"case 1 TOWN"); + p=search_list_town_new(this_->item); + this_->result.town=p; + this_->result.town->common.parent=this_->levels[0].last->data; + this_->result.country=this_->result.town->common.parent; + this_->result.c=this_->result.town->common.c; + this_->result.street=NULL; + this_->result.house_number=NULL; + this_->item=NULL; + break; + case 2: + //dbg(lvl_debug,"case 2 STREET"); + p=search_list_street_new(this_->item); + this_->result.street=p; + this_->result.street->common.parent=this_->levels[1].last->data; + this_->result.town=this_->result.street->common.parent; + this_->result.country=this_->result.town->common.parent; + this_->result.c=this_->result.street->common.c; + this_->result.house_number=NULL; + this_->item=NULL; + break; + case 3: + dbg(lvl_debug,"case 3 HOUSENUMBER"); + has_street_name=0; + + // if this housenumber has a streetname tag, set the name now + if (item_attr_get(this_->item, attr_street_name, &attr2)) { + dbg(lvl_debug,"streetname: %s",attr2.u.str); + has_street_name=1; + } + + p=search_list_house_number_new(this_->item, &this_->inter, le->attr->u.str, le->partial); + if (!p) { + house_number_interpolation_clear_all(&this_->inter); + this_->item=NULL; + continue; + } + + this_->result.house_number=p; + if (!this_->result.house_number->house_number_interpolation) { + this_->item=NULL; + } else { + dbg(lvl_debug,"interpolation!"); + } + + if(le->parent && has_street_name) { + struct search_list_street *street=this_->levels[level-1].last->data; + if(navit_utf8_strcasecmp(street->name, attr2.u.str)) { + search_list_house_number_destroy(p); + //this_->item=NULL; + continue; + } + } + + + this_->result.house_number->common.parent=this_->levels[2].last->data; + this_->result.street=this_->result.house_number->common.parent; + this_->result.town=this_->result.street->common.parent; + this_->result.country=this_->result.town->common.parent; + this_->result.c=this_->result.house_number->common.c; #if 0 - if(!has_street_name) { - static struct search_list_street null_street; - this_->result.street=&null_street; - } + if(!has_street_name) { + static struct search_list_street null_street; + this_->result.street=&null_street; + } #endif - } - if (p) - { - if (search_add_result(le, p)) - { - this_->result.id++; - return &this_->result; - } - else - { - search_list_result_destroy(level, p); - } - } - } else { - mapset_search_destroy(le->search); - le->search=NULL; - g_hash_table_destroy(le->hash); - if (! level) - break; - } - } - return NULL; -} - -void -search_list_destroy(struct search_list *this_) -{ - g_free(this_->postal); - g_free(this_); -} - -void -search_init(void) -{ + } + if (p) { + if (search_add_result(le, p)) { + this_->result.id++; + return &this_->result; + } else { + search_list_result_destroy(level, p); + } + } + } else { + mapset_search_destroy(le->search); + le->search=NULL; + g_hash_table_destroy(le->hash); + if (! level) + break; + } + } + return NULL; +} + +void search_list_destroy(struct search_list *this_) { + g_free(this_->postal); + g_free(this_); +} + +void search_init(void) { } |