05-032-MendicantBias's picture
Upload 12635 files
1d3d9a5 verified
raw
history blame
188 kB
/****************************************************************************
** OrangeBot Project
*****************************************************************************
** /
** /
** /
** ______ \
** \
** \
*****************************************************************************
** UNIVERSAL PARSER
*****************************************************************************
** Author: Orso Eric
** Creation Date: 2019-06-17
** Last Edit Date: 2020-01-15
** Revision: 2
** Version: 5.0
****************************************************************************/
/****************************************************************************
** DESCRIPTION
*****************************************************************************
** Do a universal parser that does not require malloc/free and do not use explicit dictionary
** I create a special register command function in which the message and an handler is provided
****************************************************************************/
/****************************************************************************
** COMMAND RULES
*****************************************************************************
** ADD COMMAND TO PARSER
** A command is composed by fixed alphanumeric chars and argument descriptors
** Each command is associated with a unique function callback
** A command can only start with letters
**
** EXAMPLE ADD COMMAND TO PARSER
** myparser.add_cmd("P", (void *)&my_ping_handler );
** Add a new command that is triggered when the string P\0 is received.
** function my_ping_handler will be automatically executed when the \0 is processed
** myparser.parse( 'P' );
** myparser.parse( '\0' );
** send manually bytes to the parser to test the system
*****************************************************************************
** Command restriction:
** >Can only start with a letter
** >Valid arguments are %u %s %U %S %d %D
** >There can be no commands with same start but two different argument type. Only the first one will be considered in case
** PWM%d...
** PWM%u...
** The parser has no way of knowing if the incoming input (example 10) is meant for one command or the other
** >After valid ID access parameters using Parser Macros
****************************************************************************/
/****************************************************************************
** KNOWN BUG
*****************************************************************************
**
****************************************************************************/
/****************************************************************************
** INCLUDES
****************************************************************************/
//#include <iostream>
#include <cstdio>
#include <stdint.h>
#define ENABLE_DEBUG
#include "debug.h"
//Class Header
#include "uniparser.h"
/****************************************************************************
** NAMESPACES
****************************************************************************/
namespace Orangebot
{
/****************************************************************************
** GLOBAL VARIABILES
****************************************************************************/
/****************************************************************************
*****************************************************************************
** CONSTRUCTORS
*****************************************************************************
****************************************************************************/
/***************************************************************************/
//! @brief Empty Constructor
//! Uniparser | void
/***************************************************************************/
// @param
//! @return no return
//! @details
//! Empty constructor
/***************************************************************************/
Uniparser::Uniparser( void )
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//! @details algorithm:
//Initialize structure to safe values
this -> init();
//Pass a terminator to the parser to have it initialize itself
this -> parse( '\0' );
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return;
} //end constructor:
/****************************************************************************
*****************************************************************************
** DESTRUCTORS
*****************************************************************************
****************************************************************************/
/***************************************************************************/
//! @brief Empty Destructor
//! Uniparser | void
/***************************************************************************/
// @param
//! @return no return
//! @details
//! Empty destructor
/***************************************************************************/
Uniparser::~Uniparser( void )
{
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//! @details algorithm:
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return;
} //end destructor:
/****************************************************************************
*****************************************************************************
** OPERATORS
*****************************************************************************
****************************************************************************/
/****************************************************************************
*****************************************************************************
** SETTERS
*****************************************************************************
****************************************************************************/
/****************************************************************************
*****************************************************************************
** GETTERS
*****************************************************************************
****************************************************************************/
/***************************************************************************/
//! @brief Public Getter
//! get_error | void
/***************************************************************************/
//! @return Err_codes | error code
//! @details
//! Get current error code of the parser
/***************************************************************************/
Err_codes Uniparser::get_error( void )
{
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
return this -> g_err;
} //end destructor: get_error | void
/****************************************************************************
*****************************************************************************
** TESTERS
*****************************************************************************
****************************************************************************/
/****************************************************************************
*****************************************************************************
** PUBLIC METHODS
*****************************************************************************
****************************************************************************/
/***************************************************************************/
//! @brief Public Method
//! add_command | const char *, void *
/***************************************************************************/
//! @param cmd | const char * Text that will trigger the command
//! @param handler | void * Pointer to callback function for this command
//! @return bool | false: OK | true: fail
//! @details
//! Add a string and a function pointer to the parser
//! @todo check that command is valid
/***************************************************************************/
bool Uniparser::add_cmd( const char *cmd, void *handler )
{
DENTER_ARG("cmd: %p >%s<\n", (void *)cmd, cmd );
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//index
uint8_t t;
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//if: input is invalid
if ((cmd == nullptr) || (handler == nullptr))
{
this -> g_err = ERR_INVALID_CMD;
DRETURN_ARG("ERR%d: ERR_INVALID_CMD\n", this -> g_err);
return true; //fail
}
//If: num command is invalid
if ((UNIPARSER_PENDANTIC_CHECKS) && ((this -> g_num_cmd < 0) || (this->g_num_cmd >= UNIPARSER_MAX_CMD)) )
{
this -> g_err = ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
//if: maximum number of command has been reached
if (this -> g_num_cmd >= (UNIPARSER_MAX_CMD-1))
{
this -> g_err = ERR_ADD_MAX_CMD;
DRETURN_ARG("ERR%d: ERR_ADD_MAX_CMD in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
// check the validity of the string
bool f_ret = this -> chk_cmd((const uint8_t *)cmd);
//If: command had a syntax error
if (f_ret == true)
{
DRETURN_ARG("command didnt get past argument descriptor check\n");
return true; //FAIL
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Fetch currently used command
t = this -> g_num_cmd;
//Link command handler and command text
this -> g_cmd_txt[t] = (uint8_t *)cmd;
this -> g_cmd_handler[t] = handler;
DPRINT("Command >%s< with handler >%p< has been added with index: %d\n", cmd, (void *)handler, t);
//A command has been added
this -> g_num_cmd = t +1;
DPRINT("Total number of commands: %d\n", this -> g_num_cmd);
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
DRETURN();
return false;
} //end method: add_command | const char *, void *
/***************************************************************************/
//! @brief Public Method
//! parse | char
/***************************************************************************/
//! @param data | uint8_t | incoming character to be processed through the universal parser
//! @return bool | false = OK | true = A runtime error occurred
//! @details
//! Intricate FSM. The objective is to check the incoming character against
//! charaters inside the various commands and decode a command when a \0 is detected
/***************************************************************************/
bool Uniparser::parse( uint8_t data )
{
if ((data < '0') || (data > 'z'))
{
DENTER_ARG("exe: >0x%x<\n", data );
}
else
{
DENTER_ARG("exe: >0x%x< >%c<\n", data, data );
}
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//when true, reset the FMS
bool f_rst_fsm = false;
//Index of the handler to be executer
int8_t exe_index = -1;
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//----------------------------------------------------------------
// CLEAR ERROR
//----------------------------------------------------------------
// User was notified of the error during previous call
// Errors should have triggered an FSM reset to return in working condition
// I can clear the error and keep churning bytes
//If: an error was reported
if (this -> g_err != Err_codes::NO_ERR)
{
//Clear the error
DPRINT("%d | Clear Error: %d\n", __LINE__, this -> g_err);
this -> g_err = Err_codes::NO_ERR;
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//----------------------------------------------------------------
// TERMINATOR
//----------------------------------------------------------------
//! @details when terminator is detected, close the command.
//! I either have a full match, or the command is invalid and I have to reset the FSM
//If: input terminator from user
if (data == '\0')
{
DPRINT("%d | Terminator detected | Number of partial matches: %d\n", __LINE__, this -> g_num_match);
//counter
uint8_t t;
//If: i was decoding an argument
if (this -> g_status == Orangebot::Parser_status::PARSER_ARG)
{
//I'm done decoding
DPRINT("%d | Terminator after ARG\n", __LINE__);
//Close current argument and update the argument detector FSM.
bool f_ret = this -> close_arg();
//if could not close argument
if (f_ret == true)
{
//I can recover from this.
//no matches and reset the FSM.
this -> g_num_match = 0;
}
}
//Index inside the command
uint8_t cmd_index;
//if: I have at least one parser_tmp.id_index entry
if (this -> g_num_match > 0)
{
DPRINT("%d | Scanning partially matched commands for terminators\n", __LINE__);
//For: scan all commands
for (t = 0;t<this -> g_num_cmd;t++)
{
//Fetch command index
cmd_index = this -> g_cmd_index[t];
//If: this command is a partial match
if (cmd_index > 0)
{
//If: i was decoding an argument
if (this -> g_status == Parser_status::PARSER_ARG)
{
//If: index is not pointing to an argument descriptor inside the command
if ((UNIPARSER_PENDANTIC_CHECKS) && (this -> g_cmd_txt[t][cmd_index] != '%'))
{
DPRINT("ERR: This command should have an argument descriptor in this position. | cmd: %d | cmd_index: %d | actual content: >0x%x<\n", t, cmd_index, this -> g_cmd_txt[t][cmd_index]);
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
//The argument has been closed. I need to skip the argument descriptor "%?"
cmd_index += 2;
//With argument closed I'm now doing an ID matching for terminator. Can be skipped since it's the last char
this -> g_status = Parser_status::PARSER_ID;
//I should write back the index. Can be skipped since it's the last char
this -> g_cmd_index[t] = cmd_index;
}
//Check match against the character after the one already matched.
//If: the next command data would be the terminator '\0'
if ( this -> g_cmd_txt[t][ cmd_index ] == '\0')
{
//If there is a pending execution already
if ((UNIPARSER_PENDANTIC_CHECKS) && (exe_index != -1))
{
//this should never happen
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
//Issue execution of the callback function linked
exe_index = t;
DPRINT("Valid command ID%d decoded\n", t);
//I can stop the search
t = this -> g_num_cmd;
}
//If: command would keep on going
else
{
DPRINT("%d | no match in %x cmd %x | ", __LINE__ ,data , this -> g_cmd_txt[t][ cmd_index ] );
}
} //End If: this command is a partial match
} //End For: scan all commands
} //end if: I have at least one parser_tmp.id_index entry
//If I have just one match. g_num_match now holds the index of the match shifted by one
else if (this -> g_num_match < 0)
{
//decode command index | BUGFIX: -1 means only one match of command ID 0
t = -this -> g_num_match -1;
DPRINT("just one partial match: %d\n", t);
//Fetch command index
cmd_index = this -> g_cmd_index[t];
//If: i was decoding an argument
if (this -> g_status == Parser_status::PARSER_ARG)
{
//If: index is not pointing to an argument descriptor inside the command
if ((UNIPARSER_PENDANTIC_CHECKS) && (this -> g_cmd_txt[t][cmd_index] != '%'))
{
DPRINT("ERR: This command should have an argument descriptor in this position. | cmd: %d | cmd_index: %d | actual content: >0x%x<\n", t, cmd_index, this -> g_cmd_txt[t][cmd_index]);
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
//The argument has been closed. I need to skip the argument descriptor "%?"
cmd_index += 2;
//With argument closed I'm now doing an ID matching for terminator. Can be skipped since it's the last char
//this -> g_status == Parser_status::PARSER_ID;
}
//BUGFIX: this branch can now be executed with null pointer if dictionary is yet to be initialized. This is not a pedantic check
//Check match against the character after the one already matched.
//If: the next command data would be the terminator '\0'
if ((this -> g_cmd_txt[t] != nullptr) && (this -> g_cmd_txt[t][ cmd_index ] == '\0'))
{
//If there is a pending execution already
if ((UNIPARSER_PENDANTIC_CHECKS) && (exe_index != -1))
{
//this should never happen
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
//Issue execution of the callback function linked
exe_index = t;
DPRINT("%d | Valid command ID%d decoded\n", __LINE__, t);
//I can stop the search
t = this -> g_num_cmd;
}
//BUGFIX: this branch can now be executed with null pointer if dictionary is yet to be initialized. This is not a pedantic check
//if: I'm given a terminator but dictionary does not contain a terminator
else
{
if (this -> g_cmd_txt[t] != nullptr)
{
//This happen if user gives a command that lack one char
DPRINT("%d | no match. given: >0x%x< expected: >0x%x<\n" ,__LINE__, data , this -> g_cmd_txt[t][ cmd_index ] );
}
else
{
//This happen if user gives a command that lack one char
DPRINT("%d | Dictionary entry is nullptr. Maybe dictionary is yet to be initialized? Dictionary entry: %d\n",__LINE__, t );
}
//Issue a FSM reset
f_rst_fsm = true;
} //End if: I'm given a terminator but dictionary does not contain a terminator
} //End If: I have just one match g_num_match now holds the index of the match shifted by one
//If: exactly zero matches.
else
{
DPRINT("%d | No partial matches\n", __LINE__ );
}
//Issue a FSM reset
f_rst_fsm = true;
} //End If: input terminator from user
//--------------------------------------------------------------------------
// PARSER_IDLE
//--------------------------------------------------------------------------
// Only letters can be used as first character in a command
// This section matches the first character in each command
// This section takes care of initializing g_cmd_index[] to valid partial match values
//If: PARSER_IDLE
else if (this -> g_status == Parser_status::PARSER_IDLE)
{
DPRINT("%d | PARSER_IDLE\n", __LINE__);
//If: letter First character in a command can only be a letter
if (IS_LETTER( data ))
{
//counter
uint8_t t;
//for each command
for (t = 0; t < this -> g_num_cmd;t++)
{
//if: dictionary is unlinked
if ((UNIPARSER_PENDANTIC_CHECKS) && (this -> g_cmd_txt[t] == nullptr))
{
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("%d | ERR%d: ERR_GENERIC\n", __LINE__, this -> g_err );
return true; //fail
}
//If: partial match
if (this -> g_cmd_txt[t][0] == data)
{
//A partial match has been found
this -> g_num_match++;
//Match has been found up to first character. Point to the next unmatched char
this -> g_cmd_index[t] = 1;
//Next, I'm matching ID entries
this -> g_status = Parser_status::PARSER_ID;
//TIP: I can't speculatively detect % here because two commands may have the same first section and diverge later.
DPRINT("%d | Match command %d, total partial matches: %d\n", __LINE__, t, this -> g_num_match);
}
//if: no match
else
{
//special code for no match found
this -> g_cmd_index[t] = 0;
}
} //end for: each command
} //End If: letter
//Non letter can never be a first character
else
{
//Issue a FSM reset
f_rst_fsm = true;
}
} //End If: PARSER_IDLE
//--------------------------------------------------------------------------
// ID matching
//--------------------------------------------------------------------------
//if: I'm ID matching
else if (this -> g_status == Parser_status::PARSER_ID)
{
DPRINT("%d | PARSER_ID ", __LINE__);
//! @todo only go ARG if a command has an arg descriptor if there are number or sign. allow number or sign to be used as command ID
//if: I'm being fed an argument
if (IS_NUMBER( data ) || IS_SIGN( data ))
{
DPRINT_NOTAB("- ARG | num_match %d\n", this -> g_num_match);
//if: I have at least one partial match
if (this -> g_num_match > 0)
{
//for each dictionary command
for (uint8_t t = 0;t < this -> g_num_cmd;t++)
{
//if: the command is a partial match
if (this -> g_cmd_index[t] > 0)
{
//Search in the dictionary for a % entry. An argument descriptor
if (this -> g_cmd_txt[t][ this -> g_cmd_index[t] ] == '%')
{
//Do not increment index but go in ARG parsing mode
this -> g_status = Parser_status::PARSER_ARG;
//Do not advance index until argument decoding is complete
DPRINT("%d | ARG begins | command: %d\n", __LINE__, t);
//Add an argument using current partial match as template
bool f_ret = this -> add_arg( t );
//if: adding argument failed
if ((UNIPARSER_PENDANTIC_CHECKS) && (f_ret == true))
{
this -> error_handler( Err_codes::ERR_ADD_ARG );
DPRINT("%d | ERR Failed to add an argument\n", __LINE__ );
//I can recover from this by resetting the FSM
f_rst_fsm = true;
}
//initialize agrument
this -> accumulate_arg( data );
//argument detection make the detection unique. Remove all other partial matches | BUGFIX: now negative index is shifted by one
this -> g_num_match = -t -1;
//Single match has been found. Break the cycle
t = UNIPARSER_MAX_CMD;
}
//If: this dictionary entry does not contain an argument descriptor
else
{
//Prune away the partial match
this -> g_cmd_index[t] = 0;
DPRINT("%d | Prune away partial match: %d | ", __LINE__, t);
//if: I still have partial matches after pruning
if (this -> g_num_match >= 2)
{
//One fewer partial match
this -> g_num_match--;
DPRINT_NOTAB(" num_match: %d\n", this -> g_num_match );
}
//if: all partial matches have been pruned away
else
{
//No more commands. Reset the machine
f_rst_fsm = true;
//No more matches. Can breack cycle early
t = UNIPARSER_MAX_CMD;
DPRINT_NOTAB("%d | Last partial match has been pruned away... RESET\n", __LINE__);
//! @todo command refeed function. Safe and refeed last char to detect other partial commands
}
} //End If: this dictionary entry does not contain an argument descriptor
} //End if: the command is a partial match
//If: this commnd did not match to begin with
else
{
//do nothing
}
} //end for each dictionary command
} //end if: I have at least one partial match
//If I only have one match | BUGFIX: single match is now shifted by one
else if (this -> g_num_match < 0)
{
//decode command index
uint8_t t = -this -> g_num_match -1;
//Search in the dictionary for a % entry. An argument descriptor
if (this -> g_cmd_txt[t][ this -> g_cmd_index[t] ] == '%')
{
//! This is the first char of an argument
//Do not increment index but go in ARG parsing mode
this -> g_status = Parser_status::PARSER_ARG;
//Do not advance index until argument decoding is complete
DPRINT("%d | ARG begins | command: %d\n", __LINE__, t);
//Add an argument using current partial match as template
bool f_ret = this -> add_arg( t );
//if: adding argument failed
if ((UNIPARSER_PENDANTIC_CHECKS) && (f_ret == true))
{
this -> g_err = Err_codes::ERR_GENERIC;
DPRINT("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
//I can recover from this by resetting the FSM
f_rst_fsm = true;
}
//! accumulate argument character inside argument.
f_ret = this -> accumulate_arg( data );
//if: adding argument failed
if ((UNIPARSER_PENDANTIC_CHECKS) && (f_ret == true))
{
this -> g_err = Err_codes::ERR_GENERIC;
DPRINT("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
//I can recover from this by resetting the FSM
f_rst_fsm = true;
}
}
} //If I only have one match
//If: I had no matches to begin with
else
{
//DO nothing
}
} //end if: I'm being fed an argument
//if: I'm matching a non argument non terminator
else
{
DPRINT_NOTAB("- ID\n");
//if: I have at least one partial match
if (this -> g_num_match > 0)
{
//If I have just one match, I can upgrade num_match to skip for next time
bool f_match = (this -> g_num_match == 1);
//for each dictionary command
for (uint8_t t = 0;t < this -> g_num_cmd;t++)
{
//if: the command is a partial match
if (this -> g_cmd_index[t] > 0)
{
//check that the dictionary holds the same value as data
if (this -> g_cmd_txt[t][ this -> g_cmd_index[t] ] == data)
{
//Advance to the next dictionary entry for this command
this -> g_cmd_index[t]++;
//if: This is the sole partial match surviving
if (f_match == true)
{
//Save the index inside num match to skip the for next time | BUGFIX: Now single match is shifted by one
this -> g_num_match = -t -1;
//Single match has been found. Break the cycle
t = UNIPARSER_MAX_CMD;
DPRINT("%d | Only one partial match remains. Num_match: %d\n", __LINE__, this -> g_num_match);
}
}
//Else: this dictionary entry does not contain an argument descriptor
else
{
//Prune away the partial match
this -> g_cmd_index[t] = 0;
DPRINT("%d | Prune away partial match: %d | ", __LINE__, t);
//if: I still have partial matches after pruning
if (this -> g_num_match >= 2)
{
//One fewer partial match
this -> g_num_match--;
DPRINT_NOTAB(" num_match: %d\n", this -> g_num_match );
}
//if: all partial matches have been pruned away
else
{
//No more commands. Reset the machine
f_rst_fsm = true;
//No more matches. Can breack cycle early
t = UNIPARSER_MAX_CMD;
DPRINT_NOTAB("Last partial match has been pruned away... RESET\n");
//! @todo replay system. Safe and refeed last char to detect other partial commands
}
}
} //End if: the command is a partial match
//if: the command was pruned away long ago
else
{
//do nothing
}
} //end for each dictionary command
} //end if: I have at least one partial match
//BUGFIX: If the only match is also entry 0
//If I only have one match
else //if (this -> g_num_match <= 0)
{
//decode command index | BUGFIX: Now single match is shifted by one
uint8_t t = -this -> g_num_match -1;
//check that the dictionary holds the same value as data
if (this -> g_cmd_txt[t][ this -> g_cmd_index[t] ] == data)
{
//Match! Scan next entry
this -> g_cmd_index[t]++;
DPRINT("%d | Match still valid...\n", __LINE__);
}
//no match
else
{
//Last partial match has been pruned away. Issue a FSM reset
f_rst_fsm = true;
DPRINT("%d | Last match was pruned away. Expected >0x%x< got >0x%x< instead\n", __LINE__, this -> g_cmd_txt[t][ this -> g_cmd_index[t] ], data);
}
} //If I only have one match
} //end if: I'm matching a non argument non terminator
} //end if: I'm ID matching
//--------------------------------------------------------------------------
// ARG decoder
//--------------------------------------------------------------------------
//if: I'm decoding arguments
else if (this -> g_status == Parser_status::PARSER_ARG)
{
DPRINT("%d | PARSER_ARG\n", __LINE__);
//If: I'm fed a number
if (IS_NUMBER(data))
{
//! accumulate argument character inside argument.
bool f_ret = this -> accumulate_arg( data );
//if: adding argument failed
if ((UNIPARSER_PENDANTIC_CHECKS) && (f_ret == true))
{
this -> g_err = Err_codes::ERR_GENERIC;
DPRINT("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
//I can recover from this by resetting the FSM
f_rst_fsm = true;
}
//Do not advance to next dictionary entry
} //If: I'm fed a number
//if: I'm fed a non number
else
{
DPRINT("Closing argument\n");
//! Exit argument mode
//Close current argument and update argument FSM
this -> close_arg();
//BUGFIX: If the only match is also entry 0
//if: I have multiple matches. I should have just one match by this point.
if ((UNIPARSER_PENDANTIC_CHECKS) && (this -> g_num_match > 0))
{
this -> g_err = Err_codes::ERR_GENERIC;
DPRINT("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
//I can recover from this by resetting the FSM
f_rst_fsm = true;
}
else
{
//After argument, I can only have one match. | BUGFIX: Now single match is shifted by one
uint8_t cmd_id = -this -> g_num_match -1;
//Update the parser index by skipping % and the argument descriptor
this -> g_cmd_index[ cmd_id ] += 2;
uint8_t u8_index = this -> g_cmd_index[ cmd_id ];
//Get the next cmd match
uint8_t u8_next_cmd_id = this -> g_cmd_txt[ cmd_id ][ u8_index ];
DPRINT("%d | Expected CMD ID %d | Got CMD ID %d\n", __LINE__, this -> g_cmd_txt[ cmd_id ][ u8_index ], data);
//check that the dictionary holds the same value as data
if (u8_next_cmd_id == data)
{
//Advance to the next dictionary entry for this command
this -> g_cmd_index[ cmd_id ]++;
}
//No match
else
{
DPRINT("%d | Pruning away last match\n", __LINE__ );
//I can recover from this by resetting the FSM
f_rst_fsm = true;
}
this -> g_status = Parser_status::PARSER_ID;
}
} //if: I'm fed a non number
} //if: I'm decoding arguments
//----------------------------------------------------------------
// FSM RESET
//----------------------------------------------------------------
//! @detail
//! FSM reset. Clear up the machine for the next clean execution
//If: a reset was issued
if (f_rst_fsm == true)
{
DPRINT("%d | FSM RESET\n", __LINE__);
//Clear reset flag
f_rst_fsm = false;
//Status becomes IDLE
this -> g_status = Orangebot::Parser_status::PARSER_IDLE;
//I have no partial matches anymore
this -> g_num_match = 0;
//If I don't have a pending execution
if (exe_index == -1)
{
//Reset the argument decoder and prepare for a new command
this -> init_arg_decoder();
}
} //If: a reset was issued
//----------------------------------------------------------------
// HANDLER EXECUTION
//----------------------------------------------------------------
//! @detail
//! FSM reset. Clear up the machine for the next clean execution
//If: an execution event has been launched
if (exe_index > -1)
{
//if execution index is out of range.
if ((UNIPARSER_PENDANTIC_CHECKS) && (exe_index == this -> g_num_cmd))
{
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
DPRINT("%d | Executing handler of command %d | num arguments: %d\n", __LINE__, exe_index, this -> g_arg_fsm_status.num_arg);
//Execute handler of given function. Automatically deduce arguments from argument vector
this -> execute_callback( this ->g_cmd_handler[exe_index] );
//Reset the argument decoder and prepare for a new command
this -> init_arg_decoder();
} //If: a reset was issued
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
//Trace Return from main
DRETURN_ARG("Err_code: %d\n", this -> g_err);
//Inform the caller that an error occurred
return (this -> g_err != Err_codes::NO_ERR);
} //end method: parse | char
/****************************************************************************
*****************************************************************************
** PUBLIC STATIC METHODS
*****************************************************************************
****************************************************************************/
/****************************************************************************
*****************************************************************************
** PRIVATE METHODS
*****************************************************************************
****************************************************************************/
/***************************************************************************/
//! @brief Private Method
//! init | void
/***************************************************************************/
//! @return no return
//! @details
//! initialize structure
/***************************************************************************/
inline void Uniparser::init( void )
{
DENTER();
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//counter
uint8_t t;
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//! @details initialize structure
//No commands are currently loaded inside the parser
this -> g_num_cmd = 0;
//for: each possible command
for (t = 0;t < UNIPARSER_MAX_CMD;t++)
{
//command has no txt identifier linked
this -> g_cmd_txt[t] = nullptr;
//command has no function handler linked
this -> g_cmd_handler[t] = nullptr;
}
//I have no partial matches
this -> g_num_match = 0;
//FSM begins in idle
this -> g_status = Orangebot::Parser_status::PARSER_IDLE;
//No error
this -> g_err = Orangebot::Err_codes::NO_ERR;
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
//Trace Return from main
DRETURN();
return; //OK
} //end method: init | void
/***************************************************************************/
//! @brief Private Method
//! init_arg_decoder | void
/***************************************************************************/
//! @details
//! initialize argument decoder for a new command
/***************************************************************************/
inline void Uniparser::init_arg_decoder( void )
{
//Trace Enter with arguments
DENTER();
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//! @details algorithm:
//Prepare the argument descriptor. zero arguments are in store
this -> g_arg_fsm_status.num_arg = 0;
//First free slot in the argument vector is the first byte
this -> g_arg_fsm_status.arg_index = 0;
//if sign is not specified, default argument sign is plus
this -> g_arg_fsm_status.arg_sign = false;
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
//Trace Return vith return value
DRETURN();
return; //OK
} //end method: init_arg_decoder | void
/***************************************************************************/
//! @brief Private Method
//! chk_cmd | const uint8_t *
/***************************************************************************/
//! @param cmd |
//! @return syntax error | bool | false: OK | true: error detected. Code handled by the error handler
//! @details
//! Check command syntax to prevent bad commands from being loaded in the dictionary
//! Saves runtime check for bad dictionary entries
/***************************************************************************/
bool Uniparser::chk_cmd( const uint8_t *cmd )
{
//Trace Enter with arguments
DENTER_ARG("cmd: %p\n", (void *)cmd);
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//Counter
uint8_t t;
//Total argument size used
uint8_t arg_cnt = 0;
//Number of arguments
uint8_t arg_type_cnt = 0;
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//If a null pointer function handler was given
if (cmd == nullptr)
{
this -> error_handler( Err_codes::SYNTAX_BAD_POINTER );
DRETURN_ARG("ERR%d: | Bad handler function pointer\n", Err_codes::SYNTAX_BAD_POINTER);
return true; //FAIL
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//if: first char is not a letter
if (!IS_LETTER( cmd[0] ))
{
this -> error_handler( Err_codes::SYNTAX_FIRST_NOLETTER );
DRETURN_ARG("ERR%d | First character of a command must be a letter\n", Err_codes::SYNTAX_FIRST_NOLETTER);
return true; //FAIL
}
//Initialize counter
t = 1;
//While: parsing is not done
while ((cmd[t] != '\0') && (t < UNIPARSER_MAX_CMD_LENGTH))
{
//if: argument descriptor
if (cmd[t] == '%')
{
//!Check number of arguments
//i have an argument descriptor
arg_type_cnt++;
//if: exceed number of arguments
if (arg_type_cnt > UNIPARSER_MAX_ARGS)
{
this -> error_handler( Err_codes::SYNTAX_TOO_MANY_ARGS );
DRETURN_ARG("ERR%d in line %d | too many arguments in this command %d\n", Err_codes::SYNTAX_TOO_MANY_ARGS, __LINE__, arg_type_cnt);
return true; //FAIL
}
//!Check back to back arguments
//if: two arguments back to back
if ( (t >= 2) && (cmd[t -2] == '%') )
{
this -> error_handler( Err_codes::SYNTAX_ARG_BACKTOBACK );
DRETURN_ARG("ERR%d in line %d | Two back to back arguments were given. Add a character in between them\n", Err_codes::SYNTAX_ARG_BACKTOBACK, __LINE__);
return true; //FAIL
}
//!Check total size of arguments
//Skip the argument descriptor
t++;
//Switch: argument type
switch( cmd[t] )
{
//Decode type
case Arg_type::ARG_U8:
{
//Accumulate
arg_cnt += Arg_size::ARG_U8_SIZE;
break;
}
//Decode type
case Arg_type::ARG_S8:
{
//Accumulate
arg_cnt += Arg_size::ARG_S8_SIZE;
break;
}
//Decode type
case Arg_type::ARG_U16:
{
//Accumulate
arg_cnt += Arg_size::ARG_U16_SIZE;
break;
}
//Decode type
case Arg_type::ARG_S16:
{
//Accumulate
arg_cnt += Arg_size::ARG_S16_SIZE;
break;
}
//Decode type
case Arg_type::ARG_U32:
{
//Accumulate
arg_cnt += Arg_size::ARG_U32_SIZE;
break;
}
//Decode type
case Arg_type::ARG_S32:
{
//Accumulate
arg_cnt += Arg_size::ARG_S32_SIZE;
break;
}
default:
{
this -> error_handler( Err_codes::SYNTAX_ARG_TYPE_INVALID );
DRETURN_ARG("ERR%d in line %d | Invalid argument descriptor %x\n", Err_codes::SYNTAX_ARG_TYPE_INVALID , __LINE__, cmd[t]);
return true; //FAIL
}
} //End Switch: argument type
//Check size
if (arg_cnt > UNIPARSER_ARG_VECTOR_SIZE)
{
this -> error_handler( Err_codes::SYNTAX_ARG_LENGTH );
DRETURN_ARG("ERR%d in line %d | Invalid argument descriptor %x\n", Err_codes::SYNTAX_ARG_LENGTH , __LINE__, cmd[t]);
return true; //FAIL
}
} //End if: argument descriptor
//Parse next byte
t++;
} //End While: parsing is not done
//If command size has been exceeded
if (t >= UNIPARSER_MAX_CMD_LENGTH)
{
this -> error_handler( Err_codes::SYNTAX_LENGTH );
DRETURN_ARG("ERR%d in line %d | Given command was too long %d\n", Err_codes::SYNTAX_LENGTH , __LINE__, t);
return true; //FAIL
}
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
DRETURN();
return false; //OK
} //end method: chk_cmd | const uint8_t *
/***************************************************************************/
//! @brief Private Method
//! set_arg<uint8_t> | uint8_t
/***************************************************************************/
//! @param arg | T | numeric value of the argument to be recorded inside the general argument vector
//! @return bool | false: OK | true: argument exceed the alloted arg vector space
//! @details
//! Template based add_arg method to add the numeric value of the argument to be recorded inside the general argument vector \n
//! Each method is specialized for each supported type, while leaving space for standard or custom types to be added \n
//! It is much cleaner than encoding the type inside the name of the function and takes advantage of C++ constructs
/***************************************************************************/
template <>
inline bool Uniparser::set_arg<uint8_t>( uint8_t arg_index, uint8_t arg )
{
//Trace Enter
DENTER_ARG( "argument: %d\n", arg );
///--------------------------------------------------------------------------
/// VARS
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
/// INIT
///--------------------------------------------------------------------------
//If: add_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_U8_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: add_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return true;
}
///--------------------------------------------------------------------------
/// BODY
///--------------------------------------------------------------------------
//Save the numeric value of the argument
this -> g_arg[ arg_index ] = (uint8_t)arg;
///--------------------------------------------------------------------------
/// RETURN
///--------------------------------------------------------------------------
//Trace Return
DRETURN_ARG("Index: %d | Binary: %3x\n", arg_index, (uint8_t)this -> g_arg[arg_index +0] );
return false; //OK
} //end method: set_arg<uint8_t> | uint8_t
/***************************************************************************/
//! @brief Public Method
//! set_arg<uint8_t> | uint8_t
/***************************************************************************/
//! @param arg | T | numeric value of the argument to be recorded inside the general argument vector
//! @return bool | false: OK | true: argument exceed the alloted arg vector space
//! @details
//! Template based set_arg method to add the numeric value of the argument to be recorded inside the general argument vector \n
//! Each method is specialized for each supported type, while leaving space for standard or custom types to be added \n
//! It is much cleaner than encoding the type inside the name of the function and takes advantage of C++ constructs
/***************************************************************************/
template <>
inline bool Uniparser::set_arg<int8_t>( uint8_t arg_index, int8_t arg )
{
//Trace Enter
DENTER_ARG( "argument: %d\n", arg );
///--------------------------------------------------------------------------
/// VARS
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
/// INIT
///--------------------------------------------------------------------------
//If: add_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_S8_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: add_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return true;
}
///--------------------------------------------------------------------------
/// BODY
///--------------------------------------------------------------------------
//Link pointer to the correct data type
int8_t *arg_ptr = ARG_CAST( arg_index, int8_t );
//Save the numeric value of the argument
*arg_ptr = (int8_t)arg;
///--------------------------------------------------------------------------
/// RETURN
///--------------------------------------------------------------------------
//Trace Return
DRETURN_ARG("Index: %d | Binary: %3x\n", arg_index, (uint8_t)this -> g_arg[arg_index +0] );
return false; //OK
} //end method: set_arg<int8_t> | int8_t
/***************************************************************************/
//! @brief Public Method
//! set_arg<uint16_t> | uint16_t
/***************************************************************************/
//! @param arg | T | numeric value of the argument to be recorded inside the general argument vector
//! @return bool | false: OK | true: argument exceed the alloted arg vector space
//! @details
//! Template based add_arg method to add the numeric value of the argument to be recorded inside the general argument vector \n
//! Each method is specialized for each supported type, while leaving space for standard or custom types to be added \n
//! It is much cleaner than encoding the type inside the name of the function and takes advantage of C++ constructs
/***************************************************************************/
template <>
inline bool Uniparser::set_arg<uint16_t>( uint8_t arg_index, uint16_t arg )
{
//Trace Enter
DENTER_ARG( "argument: %d\n", arg );
///--------------------------------------------------------------------------
/// VARS
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
/// INIT
///--------------------------------------------------------------------------
//If: add_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_U16_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: add_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return true;
}
///--------------------------------------------------------------------------
/// BODY
///--------------------------------------------------------------------------
//Link pointer to the correct data type
uint16_t *arg_ptr = ARG_CAST( arg_index, uint16_t );
//Save the numeric value of the argument
*arg_ptr = (uint16_t)arg;
///--------------------------------------------------------------------------
/// RETURN
///--------------------------------------------------------------------------
//Trace Return
DRETURN_ARG("Index: %d | Binary: %3x %3x\n", arg_index, (uint8_t)this -> g_arg[arg_index +0], (uint8_t)this -> g_arg[arg_index +1] );
return false; //OK
} //end method: set_arg<uint16_t> | uint16_t
/***************************************************************************/
//! @brief Public Method
//! set_arg<int16_t> | int16_t
/***************************************************************************/
//! @param arg | T | numeric value of the argument to be recorded inside the general argument vector
//! @return bool | false: OK | true: argument exceed the alloted arg vector space
//! @details
//! Template based add_arg method to add the numeric value of the argument to be recorded inside the general argument vector \n
//! Each method is specialized for each supported type, while leaving space for standard or custom types to be added \n
//! It is much cleaner than encoding the type inside the name of the function and takes advantage of C++ constructs
/***************************************************************************/
template <>
inline bool Uniparser::set_arg<int16_t>( uint8_t arg_index, int16_t arg )
{
//Trace Enter
DENTER_ARG( "argument: %d\n", arg );
///--------------------------------------------------------------------------
/// VARS
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
/// INIT
///--------------------------------------------------------------------------
//If: set_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_S16_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: set_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return true;
}
///--------------------------------------------------------------------------
/// BODY
///--------------------------------------------------------------------------
//Link pointer to the correct data type
int16_t *arg_ptr = ARG_CAST( arg_index, int16_t );
//Save the numeric value of the argument
*arg_ptr = (int16_t)arg;
///--------------------------------------------------------------------------
/// RETURN
///--------------------------------------------------------------------------
//Trace Return
DRETURN_ARG("Index: %d | Binary: %3x %3x\n", arg_index, (uint8_t)this -> g_arg[arg_index +0], (uint8_t)this -> g_arg[arg_index +1] );
return false; //OK
} //end method: set_arg<int16_t> | int16_t
/***************************************************************************/
//! @brief Public Method
//! set_arg<uint32_t> | uint32_t
/***************************************************************************/
//! @param arg | T | numeric value of the argument to be recorded inside the general argument vector
//! @return bool | false: OK | true: argument exceed the alloted arg vector space
//! @details
//! Template based set_arg method to add the numeric value of the argument to be recorded inside the general argument vector \n
//! Each method is specialized for each supported type, while leaving space for standard or custom types to be added \n
//! It is much cleaner than encoding the type inside the name of the function and takes advantage of C++ constructs
/***************************************************************************/
template <>
inline bool Uniparser::set_arg<uint32_t>( uint8_t arg_index, uint32_t arg )
{
//Trace Enter
DENTER_ARG( "argument: %d\n", arg );
///--------------------------------------------------------------------------
/// VARS
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
/// INIT
///--------------------------------------------------------------------------
//If: add_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_U32_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: set_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return true;
}
///--------------------------------------------------------------------------
/// BODY
///--------------------------------------------------------------------------
//Link pointer to the correct data type
uint32_t *arg_ptr = ARG_CAST( arg_index, uint32_t );
//Save the numeric value of the argument
*arg_ptr = (uint32_t)arg;
///--------------------------------------------------------------------------
/// RETURN
///--------------------------------------------------------------------------
//Trace Return
DRETURN_ARG("Index: %d | Binary: %3x %3x %3x %3x\n", arg_index, (uint8_t)this -> g_arg[arg_index +0], (uint8_t)this -> g_arg[arg_index +1], (uint8_t)this -> g_arg[arg_index +2], (uint8_t)this -> g_arg[arg_index +3] );
return false; //OK
} //end method: set_arg<int32_t> | int32_t
/***************************************************************************/
//! @brief Public Method
//! set_arg<int32_t> | int32_t
/***************************************************************************/
//! @param arg | T | numeric value of the argument to be recorded inside the general argument vector
//! @return bool | false: OK | true: argument exceed the alloted arg vector space
//! @details
//! Template based set_arg method to add the numeric value of the argument to be recorded inside the general argument vector \n
//! Each method is specialized for each supported type, while leaving space for standard or custom types to be added \n
//! It is much cleaner than encoding the type inside the name of the function and takes advantage of C++ constructs
/***************************************************************************/
template <>
inline bool Uniparser::set_arg<int32_t>( uint8_t arg_index, int32_t arg )
{
//Trace Enter
DENTER_ARG( "argument: %d\n", arg );
///--------------------------------------------------------------------------
/// VARS
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
/// INIT
///--------------------------------------------------------------------------
//If: add_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_S32_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: set_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return true;
}
///--------------------------------------------------------------------------
/// BODY
///--------------------------------------------------------------------------
//Link pointer to the correct data type
int32_t *arg_ptr = ARG_CAST( arg_index, int32_t );
//Save the numeric value of the argument
*arg_ptr = (int32_t)arg;
///--------------------------------------------------------------------------
/// RETURN
///--------------------------------------------------------------------------
//Trace Return
DRETURN_ARG("Index: %d | Binary: %3x %3x %3x %3x\n", arg_index, (uint8_t)this -> g_arg[arg_index +0], (uint8_t)this -> g_arg[arg_index +1], (uint8_t)this -> g_arg[arg_index +2], (uint8_t)this -> g_arg[arg_index +3] );
return false; //OK
} //end method: set_arg<int32_t> | int32_t
/***************************************************************************/
//! @brief Private Method
//! get_arg<uint8_t> | uint8_t
/***************************************************************************/
//! @param arg_index | point to an argument inside the argument vector
//! @return decoded content of argument vector at given position
//! @details
//! fetch the numeric value of an argument from the argument vector
/***************************************************************************/
template <>
inline uint8_t Uniparser::get_arg( uint8_t arg_index )
{
DENTER_ARG("arg_index: %d\n", arg_index );
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//If: add_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_U8_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: add_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return (uint8_t)0xff;
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Link the pointer to the actual content
uint8_t *arg_ptr = &this -> g_arg[arg_index];
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
DRETURN_ARG("Decoded: %d\n", *arg_ptr);
return *arg_ptr; //OK
} //end method: get_arg<uint8_t> | uint8_t
/***************************************************************************/
//! @brief Private Method
//! get_arg<int8_t> | uint8_t
/***************************************************************************/
//! @param arg_index | point to an argument inside the argument vector
//! @return decoded content of argument vector at given position
//! @details
//! fetch the numeric value of an argument from the argument vector
/***************************************************************************/
template <>
inline int8_t Uniparser::get_arg( uint8_t arg_index )
{
DENTER_ARG("arg_index: %d\n", arg_index );
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//If: add_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_S8_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: add_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return (uint8_t)0xff;
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Link the pointer to the actual content
int8_t *arg_ptr = ARG_CAST( arg_index, int8_t);
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
DRETURN_ARG("Decoded: %d\n", *arg_ptr);
return *arg_ptr; //OK
} //end method: get_arg<int8_t> | uint8_t
/***************************************************************************/
//! @brief Private Method
//! get_arg<uint16_t> | uint8_t
/***************************************************************************/
//! @param arg_index | point to an argument inside the argument vector
//! @return decoded content of argument vector at given position
//! @details
//! fetch the numeric value of an argument from the argument vector
/***************************************************************************/
template <>
inline uint16_t Uniparser::get_arg( uint8_t arg_index )
{
DENTER_ARG("arg_index: %d\n", arg_index );
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//If: add_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_U16_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: add_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return (uint8_t)0xff;
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Link the pointer to the actual content
uint16_t *arg_ptr = ARG_CAST( arg_index, uint16_t);
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
DRETURN_ARG("Decoded: %d\n", *arg_ptr);
return *arg_ptr; //OK
} //end method: get_arg<uint16_t> | uint8_t
/***************************************************************************/
//! @brief Private Method
//! get_arg<int16_t> | uint8_t
/***************************************************************************/
//! @param arg_index | point to an argument inside the argument vector
//! @return decoded content of argument vector at given position
//! @details
//! fetch the numeric value of an argument from the argument vector
/***************************************************************************/
template <>
inline int16_t Uniparser::get_arg( uint8_t arg_index )
{
DENTER_ARG("arg_index: %d\n", arg_index );
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//If: add_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_S16_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: add_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return (uint8_t)0xff;
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Link the pointer to the actual content
int16_t *arg_ptr = ARG_CAST( arg_index, int16_t);
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
DRETURN_ARG("Decoded: %d\n", *arg_ptr);
return *arg_ptr; //OK
} //end method: get_arg<int16_t> | uint8_t
/***************************************************************************/
//! @brief Private Method
//! get_arg<uint32_t> | uint8_t
/***************************************************************************/
//! @param arg_index | point to an argument inside the argument vector
//! @return decoded content of argument vector at given position
//! @details
//! fetch the numeric value of an argument from the argument vector
/***************************************************************************/
template <>
inline uint32_t Uniparser::get_arg( uint8_t arg_index )
{
DENTER_ARG("arg_index: %d\n", arg_index );
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//If: add_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_U32_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: add_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return (uint8_t)0xff;
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Link the pointer to the actual content
uint32_t *arg_ptr = ARG_CAST( arg_index, uint32_t);
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
DRETURN_ARG("Decoded: %d\n", *arg_ptr);
return *arg_ptr; //OK
} //end method: get_arg<uint32_t> | uint8_t
/***************************************************************************/
//! @brief Private Method
//! get_arg<int32_t> | uint8_t
/***************************************************************************/
//! @param arg_index | point to an argument inside the argument vector
//! @return decoded content of argument vector at given position
//! @details
//! fetch the numeric value of an argument from the argument vector
/***************************************************************************/
template <>
inline int32_t Uniparser::get_arg( uint8_t arg_index )
{
DENTER_ARG("arg_index: %d\n", arg_index );
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//If: add_arg would exceed the maximum allowed argument vector size
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_index > UNIPARSER_ARG_VECTOR_SIZE -ARG_S32_SIZE))
{
//Trace Return
DRETURN_ARG("ERR: add_arg would exceed the maximum allowed argument vector size | max: %d | current: %d\n", UNIPARSER_ARG_VECTOR_SIZE, arg_index);
this -> error_handler( Err_codes::ERR_ARG_SIZE );
return (uint8_t)0xff;
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Link the pointer to the actual content
int32_t *arg_ptr = ARG_CAST( arg_index, int32_t);
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
DRETURN_ARG("Decoded: %d\n", *arg_ptr);
return *arg_ptr; //OK
} //end method: get_arg<int32_t> | uint8_t
/***************************************************************************/
//! @brief Private Method
//! add_arg | uint8_t
/***************************************************************************/
//! @param cmd_id | index of the command the argument is inferred from
//! @return false: ok | true: fail
//! @details
//! Add an argument to the parser argument storage.
//! It expect the command to be a partial match and the index to be pointing to '%'
//! The command is added to the class argument storage string in the format
//! 'u' data0 ... data 1
/***************************************************************************/
bool Uniparser::add_arg( uint8_t cmd_id )
{
//Trace Enter with arguments
DENTER_ARG("command index: %d\n", cmd_id);
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//return
bool f_ret = false;
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//If input index is out of range
if ((UNIPARSER_PENDANTIC_CHECKS) && (cmd_id > this -> g_num_cmd) )
{
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
//Fetch index inside the command
uint8_t cmd_index = this -> g_cmd_index[ cmd_id ];
//if: the command is not an argument
if ((UNIPARSER_PENDANTIC_CHECKS) && (this -> g_cmd_txt[cmd_id][ cmd_index ] != '%'))
{
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
//Point to the argument type
cmd_index++;
//if: the command is not an argument descriptor. PEDANTIC because dictionary should have been checked before hand
if ((UNIPARSER_PENDANTIC_CHECKS) && (!IS_ARG_DESCRIPTOR(this -> g_cmd_txt[cmd_id][ cmd_index ])) )
{
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//! @details algorithm:
//! Compute index to argument vector and number of arguments
//! Compute
//! ARG Index points to first free slot in the argument vector
//! I save argument type and initialize the content
//! Initialize argument identifier
//argument descriptor is held in the dictionary
Arg_type arg_type = (Arg_type)this -> g_cmd_txt[cmd_id][cmd_index];
//Fetch index to the next free argument slot
uint8_t arg_type_index = this -> g_arg_fsm_status.num_arg;
//Store argument type in the argument type vector
this -> g_arg_type[ arg_type_index ] = arg_type;
//A new argument is being added. Reset the argument sign (@TODO: do this earlier)
this -> g_arg_fsm_status.arg_sign = false;
//fetch argument index
uint8_t arg_index = this -> g_arg_fsm_status.arg_index;
DPRINT("argument of type >%c< added | Num arguments: %d | Arg index: %d | Arg sign %c \n", arg_type, this -> g_arg_fsm_status.num_arg, arg_index, (this -> g_arg_fsm_status.arg_sign)?('-'):('+') );
//! Initialize argument content
//switch: decode argument desriptor
switch (arg_type)
{
case Arg_type::ARG_U8:
{
//Write zero inside the argument
f_ret = this -> set_arg<uint8_t>( arg_index, (uint8_t)0 );
break;
}
case Arg_type::ARG_S8:
{
//Write zero inside the argument
f_ret = this -> set_arg<int8_t>( arg_index, (int8_t)0 );
break;
}
case Arg_type::ARG_U16:
{
//Write zero inside the argument
f_ret = this -> set_arg<uint16_t>( arg_index, (uint16_t)0 );
break;
}
case Arg_type::ARG_S16:
{
//Write zero inside the argument
f_ret = this -> set_arg<int16_t>( arg_index, (int16_t)0 );
break;
}
case Arg_type::ARG_U32:
{
//Write zero inside the argument
f_ret = this -> set_arg<uint32_t>( arg_index, (uint32_t)0 );
break;
}
case Arg_type::ARG_S32:
{
//Write zero inside the argument
f_ret = this -> set_arg<int32_t>( arg_index, (int32_t)0 );
break;
}
//if: type is not handled
default:
{
this -> error_handler( Err_codes::ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d\n", __LINE__, arg_type_index);
return true; //FAIL
}
} //end switch: decode argument desriptor
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
//Trace Return vith return value
DRETURN_ARG("Success: %x\n", f_ret);
return f_ret; //OK
} //end method: add_arg | uint8_t
/***************************************************************************/
//! @brief Private Method
//! accumulate_arg | uint8_t
/***************************************************************************/
//! @param data | input character to be decoded. It should be a number or a sign
//! @return false: ok | true: fail
//! @details
//! decode an input character and accumulate it into the argument vector
/***************************************************************************/
bool Uniparser::accumulate_arg( uint8_t data )
{
//Trace Enter with arguments
DENTER_ARG("data >%c<\n", data);
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//detect failure state
bool f_ret;
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//Fetch argument index
uint8_t arg_index = this -> g_arg_fsm_status.arg_index;
//Fetch argument type index
uint8_t arg_type_index = this -> g_arg_fsm_status.num_arg;
//If argument descriptor is bad
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_type_index >= UNIPARSER_MAX_ARGS))
{
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d | Num args: %x\n", this -> g_err, __LINE__, arg_type_index );
return true; //fail
}
//Fetch argument type
Arg_type arg_type = (Arg_type)this->g_arg_type[arg_type_index];
//If argument descriptor is bad
if ((UNIPARSER_PENDANTIC_CHECKS) && (!IS_ARG_DESCRIPTOR(arg_type)))
{
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d | Arg_type: %x\n", this -> g_err, __LINE__, arg_type );
return true; //fail
}
//If: input char is bad
if ((UNIPARSER_PENDANTIC_CHECKS) && (!IS_SIGN(data)) && (!IS_NUMBER(data)))
{
DPRINT("ERR: bad input char. Expecting number or sign and got >0x%x< instead\n", data);
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//!Detect sign
//if sign
if (IS_SIGN(data))
{
//If sign is minus, argument sign is true which means minus
this -> g_arg_fsm_status.arg_sign = (data == '-');
DRETURN();
//I'm done updating argument for now. Next round will come actual numbers.
return false;
}
//!Decode numeric value
//decode the argument descriptor
switch (arg_type)
{
//if: the command expects a uint8_t data
case (Arg_type::ARG_U8):
{
//Fetch old argument
uint8_t old = this -> get_arg<uint8_t>( arg_index );
//Shift by one digit left
old *= 10;
//If number is positive
if (this -> g_arg_fsm_status.arg_sign == false)
{
//Accumulate new digit
old += data -'0';
}
//if: number is negative
else
{
//Accumulate new digit
old -= data -'0';
}
//Write back argument inside argument vector
f_ret = this -> set_arg<uint8_t>( arg_index, old );
//If set arg failed
if (f_ret == true)
{
return true;
}
DPRINT("Updated argument with value: %d | index: %d\n", old, arg_index);
break;
}
//if: the command expects a uint8_t data
case (Arg_type::ARG_S8):
{
//Fetch old argument
int8_t old = this -> get_arg<int8_t>( arg_index );
//Shift by one digit left
old *= 10;
//If number is positive
if (this -> g_arg_fsm_status.arg_sign == false)
{
//Accumulate new digit
old += data -'0';
}
//if: number is negative
else
{
//Accumulate new digit
old -= data -'0';
}
//Write back argument inside argument vector
f_ret = this -> set_arg<int8_t>( arg_index, old );
//If set arg failed
if (f_ret == true)
{
return true;
}
DPRINT("Updated argument with value: %d | index: %d\n", old, arg_index);
break;
}
//if: the command expects a uint8_t data
case (Arg_type::ARG_U16):
{
//Fetch old argument
uint16_t old = this -> get_arg<uint16_t>( arg_index );
//Shift by one digit left
old *= 10;
//If number is positive
if (this -> g_arg_fsm_status.arg_sign == false)
{
//Accumulate new digit
old += data -'0';
}
//if: number is negative
else
{
//Accumulate new digit
old -= data -'0';
}
//Write back argument inside argument vector
f_ret = this -> set_arg<uint16_t>( arg_index, old );
//If set arg failed
if (f_ret == true)
{
return true;
}
DPRINT("Updated argument with value: %d | index: %d\n", old, arg_index);
break;
}
//if: the command expects a uint8_t data
case (Arg_type::ARG_S16):
{
//Fetch old argument
int16_t old = this -> get_arg<int16_t>( arg_index );
//Shift by one digit left
old *= 10;
//If number is positive
if (this -> g_arg_fsm_status.arg_sign == false)
{
//Accumulate new digit
old += data -'0';
}
//if: number is negative
else
{
//Accumulate new digit
old -= data -'0';
}
//Write back argument inside argument vector
f_ret = this -> set_arg<int16_t>( arg_index, old );
//If set arg failed
if (f_ret == true)
{
return true;
}
DPRINT("Updated argument with value: %d | index: %d\n", old, arg_index);
break;
}
//if: the command expects a uint8_t data
case (Arg_type::ARG_U32):
{
//Fetch old argument
uint32_t old = this -> get_arg<uint32_t>( arg_index );
//Shift by one digit left
old *= 10;
//If number is positive
if (this -> g_arg_fsm_status.arg_sign == false)
{
//Accumulate new digit
old += data -'0';
}
//if: number is negative
else
{
//Accumulate new digit
old -= data -'0';
}
//Write back argument inside argument vector
f_ret = this -> set_arg<uint32_t>( arg_index, old );
//If set arg failed
if (f_ret == true)
{
return true;
}
DPRINT("Updated argument with value: %d | index: %d\n", old, arg_index);
break;
}
//if: the command expects a uint8_t data
case (Arg_type::ARG_S32):
{
//Fetch old argument
int32_t old = this -> get_arg<int32_t>( arg_index );
//Shift by one digit left
old *= 10;
//If number is positive
if (this -> g_arg_fsm_status.arg_sign == false)
{
//Accumulate new digit
old += data -'0';
}
//if: number is negative
else
{
//Accumulate new digit
old -= data -'0';
}
//Write back argument inside argument vector
f_ret = this -> set_arg<int32_t>( arg_index, old );
//If set arg failed
if (f_ret == true)
{
return true;
}
DPRINT("Updated argument with value: %d | index: %d\n", old, arg_index);
break;
}
//Unrecognized argument descriptor in the dictionary
default:
{
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
}
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
//Trace Return vith return value
DRETURN();
return false; //OK
} //end method: accumulate_arg | uint8_t
/***************************************************************************/
//! @brief Private Method
//! close_arg | void
/***************************************************************************/
//! @return false: OK | true: fail
//! @details
//! Argument has been fully decoded into argument string. Update argument descriptor FSM.
/***************************************************************************/
bool Uniparser::close_arg( void )
{
//Trace Enter with arguments
DENTER();
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//Fetch argument index
uint8_t arg_index = this -> g_arg_fsm_status.arg_index;
//Fetch argument type index
uint8_t arg_type_index = this -> g_arg_fsm_status.num_arg;
//If argument descriptor is bad
if ((UNIPARSER_PENDANTIC_CHECKS) && (arg_type_index >= UNIPARSER_MAX_ARGS))
{
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d | Num args: %x\n", this -> g_err, __LINE__, arg_type_index );
return true; //fail
}
//Fetch argument type
Arg_type arg_type = (Arg_type)this->g_arg_type[arg_type_index];
//If argument descriptor is bad
if ((UNIPARSER_PENDANTIC_CHECKS) && (!IS_ARG_DESCRIPTOR(arg_type)))
{
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d | Arg_type: %x\n", this -> g_err, __LINE__, arg_type );
return true; //fail
}
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//! Advance the argument index to the first free byte in the argument vector
//If: one byte argument
if ((arg_type == Arg_type::ARG_U8) || (arg_type == Arg_type::ARG_S8))
{
//Skip the argument descriptor and the argument itself
arg_index += Arg_size::ARG_S8_SIZE;
}
//If: two bytes argument
else if ((arg_type == Arg_type::ARG_U16) || (arg_type == Arg_type::ARG_S16))
{
//Skip the argument descriptor and the argument itself
arg_index += Arg_size::ARG_S16_SIZE;
}
//If: four bytes argument
else if ((arg_type == Arg_type::ARG_U32) || (arg_type == Arg_type::ARG_S32))
{
//Skip the argument descriptor and the argument itself
arg_index += Arg_size::ARG_S32_SIZE;
}
//pedantic because the ditionary should have been checked before hand for bad argument descriptors
else if (UNIPARSER_PENDANTIC_CHECKS)
{
//This error means the argument descriptor was unrecognized
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true;
}
else
{
//failure
return true;
}
//! Check that index is valid
//if: index is above bit width or exceed the argument vector size
if ((arg_index > UNIPARSER_MAX_ARG_INDEX) || (arg_index > UNIPARSER_ARG_VECTOR_SIZE))
{
//Restart the argument decoder
this -> init_arg_decoder();
//
DPRINT("ERR: Exceeded alloted argument vector size with index: %d\n", arg_index);
this -> g_err = Err_codes::ERR_GENERIC;
DRETURN_ARG("ERR%d: ERR_GENERIC in line: %d\n", this -> g_err, __LINE__ );
return true; //fail
}
//Write back index
this -> g_arg_fsm_status.arg_index = arg_index;
//Update number of decoded arguments
this -> g_arg_fsm_status.num_arg++;
DPRINT("Argument closed | num arg: %d | arg index: %d\n", this -> g_arg_fsm_status.num_arg, this -> g_arg_fsm_status.arg_index);
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
//Trace Return vith return value
DRETURN();
return false; //OK
} //end method: close_arg | void
/***************************************************************************/
//! @brief Public Method
//! execute_callback | void
/***************************************************************************/
// @param
//! @return no return
//! @details
//! Execute callback by passing a vector of U8 inside which are codified the bytes of the arguments
//! @algorithm
//! It's an execution tree that execute a branch based on the argument types
//! Tree is limited by the maximum number of types and the maximum number of bytes
//! ARG0 ARG0,ARG1 ARG0,ARG1,ARG2 ARG0,ARG1,ARG2,ARG3
//! void
//! 8 8 8 8 8 8 8 8 8 8 (arg number limit)
//! ... ...
//! 8 16
//! 8 32
//! 16 16 8
//! 16 16
//! ...
//! 32 32 8 32 8 8 8 (arg number limit)
//! 32 16 8 8 (arg number and size limit)
//! 32 16 16 (arg number limit)
//! 32 32 (arg size limit)
//! (arg type limit)
//! Calls work equally with signed or unsiged arguments
/***************************************************************************/
bool Uniparser::execute_callback( void *callback_ptr )
{
//Trace Enter
DENTER();
///--------------------------------------------------------------------------
/// VARS
///--------------------------------------------------------------------------
//Argument index counter
uint8_t arg_cnt = 0;
//Number of arguments
uint8_t arg_num_types = this -> g_arg_fsm_status.num_arg;
//Count the index of the current argument type being decoded
uint8_t arg_type_cnt = 0;
//Link argument type vector
Arg_type *arg_type = this -> g_arg_type;
///--------------------------------------------------------------------------
/// INIT
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
/// BODY
///--------------------------------------------------------------------------
//if: no arguments
if (arg_num_types == 0)
{
///--------------------------------------------------------------------------
/// void
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, void ) = FUNCTION_PTR_CAST(void)callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE_VOID( f_ptr );
DPRINT("Executing void -> void: %p | Args: NONE \n", (void *)f_ptr );
}
//if: first argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode first argument
uint8_t *arg_a_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 - 1
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t ) = FUNCTION_PTR_CAST( uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr) );
DPRINT("Executing uint8_t -> void: %p | Args: %d \n", (void *)f_ptr, (*arg_a_ptr) );
} //End If: it's the only argument
//if: second argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_b_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 - 2
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr));
DPRINT("Executing uint8_t, uint8_t -> void: %p | Args: %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr) );
} //End If: it's the only argument
//if third argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_c_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 U8 - 3
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint8_t, uint8_t, uint8_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 U8 U8 - 4
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t, uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint8_t, uint8_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_d_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 U8 U16 - 5
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t, uint8_t, uint16_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t, uint8_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint8_t, uint8_t, uint16_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode second argument
uint32_t *arg_d_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U32_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 U8 U32
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t, uint8_t, uint32_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t, uint8_t, uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint8_t, uint8_t, uint32_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U8 or S8
//if third argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_c_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 U16
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t, uint16_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint8_t, uint8_t, uint16_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 U16 U8 - 5
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t, uint16_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t, uint16_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint8_t, uint16_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_d_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 U16 U16 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t, uint16_t, uint16_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t, uint16_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint8_t, uint16_t, uint16_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode second argument
uint32_t *arg_d_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U32_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 U16 U32 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t, uint16_t, uint32_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t, uint16_t, uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint8_t, uint16_t, uint32_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U16 or S16
//if third argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode second argument
uint32_t *arg_c_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U32_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 U32 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t, uint32_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t, uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint8_t, uint8_t, uint32_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 U32 U8 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t, uint32_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t, uint32_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint8_t, uint32_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_d_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U8 U32 U16 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint8_t, uint32_t, uint16_t ) = FUNCTION_PTR_CAST( uint8_t, uint8_t, uint32_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint8_t, uint32_t, uint16_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U16 or S16
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U32 or S32
//If: third argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: third argument is unhandled
} //if: second argument is U8 or S8
//if: second argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_b_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U16 - 3
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint16_t ) = FUNCTION_PTR_CAST( uint8_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr));
DPRINT("Executing uint8_t, uint16_t -> void: %p | Args: %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr) );
} //End If: it's the only argument
//if third argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_c_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U16 U8 - 4
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint16_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint16_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint8_t, uint16_t, uint8_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode fourth argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U16 U8 U8 - 5
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint16_t, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint16_t, uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint16_t, uint8_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode fourth argument
uint16_t *arg_d_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U16 U8 U16 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint16_t, uint8_t, uint16_t ) = FUNCTION_PTR_CAST( uint8_t, uint16_t, uint8_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint16_t, uint8_t, uint16_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode fourth argument
uint32_t *arg_d_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U32_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U16 U8 U32 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint16_t, uint8_t, uint32_t ) = FUNCTION_PTR_CAST( uint8_t, uint16_t, uint8_t, uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint16_t, uint8_t, uint32_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U8 or S8
//if third argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_c_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U16 U16
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint16_t, uint16_t ) = FUNCTION_PTR_CAST( uint8_t, uint16_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint8_t, uint16_t, uint16_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U16 U16 U8 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint16_t, uint16_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint16_t, uint16_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint16_t, uint16_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_d_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U16 U16 U16 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint16_t, uint16_t, uint16_t ) = FUNCTION_PTR_CAST( uint8_t, uint16_t, uint16_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint16_t, uint16_t, uint16_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U16 or S16
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U16 or S16
//if third argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode second argument
uint32_t *arg_c_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U32_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U16 U32
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint16_t, uint32_t ) = FUNCTION_PTR_CAST( uint8_t, uint16_t, uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint8_t, uint16_t, uint32_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U16 U32 U8 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint16_t, uint32_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint16_t, uint32_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint16_t, uint32_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U16 or S16
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U32 or S32
//If: third argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: third argument is unhandled
} //if: second argument is U16 or S16
//if: second argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode second argument
uint32_t *arg_b_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U32_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U32 - 5
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint32_t ) = FUNCTION_PTR_CAST( uint8_t, uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr));
DPRINT("Executing uint8_t, uint32_t -> void: %p | Args: %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr) );
} //End If: it's the only argument
//if: third argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_c_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U32 U8 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint32_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint32_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint8_t, uint32_t, uint8_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U32 U8 U8 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint32_t, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint32_t, uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint32_t, uint8_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_d_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U32 U8 U16 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint32_t, uint8_t, uint16_t ) = FUNCTION_PTR_CAST( uint8_t, uint32_t, uint8_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint32_t, uint8_t, uint16_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U16 or S16
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U8 or S8
//if third argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_c_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U32 U16 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint32_t, uint16_t ) = FUNCTION_PTR_CAST( uint8_t, uint32_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint8_t, uint32_t, uint16_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode fourth argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U8 U32 U16 U8 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint8_t, uint32_t, uint16_t, uint8_t ) = FUNCTION_PTR_CAST( uint8_t, uint32_t, uint16_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint8_t, uint32_t, uint16_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16 or U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16) || (arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U16 or S16 or U32 or S32
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U16 or S16
//if third argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
}
//If: third argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: third argument is unhandled }
} //if: second argument is U32 or S32
//If: second argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: second argument is unhandled
} //end if: first argument is U8 or S8
//if: first argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode first argument
uint16_t *arg_a_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 - 2
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t ) = FUNCTION_PTR_CAST( uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr) );
DPRINT("Executing uint16_t -> void: %p | Args: %d \n", (void *)f_ptr, (*arg_a_ptr) );
}
//if: second argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_b_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U8 - 3
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint8_t ) = FUNCTION_PTR_CAST( uint16_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr));
DPRINT("Executing uint16_t, uint8_t -> void: %p | Args: %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr) );
} //End If: it's the only argument
//if third argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_c_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U8 U8 - 4
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint16_t, uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint16_t, uint8_t, uint8_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode fourth argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U8 U8 U8 - 5
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint8_t, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint16_t, uint8_t, uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint16_t, uint8_t, uint8_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode fourth argument
uint16_t *arg_d_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U8 U8 U16 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint8_t, uint8_t, uint16_t ) = FUNCTION_PTR_CAST( uint16_t, uint8_t, uint8_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint16_t, uint8_t, uint8_t, uint16_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) ); } //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode fourth argument
uint32_t *arg_d_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U32_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U8 U8 U32 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint8_t, uint8_t, uint32_t ) = FUNCTION_PTR_CAST( uint16_t, uint8_t, uint8_t, uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint16_t, uint8_t, uint8_t, uint32_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) ); } //End If: it's the only argument
} //end if fourth argument is U32 or S32
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U8 or S8
//if third argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_c_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U8 U16 - 5
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint8_t, uint16_t ) = FUNCTION_PTR_CAST( uint16_t, uint8_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint16_t, uint8_t, uint16_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode fourth argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U8 U16 U8 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint8_t, uint16_t, uint8_t ) = FUNCTION_PTR_CAST( uint16_t, uint8_t, uint16_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint16_t, uint8_t, uint16_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode fourth argument
uint16_t *arg_d_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U8 U16 U16 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint8_t, uint16_t, uint16_t ) = FUNCTION_PTR_CAST( uint16_t, uint8_t, uint16_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint16_t, uint8_t, uint16_t, uint16_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U16 or S16
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U16 or S16
//if third argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode second argument
uint32_t *arg_c_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U32_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U8 U32 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint8_t, uint32_t ) = FUNCTION_PTR_CAST( uint16_t, uint8_t, uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint16_t, uint8_t, uint32_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode fourth argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U8 U32 U8 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint8_t, uint32_t, uint8_t ) = FUNCTION_PTR_CAST( uint16_t, uint8_t, uint32_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint16_t, uint8_t, uint32_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16 or U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16) || (arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U32 or S32
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U32 or S32
//If: third argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: third argument is unhandled
} //if: second argument is U8 or S8
//if: second argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_b_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U16 - 4
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint16_t ) = FUNCTION_PTR_CAST( uint16_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr));
DPRINT("Executing uint16_t, uint16_t -> void: %p | Args: %d %d\n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr) );
} //End If: it's the only argument
//if third argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_c_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U16 U8 - 5
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint16_t, uint8_t ) = FUNCTION_PTR_CAST( uint16_t, uint16_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint16_t, uint16_t, uint8_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode fourth argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U16 U8 U8 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint16_t, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint16_t, uint16_t, uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint16_t, uint16_t, uint8_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode fourth argument
uint16_t *arg_d_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U16 U8 U16 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint16_t, uint8_t, uint16_t ) = FUNCTION_PTR_CAST( uint16_t, uint16_t, uint8_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint16_t, uint16_t, uint8_t, uint16_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) ); } //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U16 or S16
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U8 or S8
//if third argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_c_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U16 U16 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint16_t, uint16_t ) = FUNCTION_PTR_CAST( uint16_t, uint16_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint16_t, uint16_t, uint16_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode fourth argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U16 U16 U8 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint16_t, uint16_t, uint8_t ) = FUNCTION_PTR_CAST( uint16_t, uint16_t, uint16_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint16_t, uint16_t, uint16_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode fourth argument
uint16_t *arg_d_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U16 U16 U16 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint16_t, uint16_t, uint16_t ) = FUNCTION_PTR_CAST( uint16_t, uint16_t, uint16_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint16_t, uint16_t, uint16_t, uint16_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
//if: fifth argument
else
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fifth argument
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U16 or S16
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U16 or S16
//if third argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode second argument
uint32_t *arg_c_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U32_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U16 U32 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint16_t, uint32_t ) = FUNCTION_PTR_CAST( uint16_t, uint16_t, uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint16_t, uint16_t, uint32_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if: fourth argument
else
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument
} //if: third argument is U32 or S32
//If: third argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: third argument is unhandled
} //if: second argument is U16 or S16
//if: second argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode second argument
uint32_t *arg_b_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U32_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U32 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint32_t ) = FUNCTION_PTR_CAST( uint16_t, uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr));
DPRINT("Executing uint16_t, uint32_t -> void: %p | Args: %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr) );
} //End If: it's the only argument
//if third argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_c_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U32 U8 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint32_t, uint8_t ) = FUNCTION_PTR_CAST( uint16_t, uint32_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint16_t, uint32_t, uint8_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode fourth argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U32 U8 U8 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint32_t, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint16_t, uint32_t, uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint16_t, uint32_t, uint8_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16 or U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16) || (arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U16 or S16 or U32 or S32
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U8 or S8
//if third argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_c_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U16 U32 U16 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint16_t, uint32_t, uint16_t ) = FUNCTION_PTR_CAST( uint16_t, uint32_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint16_t, uint32_t, uint16_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if: fourth argument
else
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument
} //if: third argument is U16 or S16
//if third argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //if: third argument is U32 or S32
//If: third argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: third argument is unhandled
} //if: second argument is U32 or S32
//If: second argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: second argument is unhandled
} //end if: first argument is U16 or S16
//if: first argument is S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode first argument
uint32_t *arg_a_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_S32_SIZE;
//I decoded an argument
arg_type_cnt++;
DPRINT("Decoded argument | arg_type_cnt: %d | arg_cnt: %d | arg: %d\n", arg_type_cnt, arg_cnt, (*arg_a_ptr));
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 - 4
///--------------------------------------------------------------------------
//Passing an unsigned 32 bit pointer is decoded successfully as signed of same size
FUNCTION_PTR_VAR( f_ptr, uint32_t ) = FUNCTION_PTR_CAST( uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr) );
DPRINT("Executing int32_t -> void: %p | Args: %d\n", (void *)f_ptr, (*arg_a_ptr) );
}
//if: second argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_b_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 U8 - 5
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint32_t, uint8_t ) = FUNCTION_PTR_CAST( uint32_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr));
DPRINT("Executing uint16_t, uint8_t -> void: %p | Args: %d %d\n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr) );
} //End If: it's the only argument
//if third argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_c_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 U8 U8 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint32_t, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint32_t, uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint32_t, uint8_t, uint8_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode fourth argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 U8 U8 U8 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint32_t, uint8_t, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint32_t, uint8_t, uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint32_t, uint8_t, uint8_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode fourth argument
uint16_t *arg_d_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 U8 U8 U16 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint32_t, uint8_t, uint8_t, uint16_t ) = FUNCTION_PTR_CAST( uint32_t, uint8_t, uint8_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint32_t, uint8_t, uint8_t, uint16_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) ); } //End If: it's the only argument
} //end if fourth argument is U16 or S16
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U32 or S32
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U8 or S8
//if third argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_c_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 U8 U16 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint32_t, uint8_t, uint16_t ) = FUNCTION_PTR_CAST( uint32_t, uint8_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint32_t, uint8_t, uint16_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode fourth argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 U8 U16 U8 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint32_t, uint8_t, uint16_t, uint8_t ) = FUNCTION_PTR_CAST( uint32_t, uint8_t, uint16_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint32_t, uint8_t, uint16_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16) || (arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U32 or S32
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U16 or S16
//if third argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //if: third argument is U32 or S32
//If: third argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: third argument is unhandled
} //if: second argument is U8 or S8
//if: second argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_b_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 U16 - 6
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint32_t, uint16_t ) = FUNCTION_PTR_CAST( uint32_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr));
DPRINT("Executing uint16_t, uint16_t -> void: %p | Args: %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr) );
} //End If: it's the only argument
//if third argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode second argument
uint8_t *arg_c_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 U16 U8 - 7
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint32_t, uint16_t, uint8_t ) = FUNCTION_PTR_CAST( uint32_t, uint16_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint32_t, uint16_t, uint8_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument is U8 or S8
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U8) || (arg_type[arg_type_cnt] == Arg_type::ARG_S8))
{
//Decode fourth argument
uint8_t *arg_d_ptr = ARG_CAST( arg_cnt, uint8_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U8_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 U16 U8 U8 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint32_t, uint16_t, uint8_t, uint8_t ) = FUNCTION_PTR_CAST( uint32_t, uint16_t, uint8_t, uint8_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr));
DPRINT("Executing uint32_t, uint16_t, uint8_t, uint8_t -> void: %p | Args: %d %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr), (*arg_d_ptr) );
} //End If: it's the only argument
} //end if fourth argument is U8 or S8
//if fourth argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16) || (arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument is U32 or S32
//if: more than four arguments are forbidden!
else
{
this -> error_handler( ERR_TOO_MANY_ARGS );
DRETURN_ARG("ERR_TOO_MANY_ARGS in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if: more than four arguments are forbidden!
} //if: third argument is U8 or S8
//if third argument is U16 or S16
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U16) || (arg_type[arg_type_cnt] == Arg_type::ARG_S16))
{
//Decode second argument
uint16_t *arg_c_ptr = ARG_CAST( arg_cnt, uint16_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U16_SIZE;
//I decoded an argument
arg_type_cnt++;
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 U16 U16 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint32_t, uint16_t, uint16_t ) = FUNCTION_PTR_CAST( uint32_t, uint16_t, uint16_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr));
DPRINT("Executing uint32_t, uint16_t, uint16_t -> void: %p | Args: %d %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr), (*arg_c_ptr) );
} //End If: it's the only argument
//if fourth argument
else
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //end if fourth argument
} //if: third argument is U16 or S16
//if third argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //if: third argument is U32 or S32
//If: third argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: third argument is unhandled
} //if: second argument is U16 or S16
//if: second argument is U32 or S32
else if ((arg_type[arg_type_cnt] == Arg_type::ARG_U32) || (arg_type[arg_type_cnt] == Arg_type::ARG_S32))
{
//Decode second argument
uint32_t *arg_b_ptr = ARG_CAST( arg_cnt, uint32_t );
//Accumulate argument size
arg_cnt += Arg_size::ARG_U32_SIZE;
//I decoded an argument
arg_type_cnt++;
DPRINT("Decoded argument | arg_type_cnt: %d | arg_cnt: %d | arg: %d\n", arg_type_cnt, arg_cnt, (*arg_b_ptr));
//If: it's the only argument
if (arg_num_types == arg_type_cnt)
{
///--------------------------------------------------------------------------
/// U32 U32 - 8
///--------------------------------------------------------------------------
//Declare specialized function pointer and link it to the general registered function callback address
FUNCTION_PTR_VAR( f_ptr, uint32_t, uint32_t ) = FUNCTION_PTR_CAST( uint32_t, uint32_t )callback_ptr;
//Execute function from its specialized pointer
FUNCTION_PTR_EXE( f_ptr, (*arg_a_ptr), (*arg_b_ptr));
DPRINT("Executing uint32_t, uint32_t -> void: %p | Args: %d %d \n", (void *)f_ptr, (*arg_a_ptr), (*arg_b_ptr) );
} //End If: it's the only argument
//If: I CANNOT have a third argument after this because it would exceed the argument size limit
else
{
this -> error_handler( ERR_ARG_SIZE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: argument is unhandled
} //if: second argument is U32 or S32
//If: second argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_ARG_SIZE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: second argument is unhandled
} //end if: first argument is S32
//If: argument is unhandled
else
{
this -> error_handler( ERR_UNHANDLED_ARG_TYPE );
DRETURN_ARG("ERR_UNHANDLED_ARG_TYPE in line: %d | num arg: %d | arg_index: %d\n", __LINE__, arg_type_cnt, arg_cnt);
return true; //FAIL
} //End If: argument is unhandled
///--------------------------------------------------------------------------
/// RETURN
///--------------------------------------------------------------------------
//Trace Return
DRETURN();
return false; //OK
} //end method: execute_callback
/***************************************************************************/
//! @brief Private Method
//! error_handler | Err_codes
/***************************************************************************/
//! @param err_code | Err_codes | internal uniparser error code
//! @return void
//! @details
//! Handles an internal parser error
/***************************************************************************/
void Uniparser::error_handler( Err_codes err_code )
{
//Trace Enter with arguments
DENTER_ARG( "Error code: %d\n", err_code);
//----------------------------------------------------------------
// VARS
//----------------------------------------------------------------
//----------------------------------------------------------------
// INIT
//----------------------------------------------------------------
//----------------------------------------------------------------
// BODY
//----------------------------------------------------------------
//Save the error code
this -> g_err = err_code;
//----------------------------------------------------------------
// RETURN
//----------------------------------------------------------------
//Trace Return vith return value
DRETURN();
return;
} //end method: error_handler | Err_codes
/****************************************************************************
** NAMESPACES
****************************************************************************/
} //End Namespace: Orangebot