asst-jos@yetti.UUCP (Jonathan) (07/19/89)
Is it possible to place the name of a field in a variable, and then use that variable to reference the field? For a contrived example, if I have a structure that has a large number of fields, and I want to reference a field, by querying the user for the field name rather than do the following: getfieldname(var); if ( strcmp(var, "fieldname1") == 0) do whatever to field1 else if (strcmp( var, "fieldname2) == 0) do whatever to field2 else .... In effect, this is to come up with a general solution to the problem rather than re-write the code for each situation like this that arises. This would apply to pointers to functions as well. Is it possible to use the name of a function (read in from the terminal, for example) to execute the function (assuming that it exists) without creating a cross reference table first? I have tried this and have been unable to do this. This does not seem possible, but you never know!!! Any and all help (flames included :-) ) accepted. e-mail is welcome. ------------------------------------------------------------------------- Jeffrey Klein York University, Toronto UUCP: Uunet!utai!utcsri!yunexus!yuyetti!asst-jos Standard Disclaimer: This is MY opinion, not York University's!!!
gwyn@smoke.BRL.MIL (Doug Gwyn) (07/21/89)
In article <329@yetti.UUCP> asst-jos@yetti.UUCP (Jeffrey Klein) writes: > Is it possible to place the name of a field in a variable, and >then use that variable to reference the field? Not as such, since source code identifiers vanish before run time. (Except for possible debugging or interpreter environments, but the identifiers are still not supposed to be available to the program.) You need to design some other solution. For function tables, you might set up something like: extern void func1(), func2(); struct func_pair { char *func_name; void *func_entry(); } funct_table[] = { { "func1", func1 }, { "func2", func2 }, }; and search the table for a matching func_name member, then use the struct func_pair pointer that matched to invoke the function via the corresponding funct_entry member. Selecting different members of a struct by name is a harder proposition, and it would be best to find some other way of accomplishing the desired effect in such a case.
poser@csli.Stanford.EDU (Bill Poser) (07/21/89)
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
maart@cs.vu.nl (Maarten Litmaath) (07/22/89)
gwyn@smoke.BRL.MIL (Doug Gwyn) writes:
\... extern void func1(), func2();
\ struct func_pair {
\ char *func_name;
\ void *func_entry();
Ahum: void (*func_entry)();
\ } funct_table[] = {
\ { "func1", func1 },
\ { "func2", func2 },
\ };
\...
--
"Mom! Eric Newton broke the day! In 24 |Maarten Litmaath @ VU Amsterdam:
parts!" (Mike Schmitt in misc.misc) |maart@cs.vu.nl, mcvax!botter!maart