Using vars to access structures/functions

Bill Poser poser at csli.Stanford.EDU
Fri Jul 21 16:11:48 AEST 1989


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

 



More information about the Comp.lang.c mailing list