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