Module Name: othersrc Committed By: dholland Date: Mon Mar 4 05:47:16 UTC 2013
Modified Files: othersrc/usr.bin/dholland-make2: Makefile portable.h Added Files: othersrc/usr.bin/dholland-make2: array.c array.h Log Message: Add typesafe array code. This is the same stuff found in sail and in a few other places now; if it continues to spread we should probably put it in a library. (Although make would need its own copy anyway.) To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 othersrc/usr.bin/dholland-make2/Makefile cvs rdiff -u -r0 -r1.1 othersrc/usr.bin/dholland-make2/array.c \ othersrc/usr.bin/dholland-make2/array.h cvs rdiff -u -r1.5 -r1.6 othersrc/usr.bin/dholland-make2/portable.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: othersrc/usr.bin/dholland-make2/Makefile diff -u othersrc/usr.bin/dholland-make2/Makefile:1.2 othersrc/usr.bin/dholland-make2/Makefile:1.3 --- othersrc/usr.bin/dholland-make2/Makefile:1.2 Mon Feb 25 02:12:23 2013 +++ othersrc/usr.bin/dholland-make2/Makefile Mon Mar 4 05:47:15 2013 @@ -1,10 +1,10 @@ -# $NetBSD: Makefile,v 1.2 2013/02/25 02:12:23 dholland Exp $ +# $NetBSD: Makefile,v 1.3 2013/03/04 05:47:15 dholland Exp $ # @(#)Makefile 5.2 (Berkeley) 12/28/90 PROG= make SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \ make.c parse.c str.c suff.c targ.c trace.c var.c util.c -SRCS+= strlist.c +SRCS+= array.c strlist.c SRCS+= portable.c SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \ lstDatum.c lstDeQueue.c lstDestroy.c lstDupl.c lstEnQueue.c \ Index: othersrc/usr.bin/dholland-make2/portable.h diff -u othersrc/usr.bin/dholland-make2/portable.h:1.5 othersrc/usr.bin/dholland-make2/portable.h:1.6 --- othersrc/usr.bin/dholland-make2/portable.h:1.5 Mon Feb 25 03:39:28 2013 +++ othersrc/usr.bin/dholland-make2/portable.h Mon Mar 4 05:47:15 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: portable.h,v 1.5 2013/02/25 03:39:28 dholland Exp $ */ +/* $NetBSD: portable.h,v 1.6 2013/03/04 05:47:15 dholland Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -105,6 +105,7 @@ * MAKE_ATTR_UNUSED attribute for unused objects * MAKE_ATTR_DEAD attribute for noreturn functions * MAKE_ATTR_PRINTFLIKE attribute for printf functions + * MAKE_INLINE C99 "inline" keyword * MAKE_RCSID macro for holding rcsid strings * UNCONST(p) macro for discarding const * MIN(a, b), MAX(a, b) @@ -161,6 +162,12 @@ #define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) /* delete */ #endif +#if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__) +#define MAKE_INLINE extern inline +#else +#define MAKE_INLINE inline +#endif + #if defined(lint) #define MAKE_RCSID(str) #define MAKE_COPYRIGHT(str) Added files: Index: othersrc/usr.bin/dholland-make2/array.c diff -u /dev/null othersrc/usr.bin/dholland-make2/array.c:1.1 --- /dev/null Mon Mar 4 05:47:16 2013 +++ othersrc/usr.bin/dholland-make2/array.c Mon Mar 4 05:47:15 2013 @@ -0,0 +1,124 @@ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <string.h> +#include "portable.h" + +#define ARRAYINLINE +#include "array.h" + +struct array * +array_create(void) +{ + struct array *a; + + a = bmake_malloc(sizeof(*a)); + if (a != NULL) { + array_init(a); + } + return a; +} + +void +array_destroy(struct array *a) +{ + array_cleanup(a); + free(a); +} + +void +array_init(struct array *a) +{ + a->num = a->max = 0; + a->v = NULL; +} + +void +array_cleanup(struct array *a) +{ + arrayassert(a->num == 0); + free(a->v); +#ifdef ARRAYS_CHECKED + a->v = NULL; +#endif +} + +int +array_setsize(struct array *a, unsigned num) +{ + unsigned newmax; + void **newptr; + + if (num > a->max) { + newmax = a->max; + while (num > newmax) { + newmax = newmax ? newmax*2 : 4; + } + newptr = bmake_realloc(a->v, newmax*sizeof(*a->v)); + if (newptr == NULL) { + return -1; + } + a->v = newptr; + a->max = newmax; + } + a->num = num; + return 0; +} + +int +array_insert(struct array *a, unsigned index_) +{ + unsigned movers; + + arrayassert(a->num <= a->max); + arrayassert(index_ < a->num); + + movers = a->num - index_; + + if (array_setsize(a, a->num + 1)) { + return -1; + } + + memmove(a->v + index_+1, a->v + index_, movers*sizeof(*a->v)); + return 0; +} + +void +array_remove(struct array *a, unsigned index_) +{ + unsigned movers; + + arrayassert(a->num <= a->max); + arrayassert(index_ < a->num); + + movers = a->num - (index_ + 1); + memmove(a->v + index_, a->v + index_+1, movers*sizeof(*a->v)); + a->num--; +} Index: othersrc/usr.bin/dholland-make2/array.h diff -u /dev/null othersrc/usr.bin/dholland-make2/array.h:1.1 --- /dev/null Mon Mar 4 05:47:16 2013 +++ othersrc/usr.bin/dholland-make2/array.h Mon Mar 4 05:47:15 2013 @@ -0,0 +1,239 @@ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ARRAY_H +#define ARRAY_H + +#define ARRAYS_CHECKED + +#ifdef ARRAYS_CHECKED +#include <assert.h> +#define arrayassert assert +#else +#define arrayassert(x) ((void)(x)) +#endif + +//////////////////////////////////////////////////////////// +// type and base operations + +struct array { + void **v; + unsigned num, max; +}; + +struct array *array_create(void); +void array_destroy(struct array *); +void array_init(struct array *); +void array_cleanup(struct array *); +unsigned array_num(const struct array *); +void *array_get(const struct array *, unsigned index_); +void array_set(const struct array *, unsigned index_, void *val); +int array_setsize(struct array *, unsigned num); +int array_add(struct array *, void *val, unsigned *index_ret); +int array_insert(struct array *a, unsigned index_); +void array_remove(struct array *a, unsigned index_); + +//////////////////////////////////////////////////////////// +// inlining for base operations + +#ifndef ARRAYINLINE +#define ARRAYINLINE MAKE_INLINE +#endif + +ARRAYINLINE unsigned +array_num(const struct array *a) +{ + return a->num; +} + +ARRAYINLINE void * +array_get(const struct array *a, unsigned index_) +{ + arrayassert(index_ < a->num); + return a->v[index_]; +} + +ARRAYINLINE void +array_set(const struct array *a, unsigned index_, void *val) +{ + arrayassert(index_ < a->num); + a->v[index_] = val; +} + +ARRAYINLINE int +array_add(struct array *a, void *val, unsigned *index_ret) +{ + unsigned index_ = a->num; + if (array_setsize(a, index_+1)) { + return -1; + } + a->v[index_] = val; + if (index_ret != NULL) { + *index_ret = index_; + } + return 0; +} + +//////////////////////////////////////////////////////////// +// bits for declaring and defining typed arrays + +/* + * Usage: + * + * DECLARRAY_BYTYPE(foo, bar) declares "struct foo", which is + * an array of pointers to "bar", plus the operations on it. + * + * DECLARRAY(foo) is equivalent to DECLARRAY_BYTYPE(fooarray, struct foo). + * + * DEFARRAY_BYTYPE and DEFARRAY are the same as DECLARRAY except that + * they define the operations, and both take an extra argument INLINE. + * For C99 this should be INLINE in header files and empty in the + * master source file, the same as the usage of ARRAYINLINE above and + * in array.c. + * + * Example usage in e.g. item.h of some game: + * + * DECLARRAY_BYTYPE(stringarray, char); + * DECLARRAY(potion); + * DECLARRAY(sword); + * + * #ifndef ITEMINLINE + * #define ITEMINLINE INLINE + * #endif + * + * DEFARRAY_BYTYPE(stringarray, char, ITEMINLINE); + * DEFARRAY(potion, ITEMINLINE); + * DEFARRAY(sword, ITEMINLINE); + * + * Then item.c would do "#define ITEMINLINE" before including item.h. + */ + +#define DECLARRAY_BYTYPE(ARRAY, T) \ + struct ARRAY { \ + struct array arr; \ + }; \ + \ + struct ARRAY *ARRAY##_create(void); \ + void ARRAY##_destroy(struct ARRAY *a); \ + void ARRAY##_init(struct ARRAY *a); \ + void ARRAY##_cleanup(struct ARRAY *a); \ + unsigned ARRAY##_num(const struct ARRAY *a); \ + T *ARRAY##_get(const struct ARRAY *a, unsigned index_); \ + void ARRAY##_set(struct ARRAY *a, unsigned index_, T *val); \ + int ARRAY##_setsize(struct ARRAY *a, unsigned num); \ + int ARRAY##_add(struct ARRAY *a, T *val, unsigned *index_ret); \ + int ARRAY##_insert(struct ARRAY *a, unsigned index_); \ + void ARRAY##_remove(struct ARRAY *a, unsigned index_) + + +#define DEFARRAY_BYTYPE(ARRAY, T, INLINE) \ + INLINE void \ + ARRAY##_init(struct ARRAY *a) \ + { \ + array_init(&a->arr); \ + } \ + \ + INLINE void \ + ARRAY##_cleanup(struct ARRAY *a) \ + { \ + array_cleanup(&a->arr); \ + } \ + \ + INLINE struct \ + ARRAY *ARRAY##_create(void) \ + { \ + struct ARRAY *a; \ + \ + a = bmake_malloc(sizeof(*a)); \ + if (a == NULL) { \ + return NULL; \ + } \ + ARRAY##_init(a); \ + return a; \ + } \ + \ + INLINE void \ + ARRAY##_destroy(struct ARRAY *a) \ + { \ + ARRAY##_cleanup(a); \ + free(a); \ + } \ + \ + INLINE unsigned \ + ARRAY##_num(const struct ARRAY *a) \ + { \ + return array_num(&a->arr); \ + } \ + \ + INLINE T * \ + ARRAY##_get(const struct ARRAY *a, unsigned index_) \ + { \ + return (T *)array_get(&a->arr, index_); \ + } \ + \ + INLINE void \ + ARRAY##_set(struct ARRAY *a, unsigned index_, T *val) \ + { \ + array_set(&a->arr, index_, (void *)val); \ + } \ + \ + INLINE int \ + ARRAY##_setsize(struct ARRAY *a, unsigned num) \ + { \ + return array_setsize(&a->arr, num); \ + } \ + \ + INLINE int \ + ARRAY##_add(struct ARRAY *a, T *val, unsigned *ret) \ + { \ + return array_add(&a->arr, (void *)val, ret); \ + } \ + \ + INLINE int \ + ARRAY##_insert(struct ARRAY *a, unsigned index_) \ + { \ + return array_insert(&a->arr, index_); \ + } \ + \ + INLINE void \ + ARRAY##_remove(struct ARRAY *a, unsigned index_) \ + { \ + return array_remove(&a->arr, index_); \ + } + +#define DECLARRAY(T) DECLARRAY_BYTYPE(T##array, struct T) +#define DEFARRAY(T, INLINE) DEFARRAY_BYTYPE(T##array, struct T, INLINE) + +//////////////////////////////////////////////////////////// +// basic array types + +DECLARRAY_BYTYPE(stringarray, char); +DEFARRAY_BYTYPE(stringarray, char, ARRAYINLINE); + +#endif /* ARRAY_H */