forked from mirrors/linphone-iphone
Add XML2LPC lib/tool
This commit is contained in:
parent
4c346156ce
commit
148a0a91b5
10 changed files with 578 additions and 2 deletions
|
|
@ -4,7 +4,7 @@
|
|||
ACLOCAL_AMFLAGS = -I m4 $(ACLOCAL_MACOS_FLAGS)
|
||||
|
||||
SUBDIRS = build m4 pixmaps po @ORTP_DIR@ @MS2_DIR@ \
|
||||
coreapi console gtk share scripts
|
||||
coreapi console gtk share scripts tools
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
32
configure.ac
32
configure.ac
|
|
@ -140,6 +140,33 @@ AC_ARG_ENABLE(console_ui,
|
|||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-console_ui) ;;
|
||||
esac],[console_ui=true])
|
||||
|
||||
dnl conditionnal build of tools.
|
||||
AC_ARG_ENABLE(tools,
|
||||
[AS_HELP_STRING([--enable-tools=[yes/no]], [Turn on or off compilation of console interface (default=yes)])],
|
||||
[case "${enableval}" in
|
||||
yes) build_tools=true ;;
|
||||
no) build_tools=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-tools) ;;
|
||||
esac],[build_tools=check])
|
||||
|
||||
dnl check libxml2 (needed for tools)
|
||||
if test "$build_tools" != "false" ; then
|
||||
PKG_CHECK_MODULES(LIBXML2, [libxml-2.0],[],
|
||||
[
|
||||
if test "$build_tools" = "true" ; then
|
||||
AC_MSG_ERROR([Could not found libxml2, tools cannot be compiled.])
|
||||
else
|
||||
build_tools=false
|
||||
fi
|
||||
])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(BUILD_TOOLS, test x$build_tools != xfalse)
|
||||
if test "$build_tools" != "false" ; then
|
||||
build_tools=true
|
||||
AC_DEFINE(BUILD_TOOLS, 1, [Define if tools enabled] )
|
||||
fi
|
||||
|
||||
dnl conditionnal build of gtk interface.
|
||||
AC_ARG_ENABLE(gtk_ui,
|
||||
[AS_HELP_STRING([--enable-gtk_ui=[yes/no]], [Turn on or off compilation of gtk interface (default=yes)])],
|
||||
|
|
@ -418,8 +445,10 @@ AC_ARG_ENABLE(portaudio,
|
|||
|
||||
dnl build console if required
|
||||
AM_CONDITIONAL(BUILD_CONSOLE, test x$console_ui = xtrue)
|
||||
|
||||
dnl special things for arm-linux cross compilation toolchain
|
||||
AM_CONDITIONAL(ARMBUILD, test x$use_arm_toolchain = xyes)
|
||||
|
||||
dnl compilation of gtk user interface
|
||||
AM_CONDITIONAL(BUILD_GTK_UI, [test x$gtk_ui = xtrue ] )
|
||||
AM_CONDITIONAL(BUILD_WIN32, test x$mingw_found = xyes )
|
||||
|
|
@ -642,9 +671,11 @@ share/fr/Makefile
|
|||
share/it/Makefile
|
||||
share/ja/Makefile
|
||||
share/cs/Makefile
|
||||
share/xml/Makefile
|
||||
share/linphone.pc
|
||||
share/linphone.desktop
|
||||
scripts/Makefile
|
||||
tools/Makefile
|
||||
linphone.spec
|
||||
linphone.iss
|
||||
])
|
||||
|
|
@ -657,6 +688,7 @@ printf "* Video support\t\t\t%s\n" $video
|
|||
printf "* GTK interface\t\t\t%s\n" $gtk_ui
|
||||
printf "* Account assistant\t\t%s\n" $build_wizard
|
||||
printf "* Console interface\t\t%s\n" $console_ui
|
||||
printf "* Tools\t\t\t\t%s\n" $build_tools
|
||||
printf "* zRTP encryption (GPLv3)\t%s\n" $zrtp
|
||||
|
||||
if test "$enable_tunnel" = "true" ; then
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#ifndef LPCONFIG_H
|
||||
#define LPCONFIG_H
|
||||
|
||||
#include <ortp/port.h>
|
||||
|
||||
/**
|
||||
* The LpConfig object is used to manipulate a configuration file.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
SUBDIRS=C fr it ja cs
|
||||
SUBDIRS=C fr it ja cs xml
|
||||
|
||||
LINPHONE_SOUNDS=ringback.wav hello8000.wav hello16000.wav
|
||||
LINPHONE_RINGS=rings/orig.wav \
|
||||
|
|
|
|||
1
share/xml/Makefile.am
Normal file
1
share/xml/Makefile.am
Normal file
|
|
@ -0,0 +1 @@
|
|||
EXTRA_DIST=lpconfig.xsd
|
||||
45
share/xml/lpconfig.xsd
Normal file
45
share/xml/lpconfig.xsd
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://www.linphone.org/xsds/lpconfig.xsd"
|
||||
xmlns:tns="http://www.linphone.org/xsds/lpconfig.xsd"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<xs:element name="config" type="tns:LPConfig"></xs:element>
|
||||
|
||||
<xs:complexType name="LPConfig">
|
||||
<xs:sequence>
|
||||
<xs:element name="section" type="tns:LPSection" minOccurs="0" maxOccurs="unbounded"></xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="LPSection">
|
||||
<xs:sequence>
|
||||
<xs:element name="entry" type="tns:LPEntry" maxOccurs="unbounded" minOccurs="0">
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="name" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="1"></xs:minLength>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="LPEntry">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute name="overwrite" type="xs:boolean"
|
||||
use="optional" default="false">
|
||||
</xs:attribute>
|
||||
<xs:attribute name="name" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="1"></xs:minLength>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:schema>
|
||||
31
tools/Makefile.am
Normal file
31
tools/Makefile.am
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
AM_CPPFLAGS=\
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_srcdir)/coreapi \
|
||||
-I$(top_srcdir)/exosip
|
||||
|
||||
COMMON_CFLAGS=\
|
||||
-DIN_LINPHONE \
|
||||
$(LIBXML2_CFLAGS) \
|
||||
$(ORTP_CFLAGS) \
|
||||
$(STRICT_OPTIONS)
|
||||
|
||||
if BUILD_TOOLS
|
||||
|
||||
lib_LTLIBRARIES=libxml2lpc.la
|
||||
|
||||
libxml2lpc_la_SOURCES=xml2lpc.c xml2lpc.h
|
||||
libxml2lpc_la_CFLAGS=$(COMMON_CFLAGS)
|
||||
libxml2lpc_la_LIBADD=\
|
||||
$(LIBXML2_LIBS)
|
||||
|
||||
bin_PROGRAMS=xml2lpc_test
|
||||
|
||||
xml2lpc_test_SOURCES=xml2lpc_test.c
|
||||
xml2lpc_test_CFLAGS=$(COMMON_CFLAGS)
|
||||
xml2lpc_test_LDADD=$(top_builddir)/coreapi/liblinphone.la libxml2lpc.la
|
||||
|
||||
endif
|
||||
|
||||
|
||||
341
tools/xml2lpc.c
Normal file
341
tools/xml2lpc.c
Normal file
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2012 Belledonne Communications SARL
|
||||
Yann DIORCET (yann.diorcet@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "xml2lpc.h"
|
||||
#include <string.h>
|
||||
#include <libxml/xmlreader.h>
|
||||
|
||||
|
||||
#define XML2LPC_BZ 2048
|
||||
|
||||
struct _xml2lpc_context {
|
||||
LpConfig *lpc;
|
||||
xml2lpc_function cbf;
|
||||
void *ctx;
|
||||
|
||||
xmlDoc *doc;
|
||||
xmlDoc *xsd;
|
||||
char errorBuffer[XML2LPC_BZ];
|
||||
char warningBuffer[XML2LPC_BZ];
|
||||
};
|
||||
|
||||
|
||||
xml2lpc_context* xml2lpc_context_new(xml2lpc_function cbf, void *ctx) {
|
||||
xml2lpc_context *xmlCtx = (xml2lpc_context*)malloc(sizeof(xml2lpc_context));
|
||||
if(xmlCtx != NULL) {
|
||||
xmlCtx->lpc = NULL;
|
||||
xmlCtx->cbf = cbf;
|
||||
xmlCtx->ctx = ctx;
|
||||
|
||||
xmlCtx->doc = NULL;
|
||||
xmlCtx->xsd = NULL;
|
||||
xmlCtx->errorBuffer[0]='\0';
|
||||
xmlCtx->warningBuffer[0]='\0';
|
||||
}
|
||||
return xmlCtx;
|
||||
}
|
||||
|
||||
void xml2lpc_context_destroy(xml2lpc_context *ctx) {
|
||||
if(ctx->doc != NULL) {
|
||||
xmlFreeDoc(ctx->doc);
|
||||
ctx->doc = NULL;
|
||||
}
|
||||
if(ctx->xsd != NULL) {
|
||||
xmlFreeDoc(ctx->xsd);
|
||||
ctx->xsd = NULL;
|
||||
}
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void xml2lpc_context_clear_logs(xml2lpc_context *ctx) {
|
||||
ctx->errorBuffer[0]='\0';
|
||||
ctx->warningBuffer[0]='\0';
|
||||
}
|
||||
|
||||
void xml2lpc_log(xml2lpc_context *xmlCtx, int level, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
if(xmlCtx->cbf != NULL) {
|
||||
xmlCtx->cbf((xmlCtx)->ctx, level, fmt, args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void xml2lpc_genericxml_error(void *ctx, const char *fmt, ...) {
|
||||
xml2lpc_context *xmlCtx = (xml2lpc_context *)ctx;
|
||||
int sl = strlen(xmlCtx->errorBuffer);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(xmlCtx->errorBuffer + sl, XML2LPC_BZ-sl, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void xml2lpc_genericxml_warning(void *ctx, const char *fmt, ...) {
|
||||
xml2lpc_context *xmlCtx = (xml2lpc_context *)ctx;
|
||||
int sl = strlen(xmlCtx->warningBuffer);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(xmlCtx->warningBuffer + sl, XML2LPC_BZ-sl, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void dumpNodes(int level, xmlNode * a_node, xml2lpc_context *ctx) {
|
||||
xmlNode *cur_node = NULL;
|
||||
|
||||
for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
|
||||
if (cur_node->type == XML_ELEMENT_NODE) {
|
||||
xml2lpc_log(ctx, XML2LPC_DEBUG, "node level: %d type: Element, name: %s", level, cur_node->name);
|
||||
} else {
|
||||
xml2lpc_log(ctx, XML2LPC_DEBUG, "node level: %d type: %d, name: %s", level, cur_node->type, cur_node->name);
|
||||
}
|
||||
|
||||
dumpNodes(level + 1, cur_node->children, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dumpNode(xmlNode *node, xml2lpc_context *ctx) {
|
||||
xml2lpc_log(ctx, XML2LPC_DEBUG, "node type: %d, name: %s", node->type, node->name);
|
||||
}
|
||||
|
||||
static void dumpAttr(xmlNode *node, xml2lpc_context *ctx) {
|
||||
xml2lpc_log(ctx, XML2LPC_DEBUG, "attr name: %s value:%s", node->name, node->children->content);
|
||||
}
|
||||
|
||||
static void dumpContent(xmlNode *node, xml2lpc_context *ctx) {
|
||||
xml2lpc_log(ctx, XML2LPC_DEBUG, "content: %s", node->children->content);
|
||||
}
|
||||
|
||||
static int processEntry(xmlElement *element, const char *sectionName, xml2lpc_context *ctx) {
|
||||
xmlNode *cur_attr = NULL;
|
||||
const char *name = NULL;
|
||||
const char *value = NULL;
|
||||
bool_t overwrite = FALSE;
|
||||
|
||||
for (cur_attr = (xmlNode *)element->attributes; cur_attr; cur_attr = cur_attr->next) {
|
||||
dumpAttr(cur_attr, ctx);
|
||||
if(strcmp((const char*)cur_attr->name, "name") == 0) {
|
||||
name = (const char*)cur_attr->children->content;
|
||||
} else if(strcmp((const char*)cur_attr->name, "overwrite") == 0) {
|
||||
if(strcmp((const char*)cur_attr->children->content, "true") == 0) {
|
||||
overwrite = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value = (const char *)element->children->content;
|
||||
dumpContent((xmlNode *)element, ctx);
|
||||
|
||||
if(name != NULL) {
|
||||
const char *str = lp_config_get_string(ctx->lpc, sectionName, name, NULL);
|
||||
if(str == NULL || overwrite) {
|
||||
xml2lpc_log(ctx, XML2LPC_MESSAGE, "Set %s|%s = %s",sectionName, name, value);
|
||||
lp_config_set_string(ctx->lpc, sectionName, name, value);
|
||||
} else {
|
||||
xml2lpc_log(ctx, XML2LPC_MESSAGE, "Don't touch %s|%s = %s",sectionName, name, str);
|
||||
}
|
||||
} else {
|
||||
xml2lpc_log(ctx, XML2LPC_WARNING, "ignored entry with no \"name\" attribute line:%d",xmlGetLineNo((xmlNode*)element));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int processSection(xmlElement *element, xml2lpc_context *ctx) {
|
||||
xmlNode *cur_node = NULL;
|
||||
xmlNode *cur_attr = NULL;
|
||||
const char *name = NULL;
|
||||
|
||||
for (cur_attr = (xmlNode *)element->attributes; cur_attr; cur_attr = cur_attr->next) {
|
||||
dumpAttr(cur_attr, ctx);
|
||||
if(strcmp((const char*)cur_attr->name, "name") == 0) {
|
||||
name = (const char*)cur_attr->children->content;
|
||||
}
|
||||
}
|
||||
|
||||
if(name != NULL) {
|
||||
for (cur_node = element->children; cur_node; cur_node = cur_node->next) {
|
||||
dumpNode(cur_node, ctx);
|
||||
if (cur_node->type == XML_ELEMENT_NODE) {
|
||||
if(strcmp((const char*)cur_node->name, "entry") == 0 ) {
|
||||
processEntry((xmlElement*)cur_node, name, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
xml2lpc_log(ctx, XML2LPC_WARNING, "ignored section with no \"name\" attribute, line:%d", xmlGetLineNo((xmlNode*)element));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int processConfig(xmlElement *element, xml2lpc_context *ctx) {
|
||||
xmlNode *cur_node = NULL;
|
||||
|
||||
for (cur_node = element->children; cur_node; cur_node = cur_node->next) {
|
||||
dumpNode(cur_node, ctx);
|
||||
if (cur_node->type == XML_ELEMENT_NODE &&
|
||||
strcmp((const char*)cur_node->name, "section") == 0 ) {
|
||||
processSection((xmlElement*)cur_node, ctx);
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int processDoc(xmlNode *node, xml2lpc_context *ctx) {
|
||||
dumpNode(node, ctx);
|
||||
|
||||
if (node->type == XML_ELEMENT_NODE &&
|
||||
strcmp((const char*)node->name, "config") == 0 ) {
|
||||
processConfig((xmlElement*)node, ctx);
|
||||
} else {
|
||||
xml2lpc_log(ctx, XML2LPC_WARNING, "root element is not \"config\", line:%d", xmlGetLineNo(node));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int internal_convert_xml2lpc(xmlDoc *doc, xml2lpc_context *ctx) {
|
||||
xml2lpc_log(ctx, XML2LPC_DEBUG, "Parse started");
|
||||
xmlNode *rootNode = xmlDocGetRootElement(doc);
|
||||
//dumpNodes(0, rootNode, cbf, ctx);
|
||||
int ret = processDoc(rootNode, ctx);
|
||||
xml2lpc_log(ctx, XML2LPC_DEBUG, "Parse ended ret:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xml2lpc_validate(xml2lpc_context *xmlCtx) {
|
||||
xml2lpc_context_clear_logs(xmlCtx);
|
||||
xmlSchemaValidCtxtPtr validCtx;
|
||||
xmlSchemaParserCtxtPtr parserCtx = xmlSchemaNewDocParserCtxt(xmlCtx->xsd);
|
||||
validCtx = xmlSchemaNewValidCtxt(xmlSchemaParse(parserCtx));
|
||||
xmlSchemaSetValidErrors(validCtx, xml2lpc_genericxml_error, xml2lpc_genericxml_warning, xmlCtx);
|
||||
int ret = xmlSchemaValidateDoc(validCtx, xmlCtx->doc);
|
||||
if(ret >0) {
|
||||
xml2lpc_log(xmlCtx, XML2LPC_WARNING, "%s", xmlCtx->warningBuffer);
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "%s", xmlCtx->errorBuffer);
|
||||
} else {
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "Internal error");
|
||||
}
|
||||
xmlSchemaFreeValidCtxt(validCtx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xml2lpc_convert(xml2lpc_context *xmlCtx, LpConfig *lpc) {
|
||||
xml2lpc_context_clear_logs(xmlCtx);
|
||||
xmlCtx->lpc = lpc;
|
||||
return internal_convert_xml2lpc(xmlCtx->doc, xmlCtx);
|
||||
}
|
||||
|
||||
int xml2lpc_set_xml_file(xml2lpc_context* xmlCtx, const char *filename) {
|
||||
xml2lpc_context_clear_logs(xmlCtx);
|
||||
xmlSetGenericErrorFunc(xmlCtx, xml2lpc_genericxml_error);
|
||||
if(xmlCtx->doc != NULL) {
|
||||
xmlFreeDoc(xmlCtx->doc);
|
||||
xmlCtx->doc = NULL;
|
||||
}
|
||||
xmlCtx->doc = xmlReadFile(filename, NULL, 0);
|
||||
if(xmlCtx->doc == NULL) {
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "Can't open/parse file \"%s\"", filename);
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "%s", xmlCtx->errorBuffer);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xml2lpc_set_xml_fd(xml2lpc_context* xmlCtx, int fd) {
|
||||
xml2lpc_context_clear_logs(xmlCtx);
|
||||
xmlSetGenericErrorFunc(xmlCtx, xml2lpc_genericxml_error);
|
||||
if(xmlCtx->doc != NULL) {
|
||||
xmlFreeDoc(xmlCtx->doc);
|
||||
xmlCtx->doc = NULL;
|
||||
}
|
||||
xmlCtx->doc = xmlReadFd(fd, 0, NULL, 0);
|
||||
if(xmlCtx->doc == NULL) {
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "Can't open/parse fd \"%d\"", fd);
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "%s", xmlCtx->errorBuffer);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xml2lpc_set_xml_string(xml2lpc_context* xmlCtx, const char *content) {
|
||||
xml2lpc_context_clear_logs(xmlCtx);
|
||||
xmlSetGenericErrorFunc(xmlCtx, xml2lpc_genericxml_error);
|
||||
if(xmlCtx->doc != NULL) {
|
||||
xmlFreeDoc(xmlCtx->doc);
|
||||
xmlCtx->doc = NULL;
|
||||
}
|
||||
xmlCtx->doc = xmlReadDoc((const unsigned char*)content, 0, NULL, 0);
|
||||
if(xmlCtx->doc == NULL) {
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "Can't parse string");
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "%s", xmlCtx->errorBuffer);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xml2lpc_set_xsd_file(xml2lpc_context* xmlCtx, const char *filename) {
|
||||
xml2lpc_context_clear_logs(xmlCtx);
|
||||
xmlSetGenericErrorFunc(xmlCtx, xml2lpc_genericxml_error);
|
||||
if(xmlCtx->xsd != NULL) {
|
||||
xmlFreeDoc(xmlCtx->xsd);
|
||||
xmlCtx->xsd = NULL;
|
||||
}
|
||||
xmlCtx->xsd = xmlReadFile(filename, NULL, 0);
|
||||
if(xmlCtx->xsd == NULL) {
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "Can't open/parse file \"%s\"", filename);
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "%s", xmlCtx->errorBuffer);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xml2lpc_set_xsd_fd(xml2lpc_context* xmlCtx, int fd) {
|
||||
xml2lpc_context_clear_logs(xmlCtx);
|
||||
xmlSetGenericErrorFunc(xmlCtx, xml2lpc_genericxml_error);
|
||||
if(xmlCtx->xsd != NULL) {
|
||||
xmlFreeDoc(xmlCtx->xsd);
|
||||
xmlCtx->xsd = NULL;
|
||||
}
|
||||
xmlCtx->xsd = xmlReadFd(fd, 0, NULL, 0);
|
||||
if(xmlCtx->xsd == NULL) {
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "Can't open/parse fd \"%d\"", fd);
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "%s", xmlCtx->errorBuffer);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xml2lpc_set_xsd_string(xml2lpc_context* xmlCtx, const char *content) {
|
||||
xml2lpc_context_clear_logs(xmlCtx);
|
||||
xmlSetGenericErrorFunc(xmlCtx, xml2lpc_genericxml_error);
|
||||
if(xmlCtx->xsd != NULL) {
|
||||
xmlFreeDoc(xmlCtx->xsd);
|
||||
xmlCtx->xsd = NULL;
|
||||
}
|
||||
xmlCtx->xsd = xmlReadDoc((const unsigned char*)content, 0, NULL, 0);
|
||||
if(xmlCtx->xsd == NULL) {
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "Can't parse string");
|
||||
xml2lpc_log(xmlCtx, XML2LPC_ERROR, "%s", xmlCtx->errorBuffer);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
52
tools/xml2lpc.h
Normal file
52
tools/xml2lpc.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2012 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef XML2LPC_H_
|
||||
#define XML2LPC_H_
|
||||
|
||||
#include "lpconfig.h"
|
||||
|
||||
typedef struct _xml2lpc_context xml2lpc_context;
|
||||
|
||||
typedef enum _xml2lpc_log_level {
|
||||
XML2LPC_DEBUG = 0,
|
||||
XML2LPC_MESSAGE,
|
||||
XML2LPC_WARNING,
|
||||
XML2LPC_ERROR
|
||||
} xml2lpc_log_level;
|
||||
|
||||
typedef void(*xml2lpc_function)(void *ctx, xml2lpc_log_level level, const char *fmt, va_list list);
|
||||
|
||||
xml2lpc_context* xml2lpc_context_new(xml2lpc_function cbf, void *ctx);
|
||||
void xml2lpc_context_destroy(xml2lpc_context*);
|
||||
|
||||
int xml2lpc_set_xml_file(xml2lpc_context* context, const char *filename);
|
||||
int xml2lpc_set_xml_fd(xml2lpc_context* context, int fd);
|
||||
int xml2lpc_set_xml_string(xml2lpc_context* context, const char *content);
|
||||
|
||||
int xml2lpc_set_xsd_file(xml2lpc_context* context, const char *filename);
|
||||
int xml2lpc_set_xsd_fd(xml2lpc_context* context, int fd);
|
||||
int xml2lpc_set_xsd_string(xml2lpc_context* context, const char *content);
|
||||
|
||||
int xml2lpc_validate(xml2lpc_context *context);
|
||||
int xml2lpc_convert(xml2lpc_context *context, LpConfig *lpc);
|
||||
|
||||
|
||||
|
||||
#endif //XML2LPC_H_
|
||||
72
tools/xml2lpc_test.c
Normal file
72
tools/xml2lpc_test.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2012 Belledonne Communications SARL
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "xml2lpc.h"
|
||||
|
||||
void cb_function(void *ctx, xml2lpc_log_level level, const char *msg, va_list list) {
|
||||
const char *header;
|
||||
switch(level) {
|
||||
case XML2LPC_DEBUG:
|
||||
header = "DEBUG";
|
||||
break;
|
||||
case XML2LPC_MESSAGE:
|
||||
header = "MESSAGE";
|
||||
break;
|
||||
case XML2LPC_WARNING:
|
||||
header = "WARNING";
|
||||
break;
|
||||
case XML2LPC_ERROR:
|
||||
header = "ERROR";
|
||||
break;
|
||||
}
|
||||
fprintf(stdout, "%s - ", header);
|
||||
vfprintf(stdout, msg, list);
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
|
||||
void show_usage(int argc, char *argv[]) {
|
||||
fprintf(stderr, "usage %s convert <xml_file> <lpc_file>\n"
|
||||
" %s validate <xml_file> <xsd_file>\n",
|
||||
argv[0], argv[0]);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if(argc != 4) {
|
||||
show_usage(argc, argv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
xml2lpc_context *ctx = xml2lpc_context_new(cb_function, NULL);
|
||||
xml2lpc_set_xml_file(ctx, argv[2]);
|
||||
if(strcmp("convert", argv[1]) == 0) {
|
||||
LpConfig *lpc = lp_config_new(argv[3]);
|
||||
xml2lpc_convert(ctx, lpc);
|
||||
lp_config_sync(lpc);
|
||||
lp_config_destroy(lpc);
|
||||
} else if(strcmp("validate", argv[1]) == 0) {
|
||||
xml2lpc_set_xsd_file(ctx, argv[3]);
|
||||
xml2lpc_validate(ctx);
|
||||
} else {
|
||||
show_usage(argc, argv);
|
||||
}
|
||||
xml2lpc_context_destroy(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Add table
Reference in a new issue