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