this commit includes all the changes on the OV_9510_INTEGRATION and
authorMarc Horowitz <marc@mit.edu>
Mon, 22 Jul 1996 21:11:35 +0000 (21:11 +0000)
committerMarc Horowitz <marc@mit.edu>
Mon, 22 Jul 1996 21:11:35 +0000 (21:11 +0000)
OV_MERGE branches.  This includes, but is not limited to, the new openvision
admin system, and major changes to gssapi to add functionality, and bring
the implementation in line with rfc1964.  before committing, the
code was built and tested for netbsd and solaris.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@8775 dc483132-0cff-0310-8789-dd5450dbe970

12 files changed:
src/kadmin/server/ChangeLog [new file with mode: 0644]
src/util/dyn/Makefile.ov [new file with mode: 0644]
src/util/dyn/dyn.h [new file with mode: 0644]
src/util/dyn/dyn.man [new file with mode: 0644]
src/util/dyn/dynP.h [new file with mode: 0644]
src/util/dyn/dyn_create.c [new file with mode: 0644]
src/util/dyn/dyn_debug.c [new file with mode: 0644]
src/util/dyn/dyn_delete.c [new file with mode: 0644]
src/util/dyn/dyn_header.c [new file with mode: 0644]
src/util/dyn/dyn_put.c [new file with mode: 0644]
src/util/dyn/dyn_size.c [new file with mode: 0644]
src/util/dyn/test.c [new file with mode: 0644]

