netsurf-website: branch master updated. 3f189f1d8a5107d5d5e4f8ff8b461f7c1ec33a30
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf-website.git/shortlog/3f189f1d8a510...
...commit http://git.netsurf-browser.org/netsurf-website.git/commit/3f189f1d8a5107d...
...tree http://git.netsurf-browser.org/netsurf-website.git/tree/3f189f1d8a5107d5d...
The branch, master has been updated
via 3f189f1d8a5107d5d5e4f8ff8b461f7c1ec33a30 (commit)
from 731fe1475abf4b4b189eb06eaffa57943eebaeae (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/netsurf-website.git/commit/?id=3f189f1d8a5...
commit 3f189f1d8a5107d5d5e4f8ff8b461f7c1ec33a30
Author: Michael Drake <michael.drake(a)codethink.co.uk>
Commit: Michael Drake <michael.drake(a)codethink.co.uk>
Update Tinct project status.
diff --git a/projects/projects.css b/projects/projects.css
index 3e20d20..124b042 100644
--- a/projects/projects.css
+++ b/projects/projects.css
@@ -72,10 +72,6 @@ ul ul {
ul p {
margin: 0 1.8em 0.1em 1em; }
-strong {
- color: #800;
- font-weight: bold; }
-
dl.instructions {
margin: 0 1.8em;
padding: 0; }
@@ -130,41 +126,24 @@ dl.changes {
dl.changes > dd > ul {
margin: 0.2em 0 0.6em 0; }
-div.testimonial {
- position: relative;
- float: right;
- font-family: Garamond, Times, serif;
- background: #fdb;
- margin: 1em;
- padding: 0;
- max-width: 33%; }
+div.notice {
+ width: 14cm;
+ border: 2px solid #500;
+ margin: 1.3em auto;
+}
-div.testimonial > div {
- position: relative;
+div.notice h3:first-child {
margin: 0;
- padding: 0.2em 0.2em; }
-
-div.testimonial > div > span {
- position:absolute;
- font-size: 400%;
- left: 0.2em;
- top: 0; }
-
-div.testimonial > div > p {
- background: #ffd;
- padding: 1em 1.3em; }
+ padding: 0.3em 0.5cm;
+ font-weight: bold;
+ background: #500;
+ color: #ffd;
+}
-div.testimonial > div > p + span {
- float: right;
- position: relative;
- left: -0.2em;
- top: -0.4em; }
-
-div.testimonial > p {
- font-size: 90%;
- text-align: right;
- margin: 2em 0 0 0;
- padding: 0; }
+div.notice p {
+ line-height: 1.4;
+ margin: 1em 0.5cm;
+}
p.screenshot {
float: right;
diff --git a/projects/tinct/index.html b/projects/tinct/index.html
index a535d8f..635cddc 100644
--- a/projects/tinct/index.html
+++ b/projects/tinct/index.html
@@ -3,7 +3,7 @@
<html>
<head>
<title>Tinct for RISC OS</title>
-<link rel="stylesheet" type="text/css" href="/projects/projects.css">
+<link rel="stylesheet" type="text/css" href="../../projects/projects.css">
<link rel="icon" type="image/png" href="/webimages/favicon.png">
</head>
<body>
@@ -33,6 +33,21 @@
<h2>What is Tinct?</h2>
+<div class="notice">
+<h3>Warning</h3>
+<p>Tinct is a closed-source proprietary module that is best considered
+licence-encumbered abandonware. It cannot be updated to work properly
+on modern RISC OS hardware.<p>
+</div>
+
+<div class="notice">
+<h3>Notice</h3>
+<p>Anyone interested in developing a new efficient <strong>open-source</strong>
+sprite rendering module that can render sprites with alpha channels, and
+supports error diffusion for low bits-per-pixel screen modes should please get
+in touch.</p>
+</div>
+
<p>Tinct provides RISC OS applications with support for high speed rendering of opaque and alpha-blended sprites with optional image enhancement. It was developed to enable NetSurf to plot PNGs with alpha channels and provide on-the-fly error diffusion to display images at their best in screen modes with few colours.</p>
<h2>Download</h2>
-----------------------------------------------------------------------
Summary of changes:
projects/projects.css | 51 +++++++++++++--------------------------------
projects/tinct/index.html | 17 ++++++++++++++-
2 files changed, 31 insertions(+), 37 deletions(-)
diff --git a/projects/projects.css b/projects/projects.css
index 3e20d20..124b042 100644
--- a/projects/projects.css
+++ b/projects/projects.css
@@ -72,10 +72,6 @@ ul ul {
ul p {
margin: 0 1.8em 0.1em 1em; }
-strong {
- color: #800;
- font-weight: bold; }
-
dl.instructions {
margin: 0 1.8em;
padding: 0; }
@@ -130,41 +126,24 @@ dl.changes {
dl.changes > dd > ul {
margin: 0.2em 0 0.6em 0; }
-div.testimonial {
- position: relative;
- float: right;
- font-family: Garamond, Times, serif;
- background: #fdb;
- margin: 1em;
- padding: 0;
- max-width: 33%; }
+div.notice {
+ width: 14cm;
+ border: 2px solid #500;
+ margin: 1.3em auto;
+}
-div.testimonial > div {
- position: relative;
+div.notice h3:first-child {
margin: 0;
- padding: 0.2em 0.2em; }
-
-div.testimonial > div > span {
- position:absolute;
- font-size: 400%;
- left: 0.2em;
- top: 0; }
-
-div.testimonial > div > p {
- background: #ffd;
- padding: 1em 1.3em; }
+ padding: 0.3em 0.5cm;
+ font-weight: bold;
+ background: #500;
+ color: #ffd;
+}
-div.testimonial > div > p + span {
- float: right;
- position: relative;
- left: -0.2em;
- top: -0.4em; }
-
-div.testimonial > p {
- font-size: 90%;
- text-align: right;
- margin: 2em 0 0 0;
- padding: 0; }
+div.notice p {
+ line-height: 1.4;
+ margin: 1em 0.5cm;
+}
p.screenshot {
float: right;
diff --git a/projects/tinct/index.html b/projects/tinct/index.html
index a535d8f..635cddc 100644
--- a/projects/tinct/index.html
+++ b/projects/tinct/index.html
@@ -3,7 +3,7 @@
<html>
<head>
<title>Tinct for RISC OS</title>
-<link rel="stylesheet" type="text/css" href="/projects/projects.css">
+<link rel="stylesheet" type="text/css" href="../../projects/projects.css">
<link rel="icon" type="image/png" href="/webimages/favicon.png">
</head>
<body>
@@ -33,6 +33,21 @@
<h2>What is Tinct?</h2>
+<div class="notice">
+<h3>Warning</h3>
+<p>Tinct is a closed-source proprietary module that is best considered
+licence-encumbered abandonware. It cannot be updated to work properly
+on modern RISC OS hardware.<p>
+</div>
+
+<div class="notice">
+<h3>Notice</h3>
+<p>Anyone interested in developing a new efficient <strong>open-source</strong>
+sprite rendering module that can render sprites with alpha channels, and
+supports error diffusion for low bits-per-pixel screen modes should please get
+in touch.</p>
+</div>
+
<p>Tinct provides RISC OS applications with support for high speed rendering of opaque and alpha-blended sprites with optional image enhancement. It was developed to enable NetSurf to plot PNGs with alpha channels and provide on-the-fly error diffusion to display images at their best in screen modes with few colours.</p>
<h2>Download</h2>
--
NetSurf website source for *.netsurf-browser.org
1 year, 11 months
libcss: branch master updated. release/0.9.1-26-gaccad49
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libcss.git/shortlog/accad499aed29acb7bc8fb...
...commit http://git.netsurf-browser.org/libcss.git/commit/accad499aed29acb7bc8fb00...
...tree http://git.netsurf-browser.org/libcss.git/tree/accad499aed29acb7bc8fb00be...
The branch, master has been updated
via accad499aed29acb7bc8fb00bea3d9f2b7f43bd1 (commit)
from 55017b90bc6927bf3a4d4056c04b242e1cc6c2ac (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/libcss.git/commit/?id=accad499aed29acb7bc8...
commit accad499aed29acb7bc8fb00bea3d9f2b7f43bd1
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Tests: Select test runner: Avoid forward declarations.
diff --git a/test/select.c b/test/select.c
index c104b38..5bc7856 100644
--- a/test/select.c
+++ b/test/select.c
@@ -70,1607 +70,1509 @@ typedef struct line_ctx {
lwc_string *attr_id;
} line_ctx;
+static css_error node_name(void *pw, void *n, css_qname *qname)
+{
+ node *node = n;
+ UNUSED(pw);
+ qname->name = lwc_string_ref(node->name);
-static bool handle_line(const char *data, size_t datalen, void *pw);
-static void css__parse_tree(line_ctx *ctx, const char *data, size_t len);
-static void css__parse_tree_data(line_ctx *ctx, const char *data, size_t len);
-static void css__parse_sheet(line_ctx *ctx, const char *data, size_t len);
-static void css__parse_media_list(const char **data, size_t *len, css_media *media);
-static void css__parse_pseudo_list(const char **data, size_t *len,
- uint32_t *element);
-static void css__parse_expected(line_ctx *ctx, const char *data, size_t len);
-static void run_test(line_ctx *ctx, const char *exp, size_t explen);
-static void destroy_tree(node *root);
+ return CSS_OK;
+}
-static css_error node_name(void *pw, void *node,
- css_qname *qname);
static css_error node_classes(void *pw, void *n,
- lwc_string ***classes, uint32_t *n_classes);
-static css_error node_id(void *pw, void *node,
- lwc_string **id);
-static css_error named_ancestor_node(void *pw, void *node,
- const css_qname *qname,
- void **ancestor);
-static css_error named_parent_node(void *pw, void *node,
- const css_qname *qname,
- void **parent);
-static css_error named_sibling_node(void *pw, void *node,
- const css_qname *qname,
- void **sibling);
-static css_error named_generic_sibling_node(void *pw, void *node,
- const css_qname *qname,
- void **sibling);
-static css_error parent_node(void *pw, void *node, void **parent);
-static css_error sibling_node(void *pw, void *node, void **sibling);
-static css_error node_has_name(void *pw, void *node,
- const css_qname *qname,
- bool *match);
-static css_error node_has_class(void *pw, void *node,
- lwc_string *name,
- bool *match);
-static css_error node_has_id(void *pw, void *node,
- lwc_string *name,
- bool *match);
-static css_error node_has_attribute(void *pw, void *node,
- const css_qname *qname,
- bool *match);
-static css_error node_has_attribute_equal(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_dashmatch(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_includes(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_prefix(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_suffix(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_substring(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_is_root(void *pw, void *node, bool *match);
-static css_error node_count_siblings(void *pw, void *node,
- bool same_name, bool after, int32_t *count);
-static css_error node_is_empty(void *pw, void *node, bool *match);
-static css_error node_is_link(void *pw, void *node, bool *match);
-static css_error node_is_visited(void *pw, void *node, bool *match);
-static css_error node_is_hover(void *pw, void *node, bool *match);
-static css_error node_is_active(void *pw, void *node, bool *match);
-static css_error node_is_focus(void *pw, void *node, bool *match);
-static css_error node_is_enabled(void *pw, void *node, bool *match);
-static css_error node_is_disabled(void *pw, void *node, bool *match);
-static css_error node_is_checked(void *pw, void *node, bool *match);
-static css_error node_is_target(void *pw, void *node, bool *match);
-static css_error node_is_lang(void *pw, void *node,
- lwc_string *lang, bool *match);
-static css_error node_presentational_hint(void *pw, void *node,
- uint32_t *nhints, css_hint **hints);
-static css_error ua_default_for_property(void *pw, uint32_t property,
- css_hint *hints);
-static css_error set_libcss_node_data(void *pw, void *n,
- void *libcss_node_data);
-static css_error get_libcss_node_data(void *pw, void *n,
- void **libcss_node_data);
+ lwc_string ***classes, uint32_t *n_classes)
+{
+ unsigned int i;
+ node *node = n;
+ UNUSED(pw);
-static css_unit_ctx unit_ctx = {
- .font_size_default = 16 * (1 << CSS_RADIX_POINT),
-};
+ *classes = node->classes;
+ *n_classes = node->n_classes;
-static css_select_handler select_handler = {
- CSS_SELECT_HANDLER_VERSION_1,
+ for (i = 0; i < *n_classes; i++)
+ (*classes)[i] = lwc_string_ref(node->classes[i]);
- node_name,
- node_classes,
- node_id,
- named_ancestor_node,
- named_parent_node,
- named_sibling_node,
- named_generic_sibling_node,
- parent_node,
- sibling_node,
- node_has_name,
- node_has_class,
- node_has_id,
- node_has_attribute,
- node_has_attribute_equal,
- node_has_attribute_dashmatch,
- node_has_attribute_includes,
- node_has_attribute_prefix,
- node_has_attribute_suffix,
- node_has_attribute_substring,
- node_is_root,
- node_count_siblings,
- node_is_empty,
- node_is_link,
- node_is_visited,
- node_is_hover,
- node_is_active,
- node_is_focus,
- node_is_enabled,
- node_is_disabled,
- node_is_checked,
- node_is_target,
- node_is_lang,
- node_presentational_hint,
- ua_default_for_property,
+ return CSS_OK;
- set_libcss_node_data,
- get_libcss_node_data,
-};
+}
-static css_error resolve_url(void *pw,
- const char *base, lwc_string *rel, lwc_string **abs)
+static css_error node_id(void *pw, void *n,
+ lwc_string **id)
+{
+ node *node = n;
+ uint32_t i;
+ line_ctx *lc = pw;
+
+ for (i = 0; i < node->n_attrs; i++) {
+ bool amatch = false;
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, lc->attr_id, &amatch) ==
+ lwc_error_ok);
+ if (amatch == true)
+ break;
+ }
+
+ if (i != node->n_attrs)
+ *id = lwc_string_ref(node->attrs[i].value);
+ else
+ *id = NULL;
+
+ return CSS_OK;
+}
+
+static css_error named_ancestor_node(void *pw, void *n,
+ const css_qname *qname,
+ void **ancestor)
{
+ node *node = n;
UNUSED(pw);
- UNUSED(base);
- /* About as useless as possible */
- *abs = lwc_string_ref(rel);
+ for (node = node->parent; node != NULL; node = node->parent) {
+ bool match = false;
+ assert(lwc_string_caseless_isequal(
+ qname->name, node->name,
+ &match) == lwc_error_ok);
+ if (match == true)
+ break;
+ }
+
+ *ancestor = (void *) node;
return CSS_OK;
}
-static bool fail_because_lwc_leaked = false;
+static css_error named_parent_node(void *pw, void *n,
+ const css_qname *qname,
+ void **parent)
+{
+ node *node = n;
+ UNUSED(pw);
-static void
-printing_lwc_iterator(lwc_string *str, void *pw)
+ *parent = NULL;
+ if (node->parent != NULL) {
+ bool match = false;
+ assert(lwc_string_caseless_isequal(
+ qname->name, node->parent->name, &match) ==
+ lwc_error_ok);
+ if (match == true)
+ *parent = (void *) node->parent;
+ }
+
+ return CSS_OK;
+}
+
+static css_error named_sibling_node(void *pw, void *n,
+ const css_qname *qname,
+ void **sibling)
{
+ node *node = n;
UNUSED(pw);
- printf(" DICT: %*s\n", (int)(lwc_string_length(str)), lwc_string_data(str));
- fail_because_lwc_leaked = true;
+ *sibling = NULL;
+ if (node->prev != NULL) {
+ bool match = false;
+ assert(lwc_string_caseless_isequal(
+ qname->name, node->prev->name, &match) ==
+ lwc_error_ok);
+ if (match == true)
+ *sibling = (void *) node->prev;
+ }
+
+ return CSS_OK;
}
-int main(int argc, char **argv)
+static css_error named_generic_sibling_node(void *pw, void *n,
+ const css_qname *qname,
+ void **sibling)
{
- line_ctx ctx;
+ node *node = n;
+ UNUSED(pw);
- if (argc != 2) {
- printf("Usage: %s <filename>\n", argv[0]);
- return 1;
+ for (node = node->prev; node != NULL; node = node->prev) {
+ bool match = false;
+ assert(lwc_string_caseless_isequal(
+ qname->name, node->name,
+ &match) == lwc_error_ok);
+ if (match == true)
+ break;
}
- memset(&ctx, 0, sizeof(ctx));
+ *sibling = (void *) node;
+ return CSS_OK;
+}
- lwc_intern_string("class", SLEN("class"), &ctx.attr_class);
- lwc_intern_string("id", SLEN("id"), &ctx.attr_id);
+static css_error parent_node(void *pw, void *n, void **parent)
+{
+ node *node = n;
- assert(css__parse_testfile(argv[1], handle_line, &ctx) == true);
+ UNUSED(pw);
- /* and run final test */
- if (ctx.tree != NULL)
- run_test(&ctx, ctx.exp, ctx.expused);
+ *parent = (void *) node->parent;
- free(ctx.exp);
+ return CSS_OK;
+}
- lwc_string_unref(ctx.attr_class);
- lwc_string_unref(ctx.attr_id);
+static css_error sibling_node(void *pw, void *n, void **sibling)
+{
+ node *node = n;
- lwc_iterate_strings(printing_lwc_iterator, NULL);
+ UNUSED(pw);
- assert(fail_because_lwc_leaked == false);
+ *sibling = (void *) node->prev;
- printf("PASS\n");
- return 0;
+ return CSS_OK;
}
-bool handle_line(const char *data, size_t datalen, void *pw)
+static css_error node_has_name(void *pw, void *n,
+ const css_qname *qname,
+ bool *match)
{
- line_ctx *ctx = (line_ctx *) pw;
- css_error error;
+ node *node = n;
+ UNUSED(pw);
- if (data[0] == '#') {
- if (ctx->intree) {
- if (strncasecmp(data+1, "errors", 6) == 0) {
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = true;
- ctx->inexp = false;
- } else {
- /* Assume start of stylesheet */
- css__parse_sheet(ctx, data + 1, datalen - 1);
+ if (lwc_string_length(qname->name) == 1 &&
+ lwc_string_data(qname->name)[0] == '*')
+ *match = true;
+ else
+ assert(lwc_string_caseless_isequal(node->name,
+ qname->name, match) == lwc_error_ok);
- ctx->intree = false;
- ctx->insheet = true;
- ctx->inerrors = false;
- ctx->inexp = false;
- }
- } else if (ctx->insheet) {
- if (strncasecmp(data+1, "errors", 6) == 0) {
- assert(css_stylesheet_data_done(
- ctx->sheets[ctx->n_sheets - 1].sheet)
- == CSS_OK);
+ return CSS_OK;
+}
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = true;
- ctx->inexp = false;
- } else if (strncasecmp(data+1, "ua", 2) == 0 ||
- strncasecmp(data+1, "user", 4) == 0 ||
- strncasecmp(data+1, "author", 6) == 0) {
- assert(css_stylesheet_data_done(
- ctx->sheets[ctx->n_sheets - 1].sheet)
- == CSS_OK);
+static css_error node_has_class(void *pw, void *n,
+ lwc_string *name,
+ bool *match)
+{
+ node *node = n;
+ uint32_t i;
+ line_ctx *ctx = pw;
- css__parse_sheet(ctx, data + 1, datalen - 1);
- } else {
- error = css_stylesheet_append_data(
- ctx->sheets[ctx->n_sheets - 1].sheet,
- (const uint8_t *) data,
- datalen);
- assert(error == CSS_OK ||
- error == CSS_NEEDDATA);
- }
- } else if (ctx->inerrors) {
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = false;
- ctx->inexp = true;
- } else if (ctx->inexp) {
- /* This marks end of testcase, so run it */
- run_test(ctx, ctx->exp, ctx->expused);
-
- ctx->expused = 0;
-
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = false;
- ctx->inexp = false;
- } else {
- /* Start state */
- if (strncasecmp(data+1, "tree", 4) == 0) {
- css__parse_tree(ctx, data + 5, datalen - 5);
-
- ctx->intree = true;
- ctx->insheet = false;
- ctx->inerrors = false;
- ctx->inexp = false;
- }
- }
- } else {
- if (ctx->intree) {
- /* Not interested in the '|' */
- css__parse_tree_data(ctx, data + 1, datalen - 1);
- } else if (ctx->insheet) {
- error = css_stylesheet_append_data(
- ctx->sheets[ctx->n_sheets - 1].sheet,
- (const uint8_t *) data, datalen);
- assert(error == CSS_OK || error == CSS_NEEDDATA);
- } else if (ctx->inexp) {
- css__parse_expected(ctx, data, datalen);
- }
+ for (i = 0; i < node->n_attrs; i++) {
+ bool amatch = false;
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, ctx->attr_class,
+ &amatch) == lwc_error_ok);
+ if (amatch == true)
+ break;
}
- return true;
+ /* Classes are case-sensitive in HTML */
+ if (i != node->n_attrs && name == node->attrs[i].value)
+ *match = true;
+ else
+ *match = false;
+
+ return CSS_OK;
}
-void css__parse_tree(line_ctx *ctx, const char *data, size_t len)
+static css_error node_has_id(void *pw, void *n,
+ lwc_string *name,
+ bool *match)
{
- const char *p = data;
- const char *end = data + len;
- size_t left;
-
- /* [ <media_list> <pseudo>? ] ? */
-
- ctx->media.type = CSS_MEDIA_ALL;
- ctx->pseudo_element = CSS_PSEUDO_ELEMENT_NONE;
-
- /* Consume any leading whitespace */
- while (p < end && isspace(*p))
- p++;
-
- if (p < end) {
- left = end - p;
-
- css__parse_media_list(&p, &left, &ctx->media);
+ node *node = n;
+ uint32_t i;
+ line_ctx *ctx = pw;
- end = p + left;
+ for (i = 0; i < node->n_attrs; i++) {
+ bool amatch = false;
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, ctx->attr_id, &amatch) ==
+ lwc_error_ok);
+ if (amatch == true)
+ break;
}
- if (p < end) {
- left = end - p;
+ /* IDs are case-sensitive in HTML */
+ if (i != node->n_attrs && name == node->attrs[i].value)
+ *match = true;
+ else
+ *match = false;
- css__parse_pseudo_list(&p, &left, &ctx->pseudo_element);
- }
+ return CSS_OK;
}
-void css__parse_tree_data(line_ctx *ctx, const char *data, size_t len)
+static css_error node_has_attribute(void *pw, void *n,
+ const css_qname *qname,
+ bool *match)
{
- const char *p = data;
- const char *end = data + len;
- const char *name = NULL;
- const char *value = NULL;
- size_t namelen = 0;
- size_t valuelen = 0;
- uint32_t depth = 0;
- bool target = false;
-
- /* ' '{depth+1} [ <element> '*'? | <attr> ]
- *
- * <element> ::= [^=*[:space:]]+
- * <attr> ::= [^=*[:space:]]+ '=' [^[:space:]]*
- */
-
- while (p < end && isspace(*p)) {
- depth++;
- p++;
- }
- depth--;
-
- /* Get element/attribute name */
- name = p;
- while (p < end && *p != '=' && *p != '*' && isspace(*p) == false) {
- namelen++;
- p++;
- }
-
- /* Skip whitespace */
- while (p < end && isspace(*p))
- p++;
-
- if (p < end && *p == '=') {
- /* Attribute value */
- p++;
-
- value = p;
-
- while (p < end && isspace(*p) == false) {
- valuelen++;
- p++;
- }
- } else if (p < end && *p == '*') {
- /* Element is target node */
- target = true;
- }
-
- if (value == NULL) {
- /* We have an element, so create it */
- node *n = malloc(sizeof(node));
- assert(n != NULL);
-
- memset(n, 0, sizeof(node));
-
- lwc_intern_string(name, namelen, &n->name);
-
- /* Insert it into tree */
- if (ctx->tree == NULL) {
- ctx->tree = n;
- } else {
- assert(depth > 0);
- assert(depth <= ctx->depth + 1);
-
- /* Find node to insert into */
- while (depth <= ctx->depth) {
- ctx->depth--;
- ctx->current = ctx->current->parent;
- }
-
- /* Insert into current node */
- if (ctx->current->children == NULL) {
- ctx->current->children = n;
- ctx->current->last_child = n;
- } else {
- ctx->current->last_child->next = n;
- n->prev = ctx->current->last_child;
-
- ctx->current->last_child = n;
- }
- n->parent = ctx->current;
- }
-
- ctx->current = n;
- ctx->depth = depth;
-
- /* Mark the target, if it's us */
- if (target)
- ctx->target = n;
- } else {
- /* New attribute */
- bool amatch = false;
- attribute *attr;
- node *n = ctx->current;
-
- attribute *temp = realloc(n->attrs,
- (n->n_attrs + 1) * sizeof(attribute));
- assert(temp != NULL);
-
- n->attrs = temp;
-
- attr = &n->attrs[n->n_attrs];
-
- lwc_intern_string(name, namelen, &attr->name);
- lwc_intern_string(value, valuelen, &attr->value);
+ node *node = n;
+ uint32_t i;
+ UNUSED(pw);
+ *match = false;
+ for (i = 0; i < node->n_attrs; i++) {
assert(lwc_string_caseless_isequal(
- n->attrs[n->n_attrs].name,
- ctx->attr_class, &amatch) == lwc_error_ok);
- if (amatch == true) {
- n->classes = realloc(NULL, sizeof(lwc_string **));
- assert(n->classes != NULL);
-
- n->classes[0] = lwc_string_ref(
- n->attrs[n->n_attrs].
- value);
- n->n_classes = 1;
- }
-
- n->n_attrs++;
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
+ break;
}
+
+ return CSS_OK;
}
-static css_error css_font_resolution_func(void *pw, lwc_string *name,
- css_system_font *system_font)
+static css_error node_has_attribute_equal(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
{
- lwc_error err;
-
- if (system_font == NULL) {
- return CSS_BADPARM;
- }
+ node *node = n;
+ uint32_t i;
+ UNUSED(pw);
- (void)(pw);
+ *match = false;
- if (strncmp(lwc_string_data(name), "special-system-font",
- lwc_string_length(name)) != 0) {
- return CSS_INVALID;
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
+ break;
}
- system_font->style = CSS_FONT_STYLE_NORMAL;
- system_font->variant = CSS_FONT_VARIANT_NORMAL;
- system_font->weight = CSS_FONT_WEIGHT_NORMAL;
- system_font->size.size = INTTOFIX(22);
- system_font->size.unit = CSS_UNIT_PT;
- system_font->line_height.size = INTTOFIX(33);
- system_font->line_height.unit = CSS_UNIT_EM;
- err = lwc_intern_string("special-system-font",
- strlen("special-system-font"),
- &system_font->family);
- if (err != lwc_error_ok) {
- return CSS_NOMEM;
+ if (*match == true) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, value, match) ==
+ lwc_error_ok);
}
return CSS_OK;
}
-void css__parse_sheet(line_ctx *ctx, const char *data, size_t len)
+static css_error node_has_attribute_includes(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
{
- css_stylesheet_params params;
- const char *p;
- const char *end = data + len;
- css_origin origin = CSS_ORIGIN_AUTHOR;
- css_stylesheet *sheet;
- sheet_ctx *temp;
- char *media = NULL;
+ node *node = n;
+ uint32_t i;
+ size_t vlen = lwc_string_length(value);
+ UNUSED(pw);
- /* <origin> <media_list>? */
+ *match = false;
- /* Find end of origin */
- for (p = data; p < end; p++) {
- if (isspace(*p))
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
break;
}
- if (p - data == 6 && strncasecmp(data, "author", 6) == 0)
- origin = CSS_ORIGIN_AUTHOR;
- else if (p - data == 4 && strncasecmp(data, "user", 4) == 0)
- origin = CSS_ORIGIN_USER;
- else if (p - data == 2 && strncasecmp(data, "ua", 2) == 0)
- origin = CSS_ORIGIN_UA;
- else
- assert(0 && "Unknown stylesheet origin");
-
- /* Skip any whitespace */
- while (p < end && isspace(*p))
- p++;
-
- assert(end >= p);
- media = malloc(end - p + 1);
- assert(media != NULL);
- memcpy(media, p, end - p);
- media[end - p] = '\0';
-
- 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 = css_font_resolution_func;
- params.font_pw = NULL;
-
- /** \todo How are we going to handle @import? */
- assert(css_stylesheet_create(¶ms, &sheet) == CSS_OK);
-
- /* Extend array of sheets and append new sheet to it */
- temp = realloc(ctx->sheets,
- (ctx->n_sheets + 1) * sizeof(sheet_ctx));
- assert(temp != NULL);
-
- ctx->sheets = temp;
-
- ctx->sheets[ctx->n_sheets].sheet = sheet;
- ctx->sheets[ctx->n_sheets].origin = origin;
- ctx->sheets[ctx->n_sheets].media = media;
-
- ctx->n_sheets++;
-}
-
-void css__parse_media_list(const char **data, size_t *len, css_media *media)
-{
- const char *p = *data;
- const char *end = p + *len;
- uint64_t result = 0;
-
- /* <medium> [ ',' <medium> ]* */
-
- while (p < end) {
- const char *start = p;
+ if (*match == true) {
+ const char *p;
+ const char *start = lwc_string_data(node->attrs[i].value);
+ const char *end = start +
+ lwc_string_length(node->attrs[i].value);
- /* consume a medium */
- while (isspace(*p) == false && *p != ',')
- p++;
+ *match = false;
- if (p - start == 10 &&
- strncasecmp(start, "projection", 10) == 0)
- result |= CSS_MEDIA_PROJECTION;
- else if (p - start == 8 &&
- strncasecmp(start, "handheld", 8) == 0)
- result |= CSS_MEDIA_HANDHELD;
- else if (p - start == 8 &&
- strncasecmp(start, "embossed", 8) == 0)
- result |= CSS_MEDIA_EMBOSSED;
- else if (p - start == 7 &&
- strncasecmp(start, "braille", 7) == 0)
- result |= CSS_MEDIA_BRAILLE;
- else if (p - start == 6 &&
- strncasecmp(start, "speech", 6) == 0)
- result |= CSS_MEDIA_SPEECH;
- else if (p - start == 6 &&
- strncasecmp(start, "screen", 6) == 0)
- result |= CSS_MEDIA_SCREEN;
- else if (p - start == 5 &&
- strncasecmp(start, "print", 5) == 0)
- result |= CSS_MEDIA_PRINT;
- else if (p - start == 5 &&
- strncasecmp(start, "aural", 5) == 0)
- result |= CSS_MEDIA_AURAL;
- else if (p - start == 3 &&
- strncasecmp(start, "tty", 3) == 0)
- result |= CSS_MEDIA_TTY;
- else if (p - start == 3 &&
- strncasecmp(start, "all", 3) == 0)
- result |= CSS_MEDIA_ALL;
- else if (p - start == 2 &&
- strncasecmp(start, "tv", 2) == 0)
- result |= CSS_MEDIA_TV;
- else
- assert(0 && "Unknown media type");
+ for (p = start; p < end; p++) {
+ if (*p == ' ') {
+ if ((size_t) (p - start) == vlen &&
+ strncasecmp(start,
+ lwc_string_data(value),
+ vlen) == 0) {
+ *match = true;
+ break;
+ }
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
+ start = p + 1;
+ }
+ }
+ }
- /* Stop if we've reached the end */
- if (p == end || *p != ',')
- break;
+ return CSS_OK;
+}
- /* Consume comma */
- p++;
+static css_error node_has_attribute_dashmatch(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
+{
+ node *node = n;
+ uint32_t i;
+ size_t vlen = lwc_string_length(value);
+ UNUSED(pw);
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
+ *match = false;
+
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
+ break;
}
- media->type = result;
+ if (*match == true) {
+ const char *p;
+ const char *start = lwc_string_data(node->attrs[i].value);
+ const char *end = start +
+ lwc_string_length(node->attrs[i].value);
- *data = p;
- *len = end - p;
+ *match = false;
+
+ for (p = start; p < end; p++) {
+ if (*p == '-') {
+ if ((size_t) (p - start) == vlen &&
+ strncasecmp(start,
+ lwc_string_data(value),
+ vlen) == 0) {
+ *match = true;
+ break;
+ }
+
+ start = p + 1;
+ }
+ }
+ }
+
+ return CSS_OK;
}
-void css__parse_pseudo_list(const char **data, size_t *len, uint32_t *element)
+static css_error node_has_attribute_prefix(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
{
- const char *p = *data;
- const char *end = p + *len;
+ node *node = n;
+ uint32_t i;
+ UNUSED(pw);
- /* <pseudo> [ ',' <pseudo> ]* */
+ *match = false;
- *element = CSS_PSEUDO_ELEMENT_NONE;
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
+ break;
+ }
- while (p < end) {
- const char *start = p;
+ if (*match == true) {
+ size_t len = lwc_string_length(node->attrs[i].value);
+ const char *data = lwc_string_data(node->attrs[i].value);
- /* consume a pseudo */
- while (isspace(*p) == false && *p != ',')
- p++;
+ size_t vlen = lwc_string_length(value);
+ const char *vdata = lwc_string_data(value);
- /* Pseudo elements */
- if (p - start == 12 &&
- strncasecmp(start, "first-letter", 12) == 0)
- *element = CSS_PSEUDO_ELEMENT_FIRST_LETTER;
- else if (p - start == 10 &&
- strncasecmp(start, "first-line", 10) == 0)
- *element = CSS_PSEUDO_ELEMENT_FIRST_LINE;
- else if (p - start == 6 &&
- strncasecmp(start, "before", 6) == 0)
- *element = CSS_PSEUDO_ELEMENT_BEFORE;
- else if (p - start == 5 &&
- strncasecmp(start, "after", 5) == 0)
- *element = CSS_PSEUDO_ELEMENT_AFTER;
+ if (len < vlen)
+ *match = false;
else
- assert(0 && "Unknown pseudo");
+ *match = (strncasecmp(data, vdata, vlen) == 0);
+ }
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
+ return CSS_OK;
+}
- /* Stop if we've reached the end */
- if (p == end || *p != ',')
+static css_error node_has_attribute_suffix(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
+{
+ node *node = n;
+ uint32_t i;
+ UNUSED(pw);
+
+ *match = false;
+
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
break;
+ }
- /* Consume comma */
- p++;
+ if (*match == true) {
+ size_t len = lwc_string_length(node->attrs[i].value);
+ const char *data = lwc_string_data(node->attrs[i].value);
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
+ size_t vlen = lwc_string_length(value);
+ const char *vdata = lwc_string_data(value);
+
+ size_t suffix_start = len - vlen;
+
+ if (len < vlen)
+ *match = false;
+ else {
+ *match = (strncasecmp(data + suffix_start,
+ vdata, vlen) == 0);
+ }
}
- *data = p;
- *len = end - p;
+ return CSS_OK;
}
-void css__parse_expected(line_ctx *ctx, const char *data, size_t len)
+static css_error node_has_attribute_substring(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
{
- while (ctx->expused + len >= ctx->explen) {
- size_t required = ctx->explen == 0 ? 64 : ctx->explen * 2;
- char *temp = realloc(ctx->exp, required);
- if (temp == NULL) {
- assert(0 && "No memory for expected output");
- }
+ node *node = n;
+ uint32_t i;
+ UNUSED(pw);
- ctx->exp = temp;
- ctx->explen = required;
+ *match = false;
+
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
+ break;
}
- memcpy(ctx->exp + ctx->expused, data, len);
+ if (*match == true) {
+ size_t len = lwc_string_length(node->attrs[i].value);
+ const char *data = lwc_string_data(node->attrs[i].value);
- ctx->expused += len;
-}
+ size_t vlen = lwc_string_length(value);
+ const char *vdata = lwc_string_data(value);
-static void show_differences(size_t len, const char *exp, const char *res)
-{
- const char *pos_exp, *opos_exp;
- const char *pos_res, *opos_res;
+ const char *last_start = data + len - vlen;
- opos_exp = pos_exp = exp;
- opos_res = pos_res = res;
+ if (len < vlen)
+ *match = false;
+ else {
+ while (data <= last_start) {
+ if (strncasecmp(data, vdata, vlen) == 0) {
+ *match = true;
+ break;
+ }
- printf("Line differences:\n");
- while (pos_exp < exp + len && pos_res < res + len) {
- if (*pos_exp == '\n' && *pos_res == '\n') {
- if (pos_exp - opos_exp != pos_res - opos_res ||
- memcmp(opos_exp, opos_res,
- pos_exp - opos_exp) != 0) {
- printf("Expected:\t%.*s\n",
- (int)(pos_exp - opos_exp),
- opos_exp);
- printf(" Result:\t%.*s\n",
- (int)(pos_res - opos_res),
- opos_res);
- printf("\n");
+ data++;
}
- opos_exp = ++pos_exp;
- opos_res = ++pos_res;
- } else if (*pos_exp == '\n') {
- pos_res++;
- } else if (*pos_res == '\n') {
- pos_exp++;
- } else {
- pos_exp++;
- pos_res++;
+
+ if (data > last_start)
+ *match = false;
}
}
+
+ return CSS_OK;
}
+static css_error node_is_root(void *pw, void *n, bool *match)
+{
+ node *node = n;
+ UNUSED(pw);
-static void run_test_select_tree(css_select_ctx *select,
- node *node, line_ctx *ctx,
- char *buf, size_t *buflen)
+ *match = (node->parent == NULL);
+
+ return CSS_OK;
+}
+
+static css_error node_count_siblings(void *pw, void *n,
+ bool same_name, bool after, int32_t *count)
{
- css_select_results *sr;
- struct node *n = NULL;
+ int32_t cnt = 0;
+ bool match = false;
+ node *node = n;
+ lwc_string *name = node->name;
+ UNUSED(pw);
- if (node->parent == NULL) {
- unit_ctx.root_style = NULL;
- }
+ if (after) {
+ while (node->next != NULL) {
+ if (same_name) {
+ assert(lwc_string_caseless_isequal(
+ name, node->next->name, &match) ==
+ lwc_error_ok);
+
+ if (match)
+ cnt++;
+ } else {
+ cnt++;
+ }
+ node = node->next;
+ }
+ } else {
+ while (node->prev != NULL) {
+ if (same_name) {
+ assert(lwc_string_caseless_isequal(
+ name, node->prev->name, &match) ==
+ lwc_error_ok);
- assert(css_select_style(select, node, &unit_ctx, &ctx->media, NULL,
- &select_handler, ctx, &sr) == CSS_OK);
+ if (match)
+ cnt++;
+ } else {
+ cnt++;
+ }
- if (node->parent != NULL) {
- css_computed_style *composed;
- assert(css_computed_style_compose(
- node->parent->sr->styles[ctx->pseudo_element],
- sr->styles[ctx->pseudo_element],
- &unit_ctx,
- &composed) == CSS_OK);
- css_computed_style_destroy(sr->styles[ctx->pseudo_element]);
- sr->styles[ctx->pseudo_element] = composed;
+ node = node->prev;
+ }
}
- node->sr = sr;
+ *count = cnt;
- if (node == ctx->target) {
- dump_computed_style(sr->styles[ctx->pseudo_element],
- buf, buflen);
- }
+ return CSS_OK;
+}
- if (node->parent == NULL) {
- unit_ctx.root_style = node->sr->styles[ctx->pseudo_element];
- }
+static css_error node_is_empty(void *pw, void *n, bool *match)
+{
+ node *node = n;
+ UNUSED(pw);
- for (n = node->children; n != NULL; n = n->next) {
- run_test_select_tree(select, n, ctx, buf, buflen);
- }
-}
+ *match = (node->children == NULL);
+ return CSS_OK;
+}
-void run_test(line_ctx *ctx, const char *exp, size_t explen)
+static css_error node_is_link(void *pw, void *n, bool *match)
{
- css_select_ctx *select;
- css_select_results *results;
- uint32_t i;
- char *buf;
- size_t buflen;
- static int testnum;
+ node *node = n;
- UNUSED(exp);
+ UNUSED(pw);
+ UNUSED(node);
- buf = malloc(8192);
- if (buf == NULL) {
- assert(0 && "No memory for result data");
- }
- buflen = 8192;
+ *match = false;
- assert(css_select_ctx_create(&select) == CSS_OK);
+ return CSS_OK;
+}
- for (i = 0; i < ctx->n_sheets; i++) {
- assert(css_select_ctx_append_sheet(select,
- ctx->sheets[i].sheet, ctx->sheets[i].origin,
- ctx->sheets[i].media) == CSS_OK);
- }
+static css_error node_is_visited(void *pw, void *n, bool *match)
+{
+ node *node = n;
- testnum++;
+ UNUSED(pw);
+ UNUSED(node);
- run_test_select_tree(select, ctx->tree, ctx, buf, &buflen);
+ *match = false;
- results = ctx->target->sr;
- assert(results->styles[ctx->pseudo_element] != NULL);
+ return CSS_OK;
+}
- if (8192 - buflen != explen || memcmp(buf, exp, explen) != 0) {
- size_t len = 8192 - buflen < explen ? 8192 - buflen : explen;
- printf("Expected (%u):\n%.*s\n",
- (int) explen, (int) explen, exp);
- printf("Result (%u):\n%.*s\n", (int) (8192 - buflen),
- (int) (8192 - buflen), buf);
+static css_error node_is_hover(void *pw, void *n, bool *match)
+{
+ node *node = n;
- show_differences(len, exp, buf);
- assert(0 && "Result doesn't match expected");
- }
+ UNUSED(pw);
+ UNUSED(node);
- /* Clean up */
- css_select_ctx_destroy(select);
- destroy_tree(ctx->tree);
+ *match = false;
- for (i = 0; i < ctx->n_sheets; i++) {
- css_stylesheet_destroy(ctx->sheets[i].sheet);
- free(ctx->sheets[i].media);
- }
+ return CSS_OK;
+}
- ctx->tree = NULL;
- ctx->current = NULL;
- ctx->depth = 0;
- ctx->n_sheets = 0;
- free(ctx->sheets);
- ctx->sheets = NULL;
- ctx->target = NULL;
+static css_error node_is_active(void *pw, void *n, bool *match)
+{
+ node *node = n;
- free(buf);
+ UNUSED(pw);
+ UNUSED(node);
- printf("Test %d: PASS\n", testnum);
+ *match = false;
+
+ return CSS_OK;
}
-void destroy_tree(node *root)
+static css_error node_is_focus(void *pw, void *n, bool *match)
{
- node *n, *p;
- uint32_t i;
+ node *node = n;
- for (n = root->children; n != NULL; n = p) {
- p = n->next;
+ UNUSED(pw);
+ UNUSED(node);
- destroy_tree(n);
- }
+ *match = false;
- css_select_results_destroy(root->sr);
+ return CSS_OK;
+}
- for (i = 0; i < root->n_attrs; ++i) {
- lwc_string_unref(root->attrs[i].name);
- lwc_string_unref(root->attrs[i].value);
- }
- free(root->attrs);
+static css_error node_is_enabled(void *pw, void *n, bool *match)
+{
+ node *node = n;
- if (root->classes != NULL) {
- for (i = 0; i < root->n_classes; ++i) {
- lwc_string_unref(root->classes[i]);
- }
- free(root->classes);
- }
+ UNUSED(pw);
+ UNUSED(node);
- if (root->libcss_node_data != NULL) {
- css_libcss_node_data_handler(&select_handler, CSS_NODE_DELETED,
- NULL, root, NULL, root->libcss_node_data);
- }
+ *match = false;
- lwc_string_unref(root->name);
- free(root);
+ return CSS_OK;
}
-
-css_error node_name(void *pw, void *n, css_qname *qname)
+static css_error node_is_disabled(void *pw, void *n, bool *match)
{
node *node = n;
UNUSED(pw);
+ UNUSED(node);
- qname->name = lwc_string_ref(node->name);
+ *match = false;
return CSS_OK;
}
-static css_error node_classes(void *pw, void *n,
- lwc_string ***classes, uint32_t *n_classes)
+static css_error node_is_checked(void *pw, void *n, bool *match)
{
- unsigned int i;
node *node = n;
- UNUSED(pw);
- *classes = node->classes;
- *n_classes = node->n_classes;
+ UNUSED(pw);
+ UNUSED(node);
- for (i = 0; i < *n_classes; i++)
- (*classes)[i] = lwc_string_ref(node->classes[i]);
+ *match = false;
return CSS_OK;
-
}
-css_error node_id(void *pw, void *n,
- lwc_string **id)
+static css_error node_is_target(void *pw, void *n, bool *match)
{
node *node = n;
- uint32_t i;
- line_ctx *lc = pw;
- for (i = 0; i < node->n_attrs; i++) {
- bool amatch = false;
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, lc->attr_id, &amatch) ==
- lwc_error_ok);
- if (amatch == true)
- break;
- }
+ UNUSED(pw);
+ UNUSED(node);
- if (i != node->n_attrs)
- *id = lwc_string_ref(node->attrs[i].value);
- else
- *id = NULL;
+ *match = false;
return CSS_OK;
}
-css_error named_ancestor_node(void *pw, void *n,
- const css_qname *qname,
- void **ancestor)
+static css_error node_is_lang(void *pw, void *n,
+ lwc_string *lang,
+ bool *match)
{
node *node = n;
- UNUSED(pw);
- for (node = node->parent; node != NULL; node = node->parent) {
- bool match = false;
- assert(lwc_string_caseless_isequal(
- qname->name, node->name,
- &match) == lwc_error_ok);
- if (match == true)
- break;
- }
+ UNUSED(pw);
+ UNUSED(node);
+ UNUSED(lang);
- *ancestor = (void *) node;
+ *match = false;
return CSS_OK;
}
-css_error named_parent_node(void *pw, void *n,
- const css_qname *qname,
- void **parent)
+static css_error node_presentational_hint(void *pw, void *node,
+ uint32_t *nhints, css_hint **hints)
{
- node *node = n;
UNUSED(pw);
+ UNUSED(node);
- *parent = NULL;
- if (node->parent != NULL) {
- bool match = false;
- assert(lwc_string_caseless_isequal(
- qname->name, node->parent->name, &match) ==
- lwc_error_ok);
- if (match == true)
- *parent = (void *) node->parent;
- }
+ *nhints = 0;
+ *hints = NULL;
return CSS_OK;
}
-css_error named_sibling_node(void *pw, void *n,
- const css_qname *qname,
- void **sibling)
+static css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
{
- node *node = n;
UNUSED(pw);
- *sibling = NULL;
- if (node->prev != NULL) {
- bool match = false;
- assert(lwc_string_caseless_isequal(
- qname->name, node->prev->name, &match) ==
- lwc_error_ok);
- if (match == true)
- *sibling = (void *) node->prev;
+ if (property == CSS_PROP_COLOR) {
+ hint->data.color = 0xff000000;
+ hint->status = CSS_COLOR_COLOR;
+ } else if (property == CSS_PROP_FONT_FAMILY) {
+ hint->data.strings = NULL;
+ hint->status = CSS_FONT_FAMILY_SANS_SERIF;
+ } else if (property == CSS_PROP_QUOTES) {
+ /* Not exactly useful :) */
+ hint->data.strings = NULL;
+ hint->status = CSS_QUOTES_NONE;
+ } else if (property == CSS_PROP_VOICE_FAMILY) {
+ /** \todo Fix this when we have voice-family done */
+ hint->data.strings = NULL;
+ hint->status = 0;
+ } else {
+ return CSS_INVALID;
}
return CSS_OK;
}
-css_error named_generic_sibling_node(void *pw, void *n,
- const css_qname *qname,
- void **sibling)
+static css_error set_libcss_node_data(void *pw, void *n,
+ void *libcss_node_data)
{
node *node = n;
UNUSED(pw);
- for (node = node->prev; node != NULL; node = node->prev) {
- bool match = false;
- assert(lwc_string_caseless_isequal(
- qname->name, node->name,
- &match) == lwc_error_ok);
- if (match == true)
- break;
- }
-
- *sibling = (void *) node;
+ node->libcss_node_data = libcss_node_data;
return CSS_OK;
}
-css_error parent_node(void *pw, void *n, void **parent)
+static css_error get_libcss_node_data(void *pw, void *n,
+ void **libcss_node_data)
{
node *node = n;
-
UNUSED(pw);
- *parent = (void *) node->parent;
+ /* Pass any node data back to libcss */
+ *libcss_node_data = node->libcss_node_data;
return CSS_OK;
}
-css_error sibling_node(void *pw, void *n, void **sibling)
-{
- node *node = n;
+static css_unit_ctx unit_ctx = {
+ .font_size_default = 16 * (1 << CSS_RADIX_POINT),
+};
+
+static css_select_handler select_handler = {
+ CSS_SELECT_HANDLER_VERSION_1,
+
+ node_name,
+ node_classes,
+ node_id,
+ named_ancestor_node,
+ named_parent_node,
+ named_sibling_node,
+ named_generic_sibling_node,
+ parent_node,
+ sibling_node,
+ node_has_name,
+ node_has_class,
+ node_has_id,
+ node_has_attribute,
+ node_has_attribute_equal,
+ node_has_attribute_dashmatch,
+ node_has_attribute_includes,
+ node_has_attribute_prefix,
+ node_has_attribute_suffix,
+ node_has_attribute_substring,
+ node_is_root,
+ node_count_siblings,
+ node_is_empty,
+ node_is_link,
+ node_is_visited,
+ node_is_hover,
+ node_is_active,
+ node_is_focus,
+ node_is_enabled,
+ node_is_disabled,
+ node_is_checked,
+ node_is_target,
+ node_is_lang,
+ node_presentational_hint,
+ ua_default_for_property,
+ set_libcss_node_data,
+ get_libcss_node_data,
+};
+
+static css_error resolve_url(void *pw,
+ const char *base, lwc_string *rel, lwc_string **abs)
+{
UNUSED(pw);
+ UNUSED(base);
- *sibling = (void *) node->prev;
+ /* About as useless as possible */
+ *abs = lwc_string_ref(rel);
return CSS_OK;
}
-css_error node_has_name(void *pw, void *n,
- const css_qname *qname,
- bool *match)
+static bool fail_because_lwc_leaked = false;
+
+static void
+printing_lwc_iterator(lwc_string *str, void *pw)
{
- node *node = n;
UNUSED(pw);
- if (lwc_string_length(qname->name) == 1 &&
- lwc_string_data(qname->name)[0] == '*')
- *match = true;
- else
- assert(lwc_string_caseless_isequal(node->name,
- qname->name, match) == lwc_error_ok);
+ printf(" DICT: %*s\n", (int)(lwc_string_length(str)), lwc_string_data(str));
+ fail_because_lwc_leaked = true;
+}
+
+static css_error css_font_resolution_func(void *pw, lwc_string *name,
+ css_system_font *system_font)
+{
+ lwc_error err;
+
+ if (system_font == NULL) {
+ return CSS_BADPARM;
+ }
+
+ (void)(pw);
+
+ if (strncmp(lwc_string_data(name), "special-system-font",
+ lwc_string_length(name)) != 0) {
+ return CSS_INVALID;
+ }
+
+ system_font->style = CSS_FONT_STYLE_NORMAL;
+ system_font->variant = CSS_FONT_VARIANT_NORMAL;
+ system_font->weight = CSS_FONT_WEIGHT_NORMAL;
+ system_font->size.size = INTTOFIX(22);
+ system_font->size.unit = CSS_UNIT_PT;
+ system_font->line_height.size = INTTOFIX(33);
+ system_font->line_height.unit = CSS_UNIT_EM;
+ err = lwc_intern_string("special-system-font",
+ strlen("special-system-font"),
+ &system_font->family);
+ if (err != lwc_error_ok) {
+ return CSS_NOMEM;
+ }
return CSS_OK;
}
-css_error node_has_class(void *pw, void *n,
- lwc_string *name,
- bool *match)
+static void css__parse_sheet(line_ctx *ctx, const char *data, size_t len)
{
- node *node = n;
- uint32_t i;
- line_ctx *ctx = pw;
+ css_stylesheet_params params;
+ const char *p;
+ const char *end = data + len;
+ css_origin origin = CSS_ORIGIN_AUTHOR;
+ css_stylesheet *sheet;
+ sheet_ctx *temp;
+ char *media = NULL;
- for (i = 0; i < node->n_attrs; i++) {
- bool amatch = false;
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, ctx->attr_class,
- &amatch) == lwc_error_ok);
- if (amatch == true)
+ /* <origin> <media_list>? */
+
+ /* Find end of origin */
+ for (p = data; p < end; p++) {
+ if (isspace(*p))
break;
}
- /* Classes are case-sensitive in HTML */
- if (i != node->n_attrs && name == node->attrs[i].value)
- *match = true;
+ if (p - data == 6 && strncasecmp(data, "author", 6) == 0)
+ origin = CSS_ORIGIN_AUTHOR;
+ else if (p - data == 4 && strncasecmp(data, "user", 4) == 0)
+ origin = CSS_ORIGIN_USER;
+ else if (p - data == 2 && strncasecmp(data, "ua", 2) == 0)
+ origin = CSS_ORIGIN_UA;
else
- *match = false;
+ assert(0 && "Unknown stylesheet origin");
- return CSS_OK;
+ /* Skip any whitespace */
+ while (p < end && isspace(*p))
+ p++;
+
+ assert(end >= p);
+ media = malloc(end - p + 1);
+ assert(media != NULL);
+ memcpy(media, p, end - p);
+ media[end - p] = '\0';
+
+ 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 = css_font_resolution_func;
+ params.font_pw = NULL;
+
+ /** \todo How are we going to handle @import? */
+ assert(css_stylesheet_create(¶ms, &sheet) == CSS_OK);
+
+ /* Extend array of sheets and append new sheet to it */
+ temp = realloc(ctx->sheets,
+ (ctx->n_sheets + 1) * sizeof(sheet_ctx));
+ assert(temp != NULL);
+
+ ctx->sheets = temp;
+
+ ctx->sheets[ctx->n_sheets].sheet = sheet;
+ ctx->sheets[ctx->n_sheets].origin = origin;
+ ctx->sheets[ctx->n_sheets].media = media;
+
+ ctx->n_sheets++;
}
-css_error node_has_id(void *pw, void *n,
- lwc_string *name,
- bool *match)
+static void css__parse_media_list(const char **data, size_t *len, css_media *media)
{
- node *node = n;
- uint32_t i;
- line_ctx *ctx = pw;
+ const char *p = *data;
+ const char *end = p + *len;
+ uint64_t result = 0;
- for (i = 0; i < node->n_attrs; i++) {
- bool amatch = false;
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, ctx->attr_id, &amatch) ==
- lwc_error_ok);
- if (amatch == true)
- break;
- }
+ /* <medium> [ ',' <medium> ]* */
+
+ while (p < end) {
+ const char *start = p;
+
+ /* consume a medium */
+ while (isspace(*p) == false && *p != ',')
+ p++;
+
+ if (p - start == 10 &&
+ strncasecmp(start, "projection", 10) == 0)
+ result |= CSS_MEDIA_PROJECTION;
+ else if (p - start == 8 &&
+ strncasecmp(start, "handheld", 8) == 0)
+ result |= CSS_MEDIA_HANDHELD;
+ else if (p - start == 8 &&
+ strncasecmp(start, "embossed", 8) == 0)
+ result |= CSS_MEDIA_EMBOSSED;
+ else if (p - start == 7 &&
+ strncasecmp(start, "braille", 7) == 0)
+ result |= CSS_MEDIA_BRAILLE;
+ else if (p - start == 6 &&
+ strncasecmp(start, "speech", 6) == 0)
+ result |= CSS_MEDIA_SPEECH;
+ else if (p - start == 6 &&
+ strncasecmp(start, "screen", 6) == 0)
+ result |= CSS_MEDIA_SCREEN;
+ else if (p - start == 5 &&
+ strncasecmp(start, "print", 5) == 0)
+ result |= CSS_MEDIA_PRINT;
+ else if (p - start == 5 &&
+ strncasecmp(start, "aural", 5) == 0)
+ result |= CSS_MEDIA_AURAL;
+ else if (p - start == 3 &&
+ strncasecmp(start, "tty", 3) == 0)
+ result |= CSS_MEDIA_TTY;
+ else if (p - start == 3 &&
+ strncasecmp(start, "all", 3) == 0)
+ result |= CSS_MEDIA_ALL;
+ else if (p - start == 2 &&
+ strncasecmp(start, "tv", 2) == 0)
+ result |= CSS_MEDIA_TV;
+ else
+ assert(0 && "Unknown media type");
- /* IDs are case-sensitive in HTML */
- if (i != node->n_attrs && name == node->attrs[i].value)
- *match = true;
- else
- *match = false;
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
- return CSS_OK;
-}
+ /* Stop if we've reached the end */
+ if (p == end || *p != ',')
+ break;
-css_error node_has_attribute(void *pw, void *n,
- const css_qname *qname,
- bool *match)
-{
- node *node = n;
- uint32_t i;
- UNUSED(pw);
+ /* Consume comma */
+ p++;
- *match = false;
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
}
- return CSS_OK;
+ media->type = result;
+
+ *data = p;
+ *len = end - p;
}
-css_error node_has_attribute_equal(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
+static void css__parse_pseudo_list(const char **data, size_t *len, uint32_t *element)
{
- node *node = n;
- uint32_t i;
- UNUSED(pw);
+ const char *p = *data;
+ const char *end = p + *len;
- *match = false;
+ /* <pseudo> [ ',' <pseudo> ]* */
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
- }
+ *element = CSS_PSEUDO_ELEMENT_NONE;
- if (*match == true) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, value, match) ==
- lwc_error_ok);
- }
+ while (p < end) {
+ const char *start = p;
- return CSS_OK;
-}
+ /* consume a pseudo */
+ while (isspace(*p) == false && *p != ',')
+ p++;
-css_error node_has_attribute_includes(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
-{
- node *node = n;
- uint32_t i;
- size_t vlen = lwc_string_length(value);
- UNUSED(pw);
+ /* Pseudo elements */
+ if (p - start == 12 &&
+ strncasecmp(start, "first-letter", 12) == 0)
+ *element = CSS_PSEUDO_ELEMENT_FIRST_LETTER;
+ else if (p - start == 10 &&
+ strncasecmp(start, "first-line", 10) == 0)
+ *element = CSS_PSEUDO_ELEMENT_FIRST_LINE;
+ else if (p - start == 6 &&
+ strncasecmp(start, "before", 6) == 0)
+ *element = CSS_PSEUDO_ELEMENT_BEFORE;
+ else if (p - start == 5 &&
+ strncasecmp(start, "after", 5) == 0)
+ *element = CSS_PSEUDO_ELEMENT_AFTER;
+ else
+ assert(0 && "Unknown pseudo");
- *match = false;
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
+ /* Stop if we've reached the end */
+ if (p == end || *p != ',')
break;
- }
-
- if (*match == true) {
- const char *p;
- const char *start = lwc_string_data(node->attrs[i].value);
- const char *end = start +
- lwc_string_length(node->attrs[i].value);
- *match = false;
-
- for (p = start; p < end; p++) {
- if (*p == ' ') {
- if ((size_t) (p - start) == vlen &&
- strncasecmp(start,
- lwc_string_data(value),
- vlen) == 0) {
- *match = true;
- break;
- }
+ /* Consume comma */
+ p++;
- start = p + 1;
- }
- }
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
}
- return CSS_OK;
+ *data = p;
+ *len = end - p;
}
-css_error node_has_attribute_dashmatch(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
+static void css__parse_tree(line_ctx *ctx, const char *data, size_t len)
{
- node *node = n;
- uint32_t i;
- size_t vlen = lwc_string_length(value);
- UNUSED(pw);
+ const char *p = data;
+ const char *end = data + len;
+ size_t left;
- *match = false;
+ /* [ <media_list> <pseudo>? ] ? */
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
- }
+ ctx->media.type = CSS_MEDIA_ALL;
+ ctx->pseudo_element = CSS_PSEUDO_ELEMENT_NONE;
- if (*match == true) {
- const char *p;
- const char *start = lwc_string_data(node->attrs[i].value);
- const char *end = start +
- lwc_string_length(node->attrs[i].value);
+ /* Consume any leading whitespace */
+ while (p < end && isspace(*p))
+ p++;
- *match = false;
+ if (p < end) {
+ left = end - p;
- for (p = start; p < end; p++) {
- if (*p == '-') {
- if ((size_t) (p - start) == vlen &&
- strncasecmp(start,
- lwc_string_data(value),
- vlen) == 0) {
- *match = true;
- break;
- }
+ css__parse_media_list(&p, &left, &ctx->media);
- start = p + 1;
- }
- }
+ end = p + left;
}
- return CSS_OK;
+ if (p < end) {
+ left = end - p;
+
+ css__parse_pseudo_list(&p, &left, &ctx->pseudo_element);
+ }
}
-css_error node_has_attribute_prefix(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
+static void css__parse_expected(line_ctx *ctx, const char *data, size_t len)
{
- node *node = n;
- uint32_t i;
- UNUSED(pw);
-
- *match = false;
+ while (ctx->expused + len >= ctx->explen) {
+ size_t required = ctx->explen == 0 ? 64 : ctx->explen * 2;
+ char *temp = realloc(ctx->exp, required);
+ if (temp == NULL) {
+ assert(0 && "No memory for expected output");
+ }
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
+ ctx->exp = temp;
+ ctx->explen = required;
}
- if (*match == true) {
- size_t len = lwc_string_length(node->attrs[i].value);
- const char *data = lwc_string_data(node->attrs[i].value);
-
- size_t vlen = lwc_string_length(value);
- const char *vdata = lwc_string_data(value);
-
- if (len < vlen)
- *match = false;
- else
- *match = (strncasecmp(data, vdata, vlen) == 0);
- }
+ memcpy(ctx->exp + ctx->expused, data, len);
- return CSS_OK;
+ ctx->expused += len;
}
-css_error node_has_attribute_suffix(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
+static void css__parse_tree_data(line_ctx *ctx, const char *data, size_t len)
{
- node *node = n;
- uint32_t i;
- UNUSED(pw);
+ const char *p = data;
+ const char *end = data + len;
+ const char *name = NULL;
+ const char *value = NULL;
+ size_t namelen = 0;
+ size_t valuelen = 0;
+ uint32_t depth = 0;
+ bool target = false;
- *match = false;
+ /* ' '{depth+1} [ <element> '*'? | <attr> ]
+ *
+ * <element> ::= [^=*[:space:]]+
+ * <attr> ::= [^=*[:space:]]+ '=' [^[:space:]]*
+ */
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
+ while (p < end && isspace(*p)) {
+ depth++;
+ p++;
+ }
+ depth--;
+
+ /* Get element/attribute name */
+ name = p;
+ while (p < end && *p != '=' && *p != '*' && isspace(*p) == false) {
+ namelen++;
+ p++;
}
- if (*match == true) {
- size_t len = lwc_string_length(node->attrs[i].value);
- const char *data = lwc_string_data(node->attrs[i].value);
+ /* Skip whitespace */
+ while (p < end && isspace(*p))
+ p++;
- size_t vlen = lwc_string_length(value);
- const char *vdata = lwc_string_data(value);
+ if (p < end && *p == '=') {
+ /* Attribute value */
+ p++;
- size_t suffix_start = len - vlen;
+ value = p;
- if (len < vlen)
- *match = false;
- else {
- *match = (strncasecmp(data + suffix_start,
- vdata, vlen) == 0);
+ while (p < end && isspace(*p) == false) {
+ valuelen++;
+ p++;
}
+ } else if (p < end && *p == '*') {
+ /* Element is target node */
+ target = true;
}
- return CSS_OK;
-}
-
-css_error node_has_attribute_substring(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
-{
- node *node = n;
- uint32_t i;
- UNUSED(pw);
-
- *match = false;
+ if (value == NULL) {
+ /* We have an element, so create it */
+ node *n = malloc(sizeof(node));
+ assert(n != NULL);
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
- }
+ memset(n, 0, sizeof(node));
- if (*match == true) {
- size_t len = lwc_string_length(node->attrs[i].value);
- const char *data = lwc_string_data(node->attrs[i].value);
+ lwc_intern_string(name, namelen, &n->name);
- size_t vlen = lwc_string_length(value);
- const char *vdata = lwc_string_data(value);
+ /* Insert it into tree */
+ if (ctx->tree == NULL) {
+ ctx->tree = n;
+ } else {
+ assert(depth > 0);
+ assert(depth <= ctx->depth + 1);
- const char *last_start = data + len - vlen;
+ /* Find node to insert into */
+ while (depth <= ctx->depth) {
+ ctx->depth--;
+ ctx->current = ctx->current->parent;
+ }
- if (len < vlen)
- *match = false;
- else {
- while (data <= last_start) {
- if (strncasecmp(data, vdata, vlen) == 0) {
- *match = true;
- break;
- }
+ /* Insert into current node */
+ if (ctx->current->children == NULL) {
+ ctx->current->children = n;
+ ctx->current->last_child = n;
+ } else {
+ ctx->current->last_child->next = n;
+ n->prev = ctx->current->last_child;
- data++;
+ ctx->current->last_child = n;
}
-
- if (data > last_start)
- *match = false;
+ n->parent = ctx->current;
}
- }
- return CSS_OK;
-}
+ ctx->current = n;
+ ctx->depth = depth;
-css_error node_is_root(void *pw, void *n, bool *match)
-{
- node *node = n;
- UNUSED(pw);
+ /* Mark the target, if it's us */
+ if (target)
+ ctx->target = n;
+ } else {
+ /* New attribute */
+ bool amatch = false;
+ attribute *attr;
+ node *n = ctx->current;
- *match = (node->parent == NULL);
+ attribute *temp = realloc(n->attrs,
+ (n->n_attrs + 1) * sizeof(attribute));
+ assert(temp != NULL);
- return CSS_OK;
-}
+ n->attrs = temp;
-css_error node_count_siblings(void *pw, void *n,
- bool same_name, bool after, int32_t *count)
-{
- int32_t cnt = 0;
- bool match = false;
- node *node = n;
- lwc_string *name = node->name;
- UNUSED(pw);
+ attr = &n->attrs[n->n_attrs];
- if (after) {
- while (node->next != NULL) {
- if (same_name) {
- assert(lwc_string_caseless_isequal(
- name, node->next->name, &match) ==
- lwc_error_ok);
+ lwc_intern_string(name, namelen, &attr->name);
+ lwc_intern_string(value, valuelen, &attr->value);
- if (match)
- cnt++;
- } else {
- cnt++;
- }
+ assert(lwc_string_caseless_isequal(
+ n->attrs[n->n_attrs].name,
+ ctx->attr_class, &amatch) == lwc_error_ok);
+ if (amatch == true) {
+ n->classes = realloc(NULL, sizeof(lwc_string **));
+ assert(n->classes != NULL);
- node = node->next;
+ n->classes[0] = lwc_string_ref(
+ n->attrs[n->n_attrs].
+ value);
+ n->n_classes = 1;
}
- } else {
- while (node->prev != NULL) {
- if (same_name) {
- assert(lwc_string_caseless_isequal(
- name, node->prev->name, &match) ==
- lwc_error_ok);
-
- if (match)
- cnt++;
- } else {
- cnt++;
- }
- node = node->prev;
- }
+ n->n_attrs++;
}
-
- *count = cnt;
-
- return CSS_OK;
}
-css_error node_is_empty(void *pw, void *n, bool *match)
-{
- node *node = n;
- UNUSED(pw);
-
- *match = (node->children == NULL);
-
- return CSS_OK;
-}
-css_error node_is_link(void *pw, void *n, bool *match)
+static void run_test_select_tree(css_select_ctx *select,
+ node *node, line_ctx *ctx,
+ char *buf, size_t *buflen)
{
- node *node = n;
+ css_select_results *sr;
+ struct node *n = NULL;
- UNUSED(pw);
- UNUSED(node);
+ if (node->parent == NULL) {
+ unit_ctx.root_style = NULL;
+ }
- *match = false;
- return CSS_OK;
-}
+ assert(css_select_style(select, node, &unit_ctx, &ctx->media, NULL,
+ &select_handler, ctx, &sr) == CSS_OK);
-css_error node_is_visited(void *pw, void *n, bool *match)
-{
- node *node = n;
+ if (node->parent != NULL) {
+ css_computed_style *composed;
+ assert(css_computed_style_compose(
+ node->parent->sr->styles[ctx->pseudo_element],
+ sr->styles[ctx->pseudo_element],
+ &unit_ctx,
+ &composed) == CSS_OK);
+ css_computed_style_destroy(sr->styles[ctx->pseudo_element]);
+ sr->styles[ctx->pseudo_element] = composed;
+ }
- UNUSED(pw);
- UNUSED(node);
+ node->sr = sr;
- *match = false;
+ if (node == ctx->target) {
+ dump_computed_style(sr->styles[ctx->pseudo_element],
+ buf, buflen);
+ }
- return CSS_OK;
+ if (node->parent == NULL) {
+ unit_ctx.root_style = node->sr->styles[ctx->pseudo_element];
+ }
+
+ for (n = node->children; n != NULL; n = n->next) {
+ run_test_select_tree(select, n, ctx, buf, buflen);
+ }
}
-css_error node_is_hover(void *pw, void *n, bool *match)
+static void show_differences(size_t len, const char *exp, const char *res)
{
- node *node = n;
-
- UNUSED(pw);
- UNUSED(node);
+ const char *pos_exp, *opos_exp;
+ const char *pos_res, *opos_res;
- *match = false;
+ opos_exp = pos_exp = exp;
+ opos_res = pos_res = res;
- return CSS_OK;
+ printf("Line differences:\n");
+ while (pos_exp < exp + len && pos_res < res + len) {
+ if (*pos_exp == '\n' && *pos_res == '\n') {
+ if (pos_exp - opos_exp != pos_res - opos_res ||
+ memcmp(opos_exp, opos_res,
+ pos_exp - opos_exp) != 0) {
+ printf("Expected:\t%.*s\n",
+ (int)(pos_exp - opos_exp),
+ opos_exp);
+ printf(" Result:\t%.*s\n",
+ (int)(pos_res - opos_res),
+ opos_res);
+ printf("\n");
+ }
+ opos_exp = ++pos_exp;
+ opos_res = ++pos_res;
+ } else if (*pos_exp == '\n') {
+ pos_res++;
+ } else if (*pos_res == '\n') {
+ pos_exp++;
+ } else {
+ pos_exp++;
+ pos_res++;
+ }
+ }
}
-css_error node_is_active(void *pw, void *n, bool *match)
+static void destroy_tree(node *root)
{
- node *node = n;
+ node *n, *p;
+ uint32_t i;
- UNUSED(pw);
- UNUSED(node);
+ for (n = root->children; n != NULL; n = p) {
+ p = n->next;
- *match = false;
+ destroy_tree(n);
+ }
- return CSS_OK;
-}
+ css_select_results_destroy(root->sr);
-css_error node_is_focus(void *pw, void *n, bool *match)
-{
- node *node = n;
+ for (i = 0; i < root->n_attrs; ++i) {
+ lwc_string_unref(root->attrs[i].name);
+ lwc_string_unref(root->attrs[i].value);
+ }
+ free(root->attrs);
- UNUSED(pw);
- UNUSED(node);
+ if (root->classes != NULL) {
+ for (i = 0; i < root->n_classes; ++i) {
+ lwc_string_unref(root->classes[i]);
+ }
+ free(root->classes);
+ }
- *match = false;
+ if (root->libcss_node_data != NULL) {
+ css_libcss_node_data_handler(&select_handler, CSS_NODE_DELETED,
+ NULL, root, NULL, root->libcss_node_data);
+ }
- return CSS_OK;
+ lwc_string_unref(root->name);
+ free(root);
}
-css_error node_is_enabled(void *pw, void *n, bool *match)
+static void run_test(line_ctx *ctx, const char *exp, size_t explen)
{
- node *node = n;
-
- UNUSED(pw);
- UNUSED(node);
+ css_select_ctx *select;
+ css_select_results *results;
+ uint32_t i;
+ char *buf;
+ size_t buflen;
+ static int testnum;
- *match = false;
+ UNUSED(exp);
- return CSS_OK;
-}
+ buf = malloc(8192);
+ if (buf == NULL) {
+ assert(0 && "No memory for result data");
+ }
+ buflen = 8192;
-css_error node_is_disabled(void *pw, void *n, bool *match)
-{
- node *node = n;
+ assert(css_select_ctx_create(&select) == CSS_OK);
- UNUSED(pw);
- UNUSED(node);
+ for (i = 0; i < ctx->n_sheets; i++) {
+ assert(css_select_ctx_append_sheet(select,
+ ctx->sheets[i].sheet, ctx->sheets[i].origin,
+ ctx->sheets[i].media) == CSS_OK);
+ }
- *match = false;
+ testnum++;
- return CSS_OK;
-}
+ run_test_select_tree(select, ctx->tree, ctx, buf, &buflen);
-css_error node_is_checked(void *pw, void *n, bool *match)
-{
- node *node = n;
+ results = ctx->target->sr;
+ assert(results->styles[ctx->pseudo_element] != NULL);
- UNUSED(pw);
- UNUSED(node);
+ if (8192 - buflen != explen || memcmp(buf, exp, explen) != 0) {
+ size_t len = 8192 - buflen < explen ? 8192 - buflen : explen;
+ printf("Expected (%u):\n%.*s\n",
+ (int) explen, (int) explen, exp);
+ printf("Result (%u):\n%.*s\n", (int) (8192 - buflen),
+ (int) (8192 - buflen), buf);
- *match = false;
+ show_differences(len, exp, buf);
+ assert(0 && "Result doesn't match expected");
+ }
- return CSS_OK;
-}
+ /* Clean up */
+ css_select_ctx_destroy(select);
+ destroy_tree(ctx->tree);
-css_error node_is_target(void *pw, void *n, bool *match)
-{
- node *node = n;
+ for (i = 0; i < ctx->n_sheets; i++) {
+ css_stylesheet_destroy(ctx->sheets[i].sheet);
+ free(ctx->sheets[i].media);
+ }
- UNUSED(pw);
- UNUSED(node);
+ ctx->tree = NULL;
+ ctx->current = NULL;
+ ctx->depth = 0;
+ ctx->n_sheets = 0;
+ free(ctx->sheets);
+ ctx->sheets = NULL;
+ ctx->target = NULL;
- *match = false;
+ free(buf);
- return CSS_OK;
+ printf("Test %d: PASS\n", testnum);
}
-css_error node_is_lang(void *pw, void *n,
- lwc_string *lang,
- bool *match)
+static bool handle_line(const char *data, size_t datalen, void *pw)
{
- node *node = n;
-
- UNUSED(pw);
- UNUSED(node);
- UNUSED(lang);
+ line_ctx *ctx = (line_ctx *) pw;
+ css_error error;
- *match = false;
+ if (data[0] == '#') {
+ if (ctx->intree) {
+ if (strncasecmp(data+1, "errors", 6) == 0) {
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = true;
+ ctx->inexp = false;
+ } else {
+ /* Assume start of stylesheet */
+ css__parse_sheet(ctx, data + 1, datalen - 1);
- return CSS_OK;
-}
+ ctx->intree = false;
+ ctx->insheet = true;
+ ctx->inerrors = false;
+ ctx->inexp = false;
+ }
+ } else if (ctx->insheet) {
+ if (strncasecmp(data+1, "errors", 6) == 0) {
+ assert(css_stylesheet_data_done(
+ ctx->sheets[ctx->n_sheets - 1].sheet)
+ == CSS_OK);
-css_error node_presentational_hint(void *pw, void *node,
- uint32_t *nhints, css_hint **hints)
-{
- UNUSED(pw);
- UNUSED(node);
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = true;
+ ctx->inexp = false;
+ } else if (strncasecmp(data+1, "ua", 2) == 0 ||
+ strncasecmp(data+1, "user", 4) == 0 ||
+ strncasecmp(data+1, "author", 6) == 0) {
+ assert(css_stylesheet_data_done(
+ ctx->sheets[ctx->n_sheets - 1].sheet)
+ == CSS_OK);
- *nhints = 0;
- *hints = NULL;
+ css__parse_sheet(ctx, data + 1, datalen - 1);
+ } else {
+ error = css_stylesheet_append_data(
+ ctx->sheets[ctx->n_sheets - 1].sheet,
+ (const uint8_t *) data,
+ datalen);
+ assert(error == CSS_OK ||
+ error == CSS_NEEDDATA);
+ }
+ } else if (ctx->inerrors) {
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = false;
+ ctx->inexp = true;
+ } else if (ctx->inexp) {
+ /* This marks end of testcase, so run it */
+ run_test(ctx, ctx->exp, ctx->expused);
- return CSS_OK;
-}
+ ctx->expused = 0;
-css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
-{
- UNUSED(pw);
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = false;
+ ctx->inexp = false;
+ } else {
+ /* Start state */
+ if (strncasecmp(data+1, "tree", 4) == 0) {
+ css__parse_tree(ctx, data + 5, datalen - 5);
- if (property == CSS_PROP_COLOR) {
- hint->data.color = 0xff000000;
- hint->status = CSS_COLOR_COLOR;
- } else if (property == CSS_PROP_FONT_FAMILY) {
- hint->data.strings = NULL;
- hint->status = CSS_FONT_FAMILY_SANS_SERIF;
- } else if (property == CSS_PROP_QUOTES) {
- /* Not exactly useful :) */
- hint->data.strings = NULL;
- hint->status = CSS_QUOTES_NONE;
- } else if (property == CSS_PROP_VOICE_FAMILY) {
- /** \todo Fix this when we have voice-family done */
- hint->data.strings = NULL;
- hint->status = 0;
+ ctx->intree = true;
+ ctx->insheet = false;
+ ctx->inerrors = false;
+ ctx->inexp = false;
+ }
+ }
} else {
- return CSS_INVALID;
+ if (ctx->intree) {
+ /* Not interested in the '|' */
+ css__parse_tree_data(ctx, data + 1, datalen - 1);
+ } else if (ctx->insheet) {
+ error = css_stylesheet_append_data(
+ ctx->sheets[ctx->n_sheets - 1].sheet,
+ (const uint8_t *) data, datalen);
+ assert(error == CSS_OK || error == CSS_NEEDDATA);
+ } else if (ctx->inexp) {
+ css__parse_expected(ctx, data, datalen);
+ }
}
- return CSS_OK;
+ return true;
}
-static css_error set_libcss_node_data(void *pw, void *n,
- void *libcss_node_data)
+int main(int argc, char **argv)
{
- node *node = n;
- UNUSED(pw);
+ line_ctx ctx;
- node->libcss_node_data = libcss_node_data;
+ if (argc != 2) {
+ printf("Usage: %s <filename>\n", argv[0]);
+ return 1;
+ }
- return CSS_OK;
-}
+ memset(&ctx, 0, sizeof(ctx));
-static css_error get_libcss_node_data(void *pw, void *n,
- void **libcss_node_data)
-{
- node *node = n;
- UNUSED(pw);
- /* Pass any node data back to libcss */
- *libcss_node_data = node->libcss_node_data;
+ lwc_intern_string("class", SLEN("class"), &ctx.attr_class);
+ lwc_intern_string("id", SLEN("id"), &ctx.attr_id);
- return CSS_OK;
-}
+ assert(css__parse_testfile(argv[1], handle_line, &ctx) == true);
+
+ /* and run final test */
+ if (ctx.tree != NULL)
+ run_test(&ctx, ctx.exp, ctx.expused);
+
+ free(ctx.exp);
+
+ lwc_string_unref(ctx.attr_class);
+ lwc_string_unref(ctx.attr_id);
+
+ lwc_iterate_strings(printing_lwc_iterator, NULL);
+ assert(fail_because_lwc_leaked == false);
+ printf("PASS\n");
+ return 0;
+}
-----------------------------------------------------------------------
Summary of changes:
test/select.c | 2346 +++++++++++++++++++++++++++------------------------------
1 file changed, 1124 insertions(+), 1222 deletions(-)
diff --git a/test/select.c b/test/select.c
index c104b38..5bc7856 100644
--- a/test/select.c
+++ b/test/select.c
@@ -70,1607 +70,1509 @@ typedef struct line_ctx {
lwc_string *attr_id;
} line_ctx;
+static css_error node_name(void *pw, void *n, css_qname *qname)
+{
+ node *node = n;
+ UNUSED(pw);
+ qname->name = lwc_string_ref(node->name);
-static bool handle_line(const char *data, size_t datalen, void *pw);
-static void css__parse_tree(line_ctx *ctx, const char *data, size_t len);
-static void css__parse_tree_data(line_ctx *ctx, const char *data, size_t len);
-static void css__parse_sheet(line_ctx *ctx, const char *data, size_t len);
-static void css__parse_media_list(const char **data, size_t *len, css_media *media);
-static void css__parse_pseudo_list(const char **data, size_t *len,
- uint32_t *element);
-static void css__parse_expected(line_ctx *ctx, const char *data, size_t len);
-static void run_test(line_ctx *ctx, const char *exp, size_t explen);
-static void destroy_tree(node *root);
+ return CSS_OK;
+}
-static css_error node_name(void *pw, void *node,
- css_qname *qname);
static css_error node_classes(void *pw, void *n,
- lwc_string ***classes, uint32_t *n_classes);
-static css_error node_id(void *pw, void *node,
- lwc_string **id);
-static css_error named_ancestor_node(void *pw, void *node,
- const css_qname *qname,
- void **ancestor);
-static css_error named_parent_node(void *pw, void *node,
- const css_qname *qname,
- void **parent);
-static css_error named_sibling_node(void *pw, void *node,
- const css_qname *qname,
- void **sibling);
-static css_error named_generic_sibling_node(void *pw, void *node,
- const css_qname *qname,
- void **sibling);
-static css_error parent_node(void *pw, void *node, void **parent);
-static css_error sibling_node(void *pw, void *node, void **sibling);
-static css_error node_has_name(void *pw, void *node,
- const css_qname *qname,
- bool *match);
-static css_error node_has_class(void *pw, void *node,
- lwc_string *name,
- bool *match);
-static css_error node_has_id(void *pw, void *node,
- lwc_string *name,
- bool *match);
-static css_error node_has_attribute(void *pw, void *node,
- const css_qname *qname,
- bool *match);
-static css_error node_has_attribute_equal(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_dashmatch(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_includes(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_prefix(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_suffix(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_has_attribute_substring(void *pw, void *node,
- const css_qname *qname,
- lwc_string *value,
- bool *match);
-static css_error node_is_root(void *pw, void *node, bool *match);
-static css_error node_count_siblings(void *pw, void *node,
- bool same_name, bool after, int32_t *count);
-static css_error node_is_empty(void *pw, void *node, bool *match);
-static css_error node_is_link(void *pw, void *node, bool *match);
-static css_error node_is_visited(void *pw, void *node, bool *match);
-static css_error node_is_hover(void *pw, void *node, bool *match);
-static css_error node_is_active(void *pw, void *node, bool *match);
-static css_error node_is_focus(void *pw, void *node, bool *match);
-static css_error node_is_enabled(void *pw, void *node, bool *match);
-static css_error node_is_disabled(void *pw, void *node, bool *match);
-static css_error node_is_checked(void *pw, void *node, bool *match);
-static css_error node_is_target(void *pw, void *node, bool *match);
-static css_error node_is_lang(void *pw, void *node,
- lwc_string *lang, bool *match);
-static css_error node_presentational_hint(void *pw, void *node,
- uint32_t *nhints, css_hint **hints);
-static css_error ua_default_for_property(void *pw, uint32_t property,
- css_hint *hints);
-static css_error set_libcss_node_data(void *pw, void *n,
- void *libcss_node_data);
-static css_error get_libcss_node_data(void *pw, void *n,
- void **libcss_node_data);
+ lwc_string ***classes, uint32_t *n_classes)
+{
+ unsigned int i;
+ node *node = n;
+ UNUSED(pw);
-static css_unit_ctx unit_ctx = {
- .font_size_default = 16 * (1 << CSS_RADIX_POINT),
-};
+ *classes = node->classes;
+ *n_classes = node->n_classes;
-static css_select_handler select_handler = {
- CSS_SELECT_HANDLER_VERSION_1,
+ for (i = 0; i < *n_classes; i++)
+ (*classes)[i] = lwc_string_ref(node->classes[i]);
- node_name,
- node_classes,
- node_id,
- named_ancestor_node,
- named_parent_node,
- named_sibling_node,
- named_generic_sibling_node,
- parent_node,
- sibling_node,
- node_has_name,
- node_has_class,
- node_has_id,
- node_has_attribute,
- node_has_attribute_equal,
- node_has_attribute_dashmatch,
- node_has_attribute_includes,
- node_has_attribute_prefix,
- node_has_attribute_suffix,
- node_has_attribute_substring,
- node_is_root,
- node_count_siblings,
- node_is_empty,
- node_is_link,
- node_is_visited,
- node_is_hover,
- node_is_active,
- node_is_focus,
- node_is_enabled,
- node_is_disabled,
- node_is_checked,
- node_is_target,
- node_is_lang,
- node_presentational_hint,
- ua_default_for_property,
+ return CSS_OK;
- set_libcss_node_data,
- get_libcss_node_data,
-};
+}
-static css_error resolve_url(void *pw,
- const char *base, lwc_string *rel, lwc_string **abs)
+static css_error node_id(void *pw, void *n,
+ lwc_string **id)
+{
+ node *node = n;
+ uint32_t i;
+ line_ctx *lc = pw;
+
+ for (i = 0; i < node->n_attrs; i++) {
+ bool amatch = false;
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, lc->attr_id, &amatch) ==
+ lwc_error_ok);
+ if (amatch == true)
+ break;
+ }
+
+ if (i != node->n_attrs)
+ *id = lwc_string_ref(node->attrs[i].value);
+ else
+ *id = NULL;
+
+ return CSS_OK;
+}
+
+static css_error named_ancestor_node(void *pw, void *n,
+ const css_qname *qname,
+ void **ancestor)
{
+ node *node = n;
UNUSED(pw);
- UNUSED(base);
- /* About as useless as possible */
- *abs = lwc_string_ref(rel);
+ for (node = node->parent; node != NULL; node = node->parent) {
+ bool match = false;
+ assert(lwc_string_caseless_isequal(
+ qname->name, node->name,
+ &match) == lwc_error_ok);
+ if (match == true)
+ break;
+ }
+
+ *ancestor = (void *) node;
return CSS_OK;
}
-static bool fail_because_lwc_leaked = false;
+static css_error named_parent_node(void *pw, void *n,
+ const css_qname *qname,
+ void **parent)
+{
+ node *node = n;
+ UNUSED(pw);
-static void
-printing_lwc_iterator(lwc_string *str, void *pw)
+ *parent = NULL;
+ if (node->parent != NULL) {
+ bool match = false;
+ assert(lwc_string_caseless_isequal(
+ qname->name, node->parent->name, &match) ==
+ lwc_error_ok);
+ if (match == true)
+ *parent = (void *) node->parent;
+ }
+
+ return CSS_OK;
+}
+
+static css_error named_sibling_node(void *pw, void *n,
+ const css_qname *qname,
+ void **sibling)
{
+ node *node = n;
UNUSED(pw);
- printf(" DICT: %*s\n", (int)(lwc_string_length(str)), lwc_string_data(str));
- fail_because_lwc_leaked = true;
+ *sibling = NULL;
+ if (node->prev != NULL) {
+ bool match = false;
+ assert(lwc_string_caseless_isequal(
+ qname->name, node->prev->name, &match) ==
+ lwc_error_ok);
+ if (match == true)
+ *sibling = (void *) node->prev;
+ }
+
+ return CSS_OK;
}
-int main(int argc, char **argv)
+static css_error named_generic_sibling_node(void *pw, void *n,
+ const css_qname *qname,
+ void **sibling)
{
- line_ctx ctx;
+ node *node = n;
+ UNUSED(pw);
- if (argc != 2) {
- printf("Usage: %s <filename>\n", argv[0]);
- return 1;
+ for (node = node->prev; node != NULL; node = node->prev) {
+ bool match = false;
+ assert(lwc_string_caseless_isequal(
+ qname->name, node->name,
+ &match) == lwc_error_ok);
+ if (match == true)
+ break;
}
- memset(&ctx, 0, sizeof(ctx));
+ *sibling = (void *) node;
+ return CSS_OK;
+}
- lwc_intern_string("class", SLEN("class"), &ctx.attr_class);
- lwc_intern_string("id", SLEN("id"), &ctx.attr_id);
+static css_error parent_node(void *pw, void *n, void **parent)
+{
+ node *node = n;
- assert(css__parse_testfile(argv[1], handle_line, &ctx) == true);
+ UNUSED(pw);
- /* and run final test */
- if (ctx.tree != NULL)
- run_test(&ctx, ctx.exp, ctx.expused);
+ *parent = (void *) node->parent;
- free(ctx.exp);
+ return CSS_OK;
+}
- lwc_string_unref(ctx.attr_class);
- lwc_string_unref(ctx.attr_id);
+static css_error sibling_node(void *pw, void *n, void **sibling)
+{
+ node *node = n;
- lwc_iterate_strings(printing_lwc_iterator, NULL);
+ UNUSED(pw);
- assert(fail_because_lwc_leaked == false);
+ *sibling = (void *) node->prev;
- printf("PASS\n");
- return 0;
+ return CSS_OK;
}
-bool handle_line(const char *data, size_t datalen, void *pw)
+static css_error node_has_name(void *pw, void *n,
+ const css_qname *qname,
+ bool *match)
{
- line_ctx *ctx = (line_ctx *) pw;
- css_error error;
+ node *node = n;
+ UNUSED(pw);
- if (data[0] == '#') {
- if (ctx->intree) {
- if (strncasecmp(data+1, "errors", 6) == 0) {
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = true;
- ctx->inexp = false;
- } else {
- /* Assume start of stylesheet */
- css__parse_sheet(ctx, data + 1, datalen - 1);
+ if (lwc_string_length(qname->name) == 1 &&
+ lwc_string_data(qname->name)[0] == '*')
+ *match = true;
+ else
+ assert(lwc_string_caseless_isequal(node->name,
+ qname->name, match) == lwc_error_ok);
- ctx->intree = false;
- ctx->insheet = true;
- ctx->inerrors = false;
- ctx->inexp = false;
- }
- } else if (ctx->insheet) {
- if (strncasecmp(data+1, "errors", 6) == 0) {
- assert(css_stylesheet_data_done(
- ctx->sheets[ctx->n_sheets - 1].sheet)
- == CSS_OK);
+ return CSS_OK;
+}
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = true;
- ctx->inexp = false;
- } else if (strncasecmp(data+1, "ua", 2) == 0 ||
- strncasecmp(data+1, "user", 4) == 0 ||
- strncasecmp(data+1, "author", 6) == 0) {
- assert(css_stylesheet_data_done(
- ctx->sheets[ctx->n_sheets - 1].sheet)
- == CSS_OK);
+static css_error node_has_class(void *pw, void *n,
+ lwc_string *name,
+ bool *match)
+{
+ node *node = n;
+ uint32_t i;
+ line_ctx *ctx = pw;
- css__parse_sheet(ctx, data + 1, datalen - 1);
- } else {
- error = css_stylesheet_append_data(
- ctx->sheets[ctx->n_sheets - 1].sheet,
- (const uint8_t *) data,
- datalen);
- assert(error == CSS_OK ||
- error == CSS_NEEDDATA);
- }
- } else if (ctx->inerrors) {
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = false;
- ctx->inexp = true;
- } else if (ctx->inexp) {
- /* This marks end of testcase, so run it */
- run_test(ctx, ctx->exp, ctx->expused);
-
- ctx->expused = 0;
-
- ctx->intree = false;
- ctx->insheet = false;
- ctx->inerrors = false;
- ctx->inexp = false;
- } else {
- /* Start state */
- if (strncasecmp(data+1, "tree", 4) == 0) {
- css__parse_tree(ctx, data + 5, datalen - 5);
-
- ctx->intree = true;
- ctx->insheet = false;
- ctx->inerrors = false;
- ctx->inexp = false;
- }
- }
- } else {
- if (ctx->intree) {
- /* Not interested in the '|' */
- css__parse_tree_data(ctx, data + 1, datalen - 1);
- } else if (ctx->insheet) {
- error = css_stylesheet_append_data(
- ctx->sheets[ctx->n_sheets - 1].sheet,
- (const uint8_t *) data, datalen);
- assert(error == CSS_OK || error == CSS_NEEDDATA);
- } else if (ctx->inexp) {
- css__parse_expected(ctx, data, datalen);
- }
+ for (i = 0; i < node->n_attrs; i++) {
+ bool amatch = false;
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, ctx->attr_class,
+ &amatch) == lwc_error_ok);
+ if (amatch == true)
+ break;
}
- return true;
+ /* Classes are case-sensitive in HTML */
+ if (i != node->n_attrs && name == node->attrs[i].value)
+ *match = true;
+ else
+ *match = false;
+
+ return CSS_OK;
}
-void css__parse_tree(line_ctx *ctx, const char *data, size_t len)
+static css_error node_has_id(void *pw, void *n,
+ lwc_string *name,
+ bool *match)
{
- const char *p = data;
- const char *end = data + len;
- size_t left;
-
- /* [ <media_list> <pseudo>? ] ? */
-
- ctx->media.type = CSS_MEDIA_ALL;
- ctx->pseudo_element = CSS_PSEUDO_ELEMENT_NONE;
-
- /* Consume any leading whitespace */
- while (p < end && isspace(*p))
- p++;
-
- if (p < end) {
- left = end - p;
-
- css__parse_media_list(&p, &left, &ctx->media);
+ node *node = n;
+ uint32_t i;
+ line_ctx *ctx = pw;
- end = p + left;
+ for (i = 0; i < node->n_attrs; i++) {
+ bool amatch = false;
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, ctx->attr_id, &amatch) ==
+ lwc_error_ok);
+ if (amatch == true)
+ break;
}
- if (p < end) {
- left = end - p;
+ /* IDs are case-sensitive in HTML */
+ if (i != node->n_attrs && name == node->attrs[i].value)
+ *match = true;
+ else
+ *match = false;
- css__parse_pseudo_list(&p, &left, &ctx->pseudo_element);
- }
+ return CSS_OK;
}
-void css__parse_tree_data(line_ctx *ctx, const char *data, size_t len)
+static css_error node_has_attribute(void *pw, void *n,
+ const css_qname *qname,
+ bool *match)
{
- const char *p = data;
- const char *end = data + len;
- const char *name = NULL;
- const char *value = NULL;
- size_t namelen = 0;
- size_t valuelen = 0;
- uint32_t depth = 0;
- bool target = false;
-
- /* ' '{depth+1} [ <element> '*'? | <attr> ]
- *
- * <element> ::= [^=*[:space:]]+
- * <attr> ::= [^=*[:space:]]+ '=' [^[:space:]]*
- */
-
- while (p < end && isspace(*p)) {
- depth++;
- p++;
- }
- depth--;
-
- /* Get element/attribute name */
- name = p;
- while (p < end && *p != '=' && *p != '*' && isspace(*p) == false) {
- namelen++;
- p++;
- }
-
- /* Skip whitespace */
- while (p < end && isspace(*p))
- p++;
-
- if (p < end && *p == '=') {
- /* Attribute value */
- p++;
-
- value = p;
-
- while (p < end && isspace(*p) == false) {
- valuelen++;
- p++;
- }
- } else if (p < end && *p == '*') {
- /* Element is target node */
- target = true;
- }
-
- if (value == NULL) {
- /* We have an element, so create it */
- node *n = malloc(sizeof(node));
- assert(n != NULL);
-
- memset(n, 0, sizeof(node));
-
- lwc_intern_string(name, namelen, &n->name);
-
- /* Insert it into tree */
- if (ctx->tree == NULL) {
- ctx->tree = n;
- } else {
- assert(depth > 0);
- assert(depth <= ctx->depth + 1);
-
- /* Find node to insert into */
- while (depth <= ctx->depth) {
- ctx->depth--;
- ctx->current = ctx->current->parent;
- }
-
- /* Insert into current node */
- if (ctx->current->children == NULL) {
- ctx->current->children = n;
- ctx->current->last_child = n;
- } else {
- ctx->current->last_child->next = n;
- n->prev = ctx->current->last_child;
-
- ctx->current->last_child = n;
- }
- n->parent = ctx->current;
- }
-
- ctx->current = n;
- ctx->depth = depth;
-
- /* Mark the target, if it's us */
- if (target)
- ctx->target = n;
- } else {
- /* New attribute */
- bool amatch = false;
- attribute *attr;
- node *n = ctx->current;
-
- attribute *temp = realloc(n->attrs,
- (n->n_attrs + 1) * sizeof(attribute));
- assert(temp != NULL);
-
- n->attrs = temp;
-
- attr = &n->attrs[n->n_attrs];
-
- lwc_intern_string(name, namelen, &attr->name);
- lwc_intern_string(value, valuelen, &attr->value);
+ node *node = n;
+ uint32_t i;
+ UNUSED(pw);
+ *match = false;
+ for (i = 0; i < node->n_attrs; i++) {
assert(lwc_string_caseless_isequal(
- n->attrs[n->n_attrs].name,
- ctx->attr_class, &amatch) == lwc_error_ok);
- if (amatch == true) {
- n->classes = realloc(NULL, sizeof(lwc_string **));
- assert(n->classes != NULL);
-
- n->classes[0] = lwc_string_ref(
- n->attrs[n->n_attrs].
- value);
- n->n_classes = 1;
- }
-
- n->n_attrs++;
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
+ break;
}
+
+ return CSS_OK;
}
-static css_error css_font_resolution_func(void *pw, lwc_string *name,
- css_system_font *system_font)
+static css_error node_has_attribute_equal(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
{
- lwc_error err;
-
- if (system_font == NULL) {
- return CSS_BADPARM;
- }
+ node *node = n;
+ uint32_t i;
+ UNUSED(pw);
- (void)(pw);
+ *match = false;
- if (strncmp(lwc_string_data(name), "special-system-font",
- lwc_string_length(name)) != 0) {
- return CSS_INVALID;
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
+ break;
}
- system_font->style = CSS_FONT_STYLE_NORMAL;
- system_font->variant = CSS_FONT_VARIANT_NORMAL;
- system_font->weight = CSS_FONT_WEIGHT_NORMAL;
- system_font->size.size = INTTOFIX(22);
- system_font->size.unit = CSS_UNIT_PT;
- system_font->line_height.size = INTTOFIX(33);
- system_font->line_height.unit = CSS_UNIT_EM;
- err = lwc_intern_string("special-system-font",
- strlen("special-system-font"),
- &system_font->family);
- if (err != lwc_error_ok) {
- return CSS_NOMEM;
+ if (*match == true) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, value, match) ==
+ lwc_error_ok);
}
return CSS_OK;
}
-void css__parse_sheet(line_ctx *ctx, const char *data, size_t len)
+static css_error node_has_attribute_includes(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
{
- css_stylesheet_params params;
- const char *p;
- const char *end = data + len;
- css_origin origin = CSS_ORIGIN_AUTHOR;
- css_stylesheet *sheet;
- sheet_ctx *temp;
- char *media = NULL;
+ node *node = n;
+ uint32_t i;
+ size_t vlen = lwc_string_length(value);
+ UNUSED(pw);
- /* <origin> <media_list>? */
+ *match = false;
- /* Find end of origin */
- for (p = data; p < end; p++) {
- if (isspace(*p))
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
break;
}
- if (p - data == 6 && strncasecmp(data, "author", 6) == 0)
- origin = CSS_ORIGIN_AUTHOR;
- else if (p - data == 4 && strncasecmp(data, "user", 4) == 0)
- origin = CSS_ORIGIN_USER;
- else if (p - data == 2 && strncasecmp(data, "ua", 2) == 0)
- origin = CSS_ORIGIN_UA;
- else
- assert(0 && "Unknown stylesheet origin");
-
- /* Skip any whitespace */
- while (p < end && isspace(*p))
- p++;
-
- assert(end >= p);
- media = malloc(end - p + 1);
- assert(media != NULL);
- memcpy(media, p, end - p);
- media[end - p] = '\0';
-
- 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 = css_font_resolution_func;
- params.font_pw = NULL;
-
- /** \todo How are we going to handle @import? */
- assert(css_stylesheet_create(¶ms, &sheet) == CSS_OK);
-
- /* Extend array of sheets and append new sheet to it */
- temp = realloc(ctx->sheets,
- (ctx->n_sheets + 1) * sizeof(sheet_ctx));
- assert(temp != NULL);
-
- ctx->sheets = temp;
-
- ctx->sheets[ctx->n_sheets].sheet = sheet;
- ctx->sheets[ctx->n_sheets].origin = origin;
- ctx->sheets[ctx->n_sheets].media = media;
-
- ctx->n_sheets++;
-}
-
-void css__parse_media_list(const char **data, size_t *len, css_media *media)
-{
- const char *p = *data;
- const char *end = p + *len;
- uint64_t result = 0;
-
- /* <medium> [ ',' <medium> ]* */
-
- while (p < end) {
- const char *start = p;
+ if (*match == true) {
+ const char *p;
+ const char *start = lwc_string_data(node->attrs[i].value);
+ const char *end = start +
+ lwc_string_length(node->attrs[i].value);
- /* consume a medium */
- while (isspace(*p) == false && *p != ',')
- p++;
+ *match = false;
- if (p - start == 10 &&
- strncasecmp(start, "projection", 10) == 0)
- result |= CSS_MEDIA_PROJECTION;
- else if (p - start == 8 &&
- strncasecmp(start, "handheld", 8) == 0)
- result |= CSS_MEDIA_HANDHELD;
- else if (p - start == 8 &&
- strncasecmp(start, "embossed", 8) == 0)
- result |= CSS_MEDIA_EMBOSSED;
- else if (p - start == 7 &&
- strncasecmp(start, "braille", 7) == 0)
- result |= CSS_MEDIA_BRAILLE;
- else if (p - start == 6 &&
- strncasecmp(start, "speech", 6) == 0)
- result |= CSS_MEDIA_SPEECH;
- else if (p - start == 6 &&
- strncasecmp(start, "screen", 6) == 0)
- result |= CSS_MEDIA_SCREEN;
- else if (p - start == 5 &&
- strncasecmp(start, "print", 5) == 0)
- result |= CSS_MEDIA_PRINT;
- else if (p - start == 5 &&
- strncasecmp(start, "aural", 5) == 0)
- result |= CSS_MEDIA_AURAL;
- else if (p - start == 3 &&
- strncasecmp(start, "tty", 3) == 0)
- result |= CSS_MEDIA_TTY;
- else if (p - start == 3 &&
- strncasecmp(start, "all", 3) == 0)
- result |= CSS_MEDIA_ALL;
- else if (p - start == 2 &&
- strncasecmp(start, "tv", 2) == 0)
- result |= CSS_MEDIA_TV;
- else
- assert(0 && "Unknown media type");
+ for (p = start; p < end; p++) {
+ if (*p == ' ') {
+ if ((size_t) (p - start) == vlen &&
+ strncasecmp(start,
+ lwc_string_data(value),
+ vlen) == 0) {
+ *match = true;
+ break;
+ }
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
+ start = p + 1;
+ }
+ }
+ }
- /* Stop if we've reached the end */
- if (p == end || *p != ',')
- break;
+ return CSS_OK;
+}
- /* Consume comma */
- p++;
+static css_error node_has_attribute_dashmatch(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
+{
+ node *node = n;
+ uint32_t i;
+ size_t vlen = lwc_string_length(value);
+ UNUSED(pw);
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
+ *match = false;
+
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
+ break;
}
- media->type = result;
+ if (*match == true) {
+ const char *p;
+ const char *start = lwc_string_data(node->attrs[i].value);
+ const char *end = start +
+ lwc_string_length(node->attrs[i].value);
- *data = p;
- *len = end - p;
+ *match = false;
+
+ for (p = start; p < end; p++) {
+ if (*p == '-') {
+ if ((size_t) (p - start) == vlen &&
+ strncasecmp(start,
+ lwc_string_data(value),
+ vlen) == 0) {
+ *match = true;
+ break;
+ }
+
+ start = p + 1;
+ }
+ }
+ }
+
+ return CSS_OK;
}
-void css__parse_pseudo_list(const char **data, size_t *len, uint32_t *element)
+static css_error node_has_attribute_prefix(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
{
- const char *p = *data;
- const char *end = p + *len;
+ node *node = n;
+ uint32_t i;
+ UNUSED(pw);
- /* <pseudo> [ ',' <pseudo> ]* */
+ *match = false;
- *element = CSS_PSEUDO_ELEMENT_NONE;
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
+ break;
+ }
- while (p < end) {
- const char *start = p;
+ if (*match == true) {
+ size_t len = lwc_string_length(node->attrs[i].value);
+ const char *data = lwc_string_data(node->attrs[i].value);
- /* consume a pseudo */
- while (isspace(*p) == false && *p != ',')
- p++;
+ size_t vlen = lwc_string_length(value);
+ const char *vdata = lwc_string_data(value);
- /* Pseudo elements */
- if (p - start == 12 &&
- strncasecmp(start, "first-letter", 12) == 0)
- *element = CSS_PSEUDO_ELEMENT_FIRST_LETTER;
- else if (p - start == 10 &&
- strncasecmp(start, "first-line", 10) == 0)
- *element = CSS_PSEUDO_ELEMENT_FIRST_LINE;
- else if (p - start == 6 &&
- strncasecmp(start, "before", 6) == 0)
- *element = CSS_PSEUDO_ELEMENT_BEFORE;
- else if (p - start == 5 &&
- strncasecmp(start, "after", 5) == 0)
- *element = CSS_PSEUDO_ELEMENT_AFTER;
+ if (len < vlen)
+ *match = false;
else
- assert(0 && "Unknown pseudo");
+ *match = (strncasecmp(data, vdata, vlen) == 0);
+ }
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
+ return CSS_OK;
+}
- /* Stop if we've reached the end */
- if (p == end || *p != ',')
+static css_error node_has_attribute_suffix(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
+{
+ node *node = n;
+ uint32_t i;
+ UNUSED(pw);
+
+ *match = false;
+
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
break;
+ }
- /* Consume comma */
- p++;
+ if (*match == true) {
+ size_t len = lwc_string_length(node->attrs[i].value);
+ const char *data = lwc_string_data(node->attrs[i].value);
- /* Consume whitespace */
- while (p < end && isspace(*p))
- p++;
+ size_t vlen = lwc_string_length(value);
+ const char *vdata = lwc_string_data(value);
+
+ size_t suffix_start = len - vlen;
+
+ if (len < vlen)
+ *match = false;
+ else {
+ *match = (strncasecmp(data + suffix_start,
+ vdata, vlen) == 0);
+ }
}
- *data = p;
- *len = end - p;
+ return CSS_OK;
}
-void css__parse_expected(line_ctx *ctx, const char *data, size_t len)
+static css_error node_has_attribute_substring(void *pw, void *n,
+ const css_qname *qname,
+ lwc_string *value,
+ bool *match)
{
- while (ctx->expused + len >= ctx->explen) {
- size_t required = ctx->explen == 0 ? 64 : ctx->explen * 2;
- char *temp = realloc(ctx->exp, required);
- if (temp == NULL) {
- assert(0 && "No memory for expected output");
- }
+ node *node = n;
+ uint32_t i;
+ UNUSED(pw);
- ctx->exp = temp;
- ctx->explen = required;
+ *match = false;
+
+ for (i = 0; i < node->n_attrs; i++) {
+ assert(lwc_string_caseless_isequal(
+ node->attrs[i].name, qname->name, match) ==
+ lwc_error_ok);
+ if (*match == true)
+ break;
}
- memcpy(ctx->exp + ctx->expused, data, len);
+ if (*match == true) {
+ size_t len = lwc_string_length(node->attrs[i].value);
+ const char *data = lwc_string_data(node->attrs[i].value);
- ctx->expused += len;
-}
+ size_t vlen = lwc_string_length(value);
+ const char *vdata = lwc_string_data(value);
-static void show_differences(size_t len, const char *exp, const char *res)
-{
- const char *pos_exp, *opos_exp;
- const char *pos_res, *opos_res;
+ const char *last_start = data + len - vlen;
- opos_exp = pos_exp = exp;
- opos_res = pos_res = res;
+ if (len < vlen)
+ *match = false;
+ else {
+ while (data <= last_start) {
+ if (strncasecmp(data, vdata, vlen) == 0) {
+ *match = true;
+ break;
+ }
- printf("Line differences:\n");
- while (pos_exp < exp + len && pos_res < res + len) {
- if (*pos_exp == '\n' && *pos_res == '\n') {
- if (pos_exp - opos_exp != pos_res - opos_res ||
- memcmp(opos_exp, opos_res,
- pos_exp - opos_exp) != 0) {
- printf("Expected:\t%.*s\n",
- (int)(pos_exp - opos_exp),
- opos_exp);
- printf(" Result:\t%.*s\n",
- (int)(pos_res - opos_res),
- opos_res);
- printf("\n");
+ data++;
}
- opos_exp = ++pos_exp;
- opos_res = ++pos_res;
- } else if (*pos_exp == '\n') {
- pos_res++;
- } else if (*pos_res == '\n') {
- pos_exp++;
- } else {
- pos_exp++;
- pos_res++;
+
+ if (data > last_start)
+ *match = false;
}
}
+
+ return CSS_OK;
}
+static css_error node_is_root(void *pw, void *n, bool *match)
+{
+ node *node = n;
+ UNUSED(pw);
-static void run_test_select_tree(css_select_ctx *select,
- node *node, line_ctx *ctx,
- char *buf, size_t *buflen)
+ *match = (node->parent == NULL);
+
+ return CSS_OK;
+}
+
+static css_error node_count_siblings(void *pw, void *n,
+ bool same_name, bool after, int32_t *count)
{
- css_select_results *sr;
- struct node *n = NULL;
+ int32_t cnt = 0;
+ bool match = false;
+ node *node = n;
+ lwc_string *name = node->name;
+ UNUSED(pw);
- if (node->parent == NULL) {
- unit_ctx.root_style = NULL;
- }
+ if (after) {
+ while (node->next != NULL) {
+ if (same_name) {
+ assert(lwc_string_caseless_isequal(
+ name, node->next->name, &match) ==
+ lwc_error_ok);
+
+ if (match)
+ cnt++;
+ } else {
+ cnt++;
+ }
+ node = node->next;
+ }
+ } else {
+ while (node->prev != NULL) {
+ if (same_name) {
+ assert(lwc_string_caseless_isequal(
+ name, node->prev->name, &match) ==
+ lwc_error_ok);
- assert(css_select_style(select, node, &unit_ctx, &ctx->media, NULL,
- &select_handler, ctx, &sr) == CSS_OK);
+ if (match)
+ cnt++;
+ } else {
+ cnt++;
+ }
- if (node->parent != NULL) {
- css_computed_style *composed;
- assert(css_computed_style_compose(
- node->parent->sr->styles[ctx->pseudo_element],
- sr->styles[ctx->pseudo_element],
- &unit_ctx,
- &composed) == CSS_OK);
- css_computed_style_destroy(sr->styles[ctx->pseudo_element]);
- sr->styles[ctx->pseudo_element] = composed;
+ node = node->prev;
+ }
}
- node->sr = sr;
+ *count = cnt;
- if (node == ctx->target) {
- dump_computed_style(sr->styles[ctx->pseudo_element],
- buf, buflen);
- }
+ return CSS_OK;
+}
- if (node->parent == NULL) {
- unit_ctx.root_style = node->sr->styles[ctx->pseudo_element];
- }
+static css_error node_is_empty(void *pw, void *n, bool *match)
+{
+ node *node = n;
+ UNUSED(pw);
- for (n = node->children; n != NULL; n = n->next) {
- run_test_select_tree(select, n, ctx, buf, buflen);
- }
-}
+ *match = (node->children == NULL);
+ return CSS_OK;
+}
-void run_test(line_ctx *ctx, const char *exp, size_t explen)
+static css_error node_is_link(void *pw, void *n, bool *match)
{
- css_select_ctx *select;
- css_select_results *results;
- uint32_t i;
- char *buf;
- size_t buflen;
- static int testnum;
+ node *node = n;
- UNUSED(exp);
+ UNUSED(pw);
+ UNUSED(node);
- buf = malloc(8192);
- if (buf == NULL) {
- assert(0 && "No memory for result data");
- }
- buflen = 8192;
+ *match = false;
- assert(css_select_ctx_create(&select) == CSS_OK);
+ return CSS_OK;
+}
- for (i = 0; i < ctx->n_sheets; i++) {
- assert(css_select_ctx_append_sheet(select,
- ctx->sheets[i].sheet, ctx->sheets[i].origin,
- ctx->sheets[i].media) == CSS_OK);
- }
+static css_error node_is_visited(void *pw, void *n, bool *match)
+{
+ node *node = n;
- testnum++;
+ UNUSED(pw);
+ UNUSED(node);
- run_test_select_tree(select, ctx->tree, ctx, buf, &buflen);
+ *match = false;
- results = ctx->target->sr;
- assert(results->styles[ctx->pseudo_element] != NULL);
+ return CSS_OK;
+}
- if (8192 - buflen != explen || memcmp(buf, exp, explen) != 0) {
- size_t len = 8192 - buflen < explen ? 8192 - buflen : explen;
- printf("Expected (%u):\n%.*s\n",
- (int) explen, (int) explen, exp);
- printf("Result (%u):\n%.*s\n", (int) (8192 - buflen),
- (int) (8192 - buflen), buf);
+static css_error node_is_hover(void *pw, void *n, bool *match)
+{
+ node *node = n;
- show_differences(len, exp, buf);
- assert(0 && "Result doesn't match expected");
- }
+ UNUSED(pw);
+ UNUSED(node);
- /* Clean up */
- css_select_ctx_destroy(select);
- destroy_tree(ctx->tree);
+ *match = false;
- for (i = 0; i < ctx->n_sheets; i++) {
- css_stylesheet_destroy(ctx->sheets[i].sheet);
- free(ctx->sheets[i].media);
- }
+ return CSS_OK;
+}
- ctx->tree = NULL;
- ctx->current = NULL;
- ctx->depth = 0;
- ctx->n_sheets = 0;
- free(ctx->sheets);
- ctx->sheets = NULL;
- ctx->target = NULL;
+static css_error node_is_active(void *pw, void *n, bool *match)
+{
+ node *node = n;
- free(buf);
+ UNUSED(pw);
+ UNUSED(node);
- printf("Test %d: PASS\n", testnum);
+ *match = false;
+
+ return CSS_OK;
}
-void destroy_tree(node *root)
+static css_error node_is_focus(void *pw, void *n, bool *match)
{
- node *n, *p;
- uint32_t i;
+ node *node = n;
- for (n = root->children; n != NULL; n = p) {
- p = n->next;
+ UNUSED(pw);
+ UNUSED(node);
- destroy_tree(n);
- }
+ *match = false;
- css_select_results_destroy(root->sr);
+ return CSS_OK;
+}
- for (i = 0; i < root->n_attrs; ++i) {
- lwc_string_unref(root->attrs[i].name);
- lwc_string_unref(root->attrs[i].value);
- }
- free(root->attrs);
+static css_error node_is_enabled(void *pw, void *n, bool *match)
+{
+ node *node = n;
- if (root->classes != NULL) {
- for (i = 0; i < root->n_classes; ++i) {
- lwc_string_unref(root->classes[i]);
- }
- free(root->classes);
- }
+ UNUSED(pw);
+ UNUSED(node);
- if (root->libcss_node_data != NULL) {
- css_libcss_node_data_handler(&select_handler, CSS_NODE_DELETED,
- NULL, root, NULL, root->libcss_node_data);
- }
+ *match = false;
- lwc_string_unref(root->name);
- free(root);
+ return CSS_OK;
}
-
-css_error node_name(void *pw, void *n, css_qname *qname)
+static css_error node_is_disabled(void *pw, void *n, bool *match)
{
node *node = n;
UNUSED(pw);
+ UNUSED(node);
- qname->name = lwc_string_ref(node->name);
+ *match = false;
return CSS_OK;
}
-static css_error node_classes(void *pw, void *n,
- lwc_string ***classes, uint32_t *n_classes)
+static css_error node_is_checked(void *pw, void *n, bool *match)
{
- unsigned int i;
node *node = n;
- UNUSED(pw);
- *classes = node->classes;
- *n_classes = node->n_classes;
+ UNUSED(pw);
+ UNUSED(node);
- for (i = 0; i < *n_classes; i++)
- (*classes)[i] = lwc_string_ref(node->classes[i]);
+ *match = false;
return CSS_OK;
-
}
-css_error node_id(void *pw, void *n,
- lwc_string **id)
+static css_error node_is_target(void *pw, void *n, bool *match)
{
node *node = n;
- uint32_t i;
- line_ctx *lc = pw;
- for (i = 0; i < node->n_attrs; i++) {
- bool amatch = false;
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, lc->attr_id, &amatch) ==
- lwc_error_ok);
- if (amatch == true)
- break;
- }
+ UNUSED(pw);
+ UNUSED(node);
- if (i != node->n_attrs)
- *id = lwc_string_ref(node->attrs[i].value);
- else
- *id = NULL;
+ *match = false;
return CSS_OK;
}
-css_error named_ancestor_node(void *pw, void *n,
- const css_qname *qname,
- void **ancestor)
+static css_error node_is_lang(void *pw, void *n,
+ lwc_string *lang,
+ bool *match)
{
node *node = n;
- UNUSED(pw);
- for (node = node->parent; node != NULL; node = node->parent) {
- bool match = false;
- assert(lwc_string_caseless_isequal(
- qname->name, node->name,
- &match) == lwc_error_ok);
- if (match == true)
- break;
- }
+ UNUSED(pw);
+ UNUSED(node);
+ UNUSED(lang);
- *ancestor = (void *) node;
+ *match = false;
return CSS_OK;
}
-css_error named_parent_node(void *pw, void *n,
- const css_qname *qname,
- void **parent)
+static css_error node_presentational_hint(void *pw, void *node,
+ uint32_t *nhints, css_hint **hints)
{
- node *node = n;
UNUSED(pw);
+ UNUSED(node);
- *parent = NULL;
- if (node->parent != NULL) {
- bool match = false;
- assert(lwc_string_caseless_isequal(
- qname->name, node->parent->name, &match) ==
- lwc_error_ok);
- if (match == true)
- *parent = (void *) node->parent;
- }
+ *nhints = 0;
+ *hints = NULL;
return CSS_OK;
}
-css_error named_sibling_node(void *pw, void *n,
- const css_qname *qname,
- void **sibling)
+static css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
{
- node *node = n;
UNUSED(pw);
- *sibling = NULL;
- if (node->prev != NULL) {
- bool match = false;
- assert(lwc_string_caseless_isequal(
- qname->name, node->prev->name, &match) ==
- lwc_error_ok);
- if (match == true)
- *sibling = (void *) node->prev;
+ if (property == CSS_PROP_COLOR) {
+ hint->data.color = 0xff000000;
+ hint->status = CSS_COLOR_COLOR;
+ } else if (property == CSS_PROP_FONT_FAMILY) {
+ hint->data.strings = NULL;
+ hint->status = CSS_FONT_FAMILY_SANS_SERIF;
+ } else if (property == CSS_PROP_QUOTES) {
+ /* Not exactly useful :) */
+ hint->data.strings = NULL;
+ hint->status = CSS_QUOTES_NONE;
+ } else if (property == CSS_PROP_VOICE_FAMILY) {
+ /** \todo Fix this when we have voice-family done */
+ hint->data.strings = NULL;
+ hint->status = 0;
+ } else {
+ return CSS_INVALID;
}
return CSS_OK;
}
-css_error named_generic_sibling_node(void *pw, void *n,
- const css_qname *qname,
- void **sibling)
+static css_error set_libcss_node_data(void *pw, void *n,
+ void *libcss_node_data)
{
node *node = n;
UNUSED(pw);
- for (node = node->prev; node != NULL; node = node->prev) {
- bool match = false;
- assert(lwc_string_caseless_isequal(
- qname->name, node->name,
- &match) == lwc_error_ok);
- if (match == true)
- break;
- }
-
- *sibling = (void *) node;
+ node->libcss_node_data = libcss_node_data;
return CSS_OK;
}
-css_error parent_node(void *pw, void *n, void **parent)
+static css_error get_libcss_node_data(void *pw, void *n,
+ void **libcss_node_data)
{
node *node = n;
-
UNUSED(pw);
- *parent = (void *) node->parent;
+ /* Pass any node data back to libcss */
+ *libcss_node_data = node->libcss_node_data;
return CSS_OK;
}
-css_error sibling_node(void *pw, void *n, void **sibling)
-{
- node *node = n;
+static css_unit_ctx unit_ctx = {
+ .font_size_default = 16 * (1 << CSS_RADIX_POINT),
+};
+
+static css_select_handler select_handler = {
+ CSS_SELECT_HANDLER_VERSION_1,
+
+ node_name,
+ node_classes,
+ node_id,
+ named_ancestor_node,
+ named_parent_node,
+ named_sibling_node,
+ named_generic_sibling_node,
+ parent_node,
+ sibling_node,
+ node_has_name,
+ node_has_class,
+ node_has_id,
+ node_has_attribute,
+ node_has_attribute_equal,
+ node_has_attribute_dashmatch,
+ node_has_attribute_includes,
+ node_has_attribute_prefix,
+ node_has_attribute_suffix,
+ node_has_attribute_substring,
+ node_is_root,
+ node_count_siblings,
+ node_is_empty,
+ node_is_link,
+ node_is_visited,
+ node_is_hover,
+ node_is_active,
+ node_is_focus,
+ node_is_enabled,
+ node_is_disabled,
+ node_is_checked,
+ node_is_target,
+ node_is_lang,
+ node_presentational_hint,
+ ua_default_for_property,
+ set_libcss_node_data,
+ get_libcss_node_data,
+};
+
+static css_error resolve_url(void *pw,
+ const char *base, lwc_string *rel, lwc_string **abs)
+{
UNUSED(pw);
+ UNUSED(base);
- *sibling = (void *) node->prev;
+ /* About as useless as possible */
+ *abs = lwc_string_ref(rel);
return CSS_OK;
}
-css_error node_has_name(void *pw, void *n,
- const css_qname *qname,
- bool *match)
+static bool fail_because_lwc_leaked = false;
+
+static void
+printing_lwc_iterator(lwc_string *str, void *pw)
{
- node *node = n;
UNUSED(pw);
- if (lwc_string_length(qname->name) == 1 &&
- lwc_string_data(qname->name)[0] == '*')
- *match = true;
- else
- assert(lwc_string_caseless_isequal(node->name,
- qname->name, match) == lwc_error_ok);
+ printf(" DICT: %*s\n", (int)(lwc_string_length(str)), lwc_string_data(str));
+ fail_because_lwc_leaked = true;
+}
+
+static css_error css_font_resolution_func(void *pw, lwc_string *name,
+ css_system_font *system_font)
+{
+ lwc_error err;
+
+ if (system_font == NULL) {
+ return CSS_BADPARM;
+ }
+
+ (void)(pw);
+
+ if (strncmp(lwc_string_data(name), "special-system-font",
+ lwc_string_length(name)) != 0) {
+ return CSS_INVALID;
+ }
+
+ system_font->style = CSS_FONT_STYLE_NORMAL;
+ system_font->variant = CSS_FONT_VARIANT_NORMAL;
+ system_font->weight = CSS_FONT_WEIGHT_NORMAL;
+ system_font->size.size = INTTOFIX(22);
+ system_font->size.unit = CSS_UNIT_PT;
+ system_font->line_height.size = INTTOFIX(33);
+ system_font->line_height.unit = CSS_UNIT_EM;
+ err = lwc_intern_string("special-system-font",
+ strlen("special-system-font"),
+ &system_font->family);
+ if (err != lwc_error_ok) {
+ return CSS_NOMEM;
+ }
return CSS_OK;
}
-css_error node_has_class(void *pw, void *n,
- lwc_string *name,
- bool *match)
+static void css__parse_sheet(line_ctx *ctx, const char *data, size_t len)
{
- node *node = n;
- uint32_t i;
- line_ctx *ctx = pw;
+ css_stylesheet_params params;
+ const char *p;
+ const char *end = data + len;
+ css_origin origin = CSS_ORIGIN_AUTHOR;
+ css_stylesheet *sheet;
+ sheet_ctx *temp;
+ char *media = NULL;
- for (i = 0; i < node->n_attrs; i++) {
- bool amatch = false;
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, ctx->attr_class,
- &amatch) == lwc_error_ok);
- if (amatch == true)
+ /* <origin> <media_list>? */
+
+ /* Find end of origin */
+ for (p = data; p < end; p++) {
+ if (isspace(*p))
break;
}
- /* Classes are case-sensitive in HTML */
- if (i != node->n_attrs && name == node->attrs[i].value)
- *match = true;
+ if (p - data == 6 && strncasecmp(data, "author", 6) == 0)
+ origin = CSS_ORIGIN_AUTHOR;
+ else if (p - data == 4 && strncasecmp(data, "user", 4) == 0)
+ origin = CSS_ORIGIN_USER;
+ else if (p - data == 2 && strncasecmp(data, "ua", 2) == 0)
+ origin = CSS_ORIGIN_UA;
else
- *match = false;
+ assert(0 && "Unknown stylesheet origin");
- return CSS_OK;
+ /* Skip any whitespace */
+ while (p < end && isspace(*p))
+ p++;
+
+ assert(end >= p);
+ media = malloc(end - p + 1);
+ assert(media != NULL);
+ memcpy(media, p, end - p);
+ media[end - p] = '\0';
+
+ 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 = css_font_resolution_func;
+ params.font_pw = NULL;
+
+ /** \todo How are we going to handle @import? */
+ assert(css_stylesheet_create(¶ms, &sheet) == CSS_OK);
+
+ /* Extend array of sheets and append new sheet to it */
+ temp = realloc(ctx->sheets,
+ (ctx->n_sheets + 1) * sizeof(sheet_ctx));
+ assert(temp != NULL);
+
+ ctx->sheets = temp;
+
+ ctx->sheets[ctx->n_sheets].sheet = sheet;
+ ctx->sheets[ctx->n_sheets].origin = origin;
+ ctx->sheets[ctx->n_sheets].media = media;
+
+ ctx->n_sheets++;
}
-css_error node_has_id(void *pw, void *n,
- lwc_string *name,
- bool *match)
+static void css__parse_media_list(const char **data, size_t *len, css_media *media)
{
- node *node = n;
- uint32_t i;
- line_ctx *ctx = pw;
+ const char *p = *data;
+ const char *end = p + *len;
+ uint64_t result = 0;
- for (i = 0; i < node->n_attrs; i++) {
- bool amatch = false;
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, ctx->attr_id, &amatch) ==
- lwc_error_ok);
- if (amatch == true)
- break;
- }
+ /* <medium> [ ',' <medium> ]* */
+
+ while (p < end) {
+ const char *start = p;
+
+ /* consume a medium */
+ while (isspace(*p) == false && *p != ',')
+ p++;
+
+ if (p - start == 10 &&
+ strncasecmp(start, "projection", 10) == 0)
+ result |= CSS_MEDIA_PROJECTION;
+ else if (p - start == 8 &&
+ strncasecmp(start, "handheld", 8) == 0)
+ result |= CSS_MEDIA_HANDHELD;
+ else if (p - start == 8 &&
+ strncasecmp(start, "embossed", 8) == 0)
+ result |= CSS_MEDIA_EMBOSSED;
+ else if (p - start == 7 &&
+ strncasecmp(start, "braille", 7) == 0)
+ result |= CSS_MEDIA_BRAILLE;
+ else if (p - start == 6 &&
+ strncasecmp(start, "speech", 6) == 0)
+ result |= CSS_MEDIA_SPEECH;
+ else if (p - start == 6 &&
+ strncasecmp(start, "screen", 6) == 0)
+ result |= CSS_MEDIA_SCREEN;
+ else if (p - start == 5 &&
+ strncasecmp(start, "print", 5) == 0)
+ result |= CSS_MEDIA_PRINT;
+ else if (p - start == 5 &&
+ strncasecmp(start, "aural", 5) == 0)
+ result |= CSS_MEDIA_AURAL;
+ else if (p - start == 3 &&
+ strncasecmp(start, "tty", 3) == 0)
+ result |= CSS_MEDIA_TTY;
+ else if (p - start == 3 &&
+ strncasecmp(start, "all", 3) == 0)
+ result |= CSS_MEDIA_ALL;
+ else if (p - start == 2 &&
+ strncasecmp(start, "tv", 2) == 0)
+ result |= CSS_MEDIA_TV;
+ else
+ assert(0 && "Unknown media type");
- /* IDs are case-sensitive in HTML */
- if (i != node->n_attrs && name == node->attrs[i].value)
- *match = true;
- else
- *match = false;
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
- return CSS_OK;
-}
+ /* Stop if we've reached the end */
+ if (p == end || *p != ',')
+ break;
-css_error node_has_attribute(void *pw, void *n,
- const css_qname *qname,
- bool *match)
-{
- node *node = n;
- uint32_t i;
- UNUSED(pw);
+ /* Consume comma */
+ p++;
- *match = false;
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
}
- return CSS_OK;
+ media->type = result;
+
+ *data = p;
+ *len = end - p;
}
-css_error node_has_attribute_equal(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
+static void css__parse_pseudo_list(const char **data, size_t *len, uint32_t *element)
{
- node *node = n;
- uint32_t i;
- UNUSED(pw);
+ const char *p = *data;
+ const char *end = p + *len;
- *match = false;
+ /* <pseudo> [ ',' <pseudo> ]* */
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
- }
+ *element = CSS_PSEUDO_ELEMENT_NONE;
- if (*match == true) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, value, match) ==
- lwc_error_ok);
- }
+ while (p < end) {
+ const char *start = p;
- return CSS_OK;
-}
+ /* consume a pseudo */
+ while (isspace(*p) == false && *p != ',')
+ p++;
-css_error node_has_attribute_includes(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
-{
- node *node = n;
- uint32_t i;
- size_t vlen = lwc_string_length(value);
- UNUSED(pw);
+ /* Pseudo elements */
+ if (p - start == 12 &&
+ strncasecmp(start, "first-letter", 12) == 0)
+ *element = CSS_PSEUDO_ELEMENT_FIRST_LETTER;
+ else if (p - start == 10 &&
+ strncasecmp(start, "first-line", 10) == 0)
+ *element = CSS_PSEUDO_ELEMENT_FIRST_LINE;
+ else if (p - start == 6 &&
+ strncasecmp(start, "before", 6) == 0)
+ *element = CSS_PSEUDO_ELEMENT_BEFORE;
+ else if (p - start == 5 &&
+ strncasecmp(start, "after", 5) == 0)
+ *element = CSS_PSEUDO_ELEMENT_AFTER;
+ else
+ assert(0 && "Unknown pseudo");
- *match = false;
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
+ /* Stop if we've reached the end */
+ if (p == end || *p != ',')
break;
- }
-
- if (*match == true) {
- const char *p;
- const char *start = lwc_string_data(node->attrs[i].value);
- const char *end = start +
- lwc_string_length(node->attrs[i].value);
- *match = false;
-
- for (p = start; p < end; p++) {
- if (*p == ' ') {
- if ((size_t) (p - start) == vlen &&
- strncasecmp(start,
- lwc_string_data(value),
- vlen) == 0) {
- *match = true;
- break;
- }
+ /* Consume comma */
+ p++;
- start = p + 1;
- }
- }
+ /* Consume whitespace */
+ while (p < end && isspace(*p))
+ p++;
}
- return CSS_OK;
+ *data = p;
+ *len = end - p;
}
-css_error node_has_attribute_dashmatch(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
+static void css__parse_tree(line_ctx *ctx, const char *data, size_t len)
{
- node *node = n;
- uint32_t i;
- size_t vlen = lwc_string_length(value);
- UNUSED(pw);
+ const char *p = data;
+ const char *end = data + len;
+ size_t left;
- *match = false;
+ /* [ <media_list> <pseudo>? ] ? */
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
- }
+ ctx->media.type = CSS_MEDIA_ALL;
+ ctx->pseudo_element = CSS_PSEUDO_ELEMENT_NONE;
- if (*match == true) {
- const char *p;
- const char *start = lwc_string_data(node->attrs[i].value);
- const char *end = start +
- lwc_string_length(node->attrs[i].value);
+ /* Consume any leading whitespace */
+ while (p < end && isspace(*p))
+ p++;
- *match = false;
+ if (p < end) {
+ left = end - p;
- for (p = start; p < end; p++) {
- if (*p == '-') {
- if ((size_t) (p - start) == vlen &&
- strncasecmp(start,
- lwc_string_data(value),
- vlen) == 0) {
- *match = true;
- break;
- }
+ css__parse_media_list(&p, &left, &ctx->media);
- start = p + 1;
- }
- }
+ end = p + left;
}
- return CSS_OK;
+ if (p < end) {
+ left = end - p;
+
+ css__parse_pseudo_list(&p, &left, &ctx->pseudo_element);
+ }
}
-css_error node_has_attribute_prefix(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
+static void css__parse_expected(line_ctx *ctx, const char *data, size_t len)
{
- node *node = n;
- uint32_t i;
- UNUSED(pw);
-
- *match = false;
+ while (ctx->expused + len >= ctx->explen) {
+ size_t required = ctx->explen == 0 ? 64 : ctx->explen * 2;
+ char *temp = realloc(ctx->exp, required);
+ if (temp == NULL) {
+ assert(0 && "No memory for expected output");
+ }
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
+ ctx->exp = temp;
+ ctx->explen = required;
}
- if (*match == true) {
- size_t len = lwc_string_length(node->attrs[i].value);
- const char *data = lwc_string_data(node->attrs[i].value);
-
- size_t vlen = lwc_string_length(value);
- const char *vdata = lwc_string_data(value);
-
- if (len < vlen)
- *match = false;
- else
- *match = (strncasecmp(data, vdata, vlen) == 0);
- }
+ memcpy(ctx->exp + ctx->expused, data, len);
- return CSS_OK;
+ ctx->expused += len;
}
-css_error node_has_attribute_suffix(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
+static void css__parse_tree_data(line_ctx *ctx, const char *data, size_t len)
{
- node *node = n;
- uint32_t i;
- UNUSED(pw);
+ const char *p = data;
+ const char *end = data + len;
+ const char *name = NULL;
+ const char *value = NULL;
+ size_t namelen = 0;
+ size_t valuelen = 0;
+ uint32_t depth = 0;
+ bool target = false;
- *match = false;
+ /* ' '{depth+1} [ <element> '*'? | <attr> ]
+ *
+ * <element> ::= [^=*[:space:]]+
+ * <attr> ::= [^=*[:space:]]+ '=' [^[:space:]]*
+ */
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
+ while (p < end && isspace(*p)) {
+ depth++;
+ p++;
+ }
+ depth--;
+
+ /* Get element/attribute name */
+ name = p;
+ while (p < end && *p != '=' && *p != '*' && isspace(*p) == false) {
+ namelen++;
+ p++;
}
- if (*match == true) {
- size_t len = lwc_string_length(node->attrs[i].value);
- const char *data = lwc_string_data(node->attrs[i].value);
+ /* Skip whitespace */
+ while (p < end && isspace(*p))
+ p++;
- size_t vlen = lwc_string_length(value);
- const char *vdata = lwc_string_data(value);
+ if (p < end && *p == '=') {
+ /* Attribute value */
+ p++;
- size_t suffix_start = len - vlen;
+ value = p;
- if (len < vlen)
- *match = false;
- else {
- *match = (strncasecmp(data + suffix_start,
- vdata, vlen) == 0);
+ while (p < end && isspace(*p) == false) {
+ valuelen++;
+ p++;
}
+ } else if (p < end && *p == '*') {
+ /* Element is target node */
+ target = true;
}
- return CSS_OK;
-}
-
-css_error node_has_attribute_substring(void *pw, void *n,
- const css_qname *qname,
- lwc_string *value,
- bool *match)
-{
- node *node = n;
- uint32_t i;
- UNUSED(pw);
-
- *match = false;
+ if (value == NULL) {
+ /* We have an element, so create it */
+ node *n = malloc(sizeof(node));
+ assert(n != NULL);
- for (i = 0; i < node->n_attrs; i++) {
- assert(lwc_string_caseless_isequal(
- node->attrs[i].name, qname->name, match) ==
- lwc_error_ok);
- if (*match == true)
- break;
- }
+ memset(n, 0, sizeof(node));
- if (*match == true) {
- size_t len = lwc_string_length(node->attrs[i].value);
- const char *data = lwc_string_data(node->attrs[i].value);
+ lwc_intern_string(name, namelen, &n->name);
- size_t vlen = lwc_string_length(value);
- const char *vdata = lwc_string_data(value);
+ /* Insert it into tree */
+ if (ctx->tree == NULL) {
+ ctx->tree = n;
+ } else {
+ assert(depth > 0);
+ assert(depth <= ctx->depth + 1);
- const char *last_start = data + len - vlen;
+ /* Find node to insert into */
+ while (depth <= ctx->depth) {
+ ctx->depth--;
+ ctx->current = ctx->current->parent;
+ }
- if (len < vlen)
- *match = false;
- else {
- while (data <= last_start) {
- if (strncasecmp(data, vdata, vlen) == 0) {
- *match = true;
- break;
- }
+ /* Insert into current node */
+ if (ctx->current->children == NULL) {
+ ctx->current->children = n;
+ ctx->current->last_child = n;
+ } else {
+ ctx->current->last_child->next = n;
+ n->prev = ctx->current->last_child;
- data++;
+ ctx->current->last_child = n;
}
-
- if (data > last_start)
- *match = false;
+ n->parent = ctx->current;
}
- }
- return CSS_OK;
-}
+ ctx->current = n;
+ ctx->depth = depth;
-css_error node_is_root(void *pw, void *n, bool *match)
-{
- node *node = n;
- UNUSED(pw);
+ /* Mark the target, if it's us */
+ if (target)
+ ctx->target = n;
+ } else {
+ /* New attribute */
+ bool amatch = false;
+ attribute *attr;
+ node *n = ctx->current;
- *match = (node->parent == NULL);
+ attribute *temp = realloc(n->attrs,
+ (n->n_attrs + 1) * sizeof(attribute));
+ assert(temp != NULL);
- return CSS_OK;
-}
+ n->attrs = temp;
-css_error node_count_siblings(void *pw, void *n,
- bool same_name, bool after, int32_t *count)
-{
- int32_t cnt = 0;
- bool match = false;
- node *node = n;
- lwc_string *name = node->name;
- UNUSED(pw);
+ attr = &n->attrs[n->n_attrs];
- if (after) {
- while (node->next != NULL) {
- if (same_name) {
- assert(lwc_string_caseless_isequal(
- name, node->next->name, &match) ==
- lwc_error_ok);
+ lwc_intern_string(name, namelen, &attr->name);
+ lwc_intern_string(value, valuelen, &attr->value);
- if (match)
- cnt++;
- } else {
- cnt++;
- }
+ assert(lwc_string_caseless_isequal(
+ n->attrs[n->n_attrs].name,
+ ctx->attr_class, &amatch) == lwc_error_ok);
+ if (amatch == true) {
+ n->classes = realloc(NULL, sizeof(lwc_string **));
+ assert(n->classes != NULL);
- node = node->next;
+ n->classes[0] = lwc_string_ref(
+ n->attrs[n->n_attrs].
+ value);
+ n->n_classes = 1;
}
- } else {
- while (node->prev != NULL) {
- if (same_name) {
- assert(lwc_string_caseless_isequal(
- name, node->prev->name, &match) ==
- lwc_error_ok);
-
- if (match)
- cnt++;
- } else {
- cnt++;
- }
- node = node->prev;
- }
+ n->n_attrs++;
}
-
- *count = cnt;
-
- return CSS_OK;
}
-css_error node_is_empty(void *pw, void *n, bool *match)
-{
- node *node = n;
- UNUSED(pw);
-
- *match = (node->children == NULL);
-
- return CSS_OK;
-}
-css_error node_is_link(void *pw, void *n, bool *match)
+static void run_test_select_tree(css_select_ctx *select,
+ node *node, line_ctx *ctx,
+ char *buf, size_t *buflen)
{
- node *node = n;
+ css_select_results *sr;
+ struct node *n = NULL;
- UNUSED(pw);
- UNUSED(node);
+ if (node->parent == NULL) {
+ unit_ctx.root_style = NULL;
+ }
- *match = false;
- return CSS_OK;
-}
+ assert(css_select_style(select, node, &unit_ctx, &ctx->media, NULL,
+ &select_handler, ctx, &sr) == CSS_OK);
-css_error node_is_visited(void *pw, void *n, bool *match)
-{
- node *node = n;
+ if (node->parent != NULL) {
+ css_computed_style *composed;
+ assert(css_computed_style_compose(
+ node->parent->sr->styles[ctx->pseudo_element],
+ sr->styles[ctx->pseudo_element],
+ &unit_ctx,
+ &composed) == CSS_OK);
+ css_computed_style_destroy(sr->styles[ctx->pseudo_element]);
+ sr->styles[ctx->pseudo_element] = composed;
+ }
- UNUSED(pw);
- UNUSED(node);
+ node->sr = sr;
- *match = false;
+ if (node == ctx->target) {
+ dump_computed_style(sr->styles[ctx->pseudo_element],
+ buf, buflen);
+ }
- return CSS_OK;
+ if (node->parent == NULL) {
+ unit_ctx.root_style = node->sr->styles[ctx->pseudo_element];
+ }
+
+ for (n = node->children; n != NULL; n = n->next) {
+ run_test_select_tree(select, n, ctx, buf, buflen);
+ }
}
-css_error node_is_hover(void *pw, void *n, bool *match)
+static void show_differences(size_t len, const char *exp, const char *res)
{
- node *node = n;
-
- UNUSED(pw);
- UNUSED(node);
+ const char *pos_exp, *opos_exp;
+ const char *pos_res, *opos_res;
- *match = false;
+ opos_exp = pos_exp = exp;
+ opos_res = pos_res = res;
- return CSS_OK;
+ printf("Line differences:\n");
+ while (pos_exp < exp + len && pos_res < res + len) {
+ if (*pos_exp == '\n' && *pos_res == '\n') {
+ if (pos_exp - opos_exp != pos_res - opos_res ||
+ memcmp(opos_exp, opos_res,
+ pos_exp - opos_exp) != 0) {
+ printf("Expected:\t%.*s\n",
+ (int)(pos_exp - opos_exp),
+ opos_exp);
+ printf(" Result:\t%.*s\n",
+ (int)(pos_res - opos_res),
+ opos_res);
+ printf("\n");
+ }
+ opos_exp = ++pos_exp;
+ opos_res = ++pos_res;
+ } else if (*pos_exp == '\n') {
+ pos_res++;
+ } else if (*pos_res == '\n') {
+ pos_exp++;
+ } else {
+ pos_exp++;
+ pos_res++;
+ }
+ }
}
-css_error node_is_active(void *pw, void *n, bool *match)
+static void destroy_tree(node *root)
{
- node *node = n;
+ node *n, *p;
+ uint32_t i;
- UNUSED(pw);
- UNUSED(node);
+ for (n = root->children; n != NULL; n = p) {
+ p = n->next;
- *match = false;
+ destroy_tree(n);
+ }
- return CSS_OK;
-}
+ css_select_results_destroy(root->sr);
-css_error node_is_focus(void *pw, void *n, bool *match)
-{
- node *node = n;
+ for (i = 0; i < root->n_attrs; ++i) {
+ lwc_string_unref(root->attrs[i].name);
+ lwc_string_unref(root->attrs[i].value);
+ }
+ free(root->attrs);
- UNUSED(pw);
- UNUSED(node);
+ if (root->classes != NULL) {
+ for (i = 0; i < root->n_classes; ++i) {
+ lwc_string_unref(root->classes[i]);
+ }
+ free(root->classes);
+ }
- *match = false;
+ if (root->libcss_node_data != NULL) {
+ css_libcss_node_data_handler(&select_handler, CSS_NODE_DELETED,
+ NULL, root, NULL, root->libcss_node_data);
+ }
- return CSS_OK;
+ lwc_string_unref(root->name);
+ free(root);
}
-css_error node_is_enabled(void *pw, void *n, bool *match)
+static void run_test(line_ctx *ctx, const char *exp, size_t explen)
{
- node *node = n;
-
- UNUSED(pw);
- UNUSED(node);
+ css_select_ctx *select;
+ css_select_results *results;
+ uint32_t i;
+ char *buf;
+ size_t buflen;
+ static int testnum;
- *match = false;
+ UNUSED(exp);
- return CSS_OK;
-}
+ buf = malloc(8192);
+ if (buf == NULL) {
+ assert(0 && "No memory for result data");
+ }
+ buflen = 8192;
-css_error node_is_disabled(void *pw, void *n, bool *match)
-{
- node *node = n;
+ assert(css_select_ctx_create(&select) == CSS_OK);
- UNUSED(pw);
- UNUSED(node);
+ for (i = 0; i < ctx->n_sheets; i++) {
+ assert(css_select_ctx_append_sheet(select,
+ ctx->sheets[i].sheet, ctx->sheets[i].origin,
+ ctx->sheets[i].media) == CSS_OK);
+ }
- *match = false;
+ testnum++;
- return CSS_OK;
-}
+ run_test_select_tree(select, ctx->tree, ctx, buf, &buflen);
-css_error node_is_checked(void *pw, void *n, bool *match)
-{
- node *node = n;
+ results = ctx->target->sr;
+ assert(results->styles[ctx->pseudo_element] != NULL);
- UNUSED(pw);
- UNUSED(node);
+ if (8192 - buflen != explen || memcmp(buf, exp, explen) != 0) {
+ size_t len = 8192 - buflen < explen ? 8192 - buflen : explen;
+ printf("Expected (%u):\n%.*s\n",
+ (int) explen, (int) explen, exp);
+ printf("Result (%u):\n%.*s\n", (int) (8192 - buflen),
+ (int) (8192 - buflen), buf);
- *match = false;
+ show_differences(len, exp, buf);
+ assert(0 && "Result doesn't match expected");
+ }
- return CSS_OK;
-}
+ /* Clean up */
+ css_select_ctx_destroy(select);
+ destroy_tree(ctx->tree);
-css_error node_is_target(void *pw, void *n, bool *match)
-{
- node *node = n;
+ for (i = 0; i < ctx->n_sheets; i++) {
+ css_stylesheet_destroy(ctx->sheets[i].sheet);
+ free(ctx->sheets[i].media);
+ }
- UNUSED(pw);
- UNUSED(node);
+ ctx->tree = NULL;
+ ctx->current = NULL;
+ ctx->depth = 0;
+ ctx->n_sheets = 0;
+ free(ctx->sheets);
+ ctx->sheets = NULL;
+ ctx->target = NULL;
- *match = false;
+ free(buf);
- return CSS_OK;
+ printf("Test %d: PASS\n", testnum);
}
-css_error node_is_lang(void *pw, void *n,
- lwc_string *lang,
- bool *match)
+static bool handle_line(const char *data, size_t datalen, void *pw)
{
- node *node = n;
-
- UNUSED(pw);
- UNUSED(node);
- UNUSED(lang);
+ line_ctx *ctx = (line_ctx *) pw;
+ css_error error;
- *match = false;
+ if (data[0] == '#') {
+ if (ctx->intree) {
+ if (strncasecmp(data+1, "errors", 6) == 0) {
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = true;
+ ctx->inexp = false;
+ } else {
+ /* Assume start of stylesheet */
+ css__parse_sheet(ctx, data + 1, datalen - 1);
- return CSS_OK;
-}
+ ctx->intree = false;
+ ctx->insheet = true;
+ ctx->inerrors = false;
+ ctx->inexp = false;
+ }
+ } else if (ctx->insheet) {
+ if (strncasecmp(data+1, "errors", 6) == 0) {
+ assert(css_stylesheet_data_done(
+ ctx->sheets[ctx->n_sheets - 1].sheet)
+ == CSS_OK);
-css_error node_presentational_hint(void *pw, void *node,
- uint32_t *nhints, css_hint **hints)
-{
- UNUSED(pw);
- UNUSED(node);
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = true;
+ ctx->inexp = false;
+ } else if (strncasecmp(data+1, "ua", 2) == 0 ||
+ strncasecmp(data+1, "user", 4) == 0 ||
+ strncasecmp(data+1, "author", 6) == 0) {
+ assert(css_stylesheet_data_done(
+ ctx->sheets[ctx->n_sheets - 1].sheet)
+ == CSS_OK);
- *nhints = 0;
- *hints = NULL;
+ css__parse_sheet(ctx, data + 1, datalen - 1);
+ } else {
+ error = css_stylesheet_append_data(
+ ctx->sheets[ctx->n_sheets - 1].sheet,
+ (const uint8_t *) data,
+ datalen);
+ assert(error == CSS_OK ||
+ error == CSS_NEEDDATA);
+ }
+ } else if (ctx->inerrors) {
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = false;
+ ctx->inexp = true;
+ } else if (ctx->inexp) {
+ /* This marks end of testcase, so run it */
+ run_test(ctx, ctx->exp, ctx->expused);
- return CSS_OK;
-}
+ ctx->expused = 0;
-css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
-{
- UNUSED(pw);
+ ctx->intree = false;
+ ctx->insheet = false;
+ ctx->inerrors = false;
+ ctx->inexp = false;
+ } else {
+ /* Start state */
+ if (strncasecmp(data+1, "tree", 4) == 0) {
+ css__parse_tree(ctx, data + 5, datalen - 5);
- if (property == CSS_PROP_COLOR) {
- hint->data.color = 0xff000000;
- hint->status = CSS_COLOR_COLOR;
- } else if (property == CSS_PROP_FONT_FAMILY) {
- hint->data.strings = NULL;
- hint->status = CSS_FONT_FAMILY_SANS_SERIF;
- } else if (property == CSS_PROP_QUOTES) {
- /* Not exactly useful :) */
- hint->data.strings = NULL;
- hint->status = CSS_QUOTES_NONE;
- } else if (property == CSS_PROP_VOICE_FAMILY) {
- /** \todo Fix this when we have voice-family done */
- hint->data.strings = NULL;
- hint->status = 0;
+ ctx->intree = true;
+ ctx->insheet = false;
+ ctx->inerrors = false;
+ ctx->inexp = false;
+ }
+ }
} else {
- return CSS_INVALID;
+ if (ctx->intree) {
+ /* Not interested in the '|' */
+ css__parse_tree_data(ctx, data + 1, datalen - 1);
+ } else if (ctx->insheet) {
+ error = css_stylesheet_append_data(
+ ctx->sheets[ctx->n_sheets - 1].sheet,
+ (const uint8_t *) data, datalen);
+ assert(error == CSS_OK || error == CSS_NEEDDATA);
+ } else if (ctx->inexp) {
+ css__parse_expected(ctx, data, datalen);
+ }
}
- return CSS_OK;
+ return true;
}
-static css_error set_libcss_node_data(void *pw, void *n,
- void *libcss_node_data)
+int main(int argc, char **argv)
{
- node *node = n;
- UNUSED(pw);
+ line_ctx ctx;
- node->libcss_node_data = libcss_node_data;
+ if (argc != 2) {
+ printf("Usage: %s <filename>\n", argv[0]);
+ return 1;
+ }
- return CSS_OK;
-}
+ memset(&ctx, 0, sizeof(ctx));
-static css_error get_libcss_node_data(void *pw, void *n,
- void **libcss_node_data)
-{
- node *node = n;
- UNUSED(pw);
- /* Pass any node data back to libcss */
- *libcss_node_data = node->libcss_node_data;
+ lwc_intern_string("class", SLEN("class"), &ctx.attr_class);
+ lwc_intern_string("id", SLEN("id"), &ctx.attr_id);
- return CSS_OK;
-}
+ assert(css__parse_testfile(argv[1], handle_line, &ctx) == true);
+
+ /* and run final test */
+ if (ctx.tree != NULL)
+ run_test(&ctx, ctx.exp, ctx.expused);
+
+ free(ctx.exp);
+
+ lwc_string_unref(ctx.attr_class);
+ lwc_string_unref(ctx.attr_id);
+
+ lwc_iterate_strings(printing_lwc_iterator, NULL);
+ assert(fail_because_lwc_leaked == false);
+ printf("PASS\n");
+ return 0;
+}
--
Cascading Style Sheets library
1 year, 11 months
libcss: branch master updated. release/0.9.1-25-g55017b9
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libcss.git/shortlog/55017b90bc6927bf3a4d40...
...commit http://git.netsurf-browser.org/libcss.git/commit/55017b90bc6927bf3a4d4056...
...tree http://git.netsurf-browser.org/libcss.git/tree/55017b90bc6927bf3a4d4056c0...
The branch, master has been updated
via 55017b90bc6927bf3a4d4056c04b242e1cc6c2ac (commit)
from ecf42afc3329b03ee642ede84f9ba224d2aff1e1 (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/libcss.git/commit/?id=55017b90bc6927bf3a4d...
commit 55017b90bc6927bf3a4d4056c04b242e1cc6c2ac
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Squash warning on apple darwin CI.
diff --git a/src/select/unit.c b/src/select/unit.c
index 9129d72..3294db3 100644
--- a/src/select/unit.c
+++ b/src/select/unit.c
@@ -372,17 +372,19 @@ static inline css_hint_length css_unit__get_font_size(
const css_computed_style *style,
css_fixed font_size_default)
{
- css_hint_length size;
+ css_hint_length size = {
+ .value = font_size_default,
+ .unit = CSS_UNIT_PX,
+ };
- if (style == NULL) {
- size.value = font_size_default;
- size.unit = CSS_UNIT_PX;
- } else {
- enum css_font_size_e status = get_font_size(
- style, &size.value, &size.unit);
+ if (style != NULL) {
+ enum css_font_size_e status = get_font_size(style,
+ &size.value,
+ &size.unit);
UNUSED(status);
+ /* The font size must be absolute. */
assert(status == CSS_FONT_SIZE_DIMENSION);
assert(size.unit != CSS_UNIT_EM);
assert(size.unit != CSS_UNIT_EX);
-----------------------------------------------------------------------
Summary of changes:
src/select/unit.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/select/unit.c b/src/select/unit.c
index 9129d72..3294db3 100644
--- a/src/select/unit.c
+++ b/src/select/unit.c
@@ -372,17 +372,19 @@ static inline css_hint_length css_unit__get_font_size(
const css_computed_style *style,
css_fixed font_size_default)
{
- css_hint_length size;
+ css_hint_length size = {
+ .value = font_size_default,
+ .unit = CSS_UNIT_PX,
+ };
- if (style == NULL) {
- size.value = font_size_default;
- size.unit = CSS_UNIT_PX;
- } else {
- enum css_font_size_e status = get_font_size(
- style, &size.value, &size.unit);
+ if (style != NULL) {
+ enum css_font_size_e status = get_font_size(style,
+ &size.value,
+ &size.unit);
UNUSED(status);
+ /* The font size must be absolute. */
assert(status == CSS_FONT_SIZE_DIMENSION);
assert(size.unit != CSS_UNIT_EM);
assert(size.unit != CSS_UNIT_EX);
--
Cascading Style Sheets library
1 year, 11 months
toolchains: branch chris/ndk32 created. f7429c43ddb4e35cdbf83999b9ed78e366fc1a6f
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/toolchains.git/shortlog/f7429c43ddb4e35cdb...
...commit http://git.netsurf-browser.org/toolchains.git/commit/f7429c43ddb4e35cdbf8...
...tree http://git.netsurf-browser.org/toolchains.git/tree/f7429c43ddb4e35cdbf839...
The branch, chris/ndk32 has been created
at f7429c43ddb4e35cdbf83999b9ed78e366fc1a6f (commit)
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/toolchains.git/commit/?id=f7429c43ddb4e35c...
commit f7429c43ddb4e35cdbf83999b9ed78e366fc1a6f
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Update to NDK3.2R2
This is newer than NDK3.9!
It doesn't work currently as it appears the GCC inlines are missing and/or need generating
diff --git a/m68k-unknown-amigaos/Makefile b/m68k-unknown-amigaos/Makefile
index 5c66cdd..8c6f849 100644
--- a/m68k-unknown-amigaos/Makefile
+++ b/m68k-unknown-amigaos/Makefile
@@ -29,14 +29,14 @@ UPSTREAM_CLIB2_VERSION := 1_214
UPSTREAM_CLIB2_TARBALL := V$(UPSTREAM_CLIB2_VERSION).tar.gz
UPSTREAM_CLIB2_URI := https://github.com/adtools/clib2/archive/$(UPSTREAM_CLIB2_TARBALL)
-UPSTREAM_NDK_TARBALL := ndk-3.9-includes.tar.bz2
-UPSTREAM_NDK_URI := http://kas1e.mikendezign.com/zerohero_crosscompilers_backup/files/m68k-am...
+UPSTREAM_NDK_TARBALL := NDK3.2R2.lha
+UPSTREAM_NDK_URI := "http://hyperion-entertainment.biz/index.php/downloads?view=download&forma..."
UPSTREAM_OPENURL_VERSION := 7.16
UPSTREAM_OPENURL_TARBALL := openurl-$(UPSTREAM_OPENURL_VERSION)
UPSTREAM_OPENURL_URI := https://github.com/jens-maus/libopenurl/archive/$(UPSTREAM_OPENURL_VERSIO...
-UPSTREAM_AMISSL_VERSION := 4.4
+UPSTREAM_AMISSL_VERSION := 4.9
UPSTREAM_AMISSL_TARBALL := AmiSSL-$(UPSTREAM_AMISSL_VERSION).lha
UPSTREAM_AMISSL_URI := https://github.com/jens-maus/amissl/releases/download/$(UPSTREAM_AMISSL_V...
@@ -125,11 +125,10 @@ $(BUILDSTEPS)/clib2-src.d: $(SOURCESDIR)/$(UPSTREAM_CLIB2_TARBALL)
###
$(BUILDSTEPS)/ndk.d: $(SOURCESDIR)/$(UPSTREAM_NDK_TARBALL) $(SOURCESDIR)/$(UPSTREAM_OPENURL_TARBALL) $(SOURCESDIR)/$(UPSTREAM_GUIGFX_TARBALL) $(SOURCESDIR)/$(UPSTREAM_RENDER_TARBALL) $(SOURCESDIR)/$(UPSTREAM_CODESETS_TARBALL) $(SOURCESDIR)/$(UPSTREAM_AMISSL_TARBALL)
- mkdir -p $(PREFIX)/$(TARGET_NAME)
- tar -C $(PREFIX)/$(TARGET_NAME) --strip-components=2 -xjf $(SOURCESDIR)/$(UPSTREAM_NDK_TARBALL)
- for p in `ls $(RECIPES)/patches/ndk/*.p` ; do patch -d $(PREFIX)/$(TARGET_NAME) -p0 <$$p ; done
- for dir in `find $(RECIPES)/files/ndk/ -type d | grep -v '\.svn' | sed 's#$(RECIPES)/files/ndk##'` ; do mkdir -p $(PREFIX)/$(TARGET_NAME)$$dir ; done
- for file in `find $(RECIPES)/files/ndk/ -type f | grep -v '\.svn' | sed 's#$(RECIPES)/files/ndk##'` ; do cp -p $(RECIPES)/files/ndk$$file $(PREFIX)/$(TARGET_NAME)$$file ; done
+ mkdir -p $(BUILDDIR)/ndk
+ lha xw=$(BUILDDIR)/ndk $(SOURCESDIR)/$(UPSTREAM_NDK_TARBALL)
+ mkdir -p $(PREFIX)/$(TARGET_NAME)/sys-include
+ cp -r $(BUILDDIR)/ndk/NDK3.2/Include_H/* $(PREFIX)/$(TARGET_NAME)/sys-include
mkdir -p $(BUILDDIR)/openurl
cd $(BUILDDIR)/openurl && tar xaf $(SOURCESDIR)/$(UPSTREAM_OPENURL_TARBALL)
cp -r $(BUILDDIR)/openurl/libopenurl-$(UPSTREAM_OPENURL_VERSION)/include/* $(PREFIX)/$(TARGET_NAME)/sys-include/
diff --git a/m68k-unknown-amigaos/recipes/patches/clib2/amiga_invertstring.c.p b/m68k-unknown-amigaos/recipes/patches/clib2/amiga_invertstring.c.p
new file mode 100644
index 0000000..9f74bd9
--- /dev/null
+++ b/m68k-unknown-amigaos/recipes/patches/clib2/amiga_invertstring.c.p
@@ -0,0 +1,11 @@
+--- ./builddir/clib2/amiga_invertstring.c 2017-05-01 17:06:23.000000000 +0100
++++ ./amiga_invertstring.c 2021-06-08 14:18:03.132632551 +0100
+@@ -138,7 +138,7 @@ extern VOID FreeIEvents(struct InputEven
+ /****************************************************************************/
+
+ struct InputEvent *
+-InvertString(CONST_STRPTR str, CONST struct KeyMap *km)
++InvertString(STRPTR str, CONST struct KeyMap *km)
+ {
+ /* bugs:
+ can't escape '>'
diff --git a/sdk/Makefile b/sdk/Makefile
index de5ec55..86aa68c 100644
--- a/sdk/Makefile
+++ b/sdk/Makefile
@@ -43,7 +43,7 @@ VERSION_LIBWEBP := 1.0.3
# https://c-ares.haxx.se/
VERSION_LIBCARES := 1.15.0
# https://curl.haxx.se/
-VERSION_LIBCURL := 7.76.1
+VERSION_LIBCURL := 7.77.0
VERSION_LIBGNURX := 2.5.1
# http://mission-base.com/peter/source/
VERSION_LIBPBL := 1_04
-----------------------------------------------------------------------
--
Cross-compilation toolchains and environments
1 year, 11 months