[comp.lang.c] strings as functions

mpapp@ (Mike Papper) (01/07/91)

Is there a way to use a string value as the name of a function?
In other words, can I use a string (possibly
typed in by a programmer) as a function call to a function of
the same name?

One method may be to call the same function, which uses the value
of the string to decide which real function to call.
In this case the programmer would have to edit the source code that was 
generated to match up the strings and the appropriate function calls.

The idea is to have a program that reads an ASCII file to generate
an interface, which when buttons are selected, the
appropriate function is called. The function to call
would be found in the ascii file, and the program would assume
the programmer had created the function of same name somewhere.


Can this be done? easily?
Mike Papper

bhoughto@hopi.intel.com (Blair P. Houghton) (01/08/91)

In article <mpapp.663214690@godzilla> mpapp@ (Mike Papper) writes:
>Is there a way to use a string value as the name of a function?
>In other words, can I use a string (possibly

Strings is data, and functions is text, and never the twain
will get stuck in the same location.  If, however, you can
get the user a copy of the long-integers that represent the
function pointers, get him/her to type those in, the program
can convert the typed-in number to integral data, then
call-by-reference.  It would work, but it's laughable.

There are easier ways; read on.

>One method may be to call the same function, which uses the value
>of the string to decide which real function to call.

That's the easier way.  It's a very common practice to
build lists of structures that each contain a command-name
(a string) and a pointer to the (already compiled) function
that implements that command.  The user types-in the
string, the program searches the list for a matching
string, and the program calls the associated function via
the function-pointer.

(Note:  look up the difference between function pointers
and object pointers (the sort you're used to); there are
many differences and there are many things you can't do
with a function pointer.)  (Note also:  unless all the
functions return the same type, you'll have to make them
all return nothing; the easy way out of this is to make
them return a (pointer to a) union and have the program
figure out which union-member-tag to use).

>In this case the programmer would have to edit the source code that was 
>generated to match up the strings and the appropriate function calls.

That's what programmers are for.  :-/

>The idea is to have a program that reads an ASCII file to generate
>an interface, which when buttons are selected, the
>appropriate function is called. The function to call
>would be found in the ascii file, and the program would assume
>the programmer had created the function of same name somewhere.

The program doesn't have to assume anything.  When the
search-loop finds a match for the command, simply set a
flag, and after the end of the loop you can check the flag
to see if the search was successful and if not you can
print an error message.

>Can this be done? easily?

Yes.  Virtually every program you've ever used has done something
very similar to this when dealing with interactive/interpreted input;
it's often also the way command-line arguments are handled.

				--Blair
				  "Common == easy; ethologically."

henry@zoo.toronto.edu (Henry Spencer) (01/08/91)

In article <mpapp.663214690@godzilla> mpapp@ (Mike Papper) writes:
>Is there a way to use a string value as the name of a function?
>In other words, can I use a string (possibly
>typed in by a programmer) as a function call to a function of
>the same name?

Not in standard C.  There has to be a table, somewhere, that maps names
into pointers to functions.  In a conventional implementation, that table
exists inside compiler and linker during compilation of the program, but
no longer exists at run time.  (It is sometimes present in the same file
that holds the executable program, but there is no fully portable way of
getting at that file or interpreting its contents.)  The only way to
implement such a feature portably is to decide in advance which functions
can be called this way, and provide your own table.
-- 
If the Space Shuttle was the answer,   | Henry Spencer at U of Toronto Zoology
what was the question?                 |  henry@zoo.toronto.edu   utzoo!henry

bls@u02.svl.cdc.com (Brian Scearce) (01/08/91)

mpapp@ (Mike Papper) writes:
>Is there a way to use a string value as the name of a function?

It depends on what you mean.  If, at compile time, you can make up
a table, then it is pretty easy:

#include <stdio.h>
#define MAXLEN 100

void first(), second(), third(), last();

struct mapping {
  char *name;
  void (*func)();
};

main()
{
  void first(), second(), third(), last();
  static struct mapping list[] = 
    { "first", first,
      "second", second,
      "third", third,
      "last", last,
      NULL, NULL
    };

  char buf[MAXLEN];
  int i;

  while (fgets(buf, MAXLEN, stdin) != NULL) {
    buf[strlen(buf)-1] = 0; /* Get rid of newline */
    for (i = 0; list[i].name; i++)
      if (strcmp(list[i].name, buf) == 0)
        (*list[i].func)();
  }
}

void first() { printf("First function\n"); }
void second() { printf("Second function\n"); }
void third() { printf("Third function\n"); }
void last() { printf("Last function\n"); }

--
     Brian Scearce (bls@robin.svl.cdc.com  -or-  robin!bls@shamash.cdc.com)
        "How do you explain the vast discrepancy between your testimony
         and my client's?" "He has perjured himself." "Objection!" "I am
         under oath.  I was there.  He *is* lying."
 Any opinions expressed herein do not necessarily reflect CDC corporate policy.

dsr@stl.stc.co.uk (D.S.Riches) (01/09/91)

>In article <mpapp.663214690@godzilla> mpapp@ (Mike Papper) writes:
>Is there a way to use a string value as the name of a function?
>In other words, can I use a string (possibly
>typed in by a programmer) as a function call to a function of
>the same name?

Tried to reply to you Mike but your path name is corrupted.  See your
Newsmaster about it.

It seems similar to the implementation of a State Transition Model or
Table Driven Software.  E.g.

We define a structure :-

typedef struct sy_s_bed_add_nw_object {
        gen_t_nw_object nw_object;
        STRING          form_name;
        INT             (*func_name)();
        INT             aux_row;
} sy_s_bed_add_nw_object;

Declare a table for it :-

NE_D_EXTERN sy_s_bed_add_nw_object  sy_g_bed_add_table[]
#ifdef DEFINITION
= {
   GEN_D_SITE,          "adsite",       sy_f_bed_Add_Geog_Object, 0,
   GEN_D_BLDG,          "adbldg",       sy_f_bed_Add_Geog_Object, 2,
   GEN_D_LINK,          "adlink",       sy_f_bed_Add_Tx_Object, 3,
   GEN_D_LINK_PT,       "undefined",    dummy,                  -1,
   GEN_D_NODE,          "adnode",       sy_f_bed_Add_Default_Object,
4,
  }
#endif

In this case the structure defines a pointer to a function as the 3rd
element.  In the table we have a name of a function.  We then call
that function by :-

status = (*(sy_g_bed_add_table[i_object_type].func_name))(m_cfmPtr);

Where i_object_type is the 'line_number' corresponding to the nw_object
we're interested in (in State Transitions this would be 
the trigger, we search down a table for the trigger. move across to the action
(funtion) to be called and execute it).

m_cfmPtr is the parameter to this function.

This is taken from a 'live' example, what you might need is similar in
that you could assign a string to the 3rd element and then execute it
... I think.

   Dave Riches
   PSS:    David.S.Riches@stl.stc.co.uk (or dsr@stl.stc.co.uk)
   Smail:  Systems Methods, (Dept. 607, T2 West), 
	   STC Technology Ltd., London Road,
	   Harlow, Essex. CM17 9NA.  England
   Phone:  +44 (0)279-29531 x2496