[Nickle] nickle: Branch 'master' - 14 commits
Keith Packard
keithp at keithp.com
Tue Jul 9 18:13:14 PDT 2019
autogen.sh | 2
builtin.c | 21 +++++++--
builtin.h | 2
compile.c | 37 +++++++++--------
configure.ac | 6 --
debian/changelog | 18 +++++++-
debian/tests/upstream | 8 +--
execute.c | 19 ++++++--
file.c | 5 +-
io.c | 20 ++++++---
lex.l | 107 ++++++++++++++++++++++++++++++++------------------
main.c | 36 +++++++++-------
nickle.h | 1
symbol.c | 16 +++++++
test/Makefile.am | 14 +++++-
test/arraytest.5c | 30 ++++++++++++++
test/string-file.5c | 20 +++++++++
value.h | 6 ++
18 files changed, 263 insertions(+), 105 deletions(-)
New commits:
commit 8ec2c4bd0ded52d095dbd0486880f7693d727b7b
Author: Keith Packard <keithp at keithp.com>
Date: Tue Jul 9 18:11:18 2019 -0700
Remove AM_MAINTAINER_MODE
This doesn't have any effect anymore.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/autogen.sh b/autogen.sh
index b217841..85694fc 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -7,4 +7,4 @@
# configure depends on version.m4, but autoreconf does not realize this
rm configure
autoreconf -Wall -v --install || exit 1
-./configure --enable-maintainer-mode "$@"
+./configure "$@"
diff --git a/configure.ac b/configure.ac
index b7fbeb5..e2f4b17 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,8 +14,6 @@ AC_CONFIG_AUX_DIR(.)
AM_INIT_AUTOMAKE([foreign])
-AM_MAINTAINER_MODE
-
AC_SUBST([RELEASE_DATE])
dnl Checks for programs.
AC_PROG_CC
commit f8de289ee31ca203bd33f264358aa65822801580
Author: Keith Packard <keithp at keithp.com>
Date: Tue Jul 9 18:09:11 2019 -0700
test: Add test for empty string_file
This used to crash:
$ nickle -e 'File::string_string(File::string_write())'
Add a test for that, plus a simple test for a non-empty one too.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index 8a91f92..d7fe7fc 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -15,7 +15,8 @@ check_SCRIPTS=\
factorial.5c \
is_type.5c \
jsontest.5c \
- datetest.5c
+ datetest.5c \
+ string-file.5c
TABLES=math-tables.5c
diff --git a/test/string-file.5c b/test/string-file.5c
new file mode 100644
index 0000000..90b47b9
--- /dev/null
+++ b/test/string-file.5c
@@ -0,0 +1,20 @@
+/*
+ * Nickle test suite
+ *
+ * string I/O tests
+ */
+
+exception bad_result (poly want, poly got);
+
+void check(poly want, poly got)
+{
+ if (want != got)
+ raise bad_result(want, got);
+}
+
+check("", File::string_string(File::string_write()));
+
+file f = File::string_write();
+File::fprintf(f, "hello, world");
+check("hello, world", File::string_string(f));
+
commit 9ffc51e440208cb0ba63c643342d25ef0f5aacb7
Author: Keith Packard <keithp at keithp.com>
Date: Tue Jul 9 17:19:07 2019 -0700
File::string_string can be passed an empty buffer
If no writes have been done, then file->file.output will be NULL, so
write_chain needs to check for NULL out rather than NULL out->next.
Reported-by: David B. Lamkins <dlamkins at galois.com>
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/file.c b/file.c
index a22e30b..453afc0 100644
--- a/file.c
+++ b/file.c
@@ -919,8 +919,9 @@ FileStringWrite (void)
static char *
write_chain(char *s, FileChainPtr out)
{
- if (out->next)
- s = write_chain(s, out->next);
+ if (!out)
+ return s;
+ s = write_chain(s, out->next);
memcpy(s, FileBuffer(out), out->used);
return s + out->used;
}
commit 6072bc5b8829f254bb5dea59dec615fc325921ab
Author: Keith Packard <keithp at keithp.com>
Date: Fri Oct 26 14:00:46 2018 -0700
Bump to version 2.84
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/configure.ac b/configure.ac
index 223b2cd..b7fbeb5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,8 +6,8 @@ dnl for licensing information.
AC_PREREQ([2.69])
-AC_INIT([nickle],[2.83],[http://nickle.org],[nickle])
-RELEASE_DATE="2018-10-22"
+AC_INIT([nickle],[2.84],[http://nickle.org],[nickle])
+RELEASE_DATE="2018-10-26"
AC_CONFIG_SRCDIR([nickle.h])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_AUX_DIR(.)
diff --git a/debian/changelog b/debian/changelog
index f5571b9..80d1733 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+nickle (2.84-1) unstable; urgency=medium
+
+ * Correct crash compiling implicit sized arrays with mismatching
+ init dimensionality. Closes: #911926.
+ * Fix SIGTSTP handling to work in more cases, including under dash
+ and when run as other than the process group leader.
+ * Ignore '_' in numeric values, permitting its use as a separator.
+
+ -- Keith Packard <keithp at keithp.com> Fri, 26 Oct 2018 13:36:57 -0700
+
nickle (2.83-1) unstable; urgency=medium
* Include debian/source/format in tarball
commit 5d5c84a62ad34fffb73c16ed18dc2e630bf64e21
Author: Keith Packard <keithp at keithp.com>
Date: Sat Oct 27 19:04:49 2018 -0700
Construct a separate case for lexing '0' from other octal numbers
This avoids needing code to identify this case within the octal number
token generation code.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/lex.l b/lex.l
index 256a8d2..a498b24 100644
--- a/lex.l
+++ b/lex.l
@@ -562,12 +562,13 @@ has_member { yylval.ints = HASMEMBER; return HASMEMBER; }
REFERENCE (yylval.value);
return STRING_CONST;
}
-0[0-7_]* {
+0 {
+ yylval.value = Zero;
+ return TEN_NUM;
+ }
+0[0-7_]+ {
yylval.value = atov(yytext+1, 8);
- if (yytext[1] == '\0')
- return TEN_NUM;
- else
- return OCTAL0_NUM;
+ return OCTAL0_NUM;
}
0o[0-7_]+ {
yylval.value = atov(yytext+2, 8);
@@ -913,4 +914,3 @@ aetov (char *s, int base)
v = Negate (v);
RETURN (v);
}
-
commit 3d05b8d6df9bd32fe90affe080c327e290bf85f4
Author: Keith Packard <keithp at keithp.com>
Date: Fri Oct 26 23:30:02 2018 -0700
Ignore '_' within numbers so it can be used as a separator
Adopted from languages like Rust where this can be used to group
digits in thousands for base-10 or power of two for base 2,8,16 to
make them easier to read.
123_456_789 = 123456789
0xafff_1212 = 0xafff1212
The patch makes both the lexer and string conversions support this.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/lex.l b/lex.l
index d31ca6f..256a8d2 100644
--- a/lex.l
+++ b/lex.l
@@ -562,74 +562,74 @@ has_member { yylval.ints = HASMEMBER; return HASMEMBER; }
REFERENCE (yylval.value);
return STRING_CONST;
}
-0[0-7]* {
+0[0-7_]* {
yylval.value = atov(yytext+1, 8);
if (yytext[1] == '\0')
return TEN_NUM;
else
return OCTAL0_NUM;
}
-0o[0-7]+ {
+0o[0-7_]+ {
yylval.value = atov(yytext+2, 8);
return OCTAL_NUM;
}
-0o[0-7]+\./\.\.\. {
+0o[0-7_]+\./\.\.\. {
yylval.value = aetov(yytext+2, 8);
return OCTAL_FLOAT;
}
-0o[0-7]+/\.\. {
+0o[0-7_]+/\.\. {
yylval.value = atov(yytext+2, 8);
return OCTAL_NUM;
}
-0o(([0-7]+((\.[0-7]*(\{[0-7]+\})?)?))|(\.[0-7]+)|(\.[0-7]*\{[0-7]+\}))(([Ee][-+]?[0-7]+)?) {
+0o(([0-7_]+((\.[0-7_]*(\{[0-7_]+\})?)?))|(\.[0-7_]+)|(\.[0-7_]*\{[0-7_]+\}))(([Ee][-+]?[0-7_]+)?) {
yylval.value = aetov (yytext+2, 8);
return OCTAL_FLOAT;
}
-0b[01]+ {
+0b[01_]+ {
yylval.value = atov(yytext+2, 2);
return BINARY_NUM;
}
-0b[0-1]+\./\.\.\. {
+0b[01_]+\./\.\.\. {
yylval.value = aetov(yytext+2, 2);
return BINARY_FLOAT;
}
-0b[0-1]+/\.\. {
+0b[01_]+/\.\. {
yylval.value = atov(yytext+2, 2);
return BINARY_NUM;
}
-0b(([0-1]+((\.[0-1]*(\{[0-1]+\})?)?))|(\.[0-1]+)|(\.[0-1]*\{[0-1]+\}))(([Ee][-+]?[0-1]+)?) {
+0b(([01_]+((\.[01_]*(\{[01_]+\})?)?))|(\.[01_]+)|(\.[01_]*\{[01_]+\}))(([Ee][-+]?[01_]+)?) {
yylval.value = aetov (yytext+2, 2);
return BINARY_FLOAT;
}
-0x[0-9a-fA-F]+ {
+0x[0-9a-fA-F_]+ {
yylval.value = atov(yytext+2, 16);
return HEX_NUM;
}
-0x[0-9a-fA-F]+\./\.\.\. {
+0x[0-9a-fA-F_]+\./\.\.\. {
yylval.value = aetov(yytext+2, 16);
return HEX_FLOAT;
}
-0x[0-9a-fA-F]+/\.\. {
+0x[0-9a-fA-F_]+/\.\. {
yylval.value = atov(yytext+2, 16);
return HEX_NUM;
}
-0x(([0-9a-fA-F]+((\.[0-9a-fA-F]*(\{[0-9a-fA-F]+\})?)?))|(\.[0-9a-fA-F]+)|(\.[0-9a-fA-F]*\{[0-9a-fA-F]+\}))(([Ee][-+]?[0-9a-fA-F]+)?) {
+0x(([0-9a-fA-F_]+((\.[0-9a-fA-F_]*(\{[0-9a-fA-F_]+\})?)?))|(\.[0-9a-fA-F_]+)|(\.[0-9a-fA-F_]*\{[0-9a-fA-F_]+\}))(([Ee][-+]?[0-9a-fA-F_]+)?) {
yylval.value = aetov (yytext+2, 16);
return HEX_FLOAT;
}
-[0-9]+ {
+[0-9][0-9_]* {
yylval.value = atov(yytext, 10);
return TEN_NUM;
}
-[0-9]+\./\.\.\. {
+[0-9][0-9_]*\./\.\.\. {
yylval.value = aetov(yytext, 10);
return TEN_FLOAT;
}
-[0-9]+/\.\. {
+[0-9][0-9_]*/\.\. {
yylval.value = atov(yytext, 10);
return TEN_NUM;
}
-(([0-9]+((\.[0-9]*(\{[0-9]+\})?)?))|(\.[0-9]+)|(\.[0-9]*\{[0-9]+\}))(([Ee][-+]?[0-9]+)?) {
+(([0-9][0-9_]*((\.[0-9_]*(\{[0-9_]+\})?)?))|(\.[0-9][0-9_]*)|(\.([0-9][0-9_]*)?\{[0-9_]+\}))(([Ee][-+]?[0-9_]+)?) {
yylval.value = aetov (yytext, 10);
return TEN_FLOAT;
}
@@ -788,6 +788,8 @@ atov (char *s, int base)
i = c - 'a' + 10;
else if ('A' <= c && c <= 'Z')
i = c - 'A' + 10;
+ else if (c == '_')
+ continue;
else
break;
if (i >= base)
@@ -797,12 +799,47 @@ atov (char *s, int base)
RETURN (result);
}
+static char *
+scan_number(char *s, char needle, int *lenp)
+{
+ int len = 0;
+ for (;;) {
+ char c = *s;
+ if (tolower(c) == needle)
+ break;
+ switch (c) {
+ case '\0':
+ return NULL;
+ case '_':
+ break;
+ default:
+ len++;
+ break;
+ }
+ s++;
+ }
+ if (lenp)
+ *lenp = len;
+ return s;
+}
+
+static int
+number_len(char *s)
+{
+ int len = 0;
+ char c;
+ while ((c = *s++))
+ if (c != '_')
+ len++;
+ return len;
+}
+
Value
aetov (char *s, int base)
{
ENTER ();
char *int_part, *frac_part, *rep_part, *exp_part, *next;
- int sign, frac_len, rep_len, esign;
+ int sign, int_len = -1, frac_len = -1, rep_len = -1, exp_frac_len = -1, esign;
Value v, sv;
int_part = s;
@@ -814,7 +851,7 @@ aetov (char *s, int base)
sign = -1;
}
next = int_part;
- frac_part = strchr (next, '.');
+ frac_part = scan_number(next, '.', &int_len);
frac_len = -1;
rep_part = 0;
rep_len = 0;
@@ -822,24 +859,20 @@ aetov (char *s, int base)
if (frac_part) {
frac_part++;
next = frac_part;
- rep_part = strchr (next, '{');
+ rep_part = scan_number(next, '{', &frac_len);
if (rep_part)
{
- frac_len = rep_part - frac_part;
rep_part++;
- next = strchr (rep_part, '}');
+ next = rep_part;
+ next = scan_number(next, '}', &rep_len);
if (!next)
- RETURN (Void); /* "can't" happen */
- rep_len = next - rep_part;
- next = next + 1;
+ RETURN(Void); /* can't happen */
}
}
- exp_part = strchr (next, 'e');
- if (!exp_part)
- exp_part = strchr (next, 'E');
+ exp_part = scan_number(next, 'e', &exp_frac_len);
if (exp_part) {
if (frac_len < 0)
- frac_len = exp_part - frac_part;
+ frac_len = exp_frac_len;
exp_part++;
if (*exp_part == '+')
exp_part++;
@@ -848,7 +881,7 @@ aetov (char *s, int base)
exp_part++;
}
} else if (frac_len < 0 && frac_part)
- frac_len = strlen(frac_part);
+ frac_len = number_len(frac_part);
v = atov (int_part, base);
if (frac_part)
{
@@ -859,7 +892,7 @@ aetov (char *s, int base)
if (rep_part)
{
Value rep;
-
+
rep = Divide (atov (rep_part, base), Minus (Pow (NewInt (base),
NewInt (rep_len)),
One));
@@ -868,7 +901,7 @@ aetov (char *s, int base)
NewInt (frac_len)));
v = Plus (v, rep);
}
- if (exp_part)
+ if (exp_part)
{
sv = Pow (NewInt (base), atov (exp_part, base));
if (esign > 0)
commit 336177cc7ab9e255c7384260d5d303618dc90cf9
Author: Keith Packard <keithp at keithp.com>
Date: Fri Oct 26 16:04:06 2018 -0700
Add array initalizer tests
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index 34ab8d0..8a91f92 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -6,6 +6,7 @@ check_SCRIPTS=\
orderofoptest.5c \
rattest.5c \
reftest.5c \
+ arraytest.5c \
modtest.5c \
hashtest.5c \
signal.5c \
diff --git a/test/arraytest.5c b/test/arraytest.5c
new file mode 100644
index 0000000..c283feb
--- /dev/null
+++ b/test/arraytest.5c
@@ -0,0 +1,30 @@
+/* Make sure array initalizers work as expected */
+
+void check (poly value, poly correct)
+{
+ if (is_number (value) && !is_rational (value))
+ {
+ real error = abs (value - correct);
+ if (error < abs(value) / 1e7)
+ return;
+ }
+ if (value != correct)
+ abort ("check failed (was %v, should be %v)", value, correct);
+}
+
+check (([10]) { 1, 2, ... }[9], 2);
+check (([*,*]) { { 1, 2, ...}, { 3, 4, 5, 6}} [0,3], 2);
+check (([*,*,*]) { { { 1, 2, 3 } ... }, { { 4, 5, 6}, {7, 8, 9}, {10, 11, 12}}}[0,1,2], 3);
+check (([10]) { [i] = i ** 2 + 1 }[9], 82);
+
+/* These should all generate compile errors, but shouldn't crash */
+file save_stderr = stderr;
+stderr = File::open("/dev/null", "w");
+([*,*]) { { [i] = i ** 2 + 1 }, { 4, 5, 6, 7, 8 }};
+([*]) { 1 ... };
+([*,*]) {1};
+int[*,*] x = {1};
+int[] x = {{1},2};
+stderr = save_stderr;
+
+exit(0);
commit f2ed37df1fff4660e2014bb8214c0c31b1c7127f
Author: Keith Packard <keithp at keithp.com>
Date: Fri Oct 26 16:01:22 2018 -0700
Ignore SIGTTOU/SIGTTIN. Adjust TSTP processing
When run as other than the master of a process group, nickle may not
get all of its work done before the controlling shell takes over the
tty and resets that control group. This means that any processing of
terminal parameters may generate SIGTTOU/SIGTTIN signals, which end up
re-entering the stop function and causing general chaos. Only SIG_IGN
appears to appease the kernel into dealing with this case correctly.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/main.c b/main.c
index e20f1dd..e4465c0 100644
--- a/main.c
+++ b/main.c
@@ -101,8 +101,8 @@ main (int argc, char **argv)
(void) ignoreSignal (SIGPIPE);
(void) catchSignal (SIGTERM, die);
(void) catchSignal (SIGTSTP, stop);
- (void) catchSignal (SIGTTIN, stop);
- (void) catchSignal (SIGTTOU, stop);
+ (void) ignoreSignal (SIGTTIN);
+ (void) ignoreSignal (SIGTTOU);
stdin_interactive = isatty(0);
init ();
setArgv (argc - 1, argv + 1);
@@ -180,22 +180,26 @@ stop (int sig)
sigset_t set, oset;
#if HAVE_RL_CLEANUP_AFTER_SIGNAL
- printf ("stop %d\n", stdin_in_readline);
- if (stdin_in_readline)
+ if (stdin_in_readline) {
+ rl_echo_signal_char(sig);
rl_cleanup_after_signal();
+ }
#endif
- sigfillset (&set);
- sigprocmask (SIG_SETMASK, &set, &oset);
+
IoStop ();
releaseSignal (sig);
- sigfillset (&set);
- sigdelset (&set, sig);
- sigprocmask (SIG_SETMASK, &set, &set);
- kill (getpid(), sig);
- sigprocmask (SIG_SETMASK, &oset, &set);
- IoStart ();
+ killpg (0, sig);
+ sigemptyset(&set);
+ sigaddset(&set, sig);
+ sigprocmask (SIG_UNBLOCK, &set, &oset);
+
+ /* stopped ... */
+
+ sigprocmask (SIG_SETMASK, &oset, NULL);
catchSignal (sig, stop);
-#if HAVE_RL_RESET_AFTER_SIGNAL
+ IoStart ();
+
+#if HAVE_RL_CLEANUP_AFTER_SIGNAL
if (stdin_in_readline)
rl_reset_after_signal();
#endif
@@ -204,11 +208,13 @@ stop (int sig)
void
die (int sig)
{
- IoStop ();
#if HAVE_RL_CLEANUP_AFTER_SIGNAL
- if (stdin_in_readline)
+ if (stdin_in_readline) {
+ rl_free_line_state();
rl_cleanup_after_signal();
+ }
#endif
+ IoStop ();
_exit (sig);
}
commit 549bbed54dc0c5d1361906cf1ca03f6e9cb57615
Author: Keith Packard <keithp at keithp.com>
Date: Fri Oct 26 15:51:53 2018 -0700
Make assignments to stdin/stdout/stderr affect C code
Use values of these variables in the C code.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/builtin.c b/builtin.c
index cd65b18..bba961e 100644
--- a/builtin.c
+++ b/builtin.c
@@ -45,9 +45,9 @@ static const struct envbuiltin envvars[] = {
};
static const struct filebuiltin fvars[] = {
- { "stdin", &FileStdin },
- { "stdout", &FileStdout },
- { "stderr", &FileStderr },
+ { "stdin", &FileStdinBox },
+ { "stdout", &FileStdoutBox },
+ { "stderr", &FileStderrBox },
{ 0, 0 },
};
@@ -124,6 +124,18 @@ BuiltinSymbol (NamespacePtr *namespacep,
type)));
}
+static SymbolPtr
+BuiltinSymbolValue(NamespacePtr *namespacep,
+ char *string,
+ Type *type,
+ BoxPtr value)
+{
+ ENTER ();
+ RETURN (BuiltinAddName (namespacep,
+ NewSymbolGlobalValue (AtomId (string),
+ value)));
+}
+
static Type *typeUserdef[100];
void
@@ -376,8 +388,7 @@ BuiltinInit (void)
/* Import File objects with predefined values */
for (f = fvars; f->name; f++) {
- sym = BuiltinSymbol (f->namespace, f->name, typePrim[rep_file]);
- BoxValueSet (sym->global.value, 0, *f->value);
+ sym = BuiltinSymbolValue (f->namespace, f->name, typePrim[rep_file], *f->box);
}
/* Import int objects with predefined values */
diff --git a/builtin.h b/builtin.h
index f90a893..4304b0a 100644
--- a/builtin.h
+++ b/builtin.h
@@ -91,7 +91,7 @@ struct ibuiltin {
struct filebuiltin {
char *name;
- Value *value;
+ BoxPtr *box;
NamespacePtr *namespace;
};
diff --git a/io.c b/io.c
index f3d08d1..70a6f2b 100644
--- a/io.c
+++ b/io.c
@@ -93,7 +93,7 @@ IoFini (void)
FileClose (FileStderr);
}
-Value FileStdin, FileStdout, FileStderr;
+BoxPtr FileStdinBox, FileStdoutBox, FileStderrBox;
Bool
IoTimeout (void *closure)
@@ -145,17 +145,23 @@ IoNoticeReadBlocked (void)
}
#endif
+static BoxPtr
+IoMakeFile(int fd, int flags)
+{
+ BoxPtr box = NewBox(False, False, 1, typePrim[rep_file]);
+ MemAddRoot(box);
+ BoxValueSet(box, 0, FileCreate(fd, flags));
+ return box;
+}
+
void
IoInit (void)
{
ENTER ();
catchSignal (SIGIO, sigio);
- FileStdin = FileCreate (0, FileReadable);
- FileStdout = FileCreate (1, FileWritable);
- FileStderr = FileCreate (2, FileWritable);
- MemAddRoot (FileStdin);
- MemAddRoot (FileStdout);
- MemAddRoot (FileStderr);
+ FileStdinBox = IoMakeFile(0, FileReadable);
+ FileStdoutBox = IoMakeFile(1, FileWritable);
+ FileStderrBox = IoMakeFile(2, FileWritable);
IoStart ();
EXIT ();
}
diff --git a/nickle.h b/nickle.h
index c57921e..38031aa 100644
--- a/nickle.h
+++ b/nickle.h
@@ -71,6 +71,7 @@ extern SymbolPtr NewSymbolType (Atom name, Type *type);
extern SymbolPtr NewSymbolException (Atom name, Type *type, Value doc);
extern SymbolPtr NewSymbolConst (Atom name, Type *type);
extern SymbolPtr NewSymbolGlobal (Atom name, Type *type);
+extern SymbolPtr NewSymbolGlobalValue (Atom name, BoxPtr value);
extern SymbolPtr NewSymbolArg (Atom name, Type *type);
extern SymbolPtr NewSymbolStatic (Atom name, Type *Rep);
extern SymbolPtr NewSymbolAuto (Atom name, Type *type);
diff --git a/symbol.c b/symbol.c
index 93a5411..bb710bb 100644
--- a/symbol.c
+++ b/symbol.c
@@ -127,6 +127,22 @@ NewSymbolGlobal (Atom name, Type *type)
}
SymbolPtr
+NewSymbolGlobalValue (Atom name, BoxPtr value)
+{
+ ENTER ();
+ SymbolPtr s;
+
+ s = ALLOCATE (&SymbolGlobalType, sizeof (SymbolGlobal));
+ s->symbol.next = 0;
+ s->symbol.name = name;
+ s->symbol.class = class_global;
+ s->symbol.type = value->u.type;
+ s->symbol.forward = False;
+ s->global.value = value;
+ RETURN (s);
+}
+
+SymbolPtr
NewSymbolArg (Atom name, Type *type)
{
ENTER ();
diff --git a/value.h b/value.h
index 389aff7..e6ee9fe 100644
--- a/value.h
+++ b/value.h
@@ -1237,7 +1237,11 @@ void FileSetBuffer (Value file, int buf);
extern Bool anyFileWriteBlocked;
extern Bool anyPipeReadBlocked;
-extern Value FileStdin, FileStdout, FileStderr;
+extern BoxPtr FileStdinBox, FileStdoutBox, FileStderrBox;
+
+#define FileStdin BoxValueGet(FileStdinBox, 0)
+#define FileStdout BoxValueGet(FileStdoutBox, 0)
+#define FileStderr BoxValueGet(FileStderrBox, 0)
typedef Value (*BinaryFunc) (Value, Value);
typedef Value (*UnaryFunc) (Value);
commit f0a7d677fb94d063ccefb4f8b21b15a26cb4ec49
Author: Keith Packard <keithp at keithp.com>
Date: Fri Oct 26 13:57:14 2018 -0700
Allow repeat initializers in implicit sized arrays for small dimensions
When initializing an implicitly sized multi-dimensional array, permit
repeat initializers ("...") to be used to fill out smaller dimensions.
This is done by requiring that the maximum number of elements in each
dimension be taken from an initalizer without a repeat element.
This also requires allowing repeat initializers to be useful for
resizable arrays, which required a change to the execution machinery
as well.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/compile.c b/compile.c
index 463c902..0157df8 100644
--- a/compile.c
+++ b/compile.c
@@ -1411,11 +1411,11 @@ CompileBuildArray (ObjPtr obj, ExprPtr expr, TypePtr type,
RETURN (obj);
}
-static Bool
+static void
CompileSizeDimensions (ExprPtr expr, int *dims, int ndims)
{
int dim;
-
+
if (!expr)
dim = 0;
else switch (expr->base.tag) {
@@ -1424,8 +1424,10 @@ CompileSizeDimensions (ExprPtr expr, int *dims, int ndims)
expr = expr->tree.left;
while (expr)
{
- if (expr->tree.left->base.tag == DOTDOTDOT)
- return False;
+ if (expr->tree.left->base.tag == DOTDOTDOT) {
+ dim = -dim;
+ break;
+ }
if (ndims != 1)
{
CompileSizeDimensions (expr->tree.left, dims + 1, ndims - 1);
@@ -1438,7 +1440,8 @@ CompileSizeDimensions (ExprPtr expr, int *dims, int ndims)
}
break;
case COMP:
- return False;
+ dim = -1;
+ break;
case ANONINIT:
dim = 0;
break;
@@ -1446,9 +1449,8 @@ CompileSizeDimensions (ExprPtr expr, int *dims, int ndims)
dim = 1;
break;
}
- if (dim > *dims)
+ if (abs(dim) > *dims || dim > *dims)
*dims = dim;
- return True;
}
static ExprPtr
@@ -1458,13 +1460,15 @@ CompileImplicitArray (ObjPtr obj, ExprPtr stat, ExprPtr inits, int ndim)
ExprPtr sub;
int *dims;
int n;
-
+
dims = AllocateTemp (ndim * sizeof (int));
memset (dims, '\0', ndim * sizeof (int));
- if (!CompileSizeDimensions (inits, dims, ndim))
- {
- CompileError (obj, stat, "Implicit dimensioned array with variable initializers");
- RETURN (0);
+ CompileSizeDimensions (inits, dims, ndim);
+ for (n = 0; n < ndim; n++) {
+ if (dims[n] < 0) {
+ CompileError (obj, stat, "Implicit dimensioned array with variable initializers");
+ RETURN (0);
+ }
}
sub = 0;
for (n = ndim - 1; n >= 0; n--)
@@ -1590,6 +1594,9 @@ CompileArrayInits (ObjPtr obj, ExprPtr expr, TypePtr type,
break;
case ANONINIT:
break;
+ case COMP:
+ CompileError (obj, stat, "Comprehension not valid for nested array initializer");
+ break;
default:
CompileError (obj, stat, "Not enough initializer dimensions");
break;
@@ -1831,7 +1838,7 @@ CompileArrayInit (ObjPtr obj, ExprPtr expr, Type *type, ExprPtr stat, CodePtr co
if (ndim > ninitdim ||
(ndim < ninitdim && TypeCanon(sub)->base.tag != type_array))
{
- CompileError (obj, stat, "Array dimension mismatch %d != %d\n",
+ CompileError (obj, stat, "Array dimension mismatch %d != %d",
ndim, ninitdim);
RETURN (obj);
}
diff --git a/execute.c b/execute.c
index 4329798..238b8fb 100644
--- a/execute.c
+++ b/execute.c
@@ -416,7 +416,7 @@ ThreadArrayIndex (Value array, Value thread, int ndim,
* array, so the task is just to copy that first element to the end
* of the dimension.
*/
-
+
static void
ThreadArrayReplicate (Value thread, Value array, int dim, int start)
{
@@ -425,15 +425,22 @@ ThreadArrayReplicate (Value thread, Value array, int dim, int start)
int total;
Value *elements;
- assert (!array->array.resizable);
for (i = 0; i < dim; i++)
dimsize *= ArrayDims(&array->array)[i];
start = start - dimsize;
total = ArrayDims(&array->array)[dim] * dimsize;
- elements = BoxElements (array->array.u.fix);
- for (i = start + dimsize; i % total; i += dimsize)
- memmove (elements + i, elements + start,
- dimsize * sizeof (elements[0]));
+ if (array->array.resizable) {
+ for (i = start + dimsize; i % total; i += dimsize) {
+ int j;
+ for (j = 0; j < dimsize; j++)
+ ArrayValueSet(&array->array, i + j, ArrayValueGet(&array->array, start + j));
+ }
+ } else {
+ elements = BoxElements (array->array.u.fix);
+ for (i = start + dimsize; i % total; i += dimsize)
+ memmove (elements + i, elements + start,
+ dimsize * sizeof (elements[0]));
+ }
}
void
commit b74c10a1ce0b0799e738490cb734a906950e2008
Author: Keith Packard <keithp at keithp.com>
Date: Fri Oct 26 13:32:31 2018 -0700
Remove incorrect tree walking in CompileSizeDimensions
CompileSizeDimensions was incorrectly interpreting the tree structure
for bare value nodes -- it is either passed an ARRAY, or a single
expression value, which can either be a comprehension, an empty
initializer or a simple expression. The simple expression case was
incorrectly looking for a '...' element to the left, which cannot
happen. It further recursed if it hadn't reached the end of the
dimensions, which is pointless as that case will generate an
error when the initializers are compiled later.
Debian-bug: #911926
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/compile.c b/compile.c
index 2c0640d..463c902 100644
--- a/compile.c
+++ b/compile.c
@@ -1444,10 +1444,6 @@ CompileSizeDimensions (ExprPtr expr, int *dims, int ndims)
break;
default:
dim = 1;
- if (expr->tree.left->base.tag == DOTDOTDOT)
- return False;
- if (ndims != 1)
- CompileSizeDimensions (expr, dims + 1, ndims - 1);
break;
}
if (dim > *dims)
commit c69768bd29226641c8107c56cd32d6e46af13dbb
Author: Keith Packard <keithp at keithp.com>
Date: Mon Oct 22 20:19:49 2018 -0700
Bump to version 2.83
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/configure.ac b/configure.ac
index b562d84..223b2cd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,8 +6,8 @@ dnl for licensing information.
AC_PREREQ([2.69])
-AC_INIT([nickle],[2.82],[http://nickle.org],[nickle])
-RELEASE_DATE="2018-10-02"
+AC_INIT([nickle],[2.83],[http://nickle.org],[nickle])
+RELEASE_DATE="2018-10-22"
AC_CONFIG_SRCDIR([nickle.h])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_AUX_DIR(.)
diff --git a/debian/changelog b/debian/changelog
index aa3d0ab..f5571b9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,12 @@
-nickle (2.83-1) UNRELEASED; urgency=medium
+nickle (2.83-1) unstable; urgency=medium
* Include debian/source/format in tarball
+ * Fix spelling errors in man page
+ * Fix a pile of lintian warnings
+ * Sign tarfiles when released
+ * Run CI tests from installed location
- -- Keith Packard <keithp at keithp.com> Wed, 03 Oct 2018 14:59:47 -0700
+ -- Keith Packard <keithp at keithp.com> Mon, 22 Oct 2018 19:08:54 -0700
nickle (2.82-1) unstable; urgency=medium
commit 594d768aa2cf2c9c532e4884e0da034e778c3f2f
Author: Keith Packard <keithp at keithp.com>
Date: Mon Oct 22 20:18:47 2018 -0700
debian: Run CI tests from installed location (/usr/share/nickle/test)
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/debian/tests/upstream b/debian/tests/upstream
index 5228886..e3971e8 100755
--- a/debian/tests/upstream
+++ b/debian/tests/upstream
@@ -1,5 +1,5 @@
#!/bin/sh
-cd test
-for i in *.5c; do
- nickle "$i" || exit 1
-fi
+cd /usr/share/nickle/test > /dev/null
+for test in *.5c; do
+ nickle $test || exit 1
+done
commit 9c6dd70b77b161e8d28ef759d61fbb22255d268a
Author: Keith Packard <keithp at keithp.com>
Date: Mon Oct 22 20:18:19 2018 -0700
Install tests so they can be run later
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index e1fc3f0..34ab8d0 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -16,10 +16,16 @@ check_SCRIPTS=\
jsontest.5c \
datetest.5c
-noinst_PROGRAMS=math-tables
-
TABLES=math-tables.5c
+# Install test files so they can be run later
+
+testdir=$(pkgdatadir)/test
+
+test_DATA=$(check_SCRIPTS) $(TABLES)
+
+noinst_PROGRAMS=math-tables
+
CLEANFILES=$(TABLES)
TESTS_ENVIRONMENT=NICKLESTART=$(top_srcdir)/builtin.5c NICKLEPATH=$(top_srcdir)
More information about the Nickle
mailing list