[alt.sources] A Dynamic Object library for C

bjaspan@athena.mit.edu (Barr3y Jaspan) (01/16/90)

The following is a library that implements "dynamic objects" in C.  A
dynamic object is basically an array that resizes itself automatically
as elements are added to it (thus freeing the programmer from having to
deal with it).  It is similar the GNU's opstack code, except my library
isn't covered by the gnu license.  The code is not complicated, and you
could probably hit ten people with a rope on a crowded street that could
have written it as well.  However, I actually got around to doing it
right and testing and documenting it.

#! /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_create.c
#   dyn_debug.c dyn_delete.c dyn_put.c dyn_size.c test.c
# Wrapped by bjaspan@steve-dallas on Mon Jan 15 19:17:43 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'\" \(804 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
XCC	= cc
XCFLAGS	= -O
XLDFLAGS	=
XDEST	= libdyn.a
X
XSRCS	= dyn_create.c dyn_put.c dyn_debug.c dyn_delete.c dyn_size.c
XOBJS	= dyn_create.o dyn_put.o dyn_debug.o dyn_delete.o dyn_size.o
XHDRS	= dyn.h dynP.h
X
Xall: $(DEST)
X
X$(DEST): $(OBJS)
X	rm -f $(DEST)
X	ar rc $(DEST) $(OBJS)
X	ranlib $(DEST)
X
Xclean:
X	rm -f $(OBJS) $(DEST) *~
X
Xdepend:
X	makedepend -- $(CLFAGS) -- $(HDRS) $(SRCS)
X
X# DO NOT DELETE THIS LINE -- make depend depends on it.
END_OF_FILE
if test 804 -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'\" \(1376 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
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 left-copying overlapping regions,
Xadd -DLOCAL_BCOPY to the CFLAGS macro in the Makefile.  (Look at the
Xsource code for dyn_delete.c if you don't understand that.)
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
XTo build the test/demo program, do "cc -L. -o test test.c -ldyn".
XThis program produces the library's debugging output (to stderr) as
Xwell as some of its own output (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
XBarr3y Jaspan, Student Information Processing Board (SIPB) and
XMIT-Project Athena, bjaspan@athena.mit.edu, 1989
END_OF_FILE
if test 1376 -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'\" \(949 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
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
X/* Function declarations */
XDynObject 	DynCreate();
Xint		DynAdd(), DynDelete(), DynDestroy(), DynDebug();
Xchar		*DynGet();
X
X#endif /* _Dyn_h */
X/* DO NOT ADD ANYTHING AFTER THIS #endif */
END_OF_FILE
if test 949 -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'\" \(4567 characters\)
sed "s/^X//" >'dyn.man' <<'END_OF_FILE'
X.TH DYN 3M "22 October 1989"
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	char *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 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 BUGS
XDynGet should return DYN_BADINDEX instead of NULL but since it can
Xalso return a pointer..
X.PP
XThe entire library should work in terms of void * instead of char *,
Xbut some compilers don't understand the ANSI types.
X.SH AUTHOR
XBarr3y Jaspan, Student Information Processing Board (SIPB) and
XMIT-Project Athena, bjaspan@athena.mit.edu
END_OF_FILE
if test 4567 -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'\" \(744 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#define ARRAY	char *
X
Xtypedef struct _DynObject {
X     ARRAY	array;
X     int	el_size, num_el, size, inc, debug;
X} Int_DynObjectRec, *Int_DynObject;
X
X#endif /* _DynP_h */
X/* DON'T ADD STUFF AFTER THIS #endif */
END_OF_FILE
if test 744 -ne `wc -c <'dynP.h'`; then
    echo shar: \"'dynP.h'\" unpacked with wrong size!
fi
# end of 'dynP.h'
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'\" \(1057 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
XInt_DynObject DynCreate(el_size, inc)
X   int	el_size, inc;
X{
X     Int_DynObject	obj;
X
X     obj = (Int_DynObject) malloc(sizeof(Int_DynObjectRec));
X     if (obj == NULL)
X	  return NULL;
X
X     obj->array = (ARRAY) malloc(0);
X     obj->el_size = el_size;
X     obj->num_el = obj->size = obj->debug = 0;
X     obj->inc = (!! inc) ? inc : default_increment;
X
X     return obj;
X}
X
Xint DynDestroy(obj)
X   Int_DynObject	obj;
X{
X     free(obj->array);
X     free(obj);
X     return DYN_OK;
X}
END_OF_FILE
if test 1057 -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'\" \(643 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   Int_DynObject	obj;
X   int 		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 643 -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'\" \(1595 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
X#ifdef LOCAL_BCOPY
Xstatic bcopy(src, dst, length)
X   char	*src, *dest;
X   int	length;
X{
X     while (length--)
X	  *dst++ = *src++;
X}
X#endif
X
Xint DynDelete(obj, index)
X   Int_DynObject	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->debug)
X	       fprintf(stderr, "dyn: delete: last element, doing nothing.\n");
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     
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 1595 -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_put.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dyn_put.c'\"
else
echo shar: Extracting \"'dyn_put.c'\" \(2680 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 _DynRealloc(), DynPut();
X
Xchar *DynGet(obj, num)
X   Int_DynObject	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 obj->array + obj->el_size*num;
X}
X
Xint DynAdd(obj, el)
X   Int_DynObject	obj;
X   char		*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   Int_DynObject	obj;
X   char		*el;
X   int		index;
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 (obj->size <= index) {
X	  int	num_incs, ret;
X
X	  num_incs = ((index - obj->size) / obj->inc) + 1;
X	  if ((ret = _DynRealloc(obj, num_incs)) != DYN_OK)
X	       return ret;
X     }
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}
X
Xstatic int _DynRealloc(obj, num_incs)
X   Int_DynObject	obj;
X   int		num_incs;
X{
X     ARRAY	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 = (ARRAY) 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 2680 -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_size.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dyn_size.c'\"
else
echo shar: Extracting \"'dyn_size.c'\" \(618 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   Int_DynObject	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 618 -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'\" \(2228 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
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
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 (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, 14);
X     if (data) {
X	  fprintf(stderr, "DynGet did not return NULL when it should have.\n");
X	  exit(1);
X     }
X
X     DynDestroy(obj);
X
X     return 0;
X}
END_OF_FILE
if test 2228 -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
 


Barry Jaspan, MIT-Project Athena
bjaspan@athena.mit.edu