date and time created 90/10/11 11:35:34 by bostic
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Fri, 12 Oct 1990 03:35:34 +0000 (19:35 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Fri, 12 Oct 1990 03:35:34 +0000 (19:35 -0800)
SCCS-vsn: contrib/sc/range.c 5.1

usr/src/contrib/sc/range.c [new file with mode: 0644]

diff --git a/usr/src/contrib/sc/range.c b/usr/src/contrib/sc/range.c
new file mode 100644 (file)
index 0000000..8d4c720
--- /dev/null
@@ -0,0 +1,263 @@
+
+/*     SC      A Spreadsheet Calculator
+ *             Range Manipulations
+ *
+ *              Robert Bond, 4/87
+ *
+ *             $Revision: 6.8 $
+ */
+
+#include <stdio.h>
+#include <curses.h>
+#include <ctype.h>
+#include "sc.h"
+
+#ifdef BSD42
+#include <strings.h>
+#else
+#ifndef SYSIII
+#include <string.h>
+#endif
+#endif
+
+static struct range *rng_base;
+
+add_range(name, left, right, is_range)
+char *name;
+struct ent_ptr left, right;
+int is_range;
+{
+    struct range *r;
+    register char *p;
+    int len;
+    int minr,minc,maxr,maxc;
+    int minrf, mincf, maxrf, maxcf;
+
+    if (left.vp->row < right.vp->row) {
+       minr = left.vp->row; minrf = left.vf & FIX_ROW;
+       maxr = right.vp->row; maxrf = right.vf & FIX_ROW;
+    } else {
+       minr = right.vp->row; minrf = right.vf & FIX_ROW;
+       maxr = left.vp->row; maxrf = right.vf & FIX_ROW;
+    } 
+
+    if (left.vp->col < right.vp->col) {
+       minc = left.vp->col; mincf = left.vf & FIX_COL;
+       maxc = right.vp->col; maxcf = right.vf & FIX_COL;
+    } else {
+       minc = right.vp->col; mincf = right.vf & FIX_COL;
+       maxc = left.vp->col; maxcf = left.vf & FIX_COL;
+    } 
+
+    left.vp = lookat(minr, minc);
+    left.vf = minrf | mincf;
+    right.vp = lookat(maxr, maxc);
+    right.vf = maxrf | maxcf;
+
+    if (find_range(name, strlen(name), (struct ent *)0, (struct ent *)0)) {
+       error("Error: range name already defined");
+       xfree(name);
+       return;
+    }
+
+    if (strlen(name) <= 2) {
+       error("Invalid range name - too short");
+       xfree(name);
+       return;
+    }
+
+    for(p=name, len=0; *p; p++, len++)
+       if (!((isalpha(*p) && (len<=2)) ||
+           ((isdigit(*p) || isalpha(*p) || (*p == '_')) && (len>2)))) {
+           error("Invalid range name - illegal combination");
+           xfree(name);
+           return;
+        }
+
+    r = (struct range *)xmalloc((unsigned)sizeof(struct range));
+    r->r_name = name;
+    r->r_left = left;
+    r->r_right = right;
+    r->r_next = rng_base;
+    r->r_prev = (struct range *)0;
+    r->r_is_range = is_range;
+    if (rng_base)
+        rng_base->r_prev = r;
+    rng_base = r;
+}
+
+del_range(left, right)
+struct ent *left, *right;
+{
+    register struct range *r;
+    int minr,minc,maxr,maxc;
+
+    minr = left->row < right->row ? left->row : right->row;
+    minc = left->col < right->col ? left->col : right->col;
+    maxr = left->row > right->row ? left->row : right->row;
+    maxc = left->col > right->col ? left->col : right->col;
+
+    left = lookat(minr, minc);
+    right = lookat(maxr, maxc);
+
+    if (!(r = find_range((char *)0, 0, left, right))) 
+       return;
+
+    if (r->r_next)
+        r->r_next->r_prev = r->r_prev;
+    if (r->r_prev)
+        r->r_prev->r_next = r->r_next;
+    else
+       rng_base = r->r_next;
+    xfree((char *)(r->r_name));
+    xfree((char *)r);
+}
+
+clean_range()
+{
+    register struct range *r;
+    register struct range *nextr;
+
+    r = rng_base;
+    rng_base = (struct range *)0;
+
+    while (r) {
+       nextr = r->r_next;
+       xfree((char *)(r->r_name));
+       xfree((char *)r);
+       r = nextr;
+    }
+}
+
+/* Match on name or lmatch, rmatch */
+
+struct range *
+find_range(name, len, lmatch, rmatch)
+char *name;
+int len;
+struct ent *lmatch;
+struct ent *rmatch;
+{
+    struct range *r;
+    register char *rp, *np;
+    register int c;
+
+    if (name) {
+       for (r = rng_base; r; r = r->r_next) {
+           for (np = name, rp = r->r_name, c = len;
+                c && *rp && (*rp == *np);
+                rp++, np++, c--) /* */;
+           if (!c && !*rp)
+               return(r);
+       }
+       return((struct range *)0);
+    }
+
+    for (r = rng_base; r; r= r->r_next) {
+       if ((lmatch == r->r_left.vp) && (rmatch == r->r_right.vp)) 
+           return(r);
+    }
+    return((struct range *)0);
+}
+
+sync_ranges()
+{
+    register struct range *r;
+
+    r = rng_base;
+    while(r) {
+       r->r_left.vp = lookat(r->r_left.vp->row, r->r_left.vp->col);
+       r->r_right.vp = lookat(r->r_right.vp->row, r->r_right.vp->col);
+       r = r->r_next;
+    }
+}
+
+write_range(f)
+FILE *f;
+{
+    register struct range *r;
+
+    for (r = rng_base; r; r = r->r_next) {
+       (void) fprintf(f, "define \"%s\" %s%s%s%d",
+                       r->r_name,
+                       r->r_left.vf & FIX_COL ? "$":"",
+                       coltoa(r->r_left.vp->col), 
+                       r->r_left.vf & FIX_ROW ? "$":"",
+                       r->r_left.vp->row);
+       if (r->r_is_range)
+           (void) fprintf(f, ":%s%s%s%d\n",
+                           r->r_right.vf & FIX_COL ? "$":"",
+                           coltoa(r->r_right.vp->col), 
+                           r->r_right.vf & FIX_ROW ? "$":"",
+                           r->r_right.vp->row);
+       else
+           (void) fprintf(f, "\n");
+    }
+}
+
+void
+list_range(f)
+FILE *f;
+{
+    register struct range *r;
+
+    (void) fprintf(f, "%-30s %s\n\n","Name","Definition");
+
+    for (r = rng_base; r; r = r->r_next) {
+       (void) fprintf(f, "%-30s %s%s%s%d",
+                           r->r_name,
+                           r->r_left.vf & FIX_COL ? "$":"",
+                           coltoa(r->r_left.vp->col), 
+                           r->r_left.vf & FIX_ROW ? "$":"",
+                           r->r_left.vp->row);
+       if (r->r_is_range)
+           (void) fprintf(f, ":%s%s%s%d\n",
+                           r->r_right.vf & FIX_COL ? "$":"",
+                           coltoa(r->r_right.vp->col), 
+                           r->r_right.vf & FIX_ROW ? "$":"",
+                           r->r_right.vp->row);
+       else
+           (void) fprintf(f, "\n");
+    }
+}
+
+char *
+v_name(row, col)
+int row, col;
+{
+    struct ent *v;
+    struct range *r;
+    static char buf[20];
+
+    v = lookat(row, col);
+    if (r = find_range((char *)0, 0, v, v)) {
+       return(r->r_name);
+    } else {
+        (void) sprintf(buf, "%s%d", coltoa(col), row);
+       return(buf);
+    }
+}
+
+char *
+r_name(r1, c1, r2, c2)
+int r1, c1, r2, c2;
+{
+    struct ent *v1, *v2;
+    struct range *r;
+    static char buf[100];
+
+    v1 = lookat(r1, c1);
+    v2 = lookat(r2, c2);
+    if (r = find_range((char *)0, 0, v1, v2)) {
+       return(r->r_name);
+    } else {
+        (void) sprintf(buf, "%s", v_name(r1, c1));
+       (void) sprintf(buf+strlen(buf), ":%s", v_name(r2, c2));
+       return(buf);
+    }
+}
+
+are_ranges()
+{
+return (rng_base != 0);
+}