1

I am writing a shell that needs a command interpreter. The current pattern I am using is as follows:

if(strcmp(command, "my_cmd_keyword1") == 0) {
  ...
}
else if(strcmp(command, "my_cmd_keyword2") == 0) {
  ..
}
...

However, the number of predefined command keywords might be very huge. The if-else branching turns out to be inefficient since it has to compare with every keyword (in the worst case). Is there any more efficient way to handle this? I am using C/C++ languages for my applications.

Jes
  • 2,614
  • 4
  • 25
  • 45

2 Answers2

5

You want function pointers and some kind of lookup table. Consider

std::unordered_map<String, std::function<void(std::string)>> 

or a pair of sorted

std::vector<>'s 

which might be faster.

Using C++11, and ignoring the string parsing issue for now, here's how the unordered_map and std::function work together:

#include <string>
#include <functional>
#include <unordered_map>

std::unordered_map<std::string, std::function<void(const std::string &)>> functions;

void xyz_function(const std::string & commandLine)
{
   // this will be called
}

void register_functions()
{
    functions["xyz"] = xyz_function;
}


int main()
{
    register_functions();

    std::string completeCommandLine = "xyz parameter parameter";
    std::string exampleCommand = "xyz";

    // now look up the command, and run the function registered
    functions[exampleCommand](completeCommandLine);

}
JCx
  • 2,689
  • 22
  • 32
2

A common solution to this problem is a hash table which maps command names to function pointers. (All the functions have to have to same signature; commonly, that would consist of a pointer to the remaining command line arguments.)

C++ conveniently has std::unordered_map (since C++11, or check in boost), which will save you a lot of implementation effort. Posix (since 2001, at least) defines the <search.h> header, which includes a simple hash map implementation. (As usual with C datastructure libraries, the associated value type is void*, so you need to cast to the desired datatype.) If neither of those works out for you, it's not hard to find open source hash table implementations, or even write one.

rici
  • 234,347
  • 28
  • 237
  • 341