|
|
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.