From d6037fa3123d25c8c7dd7620a9afc8717378eb3c Mon Sep 17 00:00:00 2001
From: smorlat <smorlat@3f6dc0c8-ddfe-455d-9043-3cd528dc4637>
Date: Tue, 15 Dec 2009 14:02:06 +0000
Subject: [PATCH] add doxygen framework to start documenting liblinphone
 enhance lpconfig to be able to load additional config files.

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@781 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
---
 linphone/configure.in                |  11 ++
 linphone/coreapi/Makefile.am         |   1 +
 linphone/coreapi/friend.c            |  34 ++++
 linphone/coreapi/help/Doxyfile.in    | 233 +++++++++++++++++++++++++++
 linphone/coreapi/help/Makefile.am    |  32 ++++
 linphone/coreapi/help/doxygen.dox.in |  37 +++++
 linphone/coreapi/linphonecore.c      |   2 +-
 linphone/coreapi/linphonecore.h      |  10 +-
 linphone/coreapi/lpconfig.c          | 135 +++++++---------
 linphone/coreapi/lpconfig.h          |   1 +
 linphone/coreapi/private.h           |   4 +
 linphone/po/Makefile.in.in           |   4 +-
 12 files changed, 417 insertions(+), 87 deletions(-)
 create mode 100644 linphone/coreapi/help/Doxyfile.in
 create mode 100644 linphone/coreapi/help/Makefile.am
 create mode 100644 linphone/coreapi/help/doxygen.dox.in

diff --git a/linphone/configure.in b/linphone/configure.in
index 1af3e9f0a9..d7ec758958 100644
--- a/linphone/configure.in
+++ b/linphone/configure.in
@@ -390,12 +390,23 @@ changequote([, ])dnl
 AC_SUBST([ORTP_VERSION])
 AC_SUBST([MS2_VERSION])
 
+dnl ##################################################
+dnl # Check for doxygen
+dnl ##################################################
+
+AC_PATH_PROG(DOXYGEN,doxygen,false)
+AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN != false)
+
+
 AC_OUTPUT([ 
 Makefile 
 m4/Makefile
 po/Makefile.in 
 pixmaps/Makefile
 coreapi/Makefile
+coreapi/help/Makefile
+coreapi/help/Doxyfile
+coreapi/help/doxygen.dox
 gtk-glade/Makefile
 console/Makefile
 share/Makefile
diff --git a/linphone/coreapi/Makefile.am b/linphone/coreapi/Makefile.am
index d2506730e9..c920c2d788 100644
--- a/linphone/coreapi/Makefile.am
+++ b/linphone/coreapi/Makefile.am
@@ -1,4 +1,5 @@
 
+SUBDIRS=help
 
 ## Process this file with automake to produce Makefile.in
 linphone_includedir=$(includedir)/linphone
diff --git a/linphone/coreapi/friend.c b/linphone/coreapi/friend.c
index b73cf8d8c5..6cc61458cc 100644
--- a/linphone/coreapi/friend.c
+++ b/linphone/coreapi/friend.c
@@ -646,6 +646,21 @@ void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){
 	}
 }
 
