bjaspan@athena.mit.edu (Barr3y Jaspan) (04/09/90)
This is "release 1" of the Dynamic Object library I posted here a few months ago. (I am considering the original posting a "pre-release"). The README file has all the details. Barry Jaspan, MIT-Project Athena bjaspan@athena.mit.edu ----------- snip snip ------------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 1)." # Contents: Makefile README dyn.h dyn.man dynP.h dyn_append.c # dyn_create.c dyn_debug.c dyn_delete.c dyn_header.c dyn_insert.c # dyn_paranoid.c dyn_put.c dyn_realloc.c dyn_size.c test.c # Wrapped by bjaspan@bill-the-cat on Mon Apr 9 10:27:08 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(1305 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# This file is part of libdyn.a, the C Dynamic Object library. It X# contains the Makefile. X# X# There are no restrictions on this code; however, if you make any X# changes, I request that you document them so that I do not get X# credit or blame for your modifications. X# X# Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X# and MIT-Project Athena, 1989. X XDESTDIR = /afs/.athena.mit.edu/contrib/sipb/$(MACHINE)lib XCC = cc XCFLAGS = -g XDEST = libdyn.a X XSRCS = dyn_create.c dyn_put.c dyn_debug.c dyn_delete.c dyn_size.c \ X dyn_append.c dyn_realloc.c dyn_paranoid.c dyn_insert.c XOBJS = dyn_create.o dyn_put.o dyn_debug.o dyn_delete.o dyn_size.o \ X dyn_append.o dyn_realloc.o dyn_paranoid.o dyn_insert.o XHDRS = dyn.h dynP.h X X$(DEST): $(OBJS) X rm -f $(DEST) X ar rc $(DEST) $(OBJS) X ranlib $(DEST) X Xinstall: X make $(INSTFLAGS) DEST="libdyn.a" CFLAGS="-g" clean libdyn.a X cp libdyn.a $(DESTDIR) X ranlib $(DESTDIR)/libdyn.a X make $(INSTFLAGS) DEST="libdyn_p.a" CFLAGS="-g -pg" clean libdyn_p.a X cp libdyn_p.a $(DESTDIR) X ranlib $(DESTDIR)/libdyn_p.a X Xall: $(DEST) test X Xtest: $(DEST) test.o X $(CC) -o test test.o $(DEST) X Xsaber: X #load $(SRCS) X Xclean: X rm -f $(OBJS) $(DEST) test *~ X Xdepend: X makedepend -- $(CLFAGS) -- $(HDRS) $(SRCS) X X# DO NOT DELETE THIS LINE -- make depend depends on it. END_OF_FILE if test 1305 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1503 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' Xlibdyn.a -- Release 1.0 X XA C Dynamic Object is an array that takes care of resizing itself as Xelements are added and deleted from it. It can be of any type for Xwhich sizeof is defined and for which an address of a variable of that Xtype can be passed to a function. X XTo build libdyn.a, simply type "make depend all" (if you don't have Xthe program makedepend, of course, leave out the "depend" part). If Xyour system's bcopy() cannot handle overlapping regions, you'll need Xto write one that can. (Left as an excercise for the reader..) X XThe library should compile and work without modification on a vast Xnumber of systems. It only uses 5 external functions: malloc, Xrealloc, free, bcopy, and fprintf (to stderr). Of these, only bcopy Xshould need to be changed for other systems (such as MS-DOS) and it Xcould probably be done with a -D flag to the compiler. X XThe test/demo program is built by "make all". This program produces Xthe library's debugging output (to stderr) as well as some of its own Xoutput (to stdout). X XThe library has been tested (with test.c) on a VAX VSII, VAXstation X3100, DECstation 3100, and IBM RT all running BSD4.3 (except for the XDECstation, which was running Ultrix V2.1). X XAn earlier version of this library was posted to alt.sources. This Xversion contains one new function (DynInsert) and slightly cleaner Xcode, but no bugfixes (no bugs were found). X XAuthor: Barr3y Jaspan, Student Information Processing Board (SIPB) and XMIT-Project Athena, bjaspan@athena.mit.edu, 1990 END_OF_FILE if test 1503 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'dyn.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn.h'\" else echo shar: Extracting \"'dyn.h'\" \(1087 characters\) sed "s/^X//" >'dyn.h' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the public header file. X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X X/* X * dyn.h -- header file to be included by programs linking against X * libdyn.a. X */ X X#ifndef _Dyn_h X#define _Dyn_h X X#ifdef notdef Xtypedef void *DynPtr; X#else Xtypedef char *DynPtr; X#endif X Xtypedef struct _DynObject DynObjectRec, *DynObject; X X/* Function macros */ X#define DynHigh(obj) (DynSize(obj) - 1) X#define DynLow(obj) (0) X X/* Return status codes */ X#define DYN_OK -1000 X#define DYN_NOMEM -1001 X#define DYN_BADINDEX -1002 X#define DYN_BADVALUE -1003 X X/* Function declarations */ XDynObject DynCreate(); Xint DynAdd(), DynDelete(), DynDestroy(), DynDebug(); Xint DynInsert(), DynParanoid(); XDynPtr DynGet(); X X#endif /* _Dyn_h */ X/* DO NOT ADD ANYTHING AFTER THIS #endif */ END_OF_FILE if test 1087 -ne `wc -c <'dyn.h'`; then echo shar: \"'dyn.h'\" unpacked with wrong size! fi # end of 'dyn.h' fi if test -f 'dyn.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn.man'\" else echo shar: Extracting \"'dyn.man'\" \(4993 characters\) sed "s/^X//" >'dyn.man' <<'END_OF_FILE' X.TH DYN 3M "15 March 1990" X X.SH NAME Xdyn \- the C Dynamic Object library X X.SH DESCRIPTION X XA C Dynamic Object is an array that takes care of resizing Xitself as you add and delete elements from it. It can be of any type Xfor which sizeof is defined and for which an address of a variable of Xthat type can be passed to a function. The library containing the Xfunctions described below is called X.IR libdyn.a , Xand the necessary declarations to use them are in X.RI < dyn.h >. X.PP XA DynObject is actually a structure that contains an array and a Xcouple of integers to maintain necessary state information. When a XDyn function is said to operate on "the object" or "the array", it is Xoperating on the array stored in the structure while at the same time Xupdating internal state information. X X.SH LIST OF FUNCTIONS X.nf XDynObject DynCreate(size, increment) X int size, increment; X.fi X.PP X.IR Requires : X.I size Xand X.I increment Xare greater than zero. X.PP X.IR Effects : XCreates a new DynObject that will store elements of size X.I size Xand will allocate memory in blocks large enough to hold exactly X.I increment Xelements. For example, if you are storing 8-byte double Xprecision numbers and X.I increment Xis 5, each 5th element you add to the object will cause it to request X40 more bytes (8 * 5) from the operating system. If X.I increment Xis zero, a default value is used (currently 100). This is the only Xtime the programmer deals with a dynamic object's memory allocation. X.PP X.IR Returns : X.B DynCreate Xreturns the new DynObject, or NULL if there is insufficient memory. X.PP X.nf Xint DynDestroy(obj) X DynObject obj; X.fi X.PP X.IR Modifies : Xobj X.PP X.IR Effects : XFrees all memory associated with X.IR obj . XThe results of calling any Dyn function on a destroyed object are Xundefined (except for DynCreate, which resets the object). X.PP X.IR Returns : X.B DynDestroy Xreturns DYN_OK. X.PP X.nf Xint DynAdd(obj, el) X DynObject obj; X DynPtr el; X.fi X.PP X.IR Modifies : Xobj X.PP X.IR Effects : XAdds the element pointed to by X.I el Xto the object X.IR obj , Xresizing the object if necessary. XThe new element becomes the last element in obj's array. X.PP X.IR Returns : X.B DynAdd Xreturns DYN_OK on success or DYN_NOMEM if there is insufficient Xmemory. X.PP X.nf Xint DynInsert(obj, index, els, num) X DynObject obj; X DynPtr els; X int index, num; X.fi X.PP X.IR Modifies : Xobj X.PP X.IR Effects : XInserts the array of X.I num Xelements, pointed to by X.IR els, Xinto the object X.I obj Xstarting at the array location X.IR index , Xresizing the object if necessary. Order is preserved; if you have the Xarray "1 2 3 4 5" and insert "10 11 12" at the third position, you Xwill have the array "1 2 10 11 12 3 4 5". X.PP X.IR Returns : X.B DynInsert Xreturns DYN_BADINDEX if X.I index Xis not between 0 and X.BR DynSize ( obj ) ; XDYN_BADVALUE if X.I num Xis less than 1; DYN_NOMEM if there is insufficient memory. X.PP X.nf Xint DynGet(obj, index) X DynObject obj; X int index; X.fi X.PP X.IR Effects : XReturns the address of the element X.I index Xin the array of X.IR obj . XThis pointer can be treated as a normal array of the type specified to X.BR DynCreate . XThe order of elements in this array is the order in which they were Xadded to the object. The returned pointer is guaranteed to be valid Xonly until obj is modified. X.PP X.IR Returns : X.B DynGet Xreturns NULL if X.I index Xis larger than the number of elements in the array of less than zero. X.PP X.nf Xint DynDelete(obj, index) X DynObject obj; X int index; X.fi X.PP X.IR Modifies : Xobj X.PP X.IR Effects : XThe element X.I index Xis deleted from the object X.IR obj . XNote that the element is actually removed permanently from the array. XIf you have the array "1 2 3 4 5" and delete the third element, you Xwill have the array "1 2 4 5". The order of elements in not affected. X.PP X.IR Returns : X.B DynDelete Xwill return DYN_OK on success or DYN_BADINDEX if the element X.I index Xdoes not exist in the array or is less than zero. X.PP X.nf Xint DynSize(obj) X DynObject obj; X.fi X.PP X.IR Effects : XReturns the number of elements in the object X.IR obj . X.PP X.nf Xint DynHigh(obj) X DynObject obj; X.fi X.PP X.IR Effects : XReturns the index of the highest element in the object X.IR obj . XIn this version, X.B DynHigh Xis macro that expands to X.B DynSize X- 1. X.PP X.nf Xint DynLow(obj) X DynObject obj; X.fi X.PP X.IR Effects : XReturns the index of the lowest element in the object X.IR obj . XIn this version, X.B DynLow Xis macro that expands to 0. X.PP X.nf Xint DynDebug(obj, state) X DynObject obj; X int state; X.fi X.PP X.IR Modifies : Xobj X.PP X.IR Effects : XSets the debugging state of X.I obj Xto X.I state Xand prints a message on stderr saying what state debugging was set to. XAny non-zero value for X.I state Xturns debugging ``on''. When debugging is on, all Dyn functions will Xproduce (hopefully useful) output describing what is going on on Xstderr. X.PP X.IR Returns : X.B DynDebug Xreturns DYN_OK. X.SH AUTHOR XBarr3y Jaspan, Student Information Processing Board (SIPB) and XMIT-Project Athena, bjaspan@athena.mit.edu END_OF_FILE if test 4993 -ne `wc -c <'dyn.man'`; then echo shar: \"'dyn.man'\" unpacked with wrong size! fi # end of 'dyn.man' fi if test -f 'dynP.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dynP.h'\" else echo shar: Extracting \"'dynP.h'\" \(1344 characters\) sed "s/^X//" >'dynP.h' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the private header file. X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X X/* X * dynP.h -- private header file included by source files for libdyn.a. X */ X X#ifndef _DynP_h X#define _DynP_h X X#include "dyn.h" X X/* X * Rep invariant: X * 1) el_size is the number of bytes per element in the object X * 2) num_el is the number of elements currently in the object. It is X * one higher than the highest index at which an element lives. X * 3) size is the number of elements the object can hold without X * resizing. num_el <= index. X * 4) inc is a multiple of the number of elements the object grows by X * each time it is reallocated. X */ X Xtypedef struct _DynObject { X DynPtr array; X int el_size, num_el, size, inc; X char debug, paranoid; X} DynObjectRecP, *DynObjectP; X X/* Internal functions */ Xint _DynRealloc(); X X#define _DynResize(obj, req) \ X ((obj)->size > (req) ? DYN_OK : \ X (_DynRealloc((obj), (((req) - (obj)->size) / (obj)->inc) + 1))) X X#endif /* _DynP_h */ X/* DON'T ADD STUFF AFTER THIS #endif */ END_OF_FILE if test 1344 -ne `wc -c <'dynP.h'`; then echo shar: \"'dynP.h'\" unpacked with wrong size! fi # end of 'dynP.h' fi if test -f 'dyn_append.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn_append.c'\" else echo shar: Extracting \"'dyn_append.c'\" \(1100 characters\) sed "s/^X//" >'dyn_append.c' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the source code for the function DynAppend(). X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X#include <stdio.h> X X#include "dynP.h" X Xint DynAppend(obj, els, num) X DynObjectP obj; X DynPtr els; X int num; X{ X if (obj->debug) X fprintf(stderr, "dyn: append: Writing %d bytes from %d to %d + %d\n", X obj->el_size*num, els, obj->array, obj->num_el*obj->el_size); X X if (obj->size < obj->num_el + num) { X int num_incs, ret; X X num_incs = ((obj->num_el + num - obj->size) / obj->inc) + 1; X if ((ret = _DynRealloc(obj, num_incs)) != DYN_OK) X return ret; X } X X bcopy(els, obj->array + obj->num_el*obj->el_size, obj->el_size*num); X X obj->num_el += num; X X if (obj->debug) X fprintf(stderr, "dyn: append: done.\n"); X X return DYN_OK; X} X END_OF_FILE if test 1100 -ne `wc -c <'dyn_append.c'`; then echo shar: \"'dyn_append.c'\" unpacked with wrong size! fi # end of 'dyn_append.c' fi if test -f 'dyn_create.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn_create.c'\" else echo shar: Extracting \"'dyn_create.c'\" \(1067 characters\) sed "s/^X//" >'dyn_create.c' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the source code for the functions DynCreate() and X * DynDestroy(). X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X#include <stdio.h> X X#include "dynP.h" X X#ifndef DEFAULT_INC X#define DEFAULT_INC 100 X#endif X Xstatic int default_increment = DEFAULT_INC; X XDynObjectP DynCreate(el_size, inc) X int el_size, inc; X{ X DynObjectP obj; X X obj = (DynObjectP) malloc(sizeof(DynObjectRecP)); X if (obj == NULL) X return NULL; X X obj->array = (DynPtr) malloc(0); X obj->el_size = el_size; X obj->num_el = obj->size = 0; X obj->debug = obj->paranoid = 0; X obj->inc = (!! inc) ? inc : default_increment; X X return obj; X} X Xint DynDestroy(obj) X DynObjectP obj; X{ X free(obj->array); X free(obj); X return DYN_OK; X} END_OF_FILE if test 1067 -ne `wc -c <'dyn_create.c'`; then echo shar: \"'dyn_create.c'\" unpacked with wrong size! fi # end of 'dyn_create.c' fi if test -f 'dyn_debug.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn_debug.c'\" else echo shar: Extracting \"'dyn_debug.c'\" \(639 characters\) sed "s/^X//" >'dyn_debug.c' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the source code for the function DynDebug(). X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X#include <stdio.h> X X#include "dynP.h" X Xint DynDebug(obj, state) X DynObjectP obj; X char state; X{ X obj->debug = state; X X fprintf(stderr, "dyn: debug: Debug state set to %d.\n", state); X return DYN_OK; X} END_OF_FILE if test 639 -ne `wc -c <'dyn_debug.c'`; then echo shar: \"'dyn_debug.c'\" unpacked with wrong size! fi # end of 'dyn_debug.c' fi if test -f 'dyn_delete.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn_delete.c'\" else echo shar: Extracting \"'dyn_delete.c'\" \(1929 characters\) sed "s/^X//" >'dyn_delete.c' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the source code for the function DynDelete(). X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X#include <stdio.h> X X#include "dynP.h" X Xint DynDelete(obj, index) X DynObjectP obj; X int index; X{ X if (index < 0) { X if (obj->debug) X fprintf(stderr, "dyn: delete: bad index %d\n", index); X return DYN_BADINDEX; X } X X if (index >= obj->num_el) { X if (obj->debug) X fprintf(stderr, "dyn: delete: Highest index is %d.\n", X obj->num_el); X return DYN_BADINDEX; X } X X if (index == obj->num_el-1) { X if (obj->paranoid) { X if (obj->debug) X fprintf(stderr, "dyn: delete: last element, zeroing.\n"); X bzero(obj->array + index*obj->el_size, obj->el_size); X } X else { X if (obj->debug) X fprintf(stderr, "dyn: delete: last element, punting.\n"); X } X } X else { X if (obj->debug) X fprintf(stderr, X "dyn: delete: copying %d bytes from %d + %d to + %d.\n", X obj->el_size*(obj->num_el - index), obj->array, X (index+1)*obj->el_size, index*obj->el_size); X X bcopy(obj->array + (index+1)*obj->el_size, X obj->array + index*obj->el_size, X obj->el_size*(obj->num_el - index)); X X if (obj->paranoid) { X if (obj->debug) X fprintf(stderr, X "dyn: delete: zeroing %d bytes from %d + %d\n", X obj->el_size, obj->array, X obj->el_size*(obj->num_el - 1)); X bzero(obj->array + obj->el_size*(obj->num_el - 1), X obj->el_size); X } X } X X --obj->num_el; X X if (obj->debug) X fprintf(stderr, "dyn: delete: done.\n"); X X return DYN_OK; X} END_OF_FILE if test 1929 -ne `wc -c <'dyn_delete.c'`; then echo shar: \"'dyn_delete.c'\" unpacked with wrong size! fi # end of 'dyn_delete.c' fi if test -f 'dyn_header.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn_header.c'\" else echo shar: Extracting \"'dyn_header.c'\" \(414 characters\) sed "s/^X//" >'dyn_header.c' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the source code for the function xxx. X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ END_OF_FILE if test 414 -ne `wc -c <'dyn_header.c'`; then echo shar: \"'dyn_header.c'\" unpacked with wrong size! fi # end of 'dyn_header.c' fi if test -f 'dyn_insert.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn_insert.c'\" else echo shar: Extracting \"'dyn_insert.c'\" \(1633 characters\) sed "s/^X//" >'dyn_insert.c' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the source code for the function DynInsert(). X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X#include <stdio.h> X#include "dynP.h" X Xint DynInsert(obj, index, els, num) X DynObjectP obj; X DynPtr els; X int index, num; X{ X int ret; X X if (index < 0 || index > obj->num_el) { X if (obj->debug) X fprintf(stderr, "dyn: insert: index %d is not in [0,%d]\n", X index, obj->num_el); X return DYN_BADINDEX; X } X X if (num < 1) { X if (obj->debug) X fprintf(stderr, "dyn: insert: cannot insert %d elements\n", X num); X return DYN_BADVALUE; X } X X if (obj->debug) X fprintf(stderr,"dyn: insert: Moving %d bytes from %d + %d to + %d\n", X (obj->num_el-index)*obj->el_size, obj->array, X obj->el_size*index, obj->el_size*(index+num)); X X if ((ret = _DynResize(obj, obj->num_el + num)) != DYN_OK) X return ret; X X bcopy(obj->array + index, obj->array + (index + num), X (obj->num_el-index)*obj->el_size); X X if (obj->debug) X fprintf(stderr, "dyn: insert: Copying %d bytes from %d to %d + %d\n", X obj->el_size*num, els, obj->array, obj->el_size*index); X X bcopy(els, obj->array + obj->el_size*index, obj->el_size*num); X X obj->num_el += num; X X if (obj->debug) X fprintf(stderr, "dyn: insert: done.\n"); X X return DYN_OK; X} END_OF_FILE if test 1633 -ne `wc -c <'dyn_insert.c'`; then echo shar: \"'dyn_insert.c'\" unpacked with wrong size! fi # end of 'dyn_insert.c' fi if test -f 'dyn_paranoid.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn_paranoid.c'\" else echo shar: Extracting \"'dyn_paranoid.c'\" \(664 characters\) sed "s/^X//" >'dyn_paranoid.c' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the source code for the function DynDebug(). X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X#include <stdio.h> X X#include "dynP.h" X Xint DynParanoid(obj, state) X DynObjectP obj; X char state; X{ X obj->paranoid = state; X X if (obj->debug) X fprintf(stderr, "dyn: paranoid: Paranoia set to %d.\n", state); X return DYN_OK; X} END_OF_FILE if test 664 -ne `wc -c <'dyn_paranoid.c'`; then echo shar: \"'dyn_paranoid.c'\" unpacked with wrong size! fi # end of 'dyn_paranoid.c' fi if test -f 'dyn_put.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn_put.c'\" else echo shar: Extracting \"'dyn_put.c'\" \(1850 characters\) sed "s/^X//" >'dyn_put.c' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the source code for the functions DynGet() and DynAdd(). X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X#include <stdio.h> X X#include "dynP.h" X Xstatic int DynPut(); X XDynPtr DynGet(obj, num) X DynObjectP obj; X int num; X{ X if (num < 0) { X if (obj->debug) X fprintf(stderr, "dyn: get: bad index %d\n", num); X return NULL; X } X X if (num >= obj->num_el) { X if (obj->debug) X fprintf(stderr, "dyn: get: highest element is %d.\n", X obj->num_el); X return NULL; X } X X if (obj->debug) X fprintf(stderr, "dyn: get: Returning address %d + %d.\n", X obj->array, obj->el_size*num); X X return (DynPtr) obj->array + obj->el_size*num; X} X Xint DynAdd(obj, el) X DynObjectP obj; X DynPtr el; X{ X int ret; X X ret = DynPut(obj, el, obj->num_el); X if (ret != DYN_OK) X return ret; X X ++obj->num_el; X return ret; X} X X/* X * This function is not exported because if index is large enough to X * cause two or more increments to be allocated the rep invariant X * is not preserved. X */ Xstatic int DynPut(obj, el, index) X DynObjectP obj; X DynPtr el; X int index; X{ X int ret; X X if (obj->debug) X fprintf(stderr, "dyn: put: Writing %d bytes from %d to %d + %d\n", X obj->el_size, el, obj->array, index*obj->el_size); X X if ((ret = _DynResize(obj, index)) != DYN_OK) X return ret; X X bcopy(el, obj->array + index*obj->el_size, obj->el_size); X X if (obj->debug) X fprintf(stderr, "dyn: put: done.\n"); X X return DYN_OK; X} END_OF_FILE if test 1850 -ne `wc -c <'dyn_put.c'`; then echo shar: \"'dyn_put.c'\" unpacked with wrong size! fi # end of 'dyn_put.c' fi if test -f 'dyn_realloc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn_realloc.c'\" else echo shar: Extracting \"'dyn_realloc.c'\" \(1300 characters\) sed "s/^X//" >'dyn_realloc.c' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the source code for the internal function _DynRealloc(). X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X#include <stdio.h> X X#include "dynP.h" X X/* X * Ideally, this function should not be called from outside the X * library. However, nothing will break if it is. X */ Xint _DynRealloc(obj, num_incs) X DynObjectP obj; X int num_incs; X{ X DynPtr temp; X int new_size_in_bytes; X X new_size_in_bytes = obj->el_size*(obj->size + obj->inc*num_incs); X X if (obj->debug) X fprintf(stderr, X "dyn: alloc: Increasing object by %d bytes (%d incs).\n", X obj->el_size*obj->inc*num_incs, num_incs); X X temp = (DynPtr) realloc(obj->array, new_size_in_bytes); X if (temp == NULL) { X if (obj->debug) X fprintf(stderr, "dyn: alloc: Out of memory.\n"); X return DYN_NOMEM; X } X else { X obj->array = temp; X obj->size += obj->inc*num_incs; X } X X if (obj->debug) X fprintf(stderr, "dyn: alloc: done.\n"); X X return DYN_OK; X} END_OF_FILE if test 1300 -ne `wc -c <'dyn_realloc.c'`; then echo shar: \"'dyn_realloc.c'\" unpacked with wrong size! fi # end of 'dyn_realloc.c' fi if test -f 'dyn_size.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dyn_size.c'\" else echo shar: Extracting \"'dyn_size.c'\" \(615 characters\) sed "s/^X//" >'dyn_size.c' <<'END_OF_FILE' X/* X * This file is part of libdyn.a, the C Dynamic Object library. It X * contains the source code for the function DynSize(). X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X#include <stdio.h> X X#include "dynP.h" X Xint DynSize(obj) X DynObjectP obj; X{ X if (obj->debug) X fprintf(stderr, "dyn: size: returning size %d.\n", obj->num_el); X X return obj->num_el; X} END_OF_FILE if test 615 -ne `wc -c <'dyn_size.c'`; then echo shar: \"'dyn_size.c'\" unpacked with wrong size! fi # end of 'dyn_size.c' fi if test -f 'test.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'test.c'\" else echo shar: Extracting \"'test.c'\" \(3603 characters\) sed "s/^X//" >'test.c' <<'END_OF_FILE' X/* X * This file is a (rather silly) demonstration of the use of the X * C Dynamic Object library. It is a also reasonably thorough test X * of the library (except that it only tests it with one data size). X * X * There are no restrictions on this code; however, if you make any X * changes, I request that you document them so that I do not get X * credit or blame for your modifications. X * X * Written by Barr3y Jaspan, Student Information Processing Board (SIPB) X * and MIT-Project Athena, 1989. X */ X X#include <stdio.h> X X#include "dyn.h" X Xstatic char random_string[] = "This is a random string."; Xstatic char insert1[] = "This will be put at the beginning."; Xstatic char insert2[] = "(parenthetical remark!) "; Xstatic char insert3[] = " This follows the random string."; X Xmain(argc, argv) X int argc; X char **argv; X{ X DynObject obj; X int i, s; X char d, *data; X X obj = DynCreate(sizeof(char), 8); X if (! obj) { X fprintf(stderr, "test: create failed.\n"); X exit(1); X } X X DynDebug(obj, 1); X DynParanoid(obj, 1); X X if (DynGet(obj, -5) || DynGet(obj, 0) || DynGet(obj, 1000)) { X fprintf(stderr, "test: Get did not fail when it should have.\n"); X exit(1); X } X X if (DynDelete(obj, -1) != DYN_BADINDEX || X DynDelete(obj, 0) != DYN_BADINDEX || X DynDelete(obj, 100) != DYN_BADINDEX) { X fprintf(stderr, "test: Delete did not fail when it should have.\n"); X exit(1); X } X X printf("Size of empty object: %d\n", DynSize(obj)); X X for (i=0; i<14; i++) { X d = (char) i; X if (DynAdd(obj, &d) != DYN_OK) { X fprintf(stderr, "test: Adding %d failed.\n", i); X exit(1); X } X } X X if (DynAppend(obj, random_string, strlen(random_string)+1) != DYN_OK) { X fprintf(stderr, "test: appending array failed.\n"); X exit(1); X } X X if (DynDelete(obj, DynHigh(obj) / 2) != DYN_OK) { X fprintf(stderr, "test: deleting element failed.\n"); X exit(1); X } X X if (DynDelete(obj, DynHigh(obj) * 2) == DYN_OK) { X fprintf(stderr, "test: delete should have failed here.\n"); X exit(1); X } X X d = 200; X if (DynAdd(obj, &d) != DYN_OK) { X fprintf(stderr, "test: Adding %d failed.\n", i); X exit(1); X } X X data = (char *) DynGet(obj, 0); X s = DynSize(obj); X for (i=0; i < s; i++) X printf("Element %d is %d.\n", i, (unsigned char) data[i]); X X data = (char *) DynGet(obj, 13); X printf("Element 13 is %d.\n", (unsigned char) *data); X X data = (char *) DynGet(obj, DynSize(obj)); X if (data) { X fprintf(stderr, "DynGet did not return NULL when it should have.\n"); X exit(1); X } X X printf("This should be the random string: \"%s\"\n", DynGet(obj, 14)); X X if (DynInsert(obj, -1, "foo", 4) != DYN_BADINDEX || X DynInsert(obj, DynSize(obj) + 1, "foo", 4) != DYN_BADINDEX || X DynInsert(obj, 0, "foo", -1) != DYN_BADVALUE) { X fprintf(stderr, "DynInsert did not fail when it should have.\n"); X exit(1); X } X X if (DynInsert(obj, DynSize(obj) - 2, insert3, strlen(insert3) + X 1) != DYN_OK) { X fprintf(stderr, "DynInsert to end failed.\n"); X exit(1); X } X X if (DynInsert(obj, 19, insert2, strlen(insert2)) != DYN_OK) { X fprintf(stderr, "DynInsert to middle failed.\n"); X exit(1); X } X X if (DynInsert(obj, 0, insert1, strlen(insert1)+1) != DYN_OK) { X fprintf(stderr, "DynInsert to start failed.\n"); X exit(1); X } X X printf("A new random string: \"%s\"\n", DynGet(obj, 14 + X strlen(insert1) + 1)); X printf("This was put at the beginning: \"%s\"\n", DynGet(obj, 0)); X X DynDestroy(obj); X X return 0; X} END_OF_FILE if test 3603 -ne `wc -c <'test.c'`; then echo shar: \"'test.c'\" unpacked with wrong size! fi # end of 'test.c' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0