home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / EFFO / pd7.lzh / SRC / range.c < prev    next >
Text File  |  1990-04-19  |  6KB  |  266 lines

  1.  
  2. /*      SC      A Spreadsheet Calculator
  3.  *              Range Manipulations
  4.  *
  5.  *              Robert Bond, 4/87
  6.  *
  7.  *              $Revision: 6.1 $
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <curses.h>
  12. #include <ctype.h>
  13. #include "sc.h"
  14.  
  15. #if defined(BSD42) || defined(OSK)
  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. void 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 = 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. void 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 = 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(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(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. list_range(f)
  199. FILE *f;
  200. {
  201.     register struct range *r;
  202.  
  203.     (void) fprintf(f, "%-30s %s\n\n","Name","Definition");
  204. #ifdef OSK
  205.     (void) fprintf(f, "----------------------------- -----------\n");
  206. #endif
  207.  
  208.     for (r = rng_base; r; r = r->r_next) {
  209.         (void) fprintf(f, "%-30s %s%s%s%d",
  210.                             r->r_name,
  211.                             r->r_left.vf & FIX_COL ? "$":"",
  212.                             coltoa(r->r_left.vp->col),
  213.                             r->r_left.vf & FIX_ROW ? "$":"",
  214.                             r->r_left.vp->row);
  215.         if (r->r_is_range)
  216.             (void) fprintf(f, ":%s%s%s%d\n",
  217.                             r->r_right.vf & FIX_COL ? "$":"",
  218.                             coltoa(r->r_right.vp->col),
  219.                             r->r_right.vf & FIX_ROW ? "$":"",
  220.                             r->r_right.vp->row);
  221.         else
  222.             (void) fprintf(f, "\n");
  223.     }
  224. }
  225.  
  226. char *
  227. v_name(row, col)
  228. int row, col;
  229. {
  230.     struct ent *v;
  231.     struct range *r;
  232.     static char buf[20];
  233.  
  234.     v = lookat(row, col);
  235.     if (r = find_range((char *)0, 0, v, v)) {
  236.         return(r->r_name);
  237.     } else {
  238.         (void) sprintf(buf, "%s%d", coltoa(col), row);
  239.         return(buf);
  240.     }
  241. }
  242.  
  243. char *
  244. r_name(r1, c1, r2, c2)
  245. int r1, c1, r2, c2;
  246. {
  247.     struct ent *v1, *v2;
  248.     struct range *r;
  249.     static char buf[100];
  250.  
  251.     v1 = lookat(r1, c1);
  252.     v2 = lookat(r2, c2);
  253.     if (r = find_range((char *)0, 0, v1, v2)) {
  254.         return(r->r_name);
  255.     } else {
  256.         (void) sprintf(buf, "%s", v_name(r1, c1));
  257.         (void) sprintf(buf+strlen(buf), ":%s", v_name(r2, c2));
  258.         return(buf);
  259.     }
  260. }
  261.  
  262. are_ranges()
  263. {
  264. return (rng_base != 0);
  265. }
  266.