[Nickle] nickle: Branch 'master' - 5 commits
Keith Packard
keithp at keithp.com
Thu Apr 20 18:42:25 PDT 2023
builtin-date.c | 44 +++++++++++++++++++++++++++++++++++++------
configure.ac | 10 +++++++++
edit.c | 1
execute.c | 56 +++++++++++++++++++++++++------------------------------
main.c | 14 ++++++++-----
test/datetest.5c | 23 ++++++++++++++++++++--
6 files changed, 105 insertions(+), 43 deletions(-)
New commits:
commit a03c59853929c50f199d2b54729dfcb3a76c084c
Author: Keith Packard <keithp at keithp.com>
Date: Thu Apr 20 18:18:59 2023 -0700
Check for all readline helper functions separately
Don't assume any of the rl_ functions exist.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/configure.ac b/configure.ac
index d1a10d4..bdccb3d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -130,6 +130,10 @@ if test "x$ac_cv_header_readline_readline_h" = xyes; then
AC_DEFINE(HAVE_RL_RESET_AFTER_SIGNAL,1,[Has rl_reset_after_signal]),,[#include <readline/readline.h>])
AC_CHECK_DECL(rl_cleanup_after_signal,
AC_DEFINE(HAVE_RL_CLEANUP_AFTER_SIGNAL,1,[Has rl_cleanup_after_signal]),,[#include <readline/readline.h>])
+ AC_CHECK_DECL(rl_echo_signal_char,
+ AC_DEFINE(HAVE_RL_ECHO_SIGNAL_CHAR,1,[Has rl_echo_signal_char]),,[#include <readline/readline.h>])
+ AC_CHECK_DECL(rl_free_line_state,
+ AC_DEFINE(HAVE_RL_FREE_LINE_STATE,1,[Has rl_free_line_state]),,[#include <readline/readline.h>])
fi
if test "x$prefix" = xNONE; then
diff --git a/main.c b/main.c
index 3286d7f..85fc70b 100644
--- a/main.c
+++ b/main.c
@@ -177,12 +177,14 @@ stop (int sig)
{
sigset_t set, oset;
-#if HAVE_RL_CLEANUP_AFTER_SIGNAL
if (stdin_in_readline) {
+#if HAVE_RL_ECHO_SIGNAL_CHAR
rl_echo_signal_char(sig);
+#endif
+#if HAVE_RL_CLEANUP_AFTER_SIGNAL
rl_cleanup_after_signal();
- }
#endif
+ }
IoStop ();
releaseSignal (sig);
@@ -197,7 +199,7 @@ stop (int sig)
catchSignal (sig, stop);
IoStart ();
-#if HAVE_RL_CLEANUP_AFTER_SIGNAL
+#if HAVE_RL_RESET_AFTER_SIGNAL
if (stdin_in_readline)
rl_reset_after_signal();
#endif
@@ -206,12 +208,14 @@ stop (int sig)
void
die (int sig)
{
-#if HAVE_RL_CLEANUP_AFTER_SIGNAL
if (stdin_in_readline) {
+#if HAVE_RL_FREE_LINE_STATE
rl_free_line_state();
+#endif
+#if HAVE_RL_CLEANUP_AFTER_SIGNAL
rl_cleanup_after_signal();
- }
#endif
+ }
IoStop ();
_exit (sig);
}
commit 5bcd0f4a2bd8ddbcaea33ba9b0b54300515e4315
Author: Keith Packard <keithp at keithp.com>
Date: Thu Apr 20 18:18:15 2023 -0700
Define _GNU_SOURCE in edit.c to get asprintf declared
asprintf is not declared by default.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/edit.c b/edit.c
index 6c7b9ad..b808fab 100644
--- a/edit.c
+++ b/edit.c
@@ -10,6 +10,7 @@
* invoke the users editor (default /bin/ed)
*/
+#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
commit 1a1f47bc31c26d7cccbe367ce854b3c0e9145535
Author: Keith Packard <keithp at keithp.com>
Date: Thu Apr 20 18:09:27 2023 -0700
Remove redundant box value check in ThreadBoxSetDefault
All of the callers perform the box value check before calling, so
remove it within the function.
Replace the ?: in ThreadBoxCheck with an if statement to avoid
having a void type mixed with an int type.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/execute.c b/execute.c
index 22c64f6..9e73be9 100644
--- a/execute.c
+++ b/execute.c
@@ -735,7 +735,7 @@ ThreadUnwind (Value thread, int twixt, int catch)
#endif
}
-#define ThreadBoxCheck(box,i) (BoxValueGet(box,i) == 0 ? ThreadBoxSetDefault(box,i,0) : 0)
+#define ThreadBoxCheck(box,i) do { if (BoxValueGet(box, i) == 0) ThreadBoxSetDefault(box,i,0); } while(0)
typedef struct _TypeChain {
struct _TypeChain *prev;
@@ -745,38 +745,34 @@ typedef struct _TypeChain {
static void
ThreadBoxSetDefault (BoxPtr box, int i, TypeChain *chain)
{
- if (BoxValueGet (box, i) == 0)
- {
- Type *ctype = TypeCanon (BoxType (box, i));
- StructType *st = ctype->structs.structs;
- TypeChain link, *c;
+ Type *ctype = TypeCanon (BoxType (box, i));
+ StructType *st = ctype->structs.structs;
+ TypeChain link, *c;
- /*
- * Check for recursion
- */
- for (c = chain; c; c = c->prev)
- if (c->type == ctype)
- return;
+ /*
+ * Check for recursion
+ */
+ for (c = chain; c; c = c->prev)
+ if (c->type == ctype)
+ return;
- link.prev = chain;
- link.type = ctype;
-
- switch (ctype->base.tag) {
- case type_union:
- BoxValueSet (box, i, NewUnion (st, False));
- break;
- case type_struct:
- BoxValueSet (box, i, NewStruct (st, False));
- box = BoxValueGet (box, i)->structs.values;
- for (i = 0; i < st->nelements; i++)
- {
- if (BoxValueGet (box, i) == 0)
- ThreadBoxSetDefault (box, i, &link);
- }
- break;
- default:
- break;
+ link.prev = chain;
+ link.type = ctype;
+
+ switch (ctype->base.tag) {
+ case type_union:
+ BoxValueSet (box, i, NewUnion (st, False));
+ break;
+ case type_struct:
+ BoxValueSet (box, i, NewStruct (st, False));
+ box = BoxValueGet (box, i)->structs.values;
+ for (i = 0; i < st->nelements; i++) {
+ if (BoxValueGet (box, i) == 0)
+ ThreadBoxSetDefault (box, i, &link);
}
+ break;
+ default:
+ break;
}
}
commit ad872b08d7c910c0c89dde6a6267cbcb4b0afcf8
Author: Keith Packard <keithp at keithp.com>
Date: Tue Apr 18 21:58:03 2023 -0700
test: Allow "UTC", "GMT", or "NONE" to be returned for GMT time zone
When converting seconds into a time struct using gmtime, the time zone
used is not well defined, so allow either UTC or GMT. For targets that
don't provide anything, allow "NONE" too.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/test/datetest.5c b/test/datetest.5c
index 38947b0..db0ce57 100644
--- a/test/datetest.5c
+++ b/test/datetest.5c
@@ -28,11 +28,29 @@ void test_round_date(date_t date) {
raise bad_date(date, sl, l);
}
+/* Allow either "UTC" or "GMT" to represent times that are 0 minutes
+ * from "UTC".
+ */
+string
+canonical_zone(string z)
+{
+ if (z == "UTC" || z == "NONE")
+ return "GMT";
+ return z;
+}
+
+bool
+date_equal(date_t a, date_t b) {
+ a.zone = canonical_zone(a.zone);
+ b.zone = canonical_zone(b.zone);
+ return a == b;
+}
+
void test_utc_seconds(int seconds, date_t date) {
date_t got_date = gmtime(seconds);
int got_seconds = timegm(date);
- if (got_date != date)
+ if (!date_equal(got_date, date))
raise bad_date(date, seconds, got_date);
if (got_seconds != seconds)
raise bad_seconds(seconds, date, got_seconds);
@@ -53,6 +71,7 @@ test_utc_seconds(0,
.yday = 0,
.year = 1970,
.isdst = false,
+ .gmtoff = 0,
.zone = "GMT"
});
@@ -61,4 +80,4 @@ test_utc_seconds(0,
*/
test_utc_seconds(2**31-1,
(date_t) {sec = 7, min = 14, hour = 3, mday = 19, mon = 1, year = 2038,
- wday = 2, yday = 18, isdst = false, zone = "GMT"});
+ wday = 2, yday = 18, isdst = false, gmtoff = 0, zone = "GMT"});
commit ee4c6d68920656af4d8f42013a61c095e3701c0e
Author: Keith Packard <keithp at keithp.com>
Date: Thu Apr 20 14:57:56 2023 -0700
Make tm_zone and tm_gmtoff fields optional
These fields aren't part of the POSIX standard, and various operating
systems might not support them. Only use them if they're available.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/builtin-date.c b/builtin-date.c
index 1c24441..021866e 100644
--- a/builtin-date.c
+++ b/builtin-date.c
@@ -23,9 +23,9 @@ static Type *typeDate;
#define DATE_S "00"
static Value
-int_value(int s)
+int_value(signed_digit s)
{
- return Reduce(NewSignedDigitInteger((signed_digit) s));
+ return Reduce(NewSignedDigitInteger(s));
}
static int
@@ -59,6 +59,22 @@ value_bool(Value s, Atom member, char *error, int def)
return BoolPart(mem, error);
}
+static const char *
+value_string(Value s, Atom member, char *error, const char *def)
+{
+ Value ref = StructMemRef(s, AtomId(member));
+ Value mem;
+
+ if (ref == 0)
+ return def;
+
+ mem = RefValueGet(ref);
+ if (mem == 0)
+ return def;
+
+ return StrzPart(mem, error);
+}
+
static Value
to_date(struct tm *tm)
{
@@ -76,7 +92,16 @@ to_date(struct tm *tm)
BoxValueSet (box, 6, int_value(tm->tm_wday));
BoxValueSet (box, 7, int_value(tm->tm_yday));
BoxValueSet (box, 8, tm->tm_isdst ? TrueVal : FalseVal);
- BoxValueSet (box, 9, NewStrString(tm->tm_zone));
+#ifdef HAVE_STRUCT_TM_TM_GMTOFF
+ BoxValueSet (box, 9, int_value(tm->tm_gmtoff));
+#else
+ BoxValueSet (box, 9, 0);
+#endif
+#ifdef HAVE_STRUCT_TM_TM_ZONE
+ BoxValueSet (box, 10, NewStrString(tm->tm_zone));
+#else
+ BoxValueSet (box, 10, NewStrString("NONE"));
+#endif
return ret;
}
@@ -92,7 +117,12 @@ from_date(Value date, struct tm *tm)
tm->tm_wday = value_int(date, "wday", "invalid wday", 0);
tm->tm_yday = value_int(date, "yday", "invalid yday", 0);
tm->tm_isdst = value_bool(date, "isdst", "invalid isdst", 0);
- tm->tm_zone = NULL;
+#ifdef HAVE_STRUCT_TM_TM_GMTOFF
+ tm->tm_gmtoff = value_int(date, "gmtoff", "invalid gmtoff", 0);
+#endif
+#ifdef HAVE_STRUCT_TM_TM_ZONE
+ tm->tm_zone = value_string(date, "zone", "invalid zone", "NONE");
+#endif
}
static Value
@@ -205,7 +235,7 @@ import_Date_namespace()
publish_public,
DATE_I,
NULL,
- BuildStructType (10,
+ BuildStructType (11,
typePrim[rep_integer], "sec",
typePrim[rep_integer], "min",
typePrim[rep_integer], "hour",
@@ -215,7 +245,9 @@ import_Date_namespace()
typePrim[rep_integer], "wday",
typePrim[rep_integer], "yday",
typePrim[rep_bool], "isdst",
- typePrim[rep_string], "zone"));
+ typePrim[rep_integer], "gmtoff",
+ typePrim[rep_string], "zone"
+ ));
BuiltinFuncs1 (&DateNamespace, funcs_1);
EXIT ();
diff --git a/configure.ac b/configure.ac
index 6691cf5..d1a10d4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -98,6 +98,12 @@ AC_CHECK_FUNCS(unsetenv setenv putenv gettimeofday hstrerror select)
AC_CHECK_FUNCS(sigaction sigrelse sigignore setrlimit getrlimit)
AC_CHECK_FUNCS(dlopen dlsym dlerror dlclose)
AC_CHECK_FUNC(significand,,AC_CHECK_LIB(m, significand))
+AC_CHECK_MEMBER([struct tm.tm_zone],
+ AC_DEFINE([HAVE_STRUCT_TM_TM_ZONE], 1, [Has tm_zone in struct tm]),,
+ [[#include <time.h>]])
+AC_CHECK_MEMBER([struct tm.tm_gmtoff],
+ AC_DEFINE([HAVE_STRUCT_TM_TM_GMTOFF], 1, [Has tm_gmtoff in struct tm]),,
+ [[#include <time.h>]])
case "$ac_cv_func_significand""$ac_cv_lib_m_significand" in
*yes*)
More information about the Nickle
mailing list