text: /*
   * Copyright (c) 2016 ARM Limited. All rights reserved.
   * SPDX-License-Identifier: Apache-2.0
   * Licensed under the Apache License, Version 2.0 (the License); you may
   * not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an AS IS BASIS, WITHOUT
   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  /**
   * \file ns_cmdline.h
   *
   * Command line library - mbedOS shell
   *
   * Usage example:
   *
   * \code
   * //simple print function
   * void myprint(const char* fmt, va_list ap){ vprintf(fmt, ap); }
   * // simple ready cb, which call next command to be execute
   * void cmd_ready_cb(int retcode) { cmd_next( retcode ); }
   *
   * // dummy command with some option
   * int cmd_dummy(int argc, char *argv[]){
   *  if( cmd_has_option(argc, argv, "o") ) {
   *    cmd_printf("This is o option");
   *  } else {
   *    return CMDLINE_RETCODE_INVALID_PARAMETERS;
   *  }
   *  return CMDLINE_RETCODE_SUCCESS;
   *}
   * // timer cb ( pseudo-timer-code )
   * void timer_ready_cb(void) {
   *   cmd_ready(CMDLINE_RETCODE_SUCCESS);
   * }
   * // long command, which need e.g. some events to finalize command execution
   * int cmd_long(int argc, char *argv[] ) {
       timer_start( 5000, timer_ready_cb );
   *   return CMDLINE_RETCODE_EXCUTING_CONTINUE;
   * }
   * void main(void) {
   *   cmd_init( &myprint );              // initialize cmdline with print function
   *   cmd_set_ready_cb( cmd_ready_cb );  // configure ready cb
   *   cmd_add("dummy", cmd_dummy, 0, 0); // add one dummy command
   *   cmd_add("long", cmd_long, 0, 0);   // add one dummy command
   *   //execute dummy and long commands
   *   cmd_exe( "dymmy;long" );
   * }
   * \endcode
   */
  #ifndef _CMDLINE_H_
  #define _CMDLINE_H_
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  #include <stdarg.h>
  #include <stdint.h>
  #include <stddef.h>
  #include <stdbool.h>
  
  #define CMDLINE_RETCODE_COMMAND_BUSY            2   //!< Command Busy
  #define CMDLINE_RETCODE_EXCUTING_CONTINUE       1   //!< Execution continue in background
  #define CMDLINE_RETCODE_SUCCESS                 0   //!< Execution Success
  #define CMDLINE_RETCODE_FAIL                    -1  //!< Execution Fail
  #define CMDLINE_RETCODE_INVALID_PARAMETERS      -2  //!< Command parameters was incorrect
  #define CMDLINE_RETCODE_COMMAND_NOT_IMPLEMENTED -3  //!< Command not implemented
  #define CMDLINE_RETCODE_COMMAND_CB_MISSING      -4  //!< Command callback function missing
  #define CMDLINE_RETCODE_COMMAND_NOT_FOUND       -5  //!< Command not found
  
  /**
   * typedef for print functions
   */
  typedef void (cmd_print_t)(const char *, va_list);
  /**
   * Initialize cmdline class.
   * This is command line editor without any commands. Application
   * needs to add commands that should be enabled.
   * usage e.g.
   * \code
      cmd_init( &default_cmd_response_out );
   * \endcode
   * \param outf  console printing function (like vprintf)
   */
  void cmd_init(cmd_print_t *outf);
  /** Command ready function for __special__ cases.
   * This need to be call if command implementation return CMDLINE_RETCODE_EXECUTING_CONTINUE
   * because there is some background stuff ongoing before command is finally completed.
   * Normally there is some event, which call cmd_ready().
   * \param retcode return code for command
   */
  void cmd_ready(int retcode);
  /** typedef for ready cb function */
  typedef void (cmd_ready_cb_f)(int);
  /**
   * Configure cb which will be called after commands are executed
   * or cmd_ready is called
   * \param cb    callback function for command ready
   */
  void cmd_set_ready_cb(cmd_ready_cb_f *cb);
  /**
   * execute next command if any
   * \param retcode last command return value
   */
  void cmd_next(int retcode);
  /** Free cmd class */
  void cmd_free(void);
  /** Reset cmdline to default values
   *  detach external commands, delete all variables and aliases
   */
  void cmd_reset(void);
  /** Configure command history size (default 32)
   *  \param max  maximum history size
   *  max > 0 -> configure new value
   *  max = 0 -> just return current value
   *  \return current history max-size
   */
  uint8_t cmd_history_size(uint8_t max);
  /** command line print function
   *  This function should be used when user want to print something to the console
   *  \param fmt   console print function (like printf)
   */
  #if defined(__GNUC__)
  void cmd_printf(const char *fmt, ...)  __attribute__((__format__(__printf__, 1, 2)));
  #else
  void cmd_printf(const char *fmt, ...);
  #endif
  /** command line print function
   *  This function should be used when user want to print something to the console with vprintf functionality
   *  \param fmt  The format string is a character string, beginning and ending in its initial shift state, if any. The format string is composed of zero or more directives.
   *  \param ap   list of parameters needed by format string. This must correspond properly with the conversion specifier.
   */
  #if defined(__GNUC__)
  void cmd_vprintf(const char *fmt, va_list ap)  __attribute__((__format__(__printf__, 1, 0)));
  #else
  void cmd_vprintf(const char *fmt, va_list ap);
  #endif
  /** Reconfigure default cmdline out function (cmd_printf)
   *  \param outf  select console print function
   */
  void cmd_out_func(cmd_print_t *outf);
  /** Configure function, which will be called when Ctrl+A is pressed
   * \param sohf control function which called every time when user input control keys
   */
  void cmd_ctrl_func(void (*sohf)(uint8_t c));
  /**
   * Configure mutex wait function
   * By default, cmd_printf calls may not be thread safe, depending on the implementation of the used output.
   * This can be used to set a callback function that will be called before each cmd_printf call.
   * The specific implementation is up to the application developer, but simple mutex locking is assumed.
   */
  void cmd_mutex_wait_func(void (*mutex_wait_f)(void));
  /**
   * Configure mutex wait function
   * By default, cmd_printf calls may not be thread safe, depending on the implementation of the used output.
   * This can be used to set a callback function that will be called after each cmd_printf call.
   * The specific implementation is up to the application developer, but simple mutex locking is assumed.
   */
  void cmd_mutex_release_func(void (*mutex_release_f)(void));
  /**
   * Retrieve output mutex lock
   * This can be used to retrieve the output mutex when multiple cmd_printf/cmd_vprintf calls must be
   * guaranteed to be grouped together in a thread safe manner. Must be released by a following call to
   * cmd_mutex_unlock()
   * For example:
   * * \code
   * cmd_mutex_lock();
     for (i = 0; i < 10; i++) {
         cmd_printf("%02x ", i);
     }
     // without locking a print from another thread could happen here
     cmd_printf("\r\n);
     cmd_mutex_unlock();
   * \endcode
   * Exact behaviour depends on the implementation of the configured mutex,
   * but counting mutexes are required.
   */
  void cmd_mutex_lock(void);
  /**
   * Release output mutex lock
   * This can be used to release the output mutex once it has been retrieved with cmd_mutex_lock()
   * Exact behaviour depends on the implementation of the configured mutex,
   * but counting mutexes are required.
   */
  void cmd_mutex_unlock(void);
  /** Refresh output */
  void cmd_output(void);
  /** default cmd response function, use stdout
   *  \param fmt  The format string is a character string, beginning and ending in its initial shift state, if any. The format string is composed of zero or more directives.
   *  \param ap   list of parameters needed by format string. This must correspond properly with the conversion specifier.
   */
  void default_cmd_response_out(const char *fmt, va_list ap);
  /** Initialize screen */
  void cmd_init_screen(void);
  /** Get echo state
   * \return true if echo is on otherwise false
   */
  bool cmd_echo_state(void);
  /** Echo off */
  void cmd_echo_off(void);
  /** Echo on */
  void cmd_echo_on(void);
  /** Enter character to console.
   * insert key pressess to cmdline called from main loop of application
   * \param u_data char to be added to console
   */
  void cmd_char_input(int16_t u_data);
  /*
   * Set the passthrough mode callback function. In passthrough mode normal command input handling is skipped and any
   * received characters are passed to the passthrough callback function. Setting this to null will disable passthrough mode.
   * \param passthrough_fnc The passthrough callback function
   */
  typedef void (*input_passthrough_func_t)(uint8_t c);
  void cmd_input_passthrough_func(input_passthrough_func_t passthrough_fnc);
  
  /* Methods used for adding and handling of commands and aliases
   */
  
  /** Callback called when your command is run.
   * \param argc argc is the count of arguments given in argv pointer list. value begins from 1 and this means that the 0 item in list argv is a string to name of command.
   * \param argv argv is list of arguments. List size is given in argc parameter. Value in argv[0] is string to name of command.
   */
  typedef int (cmd_run_cb)(int argc, char *argv[]);
  /** Add command to intepreter
   * \param name      command string
   * \param callback  This function is called when command line start executing
   * \param info      Command short description which is visible in help command, or null if not in use
   * \param man       Help page for this command. This is shown when executing command with invalid parameters or command with --help parameter. Can be null if not in use.
   */
  void cmd_add(const char *name, cmd_run_cb *callback, const char *info, const char *man);
  
  /** delete command from intepreter
   *  \param name command to be delete
   */
  void cmd_delete(const char *name);
  /** Command executer.
   * Command executer, which split&push command(s) to the buffer and
   * start executing commands in cmd tasklet.
   * if not, execute command directly.
   * If command implementation returns CMDLINE_RETCODE_EXCUTING_CONTINUE,
   * executor will wait for cmd_ready() before continue to next command.
   * \param str  command string, e.g. "help"
   */
  void cmd_exe(char *str);
  /** Add alias to interpreter.
   * Aliases are replaced with values before executing a command. All aliases must be started from beginning of line.
   * null or empty value deletes alias.
   * \code
     cmd_alias_add("print", "echo");
     cmd_exe("print \"hello world!\""); // this is now same as "echo \"hello world!\"" .
   * \endcode
   * \param alias     alias name
   * \param value     value for alias. Values can be any visible ASCII -characters.
   */
  void cmd_alias_add(const char *alias, const char *value);
  /** Add Variable to interpreter.
   * Variables are replaced with values before executing a command.
   * To use variables from cli, use dollar ($) -character so that interpreter knows user want to use variable in that place.
   * null or empty value deletes variable.
   * \code
     cmd_variable_add("world", "hello world!");
     cmd_exe("echo $world"); // this is now same as echo "hello world!" .
   * \endcode
   * \param variable  Variable name, which will be replaced in interpreter.
   * \param value     Value for variable. Values can contains white spaces and '"' or '"' characters.
   */
  void cmd_variable_add(char *variable, char *value);
  /**
   * Add integer variable to interpreter.
   * Variables are replaced with values before executing a command.
   * \code
     cmd_variable_add_int("world", 2);
     cmd_exe("echo $world"); // this is now same as 'echo 2' .
   * \endcode
   * \param variable  Variable name, which will be replaced in interpreter.
   * \param value     Value for variable
  
   */
  void cmd_variable_add_int(char *variable, int value);
  /**
   * Request screen size from host
   * Response are stored to variables:
   * COLUMNS and LINES - as integer values.
   * Note: Require terminal that handle request codes, like screen.
   */
  void cmd_request_screen_size(void);
  
  
  /** find command parameter index by key.
   * e.g.
   * \code
        int main(void){
              //..init cmd..
              //..
              cmd_exe("mycmd enable")
        }
        int mycmd_command(int argc, char *argv[]) {
          bool found = cmd_parameter_index( argc, argv, "enable" ) > 0;
        }
   * \endcode
   * \param argc  argc is the count of arguments given in argv pointer list. value begins from 1 and this means that the 0 item in list argv is a string to name of command.
   * \param argv  is list of arguments. List size is given in argc parameter. Value in argv[0] is string to name of command.
   * \param key   option key, which index you want to find out.
   * \return index where parameter was or -1 when not found
   */
  int cmd_parameter_index(int argc, char *argv[], const char *key);
  /** check if command option is present.
   * e.g. cmd: "mycmd -c"
   * \code
   *    bool on = cmd_has_option( argc, argv, "p" );
   * \endcode
   * \param argc  argc is the count of arguments given in argv pointer list. value begins from 1 and this means that the 0 item in list argv is a string to name of command.
   * \param argv  is list of arguments. List size is given in argc parameter. Value in argv[0] is string to name of command.
   * \param key   option key to be find
   * \return true if option found otherwise false
   */
  bool cmd_has_option(int argc, char *argv[], const char *key);
  /** find command parameter by key.
   * if exists, return true, otherwise false.
   * e.g. cmd: "mycmd enable 1"
   * \code
    int mycmd_command(int argc, char *argv[]) {
          bool value;
          bool found = cmd_parameter_bool( argc, argv, "mykey", &value );
          if( found ) return CMDLINE_RETCODE_SUCCESS;
          else return CMDLINE_RETCODE_FAIL;
      }
   * \endcode
   * \param argc  argc is the count of arguments given in argv pointer list. value begins from 1 and this means that the 0 item in list argv is a string to name of command.
   * \param argv  is list of arguments. List size is given in argc parameter. Value in argv[0] is string to name of command.
   * \param key   parameter key to be find
   * \param value parameter value to be fetch, if key not found value are untouched. "1" and "on" and "true" and "enable" and "allow" are True -value, all others false.
   * \return true if parameter key and value found otherwise false
   */
  bool cmd_parameter_bool(int argc, char *argv[], const char *key, bool *value);
  /** find command parameter by key and return value (next parameter).
   * if exists, return parameter pointer, otherwise null.
   * e.g. cmd: "mycmd mykey myvalue"
   * \code
      int mycmd_command(int argc, char *argv[]) {
          char *value;
          bool found = cmd_parameter_val( argc, argv, "mykey", &value );
          if( found ) return CMDLINE_RETCODE_SUCCESS;
          else return CMDLINE_RETCODE_FAIL;
      }
   * \endcode
   * \param argc  argc is the count of arguments given in argv pointer list. value begins from 1 and this means that the 0 item in list argv is a string to name of command.
   * \param argv  is list of arguments. List size is given in argc parameter. Value in argv[0] is string to name of command.
   * \param key   parameter key to be find
   * \param value pointer to pointer, which will point to cli input data when key and value found. if key or value not found this parameter are untouched.
   * \return true if parameter key and value found otherwise false
   */
  bool cmd_parameter_val(int argc, char *argv[], const char *key, char **value);
  /** find command parameter by key and return value (next parameter) in integer. Only whitespaces are allowed in addition to the float to be read.
   * e.g. cmd: "mycmd mykey myvalue"
   * \code
       int32_t value;
       cmd_parameter_int( argc, argv, "key", &value );
   * \endcode
   * \param argc  argc is the count of arguments given in argv pointer list. value begins from 1 and this means that the item 0 in the list argv is a string to name of command.
   * \param argv  is list of arguments. List size is given in argc parameter. Value in argv[0] is string to name of command.
   * \param key   parameter key to be found
   * \param value A pointer to a variable where to write the converted number. If value cannot be converted, it is not touched.
   * \return true if parameter key and an integer is found, otherwise return false
   */
  bool cmd_parameter_int(int argc, char *argv[], const char *key, int32_t *value);
  /** find command parameter by key and return value (next parameter) in float. Only whitespaces are allowed in addition to the float to be read.
   * e.g. cmd: "mycmd mykey myvalue"
   * \code
       float value;
       cmd_parameter_float( argc, argv, "key", &value );
   * \endcode
   * \param argc  argc is the count of arguments given in argv pointer list. values begin from 1 and this means that the item 0 in the list argv is a string to name of command.
   * \param argv  is list of arguments. List size is given in argc parameter. Value in argv[0] is string to name of command.
   * \param key   parameter key to be found
   * \param value A pointer to a variable where to write the converted number. If value cannot be converted, it is not touched.
   * \return true if parameter key and a float found, otherwise return false
   */
  bool cmd_parameter_float(int argc, char *argv[], const char *key, float *value);
  /** Get last command line parameter as string.
   * e.g.
   *     cmd: "mycmd hello world"
   *     cmd_parameter_last -> "world"
   *     cmd: "mycmd"
   *     cmd_parameter_last() -> NULL
   * \code
      cmd_parameter_last(argc, argv)
   * \endcode
   * \param argc  argc is the count of arguments given in argv pointer list. value begins from 1 and this means that the 0 item in list argv is a string to name of command.
   * \param argv  is list of arguments. List size is given in argc parameter. Value in argv[0] is string to name of command.
   * \return pointer to last parameter or NULL when there is no any parameters.
   */
  char *cmd_parameter_last(int argc, char *argv[]);
  
  /** find command parameter by key and return value (next parameter) in int64.
   * e.g. cmd: "mycmd mykey myvalue"
   * \code
       uint32_t i;
       cmd_parameter_timestamp( argc, argv, "mykey", &i );
   * \endcode
   *
   * Supports following formats:
   *  number -> direct conversion
   *  11:22:33:44:55:66:77:88 -> converts to number
   *  seconds,tics -> converts thread type timestamp to int64
   *
   * \param argc  argc is the count of arguments given in argv pointer list. value begins from 1 and this means that the 0 item in list argv is a string to name of command.
   * \param argv  is list of arguments. List size is given in argc parameter. Value in argv[0] is string to name of command.
   * \param key   parameter key to be find
   * \param value parameter value to be fetch, if key not found value are untouched.
   * \return true if parameter key and value found otherwise false
   */
  bool cmd_parameter_timestamp(int argc, char *argv[], const char *key, int64_t *value);
  
  #ifdef __cplusplus
  }
  #endif
  #endif /*_CMDLINE_H_*/
  