nsgenbind: branch master updated. release/0.2-3-gd81d306
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/nsgenbind.git/shortlog/d81d30699f57f0ca41b...
...commit http://git.netsurf-browser.org/nsgenbind.git/commit/d81d30699f57f0ca41b91...
...tree http://git.netsurf-browser.org/nsgenbind.git/tree/d81d30699f57f0ca41b917c...
The branch, master has been updated
via d81d30699f57f0ca41b917c854ef6d0875a18129 (commit)
from 5c2dc7300edb6449b29285818fde794ce2669f29 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/nsgenbind.git/commit/?id=d81d30699f57f0ca4...
commit d81d30699f57f0ca41b917c854ef6d0875a18129
Author: John-Mark Bell <jmb(a)netsurf-browser.org>
Commit: John-Mark Bell <jmb(a)netsurf-browser.org>
Make generated string attribute getters cope with libdom returning NULL.
Fixes #2415, #2418.
diff --git a/src/duk-libdom-generated.c b/src/duk-libdom-generated.c
index e40c43e..bae0826 100644
--- a/src/duk-libdom-generated.c
+++ b/src/duk-libdom-generated.c
@@ -97,10 +97,14 @@ output_generated_attribute_getter(FILE* outf,
"\t\treturn 0;\n"
"\t}\n"
"\n"
- "\tduk_push_lstring(ctx,\n"
- "\t\tdom_string_data(str),\n"
- "\t\tdom_string_length(str));\n"
- "\tdom_string_unref(str);\n"
+ "\tif (str != NULL) {\n"
+ "\t\tduk_push_lstring(ctx,\n"
+ "\t\t\tdom_string_data(str),\n"
+ "\t\t\tdom_string_length(str));\n"
+ "\t\tdom_string_unref(str);\n"
+ "\t} else {\n"
+ "\t\tduk_push_lstring(ctx, NULL, 0);\n"
+ "\t}\n"
"\n"
"\treturn 1;\n");
break;
-----------------------------------------------------------------------
Summary of changes:
src/duk-libdom-generated.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/duk-libdom-generated.c b/src/duk-libdom-generated.c
index e40c43e..bae0826 100644
--- a/src/duk-libdom-generated.c
+++ b/src/duk-libdom-generated.c
@@ -97,10 +97,14 @@ output_generated_attribute_getter(FILE* outf,
"\t\treturn 0;\n"
"\t}\n"
"\n"
- "\tduk_push_lstring(ctx,\n"
- "\t\tdom_string_data(str),\n"
- "\t\tdom_string_length(str));\n"
- "\tdom_string_unref(str);\n"
+ "\tif (str != NULL) {\n"
+ "\t\tduk_push_lstring(ctx,\n"
+ "\t\t\tdom_string_data(str),\n"
+ "\t\t\tdom_string_length(str));\n"
+ "\t\tdom_string_unref(str);\n"
+ "\t} else {\n"
+ "\t\tduk_push_lstring(ctx, NULL, 0);\n"
+ "\t}\n"
"\n"
"\treturn 1;\n");
break;
--
NetSurf Generator for JavaScript bindings
7 years, 8 months
netsurf: branch master updated. release/3.3-672-gcd0bcc4
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/cd0bcc421a2ae5a4bf64f...
...commit http://git.netsurf-browser.org/netsurf.git/commit/cd0bcc421a2ae5a4bf64f4e...
...tree http://git.netsurf-browser.org/netsurf.git/tree/cd0bcc421a2ae5a4bf64f4e21...
The branch, master has been updated
via cd0bcc421a2ae5a4bf64f4e21c92a0004ef7ece8 (commit)
from cc0abb66b092f2198e1931ee6921fe79da4ed94d (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.git/commit/?id=cd0bcc421a2ae5a4bf6...
commit cd0bcc421a2ae5a4bf64f4e21c92a0004ef7ece8
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Add an option to close inactive tabs to the tab bar context menu
diff --git a/amiga/arexx.c b/amiga/arexx.c
index 1960af0..412fc40 100644
--- a/amiga/arexx.c
+++ b/amiga/arexx.c
@@ -614,7 +614,7 @@ STATIC VOID rx_close(struct ARexxCmd *cmd, struct RexxMsg *rxm __attribute__((un
gw = ami_find_tab(*(ULONG *)cmd->ac_ArgList[0], *(ULONG *)cmd->ac_ArgList[1]);
else if(cmd->ac_ArgList[0])
{
- ami_close_all_tabs(gw->shared);
+ ami_gui_close_window(gw->shared);
return;
}
diff --git a/amiga/ctxmenu.c b/amiga/ctxmenu.c
index e9de270..8d49d4f 100644
--- a/amiga/ctxmenu.c
+++ b/amiga/ctxmenu.c
@@ -82,6 +82,7 @@ enum {
/* Tabs */
AMI_CTX_ID_TABNEW,
+ AMI_CTX_ID_TABCLOSE_OTHER,
AMI_CTX_ID_MAX
};
@@ -251,6 +252,14 @@ HOOKF(void, ami_ctxmenu_item_tabnew, APTR, window, struct IntuiMessage *)
ami_gui_new_blank_tab(gwin);
}
+HOOKF(void, ami_ctxmenu_item_tabclose_other, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+ ami_gui_close_inactive_tabs(gwin);
+}
+
/** Hook for history context menu entries **/
HOOKF(void, ami_ctxmenu_item_history, APTR, window, struct IntuiMessage *)
{
@@ -471,8 +480,10 @@ void ami_ctxmenu_init(void)
ami_ctxmenu_alloc_item(AMI_CTX_ID_FRAMESHOW, "FrameOnly", NULL, "TBImages:list_preview",
ami_ctxmenu_item_frameshow);
- ami_ctxmenu_alloc_item(AMI_CTX_ID_TABNEW, "NewTab", "T", "TBImages:list_add",
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_TABNEW, "NewTab", "T", "TBImages:list_tab",
ami_ctxmenu_item_tabnew);
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_TABCLOSE_OTHER, "CloseInactive", "K", "TBImages:list_cancel",
+ ami_ctxmenu_item_tabclose_other);
}
/********************************
@@ -582,6 +593,7 @@ struct Menu *ami_ctxmenu_clicktab_create(struct gui_window_2 *gwin)
MEnd;
ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_TABNEW, gwin);
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_TABCLOSE_OTHER, gwin);
return (struct Menu *)gwin->clicktab_ctxmenu;
}
diff --git a/amiga/gui.c b/amiga/gui.c
index e4cdd18..15a5e9d 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -2455,7 +2455,7 @@ static void ami_handle_msg(void)
break;
case WMHI_CLOSEWINDOW:
- ami_close_all_tabs(gwin);
+ ami_gui_close_window(gwin);
break;
#ifdef __amigaos4__
case WMHI_ICONIFY:
@@ -2524,7 +2524,7 @@ static void ami_handle_msg(void)
if(ami_menu_window_close == (void *)AMI_MENU_WINDOW_CLOSE_ALL)
ami_quit_netsurf();
else
- ami_close_all_tabs(ami_menu_window_close);
+ ami_gui_close_window(ami_menu_window_close);
ami_menu_window_close = NULL;
}
@@ -2914,7 +2914,7 @@ void ami_quit_netsurf(void)
/* This also closes windows that are attached to the
* gui_window, such as local history and find. */
ShowWindow(gwin->win, WINDOW_BACKMOST);
- ami_close_all_tabs(gwin);
+ ami_gui_close_window(gwin);
break;
case AMINS_GUIOPTSWINDOW:
@@ -4386,36 +4386,46 @@ gui_window_create(struct browser_window *bw,
return g;
}
-void ami_close_all_tabs(struct gui_window_2 *gwin)
+static void ami_gui_close_tabs(struct gui_window_2 *gwin, bool other_tabs)
{
struct Node *tab;
struct Node *ntab;
-
+ struct gui_window *gw;
+
if((gwin->tabs > 1) && (nsoption_bool(tab_close_warn) == true)) {
char *req_body = ami_utf8_easy(messages_get("MultiTabClose"));
int32 res = ami_warn_user_multi(req_body, "Yes", "No", gwin->win);
free(req_body);
-
+
if(res == 0) return;
}
-
- if(gwin->tabs)
- {
+
+ if(gwin->tabs) {
tab = GetHead(&gwin->tab_list);
- do
- {
+ do {
ntab=GetSucc(tab);
GetClickTabNodeAttrs(tab,
- TNA_UserData,&gwin->gw,
+ TNA_UserData,&gw,
TAG_DONE);
- browser_window_destroy(gwin->gw->bw);
+
+ if((other_tabs == false) || (gwin->gw != gw)) {
+ browser_window_destroy(gw->bw);
+ }
} while((tab=ntab));
+ } else {
+ if(other_tabs == false) browser_window_destroy(gwin->gw->bw);
}
- else
- {
- browser_window_destroy(gwin->gw->bw);
- }
+}
+
+void ami_gui_close_window(struct gui_window_2 *gwin)
+{
+ ami_gui_close_tabs(gwin, false);
+}
+
+void ami_gui_close_inactive_tabs(struct gui_window_2 *gwin)
+{
+ ami_gui_close_tabs(gwin, true);
}
static void gui_window_destroy(struct gui_window *g)
diff --git a/amiga/gui.h b/amiga/gui.h
index 38eee52..92ede2a 100644
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -169,7 +169,6 @@ struct gui_window
};
void ami_get_msg(void);
-void ami_close_all_tabs(struct gui_window_2 *gwin);
void ami_try_quit(void);
void ami_quit_netsurf(void);
void ami_schedule_redraw(struct gui_window_2 *gwin, bool full_redraw);
@@ -189,6 +188,21 @@ char *ami_gui_get_cache_favicon_name(nsurl *url, bool only_if_avail);
int ami_gui_count_windows(int window, int *tabs);
void ami_gui_set_scale(struct gui_window *gw, float scale);
+
+/**
+ * Close a window and all tabs attached to it.
+ *
+ * @param gwin gui_window_2 to act upon.
+ */
+void ami_gui_close_window(struct gui_window_2 *gwin);
+
+/**
+ * Close all tabs in a window except the active one.
+ *
+ * @param gwin gui_window_2 to act upon.
+ */
+void ami_gui_close_inactive_tabs(struct gui_window_2 *gwin);
+
/**
* Compatibility function to get space.gadget render area.
*
diff --git a/amiga/menu.c b/amiga/menu.c
index 1457744..5584758 100644
--- a/amiga/menu.c
+++ b/amiga/menu.c
@@ -600,7 +600,7 @@ static void ami_init_menulabs(struct gui_window_2 *gwin)
ami_menu_alloc_item(gwin, M_PROJECT, NM_TITLE, "Project", 0, NULL, NULL, NULL);
ami_menu_alloc_item(gwin, M_NEWWIN, NM_ITEM, "NewWindowNS", 'N', "TBImages:list_app",
ami_menu_item_project_newwin, NULL);
- ami_menu_alloc_item(gwin, M_NEWTAB, NM_ITEM, "NewTab", 'T', "TBImages:list_add",
+ ami_menu_alloc_item(gwin, M_NEWTAB, NM_ITEM, "NewTab", 'T', "TBImages:list_tab",
ami_menu_item_project_newtab, NULL);
ami_menu_alloc_item(gwin, M_BAR_P1, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
ami_menu_alloc_item(gwin, M_OPEN, NM_ITEM, "OpenFile", 'O', "TBImages:list_folder_misc",
diff --git a/resources/FatMessages b/resources/FatMessages
index 67de72a..6b66685 100644
--- a/resources/FatMessages
+++ b/resources/FatMessages
@@ -967,6 +967,11 @@ de.all.Close:Schließen
fr.all.Close:Fermer
it.all.Close:Chiudi
nl.all.Close:Sluit
+en.ami.CloseInactive:Close inactive tabs
+de.ami.CloseInactive:Close inactive tabs
+fr.ami.CloseInactive:Close inactive tabs
+it.ami.CloseInactive:Close inactive tabs
+nl.ami.CloseInactive:Close inactive tabs
en.all.ObjShow:Show object
de.all.ObjShow:Zeige Objekt
fr.all.ObjShow:Afficher l'objet
-----------------------------------------------------------------------
Summary of changes:
amiga/arexx.c | 2 +-
amiga/ctxmenu.c | 14 +++++++++++++-
amiga/gui.c | 44 +++++++++++++++++++++++++++-----------------
amiga/gui.h | 16 +++++++++++++++-
amiga/menu.c | 2 +-
resources/FatMessages | 5 +++++
6 files changed, 62 insertions(+), 21 deletions(-)
diff --git a/amiga/arexx.c b/amiga/arexx.c
index 1960af0..412fc40 100644
--- a/amiga/arexx.c
+++ b/amiga/arexx.c
@@ -614,7 +614,7 @@ STATIC VOID rx_close(struct ARexxCmd *cmd, struct RexxMsg *rxm __attribute__((un
gw = ami_find_tab(*(ULONG *)cmd->ac_ArgList[0], *(ULONG *)cmd->ac_ArgList[1]);
else if(cmd->ac_ArgList[0])
{
- ami_close_all_tabs(gw->shared);
+ ami_gui_close_window(gw->shared);
return;
}
diff --git a/amiga/ctxmenu.c b/amiga/ctxmenu.c
index e9de270..8d49d4f 100644
--- a/amiga/ctxmenu.c
+++ b/amiga/ctxmenu.c
@@ -82,6 +82,7 @@ enum {
/* Tabs */
AMI_CTX_ID_TABNEW,
+ AMI_CTX_ID_TABCLOSE_OTHER,
AMI_CTX_ID_MAX
};
@@ -251,6 +252,14 @@ HOOKF(void, ami_ctxmenu_item_tabnew, APTR, window, struct IntuiMessage *)
ami_gui_new_blank_tab(gwin);
}
+HOOKF(void, ami_ctxmenu_item_tabclose_other, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+ ami_gui_close_inactive_tabs(gwin);
+}
+
/** Hook for history context menu entries **/
HOOKF(void, ami_ctxmenu_item_history, APTR, window, struct IntuiMessage *)
{
@@ -471,8 +480,10 @@ void ami_ctxmenu_init(void)
ami_ctxmenu_alloc_item(AMI_CTX_ID_FRAMESHOW, "FrameOnly", NULL, "TBImages:list_preview",
ami_ctxmenu_item_frameshow);
- ami_ctxmenu_alloc_item(AMI_CTX_ID_TABNEW, "NewTab", "T", "TBImages:list_add",
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_TABNEW, "NewTab", "T", "TBImages:list_tab",
ami_ctxmenu_item_tabnew);
+ ami_ctxmenu_alloc_item(AMI_CTX_ID_TABCLOSE_OTHER, "CloseInactive", "K", "TBImages:list_cancel",
+ ami_ctxmenu_item_tabclose_other);
}
/********************************
@@ -582,6 +593,7 @@ struct Menu *ami_ctxmenu_clicktab_create(struct gui_window_2 *gwin)
MEnd;
ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_TABNEW, gwin);
+ ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_TABCLOSE_OTHER, gwin);
return (struct Menu *)gwin->clicktab_ctxmenu;
}
diff --git a/amiga/gui.c b/amiga/gui.c
index e4cdd18..15a5e9d 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -2455,7 +2455,7 @@ static void ami_handle_msg(void)
break;
case WMHI_CLOSEWINDOW:
- ami_close_all_tabs(gwin);
+ ami_gui_close_window(gwin);
break;
#ifdef __amigaos4__
case WMHI_ICONIFY:
@@ -2524,7 +2524,7 @@ static void ami_handle_msg(void)
if(ami_menu_window_close == (void *)AMI_MENU_WINDOW_CLOSE_ALL)
ami_quit_netsurf();
else
- ami_close_all_tabs(ami_menu_window_close);
+ ami_gui_close_window(ami_menu_window_close);
ami_menu_window_close = NULL;
}
@@ -2914,7 +2914,7 @@ void ami_quit_netsurf(void)
/* This also closes windows that are attached to the
* gui_window, such as local history and find. */
ShowWindow(gwin->win, WINDOW_BACKMOST);
- ami_close_all_tabs(gwin);
+ ami_gui_close_window(gwin);
break;
case AMINS_GUIOPTSWINDOW:
@@ -4386,36 +4386,46 @@ gui_window_create(struct browser_window *bw,
return g;
}
-void ami_close_all_tabs(struct gui_window_2 *gwin)
+static void ami_gui_close_tabs(struct gui_window_2 *gwin, bool other_tabs)
{
struct Node *tab;
struct Node *ntab;
-
+ struct gui_window *gw;
+
if((gwin->tabs > 1) && (nsoption_bool(tab_close_warn) == true)) {
char *req_body = ami_utf8_easy(messages_get("MultiTabClose"));
int32 res = ami_warn_user_multi(req_body, "Yes", "No", gwin->win);
free(req_body);
-
+
if(res == 0) return;
}
-
- if(gwin->tabs)
- {
+
+ if(gwin->tabs) {
tab = GetHead(&gwin->tab_list);
- do
- {
+ do {
ntab=GetSucc(tab);
GetClickTabNodeAttrs(tab,
- TNA_UserData,&gwin->gw,
+ TNA_UserData,&gw,
TAG_DONE);
- browser_window_destroy(gwin->gw->bw);
+
+ if((other_tabs == false) || (gwin->gw != gw)) {
+ browser_window_destroy(gw->bw);
+ }
} while((tab=ntab));
+ } else {
+ if(other_tabs == false) browser_window_destroy(gwin->gw->bw);
}
- else
- {
- browser_window_destroy(gwin->gw->bw);
- }
+}
+
+void ami_gui_close_window(struct gui_window_2 *gwin)
+{
+ ami_gui_close_tabs(gwin, false);
+}
+
+void ami_gui_close_inactive_tabs(struct gui_window_2 *gwin)
+{
+ ami_gui_close_tabs(gwin, true);
}
static void gui_window_destroy(struct gui_window *g)
diff --git a/amiga/gui.h b/amiga/gui.h
index 38eee52..92ede2a 100644
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -169,7 +169,6 @@ struct gui_window
};
void ami_get_msg(void);
-void ami_close_all_tabs(struct gui_window_2 *gwin);
void ami_try_quit(void);
void ami_quit_netsurf(void);
void ami_schedule_redraw(struct gui_window_2 *gwin, bool full_redraw);
@@ -189,6 +188,21 @@ char *ami_gui_get_cache_favicon_name(nsurl *url, bool only_if_avail);
int ami_gui_count_windows(int window, int *tabs);
void ami_gui_set_scale(struct gui_window *gw, float scale);
+
+/**
+ * Close a window and all tabs attached to it.
+ *
+ * @param gwin gui_window_2 to act upon.
+ */
+void ami_gui_close_window(struct gui_window_2 *gwin);
+
+/**
+ * Close all tabs in a window except the active one.
+ *
+ * @param gwin gui_window_2 to act upon.
+ */
+void ami_gui_close_inactive_tabs(struct gui_window_2 *gwin);
+
/**
* Compatibility function to get space.gadget render area.
*
diff --git a/amiga/menu.c b/amiga/menu.c
index 1457744..5584758 100644
--- a/amiga/menu.c
+++ b/amiga/menu.c
@@ -600,7 +600,7 @@ static void ami_init_menulabs(struct gui_window_2 *gwin)
ami_menu_alloc_item(gwin, M_PROJECT, NM_TITLE, "Project", 0, NULL, NULL, NULL);
ami_menu_alloc_item(gwin, M_NEWWIN, NM_ITEM, "NewWindowNS", 'N', "TBImages:list_app",
ami_menu_item_project_newwin, NULL);
- ami_menu_alloc_item(gwin, M_NEWTAB, NM_ITEM, "NewTab", 'T', "TBImages:list_add",
+ ami_menu_alloc_item(gwin, M_NEWTAB, NM_ITEM, "NewTab", 'T', "TBImages:list_tab",
ami_menu_item_project_newtab, NULL);
ami_menu_alloc_item(gwin, M_BAR_P1, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
ami_menu_alloc_item(gwin, M_OPEN, NM_ITEM, "OpenFile", 'O', "TBImages:list_folder_misc",
diff --git a/resources/FatMessages b/resources/FatMessages
index 67de72a..6b66685 100644
--- a/resources/FatMessages
+++ b/resources/FatMessages
@@ -967,6 +967,11 @@ de.all.Close:Schließen
fr.all.Close:Fermer
it.all.Close:Chiudi
nl.all.Close:Sluit
+en.ami.CloseInactive:Close inactive tabs
+de.ami.CloseInactive:Close inactive tabs
+fr.ami.CloseInactive:Close inactive tabs
+it.ami.CloseInactive:Close inactive tabs
+nl.ami.CloseInactive:Close inactive tabs
en.all.ObjShow:Show object
de.all.ObjShow:Zeige Objekt
fr.all.ObjShow:Afficher l'objet
--
NetSurf Browser
7 years, 8 months
netsurf: branch master updated. release/3.3-671-gcc0abb6
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/cc0abb66b092f2198e193...
...commit http://git.netsurf-browser.org/netsurf.git/commit/cc0abb66b092f2198e1931e...
...tree http://git.netsurf-browser.org/netsurf.git/tree/cc0abb66b092f2198e1931ee6...
The branch, master has been updated
via cc0abb66b092f2198e1931ee6921fe79da4ed94d (commit)
via e98c220813cb12a413711990d9b25aa8a9cb847a (commit)
via 1acc32b3a952c5d5526193ac546389c0a42420e3 (commit)
via 7729d9369696e5983ac7959f21171ffdf684d2a1 (commit)
from bf4382e3ec9af8e65e0903af7b1f492454877558 (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.git/commit/?id=cc0abb66b092f2198e1...
commit cc0abb66b092f2198e1931ee6921fe79da4ed94d
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Implement warn_multi for OS3 (needed for the multiple tab close warning)
diff --git a/amiga/misc.c b/amiga/misc.c
index 407aec1..aa9d119 100755
--- a/amiga/misc.c
+++ b/amiga/misc.c
@@ -137,7 +137,7 @@ void warn_user(const char *warning, const char *detail)
int32 ami_warn_user_multi(const char *body, const char *opt1, const char *opt2, struct Window *win)
{
int res = 0;
-#ifdef __amigaos4__
+
char *utf8text = ami_utf8_easy(body);
char *utf8gadget1 = ami_utf8_easy(messages_get(opt1));
char *utf8gadget2 = ami_utf8_easy(messages_get(opt2));
@@ -145,18 +145,28 @@ int32 ami_warn_user_multi(const char *body, const char *opt1, const char *opt2,
free(utf8gadget1);
free(utf8gadget2);
+#ifdef __amigaos4__
res = TimedDosRequesterTags(TDR_ImageType, TDRIMAGE_WARNING,
TDR_TitleString, messages_get("NetSurf"),
TDR_FormatString, utf8text,
TDR_GadgetString, utf8gadgets,
TDR_Window, win,
TAG_DONE);
+#else
+ struct EasyStruct easyreq = {
+ sizeof(struct EasyStruct),
+ 0,
+ messages_get("NetSurf"),
+ utf8text,
+ utf8gadgets,
+ };
+
+ res = EasyRequest(win, &easyreq, NULL);
+#endif
if(utf8text) free(utf8text);
if(utf8gadgets) FreeVec(utf8gadgets);
-#else
-#warning write this for os3
-#endif
+
return res;
}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=e98c220813cb12a4137...
commit e98c220813cb12a413711990d9b25aa8a9cb847a
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Fix some enable/disable gadget logic
diff --git a/amiga/gui.c b/amiga/gui.c
index 2eb4984..e4cdd18 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -1163,8 +1163,8 @@ static void ami_update_buttons(struct gui_window_2 *gwin)
SetGadgetAttrs((struct Gadget *)gwin->objects[GID_STOP],
gwin->win, NULL, GA_Disabled, stop, TAG_DONE);
- if((gwin->tabs) && (ClickTabBase->lib_Version < 53))
- {
+ if(ClickTabBase->lib_Version < 53) {
+ if(gwin->tabs <= 1) tabclose = TRUE;
GetAttr(GA_Disabled, gwin->objects[GID_CLOSETAB], (uint32 *)&storage);
if(storage != tabclose)
SetGadgetAttrs((struct Gadget *)gwin->objects[GID_CLOSETAB],
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=1acc32b3a952c5d5526...
commit 1acc32b3a952c5d5526193ac546389c0a42420e3
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Force always show tabs when clicktab.gadget is older than v53
diff --git a/amiga/gui.c b/amiga/gui.c
index 41a0a45..2eb4984 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -556,6 +556,10 @@ static nserror ami_set_options(struct nsoption_s *defaults)
*/
nsoption_set_bool(core_select_menu, true);
+ /* ClickTab < 53 doesn't work with the auto show/hide tab-bar (for reasons forgotten) */
+ if(ClickTabBase->lib_Version < 53)
+ nsoption_set_bool(tab_always_show, true);
+
/* Some AmigaOS3 overrides */
#ifndef __amigaos4__
nsoption_set_bool(download_notify, false);
@@ -3985,7 +3989,6 @@ gui_window_create(struct browser_window *bw,
if(ClickTabBase->lib_Version < 53)
{
-//#ifdef __amigaos4__
addtabclosegadget = LAYOUT_AddChild;
g->shared->objects[GID_CLOSETAB] = ButtonObj,
GA_ID, GID_CLOSETAB,
@@ -4007,9 +4010,6 @@ gui_window_create(struct browser_window *bw,
GA_Text, "+",
BUTTON_RenderImage, g->shared->objects[GID_ADDTAB_BM],
ButtonEnd;
-//#else
-//#warning OS3 tab bar permanently disabled!
-//#endif
}
else
{
diff --git a/amiga/gui_options.c b/amiga/gui_options.c
index cd23880..3be0cd5 100755
--- a/amiga/gui_options.c
+++ b/amiga/gui_options.c
@@ -504,7 +504,7 @@ void ami_gui_opts_open(void)
BOOL disableanims, animspeeddisabled = FALSE, acceptlangdisabled = FALSE;
BOOL scaleselected = nsoption_bool(scale_quality), scaledisabled = FALSE;
BOOL ditherdisable = TRUE, nativebm_disable = FALSE;
- BOOL download_notify_disabled = FALSE;
+ BOOL download_notify_disabled = FALSE, tab_always_show_disabled = FALSE;
BOOL ptr_disable = FALSE;
char animspeed[10];
char *homepage_url_lc = ami_utf8_easy(nsoption_charp(homepage_url));
@@ -602,6 +602,10 @@ void ami_gui_opts_open(void)
nsoption_set_bool(download_notify, FALSE);
}
+ if(ClickTabBase->lib_Version < 53) {
+ tab_always_show_disabled = TRUE;
+ }
+
fontsans.ta_Name = ASPrintf("%s.font", nsoption_charp(font_sans));
fontserif.ta_Name = ASPrintf("%s.font", nsoption_charp(font_serif));
fontmono.ta_Name = ASPrintf("%s.font", nsoption_charp(font_mono));
@@ -1344,6 +1348,7 @@ void ami_gui_opts_open(void)
GA_RelVerify, TRUE,
GA_Text, gadlab[GID_OPTS_TAB_ALWAYS],
GA_Selected, nsoption_bool(tab_always_show),
+ GA_Disabled, tab_always_show_disabled,
CheckBoxEnd,
LAYOUT_AddChild, gow->objects[GID_OPTS_TAB_CLOSE] = CheckBoxObj,
GA_ID, GID_OPTS_TAB_CLOSE,
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=7729d9369696e5983ac...
commit 7729d9369696e5983ac7959f21171ffdf684d2a1
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Enable tabbed browsing on OS3
diff --git a/amiga/gui.c b/amiga/gui.c
index c7f920f..41a0a45 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -2162,8 +2162,13 @@ static void ami_handle_msg(void)
{
case GID_TABS:
if(gwin->objects[GID_TABS] == NULL) break;
- GetAttrs(gwin->objects[GID_TABS],
- CLICKTAB_NodeClosed, &tabnode, TAG_DONE);
+ if(ClickTabBase->lib_Version >= 53) {
+ GetAttrs(gwin->objects[GID_TABS],
+ CLICKTAB_NodeClosed, &tabnode, TAG_DONE);
+ } else {
+ tabnode = NULL;
+ }
+
if(tabnode) {
struct gui_window *closedgw;
@@ -3980,7 +3985,7 @@ gui_window_create(struct browser_window *bw,
if(ClickTabBase->lib_Version < 53)
{
-#ifdef __amigaos4__
+//#ifdef __amigaos4__
addtabclosegadget = LAYOUT_AddChild;
g->shared->objects[GID_CLOSETAB] = ButtonObj,
GA_ID, GID_CLOSETAB,
@@ -4002,9 +4007,9 @@ gui_window_create(struct browser_window *bw,
GA_Text, "+",
BUTTON_RenderImage, g->shared->objects[GID_ADDTAB_BM],
ButtonEnd;
-#else
-#warning OS3 tab bar permanently disabled!
-#endif
+//#else
+//#warning OS3 tab bar permanently disabled!
+//#endif
}
else
{
-----------------------------------------------------------------------
Summary of changes:
amiga/gui.c | 21 +++++++++++++--------
amiga/gui_options.c | 7 ++++++-
amiga/misc.c | 18 ++++++++++++++----
3 files changed, 33 insertions(+), 13 deletions(-)
diff --git a/amiga/gui.c b/amiga/gui.c
index c7f920f..e4cdd18 100644
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -556,6 +556,10 @@ static nserror ami_set_options(struct nsoption_s *defaults)
*/
nsoption_set_bool(core_select_menu, true);
+ /* ClickTab < 53 doesn't work with the auto show/hide tab-bar (for reasons forgotten) */
+ if(ClickTabBase->lib_Version < 53)
+ nsoption_set_bool(tab_always_show, true);
+
/* Some AmigaOS3 overrides */
#ifndef __amigaos4__
nsoption_set_bool(download_notify, false);
@@ -1159,8 +1163,8 @@ static void ami_update_buttons(struct gui_window_2 *gwin)
SetGadgetAttrs((struct Gadget *)gwin->objects[GID_STOP],
gwin->win, NULL, GA_Disabled, stop, TAG_DONE);
- if((gwin->tabs) && (ClickTabBase->lib_Version < 53))
- {
+ if(ClickTabBase->lib_Version < 53) {
+ if(gwin->tabs <= 1) tabclose = TRUE;
GetAttr(GA_Disabled, gwin->objects[GID_CLOSETAB], (uint32 *)&storage);
if(storage != tabclose)
SetGadgetAttrs((struct Gadget *)gwin->objects[GID_CLOSETAB],
@@ -2162,8 +2166,13 @@ static void ami_handle_msg(void)
{
case GID_TABS:
if(gwin->objects[GID_TABS] == NULL) break;
- GetAttrs(gwin->objects[GID_TABS],
- CLICKTAB_NodeClosed, &tabnode, TAG_DONE);
+ if(ClickTabBase->lib_Version >= 53) {
+ GetAttrs(gwin->objects[GID_TABS],
+ CLICKTAB_NodeClosed, &tabnode, TAG_DONE);
+ } else {
+ tabnode = NULL;
+ }
+
if(tabnode) {
struct gui_window *closedgw;
@@ -3980,7 +3989,6 @@ gui_window_create(struct browser_window *bw,
if(ClickTabBase->lib_Version < 53)
{
-#ifdef __amigaos4__
addtabclosegadget = LAYOUT_AddChild;
g->shared->objects[GID_CLOSETAB] = ButtonObj,
GA_ID, GID_CLOSETAB,
@@ -4002,9 +4010,6 @@ gui_window_create(struct browser_window *bw,
GA_Text, "+",
BUTTON_RenderImage, g->shared->objects[GID_ADDTAB_BM],
ButtonEnd;
-#else
-#warning OS3 tab bar permanently disabled!
-#endif
}
else
{
diff --git a/amiga/gui_options.c b/amiga/gui_options.c
index cd23880..3be0cd5 100755
--- a/amiga/gui_options.c
+++ b/amiga/gui_options.c
@@ -504,7 +504,7 @@ void ami_gui_opts_open(void)
BOOL disableanims, animspeeddisabled = FALSE, acceptlangdisabled = FALSE;
BOOL scaleselected = nsoption_bool(scale_quality), scaledisabled = FALSE;
BOOL ditherdisable = TRUE, nativebm_disable = FALSE;
- BOOL download_notify_disabled = FALSE;
+ BOOL download_notify_disabled = FALSE, tab_always_show_disabled = FALSE;
BOOL ptr_disable = FALSE;
char animspeed[10];
char *homepage_url_lc = ami_utf8_easy(nsoption_charp(homepage_url));
@@ -602,6 +602,10 @@ void ami_gui_opts_open(void)
nsoption_set_bool(download_notify, FALSE);
}
+ if(ClickTabBase->lib_Version < 53) {
+ tab_always_show_disabled = TRUE;
+ }
+
fontsans.ta_Name = ASPrintf("%s.font", nsoption_charp(font_sans));
fontserif.ta_Name = ASPrintf("%s.font", nsoption_charp(font_serif));
fontmono.ta_Name = ASPrintf("%s.font", nsoption_charp(font_mono));
@@ -1344,6 +1348,7 @@ void ami_gui_opts_open(void)
GA_RelVerify, TRUE,
GA_Text, gadlab[GID_OPTS_TAB_ALWAYS],
GA_Selected, nsoption_bool(tab_always_show),
+ GA_Disabled, tab_always_show_disabled,
CheckBoxEnd,
LAYOUT_AddChild, gow->objects[GID_OPTS_TAB_CLOSE] = CheckBoxObj,
GA_ID, GID_OPTS_TAB_CLOSE,
diff --git a/amiga/misc.c b/amiga/misc.c
index 407aec1..aa9d119 100755
--- a/amiga/misc.c
+++ b/amiga/misc.c
@@ -137,7 +137,7 @@ void warn_user(const char *warning, const char *detail)
int32 ami_warn_user_multi(const char *body, const char *opt1, const char *opt2, struct Window *win)
{
int res = 0;
-#ifdef __amigaos4__
+
char *utf8text = ami_utf8_easy(body);
char *utf8gadget1 = ami_utf8_easy(messages_get(opt1));
char *utf8gadget2 = ami_utf8_easy(messages_get(opt2));
@@ -145,18 +145,28 @@ int32 ami_warn_user_multi(const char *body, const char *opt1, const char *opt2,
free(utf8gadget1);
free(utf8gadget2);
+#ifdef __amigaos4__
res = TimedDosRequesterTags(TDR_ImageType, TDRIMAGE_WARNING,
TDR_TitleString, messages_get("NetSurf"),
TDR_FormatString, utf8text,
TDR_GadgetString, utf8gadgets,
TDR_Window, win,
TAG_DONE);
+#else
+ struct EasyStruct easyreq = {
+ sizeof(struct EasyStruct),
+ 0,
+ messages_get("NetSurf"),
+ utf8text,
+ utf8gadgets,
+ };
+
+ res = EasyRequest(win, &easyreq, NULL);
+#endif
if(utf8text) free(utf8text);
if(utf8gadgets) FreeVec(utf8gadgets);
-#else
-#warning write this for os3
-#endif
+
return res;
}
--
NetSurf Browser
7 years, 8 months
netsurf: branch master updated. release/3.3-667-gbf4382e
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/bf4382e3ec9af8e65e090...
...commit http://git.netsurf-browser.org/netsurf.git/commit/bf4382e3ec9af8e65e0903a...
...tree http://git.netsurf-browser.org/netsurf.git/tree/bf4382e3ec9af8e65e0903af7...
The branch, master has been updated
via bf4382e3ec9af8e65e0903af7b1f492454877558 (commit)
from 720a8fec0e2b435e09d76eabf3c40e78dba414cc (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.git/commit/?id=bf4382e3ec9af8e65e0...
commit bf4382e3ec9af8e65e0903af7b1f492454877558
Author: John-Mark Bell <jmb(a)netsurf-browser.org>
Commit: John-Mark Bell <jmb(a)netsurf-browser.org>
HTMLElement: stub .style getter. For #2413.
diff --git a/javascript/duktape/HTMLElement.bnd b/javascript/duktape/HTMLElement.bnd
index d2b913a..b3de9c8 100644
--- a/javascript/duktape/HTMLElement.bnd
+++ b/javascript/duktape/HTMLElement.bnd
@@ -151,3 +151,12 @@ getter HTMLElement::onwaiting();
setter HTMLElement::onwaiting();
getter HTMLElement::onwheel();
setter HTMLElement::onwheel();
+
+getter HTMLElement::style()
+%{
+ /* Minimal implementation to avoid infinite-loop in Modernizr (c.f. #2413) */
+ if (dukky_create_object(ctx, PROTO_NAME(CSSSTYLEDECLARATION), 0) != DUK_EXEC_SUCCESS) {
+ return 0;
+ }
+ return 1;
+%}
-----------------------------------------------------------------------
Summary of changes:
javascript/duktape/HTMLElement.bnd | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/javascript/duktape/HTMLElement.bnd b/javascript/duktape/HTMLElement.bnd
index d2b913a..b3de9c8 100644
--- a/javascript/duktape/HTMLElement.bnd
+++ b/javascript/duktape/HTMLElement.bnd
@@ -151,3 +151,12 @@ getter HTMLElement::onwaiting();
setter HTMLElement::onwaiting();
getter HTMLElement::onwheel();
setter HTMLElement::onwheel();
+
+getter HTMLElement::style()
+%{
+ /* Minimal implementation to avoid infinite-loop in Modernizr (c.f. #2413) */
+ if (dukky_create_object(ctx, PROTO_NAME(CSSSTYLEDECLARATION), 0) != DUK_EXEC_SUCCESS) {
+ return 0;
+ }
+ return 1;
+%}
--
NetSurf Browser
7 years, 8 months
libdom: branch master updated. release/0.2.0-33-g140a849
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libdom.git/shortlog/140a849dc70bf1d9270bee...
...commit http://git.netsurf-browser.org/libdom.git/commit/140a849dc70bf1d9270bee81...
...tree http://git.netsurf-browser.org/libdom.git/tree/140a849dc70bf1d9270bee8165...
The branch, master has been updated
via 140a849dc70bf1d9270bee8165bc0f098e097314 (commit)
via d49ce7364ef8d6b577a077c9883f251acb5a3f99 (commit)
from 2e707ef487896b68494ecb07f0047be164e4ae8e (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/libdom.git/commit/?id=140a849dc70bf1d9270b...
commit 140a849dc70bf1d9270bee8165bc0f098e097314
Merge: 2e707ef d49ce73
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Merge branch 'tlsa/faster-strings'
-----------------------------------------------------------------------
Summary of changes:
src/core/string.c | 68 +++++++++++++++++++++++++++++++++++------------------
1 file changed, 45 insertions(+), 23 deletions(-)
diff --git a/src/core/string.c b/src/core/string.c
index 9af2e74..1f0fdd5 100644
--- a/src/core/string.c
+++ b/src/core/string.c
@@ -978,36 +978,58 @@ dom_string_toupper(dom_string *source, bool ascii_only, dom_string **upper)
dom_exception
dom_string_tolower(dom_string *source, bool ascii_only, dom_string **lower)
{
- const uint8_t *orig_s = (const uint8_t *) dom_string_data(source);
- const size_t nbytes = dom_string_byte_length(source);
- uint8_t *copy_s;
- size_t index = 0;
- dom_exception exc;
-
+ dom_string_internal *isource = (dom_string_internal *)source;
+ dom_exception exc = DOM_NO_ERR;
+
if (ascii_only == false)
return DOM_NOT_SUPPORTED_ERR;
-
- copy_s = malloc(nbytes);
- if (copy_s == NULL)
- return DOM_NO_MEM_ERR;
- memcpy(copy_s, orig_s, nbytes);
-
- while (index < nbytes) {
- if (orig_s[index] >= 'A' && orig_s[index] <= 'Z') {
- copy_s[index] += 'a' - 'A';
- }
- index++;
- }
-
- if (((dom_string_internal*)source)->type == DOM_STRING_CDATA) {
+ if (isource->type == DOM_STRING_CDATA) {
+ const uint8_t *orig_s = (const uint8_t *)
+ dom_string_data(source);
+ const size_t nbytes = dom_string_byte_length(source);
+ size_t index = 0;
+ uint8_t *copy_s;
+
+ copy_s = malloc(nbytes);
+ if (copy_s == NULL)
+ return DOM_NO_MEM_ERR;
+ memcpy(copy_s, orig_s, nbytes);
+
+ while (index < nbytes) {
+ if (orig_s[index] >= 'A' && orig_s[index] <= 'Z') {
+ copy_s[index] += 'a' - 'A';
+ }
+
+ index++;
+ }
exc = dom_string_create(copy_s, nbytes, lower);
+
+ free(copy_s);
} else {
- exc = dom_string_create_interned(copy_s, nbytes, lower);
+ bool equal;
+ lwc_error err;
+ lwc_string *l;
+
+ err = lwc_string_tolower(isource->data.intern, &l);
+ if (err != lwc_error_ok) {
+ return DOM_NO_MEM_ERR;
+ }
+
+ if (lwc_string_isequal(isource->data.intern, l, &equal) ==
+ lwc_error_ok && equal == true) {
+ /* String is already lower case. */
+ *lower = dom_string_ref(source);
+ } else {
+ /* TODO: create dom_string wrapper around existing
+ * lwc string. */
+ exc = dom_string_create_interned(
+ (const uint8_t *)lwc_string_data(l),
+ lwc_string_length(l), lower);
+ }
+ lwc_string_unref(l);
}
- free(copy_s);
-
return exc;
}
--
Document Object Model library
7 years, 8 months
libdom: branch tlsa/faster-strings updated. release/0.2.0-32-gd49ce73
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libdom.git/shortlog/d49ce7364ef8d6b577a077...
...commit http://git.netsurf-browser.org/libdom.git/commit/d49ce7364ef8d6b577a077c9...
...tree http://git.netsurf-browser.org/libdom.git/tree/d49ce7364ef8d6b577a077c988...
The branch, tlsa/faster-strings has been updated
via d49ce7364ef8d6b577a077c9883f251acb5a3f99 (commit)
from 2e707ef487896b68494ecb07f0047be164e4ae8e (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/libdom.git/commit/?id=d49ce7364ef8d6b577a0...
commit d49ce7364ef8d6b577a077c9883f251acb5a3f99
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Optimise dom_string_tolower where interned string was already lower case.
Now we detect that the string was lower case, and return a new ref to the same
dom_string.
diff --git a/src/core/string.c b/src/core/string.c
index 9af2e74..1f0fdd5 100644
--- a/src/core/string.c
+++ b/src/core/string.c
@@ -978,36 +978,58 @@ dom_string_toupper(dom_string *source, bool ascii_only, dom_string **upper)
dom_exception
dom_string_tolower(dom_string *source, bool ascii_only, dom_string **lower)
{
- const uint8_t *orig_s = (const uint8_t *) dom_string_data(source);
- const size_t nbytes = dom_string_byte_length(source);
- uint8_t *copy_s;
- size_t index = 0;
- dom_exception exc;
-
+ dom_string_internal *isource = (dom_string_internal *)source;
+ dom_exception exc = DOM_NO_ERR;
+
if (ascii_only == false)
return DOM_NOT_SUPPORTED_ERR;
-
- copy_s = malloc(nbytes);
- if (copy_s == NULL)
- return DOM_NO_MEM_ERR;
- memcpy(copy_s, orig_s, nbytes);
-
- while (index < nbytes) {
- if (orig_s[index] >= 'A' && orig_s[index] <= 'Z') {
- copy_s[index] += 'a' - 'A';
- }
- index++;
- }
-
- if (((dom_string_internal*)source)->type == DOM_STRING_CDATA) {
+ if (isource->type == DOM_STRING_CDATA) {
+ const uint8_t *orig_s = (const uint8_t *)
+ dom_string_data(source);
+ const size_t nbytes = dom_string_byte_length(source);
+ size_t index = 0;
+ uint8_t *copy_s;
+
+ copy_s = malloc(nbytes);
+ if (copy_s == NULL)
+ return DOM_NO_MEM_ERR;
+ memcpy(copy_s, orig_s, nbytes);
+
+ while (index < nbytes) {
+ if (orig_s[index] >= 'A' && orig_s[index] <= 'Z') {
+ copy_s[index] += 'a' - 'A';
+ }
+
+ index++;
+ }
exc = dom_string_create(copy_s, nbytes, lower);
+
+ free(copy_s);
} else {
- exc = dom_string_create_interned(copy_s, nbytes, lower);
+ bool equal;
+ lwc_error err;
+ lwc_string *l;
+
+ err = lwc_string_tolower(isource->data.intern, &l);
+ if (err != lwc_error_ok) {
+ return DOM_NO_MEM_ERR;
+ }
+
+ if (lwc_string_isequal(isource->data.intern, l, &equal) ==
+ lwc_error_ok && equal == true) {
+ /* String is already lower case. */
+ *lower = dom_string_ref(source);
+ } else {
+ /* TODO: create dom_string wrapper around existing
+ * lwc string. */
+ exc = dom_string_create_interned(
+ (const uint8_t *)lwc_string_data(l),
+ lwc_string_length(l), lower);
+ }
+ lwc_string_unref(l);
}
- free(copy_s);
-
return exc;
}
-----------------------------------------------------------------------
Summary of changes:
src/core/string.c | 68 +++++++++++++++++++++++++++++++++++------------------
1 file changed, 45 insertions(+), 23 deletions(-)
diff --git a/src/core/string.c b/src/core/string.c
index 9af2e74..1f0fdd5 100644
--- a/src/core/string.c
+++ b/src/core/string.c
@@ -978,36 +978,58 @@ dom_string_toupper(dom_string *source, bool ascii_only, dom_string **upper)
dom_exception
dom_string_tolower(dom_string *source, bool ascii_only, dom_string **lower)
{
- const uint8_t *orig_s = (const uint8_t *) dom_string_data(source);
- const size_t nbytes = dom_string_byte_length(source);
- uint8_t *copy_s;
- size_t index = 0;
- dom_exception exc;
-
+ dom_string_internal *isource = (dom_string_internal *)source;
+ dom_exception exc = DOM_NO_ERR;
+
if (ascii_only == false)
return DOM_NOT_SUPPORTED_ERR;
-
- copy_s = malloc(nbytes);
- if (copy_s == NULL)
- return DOM_NO_MEM_ERR;
- memcpy(copy_s, orig_s, nbytes);
-
- while (index < nbytes) {
- if (orig_s[index] >= 'A' && orig_s[index] <= 'Z') {
- copy_s[index] += 'a' - 'A';
- }
- index++;
- }
-
- if (((dom_string_internal*)source)->type == DOM_STRING_CDATA) {
+ if (isource->type == DOM_STRING_CDATA) {
+ const uint8_t *orig_s = (const uint8_t *)
+ dom_string_data(source);
+ const size_t nbytes = dom_string_byte_length(source);
+ size_t index = 0;
+ uint8_t *copy_s;
+
+ copy_s = malloc(nbytes);
+ if (copy_s == NULL)
+ return DOM_NO_MEM_ERR;
+ memcpy(copy_s, orig_s, nbytes);
+
+ while (index < nbytes) {
+ if (orig_s[index] >= 'A' && orig_s[index] <= 'Z') {
+ copy_s[index] += 'a' - 'A';
+ }
+
+ index++;
+ }
exc = dom_string_create(copy_s, nbytes, lower);
+
+ free(copy_s);
} else {
- exc = dom_string_create_interned(copy_s, nbytes, lower);
+ bool equal;
+ lwc_error err;
+ lwc_string *l;
+
+ err = lwc_string_tolower(isource->data.intern, &l);
+ if (err != lwc_error_ok) {
+ return DOM_NO_MEM_ERR;
+ }
+
+ if (lwc_string_isequal(isource->data.intern, l, &equal) ==
+ lwc_error_ok && equal == true) {
+ /* String is already lower case. */
+ *lower = dom_string_ref(source);
+ } else {
+ /* TODO: create dom_string wrapper around existing
+ * lwc string. */
+ exc = dom_string_create_interned(
+ (const uint8_t *)lwc_string_data(l),
+ lwc_string_length(l), lower);
+ }
+ lwc_string_unref(l);
}
- free(copy_s);
-
return exc;
}
--
Document Object Model library
7 years, 8 months
libdom: branch tlsa/faster-strings updated. release/0.2.0-31-g2e707ef
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libdom.git/shortlog/2e707ef487896b68494ecb...
...commit http://git.netsurf-browser.org/libdom.git/commit/2e707ef487896b68494ecb07...
...tree http://git.netsurf-browser.org/libdom.git/tree/2e707ef487896b68494ecb07f0...
The branch, tlsa/faster-strings has been updated
via 2e707ef487896b68494ecb07f0047be164e4ae8e (commit)
via 4ef9aeab25b67fa27e951473c78f33a600503ee4 (commit)
via 737cb995c1b2bf144ee5087a011418b1f9b8aa69 (commit)
via 2196dd1c1d5a78e82e8b57d77008a0486011bec9 (commit)
via 7e9681b5e1829e533d9cce3b28ee94ecf2daff24 (commit)
via b4a245f67fe6c40f3aa8ddfe627d28e3513a9463 (commit)
from a37713d9b0d49e9996b6eba9789e6f4ace88cb85 (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 -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
include/dom/html/html_elements.h | 3 +-
src/core/node.c | 99 ++++++++++++++++++++++++++++----------
2 files changed, 76 insertions(+), 26 deletions(-)
diff --git a/include/dom/html/html_elements.h b/include/dom/html/html_elements.h
index 5774657..1e6b3fc 100644
--- a/include/dom/html/html_elements.h
+++ b/include/dom/html/html_elements.h
@@ -91,4 +91,5 @@ DOM_HTML_ELEMENT_LIST
#endif
#undef DOM_HTML_ELEMENT_LIST
-#endif
\ No newline at end of file
+#endif
+
diff --git a/src/core/node.c b/src/core/node.c
index 45db915..8800a4b 100644
--- a/src/core/node.c
+++ b/src/core/node.c
@@ -2316,11 +2316,43 @@ dom_exception _dom_node_remove_event_listener_ns(dom_event_target *et,
namespace, type, listener, capture);
}
+
+/** Helper for allocating/expanding array of event targets */
+static inline dom_exception _dom_event_targets_expand(
+ uint32_t *ntargets_allocated,
+ dom_event_target ***targets)
+{
+ dom_event_target **t = *targets;
+ uint32_t size = *ntargets_allocated;
+
+ if (t == NULL) {
+ /* Create the event target list */
+ size = 64;
+ t = calloc(sizeof(*t), size);
+ if (targets == NULL) {
+ return DOM_NO_MEM_ERR;
+ }
+ } else {
+ /* Extend events target list */
+ dom_event_target **tmp = realloc(t, size * 2 * sizeof(*t));
+ if (tmp == NULL) {
+ return DOM_NO_MEM_ERR;
+ }
+ memset(tmp + size, 0, size * sizeof(*tmp));
+ t = tmp;
+ size *= 2;
+ }
+
+ *ntargets_allocated = size;
+ *targets = t;
+
+ return DOM_NO_ERR;
+}
+
/**
* Dispatch an event into the implementation's event model
*
* \param et The EventTarget object
- * \param eti Internal EventTarget
* \param evt The event object
* \param success Indicates whether any of the listeners which handled the
* event called Event.preventDefault(). If
@@ -2369,31 +2401,46 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
*success = true;
- /* Compose the event target list */
+ /* Initialise array of targets for capture/bubbling phases */
+ targets = NULL;
+ ntargets_allocated = 0;
ntargets = 0;
- ntargets_allocated = 64;
- targets = calloc(sizeof(*targets), ntargets_allocated);
- if (targets == NULL) {
- /** \todo Report memory exhaustion? */
- return DOM_NO_ERR;
- }
- targets[ntargets++] = (dom_event_target *)dom_node_ref(et);
- target = target->parent;
- while (target != NULL) {
+ /* Add interested event listeners to array */
+ for (; target != NULL; target = target->parent) {
+ struct listener_entry *le = target->eti.listeners;
+ bool target_has_listener = false;
+
+ if (le == NULL) {
+ /* This event target isn't listening to anything */
+ continue;
+ }
+
+ /* Check whether the event target is listening for this
+ * event type */
+ do {
+ if (dom_string_isequal(le->type, evt->type)) {
+ target_has_listener = true;
+ break;
+ }
+ le = (struct listener_entry *) le->list.next;
+ } while (le != target->eti.listeners);
+
+ if (target_has_listener == false) {
+ continue;
+ }
+
+ /* The event target is listening for this event type,
+ * so add it to the array. */
if (ntargets == ntargets_allocated) {
- dom_event_target **newtargets = realloc(
- targets,
- ntargets_allocated * 2 * sizeof(*targets));
- if (newtargets == NULL)
+ err = _dom_event_targets_expand(&ntargets_allocated,
+ &targets);
+ if (err != DOM_NO_ERR) {
+ ret = err;
goto cleanup;
- memset(newtargets + ntargets_allocated,
- 0, ntargets_allocated * sizeof(*newtargets));
- targets = newtargets;
- ntargets_allocated *= 2;
+ }
}
targets[ntargets++] = (dom_event_target *)dom_node_ref(target);
- target = target->parent;
}
/* Fill the target of the event */
@@ -2412,7 +2459,7 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
}
/* The capture phase */
- for (targetnr = ntargets; targetnr > 1; --targetnr) {
+ for (targetnr = ntargets; targetnr > 0; --targetnr) {
dom_node_internal *node =
(dom_node_internal *) targets[targetnr - 1];
@@ -2443,7 +2490,7 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
/* Bubbling phase */
evt->phase = DOM_BUBBLING_PHASE;
- for (targetnr = 1; targetnr < ntargets; ++targetnr) {
+ for (targetnr = 0; targetnr < ntargets; ++targetnr) {
dom_node_internal *node =
(dom_node_internal *) targets[targetnr];
err = _dom_event_target_dispatch(targets[targetnr],
@@ -2465,8 +2512,8 @@ dom_exception _dom_node_dispatch_event(dom_event_target *et,
dom_default_action_phase phase = DOM_DEFAULT_ACTION_END;
if (evt->prevent_default == true)
phase = DOM_DEFAULT_ACTION_PREVENTED;
- dom_default_action_callback cb = dei->actions(evt->type, phase,
- &pw);
+ dom_default_action_callback cb = dei->actions(
+ evt->type, phase, &pw);
if (cb != NULL) {
cb(evt, pw);
}
@@ -2480,7 +2527,9 @@ cleanup:
while (ntargets--) {
dom_node_unref(targets[ntargets]);
}
- free(targets);
+ if (targets != NULL) {
+ free(targets);
+ }
if (dei != NULL && dei->actions != NULL) {
dom_default_action_callback cb = dei->actions(evt->type,
--
Document Object Model library
7 years, 8 months
netsurf: branch master updated. release/3.3-666-g720a8fe
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/720a8fec0e2b435e09d76...
...commit http://git.netsurf-browser.org/netsurf.git/commit/720a8fec0e2b435e09d76ea...
...tree http://git.netsurf-browser.org/netsurf.git/tree/720a8fec0e2b435e09d76eabf...
The branch, master has been updated
via 720a8fec0e2b435e09d76eabf3c40e78dba414cc (commit)
from f5ab5703207975bd266356aea95b58cdc91347e9 (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.git/commit/?id=720a8fec0e2b435e09d...
commit 720a8fec0e2b435e09d76eabf3c40e78dba414cc
Author: John-Mark Bell <jmb(a)netsurf-browser.org>
Commit: John-Mark Bell <jmb(a)netsurf-browser.org>
Javascript: introduce script execution timeout. For #2413.
diff --git a/javascript/duktape/duk_custom.h b/javascript/duktape/duk_custom.h
index 95a47ac..1f98b78 100644
--- a/javascript/duktape/duk_custom.h
+++ b/javascript/duktape/duk_custom.h
@@ -29,3 +29,9 @@
#endif
#define DUK_USE_REGEXP_CANON_WORKAROUND
+
+/* Required for execution timeout checking */
+#define DUK_USE_INTERRUPT_COUNTER
+
+extern duk_bool_t dukky_check_timeout(void *udata);
+#define DUK_USE_EXEC_TIMEOUT_CHECK dukky_check_timeout
diff --git a/javascript/duktape/dukky.c b/javascript/duktape/dukky.c
index d583484..2c929b8 100644
--- a/javascript/duktape/dukky.c
+++ b/javascript/duktape/dukky.c
@@ -21,6 +21,10 @@
* Duktapeish implementation of javascript engine functions.
*/
+#include <inttypes.h>
+
+#include <nsutils/time.h>
+
#include "content/content.h"
#include "utils/nsoption.h"
@@ -328,6 +332,7 @@ static void dukky_free_function(void *udata, void *ptr)
struct jscontext {
duk_context *ctx;
duk_context *thread;
+ uint64_t exec_start_time;
};
#define CTX (ctx->thread)
@@ -363,7 +368,7 @@ nserror js_newcontext(int timeout, jscallback *cb, void *cbctx,
dukky_alloc_function,
dukky_realloc_function,
dukky_free_function,
- NULL,
+ ret,
NULL);
if (ret->ctx == NULL) { free(ret); return NSERROR_NOMEM; }
/* Create the prototype stuffs */
@@ -425,6 +430,22 @@ static duk_ret_t eval_top_string(duk_context *ctx)
return 0;
}
+duk_bool_t dukky_check_timeout(void *udata)
+{
+#define JS_EXEC_TIMEOUT_MS 10000 /* 10 seconds */
+ jscontext *ctx = (jscontext *) udata;
+ uint64_t now;
+
+ (void) nsu_getmonotonic_ms(&now);
+
+ /* This function may be called during duk heap construction,
+ * so only test for execution timeout if we've recorded a
+ * start time.
+ */
+ return ctx->exec_start_time != 0 &&
+ now > (ctx->exec_start_time + JS_EXEC_TIMEOUT_MS);
+}
+
bool js_exec(jscontext *ctx, const char *txt, size_t txtlen)
{
assert(ctx);
@@ -432,6 +453,7 @@ bool js_exec(jscontext *ctx, const char *txt, size_t txtlen)
duk_set_top(CTX, 0);
duk_push_lstring(CTX, txt, txtlen);
+ (void) nsu_getmonotonic_ms(&ctx->exec_start_time);
if (duk_safe_call(CTX, eval_top_string, 1, 1) == DUK_EXEC_ERROR) {
duk_get_prop_string(CTX, 0, "name");
duk_get_prop_string(CTX, 0, "message");
@@ -581,12 +603,18 @@ bool dukky_get_current_value_of_event_handler(duk_context *ctx,
static void dukky_generic_event_handler(dom_event *evt, void *pw)
{
+ duk_memory_functions funcs;
duk_context *ctx = (duk_context *)pw;
+ jscontext *jsctx;
dom_string *name;
dom_exception exc;
dom_event_target *targ;
dom_event_flow_phase phase;
+ /* Retrieve the JS context from the Duktape context */
+ duk_get_memory_functions(ctx, &funcs);
+ jsctx = funcs.udata;
+
LOG("WOOP WOOP, An event:");
exc = dom_event_get_type(evt, &name);
if (exc != DOM_NO_ERR) {
@@ -633,6 +661,7 @@ static void dukky_generic_event_handler(dom_event *evt, void *pw)
/* ... handler node */
dukky_push_event(ctx, evt);
/* ... handler node event */
+ (void) nsu_getmonotonic_ms(&jsctx->exec_start_time);
if (duk_pcall_method(ctx, 1) != 0) {
/* Failed to run the method */
/* ... err */
@@ -874,6 +903,7 @@ bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, s
/* ... handler Window */
dukky_push_event(CTX, evt);
/* ... handler Window event */
+ (void) nsu_getmonotonic_ms(&ctx->exec_start_time);
if (duk_pcall_method(CTX, 1) != 0) {
/* Failed to run the handler */
/* ... err */
-----------------------------------------------------------------------
Summary of changes:
javascript/duktape/duk_custom.h | 6 ++++++
javascript/duktape/dukky.c | 32 +++++++++++++++++++++++++++++++-
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/javascript/duktape/duk_custom.h b/javascript/duktape/duk_custom.h
index 95a47ac..1f98b78 100644
--- a/javascript/duktape/duk_custom.h
+++ b/javascript/duktape/duk_custom.h
@@ -29,3 +29,9 @@
#endif
#define DUK_USE_REGEXP_CANON_WORKAROUND
+
+/* Required for execution timeout checking */
+#define DUK_USE_INTERRUPT_COUNTER
+
+extern duk_bool_t dukky_check_timeout(void *udata);
+#define DUK_USE_EXEC_TIMEOUT_CHECK dukky_check_timeout
diff --git a/javascript/duktape/dukky.c b/javascript/duktape/dukky.c
index d583484..2c929b8 100644
--- a/javascript/duktape/dukky.c
+++ b/javascript/duktape/dukky.c
@@ -21,6 +21,10 @@
* Duktapeish implementation of javascript engine functions.
*/
+#include <inttypes.h>
+
+#include <nsutils/time.h>
+
#include "content/content.h"
#include "utils/nsoption.h"
@@ -328,6 +332,7 @@ static void dukky_free_function(void *udata, void *ptr)
struct jscontext {
duk_context *ctx;
duk_context *thread;
+ uint64_t exec_start_time;
};
#define CTX (ctx->thread)
@@ -363,7 +368,7 @@ nserror js_newcontext(int timeout, jscallback *cb, void *cbctx,
dukky_alloc_function,
dukky_realloc_function,
dukky_free_function,
- NULL,
+ ret,
NULL);
if (ret->ctx == NULL) { free(ret); return NSERROR_NOMEM; }
/* Create the prototype stuffs */
@@ -425,6 +430,22 @@ static duk_ret_t eval_top_string(duk_context *ctx)
return 0;
}
+duk_bool_t dukky_check_timeout(void *udata)
+{
+#define JS_EXEC_TIMEOUT_MS 10000 /* 10 seconds */
+ jscontext *ctx = (jscontext *) udata;
+ uint64_t now;
+
+ (void) nsu_getmonotonic_ms(&now);
+
+ /* This function may be called during duk heap construction,
+ * so only test for execution timeout if we've recorded a
+ * start time.
+ */
+ return ctx->exec_start_time != 0 &&
+ now > (ctx->exec_start_time + JS_EXEC_TIMEOUT_MS);
+}
+
bool js_exec(jscontext *ctx, const char *txt, size_t txtlen)
{
assert(ctx);
@@ -432,6 +453,7 @@ bool js_exec(jscontext *ctx, const char *txt, size_t txtlen)
duk_set_top(CTX, 0);
duk_push_lstring(CTX, txt, txtlen);
+ (void) nsu_getmonotonic_ms(&ctx->exec_start_time);
if (duk_safe_call(CTX, eval_top_string, 1, 1) == DUK_EXEC_ERROR) {
duk_get_prop_string(CTX, 0, "name");
duk_get_prop_string(CTX, 0, "message");
@@ -581,12 +603,18 @@ bool dukky_get_current_value_of_event_handler(duk_context *ctx,
static void dukky_generic_event_handler(dom_event *evt, void *pw)
{
+ duk_memory_functions funcs;
duk_context *ctx = (duk_context *)pw;
+ jscontext *jsctx;
dom_string *name;
dom_exception exc;
dom_event_target *targ;
dom_event_flow_phase phase;
+ /* Retrieve the JS context from the Duktape context */
+ duk_get_memory_functions(ctx, &funcs);
+ jsctx = funcs.udata;
+
LOG("WOOP WOOP, An event:");
exc = dom_event_get_type(evt, &name);
if (exc != DOM_NO_ERR) {
@@ -633,6 +661,7 @@ static void dukky_generic_event_handler(dom_event *evt, void *pw)
/* ... handler node */
dukky_push_event(ctx, evt);
/* ... handler node event */
+ (void) nsu_getmonotonic_ms(&jsctx->exec_start_time);
if (duk_pcall_method(ctx, 1) != 0) {
/* Failed to run the method */
/* ... err */
@@ -874,6 +903,7 @@ bool js_fire_event(jscontext *ctx, const char *type, struct dom_document *doc, s
/* ... handler Window */
dukky_push_event(CTX, evt);
/* ... handler Window event */
+ (void) nsu_getmonotonic_ms(&ctx->exec_start_time);
if (duk_pcall_method(CTX, 1) != 0) {
/* Failed to run the handler */
/* ... err */
--
NetSurf Browser
7 years, 8 months
libwapcaplet: branch master updated. release/0.2.3-4-g436e979
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libwapcaplet.git/shortlog/436e979d9f9ae889...
...commit http://git.netsurf-browser.org/libwapcaplet.git/commit/436e979d9f9ae8897b...
...tree http://git.netsurf-browser.org/libwapcaplet.git/tree/436e979d9f9ae8897bf2...
The branch, master has been updated
via 436e979d9f9ae8897bf2cc0afc985dbfa09347ba (commit)
via 08c5618a803fa32243dfa434225604566c5dac91 (commit)
via 43b2081b8d5e23c8582e2729f18ccd7555be8a40 (commit)
via 86508f207b5fbb26db06dd9411d08bb0b9bfa6c8 (commit)
from 7c802fa89776e5a39eb97286020ccc06663f6226 (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/libwapcaplet.git/commit/?id=436e979d9f9ae8...
commit 436e979d9f9ae8897bf2cc0afc985dbfa09347ba
Merge: 7c802fa 08c5618
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Merge branch 'tlsa/tolower'
-----------------------------------------------------------------------
Summary of changes:
include/libwapcaplet/libwapcaplet.h | 10 ++
src/libwapcaplet.c | 295 ++++++++++++++++++-----------------
test/basictests.c | 59 +++++++
3 files changed, 225 insertions(+), 139 deletions(-)
diff --git a/include/libwapcaplet/libwapcaplet.h b/include/libwapcaplet/libwapcaplet.h
index 4c0fc71..c0e8c29 100644
--- a/include/libwapcaplet/libwapcaplet.h
+++ b/include/libwapcaplet/libwapcaplet.h
@@ -106,6 +106,16 @@ extern lwc_error lwc_intern_substring(lwc_string *str,
lwc_string **ret);
/**
+ * Optain a lowercased lwc_string from given lwc_string.
+ *
+ * @param str String to create lowercase string from.
+ * @param ret Pointer to ::lwc_string pointer to fill out.
+ * @return Result of operation, if not OK then the value pointed
+ * to by \a ret will not be valid.
+ */
+extern lwc_error lwc_string_tolower(lwc_string *str, lwc_string **ret);
+
+/**
* Increment the reference count on an lwc_string.
*
* This increases the reference count on the given string. You should
diff --git a/src/libwapcaplet.c b/src/libwapcaplet.c
index b82d62f..9521e96 100644
--- a/src/libwapcaplet.c
+++ b/src/libwapcaplet.c
@@ -20,12 +20,11 @@ static inline lwc_hash
lwc__calculate_hash(const char *str, size_t len)
{
lwc_hash z = 0x811c9dc5;
-
while (len > 0) {
z *= 0x01000193;
z ^= *str++;
- len--;
+ len--;
}
return z;
@@ -37,8 +36,8 @@ lwc__calculate_hash(const char *str, size_t len)
#define NR_BUCKETS_DEFAULT (4091)
typedef struct lwc_context_s {
- lwc_string ** buckets;
- lwc_hash bucketcount;
+ lwc_string ** buckets;
+ lwc_hash bucketcount;
} lwc_context;
static lwc_context *ctx = NULL;
@@ -53,136 +52,155 @@ typedef void (*lwc_memcpy)(char *, const char *, size_t);
static lwc_error
lwc__initialise(void)
{
- if (ctx != NULL)
- return lwc_error_ok;
-
- ctx = LWC_ALLOC(sizeof(lwc_context));
-
- if (ctx == NULL)
- return lwc_error_oom;
-
- memset(ctx, 0, sizeof(lwc_context));
-
- ctx->bucketcount = NR_BUCKETS_DEFAULT;
- ctx->buckets = LWC_ALLOC(sizeof(lwc_string *) * ctx->bucketcount);
-
- if (ctx->buckets == NULL) {
- LWC_FREE(ctx);
+ if (ctx != NULL)
+ return lwc_error_ok;
+
+ ctx = LWC_ALLOC(sizeof(lwc_context));
+
+ if (ctx == NULL)
+ return lwc_error_oom;
+
+ memset(ctx, 0, sizeof(lwc_context));
+
+ ctx->bucketcount = NR_BUCKETS_DEFAULT;
+ ctx->buckets = LWC_ALLOC(sizeof(lwc_string *) * ctx->bucketcount);
+
+ if (ctx->buckets == NULL) {
+ LWC_FREE(ctx);
ctx = NULL;
- return lwc_error_oom;
- }
-
- memset(ctx->buckets, 0, sizeof(lwc_string *) * ctx->bucketcount);
-
- return lwc_error_ok;
+ return lwc_error_oom;
+ }
+
+ memset(ctx->buckets, 0, sizeof(lwc_string *) * ctx->bucketcount);
+
+ return lwc_error_ok;
}
static lwc_error
lwc__intern(const char *s, size_t slen,
- lwc_string **ret,
- lwc_hasher hasher,
- lwc_strncmp compare,
- lwc_memcpy copy)
+ lwc_string **ret,
+ lwc_hasher hasher,
+ lwc_strncmp compare,
+ lwc_memcpy copy)
{
- lwc_hash h;
- lwc_hash bucket;
- lwc_string *str;
- lwc_error eret;
-
- assert((s != NULL) || (slen == 0));
- assert(ret);
-
- if (ctx == NULL) {
- eret = lwc__initialise();
- if (eret != lwc_error_ok)
- return eret;
- if (ctx == NULL)
- return lwc_error_oom;
- }
-
- h = hasher(s, slen);
- bucket = h % ctx->bucketcount;
- str = ctx->buckets[bucket];
-
- while (str != NULL) {
- if ((str->hash == h) && (str->len == slen)) {
- if (compare(CSTR_OF(str), s, slen) == 0) {
- str->refcnt++;
- *ret = str;
- return lwc_error_ok;
- }
- }
- str = str->next;
- }
-
- /* Add one for the additional NUL. */
- *ret = str = LWC_ALLOC(sizeof(lwc_string) + slen + 1);
-
- if (str == NULL)
- return lwc_error_oom;
-
- str->prevptr = &(ctx->buckets[bucket]);
- str->next = ctx->buckets[bucket];
- if (str->next != NULL)
- str->next->prevptr = &(str->next);
- ctx->buckets[bucket] = str;
-
- str->len = slen;
- str->hash = h;
- str->refcnt = 1;
- str->insensitive = NULL;
-
- copy(STR_OF(str), s, slen);
-
- /* Guarantee NUL termination */
- STR_OF(str)[slen] = '\0';
-
- return lwc_error_ok;
+ lwc_hash h;
+ lwc_hash bucket;
+ lwc_string *str;
+ lwc_error eret;
+
+ assert((s != NULL) || (slen == 0));
+ assert(ret);
+
+ if (ctx == NULL) {
+ eret = lwc__initialise();
+ if (eret != lwc_error_ok)
+ return eret;
+ if (ctx == NULL)
+ return lwc_error_oom;
+ }
+
+ h = hasher(s, slen);
+ bucket = h % ctx->bucketcount;
+ str = ctx->buckets[bucket];
+
+ while (str != NULL) {
+ if ((str->hash == h) && (str->len == slen)) {
+ if (compare(CSTR_OF(str), s, slen) == 0) {
+ str->refcnt++;
+ *ret = str;
+ return lwc_error_ok;
+ }
+ }
+ str = str->next;
+ }
+
+ /* Add one for the additional NUL. */
+ *ret = str = LWC_ALLOC(sizeof(lwc_string) + slen + 1);
+
+ if (str == NULL)
+ return lwc_error_oom;
+
+ str->prevptr = &(ctx->buckets[bucket]);
+ str->next = ctx->buckets[bucket];
+ if (str->next != NULL)
+ str->next->prevptr = &(str->next);
+ ctx->buckets[bucket] = str;
+
+ str->len = slen;
+ str->hash = h;
+ str->refcnt = 1;
+ str->insensitive = NULL;
+
+ copy(STR_OF(str), s, slen);
+
+ /* Guarantee NUL termination */
+ STR_OF(str)[slen] = '\0';
+
+ return lwc_error_ok;
}
lwc_error
lwc_intern_string(const char *s, size_t slen,
- lwc_string **ret)
+ lwc_string **ret)
{
- return lwc__intern(s, slen, ret,
- lwc__calculate_hash,
- strncmp, (lwc_memcpy)memcpy);
+ return lwc__intern(s, slen, ret,
+ lwc__calculate_hash,
+ strncmp, (lwc_memcpy)memcpy);
}
lwc_error
lwc_intern_substring(lwc_string *str,
- size_t ssoffset, size_t sslen,
- lwc_string **ret)
+ size_t ssoffset, size_t sslen,
+ lwc_string **ret)
+{
+ assert(str);
+ assert(ret);
+
+ if (ssoffset >= str->len)
+ return lwc_error_range;
+ if ((ssoffset + sslen) > str->len)
+ return lwc_error_range;
+
+ return lwc_intern_string(CSTR_OF(str) + ssoffset, sslen, ret);
+}
+
+lwc_error
+lwc_string_tolower(lwc_string *str, lwc_string **ret)
{
- assert(str);
- assert(ret);
-
- if (ssoffset >= str->len)
- return lwc_error_range;
- if ((ssoffset + sslen) > str->len)
- return lwc_error_range;
-
- return lwc_intern_string(CSTR_OF(str) + ssoffset, sslen, ret);
+ assert(str);
+ assert(ret);
+
+ /* Internally make use of knowledge that insensitive strings
+ * are lower case. */
+ if (str->insensitive == NULL) {
+ lwc_error error = lwc__intern_caseless_string(str);
+ if (error != lwc_error_ok) {
+ return error;
+ }
+ }
+
+ *ret = lwc_string_ref(str->insensitive);
+ return lwc_error_ok;
}
void
lwc_string_destroy(lwc_string *str)
{
- assert(str);
-
- *(str->prevptr) = str->next;
-
- if (str->next != NULL)
- str->next->prevptr = str->prevptr;
+ assert(str);
+
+ *(str->prevptr) = str->next;
+
+ if (str->next != NULL)
+ str->next->prevptr = str->prevptr;
- if (str->insensitive != NULL && str->refcnt == 0)
- lwc_string_unref(str->insensitive);
+ if (str->insensitive != NULL && str->refcnt == 0)
+ lwc_string_unref(str->insensitive);
#ifndef NDEBUG
- memset(str, 0xA5, sizeof(*str) + str->len);
+ memset(str, 0xA5, sizeof(*str) + str->len);
#endif
-
- LWC_FREE(str);
+
+ LWC_FREE(str);
}
/**** Shonky caseless bits ****/
@@ -190,21 +208,20 @@ lwc_string_destroy(lwc_string *str)
static inline char
lwc__dolower(const char c)
{
- if (c >= 'A' && c <= 'Z')
- return c + 'a' - 'A';
- return c;
+ if (c >= 'A' && c <= 'Z')
+ return c + 'a' - 'A';
+ return c;
}
static inline lwc_hash
lwc__calculate_lcase_hash(const char *str, size_t len)
{
lwc_hash z = 0x811c9dc5;
-
while (len > 0) {
z *= 0x01000193;
z ^= lwc__dolower(*str++);
- len--;
+ len--;
}
return z;
@@ -213,33 +230,33 @@ lwc__calculate_lcase_hash(const char *str, size_t len)
static int
lwc__lcase_strncmp(const char *s1, const char *s2, size_t n)
{
- while (n--) {
- if (*s1++ != lwc__dolower(*s2++))
- /** @todo Test this somehow? */
- return 1;
- }
- return 0;
+ while (n--) {
+ if (*s1++ != lwc__dolower(*s2++))
+ /** @todo Test this somehow? */
+ return 1;
+ }
+ return 0;
}
static void
lwc__lcase_memcpy(char *target, const char *source, size_t n)
{
- while (n--) {
- *target++ = lwc__dolower(*source++);
- }
+ while (n--) {
+ *target++ = lwc__dolower(*source++);
+ }
}
lwc_error
lwc__intern_caseless_string(lwc_string *str)
{
- assert(str);
- assert(str->insensitive == NULL);
-
- return lwc__intern(CSTR_OF(str),
- str->len, &(str->insensitive),
- lwc__calculate_lcase_hash,
- lwc__lcase_strncmp,
- lwc__lcase_memcpy);
+ assert(str);
+ assert(str->insensitive == NULL);
+
+ return lwc__intern(CSTR_OF(str),
+ str->len, &(str->insensitive),
+ lwc__calculate_lcase_hash,
+ lwc__lcase_strncmp,
+ lwc__lcase_memcpy);
}
/**** Iteration ****/
@@ -247,14 +264,14 @@ lwc__intern_caseless_string(lwc_string *str)
void
lwc_iterate_strings(lwc_iteration_callback_fn cb, void *pw)
{
- lwc_hash n;
- lwc_string *str;
-
+ lwc_hash n;
+ lwc_string *str;
+
if (ctx == NULL)
return;
-
- for (n = 0; n < ctx->bucketcount; ++n) {
- for (str = ctx->buckets[n]; str != NULL; str = str->next)
- cb(str, pw);
- }
+
+ for (n = 0; n < ctx->bucketcount; ++n) {
+ for (str = ctx->buckets[n]; str != NULL; str = str->next)
+ cb(str, pw);
+ }
}
diff --git a/test/basictests.c b/test/basictests.c
index ec9bf20..c23b547 100644
--- a/test/basictests.c
+++ b/test/basictests.c
@@ -50,6 +50,22 @@ START_TEST (test_lwc_intern_substring_aborts2)
}
END_TEST
+START_TEST (test_lwc_string_tolower_aborts1)
+{
+ lwc_string_tolower(null_lwc, null_lwc_p);
+}
+END_TEST
+
+START_TEST (test_lwc_string_tolower_aborts2)
+{
+ lwc_string *str;
+ fail_unless(lwc_intern_string("Badger", 6, &str) == lwc_error_ok,
+ "unable to intern 'Badger'");
+
+ lwc_string_tolower(str, null_lwc_p);
+}
+END_TEST
+
START_TEST (test_lwc_string_ref_aborts)
{
lwc_string_ref(null_lwc);
@@ -330,6 +346,41 @@ START_TEST (test_lwc_substring_is_nul_terminated)
}
END_TEST
+START_TEST (test_lwc_string_tolower_ok1)
+{
+ bool result = true;
+ lwc_string *new_ONE;
+ lwc_string *new_one;
+
+ fail_unless(lwc_intern_string("ONE", 3, &new_ONE) == lwc_error_ok,
+ "Failure interning 'ONE'");
+ fail_unless(lwc_string_tolower(new_ONE, &new_one) == lwc_error_ok);
+ fail_unless(lwc_string_isequal(intern_one, new_ONE, &result) == lwc_error_ok);
+ fail_unless(result == false, "'one' == 'ONE' ?!");
+ fail_unless(lwc_string_isequal(intern_one, new_one, &result) == lwc_error_ok);
+ fail_unless(result == true, "'one' != 'one' ?!");
+}
+END_TEST
+
+START_TEST (test_lwc_string_tolower_ok2)
+{
+ bool result = true;
+ lwc_string *new_ONE;
+ lwc_string *new_one;
+
+ fail_unless(lwc_intern_string("ONE", 3, &new_ONE) == lwc_error_ok,
+ "Failure interning 'ONE'");
+ /* Ensure new_ONE has an insensitive pointer set */
+ fail_unless(lwc_string_caseless_isequal(intern_one, new_ONE, &result) == lwc_error_ok);
+ fail_unless(result == true, "'one' != 'ONE' (caseless) ?!");
+ fail_unless(lwc_string_tolower(new_ONE, &new_one) == lwc_error_ok);
+ fail_unless(lwc_string_isequal(intern_one, new_ONE, &result) == lwc_error_ok);
+ fail_unless(result == false, "'one' == 'ONE' ?!");
+ fail_unless(lwc_string_isequal(intern_one, new_one, &result) == lwc_error_ok);
+ fail_unless(result == true, "'one' != 'one' ?!");
+}
+END_TEST
+
static void
counting_cb(lwc_string *str, void *pw)
{
@@ -368,6 +419,12 @@ lwc_basic_suite(SRunner *sr)
test_lwc_intern_substring_aborts2,
SIGABRT);
tcase_add_test_raise_signal(tc_basic,
+ test_lwc_string_tolower_aborts1,
+ SIGABRT);
+ tcase_add_test_raise_signal(tc_basic,
+ test_lwc_string_tolower_aborts2,
+ SIGABRT);
+ tcase_add_test_raise_signal(tc_basic,
test_lwc_string_ref_aborts,
SIGABRT);
tcase_add_test_raise_signal(tc_basic,
@@ -408,6 +465,8 @@ lwc_basic_suite(SRunner *sr)
tcase_add_test(tc_basic, test_lwc_string_caseless_isequal_ok1);
tcase_add_test(tc_basic, test_lwc_string_caseless_isequal_ok2);
tcase_add_test(tc_basic, test_lwc_string_caseless_isequal_bad);
+ tcase_add_test(tc_basic, test_lwc_string_tolower_ok1);
+ tcase_add_test(tc_basic, test_lwc_string_tolower_ok2);
tcase_add_test(tc_basic, test_lwc_extract_data_ok);
tcase_add_test(tc_basic, test_lwc_string_hash_value_ok);
tcase_add_test(tc_basic, test_lwc_string_is_nul_terminated);
--
String internment library
7 years, 8 months