static char rcsid[] = "$Id: dtable.c,v 1.1 1992/09/06 19:31:32 mike Exp $"; /* $Log: dtable.c,v $ * Revision 1.1 1992/09/06 19:31:32 mike * Initial revision * */ /* dtable.c : dynamic tables * xpand_dTable: Make sure a dTable can hold n more items. * Input: * dtable: A pointer to a dTable. * n: Number of items that will be added to the table after * this call. * initial_size: Number of cells to initialize table to. * step: Grow table by multiples of step cells. * Output: * TRUE: table has room for n items. * FALSE: Not enough memory - table is junk. !!! not in ansi C * How to use: * #include "dtable.h" * typedef struct { ... } Blob; * * IF dTable is global (or static): * declare_and_init_dTable(foobar,Blob); * * IF dTable is a typdef'ed global: * typedef declare_dTable_of(Blob) FooBar; * FooBar foobar = initial_dTable_data(foobar); * * IF dTable is automatic (local): * declare_dTable_of(Blob) foobar; * INIT_dTable(&foobar); or initialize_dTable(&foobar,sizeof(Blob)); * xpand_dTable(&foobar, n, initial_size, step); * foobar.table[j] = a_Blob; -- do this n times * Notes: * Make sure the dTable is initialized! See "How to use" above. * If you want to reuse the table: reset_dTable(dtable); * sizeof_dTable(dtable) is the number of items in the table (not the * max). * To release the dtable: free_dTable(dtable). If you are going to * reuse the table header, do an INIT_dTable(dtable) after the * free. * extern declare_dTable_of(Blob) foobar; is legal. * typedef declare_dTable_of(Blob) foobar; is legal. * If initial_size is not big enough to hold the first n items, the * table is created n+step big. * Warning: * Table may be moved during xpand_dTable(). So don't expect * ptr = foo->table; xpand_dTable(foo,...) to work. Always set ptr * after the xpand. * Craig Durland 6/89 */ /* Copyright 1989, 1990 Craig Durland * Distributed under the terms of the GNU General Public License. * Distributed "as is", without warranties of any kind, but comments, * suggestions and bug reports are welcome. */ #include "const.h" #include "dtable.h" void initialize_dTable(dtable,blob_size) dTable *dtable; { dtable->max_items = dtable->num_items = 0; dtable->blob_size = blob_size; dtable->table = NULL; /* for debugging purposes */ } void free_dTable(dtable) dTable *dtable; { if (dtable->max_items) free((char *)dtable->table); } extern char *malloc(), *realloc(); xpand_dTable(dtable, n, initial_size, step) dTable *dtable; { register int max_items, num_items, a, blob_size; register char *ptr; max_items = dtable->max_items; num_items = (dtable->num_items += n); /* check to see if already have enough room for n more items */ if (num_items <= max_items) return TRUE; blob_size = dtable->blob_size; if (max_items == 0) /* table not allocated yet */ { if ((a = initial_size) < num_items) /* initial size ain't big enough */ a = num_items +step; ptr = malloc(a*blob_size); } else /* table full, make bigger */ { a = (num_items -max_items +step -1)/step; a = max_items +a*step; ptr = realloc(dtable->table,a*blob_size); /*!!! in ANSI C, realloc may fail but table is still OK */ } dtable->max_items = a; if ((dtable->table = ptr) == NULL) /* out of memory => table is mush */ { initialize_dTable(dtable,blob_size); return FALSE; } return TRUE; } #ifdef TEST /* ******************************************************************** */ /* *************** TEST *********************************************** */ /* ******************************************************************** */ typedef struct { char *name; int token; } Blob; declare_and_init_dTable(foobar,Blob); main() { char zik[100], *name, *savestr(); int n, s, j; for (j = 0; 1; j++) { printf("name: "); gets(zik); if (*zik=='q') break; name = savestr(zik); printf("token: "); gets(zik); n = atoi(zik); s = xpand_dTable(&foobar, 1, 3, 2); foobar.table[j].name = name; foobar.table[j].token = n; printf("%d | num_items = %d, max_items = %d: %d %s\n", s, sizeof_dTable(&foobar), foobar.max_items, foobar.table[j].token,foobar.table[j].name); } for (n=0; n