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
|
@ -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