ref: 7e3533cf6041b0c950a0161c11f391617f1aa21d
parent: d0df10c1ad637b550cea8e7dfd538d1f02e9fc0a
author: sirjofri <sirjofri@sirjofri.de>
date: Fri Jul 5 10:06:38 EDT 2024
do some rudimentary cyclic dependency check
--- a/cells.c
+++ b/cells.c
@@ -200,11 +200,23 @@
c->num = 0;
}
-void
+int
+findfree(int i)
+{
+ for (; i < block.num; i++) {
+ if (block.cells[i].type == INVALID)
+ return i;
+ }
+ return -1;
+}
+
+int
sortcells(void)
{
Cell *c;
Cellblock b;
+ int nq;
+ P p;
// build DAG information
funcregexp = regcomp("[A-Z]+[0-9]+[(]+[)]+");
@@ -225,9 +237,62 @@
b.num++;
}
+ for (int i = 0; i < b.num; i++) {
+ c = &b.cells[i];
+ if (c->points)
+ free(c->points);
+ c->points = nil;
+ c->num = 0;
+ c->size = 0;
+ c->indeg = 0;
+ }
+
+ for (int i = 0; i < block.num; i++) {
+ c = &block.cells[i];
+ if (c->type == 0)
+ continue;
+ goto Errout;
+ }
+
block.num = b.num;
block.cells = b.cells;
memset(&b, 0, sizeof(Cellblock));
+ return 1;
+
+Errout:
+ p = c->p;
+
+ /* free dependency calculation */
+ for (int i = 0; i < block.num; i++) {
+ c = &block.cells[i];
+ if (c->type == 0)
+ continue;
+ if (c->points)
+ free(c->points);
+ c->points = nil;
+ c->num = 0;
+ c->size = 0;
+ c->indeg = 0;
+ }
+
+ /* move cells back to original block */
+ nq = 0;
+ for (int i = 0; i < b.num; i++) {
+ c = &b.cells[i];
+ if (c->type == 0)
+ continue;
+ nq = findfree(nq);
+ if (nq < 0)
+ sysfatal("can't happen");
+ memcpy(&block.cells[nq], c, sizeof(Cell));
+ nq++;
+ }
+
+ free(b.cells);
+ memset(&b, 0, sizeof(Cellblock));
+
+ werrstr("cyclic dependencies found involving %s", ptoa(p));
+ return 0;
}
void
--- a/engine.c
+++ b/engine.c
@@ -380,11 +380,13 @@
return 1;
}
-void
+int
updatecells()
{
- sortcells();
+ if (!sortcells())
+ return 0;
foreachcell(sendctohoc, nil);
+ return 1;
}
static void
--- a/spread.c
+++ b/spread.c
@@ -84,6 +84,7 @@
char *file = nil;
int dirty = 0;
char *error = nil;
+char errstring[ERRMAX] = "";
void
drawtopline(void)
@@ -226,7 +227,11 @@
return;
addcell(p, s, type);
- updatecells();
+ if (!updatecells()) {
+ rerrstr(errstring, ERRMAX);
+ error = errstring;
+ } else
+ error = nil;
dirty = 1;
redraw();
}
--- a/spread.h
+++ b/spread.h
@@ -5,6 +5,7 @@
typedef struct Cell Cell;
typedef struct Response Response;
+#define INVALID 0
#define FUNCTION 1
#define STRING 2
@@ -21,8 +22,8 @@
void gccells(void);
void dumpcells(void);
void foreachcell(void (*f)(Cell*,void*), void*);
-void sortcells(void);
-void updatecells(void);
+int sortcells(void);
+int updatecells(void);
void toupperil(char*);
P atop(char*);