diff options
author | 1990-11-16 06:41:56 +0000 | |
---|---|---|
committer | 1990-11-16 06:41:56 +0000 | |
commit | e17eedd8e03e6e429d6d0587baf055fe3ff4f29c (patch) | |
tree | cfe5308b659f1633f381e7d31bca01f6f14b3c06 /libdyn | |
parent | 35c501612c73a9e46b211223438d6acf6d3fef4f (diff) |
Initial revision
Diffstat (limited to 'libdyn')
-rw-r--r-- | libdyn/Imakefile | 48 | ||||
-rw-r--r-- | libdyn/README | 32 | ||||
-rw-r--r-- | libdyn/dyn.3 | 233 | ||||
-rw-r--r-- | libdyn/dyn.h | 47 | ||||
-rw-r--r-- | libdyn/dynP.h | 67 | ||||
-rw-r--r-- | libdyn/dyn_append.c | 43 | ||||
-rw-r--r-- | libdyn/dyn_create.c | 48 | ||||
-rw-r--r-- | libdyn/dyn_debug.c | 25 | ||||
-rw-r--r-- | libdyn/dyn_delete.c | 77 | ||||
-rw-r--r-- | libdyn/dyn_header.c | 11 | ||||
-rw-r--r-- | libdyn/dyn_insert.c | 60 | ||||
-rw-r--r-- | libdyn/dyn_paranoid.c | 26 | ||||
-rw-r--r-- | libdyn/dyn_put.c | 85 | ||||
-rw-r--r-- | libdyn/dyn_realloc.c | 50 | ||||
-rw-r--r-- | libdyn/dyn_size.c | 24 | ||||
-rw-r--r-- | libdyn/dyntest.c | 129 |
16 files changed, 1005 insertions, 0 deletions
diff --git a/libdyn/Imakefile b/libdyn/Imakefile new file mode 100644 index 0000000..609e878 --- /dev/null +++ b/libdyn/Imakefile @@ -0,0 +1,48 @@ +# This file is part of libdyn.a, the C Dynamic Object library. It +# contains the Makefile. +# +# There are no restrictions on this code; however, if you make any +# changes, I request that you document them so that I do not get +# credit or blame for your modifications. +# +# Written by Barr3y Jaspan, Student Information Processing Board (SIPB) +# and MIT-Project Athena, 1989. + +SRCS = dyn_create.c dyn_put.c dyn_debug.c dyn_delete.c dyn_size.c \ + dyn_append.c dyn_realloc.c dyn_paranoid.c dyn_insert.c +OBJS = dyn_create.o dyn_put.o dyn_debug.o dyn_delete.o dyn_size.o \ + dyn_append.o dyn_realloc.o dyn_paranoid.o dyn_insert.o +HDRS = dyn.h dynP.h + +SRCDIR = ${SRCTOP}/libdyn +CODE = ${SRCS} ${HDRS} Imakefile dyn.3 + +all:: libdyn.a + +llib-ldyn.ln:: ${HDRS} + +depend:: dyn.h + $(RM) ../include/dyn.h + $(CP) dyn.h ../include/dyn.h + +library_obj_rule() + +install_library_target(dyn,${OBJS},${SRCS},) + +all:: + $(RM) ../libs/libdyn.a ../libs/libdyn_p.a + $(CP) libdyn.a ../libs/libdyn.a + $(RANLIB) ../libs/libdyn.a +#ifdef PROFILED_LIBS + $(CP) libdyn_p.a ../libs/libdyn_p.a + $(RANLIB) ../libs/libdyn_p.a +#endif + +dyntest: libdyn.a dyntest.o + $(CC) -o dyntest dyntest.o libdyn.a + +manpage(3,dyn.3) + +#define last_licks() @@\ +llib-ldyn.ln:: @@\ + $(CP) llib-ldyn.ln ../libs/llib-ldyn.ln diff --git a/libdyn/README b/libdyn/README new file mode 100644 index 0000000..0c08ac5 --- /dev/null +++ b/libdyn/README @@ -0,0 +1,32 @@ +libdyn.a -- Release 1.0 + +A C Dynamic Object is an array that takes care of resizing itself as +elements are added and deleted from it. It can be of any type for +which sizeof is defined and for which an address of a variable of that +type can be passed to a function. + +To build libdyn.a, simply type "make depend all" (if you don't have +the program makedepend, of course, leave out the "depend" part). If +your system's bcopy() cannot handle overlapping regions, you'll need +to write one that can. (Left as an excercise for the reader..) + +The library should compile and work without modification on a vast +number of systems. It only uses 5 external functions: malloc, +realloc, free, bcopy, and fprintf (to stderr). Of these, only bcopy +should need to be changed for other systems (such as MS-DOS) and it +could probably be done with a -D flag to the compiler. + +The test/demo program is built by "make all". This program produces +the library's debugging output (to stderr) as well as some of its own +output (to stdout). + +The library has been tested (with test.c) on a VAX VSII, VAXstation +3100, DECstation 3100, and IBM RT all running BSD4.3 (except for the +DECstation, which was running Ultrix V2.1). + +An earlier version of this library was posted to alt.sources. This +version contains one new function (DynInsert) and slightly cleaner +code, but no bugfixes (no bugs were found). + +Author: Barr3y Jaspan, Student Information Processing Board (SIPB) and +MIT-Project Athena, bjaspan@athena.mit.edu, 1990 diff --git a/libdyn/dyn.3 b/libdyn/dyn.3 new file mode 100644 index 0000000..0376b2f --- /dev/null +++ b/libdyn/dyn.3 @@ -0,0 +1,233 @@ +.TH DYN 3M "15 March 1990" + +.SH NAME +dyn \- the C Dynamic Object library + +.SH DESCRIPTION + +A C Dynamic Object is an array that takes care of resizing +itself as you add and delete elements from it. It can be of any type +for which sizeof is defined and for which an address of a variable of +that type can be passed to a function. The library containing the +functions described below is called +.IR libdyn.a , +and the necessary declarations to use them are in +.RI < dyn.h >. +.PP +A DynObject is actually a structure that contains an array and a +couple of integers to maintain necessary state information. When a +Dyn function is said to operate on "the object" or "the array", it is +operating on the array stored in the structure while at the same time +updating internal state information. + +.SH LIST OF FUNCTIONS +.nf +DynObject DynCreate(size, increment) + int size, increment; +.fi +.PP +.IR Requires : +.I size +and +.I increment +are greater than zero. +.PP +.IR Effects : +Creates a new DynObject that will store elements of size +.I size +and will allocate memory in blocks large enough to hold exactly +.I increment +elements. For example, if you are storing 8-byte double +precision numbers and +.I increment +is 5, each 5th element you add to the object will cause it to request +40 more bytes (8 * 5) from the operating system. If +.I increment +is zero, a default value is used (currently 100). This is the only +time the programmer deals with a dynamic object's memory allocation. +.PP +.IR Returns : +.B DynCreate +returns the new DynObject, or NULL if there is insufficient memory. +.PP +.nf +int DynDestroy(obj) + DynObject obj; +.fi +.PP +.IR Modifies : +obj +.PP +.IR Effects : +Frees all memory associated with +.IR obj . +The results of calling any Dyn function on a destroyed object are +undefined (except for DynCreate, which resets the object). +.PP +.IR Returns : +.B DynDestroy +returns DYN_OK. +.PP +.nf +int DynAdd(obj, el) + DynObject obj; + DynPtr el; +.fi +.PP +.IR Modifies : +obj +.PP +.IR Effects : +Adds the element pointed to by +.I el +to the object +.IR obj , +resizing the object if necessary. +The new element becomes the last element in obj's array. +.PP +.IR Returns : +.B DynAdd +returns DYN_OK on success or DYN_NOMEM if there is insufficient +memory. +.PP +.nf +int DynInsert(obj, index, els, num) + DynObject obj; + DynPtr els; + int index, num; +.fi +.PP +.IR Modifies : +obj +.PP +.IR Effects : +Inserts the array of +.I num +elements, pointed to by +.IR els, +into the object +.I obj +starting at the array location +.IR index , +resizing the object if necessary. Order is preserved; if you have the +array "1 2 3 4 5" and insert "10 11 12" at the third position, you +will have the array "1 2 10 11 12 3 4 5". +.PP +.IR Returns : +.B DynInsert +returns DYN_BADINDEX if +.I index +is not between 0 and +.BR DynSize ( obj ) ; +DYN_BADVALUE if +.I num +is less than 1; DYN_NOMEM if there is insufficient memory. +.PP +.nf +int DynGet(obj, index) + DynObject obj; + int index; +.fi +.PP +.IR Effects : +Returns the address of the element +.I index +in the array of +.IR obj . +This pointer can be treated as a normal array of the type specified to +.BR DynCreate . +The order of elements in this array is the order in which they were +added to the object. The returned pointer is guaranteed to be valid +only until obj is modified. +.PP +.IR Returns : +.B DynGet +returns NULL if +.I index +is larger than the number of elements in the array of less than zero. +.PP +.nf +int DynDelete(obj, index) + DynObject obj; + int index; +.fi +.PP +.IR Modifies : +obj +.PP +.IR Effects : +The element +.I index +is deleted from the object +.IR obj . +Note that the element is actually removed permanently from the array. +If you have the array "1 2 3 4 5" and delete the third element, you +will have the array "1 2 4 5". The order of elements in not affected. +.PP +.IR Returns : +.B DynDelete +will return DYN_OK on success or DYN_BADINDEX if the element +.I index +does not exist in the array or is less than zero. +.PP +.nf +int DynSize(obj) + DynObject obj; +.fi +.PP +.IR Effects : +Returns the number of elements in the object +.IR obj . +.PP +.nf +int DynHigh(obj) + DynObject obj; +.fi +.PP +.IR Effects : +Returns the index of the highest element in the object +.IR obj . +In this version, +.B DynHigh +is macro that expands to +.B DynSize +- 1. +.PP +.nf +int DynLow(obj) + DynObject obj; +.fi +.PP +.IR Effects : +Returns the index of the lowest element in the object +.IR obj . +In this version, +.B DynLow +is macro that expands to 0. +.PP +.nf +int DynDebug(obj, state) + DynObject obj; + int state; +.fi +.PP +.IR Modifies : +obj +.PP +.IR Effects : +Sets the debugging state of +.I obj +to +.I state +and prints a message on stderr saying what state debugging was set to. +Any non-zero value for +.I state +turns debugging ``on''. When debugging is on, all Dyn functions will +produce (hopefully useful) output to stderr describing what is going on. +.PP +.IR Returns : +.B DynDebug +returns DYN_OK. +.SH AUTHOR +Barr3y Jaspan, Student Information Processing Board (SIPB) and +MIT-Project Athena, bjaspan@athena.mit.edu diff --git a/libdyn/dyn.h b/libdyn/dyn.h new file mode 100644 index 0000000..2d605ff --- /dev/null +++ b/libdyn/dyn.h @@ -0,0 +1,47 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the public header file. + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + + +/* + * dyn.h -- header file to be included by programs linking against + * libdyn.a. + */ + +#ifndef _Dyn_h +#define _Dyn_h + +#ifdef notdef +typedef void *DynPtr; +#else +typedef char *DynPtr; +#endif + +typedef struct _DynObject DynObjectRec, *DynObject; + +/* Function macros */ +#define DynHigh(obj) (DynSize(obj) - 1) +#define DynLow(obj) (0) + +/* Return status codes */ +#define DYN_OK -1000 +#define DYN_NOMEM -1001 +#define DYN_BADINDEX -1002 +#define DYN_BADVALUE -1003 + +/* Function declarations */ +DynObject DynCreate(); +int DynAdd(), DynDelete(), DynDestroy(), DynDebug(); +int DynInsert(), DynParanoid(); +DynPtr DynGet(); + +#endif /* _Dyn_h */ +/* DO NOT ADD ANYTHING AFTER THIS #endif */ diff --git a/libdyn/dynP.h b/libdyn/dynP.h new file mode 100644 index 0000000..1094209 --- /dev/null +++ b/libdyn/dynP.h @@ -0,0 +1,67 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the private header file. + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + + +/* + * dynP.h -- private header file included by source files for libdyn.a. + */ + +#ifndef _DynP_h +#define _DynP_h + +#include "dyn.h" + +/* + * Rep invariant: + * 1) el_size is the number of bytes per element in the object + * 2) num_el is the number of elements currently in the object. It is + * one higher than the highest index at which an element lives. + * 3) size is the number of elements the object can hold without + * resizing. num_el <= index. + * 4) inc is a multiple of the number of elements the object grows by + * each time it is reallocated. + */ + +typedef struct _DynObject { + DynPtr array; + int el_size, num_el, size, inc; + char debug, paranoid; +} DynObjectRecP, *DynObjectP; + +/* Internal functions */ +int _DynRealloc(); + +#define _DynResize(obj, req) \ + ((obj)->size > (req) ? DYN_OK : \ + (_DynRealloc((obj), (((req) - (obj)->size) / (obj)->inc) + 1))) + +/* external (C library) functions */ +#ifndef __STDC__ +extern char *malloc (); +extern char *realloc (); +extern void free (); +extern int fprintf (); +extern void bzero (); +extern void bcopy (); +#else +#include <stdio.h> +extern void *malloc (unsigned); +extern void *realloc (void *, unsigned); +extern void free (void *); +extern int fprintf (FILE *, const char *, ...); +extern void bzero (void *, unsigned); +extern void memcpy (void *, void *, unsigned); +#define bcopy(src,dest,size) memcpy(dest,src,size) +#endif + +#endif /* _DynP_h */ +/* DON'T ADD STUFF AFTER THIS #endif */ diff --git a/libdyn/dyn_append.c b/libdyn/dyn_append.c new file mode 100644 index 0000000..e4ca16b --- /dev/null +++ b/libdyn/dyn_append.c @@ -0,0 +1,43 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the source code for the function DynAppend(). + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + +#include <stdio.h> + +#include "dynP.h" + +int DynAppend(obj, els, num) + DynObjectP obj; + DynPtr els; + int num; +{ + if (obj->debug) + fprintf(stderr, "dyn: append: Writing %d bytes from %d to %d + %d\n", + obj->el_size*num, els, obj->array, obj->num_el*obj->el_size); + + if (obj->size < obj->num_el + num) { + int num_incs, ret; + + num_incs = ((obj->num_el + num - obj->size) / obj->inc) + 1; + if ((ret = _DynRealloc(obj, num_incs)) != DYN_OK) + return ret; + } + + bcopy(els, obj->array + obj->num_el*obj->el_size, obj->el_size*num); + + obj->num_el += num; + + if (obj->debug) + fprintf(stderr, "dyn: append: done.\n"); + + return DYN_OK; +} + diff --git a/libdyn/dyn_create.c b/libdyn/dyn_create.c new file mode 100644 index 0000000..16890ae --- /dev/null +++ b/libdyn/dyn_create.c @@ -0,0 +1,48 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the source code for the functions DynCreate() and + * DynDestroy(). + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + +#include <stdio.h> + +#include "dynP.h" + +#ifndef DEFAULT_INC +#define DEFAULT_INC 100 +#endif + +static int default_increment = DEFAULT_INC; + +DynObjectP DynCreate(el_size, inc) + int el_size, inc; +{ + DynObjectP obj; + + obj = (DynObjectP) malloc(sizeof(DynObjectRecP)); + if (obj == NULL) + return NULL; + + obj->array = (DynPtr) malloc(0); + obj->el_size = el_size; + obj->num_el = obj->size = 0; + obj->debug = obj->paranoid = 0; + obj->inc = (!! inc) ? inc : default_increment; + + return obj; +} + +int DynDestroy(obj) + DynObjectP obj; +{ + free(obj->array); + free(obj); + return DYN_OK; +} diff --git a/libdyn/dyn_debug.c b/libdyn/dyn_debug.c new file mode 100644 index 0000000..d3d72bb --- /dev/null +++ b/libdyn/dyn_debug.c @@ -0,0 +1,25 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the source code for the function DynDebug(). + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + +#include <stdio.h> + +#include "dynP.h" + +int DynDebug(obj, state) + DynObjectP obj; + char state; +{ + obj->debug = state; + + fprintf(stderr, "dyn: debug: Debug state set to %d.\n", state); + return DYN_OK; +} diff --git a/libdyn/dyn_delete.c b/libdyn/dyn_delete.c new file mode 100644 index 0000000..4bb1b07 --- /dev/null +++ b/libdyn/dyn_delete.c @@ -0,0 +1,77 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the source code for the function DynDelete(). + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + +#include <stdio.h> + +#include "dynP.h" + +/* + * Checkers! Get away from that "hard disk erase" button! + * (Stupid dog. He almost did it to me again ...) + */ +int DynDelete(obj, index) + DynObjectP obj; + int index; +{ + if (index < 0) { + if (obj->debug) + fprintf(stderr, "dyn: delete: bad index %d\n", index); + return DYN_BADINDEX; + } + + if (index >= obj->num_el) { + if (obj->debug) + fprintf(stderr, "dyn: delete: Highest index is %d.\n", + obj->num_el); + return DYN_BADINDEX; + } + + if (index == obj->num_el-1) { + if (obj->paranoid) { + if (obj->debug) + fprintf(stderr, "dyn: delete: last element, zeroing.\n"); + bzero(obj->array + index*obj->el_size, obj->el_size); + } + else { + if (obj->debug) + fprintf(stderr, "dyn: delete: last element, punting.\n"); + } + } + else { + if (obj->debug) + fprintf(stderr, + "dyn: delete: copying %d bytes from %d + %d to + %d.\n", + obj->el_size*(obj->num_el - index), obj->array, + (index+1)*obj->el_size, index*obj->el_size); + + bcopy(obj->array + (index+1)*obj->el_size, + obj->array + index*obj->el_size, + obj->el_size*(obj->num_el - index)); + + if (obj->paranoid) { + if (obj->debug) + fprintf(stderr, + "dyn: delete: zeroing %d bytes from %d + %d\n", + obj->el_size, obj->array, + obj->el_size*(obj->num_el - 1)); + bzero(obj->array + obj->el_size*(obj->num_el - 1), + obj->el_size); + } + } + + --obj->num_el; + + if (obj->debug) + fprintf(stderr, "dyn: delete: done.\n"); + + return DYN_OK; +} diff --git a/libdyn/dyn_header.c b/libdyn/dyn_header.c new file mode 100644 index 0000000..ffe2c92 --- /dev/null +++ b/libdyn/dyn_header.c @@ -0,0 +1,11 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the source code for the function xxx. + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ diff --git a/libdyn/dyn_insert.c b/libdyn/dyn_insert.c new file mode 100644 index 0000000..c0ed297 --- /dev/null +++ b/libdyn/dyn_insert.c @@ -0,0 +1,60 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the source code for the function DynInsert(). + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + +#include <stdio.h> +#include "dynP.h" + +int DynInsert(obj, index, els, num) + DynObjectP obj; + DynPtr els; + int index, num; +{ + int ret; + + if (index < 0 || index > obj->num_el) { + if (obj->debug) + fprintf(stderr, "dyn: insert: index %d is not in [0,%d]\n", + index, obj->num_el); + return DYN_BADINDEX; + } + + if (num < 1) { + if (obj->debug) + fprintf(stderr, "dyn: insert: cannot insert %d elements\n", + num); + return DYN_BADVALUE; + } + + if (obj->debug) + fprintf(stderr,"dyn: insert: Moving %d bytes from %d + %d to + %d\n", + (obj->num_el-index)*obj->el_size, obj->array, + obj->el_size*index, obj->el_size*(index+num)); + + if ((ret = _DynResize(obj, obj->num_el + num)) != DYN_OK) + return ret; + + bcopy(obj->array + index, obj->array + (index + num), + (obj->num_el-index)*obj->el_size); + + if (obj->debug) + fprintf(stderr, "dyn: insert: Copying %d bytes from %d to %d + %d\n", + obj->el_size*num, els, obj->array, obj->el_size*index); + + bcopy(els, obj->array + obj->el_size*index, obj->el_size*num); + + obj->num_el += num; + + if (obj->debug) + fprintf(stderr, "dyn: insert: done.\n"); + + return DYN_OK; +} diff --git a/libdyn/dyn_paranoid.c b/libdyn/dyn_paranoid.c new file mode 100644 index 0000000..86c69dd --- /dev/null +++ b/libdyn/dyn_paranoid.c @@ -0,0 +1,26 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the source code for the function DynDebug(). + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + +#include <stdio.h> + +#include "dynP.h" + +int DynParanoid(obj, state) + DynObjectP obj; + char state; +{ + obj->paranoid = state; + + if (obj->debug) + fprintf(stderr, "dyn: paranoid: Paranoia set to %d.\n", state); + return DYN_OK; +} diff --git a/libdyn/dyn_put.c b/libdyn/dyn_put.c new file mode 100644 index 0000000..396ef80 --- /dev/null +++ b/libdyn/dyn_put.c @@ -0,0 +1,85 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the source code for the functions DynGet() and DynAdd(). + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + +#include <stdio.h> + +#include "dynP.h" + +int DynPut(); + +DynPtr DynGet(obj, num) + DynObjectP obj; + int num; +{ + if (num < 0) { + if (obj->debug) + fprintf(stderr, "dyn: get: bad index %d\n", num); + return NULL; + } + + if (num >= obj->num_el) { + if (obj->debug) + fprintf(stderr, "dyn: get: highest element is %d.\n", + obj->num_el); + return NULL; + } + + if (obj->debug) + fprintf(stderr, "dyn: get: Returning address %d + %d.\n", + obj->array, obj->el_size*num); + + return (DynPtr) obj->array + obj->el_size*num; +} + +int DynAdd(obj, el) + DynObjectP obj; + DynPtr el; +{ + int ret; + + ret = DynPut(obj, el, obj->num_el); + if (ret != DYN_OK) + return ret; + + ++obj->num_el; + return ret; +} + +/* + * WARNING! There is a reason this function is not documented in the + * man page. If DynPut used to mutate already existing elements, + * everything will go fine. If it is used to add new elements + * directly, however, the state within the object (such as + * obj->num_el) will not be updated properly and many other functions + * in the library will lose. Have a nice day. + */ +int DynPut(obj, el, index) + DynObjectP obj; + DynPtr el; + int index; +{ + int ret; + + if (obj->debug) + fprintf(stderr, "dyn: put: Writing %d bytes from %d to %d + %d\n", + obj->el_size, el, obj->array, index*obj->el_size); + + if ((ret = _DynResize(obj, index)) != DYN_OK) + return ret; + + bcopy(el, obj->array + index*obj->el_size, obj->el_size); + + if (obj->debug) + fprintf(stderr, "dyn: put: done.\n"); + + return DYN_OK; +} diff --git a/libdyn/dyn_realloc.c b/libdyn/dyn_realloc.c new file mode 100644 index 0000000..bf13910 --- /dev/null +++ b/libdyn/dyn_realloc.c @@ -0,0 +1,50 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the source code for the internal function _DynRealloc(). + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + +#include <stdio.h> + +#include "dynP.h" + +/* + * Ideally, this function should not be called from outside the + * library. However, nothing will break if it is. + */ +int _DynRealloc(obj, num_incs) + DynObjectP obj; + int num_incs; +{ + DynPtr temp; + int new_size_in_bytes; + + new_size_in_bytes = obj->el_size*(obj->size + obj->inc*num_incs); + + if (obj->debug) + fprintf(stderr, + "dyn: alloc: Increasing object by %d bytes (%d incs).\n", + obj->el_size*obj->inc*num_incs, num_incs); + + temp = (DynPtr) realloc(obj->array, new_size_in_bytes); + if (temp == NULL) { + if (obj->debug) + fprintf(stderr, "dyn: alloc: Out of memory.\n"); + return DYN_NOMEM; + } + else { + obj->array = temp; + obj->size += obj->inc*num_incs; + } + + if (obj->debug) + fprintf(stderr, "dyn: alloc: done.\n"); + + return DYN_OK; +} diff --git a/libdyn/dyn_size.c b/libdyn/dyn_size.c new file mode 100644 index 0000000..773db4a --- /dev/null +++ b/libdyn/dyn_size.c @@ -0,0 +1,24 @@ +/* + * This file is part of libdyn.a, the C Dynamic Object library. It + * contains the source code for the function DynSize(). + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + +#include <stdio.h> + +#include "dynP.h" + +int DynSize(obj) + DynObjectP obj; +{ + if (obj->debug) + fprintf(stderr, "dyn: size: returning size %d.\n", obj->num_el); + + return obj->num_el; +} diff --git a/libdyn/dyntest.c b/libdyn/dyntest.c new file mode 100644 index 0000000..b08118d --- /dev/null +++ b/libdyn/dyntest.c @@ -0,0 +1,129 @@ +/* + * This file is a (rather silly) demonstration of the use of the + * C Dynamic Object library. It is a also reasonably thorough test + * of the library (except that it only tests it with one data size). + * + * There are no restrictions on this code; however, if you make any + * changes, I request that you document them so that I do not get + * credit or blame for your modifications. + * + * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) + * and MIT-Project Athena, 1989. + */ + +#include <stdio.h> + +#include "dyn.h" + +static char random_string[] = "This is a random string."; +static char insert1[] = "This will be put at the beginning."; +static char insert2[] = "(parenthetical remark!) "; +static char insert3[] = " This follows the random string."; + +main(argc, argv) + int argc; + char **argv; +{ + DynObject obj; + int i, s; + char d, *data; + + obj = DynCreate(sizeof(char), 8); + if (! obj) { + fprintf(stderr, "test: create failed.\n"); + exit(1); + } + + DynDebug(obj, 1); + DynParanoid(obj, 1); + + if (DynGet(obj, -5) || DynGet(obj, 0) || DynGet(obj, 1000)) { + fprintf(stderr, "test: Get did not fail when it should have.\n"); + exit(1); + } + + if (DynDelete(obj, -1) != DYN_BADINDEX || + DynDelete(obj, 0) != DYN_BADINDEX || + DynDelete(obj, 100) != DYN_BADINDEX) { + fprintf(stderr, "test: Delete did not fail when it should have.\n"); + exit(1); + } + + printf("Size of empty object: %d\n", DynSize(obj)); + + for (i=0; i<14; i++) { + d = (char) i; + if (DynAdd(obj, &d) != DYN_OK) { + fprintf(stderr, "test: Adding %d failed.\n", i); + exit(1); + } + } + + if (DynAppend(obj, random_string, strlen(random_string)+1) != DYN_OK) { + fprintf(stderr, "test: appending array failed.\n"); + exit(1); + } + + if (DynDelete(obj, DynHigh(obj) / 2) != DYN_OK) { + fprintf(stderr, "test: deleting element failed.\n"); + exit(1); + } + + if (DynDelete(obj, DynHigh(obj) * 2) == DYN_OK) { + fprintf(stderr, "test: delete should have failed here.\n"); + exit(1); + } + + d = 200; + if (DynAdd(obj, &d) != DYN_OK) { + fprintf(stderr, "test: Adding %d failed.\n", i); + exit(1); + } + + data = (char *) DynGet(obj, 0); + s = DynSize(obj); + for (i=0; i < s; i++) + printf("Element %d is %d.\n", i, (unsigned char) data[i]); + + data = (char *) DynGet(obj, 13); + printf("Element 13 is %d.\n", (unsigned char) *data); + + data = (char *) DynGet(obj, DynSize(obj)); + if (data) { + fprintf(stderr, "DynGet did not return NULL when it should have.\n"); + exit(1); + } + + printf("This should be the random string: \"%s\"\n", DynGet(obj, 14)); + + if (DynInsert(obj, -1, "foo", 4) != DYN_BADINDEX || + DynInsert(obj, DynSize(obj) + 1, "foo", 4) != DYN_BADINDEX || + DynInsert(obj, 0, "foo", -1) != DYN_BADVALUE) { + fprintf(stderr, "DynInsert did not fail when it should have.\n"); + exit(1); + } + + if (DynInsert(obj, DynSize(obj) - 2, insert3, strlen(insert3) + + 1) != DYN_OK) { + fprintf(stderr, "DynInsert to end failed.\n"); + exit(1); + } + + if (DynInsert(obj, 19, insert2, strlen(insert2)) != DYN_OK) { + fprintf(stderr, "DynInsert to middle failed.\n"); + exit(1); + } + + if (DynInsert(obj, 0, insert1, strlen(insert1)+1) != DYN_OK) { + fprintf(stderr, "DynInsert to start failed.\n"); + exit(1); + } + + printf("A new random string: \"%s\"\n", DynGet(obj, 14 + + strlen(insert1) + 1)); + printf("This was put at the beginning: \"%s\"\n", DynGet(obj, 0)); + + DynDestroy(obj); + + return 0; +} |