diff --git a/CMakeLists.txt b/CMakeLists.txt index 1961f6b..8c6b858 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(argparser) set(ARGPARSER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/argparser") set(TEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}/test") -set(TEST_ENABLE ON) +set(TEST_ENABLE OFF) if(TEST_ENABLE) # Add test-related configurations or dependencies here diff --git a/README.md b/README.md index 6dd580a..74478a0 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,10 @@ To use ArgParser in your C++ program, include the `argparser.h` header file and #include int main(int argc, char* argv[]) { - ArgParser parser; + ArgParser parser( + "Argument Parser v1.1", // Project name + "This project can be used to parse command line arguments" // Description + ); // Add arguments parser.addArgument("boolArg", "-b", "--bool", "Bool argument", false); @@ -60,6 +63,53 @@ int main(int argc, char* argv[]) { } ``` +## Help Command +To display help information, use the following commands: + +```cmd +./.exe -h +``` +or +```cmd +./.exe --help +``` + +Upon execution, it will output: +``` +Argument Parser v1.1 + +DESCRIPTION: + This project can be used to parse command line arguments +USAGE: + -b, --bool : This is a flag argument + -d, --double : This is a double argument + -i, --int : This is a int argument + -s, --string : This is a string argument +``` +Replace `` with the actual name of your executable. This section provides a quick guide on how users can access `help` information along with an example output showcasing the available command-line arguments. + +Otherthan that user can add own help command with built-in help command, then the user specified function will execute before `help` command. + +```cpp +// Example user-specified callback +void userSpecifiedCallback() { + printf("Executing user-specified callback before the built-in help command."); +} + +int main(int argc, char* argv[]) { + ArgParser parser; + + // Set user-specified callback for help + parser.setHelpCallback(userSpecifiedCallback); + + // Parse command-line arguments + parser.parse(argc, argv); + + // ... rest of the program + return 0; +} +``` + ## Examples Here are some examples demonstrating the usage of ArgParser: diff --git a/argparser/include/argparser.h b/argparser/include/argparser.h index 452bb2e..cb30c0d 100644 --- a/argparser/include/argparser.h +++ b/argparser/include/argparser.h @@ -12,7 +12,10 @@ using namespace std; class ArgParser { public: + using Callback = std::function; + ArgParser(); + ArgParser(const string& _name, const string& _description); ~ArgParser(); template @@ -33,13 +36,19 @@ class ArgParser { } bool argExists(const string &name) const; + void setHelpCallback(const Callback& callback); private: bool precheck(const string& name, const string& shortcmd, const string& longcmd); void postcheck(); + void help(); + Callback help_callback; map args; + + string name; + string description; }; #endif // !_ARGPARSER_H_ \ No newline at end of file diff --git a/argparser/include/argument.h b/argparser/include/argument.h index 39809b8..1de3c49 100644 --- a/argparser/include/argument.h +++ b/argparser/include/argument.h @@ -37,6 +37,7 @@ class Argument{ string getName() const; string getShortCmd() const; string getLongCmd() const; + string getHelp() const; void setArgPosition(int position); private: diff --git a/argparser/src/argdouble.cpp b/argparser/src/argdouble.cpp index a4fe1d1..07af5c7 100644 --- a/argparser/src/argdouble.cpp +++ b/argparser/src/argdouble.cpp @@ -17,7 +17,6 @@ ArgStatus DoubleArgument::loadValue(const string& arg, int pos){ try{ value = stod(arg); - printf("Float Value: %f\n", value); return PARSER_OK; } catch (const std::invalid_argument& e) { fprintf(stderr, "Error: %s is not a valid float.\n", arg.c_str()); diff --git a/argparser/src/argint.cpp b/argparser/src/argint.cpp index 7074657..7709ae9 100644 --- a/argparser/src/argint.cpp +++ b/argparser/src/argint.cpp @@ -17,7 +17,6 @@ ArgStatus IntArgument::loadValue(const string& arg, int pos){ try{ value = stoi(arg); - printf("Int Value: %d\n", value); return PARSER_OK; } catch (const std::invalid_argument& e) { fprintf(stderr, "Error: %s is not a valid integer.\n", arg.c_str()); diff --git a/argparser/src/argparser.cpp b/argparser/src/argparser.cpp index b206331..b0024c3 100644 --- a/argparser/src/argparser.cpp +++ b/argparser/src/argparser.cpp @@ -3,6 +3,7 @@ #include #include #include +#include // #define VALIDATE_STRING(x) \ // do { \ // if (x.empty()) { \ @@ -14,8 +15,20 @@ #define VALIDATE_STRING(x) #define LONGCMD_STRING "--" #define SHORTCMD_STRING '-' +#define LONG_HELPCMD "--help" +#define SHORT_HELPCMD "-h" -ArgParser::ArgParser() { +#define DEFAULT_PARSER_NAME "Default Project Name" +#define DEFAULT_PARSER_DESCRIPTION "Default Project Description" + + +ArgParser::ArgParser() + : name(DEFAULT_PARSER_NAME), description(DEFAULT_PARSER_DESCRIPTION){ + +} + +ArgParser::ArgParser(const string& _name, const string& _description) + : name(_name), description(_description){ } @@ -36,6 +49,10 @@ bool ArgParser::precheck( return false; } + if(longcmd == LONG_HELPCMD || shortcmd == SHORT_HELPCMD){ + return false; + } + for (const auto& argument : args) { if( argument.second->getName() == name || argument.second->getLongCmd() == longcmd || @@ -51,6 +68,30 @@ void ArgParser::postcheck(){ } +void ArgParser::help(){ + + if (help_callback) { + help_callback(); + } + + printf("%s\n\n", name.c_str()); + printf("DESCRIPTION:\n\t%s\n", description.c_str()); + + printf("USAGE:\n"); + for (const auto& argument : args) { + printf("\t%s, %s \t: %s\n", + argument.second->getShortCmd().c_str(), + argument.second->getLongCmd().c_str(), + argument.second->getHelp().c_str()); + } + + printf("\n"); +} + +void ArgParser::setHelpCallback(const Callback& callback){ + help_callback = callback; +} + template <> ArgStatus ArgParser::addArgument( const string& name, @@ -164,6 +205,11 @@ ArgStatus ArgParser::parse(int argc, char* argv[]){ Argument* temp = nullptr; ArgStatus ret = PARSER_ERROR; + if(strcmp(argv[1], LONG_HELPCMD) == PARSER_OK || strcmp(argv[1], SHORT_HELPCMD) == PARSER_OK){ + help(); + return PARSER_OK; + } + for (int i = 0; i < argc; ++i) { temp = find(argv[i]); if(temp != nullptr && !temp->status()) { diff --git a/argparser/src/argstring.cpp b/argparser/src/argstring.cpp index 14379be..ed6be17 100644 --- a/argparser/src/argstring.cpp +++ b/argparser/src/argstring.cpp @@ -16,7 +16,6 @@ ArgStatus StringArgument::loadValue(const string& arg, int pos){ if(!arg.empty()){ value = arg; - printf("String Value: %s\n", value.c_str()); } else{ return PARSER_INVALID_ARGUMENT; diff --git a/argparser/src/argument.cpp b/argparser/src/argument.cpp index cdc577b..934da8a 100644 --- a/argparser/src/argument.cpp +++ b/argparser/src/argument.cpp @@ -40,6 +40,10 @@ string Argument::getLongCmd() const { return longcmd; } +string Argument::getHelp() const { + return help; +} + void Argument::setArgPosition(int position){ argpos = position; } diff --git a/main.cpp b/main.cpp index a00cd21..ddd647b 100644 --- a/main.cpp +++ b/main.cpp @@ -4,28 +4,40 @@ using namespace std; int main(int argc, char* argv[]){ - ArgParser parser; + ArgParser parser( + "Argument Parser v1.1", // Project name + "This project can be used to parse command line arguments" // Description + ); - parser.addArgument("debug", "-d", "--debug", "This is a flag argument", false); + // char* sargv[] = { (char*)"program_name", + // (char*)"--int", (char*)"123", // Int Argument + // (char*)"--string", (char*)"Hello World", // String Argument + // (char*)"--bool", // Bool Argument + // (char*)"--double", (char*)"65.343"}; // Double Argument + char* sargv[] = { (char*)"program_name", (char*)"-h"}; + int sargc = sizeof(sargv) / sizeof(sargv[0]); + + + parser.addArgument("bool", "-b", "--bool", "This is a flag argument", false); parser.addArgument("int", "-i", "--int", "This is a int argument", 10); parser.addArgument("double", "-d", "--double", "This is a double argument", 0.0); parser.addArgument("string", "-s", "--string", "This is a string argument", "null"); parser.parse(argc, argv); - parser.print(); + //parser.print(); auto intValue = parser.get("int"); auto doubleValue = parser.get("double"); auto stringValue = parser.get("string"); - printf("Int Value : %d\n", intValue); - printf("Double Value : %f\n", doubleValue); - printf("String Value : %s\n", stringValue.c_str()); - if(parser.argExists("debug")){ - printf("debug is there\n"); - } - else{ - printf("debug is not there\n"); - } + // printf("Int Value : %d\n", intValue); + // printf("Double Value : %f\n", doubleValue); + // printf("String Value : %s\n", stringValue.c_str()); + // if(parser.argExists("debug")){ + // printf("debug is there\n"); + // } + // else{ + // printf("debug is not there\n"); + // } } \ No newline at end of file