7 static char *rcsid_gdb_struct_c = "$Header$";
30 /************************************************************************/
34 /* GDB - Structured Data Maintenance Routines
36 /* Author: Noah Mendelsohn
37 /* Copyright: 1986 MIT Project Athena
38 /* For copying and distribution information, please see
39 /* the file <mit-copyright.h>.
41 /* These routines implement the following layers of the
42 /* Client Library Specification of the GDB system:
46 /* 2 Structured Data Management at a
49 /* 4 Memory Management
51 /* 5 String Management
53 /* Some of the routines specified are actually implemented as
54 /* macros defined in gdb.h.
56 /************************************************************************/
58 #include <mit-copyright.h>
63 extern char *malloc();
66 /************************************************************************/
70 /* In anticipation of the day when we may want to do something
71 /* fancy with memory management, all of the gdb routines which
72 /* require dynamic allocation of memory call the routines named
73 /* db_alloc and db_free. For the moment, these are implemented
74 /* as calls to malloc and free.
76 /************************************************************************/
78 /*----------------------------------------------------------*/
82 /* Allocate memory for use by gdb. Current implementation
83 /* just does a malloc.
85 /*----------------------------------------------------------*/
91 return(malloc((unsigned)bytes));
94 /*----------------------------------------------------------*/
98 /* Return allocated memory. Note: the current
99 /* implementation ignores the byte count supplied,
100 /* but future implementations may require that it
103 /*----------------------------------------------------------*/
114 /************************************************************************/
118 /* To allow dynamic manipulation of strings in gdb without
119 /* excessive memory re-allocation, we define a string as a
120 /* counted byte space. Though this space will frequently be used
121 /* to store a standard null terminated string, that is not
124 /* Current representation for a string is a pointer followed by
125 /* an integer length. A null pointer indicates a null string, in
126 /* which case the length is arbitrary. Any other pointer is to
127 /* memory which was allocated by db_alloc in which must be free'd
128 /* eventually with db_free.
130 /************************************************************************/
132 /*----------------------------------------------------------*/
134 /* string_alloc (string_alloc)
136 /* Fills in supplied string descriptor and returns
137 /* pointer to the newly allocated data.
139 /*----------------------------------------------------------*/
142 string_alloc(stringp, bytes)
143 STRING *stringp; /* pointer to string */
144 /* descriptor to be */
146 int bytes; /* number of bytes to alloc */
150 MAX_STRING_SIZE(*stringp) = bytes; /* put length in returned */
151 /* string descriptor-- */
152 /* will be irrelavent if */
155 STRING_DATA(*stringp) = db_alloc(bytes); /* try to get the data */
156 return (STRING_DATA(*stringp)); /* return ptr to new string */
160 /*----------------------------------------------------------*/
162 /* string_free (string_free)
164 /* Releases the data space for a gdb string. Must have
165 /* been allocated with string_alloc. Remember to pass
166 /* in the address of the string descriptor, not the
167 /* descriptor itself!
169 /*----------------------------------------------------------*/
176 if (stringp->ptr == NULL)
178 db_free(stringp->ptr, stringp->length);
184 /************************************************************************/
186 /* STRUCTURED DATA MANAGEMENT AT A SINGLE SITE
188 /* These routines provide the abstraction of typed, structured
189 /* data at a single site. Tuples are collections of typed fields,
190 /* and they are each described by a tuple descriptor. Relations
191 /* are circularly linked lists of tuples. For completeness, a
192 /* relation also carries a tuple descriptor, which should match
193 /* the descriptor for each of its constituent tuples. This allows
194 /* a null relation to be typed.
196 /* Some of the facilities of structured data management are
197 /* defined as macros in gdb.h. In many cases, the routines
198 /* declared below are known by defines of more descriptive
199 /* names, also in gdb.h.
201 /************************************************************************/
202 /************************************************************************/
204 /* TUPLE_DESCRIPTOR MANAGEMENT
206 /************************************************************************/
209 /*----------------------------------------------------------*/
211 /* create_tuple_descriptor (create_tuple_descriptor)
213 /* Allocates space for a tuple descriptor and fills
214 /* it in. Gives up if space is not available.
215 /* Should be passed a list of integer coded types
216 /* and a list of string field names.
218 /* Tuple descriptors are reference counted, and they are
219 /* not really deleted until the reference count goes
220 /* to zero. It is presumed that all callers use the
221 /* create and delete routines, or otherwise maintain
222 /* the reference count appropriately.
224 /*----------------------------------------------------------*/
228 create_tuple_descriptor(number_of_fields, name_list, type_list)
230 FIELD_TYPE type_list[];
231 int number_of_fields;
233 register TUPLE_DESCRIPTOR tpd; /* pointer to new descriptor */
235 register int data_len; /* length of the actual */
236 int field_len; /* length of current field */
237 int align; /* code describing alignment */
238 /* requirement for this field*/
239 /* (4 for fullword, 1 for */
241 int next_offset; /* byte offset to next field */
242 int descriptor_length; /* length of the part of */
243 /* the allocated storage */
244 /* actually used for the */
246 int str_len; /* we also have to retain */
247 /* the string names for the */
248 /* fields. These are stored */
249 /* immediately off the end */
250 /* of the descriptor, and */
251 /* all are allocated */
252 /* together. This is the */
253 /* length of the string data */
254 char *next_name; /* place to put the next */
255 /* copied fieldname*/
261 * Calculate size and allocate descriptor
264 descriptor_length = sizeof(struct tupl_desc) +
265 (number_of_fields-1) * sizeof(struct tupld_var);
269 for (i=0; i<number_of_fields; i++)
270 str_len += strlen(name_list[i]) +1;
272 tpd = (TUPLE_DESCRIPTOR)db_alloc(descriptor_length+str_len);
273 /* try to allocate it */
276 GDB_GIVEUP("create_tuple_descriptor (gbd_ctd) could not get enough memory.\n")
279 * Fill in the descriptor fields:
281 * Each field is aligned according to its own alignment code.
282 * Going in to the top of the for loop, next_offset is set to
283 * the offset of the first possible byte for storing the next field.
284 * During the loop, that number is rounded up, if necessary, to
285 * achieve the alignment actually required for the field. Finally,
286 * the length of the new field is added, which yields the first
287 * possible byte of any field to follow.
290 tpd->id = GDB_DESC_ID;
292 tpd->ref_count = 1; /* whoever asked for creation*/
293 /* is expected to delete*/
295 tpd->field_count = number_of_fields;
296 tpd->str_len = str_len;
298 data_len = sizeof(struct tuple_dat) - 1; /* tuple_dat includes the */
299 /* first byte of data */
301 next_name = ((char *)tpd) + descriptor_length;
302 /* place to put first */
304 for (i=0; i<number_of_fields; i++) {
306 * Calculate lengths and alignments for the field data.
308 field_len = INT_PROPERTY(type_list[i],LENGTH_PROPERTY);
309 align = INT_PROPERTY(type_list[i],ALIGNMENT_PROPERTY);
311 * Copy the string field name into the newly allocated
312 * space just after the descriptor itself.
314 tpd->var[i].name = strcpy(next_name, name_list[i]);
315 next_name += strlen(next_name) + 1;
317 * Put in the type and the length for the field data
319 tpd->var[i].type = type_list[i];
320 tpd->var[i].length = field_len;
322 * Now store the actual offset of this field, and
323 * compute the first byte address we could conceivably
324 * use for the next field.
326 next_offset = GDB_ROUNDUP(next_offset, align);
327 tpd->var[i].offset = next_offset;
328 next_offset += field_len;
331 data_len += next_offset;
332 tpd->data_len = data_len;
334 return tpd; /* return the new descriptor */
337 /*----------------------------------------------------------*/
339 /* delete_tuple_descriptor (delete_tuple_descriptor)
341 /* Return the space for a tuple descriptor
343 /*----------------------------------------------------------*/
346 delete_tuple_descriptor(t)
349 int descriptor_length;
350 register int ref_count; /* buffer the reference */
356 GDB_CHECK_TPD(t, "delete_tuple_descriptor")
360 * Decrement the reference count. If it's not zero, then just
363 if ((ref_count = --(t->ref_count)) >0)
366 GDB_GIVEUP("Tuple descriptor reference count is less than zero")
368 * Current representation is to allocate the space for the string
369 * right off the end of the descriptor itself. We therefore have
370 * to add their length into the amount we free.
372 descriptor_length = gdb_descriptor_length(t->field_count);
373 db_free((char *)t, descriptor_length+t->str_len);
378 /*----------------------------------------------------------*/
380 /* field_index (field_index)
382 /*----------------------------------------------------------*/
385 field_index(tuple_descriptor, field_name)
386 TUPLE_DESCRIPTOR tuple_descriptor;
391 register TUPLE_DESCRIPTOR tpd = tuple_descriptor;
394 * Make sure supplied descriptor is valid
397 GDB_GIVEUP("null tuple descriptor passed to field_index function")
398 GDB_CHECK_TPD(tpd, "field_index")
400 n = tpd -> field_count;
403 * Loop through each field in descriptor, return index if match
407 if (strcmp(field_name, tpd->var[i].name) == 0)
410 * No match, return -1
416 /************************************************************************/
420 /************************************************************************/
422 /*----------------------------------------------------------*/
424 /* create_tuple (create_tuple)
426 /* Allocate space for a new tuple, given its
427 /* descriptor. Giveup if out of memory.
429 /*----------------------------------------------------------*/
432 create_tuple(descriptor)
433 TUPLE_DESCRIPTOR descriptor;
437 GDB_CHECK_TPD(descriptor, "create_tuple")
439 t = (TUPLE)db_alloc(descriptor -> data_len);
442 GDB_GIVEUP("create_tuple (create_tuple) could not allocate enough memory.\n")
446 t->desc = descriptor; /* fill in descriptor */
447 /* pointer in new tuple */
448 REFERENCE_TUPLE_DESCRIPTOR(descriptor); /* bump the reference count */
451 * Only for the sake of keeping things clean, null out the pointers.
452 * Wastes time, but helps debugging.
454 t->next = t->prev = NULL;
460 /*----------------------------------------------------------*/
462 /* delete_tuple (delete_tuple)
464 /* Release the data space occupied by a tuple.
466 /*----------------------------------------------------------*/
472 register TUPLE_DESCRIPTOR tpd;
474 GDB_GIVEUP("Delete_tuple called with null tuple")
475 GDB_CHECK_TUP(t, "delete_tuple")
477 db_free((char *)t, t->desc->data_len);
478 delete_tuple_descriptor(tpd); /* does a reference counted */
482 /*----------------------------------------------------------*/
484 /* initialize_tuple (initialize_tuple)
486 /* Set each field in tuple to its null value.
488 /*----------------------------------------------------------*/
494 register char *field_data; /* pointer to first byte */
495 /* of field data in tuple*/
496 register TUPLE_DESCRIPTOR tpd; /* pointer to descriptor */
497 register int i; /* counter of fields */
498 int num_fields; /* total number of fields */
501 * Return if no tuple at all supplied--perhaps this should be
502 * an error. If supplied, make sure it looks like a tuple.
508 GDB_CHECK_TUP(t, "initialize_tuple")
511 * Set up to loop through fields: get tuple descriptor, field count
512 * and pointer to first data byte in the tuple.
516 num_fields = tpd->field_count;
517 field_data = t->data; /* address of first byte of */
522 * For each field in the tuple, loop calling its null value
523 * initialization routine.
526 for (i=0; i<num_fields; i++) {
527 FCN_PROPERTY(tpd->var[i].type, NULL_PROPERTY)
528 (field_data+tpd->var[i].offset);
533 /*----------------------------------------------------------*/
535 /* null_tuple_strings (null_tuple_strings)
537 /* Reclaim the space for all fields in the tuple
538 /* whose type is 'string.'
540 /*----------------------------------------------------------*/
543 null_tuple_strings(t)
546 register char *field_data; /* pointer to first byte of */
547 /* field data in tuple */
548 register TUPLE_DESCRIPTOR tpd; /* pointer to descriptor */
549 register int i; /* counter of fields */
550 int num_fields; /* total number of fields */
553 * Return if no tuple at all supplied--perhaps this should be
560 GDB_CHECK_TUP(t, "null_tuple_strings")
563 * Set up to loop through fields: get tuple descriptor, field count
564 * and pointer to first data byte in the tuple.
568 num_fields = tpd->field_count;
569 field_data = t->data; /* address of first byte of */
573 * For each field in the tuple, loop calling its null value
574 * initialization routine.
577 for (i=0; i<num_fields; i++) {
578 if(FIELD_TYPE_IN_TUPLE(tpd,i) == STRING_T &&
579 (*(char **)(field_data+FIELD_OFFSET_IN_TUPLE(tpd,i)))!=NULL)
580 string_free((STRING *)(field_data+
581 FIELD_OFFSET_IN_TUPLE(tpd,i)));
585 /************************************************************************/
587 /* RELATION MANAGEMENT
589 /************************************************************************/
591 /*----------------------------------------------------------*/
593 /* create_relation (create_relation)
595 /*----------------------------------------------------------*/
598 create_relation(desc)
599 TUPLE_DESCRIPTOR desc;
603 GDB_CHECK_TPD(desc, "create_relation")
605 r = (RELATION)db_alloc(sizeof(struct rel_dat));
608 GDB_GIVEUP("create_relation (create_relation) could not get enough space.\n")
611 * Fill in the empty relation. Create a null circular list
612 * of tuples and also hang the description.
620 REFERENCE_TUPLE_DESCRIPTOR(desc); /* bump the reference count */
625 /*----------------------------------------------------------*/
629 /* Deletes the tuples which comprise a relation.
630 /* For each tuple, it does a null-tuple-strings
631 /* prior to deleting, but it does not yet handle
632 /* any other non-contiguous data.
634 /*----------------------------------------------------------*/
640 register TUPLE t, next;
641 TUPLE_DESCRIPTOR desc;
644 * Make sure a proper relation is supplied.
648 GDB_GIVEUP("delete_relation called with null relation")
649 GDB_CHECK_REL(rel, "delete_relation")
651 t = FIRST_TUPLE_IN_RELATION(rel);
653 /*----------------------------------------------------------*/
655 /* Free all the tuples
657 /*----------------------------------------------------------*/
660 null_tuple_strings(t);
661 next = NEXT_TUPLE_IN_RELATION(rel, t);
666 /*----------------------------------------------------------*/
668 /* Give back the memory for the relation
670 /*----------------------------------------------------------*/
672 desc = DESCRIPTOR_FROM_RELATION(rel);
673 db_free((char *)rel, sizeof(struct rel_dat));
674 delete_tuple_descriptor(desc); /* does a reference */
678 /*----------------------------------------------------------*/
680 /* tuples_in_relation
682 /* Returns number of tuples in a relation.
685 /*----------------------------------------------------------*/
688 tuples_in_relation(rel)
692 register RELATION r=rel;
697 for (t=FIRST_TUPLE_IN_RELATION(r);
699 t=NEXT_TUPLE_IN_RELATION(r,t)) {