home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 498a.lha / SC_v6.7 / range.c < prev    next >
C/C++ Source or Header  |  1991-04-08  |  6KB  |  264 lines

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