+void linphone_friend_set_ref_key(LinphoneFriend *lf, const char *key){
+	if (lf->refkey!=NULL){
+		ms_free(lf->refkey);
+		lf->refkey=NULL;
+	}
+	if (key)
+		lf->refkey=ms_strdup(key);
+	if (lf->lc)
+		linphone_core_write_friends_config(lf->lc);
+}
+
+const char *linphone_friend_get_ref_key(const LinphoneFriend *lf){
+	return lf->refkey;
+}
+
 static bool_t username_match(const char *u1, const char *u2){
 	if (u1==NULL && u2==NULL) return TRUE;
 	if (u1 && u2 && strcasecmp(u1,u2)==0) return TRUE;
@@ -675,6 +690,18 @@ LinphoneFriend *linphone_core_get_friend_by_uri(const LinphoneCore *lc, const ch
 	return lf;
 }
 
+LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key){
+	const MSList *elem;
+	if (key==NULL) return NULL;
+	for(elem=linphone_core_get_friend_list(lc);elem!=NULL;elem=elem->next){
+		LinphoneFriend *lf=(LinphoneFriend*)elem->data;
+		if (lf->refkey!=NULL && strcmp(lf->refkey,key)==0){
+			return lf;
+		}
+	}
+	return NULL;
+}
+
 #define key_compare(key, word) strncasecmp((key),(word),strlen(key))
 
 LinphoneSubscribePolicy __policy_str_to_enum(const char* pol){
@@ -729,6 +756,7 @@ LinphoneFriend * linphone_friend_new_from_config_file(LinphoneCore *lc, int inde
 	if (a!=-1) {
 		linphone_friend_set_proxy(lf,__index_to_proxy(lc,a));
 	}
+	linphone_friend_set_ref_key(lf,lp_config_get_string(config,item,"refkey",NULL));
 	return lf;
 }
 
@@ -752,6 +780,7 @@ void linphone_friend_write_to_config_file(LpConfig *config, LinphoneFriend *lf,
 	char key[50];
 	char *tmp;
 	int a;
+	const char *refkey;
 	
 	sprintf(key,"friend_%i",index);
 	
@@ -773,6 +802,11 @@ void linphone_friend_write_to_config_file(LpConfig *config, LinphoneFriend *lf,
 		a=ms_list_index(lf->lc->sip_conf.proxies,lf->proxy);
 		lp_config_set_int(config,key,"proxy",a);
 	}else lp_config_set_int(config,key,"proxy",-1);
+
+	refkey=linphone_friend_get_ref_key(lf);
+	if (refkey){
+		lp_config_set_string(config,key,"refkey",refkey);
+	}
 }
 
 void linphone_core_write_friends_config(LinphoneCore* lc)
diff --git a/linphone/coreapi/help/Doxyfile.in b/linphone/coreapi/help/Doxyfile.in
new file mode 100644
index 0000000000..8ba0afbe14
--- /dev/null
+++ b/linphone/coreapi/help/Doxyfile.in
@@ -0,0 +1,233 @@
+# Doxyfile 1.4.1
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = liblinphone
+PROJECT_NUMBER         = @LINPHONE_VERSION@
+OUTPUT_DIRECTORY       = doc
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = NO
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = NO
+EXTRACT_STATIC         = NO
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = YES
+HIDE_UNDOC_CLASSES     = YES
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = NO
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = YES
+FILE_VERSION_FILTER    = 
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = . ../
+
+FILE_PATTERNS          = *.h \
+                         *.c \
+                         *.dox
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = ../
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION    = NO
+VERBATIM_HEADERS       = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 1
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = YES
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = YES
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = YES
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = .
+INCLUDE_FILE_PATTERNS  = *.h
+PREDEFINED             = DOXYGEN
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = YES
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DIRECTORY_GRAPH        = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 1000
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = NO
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/linphone/coreapi/help/Makefile.am b/linphone/coreapi/help/Makefile.am
new file mode 100644
index 0000000000..70f5b5739c
--- /dev/null
+++ b/linphone/coreapi/help/Makefile.am
@@ -0,0 +1,32 @@
+
+EXTRA_DIST = Doxyfile.in doxygen.dox.in
+
+SOURCES=$(top_srcdir)/coreapi/*.h 
+
+#html doc
+if HAVE_DOXYGEN
+
+# doxdir & pkgdocdir are not always defined by automake
+docdir=$(datadir)/doc
+pkgdocdir=$(docdir)/$(PACKAGE)-$(VERSION)
+doc_htmldir=$(pkgdocdir)/html
+
+doc_html_DATA = $(top_builddir)/coreapi/help/doc/html/html.tar
+
+$(doc_html_DATA): $(top_builddir)/coreapi/help/doc/html/index.html
+	cd $(<D) && tar cf html.tar *
+
+$(top_builddir)/coreapi/help/doc/html/index.html: $(SOURCES) Doxyfile Makefile.am
+	rm -rf doc
+	$(DOXYGEN) Doxyfile
+
+install-data-hook:
+	cd $(DESTDIR)$(doc_htmldir) && tar xf html.tar && rm -f html.tar
+
+uninstall-hook:
+	cd $(DESTDIR)$(doc_htmldir) && rm -f *
+
+endif
+
+clean-local:
+	rm -rf doc
\ No newline at end of file
diff --git a/linphone/coreapi/help/doxygen.dox.in b/linphone/coreapi/help/doxygen.dox.in
new file mode 100644
index 0000000000..74cb2534bd
--- /dev/null
+++ b/linphone/coreapi/help/doxygen.dox.in
@@ -0,0 +1,37 @@
+/**
+ * @mainpage
+ * Project Website: http://savannah.gnu.org/projects/linphone
+ *
+ * @verbinclude README
+ *
+ */
+
+/** 
+ * @defgroup liblinphone liblinphone library - high level library for building SIP applications
+ * @brief liblinphone Version @LINPHONE_VERSION@
+ *
+ * @see http://savannah.gnu.org/projects/linphone
+ *
+ * @section what_is_it What is liblinphone
+ *
+ * Liblinphone is a high level library for bringing SIP video call functionnality
+ * into an application. It aims at making easy the integration of the SIP
+ * video calls into any applications. All variants of linphone are directly based
+ * on it:
+ * 	- linphone (gtk interface)
+ *  - linphonec (console interface)
+ * Liblinphone is GPL (see COPYING file). Please understand the licencing details
+ * before using it!
+ * 
+ * For any use of this library beyond the rights granted to you by the
+ * GPL license, please contact Belledonne Communications 
+ * (contact@belledonne-communications.com)
+ * 
+ * 
+
+/**
+ * @page liblinphone_license COPYING 
+ * @verbinclude COPYING
+ */
+
+
diff --git a/linphone/coreapi/linphonecore.c b/linphone/coreapi/linphonecore.c
index c69d9edf1e..e1c358bf8a 100644
--- a/linphone/coreapi/linphonecore.c
+++ b/linphone/coreapi/linphonecore.c
@@ -885,7 +885,7 @@ int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs)
 	return 0;
 }
 
