]> andersk Git - moira.git/blame - gdb/gdb_struct.c
Added make depend.
[moira.git] / gdb / gdb_struct.c
CommitLineData
5580185e 1/*
2 * $Source$
3 * $Header$
4 */
5
6#ifndef lint
7static char *rcsid_gdb_struct_c = "$Header$";
8#endif lint
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30/************************************************************************/
31/*
32/* gdb_struct.c
33/*
34/* GDB - Structured Data Maintenance Routines
35/*
36/* Author: Noah Mendelsohn
37/* Copyright: 1986 MIT Project Athena
38/*
39/* These routines implement the following layers of the
40/* Client Library Specification of the GDB system:
41/*
42/* Layer Function
43/* ----- --------
44/* 2 Structured Data Management at a
45/* Single Site
46/*
47/* 4 Memory Management
48/*
49/* 5 String Management
50/*
51/* Some of the routines specified are actually implemented as
52/* macros defined in gdb.h.
53/*
54/************************************************************************/
55
56#include <stdio.h>
57#include <strings.h>
58#include "gdb.h"
59
60extern char *malloc();
61extern int free();
62\f
63/************************************************************************/
64/*
65/* MEMORY MANAGEMENT
66/*
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.
72/*
73/************************************************************************/
74
75 /*----------------------------------------------------------*/
76 /*
77 /* gdb_am
78 /*
79 /* Allocate memory for use by gdb. Current implementation
80 /* just does a malloc.
81 /*
82 /*----------------------------------------------------------*/
83
84char *
85gdb_am(bytes)
86int bytes;
87{
88 return(malloc((unsigned)bytes));
89}
90
91 /*----------------------------------------------------------*/
92 /*
93 /* gdb_fm
94 /*
95 /* Return allocated memory. Note: the current
96 /* implementation ignores the byte count supplied,
97 /* but future implementations may require that it
98 /* be correct.
99 /*
100 /*----------------------------------------------------------*/
101
102int
103gdb_fm(ptr, bytes)
104char *ptr;
105int bytes;
106{
107 free(ptr);
108 return;
109}
110\f
111/************************************************************************/
112/*
113/* STRING MANAGEMENT
114/*
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
119/* required.
120/*
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.
126/*
127/************************************************************************/
128
129 /*----------------------------------------------------------*/
130 /*
131 /* string_alloc (string_alloc)
132 /*
133 /* Fills in supplied string descriptor and returns
134 /* pointer to the newly allocated data.
135 /*
136 /*----------------------------------------------------------*/
137
138char *
139string_alloc(stringp, bytes)
140STRING *stringp; /* pointer to string */
141 /* descriptor to be */
142 /* filled in */
143int bytes; /* number of bytes to alloc */
144{
145 GDB_INIT_CHECK
146
147 MAX_STRING_SIZE(*stringp) = bytes; /* put length in returned */
148 /* string descriptor-- */
149 /* will be irrelavent if */
150 /* alloc fails */
151
152 STRING_DATA(*stringp) = db_alloc(bytes); /* try to get the data */
153 return (STRING_DATA(*stringp)); /* return ptr to new string */
154 /* if any */
155}
156
157 /*----------------------------------------------------------*/
158 /*
159 /* string_free (string_free)
160 /*
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!
165 /*
166 /*----------------------------------------------------------*/
167int
168string_free(stringp)
169STRING *stringp;
170{
171 GDB_INIT_CHECK
172
173 if (stringp->ptr == NULL)
174 return;
175 db_free(stringp->ptr, stringp->length);
176 stringp->ptr = NULL;
177 stringp->length = 0;
178 return;
179}
180\f
181/************************************************************************/
182/*
183/* STRUCTURED DATA MANAGEMENT AT A SINGLE SITE
184/*
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.
192/*
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.
197/*
198/************************************************************************/
199/************************************************************************/
200/*
201/* TUPLE_DESCRIPTOR MANAGEMENT
202/*
203/************************************************************************/
204
205
206 /*----------------------------------------------------------*/
207 /*
208 /* create_tuple_descriptor (create_tuple_descriptor)
209 /*
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.
214 /*
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.
220 /*
221 /*----------------------------------------------------------*/
222
223
224TUPLE_DESCRIPTOR
225create_tuple_descriptor(number_of_fields, name_list, type_list)
226char *name_list[];
227FIELD_TYPE type_list[];
228int number_of_fields;
229{
230 register TUPLE_DESCRIPTOR tpd; /* pointer to new descriptor */
231 register int i;
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 */
237 /* char, etc.) */
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 */
242 /* descriptor.*/
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*/
253
254
255 GDB_INIT_CHECK
256
257 /*
258 * Calculate size and allocate descriptor
259 */
260
261 descriptor_length = sizeof(struct tupl_desc) +
262 (number_of_fields-1) * sizeof(struct tupld_var);
263
264 str_len = 0;
265
266 for (i=0; i<number_of_fields; i++)
267 str_len += strlen(name_list[i]) +1;
268
269 tpd = (TUPLE_DESCRIPTOR)db_alloc(descriptor_length+str_len);
270 /* try to allocate it */
271
272 if (tpd == NULL)
273 GDB_GIVEUP("create_tuple_descriptor (gbd_ctd) could not get enough memory.\n")
274
275 /*
276 * Fill in the descriptor fields:
277 *
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.
285 */
286
287 tpd->id = GDB_DESC_ID;
288
289 tpd->ref_count = 1; /* whoever asked for creation*/
290 /* is expected to delete*/
291
292 tpd->field_count = number_of_fields;
293 tpd->str_len = str_len;
294
295 data_len = sizeof(struct tuple_dat) - 1; /* tuple_dat includes the */
296 /* first byte of data */
297 next_offset = 0;
298 next_name = ((char *)tpd) + descriptor_length;
299 /* place to put first */
300 /* field name*/
301 for (i=0; i<number_of_fields; i++) {
302 /*
303 * Calculate lengths and alignments for the field data.
304 */
305 field_len = INT_PROPERTY(type_list[i],LENGTH_PROPERTY);
306 align = INT_PROPERTY(type_list[i],ALIGNMENT_PROPERTY);
307 /*
308 * Copy the string field name into the newly allocated
309 * space just after the descriptor itself.
310 */
311 tpd->var[i].name = strcpy(next_name, name_list[i]);
312 next_name += strlen(next_name) + 1;
313 /*
314 * Put in the type and the length for the field data
315 */
316 tpd->var[i].type = type_list[i];
317 tpd->var[i].length = field_len;
318 /*
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.
322 */
323 next_offset = GDB_ROUNDUP(next_offset, align);
324 tpd->var[i].offset = next_offset;
325 next_offset += field_len;
326 }
327
328 data_len += next_offset;
329 tpd->data_len = data_len;
330
331 return tpd; /* return the new descriptor */
332}
333
334 /*----------------------------------------------------------*/
335 /*
336 /* delete_tuple_descriptor (delete_tuple_descriptor)
337 /*
338 /* Return the space for a tuple descriptor
339 /*
340 /*----------------------------------------------------------*/
341
342int
343delete_tuple_descriptor(t)
344TUPLE_DESCRIPTOR t;
345{
346 int descriptor_length;
347 register int ref_count; /* buffer the reference */
348 /* count here */
349
350 if (t == NULL)
351 return ;
352
353 GDB_CHECK_TPD(t, "delete_tuple_descriptor")
354
355
356 /*
357 * Decrement the reference count. If it's not zero, then just
358 * return.
359 */
360 if ((ref_count = --(t->ref_count)) >0)
361 return ;
362 if (ref_count <0)
363 GDB_GIVEUP("Tuple descriptor reference count is less than zero")
364 /*
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.
368 */
369 descriptor_length = gdb_descriptor_length(t->field_count);
370 db_free((char *)t, descriptor_length+t->str_len);
371
372 return ;
373}
374
375 /*----------------------------------------------------------*/
376 /*
377 /* field_index (field_index)
378 /*
379 /*----------------------------------------------------------*/
380
381int
382field_index(tuple_descriptor, field_name)
383TUPLE_DESCRIPTOR tuple_descriptor;
384char *field_name;
385{
386 register int i;
387 register int n;
388 register TUPLE_DESCRIPTOR tpd = tuple_descriptor;
389
390 /*
391 * Make sure supplied descriptor is valid
392 */
393 if (tpd == NULL)
394 GDB_GIVEUP("null tuple descriptor passed to field_index function")
395 GDB_CHECK_TPD(tpd, "field_index")
396
397 n = tpd -> field_count;
398
399 /*
400 * Loop through each field in descriptor, return index if match
401 */
402
403 for(i=0; i<n; i++)
404 if (strcmp(field_name, tpd->var[i].name) == 0)
405 return i;
406 /*
407 * No match, return -1
408 */
409 return (-1);
410}
411
412\f
413/************************************************************************/
414/*
415/* TUPLE MANAGEMENT
416/*
417/************************************************************************/
418
419 /*----------------------------------------------------------*/
420 /*
421 /* create_tuple (create_tuple)
422 /*
423 /* Allocate space for a new tuple, given its
424 /* descriptor. Giveup if out of memory.
425 /*
426 /*----------------------------------------------------------*/
427
428TUPLE
429create_tuple(descriptor)
430TUPLE_DESCRIPTOR descriptor;
431{
432 register TUPLE t;
433
434 GDB_CHECK_TPD(descriptor, "create_tuple")
435
436 t = (TUPLE)db_alloc(descriptor -> data_len);
437
438 if (t == NULL)
439 GDB_GIVEUP("create_tuple (create_tuple) could not allocate enough memory.\n")
440
441 t->id = GDB_TUP_ID;
442
443 t->desc = descriptor; /* fill in descriptor */
444 /* pointer in new tuple */
445 REFERENCE_TUPLE_DESCRIPTOR(descriptor); /* bump the reference count */
446#ifdef GDB_CHECK
447 /*
448 * Only for the sake of keeping things clean, null out the pointers.
449 * Wastes time, but helps debugging.
450 */
451 t->next = t->prev = NULL;
452#endif GDB_CHECK
453
454 return t;
455}
456
457 /*----------------------------------------------------------*/
458 /*
459 /* delete_tuple (delete_tuple)
460 /*
461 /* Release the data space occupied by a tuple.
462 /*
463 /*----------------------------------------------------------*/
464
465int
466delete_tuple(t)
467TUPLE t;
468{
469 register TUPLE_DESCRIPTOR tpd;
470 if (t==NULL)
471 GDB_GIVEUP("Delete_tuple called with null tuple")
472 GDB_CHECK_TUP(t, "delete_tuple")
473 tpd = t->desc;
474 db_free((char *)t, t->desc->data_len);
475 delete_tuple_descriptor(tpd); /* does a reference counted */
476 /* delete*/
477}
478
479 /*----------------------------------------------------------*/
480 /*
481 /* initialize_tuple (initialize_tuple)
482 /*
483 /* Set each field in tuple to its null value.
484 /*
485 /*----------------------------------------------------------*/
486
487int
488initialize_tuple(t)
489TUPLE t;
490{
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 */
496
497 /*
498 * Return if no tuple at all supplied--perhaps this should be
499 * an error. If supplied, make sure it looks like a tuple.
500 */
501
502 if (t == NULL)
503 return;
504
505 GDB_CHECK_TUP(t, "initialize_tuple")
506
507 /*
508 * Set up to loop through fields: get tuple descriptor, field count
509 * and pointer to first data byte in the tuple.
510 */
511
512 tpd = t->desc;
513 num_fields = tpd->field_count;
514 field_data = t->data; /* address of first byte of */
515 /* user data */
516
517
518 /*
519 * For each field in the tuple, loop calling its null value
520 * initialization routine.
521 */
522
523 for (i=0; i<num_fields; i++) {
524 FCN_PROPERTY(tpd->var[i].type, NULL_PROPERTY)
525 (field_data+tpd->var[i].offset);
526 }
527}
528
529
530 /*----------------------------------------------------------*/
531 /*
532 /* null_tuple_strings (null_tuple_strings)
533 /*
534 /* Reclaim the space for all fields in the tuple
535 /* whose type is 'string.'
536 /*
537 /*----------------------------------------------------------*/
538
539int
540null_tuple_strings(t)
541TUPLE t;
542{
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 */
548
549 /*
550 * Return if no tuple at all supplied--perhaps this should be
551 * an error
552 */
553
554 if (t == NULL)
555 return;
556
557 GDB_CHECK_TUP(t, "null_tuple_strings")
558
559 /*
560 * Set up to loop through fields: get tuple descriptor, field count
561 * and pointer to first data byte in the tuple.
562 */
563
564 tpd = t->desc;
565 num_fields = tpd->field_count;
566 field_data = t->data; /* address of first byte of */
567 /* user data */
568
569 /*
570 * For each field in the tuple, loop calling its null value
571 * initialization routine.
572 */
573
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)));
579 }
580}
581\f
582/************************************************************************/
583/*
584/* RELATION MANAGEMENT
585/*
586/************************************************************************/
587
588 /*----------------------------------------------------------*/
589 /*
590 /* create_relation (create_relation)
591 /*
592 /*----------------------------------------------------------*/
593
594RELATION
595create_relation(desc)
596TUPLE_DESCRIPTOR desc;
597{
598 register RELATION r;
599
600 GDB_CHECK_TPD(desc, "create_relation")
601
602 r = (RELATION)db_alloc(sizeof(struct rel_dat));
603
604 if (r == NULL)
605 GDB_GIVEUP("create_relation (create_relation) could not get enough space.\n")
606
607 /*
608 * Fill in the empty relation. Create a null circular list
609 * of tuples and also hang the description.
610 */
611
612 r->id = GDB_REL_ID;
613
614 r->first = (TUPLE)r;
615 r->last = (TUPLE)r;
616 r->desc = desc;
617 REFERENCE_TUPLE_DESCRIPTOR(desc); /* bump the reference count */
618
619 return r;
620}
621
622 /*----------------------------------------------------------*/
623 /*
624 /* delete_relation
625 /*
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.
630 /*
631 /*----------------------------------------------------------*/
632
633int
634delete_relation(rel)
635RELATION rel;
636{
637 register TUPLE t, next;
638 TUPLE_DESCRIPTOR desc;
639
640 /*
641 * Make sure a proper relation is supplied.
642 */
643
644 if (rel == NULL)
645 GDB_GIVEUP("delete_relation called with null relation")
646 GDB_CHECK_REL(rel, "delete_relation")
647
648 t = FIRST_TUPLE_IN_RELATION(rel);
649
650 /*----------------------------------------------------------*/
651 /*
652 /* Free all the tuples
653 /*
654 /*----------------------------------------------------------*/
655
656 while (t!=NULL) {
657 null_tuple_strings(t);
658 next = NEXT_TUPLE_IN_RELATION(rel, t);
659 delete_tuple(t);
660 t = next;
661 }
662
663 /*----------------------------------------------------------*/
664 /*
665 /* Give back the memory for the relation
666 /*
667 /*----------------------------------------------------------*/
668
669 desc = DESCRIPTOR_FROM_RELATION(rel);
670 db_free((char *)rel, sizeof(struct rel_dat));
671 delete_tuple_descriptor(desc); /* does a reference */
672 /* counted delete */
673}
674
675 /*----------------------------------------------------------*/
676 /*
677 /* tuples_in_relation
678 /*
679 /* Returns number of tuples in a relation.
680 /*
681 /*
682 /*----------------------------------------------------------*/
683
684int
685tuples_in_relation(rel)
686RELATION rel;
687{
688 register int count;
689 register RELATION r=rel;
690 register TUPLE t;
691
692 count = 0;
693
694 for (t=FIRST_TUPLE_IN_RELATION(r);
695 t != NULL;
696 t=NEXT_TUPLE_IN_RELATION(r,t)) {
697 count++;
698 }
699 return count;
700}
701
702
703
This page took 0.138595 seconds and 5 git commands to generate.