home *** CD-ROM | disk | FTP | other *** search
/ pc.louisiana.edu/pub/unix/ / Louisiana_UNIX.tar / Louisiana_UNIX / xspread3.0.zoo / range.c < prev    next >
C/C++ Source or Header  |  1994-03-25  |  6KB  |  284 lines

  1.  
  2. /*    SC    A Spreadsheet Calculator
  3.  *        Range Manipulations
  4.  *
  5.  *              Robert Bond, 4/87
  6.  *
  7.  *        $Revision: 6.21 A $
  8.  */
  9. #include "config.h"
  10.  
  11. #include <sys/types.h>
  12. #if defined(BSD42) || defined(BSD43)
  13. #include <strings.h>
  14. #else
  15. #ifndef SYSIII
  16. #include <string.h>
  17. #endif
  18. #endif
  19.  
  20. #include <stdio.h>
  21. #ifdef DOINGX
  22. #include <X11/Xlib.h>
  23. #include <X11/Xutil.h>
  24. #else
  25. #include <curses.h>
  26. #endif
  27. #include <ctype.h>
  28. #include "sc.h"
  29.  
  30. static struct range *rng_base;
  31.  
  32. void
  33. add_range(name, left, right, is_range)
  34. char *name;
  35. struct ent_ptr left, right;
  36. int is_range;
  37. {
  38.     struct range *r;
  39.     register char *p;
  40.     int len;
  41.     int minr,minc,maxr,maxc;
  42.     int minrf, mincf, maxrf, maxcf;
  43.     register struct ent *rcp;
  44.  
  45.     if (left.vp->row < right.vp->row) {
  46.     minr = left.vp->row; minrf = left.vf & FIX_ROW;
  47.     maxr = right.vp->row; maxrf = right.vf & FIX_ROW;
  48.     } else {
  49.     minr = right.vp->row; minrf = right.vf & FIX_ROW;
  50.     maxr = left.vp->row; maxrf = right.vf & FIX_ROW;
  51.     } 
  52.  
  53.     if (left.vp->col < right.vp->col) {
  54.     minc = left.vp->col; mincf = left.vf & FIX_COL;
  55.     maxc = right.vp->col; maxcf = right.vf & FIX_COL;
  56.     } else {
  57.     minc = right.vp->col; mincf = right.vf & FIX_COL;
  58.     maxc = left.vp->col; maxcf = left.vf & FIX_COL;
  59.     } 
  60.  
  61.     left.vp = lookat(minr, minc);
  62.     left.vf = minrf | mincf;
  63.     right.vp = lookat(maxr, maxc);
  64.     right.vf = maxrf | maxcf;
  65.  
  66.     if (find_range(name, strlen(name), (struct ent *)0, (struct ent *)0)) {
  67.     error("Error: range name already defined");
  68.     scxfree(name);
  69.     return;
  70.     }
  71.  
  72.     if (strlen(name) <= (unsigned)2) {
  73.     error("Invalid range name - too short");
  74.     scxfree(name);
  75.     return;
  76.     }
  77.  
  78.     for(p=name, len=0; *p; p++, len++)
  79.     if (!((isalpha(*p) && (len<=2)) ||
  80.         ((isdigit(*p) || isalpha(*p) || (*p == '_')) && (len>2)))) {
  81.         error("Invalid range name - illegal combination");
  82.         scxfree(name);
  83.         return;
  84.     }
  85.  
  86.     if(autolabel && minc>0 && !is_range) {
  87.     rcp = lookat(minr,minc-1);
  88.     if (rcp->label==0 && rcp->expr==0 && rcp->v==0)
  89.         label(rcp, name, 0);
  90.     }
  91.  
  92.     r = (struct range *)scxmalloc((unsigned)sizeof(struct range));
  93.     r->r_name = name;
  94.     r->r_left = left;
  95.     r->r_right = right;
  96.     r->r_next = rng_base;
  97.     r->r_prev = (struct range *)0;
  98.     r->r_is_range = is_range;
  99.     if (rng_base)
  100.         rng_base->r_prev = r;
  101.     rng_base = r;
  102. }
  103.  
  104. void
  105. del_range(left, right)
  106. struct ent *left, *right;
  107. {
  108.     register struct range *r;
  109.     int minr,minc,maxr,maxc;
  110.  
  111.     minr = left->row < right->row ? left->row : right->row;
  112.     minc = left->col < right->col ? left->col : right->col;
  113.     maxr = left->row > right->row ? left->row : right->row;
  114.     maxc = left->col > right->col ? left->col : right->col;
  115.  
  116.     left = lookat(minr, minc);
  117.     right = lookat(maxr, maxc);
  118.  
  119.     if (!(r = find_range((char *)0, 0, left, right))) 
  120.     return;
  121.  
  122.     if (r->r_next)
  123.         r->r_next->r_prev = r->r_prev;
  124.     if (r->r_prev)
  125.         r->r_prev->r_next = r->r_next;
  126.     else
  127.     rng_base = r->r_next;
  128.     scxfree((char *)(r->r_name));
  129.     scxfree((char *)r);
  130. }
  131.  
  132. void
  133. clean_range()
  134. {
  135.     register struct range *r;
  136.     register struct range *nextr;
  137.  
  138.     r = rng_base;
  139.     rng_base = (struct range *)0;
  140.  
  141.     while (r) {
  142.     nextr = r->r_next;
  143.     scxfree((char *)(r->r_name));
  144.     scxfree((char *)r);
  145.     r = nextr;
  146.     }
  147. }
  148.  
  149. /* Match on name or lmatch, rmatch */
  150.  
  151. struct range *
  152. find_range(name, len, lmatch, rmatch)
  153. char *name;
  154. int len;
  155. struct ent *lmatch;
  156. struct ent *rmatch;
  157. {
  158.     struct range *r;
  159.     register char *rp, *np;
  160.     register int c;
  161.  
  162.     if (name) {
  163.     for (r = rng_base; r; r = r->r_next) {
  164.         for (np = name, rp = r->r_name, c = len;
  165.          c && *rp && (*rp == *np);
  166.          rp++, np++, c--) /* */;
  167.         if (!c && !*rp)
  168.         return(r);
  169.     }
  170.     return((struct range *)0);
  171.     }
  172.  
  173.     for (r = rng_base; r; r= r->r_next) {
  174.     if ((lmatch == r->r_left.vp) && (rmatch == r->r_right.vp)) 
  175.         return(r);
  176.     }
  177.     return((struct range *)0);
  178. }
  179.  
  180. void
  181. sync_ranges()
  182. {
  183.     register struct range *r;
  184.  
  185.     r = rng_base;
  186.     while(r) {
  187.     r->r_left.vp = lookat(r->r_left.vp->row, r->r_left.vp->col);
  188.     r->r_right.vp = lookat(r->r_right.vp->row, r->r_right.vp->col);
  189.     r = r->r_next;
  190.     }
  191. }
  192.  
  193. void
  194. write_range(f)
  195. FILE *f;
  196. {
  197.     register struct range *r;
  198.  
  199.     for (r = rng_base; r; r = r->r_next) {
  200.     (void) fprintf(f, "define \"%s\" %s%s%s%d",
  201.             r->r_name,
  202.             r->r_left.vf & FIX_COL ? "$":"",
  203.             coltoa(r->r_left.vp->col), 
  204.             r->r_left.vf & FIX_ROW ? "$":"",
  205.             r->r_left.vp->row);
  206.     if (r->r_is_range)
  207.         (void) fprintf(f, ":%s%s%s%d\n",
  208.                 r->r_right.vf & FIX_COL ? "$":"",
  209.                 coltoa(r->r_right.vp->col), 
  210.                 r->r_right.vf & FIX_ROW ? "$":"",
  211.                 r->r_right.vp->row);
  212.     else
  213.         (void) fprintf(f, "\n");
  214.     }
  215. }
  216.  
  217. void
  218. list_range(f)
  219. FILE *f;
  220. {
  221.     register struct range *r;
  222.  
  223.     (void) fprintf(f, "%-30s %s\n\n","Name","Definition");
  224.  
  225.     for (r = rng_base; r; r = r->r_next) {
  226.     (void) fprintf(f, "%-30s %s%s%s%d",
  227.                 r->r_name,
  228.                 r->r_left.vf & FIX_COL ? "$":"",
  229.                 coltoa(r->r_left.vp->col), 
  230.                 r->r_left.vf & FIX_ROW ? "$":"",
  231.                 r->r_left.vp->row);
  232.     if (r->r_is_range)
  233.         (void) fprintf(f, ":%s%s%s%d\n",
  234.                 r->r_right.vf & FIX_COL ? "$":"",
  235.                 coltoa(r->r_right.vp->col), 
  236.                 r->r_right.vf & FIX_ROW ? "$":"",
  237.                 r->r_right.vp->row);
  238.     else
  239.         (void) fprintf(f, "\n");
  240.     }
  241. }
  242.  
  243. char *
  244. v_name(row, col)
  245. int row, col;
  246. {
  247.     struct ent *v;
  248.     struct range *r;
  249.     static char buf[20];
  250.  
  251.     v = lookat(row, col);
  252.     if (r = find_range((char *)0, 0, v, v)) {
  253.     return(r->r_name);
  254.     } else {
  255.         (void) sprintf(buf, "%s%d", coltoa(col), row);
  256.     return(buf);
  257.     }
  258. }
  259.  
  260. char *
  261. r_name(r1, c1, r2, c2)
  262. int r1, c1, r2, c2;
  263. {
  264.     struct ent *v1, *v2;
  265.     struct range *r;
  266.     static char buf[100];
  267.  
  268.     v1 = lookat(r1, c1);
  269.     v2 = lookat(r2, c2);
  270.     if (r = find_range((char *)0, 0, v1, v2)) {
  271.     return(r->r_name);
  272.     } else {
  273.         (void) sprintf(buf, "%s", v_name(r1, c1));
  274.     (void) sprintf(buf+strlen(buf), ":%s", v_name(r2, c2));
  275.     return(buf);
  276.     }
  277. }
  278.  
  279. int
  280. are_ranges()
  281. {
  282.     return (rng_base != 0);
  283. }
  284.