/* $Id$ */ #include #include #include #include "cmsys.h" #define chartoupper(c) ((c >= 'a' && c <= 'z') ? c+'A'-'a' : c) void Vector_init(struct Vector *self, const int size) { assert(size != 0); self->size = size; self->length = 0; self->capacity = 0; self->base = NULL; self->constant = false; } void Vector_init_const(struct Vector *self, char * base, const int length, const int size) { assert(size != 0); self->size = size; self->length = length; self->capacity = 0; self->base = base; self->constant = true; } void Vector_delete(struct Vector *self) { self->length = 0; self->capacity = 0; if (self->base && !self->constant) free(self->base); self->base = NULL; self->constant = false; } void Vector_clear(struct Vector *self, const int size) { Vector_delete(self); Vector_init(self, size); } int Vector_length(const struct Vector *self) { return self->length; } void Vector_resize(struct Vector *self, const int length) { int capacity = length * self->size; assert(!self->constant); #define MIN_CAPACITY 4096 if (capacity == 0) { if (self->base) free(self->base); self->base = NULL; self->capacity = 0; } else { int old_capacity = self->capacity; assert(capacity > 0); if (self->capacity == 0) self->capacity = MIN_CAPACITY; //if (self->capacity > capacity && self->capacity > MIN_CAPACITY) // self->capacity /= 2; while (self->capacity < capacity) self->capacity *= 2; if (old_capacity != self->capacity || self->base == NULL) { char *tmp = (char *)realloc(self->base, self->capacity); assert(tmp); self->base = tmp; } } } void Vector_add(struct Vector *self, const char *name) { assert(!self->constant); Vector_resize(self, self->length+1); strlcpy(self->base + self->size * self->length, name, self->size); self->length++; } const char* Vector_get(const struct Vector *self, const int idx) { assert(0 <= idx && idx < self->length); return self->base + self->size * idx; } int Vector_MaxLen(const struct Vector *list, const int offset, const int count) { int i, j; int maxlen = 0; for(i=offset, j=count; ilength && j > 0; i++, j--) { int len = strlen(list->base + list->size * i); if (len > maxlen) maxlen = len; } assert(maxlen <= list->size); return maxlen; } int Vector_match(const struct Vector *src, struct Vector *dst, const int key, const int pos) { int uckey, lckey; int i; Vector_clear(dst, src->size); uckey = chartoupper(key); if (key >= 'A' && key <= 'Z') lckey = key | 0x20; else lckey = key; for (i=0; ilength; i++) { int ch = src->base[src->size * i + pos]; if (ch == lckey || ch == uckey) Vector_add(dst, src->base + src->size * i); } return dst->length; } void Vector_sublist(const struct Vector *src, struct Vector *dst, const char *tag) { int i; int len; Vector_clear(dst, src->size); len = strlen(tag); for (i=0; ilength; i++) if (len==0 || strncasecmp(src->base + src->size * i, tag, len)==0) Vector_add(dst, src->base + src->size * i); } int Vector_remove(struct Vector *self, const char *name) { int i; assert(!self->constant); for (i=0; ilength; i++) if (strcasecmp(self->base + self->size * i, name) == 0) { strlcpy(self->base + self->size * i, self->base + self->size * (self->length-1), self->size); self->length--; Vector_resize(self, self->length); return 1; } return 0; } int Vector_search(const struct Vector *self, const char *name) { int i; for (i=0; ilength; i++) if (strcasecmp(self->base + self->size * i, name) == 0) return i; return -1; }