libnslayout: branch tlsa/listener-no-mutation-events-test created. f9e63b6e91ea15cc2e93f586b1b82ae6d464d658
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libnslayout.git/shortlog/f9e63b6e91ea15cc2...
...commit http://git.netsurf-browser.org/libnslayout.git/commit/f9e63b6e91ea15cc2e9...
...tree http://git.netsurf-browser.org/libnslayout.git/tree/f9e63b6e91ea15cc2e93f...
The branch, tlsa/listener-no-mutation-events-test has been created
at f9e63b6e91ea15cc2e93f586b1b82ae6d464d658 (commit)
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/libnslayout.git/commit/?id=f9e63b6e91ea15c...
commit f9e63b6e91ea15cc2e93f586b1b82ae6d464d658
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Test: not getting mutation events out of listener.
diff --git a/src/layout.c b/src/layout.c
index b5d74c2..a29c8a6 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -10,10 +10,47 @@
#include <assert.h>
#include <stdlib.h>
+#include <stdio.h>
#include "layout.h"
+static void nsl__event_handler(struct dom_event *evt, void *pw)
+{
+ dom_event_target *node;
+ dom_node_type type;
+ dom_string *name, *evt_type;
+ dom_exception exc;
+
+ UNUSED(pw);
+
+ printf("Some kind of event!\n");
+
+ /* Ugly test to see what events come out */
+ exc = dom_event_get_target(evt, &node);
+ if ((exc == DOM_NO_ERR) && (node != NULL)) {
+ exc = dom_node_get_node_type(node, &type);
+ if ((exc == DOM_NO_ERR) && (type == DOM_ELEMENT_NODE)) {
+ /* an element node has an event */
+ exc = dom_node_get_node_name(node, &name);
+ if ((exc == DOM_NO_ERR) && (name != NULL)) {
+
+ exc = _dom_event_get_type(evt, &evt_type);
+ if ((exc == DOM_NO_ERR) && (evt_type != NULL)) {
+ /* Print the event */
+ printf("DOM Event: <%s>: %s\n",
+ dom_string_data(name),
+ dom_string_data(evt_type));
+ dom_string_unref(evt_type);
+ }
+
+ dom_string_unref(name);
+ }
+ }
+ dom_node_unref(node);
+ }
+}
+
/* Publically exported function, documented in include/libnslayout/nslayout.h */
nslayout_error nslayout_layout_create(
dom_document *doc,
@@ -23,13 +60,16 @@ nslayout_error nslayout_layout_create(
void *pw,
nslayout_layout **layout)
{
- nslayout_layout *l;
+ nslayout_layout *l = NULL;
+ dom_exception exc;
assert(doc != NULL);
assert(css_ctx != NULL);
assert(media != NULL);
assert(cb != NULL);
+ printf("Called layout_create\n");
+
l = calloc(1, sizeof(nslayout_layout));
if (l == NULL) {
return NSLAYOUT_NO_MEM;
@@ -42,6 +82,16 @@ nslayout_error nslayout_layout_create(
l->cb = cb;
l->pw = pw;
+ exc = dom_event_listener_create(doc, nsl__event_handler,
+ l, &l->listener);
+ if (exc != DOM_NO_ERR) {
+ /* TODO: free stuff, return value */
+ printf("Failed to register even handler!\n");
+ return NSLAYOUT_NO_MEM;
+ }
+
+ printf("Registered event handler!\n");
+
*layout = l;
return NSLAYOUT_OK;
}
@@ -51,9 +101,11 @@ nslayout_error nslayout_layout_create(
nslayout_error nslayout_layout_destroy(
nslayout_layout *layout)
{
- /* TODO: free/unref the stuff we own in the layout */
assert(layout != NULL);
+ /* TODO: free/unref the stuff we own in the layout */
+ dom_event_listener_unref(layout->listener);
+
free(layout);
return NSLAYOUT_OK;
}
diff --git a/src/layout.h b/src/layout.h
index 9946663..e689246 100644
--- a/src/layout.h
+++ b/src/layout.h
@@ -13,12 +13,18 @@
#include <libnslayout/nslayout.h>
+#ifndef UNUSED
+#define UNUSED(x) (void)(x)
+#endif
+
struct nslayout_layout {
dom_document *doc;
css_select_ctx *css_ctx;
css_media_type *media;
nslayout_callback cb;
void *pw;
+
+ dom_event_listener *listener;
};
#endif
diff --git a/test/main.c b/test/main.c
new file mode 100644
index 0000000..b48eb46
--- /dev/null
+++ b/test/main.c
@@ -0,0 +1,22 @@
+/*
+ * This file is part of LibNSLayout's tests
+ * Licensed under the ISC License, http://opensource.org/licenses/ISC
+ * Copyright 2015 Michael Drake <tlsa(a)netsurf-browser.org>
+ */
+
+#include <check.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tests.h"
+
+#include "test-loader.c"
+
+/*
+ * cd ../ && make && make install && cd test && gcc `pkg-config libnslayout --cflags` main.c `pkg-config libnslayout --libs` && ./a.out
+ */
+
+int main(void)
+{
+ return test_loader("test-writing-mode.html", CSS_MEDIA_ALL, 15);
+}
diff --git a/test/test-loader.c b/test/test-loader.c
new file mode 100644
index 0000000..e9be591
--- /dev/null
+++ b/test/test-loader.c
@@ -0,0 +1,298 @@
+/*
+ * This file is part of LibNSLayout's tests
+ * Licensed under the ISC License, http://opensource.org/licenses/ISC
+ * Copyright 2015 Michael Drake <tlsa(a)netsurf-browser.org>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <dom/dom.h>
+#include <dom/bindings/hubbub/parser.h>
+#include <libcss/libcss.h>
+
+#include <libnslayout/nslayout.h>
+
+#ifndef UNUSED
+#define UNUSED(x) (void)(x)
+#endif
+
+static nslayout_error nslayout_test_callback(
+ nslayout_layout *layout,
+ void *pw,
+ nslayout_request *req)
+{
+ UNUSED(req);
+ UNUSED(layout);
+ UNUSED(pw);
+ return NSLAYOUT_OK;
+}
+
+struct doc_load_ctx {
+ dom_hubbub_parser *parser;
+ dom_document *doc;
+ unsigned char *buffer;
+ size_t buffer_size;
+ FILE *handle;
+ css_select_ctx *css_ctx;
+ css_stylesheet *css_sheet;
+};
+
+
+static bool doc_load_start(const char *file, size_t buffer_size,
+ struct doc_load_ctx *load_ctx)
+{
+ dom_hubbub_parser_params params;
+ dom_hubbub_error error;
+ size_t chunk_length;
+
+ params.enc = NULL;
+ params.fix_enc = true;
+ params.enable_script = false;
+ params.msg = NULL;
+ params.script = NULL;
+ params.ctx = NULL;
+ params.daf = NULL;
+
+ load_ctx->buffer = malloc(buffer_size);
+ if (load_ctx->buffer == NULL) {
+ return false;
+ }
+
+ load_ctx->buffer_size = buffer_size;
+
+ /* Create Hubbub parser */
+ error = dom_hubbub_parser_create(¶ms, &load_ctx->parser,
+ &load_ctx->doc);
+ if (error != DOM_HUBBUB_OK) {
+ free(load_ctx->buffer);
+ return false;
+ }
+
+ /* Open input file */
+ load_ctx->handle = fopen(file, "rb");
+ if (load_ctx->handle == NULL) {
+ dom_hubbub_parser_destroy(load_ctx->parser);
+ free(load_ctx->buffer);
+ return false;
+ }
+
+ /* Parse input file in chunks */
+ chunk_length = buffer_size;
+ chunk_length = fread(load_ctx->buffer, 1, load_ctx->buffer_size,
+ load_ctx->handle);
+ error = dom_hubbub_parser_parse_chunk(load_ctx->parser,
+ load_ctx->buffer, chunk_length);
+ if (error != DOM_HUBBUB_OK) {
+ dom_hubbub_parser_destroy(load_ctx->parser);
+ printf("Parsing errors occur\n");
+ return false;
+ }
+
+ return true;
+}
+
+
+static bool doc_load_next(struct doc_load_ctx *load_ctx, bool *complete)
+{
+ dom_hubbub_error error;
+ int chunk_length;
+
+ /* Parse input file in chunks */
+ chunk_length = fread(load_ctx->buffer, 1, load_ctx->buffer_size,
+ load_ctx->handle);
+ if (chunk_length != 0) {
+ error = dom_hubbub_parser_parse_chunk(load_ctx->parser,
+ load_ctx->buffer, chunk_length);
+ if (error != DOM_HUBBUB_OK) {
+ dom_hubbub_parser_destroy(load_ctx->parser);
+ printf("Parsing errors occur\n");
+ return false;
+ }
+ *complete = false;
+ return true;
+ }
+
+ *complete = true;
+
+ /* Done parsing file */
+ error = dom_hubbub_parser_completed(load_ctx->parser);
+ if (error != DOM_HUBBUB_OK) {
+ dom_hubbub_parser_destroy(load_ctx->parser);
+ printf("Parsing error when construct DOM\n");
+ return false;
+ }
+
+ /* Finished with parser */
+ dom_hubbub_parser_destroy(load_ctx->parser);
+
+ /* Close input file */
+ if (fclose(load_ctx->handle) != 0) {
+ printf("Can't close test input file\n");
+ return false;
+ }
+
+ return true;
+}
+
+
+static css_error resolve_url(void *pw, const char *base,
+ lwc_string *rel, lwc_string **abs)
+{
+ UNUSED(pw);
+ UNUSED(base);
+
+ /* No join implementation; just copy rel to abs for now. */
+ *abs = lwc_string_ref(rel);
+
+ return CSS_OK;
+}
+
+
+static bool test_loader_css_fini(struct doc_load_ctx *load_ctx)
+{
+ css_error css_err = CSS_OK;
+
+ if (load_ctx->css_ctx != NULL) {
+ css_err = css_select_ctx_destroy(load_ctx->css_ctx);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_select_ctx_destroy\n");
+ }
+ }
+ if (load_ctx->css_sheet != NULL) {
+ css_err = css_stylesheet_destroy(load_ctx->css_sheet);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_stylesheet_destroy\n");
+ }
+ }
+
+ return (css_err == CSS_OK);
+}
+
+
+static bool test_loader_css_init(struct doc_load_ctx *load_ctx)
+{
+ css_error css_err;
+ css_stylesheet_params params;
+ const char *ua_style =
+ "div, p, h1, h2, h3, h4, h5 {display:block}";
+
+ params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
+ params.level = CSS_LEVEL_21;
+ params.charset = "UTF-8";
+ params.url = "foo";
+ params.title = "foo";
+ params.allow_quirks = false;
+ params.inline_style = false;
+ params.resolve = resolve_url;
+ params.resolve_pw = NULL;
+ params.import = NULL;
+ params.import_pw = NULL;
+ params.color = NULL;
+ params.color_pw = NULL;
+ params.font = NULL;
+ params.font_pw = NULL;
+
+ /* create a stylesheet */
+ css_err = css_stylesheet_create(¶ms, &load_ctx->css_sheet);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_stylesheet_create\n");
+ goto fail;
+ }
+
+ css_err = css_stylesheet_append_data(load_ctx->css_sheet,
+ (const uint8_t *) ua_style, sizeof ua_style);
+ if (css_err != CSS_OK && css_err != CSS_NEEDDATA) {
+ printf("ERROR: css_stylesheet_append_data\n");
+ goto fail;
+ }
+ css_err = css_stylesheet_data_done(load_ctx->css_sheet);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_stylesheet_data_done\n");
+ goto fail;
+ }
+
+ /* Create a selection context (with no sheets added) */
+ css_err = css_select_ctx_create(&load_ctx->css_ctx);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_select_ctx_create\n");
+ goto fail;
+ }
+
+ css_err = css_select_ctx_append_sheet(load_ctx->css_ctx,
+ load_ctx->css_sheet, CSS_ORIGIN_UA, CSS_MEDIA_ALL);
+ if (css_err != CSS_OK) {
+ printf("ERROR: css_select_ctx_append_sheet\n");
+ goto fail;
+ }
+
+ return true;
+
+fail:
+ test_loader_css_fini(load_ctx);
+
+ return false;
+}
+
+
+static bool test_loader(const char *document_path,
+ css_media_type media,
+ size_t chunk_size)
+{
+ nslayout_layout *layout = NULL;
+ nslayout_error error;
+ struct doc_load_ctx load_ctx;
+ bool complete = false;
+ bool ret = false;
+
+ load_ctx.parser = NULL;
+ load_ctx.doc = NULL;
+ load_ctx.buffer = NULL;
+ load_ctx.buffer_size = 0;
+ load_ctx.handle = NULL;
+ load_ctx.css_sheet = NULL;
+ load_ctx.css_ctx = NULL;
+printf(" Test loader\n");
+ if (!doc_load_start(document_path, chunk_size, &load_ctx)) {
+ printf("ERROR: doc_load_start\n");
+ goto fail;
+ }
+printf(" Started load\n");
+ if (!test_loader_css_init(&load_ctx)) {
+ printf("ERROR: create_style_context\n");
+ goto fail;
+ }
+printf(" Created style context\n");
+ error = nslayout_layout_create(load_ctx.doc,
+ load_ctx.css_ctx,
+ &media,
+ nslayout_test_callback,
+ NULL,
+ &layout);
+ if (error != NSLAYOUT_OK) {
+ goto fail;
+ }
+printf(" Created nsl layout\n");
+ while (!complete) {
+ if (!doc_load_next(&load_ctx, &complete)) {
+ printf("ERROR: doc_load_next\n");
+ goto fail;
+ }
+ printf(" Loaded a chunk of the document\n");
+ }
+printf(" Finished loading document\n");
+ error = nslayout_layout_destroy(layout);
+ layout = NULL;
+printf(" Destroyed layout\n");
+ ret = (error == NSLAYOUT_OK);
+fail:
+ if (layout != NULL) {
+ nslayout_layout_destroy(layout);
+ }
+ test_loader_css_fini(&load_ctx);
+ dom_node_unref(load_ctx.doc);
+
+ return ret;
+}
+
diff --git a/test/test-writing-mode.html b/test/test-writing-mode.html
new file mode 100644
index 0000000..96c811e
--- /dev/null
+++ b/test/test-writing-mode.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+html {
+ -ms-writing-mode: lr-tb;
+ -webkit-writing-mode: horizontal-tb;
+ -moz-writing-mode: horizontal-tb;
+ -ms-writing-mode: horizontal-tb;
+ writing-mode: horizontal-tb;
+}
+html:hover {
+ -ms-writing-mode: tb-rl;
+ -webkit-writing-mode: vertical-rl;
+ -moz-writing-mode: vertical-rl;
+ -ms-writing-mode: vertical-rl;
+ writing-mode: vertical-rl;
+}
+h1 {
+ background: #600;
+ color: #fff;
+ width: 50%;
+ margin: 0;
+ padding: 3px;
+ border-bottom: 2px solid black;
+}
+p {
+ margin: 0;
+ padding: 3px;
+ border: 1px solid green;
+ border-left-width: 1em;
+ margin-top: 3em;
+}
+</style>
+</head>
+<body>
+<h1>Test</h1>
+<p>Here's some text to test CSS3 writing modes <a href="https://drafts.csswg.org/css-writing-modes/#abstract-layout">abstract box layout</a>!</p>
+</body>
+</html>
-----------------------------------------------------------------------
--
NetSurf Layout Engine
8 years, 1 month
libnslayout: branch master updated. 0367977ad546bd82a4c5c6bb747f913e4c40e00a
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libnslayout.git/shortlog/0367977ad546bd82a...
...commit http://git.netsurf-browser.org/libnslayout.git/commit/0367977ad546bd82a4c...
...tree http://git.netsurf-browser.org/libnslayout.git/tree/0367977ad546bd82a4c5c...
The branch, master has been updated
via 0367977ad546bd82a4c5c6bb747f913e4c40e00a (commit)
from 29c85a74a5fe16bfa6cba7d82e4748367e261a20 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/libnslayout.git/commit/?id=0367977ad546bd8...
commit 0367977ad546bd82a4c5c6bb747f913e4c40e00a
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
s/_/-/
diff --git a/test/Makefile b/test/Makefile
index 24a036e..967d8da 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,3 +1,3 @@
-DIR_TEST_ITEMS := testrunner:tests.c;assert-tests.c;nslayout_object-tests.c
+DIR_TEST_ITEMS := testrunner:tests.c;assert-tests.c;nslayout-object-tests.c
include $(NSBUILD)/Makefile.subdir
diff --git a/test/nslayout-object-tests.c b/test/nslayout-object-tests.c
new file mode 100644
index 0000000..a2f9afc
--- /dev/null
+++ b/test/nslayout-object-tests.c
@@ -0,0 +1,79 @@
+/*
+ * This file is part of LibNSLayout's tests
+ * Licensed under the ISC License, http://opensource.org/licenses/ISC
+ * Copyright 2015 Michael Drake <tlsa(a)netsurf-browser.org>
+ */
+
+#include <check.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tests.h"
+
+#ifndef UNUSED
+#define UNUSED(x) (void)(x)
+#endif
+
+static nslayout_error nslayout_test_callback(
+ nslayout_layout *layout,
+ void *pw,
+ nslayout_request *req)
+{
+ UNUSED(req);
+ UNUSED(layout);
+ UNUSED(pw);
+ return NSLAYOUT_OK;
+}
+
+START_TEST (test_nslayout_layout_create_ok)
+{
+ nslayout_layout *layout = NULL;
+ nslayout_error error;
+ dom_exception dom_error;
+ css_error css_err;
+ dom_document *doc;
+ css_select_ctx *css_ctx;
+ css_media_type media = CSS_MEDIA_SCREEN;
+
+ /* Create a DOM document */
+ dom_error = dom_implementation_create_document(DOM_IMPLEMENTATION_HTML,
+ NULL, NULL, NULL, NULL, NULL, &doc);
+ ck_assert(dom_error == DOM_NO_ERR);
+
+ /* Create a selection context (with no sheets added) */
+ css_err = css_select_ctx_create(&css_ctx);
+ ck_assert(css_err == CSS_OK);
+
+ error = nslayout_layout_create(doc,
+ css_ctx,
+ &media,
+ nslayout_test_callback,
+ NULL,
+ &layout);
+ fail_unless(error == NSLAYOUT_OK,
+ "Unable to create layout");
+ fail_unless(layout != NULL,
+ "Returned OK but str was still NULL");
+
+ error = nslayout_layout_destroy(layout);
+ fail_unless(error == NSLAYOUT_OK,
+ "Unable to destroy layout");
+
+ css_err = css_select_ctx_destroy(css_ctx);
+ ck_assert(css_err == CSS_OK);
+
+ dom_node_unref(doc);
+}
+END_TEST
+
+
+void nslayout_nslayout_object_suite(SRunner *sr)
+{
+ Suite *s = suite_create("libnslayout: nslayout object tests");
+ TCase *tc_layout_basic = tcase_create("Creation/Destruction");
+
+ tcase_add_test(tc_layout_basic, test_nslayout_layout_create_ok);
+ suite_add_tcase(s, tc_layout_basic);
+
+ srunner_add_suite(sr, s);
+}
diff --git a/test/nslayout_object-tests.c b/test/nslayout_object-tests.c
deleted file mode 100644
index a2f9afc..0000000
--- a/test/nslayout_object-tests.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * This file is part of LibNSLayout's tests
- * Licensed under the ISC License, http://opensource.org/licenses/ISC
- * Copyright 2015 Michael Drake <tlsa(a)netsurf-browser.org>
- */
-
-#include <check.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "tests.h"
-
-#ifndef UNUSED
-#define UNUSED(x) (void)(x)
-#endif
-
-static nslayout_error nslayout_test_callback(
- nslayout_layout *layout,
- void *pw,
- nslayout_request *req)
-{
- UNUSED(req);
- UNUSED(layout);
- UNUSED(pw);
- return NSLAYOUT_OK;
-}
-
-START_TEST (test_nslayout_layout_create_ok)
-{
- nslayout_layout *layout = NULL;
- nslayout_error error;
- dom_exception dom_error;
- css_error css_err;
- dom_document *doc;
- css_select_ctx *css_ctx;
- css_media_type media = CSS_MEDIA_SCREEN;
-
- /* Create a DOM document */
- dom_error = dom_implementation_create_document(DOM_IMPLEMENTATION_HTML,
- NULL, NULL, NULL, NULL, NULL, &doc);
- ck_assert(dom_error == DOM_NO_ERR);
-
- /* Create a selection context (with no sheets added) */
- css_err = css_select_ctx_create(&css_ctx);
- ck_assert(css_err == CSS_OK);
-
- error = nslayout_layout_create(doc,
- css_ctx,
- &media,
- nslayout_test_callback,
- NULL,
- &layout);
- fail_unless(error == NSLAYOUT_OK,
- "Unable to create layout");
- fail_unless(layout != NULL,
- "Returned OK but str was still NULL");
-
- error = nslayout_layout_destroy(layout);
- fail_unless(error == NSLAYOUT_OK,
- "Unable to destroy layout");
-
- css_err = css_select_ctx_destroy(css_ctx);
- ck_assert(css_err == CSS_OK);
-
- dom_node_unref(doc);
-}
-END_TEST
-
-
-void nslayout_nslayout_object_suite(SRunner *sr)
-{
- Suite *s = suite_create("libnslayout: nslayout object tests");
- TCase *tc_layout_basic = tcase_create("Creation/Destruction");
-
- tcase_add_test(tc_layout_basic, test_nslayout_layout_create_ok);
- suite_add_tcase(s, tc_layout_basic);
-
- srunner_add_suite(sr, s);
-}
-----------------------------------------------------------------------
Summary of changes:
test/Makefile | 2 +-
test/{nslayout_object-tests.c => nslayout-object-tests.c} | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename test/{nslayout_object-tests.c => nslayout-object-tests.c} (100%)
diff --git a/test/Makefile b/test/Makefile
index 24a036e..967d8da 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,3 +1,3 @@
-DIR_TEST_ITEMS := testrunner:tests.c;assert-tests.c;nslayout_object-tests.c
+DIR_TEST_ITEMS := testrunner:tests.c;assert-tests.c;nslayout-object-tests.c
include $(NSBUILD)/Makefile.subdir
diff --git a/test/nslayout_object-tests.c b/test/nslayout-object-tests.c
similarity index 100%
rename from test/nslayout_object-tests.c
rename to test/nslayout-object-tests.c
--
NetSurf Layout Engine
8 years, 1 month
nsgenbind: branch vince/interfacemap updated. release/0.1.0-31-gcb20895
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/nsgenbind.git/shortlog/cb2089531d416578677...
...commit http://git.netsurf-browser.org/nsgenbind.git/commit/cb2089531d4165786772c...
...tree http://git.netsurf-browser.org/nsgenbind.git/tree/cb2089531d4165786772c5c...
The branch, vince/interfacemap has been updated
via cb2089531d4165786772c5cef17d28dc1a8e28d6 (commit)
from 02ebfefd0fc3d81b59cc15f34033210a6344f430 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/nsgenbind.git/commit/?id=cb2089531d4165786...
commit cb2089531d4165786772c5cef17d28dc1a8e28d6
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
ensure nothing is generated for interfaces marked with NoInterfaceObject
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index 49f100a..590afa2 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -1002,7 +1002,12 @@ static int output_interface(struct interface_map *interface_map,
struct interface_map_entry *inherite;
int res = 0;
- /* compute clas name */
+ /* do not generate class for interfaces marked no output */
+ if (interfacee->noobject) {
+ return 0;
+ }
+
+ /* compute class name */
interfacee->class_name = gen_class_name(interfacee);
/* generate source filename */
@@ -1125,6 +1130,13 @@ output_private_header(struct interface_map *interface_map)
interfacee = interface_map->entries + idx;
+ /* do not generate private structs for interfaces marked no
+ * output
+ */
+ if (interfacee->noobject) {
+ continue;
+ }
+
/* find parent interface entry */
inherite = interface_map_inherit_entry(interface_map,
interfacee);
@@ -1201,6 +1213,13 @@ output_prototype_header(struct interface_map *interface_map)
interfacee = interface_map->entries + idx;
+ /* do not generate prototype declarations for interfaces marked
+ * no output
+ */
+ if (interfacee->noobject) {
+ continue;
+ }
+
/* prototype declaration */
fprintf(protof, "duk_ret_t %s_%s___proto(duk_context *ctx);\n",
DLPFX, interfacee->class_name);
@@ -1255,6 +1274,11 @@ output_makefile(struct interface_map *interface_map)
interfacee = interface_map->entries + idx;
+ /* no source for interfaces marked no output */
+ if (interfacee->noobject) {
+ continue;
+ }
+
fprintf(makef, "%s ", interfacee->filename);
}
fprintf(makef, "\nNSGENBIND_PREFIX:=%s\n", options->outdirname);
diff --git a/src/interface-map.c b/src/interface-map.c
index 13d6106..467c0ed 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -110,6 +110,7 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
dstinf[idx].name = srcinf[inf].name;
dstinf[idx].node = srcinf[inf].node;
dstinf[idx].inherit_name = srcinf[inf].inherit_name;
+ dstinf[idx].noobject = srcinf[inf].noobject;
dstinf[idx].operationc = srcinf[inf].operationc;
dstinf[idx].operationv = srcinf[inf].operationv;
dstinf[idx].attributec = srcinf[inf].attributec;
@@ -391,7 +392,7 @@ int interface_map_new(struct genbind_node *genbind,
WEBIDL_NODE_TYPE_INTERFACE);
if (options->verbose) {
- printf("Maping %d interfaces\n", interfacec);
+ printf("Mapping %d interfaces\n", interfacec);
}
entries = calloc(interfacec, sizeof(struct interface_map_entry));
@@ -421,6 +422,17 @@ int interface_map_new(struct genbind_node *genbind,
NULL,
WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE));
+ if (webidl_node_find_type_ident(
+ webidl_node_getnode(node),
+ WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE,
+ "NoInterfaceObject") != NULL) {
+ /** \todo we should ensure inherit is unset as this
+ * cannot form part of an inheritance chain if it is
+ * not generating an output class
+ */
+ ecur->noobject = true;
+ }
+
/* matching class from binding */
ecur->class = genbind_node_find_type_ident(genbind,
NULL, GENBIND_NODE_TYPE_CLASS, ecur->name);
@@ -579,16 +591,20 @@ int interface_map_dumpdot(struct interface_map *index)
fprintf(dumpf, "digraph interfaces {\n");
+ fprintf(dumpf, "node [shape=box]\n");
+
ecur = index->entries;
for (eidx = 0; eidx < index->entryc; eidx++) {
- if (ecur->class != NULL) {
- /* interfaces bound to a class are shown in blue */
- fprintf(dumpf, "%04d [label=\"%s\" fontcolor=\"blue\"];\n",
- eidx, ecur->name);
- } else {
- fprintf(dumpf, "%04d [label=\"%s\"];\n", eidx, ecur->name);
- }
- ecur++;
+ fprintf(dumpf, "%04d [label=\"%s\"", eidx, ecur->name);
+ if (ecur->noobject == true) {
+ /* noobject interfaces in red */
+ fprintf(dumpf, "fontcolor=\"red\"");
+ } else if (ecur->class != NULL) {
+ /* interfaces bound to a class are shown in blue */
+ fprintf(dumpf, "fontcolor=\"blue\"");
+ }
+ fprintf(dumpf, "];\n");
+ ecur++;
}
ecur = index->entries;
diff --git a/src/interface-map.h b/src/interface-map.h
index e44380a..e07aa19 100644
--- a/src/interface-map.h
+++ b/src/interface-map.h
@@ -39,6 +39,16 @@ struct interface_map_entry {
const char *name; /** interface name */
struct webidl_node *node; /**< AST interface node */
const char *inherit_name; /**< Name of interface inhertited from */
+ int inherit_idx; /**< index into map of inherited interface or -1 for
+ * not in map
+ */
+ int refcount; /**< number of interfacess in map that refer to this
+ * interface
+ */
+ bool noobject; /**< flag indicating if no interface object should eb
+ * generated. This allows for interfaces which do not
+ * generate code. For implements (mixin) interfaces
+ */
int operationc; /**< number of operations on interface */
struct interface_map_operation_entry *operationv;
@@ -49,12 +59,7 @@ struct interface_map_entry {
int constantc; /**< number of constants on interface */
struct interface_map_constant_entry *constantv;
- int inherit_idx; /**< index into map of inherited interface or -1 for
- * not in map
- */
- int refcount; /**< number of interfacess in map that refer to this
- * interface
- */
+
struct genbind_node *class; /**< class from binding (if any) */
/* The variables are created and used by the output generation but
-----------------------------------------------------------------------
Summary of changes:
src/duk-libdom.c | 26 +++++++++++++++++++++++++-
src/interface-map.c | 34 +++++++++++++++++++++++++---------
src/interface-map.h | 17 +++++++++++------
3 files changed, 61 insertions(+), 16 deletions(-)
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index 49f100a..590afa2 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -1002,7 +1002,12 @@ static int output_interface(struct interface_map *interface_map,
struct interface_map_entry *inherite;
int res = 0;
- /* compute clas name */
+ /* do not generate class for interfaces marked no output */
+ if (interfacee->noobject) {
+ return 0;
+ }
+
+ /* compute class name */
interfacee->class_name = gen_class_name(interfacee);
/* generate source filename */
@@ -1125,6 +1130,13 @@ output_private_header(struct interface_map *interface_map)
interfacee = interface_map->entries + idx;
+ /* do not generate private structs for interfaces marked no
+ * output
+ */
+ if (interfacee->noobject) {
+ continue;
+ }
+
/* find parent interface entry */
inherite = interface_map_inherit_entry(interface_map,
interfacee);
@@ -1201,6 +1213,13 @@ output_prototype_header(struct interface_map *interface_map)
interfacee = interface_map->entries + idx;
+ /* do not generate prototype declarations for interfaces marked
+ * no output
+ */
+ if (interfacee->noobject) {
+ continue;
+ }
+
/* prototype declaration */
fprintf(protof, "duk_ret_t %s_%s___proto(duk_context *ctx);\n",
DLPFX, interfacee->class_name);
@@ -1255,6 +1274,11 @@ output_makefile(struct interface_map *interface_map)
interfacee = interface_map->entries + idx;
+ /* no source for interfaces marked no output */
+ if (interfacee->noobject) {
+ continue;
+ }
+
fprintf(makef, "%s ", interfacee->filename);
}
fprintf(makef, "\nNSGENBIND_PREFIX:=%s\n", options->outdirname);
diff --git a/src/interface-map.c b/src/interface-map.c
index 13d6106..467c0ed 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -110,6 +110,7 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
dstinf[idx].name = srcinf[inf].name;
dstinf[idx].node = srcinf[inf].node;
dstinf[idx].inherit_name = srcinf[inf].inherit_name;
+ dstinf[idx].noobject = srcinf[inf].noobject;
dstinf[idx].operationc = srcinf[inf].operationc;
dstinf[idx].operationv = srcinf[inf].operationv;
dstinf[idx].attributec = srcinf[inf].attributec;
@@ -391,7 +392,7 @@ int interface_map_new(struct genbind_node *genbind,
WEBIDL_NODE_TYPE_INTERFACE);
if (options->verbose) {
- printf("Maping %d interfaces\n", interfacec);
+ printf("Mapping %d interfaces\n", interfacec);
}
entries = calloc(interfacec, sizeof(struct interface_map_entry));
@@ -421,6 +422,17 @@ int interface_map_new(struct genbind_node *genbind,
NULL,
WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE));
+ if (webidl_node_find_type_ident(
+ webidl_node_getnode(node),
+ WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE,
+ "NoInterfaceObject") != NULL) {
+ /** \todo we should ensure inherit is unset as this
+ * cannot form part of an inheritance chain if it is
+ * not generating an output class
+ */
+ ecur->noobject = true;
+ }
+
/* matching class from binding */
ecur->class = genbind_node_find_type_ident(genbind,
NULL, GENBIND_NODE_TYPE_CLASS, ecur->name);
@@ -579,16 +591,20 @@ int interface_map_dumpdot(struct interface_map *index)
fprintf(dumpf, "digraph interfaces {\n");
+ fprintf(dumpf, "node [shape=box]\n");
+
ecur = index->entries;
for (eidx = 0; eidx < index->entryc; eidx++) {
- if (ecur->class != NULL) {
- /* interfaces bound to a class are shown in blue */
- fprintf(dumpf, "%04d [label=\"%s\" fontcolor=\"blue\"];\n",
- eidx, ecur->name);
- } else {
- fprintf(dumpf, "%04d [label=\"%s\"];\n", eidx, ecur->name);
- }
- ecur++;
+ fprintf(dumpf, "%04d [label=\"%s\"", eidx, ecur->name);
+ if (ecur->noobject == true) {
+ /* noobject interfaces in red */
+ fprintf(dumpf, "fontcolor=\"red\"");
+ } else if (ecur->class != NULL) {
+ /* interfaces bound to a class are shown in blue */
+ fprintf(dumpf, "fontcolor=\"blue\"");
+ }
+ fprintf(dumpf, "];\n");
+ ecur++;
}
ecur = index->entries;
diff --git a/src/interface-map.h b/src/interface-map.h
index e44380a..e07aa19 100644
--- a/src/interface-map.h
+++ b/src/interface-map.h
@@ -39,6 +39,16 @@ struct interface_map_entry {
const char *name; /** interface name */
struct webidl_node *node; /**< AST interface node */
const char *inherit_name; /**< Name of interface inhertited from */
+ int inherit_idx; /**< index into map of inherited interface or -1 for
+ * not in map
+ */
+ int refcount; /**< number of interfacess in map that refer to this
+ * interface
+ */
+ bool noobject; /**< flag indicating if no interface object should eb
+ * generated. This allows for interfaces which do not
+ * generate code. For implements (mixin) interfaces
+ */
int operationc; /**< number of operations on interface */
struct interface_map_operation_entry *operationv;
@@ -49,12 +59,7 @@ struct interface_map_entry {
int constantc; /**< number of constants on interface */
struct interface_map_constant_entry *constantv;
- int inherit_idx; /**< index into map of inherited interface or -1 for
- * not in map
- */
- int refcount; /**< number of interfacess in map that refer to this
- * interface
- */
+
struct genbind_node *class; /**< class from binding (if any) */
/* The variables are created and used by the output generation but
--
NetSurf Generator for JavaScript bindings
8 years, 1 month
nsgenbind: branch vince/interfacemap updated. release/0.1.0-30-g02ebfef
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/nsgenbind.git/shortlog/02ebfefd0fc3d81b59c...
...commit http://git.netsurf-browser.org/nsgenbind.git/commit/02ebfefd0fc3d81b59cc1...
...tree http://git.netsurf-browser.org/nsgenbind.git/tree/02ebfefd0fc3d81b59cc15f...
The branch, vince/interfacemap has been updated
via 02ebfefd0fc3d81b59cc15f34033210a6344f430 (commit)
from 4b723a410bc1a3355d401b95ac390f377b5d77b8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/nsgenbind.git/commit/?id=02ebfefd0fc3d81b5...
commit 02ebfefd0fc3d81b59cc15f34033210a6344f430
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Generate makefile fragment and add header guards
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index a883f7c..49f100a 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -968,12 +968,20 @@ output_interface_attributes(FILE* outf,
*/
static int output_tool_preface(FILE* outf)
{
- char *fpath;
+ fprintf(outf, "\n%s\n", NSGENBIND_PREAMBLE);
- fprintf(outf, "\n%s\n\n", NSGENBIND_PREAMBLE);
+ return 0;
+}
+
+/**
+ * generate preface block for nsgenbind
+ */
+static int output_tool_prologue(FILE* outf)
+{
+ char *fpath;
fpath = genb_fpath("private.h");
- fprintf(outf, "#include \"%s\"\n", fpath);
+ fprintf(outf, "\n#include \"%s\"\n", fpath);
free(fpath);
fpath = genb_fpath("prototype.h");
@@ -986,13 +994,11 @@ static int output_tool_preface(FILE* outf)
/**
* generate a source file to implement an interface using duk and libdom.
*/
-static int output_interface(struct genbind_node *genbind,
- struct interface_map *interface_map,
+static int output_interface(struct interface_map *interface_map,
struct interface_map_entry *interfacee)
{
FILE *ifacef;
int ifacenamelen;
- struct genbind_node *binding_node;
struct interface_map_entry *inherite;
int res = 0;
@@ -1014,11 +1020,10 @@ static int output_interface(struct genbind_node *genbind,
/* find parent interface entry */
inherite = interface_map_inherit_entry(interface_map, interfacee);
- binding_node = genbind_node_find_type(genbind, NULL,
- GENBIND_NODE_TYPE_BINDING);
-
/* binding preface */
- output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_PREFACE);
+ output_cdata(ifacef,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_PREFACE);
/* tool preface */
output_tool_preface(ifacef);
@@ -1027,7 +1032,11 @@ static int output_interface(struct genbind_node *genbind,
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PREFACE);
/* binding prologue */
- output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_PROLOGUE);
+ output_cdata(ifacef,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_PROLOGUE);
+
+ output_tool_prologue(ifacef);
/* class prologue */
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PROLOGUE);
@@ -1064,13 +1073,17 @@ static int output_interface(struct genbind_node *genbind,
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_EPILOGUE);
/* binding epilogue */
- output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_EPILOGUE);
+ output_cdata(ifacef,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_EPILOGUE);
/* class postface */
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_POSTFACE);
/* binding postface */
- output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_POSTFACE);
+ output_cdata(ifacef,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_POSTFACE);
op_error:
fclose(ifacef);
@@ -1093,6 +1106,18 @@ output_private_header(struct interface_map *interface_map)
return -1;
}
+ /* binding preface */
+ output_cdata(privf,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_PREFACE);
+
+ /* tool preface */
+ output_tool_preface(privf);
+
+ /* header guard */
+ fprintf(privf, "\n#ifndef duk_libdom_private_h\n");
+ fprintf(privf, "#define duk_libdom_private_h\n\n");
+
for (idx = 0; idx < interface_map->entryc; idx++) {
struct interface_map_entry *interfacee;
struct interface_map_entry *inherite;
@@ -1131,6 +1156,13 @@ output_private_header(struct interface_map *interface_map)
}
+ /* binding postface */
+ output_cdata(privf,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_POSTFACE);
+
+ fprintf(privf, "\n#endif\n");
+
fclose(privf);
return 0;
@@ -1151,6 +1183,18 @@ output_prototype_header(struct interface_map *interface_map)
return -1;
}
+ /* binding preface */
+ output_cdata(protof,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_PREFACE);
+
+ /* tool preface */
+ output_tool_preface(protof);
+
+ /* header guard */
+ fprintf(protof, "\n#ifndef duk_libdom_prototype_h\n");
+ fprintf(protof, "#define duk_libdom_prototype_h\n\n");
+
for (idx = 0; idx < interface_map->entryc; idx++) {
struct interface_map_entry *interfacee;
struct genbind_node *init_node;
@@ -1176,22 +1220,58 @@ output_prototype_header(struct interface_map *interface_map)
fprintf(protof, ";\n\n");
}
+ /* binding postface */
+ output_cdata(protof,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_POSTFACE);
+
+ fprintf(protof, "\n#endif\n");
+
fclose(protof);
return 0;
}
-int duk_libdom_output(struct genbind_node *genbind,
- struct webidl_node *webidl,
- struct interface_map *interface_map)
+/**
+ * generate protottype header
+ */
+static int
+output_makefile(struct interface_map *interface_map)
+{
+ int idx;
+ FILE *makef;
+
+ /* open output file */
+ makef = genb_fopen("Makefile", "w");
+ if (makef == NULL) {
+ return -1;
+ }
+
+ fprintf(makef, "# duk libdom makefile fragment\n\n");
+
+ fprintf(makef, "NSGENBIND_SOURCES:=");
+ for (idx = 0; idx < interface_map->entryc; idx++) {
+ struct interface_map_entry *interfacee;
+
+ interfacee = interface_map->entries + idx;
+
+ fprintf(makef, "%s ", interfacee->filename);
+ }
+ fprintf(makef, "\nNSGENBIND_PREFIX:=%s\n", options->outdirname);
+
+ fclose(makef);
+
+ return 0;
+}
+
+int duk_libdom_output(struct interface_map *interface_map)
{
int idx;
int res = 0;
/* generate interfaces */
for (idx = 0; idx < interface_map->entryc; idx++) {
- res = output_interface(genbind,
- interface_map,
+ res = output_interface(interface_map,
interface_map->entries + idx);
if (res != 0) {
goto output_err;
@@ -1211,7 +1291,8 @@ int duk_libdom_output(struct genbind_node *genbind,
}
/* generate makefile fragment */
- /** \todo implement makefile generation */
+ res = output_makefile(interface_map);
+
output_err:
return res;
diff --git a/src/duk-libdom.h b/src/duk-libdom.h
index 8e86d74..e1dd2c4 100644
--- a/src/duk-libdom.h
+++ b/src/duk-libdom.h
@@ -9,8 +9,6 @@
#ifndef nsgenbind_duk_libdom_h
#define nsgenbind_duk_libdom_h
-int duk_libdom_output(struct genbind_node *genbind,
- struct webidl_node *webidl,
- struct interface_map *interface_map);
+int duk_libdom_output(struct interface_map *interface_map);
#endif
diff --git a/src/interface-map.c b/src/interface-map.c
index 2ac1871..13d6106 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -378,20 +378,20 @@ constant_map_new(struct webidl_node *interface,
int interface_map_new(struct genbind_node *genbind,
struct webidl_node *webidl,
- struct interface_map **index_out)
+ struct interface_map **map_out)
{
int interfacec;
struct interface_map_entry *entries;
struct interface_map_entry *sorted_entries;
struct interface_map_entry *ecur;
struct webidl_node *node;
- struct interface_map *index;
+ struct interface_map *map;
interfacec = webidl_node_enumerate_type(webidl,
WEBIDL_NODE_TYPE_INTERFACE);
if (options->verbose) {
- printf("Indexing %d interfaces\n", interfacec);
+ printf("Maping %d interfaces\n", interfacec);
}
entries = calloc(interfacec, sizeof(struct interface_map_entry));
@@ -399,12 +399,12 @@ int interface_map_new(struct genbind_node *genbind,
return -1;
}
- /* for each interface populate an entry in the index */
+ /* for each interface populate an entry in the map */
ecur = entries;
node = webidl_node_find_type(webidl, NULL, WEBIDL_NODE_TYPE_INTERFACE);
while (node != NULL) {
- /* fill index entry */
+ /* fill map entry */
ecur->node = node;
/* name of interface */
@@ -461,11 +461,14 @@ int interface_map_new(struct genbind_node *genbind,
/* compute inheritance and refcounts on sorted map */
compute_inherit_refcount(sorted_entries, interfacec);
- index = malloc(sizeof(struct interface_map));
- index->entryc = interfacec;
- index->entries = sorted_entries;
+ map = malloc(sizeof(struct interface_map));
+ map->entryc = interfacec;
+ map->entries = sorted_entries;
+ map->webidl = webidl;
+ map->binding_node = genbind_node_find_type(genbind, NULL,
+ GENBIND_NODE_TYPE_BINDING);
- *index_out = index;
+ *map_out = map;
return 0;
}
diff --git a/src/interface-map.h b/src/interface-map.h
index 8ce6c01..e44380a 100644
--- a/src/interface-map.h
+++ b/src/interface-map.h
@@ -77,12 +77,21 @@ struct interface_map_entry {
/** WebIDL interface map */
struct interface_map {
int entryc; /**< count of interfaces */
- struct interface_map_entry *entries;
+ struct interface_map_entry *entries; /**< interface entries */
+
+ /** The AST node of the binding information */
+ struct genbind_node *binding_node;
+
+ /** Root AST node of the webIDL */
+ struct webidl_node *webidl;
};
+/**
+ * Create a new interface map
+ */
int interface_map_new(struct genbind_node *genbind,
struct webidl_node *webidl,
- struct interface_map **index_out);
+ struct interface_map **map_out);
int interface_map_dump(struct interface_map *map);
diff --git a/src/nsgenbind.c b/src/nsgenbind.c
index b3191ba..65feedd 100644
--- a/src/nsgenbind.c
+++ b/src/nsgenbind.c
@@ -207,7 +207,7 @@ int main(int argc, char **argv)
/* debug dump of web idl AST */
webidl_dump_ast(webidl_root);
- /* generate index of interfaces in idl sorted by inheritance */
+ /* generate map of WebIDL interfaces sorted by inheritance */
res = interface_map_new(genbind_root, webidl_root, &interface_map);
if (res != 0) {
return 5;
@@ -220,7 +220,7 @@ int main(int argc, char **argv)
/* generate binding */
switch (bindingtype) {
case BINDINGTYPE_DUK_LIBDOM:
- res = duk_libdom_output(genbind_root, webidl_root, interface_map);
+ res = duk_libdom_output(interface_map);
break;
default:
-----------------------------------------------------------------------
Summary of changes:
src/duk-libdom.c | 119 +++++++++++++++++++++++++++++++++++++++++++--------
src/duk-libdom.h | 4 +-
src/interface-map.c | 21 +++++----
src/interface-map.h | 13 +++++-
src/nsgenbind.c | 4 +-
5 files changed, 126 insertions(+), 35 deletions(-)
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index a883f7c..49f100a 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -968,12 +968,20 @@ output_interface_attributes(FILE* outf,
*/
static int output_tool_preface(FILE* outf)
{
- char *fpath;
+ fprintf(outf, "\n%s\n", NSGENBIND_PREAMBLE);
- fprintf(outf, "\n%s\n\n", NSGENBIND_PREAMBLE);
+ return 0;
+}
+
+/**
+ * generate preface block for nsgenbind
+ */
+static int output_tool_prologue(FILE* outf)
+{
+ char *fpath;
fpath = genb_fpath("private.h");
- fprintf(outf, "#include \"%s\"\n", fpath);
+ fprintf(outf, "\n#include \"%s\"\n", fpath);
free(fpath);
fpath = genb_fpath("prototype.h");
@@ -986,13 +994,11 @@ static int output_tool_preface(FILE* outf)
/**
* generate a source file to implement an interface using duk and libdom.
*/
-static int output_interface(struct genbind_node *genbind,
- struct interface_map *interface_map,
+static int output_interface(struct interface_map *interface_map,
struct interface_map_entry *interfacee)
{
FILE *ifacef;
int ifacenamelen;
- struct genbind_node *binding_node;
struct interface_map_entry *inherite;
int res = 0;
@@ -1014,11 +1020,10 @@ static int output_interface(struct genbind_node *genbind,
/* find parent interface entry */
inherite = interface_map_inherit_entry(interface_map, interfacee);
- binding_node = genbind_node_find_type(genbind, NULL,
- GENBIND_NODE_TYPE_BINDING);
-
/* binding preface */
- output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_PREFACE);
+ output_cdata(ifacef,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_PREFACE);
/* tool preface */
output_tool_preface(ifacef);
@@ -1027,7 +1032,11 @@ static int output_interface(struct genbind_node *genbind,
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PREFACE);
/* binding prologue */
- output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_PROLOGUE);
+ output_cdata(ifacef,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_PROLOGUE);
+
+ output_tool_prologue(ifacef);
/* class prologue */
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PROLOGUE);
@@ -1064,13 +1073,17 @@ static int output_interface(struct genbind_node *genbind,
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_EPILOGUE);
/* binding epilogue */
- output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_EPILOGUE);
+ output_cdata(ifacef,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_EPILOGUE);
/* class postface */
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_POSTFACE);
/* binding postface */
- output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_POSTFACE);
+ output_cdata(ifacef,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_POSTFACE);
op_error:
fclose(ifacef);
@@ -1093,6 +1106,18 @@ output_private_header(struct interface_map *interface_map)
return -1;
}
+ /* binding preface */
+ output_cdata(privf,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_PREFACE);
+
+ /* tool preface */
+ output_tool_preface(privf);
+
+ /* header guard */
+ fprintf(privf, "\n#ifndef duk_libdom_private_h\n");
+ fprintf(privf, "#define duk_libdom_private_h\n\n");
+
for (idx = 0; idx < interface_map->entryc; idx++) {
struct interface_map_entry *interfacee;
struct interface_map_entry *inherite;
@@ -1131,6 +1156,13 @@ output_private_header(struct interface_map *interface_map)
}
+ /* binding postface */
+ output_cdata(privf,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_POSTFACE);
+
+ fprintf(privf, "\n#endif\n");
+
fclose(privf);
return 0;
@@ -1151,6 +1183,18 @@ output_prototype_header(struct interface_map *interface_map)
return -1;
}
+ /* binding preface */
+ output_cdata(protof,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_PREFACE);
+
+ /* tool preface */
+ output_tool_preface(protof);
+
+ /* header guard */
+ fprintf(protof, "\n#ifndef duk_libdom_prototype_h\n");
+ fprintf(protof, "#define duk_libdom_prototype_h\n\n");
+
for (idx = 0; idx < interface_map->entryc; idx++) {
struct interface_map_entry *interfacee;
struct genbind_node *init_node;
@@ -1176,22 +1220,58 @@ output_prototype_header(struct interface_map *interface_map)
fprintf(protof, ";\n\n");
}
+ /* binding postface */
+ output_cdata(protof,
+ interface_map->binding_node,
+ GENBIND_NODE_TYPE_POSTFACE);
+
+ fprintf(protof, "\n#endif\n");
+
fclose(protof);
return 0;
}
-int duk_libdom_output(struct genbind_node *genbind,
- struct webidl_node *webidl,
- struct interface_map *interface_map)
+/**
+ * generate protottype header
+ */
+static int
+output_makefile(struct interface_map *interface_map)
+{
+ int idx;
+ FILE *makef;
+
+ /* open output file */
+ makef = genb_fopen("Makefile", "w");
+ if (makef == NULL) {
+ return -1;
+ }
+
+ fprintf(makef, "# duk libdom makefile fragment\n\n");
+
+ fprintf(makef, "NSGENBIND_SOURCES:=");
+ for (idx = 0; idx < interface_map->entryc; idx++) {
+ struct interface_map_entry *interfacee;
+
+ interfacee = interface_map->entries + idx;
+
+ fprintf(makef, "%s ", interfacee->filename);
+ }
+ fprintf(makef, "\nNSGENBIND_PREFIX:=%s\n", options->outdirname);
+
+ fclose(makef);
+
+ return 0;
+}
+
+int duk_libdom_output(struct interface_map *interface_map)
{
int idx;
int res = 0;
/* generate interfaces */
for (idx = 0; idx < interface_map->entryc; idx++) {
- res = output_interface(genbind,
- interface_map,
+ res = output_interface(interface_map,
interface_map->entries + idx);
if (res != 0) {
goto output_err;
@@ -1211,7 +1291,8 @@ int duk_libdom_output(struct genbind_node *genbind,
}
/* generate makefile fragment */
- /** \todo implement makefile generation */
+ res = output_makefile(interface_map);
+
output_err:
return res;
diff --git a/src/duk-libdom.h b/src/duk-libdom.h
index 8e86d74..e1dd2c4 100644
--- a/src/duk-libdom.h
+++ b/src/duk-libdom.h
@@ -9,8 +9,6 @@
#ifndef nsgenbind_duk_libdom_h
#define nsgenbind_duk_libdom_h
-int duk_libdom_output(struct genbind_node *genbind,
- struct webidl_node *webidl,
- struct interface_map *interface_map);
+int duk_libdom_output(struct interface_map *interface_map);
#endif
diff --git a/src/interface-map.c b/src/interface-map.c
index 2ac1871..13d6106 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -378,20 +378,20 @@ constant_map_new(struct webidl_node *interface,
int interface_map_new(struct genbind_node *genbind,
struct webidl_node *webidl,
- struct interface_map **index_out)
+ struct interface_map **map_out)
{
int interfacec;
struct interface_map_entry *entries;
struct interface_map_entry *sorted_entries;
struct interface_map_entry *ecur;
struct webidl_node *node;
- struct interface_map *index;
+ struct interface_map *map;
interfacec = webidl_node_enumerate_type(webidl,
WEBIDL_NODE_TYPE_INTERFACE);
if (options->verbose) {
- printf("Indexing %d interfaces\n", interfacec);
+ printf("Maping %d interfaces\n", interfacec);
}
entries = calloc(interfacec, sizeof(struct interface_map_entry));
@@ -399,12 +399,12 @@ int interface_map_new(struct genbind_node *genbind,
return -1;
}
- /* for each interface populate an entry in the index */
+ /* for each interface populate an entry in the map */
ecur = entries;
node = webidl_node_find_type(webidl, NULL, WEBIDL_NODE_TYPE_INTERFACE);
while (node != NULL) {
- /* fill index entry */
+ /* fill map entry */
ecur->node = node;
/* name of interface */
@@ -461,11 +461,14 @@ int interface_map_new(struct genbind_node *genbind,
/* compute inheritance and refcounts on sorted map */
compute_inherit_refcount(sorted_entries, interfacec);
- index = malloc(sizeof(struct interface_map));
- index->entryc = interfacec;
- index->entries = sorted_entries;
+ map = malloc(sizeof(struct interface_map));
+ map->entryc = interfacec;
+ map->entries = sorted_entries;
+ map->webidl = webidl;
+ map->binding_node = genbind_node_find_type(genbind, NULL,
+ GENBIND_NODE_TYPE_BINDING);
- *index_out = index;
+ *map_out = map;
return 0;
}
diff --git a/src/interface-map.h b/src/interface-map.h
index 8ce6c01..e44380a 100644
--- a/src/interface-map.h
+++ b/src/interface-map.h
@@ -77,12 +77,21 @@ struct interface_map_entry {
/** WebIDL interface map */
struct interface_map {
int entryc; /**< count of interfaces */
- struct interface_map_entry *entries;
+ struct interface_map_entry *entries; /**< interface entries */
+
+ /** The AST node of the binding information */
+ struct genbind_node *binding_node;
+
+ /** Root AST node of the webIDL */
+ struct webidl_node *webidl;
};
+/**
+ * Create a new interface map
+ */
int interface_map_new(struct genbind_node *genbind,
struct webidl_node *webidl,
- struct interface_map **index_out);
+ struct interface_map **map_out);
int interface_map_dump(struct interface_map *map);
diff --git a/src/nsgenbind.c b/src/nsgenbind.c
index b3191ba..65feedd 100644
--- a/src/nsgenbind.c
+++ b/src/nsgenbind.c
@@ -207,7 +207,7 @@ int main(int argc, char **argv)
/* debug dump of web idl AST */
webidl_dump_ast(webidl_root);
- /* generate index of interfaces in idl sorted by inheritance */
+ /* generate map of WebIDL interfaces sorted by inheritance */
res = interface_map_new(genbind_root, webidl_root, &interface_map);
if (res != 0) {
return 5;
@@ -220,7 +220,7 @@ int main(int argc, char **argv)
/* generate binding */
switch (bindingtype) {
case BINDINGTYPE_DUK_LIBDOM:
- res = duk_libdom_output(genbind_root, webidl_root, interface_map);
+ res = duk_libdom_output(interface_map);
break;
default:
--
NetSurf Generator for JavaScript bindings
8 years, 1 month
nsgenbind: branch vince/interfacemap updated. release/0.1.0-29-g4b723a4
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/nsgenbind.git/shortlog/4b723a410bc1a3355d4...
...commit http://git.netsurf-browser.org/nsgenbind.git/commit/4b723a410bc1a3355d401...
...tree http://git.netsurf-browser.org/nsgenbind.git/tree/4b723a410bc1a3355d401b9...
The branch, vince/interfacemap has been updated
via 4b723a410bc1a3355d401b95ac390f377b5d77b8 (commit)
via 1fcab4d37de137bbc346e6ed82d92ed97f2024cf (commit)
from 2976a0e461da9777b23851eb37e285cbf1b8d6b1 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/nsgenbind.git/commit/?id=4b723a410bc1a3355...
commit 4b723a410bc1a3355d401b95ac390f377b5d77b8
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Clean up code generation functions
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index 173d22f..a883f7c 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -34,6 +34,207 @@
" */"
/**
+ * Output code to create a private structure
+ *
+ */
+static int output_create_private(FILE* outf, char *class_name)
+{
+ fprintf(outf, "\t/* create private data and attach to instance */\n");
+ fprintf(outf, "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n",
+ class_name);
+ fprintf(outf, "\tif (priv == NULL) return 0;\n");
+ fprintf(outf, "\tduk_push_pointer(ctx, priv);\n");
+ fprintf(outf, "\tduk_put_prop_string(ctx, 0, PRIVATE_MAGIC)\n\n");
+
+ return 0;
+}
+
+/**
+ * generate code that gets a private pointer
+ */
+static int output_safe_get_private(FILE* outf, char *class_name, int idx)
+{
+ fprintf(outf, "\t%s_private_t *priv;\n", class_name);
+ fprintf(outf, "\tduk_get_prop_string(ctx, %d, PRIVATE_MAGIC);\n",idx);
+ fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
+ fprintf(outf, "\tduk_pop(ctx);\n");
+ fprintf(outf, "\tif (priv == NULL) return 0;\n\n");
+ return 0;
+}
+
+/**
+ * generate code that gets a prototype by name
+ */
+static int output_get_prototype(FILE* outf, const char *interface_name)
+{
+ char *proto_name;
+ int pnamelen;
+
+ /* duplicate the interface name in upper case */
+ pnamelen = strlen(interface_name) + 1; /* allow for null byte */
+ proto_name = malloc(pnamelen);
+ for ( ; pnamelen >= 0; pnamelen--) {
+ proto_name[pnamelen] = toupper(interface_name[pnamelen]);
+ }
+ fprintf(outf, "\t/* get prototype */\n");
+ fprintf(outf, "\tduk_get_global_string(ctx, PROTO_MAGIC);\n");
+ fprintf(outf, "\tduk_get_prop_string(ctx, -1, PROTO_NAME(%s));\n",
+ proto_name);
+ fprintf(outf, "\tduk_replace(ctx, -2);\n");
+
+ free(proto_name);
+
+ return 0;
+}
+
+/**
+ * generate code that sets a destructor in a prototype
+ */
+static int output_set_destructor(FILE* outf, char *class_name, int idx)
+{
+ fprintf(outf, "\t/* Set the destructor */\n");
+ fprintf(outf, "\tduk_dup(ctx, %d);\n", idx);
+ fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___destructor, 1);\n",
+ DLPFX, class_name);
+ fprintf(outf, "\tduk_set_finalizer(ctx, -2);\n");
+ fprintf(outf, "\tduk_pop(ctx);\n\n");
+
+ return 0;
+}
+
+/**
+ * generate code that sets a constructor in a prototype
+ */
+static int
+output_set_constructor(FILE* outf, char *class_name, int idx, int argc)
+{
+ fprintf(outf, "\t/* Set the constructor */\n");
+ fprintf(outf, "\tduk_dup(ctx, %d);\n", idx);
+ fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___constructor, %d);\n",
+ DLPFX, class_name, 1 + argc);
+ fprintf(outf, "\tduk_put_prop_string(ctx, -2, INIT_MAGIC);\n");
+ fprintf(outf, "\tduk_pop(ctx);\n\n");
+
+ return 0;
+}
+
+static int
+output_dump_stack(FILE* outf)
+{
+ if (options->dbglog) {
+ /* dump stack */
+ fprintf(outf, "\tduk_push_context_dump(ctx);\n");
+ fprintf(outf, "\tLOG(\"Stack: %%s\", duk_to_string(ctx, -1));\n");
+ fprintf(outf, "\tduk_pop(ctx);\n");
+ }
+ return 0;
+}
+
+/**
+ * generate code that adds a method in a prototype
+ */
+static int
+output_add_method(FILE* outf, char *class_name, char *method, int argc)
+{
+ fprintf(outf, "\t/* Add a method */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, %s);\n", method);
+ fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s, ",
+ DLPFX, class_name, method);
+ if (argc == -1) {
+ fprintf(outf, "DUK_VARARGS);\n");
+ } else {
+ fprintf(outf, "%d);\n", argc);
+ }
+ output_dump_stack(outf);
+ fprintf(outf, "\tduk_def_prop(ctx, -3,\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_VALUE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+/**
+ * Generate source to populate a read/write property on a prototype
+ */
+static int
+output_populate_rw_property(FILE* outf, const char *class_name, const char *property)
+{
+ fprintf(outf, "\t/* Add read/write property */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ DLPFX, class_name, property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_setter, 1);\n",
+ DLPFX, class_name, property);
+ fprintf(outf, "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_SETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+/**
+ * Generate source to populate a readonly property on a prototype
+ */
+static int
+output_populate_ro_property(FILE* outf, const char *class_name, const char *property)
+{
+ fprintf(outf, "\t/* Add readonly property */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ DLPFX, class_name, property);
+ fprintf(outf,
+ "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+/**
+ * Generate source to add a constant int value on a prototype
+ */
+static int
+output_prototype_constant_int(FILE *outf, const char *constant_name, int value)
+{
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", constant_name);
+ fprintf(outf, "\tduk_push_int(ctx, %d);\n", value);
+ fprintf(outf, "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+ return 0;
+}
+
+/**
+ * generate code that gets a private pointer for a method
+ */
+static int
+output_get_method_private(FILE* outf, char *class_name)
+{
+ fprintf(outf, "\t/* Get private data for method */\n");
+ fprintf(outf, "\t%s_private_t *priv = NULL;\n", class_name);
+ fprintf(outf, "\tduk_push_this(ctx);\n");
+ fprintf(outf, "\tduk_get_prop_string(ctx, -1, PRIVATE_MAGIC);\n");
+ fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
+ fprintf(outf, "\tduk_pop_2(ctx);\n");
+ fprintf(outf, "\tif (priv == NULL) return 0; /* can do? No can do. */\n\n");
+ return 0;
+}
+
+/**
* Generate a C class name for the interface.
*
* The IDL interface names are camelcase and not similar to libdom naming so it
@@ -119,35 +320,6 @@ output_cdata(FILE* outf,
}
/**
- * Output code to create a private structure
- *
- */
-static int output_duckky_create_private(FILE* outf, char *class_name)
-{
- fprintf(outf, "\t/* create private data and attach to instance */\n");
- fprintf(outf, "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n",
- class_name);
- fprintf(outf, "\tif (priv == NULL) return 0;\n");
- fprintf(outf, "\tduk_push_pointer(ctx, priv);\n");
- fprintf(outf, "\tduk_put_prop_string(ctx, 0, PRIVATE_MAGIC)\n\n");
-
- return 0;
-}
-
-/**
- * generate code that gets a private pointer
- */
-static int output_ducky_safe_get_private(FILE* outf, char *class_name, int idx)
-{
- fprintf(outf,
- "\t%s_private_t *priv = dukky_get_private(ctx, %d);\n",
- class_name, idx);
- fprintf(outf, "\tif (priv == NULL) return 0;\n\n");
- return 0;
-}
-
-
-/**
* generate the interface constructor
*/
static int
@@ -161,7 +333,7 @@ output_interface_constructor(FILE* outf, struct interface_map_entry *interfacee)
DLPFX, interfacee->class_name);
fprintf(outf,"{\n");
- output_duckky_create_private(outf, interfacee->class_name);
+ output_create_private(outf, interfacee->class_name);
/* generate call to initialisor */
fprintf(outf,
@@ -195,7 +367,7 @@ output_interface_destructor(FILE* outf, struct interface_map_entry *interfacee)
DLPFX, interfacee->class_name);
fprintf(outf,"{\n");
- output_ducky_safe_get_private(outf, interfacee->class_name, 0);
+ output_safe_get_private(outf, interfacee->class_name, 0);
/* generate call to finaliser */
fprintf(outf,
@@ -419,89 +591,6 @@ output_interface_fini(FILE* outf,
return 0;
}
-/**
- * generate code that gets a prototype by name
- */
-static int output_get_prototype(FILE* outf, const char *interface_name)
-{
- char *proto_name;
- int pnamelen;
-
- /* duplicate the interface name in upper case */
- pnamelen = strlen(interface_name) + 1; /* allow for null byte */
- proto_name = malloc(pnamelen);
- for ( ; pnamelen >= 0; pnamelen--) {
- proto_name[pnamelen] = toupper(interface_name[pnamelen]);
- }
- fprintf(outf, "\t/* get prototype */\n");
- fprintf(outf, "\tduk_get_global_string(ctx, PROTO_MAGIC);\n");
- fprintf(outf, "\tduk_get_prop_string(ctx, -1, PROTO_NAME(%s));\n",
- proto_name);
- fprintf(outf, "\tduk_replace(ctx, -2);\n");
-
- free(proto_name);
-
- return 0;
-}
-
-/**
- * generate code that sets a destructor in a prototype
- */
-static int output_set_destructor(FILE* outf, char *class_name, int idx)
-{
- fprintf(outf, "\t/* Set the destructor */\n");
- fprintf(outf, "\tduk_dup(ctx, %d);\n", idx);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___destructor, 1);\n",
- DLPFX, class_name);
- fprintf(outf, "\tduk_set_finalizer(ctx, -2);\n");
- fprintf(outf, "\tduk_pop(ctx);\n\n");
-
- return 0;
-}
-
-/**
- * generate code that sets a constructor in a prototype
- */
-static int
-output_set_constructor(FILE* outf, char *class_name, int idx, int argc)
-{
- fprintf(outf, "\t/* Set the constructor */\n");
- fprintf(outf, "\tduk_dup(ctx, %d);\n", idx);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___constructor, %d);\n",
- DLPFX, class_name, 1 + argc);
- fprintf(outf, "\tduk_put_prop_string(ctx, -2, INIT_MAGIC);\n");
- fprintf(outf, "\tduk_pop(ctx);\n\n");
-
- return 0;
-}
-
-/**
- * generate code that adds a method in a prototype
- */
-static int
-output_add_method(FILE* outf, char *class_name, char *method, int argc)
-{
- fprintf(outf, "\t/* Add a method */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, %s);\n", method);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s, ",
- DLPFX, class_name, method);
- if (argc == -1) {
- fprintf(outf, "DUK_VARARGS);\n");
-
- } else {
- fprintf(outf, "%d);\n", argc);
- }
- fprintf(outf, "\tDUKKY_DUMP_STACK(ctx);\n");
- fprintf(outf, "\tduk_def_prop(ctx, -3,\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_VALUE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
-
- return 0;
-}
/**
* count the number of arguments to an operation
@@ -554,7 +643,6 @@ output_prototype_method(FILE* outf,
output_add_method(outf, interfacee->class_name, op_name, op_argc);
return 0;
-
}
/**
@@ -600,47 +688,8 @@ output_prototype_methods(FILE *outf, struct interface_map_entry *interfacee)
}
return 0;
-
}
-static int
-output_populate_rw_property(FILE* outf, const char *class_name, const char *property)
-{
- fprintf(outf, "\t/* Add read/write property */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
- fprintf(outf,
- "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
- DLPFX, class_name, property);
- fprintf(outf,
- "\tduk_push_c_function(ctx, %s_%s_%s_setter, 1);\n",
- DLPFX, class_name, property);
- fprintf(outf, "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_SETTER |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
-
- return 0;
-}
-
-static int
-output_populate_ro_property(FILE* outf, const char *class_name, const char *property)
-{
- fprintf(outf, "\t/* Add readonly property */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
- fprintf(outf,
- "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
- DLPFX, class_name, property);
- fprintf(outf,
- "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
-
- return 0;
-}
static int
output_prototype_attribute(FILE *outf,
@@ -651,11 +700,10 @@ output_prototype_attribute(FILE *outf,
return output_populate_ro_property(outf,
interfacee->class_name,
attributee->name);
- } else {
- return output_populate_rw_property(outf,
- interfacee->class_name,
- attributee->name);
}
+ return output_populate_rw_property(outf,
+ interfacee->class_name,
+ attributee->name);
}
/**
@@ -665,14 +713,17 @@ static int
output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
{
int attrc;
+ int res = 0;
for (attrc = 0; attrc < interfacee->attributec; attrc++) {
- output_prototype_attribute(outf,
- interfacee,
- interfacee->attributev + attrc);
+ res = output_prototype_attribute(outf,interfacee,
+ interfacee->attributev + attrc);
+ if (res != 0) {
+ break;
+ }
}
- return 0;
+ return res;
}
/**
@@ -693,14 +744,8 @@ output_prototype_constant(FILE *outf,
NULL,
WEBIDL_NODE_TYPE_LITERAL_INT));
+ output_prototype_constant_int(outf, constante->name, *value);
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", constante->name);
- fprintf(outf, "\tduk_push_int(ctx, %d);\n", *value);
- fprintf(outf, "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
return 0;
}
@@ -711,12 +756,17 @@ static int
output_prototype_constants(FILE *outf, struct interface_map_entry *interfacee)
{
int attrc;
+ int res = 0;
for (attrc = 0; attrc < interfacee->constantc; attrc++) {
- output_prototype_constant(outf, interfacee->constantv + attrc);
+ res = output_prototype_constant(outf,
+ interfacee->constantv + attrc);
+ if (res != 0) {
+ break;
+ }
}
- return 0;
+ return res;
}
/**
@@ -766,21 +816,6 @@ output_interface_prototype(FILE* outf,
return 0;
}
-/**
- * generate code that gets a private pointer for a method
- */
-static int
-output_get_method_private(FILE* outf, char *class_name)
-{
- fprintf(outf, "\t/* Get private data for method */\n");
- fprintf(outf, "\t%s_private_t *priv = NULL;\n", class_name);
- fprintf(outf, "\tduk_push_this(ctx);\n");
- fprintf(outf, "\tduk_get_prop_string(ctx, -1, PRIVATE_MAGIC);\n");
- fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
- fprintf(outf, "\tduk_pop_2(ctx);\n");
- fprintf(outf, "\tif (priv == NULL) return 0; /* can do? No can do. */\n\n");
- return 0;
-}
/**
* generate a single class method for an interface operation
commitdiff http://git.netsurf-browser.org/nsgenbind.git/commit/?id=1fcab4d37de137bbc...
commit 1fcab4d37de137bbc346e6ed82d92ed97f2024cf
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Generate prototype header and include it from each class source
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index e277eec..173d22f 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -309,20 +309,12 @@ output_interface_inherit_init(FILE* outf,
}
static int
-output_interface_init(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_entry *inherite)
+output_interface_init_declaration(FILE* outf,
+ struct interface_map_entry *interfacee,
+ struct genbind_node *init_node)
{
- struct genbind_node *init_node;
struct genbind_node *param_node;
- int res;
- /* find the initialisor method on the class (if any) */
- init_node = genbind_node_find_method(interfacee->class,
- NULL,
- GENBIND_METHOD_TYPE_INIT);
-
- /* initialisor definition */
fprintf(outf,
"void %s_%s___init(duk_context *ctx, %s_private_t *priv",
DLPFX, interfacee->class_name, interfacee->class_name);
@@ -345,7 +337,28 @@ output_interface_init(FILE* outf,
param_node, GENBIND_NODE_TYPE_METHOD);
}
- fprintf(outf,")\n{\n");
+ fprintf(outf,")");
+
+ return 0;
+}
+
+static int
+output_interface_init(FILE* outf,
+ struct interface_map_entry *interfacee,
+ struct interface_map_entry *inherite)
+{
+ struct genbind_node *init_node;
+ int res;
+
+ /* find the initialisor method on the class (if any) */
+ init_node = genbind_node_find_method(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_INIT);
+
+ /* initialisor definition */
+ output_interface_init_declaration(outf, interfacee, init_node);
+
+ fprintf(outf,"\n{\n");
/* if this interface inherits ensure we call its initialisor */
res = output_interface_inherit_init(outf, interfacee, inherite);
@@ -915,12 +928,22 @@ output_interface_attributes(FILE* outf,
return 0;
}
-static int output_private_include(FILE* outf)
+/**
+ * generate preface block for nsgenbind
+ */
+static int output_tool_preface(FILE* outf)
{
char *fpath;
+
+ fprintf(outf, "\n%s\n\n", NSGENBIND_PREAMBLE);
+
fpath = genb_fpath("private.h");
+ fprintf(outf, "#include \"%s\"\n", fpath);
+ free(fpath);
- fprintf(outf, "\n#include \"%s\"\n", fpath);
+ fpath = genb_fpath("prototype.h");
+ fprintf(outf, "#include \"%s\"\n", fpath);
+ free(fpath);
return 0;
}
@@ -963,8 +986,7 @@ static int output_interface(struct genbind_node *genbind,
output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_PREFACE);
/* tool preface */
- fprintf(ifacef, "\n%s\n", NSGENBIND_PREAMBLE);
- output_private_include(ifacef);
+ output_tool_preface(ifacef);
/* class preface */
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PREFACE);
@@ -1021,7 +1043,9 @@ op_error:
return res;
}
-/** generate private header */
+/**
+ * generate private header
+ */
static int
output_private_header(struct interface_map *interface_map)
{
@@ -1072,12 +1096,56 @@ output_private_header(struct interface_map *interface_map)
}
-
fclose(privf);
return 0;
}
+/**
+ * generate protottype header
+ */
+static int
+output_prototype_header(struct interface_map *interface_map)
+{
+ int idx;
+ FILE *protof;
+
+ /* open output file */
+ protof = genb_fopen("prototype.h", "w");
+ if (protof == NULL) {
+ return -1;
+ }
+
+ for (idx = 0; idx < interface_map->entryc; idx++) {
+ struct interface_map_entry *interfacee;
+ struct genbind_node *init_node;
+
+ interfacee = interface_map->entries + idx;
+
+ /* prototype declaration */
+ fprintf(protof, "duk_ret_t %s_%s___proto(duk_context *ctx);\n",
+ DLPFX, interfacee->class_name);
+
+ /* finaliser declaration */
+ fprintf(protof,
+ "void %s_%s___fini(duk_context *ctx, %s_private_t *priv);\n",
+ DLPFX, interfacee->class_name, interfacee->class_name);
+
+ /* find the initialisor method on the class (if any) */
+ init_node = genbind_node_find_method(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_INIT);
+
+ /* initialisor definition */
+ output_interface_init_declaration(protof, interfacee, init_node);
+ fprintf(protof, ";\n\n");
+ }
+
+ fclose(protof);
+
+ return 0;
+}
+
int duk_libdom_output(struct genbind_node *genbind,
struct webidl_node *webidl,
struct interface_map *interface_map)
@@ -1101,9 +1169,11 @@ int duk_libdom_output(struct genbind_node *genbind,
goto output_err;
}
-
/* generate prototype header */
- /** \todo implement header */
+ res = output_prototype_header(interface_map);
+ if (res != 0) {
+ goto output_err;
+ }
/* generate makefile fragment */
/** \todo implement makefile generation */
-----------------------------------------------------------------------
Summary of changes:
src/duk-libdom.c | 517 ++++++++++++++++++++++++++++++++----------------------
1 file changed, 311 insertions(+), 206 deletions(-)
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index e277eec..a883f7c 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -34,6 +34,207 @@
" */"
/**
+ * Output code to create a private structure
+ *
+ */
+static int output_create_private(FILE* outf, char *class_name)
+{
+ fprintf(outf, "\t/* create private data and attach to instance */\n");
+ fprintf(outf, "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n",
+ class_name);
+ fprintf(outf, "\tif (priv == NULL) return 0;\n");
+ fprintf(outf, "\tduk_push_pointer(ctx, priv);\n");
+ fprintf(outf, "\tduk_put_prop_string(ctx, 0, PRIVATE_MAGIC)\n\n");
+
+ return 0;
+}
+
+/**
+ * generate code that gets a private pointer
+ */
+static int output_safe_get_private(FILE* outf, char *class_name, int idx)
+{
+ fprintf(outf, "\t%s_private_t *priv;\n", class_name);
+ fprintf(outf, "\tduk_get_prop_string(ctx, %d, PRIVATE_MAGIC);\n",idx);
+ fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
+ fprintf(outf, "\tduk_pop(ctx);\n");
+ fprintf(outf, "\tif (priv == NULL) return 0;\n\n");
+ return 0;
+}
+
+/**
+ * generate code that gets a prototype by name
+ */
+static int output_get_prototype(FILE* outf, const char *interface_name)
+{
+ char *proto_name;
+ int pnamelen;
+
+ /* duplicate the interface name in upper case */
+ pnamelen = strlen(interface_name) + 1; /* allow for null byte */
+ proto_name = malloc(pnamelen);
+ for ( ; pnamelen >= 0; pnamelen--) {
+ proto_name[pnamelen] = toupper(interface_name[pnamelen]);
+ }
+ fprintf(outf, "\t/* get prototype */\n");
+ fprintf(outf, "\tduk_get_global_string(ctx, PROTO_MAGIC);\n");
+ fprintf(outf, "\tduk_get_prop_string(ctx, -1, PROTO_NAME(%s));\n",
+ proto_name);
+ fprintf(outf, "\tduk_replace(ctx, -2);\n");
+
+ free(proto_name);
+
+ return 0;
+}
+
+/**
+ * generate code that sets a destructor in a prototype
+ */
+static int output_set_destructor(FILE* outf, char *class_name, int idx)
+{
+ fprintf(outf, "\t/* Set the destructor */\n");
+ fprintf(outf, "\tduk_dup(ctx, %d);\n", idx);
+ fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___destructor, 1);\n",
+ DLPFX, class_name);
+ fprintf(outf, "\tduk_set_finalizer(ctx, -2);\n");
+ fprintf(outf, "\tduk_pop(ctx);\n\n");
+
+ return 0;
+}
+
+/**
+ * generate code that sets a constructor in a prototype
+ */
+static int
+output_set_constructor(FILE* outf, char *class_name, int idx, int argc)
+{
+ fprintf(outf, "\t/* Set the constructor */\n");
+ fprintf(outf, "\tduk_dup(ctx, %d);\n", idx);
+ fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___constructor, %d);\n",
+ DLPFX, class_name, 1 + argc);
+ fprintf(outf, "\tduk_put_prop_string(ctx, -2, INIT_MAGIC);\n");
+ fprintf(outf, "\tduk_pop(ctx);\n\n");
+
+ return 0;
+}
+
+static int
+output_dump_stack(FILE* outf)
+{
+ if (options->dbglog) {
+ /* dump stack */
+ fprintf(outf, "\tduk_push_context_dump(ctx);\n");
+ fprintf(outf, "\tLOG(\"Stack: %%s\", duk_to_string(ctx, -1));\n");
+ fprintf(outf, "\tduk_pop(ctx);\n");
+ }
+ return 0;
+}
+
+/**
+ * generate code that adds a method in a prototype
+ */
+static int
+output_add_method(FILE* outf, char *class_name, char *method, int argc)
+{
+ fprintf(outf, "\t/* Add a method */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, %s);\n", method);
+ fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s, ",
+ DLPFX, class_name, method);
+ if (argc == -1) {
+ fprintf(outf, "DUK_VARARGS);\n");
+ } else {
+ fprintf(outf, "%d);\n", argc);
+ }
+ output_dump_stack(outf);
+ fprintf(outf, "\tduk_def_prop(ctx, -3,\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_VALUE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+/**
+ * Generate source to populate a read/write property on a prototype
+ */
+static int
+output_populate_rw_property(FILE* outf, const char *class_name, const char *property)
+{
+ fprintf(outf, "\t/* Add read/write property */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ DLPFX, class_name, property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_setter, 1);\n",
+ DLPFX, class_name, property);
+ fprintf(outf, "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_SETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+/**
+ * Generate source to populate a readonly property on a prototype
+ */
+static int
+output_populate_ro_property(FILE* outf, const char *class_name, const char *property)
+{
+ fprintf(outf, "\t/* Add readonly property */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ DLPFX, class_name, property);
+ fprintf(outf,
+ "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+/**
+ * Generate source to add a constant int value on a prototype
+ */
+static int
+output_prototype_constant_int(FILE *outf, const char *constant_name, int value)
+{
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", constant_name);
+ fprintf(outf, "\tduk_push_int(ctx, %d);\n", value);
+ fprintf(outf, "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+ return 0;
+}
+
+/**
+ * generate code that gets a private pointer for a method
+ */
+static int
+output_get_method_private(FILE* outf, char *class_name)
+{
+ fprintf(outf, "\t/* Get private data for method */\n");
+ fprintf(outf, "\t%s_private_t *priv = NULL;\n", class_name);
+ fprintf(outf, "\tduk_push_this(ctx);\n");
+ fprintf(outf, "\tduk_get_prop_string(ctx, -1, PRIVATE_MAGIC);\n");
+ fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
+ fprintf(outf, "\tduk_pop_2(ctx);\n");
+ fprintf(outf, "\tif (priv == NULL) return 0; /* can do? No can do. */\n\n");
+ return 0;
+}
+
+/**
* Generate a C class name for the interface.
*
* The IDL interface names are camelcase and not similar to libdom naming so it
@@ -119,35 +320,6 @@ output_cdata(FILE* outf,
}
/**
- * Output code to create a private structure
- *
- */
-static int output_duckky_create_private(FILE* outf, char *class_name)
-{
- fprintf(outf, "\t/* create private data and attach to instance */\n");
- fprintf(outf, "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n",
- class_name);
- fprintf(outf, "\tif (priv == NULL) return 0;\n");
- fprintf(outf, "\tduk_push_pointer(ctx, priv);\n");
- fprintf(outf, "\tduk_put_prop_string(ctx, 0, PRIVATE_MAGIC)\n\n");
-
- return 0;
-}
-
-/**
- * generate code that gets a private pointer
- */
-static int output_ducky_safe_get_private(FILE* outf, char *class_name, int idx)
-{
- fprintf(outf,
- "\t%s_private_t *priv = dukky_get_private(ctx, %d);\n",
- class_name, idx);
- fprintf(outf, "\tif (priv == NULL) return 0;\n\n");
- return 0;
-}
-
-
-/**
* generate the interface constructor
*/
static int
@@ -161,7 +333,7 @@ output_interface_constructor(FILE* outf, struct interface_map_entry *interfacee)
DLPFX, interfacee->class_name);
fprintf(outf,"{\n");
- output_duckky_create_private(outf, interfacee->class_name);
+ output_create_private(outf, interfacee->class_name);
/* generate call to initialisor */
fprintf(outf,
@@ -195,7 +367,7 @@ output_interface_destructor(FILE* outf, struct interface_map_entry *interfacee)
DLPFX, interfacee->class_name);
fprintf(outf,"{\n");
- output_ducky_safe_get_private(outf, interfacee->class_name, 0);
+ output_safe_get_private(outf, interfacee->class_name, 0);
/* generate call to finaliser */
fprintf(outf,
@@ -309,20 +481,12 @@ output_interface_inherit_init(FILE* outf,
}
static int
-output_interface_init(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_entry *inherite)
+output_interface_init_declaration(FILE* outf,
+ struct interface_map_entry *interfacee,
+ struct genbind_node *init_node)
{
- struct genbind_node *init_node;
struct genbind_node *param_node;
- int res;
-
- /* find the initialisor method on the class (if any) */
- init_node = genbind_node_find_method(interfacee->class,
- NULL,
- GENBIND_METHOD_TYPE_INIT);
- /* initialisor definition */
fprintf(outf,
"void %s_%s___init(duk_context *ctx, %s_private_t *priv",
DLPFX, interfacee->class_name, interfacee->class_name);
@@ -345,7 +509,28 @@ output_interface_init(FILE* outf,
param_node, GENBIND_NODE_TYPE_METHOD);
}
- fprintf(outf,")\n{\n");
+ fprintf(outf,")");
+
+ return 0;
+}
+
+static int
+output_interface_init(FILE* outf,
+ struct interface_map_entry *interfacee,
+ struct interface_map_entry *inherite)
+{
+ struct genbind_node *init_node;
+ int res;
+
+ /* find the initialisor method on the class (if any) */
+ init_node = genbind_node_find_method(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_INIT);
+
+ /* initialisor definition */
+ output_interface_init_declaration(outf, interfacee, init_node);
+
+ fprintf(outf,"\n{\n");
/* if this interface inherits ensure we call its initialisor */
res = output_interface_inherit_init(outf, interfacee, inherite);
@@ -406,89 +591,6 @@ output_interface_fini(FILE* outf,
return 0;
}
-/**
- * generate code that gets a prototype by name
- */
-static int output_get_prototype(FILE* outf, const char *interface_name)
-{
- char *proto_name;
- int pnamelen;
-
- /* duplicate the interface name in upper case */
- pnamelen = strlen(interface_name) + 1; /* allow for null byte */
- proto_name = malloc(pnamelen);
- for ( ; pnamelen >= 0; pnamelen--) {
- proto_name[pnamelen] = toupper(interface_name[pnamelen]);
- }
- fprintf(outf, "\t/* get prototype */\n");
- fprintf(outf, "\tduk_get_global_string(ctx, PROTO_MAGIC);\n");
- fprintf(outf, "\tduk_get_prop_string(ctx, -1, PROTO_NAME(%s));\n",
- proto_name);
- fprintf(outf, "\tduk_replace(ctx, -2);\n");
-
- free(proto_name);
-
- return 0;
-}
-
-/**
- * generate code that sets a destructor in a prototype
- */
-static int output_set_destructor(FILE* outf, char *class_name, int idx)
-{
- fprintf(outf, "\t/* Set the destructor */\n");
- fprintf(outf, "\tduk_dup(ctx, %d);\n", idx);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___destructor, 1);\n",
- DLPFX, class_name);
- fprintf(outf, "\tduk_set_finalizer(ctx, -2);\n");
- fprintf(outf, "\tduk_pop(ctx);\n\n");
-
- return 0;
-}
-
-/**
- * generate code that sets a constructor in a prototype
- */
-static int
-output_set_constructor(FILE* outf, char *class_name, int idx, int argc)
-{
- fprintf(outf, "\t/* Set the constructor */\n");
- fprintf(outf, "\tduk_dup(ctx, %d);\n", idx);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___constructor, %d);\n",
- DLPFX, class_name, 1 + argc);
- fprintf(outf, "\tduk_put_prop_string(ctx, -2, INIT_MAGIC);\n");
- fprintf(outf, "\tduk_pop(ctx);\n\n");
-
- return 0;
-}
-
-/**
- * generate code that adds a method in a prototype
- */
-static int
-output_add_method(FILE* outf, char *class_name, char *method, int argc)
-{
- fprintf(outf, "\t/* Add a method */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, %s);\n", method);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s, ",
- DLPFX, class_name, method);
- if (argc == -1) {
- fprintf(outf, "DUK_VARARGS);\n");
-
- } else {
- fprintf(outf, "%d);\n", argc);
- }
- fprintf(outf, "\tDUKKY_DUMP_STACK(ctx);\n");
- fprintf(outf, "\tduk_def_prop(ctx, -3,\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_VALUE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
-
- return 0;
-}
/**
* count the number of arguments to an operation
@@ -541,7 +643,6 @@ output_prototype_method(FILE* outf,
output_add_method(outf, interfacee->class_name, op_name, op_argc);
return 0;
-
}
/**
@@ -587,47 +688,8 @@ output_prototype_methods(FILE *outf, struct interface_map_entry *interfacee)
}
return 0;
-
}
-static int
-output_populate_rw_property(FILE* outf, const char *class_name, const char *property)
-{
- fprintf(outf, "\t/* Add read/write property */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
- fprintf(outf,
- "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
- DLPFX, class_name, property);
- fprintf(outf,
- "\tduk_push_c_function(ctx, %s_%s_%s_setter, 1);\n",
- DLPFX, class_name, property);
- fprintf(outf, "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_SETTER |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
-
- return 0;
-}
-
-static int
-output_populate_ro_property(FILE* outf, const char *class_name, const char *property)
-{
- fprintf(outf, "\t/* Add readonly property */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
- fprintf(outf,
- "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
- DLPFX, class_name, property);
- fprintf(outf,
- "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
-
- return 0;
-}
static int
output_prototype_attribute(FILE *outf,
@@ -638,11 +700,10 @@ output_prototype_attribute(FILE *outf,
return output_populate_ro_property(outf,
interfacee->class_name,
attributee->name);
- } else {
- return output_populate_rw_property(outf,
- interfacee->class_name,
- attributee->name);
}
+ return output_populate_rw_property(outf,
+ interfacee->class_name,
+ attributee->name);
}
/**
@@ -652,14 +713,17 @@ static int
output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
{
int attrc;
+ int res = 0;
for (attrc = 0; attrc < interfacee->attributec; attrc++) {
- output_prototype_attribute(outf,
- interfacee,
- interfacee->attributev + attrc);
+ res = output_prototype_attribute(outf,interfacee,
+ interfacee->attributev + attrc);
+ if (res != 0) {
+ break;
+ }
}
- return 0;
+ return res;
}
/**
@@ -680,14 +744,8 @@ output_prototype_constant(FILE *outf,
NULL,
WEBIDL_NODE_TYPE_LITERAL_INT));
+ output_prototype_constant_int(outf, constante->name, *value);
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", constante->name);
- fprintf(outf, "\tduk_push_int(ctx, %d);\n", *value);
- fprintf(outf, "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
return 0;
}
@@ -698,12 +756,17 @@ static int
output_prototype_constants(FILE *outf, struct interface_map_entry *interfacee)
{
int attrc;
+ int res = 0;
for (attrc = 0; attrc < interfacee->constantc; attrc++) {
- output_prototype_constant(outf, interfacee->constantv + attrc);
+ res = output_prototype_constant(outf,
+ interfacee->constantv + attrc);
+ if (res != 0) {
+ break;
+ }
}
- return 0;
+ return res;
}
/**
@@ -753,21 +816,6 @@ output_interface_prototype(FILE* outf,
return 0;
}
-/**
- * generate code that gets a private pointer for a method
- */
-static int
-output_get_method_private(FILE* outf, char *class_name)
-{
- fprintf(outf, "\t/* Get private data for method */\n");
- fprintf(outf, "\t%s_private_t *priv = NULL;\n", class_name);
- fprintf(outf, "\tduk_push_this(ctx);\n");
- fprintf(outf, "\tduk_get_prop_string(ctx, -1, PRIVATE_MAGIC);\n");
- fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
- fprintf(outf, "\tduk_pop_2(ctx);\n");
- fprintf(outf, "\tif (priv == NULL) return 0; /* can do? No can do. */\n\n");
- return 0;
-}
/**
* generate a single class method for an interface operation
@@ -915,12 +963,22 @@ output_interface_attributes(FILE* outf,
return 0;
}
-static int output_private_include(FILE* outf)
+/**
+ * generate preface block for nsgenbind
+ */
+static int output_tool_preface(FILE* outf)
{
char *fpath;
+
+ fprintf(outf, "\n%s\n\n", NSGENBIND_PREAMBLE);
+
fpath = genb_fpath("private.h");
+ fprintf(outf, "#include \"%s\"\n", fpath);
+ free(fpath);
- fprintf(outf, "\n#include \"%s\"\n", fpath);
+ fpath = genb_fpath("prototype.h");
+ fprintf(outf, "#include \"%s\"\n", fpath);
+ free(fpath);
return 0;
}
@@ -963,8 +1021,7 @@ static int output_interface(struct genbind_node *genbind,
output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_PREFACE);
/* tool preface */
- fprintf(ifacef, "\n%s\n", NSGENBIND_PREAMBLE);
- output_private_include(ifacef);
+ output_tool_preface(ifacef);
/* class preface */
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PREFACE);
@@ -1021,7 +1078,9 @@ op_error:
return res;
}
-/** generate private header */
+/**
+ * generate private header
+ */
static int
output_private_header(struct interface_map *interface_map)
{
@@ -1072,12 +1131,56 @@ output_private_header(struct interface_map *interface_map)
}
-
fclose(privf);
return 0;
}
+/**
+ * generate protottype header
+ */
+static int
+output_prototype_header(struct interface_map *interface_map)
+{
+ int idx;
+ FILE *protof;
+
+ /* open output file */
+ protof = genb_fopen("prototype.h", "w");
+ if (protof == NULL) {
+ return -1;
+ }
+
+ for (idx = 0; idx < interface_map->entryc; idx++) {
+ struct interface_map_entry *interfacee;
+ struct genbind_node *init_node;
+
+ interfacee = interface_map->entries + idx;
+
+ /* prototype declaration */
+ fprintf(protof, "duk_ret_t %s_%s___proto(duk_context *ctx);\n",
+ DLPFX, interfacee->class_name);
+
+ /* finaliser declaration */
+ fprintf(protof,
+ "void %s_%s___fini(duk_context *ctx, %s_private_t *priv);\n",
+ DLPFX, interfacee->class_name, interfacee->class_name);
+
+ /* find the initialisor method on the class (if any) */
+ init_node = genbind_node_find_method(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_INIT);
+
+ /* initialisor definition */
+ output_interface_init_declaration(protof, interfacee, init_node);
+ fprintf(protof, ";\n\n");
+ }
+
+ fclose(protof);
+
+ return 0;
+}
+
int duk_libdom_output(struct genbind_node *genbind,
struct webidl_node *webidl,
struct interface_map *interface_map)
@@ -1101,9 +1204,11 @@ int duk_libdom_output(struct genbind_node *genbind,
goto output_err;
}
-
/* generate prototype header */
- /** \todo implement header */
+ res = output_prototype_header(interface_map);
+ if (res != 0) {
+ goto output_err;
+ }
/* generate makefile fragment */
/** \todo implement makefile generation */
--
NetSurf Generator for JavaScript bindings
8 years, 2 months
nsgenbind: branch vince/interfacemap updated. release/0.1.0-27-g2976a0e
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/nsgenbind.git/shortlog/2976a0e461da9777b23...
...commit http://git.netsurf-browser.org/nsgenbind.git/commit/2976a0e461da9777b2385...
...tree http://git.netsurf-browser.org/nsgenbind.git/tree/2976a0e461da9777b23851e...
The branch, vince/interfacemap has been updated
via 2976a0e461da9777b23851eb37e285cbf1b8d6b1 (commit)
from 0c5f196017056b257c4c5a28338f90ada379310a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/nsgenbind.git/commit/?id=2976a0e461da9777b...
commit 2976a0e461da9777b23851eb37e285cbf1b8d6b1
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Add generation of private header and cause class files to include it
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index 00f1bbc..e277eec 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -124,7 +124,7 @@ output_cdata(FILE* outf,
*/
static int output_duckky_create_private(FILE* outf, char *class_name)
{
- fprintf(outf, "\t/* create private data and attach to instance */");
+ fprintf(outf, "\t/* create private data and attach to instance */\n");
fprintf(outf, "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n",
class_name);
fprintf(outf, "\tif (priv == NULL) return 0;\n");
@@ -660,7 +660,6 @@ output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
}
return 0;
-
}
/**
@@ -671,8 +670,7 @@ output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
*/
static int
output_prototype_constant(FILE *outf,
- struct interface_map_entry *interfacee,
- struct interface_map_constant_entry *constante)
+ struct interface_map_constant_entry *constante)
{
int *value;
@@ -702,13 +700,10 @@ output_prototype_constants(FILE *outf, struct interface_map_entry *interfacee)
int attrc;
for (attrc = 0; attrc < interfacee->constantc; attrc++) {
- output_prototype_constant(outf,
- interfacee,
- interfacee->constantv + attrc);
+ output_prototype_constant(outf, interfacee->constantv + attrc);
}
return 0;
-
}
/**
@@ -920,11 +915,20 @@ output_interface_attributes(FILE* outf,
return 0;
}
+static int output_private_include(FILE* outf)
+{
+ char *fpath;
+ fpath = genb_fpath("private.h");
+
+ fprintf(outf, "\n#include \"%s\"\n", fpath);
+
+ return 0;
+}
+
/**
* generate a source file to implement an interface using duk and libdom.
*/
static int output_interface(struct genbind_node *genbind,
- struct webidl_node *webidl,
struct interface_map *interface_map,
struct interface_map_entry *interfacee)
{
@@ -958,8 +962,9 @@ static int output_interface(struct genbind_node *genbind,
/* binding preface */
output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_PREFACE);
- /* nsgenbind preamble */
+ /* tool preface */
fprintf(ifacef, "\n%s\n", NSGENBIND_PREAMBLE);
+ output_private_include(ifacef);
/* class preface */
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PREFACE);
@@ -1016,6 +1021,63 @@ op_error:
return res;
}
+/** generate private header */
+static int
+output_private_header(struct interface_map *interface_map)
+{
+ int idx;
+ FILE *privf;
+
+ /* open output file */
+ privf = genb_fopen("private.h", "w");
+ if (privf == NULL) {
+ return -1;
+ }
+
+ for (idx = 0; idx < interface_map->entryc; idx++) {
+ struct interface_map_entry *interfacee;
+ struct interface_map_entry *inherite;
+ struct genbind_node *priv_node;
+
+ interfacee = interface_map->entries + idx;
+
+ /* find parent interface entry */
+ inherite = interface_map_inherit_entry(interface_map,
+ interfacee);
+
+ fprintf(privf, "typedef struct {\n");
+ if (inherite != NULL) {
+ fprintf(privf, "\t%s_private_t parent;\n",
+ inherite->class_name);
+ }
+
+ /* for each private variable on the class output it here. */
+ priv_node = genbind_node_find_type(
+ genbind_node_getnode(interfacee->class),
+ NULL,
+ GENBIND_NODE_TYPE_PRIVATE);
+ while (priv_node != NULL) {
+ fprintf(privf, "\t");
+ output_cdata(privf, priv_node, GENBIND_NODE_TYPE_TYPE);
+ output_cdata(privf, priv_node, GENBIND_NODE_TYPE_IDENT);
+ fprintf(privf, ";\n");
+
+ priv_node = genbind_node_find_type(
+ genbind_node_getnode(interfacee->class),
+ priv_node,
+ GENBIND_NODE_TYPE_PRIVATE);
+ }
+
+ fprintf(privf, "} %s_private_t;\n\n", interfacee->class_name);
+
+ }
+
+
+ fclose(privf);
+
+ return 0;
+}
+
int duk_libdom_output(struct genbind_node *genbind,
struct webidl_node *webidl,
struct interface_map *interface_map)
@@ -1025,18 +1087,27 @@ int duk_libdom_output(struct genbind_node *genbind,
/* generate interfaces */
for (idx = 0; idx < interface_map->entryc; idx++) {
- res = output_interface(genbind, webidl, interface_map,
- &interface_map->entries[idx]);
+ res = output_interface(genbind,
+ interface_map,
+ interface_map->entries + idx);
if (res != 0) {
- break;
+ goto output_err;
}
}
- /* generate header */
+ /* generate private header */
+ res = output_private_header(interface_map);
+ if (res != 0) {
+ goto output_err;
+ }
+
+
+ /* generate prototype header */
/** \todo implement header */
/* generate makefile fragment */
/** \todo implement makefile generation */
+output_err:
return res;
}
diff --git a/src/utils.c b/src/utils.c
index 7bab058..9e50a93 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -7,16 +7,27 @@
#include "options.h"
#include "utils.h"
-FILE *genb_fopen(const char *fname, const char *mode)
+/* exported function documented in utils.h */
+char *genb_fpath(const char *fname)
{
char *fpath;
int fpathl;
- FILE *filef;
fpathl = strlen(options->outdirname) + strlen(fname) + 2;
fpath = malloc(fpathl);
snprintf(fpath, fpathl, "%s/%s", options->outdirname, fname);
+ return fpath;
+}
+
+/* exported function documented in utils.h */
+FILE *genb_fopen(const char *fname, const char *mode)
+{
+ char *fpath;
+ FILE *filef;
+
+ fpath = genb_fpath(fname);
+
filef = fopen(fpath, mode);
if (filef == NULL) {
fprintf(stderr, "Error: unable to open file %s (%s)\n",
@@ -29,6 +40,7 @@ FILE *genb_fopen(const char *fname, const char *mode)
return filef;
}
+
#ifdef NEED_STRNDUP
char *strndup(const char *s, size_t n)
diff --git a/src/utils.h b/src/utils.h
index 98a4c6b..b37d755 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -9,6 +9,17 @@
#ifndef nsgenbind_utils_h
#define nsgenbind_utils_h
+/**
+ * get a pathname with the output prefix prepended
+ *
+ * \param fname leaf filename.
+ * \return full prefixed path to file caller must free
+ */
+char *genb_fpath(const char *fname);
+
+/**
+ * Open file allowing for output path prefix
+ */
FILE *genb_fopen(const char *fname, const char *mode);
#ifdef _WIN32
-----------------------------------------------------------------------
Summary of changes:
src/duk-libdom.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++--------
src/utils.c | 16 +++++++--
src/utils.h | 11 ++++++
3 files changed, 110 insertions(+), 16 deletions(-)
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index 00f1bbc..e277eec 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -124,7 +124,7 @@ output_cdata(FILE* outf,
*/
static int output_duckky_create_private(FILE* outf, char *class_name)
{
- fprintf(outf, "\t/* create private data and attach to instance */");
+ fprintf(outf, "\t/* create private data and attach to instance */\n");
fprintf(outf, "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n",
class_name);
fprintf(outf, "\tif (priv == NULL) return 0;\n");
@@ -660,7 +660,6 @@ output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
}
return 0;
-
}
/**
@@ -671,8 +670,7 @@ output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
*/
static int
output_prototype_constant(FILE *outf,
- struct interface_map_entry *interfacee,
- struct interface_map_constant_entry *constante)
+ struct interface_map_constant_entry *constante)
{
int *value;
@@ -702,13 +700,10 @@ output_prototype_constants(FILE *outf, struct interface_map_entry *interfacee)
int attrc;
for (attrc = 0; attrc < interfacee->constantc; attrc++) {
- output_prototype_constant(outf,
- interfacee,
- interfacee->constantv + attrc);
+ output_prototype_constant(outf, interfacee->constantv + attrc);
}
return 0;
-
}
/**
@@ -920,11 +915,20 @@ output_interface_attributes(FILE* outf,
return 0;
}
+static int output_private_include(FILE* outf)
+{
+ char *fpath;
+ fpath = genb_fpath("private.h");
+
+ fprintf(outf, "\n#include \"%s\"\n", fpath);
+
+ return 0;
+}
+
/**
* generate a source file to implement an interface using duk and libdom.
*/
static int output_interface(struct genbind_node *genbind,
- struct webidl_node *webidl,
struct interface_map *interface_map,
struct interface_map_entry *interfacee)
{
@@ -958,8 +962,9 @@ static int output_interface(struct genbind_node *genbind,
/* binding preface */
output_cdata(ifacef, binding_node, GENBIND_NODE_TYPE_PREFACE);
- /* nsgenbind preamble */
+ /* tool preface */
fprintf(ifacef, "\n%s\n", NSGENBIND_PREAMBLE);
+ output_private_include(ifacef);
/* class preface */
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PREFACE);
@@ -1016,6 +1021,63 @@ op_error:
return res;
}
+/** generate private header */
+static int
+output_private_header(struct interface_map *interface_map)
+{
+ int idx;
+ FILE *privf;
+
+ /* open output file */
+ privf = genb_fopen("private.h", "w");
+ if (privf == NULL) {
+ return -1;
+ }
+
+ for (idx = 0; idx < interface_map->entryc; idx++) {
+ struct interface_map_entry *interfacee;
+ struct interface_map_entry *inherite;
+ struct genbind_node *priv_node;
+
+ interfacee = interface_map->entries + idx;
+
+ /* find parent interface entry */
+ inherite = interface_map_inherit_entry(interface_map,
+ interfacee);
+
+ fprintf(privf, "typedef struct {\n");
+ if (inherite != NULL) {
+ fprintf(privf, "\t%s_private_t parent;\n",
+ inherite->class_name);
+ }
+
+ /* for each private variable on the class output it here. */
+ priv_node = genbind_node_find_type(
+ genbind_node_getnode(interfacee->class),
+ NULL,
+ GENBIND_NODE_TYPE_PRIVATE);
+ while (priv_node != NULL) {
+ fprintf(privf, "\t");
+ output_cdata(privf, priv_node, GENBIND_NODE_TYPE_TYPE);
+ output_cdata(privf, priv_node, GENBIND_NODE_TYPE_IDENT);
+ fprintf(privf, ";\n");
+
+ priv_node = genbind_node_find_type(
+ genbind_node_getnode(interfacee->class),
+ priv_node,
+ GENBIND_NODE_TYPE_PRIVATE);
+ }
+
+ fprintf(privf, "} %s_private_t;\n\n", interfacee->class_name);
+
+ }
+
+
+ fclose(privf);
+
+ return 0;
+}
+
int duk_libdom_output(struct genbind_node *genbind,
struct webidl_node *webidl,
struct interface_map *interface_map)
@@ -1025,18 +1087,27 @@ int duk_libdom_output(struct genbind_node *genbind,
/* generate interfaces */
for (idx = 0; idx < interface_map->entryc; idx++) {
- res = output_interface(genbind, webidl, interface_map,
- &interface_map->entries[idx]);
+ res = output_interface(genbind,
+ interface_map,
+ interface_map->entries + idx);
if (res != 0) {
- break;
+ goto output_err;
}
}
- /* generate header */
+ /* generate private header */
+ res = output_private_header(interface_map);
+ if (res != 0) {
+ goto output_err;
+ }
+
+
+ /* generate prototype header */
/** \todo implement header */
/* generate makefile fragment */
/** \todo implement makefile generation */
+output_err:
return res;
}
diff --git a/src/utils.c b/src/utils.c
index 7bab058..9e50a93 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -7,16 +7,27 @@
#include "options.h"
#include "utils.h"
-FILE *genb_fopen(const char *fname, const char *mode)
+/* exported function documented in utils.h */
+char *genb_fpath(const char *fname)
{
char *fpath;
int fpathl;
- FILE *filef;
fpathl = strlen(options->outdirname) + strlen(fname) + 2;
fpath = malloc(fpathl);
snprintf(fpath, fpathl, "%s/%s", options->outdirname, fname);
+ return fpath;
+}
+
+/* exported function documented in utils.h */
+FILE *genb_fopen(const char *fname, const char *mode)
+{
+ char *fpath;
+ FILE *filef;
+
+ fpath = genb_fpath(fname);
+
filef = fopen(fpath, mode);
if (filef == NULL) {
fprintf(stderr, "Error: unable to open file %s (%s)\n",
@@ -29,6 +40,7 @@ FILE *genb_fopen(const char *fname, const char *mode)
return filef;
}
+
#ifdef NEED_STRNDUP
char *strndup(const char *s, size_t n)
diff --git a/src/utils.h b/src/utils.h
index 98a4c6b..b37d755 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -9,6 +9,17 @@
#ifndef nsgenbind_utils_h
#define nsgenbind_utils_h
+/**
+ * get a pathname with the output prefix prepended
+ *
+ * \param fname leaf filename.
+ * \return full prefixed path to file caller must free
+ */
+char *genb_fpath(const char *fname);
+
+/**
+ * Open file allowing for output path prefix
+ */
FILE *genb_fopen(const char *fname, const char *mode);
#ifdef _WIN32
--
NetSurf Generator for JavaScript bindings
8 years, 2 months
libnslayout: branch master updated. 29c85a74a5fe16bfa6cba7d82e4748367e261a20
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libnslayout.git/shortlog/29c85a74a5fe16bfa...
...commit http://git.netsurf-browser.org/libnslayout.git/commit/29c85a74a5fe16bfa6c...
...tree http://git.netsurf-browser.org/libnslayout.git/tree/29c85a74a5fe16bfa6cba...
The branch, master has been updated
via 29c85a74a5fe16bfa6cba7d82e4748367e261a20 (commit)
from 13ee56ee329244d3a1bb6114ad3b0a8f14f392a9 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/libnslayout.git/commit/?id=29c85a74a5fe16b...
commit 29c85a74a5fe16bfa6cba7d82e4748367e261a20
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Add pkgconfig file.
diff --git a/libnslayout.pc.in b/libnslayout.pc.in
new file mode 100644
index 0000000..89b2cbd
--- /dev/null
+++ b/libnslayout.pc.in
@@ -0,0 +1,11 @@
+prefix=PREFIX
+exec_prefix=${prefix}
+libdir=${exec_prefix}/LIBDIR
+includedir=${prefix}/INCLUDEDIR
+
+Name: libnslayout
+Description: The NetSurf browser layout engine
+Version: VERSION
+Requires: libdom, libcss, libparserutils, libwapcaplet
+Libs: -L${libdir} -lnslayout
+Cflags: -I${includedir}
-----------------------------------------------------------------------
Summary of changes:
libnslayout.pc.in | 11 +++++++++++
1 file changed, 11 insertions(+)
create mode 100644 libnslayout.pc.in
diff --git a/libnslayout.pc.in b/libnslayout.pc.in
new file mode 100644
index 0000000..89b2cbd
--- /dev/null
+++ b/libnslayout.pc.in
@@ -0,0 +1,11 @@
+prefix=PREFIX
+exec_prefix=${prefix}
+libdir=${exec_prefix}/LIBDIR
+includedir=${prefix}/INCLUDEDIR
+
+Name: libnslayout
+Description: The NetSurf browser layout engine
+Version: VERSION
+Requires: libdom, libcss, libparserutils, libwapcaplet
+Libs: -L${libdir} -lnslayout
+Cflags: -I${includedir}
--
NetSurf Layout Engine
8 years, 2 months
libnslayout: branch master updated. 13ee56ee329244d3a1bb6114ad3b0a8f14f392a9
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libnslayout.git/shortlog/13ee56ee329244d3a...
...commit http://git.netsurf-browser.org/libnslayout.git/commit/13ee56ee329244d3a1b...
...tree http://git.netsurf-browser.org/libnslayout.git/tree/13ee56ee329244d3a1bb6...
The branch, master has been updated
via 13ee56ee329244d3a1bb6114ad3b0a8f14f392a9 (commit)
via 8e9c2de002d0592b8720f70826c287de36d1f959 (commit)
via 67a2b80df2804992ffd53365a54b014adb4f1c6e (commit)
from 9b0852e12713b44d4dd82ff67496c84a19af84b3 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/libnslayout.git/commit/?id=13ee56ee329244d...
commit 13ee56ee329244d3a1bb6114ad3b0a8f14f392a9
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Install correct header file.
diff --git a/Makefile b/Makefile
index 0a84269..eed0e81 100644
--- a/Makefile
+++ b/Makefile
@@ -64,6 +64,6 @@ endif
# Extra installation rules
I := /$(INCLUDEDIR)/lib$(COMPONENT)
-INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/lib$(COMPONENT)/libnslayout.h
+INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/lib$(COMPONENT)/nslayout.h
INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR)/pkgconfig:lib$(COMPONENT).pc.in
INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR):$(OUTPUT)
commitdiff http://git.netsurf-browser.org/libnslayout.git/commit/?id=8e9c2de002d0592...
commit 8e9c2de002d0592b8720f70826c287de36d1f959
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Move nslayout object tests.
diff --git a/test/Makefile b/test/Makefile
index 5703e79..24a036e 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,3 +1,3 @@
-DIR_TEST_ITEMS := testrunner:tests.c;assert-tests.c;basic-layout-tests.c
+DIR_TEST_ITEMS := testrunner:tests.c;assert-tests.c;nslayout_object-tests.c
include $(NSBUILD)/Makefile.subdir
diff --git a/test/basic-layout-tests.c b/test/basic-layout-tests.c
deleted file mode 100644
index 273cdf9..0000000
--- a/test/basic-layout-tests.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * This file is part of LibNSLayout's tests
- * Licensed under the ISC License, http://opensource.org/licenses/ISC
- * Copyright 2015 Michael Drake <tlsa(a)netsurf-browser.org>
- */
-
-#include <check.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "tests.h"
-
-#ifndef UNUSED
-#define UNUSED(x) (void)(x)
-#endif
-
-static nslayout_error nslayout_test_callback(
- nslayout_layout *layout,
- void *pw,
- nslayout_request *req)
-{
- UNUSED(req);
- UNUSED(layout);
- UNUSED(pw);
- return NSLAYOUT_OK;
-}
-
-START_TEST (test_nslayout_layout_create_ok)
-{
- nslayout_layout *layout = NULL;
- nslayout_error error;
- dom_exception dom_error;
- css_error css_err;
- dom_document *doc;
- css_select_ctx *css_ctx;
- css_media_type media = CSS_MEDIA_SCREEN;
-
- /* Create a DOM document */
- dom_error = dom_implementation_create_document(DOM_IMPLEMENTATION_HTML,
- NULL, NULL, NULL, NULL, NULL, &doc);
- ck_assert(dom_error == DOM_NO_ERR);
-
- /* Create a selection context (with no sheets added) */
- css_err = css_select_ctx_create(&css_ctx);
- ck_assert(css_err == CSS_OK);
-
- error = nslayout_layout_create(doc,
- css_ctx,
- &media,
- nslayout_test_callback,
- NULL,
- &layout);
- fail_unless(error == NSLAYOUT_OK,
- "Unable to create layout");
- fail_unless(layout != NULL,
- "Returned OK but str was still NULL");
-
- error = nslayout_layout_destroy(layout);
- fail_unless(error == NSLAYOUT_OK,
- "Unable to destroy layout");
-
- css_err = css_select_ctx_destroy(css_ctx);
- ck_assert(css_err == CSS_OK);
-
- dom_node_unref(doc);
-}
-END_TEST
-
-
-void nslayout_basic_layout_suite(SRunner *sr)
-{
- Suite *s = suite_create("libnslayout: basic layout tests");
- TCase *tc_layout_basic = tcase_create("Creation/Destruction");
-
- tcase_add_test(tc_layout_basic, test_nslayout_layout_create_ok);
- suite_add_tcase(s, tc_layout_basic);
-
- srunner_add_suite(sr, s);
-}
diff --git a/test/nslayout_object-tests.c b/test/nslayout_object-tests.c
new file mode 100644
index 0000000..a2f9afc
--- /dev/null
+++ b/test/nslayout_object-tests.c
@@ -0,0 +1,79 @@
+/*
+ * This file is part of LibNSLayout's tests
+ * Licensed under the ISC License, http://opensource.org/licenses/ISC
+ * Copyright 2015 Michael Drake <tlsa(a)netsurf-browser.org>
+ */
+
+#include <check.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tests.h"
+
+#ifndef UNUSED
+#define UNUSED(x) (void)(x)
+#endif
+
+static nslayout_error nslayout_test_callback(
+ nslayout_layout *layout,
+ void *pw,
+ nslayout_request *req)
+{
+ UNUSED(req);
+ UNUSED(layout);
+ UNUSED(pw);
+ return NSLAYOUT_OK;
+}
+
+START_TEST (test_nslayout_layout_create_ok)
+{
+ nslayout_layout *layout = NULL;
+ nslayout_error error;
+ dom_exception dom_error;
+ css_error css_err;
+ dom_document *doc;
+ css_select_ctx *css_ctx;
+ css_media_type media = CSS_MEDIA_SCREEN;
+
+ /* Create a DOM document */
+ dom_error = dom_implementation_create_document(DOM_IMPLEMENTATION_HTML,
+ NULL, NULL, NULL, NULL, NULL, &doc);
+ ck_assert(dom_error == DOM_NO_ERR);
+
+ /* Create a selection context (with no sheets added) */
+ css_err = css_select_ctx_create(&css_ctx);
+ ck_assert(css_err == CSS_OK);
+
+ error = nslayout_layout_create(doc,
+ css_ctx,
+ &media,
+ nslayout_test_callback,
+ NULL,
+ &layout);
+ fail_unless(error == NSLAYOUT_OK,
+ "Unable to create layout");
+ fail_unless(layout != NULL,
+ "Returned OK but str was still NULL");
+
+ error = nslayout_layout_destroy(layout);
+ fail_unless(error == NSLAYOUT_OK,
+ "Unable to destroy layout");
+
+ css_err = css_select_ctx_destroy(css_ctx);
+ ck_assert(css_err == CSS_OK);
+
+ dom_node_unref(doc);
+}
+END_TEST
+
+
+void nslayout_nslayout_object_suite(SRunner *sr)
+{
+ Suite *s = suite_create("libnslayout: nslayout object tests");
+ TCase *tc_layout_basic = tcase_create("Creation/Destruction");
+
+ tcase_add_test(tc_layout_basic, test_nslayout_layout_create_ok);
+ suite_add_tcase(s, tc_layout_basic);
+
+ srunner_add_suite(sr, s);
+}
diff --git a/test/tests.c b/test/tests.c
index a58e038..48fc68c 100644
--- a/test/tests.c
+++ b/test/tests.c
@@ -40,7 +40,7 @@ int main(int argc, char **argv)
#ifndef NDEBUG
nslayout_assert_suite(sr);
#endif
- nslayout_basic_layout_suite(sr);
+ nslayout_nslayout_object_suite(sr);
srunner_set_fork_status(sr, CK_FORK);
srunner_run_all(sr, CK_ENV);
diff --git a/test/tests.h b/test/tests.h
index 4f7795f..9f05d9c 100644
--- a/test/tests.h
+++ b/test/tests.h
@@ -14,6 +14,6 @@
#include <libnslayout/nslayout.h>
extern void nslayout_assert_suite(SRunner *);
-extern void nslayout_basic_layout_suite(SRunner *);
+extern void nslayout_nslayout_object_suite(SRunner *);
#endif
commitdiff http://git.netsurf-browser.org/libnslayout.git/commit/?id=67a2b80df280499...
commit 67a2b80df2804992ffd53365a54b014adb4f1c6e
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Client may pass NULL pointer for its pw.
diff --git a/src/layout.c b/src/layout.c
index 915475b..b5d74c2 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -29,7 +29,6 @@ nslayout_error nslayout_layout_create(
assert(css_ctx != NULL);
assert(media != NULL);
assert(cb != NULL);
- assert(pw != NULL);
l = calloc(1, sizeof(nslayout_layout));
if (l == NULL) {
diff --git a/test/basic-layout-tests.c b/test/basic-layout-tests.c
index cdaf5e2..273cdf9 100644
--- a/test/basic-layout-tests.c
+++ b/test/basic-layout-tests.c
@@ -14,8 +14,6 @@
#define UNUSED(x) (void)(x)
#endif
-int pw;
-
static nslayout_error nslayout_test_callback(
nslayout_layout *layout,
void *pw,
@@ -50,7 +48,7 @@ START_TEST (test_nslayout_layout_create_ok)
css_ctx,
&media,
nslayout_test_callback,
- &pw,
+ NULL,
&layout);
fail_unless(error == NSLAYOUT_OK,
"Unable to create layout");
-----------------------------------------------------------------------
Summary of changes:
Makefile | 2 +-
src/layout.c | 1 -
test/Makefile | 2 +-
test/{basic-layout-tests.c => nslayout_object-tests.c} | 8 +++-----
test/tests.c | 2 +-
test/tests.h | 2 +-
6 files changed, 7 insertions(+), 10 deletions(-)
rename test/{basic-layout-tests.c => nslayout_object-tests.c} (93%)
diff --git a/Makefile b/Makefile
index 0a84269..eed0e81 100644
--- a/Makefile
+++ b/Makefile
@@ -64,6 +64,6 @@ endif
# Extra installation rules
I := /$(INCLUDEDIR)/lib$(COMPONENT)
-INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/lib$(COMPONENT)/libnslayout.h
+INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/lib$(COMPONENT)/nslayout.h
INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR)/pkgconfig:lib$(COMPONENT).pc.in
INSTALL_ITEMS := $(INSTALL_ITEMS) /$(LIBDIR):$(OUTPUT)
diff --git a/src/layout.c b/src/layout.c
index 915475b..b5d74c2 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -29,7 +29,6 @@ nslayout_error nslayout_layout_create(
assert(css_ctx != NULL);
assert(media != NULL);
assert(cb != NULL);
- assert(pw != NULL);
l = calloc(1, sizeof(nslayout_layout));
if (l == NULL) {
diff --git a/test/Makefile b/test/Makefile
index 5703e79..24a036e 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,3 +1,3 @@
-DIR_TEST_ITEMS := testrunner:tests.c;assert-tests.c;basic-layout-tests.c
+DIR_TEST_ITEMS := testrunner:tests.c;assert-tests.c;nslayout_object-tests.c
include $(NSBUILD)/Makefile.subdir
diff --git a/test/basic-layout-tests.c b/test/nslayout_object-tests.c
similarity index 93%
rename from test/basic-layout-tests.c
rename to test/nslayout_object-tests.c
index cdaf5e2..a2f9afc 100644
--- a/test/basic-layout-tests.c
+++ b/test/nslayout_object-tests.c
@@ -14,8 +14,6 @@
#define UNUSED(x) (void)(x)
#endif
-int pw;
-
static nslayout_error nslayout_test_callback(
nslayout_layout *layout,
void *pw,
@@ -50,7 +48,7 @@ START_TEST (test_nslayout_layout_create_ok)
css_ctx,
&media,
nslayout_test_callback,
- &pw,
+ NULL,
&layout);
fail_unless(error == NSLAYOUT_OK,
"Unable to create layout");
@@ -69,9 +67,9 @@ START_TEST (test_nslayout_layout_create_ok)
END_TEST
-void nslayout_basic_layout_suite(SRunner *sr)
+void nslayout_nslayout_object_suite(SRunner *sr)
{
- Suite *s = suite_create("libnslayout: basic layout tests");
+ Suite *s = suite_create("libnslayout: nslayout object tests");
TCase *tc_layout_basic = tcase_create("Creation/Destruction");
tcase_add_test(tc_layout_basic, test_nslayout_layout_create_ok);
diff --git a/test/tests.c b/test/tests.c
index a58e038..48fc68c 100644
--- a/test/tests.c
+++ b/test/tests.c
@@ -40,7 +40,7 @@ int main(int argc, char **argv)
#ifndef NDEBUG
nslayout_assert_suite(sr);
#endif
- nslayout_basic_layout_suite(sr);
+ nslayout_nslayout_object_suite(sr);
srunner_set_fork_status(sr, CK_FORK);
srunner_run_all(sr, CK_ENV);
diff --git a/test/tests.h b/test/tests.h
index 4f7795f..9f05d9c 100644
--- a/test/tests.h
+++ b/test/tests.h
@@ -14,6 +14,6 @@
#include <libnslayout/nslayout.h>
extern void nslayout_assert_suite(SRunner *);
-extern void nslayout_basic_layout_suite(SRunner *);
+extern void nslayout_nslayout_object_suite(SRunner *);
#endif
--
NetSurf Layout Engine
8 years, 2 months
nsgenbind: branch vince/interfacemap updated. release/0.1.0-26-g0c5f196
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/nsgenbind.git/shortlog/0c5f196017056b257c4...
...commit http://git.netsurf-browser.org/nsgenbind.git/commit/0c5f196017056b257c4c5...
...tree http://git.netsurf-browser.org/nsgenbind.git/tree/0c5f196017056b257c4c5a2...
The branch, vince/interfacemap has been updated
via 0c5f196017056b257c4c5a28338f90ada379310a (commit)
from cb23f1f911523752db095781d0d5fa3e334f1aa5 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/nsgenbind.git/commit/?id=0c5f196017056b257...
commit 0c5f196017056b257c4c5a28338f90ada379310a
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Generate constant values on the class prototype
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index f7a1a5f..00f1bbc 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -664,6 +664,54 @@ output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
}
/**
+ * output constants on the prototype
+ *
+ * \todo This implementation assumes the constant is a literal int and should
+ * check the type node base value.
+ */
+static int
+output_prototype_constant(FILE *outf,
+ struct interface_map_entry *interfacee,
+ struct interface_map_constant_entry *constante)
+{
+ int *value;
+
+ value = webidl_node_getint(
+ webidl_node_find_type(
+ webidl_node_getnode(constante->node),
+ NULL,
+ WEBIDL_NODE_TYPE_LITERAL_INT));
+
+
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", constante->name);
+ fprintf(outf, "\tduk_push_int(ctx, %d);\n", *value);
+ fprintf(outf, "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+ return 0;
+}
+
+/**
+ * generate prototype constant definitions
+ */
+static int
+output_prototype_constants(FILE *outf, struct interface_map_entry *interfacee)
+{
+ int attrc;
+
+ for (attrc = 0; attrc < interfacee->constantc; attrc++) {
+ output_prototype_constant(outf,
+ interfacee,
+ interfacee->constantv + attrc);
+ }
+
+ return 0;
+
+}
+
+/**
* generate the interface prototype creator
*/
static int
@@ -691,6 +739,9 @@ output_interface_prototype(FILE* outf,
/* generate setting of attributes */
output_prototype_attributes(outf, interfacee);
+ /* generate setting of constants */
+ output_prototype_constants(outf, interfacee);
+
/* generate setting of destructor */
output_set_destructor(outf, interfacee->class_name, 0);
diff --git a/src/interface-map.c b/src/interface-map.c
index 6a77b6a..2ac1871 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -114,6 +114,8 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
dstinf[idx].operationv = srcinf[inf].operationv;
dstinf[idx].attributec = srcinf[inf].attributec;
dstinf[idx].attributev = srcinf[inf].attributev;
+ dstinf[idx].constantc = srcinf[inf].constantc;
+ dstinf[idx].constantv = srcinf[inf].constantv;
dstinf[idx].class = srcinf[inf].class;
/* reduce refcount on inherit index if !=-1 */
@@ -302,6 +304,78 @@ attribute_map_new(struct webidl_node *interface,
return 0;
}
+static int
+constant_map_new(struct webidl_node *interface,
+ int *constantc_out,
+ struct interface_map_constant_entry **constantv_out)
+{
+ struct webidl_node *list_node;
+ struct webidl_node *constant_node; /* constant node */
+ struct interface_map_constant_entry *cure; /* current entry */
+ struct interface_map_constant_entry *constantv;
+ int constantc;
+
+ /* enumerate constants */
+ constantc = enumerate_interface_type(interface,
+ WEBIDL_NODE_TYPE_CONST);
+
+ if (constantc < 1) {
+ *constantc_out = 0;
+ *constantv_out = NULL; /* no constants so empty map */
+ return 0;
+ }
+
+ *constantc_out = constantc;
+
+ constantv = calloc(constantc,
+ sizeof(struct interface_map_constant_entry));
+ if (constantv == NULL) {
+ return -1;
+ };
+ cure = constantv;
+
+ /* iterate each list node within the interface */
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ while (list_node != NULL) {
+ /* iterate through constants on list */
+ constant_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_CONST);
+
+ while (constant_node != NULL) {
+ cure->node = constant_node;
+
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(constant_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ cure++;
+
+ /* move to next constant */
+ constant_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ constant_node,
+ WEBIDL_NODE_TYPE_CONST);
+ }
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ *constantv_out = constantv; /* resulting constants map */
+
+ return 0;
+}
+
int interface_map_new(struct genbind_node *genbind,
struct webidl_node *webidl,
struct interface_map **index_out)
@@ -363,6 +437,11 @@ int interface_map_new(struct genbind_node *genbind,
&ecur->attributec,
&ecur->attributev);
+ /* enumerate and map the interface constants */
+ constant_map_new(node,
+ &ecur->constantc,
+ &ecur->constantv);
+
/* move to next interface */
node = webidl_node_find_type(webidl, node,
WEBIDL_NODE_TYPE_INTERFACE);
@@ -458,6 +537,19 @@ int interface_map_dump(struct interface_map *index)
}
}
}
+ if (ecur->constantc > 0) {
+ int idx;
+
+ fprintf(dumpf, " %d constants\n",
+ ecur->constantc);
+
+ for (idx = 0; idx < ecur->constantc; idx++) {
+ struct interface_map_constant_entry *cone;
+ cone = ecur->constantv + idx;
+ fprintf(dumpf, " %s\n",
+ cone->name);
+ }
+ }
ecur++;
}
diff --git a/src/interface-map.h b/src/interface-map.h
index 9d66dfb..8ce6c01 100644
--- a/src/interface-map.h
+++ b/src/interface-map.h
@@ -12,12 +12,14 @@
struct genbind_node;
struct webidl_node;
+/** map entry for operations on an interface */
struct interface_map_operation_entry {
const char *name; /** operation name */
struct webidl_node *node; /**< AST operation node */
struct genbind_node *method; /**< method from binding (if any) */
};
+/** map entry for attributes on an interface */
struct interface_map_attribute_entry {
const char *name; /** attribute name */
struct webidl_node *node; /**< AST attribute node */
@@ -26,6 +28,13 @@ struct interface_map_attribute_entry {
struct genbind_node *setter; /**< getter from binding (if any) */
};
+/** map entry for constants on an interface */
+struct interface_map_constant_entry {
+ const char *name; /** attribute name */
+ struct webidl_node *node; /**< AST constant node */
+};
+
+/** map entry for an interface */
struct interface_map_entry {
const char *name; /** interface name */
struct webidl_node *node; /**< AST interface node */
@@ -37,6 +46,9 @@ struct interface_map_entry {
int attributec; /**< number of attributes on interface */
struct interface_map_attribute_entry *attributev;
+ int constantc; /**< number of constants on interface */
+ struct interface_map_constant_entry *constantv;
+
int inherit_idx; /**< index into map of inherited interface or -1 for
* not in map
*/
@@ -62,6 +74,7 @@ struct interface_map_entry {
*/
};
+/** WebIDL interface map */
struct interface_map {
int entryc; /**< count of interfaces */
struct interface_map_entry *entries;
-----------------------------------------------------------------------
Summary of changes:
src/duk-libdom.c | 51 ++++++++++++++++++++++++++++
src/interface-map.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/interface-map.h | 13 ++++++++
3 files changed, 156 insertions(+)
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index f7a1a5f..00f1bbc 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -664,6 +664,54 @@ output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
}
/**
+ * output constants on the prototype
+ *
+ * \todo This implementation assumes the constant is a literal int and should
+ * check the type node base value.
+ */
+static int
+output_prototype_constant(FILE *outf,
+ struct interface_map_entry *interfacee,
+ struct interface_map_constant_entry *constante)
+{
+ int *value;
+
+ value = webidl_node_getint(
+ webidl_node_find_type(
+ webidl_node_getnode(constante->node),
+ NULL,
+ WEBIDL_NODE_TYPE_LITERAL_INT));
+
+
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", constante->name);
+ fprintf(outf, "\tduk_push_int(ctx, %d);\n", *value);
+ fprintf(outf, "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+ return 0;
+}
+
+/**
+ * generate prototype constant definitions
+ */
+static int
+output_prototype_constants(FILE *outf, struct interface_map_entry *interfacee)
+{
+ int attrc;
+
+ for (attrc = 0; attrc < interfacee->constantc; attrc++) {
+ output_prototype_constant(outf,
+ interfacee,
+ interfacee->constantv + attrc);
+ }
+
+ return 0;
+
+}
+
+/**
* generate the interface prototype creator
*/
static int
@@ -691,6 +739,9 @@ output_interface_prototype(FILE* outf,
/* generate setting of attributes */
output_prototype_attributes(outf, interfacee);
+ /* generate setting of constants */
+ output_prototype_constants(outf, interfacee);
+
/* generate setting of destructor */
output_set_destructor(outf, interfacee->class_name, 0);
diff --git a/src/interface-map.c b/src/interface-map.c
index 6a77b6a..2ac1871 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -114,6 +114,8 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
dstinf[idx].operationv = srcinf[inf].operationv;
dstinf[idx].attributec = srcinf[inf].attributec;
dstinf[idx].attributev = srcinf[inf].attributev;
+ dstinf[idx].constantc = srcinf[inf].constantc;
+ dstinf[idx].constantv = srcinf[inf].constantv;
dstinf[idx].class = srcinf[inf].class;
/* reduce refcount on inherit index if !=-1 */
@@ -302,6 +304,78 @@ attribute_map_new(struct webidl_node *interface,
return 0;
}
+static int
+constant_map_new(struct webidl_node *interface,
+ int *constantc_out,
+ struct interface_map_constant_entry **constantv_out)
+{
+ struct webidl_node *list_node;
+ struct webidl_node *constant_node; /* constant node */
+ struct interface_map_constant_entry *cure; /* current entry */
+ struct interface_map_constant_entry *constantv;
+ int constantc;
+
+ /* enumerate constants */
+ constantc = enumerate_interface_type(interface,
+ WEBIDL_NODE_TYPE_CONST);
+
+ if (constantc < 1) {
+ *constantc_out = 0;
+ *constantv_out = NULL; /* no constants so empty map */
+ return 0;
+ }
+
+ *constantc_out = constantc;
+
+ constantv = calloc(constantc,
+ sizeof(struct interface_map_constant_entry));
+ if (constantv == NULL) {
+ return -1;
+ };
+ cure = constantv;
+
+ /* iterate each list node within the interface */
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ while (list_node != NULL) {
+ /* iterate through constants on list */
+ constant_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_CONST);
+
+ while (constant_node != NULL) {
+ cure->node = constant_node;
+
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(constant_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ cure++;
+
+ /* move to next constant */
+ constant_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ constant_node,
+ WEBIDL_NODE_TYPE_CONST);
+ }
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ *constantv_out = constantv; /* resulting constants map */
+
+ return 0;
+}
+
int interface_map_new(struct genbind_node *genbind,
struct webidl_node *webidl,
struct interface_map **index_out)
@@ -363,6 +437,11 @@ int interface_map_new(struct genbind_node *genbind,
&ecur->attributec,
&ecur->attributev);
+ /* enumerate and map the interface constants */
+ constant_map_new(node,
+ &ecur->constantc,
+ &ecur->constantv);
+
/* move to next interface */
node = webidl_node_find_type(webidl, node,
WEBIDL_NODE_TYPE_INTERFACE);
@@ -458,6 +537,19 @@ int interface_map_dump(struct interface_map *index)
}
}
}
+ if (ecur->constantc > 0) {
+ int idx;
+
+ fprintf(dumpf, " %d constants\n",
+ ecur->constantc);
+
+ for (idx = 0; idx < ecur->constantc; idx++) {
+ struct interface_map_constant_entry *cone;
+ cone = ecur->constantv + idx;
+ fprintf(dumpf, " %s\n",
+ cone->name);
+ }
+ }
ecur++;
}
diff --git a/src/interface-map.h b/src/interface-map.h
index 9d66dfb..8ce6c01 100644
--- a/src/interface-map.h
+++ b/src/interface-map.h
@@ -12,12 +12,14 @@
struct genbind_node;
struct webidl_node;
+/** map entry for operations on an interface */
struct interface_map_operation_entry {
const char *name; /** operation name */
struct webidl_node *node; /**< AST operation node */
struct genbind_node *method; /**< method from binding (if any) */
};
+/** map entry for attributes on an interface */
struct interface_map_attribute_entry {
const char *name; /** attribute name */
struct webidl_node *node; /**< AST attribute node */
@@ -26,6 +28,13 @@ struct interface_map_attribute_entry {
struct genbind_node *setter; /**< getter from binding (if any) */
};
+/** map entry for constants on an interface */
+struct interface_map_constant_entry {
+ const char *name; /** attribute name */
+ struct webidl_node *node; /**< AST constant node */
+};
+
+/** map entry for an interface */
struct interface_map_entry {
const char *name; /** interface name */
struct webidl_node *node; /**< AST interface node */
@@ -37,6 +46,9 @@ struct interface_map_entry {
int attributec; /**< number of attributes on interface */
struct interface_map_attribute_entry *attributev;
+ int constantc; /**< number of constants on interface */
+ struct interface_map_constant_entry *constantv;
+
int inherit_idx; /**< index into map of inherited interface or -1 for
* not in map
*/
@@ -62,6 +74,7 @@ struct interface_map_entry {
*/
};
+/** WebIDL interface map */
struct interface_map {
int entryc; /**< count of interfaces */
struct interface_map_entry *entries;
--
NetSurf Generator for JavaScript bindings
8 years, 2 months
nsgenbind: branch vince/interfacemap updated. release/0.1.0-25-gcb23f1f
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/nsgenbind.git/shortlog/cb23f1f911523752db0...
...commit http://git.netsurf-browser.org/nsgenbind.git/commit/cb23f1f911523752db095...
...tree http://git.netsurf-browser.org/nsgenbind.git/tree/cb23f1f911523752db09578...
The branch, vince/interfacemap has been updated
via cb23f1f911523752db095781d0d5fa3e334f1aa5 (commit)
via 3f0d06f529fb5efaeb4edd89e61b3421951b8bf2 (commit)
from d67501b49bb147ac8784618906c024906ae25cbc (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/nsgenbind.git/commit/?id=cb23f1f911523752d...
commit cb23f1f911523752db095781d0d5fa3e334f1aa5
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Add property generation and add it to prototype construction
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index d1af70c..f7a1a5f 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -98,68 +98,6 @@ static char *gen_class_name(struct interface_map_entry *interfacee)
}
/**
- * find method by type on class
- */
-static struct genbind_node *
-find_class_method(struct genbind_node *node,
- struct genbind_node *prev,
- enum genbind_node_type nodetype)
-{
- struct genbind_node *res_node;
-
- res_node = genbind_node_find_type(
- genbind_node_getnode(node),
- prev, GENBIND_NODE_TYPE_METHOD);
- while (res_node != NULL) {
- struct genbind_node *type_node;
- enum genbind_node_type *type;
-
- type_node = genbind_node_find_type(
- genbind_node_getnode(res_node),
- NULL, GENBIND_NODE_TYPE_METHOD_TYPE);
-
- type = (enum genbind_node_type *)genbind_node_getint(type_node);
- if (*type == nodetype) {
- break;
- }
-
- res_node = genbind_node_find_type(
- genbind_node_getnode(node),
- res_node, GENBIND_NODE_TYPE_METHOD);
- }
-
- return res_node;
-}
-
-/**
- * find method by type on class with a specific ident
- */
-static struct genbind_node *
-find_class_method_ident(struct genbind_node *node,
- struct genbind_node *prev,
- enum genbind_node_type nodetype,
- char *ident)
-{
- struct genbind_node *res_node;
- char *method_ident;
-
- res_node = find_class_method(node, prev, nodetype);
- while (res_node != NULL) {
- method_ident = genbind_node_gettext(
- genbind_node_find_type(
- genbind_node_getnode(res_node),
- NULL,
- GENBIND_NODE_TYPE_IDENT));
- if ((method_ident != NULL) && strcmp(ident, method_ident) == 0) {
- break;
- }
-
- res_node = find_class_method(node, res_node, nodetype);
- }
- return res_node;
-}
-
-/**
* output character data of node of given type.
*
* used for pre/pro/epi/post sections
@@ -291,14 +229,14 @@ output_interface_inherit_init(FILE* outf,
}
/* find the initialisor method on the class (if any) */
- init_node = find_class_method(interfacee->class,
- NULL,
- GENBIND_METHOD_TYPE_INIT);
+ init_node = genbind_node_find_method(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_INIT);
- inh_init_node = find_class_method(inherite->class,
- NULL,
- GENBIND_METHOD_TYPE_INIT);
+ inh_init_node = genbind_node_find_method(inherite->class,
+ NULL,
+ GENBIND_METHOD_TYPE_INIT);
@@ -380,9 +318,9 @@ output_interface_init(FILE* outf,
int res;
/* find the initialisor method on the class (if any) */
- init_node = find_class_method(interfacee->class,
- NULL,
- GENBIND_METHOD_TYPE_INIT);
+ init_node = genbind_node_find_method(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_INIT);
/* initialisor definition */
fprintf(outf,
@@ -438,9 +376,9 @@ output_interface_fini(FILE* outf,
struct genbind_node *fini_node;
/* find the finaliser method on the class (if any) */
- fini_node = find_class_method(interfacee->class,
- NULL,
- GENBIND_METHOD_TYPE_FINI);
+ fini_node = genbind_node_find_method(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_FINI);
/* finaliser definition */
fprintf(outf,
@@ -530,7 +468,6 @@ output_set_constructor(FILE* outf, char *class_name, int idx, int argc)
static int
output_add_method(FILE* outf, char *class_name, char *method, int argc)
{
- //#define DUKKY_ADD_METHOD(klass,meth,nargs)
fprintf(outf, "\t/* Add a method */\n");
fprintf(outf, "\tduk_dup(ctx, 0);\n");
fprintf(outf, "\tduk_push_string(ctx, %s);\n", method);
@@ -653,6 +590,79 @@ output_prototype_methods(FILE *outf, struct interface_map_entry *interfacee)
}
+static int
+output_populate_rw_property(FILE* outf, const char *class_name, const char *property)
+{
+ fprintf(outf, "\t/* Add read/write property */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ DLPFX, class_name, property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_setter, 1);\n",
+ DLPFX, class_name, property);
+ fprintf(outf, "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_SETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+static int
+output_populate_ro_property(FILE* outf, const char *class_name, const char *property)
+{
+ fprintf(outf, "\t/* Add readonly property */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ DLPFX, class_name, property);
+ fprintf(outf,
+ "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+static int
+output_prototype_attribute(FILE *outf,
+ struct interface_map_entry *interfacee,
+ struct interface_map_attribute_entry *attributee)
+{
+ if (attributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY) {
+ return output_populate_ro_property(outf,
+ interfacee->class_name,
+ attributee->name);
+ } else {
+ return output_populate_rw_property(outf,
+ interfacee->class_name,
+ attributee->name);
+ }
+}
+
+/**
+ * generate prototype attribute definitions
+ */
+static int
+output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
+{
+ int attrc;
+
+ for (attrc = 0; attrc < interfacee->attributec; attrc++) {
+ output_prototype_attribute(outf,
+ interfacee,
+ interfacee->attributev + attrc);
+ }
+
+ return 0;
+
+}
+
/**
* generate the interface prototype creator
*/
@@ -678,6 +688,9 @@ output_interface_prototype(FILE* outf,
/* generate setting of methods */
output_prototype_methods(outf, interfacee);
+ /* generate setting of attributes */
+ output_prototype_attributes(outf, interfacee);
+
/* generate setting of destructor */
output_set_destructor(outf, interfacee->class_name, 0);
@@ -727,10 +740,10 @@ output_interface_operation(FILE* outf,
NULL,
WEBIDL_NODE_TYPE_IDENT));
- method_node = find_class_method_ident(interfacee->class,
- NULL,
- GENBIND_METHOD_TYPE_METHOD,
- op_name);
+ method_node = genbind_node_find_method_ident(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_METHOD,
+ op_name);
/* method definition */
fprintf(outf,
@@ -747,7 +760,6 @@ output_interface_operation(FILE* outf,
fprintf(outf, "}\n\n");
return 0;
-
}
/**
@@ -796,6 +808,68 @@ output_interface_operations(FILE* outf, struct interface_map_entry *interfacee)
}
/**
+ * Generate class property getter/setter for a single attribute
+ */
+static int
+output_interface_attribute(FILE* outf,
+ struct interface_map_entry *interfacee,
+ struct interface_map_attribute_entry *atributee)
+{
+ /* getter definition */
+ fprintf(outf,
+ "static duk_ret_t %s_%s_%s_getter(duk_context *ctx)\n",
+ DLPFX, interfacee->class_name, atributee->name);
+ fprintf(outf,"{\n");
+
+ output_get_method_private(outf, interfacee->class_name);
+
+ output_cdata(outf, atributee->getter, GENBIND_NODE_TYPE_CDATA);
+
+ fprintf(outf,"\treturn 0;\n");
+
+ fprintf(outf, "}\n\n");
+
+ /* readonly attributes have no setter */
+ if (atributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY) {
+ return 0;
+ }
+
+ /* setter definition */
+ fprintf(outf,
+ "static duk_ret_t %s_%s_%s_setter(duk_context *ctx)\n",
+ DLPFX, interfacee->class_name, atributee->name);
+ fprintf(outf,"{\n");
+
+ output_get_method_private(outf, interfacee->class_name);
+
+ output_cdata(outf, atributee->setter, GENBIND_NODE_TYPE_CDATA);
+
+ fprintf(outf,"\treturn 0;\n");
+
+ fprintf(outf, "}\n\n");
+
+ return 0;
+}
+
+/**
+ * generate class property getters and setters for each interface attribute
+ */
+static int
+output_interface_attributes(FILE* outf,
+ struct interface_map_entry *interfacee)
+{
+ int attrc;
+
+ for (attrc = 0; attrc < interfacee->attributec; attrc++) {
+ output_interface_attribute(outf,
+ interfacee,
+ interfacee->attributev + attrc);
+ }
+
+ return 0;
+}
+
+/**
* generate a source file to implement an interface using duk and libdom.
*/
static int output_interface(struct genbind_node *genbind,
@@ -866,6 +940,7 @@ static int output_interface(struct genbind_node *genbind,
output_interface_operations(ifacef, interfacee);
/* attributes */
+ output_interface_attributes(ifacef, interfacee);
/* prototype */
output_interface_prototype(ifacef, interfacee, inherite);
diff --git a/src/interface-map.c b/src/interface-map.c
index 44ece42..6a77b6a 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -110,8 +110,10 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
dstinf[idx].name = srcinf[inf].name;
dstinf[idx].node = srcinf[inf].node;
dstinf[idx].inherit_name = srcinf[inf].inherit_name;
- dstinf[idx].operations = srcinf[inf].operations;
- dstinf[idx].attributes = srcinf[inf].attributes;
+ dstinf[idx].operationc = srcinf[inf].operationc;
+ dstinf[idx].operationv = srcinf[inf].operationv;
+ dstinf[idx].attributec = srcinf[inf].attributec;
+ dstinf[idx].attributev = srcinf[inf].attributev;
dstinf[idx].class = srcinf[inf].class;
/* reduce refcount on inherit index if !=-1 */
@@ -126,6 +128,180 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
return dstinf;
}
+static int
+operation_map_new(struct webidl_node *interface,
+ struct genbind_node *class,
+ int *operationc_out,
+ struct interface_map_operation_entry **operationv_out)
+{
+ struct webidl_node *list_node;
+ struct webidl_node *op_node; /* attribute node */
+ struct interface_map_operation_entry *cure; /* current entry */
+ struct interface_map_operation_entry *operationv;
+ int operationc;
+
+ /* enumerate operationss */
+ operationc = enumerate_interface_type(interface,
+ WEBIDL_NODE_TYPE_OPERATION);
+ *operationc_out = operationc;
+
+ if (operationc < 1) {
+ *operationv_out = NULL; /* no operations so empty map */
+ return 0;
+ }
+
+ operationv = calloc(operationc,
+ sizeof(struct interface_map_operation_entry));
+ if (operationv == NULL) {
+ return -1;
+ };
+ cure = operationv;
+
+ /* iterate each list node within the interface */
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ while (list_node != NULL) {
+ /* iterate through operations on list */
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_OPERATION);
+
+ while (op_node != NULL) {
+ cure->node = op_node;
+
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(op_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ cure->method = genbind_node_find_method_ident(
+ class,
+ NULL,
+ GENBIND_METHOD_TYPE_METHOD,
+ cure->name);
+
+ cure++;
+
+ /* move to next operation */
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ op_node,
+ WEBIDL_NODE_TYPE_OPERATION);
+ }
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ *operationv_out = operationv; /* resulting operations map */
+
+ return 0;
+}
+
+static int
+attribute_map_new(struct webidl_node *interface,
+ struct genbind_node *class,
+ int *attributec_out,
+ struct interface_map_attribute_entry **attributev_out)
+{
+ struct webidl_node *list_node;
+ struct webidl_node *at_node; /* attribute node */
+ struct interface_map_attribute_entry *cure; /* current entry */
+ struct interface_map_attribute_entry *attributev;
+ int attributec;
+
+ /* enumerate attributes */
+ attributec = enumerate_interface_type(interface,
+ WEBIDL_NODE_TYPE_ATTRIBUTE);
+ *attributec_out = attributec;
+
+ if (attributec < 1) {
+ *attributev_out = NULL; /* no attributes so empty map */
+ return 0;
+ }
+
+ attributev = calloc(attributec,
+ sizeof(struct interface_map_attribute_entry));
+ if (attributev == NULL) {
+ return -1;
+ };
+ cure = attributev;
+
+ /* iterate each list node within the interface */
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ while (list_node != NULL) {
+ /* iterate through attributes on list */
+ at_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_ATTRIBUTE);
+
+ while (at_node != NULL) {
+ enum webidl_type_modifier *modifier;
+
+ cure->node = at_node;
+
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(at_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ cure->getter = genbind_node_find_method_ident(
+ class,
+ NULL,
+ GENBIND_METHOD_TYPE_GETTER,
+ cure->name);
+
+ /* check fo readonly attributes */
+ modifier = (enum webidl_type_modifier *)webidl_node_getint(
+ webidl_node_find_type(
+ webidl_node_getnode(at_node),
+ NULL,
+ WEBIDL_NODE_TYPE_MODIFIER));
+ if ((modifier != NULL) &&
+ (*modifier == WEBIDL_TYPE_MODIFIER_READONLY)) {
+ cure->modifier = WEBIDL_TYPE_MODIFIER_READONLY;
+ } else {
+ cure->modifier = WEBIDL_TYPE_MODIFIER_NONE;
+ cure->setter = genbind_node_find_method_ident(
+ class,
+ NULL,
+ GENBIND_METHOD_TYPE_SETTER,
+ cure->name);
+ }
+
+ cure++;
+
+ /* move to next attribute */
+ at_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ at_node,
+ WEBIDL_NODE_TYPE_ATTRIBUTE);
+ }
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ *attributev_out = attributev; /* resulting attributes map */
+
+ return 0;
+}
+
int interface_map_new(struct genbind_node *genbind,
struct webidl_node *webidl,
struct interface_map **index_out)
@@ -162,7 +338,7 @@ int interface_map_new(struct genbind_node *genbind,
webidl_node_find_type(
webidl_node_getnode(node),
NULL,
- GENBIND_NODE_TYPE_IDENT));
+ WEBIDL_NODE_TYPE_IDENT));
/* name of the inherited interface (if any) */
ecur->inherit_name = webidl_node_gettext(
@@ -171,20 +347,22 @@ int interface_map_new(struct genbind_node *genbind,
NULL,
WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE));
-
- /* enumerate the number of operations */
- ecur->operations = enumerate_interface_type(node,
- WEBIDL_NODE_TYPE_OPERATION);
-
- /* enumerate the number of attributes */
- ecur->attributes = enumerate_interface_type(node,
- WEBIDL_NODE_TYPE_ATTRIBUTE);
-
-
/* matching class from binding */
ecur->class = genbind_node_find_type_ident(genbind,
NULL, GENBIND_NODE_TYPE_CLASS, ecur->name);
+ /* enumerate and map the interface operations */
+ operation_map_new(node,
+ ecur->class,
+ &ecur->operationc,
+ &ecur->operationv);
+
+ /* enumerate and map the interface attributes */
+ attribute_map_new(node,
+ ecur->class,
+ &ecur->attributec,
+ &ecur->attributev);
+
/* move to next interface */
node = webidl_node_find_type(webidl, node,
WEBIDL_NODE_TYPE_INTERFACE);
@@ -218,27 +396,68 @@ int interface_map_dump(struct interface_map *index)
FILE *dumpf;
int eidx;
struct interface_map_entry *ecur;
- const char *inherit_name;
/* only dump AST to file if required */
if (!options->debug) {
return 0;
}
- dumpf = genb_fopen("interface-index", "w");
+ dumpf = genb_fopen("interface-map", "w");
if (dumpf == NULL) {
return 2;
}
ecur = index->entries;
for (eidx = 0; eidx < index->entryc; eidx++) {
- inherit_name = ecur->inherit_name;
- if (inherit_name == NULL) {
- inherit_name = "";
- }
- fprintf(dumpf, "%d %s %s i:%d a:%d %p\n", eidx, ecur->name,
- inherit_name, ecur->operations, ecur->attributes,
- ecur->class);
+ fprintf(dumpf, "%d %s\n", eidx, ecur->name);
+ if (ecur->inherit_name != NULL) {
+ fprintf(dumpf, " inherit:%s\n", ecur->inherit_name);
+ }
+ if (ecur->class != NULL) {
+ fprintf(dumpf, " class:%p\n", ecur->class);
+ }
+ if (ecur->operationc > 0) {
+ int opc = ecur->operationc;
+ struct interface_map_operation_entry *ope;
+
+ fprintf(dumpf, " %d operations\n",
+ ecur->operationc);
+
+ ope = ecur->operationv;
+ while (ope != NULL) {
+ fprintf(dumpf, " %s %p\n",
+ ope->name, ope->method);
+ ope++;
+ opc--;
+ if (opc == 0) {
+ break;
+ }
+ }
+
+ }
+ if (ecur->attributec > 0) {
+ int attrc = ecur->attributec;
+ struct interface_map_attribute_entry *attre;
+
+ fprintf(dumpf, " %d attributes\n", attrc);
+
+ attre = ecur->attributev;
+ while (attre != NULL) {
+ fprintf(dumpf, " %s %p",
+ attre->name,
+ attre->getter);
+ if (attre->modifier == WEBIDL_TYPE_MODIFIER_NONE) {
+ fprintf(dumpf, " %p\n", attre->setter);
+ } else {
+ fprintf(dumpf, "\n");
+ }
+ attre++;
+ attrc--;
+ if (attrc == 0) {
+ break;
+ }
+ }
+ }
ecur++;
}
@@ -269,7 +488,8 @@ int interface_map_dumpdot(struct interface_map *index)
for (eidx = 0; eidx < index->entryc; eidx++) {
if (ecur->class != NULL) {
/* interfaces bound to a class are shown in blue */
- fprintf(dumpf, "%04d [label=\"%s\" fontcolor=\"blue\"];\n", eidx, ecur->name);
+ fprintf(dumpf, "%04d [label=\"%s\" fontcolor=\"blue\"];\n",
+ eidx, ecur->name);
} else {
fprintf(dumpf, "%04d [label=\"%s\"];\n", eidx, ecur->name);
}
diff --git a/src/interface-map.h b/src/interface-map.h
index 7373580..9d66dfb 100644
--- a/src/interface-map.h
+++ b/src/interface-map.h
@@ -12,12 +12,31 @@
struct genbind_node;
struct webidl_node;
+struct interface_map_operation_entry {
+ const char *name; /** operation name */
+ struct webidl_node *node; /**< AST operation node */
+ struct genbind_node *method; /**< method from binding (if any) */
+};
+
+struct interface_map_attribute_entry {
+ const char *name; /** attribute name */
+ struct webidl_node *node; /**< AST attribute node */
+ enum webidl_type_modifier modifier;
+ struct genbind_node *getter; /**< getter from binding (if any) */
+ struct genbind_node *setter; /**< getter from binding (if any) */
+};
+
struct interface_map_entry {
const char *name; /** interface name */
struct webidl_node *node; /**< AST interface node */
const char *inherit_name; /**< Name of interface inhertited from */
- int operations; /**< number of operations on interface */
- int attributes; /**< number of attributes on interface */
+
+ int operationc; /**< number of operations on interface */
+ struct interface_map_operation_entry *operationv;
+
+ int attributec; /**< number of attributes on interface */
+ struct interface_map_attribute_entry *attributev;
+
int inherit_idx; /**< index into map of inherited interface or -1 for
* not in map
*/
diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c
index c1acee1..28326aa 100644
--- a/src/nsgenbind-ast.c
+++ b/src/nsgenbind-ast.c
@@ -288,6 +288,69 @@ genbind_node_find_type_type(struct genbind_node *node,
return found_node;
}
+
+/* exported interface documented in nsgenbind-ast.h */
+struct genbind_node *
+genbind_node_find_method(struct genbind_node *node,
+ struct genbind_node *prev,
+ enum genbind_method_type methodtype)
+{
+ struct genbind_node *res_node;
+
+ res_node = genbind_node_find_type(
+ genbind_node_getnode(node),
+ prev, GENBIND_NODE_TYPE_METHOD);
+ while (res_node != NULL) {
+ struct genbind_node *type_node;
+ enum genbind_method_type *type;
+
+ type_node = genbind_node_find_type(
+ genbind_node_getnode(res_node),
+ NULL, GENBIND_NODE_TYPE_METHOD_TYPE);
+
+ type = (enum genbind_method_type *)genbind_node_getint(type_node);
+ if (*type == methodtype) {
+ break;
+ }
+
+ res_node = genbind_node_find_type(
+ genbind_node_getnode(node),
+ res_node, GENBIND_NODE_TYPE_METHOD);
+ }
+
+ return res_node;
+}
+
+
+/* exported interface documented in nsgenbind-ast.h */
+struct genbind_node *
+genbind_node_find_method_ident(struct genbind_node *node,
+ struct genbind_node *prev,
+ enum genbind_method_type nodetype,
+ const char *ident)
+{
+ struct genbind_node *res_node;
+ char *method_ident;
+
+ res_node = genbind_node_find_method(node, prev, nodetype);
+ while (res_node != NULL) {
+ method_ident = genbind_node_gettext(
+ genbind_node_find_type(
+ genbind_node_getnode(res_node),
+ NULL,
+ GENBIND_NODE_TYPE_IDENT));
+ if ((method_ident != NULL) &&
+ strcmp(ident, method_ident) == 0) {
+ break;
+ }
+
+ res_node = genbind_node_find_method(node, res_node, nodetype);
+ }
+ return res_node;
+}
+
+
+/* exported interface documented in nsgenbind-ast.h */
int genbind_cmp_node_type(struct genbind_node *node, void *ctx)
{
if (node->type == (enum genbind_node_type)ctx)
diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h
index 9c564b9..0b0fcfd 100644
--- a/src/nsgenbind-ast.h
+++ b/src/nsgenbind-ast.h
@@ -101,7 +101,8 @@ genbind_node_find(struct genbind_node *node,
genbind_callback_t *cb,
void *ctx);
-/** Depth first left hand search returning nodes of the specified type
+/**
+ * Depth first left hand search returning nodes of the specified type
*
* @param node The node to start the search from
* @param prev The node at which to stop the search, either NULL to
@@ -115,7 +116,8 @@ genbind_node_find_type(struct genbind_node *node,
struct genbind_node *prev,
enum genbind_node_type nodetype);
-/** count how many nodes of a specified type.
+/**
+ * count how many nodes of a specified type.
*
* Enumerate how many nodes of the specified type there are by
* performing a depth first search for nodes of the given type and
@@ -129,7 +131,9 @@ int
genbind_node_enumerate_type(struct genbind_node *node,
enum genbind_node_type type);
-/** Depth first left hand search returning nodes of the specified type
+
+/**
+ * Depth first left hand search returning nodes of the specified type
* with an ident child node with matching text
*
* @param node The node to start the search from
@@ -145,7 +149,9 @@ genbind_node_find_type_ident(struct genbind_node *node,
enum genbind_node_type nodetype,
const char *ident);
-/** Returning node of the specified type with a GENBIND_NODE_TYPE_TYPE
+
+/**
+ * Returning node of the specified type with a GENBIND_NODE_TYPE_TYPE
* subnode with matching text.
*
* This is a conveniance wrapper around nested calls to
@@ -167,7 +173,43 @@ genbind_node_find_type_type(struct genbind_node *node,
enum genbind_node_type nodetype,
const char *type_text);
-/** Iterate all nodes of a certian type from a node with a callback.
+
+/**
+ * Find a method node of a given method type
+ *
+ * \param node A node of type GENBIND_NODE_TYPE_CLASS to search for methods.
+ * \param prev The node at which to stop the search, either NULL to
+ * search the full tree depth (initial search) or the result
+ * of a previous search to continue.
+ * \param methodtype The type of method to find.
+ * \return A node of type GENBIND_NODE_TYPE_METHOD on success or NULL on faliure
+ */
+struct genbind_node *
+genbind_node_find_method(struct genbind_node *node,
+ struct genbind_node *prev,
+ enum genbind_method_type methodtype);
+
+
+/**
+ * Find a method node of a given method type and identifier
+ *
+ * \param node A node of type GENBIND_NODE_TYPE_CLASS to search for methods.
+ * \param prev The node at which to stop the search, either NULL to
+ * search the full tree depth (initial search) or the result
+ * of a previous search to continue.
+ * \param methodtype The type of method to find.
+ * \param ident The identifier to search for
+ * \return A node of type GENBIND_NODE_TYPE_METHOD on success or NULL on faliure
+ */
+struct genbind_node *
+genbind_node_find_method_ident(struct genbind_node *node,
+ struct genbind_node *prev,
+ enum genbind_method_type methodtype,
+ const char *ident);
+
+
+/**
+ * Iterate all nodes of a certian type from a node with a callback.
*
* Depth first search for nodes of the given type calling the callback
* with context.
diff --git a/src/webidl-ast.c b/src/webidl-ast.c
index 6c24c41..75f969b 100644
--- a/src/webidl-ast.c
+++ b/src/webidl-ast.c
@@ -277,7 +277,7 @@ char *webidl_node_gettext(struct webidl_node *node)
}
/* exported interface defined in webidl-ast.h */
-int
+int *
webidl_node_getint(struct webidl_node *node)
{
if (node != NULL) {
@@ -285,14 +285,13 @@ webidl_node_getint(struct webidl_node *node)
case WEBIDL_NODE_TYPE_MODIFIER:
case WEBIDL_NODE_TYPE_TYPE_BASE:
case WEBIDL_NODE_TYPE_LITERAL_INT:
- return node->r.number;
+ return &node->r.number;
default:
break;
}
}
- return -1;
-
+ return NULL;
}
/* exported interface defined in webidl-ast.h */
@@ -400,6 +399,7 @@ static int webidl_ast_dump(FILE *dumpf, struct webidl_node *node, int indent)
{
const char *SPACES=" ";
char *txt;
+ int *value;
while (node != NULL) {
fprintf(dumpf, "%.*s%s", indent, SPACES,
webidl_node_type_to_str(node->type));
@@ -415,8 +415,10 @@ static int webidl_ast_dump(FILE *dumpf, struct webidl_node *node, int indent)
webidl_ast_dump(dumpf, next, indent + 2);
} else {
/* not txt or node has to be an int */
- fprintf(dumpf, ": %d\n",
- webidl_node_getint(node));
+ value = webidl_node_getint(node);
+ if (value != NULL) {
+ fprintf(dumpf, ": %d\n", *value);
+ }
}
} else {
fprintf(dumpf, ": \"%s\"\n", txt);
diff --git a/src/webidl-ast.h b/src/webidl-ast.h
index 5d0cbc0..38968f3 100644
--- a/src/webidl-ast.h
+++ b/src/webidl-ast.h
@@ -62,9 +62,10 @@ enum webidl_type {
};
enum webidl_type_modifier {
+ WEBIDL_TYPE_MODIFIER_NONE,
WEBIDL_TYPE_MODIFIER_UNSIGNED,
WEBIDL_TYPE_MODIFIER_UNRESTRICTED,
- WEBIDL_TYPE_READONLY,
+ WEBIDL_TYPE_MODIFIER_READONLY,
};
struct webidl_node;
@@ -86,7 +87,7 @@ struct webidl_node *webidl_node_add(struct webidl_node *node, struct webidl_node
/* node contents acessors */
char *webidl_node_gettext(struct webidl_node *node);
struct webidl_node *webidl_node_getnode(struct webidl_node *node);
-int webidl_node_getint(struct webidl_node *node);
+int *webidl_node_getint(struct webidl_node *node);
enum webidl_node_type webidl_node_gettype(struct webidl_node *node);
/* node searches */
diff --git a/src/webidl-parser.y b/src/webidl-parser.y
index 9717b8c..a48f3fd 100644
--- a/src/webidl-parser.y
+++ b/src/webidl-parser.y
@@ -689,7 +689,7 @@ Attribute:
/* deal with readonly modifier */
if ($2) {
- attribute = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER, attribute, (void *)WEBIDL_TYPE_READONLY);
+ attribute = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER, attribute, (void *)WEBIDL_TYPE_MODIFIER_READONLY);
}
$$ = webidl_node_new(WEBIDL_NODE_TYPE_ATTRIBUTE, NULL, attribute);
diff --git a/test/data/bindings/browser-duk.bnd b/test/data/bindings/browser-duk.bnd
index 0ddfa02..513ad99 100644
--- a/test/data/bindings/browser-duk.bnd
+++ b/test/data/bindings/browser-duk.bnd
@@ -161,10 +161,23 @@ method Node::appendChild()
dom_node_unref(spare);
%}
-getter Node::aprop()
+getter Node::textContent()
%{
+ dom_exception exc;
+ dom_string *content;
+
+ exc = dom_node_get_text_content(priv->node, &content);
+ if (exc != DOM_NO_ERR) {
+ return 0;
+ }
+
+ if (content != NULL) {
+ duk_push_lstring(ctx, dom_string_data(content), dom_string_length(content));
+ dom_string_unref(content);
+ return 1;
+ }
%}
-setter Node::aprop()
+setter Node::textContent()
%{
%}
commitdiff http://git.netsurf-browser.org/nsgenbind.git/commit/?id=3f0d06f529fb5efae...
commit 3f0d06f529fb5efaeb4edd89e61b3421951b8bf2
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Generate class methods from interface operations
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index b372df7..d1af70c 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -132,6 +132,34 @@ find_class_method(struct genbind_node *node,
}
/**
+ * find method by type on class with a specific ident
+ */
+static struct genbind_node *
+find_class_method_ident(struct genbind_node *node,
+ struct genbind_node *prev,
+ enum genbind_node_type nodetype,
+ char *ident)
+{
+ struct genbind_node *res_node;
+ char *method_ident;
+
+ res_node = find_class_method(node, prev, nodetype);
+ while (res_node != NULL) {
+ method_ident = genbind_node_gettext(
+ genbind_node_find_type(
+ genbind_node_getnode(res_node),
+ NULL,
+ GENBIND_NODE_TYPE_IDENT));
+ if ((method_ident != NULL) && strcmp(ident, method_ident) == 0) {
+ break;
+ }
+
+ res_node = find_class_method(node, res_node, nodetype);
+ }
+ return res_node;
+}
+
+/**
* output character data of node of given type.
*
* used for pre/pro/epi/post sections
@@ -158,6 +186,7 @@ output_cdata(FILE* outf,
*/
static int output_duckky_create_private(FILE* outf, char *class_name)
{
+ fprintf(outf, "\t/* create private data and attach to instance */");
fprintf(outf, "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n",
class_name);
fprintf(outf, "\tif (priv == NULL) return 0;\n");
@@ -453,11 +482,11 @@ static int output_get_prototype(FILE* outf, const char *interface_name)
for ( ; pnamelen >= 0; pnamelen--) {
proto_name[pnamelen] = toupper(interface_name[pnamelen]);
}
-
- fprintf(outf,"\tduk_get_global_string(ctx, PROTO_MAGIC);\n");
- fprintf(outf,"\tduk_get_prop_string(ctx, -1, PROTO_NAME(%s));\n",
+ fprintf(outf, "\t/* get prototype */\n");
+ fprintf(outf, "\tduk_get_global_string(ctx, PROTO_MAGIC);\n");
+ fprintf(outf, "\tduk_get_prop_string(ctx, -1, PROTO_NAME(%s));\n",
proto_name);
- fprintf(outf,"\tduk_replace(ctx, -2);\n");
+ fprintf(outf, "\tduk_replace(ctx, -2);\n");
free(proto_name);
@@ -496,6 +525,135 @@ output_set_constructor(FILE* outf, char *class_name, int idx, int argc)
}
/**
+ * generate code that adds a method in a prototype
+ */
+static int
+output_add_method(FILE* outf, char *class_name, char *method, int argc)
+{
+ //#define DUKKY_ADD_METHOD(klass,meth,nargs)
+ fprintf(outf, "\t/* Add a method */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, %s);\n", method);
+ fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s, ",
+ DLPFX, class_name, method);
+ if (argc == -1) {
+ fprintf(outf, "DUK_VARARGS);\n");
+
+ } else {
+ fprintf(outf, "%d);\n", argc);
+ }
+ fprintf(outf, "\tDUKKY_DUMP_STACK(ctx);\n");
+ fprintf(outf, "\tduk_def_prop(ctx, -3,\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_VALUE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+/**
+ * count the number of arguments to an operation
+ *
+ * \todo this needs to consider multiple lists (overloaded calls?), varadic
+ * parameters.
+ *
+ * \retuen number of arguments or -1 if variable
+ */
+static int count_operation_arguments(struct webidl_node *node)
+{
+ int argc;
+ struct webidl_node *list_node;
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+ if (list_node == NULL) {
+ /** \todo is having no argument list an error or a warning? */
+ return 0;
+ }
+ argc = webidl_node_enumerate_type(webidl_node_getnode(list_node),
+ WEBIDL_NODE_TYPE_OPTIONAL_ARGUMENT);
+ if (argc != 0) {
+ return -1;
+ }
+ return webidl_node_enumerate_type(webidl_node_getnode(list_node),
+ WEBIDL_NODE_TYPE_ARGUMENT);
+}
+
+/**
+ * generate a prototype add for a single class method
+ */
+static int
+output_prototype_method(FILE* outf,
+ struct interface_map_entry *interfacee,
+ struct webidl_node *op_node)
+{
+ char *op_name;
+ int op_argc;
+
+ op_name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(op_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ op_argc = count_operation_arguments(op_node);
+
+ output_add_method(outf, interfacee->class_name, op_name, op_argc);
+
+ return 0;
+
+}
+
+/**
+ * generate prototype method definitions
+ */
+static int
+output_prototype_methods(FILE *outf, struct interface_map_entry *interfacee)
+{
+ int res;
+ struct webidl_node *list_node;
+ struct webidl_node *op_node; /* operation on list node */
+
+ /* iterate each list node within the interface */
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interfacee->node),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ while (list_node != NULL) {
+ /* iterate through operations in a list */
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_OPERATION);
+
+ while (op_node != NULL) {
+ res = output_prototype_method(outf, interfacee, op_node);
+ if (res != 0) {
+ return res;
+ }
+
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ op_node,
+ WEBIDL_NODE_TYPE_OPERATION);
+ }
+
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interfacee->node),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ return 0;
+
+}
+
+/**
* generate the interface prototype creator
*/
static int
@@ -517,6 +675,9 @@ output_interface_prototype(FILE* outf,
fprintf(outf, "\tduk_set_prototype(ctx, 0);\n\n");
}
+ /* generate setting of methods */
+ output_prototype_methods(outf, interfacee);
+
/* generate setting of destructor */
output_set_destructor(outf, interfacee->class_name, 0);
@@ -534,6 +695,107 @@ output_interface_prototype(FILE* outf,
}
/**
+ * generate code that gets a private pointer for a method
+ */
+static int
+output_get_method_private(FILE* outf, char *class_name)
+{
+ fprintf(outf, "\t/* Get private data for method */\n");
+ fprintf(outf, "\t%s_private_t *priv = NULL;\n", class_name);
+ fprintf(outf, "\tduk_push_this(ctx);\n");
+ fprintf(outf, "\tduk_get_prop_string(ctx, -1, PRIVATE_MAGIC);\n");
+ fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
+ fprintf(outf, "\tduk_pop_2(ctx);\n");
+ fprintf(outf, "\tif (priv == NULL) return 0; /* can do? No can do. */\n\n");
+ return 0;
+}
+
+/**
+ * generate a single class method for an interface operation
+ */
+static int
+output_interface_operation(FILE* outf,
+ struct interface_map_entry *interfacee,
+ struct webidl_node *op_node)
+{
+ char *op_name;
+ struct genbind_node *method_node;
+
+ op_name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(op_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ method_node = find_class_method_ident(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_METHOD,
+ op_name);
+
+ /* method definition */
+ fprintf(outf,
+ "static duk_ret_t %s_%s_%s(duk_context *ctx)\n",
+ DLPFX, interfacee->class_name, op_name);
+ fprintf(outf,"{\n");
+
+ output_get_method_private(outf, interfacee->class_name);
+
+ output_cdata(outf, method_node, GENBIND_NODE_TYPE_CDATA);
+
+ fprintf(outf,"\treturn 0;\n");
+
+ fprintf(outf, "}\n\n");
+
+ return 0;
+
+}
+
+/**
+ * generate class methods for each interface operation
+ */
+static int
+output_interface_operations(FILE* outf, struct interface_map_entry *interfacee)
+{
+ int res;
+ struct webidl_node *list_node;
+ struct webidl_node *op_node; /* operation on list node */
+
+ /* iterate each list node within the interface */
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interfacee->node),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ while (list_node != NULL) {
+ /* iterate through operations in a list */
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_OPERATION);
+
+ while (op_node != NULL) {
+ res = output_interface_operation(outf, interfacee, op_node);
+ if (res != 0) {
+ return res;
+ }
+
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ op_node,
+ WEBIDL_NODE_TYPE_OPERATION);
+ }
+
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interfacee->node),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ return 0;
+}
+
+/**
* generate a source file to implement an interface using duk and libdom.
*/
static int output_interface(struct genbind_node *genbind,
@@ -600,6 +862,11 @@ static int output_interface(struct genbind_node *genbind,
/* destructor */
output_interface_destructor(ifacef, interfacee);
+ /* operations */
+ output_interface_operations(ifacef, interfacee);
+
+ /* attributes */
+
/* prototype */
output_interface_prototype(ifacef, interfacee, inherite);
diff --git a/test/data/bindings/browser-duk.bnd b/test/data/bindings/browser-duk.bnd
index 392f652..0ddfa02 100644
--- a/test/data/bindings/browser-duk.bnd
+++ b/test/data/bindings/browser-duk.bnd
@@ -147,8 +147,18 @@ fini Node()
dom_node_unref(priv->node);
%}
-method Node::AppendChild()
+method Node::appendChild()
%{
+ if (!dukky_instanceof(ctx, PROTO_NAME(NODE))) return 0;
+
+ DUKKY_SAFE_GET_ANOTHER(other,node,0);
+
+ dom_exception err;
+ dom_node *spare;
+
+ err = dom_node_append_child(priv->node, other->node, &spare);
+ if (err != DOM_NO_ERR) return 0;
+ dom_node_unref(spare);
%}
getter Node::aprop()
-----------------------------------------------------------------------
Summary of changes:
src/duk-libdom.c | 442 ++++++++++++++++++++++++++++++++----
src/interface-map.c | 266 ++++++++++++++++++++--
src/interface-map.h | 23 +-
src/nsgenbind-ast.c | 63 +++++
src/nsgenbind-ast.h | 52 ++++-
src/webidl-ast.c | 14 +-
src/webidl-ast.h | 5 +-
src/webidl-parser.y | 2 +-
test/data/bindings/browser-duk.bnd | 29 ++-
9 files changed, 804 insertions(+), 92 deletions(-)
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index b372df7..f7a1a5f 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -98,40 +98,6 @@ static char *gen_class_name(struct interface_map_entry *interfacee)
}
/**
- * find method by type on class
- */
-static struct genbind_node *
-find_class_method(struct genbind_node *node,
- struct genbind_node *prev,
- enum genbind_node_type nodetype)
-{
- struct genbind_node *res_node;
-
- res_node = genbind_node_find_type(
- genbind_node_getnode(node),
- prev, GENBIND_NODE_TYPE_METHOD);
- while (res_node != NULL) {
- struct genbind_node *type_node;
- enum genbind_node_type *type;
-
- type_node = genbind_node_find_type(
- genbind_node_getnode(res_node),
- NULL, GENBIND_NODE_TYPE_METHOD_TYPE);
-
- type = (enum genbind_node_type *)genbind_node_getint(type_node);
- if (*type == nodetype) {
- break;
- }
-
- res_node = genbind_node_find_type(
- genbind_node_getnode(node),
- res_node, GENBIND_NODE_TYPE_METHOD);
- }
-
- return res_node;
-}
-
-/**
* output character data of node of given type.
*
* used for pre/pro/epi/post sections
@@ -158,6 +124,7 @@ output_cdata(FILE* outf,
*/
static int output_duckky_create_private(FILE* outf, char *class_name)
{
+ fprintf(outf, "\t/* create private data and attach to instance */");
fprintf(outf, "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n",
class_name);
fprintf(outf, "\tif (priv == NULL) return 0;\n");
@@ -262,14 +229,14 @@ output_interface_inherit_init(FILE* outf,
}
/* find the initialisor method on the class (if any) */
- init_node = find_class_method(interfacee->class,
- NULL,
- GENBIND_METHOD_TYPE_INIT);
+ init_node = genbind_node_find_method(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_INIT);
- inh_init_node = find_class_method(inherite->class,
- NULL,
- GENBIND_METHOD_TYPE_INIT);
+ inh_init_node = genbind_node_find_method(inherite->class,
+ NULL,
+ GENBIND_METHOD_TYPE_INIT);
@@ -351,9 +318,9 @@ output_interface_init(FILE* outf,
int res;
/* find the initialisor method on the class (if any) */
- init_node = find_class_method(interfacee->class,
- NULL,
- GENBIND_METHOD_TYPE_INIT);
+ init_node = genbind_node_find_method(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_INIT);
/* initialisor definition */
fprintf(outf,
@@ -409,9 +376,9 @@ output_interface_fini(FILE* outf,
struct genbind_node *fini_node;
/* find the finaliser method on the class (if any) */
- fini_node = find_class_method(interfacee->class,
- NULL,
- GENBIND_METHOD_TYPE_FINI);
+ fini_node = genbind_node_find_method(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_FINI);
/* finaliser definition */
fprintf(outf,
@@ -453,11 +420,11 @@ static int output_get_prototype(FILE* outf, const char *interface_name)
for ( ; pnamelen >= 0; pnamelen--) {
proto_name[pnamelen] = toupper(interface_name[pnamelen]);
}
-
- fprintf(outf,"\tduk_get_global_string(ctx, PROTO_MAGIC);\n");
- fprintf(outf,"\tduk_get_prop_string(ctx, -1, PROTO_NAME(%s));\n",
+ fprintf(outf, "\t/* get prototype */\n");
+ fprintf(outf, "\tduk_get_global_string(ctx, PROTO_MAGIC);\n");
+ fprintf(outf, "\tduk_get_prop_string(ctx, -1, PROTO_NAME(%s));\n",
proto_name);
- fprintf(outf,"\tduk_replace(ctx, -2);\n");
+ fprintf(outf, "\tduk_replace(ctx, -2);\n");
free(proto_name);
@@ -496,6 +463,207 @@ output_set_constructor(FILE* outf, char *class_name, int idx, int argc)
}
/**
+ * generate code that adds a method in a prototype
+ */
+static int
+output_add_method(FILE* outf, char *class_name, char *method, int argc)
+{
+ fprintf(outf, "\t/* Add a method */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, %s);\n", method);
+ fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s, ",
+ DLPFX, class_name, method);
+ if (argc == -1) {
+ fprintf(outf, "DUK_VARARGS);\n");
+
+ } else {
+ fprintf(outf, "%d);\n", argc);
+ }
+ fprintf(outf, "\tDUKKY_DUMP_STACK(ctx);\n");
+ fprintf(outf, "\tduk_def_prop(ctx, -3,\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_VALUE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+/**
+ * count the number of arguments to an operation
+ *
+ * \todo this needs to consider multiple lists (overloaded calls?), varadic
+ * parameters.
+ *
+ * \retuen number of arguments or -1 if variable
+ */
+static int count_operation_arguments(struct webidl_node *node)
+{
+ int argc;
+ struct webidl_node *list_node;
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+ if (list_node == NULL) {
+ /** \todo is having no argument list an error or a warning? */
+ return 0;
+ }
+ argc = webidl_node_enumerate_type(webidl_node_getnode(list_node),
+ WEBIDL_NODE_TYPE_OPTIONAL_ARGUMENT);
+ if (argc != 0) {
+ return -1;
+ }
+ return webidl_node_enumerate_type(webidl_node_getnode(list_node),
+ WEBIDL_NODE_TYPE_ARGUMENT);
+}
+
+/**
+ * generate a prototype add for a single class method
+ */
+static int
+output_prototype_method(FILE* outf,
+ struct interface_map_entry *interfacee,
+ struct webidl_node *op_node)
+{
+ char *op_name;
+ int op_argc;
+
+ op_name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(op_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ op_argc = count_operation_arguments(op_node);
+
+ output_add_method(outf, interfacee->class_name, op_name, op_argc);
+
+ return 0;
+
+}
+
+/**
+ * generate prototype method definitions
+ */
+static int
+output_prototype_methods(FILE *outf, struct interface_map_entry *interfacee)
+{
+ int res;
+ struct webidl_node *list_node;
+ struct webidl_node *op_node; /* operation on list node */
+
+ /* iterate each list node within the interface */
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interfacee->node),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ while (list_node != NULL) {
+ /* iterate through operations in a list */
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_OPERATION);
+
+ while (op_node != NULL) {
+ res = output_prototype_method(outf, interfacee, op_node);
+ if (res != 0) {
+ return res;
+ }
+
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ op_node,
+ WEBIDL_NODE_TYPE_OPERATION);
+ }
+
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interfacee->node),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ return 0;
+
+}
+
+static int
+output_populate_rw_property(FILE* outf, const char *class_name, const char *property)
+{
+ fprintf(outf, "\t/* Add read/write property */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ DLPFX, class_name, property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_setter, 1);\n",
+ DLPFX, class_name, property);
+ fprintf(outf, "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_SETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+static int
+output_populate_ro_property(FILE* outf, const char *class_name, const char *property)
+{
+ fprintf(outf, "\t/* Add readonly property */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ DLPFX, class_name, property);
+ fprintf(outf,
+ "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+static int
+output_prototype_attribute(FILE *outf,
+ struct interface_map_entry *interfacee,
+ struct interface_map_attribute_entry *attributee)
+{
+ if (attributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY) {
+ return output_populate_ro_property(outf,
+ interfacee->class_name,
+ attributee->name);
+ } else {
+ return output_populate_rw_property(outf,
+ interfacee->class_name,
+ attributee->name);
+ }
+}
+
+/**
+ * generate prototype attribute definitions
+ */
+static int
+output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
+{
+ int attrc;
+
+ for (attrc = 0; attrc < interfacee->attributec; attrc++) {
+ output_prototype_attribute(outf,
+ interfacee,
+ interfacee->attributev + attrc);
+ }
+
+ return 0;
+
+}
+
+/**
* generate the interface prototype creator
*/
static int
@@ -517,6 +685,12 @@ output_interface_prototype(FILE* outf,
fprintf(outf, "\tduk_set_prototype(ctx, 0);\n\n");
}
+ /* generate setting of methods */
+ output_prototype_methods(outf, interfacee);
+
+ /* generate setting of attributes */
+ output_prototype_attributes(outf, interfacee);
+
/* generate setting of destructor */
output_set_destructor(outf, interfacee->class_name, 0);
@@ -534,6 +708,168 @@ output_interface_prototype(FILE* outf,
}
/**
+ * generate code that gets a private pointer for a method
+ */
+static int
+output_get_method_private(FILE* outf, char *class_name)
+{
+ fprintf(outf, "\t/* Get private data for method */\n");
+ fprintf(outf, "\t%s_private_t *priv = NULL;\n", class_name);
+ fprintf(outf, "\tduk_push_this(ctx);\n");
+ fprintf(outf, "\tduk_get_prop_string(ctx, -1, PRIVATE_MAGIC);\n");
+ fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
+ fprintf(outf, "\tduk_pop_2(ctx);\n");
+ fprintf(outf, "\tif (priv == NULL) return 0; /* can do? No can do. */\n\n");
+ return 0;
+}
+
+/**
+ * generate a single class method for an interface operation
+ */
+static int
+output_interface_operation(FILE* outf,
+ struct interface_map_entry *interfacee,
+ struct webidl_node *op_node)
+{
+ char *op_name;
+ struct genbind_node *method_node;
+
+ op_name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(op_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ method_node = genbind_node_find_method_ident(interfacee->class,
+ NULL,
+ GENBIND_METHOD_TYPE_METHOD,
+ op_name);
+
+ /* method definition */
+ fprintf(outf,
+ "static duk_ret_t %s_%s_%s(duk_context *ctx)\n",
+ DLPFX, interfacee->class_name, op_name);
+ fprintf(outf,"{\n");
+
+ output_get_method_private(outf, interfacee->class_name);
+
+ output_cdata(outf, method_node, GENBIND_NODE_TYPE_CDATA);
+
+ fprintf(outf,"\treturn 0;\n");
+
+ fprintf(outf, "}\n\n");
+
+ return 0;
+}
+
+/**
+ * generate class methods for each interface operation
+ */
+static int
+output_interface_operations(FILE* outf, struct interface_map_entry *interfacee)
+{
+ int res;
+ struct webidl_node *list_node;
+ struct webidl_node *op_node; /* operation on list node */
+
+ /* iterate each list node within the interface */
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interfacee->node),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ while (list_node != NULL) {
+ /* iterate through operations in a list */
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_OPERATION);
+
+ while (op_node != NULL) {
+ res = output_interface_operation(outf, interfacee, op_node);
+ if (res != 0) {
+ return res;
+ }
+
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ op_node,
+ WEBIDL_NODE_TYPE_OPERATION);
+ }
+
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interfacee->node),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ return 0;
+}
+
+/**
+ * Generate class property getter/setter for a single attribute
+ */
+static int
+output_interface_attribute(FILE* outf,
+ struct interface_map_entry *interfacee,
+ struct interface_map_attribute_entry *atributee)
+{
+ /* getter definition */
+ fprintf(outf,
+ "static duk_ret_t %s_%s_%s_getter(duk_context *ctx)\n",
+ DLPFX, interfacee->class_name, atributee->name);
+ fprintf(outf,"{\n");
+
+ output_get_method_private(outf, interfacee->class_name);
+
+ output_cdata(outf, atributee->getter, GENBIND_NODE_TYPE_CDATA);
+
+ fprintf(outf,"\treturn 0;\n");
+
+ fprintf(outf, "}\n\n");
+
+ /* readonly attributes have no setter */
+ if (atributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY) {
+ return 0;
+ }
+
+ /* setter definition */
+ fprintf(outf,
+ "static duk_ret_t %s_%s_%s_setter(duk_context *ctx)\n",
+ DLPFX, interfacee->class_name, atributee->name);
+ fprintf(outf,"{\n");
+
+ output_get_method_private(outf, interfacee->class_name);
+
+ output_cdata(outf, atributee->setter, GENBIND_NODE_TYPE_CDATA);
+
+ fprintf(outf,"\treturn 0;\n");
+
+ fprintf(outf, "}\n\n");
+
+ return 0;
+}
+
+/**
+ * generate class property getters and setters for each interface attribute
+ */
+static int
+output_interface_attributes(FILE* outf,
+ struct interface_map_entry *interfacee)
+{
+ int attrc;
+
+ for (attrc = 0; attrc < interfacee->attributec; attrc++) {
+ output_interface_attribute(outf,
+ interfacee,
+ interfacee->attributev + attrc);
+ }
+
+ return 0;
+}
+
+/**
* generate a source file to implement an interface using duk and libdom.
*/
static int output_interface(struct genbind_node *genbind,
@@ -600,6 +936,12 @@ static int output_interface(struct genbind_node *genbind,
/* destructor */
output_interface_destructor(ifacef, interfacee);
+ /* operations */
+ output_interface_operations(ifacef, interfacee);
+
+ /* attributes */
+ output_interface_attributes(ifacef, interfacee);
+
/* prototype */
output_interface_prototype(ifacef, interfacee, inherite);
diff --git a/src/interface-map.c b/src/interface-map.c
index 44ece42..6a77b6a 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -110,8 +110,10 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
dstinf[idx].name = srcinf[inf].name;
dstinf[idx].node = srcinf[inf].node;
dstinf[idx].inherit_name = srcinf[inf].inherit_name;
- dstinf[idx].operations = srcinf[inf].operations;
- dstinf[idx].attributes = srcinf[inf].attributes;
+ dstinf[idx].operationc = srcinf[inf].operationc;
+ dstinf[idx].operationv = srcinf[inf].operationv;
+ dstinf[idx].attributec = srcinf[inf].attributec;
+ dstinf[idx].attributev = srcinf[inf].attributev;
dstinf[idx].class = srcinf[inf].class;
/* reduce refcount on inherit index if !=-1 */
@@ -126,6 +128,180 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
return dstinf;
}
+static int
+operation_map_new(struct webidl_node *interface,
+ struct genbind_node *class,
+ int *operationc_out,
+ struct interface_map_operation_entry **operationv_out)
+{
+ struct webidl_node *list_node;
+ struct webidl_node *op_node; /* attribute node */
+ struct interface_map_operation_entry *cure; /* current entry */
+ struct interface_map_operation_entry *operationv;
+ int operationc;
+
+ /* enumerate operationss */
+ operationc = enumerate_interface_type(interface,
+ WEBIDL_NODE_TYPE_OPERATION);
+ *operationc_out = operationc;
+
+ if (operationc < 1) {
+ *operationv_out = NULL; /* no operations so empty map */
+ return 0;
+ }
+
+ operationv = calloc(operationc,
+ sizeof(struct interface_map_operation_entry));
+ if (operationv == NULL) {
+ return -1;
+ };
+ cure = operationv;
+
+ /* iterate each list node within the interface */
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ while (list_node != NULL) {
+ /* iterate through operations on list */
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_OPERATION);
+
+ while (op_node != NULL) {
+ cure->node = op_node;
+
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(op_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ cure->method = genbind_node_find_method_ident(
+ class,
+ NULL,
+ GENBIND_METHOD_TYPE_METHOD,
+ cure->name);
+
+ cure++;
+
+ /* move to next operation */
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ op_node,
+ WEBIDL_NODE_TYPE_OPERATION);
+ }
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ *operationv_out = operationv; /* resulting operations map */
+
+ return 0;
+}
+
+static int
+attribute_map_new(struct webidl_node *interface,
+ struct genbind_node *class,
+ int *attributec_out,
+ struct interface_map_attribute_entry **attributev_out)
+{
+ struct webidl_node *list_node;
+ struct webidl_node *at_node; /* attribute node */
+ struct interface_map_attribute_entry *cure; /* current entry */
+ struct interface_map_attribute_entry *attributev;
+ int attributec;
+
+ /* enumerate attributes */
+ attributec = enumerate_interface_type(interface,
+ WEBIDL_NODE_TYPE_ATTRIBUTE);
+ *attributec_out = attributec;
+
+ if (attributec < 1) {
+ *attributev_out = NULL; /* no attributes so empty map */
+ return 0;
+ }
+
+ attributev = calloc(attributec,
+ sizeof(struct interface_map_attribute_entry));
+ if (attributev == NULL) {
+ return -1;
+ };
+ cure = attributev;
+
+ /* iterate each list node within the interface */
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ while (list_node != NULL) {
+ /* iterate through attributes on list */
+ at_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_ATTRIBUTE);
+
+ while (at_node != NULL) {
+ enum webidl_type_modifier *modifier;
+
+ cure->node = at_node;
+
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(at_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ cure->getter = genbind_node_find_method_ident(
+ class,
+ NULL,
+ GENBIND_METHOD_TYPE_GETTER,
+ cure->name);
+
+ /* check fo readonly attributes */
+ modifier = (enum webidl_type_modifier *)webidl_node_getint(
+ webidl_node_find_type(
+ webidl_node_getnode(at_node),
+ NULL,
+ WEBIDL_NODE_TYPE_MODIFIER));
+ if ((modifier != NULL) &&
+ (*modifier == WEBIDL_TYPE_MODIFIER_READONLY)) {
+ cure->modifier = WEBIDL_TYPE_MODIFIER_READONLY;
+ } else {
+ cure->modifier = WEBIDL_TYPE_MODIFIER_NONE;
+ cure->setter = genbind_node_find_method_ident(
+ class,
+ NULL,
+ GENBIND_METHOD_TYPE_SETTER,
+ cure->name);
+ }
+
+ cure++;
+
+ /* move to next attribute */
+ at_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ at_node,
+ WEBIDL_NODE_TYPE_ATTRIBUTE);
+ }
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ *attributev_out = attributev; /* resulting attributes map */
+
+ return 0;
+}
+
int interface_map_new(struct genbind_node *genbind,
struct webidl_node *webidl,
struct interface_map **index_out)
@@ -162,7 +338,7 @@ int interface_map_new(struct genbind_node *genbind,
webidl_node_find_type(
webidl_node_getnode(node),
NULL,
- GENBIND_NODE_TYPE_IDENT));
+ WEBIDL_NODE_TYPE_IDENT));
/* name of the inherited interface (if any) */
ecur->inherit_name = webidl_node_gettext(
@@ -171,20 +347,22 @@ int interface_map_new(struct genbind_node *genbind,
NULL,
WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE));
-
- /* enumerate the number of operations */
- ecur->operations = enumerate_interface_type(node,
- WEBIDL_NODE_TYPE_OPERATION);
-
- /* enumerate the number of attributes */
- ecur->attributes = enumerate_interface_type(node,
- WEBIDL_NODE_TYPE_ATTRIBUTE);
-
-
/* matching class from binding */
ecur->class = genbind_node_find_type_ident(genbind,
NULL, GENBIND_NODE_TYPE_CLASS, ecur->name);
+ /* enumerate and map the interface operations */
+ operation_map_new(node,
+ ecur->class,
+ &ecur->operationc,
+ &ecur->operationv);
+
+ /* enumerate and map the interface attributes */
+ attribute_map_new(node,
+ ecur->class,
+ &ecur->attributec,
+ &ecur->attributev);
+
/* move to next interface */
node = webidl_node_find_type(webidl, node,
WEBIDL_NODE_TYPE_INTERFACE);
@@ -218,27 +396,68 @@ int interface_map_dump(struct interface_map *index)
FILE *dumpf;
int eidx;
struct interface_map_entry *ecur;
- const char *inherit_name;
/* only dump AST to file if required */
if (!options->debug) {
return 0;
}
- dumpf = genb_fopen("interface-index", "w");
+ dumpf = genb_fopen("interface-map", "w");
if (dumpf == NULL) {
return 2;
}
ecur = index->entries;
for (eidx = 0; eidx < index->entryc; eidx++) {
- inherit_name = ecur->inherit_name;
- if (inherit_name == NULL) {
- inherit_name = "";
- }
- fprintf(dumpf, "%d %s %s i:%d a:%d %p\n", eidx, ecur->name,
- inherit_name, ecur->operations, ecur->attributes,
- ecur->class);
+ fprintf(dumpf, "%d %s\n", eidx, ecur->name);
+ if (ecur->inherit_name != NULL) {
+ fprintf(dumpf, " inherit:%s\n", ecur->inherit_name);
+ }
+ if (ecur->class != NULL) {
+ fprintf(dumpf, " class:%p\n", ecur->class);
+ }
+ if (ecur->operationc > 0) {
+ int opc = ecur->operationc;
+ struct interface_map_operation_entry *ope;
+
+ fprintf(dumpf, " %d operations\n",
+ ecur->operationc);
+
+ ope = ecur->operationv;
+ while (ope != NULL) {
+ fprintf(dumpf, " %s %p\n",
+ ope->name, ope->method);
+ ope++;
+ opc--;
+ if (opc == 0) {
+ break;
+ }
+ }
+
+ }
+ if (ecur->attributec > 0) {
+ int attrc = ecur->attributec;
+ struct interface_map_attribute_entry *attre;
+
+ fprintf(dumpf, " %d attributes\n", attrc);
+
+ attre = ecur->attributev;
+ while (attre != NULL) {
+ fprintf(dumpf, " %s %p",
+ attre->name,
+ attre->getter);
+ if (attre->modifier == WEBIDL_TYPE_MODIFIER_NONE) {
+ fprintf(dumpf, " %p\n", attre->setter);
+ } else {
+ fprintf(dumpf, "\n");
+ }
+ attre++;
+ attrc--;
+ if (attrc == 0) {
+ break;
+ }
+ }
+ }
ecur++;
}
@@ -269,7 +488,8 @@ int interface_map_dumpdot(struct interface_map *index)
for (eidx = 0; eidx < index->entryc; eidx++) {
if (ecur->class != NULL) {
/* interfaces bound to a class are shown in blue */
- fprintf(dumpf, "%04d [label=\"%s\" fontcolor=\"blue\"];\n", eidx, ecur->name);
+ fprintf(dumpf, "%04d [label=\"%s\" fontcolor=\"blue\"];\n",
+ eidx, ecur->name);
} else {
fprintf(dumpf, "%04d [label=\"%s\"];\n", eidx, ecur->name);
}
diff --git a/src/interface-map.h b/src/interface-map.h
index 7373580..9d66dfb 100644
--- a/src/interface-map.h
+++ b/src/interface-map.h
@@ -12,12 +12,31 @@
struct genbind_node;
struct webidl_node;
+struct interface_map_operation_entry {
+ const char *name; /** operation name */
+ struct webidl_node *node; /**< AST operation node */
+ struct genbind_node *method; /**< method from binding (if any) */
+};
+
+struct interface_map_attribute_entry {
+ const char *name; /** attribute name */
+ struct webidl_node *node; /**< AST attribute node */
+ enum webidl_type_modifier modifier;
+ struct genbind_node *getter; /**< getter from binding (if any) */
+ struct genbind_node *setter; /**< getter from binding (if any) */
+};
+
struct interface_map_entry {
const char *name; /** interface name */
struct webidl_node *node; /**< AST interface node */
const char *inherit_name; /**< Name of interface inhertited from */
- int operations; /**< number of operations on interface */
- int attributes; /**< number of attributes on interface */
+
+ int operationc; /**< number of operations on interface */
+ struct interface_map_operation_entry *operationv;
+
+ int attributec; /**< number of attributes on interface */
+ struct interface_map_attribute_entry *attributev;
+
int inherit_idx; /**< index into map of inherited interface or -1 for
* not in map
*/
diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c
index c1acee1..28326aa 100644
--- a/src/nsgenbind-ast.c
+++ b/src/nsgenbind-ast.c
@@ -288,6 +288,69 @@ genbind_node_find_type_type(struct genbind_node *node,
return found_node;
}
+
+/* exported interface documented in nsgenbind-ast.h */
+struct genbind_node *
+genbind_node_find_method(struct genbind_node *node,
+ struct genbind_node *prev,
+ enum genbind_method_type methodtype)
+{
+ struct genbind_node *res_node;
+
+ res_node = genbind_node_find_type(
+ genbind_node_getnode(node),
+ prev, GENBIND_NODE_TYPE_METHOD);
+ while (res_node != NULL) {
+ struct genbind_node *type_node;
+ enum genbind_method_type *type;
+
+ type_node = genbind_node_find_type(
+ genbind_node_getnode(res_node),
+ NULL, GENBIND_NODE_TYPE_METHOD_TYPE);
+
+ type = (enum genbind_method_type *)genbind_node_getint(type_node);
+ if (*type == methodtype) {
+ break;
+ }
+
+ res_node = genbind_node_find_type(
+ genbind_node_getnode(node),
+ res_node, GENBIND_NODE_TYPE_METHOD);
+ }
+
+ return res_node;
+}
+
+
+/* exported interface documented in nsgenbind-ast.h */
+struct genbind_node *
+genbind_node_find_method_ident(struct genbind_node *node,
+ struct genbind_node *prev,
+ enum genbind_method_type nodetype,
+ const char *ident)
+{
+ struct genbind_node *res_node;
+ char *method_ident;
+
+ res_node = genbind_node_find_method(node, prev, nodetype);
+ while (res_node != NULL) {
+ method_ident = genbind_node_gettext(
+ genbind_node_find_type(
+ genbind_node_getnode(res_node),
+ NULL,
+ GENBIND_NODE_TYPE_IDENT));
+ if ((method_ident != NULL) &&
+ strcmp(ident, method_ident) == 0) {
+ break;
+ }
+
+ res_node = genbind_node_find_method(node, res_node, nodetype);
+ }
+ return res_node;
+}
+
+
+/* exported interface documented in nsgenbind-ast.h */
int genbind_cmp_node_type(struct genbind_node *node, void *ctx)
{
if (node->type == (enum genbind_node_type)ctx)
diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h
index 9c564b9..0b0fcfd 100644
--- a/src/nsgenbind-ast.h
+++ b/src/nsgenbind-ast.h
@@ -101,7 +101,8 @@ genbind_node_find(struct genbind_node *node,
genbind_callback_t *cb,
void *ctx);
-/** Depth first left hand search returning nodes of the specified type
+/**
+ * Depth first left hand search returning nodes of the specified type
*
* @param node The node to start the search from
* @param prev The node at which to stop the search, either NULL to
@@ -115,7 +116,8 @@ genbind_node_find_type(struct genbind_node *node,
struct genbind_node *prev,
enum genbind_node_type nodetype);
-/** count how many nodes of a specified type.
+/**
+ * count how many nodes of a specified type.
*
* Enumerate how many nodes of the specified type there are by
* performing a depth first search for nodes of the given type and
@@ -129,7 +131,9 @@ int
genbind_node_enumerate_type(struct genbind_node *node,
enum genbind_node_type type);
-/** Depth first left hand search returning nodes of the specified type
+
+/**
+ * Depth first left hand search returning nodes of the specified type
* with an ident child node with matching text
*
* @param node The node to start the search from
@@ -145,7 +149,9 @@ genbind_node_find_type_ident(struct genbind_node *node,
enum genbind_node_type nodetype,
const char *ident);
-/** Returning node of the specified type with a GENBIND_NODE_TYPE_TYPE
+
+/**
+ * Returning node of the specified type with a GENBIND_NODE_TYPE_TYPE
* subnode with matching text.
*
* This is a conveniance wrapper around nested calls to
@@ -167,7 +173,43 @@ genbind_node_find_type_type(struct genbind_node *node,
enum genbind_node_type nodetype,
const char *type_text);
-/** Iterate all nodes of a certian type from a node with a callback.
+
+/**
+ * Find a method node of a given method type
+ *
+ * \param node A node of type GENBIND_NODE_TYPE_CLASS to search for methods.
+ * \param prev The node at which to stop the search, either NULL to
+ * search the full tree depth (initial search) or the result
+ * of a previous search to continue.
+ * \param methodtype The type of method to find.
+ * \return A node of type GENBIND_NODE_TYPE_METHOD on success or NULL on faliure
+ */
+struct genbind_node *
+genbind_node_find_method(struct genbind_node *node,
+ struct genbind_node *prev,
+ enum genbind_method_type methodtype);
+
+
+/**
+ * Find a method node of a given method type and identifier
+ *
+ * \param node A node of type GENBIND_NODE_TYPE_CLASS to search for methods.
+ * \param prev The node at which to stop the search, either NULL to
+ * search the full tree depth (initial search) or the result
+ * of a previous search to continue.
+ * \param methodtype The type of method to find.
+ * \param ident The identifier to search for
+ * \return A node of type GENBIND_NODE_TYPE_METHOD on success or NULL on faliure
+ */
+struct genbind_node *
+genbind_node_find_method_ident(struct genbind_node *node,
+ struct genbind_node *prev,
+ enum genbind_method_type methodtype,
+ const char *ident);
+
+
+/**
+ * Iterate all nodes of a certian type from a node with a callback.
*
* Depth first search for nodes of the given type calling the callback
* with context.
diff --git a/src/webidl-ast.c b/src/webidl-ast.c
index 6c24c41..75f969b 100644
--- a/src/webidl-ast.c
+++ b/src/webidl-ast.c
@@ -277,7 +277,7 @@ char *webidl_node_gettext(struct webidl_node *node)
}
/* exported interface defined in webidl-ast.h */
-int
+int *
webidl_node_getint(struct webidl_node *node)
{
if (node != NULL) {
@@ -285,14 +285,13 @@ webidl_node_getint(struct webidl_node *node)
case WEBIDL_NODE_TYPE_MODIFIER:
case WEBIDL_NODE_TYPE_TYPE_BASE:
case WEBIDL_NODE_TYPE_LITERAL_INT:
- return node->r.number;
+ return &node->r.number;
default:
break;
}
}
- return -1;
-
+ return NULL;
}
/* exported interface defined in webidl-ast.h */
@@ -400,6 +399,7 @@ static int webidl_ast_dump(FILE *dumpf, struct webidl_node *node, int indent)
{
const char *SPACES=" ";
char *txt;
+ int *value;
while (node != NULL) {
fprintf(dumpf, "%.*s%s", indent, SPACES,
webidl_node_type_to_str(node->type));
@@ -415,8 +415,10 @@ static int webidl_ast_dump(FILE *dumpf, struct webidl_node *node, int indent)
webidl_ast_dump(dumpf, next, indent + 2);
} else {
/* not txt or node has to be an int */
- fprintf(dumpf, ": %d\n",
- webidl_node_getint(node));
+ value = webidl_node_getint(node);
+ if (value != NULL) {
+ fprintf(dumpf, ": %d\n", *value);
+ }
}
} else {
fprintf(dumpf, ": \"%s\"\n", txt);
diff --git a/src/webidl-ast.h b/src/webidl-ast.h
index 5d0cbc0..38968f3 100644
--- a/src/webidl-ast.h
+++ b/src/webidl-ast.h
@@ -62,9 +62,10 @@ enum webidl_type {
};
enum webidl_type_modifier {
+ WEBIDL_TYPE_MODIFIER_NONE,
WEBIDL_TYPE_MODIFIER_UNSIGNED,
WEBIDL_TYPE_MODIFIER_UNRESTRICTED,
- WEBIDL_TYPE_READONLY,
+ WEBIDL_TYPE_MODIFIER_READONLY,
};
struct webidl_node;
@@ -86,7 +87,7 @@ struct webidl_node *webidl_node_add(struct webidl_node *node, struct webidl_node
/* node contents acessors */
char *webidl_node_gettext(struct webidl_node *node);
struct webidl_node *webidl_node_getnode(struct webidl_node *node);
-int webidl_node_getint(struct webidl_node *node);
+int *webidl_node_getint(struct webidl_node *node);
enum webidl_node_type webidl_node_gettype(struct webidl_node *node);
/* node searches */
diff --git a/src/webidl-parser.y b/src/webidl-parser.y
index 9717b8c..a48f3fd 100644
--- a/src/webidl-parser.y
+++ b/src/webidl-parser.y
@@ -689,7 +689,7 @@ Attribute:
/* deal with readonly modifier */
if ($2) {
- attribute = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER, attribute, (void *)WEBIDL_TYPE_READONLY);
+ attribute = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER, attribute, (void *)WEBIDL_TYPE_MODIFIER_READONLY);
}
$$ = webidl_node_new(WEBIDL_NODE_TYPE_ATTRIBUTE, NULL, attribute);
diff --git a/test/data/bindings/browser-duk.bnd b/test/data/bindings/browser-duk.bnd
index 392f652..513ad99 100644
--- a/test/data/bindings/browser-duk.bnd
+++ b/test/data/bindings/browser-duk.bnd
@@ -147,14 +147,37 @@ fini Node()
dom_node_unref(priv->node);
%}
-method Node::AppendChild()
+method Node::appendChild()
%{
+ if (!dukky_instanceof(ctx, PROTO_NAME(NODE))) return 0;
+
+ DUKKY_SAFE_GET_ANOTHER(other,node,0);
+
+ dom_exception err;
+ dom_node *spare;
+
+ err = dom_node_append_child(priv->node, other->node, &spare);
+ if (err != DOM_NO_ERR) return 0;
+ dom_node_unref(spare);
%}
-getter Node::aprop()
+getter Node::textContent()
%{
+ dom_exception exc;
+ dom_string *content;
+
+ exc = dom_node_get_text_content(priv->node, &content);
+ if (exc != DOM_NO_ERR) {
+ return 0;
+ }
+
+ if (content != NULL) {
+ duk_push_lstring(ctx, dom_string_data(content), dom_string_length(content));
+ dom_string_unref(content);
+ return 1;
+ }
%}
-setter Node::aprop()
+setter Node::textContent()
%{
%}
--
NetSurf Generator for JavaScript bindings
8 years, 2 months