2
* This file is the collected implementation of libdyn.a, the C
3
* Dynamic Object library. It contains everything.
5
* There are no restrictions on this code; however, if you make any
6
* changes, I request that you document them so that I do not get
7
* credit or blame for your modifications.
9
* Written by Barr3y Jaspan, Student Information Processing Board (SIPB)
10
* and MIT-Project Athena, 1989.
12
* 2002-07-17 Collected full implementation into one source file for
13
* easy inclusion into the one library still dependent on
14
* libdyn. Assume memmove. Old ChangeLog appended.
24
/* old dyn_append.c */
26
* This file is part of libdyn.a, the C Dynamic Object library. It
27
* contains the source code for the function DynAppend().
31
* Made obsolete by DynInsert, now just a convenience function.
33
int DynAppend(obj, els, num)
38
return DynInsert(obj, DynSize(obj), els, num);
42
/* old dyn_create.c */
44
* This file is part of libdyn.a, the C Dynamic Object library. It
45
* contains the source code for the functions DynCreate() and
50
#define DEFAULT_INC 100
53
static int default_increment = DEFAULT_INC;
55
DynObjectP DynCreate(el_size, inc)
60
obj = (DynObjectP) malloc(sizeof(DynObjectRecP));
64
obj->array = (DynPtr) malloc(1);
65
if (obj->array == NULL) {
71
obj->el_size = el_size;
72
obj->num_el = obj->size = 0;
73
obj->debug = obj->paranoid = 0;
74
obj->inc = (inc) ? inc : default_increment;
80
DynObjectP DynCopy(obj)
85
obj1 = (DynObjectP) malloc(sizeof(DynObjectRecP));
89
obj1->el_size = obj->el_size;
90
obj1->num_el = obj->num_el;
91
obj1->size = obj->size;
93
obj1->debug = obj->debug;
94
obj1->paranoid = obj->paranoid;
95
obj1->initzero = obj->initzero;
96
obj1->array = (char *) malloc((size_t) (obj1->el_size * obj1->size));
97
if (obj1->array == NULL) {
101
memcpy(obj1->array, obj->array,
102
(size_t) (obj1->el_size * obj1->size));
108
/*@only@*/DynObjectP obj;
112
fprintf(stderr, "dyn: destroy: zeroing %d bytes from %p.\n",
113
obj->el_size * obj->size, obj->array);
114
memset(obj->array, 0, (size_t) (obj->el_size * obj->size));
125
fprintf(stderr, "dyn: release: freeing object structure.\n");
131
/* old dyn_debug.c */
133
* This file is part of libdyn.a, the C Dynamic Object library. It
134
* contains the source code for the function DynDebug().
137
int DynDebug(obj, state)
143
fprintf(stderr, "dyn: debug: Debug state set to %d.\n", state);
148
/* old dyn_delete.c */
150
* This file is part of libdyn.a, the C Dynamic Object library. It
151
* contains the source code for the function DynDelete().
155
* Checkers! Get away from that "hard disk erase" button!
156
* (Stupid dog. He almost did it to me again ...)
158
int DynDelete(obj, idx)
164
fprintf(stderr, "dyn: delete: bad index %d\n", idx);
168
if (idx >= obj->num_el) {
170
fprintf(stderr, "dyn: delete: Highest index is %d.\n",
175
if (idx == obj->num_el-1) {
178
fprintf(stderr, "dyn: delete: last element, zeroing.\n");
179
memset(obj->array + idx*obj->el_size, 0, (size_t) obj->el_size);
183
fprintf(stderr, "dyn: delete: last element, punting.\n");
189
"dyn: delete: copying %d bytes from %p + %d to + %d.\n",
190
obj->el_size*(obj->num_el - idx), obj->array,
191
(idx+1)*obj->el_size, idx*obj->el_size);
193
memmove(obj->array + idx*obj->el_size,
194
obj->array + (idx+1)*obj->el_size,
195
(size_t) obj->el_size*(obj->num_el - idx));
199
"dyn: delete: zeroing %d bytes from %p + %d\n",
200
obj->el_size, obj->array,
201
obj->el_size*(obj->num_el - 1));
202
memset(obj->array + obj->el_size*(obj->num_el - 1), 0,
203
(size_t) obj->el_size);
210
fprintf(stderr, "dyn: delete: done.\n");
216
/* old dyn_initzero.c */
218
* This file is part of libdyn.a, the C Dynamic Object library. It
219
* contains the source code for the function DynInitZero().
222
int DynInitzero(obj, state)
226
obj->initzero = state;
229
fprintf(stderr, "dyn: initzero: initzero set to %d.\n", state);
234
/* old dyn_insert.c */
236
* This file is part of libdyn.a, the C Dynamic Object library. It
237
* contains the source code for the function DynInsert().
240
int DynInsert(obj, idx, els_in, num)
245
DynPtr els = (DynPtr) els_in;
248
if (idx < 0 || idx > obj->num_el) {
250
fprintf(stderr, "dyn: insert: index %d is not in [0,%d]\n",
257
fprintf(stderr, "dyn: insert: cannot insert %d elements\n",
263
fprintf(stderr,"dyn: insert: Moving %d bytes from %p + %d to + %d\n",
264
(obj->num_el-idx)*obj->el_size, obj->array,
265
obj->el_size*idx, obj->el_size*(idx+num));
267
if ((ret = _DynResize(obj, obj->num_el + num)) != DYN_OK)
269
memmove(obj->array + obj->el_size*(idx + num),
270
obj->array + obj->el_size*idx,
271
(size_t) ((obj->num_el-idx)*obj->el_size));
274
fprintf(stderr, "dyn: insert: Copying %d bytes from %p to %p + %d\n",
275
obj->el_size*num, els, obj->array, obj->el_size*idx);
277
memmove(obj->array + obj->el_size*idx, els, (size_t) (obj->el_size*num));
281
fprintf(stderr, "dyn: insert: done.\n");
287
/* old dyn_paranoid.c */
289
* This file is part of libdyn.a, the C Dynamic Object library. It
290
* contains the source code for the function DynDebug().
293
int DynParanoid(obj, state)
297
obj->paranoid = state;
300
fprintf(stderr, "dyn: paranoid: Paranoia set to %d.\n", state);
307
* This file is part of libdyn.a, the C Dynamic Object library. It
308
* contains the source code for the functions DynGet() and DynAdd().
315
fprintf(stderr, "dyn: array: returning array pointer %p.\n",
321
DynPtr DynGet(obj, num)
327
fprintf(stderr, "dyn: get: bad index %d\n", num);
331
if (num >= obj->num_el) {
333
fprintf(stderr, "dyn: get: highest element is %d.\n",
339
fprintf(stderr, "dyn: get: Returning address %p + %d.\n",
340
obj->array, obj->el_size*num);
342
return (DynPtr) obj->array + obj->el_size*num;
351
ret = DynPut(obj, el, obj->num_el);
360
* WARNING! There is a reason this function is not documented in the
361
* man page. If DynPut used to mutate already existing elements,
362
* everything will go fine. If it is used to add new elements
363
* directly, however, the state within the object (such as
364
* obj->num_el) will not be updated properly and many other functions
365
* in the library will lose. Have a nice day.
367
int DynPut(obj, el_in, idx)
372
DynPtr el = (DynPtr) el_in;
376
fprintf(stderr, "dyn: put: Writing %d bytes from %p to %p + %d\n",
377
obj->el_size, el, obj->array, idx*obj->el_size);
379
if ((ret = _DynResize(obj, idx)) != DYN_OK)
382
memmove(obj->array + idx*obj->el_size, el, (size_t) obj->el_size);
385
fprintf(stderr, "dyn: put: done.\n");
391
/* old dyn_realloc.c */
393
* This file is part of libdyn.a, the C Dynamic Object library. It
394
* contains the source code for the internal function _DynRealloc().
398
* Resize the array so that element req exists.
400
int _DynResize(obj, req)
408
else if (obj->inc > 0)
409
return _DynRealloc(obj, (req - obj->size) / obj->inc + 1);
421
return _DynRealloc(obj, size);
426
* Resize the array by num_incs units. If obj->inc is positive, this
427
* means make it obj->inc*num_incs elements larger. If obj->inc is
428
* negative, this means make the array num_incs elements long.
430
* Ideally, this function should not be called from outside the
431
* library. However, nothing will break if it is.
433
int _DynRealloc(obj, num_incs)
438
int new_size_in_bytes;
441
new_size_in_bytes = obj->el_size*(obj->size + obj->inc*num_incs);
443
new_size_in_bytes = obj->el_size*num_incs;
447
"dyn: alloc: Increasing object by %d bytes (%d incs).\n",
448
new_size_in_bytes - obj->el_size*obj->size,
451
temp = (DynPtr) realloc(obj->array, (size_t) new_size_in_bytes);
454
fprintf(stderr, "dyn: alloc: Out of memory.\n");
460
obj->size += obj->inc*num_incs;
462
obj->size = num_incs;
466
fprintf(stderr, "dyn: alloc: done.\n");
474
* This file is part of libdyn.a, the C Dynamic Object library. It
475
* contains the source code for the function DynSize().
482
fprintf(stderr, "dyn: size: returning size %d.\n", obj->num_el);
491
fprintf(stderr, "dyn: capacity: returning cap of %d.\n", obj->size);
496
/* Old change log, as it relates to source code; build system stuff
499
2001-10-09 Ken Raeburn <raeburn@mit.edu>
501
* dyn.h, dynP.h: Make prototypes unconditional. Don't define
504
2001-04-25 Ezra Peisach <epeisach@mit.edu>
506
* dyn.h: Lclint annotate functions.
508
* dyn_create.c (DynCreate): Do not assume that malloc(0) is valid
509
and returns a valid pointer. Fix memory leak if malloc fails.
511
* dyn_realloc.c (_DynResize): Turn off warning of shifting a
514
Thu Nov 9 15:31:31 2000 Ezra Peisach <epeisach@mit.edu>
516
* dyn_create.c (DynCopy): Arguments to memcpy were reversed. Found
517
while playing with lclint.
519
2000-11-09 Ezra Peisach <epeisach@mit.edu>
521
* dyn_create.c, dyn_delete.c, dyn_insert.c, dyn_put.c,
522
dyn_realloc.c: Cast arguments to malloc(), realloc(), memmove() to
525
* dynP.h: Provide full prototypes for _DynRealloc() and _DynResize().
527
* dyn.h: Add prototype for DynAppend.
529
2000-06-29 Ezra Peisach <epeisach@mit.edu>
531
* dyn_insert.c, dyn_put.c: Include string.h for memmove prototype.
533
2000-06-28 Ezra Peisach <epeisach@mit.edu>
535
* dyn_create.c, dyn_delete.c, dyn_insert.c, dyn_put.c: Use %p
536
format for displaying pointers.
538
2000-06-26 Ezra Peisach <epeisach@mit.edu>
540
* dyn_realloc.c: Remove unused variable.
542
Sat Dec 6 22:50:03 1997 Ezra Peisach <epeisach@mit.edu>
544
* dyn_delete.c: Include <string.h>
546
Mon Jul 22 21:37:52 1996 Ezra Peisach <epeisach@mit.edu>
548
* dyn.h: If __STDC__ is not defined, generate prototypes implying
549
functions and not variables.
551
Mon Jul 22 04:20:48 1996 Marc Horowitz <marc@mit.edu>
553
* dyn_insert.c (DynInsert): what used to be #ifdef POSIX, should
554
be #ifdef HAVE_MEMMOVE