home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. CD ROM (Annual Premium Edition)
/
premium.zip
/
premium
/
IBMOS2_1
/
SC621.ZIP
/
sc621
/
range.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-01
|
6KB
|
278 lines
/* SC A Spreadsheet Calculator
* Range Manipulations
*
* Robert Bond, 4/87
*
* $Revision: 6.21 $
*/
#include <sys/types.h>
#ifdef BSD42
#include <strings.h>
#else
#ifndef SYSIII
#include <string.h>
#endif
#endif
#include <stdio.h>
#include <curses.h>
#include <ctype.h>
#include "sc.h"
static struct range *rng_base;
void
add_range(name, left, right, is_range)
char *name;
struct ent_ptr left, right;
int is_range;
{
struct range *r;
register char *p;
int len;
int minr,minc,maxr,maxc;
int minrf, mincf, maxrf, maxcf;
register struct ent *rcp;
if (left.vp->row < right.vp->row) {
minr = left.vp->row; minrf = left.vf & FIX_ROW;
maxr = right.vp->row; maxrf = right.vf & FIX_ROW;
} else {
minr = right.vp->row; minrf = right.vf & FIX_ROW;
maxr = left.vp->row; maxrf = right.vf & FIX_ROW;
}
if (left.vp->col < right.vp->col) {
minc = left.vp->col; mincf = left.vf & FIX_COL;
maxc = right.vp->col; maxcf = right.vf & FIX_COL;
} else {
minc = right.vp->col; mincf = right.vf & FIX_COL;
maxc = left.vp->col; maxcf = left.vf & FIX_COL;
}
left.vp = lookat(minr, minc);
left.vf = minrf | mincf;
right.vp = lookat(maxr, maxc);
right.vf = maxrf | maxcf;
if (find_range(name, strlen(name), (struct ent *)0, (struct ent *)0)) {
error("Error: range name already defined");
scxfree(name);
return;
}
if (strlen(name) <= 2) {
error("Invalid range name - too short");
scxfree(name);
return;
}
for(p=name, len=0; *p; p++, len++)
if (!((isalpha(*p) && (len<=2)) ||
((isdigit(*p) || isalpha(*p) || (*p == '_')) && (len>2)))) {
error("Invalid range name - illegal combination");
scxfree(name);
return;
}
if(autolabel && minc>0 && !is_range) {
rcp = lookat(minr,minc-1);
if (rcp->label==0 && rcp->expr==0 && rcp->v==0)
label(rcp, name, 0);
}
r = (struct range *)scxmalloc((unsigned)sizeof(struct range));
r->r_name = name;
r->r_left = left;
r->r_right = right;
r->r_next = rng_base;
r->r_prev = (struct range *)0;
r->r_is_range = is_range;
if (rng_base)
rng_base->r_prev = r;
rng_base = r;
}
void
del_range(left, right)
struct ent *left, *right;
{
register struct range *r;
int minr,minc,maxr,maxc;
minr = left->row < right->row ? left->row : right->row;
minc = left->col < right->col ? left->col : right->col;
maxr = left->row > right->row ? left->row : right->row;
maxc = left->col > right->col ? left->col : right->col;
left = lookat(minr, minc);
right = lookat(maxr, maxc);
if (!(r = find_range((char *)0, 0, left, right)))
return;
if (r->r_next)
r->r_next->r_prev = r->r_prev;
if (r->r_prev)
r->r_prev->r_next = r->r_next;
else
rng_base = r->r_next;
scxfree((char *)(r->r_name));
scxfree((char *)r);
}
void
clean_range()
{
register struct range *r;
register struct range *nextr;
r = rng_base;
rng_base = (struct range *)0;
while (r) {
nextr = r->r_next;
scxfree((char *)(r->r_name));
scxfree((char *)r);
r = nextr;
}
}
/* Match on name or lmatch, rmatch */
struct range *
find_range(name, len, lmatch, rmatch)
char *name;
int len;
struct ent *lmatch;
struct ent *rmatch;
{
struct range *r;
register char *rp, *np;
register int c;
if (name) {
for (r = rng_base; r; r = r->r_next) {
for (np = name, rp = r->r_name, c = len;
c && *rp && (*rp == *np);
rp++, np++, c--) /* */;
if (!c && !*rp)
return(r);
}
return((struct range *)0);
}
for (r = rng_base; r; r= r->r_next) {
if ((lmatch == r->r_left.vp) && (rmatch == r->r_right.vp))
return(r);
}
return((struct range *)0);
}
void
sync_ranges()
{
register struct range *r;
r = rng_base;
while(r) {
r->r_left.vp = lookat(r->r_left.vp->row, r->r_left.vp->col);
r->r_right.vp = lookat(r->r_right.vp->row, r->r_right.vp->col);
r = r->r_next;
}
}
void
write_range(f)
FILE *f;
{
register struct range *r;
for (r = rng_base; r; r = r->r_next) {
(void) fprintf(f, "define \"%s\" %s%s%s%d",
r->r_name,
r->r_left.vf & FIX_COL ? "$":"",
coltoa(r->r_left.vp->col),
r->r_left.vf & FIX_ROW ? "$":"",
r->r_left.vp->row);
if (r->r_is_range)
(void) fprintf(f, ":%s%s%s%d\n",
r->r_right.vf & FIX_COL ? "$":"",
coltoa(r->r_right.vp->col),
r->r_right.vf & FIX_ROW ? "$":"",
r->r_right.vp->row);
else
(void) fprintf(f, "\n");
}
}
void
list_range(f)
FILE *f;
{
register struct range *r;
(void) fprintf(f, "%-30s %s\n\n","Name","Definition");
for (r = rng_base; r; r = r->r_next) {
(void) fprintf(f, "%-30s %s%s%s%d",
r->r_name,
r->r_left.vf & FIX_COL ? "$":"",
coltoa(r->r_left.vp->col),
r->r_left.vf & FIX_ROW ? "$":"",
r->r_left.vp->row);
if (r->r_is_range)
(void) fprintf(f, ":%s%s%s%d\n",
r->r_right.vf & FIX_COL ? "$":"",
coltoa(r->r_right.vp->col),
r->r_right.vf & FIX_ROW ? "$":"",
r->r_right.vp->row);
else
(void) fprintf(f, "\n");
}
}
char *
v_name(row, col)
int row, col;
{
struct ent *v;
struct range *r;
static char buf[20];
v = lookat(row, col);
if (r = find_range((char *)0, 0, v, v)) {
return(r->r_name);
} else {
(void) sprintf(buf, "%s%d", coltoa(col), row);
return(buf);
}
}
char *
r_name(r1, c1, r2, c2)
int r1, c1, r2, c2;
{
struct ent *v1, *v2;
struct range *r;
static char buf[100];
v1 = lookat(r1, c1);
v2 = lookat(r2, c2);
if (r = find_range((char *)0, 0, v1, v2)) {
return(r->r_name);
} else {
(void) sprintf(buf, "%s", v_name(r1, c1));
(void) sprintf(buf+strlen(buf), ":%s", v_name(r2, c2));
return(buf);
}
}
int
are_ranges()
{
return (rng_base != 0);
}