From ac6ae0a7b545dbf3391760cfe9e6b86ce0c579db Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Sep 2015 14:29:00 +0100 Subject: Implement putforwards processing. interface attributes with the putforwards extended attribute call the setter specified in that extended attribute. The WebIDL is supposed to ensure the attribute is readonly before allowing a putforwards but we only warn about this as there are several examples where readonly is omitted. --- src/ir.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 4 deletions(-) (limited to 'src/ir.c') diff --git a/src/ir.c b/src/ir.c index b3631f4..6dc2d2a 100644 --- a/src/ir.c +++ b/src/ir.c @@ -377,6 +377,56 @@ operation_map_new(struct webidl_node *interface, return 0; } +/** + * get the value of an extended attribute key/value item + */ +static char * +get_extended_value(struct webidl_node *node, const char *key) +{ + char *ident; + struct webidl_node *ext_attr; + struct webidl_node *elem; + + /* walk each extended attribute */ + ext_attr = webidl_node_find_type( + webidl_node_getnode(node), + NULL, + WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE); + while (ext_attr != NULL) { + + elem = webidl_node_find_type( + webidl_node_getnode(ext_attr), + NULL, + WEBIDL_NODE_TYPE_IDENT); + ident = webidl_node_gettext(elem); + + if ((ident != NULL) && (strcmp(ident, key) == 0)) { + /* first identifier matches */ + + elem = webidl_node_find_type( + webidl_node_getnode(ext_attr), + elem, + WEBIDL_NODE_TYPE_IDENT); + ident = webidl_node_gettext(elem); + + if ((ident != NULL) && (*ident == '=')) { + return webidl_node_gettext( + webidl_node_find_type( + webidl_node_getnode(ext_attr), + elem, + WEBIDL_NODE_TYPE_IDENT)); + } + } + + ext_attr = webidl_node_find_type( + webidl_node_getnode(node), + ext_attr, + WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE); + } + + return NULL; +} + static int attribute_map_new(struct webidl_node *interface, struct genbind_node *class, @@ -399,8 +449,7 @@ attribute_map_new(struct webidl_node *interface, return 0; } - attributev = calloc(attributec, - sizeof(struct ir_attribute_entry)); + attributev = calloc(attributec, sizeof(struct ir_attribute_entry)); if (attributev == NULL) { return -1; }; @@ -436,7 +485,7 @@ attribute_map_new(struct webidl_node *interface, GENBIND_METHOD_TYPE_GETTER, cure->name); - /* check fo readonly attributes */ + /* check for readonly attributes */ modifier = (enum webidl_type_modifier *)webidl_node_getint( webidl_node_find_type( webidl_node_getnode(at_node), @@ -454,9 +503,20 @@ attribute_map_new(struct webidl_node *interface, cure->name); } - cure++; + /* check for putforwards extended attribute */ + cure->putforwards = get_extended_value(at_node, + "PutForwards"); + + if ((cure->putforwards != NULL) && + (cure->modifier != WEBIDL_TYPE_MODIFIER_READONLY)) { + WARN(WARNING_WEBIDL, + "putforwards on a writable attribute (%s) is prohibited", + cure->name); + } /* move to next attribute */ + cure++; + at_node = webidl_node_find_type( webidl_node_getnode(list_node), at_node, -- cgit v1.2.3