-const MSList * linphone_core_get_friend_list(LinphoneCore *lc)
+const MSList * linphone_core_get_friend_list(const LinphoneCore *lc)
 {
 	return lc->friends;
 }
diff --git a/linphone/coreapi/linphonecore.h b/linphone/coreapi/linphonecore.h
index 4628292f7c..684d89c91d 100644
--- a/linphone/coreapi/linphonecore.h
+++ b/linphone/coreapi/linphonecore.h
@@ -234,6 +234,7 @@ typedef struct _LinphoneFriend{
 	struct _LinphoneProxyConfig *proxy;
 	struct _LinphoneCore *lc;
 	BuddyInfo *info;
+	char *refkey;
 	bool_t subscribe;
 	bool_t inc_subscribe_pending;
 }LinphoneFriend;	
@@ -253,6 +254,8 @@ bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf);
 LinphoneSubscribePolicy linphone_friend_get_inc_subscribe_policy(const LinphoneFriend *lf);
 LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf);
 BuddyInfo * linphone_friend_get_info(const LinphoneFriend *lf);
+void linphone_friend_set_ref_key(LinphoneFriend *lf, const char *key);
+const char *linphone_friend_get_ref_key(const LinphoneFriend *lf);
 #define linphone_friend_in_list(lf)	((lf)->lc!=NULL)
 
 #define linphone_friend_url(lf) ((lf)->url)
@@ -547,9 +550,6 @@ const char *linphone_core_get_version(void);
 LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable,
 						const char *config_path, void* userdata);
 
-void linphone_core_init(LinphoneCore *lc, const LinphoneCoreVTable *vtable,
-						const char *config_path, void * userdata);
-
 /* function to be periodically called in a main loop */
 void linphone_core_iterate(LinphoneCore *lc);
 
@@ -721,10 +721,11 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *fr);
 void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *fr);
 void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf);
 /* a list of LinphoneFriend */
-const MSList * linphone_core_get_friend_list(LinphoneCore *lc);
+const MSList * linphone_core_get_friend_list(const LinphoneCore *lc);
 /* notify all friends that have subscribed */
 void linphone_core_notify_all_friends(LinphoneCore *lc, LinphoneOnlineStatus os);
 LinphoneFriend *linphone_core_get_friend_by_uri(const LinphoneCore *lc, const char *uri);
+LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key);
 
 /* returns a list of LinphoneCallLog */
 const MSList * linphone_core_get_call_logs(LinphoneCore *lc);
