[PATCH wayland v3 3/4] scanner: enforce correct argument type for enums
Bryce Harrington
bryce at osg.samsung.com
Mon Oct 26 11:56:29 PDT 2015
On Mon, Oct 26, 2015 at 06:37:28PM +0000, Auke Booij wrote:
> On 26 October 2015 at 18:07, Bryce Harrington <bryce at osg.samsung.com> wrote:
> > On Sat, Oct 24, 2015 at 12:07:49PM +0100, Auke Booij wrote:
> >> The scanner now checks whether arguments that have an associated
> >> <enum> have the right type.
> >> An argument with an enum attribute must be of type int or uint,
> >> and if the <enum> with that name has the bitfield attribute
> >> set to true, then the argument must be of type uint.
> >>
> >> Signed-off-by: Auke Booij <auke at tulcod.com>
> >
> > Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>
> >
> > A couple really minor nits below, not really worth doing unless you need
> > to do another rev of this patch for some other reason.
> >
> >> ---
> >> src/scanner.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >> 1 file changed, 70 insertions(+)
> >>
> >> diff --git a/src/scanner.c b/src/scanner.c
> >> index f456aa5..9856475 100644
> >> --- a/src/scanner.c
> >> +++ b/src/scanner.c
> >> @@ -128,6 +128,7 @@ struct arg {
> >> char *interface_name;
> >> struct wl_list link;
> >> char *summary;
> >> + char *enumeration_name;
> >> };
> >>
> >> struct enumeration {
> >> @@ -136,6 +137,7 @@ struct enumeration {
> >> struct wl_list entry_list;
> >> struct wl_list link;
> >> struct description *description;
> >> + int bitfield;
> >
> > This appears to be used for tracking only a yes/no type value, so maybe
> > consider making it a boolean?
> >
> >> };
> >>
> >> struct entry {
> >> @@ -540,6 +542,8 @@ start_element(void *data, const char *element_name, const char **atts)
> >> const char *summary = NULL;
> >> const char *since = NULL;
> >> const char *allow_null = NULL;
> >> + const char *enumeration_name = NULL;
> >> + const char *bitfield = NULL;
> >> int i, version = 0;
> >>
> >> ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
> >> @@ -562,6 +566,10 @@ start_element(void *data, const char *element_name, const char **atts)
> >> since = atts[i + 1];
> >> if (strcmp(atts[i], "allow-null") == 0)
> >> allow_null = atts[i + 1];
> >> + if (strcmp(atts[i], "enum") == 0)
> >> + enumeration_name = atts[i + 1];
> >> + if (strcmp(atts[i], "bitfield") == 0)
> >> + bitfield = atts[i + 1];
> >> }
> >>
> >> ctx->character_data_length = 0;
> >> @@ -655,6 +663,14 @@ start_element(void *data, const char *element_name, const char **atts)
> >> "allow-null is only valid for objects, strings, and arrays");
> >> }
> >>
> >> + if (enumeration_name == NULL || strcmp(enumeration_name, "") == 0)
> >> + arg->enumeration_name = NULL;
> >> + else
> >> + arg->enumeration_name = xstrdup(enumeration_name);
> >> +
> >> + if (allow_null != NULL && !is_nullable_type(arg))
> >> + fail(&ctx->loc, "allow-null is only valid for objects, strings, and arrays");
> >> +
> >> if (summary)
> >> arg->summary = xstrdup(summary);
> >>
> >> @@ -665,6 +681,14 @@ start_element(void *data, const char *element_name, const char **atts)
> >> fail(&ctx->loc, "no enum name given");
> >>
> >> enumeration = create_enumeration(name);
> >> +
> >> + if (bitfield == NULL || strcmp(bitfield, "false") == 0)
> >> + enumeration->bitfield = 0;
> >> + else if (strcmp(bitfield, "true") == 0)
> >> + enumeration->bitfield =1;
> >
> > Space needed after the =
> >
> >> + else
> >> + fail(&ctx->loc, "invalid value for bitfield attribute (%s)", bitfield);
> >> +
> >> wl_list_insert(ctx->interface->enumeration_list.prev,
> >> &enumeration->link);
> >>
> >> @@ -701,6 +725,46 @@ start_element(void *data, const char *element_name, const char **atts)
> >> }
> >>
> >> static void
> >> +verify_arguments(struct parse_context *ctx, struct wl_list *messages, struct wl_list *enumerations)
> >> +{
> >> + struct message *m;
> >> + wl_list_for_each(m, messages, link) {
> >> + struct arg *a;
> >> + wl_list_for_each(a, &m->arg_list, link) {
> >> + struct enumeration *e, *f;
> >> +
> >> + if (!a->enumeration_name)
> >> + continue;
> >> +
> >> + f = NULL;
> >> + wl_list_for_each(e, enumerations, link) {
> >> + if(strcmp(e->name, a->enumeration_name) == 0)
> >> + f = e;
> >> + }
> >> +
> >> + if (f == NULL)
> >> + fail(&ctx->loc,
> >> + "could not find enumeration %s",
> >> + a->enumeration_name);
> >> +
> >> + switch (a->type) {
> >> + case INT:
> >> + if (f->bitfield)
> >> + fail(&ctx->loc,
> >> + "bitfield-style enum must be referenced by uint");
> >
> > I think maybe you mean "must only be referenced"?
> >
> >> + break;
> >> + case UNSIGNED:
> >> + break;
> >> + default:
> >> + fail(&ctx->loc,
> >> + "enumeration-style argument has wrong type");
> >> + }
> >> + }
> >> + }
> >> +
> >> +}
> >> +
> >> +static void
> >> end_element(void *data, const XML_Char *name)
> >> {
> >> struct parse_context *ctx = data;
> >> @@ -723,6 +787,12 @@ end_element(void *data, const XML_Char *name)
> >> ctx->enumeration->name);
> >> }
> >> ctx->enumeration = NULL;
> >> + } else if (strcmp(name, "interface") == 0) {
> >> + struct interface *i = ctx->interface;
> >> +
> >> + verify_arguments(ctx, &i->request_list, &i->enumeration_list);
> >> + verify_arguments(ctx, &i->event_list, &i->enumeration_list);
> >> +
> >> }
> >> }
> >>
> >> --
> >> 2.6.1
> >>
> >> _______________________________________________
> >> wayland-devel mailing list
> >> wayland-devel at lists.freedesktop.org
> >> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
> I was actually somewhat planning to fix these things (for both
> bitfield and allow-null) in after this patch is merged: I didn't want
> to include unrelated fixes into this series, but also wanted to write
> code in a consistent style. So that's why it is still like this.
>
> (except for the space after = of course, which I missed)
>
> But now I noticed that my patch introduces a useless check regarding
> allow_null on line 672 (this is already checked earlier, and is there
> because I rebased incorrectly at some point) - this should NOT be in
> here!
>
> I will fix all of this. Should I send in a new series, or can I just
> update this one patch?
For now just this one patch would be more than fine.
One-off v+1's aren't usually a big deal.
The main thing we need next is I'd like to see a couple more R-b's,
particularly from folks who have expressed interest in this feature.
I'm fairly certain at this point we have solid consensus now but this'd
make it official.
> (Is there a systematic way to retract patches?)
Nope, kind of a fundamental limitation to doing change management via
mailing lists.
Bryce
More information about the wayland-devel
mailing list