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"
|
||||||
|
|
|
@ -1695,4 +1695,4 @@ While none prevents any message from being written to a DDSI2 log file.
|
||||||
|
|
||||||
The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest.
|
The categorisation of tracing output is incomplete and hence most of the verbosity levels and categories are not of much use in the current release. This is an ongoing process and here we describe the target situation rather than the current situation. Currently, the most useful verbosity levels are config, fine and finest.
|
||||||
|
|
||||||
The default value is: "none".
|
The default value is: "none".
|
||||||
|
|
|
@ -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 {
|
||||||
|
@ -1180,4 +1180,4 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br>
|
||||||
duration = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" }
|
duration = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" }
|
||||||
duration_inf = xsd:token { pattern = "inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" }
|
duration_inf = xsd:token { pattern = "inf|0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([num]?s|min|hr|day)" }
|
||||||
memsize = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" }
|
memsize = xsd:token { pattern = "0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B" }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
@ -1779,4 +1779,4 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br>
|
||||||
<xs:pattern value="0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B"/>
|
<xs:pattern value="0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B"/>
|
||||||
</xs:restriction>
|
</xs:restriction>
|
||||||
</xs:simpleType>
|
</xs:simpleType>
|
||||||
</xs:schema>
|
</xs:schema>
|
||||||
|
|
|
@ -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,27 +232,35 @@ int islist(const struct cfgelem *elem)
|
||||||
|
|
||||||
int minimum(const struct cfgelem *elem)
|
int minimum(const struct cfgelem *elem)
|
||||||
{
|
{
|
||||||
switch (elem->multiplicity) {
|
if (elem->meta.force_minimum) {
|
||||||
case 0: /* special case, treat as-if 1 */
|
return elem->meta.minimum;
|
||||||
case 1: /* required if there is no default */
|
} else {
|
||||||
if (isgroup(elem))
|
switch (elem->multiplicity) {
|
||||||
|
case 0: /* special case, treat as-if 1 */
|
||||||
|
case 1: /* required if there is no default */
|
||||||
|
if (isgroup(elem))
|
||||||
|
return 0;
|
||||||
|
return (!elem->value);
|
||||||
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
return (!elem->value);
|
}
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int maximum(const struct cfgelem *elem)
|
int maximum(const struct cfgelem *elem)
|
||||||
{
|
{
|
||||||
switch (elem->multiplicity) {
|
if (elem->meta.force_maximum) {
|
||||||
case INT_MAX:
|
return elem->meta.maximum;
|
||||||
return 0;
|
} else {
|
||||||
case 0:
|
switch (elem->multiplicity) {
|
||||||
case 1:
|
case INT_MAX:
|
||||||
return 1;
|
return 0;
|
||||||
default:
|
case 0:
|
||||||
return elem->multiplicity;
|
case 1:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return elem->multiplicity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,58 +208,63 @@ 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
|
||||||
cont = "choice";
|
number of occurences for an element is more non-zero and the
|
||||||
if (eq[0]) {
|
maximum number of occurences of it (or one of its siblings) is more
|
||||||
if (min[0] != 1)
|
than one, but that is not likely to occur */
|
||||||
snprintf(minattr, sizeof(minattr), " minOccurs=\"%d\"", min[0]);
|
if (min[0] <= 1 && max[0] == 1) {
|
||||||
flags |= FLAG_NOMIN;
|
|
||||||
}
|
|
||||||
if (eq[1]) {
|
|
||||||
if (max[0] == 0)
|
|
||||||
snprintf(maxattr, sizeof(maxattr), " maxOccurs=\"unbounded\"");
|
|
||||||
else if (max[0] != 1)
|
|
||||||
snprintf(maxattr, sizeof(maxattr), " maxOccurs=\"%d\"", max[0]);
|
|
||||||
flags |= FLAG_NOMAX;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* any order, each zero or one time */
|
/* any order, each zero or one time */
|
||||||
/* minOccurs placed in element maxOccurs always one */
|
|
||||||
cont = "all";
|
cont = "all";
|
||||||
|
} else {
|
||||||
|
cont = "choice";
|
||||||
|
if (min[0] == 0)
|
||||||
|
snprintf(minattr, sizeof(minattr), " minOccurs=\"0\"");
|
||||||
|
else if (min[0] != 1) /* incorrect, but make the most of it */
|
||||||
|
snprintf(minattr, sizeof(minattr), " minOccurs=\"%d\"", min[2]);
|
||||||
|
if (max[0] == 0)
|
||||||
|
snprintf(maxattr, sizeof(maxattr), " maxOccurs=\"unbounded\"");
|
||||||
|
else if (max[0] != 1)
|
||||||
|
snprintf(maxattr, sizeof(maxattr), " maxOccurs=\"%d\"", max[2]);
|
||||||
|
if (mineq)
|
||||||
|
flags |= FLAG_NOMIN;
|
||||||
|
if (maxeq)
|
||||||
|
flags |= FLAG_NOMAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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