@@ -793,7 +794,6 @@ void linphone_core_set_waiting_callback(LinphoneCore *lc, LinphoneWaitingCallbac
 /*returns the list of registered SipSetup (linphonecore plugins) */
 const MSList * linphone_core_get_sip_setups(LinphoneCore *lc);
 
-void linphone_core_uninit(LinphoneCore *lc);
 void linphone_core_destroy(LinphoneCore *lc);
 
 /*for advanced users:*/
diff --git a/linphone/coreapi/lpconfig.c b/linphone/coreapi/lpconfig.c
index 08abcd5e81..cc03794ad7 100644
--- a/linphone/coreapi/lpconfig.c
+++ b/linphone/coreapi/lpconfig.c
@@ -38,49 +38,6 @@
 
 #include "lpconfig.h"
 
-#define LISTNODE(_struct_)	\
-	struct _struct_ *_prev;\
-	struct _struct_ *_next;
-
-typedef struct _ListNode{
-	LISTNODE(_ListNode)
-} ListNode;
-
-typedef void (*ListNodeForEachFunc)(ListNode *);
-
-ListNode * list_node_append(ListNode *head,ListNode *elem){
-	ListNode *e=head;
-	while(e->_next!=NULL) e=e->_next;
-	e->_next=elem;
-	elem->_prev=e;
-	return head;
-}
-
-ListNode * list_node_remove(ListNode *head, ListNode *elem){
-	ListNode *before,*after;
-	before=elem->_prev;
-	after=elem->_next;
-	if (before!=NULL) before->_next=after;
-	if (after!=NULL) after->_prev=before;
-	elem->_prev=NULL;
-	elem->_next=NULL;
-	if (head==elem) return after;
-	return head;
-}
-
-void list_node_foreach(ListNode *head, ListNodeForEachFunc func){
-	for (;head!=NULL;head=head->_next){
-		func(head);
-	}
-}
-
-
-#define LIST_PREPEND(e1,e2) (  (e2)->_prev=NULL,(e2)->_next=(e1),(e1)->_prev=(e2),(e2) )
-#define LIST_APPEND(head,elem) ((head)==0 ? (elem) : (list_node_append((ListNode*)(head),(ListNode*)(elem)), (head)) ) 
-#define LIST_REMOVE(head,elem) 
-
-/* returns void */
-#define LIST_FOREACH(head) list_node_foreach((ListNode*)head)
 
 typedef struct _LpItem{
 	char *key;
@@ -148,13 +105,41 @@ static bool_t is_first_char(const char *start, const char *pos){
 	return TRUE;
 }
 
-void lp_config_parse(LpConfig *lpconfig){
+LpSection *lp_config_find_section(LpConfig *lpconfig, const char *name){
+	LpSection *sec;
+	MSList *elem;
+	/*printf("Looking for section %s\n",name);*/
+	for (elem=lpconfig->sections;elem!=NULL;elem=ms_list_next(elem)){
+		sec=(LpSection*)elem->data;
+		if (strcmp(sec->name,name)==0){
+			/*printf("Section %s found\n",name);*/
+			return sec;
+		}
+	}
+	return NULL;
+}
+
+LpItem *lp_section_find_item(LpSection *sec, const char *name){
+	MSList *elem;
+	LpItem *item;
+	/*printf("Looking for item %s\n",name);*/
+	for (elem=sec->items;elem!=NULL;elem=ms_list_next(elem)){
+		item=(LpItem*)elem->data;
+		if (strcmp(item->key,name)==0) {
+			/*printf("Item %s found\n",name);*/
+			return item;
+		}
+	}
+	return NULL;
+}
+
+void lp_config_parse(LpConfig *lpconfig, FILE *file){
 	char tmp[MAX_LEN];
 	LpSection *cur=NULL;
 	
-	if (lpconfig->file==NULL) return;
+	if (file==NULL) return;
 	
-	while(fgets(tmp,MAX_LEN,lpconfig->file)!=NULL){
+	while(fgets(tmp,MAX_LEN,file)!=NULL){
 		char *pos1,*pos2;
 		pos1=strchr(tmp,'[');
 		if (pos1!=NULL && is_first_char(tmp,pos1) ){
@@ -168,8 +153,11 @@ void lp_config_parse(LpConfig *lpconfig){
 				nbs = sscanf(pos1+1,"%s",secname);
 				if (nbs == 1 ){
 					if (strlen(secname)>0){
-						cur=lp_section_new(secname);
-						lp_config_add_section(lpconfig,cur);
+						cur=lp_config_find_section (lpconfig,secname);
+						if (cur==NULL){
+							cur=lp_section_new(secname);
+							lp_config_add_section(lpconfig,cur);
+						}
 					}
 				}else{
 					ms_warning("parse error!");
@@ -196,7 +184,13 @@ void lp_config_parse(LpConfig *lpconfig){
 					if (pos2-pos1>=0){
 						/* found a pair key,value */
 						if (cur!=NULL){
-							lp_section_add_item(cur,lp_item_new(key,pos1));
+							LpItem *item=lp_section_find_item(cur,key);
+							if (item==NULL){
+								lp_section_add_item(cur,lp_item_new(key,pos1));
+							}else{
+								ms_free(item->value);
+								item->value=strdup(pos1);
+							}
 							/*printf("Found %s %s=%s\n",cur->name,key,pos1);*/
 						}else{
 							ms_warning("found key,item but no sections");
@@ -214,8 +208,8 @@ LpConfig * lp_config_new(const char *filename){
 		lpconfig->filename=strdup(filename);
 		lpconfig->file=fopen(filename,"rw");
 		if (lpconfig->file!=NULL){
-			lp_config_parse(lpconfig);
-			fclose(lpconfig->file);
+			lp_config_parse(lpconfig,lpconfig->file);
+			fclose(lpconfig->file);			
 			/* make existing configuration files non-group/world-accessible */
 			if (chmod(filename, S_IRUSR | S_IWUSR) == -1)
 				ms_warning("unable to correct permissions on "
@@ -228,6 +222,17 @@ LpConfig * lp_config_new(const char *filename){
 	return lpconfig;
 }
 
+int lp_config_read_file(LpConfig *lpconfig, const char *filename){
+	FILE* f=fopen(filename,"r");
+	if (f!=NULL){
+		lp_config_parse(lpconfig,f);
+		fclose(f);
+		return 0;
+	}
+	ms_warning("Fail to open file %s",filename);
+	return -1;
+}
+
 void lp_item_set_value(LpItem *item, const char *value){
 	free(item->value);
 	item->value=strdup(value);
@@ -241,34 +246,6 @@ void lp_config_destroy(LpConfig *lpconfig){
 	free(lpconfig);
 }
 
-LpSection *lp_config_find_section(LpConfig *lpconfig, const char *name){
-	LpSection *sec;
-	MSList *elem;
-	/*printf("Looking for section %s\n",name);*/
-	for (elem=lpconfig->sections;elem!=NULL;elem=ms_list_next(elem)){
-		sec=(LpSection*)elem->data;
-		if (strcmp(sec->name,name)==0){
-			/*printf("Section %s found\n",name);*/
-			return sec;
-		}
-	}
-	return NULL;
-}
-
-LpItem *lp_section_find_item(LpSection *sec, const char *name){
-	MSList *elem;
-	LpItem *item;
-	/*printf("Looking for item %s\n",name);*/
-	for (elem=sec->items;elem!=NULL;elem=ms_list_next(elem)){
-		item=(LpItem*)elem->data;
-		if (strcmp(item->key,name)==0) {
-			/*printf("Item %s found\n",name);*/
-			return item;
-		}
-	}
-	return NULL;
-}
-
 void lp_section_remove_item(LpSection *sec, LpItem *item){
 	sec->items=ms_list_remove(sec->items,(void *)item);
 	lp_item_destroy(item);
diff --git a/linphone/coreapi/lpconfig.h b/linphone/coreapi/lpconfig.h
index 5c146e7d35..17707d3759 100644
--- a/linphone/coreapi/lpconfig.h
+++ b/linphone/coreapi/lpconfig.h
@@ -32,6 +32,7 @@ extern "C" {
 #endif
 
 LpConfig * lp_config_new(const char *filename);
+int lp_config_read_file(LpConfig *lpconfig, const char *filename);
 const char *lp_config_get_string(LpConfig *lpconfig, const char *section, const char *key, const char *default_string);
 int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, int default_value);
 float lp_config_get_float(LpConfig *lpconfig,const char *section, const char *key, float default_value);
diff --git a/linphone/coreapi/private.h b/linphone/coreapi/private.h
index 94fc7764ab..513fd4a005 100644
--- a/linphone/coreapi/private.h
+++ b/linphone/coreapi/private.h
@@ -190,4 +190,8 @@ void linphone_proxy_config_get_contact(LinphoneProxyConfig *cfg, const char **ip
 LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri);
 int linphone_core_get_local_ip_for(const char *dest, char *result);
 
+void linphone_core_init(LinphoneCore *lc, const LinphoneCoreVTable *vtable,
+						const char *config_path, void * userdata);
+void linphone_core_uninit(LinphoneCore *lc);
+
 #endif /* _PRIVATE_H */
diff --git a/linphone/po/Makefile.in.in b/linphone/po/Makefile.in.in
index 57ef267b3e..402a25f7ac 100644
--- a/linphone/po/Makefile.in.in
+++ b/linphone/po/Makefile.in.in
@@ -21,7 +21,7 @@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
 PACKAGE = @PACKAGE@
 VERSION = @VERSION@
 
-SHELL = /bin/sh
+SHELL = @SHELL@
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -56,7 +56,7 @@ ALL_LINGUAS = @ALL_LINGUAS@
 
 PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi)
 
-USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep ^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep ^$$lang$$`"; then printf "$$lang "; fi; done; fi)
+USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep \^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep \^$$lang$$`"; then printf "$$lang "; fi; done; fi)
 
 USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done)
 
-- 
GitLab