Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!purdue!ames!eos!shelby!csli!poser From: poser@csli.Stanford.EDU (Bill Poser) Newsgroups: comp.lang.c Subject: Re: Using vars to access structures/functions Summary: Technique for accessing structure members by name Message-ID: <9799@csli.Stanford.EDU> Date: 21 Jul 89 06:11:48 GMT References: <329@yetti.UUCP> <10570@smoke.BRL.MIL> Sender: poser@csli.Stanford.EDU (Bill Poser) Reply-To: poser@csli.stanford.edu (Bill Poser) Organization: Center for the Study of Language and Information, Stanford U. Lines: 80 If the members of the structure that you want to access are of the same type, you can create an array of pointers to the various members in which you are interested and a function that returns the index into this array given the name of the member (which can be the name you use in your source code but doesn't have to be.) You also write a function that you call at initialization time that assigns the addresses of the structure members to the array. When you want to access a member by name, you call the function that translates from the name to the array index and index into the array to get the address of the structure member. This is kind of elaborate, but there are circumstances in which it is useful. I have used this in a programmable time series editor (sort of like EMACS, only not for text) in which various attributes of a window are stored both in user-variables and in internal data structures. The user-variables are trapped so that I can do things like make sure that a color specification is valid as well as updating the internal data structure when the user-variable is assigned to. Rather than having a distinct trap function for each attribute, I have a single trap function SetColorAttribute which is called with a pointer to the variable as its argument. It checks the validity of the color specification, and then does the right thing to the internal data structure. Each window is represented by a structure that contains (along with lots of other things) both the color attribute information and an array of pointers to the color attributes. Here is an excerpt from the function that initializes the array: void InitAttAddresses(w) WINDOW_PTR w; { if(w == NULL_WINDOW) return; w->ColorAttributes[0] = &(w->AnchorLineColor); ... } And here is the function SetColorAttribute: void SetColorAttribute(vptr) VAR_PTR vptr; { int cstatus; Color *c; c = vptr->list->binder.window->ColorAttributes[GetColorAttIndex(vptr->name)]; cstatus = XParseColor(vptr->value,c); if(cstatus == 0){ mwprintf( "Could not parse color specification %s%s%s.\n%s defaulting to %s.\n", sostr,vptr->value,usostr,vptr->name,defcolor); sprintf(vptr->value,defcolor); XParseColor(vptr->value,c); } XGetHardwareColor(c); return; } (Note that each variable contains a pointer to the list that contains it and that each variable list contains a pointer to the object with which the variable list is associated, if any, so that it is possible to determine which window the variable is an attribute of. That is the value of vptr->list->binder.window.) This gets a bit complex, but it works quite nicely, and there are cases like this in which it seems to be the right thing to do. Bill