<commit_before>//--------------------------------------------------------------------------------------------------
/** @file appCmd.c
 *
 * App tool for RTOS.
 *
 * Copyright (C) Sierra Wireless Inc.
 */

#include "legato.h"

#include "microSupervisor.h"

// Maximum number of arguments for "runProc"
#define MAX_ARGS_FOR_RUN_PROC   10

// Argument list for runProc, the last one is preserved for NULL
static const char *argV[MAX_ARGS_FOR_RUN_PROC + 1];

// App name for runProc
static const char* appNameStr = NULL;

// Proc name for runProc
static const char* procNameStr = NULL;

// Number of arguments for runProc
static int argC = 0;

// Counter of collected arguments
static int argsCounter = 0;

//--------------------------------------------------------------------------------------------------
/**
 * Command-line argument handler callback for "--help".
 */
//--------------------------------------------------------------------------------------------------
static void CommandHelpHandler
(
    void
)
{
    printf("Usage: app status\n"
           "       app start appName\n"
           "       app runProc appName procName [-- <args> ]\n");
}

//--------------------------------------------------------------------------------------------------
/**
 * Command-line argument handler callback for "start" an app by the given name argument.
 */
//--------------------------------------------------------------------------------------------------
static void StartAppHandler
(
    const char* arg
)
{
    le_microSupervisor_StartApp(arg);
}

//--------------------------------------------------------------------------------------------------
/**
 * Command-line argument handler callback for the "--" arguments of "runProc".
 */
//--------------------------------------------------------------------------------------------------
static void RunProcArgsHandler
(
    const char* arg
)
{
    if (strcmp(arg, "--") != 0 &&
        argsCounter < argC)
    {
        // Collect an argument
        argV[argsCounter++] = arg;

        if (argsCounter == argC)
        {
            // Add NULL
            argV[argsCounter] = NULL;

            le_microSupervisor_RunProc(appNameStr, procNameStr, argC, argV);
        }
    }
}

//--------------------------------------------------------------------------------------------------
/**
 * Command-line argument handler callback for the proc name argument of "runProc".
 */
//--------------------------------------------------------------------------------------------------
static void RunProcProcNameHandler
(
    const char* arg
)
{
    procNameStr = arg;
    int totalArgs = le_arg_NumArgs();

    if (totalArgs == 3)
    {
        le_microSupervisor_RunProc(appNameStr, procNameStr, 0, NULL);
    }
    else if (totalArgs > 4 && strcmp(le_arg_GetArg(3), "--") == 0)
    {
        // Set the number of arguments after "--" that we need to collect
        argC = totalArgs - 4;

        // Initialize the counter of collected arguments to 0
        argsCounter = 0;

        // Allow one callback handler to deal with all rest arguments
        le_arg_AllowMorePositionalArgsThanCallbacks();

        le_arg_AddPositionalCallback(RunProcArgsHandler);
    }
}

//--------------------------------------------------------------------------------------------------
/**
 * Command-line argument handler callback for the app name argument of "runProc".
 */
//--------------------------------------------------------------------------------------------------
static void RunProcAppNameHandler
(
    const char* arg
)
{
    appNameStr = arg;

    le_arg_AddPositionalCallback(RunProcProcNameHandler);
}

//--------------------------------------------------------------------------------------------------
/**
 * Function called by command line argument scanner when the command argument is found.
 **/
//--------------------------------------------------------------------------------------------------
static void CommandArgHandler
(
    const char *command
)
{
    if (strcmp(command, "status") == 0)
    {
        le_microSupervisor_DebugAppStatus();
    }
    else if (strcmp(command, "start") == 0)
    {
        le_arg_AddPositionalCallback(StartAppHandler);
    }
    else if (strcmp(command, "runProc") == 0)
    {
        le_arg_AddPositionalCallback(RunProcAppNameHandler);
    }
    else
    {
        CommandHelpHandler();
    }
}

//--------------------------------------------------------------------------------------------------
/**
 * Component initializer.
 */
//--------------------------------------------------------------------------------------------------
COMPONENT_INIT
{
    le_arg_AddPositionalCallback(&CommandArgHandler);

    le_arg_Scan();
}<commit_msg>Rework command parsing of app command<commit_after>//--------------------------------------------------------------------------------------------------
/** @file appCmd.c
 *
 * App tool for RTOS.
 *
 * Copyright (C) Sierra Wireless Inc.
 */

#include "legato.h"

#include "microSupervisor.h"

// Maximum number of arguments for "runProc"
#define MAX_ARGS_FOR_RUN_PROC   32

// Argument list for runProc, the last one is preserved for NULL
static const char *ArgV[MAX_ARGS_FOR_RUN_PROC + 1];

// App name for runProc
static const char* AppNameStr = NULL;

// Proc name for runProc
static const char* ProcNameStr = NULL;

// Number of arguments for runProc
static int ArgC = 0;

// Has the -- argument separator been found?
static bool FoundArgSeparator = false;

// Command which to run
enum {
    CMD_UNKNOWN,
    CMD_STATUS,
    CMD_START_APP,
    CMD_START_PROC,
    CMD_ERROR
} Command;

