scanner: support "since" attribute for enum entries

This was already in the DTD but not supported by the scanner.

The check for ever-increasing "since" tags is not strictly required for enum
entries as we control the binary value. But it keeps the xml file in
good order, preventing things like:

      <entry name="first" value="…" />
      <entry name="second" value="…" since="3"/>
      <entry name="third" value="…" since="2"/>
      <entry name="fourth" value="…" since="3"/>

If this is undesirable in the future the check can be removed without
side-effects.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
This commit is contained in:
Peter Hutterer 2017-01-24 09:56:38 +10:00 committed by Pekka Paalanen
parent 6c481003a2
commit f8ab47690c
8 changed files with 131 additions and 7 deletions

View file

@ -213,6 +213,7 @@ struct enumeration {
struct wl_list link; struct wl_list link;
struct description *description; struct description *description;
bool bitfield; bool bitfield;
int since;
}; };
struct entry { struct entry {
@ -220,6 +221,7 @@ struct entry {
char *uppercase_name; char *uppercase_name;
char *value; char *value;
char *summary; char *summary;
int since;
struct wl_list link; struct wl_list link;
}; };
@ -494,6 +496,7 @@ create_enumeration(const char *name)
enumeration = xzalloc(sizeof *enumeration); enumeration = xzalloc(sizeof *enumeration);
enumeration->name = xstrdup(name); enumeration->name = xstrdup(name);
enumeration->uppercase_name = uppercase_dup(name); enumeration->uppercase_name = uppercase_dup(name);
enumeration->since = 1;
wl_list_init(&enumeration->entry_list); wl_list_init(&enumeration->entry_list);
@ -797,6 +800,12 @@ start_element(void *data, const char *element_name, const char **atts)
fail(&ctx->loc, "no entry name given"); fail(&ctx->loc, "no entry name given");
entry = create_entry(name, value); entry = create_entry(name, value);
version = version_from_since(ctx, since);
if (version < ctx->enumeration->since)
warn(&ctx->loc, "since version not increasing\n");
ctx->enumeration->since = version;
entry->since = version;
if (summary) if (summary)
entry->summary = xstrdup(summary); entry->summary = xstrdup(summary);
@ -1278,16 +1287,33 @@ emit_enumerations(struct interface *interface)
} }
printf("enum %s_%s {\n", interface->name, e->name); printf("enum %s_%s {\n", interface->name, e->name);
wl_list_for_each(entry, &e->entry_list, link) { wl_list_for_each(entry, &e->entry_list, link) {
if (entry->summary) if (entry->summary || entry->since > 1) {
printf("\t/**\n" printf("\t/**\n");
"\t * %s\n" if (entry->summary)
"\t */\n", entry->summary); printf("\t * %s\n", entry->summary);
if (entry->since > 1)
printf("\t * @since %d\n", entry->since);
printf("\t */\n");
}
printf("\t%s_%s_%s = %s,\n", printf("\t%s_%s_%s = %s,\n",
interface->uppercase_name, interface->uppercase_name,
e->uppercase_name, e->uppercase_name,
entry->uppercase_name, entry->value); entry->uppercase_name, entry->value);
} }
printf("};\n"); printf("};\n");
wl_list_for_each(entry, &e->entry_list, link) {
if (entry->since == 1)
continue;
printf("/**\n * @ingroup iface_%s\n */\n", interface->name);
printf("#define %s_%s_%s_SINCE_VERSION %d\n",
interface->uppercase_name,
e->uppercase_name, entry->uppercase_name,
entry->since);
}
printf("#endif /* %s_%s_ENUM */\n\n", printf("#endif /* %s_%s_ENUM */\n\n",
interface->uppercase_name, e->uppercase_name); interface->uppercase_name, e->uppercase_name);
} }

View file

@ -61,6 +61,29 @@ struct intf_not_here;
*/ */
extern const struct wl_interface intf_A_interface; extern const struct wl_interface intf_A_interface;
#ifndef INTF_A_FOO_ENUM
#define INTF_A_FOO_ENUM
enum intf_A_foo {
/**
* this is the first
*/
INTF_A_FOO_FIRST = 0,
/**
* this is the second
*/
INTF_A_FOO_SECOND = 1,
/**
* this is the third
* @since 2
*/
INTF_A_FOO_THIRD = 2,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_FOO_THIRD_SINCE_VERSION 2
#endif /* INTF_A_FOO_ENUM */
/** /**
* @ingroup iface_intf_A * @ingroup iface_intf_A
* @struct intf_A_listener * @struct intf_A_listener

View file

@ -61,6 +61,29 @@ struct intf_not_here;
*/ */
extern const struct wl_interface intf_A_interface; extern const struct wl_interface intf_A_interface;
#ifndef INTF_A_FOO_ENUM
#define INTF_A_FOO_ENUM
enum intf_A_foo {
/**
* this is the first
*/
INTF_A_FOO_FIRST = 0,
/**
* this is the second
*/
INTF_A_FOO_SECOND = 1,
/**
* this is the third
* @since 2
*/
INTF_A_FOO_THIRD = 2,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_FOO_THIRD_SINCE_VERSION 2
#endif /* INTF_A_FOO_ENUM */
/** /**
* @ingroup iface_intf_A * @ingroup iface_intf_A
* @struct intf_A_listener * @struct intf_A_listener

View file

@ -54,7 +54,7 @@ static const struct wl_message intf_A_events[] = {
}; };
WL_EXPORT const struct wl_interface intf_A_interface = { WL_EXPORT const struct wl_interface intf_A_interface = {
"intf_A", 1, "intf_A", 3,
3, intf_A_requests, 3, intf_A_requests,
1, intf_A_events, 1, intf_A_events,
}; };

View file

@ -54,7 +54,7 @@ static const struct wl_message intf_A_events[] = {
}; };
WL_EXPORT const struct wl_interface intf_A_interface = { WL_EXPORT const struct wl_interface intf_A_interface = {
"intf_A", 1, "intf_A", 3,
3, intf_A_requests, 3, intf_A_requests,
1, intf_A_events, 1, intf_A_events,
}; };

View file

@ -64,6 +64,29 @@ struct intf_not_here;
*/ */
extern const struct wl_interface intf_A_interface; extern const struct wl_interface intf_A_interface;
#ifndef INTF_A_FOO_ENUM
#define INTF_A_FOO_ENUM
enum intf_A_foo {
/**
* this is the first
*/
INTF_A_FOO_FIRST = 0,
/**
* this is the second
*/
INTF_A_FOO_SECOND = 1,
/**
* this is the third
* @since 2
*/
INTF_A_FOO_THIRD = 2,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_FOO_THIRD_SINCE_VERSION 2
#endif /* INTF_A_FOO_ENUM */
/** /**
* @ingroup iface_intf_A * @ingroup iface_intf_A
* @struct intf_A_interface * @struct intf_A_interface

View file

@ -64,6 +64,29 @@ struct intf_not_here;
*/ */
extern const struct wl_interface intf_A_interface; extern const struct wl_interface intf_A_interface;
#ifndef INTF_A_FOO_ENUM
#define INTF_A_FOO_ENUM
enum intf_A_foo {
/**
* this is the first
*/
INTF_A_FOO_FIRST = 0,
/**
* this is the second
*/
INTF_A_FOO_SECOND = 1,
/**
* this is the third
* @since 2
*/
INTF_A_FOO_THIRD = 2,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_FOO_THIRD_SINCE_VERSION 2
#endif /* INTF_A_FOO_ENUM */
/** /**
* @ingroup iface_intf_A * @ingroup iface_intf_A
* @struct intf_A_interface * @struct intf_A_interface

View file

@ -26,7 +26,7 @@
SOFTWARE. SOFTWARE.
</copyright> </copyright>
<interface name="intf_A" version="1"> <interface name="intf_A" version="3">
<description summary="the thing A"> <description summary="the thing A">
A useless example trying to tickle the scanner. A useless example trying to tickle the scanner.
</description> </description>
@ -48,5 +48,11 @@
<request name="destroy" type="destructor"/> <request name="destroy" type="destructor"/>
<event name="hey"/> <event name="hey"/>
<enum name="foo">
<entry name="first" value="0" summary="this is the first"/>
<entry name="second" value="1" summary="this is the second"/>
<entry name="third" value="2" since="2" summary="this is the third"/>
</enum>
</interface> </interface>
</protocol> </protocol>