Fix xsd generation in ddsconf
Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
This commit is contained in:
parent
93c75186f0
commit
f4e99f41f6
13 changed files with 132 additions and 101 deletions
|
@ -192,7 +192,6 @@ script:
|
||||||
-DENABLE_LIFESPAN=${LIFESPAN}
|
-DENABLE_LIFESPAN=${LIFESPAN}
|
||||||
-DENABLE_DEADLINE_MISSED=${DEADLINE}
|
-DENABLE_DEADLINE_MISSED=${DEADLINE}
|
||||||
-DBUILD_TESTING=on
|
-DBUILD_TESTING=on
|
||||||
-DBUILD_SCHEMA=on
|
|
||||||
-DWERROR=on
|
-DWERROR=on
|
||||||
-G "${GENERATOR}" ..
|
-G "${GENERATOR}" ..
|
||||||
- |
|
- |
|
||||||
|
@ -219,8 +218,6 @@ script:
|
||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
if [ "${SSL}" = "YES" ] && [ "${SECURITY}" = "YES" ]; then
|
if [ "${SSL}" = "YES" ] && [ "${SECURITY}" = "YES" ]; then
|
||||||
cmake --build . --config ${BUILD_TYPE} --target schema && \
|
|
||||||
cmake --build . --config ${BUILD_TYPE} --target options_doc && \
|
|
||||||
diff --strip-trailing-cr ../etc/cyclonedds.rnc docs/cyclonedds.rnc && \
|
diff --strip-trailing-cr ../etc/cyclonedds.rnc docs/cyclonedds.rnc && \
|
||||||
diff --strip-trailing-cr ../etc/cyclonedds.xsd docs/cyclonedds.xsd && \
|
diff --strip-trailing-cr ../etc/cyclonedds.xsd docs/cyclonedds.xsd && \
|
||||||
diff --strip-trailing-cr ../docs/manual/options.md docs/manual/options.md
|
diff --strip-trailing-cr ../docs/manual/options.md docs/manual/options.md
|
||||||
|
|
|
@ -210,8 +210,12 @@ option(BUILD_TESTING "Build the testing tree." OFF)
|
||||||
include(CTest)
|
include(CTest)
|
||||||
|
|
||||||
option(BUILD_DOCS "Build documentation." OFF)
|
option(BUILD_DOCS "Build documentation." OFF)
|
||||||
option(BUILD_SCHEMA "Build generated schema for configuration options." OFF)
|
if(CMAKE_CROSSCOMPILING)
|
||||||
|
set(not_crosscompiling OFF)
|
||||||
|
else()
|
||||||
|
set(not_crosscompiling ON)
|
||||||
|
endif()
|
||||||
|
option(BUILD_SCHEMA "Build generated schema for configuration options." ${not_crosscompiling})
|
||||||
# Build all executables and libraries into the top-level /bin and /lib folders.
|
# Build all executables and libraries into the top-level /bin and /lib folders.
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
||||||
|
|
|
@ -18,18 +18,14 @@ set(options_md "${CMAKE_CURRENT_BINARY_DIR}/manual/options.md")
|
||||||
|
|
||||||
if(BUILD_SCHEMA OR BUILD_DOCS)
|
if(BUILD_SCHEMA OR BUILD_DOCS)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT "${cyclonedds_rnc}" "${cyclonedds_xsd}"
|
OUTPUT "${cyclonedds_rnc}" "${cyclonedds_xsd}" "${options_md}"
|
||||||
COMMAND ddsconf ARGS -f rnc -o "${cyclonedds_rnc}"
|
COMMAND ddsconf ARGS -f rnc -o "${cyclonedds_rnc}"
|
||||||
COMMAND ddsconf ARGS -f xsd -o "${cyclonedds_xsd}"
|
COMMAND ddsconf ARGS -f xsd -o "${cyclonedds_xsd}"
|
||||||
DEPENDS ddsconf)
|
|
||||||
add_custom_target(schema DEPENDS "${cyclonedds_rnc}" "${cyclonedds_xsd}")
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT "${options_md}"
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory manual
|
COMMAND ${CMAKE_COMMAND} -E make_directory manual
|
||||||
COMMAND ddsconf ARGS -f md -o "${options_md}"
|
COMMAND ddsconf ARGS -f md -o "${options_md}"
|
||||||
DEPENDS ddsconf)
|
DEPENDS ddsconf)
|
||||||
add_custom_target(options_doc DEPENDS "${options_md}")
|
add_custom_target(
|
||||||
|
schema ALL DEPENDS "${cyclonedds_rnc}" "${cyclonedds_xsd}" "${options_md}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BUILD_DOCS)
|
if(BUILD_DOCS)
|
||||||
|
@ -39,7 +35,7 @@ if(BUILD_DOCS)
|
||||||
BREATHE_PROJECTS ddsc_api_docs
|
BREATHE_PROJECTS ddsc_api_docs
|
||||||
BUILDER html
|
BUILDER html
|
||||||
SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/manual")
|
SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/manual")
|
||||||
add_dependencies(docs options_doc)
|
add_dependencies(docs schema)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/docs"
|
DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/docs"
|
||||||
|
|
|
@ -101,7 +101,7 @@ CycloneDDS configuration""" ] ]
|
||||||
text
|
text
|
||||||
}
|
}
|
||||||
}*
|
}*
|
||||||
}?
|
}*
|
||||||
& [ a:documentation [ xml:lang="en" """
|
& [ a:documentation [ xml:lang="en" """
|
||||||
<p>This element statically configures an addresses for discovery.</p>""" ] ]
|
<p>This element statically configures an addresses for discovery.</p>""" ] ]
|
||||||
element Peer {
|
element Peer {
|
||||||
|
@ -983,7 +983,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br>
|
||||||
}?
|
}?
|
||||||
}?
|
}?
|
||||||
}?
|
}?
|
||||||
}*
|
}?
|
||||||
& [ a:documentation [ xml:lang="en" """
|
& [ a:documentation [ xml:lang="en" """
|
||||||
<p>The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c.</p>""" ] ]
|
<p>The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c.</p>""" ] ]
|
||||||
element Sizing {
|
element Sizing {
|
||||||
|
|
|
@ -17,17 +17,17 @@ CycloneDDS configuration</xs:documentation>
|
||||||
<p>The General element specifying Domain related settings.</p></xs:documentation>
|
<p>The General element specifying Domain related settings.</p></xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:choice minOccurs="0">
|
<xs:all>
|
||||||
<xs:element ref="config:Compatibility"/>
|
<xs:element minOccurs="0" ref="config:Compatibility"/>
|
||||||
<xs:element ref="config:Discovery"/>
|
<xs:element minOccurs="0" ref="config:Discovery"/>
|
||||||
<xs:element ref="config:General"/>
|
<xs:element minOccurs="0" ref="config:General"/>
|
||||||
<xs:element ref="config:Internal"/>
|
<xs:element minOccurs="0" ref="config:Internal"/>
|
||||||
<xs:element ref="config:Partitioning"/>
|
<xs:element minOccurs="0" ref="config:Partitioning"/>
|
||||||
<xs:element ref="config:SSL"/>
|
<xs:element minOccurs="0" ref="config:SSL"/>
|
||||||
<xs:element maxOccurs="unbounded" ref="config:Security"/>
|
<xs:element minOccurs="0" ref="config:Security"/>
|
||||||
<xs:element ref="config:Sizing"/>
|
<xs:element minOccurs="0" ref="config:Sizing"/>
|
||||||
<xs:element ref="config:TCP"/>
|
<xs:element minOccurs="0" ref="config:TCP"/>
|
||||||
<xs:element ref="config:ThreadPool"/>
|
<xs:element minOccurs="0" ref="config:ThreadPool"/>
|
||||||
<xs:element minOccurs="0" name="Threads">
|
<xs:element minOccurs="0" name="Threads">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>
|
<xs:documentation>
|
||||||
|
@ -39,8 +39,8 @@ CycloneDDS configuration</xs:documentation>
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element ref="config:Tracing"/>
|
<xs:element minOccurs="0" ref="config:Tracing"/>
|
||||||
</xs:choice>
|
</xs:all>
|
||||||
<xs:attribute name="Id">
|
<xs:attribute name="Id">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>
|
<xs:documentation>
|
||||||
|
@ -179,9 +179,9 @@ CycloneDDS configuration</xs:documentation>
|
||||||
<p>This element statically configures addresses for discovery.</p></xs:documentation>
|
<p>This element statically configures addresses for discovery.</p></xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:choice minOccurs="0">
|
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
<xs:element ref="config:Group"/>
|
<xs:element ref="config:Group"/>
|
||||||
<xs:element maxOccurs="unbounded" ref="config:Peer"/>
|
<xs:element ref="config:Peer"/>
|
||||||
</xs:choice>
|
</xs:choice>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
|
|
@ -1626,7 +1626,9 @@ static struct cfgelem discovery_peers_cfgelems[] = {
|
||||||
"<p>This element statically configures a fault tolerant group of "
|
"<p>This element statically configures a fault tolerant group of "
|
||||||
"addresses for discovery. Each member of the group is tried in "
|
"addresses for discovery. Each member of the group is tried in "
|
||||||
"sequence until one succeeds.</p>"
|
"sequence until one succeeds.</p>"
|
||||||
)),
|
),
|
||||||
|
MAXIMUM(0)), /* Group element can occur more than once, but 1 is required
|
||||||
|
because of the way its processed (for now) */
|
||||||
END_MARKER
|
END_MARKER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1849,7 +1851,9 @@ static struct cfgelem domain_cfgelems[] = {
|
||||||
DESCRIPTION(
|
DESCRIPTION(
|
||||||
"<p>This element is used to configure Cyclone DDS with the DDS Security "
|
"<p>This element is used to configure Cyclone DDS with the DDS Security "
|
||||||
"specification plugins and settings.</p>"
|
"specification plugins and settings.</p>"
|
||||||
)),
|
),
|
||||||
|
MAXIMUM(1)), /* Security must occur at most once, but INT_MAX is required
|
||||||
|
because of the way its processed (for now) */
|
||||||
#endif
|
#endif
|
||||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||||
GROUP("Partitioning", partitioning_cfgelems, NULL, 1,
|
GROUP("Partitioning", partitioning_cfgelems, NULL, 1,
|
||||||
|
|
|
@ -230,6 +230,8 @@ DI(if_omg_security);
|
||||||
#define RANGE(...) /* drop */
|
#define RANGE(...) /* drop */
|
||||||
#define UNIT(...) /* drop */
|
#define UNIT(...) /* drop */
|
||||||
#define VALUES(...) /* drop */
|
#define VALUES(...) /* drop */
|
||||||
|
#define MAXIMUM(...) /* drop */
|
||||||
|
#define MINIMUM(...) /* drop */
|
||||||
|
|
||||||
#define NOMEMBER 0, 0
|
#define NOMEMBER 0, 0
|
||||||
#define NOFUNCTIONS 0, 0, 0, 0
|
#define NOFUNCTIONS 0, 0, 0, 0
|
||||||
|
@ -269,6 +271,12 @@ static const struct cfgelem root_cfgelem = {
|
||||||
#undef MEMBER
|
#undef MEMBER
|
||||||
#undef MEMBEROF
|
#undef MEMBEROF
|
||||||
#undef FUNCTIONS
|
#undef FUNCTIONS
|
||||||
|
#undef DESCRIPTION
|
||||||
|
#undef RANGE
|
||||||
|
#undef UNIT
|
||||||
|
#undef VALUES
|
||||||
|
#undef MAXIMUM
|
||||||
|
#undef MINIMUM
|
||||||
#undef NOMEMBER
|
#undef NOMEMBER
|
||||||
#undef NOFUNCTIONS
|
#undef NOFUNCTIONS
|
||||||
#undef NODATA
|
#undef NODATA
|
||||||
|
|
|
@ -50,10 +50,12 @@
|
||||||
#define RANGE(str) .range = str
|
#define RANGE(str) .range = str
|
||||||
#define UNIT(str) .unit = str
|
#define UNIT(str) .unit = str
|
||||||
#define VALUES(...) .values = (const char *[]){ __VA_ARGS__, NULL }
|
#define VALUES(...) .values = (const char *[]){ __VA_ARGS__, NULL }
|
||||||
|
#define MAXIMUM(num) .force_maximum = 1, .maximum = num
|
||||||
|
#define MINIMUM(num) .force_minimum = 1, .minimum = num
|
||||||
|
|
||||||
#define NOMEMBER /* drop */
|
#define NOMEMBER /* drop */
|
||||||
#define NOFUNCTIONS /* drop */
|
#define NOFUNCTIONS /* drop */
|
||||||
#define NOMETADATA { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL }
|
#define NOMETADATA { NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL }
|
||||||
#define END_MARKER { NULL, NULL, NULL, 0, NULL, NULL, NOMETADATA }
|
#define END_MARKER { NULL, NULL, NULL, 0, NULL, NULL, NOMETADATA }
|
||||||
|
|
||||||
#define ELEMENT(name, elems, attrs, multip, dflt, desc, ...) \
|
#define ELEMENT(name, elems, attrs, multip, dflt, desc, ...) \
|
||||||
|
@ -76,8 +78,8 @@
|
||||||
EXPAND(ELEMENT, (name, NULL, attrs, multip, dflt, desc, .type = "string", __VA_ARGS__))
|
EXPAND(ELEMENT, (name, NULL, attrs, multip, dflt, desc, .type = "string", __VA_ARGS__))
|
||||||
#define LIST(name, attrs, multip, dflt, ofst, funcs, desc, ...) \
|
#define LIST(name, attrs, multip, dflt, ofst, funcs, desc, ...) \
|
||||||
EXPAND(ELEMENT, (name, NULL, attrs, multip, dflt, desc, .type = "list", __VA_ARGS__))
|
EXPAND(ELEMENT, (name, NULL, attrs, multip, dflt, desc, .type = "list", __VA_ARGS__))
|
||||||
#define GROUP(name, elems, attrs, multip, ofst, funcs, desc) \
|
#define GROUP(name, elems, attrs, multip, ofst, funcs, desc, ...) \
|
||||||
EXPAND(ELEMENT, (name, elems, attrs, multip, NULL, desc, .type = "group"))
|
EXPAND(ELEMENT, (name, elems, attrs, multip, NULL, desc, .type = "group", __VA_ARGS__))
|
||||||
|
|
||||||
#include "dds/ddsi/ddsi_cfgelems.h"
|
#include "dds/ddsi/ddsi_cfgelems.h"
|
||||||
/* undefine element macros */
|
/* undefine element macros */
|
||||||
|
@ -89,6 +91,8 @@
|
||||||
#undef RANGE
|
#undef RANGE
|
||||||
#undef UNIT
|
#undef UNIT
|
||||||
#undef VALUES
|
#undef VALUES
|
||||||
|
#undef MAXIMUM
|
||||||
|
#undef MINIMUM
|
||||||
#undef NOMEMBER
|
#undef NOMEMBER
|
||||||
#undef NOFUNCTIONS
|
#undef NOFUNCTIONS
|
||||||
#undef NOMETADATA
|
#undef NOMETADATA
|
||||||
|
@ -228,6 +232,9 @@ int islist(const struct cfgelem *elem)
|
||||||
|
|
||||||
int minimum(const struct cfgelem *elem)
|
int minimum(const struct cfgelem *elem)
|
||||||
{
|
{
|
||||||
|
if (elem->meta.force_minimum) {
|
||||||
|
return elem->meta.minimum;
|
||||||
|
} else {
|
||||||
switch (elem->multiplicity) {
|
switch (elem->multiplicity) {
|
||||||
case 0: /* special case, treat as-if 1 */
|
case 0: /* special case, treat as-if 1 */
|
||||||
case 1: /* required if there is no default */
|
case 1: /* required if there is no default */
|
||||||
|
@ -238,9 +245,13 @@ int minimum(const struct cfgelem *elem)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int maximum(const struct cfgelem *elem)
|
int maximum(const struct cfgelem *elem)
|
||||||
{
|
{
|
||||||
|
if (elem->meta.force_maximum) {
|
||||||
|
return elem->meta.maximum;
|
||||||
|
} else {
|
||||||
switch (elem->multiplicity) {
|
switch (elem->multiplicity) {
|
||||||
case INT_MAX:
|
case INT_MAX:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -251,6 +262,7 @@ int maximum(const struct cfgelem *elem)
|
||||||
return elem->multiplicity;
|
return elem->multiplicity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int haschildren(const struct cfgelem *elem)
|
int haschildren(const struct cfgelem *elem)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,6 +31,8 @@ struct cfgmeta {
|
||||||
char *pattern;
|
char *pattern;
|
||||||
char *description;
|
char *description;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
const int force_maximum, maximum;
|
||||||
|
const int force_minimum, minimum;
|
||||||
const char *type;
|
const char *type;
|
||||||
const char *unit;
|
const char *unit;
|
||||||
const char *range;
|
const char *range;
|
||||||
|
|
|
@ -103,32 +103,32 @@ static void printtype(
|
||||||
(void)units;
|
(void)units;
|
||||||
assert(!isgroup(elem));
|
assert(!isgroup(elem));
|
||||||
if (isbool(elem)) {
|
if (isbool(elem)) {
|
||||||
fprintf(out, "Boolean\n");
|
fputs("Boolean\n", out);
|
||||||
} else if (islist(elem)) {
|
} else if (islist(elem)) {
|
||||||
assert(elem->meta.values);
|
assert(elem->meta.values);
|
||||||
fprintf(out, "One of:\n");
|
fputs("One of:\n", out);
|
||||||
if (elem->value && strlen(elem->value))
|
if (elem->value && strlen(elem->value))
|
||||||
fprintf(out, "* Keyword: %s\n", elem->value);
|
fprintf(out, "* Keyword: %s\n", elem->value);
|
||||||
fprintf(out, "* Comma-separated list of: ");
|
fputs("* Comma-separated list of: ", out);
|
||||||
for (const char **v = elem->meta.values; *v; v++) {
|
for (const char **v = elem->meta.values; *v; v++) {
|
||||||
fprintf(out, "%s%s", v == elem->meta.values ? "" : ", ", *v);
|
fprintf(out, "%s%s", v == elem->meta.values ? "" : ", ", *v);
|
||||||
}
|
}
|
||||||
fprintf(out, "\n");
|
fputs("\n", out);
|
||||||
if (!elem->value || !strlen(elem->value))
|
if (!elem->value || !strlen(elem->value))
|
||||||
fprintf(out, "* Or empty\n");
|
fputs("* Or empty\n", out);
|
||||||
} else if (isenum(elem)) {
|
} else if (isenum(elem)) {
|
||||||
assert(elem->meta.values);
|
assert(elem->meta.values);
|
||||||
fprintf(out, "One of: ");
|
fputs("One of: ", out);
|
||||||
for (const char **v = elem->meta.values; *v; v++) {
|
for (const char **v = elem->meta.values; *v; v++) {
|
||||||
fprintf(out, "%s%s", v == elem->meta.values ? "" : ", ", *v);
|
fprintf(out, "%s%s", v == elem->meta.values ? "" : ", ", *v);
|
||||||
}
|
}
|
||||||
fprintf(out, "\n");
|
fputs("\n", out);
|
||||||
} else if (isint(elem)) {
|
} else if (isint(elem)) {
|
||||||
fprintf(out, "Integer\n");
|
fputs("Integer\n", out);
|
||||||
} else if (elem->meta.unit) {
|
} else if (elem->meta.unit) {
|
||||||
fprintf(out, "Number-with-unit\n");
|
fputs("Number-with-unit\n", out);
|
||||||
} else if (isstring(elem)) {
|
} else if (isstring(elem)) {
|
||||||
fprintf(out, "Text\n");
|
fputs("Text\n", out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,12 +142,14 @@ static void printattr(
|
||||||
const struct cfgunit *units)
|
const struct cfgunit *units)
|
||||||
{
|
{
|
||||||
if (flags & FLAG_LF)
|
if (flags & FLAG_LF)
|
||||||
fputs("\n\n\n", out);
|
fputs("\n\n", out);
|
||||||
printhead(out, level, flags, elem, units);
|
printhead(out, level, flags, elem, units);
|
||||||
printtype(out, level, flags, elem, units);
|
printtype(out, level, flags, elem, units);
|
||||||
fputs("\n", out);
|
fputs("\n", out);
|
||||||
if (elem->description)
|
if (elem->description) {
|
||||||
fputs(elem->meta.description, out);
|
fputs(elem->meta.description, out);
|
||||||
|
fputs("\n", out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printelem(
|
static void printelem(
|
||||||
|
@ -158,7 +160,7 @@ static void printelem(
|
||||||
const struct cfgunit *units)
|
const struct cfgunit *units)
|
||||||
{
|
{
|
||||||
if (flags & FLAG_LF)
|
if (flags & FLAG_LF)
|
||||||
fprintf(out, "\n\n\n");
|
fputs("\n\n", out);
|
||||||
printhead(out, level, flags, elem, units);
|
printhead(out, level, flags, elem, units);
|
||||||
flags &= ~FLAG_LF;
|
flags &= ~FLAG_LF;
|
||||||
if (hasattributes(elem)) {
|
if (hasattributes(elem)) {
|
||||||
|
@ -176,7 +178,7 @@ static void printelem(
|
||||||
ce = nextelem(elem->attributes, ce);
|
ce = nextelem(elem->attributes, ce);
|
||||||
}
|
}
|
||||||
if (cnt != 0) {
|
if (cnt != 0) {
|
||||||
fprintf(out, "\n");
|
fputs("\n", out);
|
||||||
flags |= FLAG_LF;
|
flags |= FLAG_LF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,18 +192,19 @@ static void printelem(
|
||||||
sep = ", ";
|
sep = ", ";
|
||||||
ce = nextelem(elem->children, ce);
|
ce = nextelem(elem->children, ce);
|
||||||
}
|
}
|
||||||
fprintf(out, "\n");
|
fputs("\n", out);
|
||||||
flags |= FLAG_LF;
|
flags |= FLAG_LF;
|
||||||
} else if (!isgroup(elem)) {
|
} else if (!isgroup(elem)) {
|
||||||
if (flags & FLAG_LF)
|
if (flags & FLAG_LF)
|
||||||
fprintf(out, "\n");
|
fputs("\n", out);
|
||||||
printtype(out, level+1, flags, elem, units);
|
printtype(out, level+1, flags, elem, units);
|
||||||
flags |= FLAG_LF;
|
flags |= FLAG_LF;
|
||||||
}
|
}
|
||||||
if (elem->description) {
|
if (elem->description) {
|
||||||
if (flags & FLAG_LF)
|
if (flags & FLAG_LF)
|
||||||
fprintf(out, "\n");
|
fputs("\n", out);
|
||||||
fputs(elem->meta.description, out);
|
fputs(elem->meta.description, out);
|
||||||
|
fputs("\n", out);
|
||||||
}
|
}
|
||||||
if (hasattributes(elem)) {
|
if (hasattributes(elem)) {
|
||||||
struct cfgelem *ce = firstelem(elem->attributes);
|
struct cfgelem *ce = firstelem(elem->attributes);
|
||||||
|
|
|
@ -158,6 +158,6 @@ int printrnc(FILE *out, struct cfgelem *elem, const struct cfgunit *units)
|
||||||
static const char *fmt = " %s = xsd:token { pattern = \"%s\" }\n";
|
static const char *fmt = " %s = xsd:token { pattern = \"%s\" }\n";
|
||||||
print(out, 0, fmt, cu->name, cu->pattern);
|
print(out, 0, fmt, cu->name, cu->pattern);
|
||||||
}
|
}
|
||||||
print(out, 0, "}");
|
print(out, 0, "}\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ printref(
|
||||||
snprintf(minattr, sizeof(minattr), "minOccurs=\"%d\" ", minimum(elem));
|
snprintf(minattr, sizeof(minattr), "minOccurs=\"%d\" ", minimum(elem));
|
||||||
if (!(flags & FLAG_NOMAX) && maximum(elem) == 0)
|
if (!(flags & FLAG_NOMAX) && maximum(elem) == 0)
|
||||||
snprintf(maxattr, sizeof(maxattr), "maxOccurs=\"unbounded\" ");
|
snprintf(maxattr, sizeof(maxattr), "maxOccurs=\"unbounded\" ");
|
||||||
else if (!(FLAG_NOMAX) && maximum(elem) != 1)
|
else if (!(flags & FLAG_NOMAX) && maximum(elem) != 1)
|
||||||
snprintf(maxattr, sizeof(maxattr), "maxOccurs=\"%d\" ", maximum(elem));
|
snprintf(maxattr, sizeof(maxattr), "maxOccurs=\"%d\" ", maximum(elem));
|
||||||
print(out, cols, fmt, minattr, maxattr, schema(), name(elem));
|
print(out, cols, fmt, minattr, maxattr, schema(), name(elem));
|
||||||
}
|
}
|
||||||
|
@ -185,11 +185,11 @@ printcomplextype(
|
||||||
assert(!ismoved(elem) && !isdeprecated(elem));
|
assert(!ismoved(elem) && !isdeprecated(elem));
|
||||||
|
|
||||||
if (flags & FLAG_REFERENCE) {
|
if (flags & FLAG_REFERENCE) {
|
||||||
if (minimum(elem) != 1)
|
if (!(flags & FLAG_NOMIN) && minimum(elem) != 1)
|
||||||
snprintf(minattr, sizeof(minattr), "minOccurs=\"%d\" ", minimum(elem));
|
snprintf(minattr, sizeof(minattr), "minOccurs=\"%d\" ", minimum(elem));
|
||||||
if (maximum(elem) == 0)
|
if (!(flags & FLAG_NOMAX) && maximum(elem) == 0)
|
||||||
snprintf(maxattr, sizeof(maxattr), "maxOccurs=\"unbounded\" ");
|
snprintf(maxattr, sizeof(maxattr), "maxOccurs=\"unbounded\" ");
|
||||||
else if (maximum(elem) != 1)
|
else if (!(flags & FLAG_NOMAX) && maximum(elem) != 1)
|
||||||
snprintf(maxattr, sizeof(maxattr), "maxOccurs=\"%d\" ", maximum(elem));
|
snprintf(maxattr, sizeof(maxattr), "maxOccurs=\"%d\" ", maximum(elem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,59 +208,64 @@ printcomplextype(
|
||||||
if ((cnt = haschildren(elem))) {
|
if ((cnt = haschildren(elem))) {
|
||||||
const char *cont = NULL;
|
const char *cont = NULL;
|
||||||
struct cfgelem *ce;
|
struct cfgelem *ce;
|
||||||
int min[2], max[2], eq[2] = { 1, 1 };
|
int min[3], max[3];
|
||||||
|
int mineq, maxeq;
|
||||||
assert(isgroup(elem));
|
assert(isgroup(elem));
|
||||||
|
|
||||||
minattr[0] = '\0';
|
minattr[0] = '\0';
|
||||||
maxattr[0] = '\0';
|
maxattr[0] = '\0';
|
||||||
|
|
||||||
if (cnt == 1) {
|
if (cnt == 1) {
|
||||||
/* minOccurs and maxOccurs placed in element */
|
|
||||||
cont = "sequence";
|
cont = "sequence";
|
||||||
} else {
|
} else {
|
||||||
assert(cnt > 1);
|
assert(cnt > 1);
|
||||||
ce = firstelem(elem->children);
|
ce = firstelem(elem->children);
|
||||||
assert(ce);
|
min[0] = min[1] = min[2] = minimum(ce);
|
||||||
min[0] = min[1] = minimum(ce);
|
max[0] = max[1] = max[2] = maximum(ce);
|
||||||
max[0] = max[1] = maximum(ce);
|
|
||||||
assert(min[1] <= max[1] || max[1] == 0);
|
assert(min[1] <= max[1] || max[1] == 0);
|
||||||
|
mineq = maxeq = 1;
|
||||||
ce = nextelem(elem->children, ce);
|
ce = nextelem(elem->children, ce);
|
||||||
assert(ce);
|
assert(ce);
|
||||||
while (ce) {
|
while (ce) {
|
||||||
min[1] = minimum(ce);
|
min[1] = minimum(ce);
|
||||||
max[1] = maximum(ce);
|
max[1] = maximum(ce);
|
||||||
assert(min[1] <= max[1] || max[1] == 0);
|
assert(min[1] <= max[1] || max[1] == 0);
|
||||||
|
min[2] += minimum(ce);
|
||||||
|
max[2] += maximum(ce);
|
||||||
if (min[1] != min[0]) {
|
if (min[1] != min[0]) {
|
||||||
eq[0] = 0;
|
mineq = 0;
|
||||||
if (min[1] < min[0])
|
if (min[1] > min[0])
|
||||||
min[0] = min[1];
|
min[0] = min[1];
|
||||||
}
|
}
|
||||||
if (max[1] != max[0]) {
|
if (max[1] != max[0]) {
|
||||||
eq[1] = 0;
|
maxeq = 0;
|
||||||
if ((max[0] != 0 && max[1] > max[0]) || max[1] == 0)
|
if ((max[0] != 0 && max[1] > max[0]) || max[1] == 0)
|
||||||
max[0] = max[1];
|
max[0] = max[1];
|
||||||
}
|
}
|
||||||
ce = nextelem(elem->children, ce);
|
ce = nextelem(elem->children, ce);
|
||||||
}
|
}
|
||||||
if (min[0] > 1 || max[0] != 1 /* unbounded or >1 */) {
|
/* xsd generation becomes significantly more difficult if the minimum
|
||||||
|
number of occurences for an element is more non-zero and the
|
||||||
|
maximum number of occurences of it (or one of its siblings) is more
|
||||||
|
than one, but that is not likely to occur */
|
||||||
|
if (min[0] <= 1 && max[0] == 1) {
|
||||||
|
/* any order, each zero or one time */
|
||||||
|
cont = "all";
|
||||||
|
} else {
|
||||||
cont = "choice";
|
cont = "choice";
|
||||||
if (eq[0]) {
|
if (min[0] == 0)
|
||||||
if (min[0] != 1)
|
snprintf(minattr, sizeof(minattr), " minOccurs=\"0\"");
|
||||||
snprintf(minattr, sizeof(minattr), " minOccurs=\"%d\"", min[0]);
|
else if (min[0] != 1) /* incorrect, but make the most of it */
|
||||||
flags |= FLAG_NOMIN;
|
snprintf(minattr, sizeof(minattr), " minOccurs=\"%d\"", min[2]);
|
||||||
}
|
|
||||||
if (eq[1]) {
|
|
||||||
if (max[0] == 0)
|
if (max[0] == 0)
|
||||||
snprintf(maxattr, sizeof(maxattr), " maxOccurs=\"unbounded\"");
|
snprintf(maxattr, sizeof(maxattr), " maxOccurs=\"unbounded\"");
|
||||||
else if (max[0] != 1)
|
else if (max[0] != 1)
|
||||||
snprintf(maxattr, sizeof(maxattr), " maxOccurs=\"%d\"", max[0]);
|
snprintf(maxattr, sizeof(maxattr), " maxOccurs=\"%d\"", max[2]);
|
||||||
|
if (mineq)
|
||||||
|
flags |= FLAG_NOMIN;
|
||||||
|
if (maxeq)
|
||||||
flags |= FLAG_NOMAX;
|
flags |= FLAG_NOMAX;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
/* any order, each zero or one time */
|
|
||||||
/* minOccurs placed in element maxOccurs always one */
|
|
||||||
cont = "all";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print(out, cols+4, "<xs:%s%s%s>\n", cont, minattr, maxattr);
|
print(out, cols+4, "<xs:%s%s%s>\n", cont, minattr, maxattr);
|
||||||
|
@ -270,7 +275,6 @@ printcomplextype(
|
||||||
ce = nextelem(elem->children, ce);
|
ce = nextelem(elem->children, ce);
|
||||||
}
|
}
|
||||||
print(out, cols+4, "</xs:%s>\n", cont);
|
print(out, cols+4, "</xs:%s>\n", cont);
|
||||||
flags &= ~(FLAG_NOMIN | FLAG_NOMAX);
|
|
||||||
} else if (!isgroup(elem) && (!isstring(elem) || elem->meta.unit)) {
|
} else if (!isgroup(elem) && (!isstring(elem) || elem->meta.unit)) {
|
||||||
ofst = 4;
|
ofst = 4;
|
||||||
print(out, cols+4, "<xs:simpleContent>\n");
|
print(out, cols+4, "<xs:simpleContent>\n");
|
||||||
|
@ -288,6 +292,7 @@ printcomplextype(
|
||||||
print(out, cols+6, extfmt, "xs", isbuiltintype(elem));
|
print(out, cols+6, extfmt, "xs", isbuiltintype(elem));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
flags &= ~(FLAG_NOMIN | FLAG_NOMAX);
|
||||||
if (hasattributes(elem)) {
|
if (hasattributes(elem)) {
|
||||||
struct cfgelem *ce;
|
struct cfgelem *ce;
|
||||||
ce = firstelem(elem->attributes);
|
ce = firstelem(elem->attributes);
|
||||||
|
@ -417,6 +422,6 @@ int printxsd(FILE *out, struct cfgelem *elem, const struct cfgunit *units)
|
||||||
print(out, 4, "</xs:restriction>\n");
|
print(out, 4, "</xs:restriction>\n");
|
||||||
print(out, 2, "</xs:simpleType>\n");
|
print(out, 2, "</xs:simpleType>\n");
|
||||||
}
|
}
|
||||||
print(out, 0, "</xs:schema>");
|
print(out, 0, "</xs:schema>\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue