diff --git a/Source/DOH/base.c b/Source/DOH/base.c index 2b85d1d22..399a1e96d 100644 --- a/Source/DOH/base.c +++ b/Source/DOH/base.c @@ -210,6 +210,43 @@ DohCmp(const DOH *obj1, const DOH *obj2) { return 1; } +/* ----------------------------------------------------------------------------- + * DohEqual() + * ----------------------------------------------------------------------------- */ + +int +DohEqual(const DOH *obj1, const DOH *obj2) { + DohBase *b1 = (DohBase *) obj1; + DohBase *b2 = (DohBase *) obj2; + if (!b1) { + return !b2; + } else if (!b2) { + return 0; + } else { + DohObjInfo *b1info = 0; + DohObjInfo *b2info = 0; + if (DohCheck(b1)) { + b1info = b1->type; + if (DohCheck(b2)) { + b2info = b2->type; + } else { + return strncmp((b1info->doh_data)(b1), (void*) obj2, (b1info->doh_len)(b1)) == 0; + } + } else if (DohCheck(b2)) { + b2info = b2->type; + return strncmp((b2info->doh_data)(b2), (void*) obj1, (b2info->doh_len)(b2)) == 0; + } + if (!b1info) { + return obj1 == obj2; + } else if ((b1info == b2info)) { + return b1info->doh_equal ? (b1info->doh_equal)(b1,b2) : + (b1info->doh_cmp ? (b1info->doh_cmp)(b1,b2) == 0 : (b1 == b2)); + } else { + return 0; + } + } +} + /* ----------------------------------------------------------------------------- * DohFirst() * ----------------------------------------------------------------------------- */ diff --git a/Source/DOH/doh.h b/Source/DOH/doh.h index 87538ae54..6d829206b 100644 --- a/Source/DOH/doh.h +++ b/Source/DOH/doh.h @@ -40,6 +40,7 @@ #define DohLen DOH_NAMESPACE(Len) #define DohHashval DOH_NAMESPACE(Hashval) #define DohCmp DOH_NAMESPACE(Cmp) +#define DohEqual DOH_NAMESPACE(Equal) #define DohIncref DOH_NAMESPACE(Incref) #define DohGetattr DOH_NAMESPACE(Getattr) #define DohSetattr DOH_NAMESPACE(Setattr) @@ -66,10 +67,11 @@ #define DohPutc DOH_NAMESPACE(Putc) #define DohUngetc DOH_NAMESPACE(Ungetc) -#define DohStringGetc DOH_NAMESPACE(StringGetc) -#define DohStringPutc DOH_NAMESPACE(StringPutc) -#define DohStringUngetc DOH_NAMESPACE(StringUngetc) -#define DohStringAppend DOH_NAMESPACE(StringAppend) +#define DohStringPutc DOH_NAMESPACE(StringPutc) +#define DohStringGetc DOH_NAMESPACE(StringGetc) +#define DohStringUngetc DOH_NAMESPACE(StringUngetc) +#define DohStringAppend DOH_NAMESPACE(StringAppend) +#define DohStringEqual DOH_NAMESPACE(StringEqual) @@ -187,6 +189,7 @@ extern int DohDump(const DOH *obj, DOHFile *out); extern int DohLen(const DOH *obj); extern int DohHashval(const DOH *obj); extern int DohCmp(const DOH *obj1, const DOH *obj2); +extern int DohEqual(const DOH *obj1, const DOH *obj2); extern void DohIncref(DOH *obj); /* Mapping methods */ @@ -248,11 +251,13 @@ extern int DohString_putc(DOH *so, int ch); extern int DohString_getc(DOH *so); extern int DohString_ungetc(DOH *so, int ch); extern void DohString_append(DOH *so, DOH *str); +extern int DohString_equal(DOH *s1, DOH *s2); #define DohStringPutc(ch,so) DohString_putc(so, ch) #define DohStringGetc(so) DohString_getc(so) #define DohStringUngetc(ch,so) DohString_ungetc(so, ch) #define DohStringAppend(so,str) DohString_append(so, str) +#define DohStringEqual(s1,s2) DohString_equal(s1,s2) /* Meta-variables */ extern DOH *DohGetmeta(DOH *, const DOH *); @@ -362,6 +367,7 @@ extern void DohMemoryDebug(void); #define Data DohData #define Char (char *) Data #define Cmp DohCmp +#define Equal DohEqual #define Setline DohSetline #define Getline DohGetline #define Setfile DohSetfile @@ -376,10 +382,11 @@ extern void DohMemoryDebug(void); #define Putc DohPutc #define Ungetc DohUngetc -#define StringGetc DohStringGetc #define StringPutc DohStringPutc +#define StringGetc DohStringGetc #define StringUngetc DohStringUngetc #define StringAppend DohStringAppend +#define StringEqual DohStringEqual #define Close DohClose #define vPrintf DohvPrintf diff --git a/Source/DOH/dohint.h b/Source/DOH/dohint.h index e105a440b..87cee1259 100644 --- a/Source/DOH/dohint.h +++ b/Source/DOH/dohint.h @@ -83,6 +83,9 @@ typedef struct DohObjInfo { /* Compare */ int (*doh_cmp)(DOH *obj1, DOH *obj2); + /* Equal */ + int (*doh_equal)(DOH *obj1, DOH *obj2); + /* Iterators */ DohIterator (*doh_first)(DOH *obj); DohIterator (*doh_next)(DohIterator ); diff --git a/Source/DOH/file.c b/Source/DOH/file.c index 3eb846b4a..7a6f12fd2 100644 --- a/Source/DOH/file.c +++ b/Source/DOH/file.c @@ -215,6 +215,7 @@ static DohObjInfo DohFileType = { 0, /* doh_len */ 0, /* doh_hash */ 0, /* doh_cmp */ + 0, /* doh_equal */ 0, /* doh_first */ 0, /* doh_next */ 0, /* doh_setfile */ diff --git a/Source/DOH/hash.c b/Source/DOH/hash.c index d4bfd6363..0f07f62bc 100644 --- a/Source/DOH/hash.c +++ b/Source/DOH/hash.c @@ -260,7 +260,7 @@ Hash_getattr(DOH *ho, DOH *k) { k_type = ((DohBase*)k)->type; while (n) { nk = (DohBase *)n->key; - if ((k_type == nk->type) && ((k_type->doh_cmp)(k, nk) == 0)) return n->object; + if ((k_type == nk->type) && ((k_type->doh_equal)(k, nk))) return n->object; n = n->next; } return 0; @@ -510,6 +510,7 @@ DohObjInfo DohHashType = { Hash_len, /* doh_len */ 0, /* doh_hash */ 0, /* doh_cmp */ + 0, /* doh_equal */ Hash_firstiter, /* doh_first */ Hash_nextiter, /* doh_next */ Hash_setfile, /* doh_setfile */ diff --git a/Source/DOH/list.c b/Source/DOH/list.c index d6a9c95ac..bbad162c5 100644 --- a/Source/DOH/list.c +++ b/Source/DOH/list.c @@ -324,6 +324,7 @@ DohObjInfo DohListType = { List_len, /* doh_len */ 0, /* doh_hash */ 0, /* doh_cmp */ + 0, /* doh_equal */ List_first, /* doh_first */ List_next, /* doh_next */ List_setfile, /* doh_setfile */ diff --git a/Source/DOH/string.c b/Source/DOH/string.c index 20a416d38..d7998f366 100644 --- a/Source/DOH/string.c +++ b/Source/DOH/string.c @@ -132,6 +132,36 @@ String_cmp(DOH *so1, DOH *so2) return -1; } +/* ----------------------------------------------------------------------------- + * int String_equal() - Say if two string are equal + * ----------------------------------------------------------------------------- */ + +int +DohString_equal(DOH *so1, DOH *so2) +{ + String *s1 = (String *) ObjData(so1); + String *s2 = (String *) ObjData(so2); + register int len = s1->len; + if (len != s2->len) { + return 0; + } else { + register char *c1 = s1->str; + register char *c2 = s2->str; + register int mlen = len >> 2; + register int i = mlen; + for (; i; --i) { + if (*(c1++) != *(c2++)) return 0; + if (*(c1++) != *(c2++)) return 0; + if (*(c1++) != *(c2++)) return 0; + if (*(c1++) != *(c2++)) return 0; + } + for (i = len - (mlen << 2); i; --i) { + if (*(c1++) != *(c2++)) return 0; + } + return 1; + } +} + /* ----------------------------------------------------------------------------- * int String_hash() - Compute string hash value * ----------------------------------------------------------------------------- */ @@ -139,18 +169,27 @@ String_cmp(DOH *so1, DOH *so2) static int String_hash(DOH *so) { String *s = (String *) ObjData(so); - char *c; - int i, h = 0, len; - - if (s->hashkey >= 0) return s->hashkey; - c = s->str; - len = s->len > 50 ? 50 : s->len; - for (i = 0; i < len; i++) { - h = (((h << 5) + *(c++))); + if (s->hashkey >= 0) { + return s->hashkey; + } else { + register char *c = s->str; + register int len = s->len > 50 ? 50 : s->len; + register int h = 0; + register int mlen = len >> 2; + register int i = mlen; + for (; i; --i) { + h = (h << 5) + *(c++); + h = (h << 5) + *(c++); + h = (h << 5) + *(c++); + h = (h << 5) + *(c++); + } + for (i = len - (mlen << 2); i; --i) { + h = (h << 5) + *(c++); + } + h &= 0x7fffffff; + s->hashkey = h; + return h; } - h = h & 0x7fffffff; - s->hashkey = h; - return h; } /* ----------------------------------------------------------------------------- @@ -159,14 +198,22 @@ String_hash(DOH *so) { void DohString_append(DOH *so, DOH *str) { - int oldlen, newlen, newmaxsize, l, i, sp; + int oldlen, newlen, newmaxsize, l, sp; char *tc; String *s = (String *) ObjData(so); - char *newstr = (char *) DohData(str); + char *newstr = 0; + if (DohCheck(str)) { + String *ss = (String *) ObjData(str); + newstr = String_data(str); + l = ss->len; + } else { + newstr = (char *) (str); + l = (int) strlen(newstr); + } if (!newstr) return; s->hashkey = -1; - l = (int) strlen(newstr); + oldlen = s->len; newlen = oldlen+l + 1; if (newlen >= s->maxsize-1) { @@ -177,12 +224,13 @@ DohString_append(DOH *so, DOH *str) { s->maxsize = newmaxsize; } tc = s->str; - strcpy(tc+oldlen,newstr); + memcpy(tc+oldlen,newstr,l+1); sp = s->sp; if (sp >= oldlen) { + int i = oldlen + l - sp; tc += sp; - for (i = sp; i < oldlen+l; i++,tc++) { - if (*tc == '\n') s->line++; + for (; i ; --i) { + if (*(tc++) == '\n') s->line++; } s->sp = oldlen+l; } @@ -910,6 +958,7 @@ DohObjInfo DohStringType = { String_len, /* doh_len */ String_hash, /* doh_hash */ String_cmp, /* doh_cmp */ + DohString_equal, /* doh_equal */ 0, /* doh_first */ 0, /* doh_next */ String_setfile, /* doh_setfile */ @@ -921,7 +970,7 @@ DohObjInfo DohStringType = { &StringFileMethods, /* doh_file */ &StringStringMethods, /* doh_string */ 0, /* doh_position */ - 0, + 0 }; @@ -937,8 +986,15 @@ DohNewString(const DOH *so) int l = 0, max; String *str; char *s; - if (DohCheck(so)) s = Char(so); - else s = (char *) so; + if (DohCheck(so)) { + str = (String *) ObjData(so); + s = String_data(so); + l = s ? str->len : 0; + } else { + s = (char *) so; + l = s ? (int) strlen(s) : 0; + } + str = (String *) DohMalloc(sizeof(String)); str->hashkey = -1; str->sp = 0; @@ -946,7 +1002,6 @@ DohNewString(const DOH *so) str->file = 0; max = INIT_MAXSIZE; if (s) { - l = (int) strlen(s); if ((l+1) > max) max = l+1; } str->str = (char *) DohMalloc(max); @@ -973,8 +1028,13 @@ DohNewStringWithSize(const DOH *so, int len) int l = 0, max; String *str; char *s; - if (DohCheck(so)) s = Char(so); - else s = (char *) so; + if (DohCheck(so)) { + s = String_data(so); + } + else { + s = (char *) so; + } + str = (String *) DohMalloc(sizeof(String)); str->hashkey = -1; str->sp = 0; diff --git a/Source/DOH/void.c b/Source/DOH/void.c index 90b85d8ec..6bf3090d6 100644 --- a/Source/DOH/void.c +++ b/Source/DOH/void.c @@ -69,6 +69,7 @@ static DohObjInfo DohVoidType = { 0, /* doh_len */ 0, /* doh_hash */ 0, /* doh_cmp */ + 0, /* doh_equal */ 0, /* doh_first */ 0, /* doh_next */ 0, /* doh_setfile */