summaryrefslogtreecommitdiff
path: root/navit/search.c
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2012-03-03 13:26:24 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2012-03-03 13:26:24 +0000
commit4ec304c3efcd77629bfb2d3193a590baa1e0b946 (patch)
treeab9557cde2af9157a09452bd74e7759eff9e8d88 /navit/search.c
parent5a7350f26d303d6e007cd0422152d2b75343c8ab (diff)
downloadnavit-4ec304c3efcd77629bfb2d3193a590baa1e0b946.tar.gz
Add:Core:New function to get unique part of search results and possible next chars
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@4956 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/search.c')
-rw-r--r--navit/search.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/navit/search.c b/navit/search.c
index 1a26dab1c..cf016e86e 100644
--- a/navit/search.c
+++ b/navit/search.c
@@ -30,6 +30,7 @@
#include "transform.h"
#include "search.h"
#include "country.h"
+#include "linguistics.h"
#if HAVE_API_ANDROID
#include "android.h"
@@ -687,6 +688,122 @@ search_add_result(struct search_list_level *le, struct search_list_common *slc)
return 0;
}
+static char *
+search_list_get_unique_truncate(char *common, char *result)
+{
+ dbg(0,"%s vs %s\n",common,result);
+ while (*common) {
+ if (g_utf8_get_char(common) != g_utf8_get_char(result)) {
+ dbg(0,"truncating at %s vs %s\n",common,result);
+ return common;
+ }
+ result=g_utf8_next_char(result);
+ common=g_utf8_next_char(common);
+ }
+ return common;
+}
+
+static char *
+search_list_get_unique_append(char *list, char *append)
+{
+ char *c=list;
+ int llen=list?strlen(list):0;
+ int len=g_utf8_next_char(append)-append;
+ gunichar a=g_utf8_get_char(append);
+ while(c && *c) {
+ if (g_utf8_get_char(c) == a)
+ return list;
+ c=g_utf8_next_char(c);
+ }
+ list=g_renew(char, list, llen+len+1);
+ strncpy(list+llen,append,len);
+ list[llen+len]='\0';
+ return list;
+}
+
+char *
+search_list_get_unique(struct search_list *this_, char *unique)
+{
+ int level=this_->level;
+ struct search_list_level *le=&this_->levels[level];
+ struct search_list_country *slc;
+ struct search_list_town *slt;
+ char *retf=NULL,*ret=NULL;
+ char *strings[4]={NULL,};
+ char *search=g_utf8_casefold(unique?unique:le->attr->u.str,-1);
+ char *name,*max;
+ int search_len=strlen(search);
+ int i,count=sizeof(strings)/sizeof(char *);
+
+ dbg(0,"enter level=%d %s\n",level,search);
+ GList *l=le->list;
+ while (l) {
+ switch (level) {
+ case 0:
+ slc=l->data;
+ strings[0]=g_strdup(slc->name);
+ strings[1]=g_strdup(slc->car);
+ strings[2]=g_strdup(slc->iso2);
+ strings[3]=g_strdup(slc->iso3);
+ break;
+ case 1:
+ slt=l->data;
+ name=slt->common.town_name;
+ for (i = 0 ; i < 3 ; i++)
+ strings[i]=linguistics_expand_special(name, i);
+ break;
+ default:
+ dbg(0,"entry\n");
+ }
+ dbg(0,"entry %s %s %s %s\n",strings[0],strings[1],strings[2],strings[3]);
+ max=NULL;
+ for (i = 0 ; i < count ; i++) {
+ char *str=strings[i];
+ while (str) {
+ char *strf=g_utf8_casefold(str,-1);
+ dbg(0,"word %s\n",strf);
+ if (!strncmp(strf, search, search_len)) {
+ dbg(0,"match\n");
+ if (unique) {
+ dbg(0,"possible next %s %s ret %s\n",strf+search_len,str+search_len,ret);
+ ret=search_list_get_unique_append(ret, strf+search_len);
+ ret=search_list_get_unique_append(ret, str+search_len);
+ dbg(0,"ret now %s\n",ret);
+ } else {
+ if (!ret) {
+ ret=g_strdup(str);
+ retf=g_utf8_casefold(ret,-1);
+ dbg(0,"ret now %s\n",ret);
+ } else {
+ char *end=search_list_get_unique_truncate(retf,strf);
+ dbg(0,"%d characters\n",end-retf);
+ if (!max || max < end)
+ max=end;
+ }
+ }
+ }
+ g_free(strf);
+ str=linguistics_next_word(str);
+ }
+ g_free(strings[i]);
+ }
+ if (!unique) {
+ if (max) {
+ dbg(0,"max %s (%d characters)\n",max,max-retf);
+ ret[max-retf]='\0';
+ } else {
+ dbg(0,"new max\n");
+ }
+ }
+ dbg(0,"common %s\n",ret);
+ l=g_list_next(l);
+ }
+ g_free(search);
+ g_free(retf);
+ dbg(0,"return %s\n",ret);
+ return ret;
+}
+
/**
* @brief Get (next) result from a search.
*