diff options
Diffstat (limited to 'src/cmd/gc/array.c')
| -rw-r--r-- | src/cmd/gc/array.c | 129 | 
1 files changed, 129 insertions, 0 deletions
| diff --git a/src/cmd/gc/array.c b/src/cmd/gc/array.c new file mode 100644 index 000000000..5e53c1ff0 --- /dev/null +++ b/src/cmd/gc/array.c @@ -0,0 +1,129 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include <u.h> +#include <libc.h> +#include "go.h" + +enum { +	DEFAULTCAPACITY = 16, +}; + +struct Array +{ +	int32	length;  // number of elements +	int32	size;  // element size +	int32	capacity;  // size of data in elements +	char	*data;  // element storage +}; + +Array* +arraynew(int32 capacity, int32 size) +{ +	Array *result; + +	if(capacity < 0) +		fatal("arraynew: capacity %d is not positive", capacity); +	if(size < 0) +		fatal("arraynew: size %d is not positive\n", size); +	result = malloc(sizeof(*result)); +	if(result == nil) +		fatal("arraynew: malloc failed\n"); +	result->length = 0; +	result->size = size; +	result->capacity = capacity == 0 ? DEFAULTCAPACITY : capacity; +	result->data = malloc(result->capacity * result->size); +	if(result->data == nil) +		fatal("arraynew: malloc failed\n"); +	return result; +} + +void +arrayfree(Array *array) +{ +	if(array == nil) +		return; +	free(array->data); +	free(array); +} + +int32 +arraylength(Array *array) +{ +	return array->length; +} + +void* +arrayget(Array *array, int32 index) +{ +	if(array == nil) +		fatal("arrayget: array is nil\n"); +	if(index < 0 || index >= array->length) +		fatal("arrayget: index %d is out of bounds for length %d\n", index, array->length); +	return array->data + index * array->size; +} + +void +arrayset(Array *array, int32 index, void *element) +{ +	if(array == nil) +		fatal("arrayset: array is nil\n"); +	if(element == nil) +		fatal("arrayset: element is nil\n"); +	if(index < 0 || index >= array->length) +		fatal("arrayget: index %d is out of bounds for length %d\n", index, array->length); +	memmove(array->data + index * array->size, element, array->size); +} + +static void +ensurecapacity(Array *array, int32 capacity) +{ +	int32 newcapacity; +	char *newdata; + +	if(array == nil) +		fatal("ensurecapacity: array is nil\n"); +	if(capacity < 0) +		fatal("ensurecapacity: capacity %d is not positive", capacity); +	if(capacity >= array->capacity) { +		newcapacity = capacity + (capacity >> 1); +		newdata = realloc(array->data, newcapacity * array->size); +		if(newdata == nil) +			fatal("ensurecapacity: realloc failed\n"); +		array->capacity = newcapacity; +		array->data = newdata; +	} +} + +void +arrayadd(Array *array, void *element) +{ +	if(array == nil) +		fatal("arrayset: array is nil\n"); +	if(element == nil) +		fatal("arrayset: element is nil\n"); +	ensurecapacity(array, array->length + 1); +	array->length++; +	arrayset(array, array->length - 1, element); +} + +int32 +arrayindexof(Array *array, void *element) +{ +	void *p; +	int32 i; + +	for(i = 0; i < array->length; i++) { +		p = arrayget(array, i); +		if(memcmp(p, &element, array->size) == 0) +			return i; +	} +	return -1; +} + +void +arraysort(Array *array, int (*cmp)(const void*, const void*)) +{ +	qsort(array->data, array->length, array->size, cmp); +} | 
