summaryrefslogtreecommitdiff
path: root/src/ir.c
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-09-30 14:29:00 +0100
committerVincent Sanders <vince@kyllikki.org>2015-09-30 14:29:00 +0100
commitac6ae0a7b545dbf3391760cfe9e6b86ce0c579db (patch)
treefcae63b386940df295fb1de624ef08eb773c9b90 /src/ir.c
parent476bc961ae4c490dfa0f09293c5611451bb42599 (diff)
downloadnsgenbind-ac6ae0a7b545dbf3391760cfe9e6b86ce0c579db.tar.gz
nsgenbind-ac6ae0a7b545dbf3391760cfe9e6b86ce0c579db.tar.bz2
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.
Diffstat (limited to 'src/ir.c')
-rw-r--r--src/ir.c68
1 files changed, 64 insertions, 4 deletions
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,