home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Product / Product.zip / sc621_3.zip / src / range.c < prev    next >
C/C++ Source or Header  |  1992-05-11  |  6KB  |  278 lines

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