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