6 static char *rcsid_gdb_struct_c = "$Header$";
10 /************************************************************************/
14 /* GDB - Structured Data Maintenance Routines
16 /* Author: Noah Mendelsohn
17 /* Copyright: 1986 MIT Project Athena
18 /* For copying and distribution information, please see
19 /* the file <mit-copyright.h>.
21 /* These routines implement the following layers of the
22 /* Client Library Specification of the GDB system:
26 /* 2 Structured Data Management at a
29 /* 4 Memory Management
31 /* 5 String Management
33 /* Some of the routines specified are actually implemented as
34 /* macros defined in gdb.h.
36 /************************************************************************/
38 #include <mit-copyright.h>
45 /************************************************************************/
49 /* In anticipation of the day when we may want to do something
50 /* fancy with memory management, all of the gdb routines which
51 /* require dynamic allocation of memory call the routines named
52 /* db_alloc and db_free. For the moment, these are implemented
53 /* as calls to malloc and free.
55 /************************************************************************/
57 /*----------------------------------------------------------*/
61 /* Allocate memory for use by gdb. Current implementation
62 /* just does a malloc.
64 /*----------------------------------------------------------*/
70 return(malloc((unsigned)bytes));
73 /*----------------------------------------------------------*/
77 /* Return allocated memory. Note: the current
78 /* implementation ignores the byte count supplied,
79 /* but future implementations may require that it
82 /*----------------------------------------------------------*/
94 /************************************************************************/
98 /* To allow dynamic manipulation of strings in gdb without
99 /* excessive memory re-allocation, we define a string as a
100 /* counted byte space. Though this space will frequently be used
101 /* to store a standard null terminated string, that is not
104 /* Current representation for a string is a pointer followed by
105 /* an integer length. A null pointer indicates a null string, in
106 /* which case the length is arbitrary. Any other pointer is to
107 /* memory which was allocated by db_alloc in which must be free'd
108 /* eventually with db_free.
110 /************************************************************************/
112 /*----------------------------------------------------------*/
114 /* string_alloc (string_alloc)
116 /* Fills in supplied string descriptor and returns
117 /* pointer to the newly allocated data.
119 /*----------------------------------------------------------*/
122 string_alloc(stringp, bytes)
123 STRING *stringp; /* pointer to string */
124 /* descriptor to be */
126 int bytes; /* number of bytes to alloc */
130 MAX_STRING_SIZE(*stringp) = bytes; /* put length in returned */
131 /* string descriptor-- */
132 /* will be irrelavent if */
135 STRING_DATA(*stringp) = db_alloc(bytes); /* try to get the data */
136 return (STRING_DATA(*stringp)); /* return ptr to new string */
140 /*----------------------------------------------------------*/
142 /* string_free (string_free)
144 /* Releases the data space for a gdb string. Must have
145 /* been allocated with string_alloc. Remember to pass
146 /* in the address of the string descriptor, not the
147 /* descriptor itself!
149 /*----------------------------------------------------------*/
156 if (stringp->ptr == NULL)
158 db_free(stringp->ptr, stringp->length);
164 /************************************************************************/
166 /* STRUCTURED DATA MANAGEMENT AT A SINGLE SITE
168 /* These routines provide the abstraction of typed, structured
169 /* data at a single site. Tuples are collections of typed fields,
170 /* and they are each described by a tuple descriptor. Relations
171 /* are circularly linked lists of tuples. For completeness, a
172 /* relation also carries a tuple descriptor, which should match
173 /* the descriptor for each of its constituent tuples. This allows
174 /* a null relation to be typed.
176 /* Some of the facilities of structured data management are
177 /* defined as macros in gdb.h. In many cases, the routines
178 /* declared below are known by defines of more descriptive
179 /* names, also in gdb.h.
181 /************************************************************************/
182 /************************************************************************/
184 /* TUPLE_DESCRIPTOR MANAGEMENT
186 /************************************************************************/
189 /*----------------------------------------------------------*/
191 /* create_tuple_descriptor (create_tuple_descriptor)
193 /* Allocates space for a tuple descriptor and fills
194 /* it in. Gives up if space is not available.
195 /* Should be passed a list of integer coded types
196 /* and a list of string field names.
198 /* Tuple descriptors are reference counted, and they are
199 /* not really deleted until the reference count goes
200 /* to zero. It is presumed that all callers use the
201 /* create and delete routines, or otherwise maintain
202 /* the reference count appropriately.
204 /*----------------------------------------------------------*/
208 create_tuple_descriptor(number_of_fields, name_list, type_list)
210 FIELD_TYPE type_list[];
211 int number_of_fields;
213 register TUPLE_DESCRIPTOR tpd; /* pointer to new descriptor */
215 register int data_len; /* length of the actual */
216 int field_len; /* length of current field */
217 int align; /* code describing alignment */
218 /* requirement for this field*/
219 /* (4 for fullword, 1 for */
221 int next_offset; /* byte offset to next field */
222 int descriptor_length; /* length of the part of */
223 /* the allocated storage */
224 /* actually used for the */
226 int str_len; /* we also have to retain */
227 /* the string names for the */
228 /* fields. These are stored */
229 /* immediately off the end */
230 /* of the descriptor, and */
231 /* all are allocated */
232 /* together. This is the */
233 /* length of the string data */
234 char *next_name; /* place to put the next */
235 /* copied fieldname*/
241 * Calculate size and allocate descriptor
244 descriptor_length = sizeof(struct tupl_desc) +
245 (number_of_fields-1) * sizeof(struct tupld_var);
249 for (i=0; i<number_of_fields; i++)
250 str_len += strlen(name_list[i]) +1;
252 tpd = (TUPLE_DESCRIPTOR)db_alloc(descriptor_length+str_len);
253 /* try to allocate it */
256 GDB_GIVEUP("create_tuple_descriptor (gbd_ctd) could not get enough memory.\n")
259 * Fill in the descriptor fields:
261 * Each field is aligned according to its own alignment code.
262 * Going in to the top of the for loop, next_offset is set to
263 * the offset of the first possible byte for storing the next field.
264 * During the loop, that number is rounded up, if necessary, to
265 * achieve the alignment actually required for the field. Finally,
266 * the length of the new field is added, which yields the first
267 * possible byte of any field to follow.
270 tpd->id = GDB_DESC_ID;
272 tpd->ref_count = 1; /* whoever asked for creation*/
273 /* is expected to delete*/
275 tpd->field_count = number_of_fields;
276 tpd->str_len = str_len;
278 data_len = sizeof(struct tuple_dat) - 1; /* tuple_dat includes the */
279 /* first byte of data */
281 next_name = ((char *)tpd) + descriptor_length;
282 /* place to put first */
284 for (i=0; i<number_of_fields; i++) {
286 * Calculate lengths and alignments for the field data.
288 field_len = INT_PROPERTY(type_list[i],LENGTH_PROPERTY);
289 align = INT_PROPERTY(type_list[i],ALIGNMENT_PROPERTY);
291 * Copy the string field name into the newly allocated
292 * space just after the descriptor itself.
294 tpd->var[i].name = strcpy(next_name, name_list[i]);
295 next_name += strlen(next_name) + 1;
297 * Put in the type and the length for the field data
299 tpd->var[i].type = type_list[i];
300 tpd->var[i].length = field_len;
302 * Now store the actual offset of this field, and
303 * compute the first byte address we could conceivably
304 * use for the next field.
306 next_offset = GDB_ROUNDUP(next_offset, align);
307 tpd->var[i].offset = next_offset;
308 next_offset += field_len;
311 data_len += next_offset;
312 tpd->data_len = data_len;
314 return tpd; /* return the new descriptor */
317 /*----------------------------------------------------------*/
319 /* delete_tuple_descriptor (delete_tuple_descriptor)
321 /* Return the space for a tuple descriptor
323 /*----------------------------------------------------------*/
326 delete_tuple_descriptor(t)
329 int descriptor_length;
330 register int ref_count; /* buffer the reference */
336 GDB_CHECK_TPD(t, "delete_tuple_descriptor")
340 * Decrement the reference count. If it's not zero, then just
343 if ((ref_count = --(t->ref_count)) >0)
346 GDB_GIVEUP("Tuple descriptor reference count is less than zero")
348 * Current representation is to allocate the space for the string
349 * right off the end of the descriptor itself. We therefore have
350 * to add their length into the amount we free.
352 descriptor_length = gdb_descriptor_length(t->field_count);
353 db_free((char *)t, descriptor_length+t->str_len);
358 /*----------------------------------------------------------*/
360 /* field_index (field_index)
362 /*----------------------------------------------------------*/
365 field_index(tuple_descriptor, field_name)
366 TUPLE_DESCRIPTOR tuple_descriptor;
371 register TUPLE_DESCRIPTOR tpd = tuple_descriptor;
374 * Make sure supplied descriptor is valid
377 GDB_GIVEUP("null tuple descriptor passed to field_index function")
378 GDB_CHECK_TPD(tpd, "field_index")
380 n = tpd -> field_count;
383 * Loop through each field in descriptor, return index if match
387 if (strcmp(field_name, tpd->var[i].name) == 0)
390 * No match, return -1
396 /************************************************************************/
400 /************************************************************************/
402 /*----------------------------------------------------------*/
404 /* create_tuple (create_tuple)
406 /* Allocate space for a new tuple, given its
407 /* descriptor. Giveup if out of memory.
409 /*----------------------------------------------------------*/
412 create_tuple(descriptor)
413 TUPLE_DESCRIPTOR descriptor;
417 GDB_CHECK_TPD(descriptor, "create_tuple")
419 t = (TUPLE)db_alloc(descriptor -> data_len);
422 GDB_GIVEUP("create_tuple (create_tuple) could not allocate enough memory.\n")
426 t->desc = descriptor; /* fill in descriptor */
427 /* pointer in new tuple */
428 REFERENCE_TUPLE_DESCRIPTOR(descriptor); /* bump the reference count */
431 * Only for the sake of keeping things clean, null out the pointers.
432 * Wastes time, but helps debugging.
434 t->next = t->prev = NULL;
440 /*----------------------------------------------------------*/
442 /* delete_tuple (delete_tuple)
444 /* Release the data space occupied by a tuple.
446 /*----------------------------------------------------------*/
452 register TUPLE_DESCRIPTOR tpd;
454 GDB_GIVEUP("Delete_tuple called with null tuple")
455 GDB_CHECK_TUP(t, "delete_tuple")
457 db_free((char *)t, t->desc->data_len);
458 delete_tuple_descriptor(tpd); /* does a reference counted */
462 /*----------------------------------------------------------*/
464 /* initialize_tuple (initialize_tuple)
466 /* Set each field in tuple to its null value.
468 /*----------------------------------------------------------*/
474 register char *field_data; /* pointer to first byte */
475 /* of field data in tuple*/
476 register TUPLE_DESCRIPTOR tpd; /* pointer to descriptor */
477 register int i; /* counter of fields */
478 int num_fields; /* total number of fields */
481 * Return if no tuple at all supplied--perhaps this should be
482 * an error. If supplied, make sure it looks like a tuple.
488 GDB_CHECK_TUP(t, "initialize_tuple")
491 * Set up to loop through fields: get tuple descriptor, field count
492 * and pointer to first data byte in the tuple.
496 num_fields = tpd->field_count;
497 field_data = t->data; /* address of first byte of */
502 * For each field in the tuple, loop calling its null value
503 * initialization routine.
506 for (i=0; i<num_fields; i++) {
507 FCN_PROPERTY(tpd->var[i].type, NULL_PROPERTY)
508 (field_data+tpd->var[i].offset);
513 /*----------------------------------------------------------*/
515 /* null_tuple_strings (null_tuple_strings)
517 /* Reclaim the space for all fields in the tuple
518 /* whose type is 'string.'
520 /*----------------------------------------------------------*/
523 null_tuple_strings(t)
526 register char *field_data; /* pointer to first byte of */
527 /* field data in tuple */
528 register TUPLE_DESCRIPTOR tpd; /* pointer to descriptor */
529 register int i; /* counter of fields */
530 int num_fields; /* total number of fields */
533 * Return if no tuple at all supplied--perhaps this should be
540 GDB_CHECK_TUP(t, "null_tuple_strings")
543 * Set up to loop through fields: get tuple descriptor, field count
544 * and pointer to first data byte in the tuple.
548 num_fields = tpd->field_count;
549 field_data = t->data; /* address of first byte of */
553 * For each field in the tuple, loop calling its null value
554 * initialization routine.
557 for (i=0; i<num_fields; i++) {
558 if(FIELD_TYPE_IN_TUPLE(tpd,i) == STRING_T &&
559 (*(char **)(field_data+FIELD_OFFSET_IN_TUPLE(tpd,i)))!=NULL)
560 string_free((STRING *)(field_data+
561 FIELD_OFFSET_IN_TUPLE(tpd,i)));
565 /************************************************************************/
567 /* RELATION MANAGEMENT
569 /************************************************************************/
571 /*----------------------------------------------------------*/
573 /* create_relation (create_relation)
575 /*----------------------------------------------------------*/
578 create_relation(desc)
579 TUPLE_DESCRIPTOR desc;
583 GDB_CHECK_TPD(desc, "create_relation")
585 r = (RELATION)db_alloc(sizeof(struct rel_dat));
588 GDB_GIVEUP("create_relation (create_relation) could not get enough space.\n")
591 * Fill in the empty relation. Create a null circular list
592 * of tuples and also hang the description.
600 REFERENCE_TUPLE_DESCRIPTOR(desc); /* bump the reference count */
605 /*----------------------------------------------------------*/
609 /* Deletes the tuples which comprise a relation.
610 /* For each tuple, it does a null-tuple-strings
611 /* prior to deleting, but it does not yet handle
612 /* any other non-contiguous data.
614 /*----------------------------------------------------------*/
620 register TUPLE t, next;
621 TUPLE_DESCRIPTOR desc;
624 * Make sure a proper relation is supplied.
628 GDB_GIVEUP("delete_relation called with null relation")
629 GDB_CHECK_REL(rel, "delete_relation")
631 t = FIRST_TUPLE_IN_RELATION(rel);
633 /*----------------------------------------------------------*/
635 /* Free all the tuples
637 /*----------------------------------------------------------*/
640 null_tuple_strings(t);
641 next = NEXT_TUPLE_IN_RELATION(rel, t);
646 /*----------------------------------------------------------*/
648 /* Give back the memory for the relation
650 /*----------------------------------------------------------*/
652 desc = DESCRIPTOR_FROM_RELATION(rel);
653 db_free((char *)rel, sizeof(struct rel_dat));
654 delete_tuple_descriptor(desc); /* does a reference */
658 /*----------------------------------------------------------*/
660 /* tuples_in_relation
662 /* Returns number of tuples in a relation.
665 /*----------------------------------------------------------*/
668 tuples_in_relation(rel)
672 register RELATION r=rel;
677 for (t=FIRST_TUPLE_IN_RELATION(r);
679 t=NEXT_TUPLE_IN_RELATION(r,t)) {