Gitweb links:
...log
http://git.netsurf-browser.org/netsurf.git/shortlog/d06c7eb34614f047bf52c97608301da52ede654b
...commit
http://git.netsurf-browser.org/netsurf.git/commit/d06c7eb34614f047bf52c97608301da52ede654b
...tree
http://git.netsurf-browser.org/netsurf.git/tree/d06c7eb34614f047bf52c97608301da52ede654b
The branch, tlsa/date has been updated
discards 947275176ff93d48621343e608ba522917f258c0 (commit)
discards 415678aa14eb4c15e8f6a41f528929b43d887576 (commit)
discards a84965be1c25d39cc8891d3c446e063dfc95ed67 (commit)
discards 206b258bd1ead216f5274af14a85290c3af950c5 (commit)
via d06c7eb34614f047bf52c97608301da52ede654b (commit)
via 640fe591e8b66e5833404b7545df8a8b522e88c6 (commit)
via 0637e4f5407bf431afdef346a846ddbec0262bf9 (commit)
via b943261af1f0c4707d24e646ccb833d530707c1f (commit)
via 62682552887e53db7f585e7b2bfd30e137c5b87f (commit)
via 68b20a382d3c2fe23ebdd152ed39c0290bcc6fa7 (commit)
via 1457a049bb9e77cd85fda95ce492a4d79f536f4a (commit)
via ebb2a33b0b68104920abbfa2c447595d2c3a2010 (commit)
via 9aecf47408f22f4f0a01e41648f25e1a7307b332 (commit)
via b63443b243bec435c1650aef2068299674b2a209 (commit)
via 4b14f9ff37b4c0614a8f039aa393aa3c6bb86c97 (commit)
via cd488602073a1775c41a60d582854feec63cb676 (commit)
via 1ca5b7332c2b10b671e6844b79ed58d50337ce52 (commit)
via 94de23dce9b4cb490bcaf08433c6ba75abf4a29c (commit)
via 9176d3233fc395f579a33484ed714649e1fd8f46 (commit)
via 6a2675557690a7eeab7b5c4ca70a80fd194e6466 (commit)
via 115985f069247d5eb6c5955de7de110114db9ca4 (commit)
via d35ad1b8e707f9dc8ccad5b11efc4eec0302f3ad (commit)
via 24c195910506e99b7d9152524aeaef042da1dedf (commit)
via 747958c14caa03f48fdd3256d63601b513ca499c (commit)
via 54860ee6b8fe1ad33977eca490200929ea9cfac5 (commit)
via 5830a4c0402da9acdcf20b62b359d762dd8c235b (commit)
via 4bc029340eb0576eb40b8766be67b31e139bf385 (commit)
via 958fb6aa5ea5ca93c5b099633ba72ee509a47547 (commit)
via 4448fa6cbf9aade05d02f5e04b9137d4c775a79a (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (947275176ff93d48621343e608ba522917f258c0)
\
N -- N -- N (d06c7eb34614f047bf52c97608301da52ede654b)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
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=d06c7eb34614f047bf52c97608301da52ede654b
commit d06c7eb34614f047bf52c97608301da52ede654b
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
Tests: Add some basic tests for date string parsing.
diff --git a/test/Makefile b/test/Makefile
index 0253f4d..d62e2fd 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,7 +1,16 @@
#
# NetSurf unit tests
-TESTS := nsurl urldbtest nsoption bloom hashtable urlescape utils messages
#llcache
+TESTS := \
+ nsurl \
+ urldbtest \
+ nsoption \
+ bloom \
+ hashtable \
+ urlescape \
+ utils \
+ messages \
+ time #llcache
# nsurl sources
nsurl_SRCS := utils/corestrings.c utils/nsurl.c utils/idna.c \
@@ -44,6 +53,9 @@ urlescape_SRCS := utils/url.c test/log.c test/urlescape.c
utils_SRCS := utils/utils.c utils/messages.c utils/hashtable.c \
test/log.c test/utils.c
+# time test sources
+time_SRCS := utils/time.c test/log.c test/time.c
+
# Coverage builds need additional flags
ifeq ($(MAKECMDGOALS),coverage)
COV_CFLAGS ?= -fprofile-arcs -ftest-coverage -O0
diff --git a/test/time.c b/test/time.c
new file mode 100644
index 0000000..b2d465c
--- /dev/null
+++ b/test/time.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright 2016 Michael Drake <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * Test time operations.
+ */
+
+#include <stdlib.h>
+#include <check.h>
+
+#include "utils/errors.h"
+#include "utils/time.h"
+
+#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
+
+struct test_string_pair {
+ const char* test;
+ const char* expected;
+};
+
+struct test_bad_string {
+ const char* test;
+ nserror res;
+};
+
+static const struct test_string_pair date_string_tests[] = {
+ {
+ .test = "Thu, 01 Jan 1970 00:00:00 GMT",
+ .expected = "Thu, 01 Jan 1970 00:00:00 GMT"
+ },
+ {
+ .test = "Tue, 16 Feb 1999 19:45:12 GMT",
+ .expected = "Tue, 16 Feb 1999 19:45:12 GMT"
+ },
+ {
+ .test = "Sun, 16 Mar 1980 19:45:12 GMT",
+ .expected = "Sun, 16 Mar 1980 19:45:12 GMT"
+ },
+ {
+ .test = "Tue, 16 Apr 2013 19:45:12 GMT",
+ .expected = "Tue, 16 Apr 2013 19:45:12 GMT"
+ },
+ {
+ .test = "Tue, 16 May 2000 19:45:12 GMT",
+ .expected = "Tue, 16 May 2000 19:45:12 GMT"
+ },
+ {
+ .test = "Tue, 12 Jun 2001 12:12:12 GMT",
+ .expected = "Tue, 12 Jun 2001 12:12:12 GMT"
+ },
+ {
+ .test = "Thu, 16 Jul 2207 12:45:12 GMT",
+ .expected = "Thu, 16 Jul 2207 12:45:12 GMT"
+ },
+ {
+ .test = "Thu, 16 Aug 2007 19:45:12 GMT",
+ .expected = "Thu, 16 Aug 2007 19:45:12 GMT"
+ },
+ {
+ .test = "Tue, 16 Sep 3456 00:45:12 GMT",
+ .expected = "Tue, 16 Sep 3456 00:45:12 GMT"
+ },
+ {
+ .test = "Sun, 16 Oct 1988 19:45:59 GMT",
+ .expected = "Sun, 16 Oct 1988 19:45:59 GMT"
+ },
+ {
+ .test = "Tue, 16 Nov 1971 19:59:12 GMT",
+ .expected = "Tue, 16 Nov 1971 19:59:12 GMT"
+ },
+ {
+ .test = "Fri, 16 Dec 1977 23:45:12 GMT",
+ .expected = "Fri, 16 Dec 1977 23:45:12 GMT"
+ },
+ {
+ .test = " 16 Dec 1977 23:45:12 GMT",
+ .expected = "Fri, 16 Dec 1977 23:45:12 GMT"
+ },
+ {
+ .test = " 16 Dec 1977 23:45 GMT",
+ .expected = "Fri, 16 Dec 1977 23:45:00 GMT"
+ },
+ {
+ .test = "23:59 16 Dec 1977 GMT",
+ .expected = "Fri, 16 Dec 1977 23:59:00 GMT"
+ },
+ {
+ .test = "23:59 16 Dec 1977 UTC",
+ .expected = "Fri, 16 Dec 1977 23:59:00 GMT"
+ },
+ {
+ .test = "1977 GMT 23:59 16 Dec",
+ .expected = "Fri, 16 Dec 1977 23:59:00 GMT"
+ },
+ {
+ .test = "1977 Dec GMT 16",
+ .expected = "Fri, 16 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "1977 Dec 12",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "1977 12 Dec",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "Dec 1977 12",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "12 Dec 1977",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "12 Dec 77",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "12 77 Dec",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "77 12 Dec",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "12 12 Dec",
+ .expected = "Wed, 12 Dec 2012 00:00:00 GMT"
+ },
+ {
+ .test = "5 12 Dec",
+ .expected = "Wed, 05 Dec 2012 00:00:00 GMT"
+ },
+ {
+ .test = "12 5 Dec",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "12/5/Dec",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "Dec-12/2005/",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "12-5-Dec",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "2005-12-Dec",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "2005-Dec-12",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "2005-dec-12",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "2005-dEC-12",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "20051212",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "20051212 GMT",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "20051212 +0000",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "20051212 UTC",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "20051212 00:00 UTC",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "00:00 20051212 UTC",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "00:00:59 20051212 UTC",
+ .expected = "Mon, 12 Dec 2005 00:00:59 GMT"
+ },
+ {
+ .test = "00:00:60 20051212 UTC", /* leap second */
+ .expected = "Mon, 12 Dec 2005 00:01:00 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 GMT",
+ .expected = "Thu, 11 Aug 2016 08:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 UTC",
+ .expected = "Thu, 11 Aug 2016 08:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0000",
+ .expected = "Thu, 11 Aug 2016 08:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0000",
+ .expected = "Thu, 11 Aug 2016 08:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0001",
+ .expected = "Thu, 11 Aug 2016 08:46:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0001",
+ .expected = "Thu, 11 Aug 2016 08:48:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0030",
+ .expected = "Thu, 11 Aug 2016 08:17:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0030",
+ .expected = "Thu, 11 Aug 2016 09:17:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0059",
+ .expected = "Thu, 11 Aug 2016 07:48:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0059",
+ .expected = "Thu, 11 Aug 2016 09:46:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0100",
+ .expected = "Thu, 11 Aug 2016 07:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0100",
+ .expected = "Thu, 11 Aug 2016 09:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +1200",
+ .expected = "Wed, 10 Aug 2016 20:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -1200",
+ .expected = "Thu, 11 Aug 2016 20:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0060",
+ .expected = "Thu, 11 Aug 2016 07:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0060",
+ .expected = "Thu, 11 Aug 2016 09:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0070",
+ .expected = "Thu, 11 Aug 2016 07:37:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0070",
+ .expected = "Thu, 11 Aug 2016 09:57:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 BST",
+ .expected = "Thu, 11 Aug 2016 07:47:30 GMT"
+ },
+};
+
+
+static const struct test_bad_string date_bad_string_tests[] = {
+ {
+ .test = NULL,
+ .res = NSERROR_BAD_PARAMETER
+ },
+ {
+ .test = "",
+ .res = NSERROR_INVALID
+ },
+ {
+ .test = "Th",
+ .res = NSERROR_INVALID
+ },
+ {
+ .test = "5",
+ .res = NSERROR_INVALID
+ },
+ {
+ .test = "5",
+ .res = NSERROR_INVALID
+ },
+ {
+ .test = "dsflihs9l84toswuhfsif74f",
+ .res = NSERROR_INVALID
+ },
+};
+
+/**
+ * Date string comparason test
+ */
+START_TEST(date_string_compare)
+{
+ nserror res;
+ time_t time_out;
+ const struct test_string_pair *t = &date_string_tests[_i];
+
+ res = nsc_strntimet(t->test, strlen(t->test), &time_out);
+ ck_assert(res == NSERROR_OK);
+ ck_assert_str_eq(rfc1123_date(time_out), t->expected);
+}
+END_TEST
+
+/**
+ * Date string conversion bad data test
+ */
+START_TEST(date_bad_string)
+{
+ nserror res;
+ time_t time_out;
+ const struct test_bad_string *t = &date_bad_string_tests[_i];
+
+ res = nsc_strntimet(t->test,
+ t->test != NULL ? strlen(t->test) : 0,
+ &time_out);
+ ck_assert(res != NSERROR_OK);
+ ck_assert(res == t->res);
+}
+END_TEST
+
+
+/* suite generation */
+static Suite *time_suite(void)
+{
+ Suite *s;
+ TCase *tc_date_string_compare;
+ TCase *tc_date_bad_string;
+
+ s = suite_create("time");
+
+ /* date parsing: string comparason */
+ tc_date_string_compare = tcase_create(
+ "date string to time_t");
+
+ /* date parsing: bad string handling */
+ tc_date_bad_string = tcase_create(
+ "date string to time_t (bad input)");
+
+ tcase_add_loop_test(tc_date_string_compare,
+ date_string_compare,
+ 0, NELEMS(date_string_tests));
+ suite_add_tcase(s, tc_date_string_compare);
+
+ tcase_add_loop_test(tc_date_bad_string,
+ date_bad_string,
+ 0, NELEMS(date_bad_string_tests));
+ suite_add_tcase(s, tc_date_bad_string);
+
+ return s;
+}
+
+int main(int argc, char **argv)
+{
+ int number_failed;
+ Suite *s;
+ SRunner *sr;
+
+ s = time_suite();
+
+ sr = srunner_create(s);
+ srunner_run_all(sr, CK_ENV);
+
+ number_failed = srunner_ntests_failed(sr);
+ srunner_free(sr);
+
+ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=640fe591e8b66e5833404b7545df8a8b522e88c6
commit 640fe591e8b66e5833404b7545df8a8b522e88c6
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
f main
diff --git a/utils/time.c b/utils/time.c
index 667e836..433b479 100644
--- a/utils/time.c
+++ b/utils/time.c
@@ -80,7 +80,7 @@ enum nsc_time_months {
/**
* Array of short weekday names.
*/
-const char * const weekdays_short[NSC_TIME_WEEKDAY__COUNT] = {
+static const char * const weekdays_short[NSC_TIME_WEEKDAY__COUNT] = {
[NSC_TIME_WEEKDAY_SUN] = "Sun",
[NSC_TIME_WEEKDAY_MON] = "Mon",
[NSC_TIME_WEEKDAY_TUE] = "Tue",
@@ -92,7 +92,7 @@ const char * const weekdays_short[NSC_TIME_WEEKDAY__COUNT] = {
/**
* Array of month names.
*/
-const char * const months[NSC_TIME_MONTH__COUNT] = {
+static const char * const months[NSC_TIME_MONTH__COUNT] = {
[NSC_TIME_MONTH_JAN] = "Jan",
[NSC_TIME_MONTH_FEB] = "Feb",
[NSC_TIME_MONTH_MAR] = "Mar",
@@ -191,7 +191,7 @@ nserror nsc_snptimet(const char *str, size_t size, time_t
*timep)
/**
* Array of long weekday names.
*/
-const char * const weekdays_long[NSC_TIME_WEEKDAY__COUNT] = {
+static const char * const weekdays_long[NSC_TIME_WEEKDAY__COUNT] = {
[NSC_TIME_WEEKDAY_SUN] = "Sunday",
[NSC_TIME_WEEKDAY_MON] = "Monday",
[NSC_TIME_WEEKDAY_TUE] = "Tuesday",
@@ -361,7 +361,7 @@ enum nsc_time_zones {
/**
* Array of minute offsets for timezones.
*/
-const int16_t timezone_mins[NSC_TIME_ZONE__COUNT] = {
+static const int16_t timezone_mins[NSC_TIME_ZONE__COUNT] = {
[NSC_TIME_ZONE_IDLE] = NSC_TIME_ZONE_OFFSET_IDLE,
[NSC_TIME_ZONE_NZST] = NSC_TIME_ZONE_OFFSET_NZST,
[NSC_TIME_ZONE_NZT] = NSC_TIME_ZONE_OFFSET_NZT,
@@ -434,7 +434,7 @@ const int16_t timezone_mins[NSC_TIME_ZONE__COUNT] = {
/**
* Array of timezone names. Order does not matter.
*/
-const char * const timezones[NSC_TIME_ZONE__COUNT] = {
+static const char * const timezones[NSC_TIME_ZONE__COUNT] = {
[NSC_TIME_ZONE_IDLE] = "IDLE",
[NSC_TIME_ZONE_NZST] = "NZST",
[NSC_TIME_ZONE_NZT] = "NZT",
@@ -783,7 +783,7 @@ static inline bool time__parse_number(
ctx->timezone_offset_mins =
value / 100 * 60 +
value % 100;
- if (ctx->state == PARSE_STATE_HAD_MINUS) {
+ if (ctx->state == PARSE_STATE_HAD_PLUS) {
ctx->timezone_offset_mins *= -1;
}
*flags |= NSC_COMPONENT_FLAGS_HAVE_TIMEZONE;
@@ -798,8 +798,9 @@ static inline bool time__parse_number(
break;
case 2:
+ case 1:
if (!flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_DAYS) &&
- value <= 31) {
+ value > 0 && value <= 31) {
ctx->day = value - 1;
*flags |= NSC_COMPONENT_FLAGS_HAVE_DAYS;
return true;
@@ -813,14 +814,6 @@ static inline bool time__parse_number(
}
break;
- case 1:
- if (!flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_DAYS)) {
- ctx->day = value - 1;
- *flags |= NSC_COMPONENT_FLAGS_HAVE_DAYS;
- return true;
- }
- break;
-
default:
break;
}
@@ -935,7 +928,7 @@ static nserror time__get_date(const char *str, time_t *time)
.timezone_offset_mins = 0
};
- if (str == NULL || *str == '\0' || time == NULL) {
+ if (str == NULL || time == NULL) {
return NSERROR_BAD_PARAMETER;
}
@@ -984,8 +977,10 @@ static nserror time__get_date(const char *str, time_t
*time)
ctx.state = PARSE_STATE_NONE;
}
- /* The initial values of 0 are used if hours, mins, secs not found */
+ /* The initial values of 0 are used if hours, mins, secs, and timezone
+ * are not found */
flags |= NSC_COMPONENT_FLAGS__HAVE_HHMMSS;
+ flags |= NSC_COMPONENT_FLAGS_HAVE_TIMEZONE;
/* Validate */
if (!flags_chk_all(flags, NSC_COMPONENT_FLAGS__HAVE_ALL)) {
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=0637e4f5407bf431afdef346a846ddbec0262bf9
commit 0637e4f5407bf431afdef346a846ddbec0262bf9
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
Time: Add date string to time_t parser.
diff --git a/utils/time.c b/utils/time.c
index dd67d8a..667e836 100644
--- a/utils/time.c
+++ b/utils/time.c
@@ -25,17 +25,21 @@
* \brief Implementation of time operations.
*/
+#include <ctype.h>
#include <errno.h>
#include <stdio.h>
-#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#ifdef USE_CURL
#include <curl/curl.h>
+#endif
+#include "utils/ascii.h"
#include "utils/errors.h"
#include "utils/time.h"
-
/**
* Weekdays
*
@@ -181,6 +185,829 @@ nserror nsc_snptimet(const char *str, size_t size, time_t
*timep)
}
+#ifndef USE_CURL
+
+
+/**
+ * Array of long weekday names.
+ */
+const char * const weekdays_long[NSC_TIME_WEEKDAY__COUNT] = {
+ [NSC_TIME_WEEKDAY_SUN] = "Sunday",
+ [NSC_TIME_WEEKDAY_MON] = "Monday",
+ [NSC_TIME_WEEKDAY_TUE] = "Tuesday",
+ [NSC_TIME_WEEKDAY_WED] = "Wednesday",
+ [NSC_TIME_WEEKDAY_THU] = "Thursday",
+ [NSC_TIME_WEEKDAY_FRI] = "Friday",
+ [NSC_TIME_WEEKDAY_SAT] = "Saturday"
+};
+
+/**
+ * Timezone offsets in mins
+ *
+ * Order doesn't matter.
+ */
+enum nsc_time_zone_offsets {
+ /* Timezones */
+ NSC_TIME_ZONE_OFFSET_IDLE = -12 * 60,
+ NSC_TIME_ZONE_OFFSET_NZST = -12 * 60,
+ NSC_TIME_ZONE_OFFSET_NZT = -12 * 60,
+ NSC_TIME_ZONE_OFFSET_EAST = -10 * 60,
+ NSC_TIME_ZONE_OFFSET_GST = -10 * 60,
+ NSC_TIME_ZONE_OFFSET_JST = - 9 * 60,
+ NSC_TIME_ZONE_OFFSET_CCT = - 8 * 60,
+ NSC_TIME_ZONE_OFFSET_WAST = - 7 * 60,
+ NSC_TIME_ZONE_OFFSET_EET = - 2 * 60,
+ NSC_TIME_ZONE_OFFSET_CET = - 1 * 60,
+ NSC_TIME_ZONE_OFFSET_FWT = - 1 * 60,
+ NSC_TIME_ZONE_OFFSET_MET = - 1 * 60,
+ NSC_TIME_ZONE_OFFSET_MEWT = - 1 * 60,
+ NSC_TIME_ZONE_OFFSET_GMT = 0,
+ NSC_TIME_ZONE_OFFSET_UTC = 0,
+ NSC_TIME_ZONE_OFFSET_WET = 0,
+ NSC_TIME_ZONE_OFFSET_WAT = 1 * 60,
+ NSC_TIME_ZONE_OFFSET_AST = 4 * 60,
+ NSC_TIME_ZONE_OFFSET_EST = 5 * 60,
+ NSC_TIME_ZONE_OFFSET_CST = 6 * 60,
+ NSC_TIME_ZONE_OFFSET_MST = 7 * 60,
+ NSC_TIME_ZONE_OFFSET_PST = 8 * 60,
+ NSC_TIME_ZONE_OFFSET_YST = 9 * 60,
+ NSC_TIME_ZONE_OFFSET_AHST = 10 * 60,
+ NSC_TIME_ZONE_OFFSET_CAT = 10 * 60,
+ NSC_TIME_ZONE_OFFSET_HST = 10 * 60,
+ NSC_TIME_ZONE_OFFSET_IDLW = 12 * 60,
+
+ /* Daylight saving modified timezones */
+ NSC_TIME_ZONE_OFFSET_NZDT = NSC_TIME_ZONE_OFFSET_NZT - 60,
+ NSC_TIME_ZONE_OFFSET_EADT = NSC_TIME_ZONE_OFFSET_EAST - 60,
+ NSC_TIME_ZONE_OFFSET_WADT = NSC_TIME_ZONE_OFFSET_WAST - 60,
+ NSC_TIME_ZONE_OFFSET_CEST = NSC_TIME_ZONE_OFFSET_CET - 60,
+ NSC_TIME_ZONE_OFFSET_FST = NSC_TIME_ZONE_OFFSET_FWT - 60,
+ NSC_TIME_ZONE_OFFSET_MEST = NSC_TIME_ZONE_OFFSET_MET - 60,
+ NSC_TIME_ZONE_OFFSET_MESZ = NSC_TIME_ZONE_OFFSET_MET - 60,
+ NSC_TIME_ZONE_OFFSET_BST = NSC_TIME_ZONE_OFFSET_GMT - 60,
+ NSC_TIME_ZONE_OFFSET_ADT = NSC_TIME_ZONE_OFFSET_AST - 60,
+ NSC_TIME_ZONE_OFFSET_EDT = NSC_TIME_ZONE_OFFSET_EST - 60,
+ NSC_TIME_ZONE_OFFSET_CDT = NSC_TIME_ZONE_OFFSET_CST - 60,
+ NSC_TIME_ZONE_OFFSET_MDT = NSC_TIME_ZONE_OFFSET_MST - 60,
+ NSC_TIME_ZONE_OFFSET_PDT = NSC_TIME_ZONE_OFFSET_PST - 60,
+ NSC_TIME_ZONE_OFFSET_YDT = NSC_TIME_ZONE_OFFSET_YST - 60,
+ NSC_TIME_ZONE_OFFSET_HDT = NSC_TIME_ZONE_OFFSET_HST - 60,
+
+ /* Military timezones */
+ NSC_TIME_ZONE_OFFSET_Y = -12 * 60,
+ NSC_TIME_ZONE_OFFSET_X = -11 * 60,
+ NSC_TIME_ZONE_OFFSET_W = -10 * 60,
+ NSC_TIME_ZONE_OFFSET_V = - 9 * 60,
+ NSC_TIME_ZONE_OFFSET_U = - 8 * 60,
+ NSC_TIME_ZONE_OFFSET_T = - 7 * 60,
+ NSC_TIME_ZONE_OFFSET_S = - 6 * 60,
+ NSC_TIME_ZONE_OFFSET_R = - 5 * 60,
+ NSC_TIME_ZONE_OFFSET_Q = - 4 * 60,
+ NSC_TIME_ZONE_OFFSET_P = - 3 * 60,
+ NSC_TIME_ZONE_OFFSET_O = - 2 * 60,
+ NSC_TIME_ZONE_OFFSET_N = - 1 * 60,
+ NSC_TIME_ZONE_OFFSET_Z = 0 * 60,
+ NSC_TIME_ZONE_OFFSET_A = 1 * 60,
+ NSC_TIME_ZONE_OFFSET_B = 2 * 60,
+ NSC_TIME_ZONE_OFFSET_C = 3 * 60,
+ NSC_TIME_ZONE_OFFSET_D = 4 * 60,
+ NSC_TIME_ZONE_OFFSET_E = 5 * 60,
+ NSC_TIME_ZONE_OFFSET_F = 6 * 60,
+ NSC_TIME_ZONE_OFFSET_G = 7 * 60,
+ NSC_TIME_ZONE_OFFSET_H = 8 * 60,
+ NSC_TIME_ZONE_OFFSET_I = 9 * 60,
+ NSC_TIME_ZONE_OFFSET_K = 10 * 60,
+ NSC_TIME_ZONE_OFFSET_L = 11 * 60,
+ NSC_TIME_ZONE_OFFSET_M = 12 * 60,
+};
+
+/**
+ * List of timezones.
+ *
+ * The order here is the order they appear in the `timezone_mins` array.
+ * So there is value in putting the most common timezones first.
+ */
+enum nsc_time_zones {
+ NSC_TIME_ZONE_IDLE,
+ NSC_TIME_ZONE_NZST,
+ NSC_TIME_ZONE_NZT,
+ NSC_TIME_ZONE_EAST,
+ NSC_TIME_ZONE_GST,
+ NSC_TIME_ZONE_JST,
+ NSC_TIME_ZONE_CCT,
+ NSC_TIME_ZONE_WAST,
+ NSC_TIME_ZONE_EET,
+ NSC_TIME_ZONE_CET,
+ NSC_TIME_ZONE_FWT,
+ NSC_TIME_ZONE_MET,
+ NSC_TIME_ZONE_MEWT,
+ NSC_TIME_ZONE_GMT,
+ NSC_TIME_ZONE_UTC,
+ NSC_TIME_ZONE_WET,
+ NSC_TIME_ZONE_WAT,
+ NSC_TIME_ZONE_AST,
+ NSC_TIME_ZONE_EST,
+ NSC_TIME_ZONE_CST,
+ NSC_TIME_ZONE_MST,
+ NSC_TIME_ZONE_PST,
+ NSC_TIME_ZONE_YST,
+ NSC_TIME_ZONE_AHST,
+ NSC_TIME_ZONE_CAT,
+ NSC_TIME_ZONE_HST,
+ NSC_TIME_ZONE_IDLW,
+ NSC_TIME_ZONE_NZDT,
+ NSC_TIME_ZONE_EADT,
+ NSC_TIME_ZONE_WADT,
+ NSC_TIME_ZONE_CEST,
+ NSC_TIME_ZONE_FST,
+ NSC_TIME_ZONE_MEST,
+ NSC_TIME_ZONE_MESZ,
+ NSC_TIME_ZONE_BST,
+ NSC_TIME_ZONE_ADT,
+ NSC_TIME_ZONE_EDT,
+ NSC_TIME_ZONE_CDT,
+ NSC_TIME_ZONE_MDT,
+ NSC_TIME_ZONE_PDT,
+ NSC_TIME_ZONE_YDT,
+ NSC_TIME_ZONE_HDT,
+ NSC_TIME_ZONE_Y,
+ NSC_TIME_ZONE_X,
+ NSC_TIME_ZONE_W,
+ NSC_TIME_ZONE_V,
+ NSC_TIME_ZONE_U,
+ NSC_TIME_ZONE_T,
+ NSC_TIME_ZONE_S,
+ NSC_TIME_ZONE_R,
+ NSC_TIME_ZONE_Q,
+ NSC_TIME_ZONE_P,
+ NSC_TIME_ZONE_O,
+ NSC_TIME_ZONE_N,
+ NSC_TIME_ZONE_Z,
+ NSC_TIME_ZONE_A,
+ NSC_TIME_ZONE_B,
+ NSC_TIME_ZONE_C,
+ NSC_TIME_ZONE_D,
+ NSC_TIME_ZONE_E,
+ NSC_TIME_ZONE_F,
+ NSC_TIME_ZONE_G,
+ NSC_TIME_ZONE_H,
+ NSC_TIME_ZONE_I,
+ NSC_TIME_ZONE_K,
+ NSC_TIME_ZONE_L,
+ NSC_TIME_ZONE_M,
+ NSC_TIME_ZONE__COUNT
+};
+
+/**
+ * Array of minute offsets for timezones.
+ */
+const int16_t timezone_mins[NSC_TIME_ZONE__COUNT] = {
+ [NSC_TIME_ZONE_IDLE] = NSC_TIME_ZONE_OFFSET_IDLE,
+ [NSC_TIME_ZONE_NZST] = NSC_TIME_ZONE_OFFSET_NZST,
+ [NSC_TIME_ZONE_NZT] = NSC_TIME_ZONE_OFFSET_NZT,
+ [NSC_TIME_ZONE_EAST] = NSC_TIME_ZONE_OFFSET_EAST,
+ [NSC_TIME_ZONE_GST] = NSC_TIME_ZONE_OFFSET_GST,
+ [NSC_TIME_ZONE_JST] = NSC_TIME_ZONE_OFFSET_JST,
+ [NSC_TIME_ZONE_CCT] = NSC_TIME_ZONE_OFFSET_CCT,
+ [NSC_TIME_ZONE_WAST] = NSC_TIME_ZONE_OFFSET_WAST,
+ [NSC_TIME_ZONE_EET] = NSC_TIME_ZONE_OFFSET_EET,
+ [NSC_TIME_ZONE_CET] = NSC_TIME_ZONE_OFFSET_CET,
+ [NSC_TIME_ZONE_FWT] = NSC_TIME_ZONE_OFFSET_FWT,
+ [NSC_TIME_ZONE_MET] = NSC_TIME_ZONE_OFFSET_MET,
+ [NSC_TIME_ZONE_MEWT] = NSC_TIME_ZONE_OFFSET_MEWT,
+ [NSC_TIME_ZONE_GMT] = NSC_TIME_ZONE_OFFSET_GMT,
+ [NSC_TIME_ZONE_UTC] = NSC_TIME_ZONE_OFFSET_UTC,
+ [NSC_TIME_ZONE_WET] = NSC_TIME_ZONE_OFFSET_WET,
+ [NSC_TIME_ZONE_WAT] = NSC_TIME_ZONE_OFFSET_WAT,
+ [NSC_TIME_ZONE_AST] = NSC_TIME_ZONE_OFFSET_AST,
+ [NSC_TIME_ZONE_EST] = NSC_TIME_ZONE_OFFSET_EST,
+ [NSC_TIME_ZONE_CST] = NSC_TIME_ZONE_OFFSET_CST,
+ [NSC_TIME_ZONE_MST] = NSC_TIME_ZONE_OFFSET_MST,
+ [NSC_TIME_ZONE_PST] = NSC_TIME_ZONE_OFFSET_PST,
+ [NSC_TIME_ZONE_YST] = NSC_TIME_ZONE_OFFSET_YST,
+ [NSC_TIME_ZONE_AHST] = NSC_TIME_ZONE_OFFSET_AHST,
+ [NSC_TIME_ZONE_CAT] = NSC_TIME_ZONE_OFFSET_CAT,
+ [NSC_TIME_ZONE_HST] = NSC_TIME_ZONE_OFFSET_HST,
+ [NSC_TIME_ZONE_IDLW] = NSC_TIME_ZONE_OFFSET_IDLW,
+ [NSC_TIME_ZONE_NZDT] = NSC_TIME_ZONE_OFFSET_NZDT,
+ [NSC_TIME_ZONE_EADT] = NSC_TIME_ZONE_OFFSET_EADT,
+ [NSC_TIME_ZONE_WADT] = NSC_TIME_ZONE_OFFSET_WADT,
+ [NSC_TIME_ZONE_CEST] = NSC_TIME_ZONE_OFFSET_CEST,
+ [NSC_TIME_ZONE_FST] = NSC_TIME_ZONE_OFFSET_FST,
+ [NSC_TIME_ZONE_MEST] = NSC_TIME_ZONE_OFFSET_MEST,
+ [NSC_TIME_ZONE_MESZ] = NSC_TIME_ZONE_OFFSET_MESZ,
+ [NSC_TIME_ZONE_BST] = NSC_TIME_ZONE_OFFSET_BST,
+ [NSC_TIME_ZONE_ADT] = NSC_TIME_ZONE_OFFSET_ADT,
+ [NSC_TIME_ZONE_EDT] = NSC_TIME_ZONE_OFFSET_EDT,
+ [NSC_TIME_ZONE_CDT] = NSC_TIME_ZONE_OFFSET_CDT,
+ [NSC_TIME_ZONE_MDT] = NSC_TIME_ZONE_OFFSET_MDT,
+ [NSC_TIME_ZONE_PDT] = NSC_TIME_ZONE_OFFSET_PDT,
+ [NSC_TIME_ZONE_YDT] = NSC_TIME_ZONE_OFFSET_YDT,
+ [NSC_TIME_ZONE_HDT] = NSC_TIME_ZONE_OFFSET_HDT,
+ [NSC_TIME_ZONE_Y] = NSC_TIME_ZONE_OFFSET_Y,
+ [NSC_TIME_ZONE_X] = NSC_TIME_ZONE_OFFSET_X,
+ [NSC_TIME_ZONE_W] = NSC_TIME_ZONE_OFFSET_W,
+ [NSC_TIME_ZONE_V] = NSC_TIME_ZONE_OFFSET_V,
+ [NSC_TIME_ZONE_U] = NSC_TIME_ZONE_OFFSET_U,
+ [NSC_TIME_ZONE_T] = NSC_TIME_ZONE_OFFSET_T,
+ [NSC_TIME_ZONE_S] = NSC_TIME_ZONE_OFFSET_S,
+ [NSC_TIME_ZONE_R] = NSC_TIME_ZONE_OFFSET_R,
+ [NSC_TIME_ZONE_Q] = NSC_TIME_ZONE_OFFSET_Q,
+ [NSC_TIME_ZONE_P] = NSC_TIME_ZONE_OFFSET_P,
+ [NSC_TIME_ZONE_O] = NSC_TIME_ZONE_OFFSET_O,
+ [NSC_TIME_ZONE_N] = NSC_TIME_ZONE_OFFSET_N,
+ [NSC_TIME_ZONE_Z] = NSC_TIME_ZONE_OFFSET_Z,
+ [NSC_TIME_ZONE_A] = NSC_TIME_ZONE_OFFSET_A,
+ [NSC_TIME_ZONE_B] = NSC_TIME_ZONE_OFFSET_B,
+ [NSC_TIME_ZONE_C] = NSC_TIME_ZONE_OFFSET_C,
+ [NSC_TIME_ZONE_D] = NSC_TIME_ZONE_OFFSET_D,
+ [NSC_TIME_ZONE_E] = NSC_TIME_ZONE_OFFSET_E,
+ [NSC_TIME_ZONE_F] = NSC_TIME_ZONE_OFFSET_F,
+ [NSC_TIME_ZONE_G] = NSC_TIME_ZONE_OFFSET_G,
+ [NSC_TIME_ZONE_H] = NSC_TIME_ZONE_OFFSET_H,
+ [NSC_TIME_ZONE_I] = NSC_TIME_ZONE_OFFSET_I,
+ [NSC_TIME_ZONE_K] = NSC_TIME_ZONE_OFFSET_K,
+ [NSC_TIME_ZONE_L] = NSC_TIME_ZONE_OFFSET_L,
+ [NSC_TIME_ZONE_M] = NSC_TIME_ZONE_OFFSET_M
+};
+
+/**
+ * Array of timezone names. Order does not matter.
+ */
+const char * const timezones[NSC_TIME_ZONE__COUNT] = {
+ [NSC_TIME_ZONE_IDLE] = "IDLE",
+ [NSC_TIME_ZONE_NZST] = "NZST",
+ [NSC_TIME_ZONE_NZT] = "NZT",
+ [NSC_TIME_ZONE_EAST] = "EAST",
+ [NSC_TIME_ZONE_GST] = "GST",
+ [NSC_TIME_ZONE_JST] = "JST",
+ [NSC_TIME_ZONE_CCT] = "CCT",
+ [NSC_TIME_ZONE_WAST] = "WAST",
+ [NSC_TIME_ZONE_EET] = "EET",
+ [NSC_TIME_ZONE_CET] = "CET",
+ [NSC_TIME_ZONE_FWT] = "FWT",
+ [NSC_TIME_ZONE_MET] = "MET",
+ [NSC_TIME_ZONE_MEWT] = "MEWT",
+ [NSC_TIME_ZONE_GMT] = "GMT",
+ [NSC_TIME_ZONE_UTC] = "UTC",
+ [NSC_TIME_ZONE_WET] = "WET",
+ [NSC_TIME_ZONE_WAT] = "WAT",
+ [NSC_TIME_ZONE_AST] = "AST",
+ [NSC_TIME_ZONE_EST] = "EST",
+ [NSC_TIME_ZONE_CST] = "CST",
+ [NSC_TIME_ZONE_MST] = "MST",
+ [NSC_TIME_ZONE_PST] = "PST",
+ [NSC_TIME_ZONE_YST] = "YST",
+ [NSC_TIME_ZONE_AHST] = "AHST",
+ [NSC_TIME_ZONE_CAT] = "CAT",
+ [NSC_TIME_ZONE_HST] = "HST",
+ [NSC_TIME_ZONE_IDLW] = "IDLW",
+ [NSC_TIME_ZONE_NZDT] = "NZDT",
+ [NSC_TIME_ZONE_EADT] = "EADT",
+ [NSC_TIME_ZONE_WADT] = "WADT",
+ [NSC_TIME_ZONE_CEST] = "CEST",
+ [NSC_TIME_ZONE_FST] = "FST",
+ [NSC_TIME_ZONE_MEST] = "MEST",
+ [NSC_TIME_ZONE_MESZ] = "MESZ",
+ [NSC_TIME_ZONE_BST] = "BST",
+ [NSC_TIME_ZONE_ADT] = "ADT",
+ [NSC_TIME_ZONE_EDT] = "EDT",
+ [NSC_TIME_ZONE_CDT] = "CDT",
+ [NSC_TIME_ZONE_MDT] = "MDT",
+ [NSC_TIME_ZONE_PDT] = "PDT",
+ [NSC_TIME_ZONE_YDT] = "YDT",
+ [NSC_TIME_ZONE_HDT] = "HDT",
+ [NSC_TIME_ZONE_Y] = "Y",
+ [NSC_TIME_ZONE_X] = "X",
+ [NSC_TIME_ZONE_W] = "W",
+ [NSC_TIME_ZONE_V] = "V",
+ [NSC_TIME_ZONE_U] = "U",
+ [NSC_TIME_ZONE_T] = "T",
+ [NSC_TIME_ZONE_S] = "S",
+ [NSC_TIME_ZONE_R] = "R",
+ [NSC_TIME_ZONE_Q] = "Q",
+ [NSC_TIME_ZONE_P] = "P",
+ [NSC_TIME_ZONE_O] = "O",
+ [NSC_TIME_ZONE_N] = "N",
+ [NSC_TIME_ZONE_Z] = "Z",
+ [NSC_TIME_ZONE_A] = "A",
+ [NSC_TIME_ZONE_B] = "B",
+ [NSC_TIME_ZONE_C] = "C",
+ [NSC_TIME_ZONE_D] = "D",
+ [NSC_TIME_ZONE_E] = "E",
+ [NSC_TIME_ZONE_F] = "F",
+ [NSC_TIME_ZONE_G] = "G",
+ [NSC_TIME_ZONE_H] = "H",
+ [NSC_TIME_ZONE_I] = "I",
+ [NSC_TIME_ZONE_K] = "K",
+ [NSC_TIME_ZONE_L] = "L",
+ [NSC_TIME_ZONE_M] = "M"
+};
+
+/**
+ * Flags for tracking the components of a date that have been parsed.
+ */
+enum nsc_date_component_flags {
+ NSC_COMPONENT_FLAGS_NONE = 0,
+ NSC_COMPONENT_FLAGS_HAVE_YEARS = (1 << 0),
+ NSC_COMPONENT_FLAGS_HAVE_MONTHS = (1 << 1),
+ NSC_COMPONENT_FLAGS_HAVE_DAYS = (1 << 2),
+ NSC_COMPONENT_FLAGS_HAVE_HOURS = (1 << 3),
+ NSC_COMPONENT_FLAGS_HAVE_MINS = (1 << 4),
+ NSC_COMPONENT_FLAGS_HAVE_SECS = (1 << 5),
+ NSC_COMPONENT_FLAGS_HAVE_TIMEZONE = (1 << 6),
+ NSC_COMPONENT_FLAGS_HAVE_WEEKDAY = (1 << 7),
+ NSC_COMPONENT_FLAGS__HAVE_YYYYMMDD =
+ NSC_COMPONENT_FLAGS_HAVE_YEARS |
+ NSC_COMPONENT_FLAGS_HAVE_MONTHS |
+ NSC_COMPONENT_FLAGS_HAVE_DAYS,
+ NSC_COMPONENT_FLAGS__HAVE_HHMMSS =
+ NSC_COMPONENT_FLAGS_HAVE_HOURS |
+ NSC_COMPONENT_FLAGS_HAVE_MINS |
+ NSC_COMPONENT_FLAGS_HAVE_SECS,
+ NSC_COMPONENT_FLAGS__HAVE_ALL =
+ NSC_COMPONENT_FLAGS_HAVE_YEARS |
+ NSC_COMPONENT_FLAGS_HAVE_MONTHS |
+ NSC_COMPONENT_FLAGS_HAVE_DAYS |
+ NSC_COMPONENT_FLAGS_HAVE_HOURS |
+ NSC_COMPONENT_FLAGS_HAVE_MINS |
+ NSC_COMPONENT_FLAGS_HAVE_SECS |
+ NSC_COMPONENT_FLAGS_HAVE_TIMEZONE
+};
+
+/**
+ * Context for date parsing.
+ */
+struct nsc_date_parse_ctx {
+ enum {
+ PARSE_STATE_NONE,
+ PARSE_STATE_HAD_PLUS,
+ PARSE_STATE_HAD_MINUS
+ } state; /**< Used for handling neumenrical timezone */
+ uint8_t secs;
+ uint8_t mins;
+ uint8_t hours;
+ uint8_t day;
+ uint8_t month;
+ uint16_t years;
+ int16_t timezone_offset_mins;
+};
+
+
+/**
+ * Helper for testing whether any of the flags in mask are set.
+ *
+ * \param[in] flags Flags to to check.
+ * \param[in] mask The set of flags to check for in `flags`.
+ * \return true iff any flags in `mask` are set in `flags`, else false.
+ */
+static bool flags_chk(
+ enum nsc_date_component_flags flags,
+ enum nsc_date_component_flags mask)
+{
+ return flags & mask;
+}
+
+/**
+ * Helper for testing whether all of the flags in mask are set.
+ *
+ * \param[in] flags Flags to to check.
+ * \param[in] mask The set of flags to check for in `flags`.
+ * \return true iff all flags in `mask` are set in `flags`, else false.
+ */
+static bool flags_chk_all(
+ enum nsc_date_component_flags flags,
+ enum nsc_date_component_flags mask)
+{
+ return (flags & mask) == mask;
+}
+
+
+/**
+ * Test for a weekday name in a string (case insensitive).
+ *
+ * \param[in] str String to parse a weekday name in.
+ * \param[in,out] flags Flags indicating which date components have been
+ * found in `str` already. If a weekday component
+ * is found, the weekday flag is set.
+ * \param[in] len Number of consecutive alphabetical characters.
+ * \return true iff weekday component is found, else false.
+ */
+static inline bool time__parse_weekday(
+ const char *str,
+ enum nsc_date_component_flags *flags,
+ size_t len)
+{
+ const char * const *names = (len == 3) ?
+ weekdays_short : weekdays_long;
+
+ if (flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_WEEKDAY)) {
+ return false;
+ }
+
+ for (uint32_t i = 0; i < NSC_TIME_WEEKDAY__COUNT; i++) {
+ if (ascii_strings_equal_caseless(names[i], str)) {
+ *flags |= NSC_COMPONENT_FLAGS_HAVE_WEEKDAY;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/**
+ * Attempt to parse a month name in a string (case insensitive).
+ *
+ * \param[in] str String to parse a month name in.
+ * \param[in,out] flags Flags indicating which date components have been
+ * found in `str` already. If a month component
+ * is found, the month flag is set.
+ * \param[in,out] ctx Current date parsing context. If month component
+ * is found, the context's month value is set.
+ * \return true iff month name component is found, else false.
+ */
+static inline bool time__parse_month(
+ const char *str,
+ enum nsc_date_component_flags *flags,
+ struct nsc_date_parse_ctx *ctx)
+{
+ if (flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_MONTHS)) {
+ return false;
+ }
+
+ for (uint32_t i = 0; i < NSC_TIME_MONTH__COUNT; i++) {
+ if (ascii_strings_equal_caseless(months[i], str)) {
+ *flags |= NSC_COMPONENT_FLAGS_HAVE_MONTHS;
+ ctx->month = i;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/**
+ * Attempt to parse a timezone name in a string (case insensitive).
+ *
+ * \param[in] str String to parse a timezone name in.
+ * \param[in,out] flags Flags indicating which date components have been
+ * found in `str` already. If a timezone component
+ * is found, the timezone flag is set.
+ * \param[in,out] ctx Current date parsing context. If timezone component
+ * is found, the context's timezone value is set.
+ * \return true iff timezone name component is found, else false.
+ */
+static inline bool time__parse_timezone(
+ const char *str,
+ enum nsc_date_component_flags *flags,
+ struct nsc_date_parse_ctx *ctx)
+{
+ if (flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_TIMEZONE)) {
+ return false;
+ }
+
+ for (uint32_t i = 0; i < NSC_TIME_ZONE__COUNT; i++) {
+ if (ascii_strings_equal_caseless(timezones[i], str)) {
+ *flags |= NSC_COMPONENT_FLAGS_HAVE_TIMEZONE;
+ ctx->timezone_offset_mins = timezone_mins[i];
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/**
+ * Attempt to parse an "hh:mm:ss" time from a string.
+ *
+ * \param[in] str String to parse a time in.
+ * \param[in,out] flags Flags indicating which date components have been
+ * found in `str` already. If a time component
+ * is found, the hours, mins and secs flags are set.
+ * \param[in,out] ctx Current date parsing context. If time component
+ * is found, the context's time values are set.
+ * \param[in,out] len The number of characters until the first non-digit.
+ * Iff a time component is found, updated to the number
+ * of comsumend characters.
+ * \return true iff time component is found, else false.
+ */
+static inline bool time__parse_hh_mm_ss(
+ const char *str,
+ enum nsc_date_component_flags *flags,
+ struct nsc_date_parse_ctx *ctx,
+ size_t *len)
+{
+ size_t l;
+
+ if (*len != 2 || flags_chk(*flags, NSC_COMPONENT_FLAGS__HAVE_HHMMSS)) {
+ return false;
+ }
+
+ l = *len + ascii_count_digit_or_colon(str + *len);
+ if (l == 8) {
+ int h, m, s, count;
+ count = sscanf(str, "%02d:%02d:%02d", &h, &m, &s);
+ if (count == 3) {
+ ctx->hours = h;
+ ctx->mins = m;
+ ctx->secs = s;
+ *flags |= NSC_COMPONENT_FLAGS__HAVE_HHMMSS;
+ *len = l;
+ return true;
+ }
+ } else if (l == 5) {
+ int h, m, count;
+ count = sscanf(str, "%02d:%02d", &h, &m);
+ if (count == 2) {
+ ctx->hours = h;
+ ctx->mins = m;
+ ctx->secs = 0;
+ *flags |= NSC_COMPONENT_FLAGS__HAVE_HHMMSS;
+ *len = l;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/**
+ * Attempt to parse a number from a date string.
+ *
+ * How the number is treated depends on various things:
+ *
+ * - its character length,
+ * - its value,
+ * - which date components have already been parsed
+ *
+ * \param[in] str String to parse a time in.
+ * \param[in,out] flags Flags indicating which date components have been
+ * found in `str` already. If any component is found,
+ * their flags are set.
+ * \param[in,out] ctx Current date parsing context. If any component
+ * is found, the appropriate context values are set.
+ * \param[in] len The number of characters until the first non-digit.
+ * \return true iff a component is found, else false.
+ */
+static inline bool time__parse_number(
+ const char *str,
+ enum nsc_date_component_flags *flags,
+ struct nsc_date_parse_ctx *ctx,
+ size_t len)
+{
+ int value;
+
+ if (len != ascii_string_to_int(str, &value)) {
+ return false;
+ }
+
+ switch (len) {
+ case 8:
+ if (!flags_chk(*flags, NSC_COMPONENT_FLAGS__HAVE_YYYYMMDD)) {
+ ctx->years = value / 10000;
+ ctx->month = (value % 10000) / 100 - 1;
+ ctx->day = value % 100 - 1;
+ *flags |= NSC_COMPONENT_FLAGS__HAVE_YYYYMMDD;
+ return true;
+ }
+ break;
+
+ case 4:
+ if (!flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_TIMEZONE)) {
+ if (ctx->state != PARSE_STATE_NONE &&
+ value <= 1400) {
+ ctx->timezone_offset_mins =
+ value / 100 * 60 +
+ value % 100;
+ if (ctx->state == PARSE_STATE_HAD_MINUS) {
+ ctx->timezone_offset_mins *= -1;
+ }
+ *flags |= NSC_COMPONENT_FLAGS_HAVE_TIMEZONE;
+ return true;
+ }
+ }
+ if (!flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_YEARS)) {
+ ctx->years = value;
+ *flags |= NSC_COMPONENT_FLAGS_HAVE_YEARS;
+ return true;
+ }
+ break;
+
+ case 2:
+ if (!flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_DAYS) &&
+ value <= 31) {
+ ctx->day = value - 1;
+ *flags |= NSC_COMPONENT_FLAGS_HAVE_DAYS;
+ return true;
+ }
+ if (!flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_YEARS)) {
+ ctx->years = (value > 70) ?
+ value + 1900 :
+ value + 2000;
+ *flags |= NSC_COMPONENT_FLAGS_HAVE_YEARS;
+ return true;
+ }
+ break;
+
+ case 1:
+ if (!flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_DAYS)) {
+ ctx->day = value - 1;
+ *flags |= NSC_COMPONENT_FLAGS_HAVE_DAYS;
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+/**
+ * Get number of leap days up until end of given year.
+ *
+ * \param[in] year Year to count leap years up to.
+ * \return Number of leap days up to end of `year`.
+ */
+static inline int time__get_leap_days(int year)
+{
+ return (year / 4) - (year / 100) + (year / 400);
+}
+
+
+/**
+ * Helper to convert a date string context to a time_t.
+ *
+ * \param[in] ctx Current date parsing context.
+ * \param[in] flags Flags indicating which date components have been set.
+ * \param[out] time Returns the number of seconds since 1 Jan 1970 00:00 UTC.
+ * \return NSERROR_OK on success, appropriate error otherwise.
+ */
+static nserror time__ctx_to_time_t(
+ const struct nsc_date_parse_ctx *ctx,
+ enum nsc_date_component_flags flags,
+ time_t *time)
+{
+ enum {
+ NSC_MONTH_DAYS_JAN = 31,
+ NSC_MONTH_DAYS_FEB = 28, /**< Leap years handled separatly */
+ NSC_MONTH_DAYS_MAR = 31,
+ NSC_MONTH_DAYS_APR = 30,
+ NSC_MONTH_DAYS_MAY = 31,
+ NSC_MONTH_DAYS_JUN = 30,
+ NSC_MONTH_DAYS_JUL = 31,
+ NSC_MONTH_DAYS_AUG = 31,
+ NSC_MONTH_DAYS_SEP = 30,
+ NSC_MONTH_DAYS_OCT = 31,
+ NSC_MONTH_DAYS_NOV = 30,
+ NSC_MONTH_DAYS_DEC = 31
+ };
+ enum {
+ NSC_MONTH_OFF_JAN = 0,
+ NSC_MONTH_OFF_FEB = NSC_MONTH_OFF_JAN + NSC_MONTH_DAYS_JAN,
+ NSC_MONTH_OFF_MAR = NSC_MONTH_OFF_FEB + NSC_MONTH_DAYS_FEB,
+ NSC_MONTH_OFF_APR = NSC_MONTH_OFF_MAR + NSC_MONTH_DAYS_MAR,
+ NSC_MONTH_OFF_MAY = NSC_MONTH_OFF_APR + NSC_MONTH_DAYS_APR,
+ NSC_MONTH_OFF_JUN = NSC_MONTH_OFF_MAY + NSC_MONTH_DAYS_MAY,
+ NSC_MONTH_OFF_JUL = NSC_MONTH_OFF_JUN + NSC_MONTH_DAYS_JUN,
+ NSC_MONTH_OFF_AUG = NSC_MONTH_OFF_JUL + NSC_MONTH_DAYS_JUL,
+ NSC_MONTH_OFF_SEP = NSC_MONTH_OFF_AUG + NSC_MONTH_DAYS_AUG,
+ NSC_MONTH_OFF_OCT = NSC_MONTH_OFF_SEP + NSC_MONTH_DAYS_SEP,
+ NSC_MONTH_OFF_NOV = NSC_MONTH_OFF_OCT + NSC_MONTH_DAYS_OCT,
+ NSC_MONTH_OFF_DEC = NSC_MONTH_OFF_NOV + NSC_MONTH_DAYS_NOV
+ };
+ static const uint16_t month_offsets[NSC_TIME_MONTH__COUNT] = {
+ [NSC_TIME_MONTH_JAN] = NSC_MONTH_OFF_JAN,
+ [NSC_TIME_MONTH_FEB] = NSC_MONTH_OFF_FEB,
+ [NSC_TIME_MONTH_MAR] = NSC_MONTH_OFF_MAR,
+ [NSC_TIME_MONTH_APR] = NSC_MONTH_OFF_APR,
+ [NSC_TIME_MONTH_MAY] = NSC_MONTH_OFF_MAY,
+ [NSC_TIME_MONTH_JUN] = NSC_MONTH_OFF_JUN,
+ [NSC_TIME_MONTH_JUL] = NSC_MONTH_OFF_JUL,
+ [NSC_TIME_MONTH_AUG] = NSC_MONTH_OFF_AUG,
+ [NSC_TIME_MONTH_SEP] = NSC_MONTH_OFF_SEP,
+ [NSC_TIME_MONTH_OCT] = NSC_MONTH_OFF_OCT,
+ [NSC_TIME_MONTH_NOV] = NSC_MONTH_OFF_NOV,
+ [NSC_TIME_MONTH_DEC] = NSC_MONTH_OFF_DEC
+ };
+ int year_days = (ctx->years - 1970) * 365;
+ int month_days = month_offsets[ctx->month];
+ int year = (ctx->month < NSC_TIME_MONTH_FEB) ?
+ ctx->years - 1 : ctx->years;
+ int leap_days = time__get_leap_days(year) - time__get_leap_days(1969);
+ int total_days = year_days + month_days + ctx->day + leap_days;
+
+ int mins = (int)ctx->mins + (int)ctx->timezone_offset_mins;
+
+ *time = (((((time_t)(total_days)) * 24) +
+ ctx->hours) * 60 +
+ mins) * 60 +
+ ctx->secs;
+ return NSERROR_OK;
+}
+
+
+/**
+ * Parse a date string to a `time_t`.
+ *
+ * \param[in] str String to parse.
+ * \param[out] time Returns the number of seconds since 1 Jan 1970 00:00 UTC.
+ * \return `NSERROR_OK` on success, else
+ * `NSERROR_INVALID` if the string parsing failed,
+ * appropriate error otherwise.
+ */
+static nserror time__get_date(const char *str, time_t *time)
+{
+ enum nsc_date_component_flags flags = NSC_COMPONENT_FLAGS_NONE;
+ struct nsc_date_parse_ctx ctx = {
+ .state = PARSE_STATE_NONE,
+ .secs = 0,
+ .mins = 0,
+ .hours = 0,
+ .day = 0,
+ .month = 0,
+ .years = 0,
+ .timezone_offset_mins = 0
+ };
+
+ if (str == NULL || *str == '\0' || time == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ /* Parse */
+ while (*str != '\0' &&
+ !flags_chk_all(flags, NSC_COMPONENT_FLAGS__HAVE_ALL)) {
+
+ if (isspace(*str)) {
+ str++;
+
+ } else if (ascii_is_alpha(*str)) {
+ size_t len = ascii_count_alpha(str + 1) + 1;
+
+ if (!time__parse_weekday(str, &flags, len) &&
+ !time__parse_month(str, &flags, &ctx) &&
+ !time__parse_timezone(str, &flags, &ctx)) {
+ return NSERROR_INVALID;
+ }
+
+ str += len;
+
+ } else if (ascii_is_digit(*str)) {
+ size_t len = ascii_count_digit(str + 1) + 1;
+
+ if (!time__parse_hh_mm_ss(str, &flags, &ctx, &len) &&
+ !time__parse_number(str, &flags, &ctx, len)) {
+ return NSERROR_INVALID;
+ }
+
+ str += len;
+
+ } else if (*str == '+') {
+ ctx.state = PARSE_STATE_HAD_PLUS;
+ str++;
+ continue;
+
+ } else if (*str == '-') {
+ ctx.state = PARSE_STATE_HAD_MINUS;
+ str++;
+ continue;
+
+ } else {
+ str++;
+ }
+
+ ctx.state = PARSE_STATE_NONE;
+ }
+
+ /* The initial values of 0 are used if hours, mins, secs not found */
+ flags |= NSC_COMPONENT_FLAGS__HAVE_HHMMSS;
+
+ /* Validate */
+ if (!flags_chk_all(flags, NSC_COMPONENT_FLAGS__HAVE_ALL)) {
+ return NSERROR_INVALID;
+ }
+ if (ctx.secs > 60 || ctx.mins > 59 || ctx.hours > 23 ||
+ ctx.day > 31 || ctx.month > 11) {
+ return NSERROR_INVALID;
+ }
+
+ /* Convert */
+ return time__ctx_to_time_t(&ctx, flags, time);
+}
+
+/* exported function documented in utils/time.h */
+nserror nsc_strntimet(const char *str, size_t size, time_t *timep)
+{
+ return time__get_date(str, timep);
+}
+
+# else
+
/* exported function documented in utils/time.h */
nserror nsc_strntimet(const char *str, size_t size, time_t *timep)
{
@@ -196,3 +1023,5 @@ nserror nsc_strntimet(const char *str, size_t size, time_t
*timep)
return NSERROR_OK;
}
+
+#endif
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=b943261af1f0c4707d24e646ccb833d530707c1f
commit b943261af1f0c4707d24e646ccb833d530707c1f
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
Utils: Add a set of ASCII string parsing helpers.
These are not affected by the current locale.
diff --git a/utils/ascii.h b/utils/ascii.h
new file mode 100644
index 0000000..ca26999
--- /dev/null
+++ b/utils/ascii.h
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2016 Michael Drake <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file utils/ascii.h
+ * \brief Helpers for ASCII string handling.
+ *
+ * These helpers for string parsing will have the correct effect for parsing
+ * ASCII text (as used by most web specs), regardless of system locale.
+ */
+
+#ifndef _NETSURF_UTILS_ASCII_H_
+#define _NETSURF_UTILS_ASCII_H_
+
+#include <stdlib.h>
+#include <limits.h>
+
+/**
+ * Test whether a character is lower-case alphabetical.
+ *
+ * \param[in] c Character to test.
+ * \return true iff `c` is lower-case alphabetical, else false.
+ */
+static inline bool ascii_is_alpha_lower(char c)
+{
+ return (c >= 'a' && c <= 'z');
+}
+
+/**
+ * Test whether a character is upper-case alphabetical.
+ *
+ * \param[in] c Character to test.
+ * \return true iff `c` is upper-case alphabetical, else false.
+ */
+static inline bool ascii_is_alpha_upper(char c)
+{
+ return (c >= 'A' && c <= 'Z');
+}
+
+/**
+ * Test whether a character is alphabetical (upper or lower case).
+ *
+ * \param[in] c Character to test.
+ * \return true iff `c` is alphabetical, else false.
+ */
+static inline bool ascii_is_alpha(char c)
+{
+ return (ascii_is_alpha_lower(c) || ascii_is_alpha_upper(c));
+}
+
+/**
+ * Test whether a character is a decimal digit.
+ *
+ * \param[in] c Character to test.
+ * \return true iff `c` is a decimal digit, else false.
+ */
+static inline bool ascii_is_digit(char c)
+{
+ return (c >= '0' && c <= '9');
+}
+
+/**
+ * Convert an upper case character to lower case.
+ *
+ * If the given character is not upper case alphabetical, it is returned
+ * unchanged.
+ *
+ * \param[in] c Character to convert.
+ * \return lower case conversion of `c` else `c`.
+ */
+static inline char ascii_to_lower(char c)
+{
+ return (ascii_is_alpha_upper(c)) ? (c + 'a' - 'A') : c;
+}
+
+/**
+ * Convert a lower case character to upper case.
+ *
+ * If the given character is not lower case alphabetical, it is returned
+ * unchanged.
+ *
+ * \param[in] c Character to convert.
+ * \return upper case conversion of `c` else `c`.
+ */
+static inline char ascii_to_upper(char c)
+{
+ return (ascii_is_alpha_lower(c)) ? (c + 'A' - 'a') : c;
+}
+
+/**
+ * Count consecutive lower case alphabetical characters in string.
+ *
+ * \param[in] str String to count characters in.
+ * \return number of consecutive lower case characters at start of `str`.
+ */
+static inline size_t ascii_count_alpha_lower(const char *str)
+{
+ size_t count = 0;
+ while (ascii_is_alpha_lower(*(str++))) {
+ count++;
+ }
+ return count;
+}
+
+/**
+ * Count consecutive upper case alphabetical characters in string.
+ *
+ * \param[in] str String to count characters in.
+ * \return number of consecutive upper case characters at start of `str`.
+ */
+static inline size_t ascii_count_alpha_upper(const char *str)
+{
+ size_t count = 0;
+ while (ascii_is_alpha_upper(*(str++))) {
+ count++;
+ }
+ return count;
+}
+
+/**
+ * Count consecutive alphabetical characters in string (upper or lower case).
+ *
+ * \param[in] str String to count characters in.
+ * \return number of consecutive alphabetical characters at start of `str`.
+ */
+static inline size_t ascii_count_alpha(const char *str)
+{
+ size_t count = 0;
+ while (ascii_is_alpha(*(str++))) {
+ count++;
+ }
+ return count;
+}
+
+/**
+ * Count consecutive decial digit characters in string.
+ *
+ * \param[in] str String to count characters in.
+ * \return number of consecutive decimal digit characters at start of `str`.
+ */
+static inline size_t ascii_count_digit(const char *str)
+{
+ size_t count = 0;
+ while (ascii_is_digit(*(str++))) {
+ count++;
+ }
+ return count;
+}
+
+/**
+ * Count consecutive characters either decimal digit or colon in string.
+ *
+ * \param[in] str String to count characters in.
+ * \return number of consecutive decimal or ':' characters at start of `str`.
+ */
+static inline size_t ascii_count_digit_or_colon(const char *str)
+{
+ size_t count = 0;
+ while (ascii_is_digit(*str) || *str == ':') {
+ count++;
+ str++;
+ }
+ return count;
+}
+
+/**
+ * Test for string equality (case insensitive).
+ *
+ * \param[in] s1 First string to compare.
+ * \param[in] s2 Second string to compare.
+ * \return true iff strings are equivalent, else false.
+ */
+static inline bool ascii_strings_equal_caseless(
+ const char *s1, const char *s2)
+{
+ while (*s1 != '\0') {
+ if (ascii_to_lower(*(s1++)) != ascii_to_lower(*(s2++))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
+ * Test for string equality (case sensitive).
+ *
+ * \param[in] s1 First string to compare.
+ * \param[in] s2 Second string to compare.
+ * \return true iff strings are equal, else false.
+ */
+static inline bool ascii_strings_equal(
+ const char *s1, const char *s2)
+{
+ while (*s1 != '\0') {
+ if (*(s1++) != *(s2++)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
+ * Parse an int out of a string.
+ *
+ * \param[in] str String to parse integer out of.
+ * \param[out] res Returns parsed integer.
+ * \return The number of characters consumed in `str`.
+ * Returning 0 indicates failure to parse an integer out of the string.
+ */
+static inline size_t ascii_string_to_int(const char *str, int *res)
+{
+ char *end = NULL;
+ long long temp = strtoll(str, &end, 10);
+
+ if (end == str || errno == ERANGE ||
+ temp < INT_MIN || temp > INT_MAX) {
+ return 0;
+ }
+
+ *res = temp;
+ return end - str;
+}
+
+#endif
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=62682552887e53db7f585e7b2bfd30e137c5b87f
commit 62682552887e53db7f585e7b2bfd30e137c5b87f
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
Time: Expose arrays of weekday and month names.
diff --git a/utils/time.c b/utils/time.c
index cf8acc0..dd67d8a 100644
--- a/utils/time.c
+++ b/utils/time.c
@@ -35,20 +35,86 @@
#include "utils/time.h"
+
+/**
+ * Weekdays
+ *
+ * Must be calender order.
+ */
+enum nsc_time_weekdays {
+ NSC_TIME_WEEKDAY_SUN,
+ NSC_TIME_WEEKDAY_MON,
+ NSC_TIME_WEEKDAY_TUE,
+ NSC_TIME_WEEKDAY_WED,
+ NSC_TIME_WEEKDAY_THU,
+ NSC_TIME_WEEKDAY_FRI,
+ NSC_TIME_WEEKDAY_SAT,
+ NSC_TIME_WEEKDAY__COUNT
+};
+/**
+ * Months
+ *
+ * Must be calender order.
+ */
+enum nsc_time_months {
+ NSC_TIME_MONTH_JAN,
+ NSC_TIME_MONTH_FEB,
+ NSC_TIME_MONTH_MAR,
+ NSC_TIME_MONTH_APR,
+ NSC_TIME_MONTH_MAY,
+ NSC_TIME_MONTH_JUN,
+ NSC_TIME_MONTH_JUL,
+ NSC_TIME_MONTH_AUG,
+ NSC_TIME_MONTH_SEP,
+ NSC_TIME_MONTH_OCT,
+ NSC_TIME_MONTH_NOV,
+ NSC_TIME_MONTH_DEC,
+ NSC_TIME_MONTH__COUNT,
+};
+
+
+/**
+ * Array of short weekday names.
+ */
+const char * const weekdays_short[NSC_TIME_WEEKDAY__COUNT] = {
+ [NSC_TIME_WEEKDAY_SUN] = "Sun",
+ [NSC_TIME_WEEKDAY_MON] = "Mon",
+ [NSC_TIME_WEEKDAY_TUE] = "Tue",
+ [NSC_TIME_WEEKDAY_WED] = "Wed",
+ [NSC_TIME_WEEKDAY_THU] = "Thu",
+ [NSC_TIME_WEEKDAY_FRI] = "Fri",
+ [NSC_TIME_WEEKDAY_SAT] = "Sat"
+};
+/**
+ * Array of month names.
+ */
+const char * const months[NSC_TIME_MONTH__COUNT] = {
+ [NSC_TIME_MONTH_JAN] = "Jan",
+ [NSC_TIME_MONTH_FEB] = "Feb",
+ [NSC_TIME_MONTH_MAR] = "Mar",
+ [NSC_TIME_MONTH_APR] = "Apr",
+ [NSC_TIME_MONTH_MAY] = "May",
+ [NSC_TIME_MONTH_JUN] = "Jun",
+ [NSC_TIME_MONTH_JUL] = "Jul",
+ [NSC_TIME_MONTH_AUG] = "Aug",
+ [NSC_TIME_MONTH_SEP] = "Sep",
+ [NSC_TIME_MONTH_OCT] = "Oct",
+ [NSC_TIME_MONTH_NOV] = "Nov",
+ [NSC_TIME_MONTH_DEC] = "Dec"
+};
+
+
/* exported interface documented in utils/time.h */
const char *rfc1123_date(time_t t)
{
static char ret[30];
struct tm *tm = gmtime(&t);
- const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
},
- *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
snprintf(ret, sizeof ret, "%s, %02d %s %d %02d:%02d:%02d GMT",
- days[tm->tm_wday], tm->tm_mday, months[tm->tm_mon],
- tm->tm_year + 1900, tm->tm_hour, tm->tm_min,
- tm->tm_sec);
+ weekdays_short[tm->tm_wday], tm->tm_mday,
+ months[tm->tm_mon], tm->tm_year + 1900,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
return ret;
}
-----------------------------------------------------------------------
Summary of changes:
content/urldb.c | 43 +++-
content/urldb.h | 3 +-
desktop/cookie_manager.c | 10 +
desktop/global_history.c | 10 +
desktop/hotlist.c | 10 +
desktop/options.h | 5 +-
desktop/sslcert_viewer.c | 10 +
desktop/tree.c | 10 -
desktop/treeview.c | 38 ++-
desktop/treeview.h | 3 +-
frontends/amiga/gui.c | 2 +-
frontends/amiga/schedule.c | 185 ++++++++------
frontends/atari/gui.c | 7 -
frontends/gtk/cookies.c | 6 -
frontends/gtk/global_history.c | 6 -
frontends/gtk/hotlist.c | 6 -
frontends/gtk/ssl_cert.c | 6 -
frontends/riscos/gui.c | 12 +-
test/bloom.c | 2 +-
test/data/Choices-all | 1 +
test/data/cookies | 38 +++
test/hashtable.c | 4 +-
test/messages.c | 6 +-
test/nsoption.c | 39 +--
test/time.c | 315 ++++++++++++++++++++++-
test/urldbtest.c | 540 ++++++++++++++++++++++++++++++++++------
test/urlescape.c | 9 +-
utils/nsoption.c | 8 +
utils/time.c | 29 +--
29 files changed, 1072 insertions(+), 291 deletions(-)
mode change 100755 => 100644 frontends/amiga/schedule.c
create mode 100644 test/data/cookies
diff --git a/content/urldb.c b/content/urldb.c
index 3525492..8c2a3ae 100644
--- a/content/urldb.c
+++ b/content/urldb.c
@@ -2480,8 +2480,10 @@ void urldb_destroy(void)
/* Clean up search trees */
for (i = 0; i < NUM_SEARCH_TREES; i++) {
- if (search_trees[i] != &empty)
+ if (search_trees[i] != &empty) {
urldb_destroy_search_tree(search_trees[i]);
+ search_trees[i] = ∅
+ }
}
/* And database */
@@ -2489,10 +2491,13 @@ void urldb_destroy(void)
b = a->next;
urldb_destroy_host_tree(a);
}
+ memset(&db_root, 0, sizeof(db_root));
/* And the bloom filter */
- if (url_bloom != NULL)
+ if (url_bloom != NULL) {
bloom_destroy(url_bloom);
+ url_bloom = NULL;
+ }
}
@@ -2801,8 +2806,16 @@ bool urldb_add_url(nsurl *url)
h = urldb_add_host(host_str);
/* Get path entry */
- p = (h != NULL) ? urldb_add_path(scheme, port_int, h, path_query,
- fragment, url) : NULL;
+ if (h != NULL) {
+ p = urldb_add_path(scheme,
+ port_int,
+ h,
+ path_query,
+ fragment,
+ url);
+ } else {
+ p = NULL;
+ }
lwc_string_unref(scheme);
if (fragment != NULL)
@@ -3074,23 +3087,29 @@ bool urldb_get_cert_permissions(nsurl *url)
/* exported interface documented in content/urldb.h */
-void urldb_set_thumbnail(nsurl *url, struct bitmap *bitmap)
+bool urldb_set_thumbnail(nsurl *url, struct bitmap *bitmap)
{
struct path_data *p;
assert(url);
- p = urldb_find_url(url);
- if (p != NULL) {
+ /* add url, in case it's missing */
+ urldb_add_url(url);
- LOG("Setting bitmap on %s", nsurl_access(url));
+ p = urldb_find_url(url);
+ if (p == NULL) {
+ return false;
+ }
- if (p->thumb && p->thumb != bitmap) {
- guit->bitmap->destroy(p->thumb);
- }
+ LOG("Setting bitmap on %s", nsurl_access(url));
- p->thumb = bitmap;
+ if ((p->thumb) && (p->thumb != bitmap)) {
+ guit->bitmap->destroy(p->thumb);
}
+
+ p->thumb = bitmap;
+
+ return true;
}
diff --git a/content/urldb.h b/content/urldb.h
index 1246401..9ff3a8d 100644
--- a/content/urldb.h
+++ b/content/urldb.h
@@ -111,8 +111,9 @@ bool urldb_get_cert_permissions(struct nsurl *url);
*
* \param url Absolute URL to consider
* \param bitmap Opaque pointer to thumbnail data, or NULL to invalidate
+ * \return true on sucessful setting else false
*/
-void urldb_set_thumbnail(struct nsurl *url, struct bitmap *bitmap);
+bool urldb_set_thumbnail(struct nsurl *url, struct bitmap *bitmap);
/**
diff --git a/desktop/cookie_manager.c b/desktop/cookie_manager.c
index 082a14a..b0c48a7 100644
--- a/desktop/cookie_manager.c
+++ b/desktop/cookie_manager.c
@@ -756,6 +756,11 @@ nserror cookie_manager_init(struct
core_window_callback_table *cw_t,
{
nserror err;
+ err = treeview_init();
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
LOG("Generating cookie manager data");
/* Init. cookie manager treeview entry fields */
@@ -822,6 +827,11 @@ nserror cookie_manager_fini(void)
if (cm_ctx.values[i].value != NULL)
free((void *) cm_ctx.values[i].value);
+ err = treeview_fini();
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
LOG("Finalised cookie manager");
return err;
diff --git a/desktop/global_history.c b/desktop/global_history.c
index d60874c..b6f4882 100644
--- a/desktop/global_history.c
+++ b/desktop/global_history.c
@@ -724,6 +724,11 @@ nserror global_history_init(struct
core_window_callback_table *cw_t,
{
nserror err;
+ err = treeview_init();
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
LOG("Loading global history");
/* Init. global history treeview time */
@@ -804,6 +809,11 @@ nserror global_history_fini(void)
if (gh_ctx.fields[i].field != NULL)
lwc_string_unref(gh_ctx.fields[i].field);
+ err = treeview_fini();
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
LOG("Finalised global history");
return err;
diff --git a/desktop/hotlist.c b/desktop/hotlist.c
index cce69be..e344b3b 100644
--- a/desktop/hotlist.c
+++ b/desktop/hotlist.c
@@ -1232,6 +1232,11 @@ nserror hotlist_init(struct core_window_callback_table
*cw_t,
{
nserror err;
+ err = treeview_init();
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
LOG("Loading hotlist");
hl_ctx.tree = NULL;
@@ -1298,6 +1303,11 @@ nserror hotlist_fini(const char *path)
if (hl_ctx.fields[i].field != NULL)
lwc_string_unref(hl_ctx.fields[i].field);
+ err = treeview_fini();
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
LOG("Finalised hotlist");
return err;
diff --git a/desktop/options.h b/desktop/options.h
index 2f36887..437d104 100644
--- a/desktop/options.h
+++ b/desktop/options.h
@@ -59,7 +59,10 @@ NSOPTION_STRING(http_proxy_auth_pass, NULL)
/** Proxy omission list */
NSOPTION_STRING(http_proxy_noproxy, "localhost")
-/** Default font size / 0.1pt. */
+/** Default treeview font size (unit: 0.1pt) */
+NSOPTION_INTEGER(treeview_font_size, 110)
+
+/** Default font size (unit: 0.1pt) */
NSOPTION_INTEGER(font_size, 128)
/** Minimum font size. */
diff --git a/desktop/sslcert_viewer.c b/desktop/sslcert_viewer.c
index 93d6919..09a281c 100644
--- a/desktop/sslcert_viewer.c
+++ b/desktop/sslcert_viewer.c
@@ -353,6 +353,11 @@ nserror sslcert_viewer_init(struct
core_window_callback_table *cw_t,
assert(ssl_d != NULL);
+ err = treeview_init();
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
LOG("Building certificate viewer");
/* Init. certificate chain treeview entry fields */
@@ -427,6 +432,11 @@ nserror sslcert_viewer_fini(struct sslcert_session_data
*ssl_d)
/* Destroy the sslcert_session_data */
sslcert_cleanup_session(ssl_d);
+ err = treeview_fini();
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
LOG("Finalised ssl certificate viewer");
return err;
diff --git a/desktop/tree.c b/desktop/tree.c
index bfe8e98..a5c97c3 100644
--- a/desktop/tree.c
+++ b/desktop/tree.c
@@ -55,7 +55,6 @@ struct tree {
struct sslcert_session_data *ssl_current_session = NULL;
const char *tree_hotlist_path = NULL;
-int treeview_inits;
static void treeview_test_redraw_request(struct core_window *cw,
const struct rect *r)
@@ -128,11 +127,6 @@ static bool treeview_test_init(struct tree *tree)
{
nserror err;
- treeview_inits++;
-
- if (treeview_inits == 1)
- treeview_init(0);
-
switch (tree->flags) {
case TREE_COOKIES:
assert(ssl_current_session == NULL &&
@@ -195,10 +189,6 @@ static bool treeview_test_fini(struct tree *tree)
break;
}
- if (treeview_inits == 1)
- treeview_fini();
- treeview_inits--;
-
return true;
}
diff --git a/desktop/treeview.c b/desktop/treeview.c
index f2af5e8..fa7fea0 100644
--- a/desktop/treeview.c
+++ b/desktop/treeview.c
@@ -24,6 +24,7 @@
#include "utils/log.h"
#include "utils/nsurl.h"
+#include "utils/nsoption.h"
#include "netsurf/bitmap.h"
#include "netsurf/content.h"
#include "netsurf/plotters.h"
@@ -44,7 +45,7 @@
#define REDRAW_MAX 8000
struct treeview_globals {
- bool initialised;
+ unsigned initialised;
int line_height;
int furniture_width;
int step_width;
@@ -3588,7 +3589,7 @@ static void treeview_init_plot_styles(int font_pt_size)
/* Text colour */
plot_style_even.text.family = PLOT_FONT_FAMILY_SANS_SERIF;
- plot_style_even.text.size = font_pt_size * FONT_SIZE_SCALE;
+ plot_style_even.text.size = font_pt_size;
plot_style_even.text.weight = 400;
plot_style_even.text.flags = FONTF_NONE;
plot_style_even.text.foreground = ns_system_colour_char("WindowText");
@@ -3948,23 +3949,29 @@ static nserror treeview_init_furniture(void)
/* Exported interface, documented in treeview.h */
-nserror treeview_init(int font_pt_size)
+nserror treeview_init(void)
{
- int font_px_size;
+ long long font_px_size;
+ long long font_pt_size;
nserror err;
- if (tree_g.initialised == true)
+ if (tree_g.initialised > 0) {
+ tree_g.initialised++;
return NSERROR_OK;
+ }
LOG("Initialising treeview module");
- if (font_pt_size <= 0)
- font_pt_size = 11;
+ font_pt_size = nsoption_int(treeview_font_size);
+ if (font_pt_size <= 0) {
+ font_pt_size = 11 * 10;
+ }
- font_px_size = (font_pt_size * FIXTOINT(nscss_screen_dpi) + 36) / 72;
+ font_px_size = (font_pt_size * FIXTOINT(nscss_screen_dpi) /
+ 10 + 36) / 72;
tree_g.line_height = (font_px_size * 8 + 3) / 6;
- treeview_init_plot_styles(font_pt_size);
+ treeview_init_plot_styles(font_pt_size * FONT_SIZE_SCALE / 10);
treeview_init_resources();
err = treeview_init_furniture();
if (err != NSERROR_OK)
@@ -3976,7 +3983,7 @@ nserror treeview_init(int font_pt_size)
tree_g.icon_step = 23;
tree_g.move_offset = 18;
- tree_g.initialised = true;
+ tree_g.initialised++;
LOG("Initialised treeview module");
@@ -3989,6 +3996,15 @@ nserror treeview_fini(void)
{
int i;
+ if (tree_g.initialised > 1) {
+ tree_g.initialised--;
+ return NSERROR_OK;
+
+ } else if (tree_g.initialised == 0) {
+ LOG("Warning: tried to finalise uninitialised treeview module");
+ return NSERROR_OK;
+ }
+
LOG("Finalising treeview module");
for (i = 0; i < TREE_RES_LAST; i++) {
@@ -4004,7 +4020,7 @@ nserror treeview_fini(void)
guit->bitmap->destroy(plot_style_even.furn[TREE_FURN_CONTRACT].bmp);
guit->bitmap->destroy(plot_style_even.furn[TREE_FURN_CONTRACT].sel);
- tree_g.initialised = false;
+ tree_g.initialised--;
LOG("Finalised treeview module");
diff --git a/desktop/treeview.h b/desktop/treeview.h
index 25349ad..abe0e56 100644
--- a/desktop/treeview.h
+++ b/desktop/treeview.h
@@ -112,10 +112,9 @@ struct treeview_callback_table {
/**
* Prepare treeview module for treeview usage
*
- * \param font_pt_size Treeview text size in pt. Set to <= 0 for default.
* \return NSERROR_OK on success, appropriate error otherwise
*/
-nserror treeview_init(int font_pt_size);
+nserror treeview_init(void);
/**
* Finalise the treeview module (all treeviews must have been destroyed first)
diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c
index 8ad21b3..8672a93 100644
--- a/frontends/amiga/gui.c
+++ b/frontends/amiga/gui.c
@@ -5550,7 +5550,7 @@ int main(int argc, char** argv)
/* Check for AltiVec */
uint32 altivec = 0;
- GetCPUInfoTags(GCIT_VectorUnit, &altivec);
+ GetCPUInfoTags(GCIT_VectorUnit, &altivec, TAG_DONE);
if(altivec == VECTORTYPE_ALTIVEC) {
LOG("AltiVec detected");
diff --git a/frontends/amiga/schedule.c b/frontends/amiga/schedule.c
old mode 100755
new mode 100644
index 2d63465..ff93e90
--- a/frontends/amiga/schedule.c
+++ b/frontends/amiga/schedule.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 - 2014 Chris Young <[email protected]>
+ * Copyright 2008 - 2016 Chris Young <[email protected]>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -21,6 +21,7 @@
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/timer.h>
+#include <proto/utility.h> /* For Amiga2Date */
#include <stdio.h>
#include <stdbool.h>
@@ -32,23 +33,20 @@
#include "amiga/misc.h"
#include "amiga/schedule.h"
-static struct TimeRequest *tioreq;
-struct Device *TimerBase;
-#ifdef __amigaos4__
-struct TimerIFace *ITimer;
-#endif
-
-static APTR restrict pool_nscb = NULL;
-static APTR restrict pool_timereq = NULL;
-
struct nscallback
{
- struct TimeVal tv;
+ struct TimeRequest timereq;
+ struct TimeVal tv; /* time we expect the event to occur */
void *restrict callback;
void *restrict p;
- struct TimeRequest *treq;
};
+static struct nscallback *tioreq;
+struct Device *TimerBase;
+#ifdef __amigaos4__
+struct TimerIFace *ITimer;
+#endif
+
static PblHeap *schedule_list;
/**
@@ -63,14 +61,10 @@ static void ami_schedule_remove_timer_event(struct
nscallback *nscb)
{
if(!nscb) return;
- if(nscb->treq)
- {
- if(CheckIO((struct IORequest *)nscb->treq)==NULL)
- AbortIO((struct IORequest *)nscb->treq);
+ if(CheckIO((struct IORequest *)nscb)==NULL)
+ AbortIO((struct IORequest *)nscb);
- WaitIO((struct IORequest *)nscb->treq);
- ami_misc_itempool_free(pool_timereq, nscb->treq, sizeof(struct
TimeRequest));
- }
+ WaitIO((struct IORequest *)nscb);
}
/**
@@ -87,22 +81,21 @@ static nserror ami_schedule_add_timer_event(struct
nscallback *nscb, int t)
struct TimeVal tv;
ULONG time_us = t * 1000; /* t converted to �s */
- nscb->tv.Seconds = time_us / 1000000;
- nscb->tv.Microseconds = time_us % 1000000;
+ tv.Seconds = time_us / 1000000;
+ tv.Microseconds = time_us % 1000000;
- GetSysTime(&tv);
- AddTime(&nscb->tv,&tv); // now contains time when event occurs
-
- if((nscb->treq = ami_misc_itempool_alloc(pool_timereq, sizeof(struct
TimeRequest)))) {
- *nscb->treq = *tioreq;
- nscb->treq->Request.io_Command=TR_ADDREQUEST;
- nscb->treq->Time.Seconds=nscb->tv.Seconds; // secs
- nscb->treq->Time.Microseconds=nscb->tv.Microseconds; // micro
- SendIO((struct IORequest *)nscb->treq);
- } else {
- return NSERROR_NOMEM;
+ if(tv.Microseconds >= 1000000) {
+ LOG("Microseconds invalid value: %ld", nscb->tv.Microseconds);
}
+ GetSysTime(&nscb->tv);
+ AddTime(&nscb->tv, &tv); // now contains time when event occurs (for
debug and heap sorting)
+
+ nscb->timereq.Request.io_Command = TR_ADDREQUEST;
+ nscb->timereq.Time.Seconds = tv.Seconds; // secs
+ nscb->timereq.Time.Microseconds = tv.Microseconds; // micro
+ SendIO((struct IORequest *)nscb);
+
return NSERROR_OK;
}
@@ -177,8 +170,9 @@ static nserror schedule_remove(void (*callback)(void *p),
void *p)
nscb = ami_schedule_locate(callback, p, true);
if(nscb != NULL) {
+ LOG("deleted callback %p", nscb);
ami_schedule_remove_timer_event(nscb);
- ami_misc_itempool_free(pool_nscb, nscb, sizeof(struct
nscallback));
+ FreeSysObject(ASOT_IOREQUEST, nscb);
pblHeapConstruct(schedule_list);
}
@@ -198,7 +192,7 @@ static void schedule_remove_all(void)
{
ami_schedule_remove_timer_event(nscb);
pblIteratorRemove(iterator);
- ami_misc_itempool_free(pool_nscb, nscb, sizeof(struct
nscallback));
+ FreeSysObject(ASOT_IOREQUEST, nscb);
};
pblIteratorFree(iterator);
@@ -209,62 +203,88 @@ static int ami_schedule_compare(const void *prev, const
void *next)
struct nscallback *nscb1 = *(struct nscallback **)prev;
struct nscallback *nscb2 = *(struct nscallback **)next;
+ /**\todo a heap probably isn't the best idea now */
return CmpTime(&nscb1->tv, &nscb2->tv);
}
+/* Outputs all scheduled events to the log */
+static void ami_schedule_dump(void)
+{
+ PblIterator *iterator;
+ struct nscallback *nscb;
+ struct ClockData clockdata;
+
+ if(pblHeapIsEmpty(schedule_list)) return;
+
+ struct TimeVal tv;
+ GetSysTime(&tv);
+ Amiga2Date(tv.Seconds, &clockdata);
+
+ LOG("Current time = %d-%d-%d %d:%d:%d.%d", clockdata.mday,
clockdata.month, clockdata.year,
+ clockdata.hour, clockdata.min, clockdata.sec, tv.Microseconds);
+ LOG("Events remaining in queue:");
+
+ iterator = pblHeapIterator(schedule_list);
+
+ while ((nscb = pblIteratorNext(iterator)) != -1)
+ {
+ Amiga2Date(nscb->tv.Seconds, &clockdata);
+ LOG("nscb: %p, at %d-%d-%d %d:%d:%d.%d, callback: %p, %p",
+ nscb, clockdata.mday, clockdata.month, clockdata.year,
clockdata.hour, clockdata.min, clockdata.sec,
+ nscb->tv.Microseconds, nscb->callback, nscb->p);
+ };
+
+ pblIteratorFree(iterator);
+}
/**
- * Process events up to current time.
+ * Process signalled event
*
- * This implementation only takes the top entry off the heap, it does not
- * venture to later scheduled events until the next time it is called -
- * immediately afterwards, if we're in a timer signalled loop.
+ * This implementation only processes the callback that arrives in the message
from timer.device.
*/
-static void ami_scheduler_run(void)
+static bool ami_scheduler_run(struct nscallback *nscb)
{
- struct nscallback *nscb;
- struct TimeVal tv;
void (*callback)(void *p);
void *p;
- nscb = pblHeapGetFirst(schedule_list);
- if(nscb == -1) return;
-
- /* Ensure the scheduled event time has passed (CmpTime<=0)
- * in case something been deleted between the timer
- * signalling us and us responding to it.
- */
+ LOG("callback %p", nscb);
+
+ /*** vvv Debugging vvv ***/
+ struct TimeVal tv;
GetSysTime(&tv);
- if(CmpTime(&tv, &nscb->tv) > 0) return;
-
+ if(CmpTime(&tv, &nscb->tv) > 0) {
+ LOG("Expected scheduled time of event has not passed: %ld.%ld <
%ld.%ld", tv.Seconds, tv.Microseconds, nscb->tv.Seconds, nscb->tv.Microseconds);
+ }
+ /*** ^^^ Debugging ^^^ ***/
+
callback = nscb->callback;
p = nscb->p;
- ami_schedule_remove_timer_event(nscb);
- pblHeapRemoveFirst(schedule_list);
- ami_misc_itempool_free(pool_nscb, nscb, sizeof(struct nscallback));
+ schedule_remove(callback, p); /* this does a lookup as we don't know if
we're the first item on the heap */
LOG("Running scheduled callback %p with arg %p", callback, p);
callback(p);
-
- return;
+ LOG("Callback finished...");
+
+ ami_schedule_dump();
+ return true;
}
static void ami_schedule_open_timer(struct MsgPort *msgport)
{
#ifdef __amigaos4__
- tioreq = (struct TimeRequest *)AllocSysObjectTags(ASOT_IOREQUEST,
- ASOIOR_Size,sizeof(struct TimeRequest),
- ASOIOR_ReplyPort,msgport,
- ASO_NoTrack,FALSE,
+ tioreq = (struct nscallback *)AllocSysObjectTags(ASOT_IOREQUEST,
+ ASOIOR_Size, sizeof(struct nscallback),
+ ASOIOR_ReplyPort, msgport,
+ ASO_NoTrack, FALSE,
TAG_DONE);
#else
- tioreq = (struct TimeRequest *)CreateIORequest(msgport, sizeof(struct
TimeRequest));
+ tioreq = (struct nscallback *)CreateIORequest(msgport, sizeof(struct
nscallback));
#endif
- OpenDevice("timer.device", UNIT_WAITUNTIL, (struct IORequest *)tioreq,
0);
+ OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)tioreq, 0);
- TimerBase = (struct Device *)tioreq->Request.io_Device;
+ TimerBase = (struct Device *)tioreq->timereq.Request.io_Device;
#ifdef __amigaos4__
ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase,
"main", 1, NULL);
#endif
@@ -282,9 +302,6 @@ static void ami_schedule_close_timer(void)
/* exported interface documented in amiga/schedule.h */
nserror ami_schedule_create(struct MsgPort *msgport)
{
- pool_nscb = ami_misc_itempool_create(sizeof(struct nscallback));
- pool_timereq = ami_misc_itempool_create(sizeof(struct TimeRequest));
-
ami_schedule_open_timer(msgport);
schedule_list = pblHeapNew();
if(schedule_list == PBL_ERROR_OUT_OF_MEMORY) return NSERROR_NOMEM;
@@ -297,14 +314,12 @@ nserror ami_schedule_create(struct MsgPort *msgport)
/* exported interface documented in amiga/schedule.h */
void ami_schedule_free(void)
{
+ ami_schedule_dump();
schedule_remove_all();
pblHeapFree(schedule_list); // this should be empty at this point
schedule_list = NULL;
ami_schedule_close_timer();
-
- ami_misc_itempool_delete(pool_timereq);
- ami_misc_itempool_delete(pool_nscb);
}
/* exported function documented in amiga/schedule.h */
@@ -312,6 +327,10 @@ nserror ami_schedule(int t, void (*callback)(void *p),
void *p)
{
struct nscallback *nscb;
+ if(t == 0) t = 1;
+
+ LOG("Scheduling callback %p with arg %p at time %d", callback, p, t);
+
if(schedule_list == NULL) return NSERROR_INIT_FAILED;
if(t < 0) return schedule_remove(callback, p);
@@ -319,9 +338,18 @@ nserror ami_schedule(int t, void (*callback)(void *p),
void *p)
return ami_schedule_reschedule(nscb, t);
}
- nscb = ami_misc_itempool_alloc(pool_nscb, sizeof(struct nscallback));
+#ifdef __amigaos4__
+ nscb = AllocSysObjectTags(ASOT_IOREQUEST,
+ ASOIOR_Duplicate,
tioreq,
+ TAG_DONE);
+#else
+ nscb = (struct nscallback *)CreateIORequest(msgport, sizeof(struct
nscallback));
+ *nscb = *tioreq;
+#endif
if(!nscb) return NSERROR_NOMEM;
+ LOG("new nscb %p", nscb);
+
if (ami_schedule_add_timer_event(nscb, t) != NSERROR_OK)
return NSERROR_NOMEM;
@@ -337,17 +365,16 @@ nserror ami_schedule(int t, void (*callback)(void *p),
void *p)
/* exported interface documented in amiga/schedule.h */
void ami_schedule_handle(struct MsgPort *nsmsgport)
{
- /* nsmsgport is the NetSurf message port that the scheduler task
- * (or timer.device in no-async mode) is sending messages to. */
+ /* nsmsgport is the NetSurf message port that
+ * timer.device is sending messages to. */
- struct TimerRequest *timermsg;
+ struct nscallback *timermsg;
- while((timermsg = (struct TimerRequest *)GetMsg(nsmsgport))) {
- /* reply first, as we don't need the message contents
and
- * it crashes if we reply after schedule_run has
executed.
- */
- ReplyMsg((struct Message *)timermsg);
- ami_scheduler_run();
- }
+ while((timermsg = (struct nscallback *)GetMsg(nsmsgport))) {
+ LOG("timermsg %p", timermsg);
+ LOG("timereq err = %d (should be 0)",
timermsg->timereq.Request.io_Error);
+ ami_scheduler_run(timermsg);
+ };
+ LOG("timermsg %p (0)", timermsg);
}
diff --git a/frontends/atari/gui.c b/frontends/atari/gui.c
index eb15777..1cf51d3 100644
--- a/frontends/atari/gui.c
+++ b/frontends/atari/gui.c
@@ -40,7 +40,6 @@
#include "netsurf/cookie_db.h"
#include "netsurf/url_db.h"
#include "content/backing_store.h"
-#include "desktop/treeview.h"
#include "atari/gemtk/gemtk.h"
#include "atari/gui.h"
@@ -828,9 +827,6 @@ static void gui_quit(void)
atari_hotlist_destroy();
atari_cookie_manager_destroy();
- /* shutdown netsurf treeview framework: */
- treeview_fini();
-
/* shutdown the toolbar framework: */
toolbar_exit();
@@ -1037,9 +1033,6 @@ static void gui_init(int argc, char** argv)
}
gemtk_wm_init();
- /* Initialize the netsurf treeview framework with default font size: */
- treeview_init(0);
-
/* Initialize the specific treeview windows: */
atari_global_history_init();
atari_hotlist_init();
diff --git a/frontends/gtk/cookies.c b/frontends/gtk/cookies.c
index 3c5d93a..d0fae97 100644
--- a/frontends/gtk/cookies.c
+++ b/frontends/gtk/cookies.c
@@ -29,7 +29,6 @@
#include "netsurf/keypress.h"
#include "netsurf/plotters.h"
#include "desktop/cookie_manager.h"
-#include "desktop/treeview.h"
#include "gtk/cookies.h"
#include "gtk/plotters.h"
@@ -247,11 +246,6 @@ static nserror nsgtk_cookies_init(void)
return NSERROR_OK;
}
- res = treeview_init(0);
- if (res != NSERROR_OK) {
- return res;
- }
-
ncwin = malloc(sizeof(struct nsgtk_cookie_window));
if (ncwin == NULL) {
return NSERROR_NOMEM;
diff --git a/frontends/gtk/global_history.c b/frontends/gtk/global_history.c
index b41d06e..7d64705 100644
--- a/frontends/gtk/global_history.c
+++ b/frontends/gtk/global_history.c
@@ -30,7 +30,6 @@
#include "netsurf/keypress.h"
#include "netsurf/plotters.h"
#include "desktop/global_history.h"
-#include "desktop/treeview.h"
#include "gtk/compat.h"
#include "gtk/plotters.h"
@@ -300,11 +299,6 @@ static nserror nsgtk_global_history_init(void)
return NSERROR_OK;
}
- res = treeview_init(0);
- if (res != NSERROR_OK) {
- return res;
- }
-
ncwin = malloc(sizeof(struct nsgtk_global_history_window));
if (ncwin == NULL) {
return NSERROR_NOMEM;
diff --git a/frontends/gtk/hotlist.c b/frontends/gtk/hotlist.c
index 2d0641f..c47d1da 100644
--- a/frontends/gtk/hotlist.c
+++ b/frontends/gtk/hotlist.c
@@ -31,7 +31,6 @@
#include "netsurf/keypress.h"
#include "netsurf/plotters.h"
#include "desktop/hotlist.h"
-#include "desktop/treeview.h"
#include "gtk/compat.h"
#include "gtk/plotters.h"
@@ -318,11 +317,6 @@ static nserror nsgtk_hotlist_init(void)
return NSERROR_OK;
}
- res = treeview_init(0);
- if (res != NSERROR_OK) {
- return res;
- }
-
ncwin = malloc(sizeof(struct nsgtk_hotlist_window));
if (ncwin == NULL) {
return NSERROR_NOMEM;
diff --git a/frontends/gtk/ssl_cert.c b/frontends/gtk/ssl_cert.c
index 1cf0beb..8270b15 100644
--- a/frontends/gtk/ssl_cert.c
+++ b/frontends/gtk/ssl_cert.c
@@ -29,7 +29,6 @@
#include "netsurf/keypress.h"
#include "netsurf/plotters.h"
#include "desktop/sslcert_viewer.h"
-#include "desktop/treeview.h"
#include "gtk/plotters.h"
#include "gtk/scaffolding.h"
@@ -177,11 +176,6 @@ nserror gtk_cert_verify(struct nsurl *url,
struct nsgtk_crtvrfy_window *ncwin;
nserror res;
- res = treeview_init(0);
- if (res != NSERROR_OK) {
- return res;
- }
-
ncwin = malloc(sizeof(struct nsgtk_crtvrfy_window));
if (ncwin == NULL) {
return NSERROR_NOMEM;
diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c
index 7c52164..7e508a8 100644
--- a/frontends/riscos/gui.c
+++ b/frontends/riscos/gui.c
@@ -55,7 +55,6 @@
#include "netsurf/cookie_db.h"
#include "netsurf/url_db.h"
#include "desktop/save_complete.h"
-#include "desktop/treeview.h"
#include "content/backing_store.h"
#include "riscos/gui.h"
@@ -315,6 +314,12 @@ static nserror set_defaults(struct nsoption_s *defaults)
*/
nsoption_set_uint(disc_cache_size, 0);
+ /* Override core default treeview font size with 12 pt.
+ * TODO: 12 is the normal desktop font size, but users might run
+ * with something different.
+ */
+ nsoption_set_int(treeview_font_size, 12 * 10);
+
/* set default system colours for riscos ui */
set_colour_from_wimp(defaults, wimp_COLOUR_BLACK,
NSOPTION_sys_colour_ActiveBorder, 0x00000000);
set_colour_from_wimp(defaults, wimp_COLOUR_CREAM,
NSOPTION_sys_colour_ActiveCaption, 0x00dddddd);
@@ -1227,11 +1232,6 @@ static nserror gui_init(int argc, char** argv)
die(error->errmess);
}
- ret = treeview_init(12);
- if (ret != NSERROR_OK) {
- die("Failed to initialise treeview");
- }
-
/* Initialise themes before dialogs */
ro_gui_theme_initialise();
diff --git a/test/bloom.c b/test/bloom.c
index 71a0b01..6ba3b48 100644
--- a/test/bloom.c
+++ b/test/bloom.c
@@ -145,7 +145,7 @@ END_TEST
/* Suite */
-Suite *bloom_suite(void)
+static Suite *bloom_suite(void)
{
Suite *s;
TCase *tc_create;
diff --git a/test/data/Choices-all b/test/data/Choices-all
index a9add1d..b9cab1f 100644
--- a/test/data/Choices-all
+++ b/test/data/Choices-all
@@ -5,6 +5,7 @@ http_proxy_auth:0
http_proxy_auth_user:
http_proxy_auth_pass:
http_proxy_noproxy:localhost
+treeview_font_size:110
font_size:128
font_min_size:85
font_sans:Sans
diff --git a/test/data/cookies b/test/data/cookies
new file mode 100644
index 0000000..739618e
--- /dev/null
+++ b/test/data/cookies
@@ -0,0 +1,38 @@
+# >/home/vince/.config/netsurf/Cookies
+# NetSurf cookies file.
+#
+# Lines starting with a '#' are comments, blank lines are ignored.
+#
+# All lines prior to "Version: 102" are discarded.
+#
+# Version Domain Domain from Set-Cookie Path Path from Set-Cookie
Secure HTTP-Only Expires Last used No destroy Name Value
Value was quoted Scheme URL Comment
+Version: 102
+0 .theguardian.com 1 / 1 0 0
1476054669 1468278669 0 GU_mvt_id 439080 0 unused
unused
+0 .reddit.com 1 / 1 0 1 1499814590
1468278656 0 __cfduid
d2c9a13e6ed171f4318aabcf558fcc6661468278590 0 unused unused
+0 www.reddit.com 0 / 1 1 0 1531350591
1468278656 0 loid lLGqu0nblR8T852T20 0 https
https://www.reddit.com/
+0 www.reddit.com 0 / 1 1 0 1531350591
1468278656 0 loidcreated 2016-07-11T23%3A09%3A50.925Z 0
https https://www.reddit.com/
+0 .giffgaff.com 1 / 1 0 0 1503402870
1440407964 0 visid_incap_456843
MSQtdY7lSvK9UJiZDP3daK0S2lUAAAAAQUIPAAAAAAAudOMnRSt1V9mQN5dPPA+R 0
unused unused
+0 .google.com 1 / 1 0 0 1497632093
1470493285 0 SID
DQAAAMoAAACuniK1mc17JMX-o-sfAVqvl0EWP0kiNpQg4lWeslWBnU_km8BK6Eww-1mC6zvnm7Jiv2vft4BOwWiAOmRzN66pbzxGNxKKGzSz2GNdWrcwvuYyQHkevwrtwmKmZGDKsgLljofq6NyNf0AP5xGXfHj18awhbbnymmv5UaDqypGx7FvptGQSMQkj_1hY6NJ5pfmO6LX8ezViJMABtqGPoO8Y8r8-eFRzLlsfbhCqM2OHkDRfoofXJCtIvDMi7Xyzoh6D5PsXbrfFZhcLSlfZpBtP
0 unused unused
+0 .google.com 1 / 1 0 1 1497632093
1470493285 0 HSID A1rFmKHX-G1exnHNv 0 unused unused
+0 .google.com 1 / 1 1 1 1497632093
1470493285 0 SSID A4wVZcYgXrCrwWns8 0 unused unused
+0 .google.com 1 / 1 0 0 1497632093
1470493285 0 APISID IeJTJt20VmceF7bS/AACvc5cSFPpX8FJMj 0
unused unused
+0 .google.com 1 / 1 1 0 1497632093
1470493285 0 SAPISID baCIIjpj-o3XQCkH/A-WEZgPvnNnguijDQ 0
unused unused
+0 accounts.google.com 0 / 1 1 1
1497632093 0 0 GAPS
1:-F43DfTc9MQPBnPFtQw7SBXNDYxGRw:-byarQeQN13vrH8I 0 https
https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1<mpl=default<mplcache=2&emr=1&osid=1
+0 accounts.google.com 0 / 1 1 1
1497632093 0 0 LSID
mail|o.mail.google.com|s.GB|ss:DQAAAMwAAADuReoJNLFTfcVkka4Mpznq77VRSAgK_50UNJQeyKZS6zdAktvmMi42CsHIKCA_qkMe373-3PwvTioyn8OGHoKi8a2tas-mS1US4KPOXsp6GrewaR6bwkvkAudNj5H97wu9p9uek5EMljgPSIcFHyTRDwGghHc918-Z5-QVQMYswD9fA8DObnL4iFPrYJyYsz2MJcYKOMTdgBc9cutZ-zgRVJLVV1IJiluuTeQb5pjfpX4ROfo8kf4M_boTxfuwO19fn_zp5jT9qdPr4jDBM9lM
0 https
https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1<mpl=default<mplcache=2&emr=1&osid=1
+0 accounts.google.com 0 / 1 1 1
1497632093 0 0 ACCOUNT_CHOOSER
AFx_qI5IqJoq6XeRvabQu34G7bErRw0LzimzBZXUqP_9H8Zh2kqTpBc-jooLHKNNCggYdxTq_ENRPogKK0V35Ap5s9N-88xwKmZLX7xXnZ25EBl-8FHjjvfMxKIj2-_xnpyKtWa5fWac
0 https
https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1<mpl=default<mplcache=2&emr=1&osid=1
+0 mail.google.com 0 / 1 1 1 1497632093
1435272960 0 OSID
DQAAANsAAABjm3QWm7iyror5Q-r_twvLnU2MeBpDTpzoY-d-4pEomtilsx1VjIp_SphmVJcv084Ilg4o1COlySeuNAVSkeYn6qPyK93aIKN7MOmQxKvYQXIAlPiBAXD7bVX2HoAQpDXKc1BQZUfL2wLIjCwns0NQVGawofTWf8gve_FAwp6hXF9hXHrZRTU9lgt3N0yBpjElda_UiyNkhUIZP27zSS1LpXh7GaYcUgM69IUrczTnfkfIX_XunEaXBT59fmc49pbFEYlMMURG3ydiPjIhGdN9eHO27V9JhxqhuYUryTM8kg
0 https
https://mail.google.com/accounts/SetOSID?continue=https%3A%2F%2Faccounts.google.co.uk%2Faccounts%2FSetSID%3Fssdc%3D1%26sidt%3DALWU2ctR9Uxp0qhL0HVYNURm01UOebegtyVV3GH%252BiVgIY9WIfqGs5NmqjVyX2IzkD0jDdGMV%252BgDLYwi9XrR%252FWsOIdwC4OO803V%252FimpsuKeLB7lk3%252FV10vr4C6wTc20A0I3ep6BLOe%252FQZgYJjfrcjzRiV2zT6fOiYXka1QrtyPIugR3R%252FaSWI%252Fau79w9hvBc%252FqqATVRi7F%252FDHv%252Be3cHMLPNOYoKwwUSOA9ORjKsyc5bCpnWM6X%252BrjsfzEEqlV5iui3EPKbBvTvCnfdF7UJjMg4EfWyMhVZaeytZdvGqJ2DfvPNmm2toULDQd4rcAAkfRZJQ95ySI4fq1ifZkfA0dhr7xnBQ0cl3%252BYTdl0yp%252BXjztO8YivQb%252Feip7gihmjfE9yRXoEboirDW8lIscN6cDDsuxzD07npdjHjRUX2wYrG4V3MLI4luH
O52mwY%252BHZMN3O681HumCIBYvX%26continue%3Dhttps%253A%252F%252Fmail.google.com%252Fmail%252F%253Fauth%253DDQAAAL8AAABzUu3D7vQTObQbtiQU-X_6NnwgrsDnQe_7yXrUrFrniwP5j04Q9jVgc203CAd7rwHnO0tvXTI8MSlRISJz3tGutyOc_uw5khR4FHviJuyTEuxKJZPUmQXnIWxZf_CQoJXGGaxn1kT0scUyrxiBjTfXllUWBVa5iuEzL2lgbAINKmSlLmyg3BaTFb-l0nmDdqGznAJMDgspYtD8iBTcPnOWpGkHXUVtkE0C6KK_3z1eULl0wEne4aU0LNJhlhUa8Xk&osidt=ALWU2cvhIheonCPoG5pecDWKf0i1a-AsQKBMvxay9B54taUbBKAxr9vzwWXg2UJDvM3oYcjYFVDxpERiv9sed5ZQXUKh9UPV5epNA25PUuVZwNDOkePm6agrIhUGR9wVz4x7I6-uU0uF4VHDwS1KDpWZvQY6tMw5vti1qF2bVdLMO_UTLcEW9mdV7Oze8OZXWxFsppfVGSxHN8N1rH8xRMCj3A5QjC-OU5h-pS3N4-AI4A5LwrMj_zvtwS0BW5otNhVmt503yBBXKIIkF5i4gGXiQGVVhCFlBeosv7KbWx97PEPTzeqf59R0ZgY9p1cd_jQWi0gYUmTn
+0 mail.google.com 0 /mail 1 1 1 1497632094
1435272960 0 GX
DQAAAMoAAADuReoJNLFTfcVkka4MpznqQGgtWpCWbF9qPINtXVzsE62rPcFtkl_t5MhqS9Ab1zrEmWlZefvaR2bknrPqFsBfVZAtMoThXQxvoQQ7K2A1XTWfEeX09w0dJvN0A8SXsjAEebTY93dZkJr5fMomABLkbizqoRqSkv6sh4x7Ysat6VGX6m6eTg81aiCjuBHzLwlAKx63On5joEI1qYhXvKF1JMc3oEzaETTv9mw-vXHt_J-YYlPQi_nG4jQKoDFJ-XCx1fjVVGlqBsPj5Pf1-SGT
0 https
https://mail.google.com/mail/?auth=DQAAAL8AAABzUu3D7vQTObQbtiQU-X_6NnwgrsDnQe_7yXrUrFrniwP5j04Q9jVgc203CAd7rwHnO0tvXTI8MSlRISJz3tGutyOc_uw5khR4FHviJuyTEuxKJZPUmQXnIWxZf_CQoJXGGaxn1kT0scUyrxiBjTfXllUWBVa5iuEzL2lgbAINKmSlLmyg3BaTFb-l0nmDdqGznAJMDgspYtD8iBTcPnOWpGkHXUVtkE0C6KK_3z1eULl0wEne4aU0LNJhlhUa8Xk
+0 www.ccrexplorers.com 0 / 1 0 0
1499619054 1468082755 0 bb_lastvisit 1468083054 0
http http://www.ccrexplorers.com/forumdisplay.php?f=17
+0 .theregister.co.uk 1 / 1 0 1
1471944077 1468278443 0 __cfduid
dbda67dd4386142349a936c252ebac7391440408077 0 unused unused
+0 nir.theregister.co.uk 0 / 1 0 0
1470697643 0 0 c 1/front.front.578426ab 0 http
http://nir.theregister.co.uk/?g=c&g=sa&s=c/front.front
+0 nir.theregister.co.uk 0 / 1 0 0
1499814443 0 0 sa 1 0 http
http://nir.theregister.co.uk/?g=c&g=sa&s=c/front.front
+0 .regmedia.co.uk 1 / 1 0 1 1471944079
1468278443 0 __cfduid
d82e13431caf77499b09ccf54c21999941440408079 0 unused unused
+0 .google.co.uk 1 / 1 0 0 1497632093
1468278489 0 SID
DQAAAMkAAACuniK1mc17JMX-o-sfAVqvl0EWP0kiNpQg4lWeslWBnU_km8BK6Eww-1mC6zvnm7Jiv2vft4BOwWiAOmRzN66pbzxGNxKKGzSz2GNdWrcwvuYyQHkevwrtwmKmZGDKsgLljofq6NyNf0AP5xGXfHj18awhbbnymmv5UaDqypGx7FvptGQSMQkj_1hY6NJ5pflIfSnKeEn0Y2mEVyhc1qUiGcJhVKqIRd6xaGKk7l235kOpqxjGK7I4_jTQaORZbp2-RWozAg7SHESSaOpxQ0ZT
0 unused unused
+0 .google.co.uk 1 / 1 0 1 1497632093
1468278489 0 HSID ANVWylWAbjjzFxKxI 0 unused unused
+0 .google.co.uk 1 / 1 1 1 1497632093
1468278489 0 SSID ANtGv1CSBG3CWbdtr 0 unused unused
+0 .google.co.uk 1 / 1 0 0 1497632093
1468278489 0 APISID IeJTJt20VmceF7bS/AACvc5cSFPpX8FJMj 0
unused unused
+0 .google.co.uk 1 / 1 1 0 1497632093
1468278489 0 SAPISID baCIIjpj-o3XQCkH/A-WEZgPvnNnguijDQ 0
unused unused
+0 .google.co.uk 1 / 1 0 1 1484089690
0 0 NID
81=BGSfpwd63LrhVNUii2KYHfuyCUKzQv2Zg2ik1H_byGynWUgd9_q-kY48oCRapIewLtzMNYtf2KzYBk0_5OoAtNrD-0YSqXDzKalLWfQ8Vxwyywy79YDvAaX_3tprJzjp
0 unused unused
+0 .bbc.co.uk 1 / 1 0 0 1595541997
1470493359 0 BBC-UID
35e7d9a5837b2e9d026d30f521339ac6826814226444c1ee4a2134fef248fe180NetSurf/3.6%20(Linux)
0 unused unused
+0 news.bbc.co.uk 0 / 1 0 0 1500933997
1469574171 0 BBC-UID
25a73995333b5e9d8ea88a16a17c7b8beea45e555eb863e913853a4de2dcbdb80NetSurf%2f3%2e6%20%28Linux%29
0 http http://news.bbc.co.uk/
+0 en.wikipedia.org 0 / 1 1 1
1473249600 1470493303 0 WMF-Last-Access 06-Aug-2016 0
http http://en.wikipedia.org/wiki/Main_Page
diff --git a/test/hashtable.c b/test/hashtable.c
index d69b108..9f46e4c 100644
--- a/test/hashtable.c
+++ b/test/hashtable.c
@@ -56,7 +56,7 @@ static const struct test_pairs match_tests[] = {
static void match_hashtable_create(void)
{
- int idx;
+ unsigned int idx;
match_hash_a = hash_create(79);
ck_assert(match_hash_a != NULL);
@@ -246,7 +246,7 @@ END_TEST
/* Suite */
-Suite *hashtable_suite(void)
+static Suite *hashtable_suite(void)
{
Suite *s;
TCase *tc_create;
diff --git a/test/messages.c b/test/messages.c
index bc6daea..050b6d4 100644
--- a/test/messages.c
+++ b/test/messages.c
@@ -41,7 +41,7 @@ const char *test_messages_path = "test/data/Messages";
struct message_test_vec_s {
int test;
- char *res;
+ const char *res;
};
struct message_test_vec_s message_errorcode_test_vec[] = {
@@ -101,7 +101,7 @@ START_TEST(message_file_load_test)
}
END_TEST
-TCase *message_session_case_create(void)
+static TCase *message_session_case_create(void)
{
TCase *tc;
tc = tcase_create("Message adding");
@@ -115,7 +115,7 @@ TCase *message_session_case_create(void)
}
-Suite *message_suite_create(void)
+static Suite *message_suite_create(void)
{
Suite *s;
s = suite_create("message");
diff --git a/test/nsoption.c b/test/nsoption.c
index 76cfeaf..3b75ca7 100644
--- a/test/nsoption.c
+++ b/test/nsoption.c
@@ -40,7 +40,7 @@ const char *test_choices_full_path = "test/data/Choices-full";
const char *test_choices_missing_path = "test/data/Choices-missing";
-nserror gui_options_init_defaults(struct nsoption_s *defaults)
+static nserror gui_options_init_defaults(struct nsoption_s *defaults)
{
/* Set defaults for absent option strings */
nsoption_setnull_charp(ca_bundle,
strdup("NetSurf:Resources.ca-bundle"));
@@ -134,7 +134,9 @@ START_TEST(nsoption_session_test)
{
nserror res;
int argc = 2;
- char *argv[] = { "nsoption", "--http_proxy_host=fooo", NULL};
+ char arg1[] = "nsoption";
+ char arg2[] = "--http_proxy_host=fooo";
+ char *argv[] = { arg1, arg2, NULL};
char *outnam;
res = nsoption_init(gui_options_init_defaults, NULL, NULL);
@@ -165,6 +167,7 @@ START_TEST(nsoption_session_test)
/* check for the correct answer */
ck_assert_int_eq(cmp(outnam, test_choices_full_path), 0);
+ /* remove test output */
unlink(outnam);
res = nsoption_finalise(NULL, NULL);
@@ -173,7 +176,7 @@ START_TEST(nsoption_session_test)
}
END_TEST
-TCase *nsoption_session_case_create(void)
+static TCase *nsoption_session_case_create(void)
{
TCase *tc;
tc = tcase_create("Full session");
@@ -263,7 +266,7 @@ END_TEST
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
-TCase *nsoption_format_case_create(void)
+static TCase *nsoption_format_case_create(void)
{
TCase *tc;
tc = tcase_create("Formatted output");
@@ -366,13 +369,11 @@ START_TEST(nsoption_commandline_test)
{
nserror res;
int argc = 4;
- char *argv[] = {
- "nsoption",
- "--http_proxy_host=fooo",
- "--http_proxy_port",
- "not-option",
- NULL
- };
+ char arg1[] = "nsoption";
+ char arg2[] = "--http_proxy_host=fooo";
+ char arg3[] = "--http_proxy_port";
+ char arg4[] = "not-option";
+ char *argv[] = { arg1, arg2, arg3, arg4, NULL};
/* commandline */
res = nsoption_commandline(&argc, &argv[0], NULL);
@@ -383,7 +384,7 @@ START_TEST(nsoption_commandline_test)
}
END_TEST
-TCase *nsoption_case_create(void)
+static TCase *nsoption_case_create(void)
{
TCase *tc;
tc = tcase_create("File operations");
@@ -508,7 +509,9 @@ START_TEST(nsoption_api_commandline_no_args_test)
{
nserror res;
int argc = 2;
- char *argv[] = { "nsoption", "--http_proxy_host=fooo", NULL};
+ char arg1[] = "nsoption";
+ char arg2[] = "--http_proxy_host=fooo";
+ char *argv[] = { arg1, arg2, NULL};
/* commandline with no argument count or init */
res = nsoption_commandline(NULL, &argv[0], NULL);
@@ -527,7 +530,9 @@ START_TEST(nsoption_api_commandline_no_init_test)
{
nserror res;
int argc = 2;
- char *argv[] = { "nsoption", "--http_proxy_host=fooo", NULL};
+ char arg1[] = "nsoption";
+ char arg2[] = "--http_proxy_host=fooo";
+ char *argv[] = { arg1, arg2, NULL};
/* write with path but no init */
res = nsoption_commandline(&argc, &argv[0], NULL);
@@ -588,7 +593,7 @@ static nserror failing_init_cb(struct nsoption_s *defaults)
}
/**
- * Test default initialisation waith failing callback
+ * Test default initialisation with failing callback
*/
START_TEST(nsoption_api_init_failcb_test)
{
@@ -633,7 +638,7 @@ START_TEST(nsoption_api_snoptionf_no_init_test)
END_TEST
-TCase *nsoption_api_case_create(void)
+static TCase *nsoption_api_case_create(void)
{
TCase *tc;
tc = tcase_create("API checks");
@@ -659,7 +664,7 @@ TCase *nsoption_api_case_create(void)
}
-Suite *nsoption_suite_create(void)
+static Suite *nsoption_suite_create(void)
{
Suite *s;
s = suite_create("User options");
diff --git a/test/time.c b/test/time.c
index 8598646..b2d465c 100644
--- a/test/time.c
+++ b/test/time.c
@@ -24,8 +24,6 @@
#include <stdlib.h>
#include <check.h>
-#include <curl/curl.h>
-
#include "utils/errors.h"
#include "utils/time.h"
@@ -36,19 +34,292 @@ struct test_string_pair {
const char* expected;
};
+struct test_bad_string {
+ const char* test;
+ nserror res;
+};
+
static const struct test_string_pair date_string_tests[] = {
{
.test = "Thu, 01 Jan 1970 00:00:00 GMT",
.expected = "Thu, 01 Jan 1970 00:00:00 GMT"
},
{
+ .test = "Tue, 16 Feb 1999 19:45:12 GMT",
+ .expected = "Tue, 16 Feb 1999 19:45:12 GMT"
+ },
+ {
+ .test = "Sun, 16 Mar 1980 19:45:12 GMT",
+ .expected = "Sun, 16 Mar 1980 19:45:12 GMT"
+ },
+ {
+ .test = "Tue, 16 Apr 2013 19:45:12 GMT",
+ .expected = "Tue, 16 Apr 2013 19:45:12 GMT"
+ },
+ {
+ .test = "Tue, 16 May 2000 19:45:12 GMT",
+ .expected = "Tue, 16 May 2000 19:45:12 GMT"
+ },
+ {
+ .test = "Tue, 12 Jun 2001 12:12:12 GMT",
+ .expected = "Tue, 12 Jun 2001 12:12:12 GMT"
+ },
+ {
+ .test = "Thu, 16 Jul 2207 12:45:12 GMT",
+ .expected = "Thu, 16 Jul 2207 12:45:12 GMT"
+ },
+ {
.test = "Thu, 16 Aug 2007 19:45:12 GMT",
.expected = "Thu, 16 Aug 2007 19:45:12 GMT"
},
+ {
+ .test = "Tue, 16 Sep 3456 00:45:12 GMT",
+ .expected = "Tue, 16 Sep 3456 00:45:12 GMT"
+ },
+ {
+ .test = "Sun, 16 Oct 1988 19:45:59 GMT",
+ .expected = "Sun, 16 Oct 1988 19:45:59 GMT"
+ },
+ {
+ .test = "Tue, 16 Nov 1971 19:59:12 GMT",
+ .expected = "Tue, 16 Nov 1971 19:59:12 GMT"
+ },
+ {
+ .test = "Fri, 16 Dec 1977 23:45:12 GMT",
+ .expected = "Fri, 16 Dec 1977 23:45:12 GMT"
+ },
+ {
+ .test = " 16 Dec 1977 23:45:12 GMT",
+ .expected = "Fri, 16 Dec 1977 23:45:12 GMT"
+ },
+ {
+ .test = " 16 Dec 1977 23:45 GMT",
+ .expected = "Fri, 16 Dec 1977 23:45:00 GMT"
+ },
+ {
+ .test = "23:59 16 Dec 1977 GMT",
+ .expected = "Fri, 16 Dec 1977 23:59:00 GMT"
+ },
+ {
+ .test = "23:59 16 Dec 1977 UTC",
+ .expected = "Fri, 16 Dec 1977 23:59:00 GMT"
+ },
+ {
+ .test = "1977 GMT 23:59 16 Dec",
+ .expected = "Fri, 16 Dec 1977 23:59:00 GMT"
+ },
+ {
+ .test = "1977 Dec GMT 16",
+ .expected = "Fri, 16 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "1977 Dec 12",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "1977 12 Dec",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "Dec 1977 12",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "12 Dec 1977",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "12 Dec 77",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "12 77 Dec",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "77 12 Dec",
+ .expected = "Mon, 12 Dec 1977 00:00:00 GMT"
+ },
+ {
+ .test = "12 12 Dec",
+ .expected = "Wed, 12 Dec 2012 00:00:00 GMT"
+ },
+ {
+ .test = "5 12 Dec",
+ .expected = "Wed, 05 Dec 2012 00:00:00 GMT"
+ },
+ {
+ .test = "12 5 Dec",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "12/5/Dec",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "Dec-12/2005/",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "12-5-Dec",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "2005-12-Dec",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "2005-Dec-12",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "2005-dec-12",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "2005-dEC-12",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "20051212",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "20051212 GMT",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "20051212 +0000",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "20051212 UTC",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "20051212 00:00 UTC",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "00:00 20051212 UTC",
+ .expected = "Mon, 12 Dec 2005 00:00:00 GMT"
+ },
+ {
+ .test = "00:00:59 20051212 UTC",
+ .expected = "Mon, 12 Dec 2005 00:00:59 GMT"
+ },
+ {
+ .test = "00:00:60 20051212 UTC", /* leap second */
+ .expected = "Mon, 12 Dec 2005 00:01:00 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 GMT",
+ .expected = "Thu, 11 Aug 2016 08:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 UTC",
+ .expected = "Thu, 11 Aug 2016 08:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0000",
+ .expected = "Thu, 11 Aug 2016 08:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0000",
+ .expected = "Thu, 11 Aug 2016 08:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0001",
+ .expected = "Thu, 11 Aug 2016 08:46:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0001",
+ .expected = "Thu, 11 Aug 2016 08:48:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0030",
+ .expected = "Thu, 11 Aug 2016 08:17:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0030",
+ .expected = "Thu, 11 Aug 2016 09:17:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0059",
+ .expected = "Thu, 11 Aug 2016 07:48:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0059",
+ .expected = "Thu, 11 Aug 2016 09:46:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0100",
+ .expected = "Thu, 11 Aug 2016 07:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0100",
+ .expected = "Thu, 11 Aug 2016 09:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +1200",
+ .expected = "Wed, 10 Aug 2016 20:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -1200",
+ .expected = "Thu, 11 Aug 2016 20:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0060",
+ .expected = "Thu, 11 Aug 2016 07:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0060",
+ .expected = "Thu, 11 Aug 2016 09:47:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 +0070",
+ .expected = "Thu, 11 Aug 2016 07:37:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 -0070",
+ .expected = "Thu, 11 Aug 2016 09:57:30 GMT"
+ },
+ {
+ .test = "Thu, 11 Aug 2016 08:47:30 BST",
+ .expected = "Thu, 11 Aug 2016 07:47:30 GMT"
+ },
+};
+
+
+static const struct test_bad_string date_bad_string_tests[] = {
+ {
+ .test = NULL,
+ .res = NSERROR_BAD_PARAMETER
+ },
+ {
+ .test = "",
+ .res = NSERROR_INVALID
+ },
+ {
+ .test = "Th",
+ .res = NSERROR_INVALID
+ },
+ {
+ .test = "5",
+ .res = NSERROR_INVALID
+ },
+ {
+ .test = "5",
+ .res = NSERROR_INVALID
+ },
+ {
+ .test = "dsflihs9l84toswuhfsif74f",
+ .res = NSERROR_INVALID
+ },
};
/**
- * url creation test
+ * Date string comparason test
*/
START_TEST(date_string_compare)
{
@@ -57,16 +328,25 @@ START_TEST(date_string_compare)
const struct test_string_pair *t = &date_string_tests[_i];
res = nsc_strntimet(t->test, strlen(t->test), &time_out);
- if (time_out < 0) {
- /* result must be invalid */
- ck_assert(res != NSERROR_OK);
+ ck_assert(res == NSERROR_OK);
+ ck_assert_str_eq(rfc1123_date(time_out), t->expected);
+}
+END_TEST
- } else {
- /* result must be valid */
- ck_assert(res == NSERROR_OK);
+/**
+ * Date string conversion bad data test
+ */
+START_TEST(date_bad_string)
+{
+ nserror res;
+ time_t time_out;
+ const struct test_bad_string *t = &date_bad_string_tests[_i];
- ck_assert_str_eq(rfc1123_date(time_out), t->expected);
- }
+ res = nsc_strntimet(t->test,
+ t->test != NULL ? strlen(t->test) : 0,
+ &time_out);
+ ck_assert(res != NSERROR_OK);
+ ck_assert(res == t->res);
}
END_TEST
@@ -76,17 +356,28 @@ static Suite *time_suite(void)
{
Suite *s;
TCase *tc_date_string_compare;
+ TCase *tc_date_bad_string;
s = suite_create("time");
/* date parsing: string comparason */
- tc_date_string_compare = tcase_create("date string to time_t");
+ tc_date_string_compare = tcase_create(
+ "date string to time_t");
+
+ /* date parsing: bad string handling */
+ tc_date_bad_string = tcase_create(
+ "date string to time_t (bad input)");
tcase_add_loop_test(tc_date_string_compare,
date_string_compare,
0, NELEMS(date_string_tests));
suite_add_tcase(s, tc_date_string_compare);
+ tcase_add_loop_test(tc_date_bad_string,
+ date_bad_string,
+ 0, NELEMS(date_bad_string_tests));
+ suite_add_tcase(s, tc_date_bad_string);
+
return s;
}
diff --git a/test/urldbtest.c b/test/urldbtest.c
index e5e5573..bc707ed 100644
--- a/test/urldbtest.c
+++ b/test/urldbtest.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <check.h>
#include <libwapcaplet/libwapcaplet.h>
@@ -34,10 +35,18 @@
#include "utils/log.h"
#include "utils/corestrings.h"
#include "utils/nsurl.h"
+#include "utils/nsoption.h"
#include "netsurf/url_db.h"
+#include "netsurf/cookie_db.h"
+#include "netsurf/bitmap.h"
#include "content/urldb.h"
+#include "desktop/gui_internal.h"
+#include "desktop/cookie_manager.h"
const char *test_urldb_path = "test/data/urldb";
+const char *test_cookies_path = "test/data/cookies";
+
+const char *wikipedia_url = "http://www.wikipedia.org/";
struct netsurf_table *guit = NULL;
@@ -117,14 +126,48 @@ static char *test_urldb_get_cookie(const char *url)
/*************************************************/
+/* mock table callbacks */
+static void destroy_bitmap(void *b)
+{
+}
+
+struct gui_bitmap_table tst_bitmap_table = {
+ .destroy = destroy_bitmap,
+};
+
+struct netsurf_table tst_table = {
+ .bitmap = &tst_bitmap_table,
+};
+
/** urldb create fixture */
static void urldb_create(void)
{
nserror res;
+
+ /* mock bitmap interface */
+ guit = &tst_table;
+
res = corestrings_init();
ck_assert_int_eq(res, NSERROR_OK);
}
+/** urldb create pre-loaded db fixture */
+static void urldb_create_loaded(void)
+{
+ nserror res;
+
+ /* mock bitmap interface */
+ guit = &tst_table;
+
+ res = corestrings_init();
+ ck_assert_int_eq(res, NSERROR_OK);
+
+ res = urldb_load(test_urldb_path);
+ ck_assert_int_eq(res, NSERROR_OK);
+
+ urldb_load_cookies(test_cookies_path);
+}
+
static void urldb_lwc_iterator(lwc_string *str, void *pw)
{
int *scount = pw;
@@ -135,11 +178,14 @@ static void urldb_lwc_iterator(lwc_string *str, void *pw)
(*scount)++;
}
-/** urldb teardown fixture */
+
+/** urldb teardown fixture with destroy */
static void urldb_teardown(void)
{
int scount = 0;
+ urldb_destroy();
+
corestrings_fini();
LOG("Remaining lwc strings:");
@@ -147,6 +193,10 @@ static void urldb_teardown(void)
ck_assert_int_eq(scount, 0);
}
+
+
+
+
START_TEST(urldb_original_test)
{
struct host_part *h;
@@ -159,24 +209,16 @@ START_TEST(urldb_original_test)
char *path_query;
h = urldb_add_host("127.0.0.1");
- if (!h) {
- LOG("failed adding host");
- return 1;
- }
+ ck_assert_msg(h != NULL, "failed adding host");
h = urldb_add_host("intranet");
- if (!h) {
- LOG("failed adding host");
- return 1;
- }
+ ck_assert_msg(h != NULL, "failed adding host");
url = make_url("http://intranet/");
scheme = nsurl_get_component(url, NSURL_SCHEME);
p = urldb_add_path(scheme, 0, h, strdup("/"), NULL, url);
- if (!p) {
- LOG("failed adding path");
- return 1;
- }
+ ck_assert_msg(p != NULL, "failed adding path");
+
lwc_string_unref(scheme);
urldb_set_url_title(url, "foo");
@@ -187,10 +229,7 @@ START_TEST(urldb_original_test)
/* Get host entry */
h = urldb_add_host("netsurf.strcprstskrzkrk.co.uk");
- if (!h) {
- LOG("failed adding host");
- return 1;
- }
+ ck_assert_msg(h != NULL, "failed adding host");
/* Get path entry */
url =
make_url("http://netsurf.strcprstskrzkrk.co.uk/path/to/resource.htm?a=b");
@@ -198,26 +237,20 @@ START_TEST(urldb_original_test)
path_query = make_path_query(url);
fragment = make_lwc("zz");
p = urldb_add_path(scheme, 0, h, strdup(path_query), fragment, url);
- if (!p) {
- LOG("failed adding path");
- return 1;
- }
+ ck_assert_msg(p != NULL, "failed adding path");
+
lwc_string_unref(fragment);
fragment = make_lwc("aa");
p = urldb_add_path(scheme, 0, h, strdup(path_query), fragment, url);
- if (!p) {
- LOG("failed adding path");
- return 1;
- }
+ ck_assert_msg(p != NULL, "failed adding path");
+
lwc_string_unref(fragment);
fragment = make_lwc("yy");
p = urldb_add_path(scheme, 0, h, strdup(path_query), fragment, url);
- if (!p) {
- LOG("failed adding path");
- return 1;
- }
+ ck_assert_msg(p != NULL, "failed adding path");
+
free(path_query);
lwc_string_unref(fragment);
lwc_string_unref(scheme);
@@ -261,118 +294,117 @@ START_TEST(urldb_original_test)
/* Mantis bug #993 */
url = make_url("http:moodle.org");
- assert(urldb_add_url(url) == true);
- assert(urldb_get_url(url) != NULL);
+ ck_assert(urldb_add_url(url) == true);
+ ck_assert(urldb_get_url(url) != NULL);
nsurl_unref(url);
/* Mantis bug #993 */
url = make_url("http://a_a/");
- assert(urldb_add_url(url));
- assert(urldb_get_url(url));
+ ck_assert(urldb_add_url(url));
+ ck_assert(urldb_get_url(url));
nsurl_unref(url);
/* Mantis bug #996 */
url = make_url("http://[email protected]/");
if (urldb_add_url(url)) {
LOG("added %s", nsurl_access(url));
- assert(urldb_get_url(url) != NULL);
+ ck_assert(urldb_get_url(url) != NULL);
}
nsurl_unref(url);
/* Mantis bug #913 */
url = make_url("http://www2.2checkout.com/");
- assert(urldb_add_url(url));
- assert(urldb_get_url(url));
+ ck_assert(urldb_add_url(url));
+ ck_assert(urldb_get_url(url));
nsurl_unref(url);
/* Numeric subdomains */
url =
make_url("http://2.bp.blogspot.com/_448y6kVhntg/TSekubcLJ7I/AAAAAAAAHJE/yZTsV5xT5t4/s1600/covers.jpg");
- assert(urldb_add_url(url));
- assert(urldb_get_url(url));
+ ck_assert(urldb_add_url(url));
+ ck_assert(urldb_get_url(url));
nsurl_unref(url);
/* Valid path */
- assert(test_urldb_set_cookie("name=value;Path=/\r\n",
"http://www.google.com/", NULL));
+ ck_assert(test_urldb_set_cookie("name=value;Path=/\r\n",
"http://www.google.com/", NULL));
/* Valid path (non-root directory) */
- assert(test_urldb_set_cookie("name=value;Path=/foo/bar/\r\n",
"http://www.example.org/foo/bar/", NULL));
+ ck_assert(test_urldb_set_cookie("name=value;Path=/foo/bar/\r\n",
"http://www.example.org/foo/bar/", NULL));
/* Defaulted path */
- assert(test_urldb_set_cookie("name=value\r\n",
"http://www.example.org/foo/bar/baz/bat.html", NULL));
-
assert(test_urldb_get_cookie("http://www.example.org/foo/bar/baz/quux.htm"));
+ ck_assert(test_urldb_set_cookie("name=value\r\n",
"http://www.example.org/foo/bar/baz/bat.html", NULL));
+
ck_assert(test_urldb_get_cookie("http://www.example.org/foo/bar/baz/quux.htm"));
/* Defaulted path with no non-leaf path segments */
- assert(test_urldb_set_cookie("name=value\r\n",
"http://no-non-leaf.example.org/index.html", NULL));
-
assert(test_urldb_get_cookie("http://no-non-leaf.example.org/page2.html"));
- assert(test_urldb_get_cookie("http://no-non-leaf.example.org/"));
+ ck_assert(test_urldb_set_cookie("name=value\r\n",
"http://no-non-leaf.example.org/index.html", NULL));
+
ck_assert(test_urldb_get_cookie("http://no-non-leaf.example.org/page2.html"));
+ ck_assert(test_urldb_get_cookie("http://no-non-leaf.example.org/"));
/* Valid path (includes leafname) */
-
assert(test_urldb_set_cookie("name=value;Version=1;Path=/index.cgi\r\n",
"http://example.org/index.cgi", NULL));
- assert(test_urldb_get_cookie("http://example.org/index.cgi"));
+
ck_assert(test_urldb_set_cookie("name=value;Version=1;Path=/index.cgi\r\n",
"http://example.org/index.cgi", NULL));
+ ck_assert(test_urldb_get_cookie("http://example.org/index.cgi"));
/* Valid path (includes leafname in non-root directory) */
- assert(test_urldb_set_cookie("name=value;Path=/foo/index.html\r\n",
"http://www.example.org/foo/index.html", NULL));
+ ck_assert(test_urldb_set_cookie("name=value;Path=/foo/index.html\r\n",
"http://www.example.org/foo/index.html", NULL));
/* Should _not_ match the above, as the leafnames differ */
- assert(test_urldb_get_cookie("http://www.example.org/foo/bar.html") ==
NULL);
+ ck_assert(test_urldb_get_cookie("http://www.example.org/foo/bar.html")
== NULL);
/* Invalid path (contains different leafname) */
- assert(test_urldb_set_cookie("name=value;Path=/index.html\r\n",
"http://example.org/index.htm", NULL) == false);
+ ck_assert(test_urldb_set_cookie("name=value;Path=/index.html\r\n",
"http://example.org/index.htm", NULL) == false);
/* Invalid path (contains leafname in different directory) */
- assert(test_urldb_set_cookie("name=value;Path=/foo/index.html\r\n",
"http://www.example.org/bar/index.html", NULL) == false);
+ ck_assert(test_urldb_set_cookie("name=value;Path=/foo/index.html\r\n",
"http://www.example.org/bar/index.html", NULL) == false);
/* Test partial domain match with IP address failing */
- assert(test_urldb_set_cookie("name=value;Domain=.foo.org\r\n",
"http://192.168.0.1/", NULL) == false);
+ ck_assert(test_urldb_set_cookie("name=value;Domain=.foo.org\r\n",
"http://192.168.0.1/", NULL) == false);
/* Test handling of non-domain cookie sent by server (domain part should
* be ignored) */
- assert(test_urldb_set_cookie("foo=value;Domain=blah.com\r\n",
"http://www.example.com/", NULL));
- assert(strcmp(test_urldb_get_cookie("http://www.example.com/"),
"foo=value") == 0);
+ ck_assert(test_urldb_set_cookie("foo=value;Domain=blah.com\r\n",
"http://www.example.com/", NULL));
+ ck_assert(strcmp(test_urldb_get_cookie("http://www.example.com/"),
"foo=value") == 0);
/* Test handling of domain cookie from wrong host (strictly invalid but
* required to support the real world) */
- assert(test_urldb_set_cookie("name=value;Domain=.example.com\r\n",
"http://foo.bar.example.com/", NULL));
- assert(strcmp(test_urldb_get_cookie("http://www.example.com/"),
"foo=value; name=value") == 0);
+ ck_assert(test_urldb_set_cookie("name=value;Domain=.example.com\r\n",
"http://foo.bar.example.com/", NULL));
+ ck_assert(strcmp(test_urldb_get_cookie("http://www.example.com/"),
"foo=value; name=value") == 0);
/* Test presence of separators in cookie value */
-
assert(test_urldb_set_cookie("name=\"value=foo\\\\bar\\\\\\\";\\\\baz=quux\";Version=1\r\n",
"http://www.example.org/", NULL));
- assert(strcmp(test_urldb_get_cookie("http://www.example.org/"),
"$Version=1; name=\"value=foo\\\\bar\\\\\\\";\\\\baz=quux\"") == 0);
+
ck_assert(test_urldb_set_cookie("name=\"value=foo\\\\bar\\\\\\\";\\\\baz=quux\";Version=1\r\n",
"http://www.example.org/", NULL));
+ ck_assert(strcmp(test_urldb_get_cookie("http://www.example.org/"),
"$Version=1; name=\"value=foo\\\\bar\\\\\\\";\\\\baz=quux\"") == 0);
/* Test cookie with blank value */
- assert(test_urldb_set_cookie("a=\r\n", "http://www.example.net/",
NULL));
- assert(strcmp(test_urldb_get_cookie("http://www.example.net/"), "a=")
== 0);
+ ck_assert(test_urldb_set_cookie("a=\r\n", "http://www.example.net/",
NULL));
+ ck_assert(strcmp(test_urldb_get_cookie("http://www.example.net/"),
"a=") == 0);
/* Test specification of multiple cookies in one header */
- assert(test_urldb_set_cookie("a=b, foo=bar; Path=/\r\n",
"http://www.example.net/", NULL));
- assert(strcmp(test_urldb_get_cookie("http://www.example.net/"), "a=b;
foo=bar") == 0);
+ ck_assert(test_urldb_set_cookie("a=b, foo=bar; Path=/\r\n",
"http://www.example.net/", NULL));
+ ck_assert(strcmp(test_urldb_get_cookie("http://www.example.net/"),
"a=b; foo=bar") == 0);
/* Test use of separators in unquoted cookie value */
- assert(test_urldb_set_cookie("foo=moo@foo:blah?moar\\ text\r\n",
"http://example.com/", NULL));
- assert(strcmp(test_urldb_get_cookie("http://example.com/"),
"foo=moo@foo:blah?moar\\ text; name=value") == 0);
+ ck_assert(test_urldb_set_cookie("foo=moo@foo:blah?moar\\ text\r\n",
"http://example.com/", NULL));
+ ck_assert(strcmp(test_urldb_get_cookie("http://example.com/"),
"foo=moo@foo:blah?moar\\ text; name=value") == 0);
/* Test use of unnecessary quotes */
- assert(test_urldb_set_cookie("foo=\"hello\";Version=1,bar=bat\r\n",
"http://example.com/", NULL));
- assert(strcmp(test_urldb_get_cookie("http://example.com/"),
"foo=\"hello\"; bar=bat; name=value") == 0);
+ ck_assert(test_urldb_set_cookie("foo=\"hello\";Version=1,bar=bat\r\n",
"http://example.com/", NULL));
+ ck_assert(strcmp(test_urldb_get_cookie("http://example.com/"),
"foo=\"hello\"; bar=bat; name=value") == 0);
/* Test domain matching in unverifiable transactions */
- assert(test_urldb_set_cookie("foo=bar; domain=.example.tld\r\n",
"http://www.foo.example.tld/", "http://bar.example.tld/"));
- assert(strcmp(test_urldb_get_cookie("http://www.foo.example.tld/"),
"foo=bar") == 0);
+ ck_assert(test_urldb_set_cookie("foo=bar; domain=.example.tld\r\n",
"http://www.foo.example.tld/", "http://bar.example.tld/"));
+ ck_assert(strcmp(test_urldb_get_cookie("http://www.foo.example.tld/"),
"foo=bar") == 0);
/* Test expiry */
- assert(test_urldb_set_cookie("foo=bar", "http://expires.com/", NULL));
- assert(strcmp(test_urldb_get_cookie("http://expires.com/"), "foo=bar")
== 0);
- assert(test_urldb_set_cookie("foo=bar; expires=Thu, 01-Jan-1970
00:00:01 GMT\r\n", "http://expires.com/", NULL));
- assert(test_urldb_get_cookie("http://expires.com/") == NULL);
+ ck_assert(test_urldb_set_cookie("foo=bar", "http://expires.com/",
NULL));
+ ck_assert(strcmp(test_urldb_get_cookie("http://expires.com/"),
"foo=bar") == 0);
+ ck_assert(test_urldb_set_cookie("foo=bar; expires=Thu, 01-Jan-1970
00:00:01 GMT\r\n", "http://expires.com/", NULL));
+ ck_assert(test_urldb_get_cookie("http://expires.com/") == NULL);
urldb_dump();
- urldb_destroy();
}
END_TEST
-TCase *urldb_original_case_create(void)
+static TCase *urldb_original_case_create(void)
{
TCase *tc;
- tc = tcase_create("Original urldb tests");
+ tc = tcase_create("Original_tests");
/* ensure corestrings are initialised and finalised for every test */
tcase_add_checked_fixture(tc,
@@ -387,18 +419,40 @@ TCase *urldb_original_case_create(void)
START_TEST(urldb_session_test)
{
nserror res;
+ char *outnam;
+
+ /* writing output requires options initialising */
+ res = nsoption_init(NULL, NULL, NULL);
+ ck_assert_int_eq(res, NSERROR_OK);
res = urldb_load(test_urldb_path);
ck_assert_int_eq(res, NSERROR_OK);
- urldb_destroy();
+ urldb_load_cookies(test_cookies_path);
+
+ /* write database out */
+ outnam = tmpnam(NULL);
+ res = urldb_save(outnam);
+ ck_assert_int_eq(res, NSERROR_OK);
+
+ /* remove test output */
+ unlink(outnam);
+
+ /* write cookies out */
+ urldb_save_cookies(outnam);
+
+ /* finalise options */
+ res = nsoption_finalise(NULL, NULL);
+ ck_assert_int_eq(res, NSERROR_OK);
+
}
END_TEST
-TCase *urldb_session_case_create(void)
+
+static TCase *urldb_session_case_create(void)
{
TCase *tc;
- tc = tcase_create("Full session");
+ tc = tcase_create("Full_session");
/* ensure corestrings are initialised and finalised for every test */
tcase_add_checked_fixture(tc,
@@ -410,6 +464,313 @@ TCase *urldb_session_case_create(void)
return tc;
}
+static int cb_count;
+
+static bool urldb_iterate_entries_cb(nsurl *url, const struct url_data *data)
+{
+ LOG("url: %s", nsurl_access(url));
+ /* fprintf(stderr, "url:%s\ntitle:%s\n\n",nsurl_access(url),
data->title); */
+ cb_count++;
+ return true;
+}
+
+START_TEST(urldb_iterate_entries_test)
+{
+ urldb_iterate_entries(urldb_iterate_entries_cb);
+}
+END_TEST
+
+/**
+ * iterate through partial matches
+ */
+START_TEST(urldb_iterate_partial_www_test)
+{
+ cb_count = 0;
+ urldb_iterate_partial("www", urldb_iterate_entries_cb);
+ ck_assert_int_eq(cb_count, 7);
+
+}
+END_TEST
+
+/**
+ * iterate through partial matches
+ */
+START_TEST(urldb_iterate_partial_nomatch_test)
+{
+ cb_count = 0;
+ urldb_iterate_partial("/", urldb_iterate_entries_cb);
+ ck_assert_int_eq(cb_count, 0);
+
+}
+END_TEST
+
+/**
+ * iterate through partial matches
+ */
+START_TEST(urldb_iterate_partial_add_test)
+{
+ nsurl *url;
+
+ cb_count = 0;
+ urldb_iterate_partial("wikipedia", urldb_iterate_entries_cb);
+ ck_assert_int_eq(cb_count, 0);
+
+ url = make_url(wikipedia_url);
+ urldb_add_url(url);
+ nsurl_unref(url);
+
+ cb_count = 0;
+ urldb_iterate_partial("wikipedia", urldb_iterate_entries_cb);
+ ck_assert_int_eq(cb_count, 1);
+}
+END_TEST
+
+/**
+ * iterate through partial matches
+ */
+START_TEST(urldb_iterate_partial_path_test)
+{
+
+ cb_count = 0;
+ urldb_iterate_partial("en.wikipedia.org/wiki",
urldb_iterate_entries_cb);
+ ck_assert_int_eq(cb_count, 2);
+}
+END_TEST
+
+/**
+ * iterate through partial matches
+ */
+START_TEST(urldb_iterate_partial_numeric_test)
+{
+ nsurl *url;
+
+ cb_count = 0;
+ urldb_iterate_partial("192.168.7.1/", urldb_iterate_entries_cb);
+ ck_assert_int_eq(cb_count, 0);
+
+ url = make_url("http://192.168.7.1/index.html");
+ urldb_add_url(url);
+ nsurl_unref(url);
+
+ cb_count = 0;
+ urldb_iterate_partial("192.168.7.1/", urldb_iterate_entries_cb);
+ ck_assert_int_eq(cb_count, 1);
+
+
+}
+END_TEST
+
+START_TEST(urldb_auth_details_test)
+{
+ nsurl *url;
+ const char *res;
+ const char *auth = "mooooo";
+
+ url = make_url(wikipedia_url);
+ urldb_set_auth_details(url, "tree", auth);
+
+ res = urldb_get_auth_details(url, "tree");
+ ck_assert_str_eq(res, auth);
+
+ nsurl_unref(url);
+}
+END_TEST
+
+
+START_TEST(urldb_thumbnail_test)
+{
+ nsurl *url;
+ struct bitmap *bmap;
+ struct bitmap *res;
+ bool set;
+
+ url = make_url(wikipedia_url);
+ bmap = (struct bitmap*)url;
+
+ set = urldb_set_thumbnail(url, bmap);
+ ck_assert(set == true);
+
+ res = urldb_get_thumbnail(url);
+ ck_assert(res != NULL);
+ ck_assert(res == bmap);
+
+ nsurl_unref(url);
+}
+END_TEST
+
+START_TEST(urldb_cert_permissions_test)
+{
+ nsurl *url;
+ bool permit;
+
+ url = make_url(wikipedia_url);
+
+ urldb_set_cert_permissions(url, true); /* permit invalid certs for url
*/
+
+ permit = urldb_get_cert_permissions(url);
+
+ ck_assert(permit == true);
+
+ urldb_set_cert_permissions(url, false); /* do not permit invalid certs
for url */
+
+ permit = urldb_get_cert_permissions(url);
+
+ ck_assert(permit == false);
+
+ nsurl_unref(url);
+}
+END_TEST
+
+START_TEST(urldb_update_visit_test)
+{
+ nsurl *url;
+
+ url = make_url(wikipedia_url);
+
+ urldb_update_url_visit_data(url);
+
+ urldb_add_url(url);
+
+ urldb_update_url_visit_data(url);
+ /** \todo test needs to check results */
+
+ nsurl_unref(url);
+}
+END_TEST
+
+START_TEST(urldb_reset_visit_test)
+{
+ nsurl *url;
+
+ url = make_url(wikipedia_url);
+
+ urldb_reset_url_visit_data(url);
+
+ urldb_add_url(url);
+
+ urldb_reset_url_visit_data(url);
+ /** \todo test needs to check results */
+
+ nsurl_unref(url);
+}
+END_TEST
+
+START_TEST(urldb_persistence_test)
+{
+ nsurl *url;
+
+ url = make_url(wikipedia_url);
+
+ urldb_set_url_persistence(url, true);
+
+ urldb_add_url(url);
+
+ urldb_set_url_persistence(url, true);
+
+ urldb_set_url_persistence(url, false);
+ /** \todo test needs to check results */
+
+ nsurl_unref(url);
+}
+END_TEST
+
+
+static TCase *urldb_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("General");
+
+ /* ensure corestrings are initialised and finalised for every test */
+ tcase_add_checked_fixture(tc,
+ urldb_create_loaded,
+ urldb_teardown);
+
+ tcase_add_test(tc, urldb_iterate_entries_test);
+ tcase_add_test(tc, urldb_iterate_partial_www_test);
+ tcase_add_test(tc, urldb_iterate_partial_nomatch_test);
+ tcase_add_test(tc, urldb_iterate_partial_add_test);
+ tcase_add_test(tc, urldb_iterate_partial_path_test);
+ tcase_add_test(tc, urldb_iterate_partial_numeric_test);
+ tcase_add_test(tc, urldb_auth_details_test);
+ tcase_add_test(tc, urldb_thumbnail_test);
+ tcase_add_test(tc, urldb_cert_permissions_test);
+ tcase_add_test(tc, urldb_update_visit_test);
+ tcase_add_test(tc, urldb_reset_visit_test);
+ tcase_add_test(tc, urldb_persistence_test);
+
+ return tc;
+}
+
+
+static bool urldb_iterate_cookies_cb(const struct cookie_data *data)
+{
+ LOG("%p", data);
+ /* fprintf(stderr, "domain:%s\npath:%s\nname:%s\n\n",data->domain,
data->path, data->name);*/
+ return true;
+}
+
+START_TEST(urldb_iterate_cookies_test)
+{
+ urldb_iterate_cookies(urldb_iterate_cookies_cb);
+}
+END_TEST
+
+START_TEST(urldb_cookie_create_test)
+{
+ /* Valid path (includes leafname) */
+ const char *cookie_hdr = "name=value;Version=1;Path=/index.cgi\r\n";
+ const char *cookie = "$Version=1; name=value; $Path=\"/index.cgi\"";
+ char *cdata; /* cookie data */
+
+ ck_assert(test_urldb_set_cookie(cookie_hdr,
"http://example.org/index.cgi", NULL));
+ cdata = test_urldb_get_cookie("http://example.org/index.cgi");
+ ck_assert_str_eq(cdata, cookie);
+
+}
+END_TEST
+
+START_TEST(urldb_cookie_delete_test)
+{
+ /* Valid path (includes leafname) */
+ const char *cookie_hdr = "name=value;Version=1;Path=/index.cgi\r\n";
+ const char *cookie = "$Version=1; name=value; $Path=\"/index.cgi\"";
+ char *cdata; /* cookie data */
+
+ ck_assert(test_urldb_set_cookie(cookie_hdr,
"http://example.org/index.cgi", NULL));
+ cdata = test_urldb_get_cookie("http://example.org/index.cgi");
+ ck_assert_str_eq(cdata, cookie);
+
+ urldb_delete_cookie("example.org", "/index.cgi", "name");
+
+ cdata = test_urldb_get_cookie("http://example.org/index.cgi");
+ ck_assert(cdata == NULL);
+
+}
+END_TEST
+
+/**
+ * Test case for urldb cookie management
+ */
+static TCase *urldb_cookie_case_create(void)
+{
+ TCase *tc;
+ tc = tcase_create("Cookies");
+
+ /* ensure corestrings are initialised and finalised for every test */
+ tcase_add_checked_fixture(tc,
+ urldb_create_loaded,
+ urldb_teardown);
+
+ tcase_add_test(tc, urldb_cookie_create_test);
+ tcase_add_test(tc, urldb_iterate_cookies_test);
+ tcase_add_test(tc, urldb_cookie_delete_test);
+
+ return tc;
+}
+
+
+
+
/**
* Test urldb_add_host asserting on NULL.
*/
@@ -421,27 +782,44 @@ START_TEST(urldb_api_add_host_assert_test)
}
END_TEST
+/**
+ * test url database finalisation without initialisation.
+ */
+START_TEST(urldb_api_destroy_no_init_test)
+{
+ urldb_destroy();
+}
+END_TEST
-TCase *urldb_api_case_create(void)
+
+/**
+ * test case for urldb API including error returns and asserts
+ */
+static TCase *urldb_api_case_create(void)
{
TCase *tc;
- tc = tcase_create("API checks");
+ tc = tcase_create("API_checks");
tcase_add_test_raise_signal(tc,
urldb_api_add_host_assert_test,
6);
+ tcase_add_test(tc, urldb_api_destroy_no_init_test);
+
+
return tc;
}
-Suite *urldb_suite_create(void)
+static Suite *urldb_suite_create(void)
{
Suite *s;
s = suite_create("URLDB");
suite_add_tcase(s, urldb_api_case_create());
suite_add_tcase(s, urldb_session_case_create());
+ suite_add_tcase(s, urldb_case_create());
+ suite_add_tcase(s, urldb_cookie_case_create());
suite_add_tcase(s, urldb_original_case_create());
return s;
diff --git a/test/urlescape.c b/test/urlescape.c
index e4e1fdb..f1655e3 100644
--- a/test/urlescape.c
+++ b/test/urlescape.c
@@ -27,7 +27,8 @@
* \note Earlier RFC (2396, 1738 and 1630) list the tilde ~ character
* as reserved so its handling is ambiguious
*
- * \todo The url_escape should be tested for application/x-www-form-urlencoded
type operation
+ * \todo The url_escape should be tested for application/x-www-form-urlencoded
+ * type operation
*/
#include <assert.h>
@@ -148,7 +149,7 @@ START_TEST(url_escape_api_nullparam_test)
}
END_TEST
-TCase *url_escape_case_create(void)
+static TCase *url_escape_case_create(void)
{
TCase *tc;
tc = tcase_create("Escape");
@@ -268,7 +269,7 @@ START_TEST(url_unescape_api_nullparam_test)
END_TEST
-TCase *url_unescape_case_create(void)
+static TCase *url_unescape_case_create(void)
{
TCase *tc;
tc = tcase_create("Unescape");
@@ -287,7 +288,7 @@ TCase *url_unescape_case_create(void)
}
-Suite *urlescape_suite_create(void)
+static Suite *urlescape_suite_create(void)
{
Suite *s;
s = suite_create("Percent escaping");
diff --git a/utils/nsoption.c b/utils/nsoption.c
index 92ecfc1..f92debb 100644
--- a/utils/nsoption.c
+++ b/utils/nsoption.c
@@ -144,6 +144,14 @@ static void nsoption_validate(struct nsoption_s *opts,
struct nsoption_s *defs)
int cloop;
bool black = true;
+ if (opts[NSOPTION_treeview_font_size].value.i < 50) {
+ opts[NSOPTION_treeview_font_size].value.i = 50;
+ }
+
+ if (opts[NSOPTION_treeview_font_size].value.i > 1000) {
+ opts[NSOPTION_treeview_font_size].value.i = 1000;
+ }
+
if (opts[NSOPTION_font_size].value.i < 50) {
opts[NSOPTION_font_size].value.i = 50;
}
diff --git a/utils/time.c b/utils/time.c
index 667e836..433b479 100644
--- a/utils/time.c
+++ b/utils/time.c
@@ -80,7 +80,7 @@ enum nsc_time_months {
/**
* Array of short weekday names.
*/
-const char * const weekdays_short[NSC_TIME_WEEKDAY__COUNT] = {
+static const char * const weekdays_short[NSC_TIME_WEEKDAY__COUNT] = {
[NSC_TIME_WEEKDAY_SUN] = "Sun",
[NSC_TIME_WEEKDAY_MON] = "Mon",
[NSC_TIME_WEEKDAY_TUE] = "Tue",
@@ -92,7 +92,7 @@ const char * const weekdays_short[NSC_TIME_WEEKDAY__COUNT] = {
/**
* Array of month names.
*/
-const char * const months[NSC_TIME_MONTH__COUNT] = {
+static const char * const months[NSC_TIME_MONTH__COUNT] = {
[NSC_TIME_MONTH_JAN] = "Jan",
[NSC_TIME_MONTH_FEB] = "Feb",
[NSC_TIME_MONTH_MAR] = "Mar",
@@ -191,7 +191,7 @@ nserror nsc_snptimet(const char *str, size_t size, time_t
*timep)
/**
* Array of long weekday names.
*/
-const char * const weekdays_long[NSC_TIME_WEEKDAY__COUNT] = {
+static const char * const weekdays_long[NSC_TIME_WEEKDAY__COUNT] = {
[NSC_TIME_WEEKDAY_SUN] = "Sunday",
[NSC_TIME_WEEKDAY_MON] = "Monday",
[NSC_TIME_WEEKDAY_TUE] = "Tuesday",
@@ -361,7 +361,7 @@ enum nsc_time_zones {
/**
* Array of minute offsets for timezones.
*/
-const int16_t timezone_mins[NSC_TIME_ZONE__COUNT] = {
+static const int16_t timezone_mins[NSC_TIME_ZONE__COUNT] = {
[NSC_TIME_ZONE_IDLE] = NSC_TIME_ZONE_OFFSET_IDLE,
[NSC_TIME_ZONE_NZST] = NSC_TIME_ZONE_OFFSET_NZST,
[NSC_TIME_ZONE_NZT] = NSC_TIME_ZONE_OFFSET_NZT,
@@ -434,7 +434,7 @@ const int16_t timezone_mins[NSC_TIME_ZONE__COUNT] = {
/**
* Array of timezone names. Order does not matter.
*/
-const char * const timezones[NSC_TIME_ZONE__COUNT] = {
+static const char * const timezones[NSC_TIME_ZONE__COUNT] = {
[NSC_TIME_ZONE_IDLE] = "IDLE",
[NSC_TIME_ZONE_NZST] = "NZST",
[NSC_TIME_ZONE_NZT] = "NZT",
@@ -783,7 +783,7 @@ static inline bool time__parse_number(
ctx->timezone_offset_mins =
value / 100 * 60 +
value % 100;
- if (ctx->state == PARSE_STATE_HAD_MINUS) {
+ if (ctx->state == PARSE_STATE_HAD_PLUS) {
ctx->timezone_offset_mins *= -1;
}
*flags |= NSC_COMPONENT_FLAGS_HAVE_TIMEZONE;
@@ -798,8 +798,9 @@ static inline bool time__parse_number(
break;
case 2:
+ case 1:
if (!flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_DAYS) &&
- value <= 31) {
+ value > 0 && value <= 31) {
ctx->day = value - 1;
*flags |= NSC_COMPONENT_FLAGS_HAVE_DAYS;
return true;
@@ -813,14 +814,6 @@ static inline bool time__parse_number(
}
break;
- case 1:
- if (!flags_chk(*flags, NSC_COMPONENT_FLAGS_HAVE_DAYS)) {
- ctx->day = value - 1;
- *flags |= NSC_COMPONENT_FLAGS_HAVE_DAYS;
- return true;
- }
- break;
-
default:
break;
}
@@ -935,7 +928,7 @@ static nserror time__get_date(const char *str, time_t *time)
.timezone_offset_mins = 0
};
- if (str == NULL || *str == '\0' || time == NULL) {
+ if (str == NULL || time == NULL) {
return NSERROR_BAD_PARAMETER;
}
@@ -984,8 +977,10 @@ static nserror time__get_date(const char *str, time_t
*time)
ctx.state = PARSE_STATE_NONE;
}
- /* The initial values of 0 are used if hours, mins, secs not found */
+ /* The initial values of 0 are used if hours, mins, secs, and timezone
+ * are not found */
flags |= NSC_COMPONENT_FLAGS__HAVE_HHMMSS;
+ flags |= NSC_COMPONENT_FLAGS_HAVE_TIMEZONE;
/* Validate */
if (!flags_chk_all(flags, NSC_COMPONENT_FLAGS__HAVE_ALL)) {
--
NetSurf Browser
_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org