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
39 /* These routines implement the following layers of the
40 /* Client Library Specification of the GDB system:
44 /* 2 Structured Data Management at a
47 /* 4 Memory Management
49 /* 5 String Management
51 /* Some of the routines specified are actually implemented as
52 /* macros defined in gdb.h.
54 /************************************************************************/
60 extern char *malloc();
63 /************************************************************************/
67 /* In anticipation of the day when we may want to do something
68 /* fancy with memory management, all of the gdb routines which
69 /* require dynamic allocation of memory call the routines named
70 /* db_alloc and db_free. For the moment, these are implemented
71 /* as calls to malloc and free.
73 /************************************************************************/
75 /*----------------------------------------------------------*/
79 /* Allocate memory for use by gdb. Current implementation
80 /* just does a malloc.
82 /*----------------------------------------------------------*/
88 return(malloc((unsigned)bytes));
91 /*----------------------------------------------------------*/
95 /* Return allocated memory. Note: the current
96 /* implementation ignores the byte count supplied,
97 /* but future implementations may require that it
100 /*----------------------------------------------------------*/
111 /************************************************************************/
115 /* To allow dynamic manipulation of strings in gdb without
116 /* excessive memory re-allocation, we define a string as a
117 /* counted byte space. Though this space will frequently be used
118 /* to store a standard null terminated string, that is not
121 /* Current representation for a string is a pointer followed by
122 /* an integer length. A null pointer indicates a null string, in
123 /* which case the length is arbitrary. Any other pointer is to
124 /* memory which was allocated by db_alloc in which must be free'd
125 /* eventually with db_free.
127 /************************************************************************/
129 /*----------------------------------------------------------*/
131 /* string_alloc (string_alloc)
133 /* Fills in supplied string descriptor and returns
134 /* pointer to the newly allocated data.
136 /*----------------------------------------------------------*/
139 string_alloc(stringp, bytes)
140 STRING *stringp; /* pointer to string */
141 /* descriptor to be */
143 int bytes; /* number of bytes to alloc */
147 MAX_STRING_SIZE(*stringp) = bytes; /* put length in returned */
148 /* string descriptor-- */
149 /* will be irrelavent if */
152 STRING_DATA(*stringp) = db_alloc(bytes); /* try to get the data */
153 return (STRING_DATA(*stringp)); /* return ptr to new string */
157 /*----------------------------------------------------------*/
159 /* string_free (string_free)
161 /* Releases the data space for a gdb string. Must have
162 /* been allocated with string_alloc. Remember to pass
163 /* in the address of the string descriptor, not the
164 /* descriptor itself!
166 /*----------------------------------------------------------*/
173 if (stringp->ptr == NULL)
175 db_free(stringp->ptr, stringp->length);
181 /************************************************************************/
183 /* STRUCTURED DATA MANAGEMENT AT A SINGLE SITE
185 /* These routines provide the abstraction of typed, structured
186 /* data at a single site. Tuples are collections of typed fields,
187 /* and they are each described by a tuple descriptor. Relations
188 /* are circularly linked lists of tuples. For completeness, a
189 /* relation also carries a tuple descriptor, which should match
190 /* the descriptor for each of its constituent tuples. This allows
191 /* a null relation to be typed.
193 /* Some of the facilities of structured data management are
194 /* defined as macros in gdb.h. In many cases, the routines
195 /* declared below are known by defines of more descriptive
196 /* names, also in gdb.h.
198 /************************************************************************/
199 /************************************************************************/
201 /* TUPLE_DESCRIPTOR MANAGEMENT
203 /************************************************************************/
206 /*----------------------------------------------------------*/
208 /* create_tuple_descriptor (create_tuple_descriptor)
210 /* Allocates space for a tuple descriptor and fills
211 /* it in. Gives up if space is not available.
212 /* Should be passed a list of integer coded types
213 /* and a list of string field names.
215 /* Tuple descriptors are reference counted, and they are
216 /* not really deleted until the reference count goes
217 /* to zero. It is presumed that all callers use the
218 /* create and delete routines, or otherwise maintain
219 /* the reference count appropriately.
221 /*----------------------------------------------------------*/
225 create_tuple_descriptor(number_of_fields, name_list, type_list)
227 FIELD_TYPE type_list[];
228 int number_of_fields;
230 register TUPLE_DESCRIPTOR tpd; /* pointer to new descriptor */
232 register int data_len; /* length of the actual */
233 int field_len; /* length of current field */
234 int align; /* code describing alignment */
235 /* requirement for this field*/
236 /* (4 for fullword, 1 for */
238 int next_offset; /* byte offset to next field */
239 int descriptor_length; /* length of the part of */
240 /* the allocated storage */
241 /* actually used for the */
243 int str_len; /* we also have to retain */
244 /* the string names for the */
245 /* fields. These are stored */
246 /* immediately off the end */
247 /* of the descriptor, and */
248 /* all are allocated */
249 /* together. This is the */
250 /* length of the string data */
251 char *next_name; /* place to put the next */
252 /* copied fieldname*/
258 * Calculate size and allocate descriptor
261 descriptor_length = sizeof(struct tupl_desc) +
262 (number_of_fields-1) * sizeof(struct tupld_var);
266 for (i=0; i<number_of_fields; i++)
267 str_len += strlen(name_list[i]) +1;
269 tpd = (TUPLE_DESCRIPTOR)db_alloc(descriptor_length+str_len);
270 /* try to allocate it */
273 GDB_GIVEUP("create_tuple_descriptor (gbd_ctd) could not get enough memory.\n")
276 * Fill in the descriptor fields:
278 * Each field is aligned according to its own alignment code.
279 * Going in to the top of the for loop, next_offset is set to
280 * the offset of the first possible byte for storing the next field.
281 * During the loop, that number is rounded up, if necessary, to
282 * achieve the alignment actually required for the field. Finally,
283 * the length of the new field is added, which yields the first
284 * possible byte of any field to follow.
287 tpd->id = GDB_DESC_ID;
289 tpd->ref_count = 1; /* whoever asked for creation*/
290 /* is expected to delete*/
292 tpd->field_count = number_of_fields;
293 tpd->str_len = str_len;
295 data_len = sizeof(struct tuple_dat) - 1; /* tuple_dat includes the */
296 /* first byte of data */
298 next_name = ((char *)tpd) + descriptor_length;
299 /* place to put first */
301 for (i=0; i<number_of_fields; i++) {
303 * Calculate lengths and alignments for the field data.
305 field_len = INT_PROPERTY(type_list[i],LENGTH_PROPERTY);
306 align = INT_PROPERTY(type_list[i],ALIGNMENT_PROPERTY);
308 * Copy the string field name into the newly allocated
309 * space just after the descriptor itself.
311 tpd->var[i].name = strcpy(next_name, name_list[i]);
312 next_name += strlen(next_name) + 1;
314 * Put in the type and the length for the field data
316 tpd->var[i].type = type_list[i];
317 tpd->var[i].length = field_len;
319 * Now store the actual offset of this field, and
320 * compute the first byte address we could conceivably
321 * use for the next field.
323 next_offset = GDB_ROUNDUP(next_offset, align);
324 tpd->var[i].offset = next_offset;
325 next_offset += field_len;
328 data_len += next_offset;
329 tpd->data_len = data_len;
331 return tpd; /* return the new descriptor */
334 /*----------------------------------------------------------*/
336 /* delete_tuple_descriptor (delete_tuple_descriptor)
338 /* Return the space for a tuple descriptor
340 /*----------------------------------------------------------*/
343 delete_tuple_descriptor(t)
346 int descriptor_length;
347 register int ref_count; /* buffer the reference */
353 GDB_CHECK_TPD(t, "delete_tuple_descriptor")
357 * Decrement the reference count. If it's not zero, then just
360 if ((ref_count = --(t->ref_count)) >0)
363 GDB_GIVEUP("Tuple descriptor reference count is less than zero")
365 * Current representation is to allocate the space for the string
366 * right off the end of the descriptor itself. We therefore have
367 * to add their length into the amount we free.
369 descriptor_length = gdb_descriptor_length(t->field_count);
370 db_free((char *)t, descriptor_length+t->str_len);
375 /*----------------------------------------------------------*/
377 /* field_index (field_index)
379 /*----------------------------------------------------------*/
382 field_index(tuple_descriptor, field_name)
383 TUPLE_DESCRIPTOR tuple_descriptor;
388 register TUPLE_DESCRIPTOR tpd = tuple_descriptor;
391 * Make sure supplied descriptor is valid
394 GDB_GIVEUP("null tuple descriptor passed to field_index function")
395 GDB_CHECK_TPD(tpd, "field_index")
397 n = tpd -> field_count;
400 * Loop through each field in descriptor, return index if match
404 if (strcmp(field_name, tpd->var[i].name) == 0)
407 * No match, return -1
413 /************************************************************************/
417 /************************************************************************/
419 /*----------------------------------------------------------*/
421 /* create_tuple (create_tuple)
423 /* Allocate space for a new tuple, given its
424 /* descriptor. Giveup if out of memory.
426 /*----------------------------------------------------------*/
429 create_tuple(descriptor)
430 TUPLE_DESCRIPTOR descriptor;
434 GDB_CHECK_TPD(descriptor, "create_tuple")
436 t = (TUPLE)db_alloc(descriptor -> data_len);
439 GDB_GIVEUP("create_tuple (create_tuple) could not allocate enough memory.\n")
443 t->desc = descriptor; /* fill in descriptor */
444 /* pointer in new tuple */
445 REFERENCE_TUPLE_DESCRIPTOR(descriptor); /* bump the reference count */
448 * Only for the sake of keeping things clean, null out the pointers.
449 * Wastes time, but helps debugging.
451 t->next = t->prev = NULL;
457 /*----------------------------------------------------------*/
459 /* delete_tuple (delete_tuple)
461 /* Release the data space occupied by a tuple.
463 /*----------------------------------------------------------*/
469 register TUPLE_DESCRIPTOR tpd;
471 GDB_GIVEUP("Delete_tuple called with null tuple")
472 GDB_CHECK_TUP(t, "delete_tuple")
474 db_free((char *)t, t->desc->data_len);
475 delete_tuple_descriptor(tpd); /* does a reference counted */
479 /*----------------------------------------------------------*/
481 /* initialize_tuple (initialize_tuple)
483 /* Set each field in tuple to its null value.
485 /*----------------------------------------------------------*/
491 register char *field_data; /* pointer to first byte */
492 /* of field data in tuple*/
493 register TUPLE_DESCRIPTOR tpd; /* pointer to descriptor */
494 register int i; /* counter of fields */
495 int num_fields; /* total number of fields */
498 * Return if no tuple at all supplied--perhaps this should be
499 * an error. If supplied, make sure it looks like a tuple.
505 GDB_CHECK_TUP(t, "initialize_tuple")
508 * Set up to loop through fields: get tuple descriptor, field count
509 * and pointer to first data byte in the tuple.
513 num_fields = tpd->field_count;
514 field_data = t->data; /* address of first byte of */
519 * For each field in the tuple, loop calling its null value
520 * initialization routine.
523 for (i=0; i<num_fields; i++) {
524 FCN_PROPERTY(tpd->var[i].type, NULL_PROPERTY)
525 (field_data+tpd->var[i].offset);
530 /*----------------------------------------------------------*/
532 /* null_tuple_strings (null_tuple_strings)
534 /* Reclaim the space for all fields in the tuple
535 /* whose type is 'string.'
537 /*----------------------------------------------------------*/
540 null_tuple_strings(t)
543 register char *field_data; /* pointer to first byte of */
544 /* field data in tuple */
545 register TUPLE_DESCRIPTOR tpd; /* pointer to descriptor */
546 register int i; /* counter of fields */
547 int num_fields; /* total number of fields */
550 * Return if no tuple at all supplied--perhaps this should be
557 GDB_CHECK_TUP(t, "null_tuple_strings")
560 * Set up to loop through fields: get tuple descriptor, field count
561 * and pointer to first data byte in the tuple.
565 num_fields = tpd->field_count;
566 field_data = t->data; /* address of first byte of */
570 * For each field in the tuple, loop calling its null value
571 * initialization routine.
574 for (i=0; i<num_fields; i++) {
575 if(FIELD_TYPE_IN_TUPLE(tpd,i) == STRING_T &&
576 (*(char **)(field_data+FIELD_OFFSET_IN_TUPLE(tpd,i)))!=NULL)
577 string_free((STRING *)(field_data+
578 FIELD_OFFSET_IN_TUPLE(tpd,i)));
582 /************************************************************************/
584 /* RELATION MANAGEMENT
586 /************************************************************************/
588 /*----------------------------------------------------------*/
590 /* create_relation (create_relation)
592 /*----------------------------------------------------------*/
595 create_relation(desc)
596 TUPLE_DESCRIPTOR desc;
600 GDB_CHECK_TPD(desc, "create_relation")
602 r = (RELATION)db_alloc(sizeof(struct rel_dat));
605 GDB_GIVEUP("create_relation (create_relation) could not get enough space.\n")
608 * Fill in the empty relation. Create a null circular list
609 * of tuples and also hang the description.
617 REFERENCE_TUPLE_DESCRIPTOR(desc); /* bump the reference count */
622 /*----------------------------------------------------------*/
626 /* Deletes the tuples which comprise a relation.
627 /* For each tuple, it does a null-tuple-strings
628 /* prior to deleting, but it does not yet handle
629 /* any other non-contiguous data.
631 /*----------------------------------------------------------*/
637 register TUPLE t, next;
638 TUPLE_DESCRIPTOR desc;
641 * Make sure a proper relation is supplied.
645 GDB_GIVEUP("delete_relation called with null relation")
646 GDB_CHECK_REL(rel, "delete_relation")
648 t = FIRST_TUPLE_IN_RELATION(rel);
650 /*----------------------------------------------------------*/
652 /* Free all the tuples
654 /*----------------------------------------------------------*/
657 null_tuple_strings(t);
658 next = NEXT_TUPLE_IN_RELATION(rel, t);
663 /*----------------------------------------------------------*/
665 /* Give back the memory for the relation
667 /*----------------------------------------------------------*/
669 desc = DESCRIPTOR_FROM_RELATION(rel);
670 db_free((char *)rel, sizeof(struct rel_dat));
671 delete_tuple_descriptor(desc); /* does a reference */
675 /*----------------------------------------------------------*/
677 /* tuples_in_relation
679 /* Returns number of tuples in a relation.
682 /*----------------------------------------------------------*/
685 tuples_in_relation(rel)
689 register RELATION r=rel;
694 for (t=FIRST_TUPLE_IN_RELATION(r);
696 t=NEXT_TUPLE_IN_RELATION(r,t)) {