[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