diff --git a/src/kadmin/server/ChangeLog b/src/kadmin/server/ChangeLog
new file mode 100644 (file)
index 0000000..07ffdd7
--- /dev/null
@@ -0,0 +1,10 @@
+Mon Jul 22 04:16:15 1996  Marc Horowitz  <marc@mit.edu>
+
+       * ovsec_kadmd.c (main): open the socket with SO_REUSEADDR.  The
+       old server did this, and the tests require it on some platforms.
+
+Tue Jul  9 16:04:53 1996  Marc Horowitz  <marc@mit.edu>
+
+       * kadm_rpc_svc.c: renamed <ovsec_admin/foo.h> to <kadm5/foo.h>
+       * configure.in: cosmetic changes.
+       * Makefile.in: complete rewrite.
diff --git a/src/util/dyn/Makefile.ov b/src/util/dyn/Makefile.ov
new file mode 100644 (file)
index 0000000..8128312
--- /dev/null
@@ -0,0 +1,35 @@
+# This file is part of libdyn.a, the C Dynamic Object library.  It
+# contains the Imakefile.
+#
+# 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.
+
+TOP    := ../..
+include $(TOP)/config.mk/template
+
+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 \
+       dyn_initzero.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 \
+       dyn_initzero.o
+HDRS   := dyn.h # dynP.h
+
+CFLAGS := $(CFLAGS) $(D_POSIX)
+
+LIB    := libdyn.a
+
+expand StageLibrary
+expand StageIncludes
+
+# PROG := test
+# OBJS := test.o
+# LIBS := libdyn.a
+# 
+# expand Program
+# 
+expand Depend
diff --git a/src/util/dyn/dyn.h b/src/util/dyn/dyn.h
new file mode 100644 (file)
index 0000000..5ca59ba
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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
+
+typedef char *DynPtr;
+typedef struct _DynObject {
+     DynPtr    array;
+     int       el_size, num_el, size, inc;
+     int       debug, paranoid, initzero;
+} 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 */
+#ifdef __STDC__
+#define P(args) args
+#else
+#define P(args)
+#endif /* __STDC__ */
+
+DynObject DynCreate P((int el_size, int inc)), DynCopy P((DynObject obj));
+int DynDestroy P((DynObject obj)), DynRelease P((DynObject obj));
+int DynAdd P((DynObject obj, void *el));
+int DynPut P((DynObject obj, void *el, int idx));
+int DynInsert P((DynObject obj, int idx, void *els, int num));
+int DynDelete P((DynObject obj, int idx));
+DynPtr DynGet P((DynObject obj, int num));
+DynPtr DynArray P((DynObject obj));
+int DynDebug P((DynObject obj, int state));
+int DynParanoid P((DynObject obj, int state));
+int DynInitzero P((DynObject obj, int state));
+int DynSize P((DynObject obj));
+int DynCapacity P((DynObject obj));
+
+#undef P
+
+#endif /* _Dyn_h */
+/* DO NOT ADD ANYTHING AFTER THIS #endif */
diff --git a/src/util/dyn/dyn.man b/src/util/dyn/dyn.man
new file mode 100644 (file)
index 0000000..3e27459
--- /dev/null
@@ -0,0 +1,303 @@
+.TH DYN 3 "07 December 1992"
+
+.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
+.IR size .
+If
+.I increment
+is positive, the object will allocate memory in blocks large enough to
+hold exactly
+.I increment
+elements; if it is negative, the object will allocate memory by
+doubling in size each time more space is needed, starting with an
+initial size of
+.RI - increment .
+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 -4, adding the first element causes the object to request 32 bytes
+(4 * 8); adding the fifth element requests 32 more bytes for a total
+of 8 elements; adding the ninth element requests 64 more bytes, for a
+total of 16 elements.  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 DynRelease(obj)
+       DynObject obj;
+.fi
+.PP
+.IR Modifies :
+obj
+.PP
+.IR Effects :
+Frees the memory used to store
+.IR obj 's
+internal state, but leaves the object's array intact.  This is useful
+when you want to use a DynObject to create an arbitrary sized array,
+but then do not want to deal with the DynObject abstraction or having
+to remember to free the object later.
+.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 DynArray(obj)
+       DynObject obj;
+.fi
+.PP
+.IR Effects :
+Returns the address of 
+.IR obj 's
+array.  This function is equivalent to
+.BR DynGet (
+.I obj
+, 0).
+.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 DynCapacity(obj)
+       DynObject obj;
+.fi
+.PP
+.IR Effects :
+Returns the number of elements that
+.IR obj .
+can store without resizing.
+.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 DynParanoid(obj, state)
+   DynObjectP obj;
+   char state;
+.fi
+.PP
+.IR Modified :
+obj
+.OO
+.IR Effects :
+Sets the paranoid state of
+.I obj
+to 
+.IR state .
+When paranoid mode is on, all data deleted from the object is erased
+with bzero.
+.PP
+.IR Returns :
+.B DynParanoid
+returns DYN_OK.
+.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/src/util/dyn/dynP.h b/src/util/dyn/dynP.h
new file mode 100644 (file)
index 0000000..0f20ba7
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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"
+#ifdef USE_DBMALLOC
+#include <sys/stdtypes.h>
+#include <malloc.h>
+#endif
+
+/*
+ * 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 DynObjectRecP, *DynObjectP;
+
+/* Internal functions */
+int _DynRealloc(), _DynResize();
+
+#endif /* _DynP_h */
+/* DON'T ADD STUFF AFTER THIS #endif */
diff --git a/src/util/dyn/dyn_create.c b/src/util/dyn/dyn_create.c
new file mode 100644 (file)
index 0000000..6f3aa50
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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 <stdlib.h>
+#include <string.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;
+
+#ifdef USE_DBMALLOC
+     obj->array = (DynPtr) malloc(1);
+#else
+     obj->array = (DynPtr) malloc(0);
+#endif
+     obj->el_size = el_size;
+     obj->num_el = obj->size = 0;
+     obj->debug = obj->paranoid = 0;
+     obj->inc = (!! inc) ? inc : default_increment;
+
+     return obj;
+}
+
+DynObjectP DynCopy(obj)
+   DynObjectP obj;
+{
+     DynObjectP obj1;
+     
+     obj1 = (DynObjectP) malloc(sizeof(DynObjectRecP));
+     if (obj1 == NULL)
+         return NULL;
+
+     obj1->el_size = obj->el_size;
+     obj1->num_el = obj->num_el;
+     obj1->size = obj->size;
+     obj1->inc = obj->inc;
+     obj1->debug = obj->debug;
+     obj1->paranoid = obj->paranoid;
+     obj1->initzero = obj->initzero;
+     obj1->array = (char *) malloc(obj1->el_size * obj1->size);
+     if (obj1->array == NULL) {
+         free(obj1);
+         return NULL;
+     }
+     memcpy(obj->array, obj1->array, 
+           (size_t) (obj1->el_size * obj1->size));
+
+     return obj1;
+}
+
+int DynDestroy(obj)
+   DynObjectP obj;
+{
+     if (obj->paranoid) {
+         if (obj->debug)
+              fprintf(stderr, "dyn: destroy: zeroing %d bytes from %d.\n",
+                      obj->el_size * obj->size, obj->array);
+         memset(obj->array, 0, obj->el_size * obj->size);
+     }
+     free(obj->array);
+     free(obj);
+     return DYN_OK;
+}
+
+int DynRelease(obj)
+   DynObjectP obj;
+{
+     if (obj->debug)
+         fprintf(stderr, "dyn: release: freeing object structure.\n");
+     free(obj);
+     return DYN_OK;
+}
diff --git a/src/util/dyn/dyn_debug.c b/src/util/dyn/dyn_debug.c
new file mode 100644 (file)
index 0000000..4e3e179
--- /dev/null
@@ -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;
+   int state;
+{
+     obj->debug = state;
+
+     fprintf(stderr, "dyn: debug: Debug state set to %d.\n", state);
+     return DYN_OK;
+}
diff --git a/src/util/dyn/dyn_delete.c b/src/util/dyn/dyn_delete.c
new file mode 100644 (file)
index 0000000..df76af2
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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, idx)
+   DynObjectP obj;
+   int idx;
+{
+     if (idx < 0) {
+         if (obj->debug)
+              fprintf(stderr, "dyn: delete: bad index %d\n", idx);
+         return DYN_BADINDEX;
+     }
+     
+     if (idx >= obj->num_el) {
+         if (obj->debug)
+              fprintf(stderr, "dyn: delete: Highest index is %d.\n",
+                      obj->num_el);
+         return DYN_BADINDEX;
+     }
+
+     if (idx == obj->num_el-1) {
+         if (obj->paranoid) {
+              if (obj->debug)
+                   fprintf(stderr, "dyn: delete: last element, zeroing.\n");
+              memset(obj->array + idx*obj->el_size, 0, 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 - idx), obj->array,
+                      (idx+1)*obj->el_size, idx*obj->el_size);
+         
+#ifdef HAVE_MEMMOVE
+         memmove(obj->array + idx*obj->el_size,
+                 obj->array + (idx+1)*obj->el_size,
+                 obj->el_size*(obj->num_el - idx));
+#else
+         bcopy(obj->array + (idx+1)*obj->el_size,
+                 obj->array + idx*obj->el_size,
+                 obj->el_size*(obj->num_el - idx));
+#endif
+         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));
+              memset(obj->array + obj->el_size*(obj->num_el - 1), 0,
+                    obj->el_size);
+         }
+     }
+     
+     --obj->num_el;
+     
+     if (obj->debug)
+         fprintf(stderr, "dyn: delete: done.\n");
+
+     return DYN_OK;
+}
diff --git a/src/util/dyn/dyn_header.c b/src/util/dyn/dyn_header.c
new file mode 100644 (file)
index 0000000..ffe2c92
--- /dev/null
@@ -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/src/util/dyn/dyn_put.c b/src/util/dyn/dyn_put.c
new file mode 100644 (file)
index 0000000..5018253
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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"
+
+DynPtr DynArray(obj)
+   DynObjectP obj;
+{
+     if (obj->debug)
+         fprintf(stderr, "dyn: array: returning array pointer %d.\n",
+                 obj->array);
+
+     return obj->array;
+}
+
+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;
+   void *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_in, idx)
+   DynObjectP obj;
+   void *el_in;
+   int idx;
+{
+     DynPtr el = (DynPtr) el_in;
+     int ret;
+     
+     if (obj->debug)
+         fprintf(stderr, "dyn: put: Writing %d bytes from %d to %d + %d\n",
+                 obj->el_size, el, obj->array, idx*obj->el_size);
+
+     if ((ret = _DynResize(obj, idx)) != DYN_OK)
+         return ret;
+
+#ifdef HAVE_MEMMOVE
+     memmove(obj->array + idx*obj->el_size, el, obj->el_size);
+#else
+     bcopy(el, obj->array + idx*obj->el_size, obj->el_size);
+#endif     
+
+     if (obj->debug)
+         fprintf(stderr, "dyn: put: done.\n");
+     
+     return DYN_OK;
+}
diff --git a/src/util/dyn/dyn_size.c b/src/util/dyn/dyn_size.c
new file mode 100644 (file)
index 0000000..b0f497a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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;
+}
+
+int DynCapacity(obj)
+   DynObjectP obj;
+{
+     if (obj->debug)
+         fprintf(stderr, "dyn: capacity: returning cap of %d.\n", obj->size);
+
+     return obj->size;
+}
diff --git a/src/util/dyn/test.c b/src/util/dyn/test.c
new file mode 100644 (file)
index 0000000..a7a7414
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * 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>
+#ifdef USE_DBMALLOC
+#include <sys/stdtypes.h>
+#include <malloc.h>
+#endif
+
+#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;
+
+#ifdef _DEBUG_MALLOC_INC
+     union dbmalloptarg arg;
+     unsigned long hist1, hist2, o_size, c_size;
+#endif
+
+#ifdef _DEBUG_MALLOC_INC
+     arg.i = 0;
+     dbmallopt(MALLOC_ZERO, &arg);
+     dbmallopt(MALLOC_REUSE, &arg);
+
+     o_size = malloc_inuse(&hist1);
+#endif 
+
+     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);
+
+#ifdef _DEBUG_MALLOC_INC
+     c_size = malloc_inuse(&hist2);
+     if (o_size != c_size) {
+         printf("\n\nIgnore a single unfreed malloc segment "
+                "(stdout buffer).\n\n");
+         malloc_list(2, hist1, hist2);
+     }
+#endif
+     
+
+     return 0;
+}