-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include <cdt.h>
/* This program reads a list of words, 1 per line, from stdin,
** alphabetic order.
*/
+#define ulong unsigned long
#define reg register
#define NIL(t) ((t)0)
-_BEGIN_EXTERNS_ extern Void_t *malloc _ARG_((int));
-extern Void_t *memcpy _ARG_((Void_t *, const Void_t *, size_t));
-extern void free _ARG_((Void_t *));
+_BEGIN_EXTERNS_
+extern Void_t* malloc _ARG_((int));
+extern Void_t* memcpy _ARG_((Void_t*, const Void_t*, size_t));
+extern void free _ARG_((Void_t*));
_END_EXTERNS_
+
/* compare two strings by their alphabetic order */
#if __STD_C
-static alphacmp(Dt_t * dt, reg Void_t * arg_s1, reg Void_t * arg_s2,
- Dtdisc_t * disc)
+static alphacmp(Dt_t* dt, reg Void_t* arg_s1, reg Void_t* arg_s2, Dtdisc_t* disc)
#else
-static alphacmp(dt, arg_s1, arg_s2, disc)
-Dt_t *dt;
-reg Void_t *arg_s1;
-reg Void_t *arg_s2;
-Dtdisc_t *disc;
+static alphacmp(dt,arg_s1,arg_s2,disc)
+Dt_t* dt;
+reg Void_t* arg_s1;
+reg Void_t* arg_s2;
+Dtdisc_t* disc;
#endif
{
- reg int c1, c2;
- reg char *s1 = (char *) arg_s1, *s2 = (char *) arg_s2;
-
- while ((c1 = *s1++) != 0) {
- if ((c2 = *s2++) == 0)
- return 1;
-
- if (c1 >= 'A' && c1 <= 'Z') {
- if (c2 >= 'a' && c2 <= 'z') {
- c2 = 'A' + (c2 - 'a');
- return c1 <= c2 ? -1 : 1;
- }
- } else if (c1 >= 'a' && c1 <= 'z') {
- if (c2 >= 'A' && c2 <= 'Z') {
- c2 = 'a' + (c2 - 'A');
- return c1 >= c2 ? 1 : -1;
- }
+ reg int c1, c2;
+ reg char *s1 = (char*)arg_s1, *s2 = (char*)arg_s2;
+
+ while((c1 = *s1++) != 0)
+ { if((c2 = *s2++) == 0)
+ return 1;
+
+ if(c1 >= 'A' && c1 <= 'Z')
+ { if(c2 >= 'a' && c2 <= 'z')
+ { c2 = 'A' + (c2 - 'a');
+ return c1 <= c2 ? -1 : 1;
+ }
+ }
+ else if(c1 >= 'a' && c1 <= 'z')
+ { if(c2 >= 'A' && c2 <= 'Z')
+ { c2 = 'a' + (c2 - 'A');
+ return c1 >= c2 ? 1 : -1;
+ }
+ }
+
+ if((c1 -= c2) != 0)
+ return c1;
}
- if ((c1 -= c2) != 0)
- return c1;
- }
-
- return *s2 ? -1 : 0;
+ return *s2 ? -1 : 0;
}
/* make a copy of a string */
#if __STD_C
-static Void_t *newstring(Dt_t * dt, reg Void_t * s, Dtdisc_t * disc)
+static Void_t* newstring(Dt_t* dt, reg Void_t* s, Dtdisc_t* disc)
#else
-static Void_t *newstring(dt, s, disc)
-Dt_t *dt;
-reg Void_t *s;
-Dtdisc_t *disc;
+static Void_t* newstring(dt,s,disc)
+Dt_t* dt;
+reg Void_t* s;
+Dtdisc_t* disc;
#endif
{
- reg Void_t *news;
- reg int n = strlen((char *) s) + 1;
+ reg Void_t* news;
+ reg int n = strlen((char*)s)+1;
- if (!(news = malloc(n)))
- return NIL(Void_t *);
- memcpy(news, s, n);
+ if(!(news = malloc(n)) )
+ return NIL(Void_t*);
+ memcpy(news, s, n);
- return (Void_t *) news;
+ return (Void_t*)news;
}
-static Dtdisc_t Disc = { 0, 0, /* Strings themselves are indexing keys
- so "key" and "size" are set to zero. */
- -1, /* negative "link" means that strings
+static Dtdisc_t Disc =
+ { 0, 0, /* Strings themselves are indexing keys
+ so "key" and "size" are set to zero. */
+ -1, /* negative "link" means that strings
do not contain Dtlink_t and internal
- dictionary holders will be allocated */
- newstring, /* duplicate strings so that they won't
- be clobbered by further I/O. */
- NIL(Dtfree_f), /* does not free anything */
- NIL(Dtcompar_f), /* uses built-in string comparison */
- NIL(Dthash_f), /* uses built-in string hashing */
- NIL(Dtmemory_f), /* uses default memory allocation */
- NIL(Dtevent_f) /* no event handling needed */
-};
+ dictionary holders will be allocated */
+ newstring, /* duplicate strings so that they won't
+ be clobbered by further I/O. */
+ NIL(Dtfree_f), /* does not free anything */
+ NIL(Dtcompar_f), /* uses built-in string comparison */
+ NIL(Dthash_f), /* uses built-in string hashing */
+ NIL(Dtmemory_f), /* uses default memory allocation */
+ NIL(Dtevent_f) /* no event handling needed */
+ };
main()
{
- char s[1024];
- reg Dt_t *dt;
- reg Dtlink_t *link;
-
- /* create a dictionary, use a hash table for speed */
- if (!(dt = dtopen(&Disc, Dtset)))
- return -1;
-
- /* read&insert strings into dt.
- Yes, gets() should be avoided and something like Sfio's sfgetr()
- should be used for robustness. But I am lazy...
- */
- while (gets(s))
- dtinsert(dt, s);
-
- /* at this point, strings in dt are unique.
- Now change the comparison function to use alphabetic order.
- At a discipline change, dtdisc() normally checks for new
- duplicates and rehashes elements. Since alphacmp() and strcmp()
- are equivalent with respect to distinguishing strings, DT_SAMECMP
- is used to tell dtdisc() to skip reordering and checking for new
- duplicates. This is ok because we are still in Dthash which does
- not require ordering. Similarly, DT_SAMEHASH is used to assert that
- there is no need to rehash elements.
- */
- Disc.comparf = alphacmp;
- if (!dtdisc(dt, &Disc, DT_SAMECMP | DT_SAMEHASH))
- return -1;
-
- /* now order strings by switching to Dttree */
- if (!dtmethod(dt, Dtorder))
- return -1;
-
- /* output the words in alphabetic order */
- for (link = dtflatten(dt); link; link = dtlink(dt, link))
- printf("%s\n", (char *) dtobj(dt, link));
-
- return 0;
+ char s[1024];
+ reg Dt_t* dt;
+ reg Dtlink_t* link;
+
+ /* create a dictionary, use a hash table for speed */
+ if(!(dt = dtopen(&Disc,Dtset)) )
+ return -1;
+
+ /* read&insert strings into dt.
+ Yes, gets() should be avoided and something like Sfio's sfgetr()
+ should be used for robustness. But I am lazy...
+ */
+ while(gets(s) )
+ dtinsert(dt,s);
+
+ /* at this point, strings in dt are unique.
+ Now change the comparison function to use alphabetic order.
+ At a discipline change, dtdisc() normally checks for new
+ duplicates and rehashes elements. Since alphacmp() and strcmp()
+ are equivalent with respect to distinguishing strings, DT_SAMECMP
+ is used to tell dtdisc() to skip reordering and checking for new
+ duplicates. This is ok because we are still in Dthash which does
+ not require ordering. Similarly, DT_SAMEHASH is used to assert that
+ there is no need to rehash elements.
+ */
+ Disc.comparf = alphacmp;
+ if(!dtdisc(dt,&Disc,DT_SAMECMP|DT_SAMEHASH))
+ return -1;
+
+ /* now order strings by switching to Dttree */
+ if(!dtmethod(dt,Dtorder) )
+ return -1;
+
+ /* output the words in alphabetic order */
+ for(link = dtflatten(dt); link; link = dtlink(dt,link))
+ printf("%s\n",(char*)dtobj(dt,link));
+
+ return 0;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include <search.h>
#include "../dthdr.h"
*/
/* type of objects in hash table */
-typedef struct _hash_s {
- Dtlink_t link;
- ENTRY item;
+typedef struct _hash_s
+{ Dtlink_t link;
+ ENTRY item;
} Hash_t;
/* object delete function */
#if __STD_C
-static void hashfree(Dt_t * dt, Void_t * obj, Dtdisc_t * disc)
+static void hashfree(Dt_t* dt, Void_t* obj, Dtdisc_t* disc)
#else
static void hashfree(dt, obj, disc)
-Dt_t *dt;
-Void_t *obj;
-Dtdisc_t *disc;
+Dt_t* dt;
+Void_t* obj;
+Dtdisc_t* disc;
#endif
{
- free(((Hash_t *) obj)->item.key);
- free(obj);
+ free(((Hash_t*)obj)->item.key);
+ free(obj);
}
-static Dt_t *Hashtab; /* object dictionary */
-static Dtdisc_t Hashdisc = /* discipline */
-{ sizeof(Dtlink_t), -1,
- 0,
- NIL(Dtmake_f), hashfree,
- NIL(Dtcompar_f), /* always use strcmp */
- NIL(Dthash_f),
- NIL(Dtmemory_f),
- NIL(Dtevent_f)
+static Dt_t* Hashtab; /* object dictionary */
+static Dtdisc_t Hashdisc = /* discipline */
+{ sizeof(Dtlink_t), -1,
+ 0,
+ NIL(Dtmake_f), hashfree,
+ NIL(Dtcompar_f), /* always use strcmp */
+ NIL(Dthash_f),
+ NIL(Dtmemory_f),
+ NIL(Dtevent_f)
};
#if __STD_C
int hcreate(size_t nel)
#else
int hcreate(nel)
-size_t nel;
+size_t nel;
#endif
{
- if (Hashtab) /* already opened */
- return 0;
+ if(Hashtab) /* already opened */
+ return 0;
- if (!(Hashtab = dtopen(&Hashdisc, Dtset)))
- return 0;
+ if(!(Hashtab = dtopen(&Hashdisc,Dtset)) )
+ return 0;
- return 1;
+ return 1;
}
void hdestroy()
-{
- if (Hashtab)
- dtclose(Hashtab);
- Hashtab = NIL(Dt_t *);
+{ if(Hashtab)
+ dtclose(Hashtab);
+ Hashtab = NIL(Dt_t*);
}
#if __STD_C
-ENTRY *hsearch(ENTRY item, ACTION action)
+ENTRY* hsearch(ENTRY item, ACTION action)
#else
-ENTRY *hsearch(item, action)
-ENTRY item;
-ACTION action;
+ENTRY* hsearch(item, action)
+ENTRY item;
+ACTION action;
#endif
{
- reg Hash_t *o;
+ reg Hash_t* o;
- if (!Hashtab)
- return NIL(ENTRY *);
+ if(!Hashtab)
+ return NIL(ENTRY*);
- if (!(o = (Hash_t *) dtmatch(Hashtab, item.key)) && action == ENTER &&
- (o = (Hash_t *) malloc(sizeof(Hash_t)))) {
- o->item = item;
- o = (Hash_t *) dtinsert(Hashtab, o);
- }
+ if(!(o = (Hash_t*)dtmatch(Hashtab,item.key)) && action == ENTER &&
+ (o = (Hash_t*)malloc(sizeof(Hash_t)) ) )
+ { o->item = item;
+ o = (Hash_t*)dtinsert(Hashtab,o);
+ }
- return o ? &(o->item) : NIL(ENTRY *);
+ return o ? &(o->item) : NIL(ENTRY*);
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include <search.h>
#include "../dthdr.h"
** Written by Kiem-Phong Vo (AT&T Labs, 07/19/95)
*/
-typedef struct _tree_s {
- Dtlink_t link;
- Void_t *key;
+typedef struct _tree_s
+{ Dtlink_t link;
+ Void_t* key;
} Tree_t;
-typedef struct _treedisc_s {
- Dtdisc_t disc;
- int (*comparf) _ARG_((const Void_t *, const Void_t *));
+typedef struct _treedisc_s
+{ Dtdisc_t disc;
+ int(* comparf)_ARG_((const Void_t*, const Void_t*));
} Treedisc_t;
/* compare function */
#if __STD_C
-static int treecompare(Dt_t * dt, char *one, char *two, Dtdisc_t * disc)
+static int treecompare(Dt_t* dt, char* one, char* two, Dtdisc_t* disc)
#else
static int treecompare(dt, one, two, disc)
-Dt_t *dt;
-char *one;
-char *two;
-Dtdisc_t *disc;
+Dt_t* dt;
+char* one;
+char* two;
+Dtdisc_t* disc;
#endif
{
- return (*((Treedisc_t *) disc)->comparf) ((Void_t *) one,
- (Void_t *) two);
+ return (*((Treedisc_t*)disc)->comparf)((Void_t*)one,(Void_t*)two);
}
-static Treedisc_t Treedisc = { {sizeof(Dtlink_t), -1, /* object is key */
- 0,
- NIL(Dtmake_f), NIL(Dtfree_f),
- treecompare,
- NIL(Dthash_f),
- NIL(Dtmemory_f),
- NIL(Dtevent_f)
- }
-,
-0
+static Treedisc_t Treedisc =
+{ { sizeof(Dtlink_t), -1, /* object is key */
+ 0,
+ NIL(Dtmake_f), NIL(Dtfree_f),
+ treecompare,
+ NIL(Dthash_f),
+ NIL(Dtmemory_f),
+ NIL(Dtevent_f)
+ },
+ 0
};
#if __STD_C
-Void_t *tsearch(const Void_t * key, Void_t ** rootp,
- int (*comparf) (const Void_t *, const Void_t *))
+Void_t* tsearch(const Void_t* key, Void_t** rootp,
+ int(*comparf)(const Void_t*,const Void_t*) )
#else
-Void_t *tsearch(key, rootp, comparf)
-Void_t *key;
-Void_t **rootp;
-int (*comparf) ();
+Void_t* tsearch(key, rootp, comparf)
+Void_t* key;
+Void_t** rootp;
+int(* comparf)();
#endif
{
- reg Dt_t *dt;
- reg Tree_t *o;
-
- if (!rootp ||
- (!(dt = *((Dt_t **) rootp))
- && !(dt = dtopen((Dtdisc_t *) (&Treedisc), Dtoset))))
- return NIL(Void_t *);
-
- /* dangerous to set comparf on each call but that's tsearch */
- Treedisc.comparf = comparf;
-
- if (!(o = (Tree_t *) dtmatch(dt, key))) {
- if (!(o = (Tree_t *) malloc(sizeof(Tree_t))))
- return NIL(Void_t *);
- o->key = (Void_t *) key;
- dtinsert(dt, o);
- }
-
- if (o)
- *rootp = (Void_t *) dt;
- else if (*rootp == NIL(Void_t *))
- dtclose(dt);
-
- return (Void_t *) (&o->key);
+ reg Dt_t* dt;
+ reg Tree_t* o;
+
+ if(!rootp ||
+ (!(dt = *((Dt_t**)rootp)) && !(dt = dtopen((Dtdisc_t*)(&Treedisc),Dtoset))) )
+ return NIL(Void_t*);
+
+ /* dangerous to set comparf on each call but that's tsearch */
+ Treedisc.comparf = comparf;
+
+ if(!(o = (Tree_t*)dtmatch(dt,key)) )
+ { if(!(o = (Tree_t*)malloc(sizeof(Tree_t))) )
+ return NIL(Void_t*);
+ o->key = (Void_t*)key;
+ dtinsert(dt,o);
+ }
+
+ if(o)
+ *rootp = (Void_t*)dt;
+ else if(*rootp == NIL(Void_t*) )
+ dtclose(dt);
+
+ return (Void_t*)(&o->key);
}
#if __STD_C
-Void_t *tfind(const Void_t * key, Void_t * const *rootp,
- int (*comparf) (const Void_t *, const Void_t *))
+Void_t* tfind(const Void_t* key, Void_t*const* rootp,
+ int(*comparf)(const Void_t*, const Void_t*) )
#else
-Void_t *tfind(key, rootp, comparf)
-Void_t *key;
-Void_t **rootp;
-int (*comparf) ();
+Void_t* tfind(key, rootp, comparf)
+Void_t* key;
+Void_t** rootp;
+int(* comparf)();
#endif
{
- reg Dt_t *dt;
- reg Tree_t *o;
+ reg Dt_t* dt;
+ reg Tree_t* o;
- if (!rootp || !(dt = *((Dt_t **) rootp)))
- return NIL(Void_t *);
- Treedisc.comparf = comparf;
+ if(!rootp || !(dt = *((Dt_t**)rootp)) )
+ return NIL(Void_t*);
+ Treedisc.comparf = comparf;
- return (o =
- (Tree_t *) dtmatch(dt,
- key)) ? (Void_t *) (&o->
- key) : NIL(Void_t *);
+ return (o = (Tree_t*)dtmatch(dt,key)) ? (Void_t*)(&o->key) : NIL(Void_t*);
}
/* the original tdelete() specifies that it will return the parent pointer
** returns the key of the new root.
*/
#if __STD_C
-Void_t *tdelete(const Void_t * key, Void_t ** rootp,
- int (*comparf) (const Void_t *, const Void_t *))
+Void_t* tdelete(const Void_t* key, Void_t** rootp,
+ int(*comparf)(const Void_t*, const Void_t*) )
#else
-Void_t *tdelete(key, rootp, comparf)
-Void_t *key;
-Void_t **rootp;
-int (*comparf) ();
+Void_t* tdelete(key, rootp, comparf)
+Void_t* key;
+Void_t** rootp;
+int(* comparf)();
#endif
{
- reg Dt_t *dt;
- reg Tree_t *o;
- Tree_t obj;
+ reg Dt_t* dt;
+ reg Tree_t* o;
+ Tree_t obj;
- if (!rootp || !(dt = *((Dt_t **) rootp)))
- return NIL(Void_t *);
+ if(!rootp || !(dt = *((Dt_t**)rootp)) )
+ return NIL(Void_t*);
- Treedisc.comparf = comparf;
+ Treedisc.comparf = comparf;
- obj.key = (Void_t *) key;
- dtdelete(dt, &obj);
+ obj.key = (Void_t*)key;
+ dtdelete(dt,&obj);
- if (!(o = dtfinger(dt))) {
- dtclose(dt);
- *rootp = NIL(Void_t *);
- }
+ if(!(o = dtfinger(dt)) )
+ { dtclose(dt);
+ *rootp = NIL(Void_t*);
+ }
- return o ? (Void_t *) (&o->key) : NIL(Void_t *);
+ return o ? (Void_t*)(&o->key) : NIL(Void_t*);
}
/* the below routine assumes a particular layout of Dtlink_t.
#define rchild link.right
#if __STD_C
-static void _twalk(Tree_t * obj, void (*action) (Void_t *, VISIT, int),
- int level)
+static void _twalk(Tree_t* obj, void(*action)(Void_t*,VISIT,int), int level)
#else
-static void _twalk(obj, action, level)
-Tree_t *obj;
-void (*action) ();
-int level;
+static void _twalk(obj,action,level)
+Tree_t* obj;
+void(* action)();
+int level;
#endif
-{
- if (!obj->lchild && !obj->rchild)
- (*action) ((Void_t *) obj, leaf, level);
- else {
- (*action) ((Void_t *) obj, preorder, level);
- if (obj->lchild)
- _twalk((Tree_t *) obj->lchild, action, level + 1);
- (*action) ((Void_t *) obj, postorder, level);
- if (obj->rchild)
- _twalk((Tree_t *) obj->rchild, action, level + 1);
- (*action) ((Void_t *) obj, endorder, level);
- }
+{ if(!obj->lchild && !obj->rchild)
+ (*action)((Void_t*)obj,leaf,level);
+ else
+ { (*action)((Void_t*)obj,preorder,level);
+ if(obj->lchild)
+ _twalk((Tree_t*)obj->lchild,action,level+1);
+ (*action)((Void_t*)obj,postorder,level);
+ if(obj->rchild)
+ _twalk((Tree_t*)obj->rchild,action,level+1);
+ (*action)((Void_t*)obj,endorder,level);
+ }
}
/* the original twalk allows specifying arbitrary node to start traversal.
** at whichever node happens to be current root.
*/
#if __STD_C
-void twalk(Void_t * root, void (*action) (Void_t *, VISIT, int))
+void twalk(Void_t* root, void(*action)(Void_t*,VISIT,int) )
#else
void twalk(root, action)
-Void_t *root;
-void (*action) ();
+Void_t* root;
+void(* action)();
#endif
{
- reg Tree_t *o;
+ reg Tree_t* o;
- if (root && (o = (Tree_t *) dtfinger((Dt_t *) root)))
- _twalk(o, action, 0);
+ if(root && (o = (Tree_t*)dtfinger((Dt_t*)root)) )
+ _twalk(o,action,0);
}
--- /dev/null
+#include <ast_common.h>
+
+#ifndef NIL
+#define NIL(t) ((t)0)
+#endif
+
+#if __STD_C
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#if _hdr_stdlib
+#include <stdlib.h>
+#endif
+#if _hdr_unistd
+#include <unistd.h>
+#endif
+#if _hdr_string
+#include <string.h>
+#endif
+
+_BEGIN_EXTERNS_
+
+#if !_SFIO_H
+extern int sprintf _ARG_((char*, const char*, ...));
+extern int vsprintf _ARG_((char*, const char*, va_list));
+#endif
+
+#if !__STD_C && !_hdr_stdlib
+extern int atexit _ARG_((void (*)(void)));
+extern void exit _ARG_((int));
+extern size_t strlen _ARG_((const char*));
+extern Void_t* malloc _ARG_((size_t));
+extern char* getenv _ARG_((const char*));
+
+extern int strncmp _ARG_((const char*, const char*, size_t));
+extern int strcmp _ARG_((const char*, const char*));
+extern int system _ARG_((const char*));
+#endif
+
+#if !_hdr_unistd
+extern int alarm _ARG_((int));
+extern int sleep _ARG_((int));
+extern int fork();
+extern int wait _ARG_((int*));
+extern int access _ARG_((const char*, int));
+extern int write _ARG_((int, const void*, int));
+extern int unlink _ARG_((const char*));
+extern Void_t* sbrk _ARG_((int));
+extern int getpid();
+#endif
+
+extern void tsterror _ARG_((char*, ...));
+extern void tstwarn _ARG_((char*, ...));
+extern void tstsuccess _ARG_((char*, ...));
+
+_END_EXTERNS_
+
+static int Tstline;
+static char Tstfile[16][256];
+
+#ifdef __LINE__
+#define terror (Tstline=__LINE__),tsterror
+#else
+#define terror (Tstline=-1),tsterror
+#endif
+
+#ifdef __LINE__
+#define twarn (Tstline=__LINE__),tstwarn
+#else
+#define twarn (Tstline=-1),tstwarn
+#endif
+
+#ifdef __LINE__
+#define tsuccess (Tstline=__LINE__),tstsuccess
+#else
+#define tsuccess (Tstline=-1),tstsuccess
+#endif
+
+#define tmesg (Tstline=-1),tstwarn
+
+#ifdef DEBUG
+#ifdef __LINE__
+#define TSTDEBUG(x) (Tstline=__LINE__),tstwarn x
+#else
+#define TSTDEBUG(x) (Tstline=-1),tstwarn x
+#endif
+#else
+#define TSTDEBUG(x)
+#endif
+
+#ifndef MAIN
+#if __STD_C
+#define MAIN() int main(int argc, char** argv)
+#else
+#define MAIN() int main(argc, argv) int argc; char** argv;
+#endif
+#endif /*MAIN*/
+
+#ifndef TSTEXIT
+#define TSTEXIT(v) { tstcleanup(); exit(v); }
+#endif
+
+static void tstcleanup()
+{
+#ifdef DEBUG
+ twarn("Temp files will not be removed");
+#else
+ int i;
+ for(i = 0; i < sizeof(Tstfile)/sizeof(Tstfile[0]); ++i)
+ if(Tstfile[i][0])
+ unlink(Tstfile[i]);
+#endif
+}
+
+#if __STD_C
+static void tstputmesg(int line, char* form, va_list args)
+#else
+static void tstputmesg(line, form, args)
+int line;
+char* form;
+va_list args;
+#endif
+{
+ char *s, buf[1024];
+ int n;
+
+ for(n = 0; n < sizeof(buf); ++n)
+ buf[n] = 0;
+
+ s = buf; n = 0;
+ if(line >= 0)
+ {
+#if _SFIO_H
+ sfsprintf(s, sizeof(buf), "\tLine=%d: ", line);
+#else
+ sprintf(s, "\tLine=%d: ", line);
+#endif
+ s += (n = strlen(s));
+ }
+#if _SFIO_H
+ sfvsprintf(s, sizeof(buf)-n, form, args);
+#else
+ vsprintf(s, form, args);
+#endif
+
+ if((n = strlen(buf)) > 0)
+ { if(buf[n-1] != '\n')
+ { buf[n] = '\n';
+ n += 1;
+ }
+ write(2,buf,n);
+ }
+}
+
+
+#if __STD_C
+void tsterror(char* form, ...)
+#else
+void tsterror(va_alist)
+va_dcl
+#endif
+{
+ char failform[1024];
+
+ va_list args;
+#if __STD_C
+ va_start(args,form);
+#else
+ char* form;
+ va_start(args);
+ form = va_arg(args,char*);
+#endif
+
+#if _SFIO_H
+ sfsprintf(failform, sizeof(failform), "Failure: %s", form);
+#else
+ sprintf(failform, "Failure: %s", form);
+#endif
+
+ tstputmesg(Tstline,failform,args);
+
+ va_end(args);
+
+ tstcleanup();
+ exit(1);
+}
+
+
+#if __STD_C
+void tstsuccess(char* form, ...)
+#else
+void tstsuccess(va_alist)
+va_dcl
+#endif
+{
+ va_list args;
+#if __STD_C
+ va_start(args,form);
+#else
+ char* form;
+ va_start(args);
+ form = va_arg(args,char*);
+#endif
+
+ tstputmesg(Tstline,form,args);
+
+ va_end(args);
+
+ tstcleanup();
+ exit(0);
+}
+
+
+#if __STD_C
+void tstwarn(char* form, ...)
+#else
+void tstwarn(va_alist)
+va_dcl
+#endif
+{
+ va_list args;
+#if __STD_C
+ va_start(args,form);
+#else
+ char* form;
+ va_start(args);
+ form = va_arg(args,char*);
+#endif
+
+ tstputmesg(Tstline,form,args);
+
+ va_end(args);
+}
+
+
+#if __STD_C
+static char* tstfile(int n)
+#else
+static char* tstfile(n)
+int n;
+#endif
+{
+ static int Setatexit = 0;
+
+ if(!Setatexit)
+ { Setatexit = 1;
+ atexit(tstcleanup);
+ }
+
+ if(n >= sizeof(Tstfile)/sizeof(Tstfile[0]))
+ terror("Bad temporary file request:%d\n", n);
+
+ if(!Tstfile[n][0])
+ {
+#ifdef DEBUG
+#if _SFIO_H
+ sfsprintf(Tstfile[n], sizeof(Tstfile[0]), "Tstfile.%c%c%c", '0'+n, '0'+n, '0'+n);
+#else
+ sprintf(Tstfile[n], "Tstfile.%c%c%c", '0'+n, '0'+n, '0'+n);
+#endif
+#else
+ static int pid;
+ static char* tmp;
+ if (!tmp)
+ { if (!(tmp = (char*)getenv("TMPDIR")) || access(tmp, 0) != 0)
+ tmp = "/tmp";
+ pid = (int)getpid() % 10000;
+ }
+#if _SFIO_H
+ sfsprintf(Tstfile[n], sizeof(Tstfile[0]), "%s/sft.%c.%d", tmp, '0'+n, pid);
+#else
+ sprintf(Tstfile[n], "%s/sft.%c.%d", tmp, '0'+n, pid);
+#endif
+#endif
+ }
+
+ return Tstfile[n];
+}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dttest.h"
+static int Pevent;
static int Event;
+static int Hinit;
#if __STD_C
-static int event(Dt_t * dt, int type, Void_t * obj, Dtdisc_t * disc)
+static int event(Dt_t* dt, int type, Void_t* obj, Dtdisc_t* disc)
#else
static int event(dt, type, obj, disc)
-Dt_t *dt;
-int type;
-Void_t *obj;
-Dtdisc_t *disc;
+Dt_t* dt;
+int type;
+Void_t* obj;
+Dtdisc_t* disc;
#endif
{
- Event = type;
- return 0;
+ Pevent = Event;
+ Event = type;
+
+ if(type == DT_HASHSIZE)
+ { Hinit += 1;
+ *(ssize_t*)obj = 1024;
+ return 1;
+ }
+
+ return 0;
}
-Dtdisc_t Disc = { 0, sizeof(int), -1,
- newint, NIL(Dtfree_f), compare, hashint,
- NIL(Dtmemory_f), event
-};
+Dtdisc_t Disc =
+ { 0, sizeof(long), -1,
+ newint, NIL(Dtfree_f), compare, hashint,
+ NIL(Dtmemory_f), event
+ };
main()
{
- Dt_t *dt;
+ Dt_t *dt;
+ long k;
+
+ if(!(dt = dtopen(&Disc,Dtset)) )
+ terror("Opening Dtset");
+ if(Pevent != DT_OPEN && Event != DT_ENDOPEN)
+ terror("No open event");
+
+ dtmethod(dt,Dtoset);
+ if(Event != DT_METH)
+ terror("No meth event");
+
+ dtdisc(dt,&Disc,0);
+ if(Event != DT_DISC)
+ terror("No disc event");
- if (!(dt = dtopen(&Disc, Dtset)))
- terror("Opening Dtset");
- if (Event != DT_OPEN)
- terror("No open event");
- dtmethod(dt, Dtorder);
- if (Event != DT_METH)
- terror("No meth event");
+ dtclose(dt);
+ if(Pevent != DT_CLOSE && Event != DT_ENDCLOSE)
+ terror("No close event");
- dtdisc(dt, &Disc, 0);
- if (Event != DT_DISC)
- terror("No disc event");
+ if(!(dt = dtopen(&Disc,Dtset)) )
+ terror("Opening Dtset");
- dtclose(dt);
- if (Event != DT_CLOSE)
- terror("No close event");
+ Pevent = Event = 0;
+ for(k = 1; k <= 3000; ++k)
+ dtinsert(dt, (Void_t*)k);
+ if(Hinit != 1)
+ terror("Wrong number of hash table events");
- return 0;
+ return 0;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dttest.h"
-Dtdisc_t Disc = { 0, sizeof(int), -1,
- newint, NIL(Dtfree_f), compare, hashint,
- NIL(Dtmemory_f), NIL(Dtevent_f)
-};
+Dtdisc_t Disc =
+ { 0, sizeof(long), -1,
+ newint, NIL(Dtfree_f), compare, hashint,
+ NIL(Dtmemory_f), NIL(Dtevent_f)
+ };
-Dtdisc_t Rdisc = { 0, sizeof(int), -1,
- newint, NIL(Dtfree_f), rcompare, hashint,
- NIL(Dtmemory_f), NIL(Dtevent_f)
-};
+Dtdisc_t Rdisc =
+ { 0, sizeof(long), -1,
+ newint, NIL(Dtfree_f), rcompare, hashint,
+ NIL(Dtmemory_f), NIL(Dtevent_f)
+ };
main()
{
- Dt_t *dt;
- Dtlink_t *link;
- int i, k, count[10];
+ Dt_t* dt;
+ Dtlink_t* link;
+ long i, k, count[10];
- /* testing Dtobag */
- dt = dtopen(&Disc, Dtobag);
- if ((int) dtinsert(dt, 5) != 5)
- terror("Insert 5.1");
- if ((int) dtinsert(dt, 2) != 2)
- terror("Insert 2.1");
- if ((int) dtinsert(dt, 5) != 5)
- terror("Insert 5.2");
- for (k = 0, i = (int) dtfirst(dt); i; k = i, i = (int) dtnext(dt, i))
- if (i < k)
- terror("Wrong order1\n");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Insert 3.1");
- if ((int) dtinsert(dt, 5) != 5)
- terror("Insert 5.3");
- for (k = 0, i = (int) dtfirst(dt); i; k = i, i = (int) dtnext(dt, i))
- if (i < k)
- terror("Wrong order2\n");
- if ((int) dtinsert(dt, 4) != 4)
- terror("Insert 4.1");
- if ((int) dtinsert(dt, 1) != 1)
- terror("Insert 1");
- for (k = 0, i = (int) dtfirst(dt); i; k = i, i = (int) dtnext(dt, i))
- if (i < k)
- terror("Wrong order3\n");
- if ((int) dtinsert(dt, 2) != 2)
- terror("Insert 2.2");
- if ((int) dtinsert(dt, 5) != 5)
- terror("Insert 5.4");
- if ((int) dtinsert(dt, 4) != 4)
- terror("Insert 4.2");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Insert 3.2");
- for (k = 0, i = (int) dtfirst(dt); i; k = i, i = (int) dtnext(dt, i))
- if (i < k)
- terror("Wrong order4\n");
- if ((int) dtinsert(dt, 4) != 4)
- terror("Insert 4.3");
- if ((int) dtinsert(dt, 5) != 5)
- terror("Insert 5.5");
- for (k = 0, i = (int) dtfirst(dt); i; k = i, i = (int) dtnext(dt, i))
- if (i < k)
- terror("Wrong order5\n");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Insert 3.3");
- if ((int) dtinsert(dt, 4) != 4)
- terror("Insert 4.4");
+ /* testing Dtobag */
+ dt = dtopen(&Disc,Dtobag);
+ if((long)dtinsert(dt,5L) != 5)
+ terror("Insert 5.1");
+ if((long)dtinsert(dt,2L) != 2)
+ terror("Insert 2.1");
+ if((long)dtinsert(dt,5L) != 5)
+ terror("Insert 5.2");
+ for(k = 0, i = (long)dtfirst(dt); i; k = i, i = (long)dtnext(dt,i))
+ if(i < k)
+ terror("Wrong order1\n");
+ if((long)dtinsert(dt,3L) != 3)
+ terror("Insert 3.1");
+ if((long)dtinsert(dt,5L) != 5)
+ terror("Insert 5.3");
+ for(k = 0, i = (long)dtfirst(dt); i; k = i, i = (long)dtnext(dt,i))
+ if(i < k)
+ terror("Wrong order2\n");
+ if((long)dtinsert(dt,4L) != 4)
+ terror("Insert 4.1");
+ if((long)dtinsert(dt,1L) != 1)
+ terror("Insert 1");
+ for(k = 0, i = (long)dtfirst(dt); i; k = i, i = (long)dtnext(dt,i))
+ if(i < k)
+ terror("Wrong order3\n");
+ if((long)dtinsert(dt,2L) != 2)
+ terror("Insert 2.2");
+ if((long)dtinsert(dt,5L) != 5)
+ terror("Insert 5.4");
+ if((long)dtinsert(dt,4L) != 4)
+ terror("Insert 4.2");
+ if((long)dtinsert(dt,3L) != 3)
+ terror("Insert 3.2");
+ for(k = 0, i = (long)dtfirst(dt); i; k = i, i = (long)dtnext(dt,i))
+ if(i < k)
+ terror("Wrong order4\n");
+ if((long)dtinsert(dt,4L) != 4)
+ terror("Insert 4.3");
+ if((long)dtinsert(dt,5L) != 5)
+ terror("Insert 5.5");
+ for(k = 0, i = (long)dtfirst(dt); i; k = i, i = (long)dtnext(dt,i))
+ if(i < k)
+ terror("Wrong order5\n");
+ if((long)dtinsert(dt,3L) != 3)
+ terror("Insert 3.3");
+ if((long)dtinsert(dt,4L) != 4)
+ terror("Insert 4.4");
- for (k = 0, i = (int) dtfirst(dt); i; k = i, i = (int) dtnext(dt, i))
- if (i < k)
- terror("Wrong order5\n");
+ for(k = 0, i = (long)dtfirst(dt); i; k = i, i = (long)dtnext(dt,i))
+ if(i < k)
+ terror("Wrong order5\n");
- for (i = 0; i <= 5; ++i)
- count[i] = 0;
- for (i = (int) dtfirst(dt); i; i = (int) dtnext(dt, i))
- count[i] += 1;
- for (i = 0; i <= 5; ++i)
- if (count[i] != i)
- terror("Wrong count\n");
+ for(i = 0; i <= 5; ++i)
+ count[i] = 0;
+ for(i = (long)dtfirst(dt); i; i = (long)dtnext(dt,i))
+ count[i] += 1;
+ for(i = 0; i <= 5; ++i)
+ if(count[i] != i)
+ terror("Wrong count\n");
- for (i = 0; i <= 5; ++i)
- count[i] = 0;
- for (i = (int) dtlast(dt); i; i = (int) dtprev(dt, i))
- count[i] += 1;
- for (i = 0; i <= 5; ++i)
- if (count[i] != i)
- terror("Wrong count2\n");
+ for(i = 0; i <= 5; ++i)
+ count[i] = 0;
+ for(i = (long)dtlast(dt); i; i = (long)dtprev(dt,i))
+ count[i] += 1;
+ for(i = 0; i <= 5; ++i)
+ if(count[i] != i)
+ terror("Wrong count2\n");
- for (k = 0, i = (int) dtfirst(dt); i; k = i, i = (int) dtnext(dt, i))
- if (i < k)
- terror("Wrong order6\n");
+ for(k = 0, i = (long)dtfirst(dt); i; k = i, i = (long)dtnext(dt,i))
+ if(i < k)
+ terror("Wrong order6\n");
- for (link = dtflatten(dt), i = 1; link; ++i) {
- for (k = 1; k <= i; ++k, link = dtlink(dt, link))
- if (i != (int) dtobj(dt, link))
- terror("Bad element\n");
- }
+ for(link = dtflatten(dt), i = 1; link; ++i)
+ { for(k = 1; k <= i; ++k, link = dtlink(dt,link))
+ if(i != (long)dtobj(dt,link))
+ terror("Bad element\n");
+ }
- return 0;
+ return 0;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dttest.h"
-Dtdisc_t Disc = { 0, sizeof(int), -1,
- newint, NIL(Dtfree_f), compare, hashint,
- NIL(Dtmemory_f), NIL(Dtevent_f)
-};
+Dtdisc_t Disc =
+ { 0, sizeof(long), -1,
+ newint, NIL(Dtfree_f), compare, hashint,
+ NIL(Dtmemory_f), NIL(Dtevent_f)
+ };
main()
{
- Dt_t *dt;
- int i;
-
- /* testing Dtqueue */
- if (!(dt = dtopen(&Disc, Dtqueue)))
- terror("dtopen queue");
- if ((int) dtinsert(dt, 1) != 1)
- terror("Dtqueue insert 1");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtqueue insert 3.1");
- if ((int) dtinsert(dt, 2) != 2)
- terror("Dtqueue insert 2.1");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtqueue insert 3.2");
- if ((int) dtinsert(dt, 2) != 2)
- terror("Dtqueue insert 2.2");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtqueue insert 3.3");
-
- if ((int) dtlast(dt) != 3)
- terror("Dtqueue dtlast");
- if ((int) dtprev(dt, 3) != 2)
- terror("Dtqueue dtprev 3.3");
- if ((int) dtprev(dt, 2) != 3)
- terror("Dtqueue dtprev 2.2");
- if ((int) dtprev(dt, 3) != 2)
- terror("Dtqueue dtprev 3.2");
- if ((int) dtprev(dt, 2) != 3)
- terror("Dtqueue dtprev 2.1");
- if ((int) dtprev(dt, 3) != 1)
- terror("Dtqueue dtprev 3.1");
- if ((int) dtprev(dt, 1) != 0)
- terror("Dtqueue dtprev 1");
-
- if ((int) dtdelete(dt, NIL(Void_t *)) != 1)
- terror("Dtqueue pop 1");
- if ((int) dtdelete(dt, NIL(Void_t *)) != 3)
- terror("Dtqueue delete 3.1");
- if ((int) dtdelete(dt, NIL(Void_t *)) != 2)
- terror("Dtqueue delete 2");
- if ((int) dtdelete(dt, NIL(Void_t *)) != 3)
- terror("Dtqueue delete 3.2");
- if ((int) dtdelete(dt, NIL(Void_t *)) != 2)
- terror("Dtqueue delete 2.1");
- if ((int) dtdelete(dt, NIL(Void_t *)) != 3)
- terror("Dtqueue delete 3.3");
-
- if (dtsize(dt) != 0)
- terror("Dtqueue size");
-
- return 0;
+ Dt_t* dt;
+
+ /* testing Dtqueue */
+ if(!(dt = dtopen(&Disc,Dtqueue)) )
+ terror("dtopen queue");
+ if((long)dtinsert(dt,1L) != 1)
+ terror("Dtqueue insert 1");
+ if((long)dtinsert(dt,3L) != 3)
+ terror("Dtqueue insert 3.1");
+ if((long)dtinsert(dt,2L) != 2)
+ terror("Dtqueue insert 2.1");
+ if((long)dtinsert(dt,3L) != 3)
+ terror("Dtqueue insert 3.2");
+ if((long)dtinsert(dt,2L) != 2)
+ terror("Dtqueue insert 2.2");
+ if((long)dtinsert(dt,3L) != 3)
+ terror("Dtqueue insert 3.3");
+
+ if((long)dtlast(dt) != 3)
+ terror("Dtqueue dtlast");
+ if((long)dtprev(dt,3L) != 2)
+ terror("Dtqueue dtprev 3.3");
+ if((long)dtprev(dt,2L) != 3)
+ terror("Dtqueue dtprev 2.2");
+ if((long)dtprev(dt,3L) != 2)
+ terror("Dtqueue dtprev 3.2");
+ if((long)dtprev(dt,2L) != 3)
+ terror("Dtqueue dtprev 2.1");
+ if((long)dtprev(dt,3L) != 1)
+ terror("Dtqueue dtprev 3.1");
+ if((long)dtprev(dt,1L) != 0)
+ terror("Dtqueue dtprev 1");
+
+ if((long)dtdelete(dt,NIL(Void_t*)) != 1)
+ terror("Dtqueue pop 1");
+ if((long)dtdelete(dt,NIL(Void_t*)) != 3)
+ terror("Dtqueue delete 3.1");
+ if((long)dtdelete(dt,NIL(Void_t*)) != 2)
+ terror("Dtqueue delete 2");
+ if((long)dtdelete(dt,NIL(Void_t*)) != 3)
+ terror("Dtqueue delete 3.2");
+ if((long)dtdelete(dt,NIL(Void_t*)) != 2)
+ terror("Dtqueue delete 2.1");
+ if((long)dtdelete(dt,NIL(Void_t*)) != 3)
+ terror("Dtqueue delete 3.3");
+
+ if(dtsize(dt) != 0)
+ terror("Dtqueue size");
+
+ return 0;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
+#include "dttest.h"
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
-#include "cdt.h"
-
-#define NIL(t) ((t)0)
-#define reg register
-
-typedef struct _obj_s {
- Dtlink_t link;
- int key;
+typedef struct _obj_s
+{ Dtlink_t link;
+ long key;
} Obj_t;
#if __STD_C
-compare(Dt_t * dt, Void_t * o1, Void_t * o2, Dtdisc_t * disc)
-#else
-compare(dt, o1, o2, disc)
-Dt_t *dt;
-Void_t *o1;
-Void_t *o2;
-Dtdisc_t *disc;
-#endif
-{
- return ((Obj_t *) o1)->key - ((Obj_t *) o2)->key;
-}
-
-#if __STD_C
-unsigned int hash(Dt_t * dt, Void_t * o, Dtdisc_t * disc)
+static int mycompare(Dt_t* dt, Void_t* o1, Void_t* o2, Dtdisc_t* disc)
#else
-unsigned int hash(dt, o, disc)
-Dt_t *dt;
-Void_t *o;
-Dtdisc_t *disc;
+static int mycompare(dt, o1, o2, disc)
+Dt_t* dt;
+Void_t* o1;
+Void_t* o2;
+Dtdisc_t* disc;
#endif
{
- return (unsigned int) ((Obj_t *) o)->key;
+ return (int)(((Obj_t*)o1)->key - ((Obj_t*)o2)->key);
}
#if __STD_C
-void terror(char *s)
+static unsigned int myhash(Dt_t* dt, Void_t* o, Dtdisc_t* disc)
#else
-void terror(s)
-char *s;
+static unsigned int myhash(dt, o, disc)
+Dt_t* dt;
+Void_t* o;
+Dtdisc_t* disc;
#endif
{
- printf("Error: %s\n", s);
- exit(-1);
+ return (unsigned int)((Obj_t*)o)->key;
}
-Dtdisc_t Disc = { 0, 0, 0,
- NIL(Dtmake_f), NIL(Dtfree_f),
- compare, hash,
- NIL(Dtmemory_f), NIL(Dtevent_f)
-};
+Dtdisc_t Disc =
+ { 0, 0, 0,
+ NIL(Dtmake_f), NIL(Dtfree_f),
+ mycompare, myhash,
+ NIL(Dtmemory_f), NIL(Dtevent_f)
+ };
main()
{
- Dt_t *dt;
- Obj_t *obj, o[6];
- int i;
-
- o[0].key = 1;
- o[1].key = 3;
- o[2].key = 5;
- o[3].key = 7;
- o[4].key = 9;
- o[5].key = 11;
-
- dt = dtopen(&Disc, Dtorder);
- dtinsert(dt, &o[0]);
- dtinsert(dt, &o[2]);
- dtinsert(dt, &o[4]);
- dtinsert(dt, &o[3]);
- dtinsert(dt, &o[1]);
- dtinsert(dt, &o[5]);
-
- if (dtrenew(dt, &o[0]))
- terror("Dtorder: can't renew yet");
-
- if ((Obj_t *) dtsearch(dt, &o[5]) != &o[5])
- terror("Dtorder: search failed");
- o[5].key = 4;
- if ((Obj_t *) dtrenew(dt, &o[5]) != &o[5])
- terror("Dtorder: renew failed");
- if ((Obj_t *) dtnext(dt, dtnext(dt, dtfirst(dt))) != &o[5])
- terror("Dtorder: wrong order after renew");
-
- dtmethod(dt, Dtset);
- if ((Obj_t *) dtsearch(dt, &o[5]) != &o[5])
- terror("Dtset: search failed");
- o[5].key = 11;
- if ((Obj_t *) dtrenew(dt, &o[5]) != &o[5])
- terror("Dtset: renew failed");
- dtmethod(dt, Dtorder);
- if ((Obj_t *) dtlast(dt) != &o[5])
- terror("Dtset: wrong order");
- dtclose(dt);
-
- o[0].key = 1;
- o[1].key = 2;
- o[2].key = 3;
- o[3].key = 4;
- o[4].key = 5;
- o[5].key = 6;
- dt = dtopen(&Disc, Dtlist);
- dtinsert(dt, &o[5]);
- dtinsert(dt, &o[3]);
- dtinsert(dt, &o[1]);
-
- dtsearch(dt, &o[5]);
- dtinsert(dt, &o[4]);
- dtsearch(dt, &o[3]);
- dtinsert(dt, &o[2]);
- dtsearch(dt, &o[1]);
- dtinsert(dt, &o[0]);
- obj = (Obj_t *) dtfirst(dt);
- for (i = 1; obj; obj = (Obj_t *) dtnext(dt, obj), i += 1)
- if (obj->key != i)
- terror("Dtlist: wrong order");
- return 0;
+ Dt_t* dt;
+ Obj_t *obj, o[6];
+ long i;
+
+ o[0].key = 1;
+ o[1].key = 3;
+ o[2].key = 5;
+ o[3].key = 7;
+ o[4].key = 9;
+ o[5].key = 11;
+
+ dt = dtopen(&Disc,Dtorder);
+ dtinsert(dt,&o[0]);
+ dtinsert(dt,&o[2]);
+ dtinsert(dt,&o[4]);
+ dtinsert(dt,&o[3]);
+ dtinsert(dt,&o[1]);
+ dtinsert(dt,&o[5]);
+
+ if(dtrenew(dt,&o[0]) )
+ terror("Dtorder: can't renew yet");
+
+ if((Obj_t*)dtsearch(dt,&o[5]) != &o[5])
+ terror("Dtorder: search failed");
+ o[5].key = 4;
+ if((Obj_t*)dtrenew(dt,&o[5]) != &o[5] )
+ terror("Dtorder: renew failed");
+ if((Obj_t*)dtnext(dt,dtnext(dt,dtfirst(dt))) != &o[5])
+ terror("Dtorder: wrong order after renew");
+
+ dtmethod(dt,Dtset);
+ if((Obj_t*)dtsearch(dt,&o[5]) != &o[5])
+ terror("Dtset: search failed");
+ o[5].key = 11;
+ if((Obj_t*)dtrenew(dt,&o[5]) != &o[5] )
+ terror("Dtset: renew failed");
+ dtmethod(dt,Dtorder);
+ if((Obj_t*)dtlast(dt) != &o[5])
+ terror("Dtset: wrong order");
+ dtclose(dt);
+
+ o[0].key = 1;
+ o[1].key = 2;
+ o[2].key = 3;
+ o[3].key = 4;
+ o[4].key = 5;
+ o[5].key = 6;
+ dt = dtopen(&Disc, Dtlist);
+ dtinsert(dt,&o[5]);
+ dtinsert(dt,&o[3]);
+ dtinsert(dt,&o[1]);
+
+ dtsearch(dt,&o[5]);
+ dtinsert(dt,&o[4]);
+ dtsearch(dt,&o[3]);
+ dtinsert(dt,&o[2]);
+ dtsearch(dt,&o[1]);
+ dtinsert(dt,&o[0]);
+ obj = (Obj_t*)dtfirst(dt);
+ for(i = 1; obj; obj = (Obj_t*)dtnext(dt,obj), i += 1)
+ if(obj->key != i)
+ terror("Dtlist: wrong order");
+ return 0;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dttest.h"
-Dtdisc_t Disc = { 0, sizeof(int), -1,
- newint, NIL(Dtfree_f), compare, hashint,
- NIL(Dtmemory_f), NIL(Dtevent_f)
-};
+Dtdisc_t Disc =
+ { 0, sizeof(long), -1,
+ newint, NIL(Dtfree_f), compare, hashint,
+ NIL(Dtmemory_f), NIL(Dtevent_f)
+ };
-Dtdisc_t Rdisc = { 0, sizeof(int), -1,
- newint, NIL(Dtfree_f), rcompare, hashint,
- NIL(Dtmemory_f), NIL(Dtevent_f)
-};
+Dtdisc_t Rdisc =
+ { 0, sizeof(long), -1,
+ newint, NIL(Dtfree_f), rcompare, hashint,
+ NIL(Dtmemory_f), NIL(Dtevent_f)
+ };
main()
{
- Dt_t *dt;
- Dtlink_t *link;
- int i, k, count[10];
+ Dt_t* dt;
+ Dtlink_t* link;
+ long i, k, count[10];
+
+ /* testing Dtoset */
+ dt = dtopen(&Disc,Dtoset);
+ if((long)dtinsert(dt,7L) != 7)
+ terror("Insert 7");
+ if((long)dtinsert(dt,1L) != 1)
+ terror("Insert 1");
+ if((long)dtinsert(dt,3L) != 3)
+ terror("Insert 3");
+ if((long)dtinsert(dt,4L) != 4)
+ terror("Insert 4");
+ if((long)dtinsert(dt,2L) != 2)
+ terror("Insert 2");
+ if((long)dtinsert(dt,6L) != 6)
+ terror("Insert 6");
+ if((long)dtinsert(dt,7L) != 7)
+ terror("Insert 7,2");
+
+ if((long)dtmost(dt, 5L) != 4)
+ terror("Should have found 4");
+ if(dtfound(dt) )
+ terror("Should not have found 5");
+ if((long)dtleast(dt, 5L) != 6)
+ terror("Should have found 6");
+ if(dtfound(dt) )
+ terror("Should not have found 5");
+
+ if((long)dtinsert(dt,5L) != 5)
+ terror("Insert 5");
+
+ if((long)dtmost(dt, 5L) != 5)
+ terror("Should have found 5");
+ if(!dtfound(dt) )
+ terror("Should have found 5");
+ if((long)dtleast(dt, 3L) != 3)
+ terror("Should have found 3");
+ if(!dtfound(dt) )
+ terror("Should have found 3");
+
+ for(i = 1; i <= 7; ++i)
+ if((long)dtsearch(dt,i) != i)
+ terror("Dtoset search");
+ for(link = dtflatten(dt), i = 1; link; link = dtlink(dt,link), i += 1)
+ if((long)dtobj(dt,link) != i)
+ terror("Dtoset flatten");
+ for(i = (long)dtlast(dt), k = 7; k >= 1; i = (long)dtprev(dt,i), k -= 1)
+ if(i != k)
+ terror("Dtoset backwalk");
- /* testing Dtorder */
- dt = dtopen(&Disc, Dtorder);
- if ((int) dtinsert(dt, 7) != 7)
- terror("Insert 7");
- if ((int) dtinsert(dt, 1) != 1)
- terror("Insert 1");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Insert 3");
- if ((int) dtinsert(dt, 4) != 4)
- terror("Insert 4");
- if ((int) dtinsert(dt, 2) != 2)
- terror("Insert 2");
- if ((int) dtinsert(dt, 6) != 6)
- terror("Insert 6");
- if ((int) dtinsert(dt, 7) != 7)
- terror("Insert 7,2");
- if ((int) dtinsert(dt, 5) != 5)
- terror("Insert 5");
+ /* test macro search function */
+ if(dttreeset(dt,6,1) >= 0)
+ { for(i = 1; i <= 7; ++i)
+ { DTTREEMATCH(dt, i, k = (long) );
+ if(i != k)
+ terror("DTTREEMATCH() failed");
+ }
- for (i = 1; i <= 7; ++i)
- if ((int) dtsearch(dt, i) != i)
- terror("Dtorder search");
- for (link = dtflatten(dt), i = 1; link;
- link = dtlink(dt, link), i += 1)
- if ((int) dtobj(dt, link) != i)
- terror("Dtorder flatten");
- for (i = (int) dtlast(dt), k = 7; k >= 1;
- i = (int) dtprev(dt, i), k -= 1)
- if (i != k)
- terror("Dtorder backwalk");
+ for(i = 1; i <= 7; ++i)
+ { DTTREESEARCH(dt, i, k = (long) );
+ if(i != k)
+ terror("DTTREESEARCH() failed");
+ }
+ }
- /* reverse ordering */
- dtdisc(dt, &Rdisc, 0);
- for (i = 7; i >= 1; --i)
- if ((int) dtsearch(dt, i) != i)
- terror("Dtorder search 2");
- for (i = (int) dtlast(dt), k = 1; k <= 7;
- i = (int) dtprev(dt, i), k += 1)
- if (i != k)
- terror("Dtorder backwalk 2");
- for (link = dtflatten(dt), i = 7; link;
- link = dtlink(dt, link), i -= 1)
- if ((int) dtobj(dt, link) != i)
- terror("Dtorder flatten 2");
+ /* reverse ordering */
+ dtdisc(dt,&Rdisc,0);
+ for(i = 7; i >= 1; --i)
+ if((long)dtsearch(dt,i) != i)
+ terror("Dtoset search 2");
+ for(i = (long)dtlast(dt), k = 1; k <= 7; i = (long)dtprev(dt,i), k += 1)
+ if(i != k)
+ terror("Dtoset backwalk 2");
+ for(link = dtflatten(dt), i = 7; link; link = dtlink(dt,link), i -= 1)
+ if((long)dtobj(dt,link) != i)
+ terror("Dtoset flatten 2");
- if (!(link = dtextract(dt)))
- terror("Fail extracting Dtorder");
- if (dtrestore(dt, link) < 0)
- terror("Fail restoring Dtorder");
- if (dtsize(dt) != 7)
- terror("Dtorder size after extract");
- for (link = dtflatten(dt), i = 7; link;
- link = dtlink(dt, link), i -= 1)
- if ((int) dtobj(dt, link) != i)
- terror("Dtorder flatten after extract");
+ if(!(link = dtextract(dt)) )
+ terror("Fail extracting Dtoset");
+ if(dtrestore(dt,link) < 0)
+ terror("Fail restoring Dtoset");
+ if(dtsize(dt) != 7)
+ terror("Dtoset size after extract");
+ for(link = dtflatten(dt), i = 7; link; link = dtlink(dt,link), i -= 1)
+ if((long)dtobj(dt,link) != i)
+ terror("Dtoset flatten after extract");
- /* change to hashing */
- dtmethod(dt, Dtset);
- for (i = 1; i <= 7; ++i)
- if ((int) dtsearch(dt, i) != i)
- terror("Dtset search");
- for (link = dtflatten(dt), i = 0; link; link = dtlink(dt, link))
- i += 1;
- if (i != 7)
- terror("Dtset flatten");
- for (i = (int) dtlast(dt), k = 0; i != 0; i = (int) dtprev(dt, i))
- k += 1;
- if (k != 7)
- terror("Dtset flatten 2");
+ /* change to hashing */
+ dtmethod(dt,Dtset);
+ for(i = 1; i <= 7; ++i)
+ if((long)dtsearch(dt,i) != i)
+ terror("Dtset search");
+ for(link = dtflatten(dt), i = 0; link; link = dtlink(dt,link))
+ i += 1;
+ if(i != 7)
+ terror("Dtset flatten");
+ for(i = (long)dtlast(dt), k = 0; i != 0; i = (long)dtprev(dt,i))
+ k += 1;
+ if(k != 7)
+ terror("Dtset flatten 2");
- if (!(link = dtextract(dt)))
- terror("Fail extracting Dtset");
- if (dtrestore(dt, link) < 0)
- terror("Fail restoring Dtset");
- if (dtsize(dt) != 7)
- terror("Dtset size after extract");
- for (i = (int) dtlast(dt), k = 0; i != 0; i = (int) dtprev(dt, i))
- k += 1;
- if (k != 7)
- terror("Dtset flatten after extract");
+ if(!(link = dtextract(dt)) )
+ terror("Fail extracting Dtset");
+ if(dtrestore(dt,link) < 0)
+ terror("Fail restoring Dtset");
+ if(dtsize(dt) != 7)
+ terror("Dtset size after extract");
+ for(i = (long)dtlast(dt), k = 0; i != 0; i = (long)dtprev(dt,i))
+ k += 1;
+ if(k != 7)
+ terror("Dtset flatten after extract");
- dtdisc(dt, &Disc, 0);
- for (i = 1; i <= 7; ++i)
- if ((int) dtsearch(dt, i) != i)
- terror("Dtset search 2");
- for (link = dtflatten(dt), i = 0; link; link = dtlink(dt, link))
- i += 1;
- if (i != 7)
- terror("Dtset flatten 2");
+ dtdisc(dt,&Disc,0);
+ for(i = 1; i <= 7; ++i)
+ if((long)dtsearch(dt,i) != i)
+ terror("Dtset search 2");
+ for(link = dtflatten(dt), i = 0; link; link = dtlink(dt,link))
+ i += 1;
+ if(i != 7)
+ terror("Dtset flatten 2");
- dtclear(dt);
- if (dtsize(dt) != 0)
- terror("Dtsize");
+ dtclear(dt);
+ if(dtsize(dt) != 0)
+ terror("Dtsize");
- /* testing Dtlist */
- dtmethod(dt, Dtlist);
- if ((int) dtinsert(dt, 1) != 1)
- terror("Dtlist insert 1.1");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtlist insert 3.1");
- if ((int) dtinsert(dt, 2) != 2)
- terror("Dtlist insert 2.1");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtlist insert 3.2");
- if ((int) dtinsert(dt, 2) != 2)
- terror("Dtlist insert 2.2");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtlist insert 3.3");
- if ((int) dtinsert(dt, 1) != 1)
- terror("Dtlist insert 1.2");
+ /* testing Dtlist */
+ dtmethod(dt,Dtlist);
+ if((long)dtinsert(dt,1) != 1)
+ terror("Dtlist insert 1.1");
+ if((long)dtinsert(dt,3) != 3)
+ terror("Dtlist insert 3.1");
+ if((long)dtinsert(dt,2) != 2)
+ terror("Dtlist insert 2.1");
+ if((long)dtinsert(dt,3) != 3)
+ terror("Dtlist insert 3.2");
+ if((long)dtinsert(dt,2) != 2)
+ terror("Dtlist insert 2.2");
+ if((long)dtinsert(dt,3) != 3)
+ terror("Dtlist insert 3.3");
+ if((long)dtinsert(dt,1) != 1)
+ terror("Dtlist insert 1.2");
- /* check multiplicities */
- for (i = 1; i <= 3; ++i)
- count[i] = 0;
- for (i = (int) dtlast(dt); i != 0; i = (int) dtprev(dt, i))
- count[i] += 1;
- if (count[1] != 2)
- terror("Dtlist count 1");
- if (count[2] != 2)
- terror("Dtlist count 2");
- if (count[3] != 3)
- terror("Dtlist count 3");
+ /* check multiplicities */
+ for(i = 1; i <= 3; ++i)
+ count[i] = 0;
+ for(i = (long)dtlast(dt); i != 0; i = (long)dtprev(dt,i))
+ count[i] += 1;
+ if(count[1] != 2)
+ terror("Dtlist count 1");
+ if(count[2] != 2)
+ terror("Dtlist count 2");
+ if(count[3] != 3)
+ terror("Dtlist count 3");
- dtclear(dt);
- if (dtsize(dt) != 0)
- terror("Dtsize");
+ dtclear(dt);
+ if(dtsize(dt) != 0)
+ terror("Dtsize");
- /* testing Dtbag */
- dtmethod(dt, Dtbag);
- if ((int) dtinsert(dt, 1) != 1)
- terror("Dtlist insert 1.1");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtlist insert 3.1");
- if ((int) dtinsert(dt, 2) != 2)
- terror("Dtlist insert 2.1");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtlist insert 3.2");
- if ((int) dtinsert(dt, 2) != 2)
- terror("Dtlist insert 2.2");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtlist insert 3.3");
- if ((int) dtinsert(dt, 1) != 1)
- terror("Dtlist insert 1.2");
+ /* testing Dtbag */
+ dtmethod(dt,Dtbag);
+ if((long)dtinsert(dt,1) != 1)
+ terror("Dtlist insert 1.1");
+ if((long)dtinsert(dt,3) != 3)
+ terror("Dtlist insert 3.1");
+ if((long)dtinsert(dt,2) != 2)
+ terror("Dtlist insert 2.1");
+ if((long)dtinsert(dt,3) != 3)
+ terror("Dtlist insert 3.2");
+ if((long)dtinsert(dt,2) != 2)
+ terror("Dtlist insert 2.2");
+ if((long)dtinsert(dt,3) != 3)
+ terror("Dtlist insert 3.3");
+ if((long)dtinsert(dt,1) != 1)
+ terror("Dtlist insert 1.2");
- /* check multiplicities */
- for (i = 1; i <= 3; ++i)
- count[i] = 0;
- for (i = (int) dtlast(dt); i != 0; i = (int) dtprev(dt, i))
- count[i] += 1;
- if (count[1] != 2)
- terror("Dtbag count 1");
- if (count[2] != 2)
- terror("Dtbag count 2");
- if (count[3] != 3)
- terror("Dtbag count 3");
+ /* check multiplicities */
+ for(i = 1; i <= 3; ++i)
+ count[i] = 0;
+ for(i = (long)dtlast(dt); i != 0; i = (long)dtprev(dt,i))
+ count[i] += 1;
+ if(count[1] != 2)
+ terror("Dtbag count 1");
+ if(count[2] != 2)
+ terror("Dtbag count 2");
+ if(count[3] != 3)
+ terror("Dtbag count 3");
- /* test consecutive 1's */
- if ((int) dtsearch(dt, 1) != 1)
- terror("Dtbag search 1");
- if ((int) dtnext(dt, 1) != 1)
- terror("Dtbag next 1");
- if ((int) dtnext(dt, 1) == 1)
- terror("Dtbag next not expecting 1");
+ /* test consecutive 1's */
+ if((long)dtsearch(dt,1) != 1)
+ terror("Dtbag search 1");
+ if((long)dtnext(dt,1) != 1)
+ terror("Dtbag next 1");
+ if((long)dtnext(dt,1) == 1)
+ terror("Dtbag next not expecting 1");
- /* test consecutive 2's */
- if ((int) dtsearch(dt, 2) != 2)
- terror("Dtbag search 2");
- if ((int) dtnext(dt, 2) != 2)
- terror("Dtbag next 2");
- if ((int) dtnext(dt, 2) == 2)
- terror("Dtbag next not expecting 2");
+ /* test consecutive 2's */
+ if((long)dtsearch(dt,2) != 2)
+ terror("Dtbag search 2");
+ if((long)dtnext(dt,2) != 2)
+ terror("Dtbag next 2");
+ if((long)dtnext(dt,2) == 2)
+ terror("Dtbag next not expecting 2");
- /* test consecutive 3's */
- if ((int) dtsearch(dt, 3) != 3)
- terror("Dtbag search 3");
- if ((int) dtnext(dt, 3) != 3)
- terror("Dtbag next 3");
- if ((int) dtnext(dt, 3) != 3)
- terror("Dtbag next 3.2");
- if ((int) dtnext(dt, 3) == 3)
- terror("Dtbag next not expecting 3");
+ /* test consecutive 3's */
+ if((long)dtsearch(dt,3) != 3)
+ terror("Dtbag search 3");
+ if((long)dtnext(dt,3) != 3)
+ terror("Dtbag next 3");
+ if((long)dtnext(dt,3) != 3)
+ terror("Dtbag next 3.2");
+ if((long)dtnext(dt,3) == 3)
+ terror("Dtbag next not expecting 3");
- /* change method to Dtobag */
- dtmethod(dt, Dtobag);
+ /* change method to Dtobag */
+ dtmethod(dt,Dtobag);
- /* check multiplicities */
- for (i = 1; i <= 3; ++i)
- count[i] = 0;
- for (i = (int) dtfirst(dt); i != 0; i = (int) dtnext(dt, i))
- count[i] += 1;
- if (count[1] != 2)
- terror("Dtobag count 1");
- if (count[2] != 2)
- terror("Dtobag count 2");
- if (count[3] != 3)
- terror("Dtobag count 3");
+ /* check multiplicities */
+ for(i = 1; i <= 3; ++i)
+ count[i] = 0;
+ for(i = (long)dtfirst(dt); i != 0; i = (long)dtnext(dt,i))
+ count[i] += 1;
+ if(count[1] != 2)
+ terror("Dtobag count 1");
+ if(count[2] != 2)
+ terror("Dtobag count 2");
+ if(count[3] != 3)
+ terror("Dtobag count 3");
- /* test consecutive 1's */
- if ((int) dtsearch(dt, 1) != 1)
- terror("Dtobag search 1");
- if ((int) dtnext(dt, 1) != 1)
- terror("Dtobag next 1");
- if ((int) dtnext(dt, 1) != 2)
- terror("Dtobag next should be 2");
+ /* test consecutive 1's */
+ if((long)dtsearch(dt,1) != 1)
+ terror("Dtobag search 1");
+ if((long)dtnext(dt,1) != 1)
+ terror("Dtobag next 1");
+ if((long)dtnext(dt,1) != 2)
+ terror("Dtobag next should be 2");
- /* test consecutive 2's */
- if ((int) dtsearch(dt, 2) != 2)
- terror("Dtobag search 2");
- if ((int) dtnext(dt, 2) != 2)
- terror("Dtobag next 2");
- if ((int) dtnext(dt, 2) != 3)
- terror("Dtobag next should be 3");
+ /* test consecutive 2's */
+ if((long)dtsearch(dt,2) != 2)
+ terror("Dtobag search 2");
+ if((long)dtnext(dt,2) != 2)
+ terror("Dtobag next 2");
+ if((long)dtnext(dt,2) != 3)
+ terror("Dtobag next should be 3");
- /* test consecutive 3's */
- if ((int) dtsearch(dt, 3) != 3)
- terror("Dtobag search 3");
- if ((int) dtnext(dt, 3) != 3)
- terror("Dtobag next 3");
- if ((int) dtnext(dt, 3) != 3)
- terror("Dtobag next 3.2");
- if ((int) dtnext(dt, 3) == 3)
- terror("Dtobag next not expecting 3");
+ /* test consecutive 3's */
+ if((long)dtsearch(dt,3) != 3)
+ terror("Dtobag search 3");
+ if((long)dtnext(dt,3) != 3)
+ terror("Dtobag next 3");
+ if((long)dtnext(dt,3) != 3)
+ terror("Dtobag next 3.2");
+ if((long)dtnext(dt,3) == 3)
+ terror("Dtobag next not expecting 3");
- /* test large set of values */
- dtclear(dt);
- dtmethod(dt, Dtset);
- for (i = 1; i < 20000; ++i)
- if ((int) dtinsert(dt, i) != i)
- terror("Can't insert");
- dtmethod(dt, Dtoset);
- for (i = 1, k = (int) dtfirst(dt); i < 20000;
- ++i, k = (int) dtnext(dt, k))
- if (i != k)
- terror("Bad value");
+ /* test large set of values */
+ dtclear(dt);
+ dtmethod(dt,Dtset);
+ for(i = 1; i < 20000; ++i)
+ if((long)dtinsert(dt,i) != i)
+ terror("Can't insert");
+ dtmethod(dt,Dtoset);
+ for(i = 1, k = (long)dtfirst(dt); i < 20000; ++i, k = (long)dtnext(dt,k))
+ if(i != k)
+ terror("Bad value");
- return 0;
+ return 0;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dttest.h"
-static Void_t *Space[1024];
-static char *Current = (char *) (&Space[0]);
+static Void_t* Space[1024];
+static char* Current = (char*)(&Space[0]);
#if __STD_C
-static int event(Dt_t * dt, int type, Void_t * obj, Dtdisc_t * disc)
+static int event(Dt_t* dt, int type, Void_t* obj, Dtdisc_t* disc)
#else
static int event(dt, type, obj, disc)
-Dt_t *dt;
-int type;
-Void_t *obj;
-Dtdisc_t *disc;
+Dt_t* dt;
+int type;
+Void_t* obj;
+Dtdisc_t* disc;
#endif
-{
- if (type != DT_OPEN)
- return 0;
+{ if(type != DT_OPEN)
+ return 0;
- /* opening first dictionary */
- if (Current == (char *) (&Space[0]))
- return 0;
- else { /* opening a dictionary sharing with some previous one */
- *((Void_t **) obj) = (Void_t *) (&Space[0]);
- return 1;
- }
+ /* opening first dictionary */
+ if(Current == (char*)(&Space[0]))
+ return 0;
+ else /* opening a dictionary sharing with some previous one */
+ { *((Void_t**)obj) = (Void_t*)(&Space[0]);
+ return 1;
+ }
}
#if __STD_C
-static Void_t *memory(Dt_t * dt, Void_t * buf, size_t size,
- Dtdisc_t * disc)
+static Void_t* memory(Dt_t* dt, Void_t* buf, size_t size, Dtdisc_t* disc)
#else
-static Void_t *memory(dt, buf, size, disc)
-Dt_t *dt;
-Void_t *buf;
-size_t size;
-Dtdisc_t *disc;
+static Void_t* memory(dt,buf,size,disc)
+Dt_t* dt;
+Void_t* buf;
+size_t size;
+Dtdisc_t* disc;
#endif
{
- if (!buf) {
- size =
- ((size + sizeof(Void_t *) -
- 1) / sizeof(Void_t *)) * sizeof(Void_t *);
- buf = (Void_t *) Current;
- Current += size;
- }
- return buf;
+ if(!buf)
+ { size = ((size + sizeof(Void_t*)-1)/sizeof(Void_t*))*sizeof(Void_t*);
+ buf = (Void_t*)Current;
+ Current += size;
+ }
+ return buf;
}
-Dtdisc_t Disc = { 0, sizeof(int), -1,
- newint, NIL(Dtfree_f), compare, hashint,
- memory, event
-};
+Dtdisc_t Disc =
+ { 0, sizeof(long), -1,
+ newint, NIL(Dtfree_f), compare, hashint,
+ memory, event
+ };
main()
{
- Dt_t *dt1, *dt2;
- int i, k;
+ Dt_t *dt1, *dt2;
+ long i, k;
- if (!(dt1 = dtopen(&Disc, Dtorder)))
- terror("Opening Dtorder1");
- if ((int) dtinsert(dt1, 1) != 1)
- terror("Inserting 1");
- if ((int) dtinsert(dt1, 3) != 3)
- terror("Inserting 3");
- if ((int) dtinsert(dt1, 5) != 5)
- terror("Inserting 5");
+ if(!(dt1 = dtopen(&Disc,Dtorder)) )
+ terror("Opening Dtorder1");
+ if((long)dtinsert(dt1,1L) != 1)
+ terror("Inserting 1");
+ if((long)dtinsert(dt1,3L) != 3)
+ terror("Inserting 3");
+ if((long)dtinsert(dt1,5L) != 5)
+ terror("Inserting 5");
- if (!(dt2 = dtopen(&Disc, Dtorder)))
- terror("Opening Dtorder2");
- if ((int) dtinsert(dt2, 2) != 2)
- terror("Inserting 2");
- if ((int) dtinsert(dt2, 4) != 4)
- terror("Inserting 4");
- if ((int) dtinsert(dt2, 6) != 6)
- terror("Inserting 6");
+ if(!(dt2 = dtopen(&Disc,Dtorder)) )
+ terror("Opening Dtorder2");
+ if((long)dtinsert(dt2,2L) != 2)
+ terror("Inserting 2");
+ if((long)dtinsert(dt2,4L) != 4)
+ terror("Inserting 4");
+ if((long)dtinsert(dt2,6L) != 6)
+ terror("Inserting 6");
- for (i = 1; i <= 6; ++i)
- if ((int) dtsearch(dt1, i) != i)
- terror("Didn't find an int");
+ for(i = 1; i <= 6; ++i)
+ if((long)dtsearch(dt1,i) != i)
+ terror("Didn't find a long");
- for (i = (int) dtlast(dt2), k = 6; i != 0;
- i = (int) dtprev(dt2, i), k -= 1)
- if (i != k)
- terror("Didn't walk an int");
+ for(i = (long)dtlast(dt2), k = 6; i != 0; i = (long)dtprev(dt2,i), k -= 1)
+ if(i != k)
+ terror("Didn't walk a long");
- return 0;
+ return 0;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dttest.h"
-Dtdisc_t Disc = { 0, sizeof(int), -1,
- newint, NIL(Dtfree_f), compare, hashint,
- NIL(Dtmemory_f), NIL(Dtevent_f)
-};
+Dtdisc_t Disc =
+ { 0, sizeof(long), -1,
+ newint, NIL(Dtfree_f), compare, hashint,
+ NIL(Dtmemory_f), NIL(Dtevent_f)
+ };
main()
{
- Dt_t *dt;
- int i;
+ Dt_t* dt;
- /* testing Dtstack */
- if (!(dt = dtopen(&Disc, Dtstack)))
- terror("dtopen stack");
- if ((int) dtinsert(dt, 1) != 1)
- terror("Dtstack insert 1");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtstack insert 3.1");
- if ((int) dtinsert(dt, 2) != 2)
- terror("Dtstack insert 2.1");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtstack insert 3.2");
- if ((int) dtinsert(dt, 2) != 2)
- terror("Dtstack insert 2.2");
- if ((int) dtinsert(dt, 3) != 3)
- terror("Dtstack insert 3.3");
+ /* testing Dtstack */
+ if(!(dt = dtopen(&Disc,Dtstack)) )
+ terror("dtopen stack");
+ if((long)dtinsert(dt,1L) != 1)
+ terror("Dtstack insert 1");
+ if((long)dtinsert(dt,3L) != 3)
+ terror("Dtstack insert 3.1");
+ if((long)dtinsert(dt,2L) != 2)
+ terror("Dtstack insert 2.1");
+ if((long)dtinsert(dt,3L) != 3)
+ terror("Dtstack insert 3.2");
+ if((long)dtinsert(dt,2L) != 2)
+ terror("Dtstack insert 2.2");
+ if((long)dtinsert(dt,3L) != 3)
+ terror("Dtstack insert 3.3");
- if ((int) dtlast(dt) != 1)
- terror("Dtstack dtlast");
- if ((int) dtprev(dt, 1) != 3)
- terror("Dtstack dtprev 1");
- if ((int) dtprev(dt, 3) != 2)
- terror("Dtstack dtprev 3.1");
- if ((int) dtprev(dt, 2) != 3)
- terror("Dtstack dtprev 2.1");
- if ((int) dtprev(dt, 3) != 2)
- terror("Dtstack dtprev 3.2");
- if ((int) dtprev(dt, 2) != 3)
- terror("Dtstack dtprev 2.2");
- if ((int) dtprev(dt, 3) != 0)
- terror("Dtstack dtprev 3.2");
+ if((long)dtlast(dt) != 1)
+ terror("Dtstack dtlast");
+ if((long)dtprev(dt,1L) != 3)
+ terror("Dtstack dtprev 1");
+ if((long)dtprev(dt,3L) != 2)
+ terror("Dtstack dtprev 3.1");
+ if((long)dtprev(dt,2L) != 3)
+ terror("Dtstack dtprev 2.1");
+ if((long)dtprev(dt,3L) != 2)
+ terror("Dtstack dtprev 3.2");
+ if((long)dtprev(dt,2L) != 3)
+ terror("Dtstack dtprev 2.2");
+ if((long)dtprev(dt,3L) != 0)
+ terror("Dtstack dtprev 3.2");
- if ((int) dtdelete(dt, NIL(Void_t *)) != 3)
- terror("Dtstack pop 3.3");
+ if((long)dtdelete(dt,NIL(Void_t*)) != 3)
+ terror("Dtstack pop 3.3");
- /* search to one of the 3 */
- if ((int) dtsearch(dt, 3) != 3)
- terror("Dtstack search 3.2");
- if ((int) dtdelete(dt, 3) != 3)
- terror("Dtstack delete 3.2");
+ /* search to one of the 3 */
+ if((long)dtsearch(dt,3L) != 3)
+ terror("Dtstack search 3.2");
+ if((long)dtdelete(dt,3L) != 3)
+ terror("Dtstack delete 3.2");
- if ((int) dtdelete(dt, NIL(Void_t *)) != 2)
- terror("Dtstack pop 2.2");
- if ((int) dtdelete(dt, NIL(Void_t *)) != 2)
- terror("Dtstack pop 2.1");
- if ((int) dtdelete(dt, NIL(Void_t *)) != 3)
- terror("Dtstack pop 3.1");
- if ((int) dtdelete(dt, NIL(Void_t *)) != 1)
- terror("Dtstack pop 1");
+ if((long)dtdelete(dt,NIL(Void_t*)) != 2)
+ terror("Dtstack pop 2.2");
+ if((long)dtdelete(dt,NIL(Void_t*)) != 2)
+ terror("Dtstack pop 2.1");
+ if((long)dtdelete(dt,NIL(Void_t*)) != 3)
+ terror("Dtstack pop 3.1");
+ if((long)dtdelete(dt,NIL(Void_t*)) != 1)
+ terror("Dtstack pop 1");
- if (dtsize(dt) != 0)
- terror("Dtstack size");
+ if(dtsize(dt) != 0)
+ terror("Dtstack size");
- return 0;
+ return 0;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dttest.h"
-Dtdisc_t Disc = { 0, sizeof(int), -1,
- newint, NIL(Dtfree_f), compare, hashint,
- NIL(Dtmemory_f), NIL(Dtevent_f)
-};
+Dtdisc_t Disc =
+ { 0, sizeof(long), -1,
+ newint, NIL(Dtfree_f), compare, hashint,
+ NIL(Dtmemory_f), NIL(Dtevent_f)
+ };
static int Count, See[10];
#if __STD_C
-static visit(Dt_t * dt, Void_t * obj, Void_t * data)
+static visit(Dt_t* dt, Void_t* obj, Void_t* data)
#else
static visit(dt, obj, data)
-Dt_t *dt;
-Void_t *obj;
-Void_t *data;
+Dt_t* dt;
+Void_t* obj;
+Void_t* data;
#endif
{
- See[(int) obj] = 1;
- Count += 1;
- return 0;
+ See[(long)obj] = 1;
+ Count += 1;
+ return 0;
}
main()
{
- Dt_t *dt1, *dt2;
- int i;
-
- if (!(dt1 = dtopen(&Disc, Dtset)))
- terror("Opening Dtset");
- if (!(dt2 = dtopen(&Disc, Dtorder)))
- terror("Opening Dtorder");
-
- dtinsert(dt1, 1);
- dtinsert(dt1, 3);
- dtinsert(dt1, 5);
-
- dtinsert(dt2, 2);
- dtinsert(dt2, 4);
- dtinsert(dt2, 6);
-
- if ((int) dtsearch(dt1, 2) != 0)
- terror("Can't find 2 here!");
-
- dtview(dt1, dt2);
- if ((int) dtsearch(dt1, 2) != 2)
- terror("Should find 2 here!");
-
- dtwalk(dt1, visit, NIL(Void_t *));
- if (Count != 6)
- terror("Walk wrong length");
- for (i = 1; i <= 6; ++i)
- if (!See[i])
- terror("Bad walk");
-
- dtinsert(dt1, 2);
-
- Count = 0;
- for (i = (int) dtfirst(dt1); i; i = (int) dtnext(dt1, i))
- Count++;
- if (Count != 6)
- terror("Walk wrong length2");
-
- Count = 0;
- for (i = (int) dtlast(dt1); i; i = (int) dtprev(dt1, i))
- Count++;
- if (Count != 6)
- terror("Walk wrong length3");
-
- /* dt1: 1 3 5 2
- dt2: 2 4 6 3
- */
- Count = 0;
- dtmethod(dt2, Dtset);
- dtinsert(dt2, 3);
- for (i = (int) dtfirst(dt1); i; i = (int) dtnext(dt1, i)) {
- dtsearch(dt1, 4);
- Count++;
- }
- if (Count != 6)
- terror("Walk wrong length4");
-
- return 0;
+ Dt_t *dt1, *dt2;
+ long i;
+
+ if(!(dt1 = dtopen(&Disc,Dtoset)) )
+ terror("Opening Dtoset");
+ if(!(dt2 = dtopen(&Disc,Dtoset)) )
+ terror("Opening Dtoset");
+
+ dtinsert(dt1,1L);
+ dtinsert(dt1,3L);
+ dtinsert(dt1,5L);
+ dtinsert(dt1,2L);
+
+ dtinsert(dt2,2L);
+ dtinsert(dt2,4L);
+ dtinsert(dt2,6L);
+ dtinsert(dt2,3L);
+
+ if((long)dtsearch(dt1,4L) != 0)
+ terror("Finding 4 here?");
+
+ dtview(dt1,dt2);
+ if((long)dtsearch(dt1,4L) != 4)
+ terror("Should find 4 here!");
+
+ dtwalk(dt1,visit,NIL(Void_t*));
+ if(Count != 6)
+ terror("Walk wrong length");
+ for(i = 1; i <= 6; ++i)
+ if(!See[i] )
+ terror("Bad walk");
+
+ dtinsert(dt1,2L);
+
+ Count = 0;
+ for(i = (long)dtfirst(dt1); i; i = (long)dtnext(dt1,i))
+ Count++;
+ if(Count != 6)
+ terror("Walk wrong length2");
+
+ Count = 0;
+ for(i = (long)dtlast(dt1); i; i = (long)dtprev(dt1,i))
+ Count++;
+ if(Count != 6)
+ terror("Walk wrong length3");
+
+ /* dt1: 1 3 5 2
+ dt2: 2 4 6 3
+ */
+ Count = 0;
+ dtmethod(dt1,Dtset);
+ dtmethod(dt2,Dtset);
+ for(i = (long)dtfirst(dt1); i; i = (long)dtnext(dt1,i))
+ Count++;
+ if(Count != 6)
+ terror("Walk wrong length4");
+
+ return 0;
}
libcdt_C_la_SOURCES = dtclose.c dtdisc.c dtextract.c dtflatten.c \
dthash.c dtlist.c dtmethod.c dtopen.c dtrenew.c dtrestore.c dtsize.c \
- dtstat.c dtstrhash.c dttree.c dtview.c dtwalk.c
+ dtstat.c dtstrhash.c dttree.c dttreeset.c dtview.c dtwalk.c
libcdt_la_LDFLAGS = -version-info $(CDT_VERSION) -no-undefined
libcdt_la_SOURCES = $(libcdt_C_la_SOURCES)
HDRS = cdt.h dthdr.h
SRCS = dtclose.c dtdisc.c dtflatten.c dthash.c dtmethod.c dtopen.c dtsize.c \
- dtextract.c dtrestore.c dtlist.c dtstat.c dttree.c dtview.c \
+ dtextract.c dtrestore.c dtlist.c dtstat.c dttree.c dttreeset.c dtview.c \
dtrenew.c dtwalk.c dtstrhash.c
OBJS = dtclose.o dtdisc.o dtflatten.o dthash.o dtmethod.o dtopen.o dtsize.o \
- dtextract.o dtrestore.o dtlist.o dtstat.o dttree.o dtview.o \
+ dtextract.o dtrestore.o dtlist.o dtstat.o dttree.o dttreeset.o dtview.o \
dtrenew.o dtwalk.o dtstrhash.o
SRC_P= Cdt_p/tsearch.c Cdt_p/hsearch.c
OBJ_P= tsearch.o hsearch.o
+.fp 5 CW
.TH LIBCDT 3
.SH NAME
\fBCdt\fR \- container data types
..
.ta 1.0i 2.0i 3.0i 4.0i 5.0i
.Cs
-#include <graphviz/cdt.h>
+#include <cdt.h>
.Ce
.Ss "DICTIONARY TYPES"
.Cs
.Ce
.Ss "DICTIONARY CONTROL"
.Cs
-Dt_t* dtopen(Dtdisc_t* disc, Dtmethod_t* meth);
+Dt_t* dtopen(const Dtdisc_t* disc, const Dtmethod_t* meth);
int dtclose(Dt_t* dt);
void dtclear(dt);
-Dtmethod_t* dtmethod(Dt_t* dt, Dtmethod_t* meth);
-Dtdisc_t* dtdisc(Dt_t* dt, Dtdisc_t* disc, int type);
+Dtmethod_t* dtmethod(Dt_t* dt, const Dtmethod_t* meth);
+Dtdisc_t* dtdisc(Dt_t* dt, const Dtdisc_t* disc, int type);
Dt_t* dtview(Dt_t* dt, Dt_t* view);
+int dttreeset(Dt_t* dt, int minp, int balance);
.Ce
.Ss "STORAGE METHODS"
.Cs
Dtmethod_t* Dtlist;
Dtmethod_t* Dtstack;
Dtmethod_t* Dtqueue;
+Dtmethod_t* Dtdeque;
.Ce
.Ss "DISCIPLINE"
.Cs
+#define DTOFFSET(struct_s,member)
+#define DTDISC(disc,key,size,link,makef,freef,comparf,hashf,memoryf,eventf)
typedef Void_t* (*Dtmake_f)(Dt_t*, Void_t*, Dtdisc_t*);
typedef void (*Dtfree_f)(Dt_t*, Void_t*, Dtdisc_t*);
typedef int (*Dtcompar_f)(Dt_t*, Void_t*, Void_t*, Dtdisc_t*);
.Ss "OBJECT OPERATIONS"
.Cs
Void_t* dtinsert(Dt_t* dt, Void_t* obj);
+Void_t* dtappend(Dt_t* dt, Void_t* obj);
Void_t* dtdelete(Dt_t* dt, Void_t* obj);
+Void_t* dtattach(Dt_t* dt, Void_t* obj);
+Void_t* dtdetach(Dt_t* dt, Void_t* obj);
Void_t* dtsearch(Dt_t* dt, Void_t* obj);
Void_t* dtmatch(Dt_t* dt, Void_t* key);
Void_t* dtfirst(Dt_t* dt);
Void_t* dtobj(Dt_t* dt, Dtlink_t* link);
Dtlink_t* dtextract(Dt_t* dt);
int dtrestore(Dt_t* dt, Dtlink_t* link);
+
+#define DTTREESEARCH(Dt_t* dt, Void_t* obj, action)
+#define DTTREEMATCH(Dt_t* dt, Void_t* key, action)
.Ce
.Ss "DICTIONARY STATUS"
.Cs
.PP
.Ss "DICTIONARY CONTROL"
.PP
-.Ss " Dt_t* dtopen(Dtdisc_t* disc, Dtmethod_t* meth)"
+.Ss " Dt_t* dtopen(const Dtdisc_t* disc, const Dtmethod_t* meth)"
This creates a new dictionary.
\f5disc\fP is a discipline structure to describe object format.
\f5meth\fP specifies a manipulation method.
\f5dtopen()\fP returns the new dictionary or \f5NULL\fP on error.
+See also the events \f5DT_OPEN\fP and \f5DT_ENDOPEN\fP below.
.PP
.Ss " int dtclose(Dt_t* dt)"
This deletes \f5dt\fP and its objects.
Note that \f5dtclose()\fP fails if \f5dt\fP is being viewed by
some other dictionaries (see \f5dtview()\fP).
\f5dtclose()\fP returns \f50\fP on success and \f5-1\fP on error.
+See also the events \f5DT_CLOSE\fP and \f5DT_ENDCLOSE\fP below.
.PP
.Ss " void dtclear(Dt_t* dt)"
This deletes all objects in \f5dt\fP without closing \f5dt\fP.
.PP
-.Ss " Dtmethod_t dtmethod(Dt_t* dt, Dtmethod_t* meth)"
+.Ss " Dtmethod_t dtmethod(Dt_t* dt, const Dtmethod_t* meth)"
If \f5meth\fP is \f5NULL\fP, \f5dtmethod()\fP returns the current method.
Otherwise, it changes the storage method of \f5dt\fP to \f5meth\fP.
Object order remains the same during a
-method switch among \f5Dtlist\fP, \f5Dtstack\fP and \f5Dtqueue\fP.
+method switch among \f5Dtlist\fP, \f5Dtstack\fP, \f5Dtqueue\fP and \f5Dtdeque\fP.
Switching to and from \f5Dtset/Dtbag\fP and \f5Dtoset/Dtobag\fP may cause
objects to be rehashed, reordered, or removed as the case requires.
\f5dtmethod()\fP returns the previous method or \f5NULL\fP on error.
.PP
-.Ss " Dtdisc_t* dtdisc(Dt_t* dt, Dtdisc_t* disc, int type)"
+.Ss " Dtdisc_t* dtdisc(Dt_t* dt, const Dtdisc_t* disc, int type)"
If \f5disc\fP is \f5NULL\fP, \f5dtdisc()\fP returns the current discipline.
Otherwise, it changes the discipline of \f5dt\fP to \f5disc\fP.
Objects may be rehashed, reordered, or removed as appropriate.
If \f5view\fP is not \f5NULL\fP, a viewpath from \f5dt\fP to \f5view\fP is established.
\f5dtview()\fP returns \f5dt\fP on success and \f5NULL\fP on error.
.PP
-If two dictionaries on the same viewpath have the same values for the discipline fields
-\f5Dtdisc_t.link\fP, \f5Dtdisc_t.key\fP, \f5Dtdisc_t.size\fP, and \f5Dtdisc_t.hashf\fP,
-it is expected that key hashing will be the same.
-If not, undefined behaviors may result during a search or a walk.
+It is an error to have dictionaries on a viewpath with different storage methods.
+In addition, dictionaries on the same view path should
+treat objects in a consistent manner with respect to comparison or hashing.
+If not, undefined behaviors may result.
+.PP
+.Ss " int dttreeset(Dt_t* dt, int minp, int balance)"
+This function only applies to dictionaries operated under the method \f5Dtoset\fP
+which uses top-down splay trees (see below). It returns 0 on success and -1 on error.
+.Tp
+\f5minp\fP:
+This parameter defines the minimum path length before a search path is adjusted.
+For example, \f5minp\fP equal 0 would mean that search paths are always adjusted.
+If \f5minp\fP is negative, the minimum search path is internally computed based
+on a function of the current dictionary size. This computed value is such that
+if the tree is balanced, it will never require adjusting.
+.Tp
+\f5balance\fP:
+If this is non-zero, the tree will be made balanced.
.PP
.Ss "STORAGE METHODS"
.PP
\f5Dtset\fP keeps unique objects.
\f5Dtbag\fP allows repeatable objects and always keeps them together
(note the effect on dictionary walking.)
+These methods use a hash table with chaining to manage the objects.
+See also the event \f5DT_HASHSIZE\fP below on how to manage hash table
+resizing when objects are inserted.
.PP
.Ss " Dtlist"
Objects are kept in a list.
-New objects are inserted either
-in front of \fIcurrent object\fP (see \f5dtfinger()\fP) if this is defined
-or at list front if there is no current object.
+The call \f5dtinsert()\fP inserts a new object
+in front of \fIthe current object\fP (see \f5dtfinger()\fP) if it is defined
+or at list front if no current object is defined.
+Similarly, the call \f5dtappend()\fP appends a new object
+after \fIthe current object\fP (see \f5dtfinger()\fP) if it is defined
+or at list end if no current object is defined.
+.PP
+.Ss " Dtdeque"
+Objects are kept in a deque. This is similar to \f5Dtlist\fP
+except that objects are always inserted at the front and appended at the tail
+of the list.
.PP
.Ss " Dtstack"
Objects are kept in a stack, i.e., in reverse order of insertion.
.PP
.Ss " Void_t* (*makef)(Dt_t* dt, Void_t* obj, Dtdisc_t* disc)"
If \f5makef\fP is not \f5NULL\fP,
-\f5dtinsert(dt,obj)\fP will call it
+\f5dtinsert(dt,obj)\fP or \f5dtappend()\fP will call it
to make a copy of \f5obj\fP suitable for insertion into \f5dt\fP.
If \f5makef\fP is \f5NULL\fP, \f5obj\fP itself will be inserted into \f5dt\fP.
.PP
If \f5addr\fP is not \f5NULL\fP and \f5size\fP is positive,
\f5addr\fP is to be resized to the given size.
If \f5memoryf\fP is \f5NULL\fP, \fImalloc(3)\fP is used.
-When dictionaries share memory,
-a record of the first allocated memory segment should be kept
-so that it can be used to initialize new dictionaries (see below.)
.PP
.Ss " int (*eventf)(Dt_t* dt, int type, Void_t* data, Dtdisc_t* disc)"
If not \f5NULL\fP, \f5eventf\fP announces various events.
-If it returns a negative value, the calling operation will terminate with failure.
-Unless noted otherwise, a non-negative return value let the
-calling function proceed normally. Following are the events:
+Each event may have particular handling of the return values from \f5eventf\fP.
+But a negative return value typically means failure.
+Following are the events:
.Tp
\f5DT_OPEN\fP:
\f5dt\fP is being opened.
-If \f5eventf\fP returns zero, the opening process proceeds normally.
-A positive return value indicates that \f5dt\fP
-uses memory already initialized by a different dictionary.
-In that case, \f5*(Void_t**)data\fP should be set to
-the first allocated memory segment as discussed in \f5memoryf\fP.
-\f5dtopen()\fP may fail if this segment is not returned or
-if it has not been properly initialized.
+If \f5eventf\fP returns negative, the opening process terminates with failure.
+If \f5eventf\fP returns zero, the opening process proceeds in a default manner.
+A positive return value indicates special treatment of memory as follows.
+If \f5*(Void_t**)data\fP is set to point to some memory segment
+as discussed in \f5memoryf\fP, that segment of memory is used to start
+the dictionary. If \f5*(Void_t**)data\fP is \f5NULL\fP,
+all memory including that of the dictionary handle itself
+will be allocated via \f5memoryf\fP.
+.Tp
+\f5DT_ENDOPEN\fP:
+This event announces that \f5dtopen()\fP has successfully opened
+a dictionary and is about to return. The \f5data\fP argument of
+\f5eventf\fP should be the new dictionary handle itself.
.Tp
\f5DT_CLOSE\fP:
-\f5dt\fP is being closed.
+\f5dt\fP is about to be closed. If \f5eventf\fP returns negative,
+the closing process stops immediately and \f5dtclose()\fP returns -1.
+Objects in the dictionary are deleted only if \f5eventf\fP returns zero.
+The dictionary handle itself is processed as follows.
+If it was allocated via \f5malloc()\fP, it will be freed.
+If it was allocated via \f5memoryf\fP (see \f5dtopen()\fP) and \f5eventf\fP
+returns 0, a call to \f5memoryf\fP will be issued to attempt freeing the handle.
+Otherwise, nothing will be done to its memory.
+
+As should be clear from their description,
+the events \f5DT_OPEN\fP and \f5DT_CLOSE\fP are designed to be used along
+with \f5memoryf\fP to manage the allocation and deallocation of dictionary and
+object memory across dictionaries. In fact, they can be used to manage
+dictionaries based on shared and/or persistent memory.
+.Tp
+\f5DT_ENDCLOSE\fP:
+This event announces that \f5dtclose()\fP has successfully closed
+a dictionary and is about to return.
.Tp
\f5DT_DISC\fP:
The discipline of \f5dt\fP is being changed to a new one given in
\f5DT_METH\fP:
The method of \f5dt\fP is being changed to a new one given in
\f5(Dtmethod_t*)data\fP.
+.Tp
+\f5DT_HASHSIZE\fP:
+The hash table (for \f5Dtset\fP and \f5Dtbag\fP) is being resized.
+In this case, \f5*(int*)data\fP has the current size of the table.
+The application can set the new table size by first changing
+\f5*(int*)data\fP to the desired size, then return a positive value.
+The application can also fix the table size at the current value
+forever by setting \f5*(int*)data\fP to a negative value, then
+again return a positive value. A non-positive return value from
+the event handling function means that Cdt will be responsible
+for choosing the hash table size.
+.PP
+.Ss "#define DTOFFSET(struct_s,member)"
+This macro function computes the offset of \f5member\fP from the start
+of structure \f5struct_s\fP. It is useful for getting the offset of
+a \f5Dtlink_t\fP embedded inside an object.
+.PP
+.Ss "#define DTDISC(disc,key,size,link,makef,freef,comparf,hashf,memoryf,eventf)"
+This macro function initializes the discipline pointed to by \f5disc\fP
+with the given values.
.PP
.Ss "OBJECT OPERATIONS"
.PP
.Ss " Void_t* dtinsert(Dt_t* dt, Void_t* obj)"
-This inserts an object prototyped by \f5obj\fP into \f5dt\fP.
+.Ss " Void_t* dtappend(Dt_t* dt, Void_t* obj)"
+These functions add an object prototyped by \f5obj\fP into \f5dt\fP.
+\f5dtinsert()\fP and \f5dtappend()\fP perform the same function
+for all methods except for \f5Dtlist\fP. See \f5Dtlist\fP for details.
If there is an existing object in \f5dt\fP matching \f5obj\fP
and the storage method is \f5Dtset\fP or \f5Dtoset\fP,
-\f5dtinsert()\fP will simply return the matching object.
+\f5dtinsert()\fP and \f5dtappend()\fP will simply return the matching object.
Otherwise, a new object is inserted according to the method in use.
See \f5Dtdisc_t.makef\fP for object construction.
-\f5dtinsert()\fP returns the new object, a matching object as noted,
-or \f5NULL\fP on error.
+The new object or a matching object as noted will be returned on success
+while \f5NULL\fP is returned on error.
.PP
.Ss " Void_t* dtdelete(Dt_t* dt, Void_t* obj)"
-If \f5obj\fP is not \f5NULL\fP, the first object matching it is deleted.
If \f5obj\fP is \f5NULL\fP, methods \f5Dtstack\fP and \f5Dtqueue\fP
delete respectively stack top or queue head while other methods do nothing.
+If \f5obj\fP is not \f5NULL\fP, there are two cases.
+If the method in use is not \f5Dtbag\fP or \f5Dtobag\fP,
+the first object matching \f5obj\fP is deleted.
+On the other hand, if the method in use is \f5Dtbag\fP or \f5Dtobag\fP,
+the library check to see if \f5obj\fP is in the dictionary and delete it.
+If \f5obj\fP is not in the dictionary, some object matching it will be deleted.
See \f5Dtdisc_t.freef\fP for object destruction.
\f5dtdelete()\fP returns the deleted object (even if it was deallocated)
or \f5NULL\fP on error.
.PP
+.Ss " Void_t* dtattach(Dt_t* dt, Void_t* obj)"
+This function is similar to \f5dtinsert()\fP but \f5obj\fP itself
+will be inserted into \f5dt\fP even if a discipline
+function \f5makef\fP is defined.
+.PP
+.Ss " Void_t* dtdetach(Dt_t* dt, Void_t* obj)"
+This function is similar to \f5dtdelete()\fP but the object to be deleted
+from \f5dt\fP will not be freed (via the discipline \f5freef\fP function).
+.PP
.Ss " Void_t* dtsearch(Dt_t* dt, Void_t* obj)"
.Ss " Void_t* dtmatch(Dt_t* dt, Void_t* key)"
These functions find an object matching \f5obj\fP or \f5key\fP either from \f5dt\fP or
For \f5Dtqueue\fP, objects are ordered in order of insertion.
For \f5Dtlist\fP, objects are ordered by list position.
For \f5Dtset\fP and \f5Dtbag\fP,
-objects use some internal ordering which
-may change on any search, insert, or delete operations.
-Therefore, these operations should not be used
-during a walk on a dictionary using either \f5Dtset\fP or \f5Dtbag\fP.
-.PP
-Objects in a dictionary or a viewpath can be walked using
+objects are ordered by some internal order (more below).
+Thus, objects in a dictionary or a viewpath can be walked using
a \f5for(;;)\fP loop as below.
-Note that only one loop can be used at a time per dictionary.
-Concurrent or nested loops may result in unexpected behaviors.
.Cs
for(obj = dtfirst(dt); obj; obj = dtnext(dt,obj))
.Ce
+When a dictionary uses \f5Dtset\fP or \f5Dtbag\fP,
+the object order is determined upon a call to \f5dtfirst()\fP/\f5dtlast()\fP.
+This order is frozen until a call \f5dtnext()\fP/\f5dtprev()\fP returns \f5NULL\fP
+or when these same functions are called with a \f5NULL\fP object argument.
+It is important that a \f5dtfirst()/dtlast()\fP call be
+balanced by a \f5dtnext()/dtprev()\fP call as described.
+Nested loops will require multiple balancing, once per loop.
+If loop balancing is not done carefully, either performance is degraded
+or unexpected behaviors may result.
.Ss " Void_t* dtlast(Dt_t* dt)"
.Ss " Void_t* dtprev(Dt_t* dt, Void_t* obj)"
\f5dtlast()\fP and \f5dtprev()\fP are like \f5dtfirst()\fP and \f5dtnext()\fP
Note that \f5dtflatten()\fP returns a list of type \f5Dtlink_t*\fP,
not \f5Void_t*\fP. That is, it returns a dictionary holder pointer,
not a user object pointer
-(although both are the same if the discipline field \f5link\fP is non-negative.)
+(although both are the same if the discipline field \f5link\fP is zero.)
The macro function \f5dtlink()\fP
returns the dictionary holder object following \f5link\fP.
The macro function \f5dtobj(dt,link)\fP
These functions can be used
to share a same \f5dt\fP handle among many sets of objects.
They are useful to reduce dictionary overhead
-in an application that creates concurrently many dictionaries.
+in an application that creates many concurrent dictionaries.
It is important that the same discipline and method are in use at both
extraction and restoration. Otherwise, undefined behaviors may result.
+.PP
+.Ss " #define DTTREESEARCH(Dt_t* dt, Void_t* obj, action)"
+.Ss " #define DTTREEMATCH(Dt_t* dt, Void_t* key, action)"
+These macro functions are analogues of \f5dtsearch()\fP and \f5dtmatch()\fP
+but they can only be used on a dictionary based on a binary
+search tree, i.e., \f5Dtoset\fP or \f5Dtobag\fP.
+.Tp
+\f5obj\fP or \f5key\fP:
+These are used to find a matching object. If there is no match,
+the result is \f5NULL\fP.
+.Tp
+\f5action\fP:
+The matching object \f5o\fP (which may be \f5NULL\fP) will be processed as follow:
+
+.Cs
+ action (o);
+.Ce
+
+Since \f5action\fP is used verbatim, it can be any C code
+fragment combinable with \f5(o)\fP to form a syntactically correct C statement.
+For example, suppose that the matching object is an integer, the below code
+accumulates the integer value in a variable \f5total\fP:
+
+.Cs
+ DTTREEMATCH(dt, key, total += (int));
+.Ce
+
.PP
.Ss "DICTIONARY INFORMATION"
.PP
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#ifndef _CDT_H
#define _CDT_H 1
/* Public interface for the dictionary library
**
-** Written by Kiem-Phong Vo (05/25/96)
+** Written by Kiem-Phong Vo
*/
-#define CDT_VERSION 19991101L
-
-#define Void_t void
-#define _ARG_(x) x
-#ifndef NIL
-#define NIL(type) ((type)0)
-#endif
-
-#include <string.h>
+#define CDT_VERSION 20050420L
#if _PACKAGE_ast
-# include <ast_std.h>
-#elif _BLD_cdt
-# include "ast_common.h"
+#include <ast_std.h>
+#else
+#include <ast_common.h>
#endif
-#ifdef __cplusplus
-extern "C" {
-#endif
+typedef struct _dtlink_s Dtlink_t;
+typedef struct _dthold_s Dthold_t;
+typedef struct _dtdisc_s Dtdisc_t;
+typedef struct _dtmethod_s Dtmethod_t;
+typedef struct _dtdata_s Dtdata_t;
+typedef struct _dt_s Dt_t;
+typedef struct _dt_s Dict_t; /* for libdict compatibility */
+typedef struct _dtstat_s Dtstat_t;
+typedef Void_t* (*Dtsearch_f)_ARG_((Dt_t*,Void_t*,int));
+typedef Void_t* (*Dtmake_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*));
+typedef void (*Dtfree_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*));
+typedef int (*Dtcompar_f)_ARG_((Dt_t*,Void_t*,Void_t*,Dtdisc_t*));
+typedef unsigned int (*Dthash_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*));
+typedef Void_t* (*Dtmemory_f)_ARG_((Dt_t*,Void_t*,size_t,Dtdisc_t*));
+typedef int (*Dtevent_f)_ARG_((Dt_t*,int,Void_t*,Dtdisc_t*));
- typedef struct _dtlink_s Dtlink_t;
- typedef struct _dthold_s Dthold_t;
- typedef struct _dtdisc_s Dtdisc_t;
- typedef struct _dtmethod_s Dtmethod_t;
- typedef struct _dtdata_s Dtdata_t;
- typedef struct _dt_s Dt_t;
- typedef struct _dt_s Dict_t; /* for libdict compatibility */
- typedef struct _dtstat_s Dtstat_t;
- typedef Void_t *(*Dtsearch_f) _ARG_((Dt_t *, Void_t *, int));
- typedef Void_t *(*Dtmake_f) _ARG_((Dt_t *, Void_t *, Dtdisc_t *));
- typedef void (*Dtfree_f) _ARG_((Dt_t *, Void_t *, Dtdisc_t *));
- typedef int (*Dtcompar_f)
- _ARG_((Dt_t *, Void_t *, Void_t *, Dtdisc_t *));
- typedef unsigned int (*Dthash_f) _ARG_((Dt_t *, Void_t *, Dtdisc_t *));
- typedef Void_t *(*Dtmemory_f)
- _ARG_((Dt_t *, Void_t *, size_t, Dtdisc_t *));
- typedef int (*Dtevent_f) _ARG_((Dt_t *, int, Void_t *, Dtdisc_t *));
-
- struct _dtlink_s {
- Dtlink_t *right; /* right child */
- union {
- unsigned int _hash; /* hash value */
- Dtlink_t *_left; /* left child */
+struct _dtlink_s
+{ Dtlink_t* right; /* right child */
+ union
+ { unsigned int _hash; /* hash value */
+ Dtlink_t* _left; /* left child */
} hl;
- };
+};
/* private structure to hold an object */
- struct _dthold_s {
- Dtlink_t hdr; /* header */
- Void_t *obj; /* user object */
- };
+struct _dthold_s
+{ Dtlink_t hdr; /* header */
+ Void_t* obj; /* user object */
+};
/* method to manipulate dictionary structure */
- struct _dtmethod_s {
- Dtsearch_f searchf; /* search function */
- int type; /* type of operation */
- };
+struct _dtmethod_s
+{ Dtsearch_f searchf; /* search function */
+ int type; /* type of operation */
+};
/* stuff that may be in shared memory */
- struct _dtdata_s {
- int type; /* type of dictionary */
- Dtlink_t *here; /* finger to last search element */
- union {
- Dtlink_t **_htab; /* hash table */
- Dtlink_t *_head; /* linked list */
+struct _dtdata_s
+{ int type; /* type of dictionary */
+ Dtlink_t* here; /* finger to last search element */
+ union
+ { Dtlink_t** _htab; /* hash table */
+ Dtlink_t* _head; /* linked list */
} hh;
- int ntab; /* number of hash slots */
- int size; /* number of objects */
- int loop; /* number of nested loops */
- };
+ int ntab; /* number of hash slots */
+ int size; /* number of objects */
+ int loop; /* number of nested loops */
+ int minp; /* min path before splay, always even */
+ /* for hash dt, > 0: fixed table size */
+};
/* structure to hold methods that manipulate an object */
- struct _dtdisc_s {
- int key; /* where the key begins in an object */
- int size; /* key size and type */
- int link; /* offset to Dtlink_t field */
- Dtmake_f makef; /* object constructor */
- Dtfree_f freef; /* object destructor */
- Dtcompar_f comparf; /* to compare two objects */
- Dthash_f hashf; /* to compute hash value of an object */
- Dtmemory_f memoryf; /* to allocate/free memory */
- Dtevent_f eventf; /* to process events */
- };
+struct _dtdisc_s
+{ int key; /* where the key begins in an object */
+ int size; /* key size and type */
+ int link; /* offset to Dtlink_t field */
+ Dtmake_f makef; /* object constructor */
+ Dtfree_f freef; /* object destructor */
+ Dtcompar_f comparf;/* to compare two objects */
+ Dthash_f hashf; /* to compute hash value of an object */
+ Dtmemory_f memoryf;/* to allocate/free memory */
+ Dtevent_f eventf; /* to process events */
+};
+
+#define DTDISC(dc,ky,sz,lk,mkf,frf,cmpf,hshf,memf,evf) \
+ ( (dc)->key = (ky), (dc)->size = (sz), (dc)->link = (lk), \
+ (dc)->makef = (mkf), (dc)->freef = (frf), \
+ (dc)->comparf = (cmpf), (dc)->hashf = (hshf), \
+ (dc)->memoryf = (memf), (dc)->eventf = (evf) )
+
+#ifdef offsetof
+#define DTOFFSET(struct_s, member) offsetof(struct_s, member)
+#else
+#define DTOFFSET(struct_s, member) ((int)(&((struct_s*)0)->member))
+#endif
/* the dictionary structure itself */
- struct _dt_s {
- Dtsearch_f searchf; /* search function */
- Dtdisc_t *disc; /* method to manipulate objs */
- Dtdata_t *data; /* sharable data */
- Dtmemory_f memoryf; /* function to alloc/free memory */
- Dtmethod_t *meth; /* dictionary method */
- int type; /* type information */
- int nview; /* number of parent view dictionaries */
- Dt_t *view; /* next on viewpath */
- Dt_t *walk; /* dictionary being walked */
- };
+struct _dt_s
+{ Dtsearch_f searchf;/* search function */
+ Dtdisc_t* disc; /* method to manipulate objs */
+ Dtdata_t* data; /* sharable data */
+ Dtmemory_f memoryf;/* function to alloc/free memory */
+ Dtmethod_t* meth; /* dictionary method */
+ int type; /* type information */
+ int nview; /* number of parent view dictionaries */
+ Dt_t* view; /* next on viewpath */
+ Dt_t* walk; /* dictionary being walked */
+ Void_t* user; /* for user's usage */
+};
/* structure to get status of a dictionary */
- struct _dtstat_s {
- int dt_meth; /* method type */
- int dt_size; /* number of elements */
- int dt_n; /* number of chains or levels */
- int dt_max; /* max size of a chain or a level */
- int *dt_count; /* counts of chains or levels by size */
- };
+struct _dtstat_s
+{ int dt_meth; /* method type */
+ int dt_size; /* number of elements */
+ int dt_n; /* number of chains or levels */
+ int dt_max; /* max size of a chain or a level */
+ int* dt_count; /* counts of chains or levels by size */
+};
+
+/* flag set if the last search operation actually found the object */
+#define DT_FOUND 0100000
/* supported storage methods */
-#define DT_SET 0000001 /* set with unique elements */
-#define DT_BAG 0000002 /* multiset */
-#define DT_OSET 0000004 /* ordered set (self-adjusting tree) */
-#define DT_OBAG 0000010 /* ordered multiset */
-#define DT_LIST 0000020 /* linked list */
-#define DT_STACK 0000040 /* stack */
-#define DT_QUEUE 0000100 /* queue */
-#define DT_METHODS 0000177 /* all currently supported methods */
+#define DT_SET 0000001 /* set with unique elements */
+#define DT_BAG 0000002 /* multiset */
+#define DT_OSET 0000004 /* ordered set (self-adjusting tree) */
+#define DT_OBAG 0000010 /* ordered multiset */
+#define DT_LIST 0000020 /* linked list */
+#define DT_STACK 0000040 /* stack: insert/delete at top */
+#define DT_QUEUE 0000100 /* queue: insert at top, delete at tail */
+#define DT_DEQUE 0000200 /* deque: insert at top, append at tail */
+#define DT_METHODS 0000377 /* all currently supported methods */
/* asserts to dtdisc() */
-#define DT_SAMECMP 0000001 /* compare methods equivalent */
-#define DT_SAMEHASH 0000002 /* hash methods equivalent */
+#define DT_SAMECMP 0000001 /* compare methods equivalent */
+#define DT_SAMEHASH 0000002 /* hash methods equivalent */
/* types of search */
-#define DT_INSERT 0000001 /* insert object if not found */
-#define DT_DELETE 0000002 /* delete object if found */
-#define DT_SEARCH 0000004 /* look for an object */
-#define DT_NEXT 0000010 /* look for next element */
-#define DT_PREV 0000020 /* find previous element */
-#define DT_RENEW 0000040 /* renewing an object */
-#define DT_CLEAR 0000100 /* clearing all objects */
-#define DT_FIRST 0000200 /* get first object */
-#define DT_LAST 0000400 /* get last object */
-#define DT_MATCH 0001000 /* find object matching key */
-#define DT_VSEARCH 0002000 /* search using internal representation */
-#define DT_ATTACH 0004000 /* attach an object to the dictionary */
-#define DT_DETACH 0010000 /* attach an object to the dictionary */
+#define DT_INSERT 0000001 /* insert object if not found */
+#define DT_DELETE 0000002 /* delete object if found */
+#define DT_SEARCH 0000004 /* look for an object */
+#define DT_NEXT 0000010 /* look for next element */
+#define DT_PREV 0000020 /* find previous element */
+#define DT_RENEW 0000040 /* renewing an object */
+#define DT_CLEAR 0000100 /* clearing all objects */
+#define DT_FIRST 0000200 /* get first object */
+#define DT_LAST 0000400 /* get last object */
+#define DT_MATCH 0001000 /* find object matching key */
+#define DT_VSEARCH 0002000 /* search using internal representation */
+#define DT_ATTACH 0004000 /* attach an object to the dictionary */
+#define DT_DETACH 0010000 /* detach an object from the dictionary */
+#define DT_APPEND 0020000 /* used on Dtlist to append an object */
/* events */
-#define DT_OPEN 1 /* a dictionary is being opened */
-#define DT_CLOSE 2 /* a dictionary is being closed */
-#define DT_DISC 3 /* discipline is about to be changed */
-#define DT_METH 4 /* method is about to be changed */
-
+#define DT_OPEN 1 /* a dictionary is being opened */
+#define DT_CLOSE 2 /* a dictionary is being closed */
+#define DT_DISC 3 /* discipline is about to be changed */
+#define DT_METH 4 /* method is about to be changed */
+#define DT_ENDOPEN 5 /* dtopen() is done */
+#define DT_ENDCLOSE 6 /* dtclose() is done */
+#define DT_HASHSIZE 7 /* setting hash table size */
+_BEGIN_EXTERNS_ /* public data */
#if _BLD_cdt && defined(__EXPORT__)
#define extern __EXPORT__
#endif
-#if !_BLD_cdt && defined(GVDLL)
-#define extern __declspec(dllimport)
-#endif
#if !_BLD_cdt && defined(__IMPORT__)
#define extern __IMPORT__
#endif
-/*visual studio*/
-#ifdef WIN32_DLL
-#ifndef CDT_EXPORTS
-#define extern __declspec(dllimport)
-#else
-#define extern __declspec(dllexport)
-#endif
-#endif
-/*end visual studio*/
-
- extern Dtmethod_t *Dtset;
- extern Dtmethod_t *Dtbag;
- extern Dtmethod_t *Dtoset;
- extern Dtmethod_t *Dtobag;
- extern Dtmethod_t *Dtlist;
- extern Dtmethod_t *Dtstack;
- extern Dtmethod_t *Dtqueue;
+extern Dtmethod_t* Dtset;
+extern Dtmethod_t* Dtbag;
+extern Dtmethod_t* Dtoset;
+extern Dtmethod_t* Dtobag;
+extern Dtmethod_t* Dtlist;
+extern Dtmethod_t* Dtstack;
+extern Dtmethod_t* Dtqueue;
+extern Dtmethod_t* Dtdeque;
/* compatibility stuff; will go away */
#ifndef KPVDEL
- extern Dtmethod_t *Dtorder;
- extern Dtmethod_t *Dttree;
- extern Dtmethod_t *Dthash;
- extern Dtmethod_t _Dttree;
- extern Dtmethod_t _Dthash;
- extern Dtmethod_t _Dtlist;
- extern Dtmethod_t _Dtqueue;
- extern Dtmethod_t _Dtstack;
+extern Dtmethod_t* Dtorder;
+extern Dtmethod_t* Dttree;
+extern Dtmethod_t* Dthash;
+extern Dtmethod_t _Dttree;
+extern Dtmethod_t _Dthash;
+extern Dtmethod_t _Dtlist;
+extern Dtmethod_t _Dtqueue;
+extern Dtmethod_t _Dtstack;
#endif
#undef extern
+_END_EXTERNS_
+
+_BEGIN_EXTERNS_ /* public functions */
#if _BLD_cdt && defined(__EXPORT__)
#define extern __EXPORT__
#endif
-#if !_BLD_cdt && defined(__IMPORT__) && defined(__EXPORT__)
-#define extern __IMPORT__
-#endif
- extern Dt_t *dtopen _ARG_((Dtdisc_t *, Dtmethod_t *));
- extern int dtclose _ARG_((Dt_t *));
- extern Dt_t *dtview _ARG_((Dt_t *, Dt_t *));
- extern Dtdisc_t *dtdisc _ARG_((Dt_t * dt, Dtdisc_t *, int));
- extern Dtmethod_t *dtmethod _ARG_((Dt_t *, Dtmethod_t *));
- extern Dtlink_t *dtflatten _ARG_((Dt_t *));
- extern Dtlink_t *dtextract _ARG_((Dt_t *));
- extern int dtrestore _ARG_((Dt_t *, Dtlink_t *));
+extern Dt_t* dtopen _ARG_((Dtdisc_t*, Dtmethod_t*));
+extern int dtclose _ARG_((Dt_t*));
+extern Dt_t* dtview _ARG_((Dt_t*, Dt_t*));
+extern Dtdisc_t* dtdisc _ARG_((Dt_t* dt, Dtdisc_t*, int));
+extern Dtmethod_t* dtmethod _ARG_((Dt_t*, Dtmethod_t*));
+
+extern Dtlink_t* dtflatten _ARG_((Dt_t*));
+extern Dtlink_t* dtextract _ARG_((Dt_t*));
+extern int dtrestore _ARG_((Dt_t*, Dtlink_t*));
+
+extern int dttreeset _ARG_((Dt_t*, int, int));
- extern int dtwalk
- _ARG_((Dt_t *, int (*)(Dt_t *, Void_t *, Void_t *), Void_t *));
+extern int dtwalk _ARG_((Dt_t*, int(*)(Dt_t*,Void_t*,Void_t*), Void_t*));
- extern Void_t *dtrenew _ARG_((Dt_t *, Void_t *));
+extern Void_t* dtrenew _ARG_((Dt_t*, Void_t*));
- extern int dtsize _ARG_((Dt_t *));
- extern int dtstat _ARG_((Dt_t *, Dtstat_t *, int));
- extern unsigned int dtstrhash _ARG_((unsigned int, Void_t *, int));
+extern int dtsize _ARG_((Dt_t*));
+extern int dtstat _ARG_((Dt_t*, Dtstat_t*, int));
+extern unsigned int dtstrhash _ARG_((unsigned int, Void_t*, int));
+
+#if !_PACKAGE_ast
+extern int memcmp _ARG_((const Void_t*, const Void_t*, size_t));
+extern int strcmp _ARG_((const char*, const char*));
+#endif
#undef extern
+_END_EXTERNS_
+
+/* internal functions for translating among holder, object and key */
+#define _DT(dt) ((Dt_t*)(dt))
+#define _DTDSC(dc,ky,sz,lk,cmpf) \
+ (ky = dc->key, sz = dc->size, lk = dc->link, cmpf = dc->comparf)
+#define _DTLNK(o,lk) ((Dtlink_t*)((char*)(o) + lk) )
+#define _DTOBJ(e,lk) (lk < 0 ? ((Dthold_t*)(e))->obj : (Void_t*)((char*)(e) - lk) )
+#define _DTKEY(o,ky,sz) (Void_t*)(sz < 0 ? *((char**)((char*)(o)+ky)) : ((char*)(o)+ky))
+
+#define _DTCMP(dt,k1,k2,dc,cmpf,sz) \
+ (cmpf ? (*cmpf)(dt,k1,k2,dc) : \
+ (sz <= 0 ? strcmp(k1,k2) : memcmp(k1,k2,sz)) )
+#define _DTHSH(dt,ky,dc,sz) (dc->hashf ? (*dc->hashf)(dt,ky,dc) : dtstrhash(0,ky,sz) )
+
+/* special search function for tree structure only */
+#define _DTMTCH(dt,key,action) \
+ do { Dtlink_t* _e; Void_t *_o, *_k, *_key; Dtdisc_t* _dc; \
+ int _ky, _sz, _lk, _cmp; Dtcompar_f _cmpf; \
+ _dc = (dt)->disc; _DTDSC(_dc, _ky, _sz, _lk, _cmpf); \
+ _key = (key); \
+ for(_e = (dt)->data->here; _e; _e = _cmp < 0 ? _e->hl._left : _e->right) \
+ { _o = _DTOBJ(_e, _lk); _k = _DTKEY(_o, _ky, _sz); \
+ if((_cmp = _DTCMP((dt), _key, _k, _dc, _cmpf, _sz)) == 0) \
+ break; \
+ } \
+ action (_e ? _o : (Void_t*)0); \
+ } while(0)
+
+#define _DTSRCH(dt,obj,action) \
+ do { Dtlink_t* _e; Void_t *_o, *_k, *_key; Dtdisc_t* _dc; \
+ int _ky, _sz, _lk, _cmp; Dtcompar_f _cmpf; \
+ _dc = (dt)->disc; _DTDSC(_dc, _ky, _sz, _lk, _cmpf); \
+ _key = _DTKEY(obj, _ky, _sz); \
+ for(_e = (dt)->data->here; _e; _e = _cmp < 0 ? _e->hl._left : _e->right) \
+ { _o = _DTOBJ(_e, _lk); _k = _DTKEY(_o, _ky, _sz); \
+ if((_cmp = _DTCMP((dt), _key, _k, _dc, _cmpf, _sz)) == 0) \
+ break; \
+ } \
+ action (_e ? _o : (Void_t*)0); \
+ } while(0)
+
+#define DTTREEMATCH(dt,key,action) _DTMTCH(_DT(dt),(Void_t*)(key),action)
+#define DTTREESEARCH(dt,obj,action) _DTSRCH(_DT(dt),(Void_t*)(obj),action)
+
+#define dtvnext(d) (_DT(d)->view)
+#define dtvcount(d) (_DT(d)->nview)
+#define dtvhere(d) (_DT(d)->walk)
-#define _DT_(d) ((Dt_t*)(d))
-#define dtvnext(d) (_DT_(d)->view)
-#define dtvcount(d) (_DT_(d)->nview)
-#define dtvhere(d) (_DT_(d)->walk)
#define dtlink(d,e) (((Dtlink_t*)(e))->right)
-#define dtobj(d,e) ((_DT_(d)->disc->link < 0) ? (((Dthold_t*)(e))->obj) : \
- (Void_t*)((char*)(e) - _DT_(d)->disc->link) )
-#define dtfinger(d) (_DT_(d)->data->here ? dtobj((d),_DT_(d)->data->here) : \
- (Void_t*)(0) )
-#define dtfirst(d) (*(_DT_(d)->searchf))((d),(Void_t*)(0),DT_FIRST)
-#define dtnext(d,o) (*(_DT_(d)->searchf))((d),(Void_t*)(o),DT_NEXT)
-#define dtlast(d) (*(_DT_(d)->searchf))((d),(Void_t*)(0),DT_LAST)
-#define dtprev(d,o) (*(_DT_(d)->searchf))((d),(Void_t*)(o),DT_PREV)
-#define dtsearch(d,o) (*(_DT_(d)->searchf))((d),(Void_t*)(o),DT_SEARCH)
-#define dtmatch(d,o) (*(_DT_(d)->searchf))((d),(Void_t*)(o),DT_MATCH)
-#define dtinsert(d,o) (*(_DT_(d)->searchf))((d),(Void_t*)(o),DT_INSERT)
-#define dtdelete(d,o) (*(_DT_(d)->searchf))((d),(Void_t*)(o),DT_DELETE)
-#define dtattach(d,o) (*(_DT_(d)->searchf))((d),(Void_t*)(o),DT_ATTACH)
-#define dtdetach(d,o) (*(_DT_(d)->searchf))((d),(Void_t*)(o),DT_DETACH)
-#define dtclear(d) (*(_DT_(d)->searchf))((d),(Void_t*)(0),DT_CLEAR)
-/* A linear congruential hash: h*17 + c + 97531 */
-#define dtcharhash(h,c) ((((unsigned int)(h))<<4) + ((unsigned int)(h)) + \
- ((unsigned char)(c)) + 97531 )
-#ifdef __cplusplus
-}
-#endif
-#endif /* _CDT_H */
+#define dtobj(d,e) _DTOBJ((e), _DT(d)->disc->link)
+#define dtfinger(d) (_DT(d)->data->here ? dtobj((d),_DT(d)->data->here):(Void_t*)(0))
+
+#define dtfirst(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_FIRST)
+#define dtnext(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_NEXT)
+#define dtleast(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_SEARCH|DT_NEXT)
+#define dtlast(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_LAST)
+#define dtprev(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_PREV)
+#define dtmost(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_SEARCH|DT_PREV)
+#define dtsearch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_SEARCH)
+#define dtmatch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_MATCH)
+#define dtinsert(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_INSERT)
+#define dtappend(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_INSERT|DT_APPEND)
+#define dtdelete(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_DELETE)
+#define dtattach(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_ATTACH)
+#define dtdetach(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_DETACH)
+#define dtclear(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_CLEAR)
+#define dtfound(d) (_DT(d)->type & DT_FOUND)
+
+#define DT_PRIME 17109811 /* 2#00000001 00000101 00010011 00110011 */
+#define dtcharhash(h,c) (((unsigned int)(h) + (unsigned int)(c)) * DT_PRIME )
+
+#endif /* _CDT_H */
RelativePath=".\dttree.c"
>
</File>
+ <File
+ RelativePath=".\dttreeset.c"
+ >
+ </File>
<File
RelativePath=".\dtview.c"
>
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Close a dictionary
**
** Written by Kiem-Phong Vo (05/25/96)
*/
#if __STD_C
-int dtclose(reg Dt_t * dt)
+int dtclose(reg Dt_t* dt)
#else
int dtclose(dt)
-reg Dt_t *dt;
+reg Dt_t* dt;
#endif
{
- if (dt->nview > 0) /* can't close if being viewed */
- return -1;
+ Dtdisc_t *disc;
+ int ev = 0;
+
+ if(!dt || dt->nview > 0 ) /* can't close if being viewed */
+ return -1;
+
+ /* announce the close event to see if we should continue */
+ disc = dt->disc;
+ if(disc->eventf &&
+ (ev = (*disc->eventf)(dt,DT_CLOSE,NIL(Void_t*),disc)) < 0)
+ return -1;
- if (dt->view) /* turn off viewing */
- dtview(dt, NIL(Dt_t *));
+ if(dt->view) /* turn off viewing */
+ dtview(dt,NIL(Dt_t*));
- /* announce the close event */
- if (dt->disc->eventf &&
- (*dt->disc->eventf) (dt, DT_CLOSE, NIL(Void_t *), dt->disc) < 0)
- return -1;
+ if(ev == 0) /* release all allocated data */
+ { (void)(*(dt->meth->searchf))(dt,NIL(Void_t*),DT_CLEAR);
+ if(dtsize(dt) > 0)
+ return -1;
- /* release all allocated data */
- (void) (*(dt->meth->searchf)) (dt, NIL(Void_t *), DT_CLEAR);
- if (dtsize(dt) > 0)
- return -1;
+ if(dt->data->ntab > 0)
+ (*dt->memoryf)(dt,(Void_t*)dt->data->htab,0,disc);
+ (*dt->memoryf)(dt,(Void_t*)dt->data,0,disc);
+ }
- if (dt->data->ntab > 0)
- (*dt->memoryf) (dt, (Void_t *) dt->data->htab, 0, dt->disc);
- (*dt->memoryf) (dt, (Void_t *) dt->data, 0, dt->disc);
+ if(dt->type == DT_MALLOC)
+ free((Void_t*)dt);
+ else if(ev == 0 && dt->type == DT_MEMORYF)
+ (*dt->memoryf)(dt, (Void_t*)dt, 0, disc);
- free((Void_t *) dt);
+ if(disc->eventf)
+ (void)(*disc->eventf)(dt, DT_ENDCLOSE, NIL(Void_t*), disc);
- return 0;
+ return 0;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Change discipline.
** dt : dictionary
** disc : discipline
*/
#if __STD_C
-static Void_t *dtmemory(Dt_t * dt, Void_t * addr, size_t size,
- Dtdisc_t * disc)
+static Void_t* dtmemory(Dt_t* dt,Void_t* addr,size_t size,Dtdisc_t* disc)
#else
-static Void_t *dtmemory(dt, addr, size, disc)
-Dt_t *dt; /* dictionary */
-Void_t *addr; /* address to be manipulate */
-size_t size; /* size to obtain */
-Dtdisc_t *disc; /* discipline */
+static Void_t* dtmemory(dt, addr, size, disc)
+Dt_t* dt; /* dictionary */
+Void_t* addr; /* address to be manipulate */
+size_t size; /* size to obtain */
+Dtdisc_t* disc; /* discipline */
#endif
{
- if (addr) {
- if (size == 0) {
- free(addr);
- return NIL(Void_t *);
- } else
- return realloc(addr, size);
- } else
- return size > 0 ? malloc(size) : NIL(Void_t *);
+ if(addr)
+ { if(size == 0)
+ { free(addr);
+ return NIL(Void_t*);
+ }
+ else return realloc(addr,size);
+ }
+ else return size > 0 ? malloc(size) : NIL(Void_t*);
}
#if __STD_C
-Dtdisc_t *dtdisc(Dt_t * dt, Dtdisc_t * disc, int type)
+Dtdisc_t* dtdisc(Dt_t* dt, Dtdisc_t* disc, int type)
#else
-Dtdisc_t *dtdisc(dt, disc, type)
-Dt_t *dt;
-Dtdisc_t *disc;
-int type;
+Dtdisc_t* dtdisc(dt,disc,type)
+Dt_t* dt;
+Dtdisc_t* disc;
+int type;
#endif
{
- reg Dtsearch_f searchf;
- reg Dtlink_t *r, *t;
- reg char *k;
- reg Dtdisc_t *old;
-
- if (!(old = dt->disc)) { /* initialization call from dtopen() */
- dt->disc = disc;
- if (!(dt->memoryf = disc->memoryf))
- dt->memoryf = dtmemory;
- return disc;
- }
-
- if (!disc) /* only want to know current discipline */
- return old;
-
- searchf = dt->meth->searchf;
+ reg Dtsearch_f searchf;
+ reg Dtlink_t *r, *t;
+ reg char* k;
+ reg Dtdisc_t* old;
+
+ if(!(old = dt->disc) ) /* initialization call from dtopen() */
+ { dt->disc = disc;
+ if(!(dt->memoryf = disc->memoryf) )
+ dt->memoryf = dtmemory;
+ return disc;
+ }
- UNFLATTEN(dt);
+ if(!disc) /* only want to know current discipline */
+ return old;
- if (old->eventf
- && (*old->eventf) (dt, DT_DISC, (Void_t *) disc, old) < 0)
- return NIL(Dtdisc_t *);
+ searchf = dt->meth->searchf;
- dt->disc = disc;
- if (!(dt->memoryf = disc->memoryf))
- dt->memoryf = dtmemory;
+ UNFLATTEN(dt);
- if (dt->data->type & (DT_STACK | DT_QUEUE | DT_LIST))
- goto done;
- else if (dt->data->type & DT_BAG) {
- if (type & DT_SAMEHASH)
- goto done;
- else
- goto dt_renew;
- } else if (dt->data->type & (DT_SET | DT_BAG)) {
- if ((type & DT_SAMEHASH) && (type & DT_SAMECMP))
- goto done;
- else
- goto dt_renew;
- } else { /*if(dt->data->type&(DT_OSET|DT_OBAG)) */
- if (type & DT_SAMECMP)
- goto done;
- dt_renew:
- r = dtflatten(dt);
- dt->data->type &= ~DT_FLATTEN;
- dt->data->here = NIL(Dtlink_t *);
- dt->data->size = 0;
+ if(old->eventf && (*old->eventf)(dt,DT_DISC,(Void_t*)disc,old) < 0)
+ return NIL(Dtdisc_t*);
- if (dt->data->type & (DT_SET | DT_BAG)) {
- reg Dtlink_t **s, **ends;
- ends = (s = dt->data->htab) + dt->data->ntab;
- while (s < ends)
- *s++ = NIL(Dtlink_t *);
+ dt->disc = disc;
+ if(!(dt->memoryf = disc->memoryf) )
+ dt->memoryf = dtmemory;
+
+ if(dt->data->type&(DT_STACK|DT_QUEUE|DT_LIST))
+ goto done;
+ else if(dt->data->type&DT_BAG)
+ { if(type&DT_SAMEHASH)
+ goto done;
+ else goto dt_renew;
}
-
- /* reinsert them */
- while (r) {
- t = r->right;
- if (!(type & DT_SAMEHASH)) { /* new hash value */
- k = (char *) OBJ(r, disc->link);
- k = KEY((Void_t *) k, disc->key, disc->size);
- r->hash = HASH(dt, k, disc, disc->size);
- }
- (void) (*searchf) (dt, (Void_t *) r, DT_RENEW);
- r = t;
+ else if(dt->data->type&(DT_SET|DT_BAG))
+ { if((type&DT_SAMEHASH) && (type&DT_SAMECMP))
+ goto done;
+ else goto dt_renew;
+ }
+ else /*if(dt->data->type&(DT_OSET|DT_OBAG))*/
+ { if(type&DT_SAMECMP)
+ goto done;
+ dt_renew:
+ r = dtflatten(dt);
+ dt->data->type &= ~DT_FLATTEN;
+ dt->data->here = NIL(Dtlink_t*);
+ dt->data->size = 0;
+
+ if(dt->data->type&(DT_SET|DT_BAG))
+ { reg Dtlink_t **s, **ends;
+ ends = (s = dt->data->htab) + dt->data->ntab;
+ while(s < ends)
+ *s++ = NIL(Dtlink_t*);
+ }
+
+ /* reinsert them */
+ while(r)
+ { t = r->right;
+ if(!(type&DT_SAMEHASH)) /* new hash value */
+ { k = (char*)_DTOBJ(r,disc->link);
+ k = _DTKEY((Void_t*)k,disc->key,disc->size);
+ r->hash = _DTHSH(dt,k,disc,disc->size);
+ }
+ (void)(*searchf)(dt,(Void_t*)r,DT_RENEW);
+ r = t;
+ }
}
- }
- done:
- return old;
+done:
+ return old;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Extract objects of a dictionary.
**
** Written by Kiem-Phong Vo (5/25/96).
*/
#if __STD_C
-Dtlink_t *dtextract(reg Dt_t * dt)
+Dtlink_t* dtextract(reg Dt_t* dt)
#else
-Dtlink_t *dtextract(dt)
-reg Dt_t *dt;
+Dtlink_t* dtextract(dt)
+reg Dt_t* dt;
#endif
{
- reg Dtlink_t *list, **s, **ends;
-
- if (dt->data->type & (DT_OSET | DT_OBAG))
- list = dt->data->here;
- else if (dt->data->type & (DT_SET | DT_BAG)) {
- list = dtflatten(dt);
- for (ends = (s = dt->data->htab) + dt->data->ntab; s < ends; ++s)
- *s = NIL(Dtlink_t *);
- } else { /*if(dt->data->type&(DT_LIST|DT_STACK|DT_QUEUE)) */
- list = dt->data->head;
- dt->data->head = NIL(Dtlink_t *);
- }
-
- dt->data->type &= ~DT_FLATTEN;
- dt->data->size = 0;
- dt->data->here = NIL(Dtlink_t *);
-
- return list;
+ reg Dtlink_t *list, **s, **ends;
+
+ if(dt->data->type&(DT_OSET|DT_OBAG) )
+ list = dt->data->here;
+ else if(dt->data->type&(DT_SET|DT_BAG))
+ { list = dtflatten(dt);
+ for(ends = (s = dt->data->htab) + dt->data->ntab; s < ends; ++s)
+ *s = NIL(Dtlink_t*);
+ }
+ else /*if(dt->data->type&(DT_LIST|DT_STACK|DT_QUEUE))*/
+ { list = dt->data->head;
+ dt->data->head = NIL(Dtlink_t*);
+ }
+
+ dt->data->type &= ~DT_FLATTEN;
+ dt->data->size = 0;
+ dt->data->here = NIL(Dtlink_t*);
+
+ return list;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Flatten a dictionary into a linked list.
** This may be used when many traversals are likely.
**
*/
#if __STD_C
-Dtlink_t *dtflatten(Dt_t * dt)
+Dtlink_t* dtflatten(Dt_t* dt)
#else
-Dtlink_t *dtflatten(dt)
-Dt_t *dt;
+Dtlink_t* dtflatten(dt)
+Dt_t* dt;
#endif
{
- reg Dtlink_t *t, *r, *list, *last, **s, **ends;
-
- /* already flattened */
- if (dt->data->type & DT_FLATTEN)
- return dt->data->here;
-
- list = last = NIL(Dtlink_t *);
- if (dt->data->type & (DT_SET | DT_BAG)) {
- for (ends = (s = dt->data->htab) + dt->data->ntab; s < ends; ++s) {
- if ((t = *s)) {
- if (last)
- last->right = t;
- else
- list = last = t;
- while (last->right)
- last = last->right;
- *s = last;
- }
+ reg Dtlink_t *t, *r, *list, *last, **s, **ends;
+
+ /* already flattened */
+ if(dt->data->type&DT_FLATTEN )
+ return dt->data->here;
+
+ list = last = NIL(Dtlink_t*);
+ if(dt->data->type&(DT_SET|DT_BAG))
+ { for(ends = (s = dt->data->htab) + dt->data->ntab; s < ends; ++s)
+ { if((t = *s) )
+ { if(last)
+ last->right = t;
+ else list = last = t;
+ while(last->right)
+ last = last->right;
+ *s = last;
+ }
+ }
}
- } else if (dt->data->type & (DT_LIST | DT_STACK | DT_QUEUE))
- list = dt->data->head;
- else if ((r = dt->data->here)) { /*if(dt->data->type&(DT_OSET|DT_OBAG)) */
- while ((t = r->left))
- RROTATE(r, t);
- for (list = last = r, r = r->right; r; last = r, r = r->right) {
- if ((t = r->left)) {
- do
- RROTATE(r, t);
- while ((t = r->left));
-
- last->right = r;
- }
+ else if(dt->data->type&(DT_LIST|DT_STACK|DT_QUEUE) )
+ list = dt->data->head;
+ else if((r = dt->data->here) ) /*if(dt->data->type&(DT_OSET|DT_OBAG))*/
+ { while((t = r->left) )
+ RROTATE(r,t);
+ for(list = last = r, r = r->right; r; last = r, r = r->right)
+ { if((t = r->left) )
+ { do RROTATE(r,t);
+ while((t = r->left) );
+
+ last->right = r;
+ }
+ }
}
- }
- dt->data->here = list;
- dt->data->type |= DT_FLATTEN;
+ dt->data->here = list;
+ dt->data->type |= DT_FLATTEN;
- return list;
+ return list;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Hash table.
** dt: dictionary
** obj: what to look for
/* resize the hash table */
#if __STD_C
-static void dthtab(Dt_t * dt)
+static void dthtab(Dt_t* dt)
#else
static void dthtab(dt)
-Dt_t *dt;
+Dt_t* dt;
#endif
{
- reg Dtlink_t *t, *r, *p, **s, **hs, **is, **olds;
- reg int n;
+ reg Dtlink_t *t, *r, *p, **s, **hs, **is, **olds;
+ int n, k;
- /* compute new table size */
- if ((n = dt->data->ntab) == 0)
- n = HSLOT;
- while (dt->data->size > HLOAD(n))
- n = HRESIZE(n);
- if (n <= dt->data->ntab)
- return;
+ if(dt->data->minp > 0 && dt->data->ntab > 0) /* fixed table size */
+ return;
+ dt->data->minp = 0;
- /* allocate new table */
- olds = dt->data->ntab == 0 ? NIL(Dtlink_t **) : dt->data->htab;
- if (!
- (s =
- (Dtlink_t **) (*dt->memoryf) (dt, olds, n * sizeof(Dtlink_t *),
- dt->disc)))
- return;
- olds = s + dt->data->ntab;
- dt->data->htab = s;
- dt->data->ntab = n;
+ n = dt->data->ntab;
+ if(dt->disc && dt->disc->eventf &&
+ (*dt->disc->eventf)(dt, DT_HASHSIZE, &n, dt->disc) > 0 )
+ { if(n < 0) /* fix table size */
+ { dt->data->minp = 1;
+ if(dt->data->ntab > 0 )
+ return;
+ }
+ else /* set a particular size */
+ { for(k = 2; k < n; k *= 2)
+ ;
+ n = k;
+ }
+ }
+ else n = 0;
- /* rehash elements */
- for (hs = s + n - 1; hs >= olds; --hs)
- *hs = NIL(Dtlink_t *);
- for (hs = s; hs < olds; ++hs) {
- for (p = NIL(Dtlink_t *), t = *hs; t; t = r) {
- r = t->right;
- if ((is = s + HINDEX(n, t->hash)) == hs)
- p = t;
- else { /* move to a new chain */
- if (p)
- p->right = r;
- else
- *hs = r;
- t->right = *is;
- *is = t;
- }
+ /* compute new table size */
+ if(n <= 0)
+ { if((n = dt->data->ntab) == 0)
+ n = HSLOT;
+ while(dt->data->size > HLOAD(n))
+ n = HRESIZE(n);
+ }
+ if(n == dt->data->ntab)
+ return;
+
+ /* allocate new table */
+ olds = dt->data->ntab == 0 ? NIL(Dtlink_t**) : dt->data->htab;
+ if(!(s = (Dtlink_t**)(*dt->memoryf)(dt,olds,n*sizeof(Dtlink_t*),dt->disc)) )
+ return;
+ olds = s + dt->data->ntab;
+ dt->data->htab = s;
+ dt->data->ntab = n;
+
+ /* rehash elements */
+ for(hs = s+n-1; hs >= olds; --hs)
+ *hs = NIL(Dtlink_t*);
+ for(hs = s; hs < olds; ++hs)
+ { for(p = NIL(Dtlink_t*), t = *hs; t; t = r)
+ { r = t->right;
+ if((is = s + HINDEX(n,t->hash)) == hs)
+ p = t;
+ else /* move to a new chain */
+ { if(p)
+ p->right = r;
+ else *hs = r;
+ t->right = *is; *is = t;
+ }
+ }
}
- }
}
#if __STD_C
-static Void_t *dthash(Dt_t * dt, reg Void_t * obj, int type)
+static Void_t* dthash(Dt_t* dt, reg Void_t* obj, int type)
#else
-static Void_t *dthash(dt, obj, type)
-Dt_t *dt;
-reg Void_t *obj;
-int type;
+static Void_t* dthash(dt,obj,type)
+Dt_t* dt;
+reg Void_t* obj;
+int type;
#endif
{
- reg Dtlink_t *t, *r, *p;
- reg Void_t *k, *key;
- reg uint hsh;
- reg int lk, sz, ky;
- reg Dtcompar_f cmpf;
- reg Dtdisc_t *disc;
- reg Dtlink_t **s, **ends;
+ reg Dtlink_t *t, *r, *p;
+ reg Void_t *k, *key;
+ reg uint hsh;
+ reg int lk, sz, ky;
+ reg Dtcompar_f cmpf;
+ reg Dtdisc_t* disc;
+ reg Dtlink_t **s, **ends;
+
+ UNFLATTEN(dt);
- r = 0;
- s = 0;
- UNFLATTEN(dt);
- INITDISC(dt, disc, ky, sz, lk, cmpf);
+ /* initialize discipline data */
+ disc = dt->disc; _DTDSC(disc,ky,sz,lk,cmpf);
+ dt->type &= ~DT_FOUND;
- if (!obj) {
- if (type & (DT_NEXT | DT_PREV))
- goto end_walk;
+ if(!obj)
+ { if(type&(DT_NEXT|DT_PREV))
+ goto end_walk;
- if (dt->data->size <= 0
- || !(type & (DT_CLEAR | DT_FIRST | DT_LAST)))
- return NIL(Void_t *);
+ if(dt->data->size <= 0 || !(type&(DT_CLEAR|DT_FIRST|DT_LAST)) )
+ return NIL(Void_t*);
- ends = (s = dt->data->htab) + dt->data->ntab;
- if (type & DT_CLEAR) { /* clean out all objects */
- for (; s < ends; ++s) {
- t = *s;
- *s = NIL(Dtlink_t *);
- if (!disc->freef && disc->link >= 0)
- continue;
- while (t) {
- r = t->right;
- if (disc->freef)
- (*disc->freef) (dt, OBJ(t, lk), disc);
- if (disc->link < 0)
- (*dt->memoryf) (dt, (Void_t *) t, 0, disc);
- t = r;
+ ends = (s = dt->data->htab) + dt->data->ntab;
+ if(type&DT_CLEAR)
+ { /* clean out all objects */
+ for(; s < ends; ++s)
+ { t = *s;
+ *s = NIL(Dtlink_t*);
+ if(!disc->freef && disc->link >= 0)
+ continue;
+ while(t)
+ { r = t->right;
+ if(disc->freef)
+ (*disc->freef)(dt,_DTOBJ(t,lk),disc);
+ if(disc->link < 0)
+ (*dt->memoryf)(dt,(Void_t*)t,0,disc);
+ t = r;
+ }
+ }
+ dt->data->here = NIL(Dtlink_t*);
+ dt->data->size = 0;
+ dt->data->loop = 0;
+ return NIL(Void_t*);
}
- }
- dt->data->here = NIL(Dtlink_t *);
- dt->data->size = 0;
- dt->data->loop = 0;
- return NIL(Void_t *);
- } else { /* computing the first/last object */
- t = NIL(Dtlink_t *);
- while (s < ends && !t)
- t = (type & DT_LAST) ? *--ends : *s++;
- if (t && (type & DT_LAST))
- for (; t->right; t = t->right);
+ else /* computing the first/last object */
+ { t = NIL(Dtlink_t*);
+ while(s < ends && !t )
+ t = (type&DT_LAST) ? *--ends : *s++;
+ if(t && (type&DT_LAST))
+ for(; t->right; t = t->right)
+ ;
- dt->data->loop += 1;
- dt->data->here = t;
- return t ? OBJ(t, lk) : NIL(Void_t *);
+ dt->data->loop += 1;
+ dt->data->here = t;
+ return t ? _DTOBJ(t,lk) : NIL(Void_t*);
+ }
}
- }
- if (type & (DT_MATCH | DT_SEARCH | DT_INSERT | DT_ATTACH)) {
- key = (type & DT_MATCH) ? obj : KEY(obj, ky, sz);
- hsh = HASH(dt, key, disc, sz);
- goto do_search;
- } else if (type & (DT_RENEW | DT_VSEARCH)) {
- r = (Dtlink_t *) obj;
- obj = OBJ(r, lk);
- key = KEY(obj, ky, sz);
- hsh = r->hash;
- goto do_search;
- } else { /*if(type&(DT_DELETE|DT_DETACH|DT_NEXT|DT_PREV)) */
- if ((t = dt->data->here) && OBJ(t, lk) == obj) {
- hsh = t->hash;
- s = dt->data->htab + HINDEX(dt->data->ntab, hsh);
- p = NIL(Dtlink_t *);
- } else {
- key = KEY(obj, ky, sz);
- hsh = HASH(dt, key, disc, sz);
- do_search:
- t = dt->data->ntab <= 0 ? NIL(Dtlink_t *) :
- *(s = dt->data->htab + HINDEX(dt->data->ntab, hsh));
- for (p = NIL(Dtlink_t *); t; p = t, t = t->right) {
- if (hsh == t->hash) {
- k = OBJ(t, lk);
- k = KEY(k, ky, sz);
- if (CMP(dt, key, k, disc, cmpf, sz) == 0)
- break;
+ /* allow apps to delete an object "actually" in the dictionary */
+ if(dt->meth->type == DT_BAG && (type&(DT_DELETE|DT_DETACH)) )
+ { if(!dtsearch(dt,obj) )
+ return NIL(Void_t*);
+
+ s = dt->data->htab + HINDEX(dt->data->ntab,dt->data->here->hash);
+ r = NIL(Dtlink_t*);
+ for(p = NIL(Dtlink_t*), t = *s; t; p = t, t = t->right)
+ { if(_DTOBJ(t,lk) == obj) /* delete this specific object */
+ goto do_delete;
+ if(t == dt->data->here)
+ r = p;
}
- }
+
+ /* delete some matching object */
+ p = r; t = dt->data->here;
+ goto do_delete;
}
- }
- if (type & (DT_MATCH | DT_SEARCH | DT_VSEARCH)) {
- if (!t)
- return NIL(Void_t *);
- if (p && (dt->data->type & DT_SET) && dt->data->loop <= 0) { /* move-to-front heuristic */
- p->right = t->right;
- t->right = *s;
- *s = t;
+ if(type&(DT_MATCH|DT_SEARCH|DT_INSERT|DT_ATTACH) )
+ { key = (type&DT_MATCH) ? obj : _DTKEY(obj,ky,sz);
+ hsh = _DTHSH(dt,key,disc,sz);
+ goto do_search;
}
- dt->data->here = t;
- return OBJ(t, lk);
- } else if (type & (DT_INSERT | DT_ATTACH)) {
- if (t && (dt->data->type & DT_SET)) {
- dt->data->here = t;
- return OBJ(t, lk);
+ else if(type&(DT_RENEW|DT_VSEARCH) )
+ { r = (Dtlink_t*)obj;
+ obj = _DTOBJ(r,lk);
+ key = _DTKEY(obj,ky,sz);
+ hsh = r->hash;
+ goto do_search;
}
-
- if (disc->makef && (type & DT_INSERT) &&
- !(obj = (*disc->makef) (dt, obj, disc)))
- return NIL(Void_t *);
- if (lk >= 0)
- r = ELT(obj, lk);
- else {
- r = (Dtlink_t *) (*dt->memoryf)
- (dt, NIL(Void_t *), sizeof(Dthold_t), disc);
- if (r)
- ((Dthold_t *) r)->obj = obj;
- else {
- if (disc->makef && disc->freef && (type & DT_INSERT))
- (*disc->freef) (dt, obj, disc);
- return NIL(Void_t *);
- }
+ else /*if(type&(DT_DELETE|DT_DETACH|DT_NEXT|DT_PREV))*/
+ { if((t = dt->data->here) && _DTOBJ(t,lk) == obj)
+ { hsh = t->hash;
+ s = dt->data->htab + HINDEX(dt->data->ntab,hsh);
+ p = NIL(Dtlink_t*);
+ }
+ else
+ { key = _DTKEY(obj,ky,sz);
+ hsh = _DTHSH(dt,key,disc,sz);
+ do_search:
+ t = dt->data->ntab <= 0 ? NIL(Dtlink_t*) :
+ *(s = dt->data->htab + HINDEX(dt->data->ntab,hsh));
+ for(p = NIL(Dtlink_t*); t; p = t, t = t->right)
+ { if(hsh == t->hash)
+ { k = _DTOBJ(t,lk); k = _DTKEY(k,ky,sz);
+ if(_DTCMP(dt,key,k,disc,cmpf,sz) == 0)
+ break;
+ }
+ }
+ }
}
- r->hash = hsh;
- /* insert object */
- do_insert:
- if ((dt->data->size += 1) > HLOAD(dt->data->ntab)
- && dt->data->loop <= 0)
- dthtab(dt);
- if (dt->data->ntab == 0) {
- dt->data->size -= 1;
- if (disc->freef && (type & DT_INSERT))
- (*disc->freef) (dt, obj, disc);
- if (disc->link < 0)
- (*disc->memoryf) (dt, (Void_t *) r, 0, disc);
- return NIL(Void_t *);
- }
- s = dt->data->htab + HINDEX(dt->data->ntab, hsh);
- if (t) {
- r->right = t->right;
- t->right = r;
- } else {
- r->right = *s;
- *s = r;
+ if(t) /* found matching object */
+ dt->type |= DT_FOUND;
+
+ if(type&(DT_MATCH|DT_SEARCH|DT_VSEARCH))
+ { if(!t)
+ return NIL(Void_t*);
+ if(p && (dt->data->type&DT_SET) && dt->data->loop <= 0)
+ { /* move-to-front heuristic */
+ p->right = t->right;
+ t->right = *s;
+ *s = t;
+ }
+ dt->data->here = t;
+ return _DTOBJ(t,lk);
}
- dt->data->here = r;
- return obj;
- } else if (type & DT_NEXT) {
- if (t && !(p = t->right)) {
- for (ends = dt->data->htab + dt->data->ntab, s += 1; s < ends;
- ++s)
- if ((p = *s))
- break;
+ else if(type&(DT_INSERT|DT_ATTACH))
+ { if(t && (dt->data->type&DT_SET) )
+ { dt->data->here = t;
+ return _DTOBJ(t,lk);
+ }
+
+ if(disc->makef && (type&DT_INSERT) &&
+ !(obj = (*disc->makef)(dt,obj,disc)) )
+ return NIL(Void_t*);
+ if(lk >= 0)
+ r = _DTLNK(obj,lk);
+ else
+ { r = (Dtlink_t*)(*dt->memoryf)
+ (dt,NIL(Void_t*),sizeof(Dthold_t),disc);
+ if(r)
+ ((Dthold_t*)r)->obj = obj;
+ else
+ { if(disc->makef && disc->freef && (type&DT_INSERT))
+ (*disc->freef)(dt,obj,disc);
+ return NIL(Void_t*);
+ }
+ }
+ r->hash = hsh;
+
+ /* insert object */
+ do_insert:
+ if((dt->data->size += 1) > HLOAD(dt->data->ntab) && dt->data->loop <= 0 )
+ dthtab(dt);
+ if(dt->data->ntab == 0)
+ { dt->data->size -= 1;
+ if(disc->freef && (type&DT_INSERT))
+ (*disc->freef)(dt,obj,disc);
+ if(disc->link < 0)
+ (*disc->memoryf)(dt,(Void_t*)r,0,disc);
+ return NIL(Void_t*);
+ }
+ s = dt->data->htab + HINDEX(dt->data->ntab,hsh);
+ if(t)
+ { r->right = t->right;
+ t->right = r;
+ }
+ else
+ { r->right = *s;
+ *s = r;
+ }
+ dt->data->here = r;
+ return obj;
}
- goto done_adj;
- } else if (type & DT_PREV) {
- if (t && !p) {
- if ((p = *s) != t) {
- while (p->right != t)
- p = p->right;
- } else {
- p = NIL(Dtlink_t *);
- for (s -= 1, ends = dt->data->htab; s >= ends; --s) {
- if ((p = *s)) {
- while (p->right)
- p = p->right;
- break;
- }
+ else if(type&DT_NEXT)
+ { if(t && !(p = t->right) )
+ { for(ends = dt->data->htab+dt->data->ntab, s += 1; s < ends; ++s)
+ if((p = *s) )
+ break;
}
- }
+ goto done_adj;
}
- done_adj:
- if (!(dt->data->here = p)) {
- end_walk:
- if ((dt->data->loop -= 1) < 0)
- dt->data->loop = 0;
- if (dt->data->size > HLOAD(dt->data->ntab)
- && dt->data->loop <= 0)
- dthtab(dt);
- return NIL(Void_t *);
- } else {
- dt->data->type |= DT_WALK;
- return OBJ(p, lk);
+ else if(type&DT_PREV)
+ { if(t && !p)
+ { if((p = *s) != t)
+ { while(p->right != t)
+ p = p->right;
+ }
+ else
+ { p = NIL(Dtlink_t*);
+ for(s -= 1, ends = dt->data->htab; s >= ends; --s)
+ { if((p = *s) )
+ { while(p->right)
+ p = p->right;
+ break;
+ }
+ }
+ }
+ }
+ done_adj:
+ if(!(dt->data->here = p) )
+ { end_walk:
+ if((dt->data->loop -= 1) < 0)
+ dt->data->loop = 0;
+ if(dt->data->size > HLOAD(dt->data->ntab) && dt->data->loop <= 0)
+ dthtab(dt);
+ return NIL(Void_t*);
+ }
+ else
+ { dt->data->type |= DT_WALK;
+ return _DTOBJ(p,lk);
+ }
}
- } else if (type & DT_RENEW) {
- if (!t || (dt->data->type & DT_BAG))
- goto do_insert;
- else {
- if (disc->freef)
- (*disc->freef) (dt, obj, disc);
- if (disc->link < 0)
- (*dt->memoryf) (dt, (Void_t *) r, 0, disc);
- return t ? OBJ(t, lk) : NIL(Void_t *);
+ else if(type&DT_RENEW)
+ { if(!t || (dt->data->type&DT_BAG) )
+ goto do_insert;
+ else
+ { if(disc->freef)
+ (*disc->freef)(dt,obj,disc);
+ if(disc->link < 0)
+ (*dt->memoryf)(dt,(Void_t*)r,0,disc);
+ return t ? _DTOBJ(t,lk) : NIL(Void_t*);
+ }
}
- } else { /*if(type&(DT_DELETE|DT_DETACH)) */
- if (!t)
- return NIL(Void_t *);
- else if (p)
- p->right = t->right;
- else if ((p = *s) == t)
- *s = t->right;
- else {
- while (p->right != t)
- p = p->right;
- p->right = t->right;
+ else /*if(type&(DT_DELETE|DT_DETACH))*/
+ { /* take an element out of the dictionary */
+ do_delete:
+ if(!t)
+ return NIL(Void_t*);
+ else if(p)
+ p->right = t->right;
+ else if((p = *s) == t)
+ p = *s = t->right;
+ else
+ { while(p->right != t)
+ p = p->right;
+ p->right = t->right;
+ }
+ obj = _DTOBJ(t,lk);
+ dt->data->size -= 1;
+ dt->data->here = p;
+ if(disc->freef && (type&DT_DELETE))
+ (*disc->freef)(dt,obj,disc);
+ if(disc->link < 0)
+ (*dt->memoryf)(dt,(Void_t*)t,0,disc);
+ return obj;
}
- obj = OBJ(t, lk);
- dt->data->size -= 1;
- dt->data->here = p;
- if (disc->freef && (type & DT_DETACH))
- (*disc->freef) (dt, obj, disc);
- if (disc->link < 0)
- (*dt->memoryf) (dt, (Void_t *) t, 0, disc);
- return obj;
- }
}
-static Dtmethod_t _Dtset = { dthash, DT_SET };
-static Dtmethod_t _Dtbag = { dthash, DT_BAG };
+static Dtmethod_t _Dtset = { dthash, DT_SET };
+static Dtmethod_t _Dtbag = { dthash, DT_BAG };
+__DEFINE__(Dtmethod_t*,Dtset,&_Dtset);
+__DEFINE__(Dtmethod_t*,Dtbag,&_Dtbag);
-__DEFINE__(Dtmethod_t *, Dtset, &_Dtset);
-__DEFINE__(Dtmethod_t *, Dtbag, &_Dtbag);
-
-#ifndef KPVDEL /* for backward compatibility - remove next time */
-Dtmethod_t _Dthash = { dthash, DT_SET };
+#ifndef KPVDEL /* for backward compatibility - remove next time */
+Dtmethod_t _Dthash = { dthash, DT_SET };
+__DEFINE__(Dtmethod_t*,Dthash,&_Dthash);
+#endif
-__DEFINE__(Dtmethod_t *, Dthash, &_Dthash);
+#ifdef NoF
+NoF(dthash)
#endif
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#ifndef _DTHDR_H
#define _DTHDR_H 1
#ifndef _BLD_cdt
#include <cdt.h>
/* short-hand notations */
+#define NIL(t) ((t)0)
#define reg register
#define uint unsigned int
#define left hl._left
#define head hh._head
/* this must be disjoint from DT_METHODS */
-#define DT_FLATTEN 010000 /* dictionary already flattened */
-#define DT_WALK 020000 /* hash table being walked */
+#define DT_FLATTEN 010000 /* dictionary already flattened */
+#define DT_WALK 020000 /* hash table being walked */
+
+/* how the Dt_t handle was allocated */
+#define DT_MALLOC 0
+#define DT_MEMORYF 1
+
+/* max search length before splaying */
+#define DT_MINP (sizeof(size_t)*8 - 2)
/* hash start size and load factor */
-#define HSLOT (32)
+#define HSLOT (256)
#define HRESIZE(n) ((n) << 1)
#define HLOAD(s) ((s) << 1)
#define HINDEX(n,h) ((h)&((n)-1))
#define UNFLATTEN(dt) \
((dt->data->type&DT_FLATTEN) ? dtrestore(dt,NIL(Dtlink_t*)) : 0)
-/* the pointer to the actual object */
-#define INITDISC(dt,d,ky,sz,lk,cmpf) \
- (d = dt->disc, ky = d->key, sz = d->size, lk = d->link, cmpf = d->comparf)
-#define ELT(o,lk) ((Dtlink_t*)((char*)(o) + lk) )
-#define OBJ(e,lk) (lk < 0 ? ((Dthold_t*)(e))->obj : (Void_t*)((char*)(e) - lk) )
-#define KEY(o,ky,sz) ((Void_t*)(sz < 0 ? *((char**)((char*)(o) + ky)) : \
- ((char*)(o) + ky) ) )
-
-/* compare and hash functions */
-#define CMP(dt,k1,k2,d,cmpf,sz) \
- (cmpf ? (*cmpf)(dt,k1,k2,d) : \
- sz <= 0 ? strcmp(k1,k2) : memcmp(k1,k2,sz) )
-#define HASH(dt,k,d,sz) (d->hashf ? (*d->hashf)(dt,k,d) : dtstrhash(0,k,sz) )
+/* tree rotation/linking functions */
+#define rrotate(x,y) ((x)->left = (y)->right, (y)->right = (x))
+#define lrotate(x,y) ((x)->right = (y)->left, (y)->left = (x))
+#define rlink(r,x) ((r) = (r)->left = (x) )
+#define llink(l,x) ((l) = (l)->right = (x) )
-/* tree rotation functions */
-#define RROTATE(x,y) ((x)->left = (y)->right, (y)->right = (x), (x) = (y))
-#define LROTATE(x,y) ((x)->right = (y)->left, (y)->left = (x), (x) = (y))
-#define RLINK(r,x) ((r) = (r)->left = (x) )
-#define LLINK(l,x) ((l) = (l)->right = (x) )
+#define RROTATE(x,y) (rrotate(x,y), (x) = (y))
+#define LROTATE(x,y) (lrotate(x,y), (x) = (y))
#if !_PACKAGE_ast
- _BEGIN_EXTERNS_ extern Void_t *malloc _ARG_((size_t));
- extern Void_t *realloc _ARG_((Void_t *, size_t));
- extern void free _ARG_((Void_t *));
- extern int memcmp _ARG_((const Void_t *, const Void_t *, size_t));
- extern int strcmp _ARG_((const char *, const char *));
- _END_EXTERNS_
-#endif
-#endif /* _DTHDR_H */
-#ifdef __cplusplus
-}
+_BEGIN_EXTERNS_
+extern Void_t* malloc _ARG_((size_t));
+extern Void_t* realloc _ARG_((Void_t*, size_t));
+extern void free _ARG_((Void_t*));
+_END_EXTERNS_
#endif
+
+#endif /* _DTHDR_H */
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-/* List, Stack, Queue.
+/* List, Deque, Stack, Queue.
**
** Written by Kiem-Phong Vo (05/25/96)
*/
#if __STD_C
-static Void_t *dtlist(reg Dt_t * dt, reg Void_t * obj, reg int type)
+static Void_t* dtlist(reg Dt_t* dt, reg Void_t* obj, reg int type)
#else
-static Void_t *dtlist(dt, obj, type)
-reg Dt_t *dt;
-reg Void_t *obj;
-reg int type;
+static Void_t* dtlist(dt, obj, type)
+reg Dt_t* dt;
+reg Void_t* obj;
+reg int type;
#endif
{
- reg int lk, sz, ky;
- reg Dtcompar_f cmpf;
- reg Dtdisc_t *disc;
- reg Dtlink_t *r, *t;
- reg Void_t *key, *k;
+ reg int lk, sz, ky;
+ reg Dtcompar_f cmpf;
+ reg Dtdisc_t* disc;
+ reg Dtlink_t *r, *t;
+ reg Void_t *key, *k;
+
+ UNFLATTEN(dt);
+ disc = dt->disc; _DTDSC(disc,ky,sz,lk,cmpf);
+ dt->type &= ~DT_FOUND;
+
+ if(!obj)
+ { if(type&(DT_LAST|DT_FIRST) )
+ { if((r = dt->data->head) )
+ { if(type&DT_LAST)
+ r = r->left;
+ dt->data->here = r;
+ }
+ return r ? _DTOBJ(r,lk) : NIL(Void_t*);
+ }
+ else if(type&(DT_DELETE|DT_DETACH))
+ { if((dt->data->type&(DT_LIST|DT_DEQUE)) || !(r = dt->data->head))
+ return NIL(Void_t*);
+ else goto dt_delete;
+ }
+ else if(type&DT_CLEAR)
+ { if(disc->freef || disc->link < 0)
+ { for(r = dt->data->head; r; r = t)
+ { t = r->right;
+ if(disc->freef)
+ (*disc->freef)(dt,_DTOBJ(r,lk),disc);
+ if(disc->link < 0)
+ (*dt->memoryf)(dt,(Void_t*)r,0,disc);
+ }
+ }
+ dt->data->head = dt->data->here = NIL(Dtlink_t*);
+ dt->data->size = 0;
+ return NIL(Void_t*);
+ }
+ else return NIL(Void_t*);
+ }
- INITDISC(dt, disc, ky, sz, lk, cmpf);
+ if(type&(DT_INSERT|DT_ATTACH))
+ { if(disc->makef && (type&DT_INSERT) &&
+ !(obj = (*disc->makef)(dt,obj,disc)) )
+ return NIL(Void_t*);
+ if(lk >= 0)
+ r = _DTLNK(obj,lk);
+ else
+ { r = (Dtlink_t*)(*dt->memoryf)
+ (dt,NIL(Void_t*),sizeof(Dthold_t),disc);
+ if(r)
+ ((Dthold_t*)r)->obj = obj;
+ else
+ { if(disc->makef && disc->freef && (type&DT_INSERT))
+ (*disc->freef)(dt,obj,disc);
+ return NIL(Void_t*);
+ }
+ }
- UNFLATTEN(dt);
+ if(dt->data->type&DT_DEQUE)
+ { if(type&DT_APPEND)
+ goto dt_queue;
+ else goto dt_stack;
+ }
+ else if(dt->data->type&DT_LIST)
+ { if(type&DT_APPEND)
+ { if(!(t = dt->data->here) || !t->right)
+ goto dt_queue;
+ r->right = t->right;
+ r->right->left = r;
+ r->left = t;
+ r->left->right = r;
+ }
+ else
+ { if(!(t = dt->data->here) || t == dt->data->head)
+ goto dt_stack;
+ r->left = t->left;
+ r->left->right = r;
+ r->right = t;
+ r->right->left = r;
+ }
+ }
+ else if(dt->data->type&DT_STACK)
+ { dt_stack:
+ r->right = t = dt->data->head;
+ if(t)
+ { r->left = t->left;
+ t->left = r;
+ }
+ else r->left = r;
+ dt->data->head = r;
+ }
+ else /* if(dt->data->type&DT_QUEUE) */
+ { dt_queue:
+ if((t = dt->data->head) )
+ { t->left->right = r;
+ r->left = t->left;
+ t->left = r;
+ }
+ else
+ { dt->data->head = r;
+ r->left = r;
+ }
+ r->right = NIL(Dtlink_t*);
+ }
+
+ if(dt->data->size >= 0)
+ dt->data->size += 1;
- if (!obj) {
- if (type & (DT_LAST | DT_FIRST)) {
- if ((r = dt->data->head)) {
- if (type & DT_LAST)
- r = r->left;
dt->data->here = r;
- }
- return r ? OBJ(r, lk) : NIL(Void_t *);
- } else if (type & (DT_DELETE | DT_DETACH)) {
- if ((dt->data->type & DT_LIST) || !(r = dt->data->head))
- return NIL(Void_t *);
- else
- goto dt_delete;
- } else if (type & DT_CLEAR) {
- if (disc->freef || disc->link < 0) {
- for (r = dt->data->head; r; r = t) {
- t = r->right;
- if (disc->freef)
- (*disc->freef) (dt, OBJ(r, lk), disc);
- if (disc->link < 0)
- (*dt->memoryf) (dt, (Void_t *) r, 0, disc);
- }
- }
- dt->data->head = dt->data->here = NIL(Dtlink_t *);
- dt->data->size = 0;
- return NIL(Void_t *);
- } else
- return NIL(Void_t *);
- }
-
- if (type & (DT_INSERT | DT_ATTACH)) {
- if (disc->makef && (type & DT_INSERT) &&
- !(obj = (*disc->makef) (dt, obj, disc)))
- return NIL(Void_t *);
- if (lk >= 0)
- r = ELT(obj, lk);
- else {
- r = (Dtlink_t *) (*dt->memoryf)
- (dt, NIL(Void_t *), sizeof(Dthold_t), disc);
- if (r)
- ((Dthold_t *) r)->obj = obj;
- else {
- if (disc->makef && disc->freef && (type & DT_INSERT))
- (*disc->freef) (dt, obj, disc);
- return NIL(Void_t *);
- }
+ return _DTOBJ(r,lk);
}
- if (dt->data->type & DT_LIST) {
- if ((t = dt->data->here) && t != dt->data->head) {
- r->left = t->left;
- t->left->right = r;
- r->right = t;
- t->left = r;
- } else
- goto dt_stack;
- } else if (dt->data->type & DT_STACK) {
- dt_stack:
- r->right = t = dt->data->head;
- if (t) {
- r->left = t->left;
- t->left = r;
- } else
- r->left = r;
- dt->data->head = r;
- } else { /* if(dt->data->type&DT_QUEUE) */
- if ((t = dt->data->head)) {
- t->left->right = r;
- r->left = t->left;
- t->left = r;
- } else {
- dt->data->head = r;
- r->left = r;
- }
- r->right = NIL(Dtlink_t *);
+ if((type&DT_MATCH) || !(r = dt->data->here) || _DTOBJ(r,lk) != obj)
+ { key = (type&DT_MATCH) ? obj : _DTKEY(obj,ky,sz);
+ for(r = dt->data->head; r; r = r->right)
+ { k = _DTOBJ(r,lk); k = _DTKEY(k,ky,sz);
+ if(_DTCMP(dt,key,k,disc,cmpf,sz) == 0)
+ break;
+ }
}
- if (dt->data->size >= 0)
- dt->data->size += 1;
+ if(!r)
+ return NIL(Void_t*);
+ dt->type |= DT_FOUND;
+
+ if(type&(DT_DELETE|DT_DETACH))
+ { dt_delete:
+ if(r->right)
+ r->right->left = r->left;
+ if(r == (t = dt->data->head) )
+ { dt->data->head = r->right;
+ if(dt->data->head)
+ dt->data->head->left = t->left;
+ }
+ else
+ { r->left->right = r->right;
+ if(r == t->left)
+ t->left = r->left;
+ }
- dt->data->here = r;
- return OBJ(r, lk);
- }
-
- if ((type & DT_MATCH) || !(r = dt->data->here) || OBJ(r, lk) != obj) {
- key = (type & DT_MATCH) ? obj : KEY(obj, ky, sz);
- for (r = dt->data->head; r; r = r->right) {
- k = OBJ(r, lk);
- k = KEY(k, ky, sz);
- if (CMP(dt, key, k, disc, cmpf, sz) == 0)
- break;
- }
- }
-
- if (!r)
- return NIL(Void_t *);
-
- if (type & (DT_DELETE | DT_DETACH)) {
- dt_delete:
- if (r->right)
- r->right->left = r->left;
- if (r == (t = dt->data->head)) {
- dt->data->head = r->right;
- if (dt->data->head)
- dt->data->head->left = t->left;
- } else {
- r->left->right = r->right;
- if (r == t->left)
- t->left = r->left;
+ dt->data->here = r == dt->data->here ? r->right : NIL(Dtlink_t*);
+ dt->data->size -= 1;
+
+ obj = _DTOBJ(r,lk);
+ if(disc->freef && (type&DT_DELETE))
+ (*disc->freef)(dt,obj,disc);
+ if(disc->link < 0)
+ (*dt->memoryf)(dt,(Void_t*)r,0,disc);
+ return obj;
}
+ else if(type&DT_NEXT)
+ r = r->right;
+ else if(type&DT_PREV)
+ r = r == dt->data->head ? NIL(Dtlink_t*) : r->left;
- dt->data->here = r == dt->data->here ? r->right : NIL(Dtlink_t *);
- dt->data->size -= 1;
-
- obj = OBJ(r, lk);
- if (disc->freef && (type & DT_DELETE))
- (*disc->freef) (dt, obj, disc);
- if (disc->link < 0)
- (*dt->memoryf) (dt, (Void_t *) r, 0, disc);
- return obj;
- } else if (type & DT_NEXT)
- r = r->right;
- else if (type & DT_PREV)
- r = r == dt->data->head ? NIL(Dtlink_t *) : r->left;
-
- dt->data->here = r;
- return r ? OBJ(r, lk) : NIL(Void_t *);
+ dt->data->here = r;
+ return r ? _DTOBJ(r,lk) : NIL(Void_t*);
}
-#ifndef KPVDEL /* to be remove next round */
-#define static
+#ifndef KPVDEL /* to be remove next round */
+#define static
#endif
-static Dtmethod_t _Dtlist = { dtlist, DT_LIST };
+static Dtmethod_t _Dtlist = { dtlist, DT_LIST };
+static Dtmethod_t _Dtdeque = { dtlist, DT_DEQUE };
static Dtmethod_t _Dtstack = { dtlist, DT_STACK };
static Dtmethod_t _Dtqueue = { dtlist, DT_QUEUE };
-__DEFINE__(Dtmethod_t *, Dtlist, &_Dtlist);
-__DEFINE__(Dtmethod_t *, Dtstack, &_Dtstack);
-__DEFINE__(Dtmethod_t *, Dtqueue, &_Dtqueue);
+__DEFINE__(Dtmethod_t*,Dtlist,&_Dtlist);
+__DEFINE__(Dtmethod_t*,Dtdeque,&_Dtdeque);
+__DEFINE__(Dtmethod_t*,Dtstack,&_Dtstack);
+__DEFINE__(Dtmethod_t*,Dtqueue,&_Dtqueue);
+
+#ifdef NoF
+NoF(dtlist)
+#endif
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Change search method.
**
** Written by Kiem-Phong Vo (05/25/96)
*/
#if __STD_C
-Dtmethod_t *dtmethod(Dt_t * dt, Dtmethod_t * meth)
+Dtmethod_t* dtmethod(Dt_t* dt, Dtmethod_t* meth)
#else
-Dtmethod_t *dtmethod(dt, meth)
-Dt_t *dt;
-Dtmethod_t *meth;
+Dtmethod_t* dtmethod(dt, meth)
+Dt_t* dt;
+Dtmethod_t* meth;
#endif
{
- reg Dtlink_t *list, *r;
- reg Dtdisc_t *disc = dt->disc;
- reg Dtmethod_t *oldmeth = dt->meth;
+ reg Dtlink_t *list, *r;
+ reg Dtdisc_t* disc = dt->disc;
+ reg Dtmethod_t* oldmeth = dt->meth;
- if (!meth || meth->type == oldmeth->type)
- return oldmeth;
+ if(!meth || meth->type == oldmeth->type)
+ return oldmeth;
+
+ if(disc->eventf &&
+ (*disc->eventf)(dt,DT_METH,(Void_t*)meth,disc) < 0)
+ return NIL(Dtmethod_t*);
- if (disc->eventf &&
- (*disc->eventf) (dt, DT_METH, (Void_t *) meth, disc) < 0)
- return NIL(Dtmethod_t *);
+ dt->data->minp = 0;
- /* get the list of elements */
- list = dtflatten(dt);
+ /* get the list of elements */
+ list = dtflatten(dt);
- if (dt->data->type & (DT_LIST | DT_STACK | DT_QUEUE))
- dt->data->head = NIL(Dtlink_t *);
- else if (dt->data->type & (DT_SET | DT_BAG)) {
- if (dt->data->ntab > 0)
- (*dt->memoryf) (dt, (Void_t *) dt->data->htab, 0, disc);
- dt->data->ntab = 0;
- dt->data->htab = NIL(Dtlink_t **);
- }
+ if(dt->data->type&(DT_LIST|DT_STACK|DT_QUEUE) )
+ dt->data->head = NIL(Dtlink_t*);
+ else if(dt->data->type&(DT_SET|DT_BAG) )
+ { if(dt->data->ntab > 0)
+ (*dt->memoryf)(dt,(Void_t*)dt->data->htab,0,disc);
+ dt->data->ntab = 0;
+ dt->data->htab = NIL(Dtlink_t**);
+ }
- dt->data->here = NIL(Dtlink_t *);
- dt->data->type =
- (dt->data->type & ~(DT_METHODS | DT_FLATTEN)) | meth->type;
- dt->meth = meth;
- if (dt->searchf == oldmeth->searchf)
- dt->searchf = meth->searchf;
+ dt->data->here = NIL(Dtlink_t*);
+ dt->data->type = (dt->data->type&~(DT_METHODS|DT_FLATTEN)) | meth->type;
+ dt->meth = meth;
+ if(dt->searchf == oldmeth->searchf)
+ dt->searchf = meth->searchf;
- if (meth->type & (DT_LIST | DT_STACK | DT_QUEUE)) {
- if (!(oldmeth->type & (DT_LIST | DT_STACK | DT_QUEUE))) {
- if ((r = list)) {
- reg Dtlink_t *t;
- for (t = r->right; t; r = t, t = t->right)
- t->left = r;
- list->left = r;
- }
+ if(meth->type&(DT_LIST|DT_STACK|DT_QUEUE) )
+ { if(!(oldmeth->type&(DT_LIST|DT_STACK|DT_QUEUE)) )
+ { if((r = list) )
+ { reg Dtlink_t* t;
+ for(t = r->right; t; r = t, t = t->right )
+ t->left = r;
+ list->left = r;
+ }
+ }
+ dt->data->head = list;
}
- dt->data->head = list;
- } else if (meth->type & (DT_OSET | DT_OBAG)) {
- dt->data->size = 0;
- while (list) {
- r = list->right;
- (*meth->searchf) (dt, (Void_t *) list, DT_RENEW);
- list = r;
+ else if(meth->type&(DT_OSET|DT_OBAG))
+ { dt->data->size = 0;
+ while(list)
+ { r = list->right;
+ (*meth->searchf)(dt,(Void_t*)list,DT_RENEW);
+ list = r;
+ }
}
- } else if (!((meth->type & DT_BAG) && (oldmeth->type & DT_SET))) {
- int rehash;
- if ((meth->type & (DT_SET | DT_BAG))
- && !(oldmeth->type & (DT_SET | DT_BAG)))
- rehash = 1;
- else
- rehash = 0;
+ else if(!((meth->type&DT_BAG) && (oldmeth->type&DT_SET)) )
+ { int rehash;
+ if((meth->type&(DT_SET|DT_BAG)) && !(oldmeth->type&(DT_SET|DT_BAG)))
+ rehash = 1;
+ else rehash = 0;
- dt->data->size = dt->data->loop = 0;
- while (list) {
- r = list->right;
- if (rehash) {
- reg Void_t *key = OBJ(list, disc->link);
- key = KEY(key, disc->key, disc->size);
- list->hash = HASH(dt, key, disc, disc->size);
- }
- (void) (*meth->searchf) (dt, (Void_t *) list, DT_RENEW);
- list = r;
+ dt->data->size = dt->data->loop = 0;
+ while(list)
+ { r = list->right;
+ if(rehash)
+ { reg Void_t* key = _DTOBJ(list,disc->link);
+ key = _DTKEY(key,disc->key,disc->size);
+ list->hash = _DTHSH(dt,key,disc,disc->size);
+ }
+ (void)(*meth->searchf)(dt,(Void_t*)list,DT_RENEW);
+ list = r;
+ }
}
- }
- return oldmeth;
+ return oldmeth;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-static char *Version = "\n@(#)cdt (AT&T Labs - kpv) 1999-11-01\0\n";
+static char* Version = "\n@(#)$Id$\0\n";
/* Make a new dictionary
**
*/
#if __STD_C
-Dt_t *dtopen(Dtdisc_t * disc, Dtmethod_t * meth)
+Dt_t* dtopen(Dtdisc_t* disc, Dtmethod_t* meth)
#else
-Dt_t *dtopen(disc, meth)
-Dtdisc_t *disc;
-Dtmethod_t *meth;
+Dt_t* dtopen(disc, meth)
+Dtdisc_t* disc;
+Dtmethod_t* meth;
#endif
{
- Dt_t *dt = (Dt_t *) Version; /* shut-up unuse warning */
- reg int e;
- Dtdata_t *data;
-
- if (!disc || !meth)
- return NIL(Dt_t *);
-
- /* allocate space for dictionary */
- if (!(dt = (Dt_t *) malloc(sizeof(Dt_t))))
- return NIL(Dt_t *);
-
- /* initialize all absolutely private data */
- dt->searchf = NIL(Dtsearch_f);
- dt->meth = NIL(Dtmethod_t *);
- dt->disc = NIL(Dtdisc_t *);
- dtdisc(dt, disc, 0);
- dt->nview = 0;
- dt->view = dt->walk = NIL(Dt_t *);
-
- if (disc->eventf) { /* if shared/persistent dictionary, get existing data */
- data = NIL(Dtdata_t *);
- if ((e =
- (*disc->eventf) (dt, DT_OPEN, (Void_t *) (&data),
- disc)) != 0) {
- if (e < 0 || !data || !(data->type & meth->type)) {
- free((Void_t *) dt);
- return NIL(Dt_t *);
- } else
- goto done;
+ Dt_t* dt = (Dt_t*)Version; /* shut-up unuse warning */
+ reg int e;
+ Dtdata_t* data;
+
+ if(!disc || !meth)
+ return NIL(Dt_t*);
+
+ /* allocate space for dictionary */
+ if(!(dt = (Dt_t*) malloc(sizeof(Dt_t))))
+ return NIL(Dt_t*);
+
+ /* initialize all absolutely private data */
+ dt->searchf = NIL(Dtsearch_f);
+ dt->meth = NIL(Dtmethod_t*);
+ dt->disc = NIL(Dtdisc_t*);
+ dtdisc(dt,disc,0);
+ dt->type = DT_MALLOC;
+ dt->nview = 0;
+ dt->view = dt->walk = NIL(Dt_t*);
+ dt->user = NIL(Void_t*);
+
+ if(disc->eventf)
+ { /* if shared/persistent dictionary, get existing data */
+ data = NIL(Dtdata_t*);
+ if((e = (*disc->eventf)(dt,DT_OPEN,(Void_t*)(&data),disc)) < 0)
+ goto err_open;
+ else if(e > 0)
+ { if(data)
+ { if(data->type&meth->type)
+ goto done;
+ else goto err_open;
+ }
+
+ if(!disc->memoryf)
+ goto err_open;
+
+ free((Void_t*)dt);
+ if(!(dt = (*disc->memoryf)(0, 0, sizeof(Dt_t), disc)) )
+ return NIL(Dt_t*);
+ dt->searchf = NIL(Dtsearch_f);
+ dt->meth = NIL(Dtmethod_t*);
+ dt->disc = NIL(Dtdisc_t*);
+ dtdisc(dt,disc,0);
+ dt->type = DT_MEMORYF;
+ dt->nview = 0;
+ dt->view = dt->walk = NIL(Dt_t*);
+ }
}
- }
- /* allocate sharable data */
- data =
- (Dtdata_t *) (dt->memoryf) (dt, NIL(Void_t *), sizeof(Dtdata_t),
- disc);
- if (!data) {
- free((Void_t *) dt);
- return NIL(Dt_t *);
- }
- data->type = meth->type;
- data->here = NIL(Dtlink_t *);
- data->htab = NIL(Dtlink_t **);
- data->ntab = data->size = data->loop = 0;
-
- done:
- dt->data = data;
- dt->searchf = meth->searchf;
- dt->meth = meth;
+ /* allocate sharable data */
+ if(!(data = (Dtdata_t*)(dt->memoryf)(dt,NIL(Void_t*),sizeof(Dtdata_t),disc)) )
+ { err_open:
+ free((Void_t*)dt);
+ return NIL(Dt_t*);
+ }
- return dt;
-}
+ data->type = meth->type;
+ data->here = NIL(Dtlink_t*);
+ data->htab = NIL(Dtlink_t**);
+ data->ntab = data->size = data->loop = 0;
+ data->minp = 0;
-#if __hppa
+done:
+ dt->data = data;
+ dt->searchf = meth->searchf;
+ dt->meth = meth;
-/*
- * some dll implementations forget that data symbols
- * need address resolution too
- */
+ if(disc->eventf)
+ (*disc->eventf)(dt, DT_ENDOPEN, (Void_t*)dt, disc);
-#if __STD_C
-int _dt_dynamic_data(void)
-#else
-int _dt_dynamic_data()
-#endif
-{
- return (Dtset != 0) + (Dtlist != 0) + (Dttree != 0);
+ return dt;
}
-
-#endif /* __hppa */
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
/* Renew the object at the current finger.
**
*/
#if __STD_C
-Void_t *dtrenew(Dt_t * dt, reg Void_t * obj)
+Void_t* dtrenew(Dt_t* dt, reg Void_t* obj)
#else
-Void_t *dtrenew(dt, obj)
-Dt_t *dt;
-reg Void_t *obj;
+Void_t* dtrenew(dt, obj)
+Dt_t* dt;
+reg Void_t* obj;
#endif
{
- reg Void_t *key;
- reg Dtlink_t *e, *t, **s;
- reg Dtdisc_t *disc = dt->disc;
-
- UNFLATTEN(dt);
-
- if (!(e = dt->data->here) || OBJ(e, disc->link) != obj)
- return NIL(Void_t *);
-
- if (dt->data->type & (DT_STACK | DT_QUEUE | DT_LIST))
- return obj;
- else if (dt->data->type & (DT_OSET | DT_OBAG)) {
- if (!e->right) /* make left child the new root */
- dt->data->here = e->left;
- else { /* make right child the new root */
- dt->data->here = e->right;
-
- /* merge left subtree to right subtree */
- if (e->left) {
- for (t = e->right; t->left; t = t->left);
- t->left = e->left;
- }
+ reg Void_t* key;
+ reg Dtlink_t *e, *t, **s;
+ reg Dtdisc_t* disc = dt->disc;
+
+ UNFLATTEN(dt);
+
+ if(!(e = dt->data->here) || _DTOBJ(e,disc->link) != obj)
+ return NIL(Void_t*);
+
+ if(dt->data->type&(DT_STACK|DT_QUEUE|DT_LIST))
+ return obj;
+ else if(dt->data->type&(DT_OSET|DT_OBAG) )
+ { if(!e->right ) /* make left child the new root */
+ dt->data->here = e->left;
+ else /* make right child the new root */
+ { dt->data->here = e->right;
+
+ /* merge left subtree to right subtree */
+ if(e->left)
+ { for(t = e->right; t->left; t = t->left)
+ ;
+ t->left = e->left;
+ }
+ }
}
- } else { /*if(dt->data->type&(DT_SET|DT_BAG)) */
- s = dt->data->htab + HINDEX(dt->data->ntab, e->hash);
- if ((t = *s) == e)
- *s = e->right;
- else {
- for (; t->right != e; t = t->right);
- t->right = e->right;
+ else /*if(dt->data->type&(DT_SET|DT_BAG))*/
+ { s = dt->data->htab + HINDEX(dt->data->ntab,e->hash);
+ if((t = *s) == e)
+ *s = e->right;
+ else
+ { for(; t->right != e; t = t->right)
+ ;
+ t->right = e->right;
+ }
+ key = _DTKEY(obj,disc->key,disc->size);
+ e->hash = _DTHSH(dt,key,disc,disc->size);
+ dt->data->here = NIL(Dtlink_t*);
}
- key = KEY(obj, disc->key, disc->size);
- e->hash = HASH(dt, key, disc, disc->size);
- dt->data->here = NIL(Dtlink_t *);
- }
- dt->data->size -= 1;
- return (*dt->meth->searchf) (dt, (Void_t *) e,
- DT_RENEW) ? obj : NIL(Void_t *);
+ dt->data->size -= 1;
+ return (*dt->meth->searchf)(dt,(Void_t*)e,DT_RENEW) ? obj : NIL(Void_t*);
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Restore dictionary from given tree or list of elements.
** There are two cases. If called from within, list is nil.
** From without, list is not nil and data->size must be 0.
** Written by Kiem-Phong Vo (5/25/96)
*/
-
-
#if __STD_C
-int dtrestore(reg Dt_t * dt, reg Dtlink_t * list)
+int dtrestore(reg Dt_t* dt, reg Dtlink_t* list)
#else
int dtrestore(dt, list)
-reg Dt_t *dt;
-reg Dtlink_t *list;
+reg Dt_t* dt;
+reg Dtlink_t* list;
#endif
{
- reg Dtlink_t *t, **s, **ends;
- reg int type;
- reg Dtsearch_f searchf = dt->meth->searchf;
+ reg Dtlink_t *t, **s, **ends;
+ reg int type;
+ reg Dtsearch_f searchf = dt->meth->searchf;
- type = dt->data->type & DT_FLATTEN;
- if (!list) { /* restoring a flattened dictionary */
- if (!type)
- return -1;
- list = dt->data->here;
- } else { /* restoring an extracted list of elements */
- if (dt->data->size != 0)
- return -1;
- type = 0;
- }
- dt->data->type &= ~DT_FLATTEN;
+ type = dt->data->type&DT_FLATTEN;
+ if(!list) /* restoring a flattened dictionary */
+ { if(!type)
+ return -1;
+ list = dt->data->here;
+ }
+ else /* restoring an extracted list of elements */
+ { if(dt->data->size != 0)
+ return -1;
+ type = 0;
+ }
+ dt->data->type &= ~DT_FLATTEN;
- if (dt->data->type & (DT_SET | DT_BAG)) {
- dt->data->here = NIL(Dtlink_t *);
- if (type) { /* restoring a flattened dictionary */
- for (ends = (s = dt->data->htab) + dt->data->ntab; s < ends;
- ++s) {
- if ((t = *s)) {
- *s = list;
- list = t->right;
- t->right = NIL(Dtlink_t *);
+ if(dt->data->type&(DT_SET|DT_BAG))
+ { dt->data->here = NIL(Dtlink_t*);
+ if(type) /* restoring a flattened dictionary */
+ { for(ends = (s = dt->data->htab) + dt->data->ntab; s < ends; ++s)
+ { if((t = *s) )
+ { *s = list;
+ list = t->right;
+ t->right = NIL(Dtlink_t*);
+ }
+ }
+ }
+ else /* restoring an extracted list of elements */
+ { dt->data->size = 0;
+ while(list)
+ { t = list->right;
+ (*searchf)(dt,(Void_t*)list,DT_RENEW);
+ list = t;
+ }
}
- }
- } else { /* restoring an extracted list of elements */
- dt->data->size = 0;
- while (list) {
- t = list->right;
- (*searchf) (dt, (Void_t *) list, DT_RENEW);
- list = t;
- }
}
- } else {
- if (dt->data->type & (DT_OSET | DT_OBAG))
- dt->data->here = list;
- else { /*if(dt->data->type&(DT_LIST|DT_STACK|DT_QUEUE)) */
- dt->data->here = NIL(Dtlink_t *);
- dt->data->head = list;
+ else
+ { if(dt->data->type&(DT_OSET|DT_OBAG))
+ dt->data->here = list;
+ else /*if(dt->data->type&(DT_LIST|DT_STACK|DT_QUEUE))*/
+ { dt->data->here = NIL(Dtlink_t*);
+ dt->data->head = list;
+ }
+ if(!type)
+ dt->data->size = -1;
}
- if (!type)
- dt->data->size = -1;
- }
- return 0;
+ return 0;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Return the # of objects in the dictionary
**
** Written by Kiem-Phong Vo (5/25/96)
*/
#if __STD_C
-static int treecount(reg Dtlink_t * e)
+static int treecount(reg Dtlink_t* e)
#else
static int treecount(e)
-reg Dtlink_t *e;
+reg Dtlink_t* e;
#endif
-{
- return e ? treecount(e->left) + treecount(e->right) + 1 : 0;
+{ return e ? treecount(e->left) + treecount(e->right) + 1 : 0;
}
#if __STD_C
-int dtsize(Dt_t * dt)
+int dtsize(Dt_t* dt)
#else
int dtsize(dt)
-Dt_t *dt;
+Dt_t* dt;
#endif
{
- reg Dtlink_t *t;
- reg int size;
-
- UNFLATTEN(dt);
-
- if (dt->data->size < 0) { /* !(dt->data->type&(DT_SET|DT_BAG)) */
- if (dt->data->type & (DT_OSET | DT_OBAG))
- dt->data->size = treecount(dt->data->here);
- else if (dt->data->type & (DT_LIST | DT_STACK | DT_QUEUE)) {
- for (size = 0, t = dt->data->head; t; t = t->right)
- size += 1;
- dt->data->size = size;
+ reg Dtlink_t* t;
+ reg int size;
+
+ UNFLATTEN(dt);
+
+ if(dt->data->size < 0) /* !(dt->data->type&(DT_SET|DT_BAG)) */
+ { if(dt->data->type&(DT_OSET|DT_OBAG))
+ dt->data->size = treecount(dt->data->here);
+ else if(dt->data->type&(DT_LIST|DT_STACK|DT_QUEUE))
+ { for(size = 0, t = dt->data->head; t; t = t->right)
+ size += 1;
+ dt->data->size = size;
+ }
}
- }
- return dt->data->size;
+ return dt->data->size;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Get statistics of a dictionary
**
** Written by Kiem-Phong Vo (5/25/96)
*/
#if __STD_C
-static void dttstat(Dtstat_t * ds, Dtlink_t * root, int depth, int *level)
+static void dttstat(Dtstat_t* ds, Dtlink_t* root, int depth, int* level)
#else
-static void dttstat(ds, root, depth, level)
-Dtstat_t *ds;
-Dtlink_t *root;
-int depth;
-int *level;
+static void dttstat(ds,root,depth,level)
+Dtstat_t* ds;
+Dtlink_t* root;
+int depth;
+int* level;
#endif
{
- if (root->left)
- dttstat(ds, root->left, depth + 1, level);
- if (root->right)
- dttstat(ds, root->right, depth + 1, level);
- if (depth > ds->dt_n)
- ds->dt_n = depth;
- if (level)
- level[depth] += 1;
+ if(root->left)
+ dttstat(ds,root->left,depth+1,level);
+ if(root->right)
+ dttstat(ds,root->right,depth+1,level);
+ if(depth > ds->dt_n)
+ ds->dt_n = depth;
+ if(level)
+ level[depth] += 1;
}
#if __STD_C
-static void dthstat(reg Dtdata_t * data, Dtstat_t * ds, reg int *count)
+static void dthstat(reg Dtdata_t* data, Dtstat_t* ds, reg int* count)
#else
static void dthstat(data, ds, count)
-reg Dtdata_t *data;
-Dtstat_t *ds;
-reg int *count;
+reg Dtdata_t* data;
+Dtstat_t* ds;
+reg int* count;
#endif
{
- reg Dtlink_t *t;
- reg int n, h;
+ reg Dtlink_t* t;
+ reg int n, h;
- for (h = data->ntab - 1; h >= 0; --h) {
- n = 0;
- for (t = data->htab[h]; t; t = t->right)
- n += 1;
- if (count)
- count[n] += 1;
- else if (n > 0) {
- ds->dt_n += 1;
- if (n > ds->dt_max)
- ds->dt_max = n;
+ for(h = data->ntab-1; h >= 0; --h)
+ { n = 0;
+ for(t = data->htab[h]; t; t = t->right)
+ n += 1;
+ if(count)
+ count[n] += 1;
+ else if(n > 0)
+ { ds->dt_n += 1;
+ if(n > ds->dt_max)
+ ds->dt_max = n;
+ }
}
- }
}
#if __STD_C
-int dtstat(reg Dt_t * dt, Dtstat_t * ds, int all)
+int dtstat(reg Dt_t* dt, Dtstat_t* ds, int all)
#else
int dtstat(dt, ds, all)
-reg Dt_t *dt;
-Dtstat_t *ds;
-int all;
+reg Dt_t* dt;
+Dtstat_t* ds;
+int all;
#endif
{
- reg int i;
- static int *Count, Size;
+ reg int i;
+ static int *Count, Size;
- UNFLATTEN(dt);
+ UNFLATTEN(dt);
- ds->dt_n = ds->dt_max = 0;
- ds->dt_count = NIL(int *);
- ds->dt_size = dtsize(dt);
- ds->dt_meth = dt->data->type & DT_METHODS;
+ ds->dt_n = ds->dt_max = 0;
+ ds->dt_count = NIL(int*);
+ ds->dt_size = dtsize(dt);
+ ds->dt_meth = dt->data->type&DT_METHODS;
- if (!all)
- return 0;
+ if(!all)
+ return 0;
- if (dt->data->type & (DT_SET | DT_BAG)) {
- dthstat(dt->data, ds, NIL(int *));
- if (ds->dt_max + 1 > Size) {
- if (Size > 0)
- free(Count);
- if (!(Count = (int *) malloc((ds->dt_max + 1) * sizeof(int))))
- return -1;
- Size = ds->dt_max + 1;
+ if(dt->data->type&(DT_SET|DT_BAG))
+ { dthstat(dt->data,ds,NIL(int*));
+ if(ds->dt_max+1 > Size)
+ { if(Size > 0)
+ free(Count);
+ if(!(Count = (int*)malloc((ds->dt_max+1)*sizeof(int))) )
+ return -1;
+ Size = ds->dt_max+1;
+ }
+ for(i = ds->dt_max; i >= 0; --i)
+ Count[i] = 0;
+ dthstat(dt->data,ds,Count);
}
- for (i = ds->dt_max; i >= 0; --i)
- Count[i] = 0;
- dthstat(dt->data, ds, Count);
- } else if (dt->data->type & (DT_OSET | DT_OBAG)) {
- if (dt->data->here) {
- dttstat(ds, dt->data->here, 0, NIL(int *));
- if (ds->dt_n + 1 > Size) {
- if (Size > 0)
- free(Count);
- if (!
- (Count = (int *) malloc((ds->dt_n + 1) * sizeof(int))))
- return -1;
- Size = ds->dt_n + 1;
- }
+ else if(dt->data->type&(DT_OSET|DT_OBAG))
+ { if(dt->data->here)
+ { dttstat(ds,dt->data->here,0,NIL(int*));
+ if(ds->dt_n+1 > Size)
+ { if(Size > 0)
+ free(Count);
+ if(!(Count = (int*)malloc((ds->dt_n+1)*sizeof(int))) )
+ return -1;
+ Size = ds->dt_n+1;
+ }
- for (i = ds->dt_n; i >= 0; --i)
- Count[i] = 0;
- dttstat(ds, dt->data->here, 0, Count);
- for (i = ds->dt_n; i >= 0; --i)
- if (Count[i] > ds->dt_max)
- ds->dt_max = Count[i];
+ for(i = ds->dt_n; i >= 0; --i)
+ Count[i] = 0;
+ dttstat(ds,dt->data->here,0,Count);
+ for(i = ds->dt_n; i >= 0; --i)
+ if(Count[i] > ds->dt_max)
+ ds->dt_max = Count[i];
+ }
}
- }
- ds->dt_count = Count;
+ ds->dt_count = Count;
- return 0;
+ return 0;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-/* Hashing a string
+/* Hashing a string into an unsigned integer.
+** The basic method is to continuingly accumulate bytes and multiply
+** with some given prime. The length n of the string is added last.
+** The recurrent equation is like this:
+** h[k] = (h[k-1] + bytes)*prime for 0 <= k < n
+** h[n] = (h[n-1] + n)*prime
+** The prime is chosen to have a good distribution of 1-bits so that
+** the multiplication will distribute the bits in the accumulator well.
+** The below code accumulates 2 bytes at a time for speed.
**
-** Written by Kiem-Phong Vo (05/22/96)
+** Written by Kiem-Phong Vo (02/28/03)
*/
+
#if __STD_C
-uint dtstrhash(reg uint h, Void_t * args, reg int n)
+uint dtstrhash(reg uint h, Void_t* args, reg int n)
#else
-uint dtstrhash(h, args, n)
-reg uint h;
-Void_t *args;
-reg int n;
+uint dtstrhash(h,args,n)
+reg uint h;
+Void_t* args;
+reg int n;
#endif
{
- reg unsigned char *s = (unsigned char *) args;
+ reg unsigned char* s = (unsigned char*)args;
- if (n <= 0) {
- for (; (n = *s) != 0; ++s)
- h = dtcharhash(h, n);
- } else {
- reg unsigned char *ends;
- for (ends = s + n; s < ends; ++s) {
- n = *s;
- h = dtcharhash(h, n);
+ if(n <= 0)
+ { for(; *s != 0; s += s[1] ? 2 : 1)
+ h = (h + (s[0]<<8) + s[1])*DT_PRIME;
+ n = s - (unsigned char*)args;
}
- }
-
- return h;
+ else
+ { reg unsigned char* ends;
+ for(ends = s+n-1; s < ends; s += 2)
+ h = (h + (s[0]<<8) + s[1])*DT_PRIME;
+ if(s <= ends)
+ h = (h + (s[0]<<8))*DT_PRIME;
+ }
+ return (h+n)*DT_PRIME;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Ordered set/multiset
** dt: dictionary being searched
** obj: the object to look for.
*/
#if __STD_C
-static Void_t *dttree(Dt_t * dt, Void_t * obj, int type)
+static Void_t* dttree(Dt_t* dt, Void_t* obj, int type)
#else
-static Void_t *dttree(dt, obj, type)
-Dt_t *dt;
-Void_t *obj;
-int type;
+static Void_t* dttree(dt,obj,type)
+Dt_t* dt;
+Void_t* obj;
+int type;
#endif
{
- reg Dtlink_t *root, *t;
- reg int cmp, lk, sz, ky;
- reg Void_t *k, *key;
- reg Dtcompar_f cmpf;
- reg Dtdisc_t *disc;
- reg Dtlink_t *l, *r, *me;
- Dtlink_t link;
+ Dtlink_t *root, *t;
+ int cmp, lk, sz, ky;
+ Void_t *o, *k, *key;
+ Dtlink_t *l, *r, *me, link;
+ int n, minp, turn[DT_MINP];
+ Dtcompar_f cmpf;
+ Dtdisc_t* disc;
+
+ UNFLATTEN(dt);
+ disc = dt->disc; _DTDSC(disc,ky,sz,lk,cmpf);
+ dt->type &= ~DT_FOUND;
+
+ root = dt->data->here;
+ if(!obj)
+ { if(!root || !(type&(DT_CLEAR|DT_FIRST|DT_LAST)) )
+ return NIL(Void_t*);
- me = 0;
- UNFLATTEN(dt);
- INITDISC(dt, disc, ky, sz, lk, cmpf);
+ if(type&DT_CLEAR) /* delete all objects */
+ { if(disc->freef || disc->link < 0)
+ { do
+ { while((t = root->left) )
+ RROTATE(root,t);
+ t = root->right;
+ if(disc->freef)
+ (*disc->freef)(dt,_DTOBJ(root,lk),disc);
+ if(disc->link < 0)
+ (*dt->memoryf)(dt,(Void_t*)root,0,disc);
+ } while((root = t) );
+ }
- root = dt->data->here;
- if (!obj) {
- if (!root || !(type & (DT_CLEAR | DT_FIRST | DT_LAST)))
- return NIL(Void_t *);
+ dt->data->size = 0;
+ dt->data->here = NIL(Dtlink_t*);
+ return NIL(Void_t*);
+ }
+ else /* computing largest/smallest element */
+ { if(type&DT_LAST)
+ { while((t = root->right) )
+ LROTATE(root,t);
+ }
+ else /* type&DT_FIRST */
+ { while((t = root->left) )
+ RROTATE(root,t);
+ }
- if (type & DT_CLEAR) { /* delete all objects */
- if (disc->freef || disc->link < 0) {
- do {
- while ((t = root->left))
- RROTATE(root, t);
- t = root->right;
- if (disc->freef)
- (*disc->freef) (dt, OBJ(root, lk), disc);
- if (disc->link < 0)
- (*dt->memoryf) (dt, (Void_t *) root, 0, disc);
- } while ((root = t));
- }
+ dt->data->here = root;
+ return _DTOBJ(root,lk);
+ }
+ }
- dt->data->size = 0;
- dt->data->here = NIL(Dtlink_t *);
- return NIL(Void_t *);
- } else { /* computing largest/smallest element */
- if (type & DT_LAST) {
- while ((t = root->right))
- LROTATE(root, t);
- } else { /* type&DT_FIRST */
- while ((t = root->left))
- RROTATE(root, t);
- }
+ /* note that link.right is LEFT tree and link.left is RIGHT tree */
+ l = r = &link;
- dt->data->here = root;
- return OBJ(root, lk);
+ /* allow apps to delete an object "actually" in the dictionary */
+ if(dt->meth->type == DT_OBAG && (type&(DT_DELETE|DT_DETACH)) )
+ { key = _DTKEY(obj,ky,sz);
+ for(o = dtsearch(dt,obj); o; o = dtnext(dt,o) )
+ { k = _DTKEY(o,ky,sz);
+ if(_DTCMP(dt,key,k,disc,cmpf,sz) != 0)
+ break;
+ if(o == obj)
+ { root = dt->data->here;
+ l->right = root->left;
+ r->left = root->right;
+ goto dt_delete;
+ }
+ }
}
- }
- /* note that link.right is LEFT tree and link.left is RIGHT tree */
- l = r = &link;
+ if(type&(DT_MATCH|DT_SEARCH|DT_INSERT|DT_ATTACH))
+ { key = (type&DT_MATCH) ? obj : _DTKEY(obj,ky,sz);
+ if(root)
+ goto do_search;
+ }
+ else if(type&DT_RENEW)
+ { me = (Dtlink_t*)obj;
+ obj = _DTOBJ(me,lk);
+ key = _DTKEY(obj,ky,sz);
+ if(root)
+ goto do_search;
+ }
+ else if(root && _DTOBJ(root,lk) != obj)
+ { key = _DTKEY(obj,ky,sz);
+ do_search:
+ if(dt->meth->type == DT_OSET &&
+ (minp = dt->data->minp) != 0 && (type&(DT_MATCH|DT_SEARCH)) )
+ { /* simple search, note that minp should be even */
+ for(t = root, n = 0; n < minp; ++n)
+ { k = _DTOBJ(t,lk); k = _DTKEY(k,ky,sz);
+ if((cmp = _DTCMP(dt,key,k,disc,cmpf,sz)) == 0)
+ return _DTOBJ(t,lk);
+ else
+ { turn[n] = cmp;
+ if(!(t = cmp < 0 ? t->left : t->right) )
+ return NIL(Void_t*);
+ }
+ }
- if (type & (DT_MATCH | DT_SEARCH | DT_INSERT | DT_ATTACH)) {
- key = (type & DT_MATCH) ? obj : KEY(obj, ky, sz);
- if (root)
- goto do_search;
- } else if (type & DT_RENEW) {
- me = (Dtlink_t *) obj;
- obj = OBJ(me, lk);
- key = KEY(obj, ky, sz);
- if (root)
- goto do_search;
- } else if (root && OBJ(root, lk) != obj) {
- key = KEY(obj, ky, sz);
- do_search:
- while (1) {
- k = OBJ(root, lk);
- k = KEY(k, ky, sz);
- if ((cmp = CMP(dt, key, k, disc, cmpf, sz)) == 0)
- break;
- else if (cmp < 0) {
- if ((t = root->left)) {
- k = OBJ(t, lk);
- k = KEY(k, ky, sz);
- if ((cmp = CMP(dt, key, k, disc, cmpf, sz)) < 0) {
- RROTATE(root, t);
- RLINK(r, root);
- if (!(root = root->left))
- break;
- } else if (cmp == 0) {
- RROTATE(root, t);
- break;
- } else { /* if(cmp > 0) */
- LLINK(l, t);
- RLINK(r, root);
- if (!(root = t->right))
- break;
- }
- } else {
- RLINK(r, root);
- root = NIL(Dtlink_t *);
- break;
+ /* exceed search length, top-down splay now */
+ for(n = 0; n < minp; n += 2)
+ { if(turn[n] < 0)
+ { t = root->left;
+ if(turn[n+1] < 0)
+ { rrotate(root,t);
+ rlink(r,t);
+ root = t->left;
+ }
+ else
+ { llink(l,t);
+ rlink(r,root);
+ root = t->right;
+ }
+ }
+ else
+ { t = root->right;
+ if(turn[n+1] > 0)
+ { lrotate(root,t);
+ llink(l,t);
+ root = t->right;
+ }
+ else
+ { rlink(r,t);
+ llink(l,root);
+ root = t->left;
+ }
+ }
+ }
}
- } else { /* if(cmp > 0) */
- if ((t = root->right)) {
- k = OBJ(t, lk);
- k = KEY(k, ky, sz);
- if ((cmp = CMP(dt, key, k, disc, cmpf, sz)) > 0) {
- LROTATE(root, t);
- LLINK(l, root);
- if (!(root = root->right))
- break;
- } else if (cmp == 0) {
- LROTATE(root, t);
- break;
- } else { /* if(cmp < 0) */
- RLINK(r, t);
- LLINK(l, root);
- if (!(root = t->left))
- break;
- }
- } else {
- LLINK(l, root);
- root = NIL(Dtlink_t *);
- break;
+
+ while(1)
+ { k = _DTOBJ(root,lk); k = _DTKEY(k,ky,sz);
+ if((cmp = _DTCMP(dt,key,k,disc,cmpf,sz)) == 0)
+ break;
+ else if(cmp < 0)
+ { if((t = root->left) )
+ { k = _DTOBJ(t,lk); k = _DTKEY(k,ky,sz);
+ if((cmp = _DTCMP(dt,key,k,disc,cmpf,sz)) < 0)
+ { rrotate(root,t);
+ rlink(r,t);
+ if(!(root = t->left) )
+ break;
+ }
+ else if(cmp == 0)
+ { rlink(r,root);
+ root = t;
+ break;
+ }
+ else /* if(cmp > 0) */
+ { llink(l,t);
+ rlink(r,root);
+ if(!(root = t->right) )
+ break;
+ }
+ }
+ else
+ { rlink(r,root);
+ root = NIL(Dtlink_t*);
+ break;
+ }
+ }
+ else /* if(cmp > 0) */
+ { if((t = root->right) )
+ { k = _DTOBJ(t,lk); k = _DTKEY(k,ky,sz);
+ if((cmp = _DTCMP(dt,key,k,disc,cmpf,sz)) > 0)
+ { lrotate(root,t);
+ llink(l,t);
+ if(!(root = t->right) )
+ break;
+ }
+ else if(cmp == 0)
+ { llink(l,root);
+ root = t;
+ break;
+ }
+ else /* if(cmp < 0) */
+ { rlink(r,t);
+ llink(l,root);
+ if(!(root = t->left) )
+ break;
+ }
+ }
+ else
+ { llink(l,root);
+ root = NIL(Dtlink_t*);
+ break;
+ }
+ }
}
- }
}
- }
- if (root) { /* found it, now isolate it */
- l->right = root->left;
- r->left = root->right;
+ if(root)
+ { /* found it, now isolate it */
+ dt->type |= DT_FOUND;
+ l->right = root->left;
+ r->left = root->right;
+
+ if(type&(DT_SEARCH|DT_MATCH))
+ { has_root:
+ root->left = link.right;
+ root->right = link.left;
+ if((dt->meth->type&DT_OBAG) && (type&(DT_SEARCH|DT_MATCH)) )
+ { key = _DTOBJ(root,lk); key = _DTKEY(key,ky,sz);
+ while((t = root->left) )
+ { /* find max of left subtree */
+ while((r = t->right) )
+ LROTATE(t,r);
+ root->left = t;
- if (type & (DT_SEARCH | DT_MATCH)) {
- has_root:
- root->left = link.right;
- root->right = link.left;
- if ((dt->meth->type & DT_OBAG)
- && (type & (DT_SEARCH | DT_MATCH))) {
- key = OBJ(root, lk);
- key = KEY(key, ky, sz);
- while ((t = root->left)) {
- k = OBJ(t, lk);
- k = KEY(k, ky, sz);
- if (CMP(dt, key, k, disc, cmpf, sz) != 0)
- break;
- RROTATE(root, t);
+ /* now see if it's in the same group */
+ k = _DTOBJ(t,lk); k = _DTKEY(k,ky,sz);
+ if(_DTCMP(dt,key,k,disc,cmpf,sz) != 0)
+ break;
+ RROTATE(root,t);
+ }
+ }
+ dt->data->here = root;
+ return _DTOBJ(root,lk);
+ }
+ else if(type&DT_NEXT)
+ { root->left = link.right;
+ root->right = NIL(Dtlink_t*);
+ link.right = root;
+ dt_next:
+ if((root = link.left) )
+ { while((t = root->left) )
+ RROTATE(root,t);
+ link.left = root->right;
+ goto has_root;
+ }
+ else goto no_root;
+ }
+ else if(type&DT_PREV)
+ { root->right = link.left;
+ root->left = NIL(Dtlink_t*);
+ link.left = root;
+ dt_prev:
+ if((root = link.right) )
+ { while((t = root->right) )
+ LROTATE(root,t);
+ link.right = root->left;
+ goto has_root;
+ }
+ else goto no_root;
+ }
+ else if(type&(DT_DELETE|DT_DETACH))
+ { /* taking an object out of the dictionary */
+ dt_delete:
+ obj = _DTOBJ(root,lk);
+ if(disc->freef && (type&DT_DELETE))
+ (*disc->freef)(dt,obj,disc);
+ if(disc->link < 0)
+ (*dt->memoryf)(dt,(Void_t*)root,0,disc);
+ if((dt->data->size -= 1) < 0)
+ dt->data->size = -1;
+ goto no_root;
+ }
+ else if(type&(DT_INSERT|DT_ATTACH))
+ { if(dt->meth->type&DT_OSET)
+ goto has_root;
+ else
+ { root->left = NIL(Dtlink_t*);
+ root->right = link.left;
+ link.left = root;
+ goto dt_insert;
+ }
+ }
+ else if(type&DT_RENEW) /* a duplicate */
+ { if(dt->meth->type&DT_OSET)
+ { if(disc->freef)
+ (*disc->freef)(dt,obj,disc);
+ if(disc->link < 0)
+ (*dt->memoryf)(dt,(Void_t*)me,0,disc);
+ }
+ else
+ { me->left = NIL(Dtlink_t*);
+ me->right = link.left;
+ link.left = me;
+ dt->data->size += 1;
+ }
+ goto has_root;
}
- }
- dt->data->here = root;
- return OBJ(root, lk);
- } else if (type & DT_NEXT) {
- root->left = link.right;
- root->right = NIL(Dtlink_t *);
- link.right = root;
- dt_next:
- if ((root = link.left)) {
- while ((t = root->left))
- RROTATE(root, t);
- link.left = root->right;
- goto has_root;
- } else
- goto no_root;
- } else if (type & DT_PREV) {
- root->right = link.left;
- root->left = NIL(Dtlink_t *);
- link.left = root;
- dt_prev:
- if ((root = link.right)) {
- while ((t = root->right))
- LROTATE(root, t);
- link.right = root->left;
- goto has_root;
- } else
- goto no_root;
- } else if (type & (DT_DELETE | DT_DETACH)) {
- obj = OBJ(root, lk);
- if (disc->freef && (type & DT_DELETE))
- (*disc->freef) (dt, obj, disc);
- if (disc->link < 0)
- (*dt->memoryf) (dt, (Void_t *) root, 0, disc);
- if ((dt->data->size -= 1) < 0)
- dt->data->size = -1;
- goto no_root;
- } else if (type & (DT_INSERT | DT_ATTACH)) {
- if (dt->meth->type & DT_OSET)
- goto has_root;
- else {
- root->left = NIL(Dtlink_t *);
- root->right = link.left;
- link.left = root;
- goto dt_insert;
- }
- } else if (type & DT_RENEW) { /* a duplicate */
- if (dt->meth->type & DT_OSET) {
- if (disc->freef)
- (*disc->freef) (dt, obj, disc);
- if (disc->link < 0)
- (*dt->memoryf) (dt, (Void_t *) me, 0, disc);
- } else {
- me->left = NIL(Dtlink_t *);
- me->right = link.left;
- link.left = me;
- dt->data->size += 1;
- }
- goto has_root;
}
- } else { /* not found, finish up LEFT and RIGHT trees */
- r->left = NIL(Dtlink_t *);
- l->right = NIL(Dtlink_t *);
+ else
+ { /* not found, finish up LEFT and RIGHT trees */
+ r->left = NIL(Dtlink_t*);
+ l->right = NIL(Dtlink_t*);
- if (type & (DT_SEARCH | DT_MATCH)) {
- no_root:
- while ((t = r->left))
- r = t;
- r->left = link.right;
- dt->data->here = link.left;
- return (type & DT_DELETE) ? obj : NIL(Void_t *);
- } else if (type & (DT_INSERT | DT_ATTACH)) {
- dt_insert:
- if (disc->makef && (type & DT_INSERT))
- obj = (*disc->makef) (dt, obj, disc);
- if (obj) {
- if (lk >= 0)
- root = ELT(obj, lk);
- else {
- root = (Dtlink_t *) (*dt->memoryf)
- (dt, NIL(Void_t *), sizeof(Dthold_t), disc);
- if (root)
- ((Dthold_t *) root)->obj = obj;
- else if (disc->makef && disc->freef &&
- (type & DT_INSERT))
- (*disc->freef) (dt, obj, disc);
+ if(type&DT_NEXT)
+ goto dt_next;
+ else if(type&DT_PREV)
+ goto dt_prev;
+ else if(type&(DT_SEARCH|DT_MATCH))
+ { no_root:
+ while((t = r->left) )
+ r = t;
+ r->left = link.right;
+ dt->data->here = link.left;
+ return (type&DT_DELETE) ? obj : NIL(Void_t*);
+ }
+ else if(type&(DT_INSERT|DT_ATTACH))
+ { dt_insert:
+ if(disc->makef && (type&DT_INSERT))
+ obj = (*disc->makef)(dt,obj,disc);
+ if(obj)
+ { if(lk >= 0)
+ root = _DTLNK(obj,lk);
+ else
+ { root = (Dtlink_t*)(*dt->memoryf)
+ (dt,NIL(Void_t*),sizeof(Dthold_t),disc);
+ if(root)
+ ((Dthold_t*)root)->obj = obj;
+ else if(disc->makef && disc->freef &&
+ (type&DT_INSERT))
+ (*disc->freef)(dt,obj,disc);
+ }
+ }
+ if(root)
+ { if(dt->data->size >= 0)
+ dt->data->size += 1;
+ goto has_root;
+ }
+ else goto no_root;
+ }
+ else if(type&DT_RENEW)
+ { root = me;
+ dt->data->size += 1;
+ goto has_root;
+ }
+ else /*if(type&DT_DELETE)*/
+ { obj = NIL(Void_t*);
+ goto no_root;
}
- }
- if (root) {
- if (dt->data->size >= 0)
- dt->data->size += 1;
- goto has_root;
- } else
- goto no_root;
- } else if (type & DT_NEXT)
- goto dt_next;
- else if (type & DT_PREV)
- goto dt_prev;
- else if (type & DT_RENEW) {
- root = me;
- dt->data->size += 1;
- goto has_root;
- } else { /*if(type&DT_DELETE) */
- obj = NIL(Void_t *);
- goto no_root;
}
- }
- return NIL(Void_t *);
+ return NIL(Void_t*);
}
/* make this method available */
-static Dtmethod_t _Dtoset = { dttree, DT_OSET };
-static Dtmethod_t _Dtobag = { dttree, DT_OBAG };
-
-__DEFINE__(Dtmethod_t *, Dtoset, &_Dtoset);
-__DEFINE__(Dtmethod_t *, Dtobag, &_Dtobag);
+static Dtmethod_t _Dtoset = { dttree, DT_OSET };
+static Dtmethod_t _Dtobag = { dttree, DT_OBAG };
+__DEFINE__(Dtmethod_t*,Dtoset,&_Dtoset);
+__DEFINE__(Dtmethod_t*,Dtobag,&_Dtobag);
-#ifndef KPVDEL /* backward compatibility - delete next time around */
-Dtmethod_t _Dttree = { dttree, DT_OSET };
+#ifndef KPVDEL /* backward compatibility - delete next time around */
+Dtmethod_t _Dttree = { dttree, DT_OSET };
+__DEFINE__(Dtmethod_t*,Dtorder,&_Dttree);
+__DEFINE__(Dtmethod_t*,Dttree,&_Dttree);
+#endif
-__DEFINE__(Dtmethod_t *, Dtorder, &_Dttree);
-__DEFINE__(Dtmethod_t *, Dttree, &_Dttree);
+#ifdef NoF
+NoF(dttree)
#endif
--- /dev/null
+#include "dthdr.h"
+
+/* Set attributes of a tree.
+**
+** Written by Kiem-Phong Vo (09/17/2001)
+*/
+
+#if __STD_C
+static Dtlink_t* treebalance(Dtlink_t* list, int size)
+#else
+static Dtlink_t* treebalance(list, size)
+Dtlink_t* list;
+int size;
+#endif
+{
+ int n;
+ Dtlink_t *l, *mid;
+
+ if(size <= 2)
+ return list;
+
+ for(l = list, n = size/2 - 1; n > 0; n -= 1)
+ l = l->right;
+
+ mid = l->right; l->right = NIL(Dtlink_t*);
+ mid->left = treebalance(list, (n = size/2) );
+ mid->right = treebalance(mid->right, size - (n + 1));
+ return mid;
+}
+
+#if __STD_C
+int dttreeset(Dt_t* dt, int minp, int balance)
+#else
+int dttreeset(dt, minp, balance)
+Dt_t* dt;
+int minp;
+int balance;
+#endif
+{
+ int size;
+
+ if(dt->meth->type != DT_OSET)
+ return -1;
+
+ size = dtsize(dt);
+
+ if(minp < 0)
+ { for(minp = 0; minp < DT_MINP; ++minp)
+ if((1 << minp) >= size)
+ break;
+ if(minp <= DT_MINP-4) /* use log(size) + 4 */
+ minp += 4;
+ }
+
+ if((dt->data->minp = minp + (minp%2)) > DT_MINP)
+ dt->data->minp = DT_MINP;
+
+ if(balance)
+ dt->data->here = treebalance(dtflatten(dt), size);
+
+ return 0;
+}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Set a view path from dict to view.
**
** Written by Kiem-Phong Vo (5/25/96)
#if __STD_C
-static Void_t *dtvsearch(Dt_t * dt, reg Void_t * obj, reg int type)
+static Void_t* dtvsearch(Dt_t* dt, reg Void_t* obj, reg int type)
#else
-static Void_t *dtvsearch(dt, obj, type)
-Dt_t *dt;
-reg Void_t *obj;
-reg int type;
+static Void_t* dtvsearch(dt,obj,type)
+Dt_t* dt;
+reg Void_t* obj;
+reg int type;
#endif
{
- reg Dt_t *d, *p;
- reg Void_t *o;
- reg Dtdisc_t *disc;
- reg Dtlink_t *here;
-
- /* these operations only happen at the top level */
- if (type & (DT_INSERT | DT_DELETE | DT_CLEAR | DT_RENEW))
- return (*(dt->meth->searchf)) (dt, obj, type);
-
- if (!obj && !(type & (DT_FIRST | DT_LAST)))
- return NIL(Void_t *);
-
- if (type & (DT_MATCH | DT_SEARCH | DT_FIRST | DT_LAST)) {
- for (d = dt; d; d = d->view) {
- if ((o = (*(d->meth->searchf)) (d, obj, type))) {
+ Dt_t *d, *p;
+ Void_t *o, *n, *ok, *nk;
+ int cmp, lk, sz, ky;
+ Dtcompar_f cmpf;
+
+ /* these operations only happen at the top level */
+ if(type&(DT_INSERT|DT_DELETE|DT_CLEAR|DT_RENEW))
+ return (*(dt->meth->searchf))(dt,obj,type);
+
+ if((type&(DT_MATCH|DT_SEARCH)) || /* order sets first/last done below */
+ ((type&(DT_FIRST|DT_LAST)) && !(dt->meth->type&(DT_OBAG|DT_OSET)) ) )
+ { for(d = dt; d; d = d->view)
+ if((o = (*(d->meth->searchf))(d,obj,type)) )
+ break;
dt->walk = d;
return o;
- }
}
- dt->walk = NIL(Dt_t *);
- return NIL(Void_t *);
- }
+ if(dt->meth->type & (DT_OBAG|DT_OSET) )
+ { if(!(type & (DT_FIRST|DT_LAST|DT_NEXT|DT_PREV)) )
+ return NIL(Void_t*);
+
+ n = nk = NIL(Void_t*); p = NIL(Dt_t*);
+ for(d = dt; d; d = d->view)
+ { if(!(o = (*d->meth->searchf)(d, obj, type)) )
+ continue;
+ _DTDSC(d->disc,ky,sz,lk,cmpf);
+ ok = _DTKEY(o,ky,sz);
+
+ if(n) /* get the right one among all dictionaries */
+ { cmp = _DTCMP(d,ok,nk,d->disc,cmpf,sz);
+ if(((type & (DT_NEXT|DT_FIRST)) && cmp < 0) ||
+ ((type & (DT_PREV|DT_LAST)) && cmp > 0) )
+ goto a_dj;
+ }
+ else /* looks good for now */
+ { a_dj: p = d;
+ n = o;
+ nk = ok;
+ }
+ }
+
+ dt->walk = p;
+ return n;
+ }
+
+ /* non-ordered methods */
+ if(!(type & (DT_NEXT|DT_PREV)) )
+ return NIL(Void_t*);
- /* must be (DT_NEXT|DT_PREV) */
- if (!dt->walk || !(here = dt->walk->data->here) ||
- obj != OBJ(here, dt->walk->disc->link)) {
- for (d = dt; d; d = d->view) {
- if ((o = (*(d->meth->searchf)) (d, obj, DT_SEARCH))) {
+ if(!dt->walk || obj != _DTOBJ(dt->walk->data->here, dt->walk->disc->link) )
+ { for(d = dt; d; d = d->view)
+ if((o = (*(d->meth->searchf))(d, obj, DT_SEARCH)) )
+ break;
dt->walk = d;
- goto do_adj;
- }
+ if(!(obj = o) )
+ return NIL(Void_t*);
}
- dt->walk = NIL(Dt_t *);
- return NIL(Void_t *);
- }
-
- do_adj:for (d = dt->walk, o = (*(d->meth->searchf)) (d, obj, type);;)
- {
- while (o) {
- disc = d->disc;
- here = (d->meth->type & (DT_SET | DT_BAG)) ?
- d->data->here : NIL(Dtlink_t *);
-
- for (p = dt;; p = p->view) {
- reg Dtdisc_t *dc;
-
- if (p == d) /* this object is uncovered */
- return o;
-
- /* see if it is covered */
- if (here && (p->meth->type & (DT_SET | DT_BAG)) &&
- (disc == (dc = p->disc) ||
- (disc->key == dc->key && disc->size == dc->size &&
- disc->link == dc->link && disc->hashf == dc->hashf)))
- {
- if ((*(p->meth->searchf)) (p, here, DT_VSEARCH))
- break;
- } else {
- if ((*(p->meth->searchf)) (p, o, DT_SEARCH))
- break;
+ for(d = dt->walk, obj = (*d->meth->searchf)(d, obj, type);; )
+ { while(obj) /* keep moving until finding an uncovered object */
+ { for(p = dt; ; p = p->view)
+ { if(p == d) /* adjacent object is uncovered */
+ return obj;
+ if((*(p->meth->searchf))(p, obj, DT_SEARCH) )
+ break;
+ }
+ obj = (*d->meth->searchf)(d, obj, type);
}
- }
- o = (*(d->meth->searchf)) (d, o, type);
+ if(!(d = dt->walk = d->view) ) /* move on to next dictionary */
+ return NIL(Void_t*);
+ else if(type&DT_NEXT)
+ obj = (*(d->meth->searchf))(d,NIL(Void_t*),DT_FIRST);
+ else obj = (*(d->meth->searchf))(d,NIL(Void_t*),DT_LAST);
}
-
- if (!(d = dt->walk = d->view))
- return NIL(Void_t *);
-
- if (type & DT_NEXT)
- o = (*(d->meth->searchf)) (d, NIL(Void_t *), DT_FIRST);
- else /* if(type&DT_PREV) */
- o = (*(d->meth->searchf)) (d, NIL(Void_t *), DT_LAST);
- }
}
#if __STD_C
-Dt_t *dtview(reg Dt_t * dt, reg Dt_t * view)
+Dt_t* dtview(reg Dt_t* dt, reg Dt_t* view)
#else
-Dt_t *dtview(dt, view)
-reg Dt_t *dt;
-reg Dt_t *view;
+Dt_t* dtview(dt,view)
+reg Dt_t* dt;
+reg Dt_t* view;
#endif
{
- reg Dt_t *d;
+ reg Dt_t* d;
- UNFLATTEN(dt);
- if (view)
- UNFLATTEN(view);
+ UNFLATTEN(dt);
+ if(view)
+ { UNFLATTEN(view);
+ if(view->meth != dt->meth) /* must use the same method */
+ return NIL(Dt_t*);
+ }
- /* make sure there won't be a cycle */
- for (d = view; d; d = d->view)
- if (d == dt)
- return NIL(Dt_t *);
+ /* make sure there won't be a cycle */
+ for(d = view; d; d = d->view)
+ if(d == dt)
+ return NIL(Dt_t*);
- /* no more viewing lower dictionary */
- if ((d = dt->view))
- d->nview -= 1;
- dt->view = dt->walk = NIL(Dt_t *);
+ /* no more viewing lower dictionary */
+ if((d = dt->view) )
+ d->nview -= 1;
+ dt->view = dt->walk = NIL(Dt_t*);
- if (!view) {
- dt->searchf = dt->meth->searchf;
- return d;
- }
+ if(!view)
+ { dt->searchf = dt->meth->searchf;
+ return d;
+ }
- /* ok */
- dt->view = view;
- dt->searchf = dtvsearch;
- view->nview += 1;
+ /* ok */
+ dt->view = view;
+ dt->searchf = dtvsearch;
+ view->nview += 1;
- return view;
+ return view;
}
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/**********************************************************
-* This software is part of the graphviz package *
-* http://www.graphviz.org/ *
-* *
-* Copyright (c) 1994-2004 AT&T Corp. *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Corp. *
-* *
-* Information and Software Systems Research *
-* AT&T Research, Florham Park NJ *
-**********************************************************/
-
#include "dthdr.h"
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
/* Walk a dictionary and all dictionaries viewed through it.
** userf: user function
**
*/
#if __STD_C
-int dtwalk(reg Dt_t * dt, int (*userf) (Dt_t *, Void_t *, Void_t *),
- Void_t * data)
+int dtwalk(reg Dt_t* dt, int (*userf)(Dt_t*, Void_t*, Void_t*), Void_t* data)
#else
-int dtwalk(dt, userf, data)
-reg Dt_t *dt;
-int (*userf) ();
-Void_t *data;
+int dtwalk(dt,userf,data)
+reg Dt_t* dt;
+int(* userf)();
+Void_t* data;
#endif
{
- reg Void_t *obj, *next;
- reg Dt_t *walk;
- reg int rv;
+ reg Void_t *obj, *next;
+ reg Dt_t* walk;
+ reg int rv;
- for (obj = dtfirst(dt); obj;) {
- if (!(walk = dt->walk))
- walk = dt;
- next = dtnext(dt, obj);
- if ((rv = (*userf) (walk, obj, data)) < 0)
- return rv;
- obj = next;
- }
- return 0;
+ for(obj = dtfirst(dt); obj; )
+ { if(!(walk = dt->walk) )
+ walk = dt;
+ next = dtnext(dt,obj);
+ if((rv = (*userf)(walk, obj, data )) < 0)
+ return rv;
+ obj = next;
+ }
+ return 0;
}
${cdt_SRCDIR}/dtstat.c
${cdt_SRCDIR}/dtstrhash.c
${cdt_SRCDIR}/dttree.c
+ ${cdt_SRCDIR}/dttreeset.c
${cdt_SRCDIR}/dtview.c
${cdt_SRCDIR}/dtwalk.c
)
Agraph_t *s;
int rec;
- switch (kind) {
- case AGRAPH:
rec = (rec_size < 0);
if (rec) rec_size = -rec_size;
+ switch (kind) {
+ case AGRAPH:
agbindrec(g, rec_name, rec_size, mtf);
if (rec)
for (s = agfstsubg(g); s; s = agnxtsubg(s))
#define NOTUSED(var) (void) var
#endif
+#ifndef NIL
+#define NIL(type) ((type)0)
+#endif
+
#define isPinned(n) (ND_pinned(n) == P_PIN)
#define hasPos(n) (ND_pinned(n) > 0)
#define isFixed(n) (ND_pinned(n) > P_SET)