|
|
1.1 ! root 1: /* Copyright Bell Telephone Laboratories Whippany, N.J. ! 2: ! 3: * ///////////////////////////////////// ! 4: * ///////////////////////////////////// ! 5: * ///////////// savars.c ////////////// ! 6: * /// J. P. Hawkins WH X4610 8C-001 /// ! 7: * ///// Fri Feb 27 06:32:38 1981 ////// ! 8: * ///////////////////////////////////// ! 9: * ///////////////////////////////////// ! 10: * @(#) savars.c: V1.2 3/4/81 ! 11: ! 12: * String array variable Allocation and Fetch routines ! 13: * For BITE ! 14: * ! 15: */ ! 16: /* "@(#) savars.c: V 1.1 2/4/81" */ ! 17: ! 18: #include "bas.h" ! 19: /* ! 20: * this is the symbol table (table of pointers) for string array ! 21: * variables. The first subscript 'j' is calculated by the ! 22: * alpha name, the second subscript 'k' is calculated by the ! 23: * numeric part + 1. If no numeric is specified, k = 0 ! 24: * ! 25: * The pointer points to an area in memory allocated by dim. ! 26: * The area is of similar form to that of numeric variables ! 27: * except, the pointers to the strings rather than values are ! 28: * actually stored. The header form is the same as that for numeric ! 29: * variables except that the constants a1,a2,a3,..,etc. ! 30: * are unnecessary due to allowing only one or two dimensions. ! 31: * (see remarks at beginning of dim.c module and diagram) ! 32: * ! 33: * The specification for a string array variable is of the form: ! 34: * Alpha[Numeric]$(a,b) ! 35: * The dimension "dim" statement is specified in the form: ! 36: * dim Alpha[numeric]$(XMAX[,YMAX]) ! 37: * The starting location is obtained by the equation: ! 38: * Loc = (a-1)*YMAX+b-1 ! 39: * ! 40: * where a <= XMAX ! 41: * b <= YMAX ! 42: * ! 43: * If dimension YMAX is not given it is set to 1, however the ! 44: * first byte of the header will specify only one dimension exists. ! 45: * ! 46: */ ! 47: char * sasymtab[26][11]; ! 48: extern char *hicore; /* pointer lowest used corespace from ! 49: top of user area */ ! 50: ! 51: ! 52: struct FREELIST freelist[MAXFREE]; ! 53: /* ! 54: * //////// FETCH VALUE OF VARIABLE //////// ! 55: * ! 56: * calling format: ! 57: * ! 58: * sagetvar(sname, &sptr); ! 59: * ! 60: * where: sname = string containing VALID variable name ! 61: * i.e. [a-z] or a[0-9] - z[0-9] ! 62: * sptr = pointer to string ! 63: */ ! 64: sagetvar(sname,sptr) ! 65: char sname[]; ! 66: char **sptr; /* pointer to string pointer */ ! 67: { ! 68: char *addr; ! 69: ! 70: if(sgetaddr(sname, &addr) < 0) ! 71: return(-1); /* error occurred in getting addr */ ! 72: ! 73: if(addr == 0) /*if no pointer for this variable */ ! 74: /* (not allocated, yet) */ ! 75: { ! 76: error2(inst.thing.linno,7,' '); /* UNASSIGNED VARIABLE */ ! 77: printf("- '%s'\n",sname); /* print variable name */ ! 78: *sptr = 0; /* return zero anyway */ ! 79: return(-1); ! 80: } ! 81: else ! 82: { ! 83: *sptr = addr; /* set ptr to data location */ ! 84: *sptr += 1; /* bump past size byte */ ! 85: } ! 86: return(0); ! 87: } ! 88: /* ! 89: * ! 90: * //// ASSIGN A VALUE TO A VARIABLE //// ! 91: * /////////// ALLOCATE SPACE ////////// ! 92: * ! 93: * Copy the string into the allocated location. ! 94: * ! 95: * calling format: ! 96: * ! 97: * saputvar(sname, sptr); ! 98: * ! 99: * where: sname = string pointer to VALID variable name ! 100: * sptr = pointer to string to be copied ! 101: */ ! 102: saputvar(sname,sptr) ! 103: char sname[]; /* valid variable string (name) */ ! 104: char *sptr; /* pointer to string */ ! 105: { ! 106: register char *ptr,*cptr; /* pointer used for string copy to mem */ ! 107: char *lookfree(); ! 108: int ssize; /* string size */ ! 109: int useagain; /* flag to use space again */ ! 110: char *addr; /* pointer array el. which is ptr to string */ ! 111: ! 112: useagain = 0; ! 113: cptr = sptr; /* get source string pointer */ ! 114: ssize = strlen(sptr); /* get size of string */ ! 115: if(sgetaddr(sname, &addr) < 0) ! 116: return(-1); /* error occurred in getting addr */ ! 117: if(addr != 0) /* if this variable was used before */ ! 118: { ! 119: ptr = addr; /* point to old space */ ! 120: savefree(ptr); /* save area old in free list */ ! 121: if((addr = ptr = lookfree(ssize)) != 0) ! 122: useagain = 1; /* if other hole is found */ ! 123: } ! 124: if(!useagain) /* if this is the first time this var was used */ ! 125: { ! 126: /* ! 127: * Return error if not enough space left ! 128: */ ! 129: if((hicore - (ssize+2)) <= linptr) ! 130: { ! 131: error(inst.thing.linno, 24); /* NOT ENOUGH ADD. CORE */ ! 132: return(-1); ! 133: } ! 134: hicore -= (ssize+2); /* set new hicore mark - */ ! 135: /* include space for null and size */ ! 136: ptr = hicore; /* set pointer for copy */ ! 137: *ptr = ssize; /* put size of 1st string in 1st loc */ ! 138: addr = ptr; /* put new pointer in array table */ ! 139: ! 140: if((unsigned)hicore & 1) /* hicore to even boundry */ ! 141: hicore--; ! 142: } ! 143: ptr++; /* bump past size */ ! 144: ! 145: while(*ptr++ = *cptr++); /* copy string into storage */ ! 146: ! 147: return(0); ! 148: } ! 149: #ifdef notdef ! 150: /* ! 151: * Return size of string up to first null character ! 152: */ ! 153: static strlen(s) ! 154: char *s; ! 155: { ! 156: register count; ! 157: for(count = 0; s[count]; count++); ! 158: return(count); ! 159: } ! 160: #endif ! 161: /* ! 162: * ! 163: * Look in freelist to for smallest free area ! 164: * which will fit new allocation. If none, return false. ! 165: * The free list points to previously scrapped areas. ! 166: */ ! 167: char * ! 168: lookfree(size) ! 169: { ! 170: register i; ! 171: int bestsize,besti; ! 172: ! 173: for(i=0, bestsize=0; i<MAXFREE; i++) ! 174: { ! 175: if(freelist[i].size == 0) /* skip null or deleted entries */ ! 176: continue; ! 177: if(freelist[i].size >= size) ! 178: { ! 179: if(bestsize == 0) /* force first fit */ ! 180: { ! 181: bestsize = freelist[i].size; ! 182: besti = i; ! 183: } ! 184: else if(freelist[i].size < bestsize) /* better fit? */ ! 185: { ! 186: bestsize = freelist[i].size; ! 187: besti = i; ! 188: } ! 189: } ! 190: } ! 191: if(bestsize == 0) ! 192: return(0); /* nothing found */ ! 193: else ! 194: { ! 195: freelist[besti].size = 0; /* take off free list */ ! 196: return(freelist[besti].fraddr); ! 197: } ! 198: } ! 199: ! 200: savefree(addr) ! 201: char *addr; ! 202: { ! 203: register i; ! 204: int size; ! 205: int there; ! 206: ! 207: size = *addr; ! 208: for(i=0,there=0; i<MAXFREE; i++) ! 209: { ! 210: if((freelist[i].size != 0) && (freelist[i].fraddr == addr)) ! 211: { ! 212: /* avoid dup entry */ ! 213: there = 1; ! 214: break; ! 215: } ! 216: } ! 217: if(!there) ! 218: { ! 219: for(i=0; i<MAXFREE; i++) ! 220: { ! 221: if(freelist[i].size == 0) ! 222: { ! 223: freelist[i].size = size; /* save size */ ! 224: freelist[i].fraddr = addr; /* save address */ ! 225: break; ! 226: } ! 227: } ! 228: } ! 229: } ! 230: /* ! 231: * ! 232: * /// COMPUTE ARRAY VARIABLE ADDRESS /// ! 233: */ ! 234: sgetaddr(vstr, addr) ! 235: char vstr[]; /* subscripted variable string */ ! 236: char **addr; /* address of subscripted variable pointer */ ! 237: { ! 238: char arname[3]; /* array name */ ! 239: int offset; ! 240: int *ptr; /* location pointer */ ! 241: int asize; /* actual array size */ ! 242: double rsize; /* requested size */ ! 243: register i; ! 244: int j,k; ! 245: double rdims[MAXDIM]; /* requested dims */ ! 246: int adims[2]; /* actual dims */ ! 247: int amax; /* max number of dims */ ! 248: ! 249: amax = 2; /* no more than two dimensions */ ! 250: /* ! 251: * GET ARRAY SYMBOL NAME, NUMBER OF DIMENSIONS & ! 252: * PUT THE VALUE OF EACH DIMENSION IN DIMLIST ! 253: */ ! 254: if(getdims(vstr,arname,&rsize,rdims) < 0) ! 255: return(-1); ! 256: if(rsize == 1.0) ! 257: { ! 258: rdims[1] = 1.0; ! 259: } ! 260: j = arname[0] - 'a'; /* compute j subscript */ ! 261: ! 262: /* ! 263: * compute k subscript ! 264: */ ! 265: if(arname[1] == '\0') /* if no numeric part */ ! 266: k = 0; /* then k = 0th column */ ! 267: else ! 268: k = arname[1] - '0' + 1; ! 269: ! 270: if(sasymtab[j][k] == 0) /* if not dimensioned complain */ ! 271: { ! 272: error(inst.thing.linno, 25); /* NOT DIMENSIONED */ ! 273: return(-1); ! 274: } ! 275: ptr = (int *)sasymtab[j][k]; /* point to header */ ! 276: asize = *--ptr; /* get actual size */ ! 277: if(asize != (int)rsize) /* error if mismatch in actual to ! 278: requested size */ ! 279: { ! 280: error(inst.thing.linno, 26); /* WRONG NUM OF DIMS */ ! 281: return(-1); ! 282: } ! 283: for(i=0; i<amax; i++) ! 284: { ! 285: adims[i] = *--ptr; ! 286: if((int)rdims[i] > adims[i]) ! 287: { ! 288: error(inst.thing.linno, 27); /* DIM > ACTUAL */ ! 289: return(-1); ! 290: } ! 291: } ! 292: *--ptr; /* BASE STARTS AFTER HEADER */ ! 293: /* ! 294: * Note that this structure starts from hi to low memory ! 295: * LOC = BASE - ((a-1)*YMAX+b-1) ! 296: */ ! 297: offset = ((int)rdims[0]-1)*adims[1]+((int)rdims[1]-1); ! 298: *addr = (char *)(ptr-offset); ! 299: return(0); ! 300: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.