argtable / argtable3

A single-file, ANSI C, command-line parsing library that parses GNU-style command-line options.
http://www.argtable.org
Other
372 stars 65 forks source link

using argtable in members functions #44

Closed t0m4s closed 4 years ago

t0m4s commented 4 years ago

Hi, I don't know if this is the right place to post the message. If it isn't, please redirect me to the correct place.

I'am developping a C++ project on an ESP32. I'd like to use esp_console + argtable3 in it. I'm trying to use argtable in my members functions. To do so, I'm creating callback functions to my members functions with a global pointer. I'm sure my class is going to be instanced only once so I assume it's ok to create callback functions.

The problem is that argtable isn't giving me back the parameters entered by the user. It checks for them successfully (number of args and their type) but the data it gives me back is random. I've tested my code outside of members functions and it works well. But I want to use it inside members functions to access other parts of my object. Here is my code :

// Pointer for my callback functions
MyClass * _callback;

struct arg_int *argInt;
struct arg_end *endPage;

// My callback function (GLOBAL)
int _setInt(int argc, char *argv[])
{
    return _callback->setInt(argc, argv);
}

// Tab of struct for argtable lib (GLOBAL)
void *setInt_argtable[] =
{
    argInt = arg_int1(NULL, NULL, "<0-12>", "Integer argument"),
    endInt = arg_end(10)
};

// Function I'm calling back
int MyClass::setInt(int argc, char *argv[])
{
    int nerrors = arg_parse(argc,argv,setInt_argtable);
    if (nerrors > 0)
    {
        arg_print_errors(stdout, endPage, "myprog");
        return 0;
    }
    printf("argc = %d\n", argc);                // argc gives the correct number of args
    printf("argv[0] = %s\n", argv[0]);          // argv[0] gives the correct command name
    printf("argv[1] = %s\n", argv[1]);          // argv[1] gives the correct value
    printf("argInt->ival[0] = %d\n", argInt->ival[0]);  // argInt->ival[0] gives random value
    return 0;
}

void MyClass::main(void)
{
    // Callback pointer initialisation
    _callback = this;

    /* Initializing the console */
    esp_console_config_t console_config
    {
        256,
        8,
        atoi(LOG_COLOR_CYAN),
        0
    };
    ESP_ERROR_CHECK( esp_console_init(&console_config) );

    /* Configure linenoise line completion library */
    /* Enable multiline editing. If not set, long commands will scroll within
    * single line.
    */
    linenoiseSetMultiLine(1);

    /* Tell linenoise where to get command completions and hints */
    linenoiseSetCompletionCallback(&esp_console_get_completion);
    linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint);

    /* Set command history size */
    linenoiseHistorySetMaxLen(100);

    esp_console_register_help_command();

    //
    // Feeding my console with argtable parameters
    //

    esp_console_cmd_t consoleCmd;
    consoleCmd.command  = "setInt";
    consoleCmd.func     = &_setInt;
    consoleCmd.help     = "Trying to set a integer argument";
    consoleCmd.argtable = setInt_argtable;
    esp_console_cmd_register(&consoleCmd);

    /* Main loop */
    while(true)
    {
        // Getting command from user
    }
}

The problem seems to be here : In argatable3.c : at the end of function static int arg_int_scanfn(struct arg_int parent, const char argval) :

if (errorcode == 0)
{
    parent->ival[parent->count++] = val;
    printf("val = %ld\n", val);
    printf("parent->ival[parent->count] = %d\n", parent->ival[parent->count]);
}

The first printf gives me back the correct value but the second one gives me back a random value.

Is my approach of using callback member function good ? Any idea of what is my problem and how I could solve it ?

Thanks in advance for your answers.

t0m4s commented 4 years ago

About the last 2 printf : as count is post-incremented, it's normal that the second printf is printing random data. The problem isn't there (and that's quite reassuring ;-).

t0m4s commented 4 years ago

After being copying/pasting very sample codes found on internet, I finally found what was the problem : I was including #include <argtable3/argtable3.h> after "myclass.h" Took my almost 2 days...

tomghuang commented 4 years ago

@t0m4s Glad that you found the issue, and thanks for sharing this info.