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>
43 extern char *malloc();
48 /************************************************************************/
52 /* In anticipation of the day when we may want to do something
53 /* fancy with memory management, all of the gdb routines which
54 /* require dynamic allocation of memory call the routines named
55 /* db_alloc and db_free. For the moment, these are implemented
56 /* as calls to malloc and free.
58 /************************************************************************/
60 /*----------------------------------------------------------*/
64 /* Allocate memory for use by gdb. Current implementation
65 /* just does a malloc.
67 /*----------------------------------------------------------*/
73 return(malloc((unsigned)bytes));
76 /*----------------------------------------------------------*/
80 /* Return allocated memory. Note: the current
81 /* implementation ignores the byte count supplied,
82 /* but future implementations may require that it
85 /*----------------------------------------------------------*/
97 /************************************************************************/
101 /* To allow dynamic manipulation of strings in gdb without
102 /* excessive memory re-allocation, we define a string as a
103 /* counted byte space. Though this space will frequently be used
104 /* to store a standard null terminated string, that is not
107 /* Current representation for a string is a pointer followed by
108 /* an integer length. A null pointer indicates a null string, in
109 /* which case the length is arbitrary. Any other pointer is to
110 /* memory which was allocated by db_alloc in which must be free'd
111 /* eventually with db_free.
113 /************************************************************************/
115 /*----------------------------------------------------------*/
117 /* string_alloc (string_alloc)
119 /* Fills in supplied string descriptor and returns
120 /* pointer to the newly allocated data.
122 /*----------------------------------------------------------*/
125 string_alloc(stringp, bytes)
126 STRING *stringp; /* pointer to string */
127 /* descriptor to be */
129 int bytes; /* number of bytes to alloc */
133 MAX_STRING_SIZE(*stringp) = bytes; /* put length in returned */
134 /* string descriptor-- */
135 /* will be irrelavent if */
138 STRING_DATA(*stringp) = db_alloc(bytes); /* try to get the data */
139 return (STRING_DATA(*stringp)); /* return ptr to new string */
143 /*----------------------------------------------------------*/
145 /* string_free (string_free)
147 /* Releases the data space for a gdb string. Must have
148 /* been allocated with string_alloc. Remember to pass
149 /* in the address of the string descriptor, not the
150 /* descriptor itself!
152 /*----------------------------------------------------------*/
159 if (stringp->ptr == NULL)
161 db_free(stringp->ptr, stringp->length);
167 /************************************************************************/
169 /* STRUCTURED DATA MANAGEMENT AT A SINGLE SITE
171 /* These routines provide the abstraction of typed, structured
172 /* data at a single site. Tuples are collections of typed fields,
173 /* and they are each described by a tuple descriptor. Relations
174 /* are circularly linked lists of tuples. For completeness, a
175 /* relation also carries a tuple descriptor, which should match
176 /* the descriptor for each of its constituent tuples. This allows
177 /* a null relation to be typed.
179 /* Some of the facilities of structured data management are
180 /* defined as macros in gdb.h. In many cases, the routines
181 /* declared below are known by defines of more descriptive
182 /* names, also in gdb.h.
184 /************************************************************************/
185 /************************************************************************/
187 /* TUPLE_DESCRIPTOR MANAGEMENT
189 /************************************************************************/
192 /*----------------------------------------------------------*/
194 /* create_tuple_descriptor (create_tuple_descriptor)
196 /* Allocates space for a tuple descriptor and fills
197 /* it in. Gives up if space is not available.
198 /* Should be passed a list of integer coded types
199 /* and a list of string field names.
201 /* Tuple descriptors are reference counted, and they are
202 /* not really deleted until the reference count goes
203 /* to zero. It is presumed that all callers use the
204 /* create and delete routines, or otherwise maintain
205 /* the reference count appropriately.
207 /*----------------------------------------------------------*/
211 create_tuple_descriptor(number_of_fields, name_list, type_list)
213 FIELD_TYPE type_list[];
214 int number_of_fields;
216 register TUPLE_DESCRIPTOR tpd; /* pointer to new descriptor */
218 register int data_len; /* length of the actual */
219 int field_len; /* length of current field */
220 int align; /* code describing alignment */
221 /* requirement for this field*/
222 /* (4 for fullword, 1 for */
224 int next_offset; /* byte offset to next field */
225 int descriptor_length; /* length of the part of */
226 /* the allocated storage */
227 /* actually used for the */
229 int str_len; /* we also have to retain */
230 /* the string names for the */
231 /* fields. These are stored */
232 /* immediately off the end */
233 /* of the descriptor, and */
234 /* all are allocated */
235 /* together. This is the */
236 /* length of the string data */
237 char *next_name; /* place to put the next */
238 /* copied fieldname*/
244 * Calculate size and allocate descriptor
247 descriptor_length = sizeof(struct tupl_desc) +
248 (number_of_fields-1) * sizeof(struct tupld_var);
252 for (i=0; i<number_of_fields; i++)
253 str_len += strlen(name_list[i]) +1;
255 tpd = (TUPLE_DESCRIPTOR)db_alloc(descriptor_length+str_len);
256 /* try to allocate it */
259 GDB_GIVEUP("create_tuple_descriptor (gbd_ctd) could not get enough memory.\n")
262 * Fill in the descriptor fields:
264 * Each field is aligned according to its own alignment code.
265 * Going in to the top of the for loop, next_offset is set to
266 * the offset of the first possible byte for storing the next field.
267 * During the loop, that number is rounded up, if necessary, to
268 * achieve the alignment actually required for the field. Finally,
269 * the length of the new field is added, which yields the first
270 * possible byte of any field to follow.
273 tpd->id = GDB_DESC_ID;
275 tpd->ref_count = 1; /* whoever asked for creation*/
276 /* is expected to delete*/
278 tpd->field_count = number_of_fields;
279 tpd->str_len = str_len;
281 data_len = sizeof(struct tuple_dat) - 1; /* tuple_dat includes the */
282 /* first byte of data */
284 next_name = ((char *)tpd) + descriptor_length;
285 /* place to put first */
287 for (i=0; i<number_of_fields; i++) {
289 * Calculate lengths and alignments for the field data.
291 field_len = INT_PROPERTY(type_list[i],LENGTH_PROPERTY);
292 align = INT_PROPERTY(type_list[i],ALIGNMENT_PROPERTY);
294 * Copy the string field name into the newly allocated
295 * space just after the descriptor itself.
297 tpd->var[i].name = strcpy(next_name, name_list[i]);
298 next_name += strlen(next_name) + 1;
300 * Put in the type and the length for the field data
302 tpd->var[i].type = type_list[i];
303 tpd->var[i].length = field_len;
305 * Now store the actual offset of this field, and
306 * compute the first byte address we could conceivably
307 * use for the next field.
309 next_offset = GDB_ROUNDUP(next_offset, align);
310 tpd->var[i].offset = next_offset;
311 next_offset += field_len;
314 data_len += next_offset;
315 tpd->data_len = data_len;
317 return tpd; /* return the new descriptor */
320 /*----------------------------------------------------------*/
322 /* delete_tuple_descriptor (delete_tuple_descriptor)
324 /* Return the space for a tuple descriptor
326 /*----------------------------------------------------------*/
329 delete_tuple_descriptor(t)
332 int descriptor_length;
333 register int ref_count; /* buffer the reference */
339 GDB_CHECK_TPD(t, "delete_tuple_descriptor")
343 * Decrement the reference count. If it's not zero, then just
346 if ((ref_count = --(t->ref_count)) >0)
349 GDB_GIVEUP("Tuple descriptor reference count is less than zero")
351 * Current representation is to allocate the space for the string
352 * right off the end of the descriptor itself. We therefore have
353 * to add their length into the amount we free.
355 descriptor_length = gdb_descriptor_length(t->field_count);
356 db_free((char *)t, descriptor_length+t->str_len);
361 /*----------------------------------------------------------*/
363 /* field_index (field_index)
365 /*----------------------------------------------------------*/
368 field_index(tuple_descriptor, field_name)
369 TUPLE_DESCRIPTOR tuple_descriptor;
374 register TUPLE_DESCRIPTOR tpd = tuple_descriptor;
377 * Make sure supplied descriptor is valid
380 GDB_GIVEUP("null tuple descriptor passed to field_index function")
381 GDB_CHECK_TPD(tpd, "field_index")
383 n = tpd -> field_count;
386 * Loop through each field in descriptor, return index if match
390 if (strcmp(field_name, tpd->var[i].name) == 0)
393 * No match, return -1
399 /************************************************************************/
403 /************************************************************************/
405 /*----------------------------------------------------------*/
407 /* create_tuple (create_tuple)
409 /* Allocate space for a new tuple, given its
410 /* descriptor. Giveup if out of memory.
412 /*----------------------------------------------------------*/
415 create_tuple(descriptor)
416 TUPLE_DESCRIPTOR descriptor;
420 GDB_CHECK_TPD(descriptor, "create_tuple")
422 t = (TUPLE)db_alloc(descriptor -> data_len);
425 GDB_GIVEUP("create_tuple (create_tuple) could not allocate enough memory.\n")
429 t->desc = descriptor; /* fill in descriptor */
430 /* pointer in new tuple */
431 REFERENCE_TUPLE_DESCRIPTOR(descriptor); /* bump the reference count */
434 * Only for the sake of keeping things clean, null out the pointers.
435 * Wastes time, but helps debugging.
437 t->next = t->prev = NULL;
443 /*----------------------------------------------------------*/
445 /* delete_tuple (delete_tuple)
447 /* Release the data space occupied by a tuple.
449 /*----------------------------------------------------------*/
455 register TUPLE_DESCRIPTOR tpd;
457 GDB_GIVEUP("Delete_tuple called with null tuple")
458 GDB_CHECK_TUP(t, "delete_tuple")
460 db_free((char *)t, t->desc->data_len);
461 delete_tuple_descriptor(tpd); /* does a reference counted */
465 /*----------------------------------------------------------*/
467 /* initialize_tuple (initialize_tuple)
469 /* Set each field in tuple to its null value.
471 /*----------------------------------------------------------*/
477 register char *field_data; /* pointer to first byte */
478 /* of field data in tuple*/
479 register TUPLE_DESCRIPTOR tpd; /* pointer to descriptor */
480 register int i; /* counter of fields */
481 int num_fields; /* total number of fields */
484 * Return if no tuple at all supplied--perhaps this should be
485 * an error. If supplied, make sure it looks like a tuple.
491 GDB_CHECK_TUP(t, "initialize_tuple")
494 * Set up to loop through fields: get tuple descriptor, field count
495 * and pointer to first data byte in the tuple.
499 num_fields = tpd->field_count;
500 field_data = t->data; /* address of first byte of */
505 * For each field in the tuple, loop calling its null value
506 * initialization routine.
509 for (i=0; i<num_fields; i++) {
510 FCN_PROPERTY(tpd->var[i].type, NULL_PROPERTY)
511 (field_data+tpd->var[i].offset);
516 /*----------------------------------------------------------*/
518 /* null_tuple_strings (null_tuple_strings)
520 /* Reclaim the space for all fields in the tuple
521 /* whose type is 'string.'
523 /*----------------------------------------------------------*/
526 null_tuple_strings(t)
529 register char *field_data; /* pointer to first byte of */
530 /* field data in tuple */
531 register TUPLE_DESCRIPTOR tpd; /* pointer to descriptor */
532 register int i; /* counter of fields */
533 int num_fields; /* total number of fields */
536 * Return if no tuple at all supplied--perhaps this should be
543 GDB_CHECK_TUP(t, "null_tuple_strings")
546 * Set up to loop through fields: get tuple descriptor, field count
547 * and pointer to first data byte in the tuple.
551 num_fields = tpd->field_count;
552 field_data = t->data; /* address of first byte of */
556 * For each field in the tuple, loop calling its null value
557 * initialization routine.
560 for (i=0; i<num_fields; i++) {
561 if(FIELD_TYPE_IN_TUPLE(tpd,i) == STRING_T &&
562 (*(char **)(field_data+FIELD_OFFSET_IN_TUPLE(tpd,i)))!=NULL)
563 string_free((STRING *)(field_data+
564 FIELD_OFFSET_IN_TUPLE(tpd,i)));
568 /************************************************************************/
570 /* RELATION MANAGEMENT
572 /************************************************************************/
574 /*----------------------------------------------------------*/
576 /* create_relation (create_relation)
578 /*----------------------------------------------------------*/
581 create_relation(desc)
582 TUPLE_DESCRIPTOR desc;
586 GDB_CHECK_TPD(desc, "create_relation")
588 r = (RELATION)db_alloc(sizeof(struct rel_dat));
591 GDB_GIVEUP("create_relation (create_relation) could not get enough space.\n")
594 * Fill in the empty relation. Create a null circular list
595 * of tuples and also hang the description.
603 REFERENCE_TUPLE_DESCRIPTOR(desc); /* bump the reference count */
608 /*----------------------------------------------------------*/
612 /* Deletes the tuples which comprise a relation.
613 /* For each tuple, it does a null-tuple-strings
614 /* prior to deleting, but it does not yet handle
615 /* any other non-contiguous data.
617 /*----------------------------------------------------------*/
623 register TUPLE t, next;
624 TUPLE_DESCRIPTOR desc;
627 * Make sure a proper relation is supplied.
631 GDB_GIVEUP("delete_relation called with null relation")
632 GDB_CHECK_REL(rel, "delete_relation")
634 t = FIRST_TUPLE_IN_RELATION(rel);
636 /*----------------------------------------------------------*/
638 /* Free all the tuples
640 /*----------------------------------------------------------*/
643 null_tuple_strings(t);
644 next = NEXT_TUPLE_IN_RELATION(rel, t);
649 /*----------------------------------------------------------*/
651 /* Give back the memory for the relation
653 /*----------------------------------------------------------*/
655 desc = DESCRIPTOR_FROM_RELATION(rel);
656 db_free((char *)rel, sizeof(struct rel_dat));
657 delete_tuple_descriptor(desc); /* does a reference */
661 /*----------------------------------------------------------*/
663 /* tuples_in_relation
665 /* Returns number of tuples in a relation.
668 /*----------------------------------------------------------*/
671 tuples_in_relation(rel)
675 register RELATION r=rel;
680 for (t=FIRST_TUPLE_IN_RELATION(r);
682 t=NEXT_TUPLE_IN_RELATION(r,t)) {