home *** CD-ROM | disk | FTP | other *** search
- 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<sizeof_dTable(&foobar); n++)
- printf("%d: %d %s\n",n, foobar.table[n].token,foobar.table[n].name);
- }
- #endif
-