//--------------------------------------------------------------------------------------------------
/**
 * Error handler
 */
//--------------------------------------------------------------------------------------------------
static size_t ErrorHandler
(
    size_t argIndex,          ///< [IN] Argument where the error occured
    le_result_t errorCode     ///< [IN] Detected error code
)
{
    const char * errorString;

    Command = CMD_ERROR;

    switch (errorCode)
    {
        case LE_OVERFLOW:

            errorString = "Too many arguments";
            break;

        case LE_UNDERFLOW:

            errorString = "Too few arguments";
            break;

        default:
            errorString = "Unknown error while processing arguments";
    }

    const char* programNamePtr = le_arg_GetProgramName();

    printf("* %s: at argument %" PRIuS ": %s.\n", programNamePtr, argIndex + 1,
        errorString);
    printf("Try '%s --help'.\n", programNamePtr);

    return 0;
}


//--------------------------------------------------------------------------------------------------
/**
 * Command-line argument handler callback for "--help".
 */
//--------------------------------------------------------------------------------------------------
static void CommandHelpHandler
(
    void
)
{
    printf("Usage: app status\n"
           "       app start appName\n"
           "       app runProc appName procName [-- <args> ]\n");
}

//--------------------------------------------------------------------------------------------------
/**
 * Command-line argument handler callback for "start" an app by the given name argument.
 */
//--------------------------------------------------------------------------------------------------
static void StartAppHandler
(
    const char* arg
)
{
    AppNameStr = arg;

    Command = CMD_START_APP;
}

//--------------------------------------------------------------------------------------------------
/**
 * Command-line argument handler callback for the "--" arguments of "runProc".
 */
//--------------------------------------------------------------------------------------------------
static void RunProcArgsHandler
(
    const char* arg
)
{
    if (!FoundArgSeparator)
    {
        if (strcmp(arg, "--") == 0)
        {
            FoundArgSeparator = true;
        }
        else
        {
            printf("app runProc: unrecognized argument %s\n", arg);
            Command = CMD_ERROR;
        }
    }
    else if (Command != CMD_ERROR)
    {
        // Collect an argument
        ArgV[ArgC++] = arg;

        if (ArgC > MAX_ARGS_FOR_RUN_PROC)
        {
            printf("%s: too many arguments\n", ArgV[0]);
            Command = CMD_ERROR;
        }
    }
}

//--------------------------------------------------------------------------------------------------
/**
 * Command-line argument handler callback for the proc name argument of "runProc".
 */
//--------------------------------------------------------------------------------------------------
static void RunProcProcNameHandler
(
    const char* arg
)
{
    ProcNameStr = arg;

    Command = CMD_START_PROC;

    // Initialize the counter of collected arguments to 0
    ArgC = 0;

    // Have not found separator "--" yet
    FoundArgSeparator = false;

    // Allow one callback handler to deal with all rest arguments
    le_arg_AllowMorePositionalArgsThanCallbacks();

    le_arg_AddPositionalCallback(RunProcArgsHandler);
}

//--------------------------------------------------------------------------------------------------
/**
 * Command-line argument handler callback for the app name argument of "runProc".
 */
//--------------------------------------------------------------------------------------------------
static void RunProcAppNameHandler
(
    const char* arg
)
{
    AppNameStr = arg;

    le_arg_AddPositionalCallback(RunProcProcNameHandler);
}

//--------------------------------------------------------------------------------------------------
/**
 * Function called by command line argument scanner when the command argument is found.
 **/
//--------------------------------------------------------------------------------------------------
static void CommandArgHandler
(
    const char *command
)
{
    if (strcmp(command, "status") == 0)
    {
        Command = CMD_STATUS;
    }
    else if (strcmp(command, "start") == 0)
    {
        le_arg_AddPositionalCallback(StartAppHandler);
    }
    else if (strcmp(command, "runProc") == 0)
    {
        le_arg_AddPositionalCallback(RunProcAppNameHandler);
    }
}

//--------------------------------------------------------------------------------------------------
/**
 * Component initializer.
 */
//--------------------------------------------------------------------------------------------------
COMPONENT_INIT
{
    le_arg_SetErrorHandler(&ErrorHandler);
    le_arg_AddPositionalCallback(&CommandArgHandler);

    le_arg_Scan();

    switch (Command)
    {
        case CMD_UNKNOWN:
            CommandHelpHandler();
            return;
        case CMD_ERROR:
            // Error occurred -- do nothing as error has already been reported
            return;
        case CMD_STATUS:
            le_microSupervisor_DebugAppStatus();
            return;
        case CMD_START_APP:
            le_microSupervisor_StartApp(AppNameStr);
            return;
        case CMD_START_PROC:
            ArgV[ArgC] = NULL;
            le_microSupervisor_RunProc(AppNameStr, ProcNameStr, ArgC, ArgV);
            return;
    }
}
{'fraction_non_alphanumeric': 0.3587950511027434, 'fraction_numerical': 0.0026896180742334587, 'mean_word_length': 1.028181818181818, 'pattern_counts': {'":': 1, '<': 8, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3944341', 'n_tokens_mistral': 2559, 'n_tokens_neox': 2473, 'n_words': 693}