summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwens <wens@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-06-15 22:34:06 +0800
committerwens <wens@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-06-15 22:34:06 +0800
commitddcba43d911f6a5faae9130073820e4442b9d4c8 (patch)
treefb06899708c9cc92654fcca8d298ef61419f886f
parent2b17144356fc625165400e7a856ad76cae4bf4b2 (diff)
downloadpttbbs-ddcba43d911f6a5faae9130073820e4442b9d4c8.tar
pttbbs-ddcba43d911f6a5faae9130073820e4442b9d4c8.tar.gz
pttbbs-ddcba43d911f6a5faae9130073820e4442b9d4c8.tar.bz2
pttbbs-ddcba43d911f6a5faae9130073820e4442b9d4c8.tar.lz
pttbbs-ddcba43d911f6a5faae9130073820e4442b9d4c8.tar.xz
pttbbs-ddcba43d911f6a5faae9130073820e4442b9d4c8.tar.zst
pttbbs-ddcba43d911f6a5faae9130073820e4442b9d4c8.zip
General vector-like list
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4357 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--common/sys/Makefile2
-rw-r--r--common/sys/vector.c161
-rw-r--r--include/cmsys.h21
3 files changed, 183 insertions, 1 deletions
diff --git a/common/sys/Makefile b/common/sys/Makefile
index e0fec71f..574ab582 100644
--- a/common/sys/Makefile
+++ b/common/sys/Makefile
@@ -5,7 +5,7 @@ MKPIC:=no
SRCROOT= ../..
.include "$(SRCROOT)/pttbbs.mk"
-SRCS:= file.c lock.c log.c net.c sort.c string.c time.c crypt.c record.c osdep.c
+SRCS:= file.c lock.c log.c net.c sort.c string.c time.c crypt.c record.c osdep.c vector.c
LIB:= cmsys
install:
diff --git a/common/sys/vector.c b/common/sys/vector.c
new file mode 100644
index 00000000..e5ed9346
--- /dev/null
+++ b/common/sys/vector.c
@@ -0,0 +1,161 @@
+/* $Id$ */
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#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;
+}
+
+void
+Vector_delete(struct Vector *self)
+{
+ self->length = 0;
+ self->capacity = 0;
+ if (self->base)
+ free(self->base);
+ self->base = NULL;
+}
+
+void
+Vector_clear(struct Vector *self, const int size)
+{
+ Vector_delete(self);
+ Vector_init(self, size);
+}
+
+int
+Vector_length(struct Vector *self)
+{
+ return self->length;
+}
+
+void
+Vector_resize(struct Vector *self, const int length)
+{
+ int capacity = length * self->size;
+#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)
+{
+ Vector_resize(self, self->length+1);
+ strlcpy(self->base + self->size * self->length, name, self->size);
+ self->length++;
+}
+
+const char*
+Vector_get(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;
+ int maxlen = 0;
+
+ for(i=offset; i<list->length; i++) {
+ 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; i<src->length; 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(struct Vector *src, struct Vector *dst, const char *tag)
+{
+ int i;
+ int len;
+ Vector_clear(dst, src->size);
+
+ len = strlen(tag);
+ for (i=0; i<src->length; 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;
+ for (i=0; i<self->length; 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; i<self->length; i++)
+ if (strcasecmp(self->base + self->size * i, name) == 0)
+ return 1;
+ return 0;
+}
+
diff --git a/include/cmsys.h b/include/cmsys.h
index 1e866630..2a219324 100644
--- a/include/cmsys.h
+++ b/include/cmsys.h
@@ -147,4 +147,25 @@ int delete_records(const char *fpath, size_t size, int id, size_t num);
#define delete_record(fpath, size, id) delete_records(fpath, size, id, 1)
int apply_record(const char *fpath, int (*fptr) (void *item, void *optarg), size_t size, void *arg);
+/* vector.c */
+struct Vector {
+ int size;
+ int length;
+ int capacity;
+ char *base;
+};
+
+void Vector_init(struct Vector *self, const int size);
+void Vector_delete(struct Vector *self);
+void Vector_clear(struct Vector *self, const int size);
+int Vector_length(struct Vector *self);
+void Vector_resize(struct Vector *self, const int length);
+void Vector_add(struct Vector *self, const char *name);
+const char* Vector_get(struct Vector *self, const int idx);
+int Vector_MaxLen(const struct Vector *list, const int offset, const int count);
+int Vector_match(const struct Vector *src, struct Vector *dst, const int key, const int pos);
+void Vector_sublist(struct Vector *src, struct Vector *dst, const char *tag);
+int Vector_remove(struct Vector *self, const char *name);
+int Vector_search(const struct Vector *self, const char *name);
+
#endif