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_DEADLINE_MISSED=${DEADLINE}
|
||||
-DBUILD_TESTING=on
|
||||
-DBUILD_SCHEMA=on
|
||||
-DWERROR=on
|
||||
-G "${GENERATOR}" ..
|
||||
- |
|
||||
|
@ -219,8 +218,6 @@ script:
|
|||
fi
|
||||
- |
|
||||
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.xsd docs/cyclonedds.xsd && \
|
||||
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)
|
||||
|
||||
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.
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
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)
|
||||
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 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 ddsconf ARGS -f md -o "${options_md}"
|
||||
DEPENDS ddsconf)
|
||||
add_custom_target(options_doc DEPENDS "${options_md}")
|
||||
add_custom_target(
|
||||
schema ALL DEPENDS "${cyclonedds_rnc}" "${cyclonedds_xsd}" "${options_md}")
|
||||
endif()
|
||||
|
||||
if(BUILD_DOCS)
|
||||
|
@ -39,7 +35,7 @@ if(BUILD_DOCS)
|
|||
BREATHE_PROJECTS ddsc_api_docs
|
||||
BUILDER html
|
||||
SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/manual")
|
||||
add_dependencies(docs options_doc)
|
||||
add_dependencies(docs schema)
|
||||
|
||||
install(
|
||||
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 default value is: "none".
|
||||
The default value is: "none".
|
||||
|
|
|
@ -101,7 +101,7 @@ CycloneDDS configuration""" ] ]
|
|||
text
|
||||
}
|
||||
}*
|
||||
}?
|
||||
}*
|
||||
& [ a:documentation [ xml:lang="en" """
|
||||
<p>This element statically configures an addresses for discovery.</p>""" ] ]
|
||||
element Peer {
|
||||
|
@ -983,7 +983,7 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br>
|
|||
}?
|
||||
}?
|
||||
}?
|
||||
}*
|
||||
}?
|
||||
& [ a:documentation [ xml:lang="en" """
|
||||
<p>The Sizing element specifies a variety of configuration settings dealing with expected system sizes, buffer sizes, &c.</p>""" ] ]
|
||||
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_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" }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,17 +17,17 @@ CycloneDDS configuration</xs:documentation>
|
|||
<p>The General element specifying Domain related settings.</p></xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:choice minOccurs="0">
|
||||
<xs:element ref="config:Compatibility"/>
|
||||
<xs:element ref="config:Discovery"/>
|
||||
<xs:element ref="config:General"/>
|
||||
<xs:element ref="config:Internal"/>
|
||||
<xs:element ref="config:Partitioning"/>
|
||||
<xs:element ref="config:SSL"/>
|
||||
<xs:element maxOccurs="unbounded" ref="config:Security"/>
|
||||
<xs:element ref="config:Sizing"/>
|
||||
<xs:element ref="config:TCP"/>
|
||||
<xs:element ref="config:ThreadPool"/>
|
||||
<xs:all>
|
||||
<xs:element minOccurs="0" ref="config:Compatibility"/>
|
||||
<xs:element minOccurs="0" ref="config:Discovery"/>
|
||||
<xs:element minOccurs="0" ref="config:General"/>
|
||||
<xs:element minOccurs="0" ref="config:Internal"/>
|
||||
<xs:element minOccurs="0" ref="config:Partitioning"/>
|
||||
<xs:element minOccurs="0" ref="config:SSL"/>
|
||||
<xs:element minOccurs="0" ref="config:Security"/>
|
||||
<xs:element minOccurs="0" ref="config:Sizing"/>
|
||||
<xs:element minOccurs="0" ref="config:TCP"/>
|
||||
<xs:element minOccurs="0" ref="config:ThreadPool"/>
|
||||
<xs:element minOccurs="0" name="Threads">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
|
@ -39,8 +39,8 @@ CycloneDDS configuration</xs:documentation>
|
|||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element ref="config:Tracing"/>
|
||||
</xs:choice>
|
||||
<xs:element minOccurs="0" ref="config:Tracing"/>
|
||||
</xs:all>
|
||||
<xs:attribute name="Id">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
|
@ -179,9 +179,9 @@ CycloneDDS configuration</xs:documentation>
|
|||
<p>This element statically configures addresses for discovery.</p></xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:choice minOccurs="0">
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element ref="config:Group"/>
|
||||
<xs:element maxOccurs="unbounded" ref="config:Peer"/>
|
||||
<xs:element ref="config:Peer"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
@ -1779,4 +1779,4 @@ MIIEpAIBAAKCAQEA3HIh...AOBaaqSV37XBUJg==<br>
|
|||
<xs:pattern value="0|(\d+(\.\d*)?([Ee][\-+]?\d+)?|\.\d+([Ee][\-+]?\d+)?) *([kMG]i?)?B"/>
|
||||
</xs:restriction>
|
||||
</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 "
|
||||
"addresses for discovery. Each member of the group is tried in "
|
||||
"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
|
||||
};
|
||||
|
||||
|
@ -1849,7 +1851,9 @@ static struct cfgelem domain_cfgelems[] = {
|
|||
DESCRIPTION(
|
||||
"<p>This element is used to configure Cyclone DDS with the DDS Security "
|
||||
"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
|
||||
#ifdef DDSI_INCLUDE_NETWORK_PARTITIONS
|
||||
GROUP("Partitioning", partitioning_cfgelems, NULL, 1,
|
||||
|
|
|
@ -230,6 +230,8 @@ DI(if_omg_security);
|
|||
#define RANGE(...) /* drop */
|
||||
#define UNIT(...) /* drop */
|
||||
#define VALUES(...) /* drop */
|
||||
#define MAXIMUM(...) /* drop */
|
||||
#define MINIMUM(...) /* drop */
|
||||
|
||||
#define NOMEMBER 0, 0
|
||||
#define NOFUNCTIONS 0, 0, 0, 0
|
||||
|
@ -269,6 +271,12 @@ static const struct cfgelem root_cfgelem = {
|
|||
#undef MEMBER
|
||||
#undef MEMBEROF
|
||||
#undef FUNCTIONS
|
||||
#undef DESCRIPTION
|
||||
#undef RANGE
|
||||
#undef UNIT
|
||||
#undef VALUES
|
||||
#undef MAXIMUM
|
||||
#undef MINIMUM
|
||||
#undef NOMEMBER
|
||||
#undef NOFUNCTIONS
|
||||
#undef NODATA
|
||||
|
|
|
@ -50,10 +50,12 @@
|
|||
#define RANGE(str) .range = str
|
||||
#define UNIT(str) .unit = str
|
||||
#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 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 ELEMENT(name, elems, attrs, multip, dflt, desc, ...) \
|
||||
|
@ -76,8 +78,8 @@
|
|||
EXPAND(ELEMENT, (name, NULL, attrs, multip, dflt, desc, .type = "string", __VA_ARGS__))
|
||||
#define LIST(name, attrs, multip, dflt, ofst, funcs, desc, ...) \
|
||||
EXPAND(ELEMENT, (name, NULL, attrs, multip, dflt, desc, .type = "list", __VA_ARGS__))
|
||||
#define GROUP(name, elems, attrs, multip, ofst, funcs, desc) \
|
||||
EXPAND(ELEMENT, (name, elems, attrs, multip, NULL, desc, .type = "group"))
|
||||
#define GROUP(name, elems, attrs, multip, ofst, funcs, desc, ...) \
|
||||
EXPAND(ELEMENT, (name, elems, attrs, multip, NULL, desc, .type = "group", __VA_ARGS__))
|
||||
|
||||
#include "dds/ddsi/ddsi_cfgelems.h"
|
||||
/* undefine element macros */
|
||||
|
@ -89,6 +91,8 @@
|
|||
#undef RANGE
|
||||
#undef UNIT
|
||||
#undef VALUES
|
||||
#undef MAXIMUM
|
||||
#undef MINIMUM
|
||||
#undef NOMEMBER
|
||||
#undef NOFUNCTIONS
|
||||
#undef NOMETADATA
|
||||
|
@ -228,27 +232,35 @@ int islist(const struct cfgelem *elem)
|
|||
|
||||
int minimum(const struct cfgelem *elem)
|
||||
{
|
||||
switch (elem->multiplicity) {
|
||||
case 0: /* special case, treat as-if 1 */
|
||||
case 1: /* required if there is no default */
|
||||
if (isgroup(elem))
|
||||
if (elem->meta.force_minimum) {
|
||||
return elem->meta.minimum;
|
||||
} else {
|
||||
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 (!elem->value);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int maximum(const struct cfgelem *elem)
|
||||
{
|
||||
switch (elem->multiplicity) {
|
||||
case INT_MAX:
|
||||
return 0;
|
||||
case 0:
|
||||
case 1:
|
||||
return 1;
|
||||
default:
|
||||
return elem->multiplicity;
|
||||
if (elem->meta.force_maximum) {
|
||||
return elem->meta.maximum;
|
||||
} else {
|
||||
switch (elem->multiplicity) {
|
||||
case INT_MAX:
|
||||
return 0;
|
||||
case 0:
|
||||
case 1:
|
||||
return 1;
|
||||
default:
|
||||
return elem->multiplicity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ struct cfgmeta {
|
|||
char *pattern;
|
||||
char *description;
|
||||
unsigned int flags;
|
||||
const int force_maximum, maximum;
|
||||
const int force_minimum, minimum;
|
||||
const char *type;
|
||||
const char *unit;
|
||||
const char *range;
|
||||
|
|
|
@ -103,32 +103,32 @@ static void printtype(
|
|||
(void)units;
|
||||
assert(!isgroup(elem));
|
||||
if (isbool(elem)) {
|
||||
fprintf(out, "Boolean\n");
|
||||
fputs("Boolean\n", out);
|
||||
} else if (islist(elem)) {
|
||||
assert(elem->meta.values);
|
||||
fprintf(out, "One of:\n");
|
||||
fputs("One of:\n", out);
|
||||
if (elem->value && strlen(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++) {
|
||||
fprintf(out, "%s%s", v == elem->meta.values ? "" : ", ", *v);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
fputs("\n", out);
|
||||
if (!elem->value || !strlen(elem->value))
|
||||
fprintf(out, "* Or empty\n");
|
||||
fputs("* Or empty\n", out);
|
||||
} else if (isenum(elem)) {
|
||||
assert(elem->meta.values);
|
||||
fprintf(out, "One of: ");
|
||||
fputs("One of: ", out);
|
||||
for (const char **v = elem->meta.values; *v; v++) {
|
||||
fprintf(out, "%s%s", v == elem->meta.values ? "" : ", ", *v);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
fputs("\n", out);
|
||||
} else if (isint(elem)) {
|
||||
fprintf(out, "Integer\n");
|
||||
fputs("Integer\n", out);
|
||||
} else if (elem->meta.unit) {
|
||||
fprintf(out, "Number-with-unit\n");
|
||||
fputs("Number-with-unit\n", out);
|
||||
} else if (isstring(elem)) {
|
||||
fprintf(out, "Text\n");
|
||||
fputs("Text\n", out);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,12 +142,14 @@ static void printattr(
|
|||
const struct cfgunit *units)
|
||||
{
|
||||
if (flags & FLAG_LF)
|
||||
fputs("\n\n\n", out);
|
||||
fputs("\n\n", out);
|
||||
printhead(out, level, flags, elem, units);
|
||||
printtype(out, level, flags, elem, units);
|
||||
fputs("\n", out);
|
||||
if (elem->description)
|
||||
if (elem->description) {
|
||||
fputs(elem->meta.description, out);
|
||||
fputs("\n", out);
|
||||
}
|
||||
}
|
||||
|
||||
static void printelem(
|
||||
|
@ -158,7 +160,7 @@ static void printelem(
|
|||
const struct cfgunit *units)
|
||||
{
|
||||
if (flags & FLAG_LF)
|
||||
fprintf(out, "\n\n\n");
|
||||
fputs("\n\n", out);
|
||||
printhead(out, level, flags, elem, units);
|
||||
flags &= ~FLAG_LF;
|
||||
if (hasattributes(elem)) {
|
||||
|
@ -176,7 +178,7 @@ static void printelem(
|
|||
ce = nextelem(elem->attributes, ce);
|
||||
}
|
||||
if (cnt != 0) {
|
||||
fprintf(out, "\n");
|
||||
fputs("\n", out);
|
||||
flags |= FLAG_LF;
|
||||
}
|
||||
}
|
||||
|
@ -190,18 +192,19 @@ static void printelem(
|
|||
sep = ", ";
|
||||
ce = nextelem(elem->children, ce);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
fputs("\n", out);
|
||||
flags |= FLAG_LF;
|
||||
} else if (!isgroup(elem)) {
|
||||
if (flags & FLAG_LF)
|
||||
fprintf(out, "\n");
|
||||
fputs("\n", out);
|
||||
printtype(out, level+1, flags, elem, units);
|
||||
flags |= FLAG_LF;
|
||||
}
|
||||
if (elem->description) {
|
||||
if (flags & FLAG_LF)
|
||||
fprintf(out, "\n");
|
||||
fputs("\n", out);
|
||||
fputs(elem->meta.description, out);
|
||||
fputs("\n", out);
|
||||
}
|
||||
if (hasattributes(elem)) {
|
||||
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";
|
||||
print(out, 0, fmt, cu->name, cu->pattern);
|
||||
}
|
||||
print(out, 0, "}");
|
||||
print(out, 0, "}\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@ printref(
|
|||
snprintf(minattr, sizeof(minattr), "minOccurs=\"%d\" ", minimum(elem));
|
||||
if (!(flags & FLAG_NOMAX) && maximum(elem) == 0)
|
||||
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));
|
||||
print(out, cols, fmt, minattr, maxattr, schema(), name(elem));
|
||||
}
|
||||
|
@ -185,11 +185,11 @@ printcomplextype(
|
|||
assert(!ismoved(elem) && !isdeprecated(elem));
|
||||
|
||||
if (flags & FLAG_REFERENCE) {
|
||||
if (minimum(elem) != 1)
|
||||
if (!(flags & FLAG_NOMIN) && minimum(elem) != 1)
|
||||
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\" ");
|
||||
else if (maximum(elem) != 1)
|
||||
else if (!(flags & FLAG_NOMAX) && maximum(elem) != 1)
|
||||
snprintf(maxattr, sizeof(maxattr), "maxOccurs=\"%d\" ", maximum(elem));
|
||||
}
|
||||
|
||||
|
@ -208,58 +208,63 @@ printcomplextype(
|
|||
if ((cnt = haschildren(elem))) {
|
||||
const char *cont = NULL;
|
||||
struct cfgelem *ce;
|
||||
int min[2], max[2], eq[2] = { 1, 1 };
|
||||
int min[3], max[3];
|
||||
int mineq, maxeq;
|
||||
assert(isgroup(elem));
|
||||
|
||||
minattr[0] = '\0';
|
||||
maxattr[0] = '\0';
|
||||
|
||||
if (cnt == 1) {
|
||||
/* minOccurs and maxOccurs placed in element */
|
||||
cont = "sequence";
|
||||
} else {
|
||||
assert(cnt > 1);
|
||||
ce = firstelem(elem->children);
|
||||
assert(ce);
|
||||
min[0] = min[1] = minimum(ce);
|
||||
max[0] = max[1] = maximum(ce);
|
||||
min[0] = min[1] = min[2] = minimum(ce);
|
||||
max[0] = max[1] = max[2] = maximum(ce);
|
||||
assert(min[1] <= max[1] || max[1] == 0);
|
||||
mineq = maxeq = 1;
|
||||
ce = nextelem(elem->children, ce);
|
||||
assert(ce);
|
||||
while (ce) {
|
||||
min[1] = minimum(ce);
|
||||
max[1] = maximum(ce);
|
||||
assert(min[1] <= max[1] || max[1] == 0);
|
||||
min[2] += minimum(ce);
|
||||
max[2] += maximum(ce);
|
||||
if (min[1] != min[0]) {
|
||||
eq[0] = 0;
|
||||
if (min[1] < min[0])
|
||||
mineq = 0;
|
||||
if (min[1] > min[0])
|
||||
min[0] = min[1];
|
||||
}
|
||||
if (max[1] != max[0]) {
|
||||
eq[1] = 0;
|
||||
maxeq = 0;
|
||||
if ((max[0] != 0 && max[1] > max[0]) || max[1] == 0)
|
||||
max[0] = max[1];
|
||||
}
|
||||
ce = nextelem(elem->children, ce);
|
||||
}
|
||||
if (min[0] > 1 || max[0] != 1 /* unbounded or >1 */) {
|
||||
cont = "choice";
|
||||
if (eq[0]) {
|
||||
if (min[0] != 1)
|
||||
snprintf(minattr, sizeof(minattr), " minOccurs=\"%d\"", min[0]);
|
||||
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 {
|
||||
/* 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 */
|
||||
/* minOccurs placed in element maxOccurs always one */
|
||||
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);
|
||||
}
|
||||
print(out, cols+4, "</xs:%s>\n", cont);
|
||||
flags &= ~(FLAG_NOMIN | FLAG_NOMAX);
|
||||
} else if (!isgroup(elem) && (!isstring(elem) || elem->meta.unit)) {
|
||||
ofst = 4;
|
||||
print(out, cols+4, "<xs:simpleContent>\n");
|
||||
|
@ -288,6 +292,7 @@ printcomplextype(
|
|||
print(out, cols+6, extfmt, "xs", isbuiltintype(elem));
|
||||
}
|
||||
}
|
||||
flags &= ~(FLAG_NOMIN | FLAG_NOMAX);
|
||||
if (hasattributes(elem)) {
|
||||
struct cfgelem *ce;
|
||||
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, 2, "</xs:simpleType>\n");
|
||||
}
|
||||
print(out, 0, "</xs:schema>");
|
||||
print(out, 0, "</xs:schema>\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue