summaryrefslogtreecommitdiff
path: root/libdyn
diff options
context:
space:
mode:
authorGravatar Kenneth G Raeburn <raeburn@mit.edu>1990-11-16 06:41:56 +0000
committerGravatar Kenneth G Raeburn <raeburn@mit.edu>1990-11-16 06:41:56 +0000
commite17eedd8e03e6e429d6d0587baf055fe3ff4f29c (patch)
treecfe5308b659f1633f381e7d31bca01f6f14b3c06 /libdyn
parent35c501612c73a9e46b211223438d6acf6d3fef4f (diff)
Initial revision
Diffstat (limited to 'libdyn')
-rw-r--r--libdyn/Imakefile48
-rw-r--r--libdyn/README32
-rw-r--r--libdyn/dyn.3233
-rw-r--r--libdyn/dyn.h47
-rw-r--r--libdyn/dynP.h67
-rw-r--r--libdyn/dyn_append.c43
-rw-r--r--libdyn/dyn_create.c48
-rw-r--r--libdyn/dyn_debug.c25
-rw-r--r--libdyn/dyn_delete.c77
-rw-r--r--libdyn/dyn_header.c11
-rw-r--r--libdyn/dyn_insert.c60
-rw-r--r--libdyn/dyn_paranoid.c26
-rw-r--r--libdyn/dyn_put.c85
-rw-r--r--libdyn/dyn_realloc.c50
-rw-r--r--libdyn/dyn_size.c24
-rw-r--r--libdyn/dyntest.c129
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;
+}