views:

54

answers:

1

Hi,

I am writing a C program which is a frontend to a myriad tools. This fronted will be launched like this:

my-frontend --action <AN ACTION>

As all the tools have the same prefix, let say for this example this prefix is "foo". I want to concatenate "AN ACTION" to this prefix and exec this (if the tool exists).

I have written something but my implementation uses strcmp to test that "AN ACTION" is a valid action. Even if this works, I do not like it. So I am looking for a nicer solution that would do the same. The list of possibilities is pretty small (less than 10) and static (the list is "hardcoded") but I am sure there is a more "C-ish" way to do this (using a struct or something like that). As I am not a C expert, I am asking for your help.

Regards

+2  A: 

Take a look at getopt_long. Its part of the standard C library. For full documentation on how C programs are supposed to handle arguments in a standard UNIX way, check this.

The above should give you the argument. But I see your problem is more than that. Dealing with multiple back-ends can be done like this:

struct cmds {
        char *name;
        void (*cmd)(int argc, char **argv);
};

You could declare a cmd_table like this:

struct cmds cmd_table[] = {
        { "backend1", backend1_exec },
        { "backend2", backend2_exec },
        ...
};

backend1_exec() and backend2_exec() are just functions which really do the grunt work for executing the real backend for you.

Then in your main() function just loop over the entries comparing each entry in the cmd_table with the argument, and then calling the corresponding backend function like this:

if (strcmp(cmdname, cmd_table[i].name)) {
        *(cmd_table[i].cmd)(argc, argv);
}

Yeah, there's nothing wrong with using strcmp() if you just got 10 entries in the table. Its not a performance critical section of your program, so I wouldn't worry too much about that. This method is a popular way of handling this, from what I have seen (that does not make it authoritative, but might help reassure you, that you're not doing anything wrong).

Sudhanshu
You did not understand my initial question. I have written the whole program using getopt_long. I can get optarg and stuff like that. The thing is simply, that given a list of acceptable choices, I want to trash all optarg values not member of this list. Currently I doing if (!strcmp (arg, "valid optarg")) ... I do not like this and I am pretty sure I could "automate" this using a data-structure (like a map or a hashtable) and immediately trash non-valid optarg without comparing agains each list members. I hope I am clear. Thank you
Xavier Maillard