DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T c ┃
Length: 21461 (0x53d5) Types: TextFile Names: »c_av.c«
└─⟦149519bd4⟧ Bits:30000546 8mm tape, Rational 1000, !projects 93-07-13 └─ ⟦124ff5788⟧ »DATA« └─⟦f2882457c⟧ └─⟦a7d1ea751⟧ Bits:30000550 8mm tape, Rational 1000, !users!projects 94_04_11 └─ ⟦129cab021⟧ »DATA« └─⟦f2882457c⟧ └─⟦f64eaa120⟧ Bits:30000752 8mm tape, Rational 1000, !projects 93 02 16 └─ ⟦6f12a12be⟧ »DATA« └─⟦f2882457c⟧ └─⟦2f6cfab89⟧ Bits:30000547 8mm tape, Rational 1000, !projects 94-01-04 └─ ⟦d65440be7⟧ »DATA« └─⟦f2882457c⟧ └─ ⟦this⟧ »C/c_av.c«
static char rcsid_c_av_c[] = "$Id: c_av.c,v 1.1 91/03/07 15:27:12 md Exp $"; /****************************************************************************** ******************************************************************************* * * (c) Copyright 1990, Non Standard Logics S.A. * ALL RIGHTS RESERVED * * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED * AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND * WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR * ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE * AVAILABLE TO ANY OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE * SOFTWARE IS HEREBY TRANSFERRED. * * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT * NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY * Non Standard Logics S.A. OR ITS THIRD PARTY SUPPLIERS. * * Non Standard Logics S.A. AND ITS THIRD PARTY SUPPLIERS, * ASSUME NO RESPONSIBILITY FOR THE USE OR INABILITY TO USE ANY OF ITS * SOFTWARE . Non Standard Logics S.A SOFTWARE IS PROVIDED "AS IS" * WITHOUT WARRANTY OF ANY KIND, AND OSF EXPRESSLY DISCLAIMS ALL * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * (c) Copyright 1990, Non Standard Logics S.A. Unpublished - all * rights reserved under the Copyright laws of France * * Non Standard Logics S.A. * 57-59 rue Lhomond, * 75005 Paris. * France. * * XFaceMaker is a registered trademark of Non Standard Logics S.A. * ******************************************************************************* ******************************************************************************/ #include <stdio.h> #include <X11/IntrinsicP.h> #include <X11/StringDefs.h> #undef XtDisplay #undef XtScreen #undef XtWindow #undef XtClass #undef XtSuperClass #undef XtIsManaged #undef XtIsRealized #undef XtIsSensitive #ifndef NIL #define NIL 0 #define Nil(type) ((type) NIL) typedef int *pointer; #endif /* * arrays */ typedef struct _ARRAY { pointer UserPtr; int Min; int Size; pointer *Data; } ARRAY; #define ArrayData(a, type) ((type *) (a)->Data) #define ArrayIndex(a, i, type) ((type) (a)->Data[i - (a)->Min]) #define CheckArray(a, i) (i > (a)->Min && i < (a)->Min + (a)->Size) /* * H-code tables */ /* * hash tables (keys are strings) */ typedef struct _HASH { char *HName; /* hash key */ pointer HInfo; /* info */ struct _HASH * HNext; /* synonyms */ } HASH; typedef struct _HTABLE { int (* Hash)(); /* hcoding function */ char * (* HCopy)(); /* copy function for the name (can be NIL) */ void (* HDel)(); /* delete function for the entries (can be NIL) */ ARRAY * HTable; /* table : must be zero based */ } HTABLE; /* * assoc tables (keys are pointers) */ typedef struct _ASSOC { pointer AKey; /* hash key */ pointer AInfo; /* info */ struct _ASSOC * ANext; /* synonyms */ } ASSOC; typedef struct _ATABLE { int (* AHash)(); /* hcoding function */ pointer (* ACopy)(); /* copy function for the key (can be NIL) */ void (* ADel)(); /* delete function for the entries (can be NIL) */ int (* ACmp)(); /* compare two keys, return 1 if equals (can be NIL) */ ARRAY * ATable; /* table : must be zero based */ } ATABLE; /* * Array management */ static ARRAY * NewArray (nb) int nb; { register ARRAY *a = (ARRAY *)XtMalloc(sizeof(ARRAY)); if (nb > 0) { a -> Data = (pointer *) XtMalloc (nb * sizeof (pointer)); if (! a -> Data) { free (a); return NIL; } } else { a -> Data = NIL; nb = 0; } a -> UserPtr = NIL; a -> Min = 0; a -> Size = nb; return a; } static void NewArraySize (a, min, sz, filler) ARRAY *a; int min; int sz; pointer filler; { pointer *new; register pointer *pnew, *copy; register int i, size; if (sz < 0) sz = 0; if (sz) pnew = new = (pointer *) XtMalloc (sz * sizeof (pointer)); else { a->Min = min; a->Size = NIL; if (a->Data) free (a->Data); a->Data = NIL; return; } /* brand new array */ if (! a -> Data) { a->Min = min; a->Size = sz; a->Data = new; while (sz --) *pnew++ = filler; return; } size = sz; copy = a->Data; /* if the new array starts before the old one, fill the beginning */ i = a->Min - min; if (i > 0) while (i--) { *pnew++ = filler; size--; } /* if the new array is longer, copy and fill end, else just copy */ if (size > a->Size) { i = a->Size; while (i--) *pnew++ = *copy++; i = size - a->Size; while (i--) *pnew++ = filler; } else { i = size; while (i--) *pnew++ = *copy++; } /* free old data and set new array */ free (a->Data); a->Data = new; a->Min = min; a->Size = sz; } static void CopyArray (to, from) ARRAY *to, *from; { register pointer *copy, *orig; register int i; if (to -> Data) free (to -> Data); *to = *from; if (to -> Size == 0 || ! to -> Data) return; copy = to -> Data = (pointer *) XtMalloc (to->Size * sizeof (pointer)); i = to->Size; orig = from->Data; while (i--) *copy++ = *orig++; } static void FreeArray (a) ARRAY *a; { if (a -> Data) free (a -> Data); free (a); } static void ResetArray (a) ARRAY *a; { register pointer *p; register int i; for (p = a -> Data, i = a->Size; i--; p++) *p = NIL; } static void SetArray (a, i, val) register ARRAY *a; register int i; pointer val; { if (i < a->Min) return; if (i > a->Min + a->Size) return; a -> Data [i - a -> Min] = val; } static pointer GetArray (a, i) register ARRAY *a; register int i; { if (i < a->Min) return NIL; if (i > a->Min + a->Size) return NIL; return a -> Data [i - a -> Min]; } /* * -- ASSOC TABLES -- * * * [mbl] 04/04/89 * */ /* * -- HCODE -- * * * [mbl] 28/01/1986 * * v1.0 * v1.1 01/05/87 * [mbl] 13/08/87 HNum devient HInfo de type int * * ajoute structure HTable * change arguments fonctions en consequence * htable = tableau de pointeurs au lieu de * tableau de structures * + fonctions de hash et de copie de nom * (avec fns par defaut si 0) * fonctions nouvelles : * enlever des element * rehasher dans une autre table * detruire une table * [mbl] 25/10/87 remplace table et taille par un ARRAY * DelHash retourne l'info (et plus le HASH *) * [mbl] 13/11/87 ajoute ForHTable pour enumerer une table * [mbl] 04/04/89 petites modifs pour integration des assoc tables */ /* * hasher ... */ static HASH** DoHash (ht, name) register HTABLE *ht; register char *name; { register int h = 0; if (ht -> Hash) h = (* ht->Hash) (name, ht -> HTable -> Size); else while (*name) h += *name++; if (h > ht -> HTable -> Size) h %= ht -> HTable -> Size; return ArrayData (ht -> HTable, HASH *) + h; } /* * allouer de la place pour un homonyme */ static HASH * NewHash () { return (HASH *) XtMalloc (sizeof (HASH)); } /* * ajouter un element en entry */ static HASH * PutHash (entry, name) register HASH **entry; register char *name; { register HASH * h; h = NewHash (); h->HName = name; h->HNext = *entry; *entry = h; return h; } /* * chercher un element dans entry * la fonction retourne son adresse, ou NIL s'il n'y est pas */ static HASH * FindHash (entry, name) register HASH **entry; register char *name; { register char *p, *q; register HASH *h; /* si l'entree est non vide, chercher dans la liste */ if (*entry) for (h = *entry; h; h = h -> HNext) { /* on fait le strcmp a la main : ca va + vite */ for (p = name, q = h->HName; *p == *q++; p++) if (*p == '\0') return h; } return NIL; } /* * enlever un element * le mettre dans la liste des libres * retourne 1 si trouve, 0 sinon */ static int RemoveHash (ht, entry, name) HTABLE *ht; HASH **entry; char *name; { register char *p, *q; register HASH *h, *hp = NIL; /* si l'entree est non vide, chercher dans la liste */ if (!*entry) return 0; for (h = *entry; h; h = h -> HNext) { /* on fait le strcmp a la main : ca va + vite */ for (p = name, q = h->HName; *p == *q++; p++) if (*p == '\0') { /* l'enlever de la liste */ if (hp) hp -> HNext = h -> HNext; else *entry = h -> HNext; /* le liberer */ if (ht -> HDel) (* ht->HDel) (h); free (h); return 1; } hp = h; } return 0; } /* * ajouter un element, sauf s'il existe deja * retourne un pointeur sur ledit element. * found indique s'il a ete ajoute (si non nil) */ static HASH * AddHash (ht, name, found) register HTABLE *ht; char *name; int *found; { HASH **entry; HASH *h; /* est-il dans la table ? */ entry = DoHash (ht, name); if (h = FindHash (entry, name)) { if (found) *found = 1; return h; } /* fonction de copie du nom ? */ if (ht -> HCopy) name = (* ht->HCopy) (name); /* do it */ h = PutHash (entry, name); if (found) *found = 0; return h; } /* * rechercher un element * retourne un pointeur sur ledit element, NIL si non trouve */ static HASH * GetHash (ht, name) HTABLE *ht; char *name; { HASH **entry; entry = DoHash (ht, name); return FindHash (entry, name); } /* * enlever un element * retourne l'info de l'element si trouve * retourne NIL si pas trouve */ static int DelHash (ht, name) HTABLE *ht; char *name; { return RemoveHash (ht, DoHash (ht, name), name); } /* * rehasher une table * retourne l'ancien tableau */ static ARRAY * ReHash (ht, new) HTABLE *ht; ARRAY *new; { register HASH *h, *hp; register HASH **entry, **e; ARRAY *old; int s; old = ht -> HTable; ht -> HTable = new; s = old -> Size; for (entry = ArrayData (old, HASH *); s--; entry++) { /* rehasher une liste */ for (h = *entry; h; h = hp) { e = DoHash (ht, h -> HName); /* deplacer l'element */ hp = h -> HNext; h -> HNext = *e; *e = h; } *entry = NIL; } return old; } /* * detruire une table * f est appellee avant chaque destruction (si non nulle) */ static void DelHTable (ht, f) HTABLE *ht; void (*f) (); { register HASH **entry; register HASH *h, *hp; int s; s = ht -> HTable -> Size; for (entry = ArrayData (ht -> HTable, HASH *); s--; entry++) { if (! *entry) continue; /* parcourir la liste */ for (h = *entry; h;) { if (f) (*f) (h); hp = h; h = h -> HNext; if (ht -> HDel) (* ht->HDel) (hp); free (hp); } *entry = NIL; } } /* * parcourir une table * f est appellee avant pour chaque element * si elle retourne 0 on continue * sinon on s'arrete et on retourne la valeur retournee par la fonction */ static int ForHTable (ht, f, arg) HTABLE *ht; int (*f) (); pointer arg; { register HASH **entry; register HASH *h; int s, res; s = ht -> HTable -> Size; for (entry = ArrayData (ht -> HTable, HASH *); s--; entry++) { if (! *entry) continue; /* parcourir la liste */ for (h = *entry; h;) { res = (*f) (h, arg); if (res) return res; h = h -> HNext; } } return 0; } /* * hasher ... */ static ASSOC** DoAssoc (at, key) register ATABLE *at; register pointer key; { register int h = 0; if (at -> AHash) h = (* at->AHash) (key, at -> ATable -> Size); else h = (int) key; if (h > at -> ATable -> Size) h %= at -> ATable -> Size; return ArrayData (at -> ATable, ASSOC *) + h; } /* * allouer de la place pour un homonyme */ static ASSOC * NewAssoc () { return (ASSOC *) XtMalloc (sizeof (ASSOC)); } /* * ajouter un element en entry */ static ASSOC * PutAssoc (entry, key) register ASSOC **entry; register pointer key; { register ASSOC * a; a = NewAssoc (); a->AKey = key; a->ANext = *entry; *entry = a; return a; } /* * chercher un element dans entry * la fonction retourne son adresse, ou NIL s'il n'y est pas */ static ASSOC * FindAssoc (at, entry, key) ATABLE *at; register ASSOC **entry; register pointer key; { register ASSOC *a; /* si l'entree est non vide, chercher dans la liste */ if (*entry) for (a = *entry; a; a = a -> ANext) { if (at -> ACmp) { if ((* at->ACmp) (a -> AKey, key)) return a; } else /* comparaison par defaut : les pointeurs eux-meme */ if (a -> AKey == key) return a; } return NIL; } /* * enlever un element * le mettre dans la liste des libres * retourner 1 si trouve, 0 sinon */ static int RemoveAssoc (at, entry, key) ATABLE *at; ASSOC **entry; pointer key; { register ASSOC *a, *ap = NIL; /* si l'entree est non vide, chercher dans la liste */ if (!*entry) return 0; /* for (a = *entry; a; a = a -> ANext, ap = a) {*/ for (a = *entry; a; ap = a, a = a -> ANext) { if (at -> ACmp) { if (! (* at->ACmp) (a -> AKey, key)) continue; } else /* comparaison par defaut : les pointeurs eux-meme */ if (a -> AKey != key) continue; /* l'enlever de la liste */ if (ap) ap -> ANext = a -> ANext; else *entry = a -> ANext; /* le liberer */ if (at -> ADel) (* at->ADel) (a); free (a); return 1; } return 0; } /* * ajouter un element, sauf s'il existe deja * retourne un pointeur sur ledit element. * found indique s'il a ete ajoute (si non nil) */ static ASSOC * AddAssoc (at, key, found) register ATABLE *at; pointer key; int *found; { ASSOC **entry; ASSOC *a; /* est-il dans la table ? */ entry = DoAssoc (at, key); if (a = FindAssoc (at, entry, key)) { if (found) *found = 1; return a; } /* fonction de copie du nom ? */ if (at -> ACopy) key = (* at->ACopy) (key); /* do it */ a = PutAssoc (entry, key); if (found) *found = 0; return a; } /* * rechercher un element * retourne un pointeur sur ledit element, NIL si non trouve */ static ASSOC * GetAssoc (at, key) ATABLE *at; pointer key; { ASSOC **entry; entry = DoAssoc (at, key); return FindAssoc (at, entry, key); } /* * enlever un element * retourne l'info de l'element si trouve * retourne NIL si pas trouve */ static int DelAssoc (at, key) ATABLE *at; pointer key; { return RemoveAssoc (at, DoAssoc (at, key), key); } /* * rehasher une table * retourne l'ancien tableau */ static ARRAY *ReAssoc (at, new) ATABLE *at; ARRAY *new; { register ASSOC *a, *ap; register ASSOC **entry, **e; ARRAY *old; int s; old = at -> ATable; at -> ATable = new; s = old -> Size; for (entry = ArrayData (old, ASSOC *); s--; entry++) { /* rehasher une liste */ for (a = *entry; a; a = ap) { e = DoAssoc (at, a -> AKey); /* deplacer l'element */ ap = a -> ANext; a -> ANext = *e; *e = a; } *entry = NIL; } return old; } /* * detruire une table * f est appellee avant chaque destruction (si non nulle) */ static void DelATable (at, f) ATABLE *at; void (*f) (); { register ASSOC **entry; register ASSOC *a, *ap; int s; s = at -> ATable -> Size; for (entry = ArrayData (at -> ATable, ASSOC *); s--; entry++) { if (! *entry) continue; /* parcourir la liste */ for (a = *entry; a;) { if (f) (*f) (a); ap = a; a = a -> ANext; if (at -> ADel) (* at->ADel) (ap); free (ap); } *entry = NIL; } } /* * parcourir une table * f est appellee avant pour chaque element * si elle retourne 0 on continue * sinon on s'arrete et on retourne la valeur retournee par la fonction */ static int ForATable (at, f, arg) ATABLE *at; int (*f) (); pointer arg; { register ASSOC **entry; register ASSOC *a; int s, res; s = at -> ATable -> Size; for (entry = ArrayData (at -> ATable, ASSOC *); s--; entry++) { if (! *entry) continue; /* parcourir la liste */ for (a = *entry; a;) { res = (*f) (a, arg); if (res) return res; a = a -> ANext; } } return 0; } static ATABLE *_FmNewAssocTable(size) int size; { ATABLE *ret; ret = (ATABLE *)XtMalloc((unsigned)sizeof(ATABLE)); ret -> AHash = NIL; ret -> ACopy = NIL; ret -> ADel = NIL; ret -> ACmp = NIL; ret -> ATable = NewArray(size); ResetArray(ret -> ATable); return ret; } static String NewString(s) String s; { return XtNewString(s); } static void DelString (h) HASH *h; { (void) free (h->HName); } static HTABLE *_FmNewHashTable(size) int size; { HTABLE *ret; ret = (HTABLE *)XtMalloc((unsigned)sizeof(HTABLE)); ret -> Hash = NIL; ret -> HCopy = NewString; ret -> HDel = DelString; ret -> HTable = NewArray(size); ResetArray(ret -> HTable); return ret; } extern void bzero(); static HTABLE *AvTable = 0; #define AV_SIZE 128 #ifdef NOVOID typedef caddr_t _pointer; #else typedef void * _pointer; #endif typedef int (*pfun) (); typedef struct __head { struct __av *next; struct __av *prev; _pointer user_addr; } _head; typedef struct __av{ struct __av *next; struct __av *prev; char *name; pfun setproc; pfun getproc; Widget widget; _head *head; } _av; static void Insert(elem, pred) _av *elem, *pred; { elem -> next = pred -> next; pred -> next = elem; elem -> prev = pred; elem -> next -> prev = elem; } static void Remove(elem) _av *elem; { elem -> prev -> next = elem -> next; elem -> next -> prev = elem -> prev; } static _head *NewHead(){ _head *ret; ret = (_head *)XtMalloc(sizeof(_head)); ret -> next = ret -> prev = (_av *)ret; ret -> user_addr = 0; return ret; } static _av* AllocNewAv(name, get, set) char *name; pfun get, set; { _av *ret; ret = (_av *)XtMalloc(sizeof(_av)); bzero(ret, sizeof(_av)); ret -> name = XtNewString(name); ret -> setproc = set; ret -> getproc = get; ret -> next = ret -> prev = ret; return ret; } static void DeleteAvs(); void FmNewAv(name, get, set, widget) String name; pfun get, set; Widget widget; { int found; HASH *entry; _av *pav; _head *head; if(AvTable == 0) AvTable = _FmNewHashTable(AV_SIZE); entry = AddHash (AvTable, name, &found); if(found){ head = (_head *)entry -> HInfo; } else { head = NewHead(); entry -> HInfo = (pointer) head; } pav = AllocNewAv(name, get, set); pav -> head = head; pav -> widget = widget; Insert(pav, head -> prev); XtAddCallback(widget, XtNdestroyCallback, DeleteAvs, 0); } /* Il faut detruire les v.a's quand on detruit * le widget... */ static int DeleteAv(entry, widget) HASH *entry; Widget widget; { _av *av; _head *head; if(!entry || !widget) return(0); head = (_head *)entry -> HInfo; for(av = head -> next; av != (_av *)head; av = av -> next){ if(av -> widget == widget){ Remove(av); XtFree(av->name); XtFree(av); return(0); } } } /* Mettre cette fonction comme DestroyCallback du widget * dans NewAv. */ static void DeleteAvs(widget) Widget widget; { ForHTable(AvTable, DeleteAv, widget); } int FmAttachAv(name, addr) String name; caddr_t addr; { HASH *entry = GetHash(AvTable, name); int found; _head *head; if(entry == 0){ entry = AddHash (AvTable, name, &found); head = NewHead(); head -> user_addr = addr; entry -> HInfo = (pointer)head; return 0; } else { head = (_head *)entry -> HInfo; head -> user_addr = addr; return 1; } } static int found; static int UpdateAv(entry, widget) HASH *entry; Widget widget; { _head *head; _av *av; if(entry == 0) return(0); head = (_head *)entry -> HInfo; for(av = head -> next; av != (_av *)head; av = av -> next){ if(widget && av -> widget != widget) continue; found = 1; if(av -> getproc) av -> getproc(av->widget, 0, head -> user_addr); } return(0); } int FmUpdateNamedAv(name) String name; { HASH *entry = GetHash(AvTable, name); found = 0; UpdateAv(entry, 0); return(found); } int FmUpdateAv(name) String name; { return(FmUpdateNamedAv(name)); } int FmUpdateWidgetAv(widget) Widget widget; { found = 0; ForHTable(AvTable, UpdateAv, widget); return(found); } static int SetAv(entry, widget) HASH *entry; Widget widget; { _head *head; _av *av; if(entry == 0) return(0); head = (_head *)entry -> HInfo; for(av = head -> next; av != (_av *)head; av = av -> next){ if(widget && av -> widget != widget) continue; found = 1; if(av -> setproc) av -> setproc(av->widget, 0, head -> user_addr); } return(0); } int FmSetNamedAv(name) String name; { HASH *entry = GetHash(AvTable, name); found = 0; SetAv(entry, 0); return(found); } int FmSetAv(name) String name; { return(FmSetNamedAv(name)); } int FmSetWidgetAv(widget) Widget widget; { found = 0; ForHTable(AvTable, SetAv, widget); return(found); } #ifdef OLD int FmSetAv(name) String name; { HASH *entry = GetHash(AvTable, name); _head *head; _av *av; if(entry == 0) return; head = (_head *)entry -> HInfo; for(av = head -> next; av != (_av *)head; av = av -> next){ if(av -> setproc){ /* printf("Set av %s : entry=%x, av=%x, widget=%x, addr=%x\n", name, entry, av, av->widget, head->user_addr); */ av -> setproc(av->widget, 0, head -> user_addr); } } } #endif _pointer FmGetAv(name) char *name; { HASH *entry = GetHash(AvTable, name); _head *head; _av *av; if(entry == 0) return(0); head = (_head *)entry -> HInfo; return(head -> user_addr); } /* Nouvel interface. */ int FmGetActiveValue(widget, name) Widget widget; String name; { HASH *entry; found = 0; if(name){ entry = GetHash(AvTable, name); UpdateAv(entry, widget); } else { FmUpdateWidgetAv(widget); } return(found); } int FmSetActiveValue(widget, name) Widget widget; String name; { HASH *entry; found = 0; if(name){ entry = GetHash(AvTable, name); SetAv(entry, widget); } else { FmSetWidgetAv(widget); } return(found); } _pointer FmGetActiveValueAddr(name) char *name; { return(FmGetAv(name)); }