#define SCPI_CORE_PRIVATE // access to 'scpi_core_private.h'
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "app/scpi/scpi_core.h"
#include "app/scpi/scpi_core_private.h"
#include "app/scpi/scpi_commands.h"
#include "app/scpi/scpi_parser.h"
#include "app/scpi/scpi_tlst_ex.h"
#include "app/scpi/CommandHandlers/idn.h"
#include "app/scpi/CommandHandlers/rst.h"
#include "app/scpi/CommandHandlers/cls.h"
#include "app/scpi/CommandHandlers/esr_stb.h"
#include "app/scpi/CommandHandlers/ese_sre.h"
#include "app/scpi/CommandHandlers/opc.h"
//#include "app/scpi/CommandHandlers/test.h"
#include "app/scpi/CommandHandlers/syst_error.h"
#include "app/scpi/CommandHandlers/syst_version.h"
#include "app/scpi/commandHandlers/memory_table_adapter.h"
#include "app/scpi/commandHandlers/memory_table_connector.h"
#include "app/scpi/commandHandlers/memory_table_group.h"
#include "app/scpi/commandHandlers/memory_table_ther_corr_group.h"
#include "app/scpi/commandHandlers/measurement_and_switch.h"
#include "app/scpi/commandHandlers/led_switch.h"
#include "app/scpi/commandHandlers/scpi_service.h"
#include "app/scpi/commandHandlers/power_switch.h"
#include "app/scpi/commandHandlers/trigger_state.h"
#include "app/scpi/commandHandlers/memory_table_freq_data.h"
#include "app/scpi/commandHandlers/memory_table_freq_segm_data.h"
#include "app/scpi/commandHandlers/interface_switch.h"
#include "app/scpi/commandHandlers/memory_table_data.h"
#include "app/scpi/commandHandlers/memory_table_ther_corr_data.h"
#include "app/scpi/commandHandlers/trg.h"
#include "app/scpi/commandHandlers/scpi_table.h"
//----------------------------------------------------------------
// Refer to:
// [1] IEEE 488.2 Standard, revision IEEE Std 488.2-1987 (1992)
//     "IEEE Standard Codes, Formats, Protocols, and Common Commands for Use With IEEE Std 488.1-1987, IEEE
//      Standard Digital Interface for Programmable Instrumentation"
// [2] SCPI Specification, revision 1999.0
//     "Standard Commands for Programmable Instruments (SCPI), VERSION 1999.0, May 1999"
//----------------------------------------------------------------

// ========================================================================================================
 static bool compareCharacter( xArgument_t allowedOption, const sStrToken_t * testingString )
 {
    assert( allowedOption );
    assert( testingString );
    assert( testingString->shead < testingString->stail );

    return scpi_command_header_compare( allowedOption, testingString );
 }

 // @processCharacterArgument
 // Argument Validation Function
 // Processes specified SCPI Character Parameter (Character Program Data) and searches it in the allowed values list.
 // Function uses smart comparing the source parameter to each one of the list allowing short and long form of value. 
 // References:
 //     "7.7.1 <CHARACTER PROGRAM DATA>", [1]
 //     "7.7.1.2 Encoding Syntax", [1]
 // @allowedList - values allowed list, use @DECLARE_ARGUMENT_CHARACTER_ALLOWED_LIST to create this parameter;
 //  Note 1: each element in the list must be a NULL-terminated string;
 //  Note 2: the list must contain NULL-pointer in the end of list;
 // @arg - parsed argument token filled by @parseArguments (SCPI_PARSE_ARGUMENTS macro)
 // @pIdx - optional pointer to the variable to store index of matched element in the @allowedList array, only valid if
 // the 'true' is returned; only positive number is returned;
 // Return:
 //  - true: parameter processed successfully, passed parameter is valid due to it matchs to
 //  one of the element of allowed list;
 //  - false: parameter fail, passed parameter not recognized or invalid function parameter; 
 bool processCharacterArgument( const xArgument_t * allowedList, const sStrToken_t * arg, int8_t * pIdx )
 {
    assert( allowedList );
    assert( allowedList[0] ); // allowed list must contain at least one element
    assert( arg );
    assert( arg->shead < arg->stail ); // argument can not be empty

    if( NULL == allowedList || NULL == allowedList[0] || NULL == arg || (arg->shead >= arg->stail) )
    {
        return false;
    }

    bool status = false;

    uint8_t idx = 0;
    while( NULL != allowedList[ idx ] )
    {
        if( compareCharacter( allowedList[ idx ], arg ) )
        {
            if( NULL != pIdx ) *pIdx = idx;
            status = true;
            break;
        }
        idx++;
    }

    return status;
 }

// ========================================================================================================
// @scpiSearchCommandHandler
// Searches for the registered SCPI-command handler for the
// ... command specified by pair of @shead and @stail.
// @proot - pointer to the root element pointer to search in, can not be NULL; 
// @shead - string head (begining), can not be NULL;
// @stail - string tail (ending), can not be NULL;
// @cmdType - the command header type, see @eScpiEntityType_t.
// @pFoundHandler - pointer to the string token structure to store found handler mnemonic (optional);
// Returns: the command handler entry pointer in success case, 
// ... and NULL in case no command handler found or on error condition.
// Note: pair of @shead and @stail shall represent a valid SCPI Command 
// ... Program Header ("7.6.1 <COMMAND PROGPRAM HEADER>", [1]), processed
// ... by @parseCommandProgramHeader function.
// Note: if the value referred by @proot is NULL, this value is considered
// ... as global root branch (scpi_commands_root_node)
// References:
//    6.2.4 Traversal of the Header Tree, [2]
//    A.1.1 Use of the Compound Header Rules, [1]
const sScpiCommandHandlerEntry_t * scpiSearchCommandHandler(
                                           const sTreeList_t * * proot,
                                           const char * shead,
                                           const char * stail, 
                                           uint8_t cmdType,
                                           sStrToken_t * pFoundHandler,
                                           bool bRememberOverride )
{
    // Since this function is called after the @parseCommandProgramHeader
    // ... call, it is assumed that the string is a valid SCPI-command,
    // ... and can contain only one of the following types of command:
    // * common command, begins with '*' sign, e.g. "*IDN?";
    // * simple/compound command, begins with the optional ':' and contain optional
    // ... ':' between "subsystems", e.g. "MEM:TABLE:DATA";
    const sTreeList_t * found = NULL;
    const sTreeList_t * root = NULL;
    bool bRememberLastBranch = true;

    if( NULL == proot || NULL == shead || NULL == stail || shead > stail )
       return NULL;

    switch( cmdType )
    {
        // common command:
        case eScpiEntityTypeCmnCommandProgHdr:
        case eScpiEntityTypeCmnQueryProgHdr:
        {
             root = &scpi_commands_root_node;  // reset current branch to the root

             sStrToken_t token = { shead, stail }; 

             // Search for mandatory commands (common form): flat search in the root
             found = tree_list_search( root, &token, treelist_header_compare, NULL );
        }
        break;

        // simple/compound command
        case eScpiEntityTypeCmpCommandProgHdr:
        case eScpiEntityTypeCmpQueryProgHdr:
        {
             root = *proot;  // move to global context

             if( NULL == root )
                 root = &scpi_commands_root_node;  // reset current branch to the root

             // check if there is leading colon:
             if( scpi_iscmdsep( *shead ) )
             {
                 // "root subsystem" found, reset current branch to the root 
                 root = &scpi_commands_root_node;
                 shead++;
             }
             else
             {
                 // A.1.1 Use of the Compound Header Rules, [1]
                 bRememberLastBranch = false;
             }

             sTreeListSearchCtx_t ts_search;

             // initialize compound command chain context
             scpi_command_search_prepare( &ts_search, shead, stail );  

             // Search for compound commands: deep search from the root 
             found = tree_list_search_deep( root, &scpi_commands_tlds, &ts_search ); 

             if( found )
             {
                 root = ts_search.parent;
             }
        }
        break;
    }

    if( found ) 
    {
        // If the command is the first in the line, the branch must be set as default branch (@bRememberOverride)
        if( bRememberLastBranch || bRememberOverride ) *proot = root; // remember last branch

        if( NULL != pFoundHandler )
        {
            pFoundHandler->shead = shead;
            pFoundHandler->stail = stail;
        }

        return (const sScpiCommandHandlerEntry_t*)(found->c_ctx);
    }

    return NULL;
}

// ========================================================================================================
// ========================================================================================================
// ========================================================================================================
// ========================================================================================================

//// @CommandEntryMEMoryTABLeADAPter
//// MEMory:TABLe:ADAPter? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeADAPter = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLeADAPter }, // connect the MemoryTableAdapter handler
//    .ctx = NULL
//};
//
//// @CommandEntryMEMoryTABLeCONNector
//// MEMory:TABLe:CONNector? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeCONNector = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLeCONNector }, // connect the MemoryTableConnector handler
//    .ctx = NULL
//};
//
//// @CommandEntryMEMoryTABLeANALyzer
//// MEMory:TABLe:ANALyzer? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeANALyzer = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLe_group }, // connect the MemoryTableAnalyzer handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableAnalyzer // grouped handler context
//};
//
//// @CommandEntryMEMoryTABLeDATE
//// MEMory:TABLe:DATE? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeDATE = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLe_group }, // connect the MemoryTableDate handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableDate  // grouped handler context
//};
//
//// @CommandEntryMEMoryTABLeOPERator
//// MEMory:TABLe:OPERator? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeOPERator = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLe_group }, // connect the MemoryTableOperator handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableOperator // grouped handler context
//};
//
//// @CommandEntryMEMoryTABLePLACe
//// MEMory:TABLe:PLACe? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLePLACe = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLe_group }, // connect the MemoryTablePlace handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTablePlace  // grouped handler context
//};
//
//// @CommandEntryMEMoryTABLePOINts
//// MEMory:TABLe:POINts? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLePOINts = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLe_group }, // connect the MemoryTablePoints handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTablePoints // grouped handler context
//};
//
//// @CommandEntryMEMoryTABLeTEMPerature
//// MEMory:TABLe:TEMPerature? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeTEMPerature = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLe_group }, // connect the MemoryTableTemperature handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableTemperature // grouped handler context
//};
//
//// @CommandEntryMEMoryTABLeTIME
//// MEMory:TABLe:TIME? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeTIME = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLe_group }, // connect the MemoryTableTime handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableTime // grouped handler context
//};

//// @CommandEntryMEMoryTABLeFREQuencySTARt
//// MEMory:TABLe:FREQuency:STARt? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeFREQuencySTARt = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLe_group }, // connect the MemoryTableFrequencyStart handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableFrequencyStart  // grouped handler context
//};
//
//// @CommandEntryMEMoryTABLeFREQuencySTOP
//// MEMory:TABLe:FREQuency:STOP? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeFREQuencySTOP = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLe_group }, // connect the MemoryTableFrequencyStop handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableFrequencyStop  // grouped handler context
//};
//
//// @CommandEntryMEMoryTABLeFREQuencyTYPE
//// MEMory:TABLe:FREQuency:TYPE? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeFREQuencyTYPE = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLe_group }, // connect the MemoryTableFrequencyType handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableFrequencyType  // grouped handler context
//};

//// @CommandEntryMEMoryTABLeTHERmoCorrectionFREQuencySTARt
//// MEMory:TABLe:THERmo:CORRection:FREQuency:STARt? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeTHERmoCORRectionFREQuencySTARt = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLeTHERmoCORRection_group }, // connect the MemoryTableThermoCorrectionFrequencyStart handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableThermoCorrectionFrequencyStart   // grouped handler context
//};
//
//// @CommandEntryMEMoryTABLeTHERmoCorrectionFREQuencySTOP
//// MEMory:TABLe:THERmo:CORRection:FREQuency:STOP? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeTHERmoCORRectionFREQuencySTOP = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLeTHERmoCORRection_group }, // connect the MemoryTableThermoCorrectionFrequencyStop handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableThermoCorrectionFrequencyStop    // grouped handler context
//};

//// @CommandEntryMEMoryTABLeTHERmoCorrectionFREQuencyPOINts
//// MEMory:TABLe:THERmo:CORRection:FREQuency:POINTs? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeTHERmoCORRectionFREQuencyPOINts = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLeTHERmoCORRection_group }, // connect the MemoryTableThermoCorrectionFrequencyPoints handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableThermoCorrectionFrequencyPoints  // grouped handler context
//};

//// @CommandEntryMEMoryTABLeFREQuencySEGMentDATA
//// :MEMory:TABLe:FREQuency:SEGMent:DATA? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeFREQuencySEGMentDATA = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLeFREQuencySEGMentDATA }, // connect the MemoryTableFrequencySegmentData handler
//    .ctx = NULL
//};

//// @CommandEntryMEMoryTABLeFREQuencyDATA
//// :MEMory:TABLe:FREQuency:DATA? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeFREQuencyDATA = {
//    .entry = { &fsqvbl_CommandHandlerMEMoryTABLeFREQuencyDATA }, // connect the MemoryTableFrequencyData handler
//    .ctx = NULL
//};

//// @CommandEntryMEMoryTABLeTHERmoCorrectionMAGNitude
//// MEMory:TABLe:THERmo:CORRection:MAGNitude? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeTHERmoCORRectionMAGNitude = {
//    .entry = { &fsqvbl_CommandHandlerMemoryTableThermoCorrectionData }, // connect the MemoryTableThermoCorrectionData handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableThermoCorrectionMagnitude_context  // grouped handler context
//};
//
//// @CommandEntryMEMoryTABLeTHERmoCorrectionPHASe
//// MEMory:TABLe:THERmo:CORRection:PHASe? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeTHERmoCORRectionPHASe = {
//    .entry = { &fsqvbl_CommandHandlerMemoryTableThermoCorrectionData }, // connect the MemoryTableThermoCorrectionData handler
//    .ctx = &fsqvbl_CommandHandlerMemoryTableThermoCorrectionPhase_context  // grouped handler context
//};

//// @NodeEntry_FREQuencySEGMent
//// "MEMory:TABLe:FREQuency:SEGMent:" command node
//static const sTreeList_t NodeEntry_FREQuencySEGMent[] = {
//
//    // create ':MEMory:TABLe:FREQuency:SEGMent:DATA' query, link @CommandEntryMEMoryTABLeFREQuencySEGMentDATA entry
//    DECLARE_TREE_LIST_CLEAF( "DATA", &CommandEntryMEMoryTABLeFREQuencySEGMentDATA ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};

//// @CommandEntryMEMoryTABLeDATA
//// :MEMory:TABLe:DATA? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMEMoryTABLeDATA = {
//    .entry = { &fsqvbl_CommandHandlerMemoryTableData }, // connect the MemoryTableData handler
//    .ctx = NULL
//};
//
//// @NodeEntry_FREQuency
//// "MEMory:TABLe:FREQuency:" command node
//static const sTreeList_t NodeEntry_FREQuency[] = {
//
//    // create ':MEMory:TABLe:FREQuency:SEGMent' sub-system for SCPI
//    DECLARE_TREE_LIST_CNODE( "SEGMent", NodeEntry_FREQuencySEGMent ),
//
//    // create ':MEMory:TABLe:FREQ:STAR query, link @CommandEntryMEMoryTABLeFREQuencySTARt entry
//    DECLARE_TREE_LIST_CLEAF( "STARt",    &CommandEntryMEMoryTABLeFREQuencySTARt ),
//
//    // create ':MEMory:TABLe:FREQ:STOP query, link @CommandEntryMEMoryTABLeFREQuencySTOP entry
//    DECLARE_TREE_LIST_CLEAF( "STOP",  &CommandEntryMEMoryTABLeFREQuencySTOP ),
//
//    // create ':MEMory:TABLe:FREQ:TYPE query, link @CommandEntryMEMoryTABLeFREQuencyTYPE entry
//    DECLARE_TREE_LIST_CLEAF( "TYPE",  &CommandEntryMEMoryTABLeFREQuencyTYPE ),
//
//    // create ':MEMory:TABLe:FREQuency:DATA' query, link @CommandEntryMEMoryTABLeFREQuencyDATA entry
//    DECLARE_TREE_LIST_CLEAF( "DATA", &CommandEntryMEMoryTABLeFREQuencyDATA ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};

//// @NodeEntry_CORRectionFREQuency
//// "MEMory:TABLe:THERmo:CORRection:FREQuency:" command node
//static const sTreeList_t NodeEntry_CORRectionFREQuency[] = {
//
//    // create ':MEMory:TABLe:FREQ:STAR query, link @CommandEntryMEMoryTABLeTHERmoCORRectionFREQuencySTARt entry
//    DECLARE_TREE_LIST_CLEAF( "STARt",    &CommandEntryMEMoryTABLeTHERmoCORRectionFREQuencySTARt ),
//
//    // create ':MEMory:TABLe:FREQ:STOP query, link @CommandEntryMEMoryTABLeTHERmoCORRectionFREQuencySTOP entry
//    DECLARE_TREE_LIST_CLEAF( "STOP",  &CommandEntryMEMoryTABLeTHERmoCORRectionFREQuencySTOP ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};

//// @NodeEntry_CORRection
//// "MEMory:TABLe:THERmo:CORRection:" command node
//static const sTreeList_t NodeEntry_CORRection[] = {
//
////    // create ':MEMory:TABLe:THERmo:CORRection:FREQuency:' sub-system for SCPI
////    DECLARE_TREE_LIST_CNODE( "FREQuency",  NodeEntry_CORRectionFREQuency ),
////
////    // create ':MEMory:TABLe:FREQ:POINts query, link @CommandEntryMEMoryTABLeTHERmoCORRectionFREQuencyPOINts entry
////    DECLARE_TREE_LIST_CLEAF( "POINts",  &CommandEntryMEMoryTABLeTHERmoCORRectionFREQuencyPOINts ),
////
////    // create ':MEMory:TABLe:FREQ:MAGNitude query, link @CommandEntryMEMoryTABLeTHERmoCORRectionMAGNitude entry
////    DECLARE_TREE_LIST_CLEAF( "MAGNitude",  &CommandEntryMEMoryTABLeTHERmoCORRectionMAGNitude ),
////
////    // create ':MEMory:TABLe:FREQ:PHASe query, link @CommandEntryMEMoryTABLeTHERmoCORRectionPHASe entry
////    DECLARE_TREE_LIST_CLEAF( "PHASe",  &CommandEntryMEMoryTABLeTHERmoCORRectionPHASe ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};

//// @NodeEntry_THERmo
//// "MEMory:TABLe:THERmo:" command node
//static const sTreeList_t NodeEntry_THERmo[] = {
//
//    // create ':MEMory:TABLe:THERmo:CORRection:' sub-system for SCPI
//    DECLARE_TREE_LIST_CNODE( "CORRection",  NodeEntry_CORRection ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};

//// @NodeEntry_TABLe
//// ":TABLE:" command node
//static const sTreeList_t NodeEntry_TABLe[] = {
//    
////    // create ':MEMory:TABLe:FREQuency:' sub-system for SCPI
////    DECLARE_TREE_LIST_CNODE( "FREQuency", NodeEntry_FREQuency ),
////
////    // create ':MEMory:TABLe:THERmo:' sub-system for SCPI
////    DECLARE_TREE_LIST_CNODE( "THERmo", NodeEntry_THERmo ),
////
////    // create ':MEMory:TABLe:ADAPter' query, link @CommandEntryMEMoryTABLeADAPter entry
////    DECLARE_TREE_LIST_CLEAF( "ADAPter", &CommandEntryMEMoryTABLeADAPter ),
////
////    // create ':MEMory:TABLe:CONNector' query, link @CommandEntryMEMoryTABLeCONNector entry
////    DECLARE_TREE_LIST_CLEAF( "CONNector", &CommandEntryMEMoryTABLeCONNector ),
////
////    // create ':MEMory:TABLe:ANALyzer' query, link @CommandEntryMEMoryTABLeANALyzer entry
////    DECLARE_TREE_LIST_CLEAF( "ANALyzer", &CommandEntryMEMoryTABLeANALyzer ),
////
////    // create ':MEMory:TABLe:DATE' query, link @CommandEntryMEMoryTABLeDATE entry
////    DECLARE_TREE_LIST_CLEAF( "DATE", &CommandEntryMEMoryTABLeDATE ),
////
////    // create ':MEMory:TABLe:OPERator' query, link @CommandEntryMEMoryTABLeOPERator entry
////    DECLARE_TREE_LIST_CLEAF( "OPERator", &CommandEntryMEMoryTABLeOPERator ),
////
////    // create ':MEMory:TABLe:PLACe' query, link @CommandEntryMEMoryTABLePLACe entry
////    DECLARE_TREE_LIST_CLEAF( "PLACe", &CommandEntryMEMoryTABLePLACe ),
////
////    // create ':MEMory:TABLe:POINts' query, link @CommandEntryMEMoryTABLePOINts entry
////    DECLARE_TREE_LIST_CLEAF( "POINts", &CommandEntryMEMoryTABLePOINts ),
////
////    // create ':MEMory:TABLe:TEMPerature' query, link @CommandEntryMEMoryTABLeTEMPerature entry
////    DECLARE_TREE_LIST_CLEAF( "TEMPerature", &CommandEntryMEMoryTABLeTEMPerature ),
////
////    // create ':MEMory:TABLe:TIME' query, link @CommandEntryMEMoryTABLeTIME entry
////    DECLARE_TREE_LIST_CLEAF( "TIME", &CommandEntryMEMoryTABLeTIME ),
////
////    // create ':MEMory:TABLe:DATA' query, link @CommandEntryMEMoryTABLeDATA entry
////    DECLARE_TREE_LIST_CLEAF( "DATA", &CommandEntryMEMoryTABLeDATA ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};

//// @scpi_cmd_memory
//// "MEM:" command node
//static const sTreeList_t NodeEntry_MEMory[] = {
//
//    // create ':MEMory:TABLe:' sub-system for SCPI
//    DECLARE_TREE_LIST_CNODE( "TABLe", NodeEntry_TABLe ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};

// @CommandEntrySystemError
// [:SYSTem]:ERRor? command entry
static const sScpiCommandHandlerEntry_t CommandEntrySystemError = {
    .entry = { &fsqvbl_CommandHandlerSystemError }, // connect the SYSTem:ERRor handler
    .ctx = NULL
};

// @CommandEntrySystemVersion
// [:SYSTem]:VERSion? command entry
static const sScpiCommandHandlerEntry_t CommandEntrySystemVersion = {
    .entry = { &fsqvbl_CommandHandlerSystemVersion }, // connect the SYSTem:VERSion handler
    .ctx = NULL
};

//// @CommandEntryMeasureInternalTemperature
//// MEASure:TEMPerature:INTernal? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMeasureIntTemperature = {
//    .entry = { &fsqvbl_CommandHandlerMEASnSWITCH_group }, // connect the MEASure:TEMPerature handler
//    .ctx = &fsqvbl_CommandHandlerMeasurementInternalTemperature // grouped handler context
//};
//
//// @CommandEntryMeasureExternalTemperature
//// MEASure:TEMPerature:EXTernal? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMeasureExtTemperature = {
//    .entry = { &fsqvbl_CommandHandlerMEASnSWITCH_group }, // connect the MEASure:TEMPerature handler
//    .ctx = &fsqvbl_CommandHandlerMeasurementExternalTemperature // grouped handler context
//};
//
//// @CommandEntryMeasureExternalTemperature
//// MEASure:TEMPerature:EXTernal? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMeasureExtTempCoefficient = {
//    .entry = { &fsqvbl_CommandHandlerMEASnSWITCH_group }, // connect the MEASure:TEMPerature handler
//    .ctx = &fsqvbl_CommandHandlerMeasurementTempCoefficient // grouped handler context
//};
//
//// @CommandEntryGainCount
//// [:SYSTEM]:GAIN:COUNt? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryGainCount = {
//    .entry = { &fsqvbl_CommandHandlerMEASnSWITCH_group }, // connect the SWITch:COUNt handler
//    .ctx = &fsqvbl_CommandHandlerAmpSwitchCount // grouped handler context
//};
//
//// @CommandEntryFiltCount
//// [:SYSTEM]:FILT:COUNt? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryFiltCount = {
//    .entry = { &fsqvbl_CommandHandlerMEASnSWITCH_group },
//    .ctx   = &fsqvbl_CommandHandlerFiltSwitchCount
//};
//
//// @CommandEntrySwitchList
//// [:SYSTEM]:AMP:SWITch:LIST? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryAmpSwitchList = {
//    .entry = { &fsqvbl_CommandHandlerMEASnSWITCH_group }, // connect the SWITch:LIST handler
//    .ctx = &fsqvbl_CommandHandlerAmpSwitchList // grouped handler context
//};
//
//static const sScpiCommandHandlerEntry_t CommandEntryFiltList = {
//    .entry = { &fsqvbl_CommandHandlerMEASnSWITCH_group }, // connect the SWITch:LIST handler
//    .ctx = &fsqvbl_CommandHandlerFiltSwitchList // grouped handler context
//};

//// @CommandEntrySwitchList
//// [:SYSTEM]:FLIT:SWITch:LIST? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryFiltSwitchList = {
//    .entry = { &fsqvbl_CommandHandlerMEASnSWITCH_group }, // connect the SWITch:LIST handler
//    .ctx = &fsqvbl_CommandHandlerFiltSwitchList // grouped handler context
//};

//// @CommandEntrySwitchState
//// [:SYSTEM]:GAIN:STATe? command entry
//static const sScpiCommandHandlerEntry_t CommandEntrySwitchState = {
//    .entry = { &fsqvbl_CommandHandlerSERVice }, // connect the SWITch:STATe handler
//    .ctx = &fsqvbl_CommandHandlerServiceState
//};
//
//// @CommandEntrySwitchState
//// [:SYSTEM]:BAND:STATe? command entry
//static const sScpiCommandHandlerEntry_t CommandEntrySwitchBandState = {
//    .entry = { &fsqvbl_CommandHandlerSERVice }, // connect the SWITch:STATe handler
//    .ctx = &fsqvbl_CommandHandlerSwitchSerial
//};

// @CommandEntryInterfaceSwitch
// :INTerface:SWitch? command entry
static const sScpiCommandHandlerEntry_t CommandEntryInterfaceSwitch = {
    .entry = { &fsqvbl_CommandHandlerInterfaceSwitch }, // connect the :INTerface:SWitch handler
    .ctx = NULL // grouped handler context
};

//// @CommandEntryMeasureInternalTemperature
//// Power:VEXTernal? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryExternalPower = {
//    .entry = { &fsqvbl_CommandHandlerPowerSWITCH_group }, // connect the POWer:VEXT handler
//    .ctx = &fsqvbl_CommandHandlerPowerVExternal // grouped handler context
//};
//
//// @CommandEntryMeasureInternalTemperature
//// Power:VBUS? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryVBUSPower = {
//    .entry = { &fsqvbl_CommandHandlerPowerSWITCH_group }, // connect the POWer:VBUS handler
//    .ctx = &fsqvbl_CommandHandlerPowerVBUS // grouped handler context
//};
//
//// @CommandEntryMeasureInternalTemperature
//// Power:EXT? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryEXTPower = {
//    .entry = { &fsqvbl_CommandHandlerPowerSWITCH_group }, // connect the POWer:EXT handler
//    .ctx = &fsqvbl_CommandHandlerPowerEXTernal // grouped handler context
//};
//
//// @CommandEntryMeasureInternalTemperature
//// Power:EXT? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryMeasPower = {
//    .entry = { &fsqvbl_CommandHandlerPowerSWITCH_group }, // connect the POWer:MEASurement handler
//    .ctx = &fsqvbl_CommandHandlerPowerMeasurement // grouped handler context
//};
//
//// @CommandEntryMeasureInternalTemperature
//// Power:AMPlifier:AMP1? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryAMP1Power = {
//    .entry = { &fsqvbl_CommandHandlerPowerSWITCH_group }, // connect the POWer:AMPlifier:AMP1 handler
//    .ctx = &fsqvbl_CommandHandlerPowerAMPlifier1 // grouped handler context
//};
//
//// @CommandEntryMeasureInternalTemperature
//// Power:AMPlifier:AMP2? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryAMP2Power = {
//    .entry = { &fsqvbl_CommandHandlerPowerSWITCH_group }, // connect the POWer:AMPlifier:AMP2 handler
//    .ctx = &fsqvbl_CommandHandlerPowerAMPlifier2 // grouped handler context
//};
//
//// @CommandEntryMeasureInternalTemperature
//// Power:AMPlifier:AMP3? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryAMP3Power = {
//    .entry = { &fsqvbl_CommandHandlerPowerSWITCH_group }, // connect the POWer:AMPlifier:AMP3 handler
//    .ctx = &fsqvbl_CommandHandlerPowerAMPlifier3 // grouped handler context
//};
//
//// @CommandEntryMeasureInternalTemperature
//// INDication:WRMP? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryWRMP = {
//    .entry = { &fsqvbl_CommandHandlerLEDSWITCH_group }, // connect the POWer:VBUS handler
//    .ctx = &fsqvbl_CommandHandlerWRMP // grouped handler context
//};
//
//// @CommandEntryMeasureInternalTemperature
//// INDication:LED:LED1? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryLED1 = {
//    .entry = { &fsqvbl_CommandHandlerLEDSWITCH_group }, // connect the POWer:VBUS handler
//    .ctx = &fsqvbl_CommandHandlerLED1 // grouped handler context
//};
//
//// @CommandEntryMeasureInternalTemperature
//// INDication:LED:LED1? command entry
//static const sScpiCommandHandlerEntry_t CommandEntryLED2 = {
//    .entry = { &fsqvbl_CommandHandlerLEDSWITCH_group }, // connect the POWer:VBUS handler
//    .ctx = &fsqvbl_CommandHandlerLED2 // grouped handler context
//};

// @CommandEntryTableAddPnts
// TABle:ADD
static const sScpiCommandHandlerEntry_t CommandEntryTableAddPnts = {
    .entry = { &fsqvbl_CommandHandlerTable_group }, // connect the TABLe:ADD handler
    .ctx = &fsqvbl_CommandHandlerTableMatrixAddPoints // grouped handler context
};

// @CommandEntryTableRemPnts
// TABle:CLR
static const sScpiCommandHandlerEntry_t CommandEntryTableClearTable = {
    .entry = { &fsqvbl_CommandHandlerTable_group }, // connect the TABLe:REM handler
    .ctx = &fsqvbl_CommandHandlerTableMatrixClear // grouped handler context
};

// @CommandEntryTableDone
// TABle:DONE
static const sScpiCommandHandlerEntry_t CommandEntryTableDone = {
    .entry = { &fsqvbl_CommandHandlerTable_group }, // connect the TABLe:DONE handler
    .ctx = &fsqvbl_CommandHandlerTableMatrixDone // grouped handler context
};

// @CommandEntryTableEdit
// TABle:EDIT
static const sScpiCommandHandlerEntry_t CommandEntryTableEdit = {
    .entry = { &fsqvbl_CommandHandlerTable_group }, // connect the TABLe:EDIT handler
    .ctx = &fsqvbl_CommandHandlerTableMatrixEdit // grouped handler context
};

// @CommandEntryTableGet
// TABle:GET
static const sScpiCommandHandlerEntry_t CommandEntryTableGet = {
    .entry = { &fsqvbl_CommandHandlerTable_group }, // connect the TABLe:GET handler
    .ctx = &fsqvbl_CommandHandlerTableMatrixGet // grouped handler context
};

// @CommandEntryPORT
// CTRL:SET:SW
static const sScpiCommandHandlerEntry_t CommandEntryPortSet = {
    .entry = { &fsqvbl_CommandHandlerCtrl_group }, // connect the CTRL:SW
    .ctx = &fsqvbl_CommandHandlerSwCtrl // grouped handler context
};

// @CommandEntryMeasStart
// MEAS:START
static const sScpiCommandHandlerEntry_t CommandEntryMeasStart = {
    .entry = { &fsqvbl_CommandHandlerCtrl_group }, // connect the MEAS:START
    .ctx = &fsqvbl_CommandHandlerMeasStart // grouped handler context
};
// @CommandEntryMeasStop
// MEAS:STOP
static const sScpiCommandHandlerEntry_t CommandEntryMeasStop = {
    .entry = { &fsqvbl_CommandHandlerCtrl_group }, // connect the MEAS:STOP
    .ctx = &fsqvbl_CommandHandlerMeasStop // grouped handler context
};
// @CommandEntryMeasContinue
// MEAS:CONTinue
static const sScpiCommandHandlerEntry_t CommandEntryMeasCont = {
    .entry = { &fsqvbl_CommandHandlerCtrl_group }, // connect the MEAS:CONT
    .ctx = &fsqvbl_CommandHandlerMeasCont // grouped handler context
};
// @CommandEntryMeasMode
// MEAS:MODE
static const sScpiCommandHandlerEntry_t CommandEntryMeasMode = {
    .entry = { &fsqvbl_CommandHandlerCtrl_group }, // connect the MEAS:MODE
    .ctx = &fsqvbl_CommandHandlerMeasMode // grouped handler context
};

// @CommandEntryTRIGger
// TRIGger:POLARity
static const sScpiCommandHandlerEntry_t CommandEntryTriggerPolarity = {
    .entry = { &fsqvbl_CommandHandlerTRIGgerSTATe_group }, // connect the TRIG:POLARity
    .ctx = &fsqvbl_CommandHandlerTriggerPolarity // grouped handler context
};

// @CommandEntryTRIGger
// TRIGger:COUNter
static const sScpiCommandHandlerEntry_t CommandEntryTriggerCounter = {
    .entry = { &fsqvbl_CommandHandlerTRIGgerSTATe_group }, // connect the TRIG:POLARity
    .ctx = &fsqvbl_CommandHandlerTriggerCounter // grouped handler context
};

// @CommandEntrySERVice
// SERVice:STATE
static const sScpiCommandHandlerEntry_t CommandEntryServiceState = {
    .entry = { &fsqvbl_CommandHandlerSERVice_group }, // connect the SERVice:STATE
    .ctx = &fsqvbl_CommandHandlerServiceState // grouped handler context
};

// @CommandEntrySERVice
// SERVice:SERIAL
static const sScpiCommandHandlerEntry_t CommandEntryServiceSerial = {
    .entry = { &fsqvbl_CommandHandlerSERVice_group }, // connect the SERVice:SERIAL
    .ctx = &fsqvbl_CommandHandlerSwitchSerial // grouped handler context
};

// @CommandEntrySERVice
// SERVice:MODEL
static const sScpiCommandHandlerEntry_t CommandEntryServiceModel = {
    .entry = { &fsqvbl_CommandHandlerSERVice_group }, // connect the SERVice:MODEL
    .ctx = &fsqvbl_CommandHandlerSwitchModel // grouped handler context
};

// @CommandEntrySERVice
// SERVice:REBOOT?
static const sScpiCommandHandlerEntry_t CommandEntryServiceReboot = {
    .entry = { &fsqvbl_CommandHandlerSERVice_group }, // connect the SERVice:REBOOT
    .ctx = &fsqvbl_CommandHandlerServiceReboot // grouped handler context
};

//// @NodeEntry_Amp_SWITch
//// "[:SYSTEM]:AMP:SWITch:" command node
//static const sTreeList_t NodeEntry_AMP[] = {
//    
//    // create '[:SYSTEM]:GAIN:COUNt' query, link @CommandEntryGainCount
//    DECLARE_TREE_LIST_CLEAF( "COUNt", &CommandEntryGainCount ),
//
//    // create '[:SYSTEM]:GAIN:LIST' query, link @CommandEntrySwitchList
//    DECLARE_TREE_LIST_CLEAF( "LIST", &CommandEntryAmpSwitchList ),
//
//    // create '[:SYSTEM]:GAIN:STATe' command/query, link @CommandEntrySwitchState
//    DECLARE_TREE_LIST_CLEAF( "STATe", &CommandEntrySwitchState ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};
//
//static const sTreeList_t  NodeEntry_FILT[] = {
//    // create '[:SYSTEM]:FILT:COUNt' query, link @CommandEntryFiltCount
//    DECLARE_TREE_LIST_CLEAF( "COUNt", &CommandEntryFiltCount ),
//
//    // create '[:SYSTEM]:FILT:LIST' query, link @CommandEntrySwitchList
//    DECLARE_TREE_LIST_CLEAF( "LIST", &CommandEntryFiltList ),
//
//    // create '[:SYSTEM]:FILT:STATe' command/query, link @CommandEntrySwitchState
//    DECLARE_TREE_LIST_CLEAF( "STATe", &CommandEntrySwitchBandState ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};
//
//// @NodeEntry_TEMP
//// "[:SYSTEM]:MEAS:TEMPerature:" command node
//static const sTreeList_t NodeEntry_TEMP[] = {
//    
//    // create 'MEASure:TEMP:INTernal' query, link @CommandEntryMeasureIntTemperature
//    DECLARE_TREE_LIST_CLEAF( "INTernal", &CommandEntryMeasureIntTemperature ),
//
//    // create 'MEASure:TEMP:EXTernal' query, link @CommandEntryMeasureExtTemperature
//    DECLARE_TREE_LIST_CLEAF( "EXTernal", &CommandEntryMeasureExtTemperature ),
//    
//    // create 'MEASure:TEMP:TCOEFficient' query, link @CommandEntrySwitchList
//    DECLARE_TREE_LIST_CLEAF( "TCOEFficient", &CommandEntryMeasureExtTempCoefficient ),
//    
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};
//
//// @NodeEntry_AMPlifier
//// "POWer:AMPlifier:AMP:" command node
//static const sTreeList_t NodeEntry_AMPlifier[] = {
//  
//    // create 'MEASure:TEMP:INTernal' query, link @CommandEntryMeasureIntTemperature
//    DECLARE_TREE_LIST_CLEAF( "AMP1", &CommandEntryAMP1Power ),
//
//    // create 'MEASure:TEMP:EXTernal' query, link @CommandEntryMeasureExtTemperature
//    DECLARE_TREE_LIST_CLEAF( "AMP2", &CommandEntryAMP2Power ),
//    
//    // create 'MEASure:TEMP:TCOEFficient' query, link @CommandEntrySwitchList
//    DECLARE_TREE_LIST_CLEAF( "AMP3", &CommandEntryAMP3Power ),
//    
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};
//
//// @NodeEntry_LED
//// "INDication:LED:LED[1,2]" command node
//static const sTreeList_t NodeEntry_LED[] = {
//  
//    // create 'MEASure:TEMP:INTernal' query, link @CommandEntryMeasureIntTemperature
//    DECLARE_TREE_LIST_CLEAF( "LED1", &CommandEntryLED1 ),
//
//    // create 'MEASure:TEMP:EXTernal' query, link @CommandEntryMeasureExtTemperature
//    DECLARE_TREE_LIST_CLEAF( "LED2", &CommandEntryLED2 ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};

static const sTreeList_t NodeEntry_CONTrol[] = {
    // create ':CTRL:SW' query, link @CommandEntryPortSet
    DECLARE_TREE_LIST_CLEAF( "SW", &CommandEntryPortSet ),
    DECLARE_TREE_LIST_LAST() // end-of-list
};

static const sTreeList_t NodeEntry_MEASure[] = {
    // create ':MEAS:START' query, link @CommandEntryMeasStart
    DECLARE_TREE_LIST_CLEAF( "START", &CommandEntryMeasStart ),

    // create ':MEAS:STOP' query, link @CommandEntryMeasStop
    DECLARE_TREE_LIST_CLEAF( "STOP", &CommandEntryMeasStop ),
    
    // create ':MEAS:CONTinue' query, link @CommandEntryMeasCont
    DECLARE_TREE_LIST_CLEAF( "CONTinue", &CommandEntryMeasCont ),
    
    // create ':MEAS:MODE' query, link @CommandEntryMeasMode
    DECLARE_TREE_LIST_CLEAF( "MODE", &CommandEntryMeasMode ),
    
    DECLARE_TREE_LIST_LAST() // end-of-list
};

static const sTreeList_t NodeEntry_TRIGger[] = {
    // create ':TRIGger:POLARity' query, link @CommandEntryTRIGgerPolarity
    DECLARE_TREE_LIST_CLEAF( "POLarity", &CommandEntryTriggerPolarity ),
    
    // create ':TRIGger:POLARity' query, link @CommandEntryTRIGgerPolarity
    DECLARE_TREE_LIST_CLEAF( "COUNter", &CommandEntryTriggerCounter ),
    
    DECLARE_TREE_LIST_LAST() // end-of-list
};

static const sTreeList_t NodeEntry_SERVice[] = {
    // create 'SERVice:STATE' query, link @CommandEntryServiceState
    DECLARE_TREE_LIST_CLEAF( "STATE", &CommandEntryServiceState ),
    
    // create 'SERVice:SERIAL' query, link @CommandEntryServiceSerial
    DECLARE_TREE_LIST_CLEAF( "SERIAL", &CommandEntryServiceSerial ),
        
    // create 'SERVice:MODEL' query, link @CommandEntryServiceModel
    DECLARE_TREE_LIST_CLEAF( "MODEL", &CommandEntryServiceModel ),
    
    // create 'SERVice:REBOOT?' query, link @CommandEntryServiceREBOOT
    DECLARE_TREE_LIST_CLEAF( "REBOOT", &CommandEntryServiceReboot ),
    
    DECLARE_TREE_LIST_LAST() // end-of-list
};

static const sTreeList_t NodeEntry_TABle[] = {
    // create 'TABLe:ADD:' query, link @CommandEntryTableAdd...
    DECLARE_TREE_LIST_CLEAF( "ADD", &CommandEntryTableAddPnts ),
    
    // create 'TABLe:CLR:' query, link @CommandEntryTableRemove...
    DECLARE_TREE_LIST_CLEAF( "CLR", &CommandEntryTableClearTable ),
    
    // create 'TABLe:DONE' query, link @CommandEntryTableDone
    DECLARE_TREE_LIST_CLEAF( "DONE", &CommandEntryTableDone ),
    
    // create 'TABLe:EDIT' query, link @CommandEntryTableEdit
    DECLARE_TREE_LIST_CLEAF( "EDIT", &CommandEntryTableEdit ),
    
    // create 'TABLe:GET' query, link @CommandEntryTableGet
    DECLARE_TREE_LIST_CLEAF( "GET", &CommandEntryTableGet ),
    
    DECLARE_TREE_LIST_LAST() // end-of-list
};

// @NodeEntry_SYSTem
// ":SYSTem:" command node
static const sTreeList_t NodeEntry_SYSTem[] = {
    
//    // create ':SYSTem:GAIN' sub-system command for SCPI
//    DECLARE_TREE_LIST_CNODE( "GAIN",  NodeEntry_AMP ),
//    
    // create ':SYSTem:CTRL' sub-system command for SCPI
    DECLARE_TREE_LIST_CNODE( "CTRL",  NodeEntry_CONTrol ),
    
    // create ':SYSTem:MEASure' sub-system command for SCPI
    DECLARE_TREE_LIST_CNODE( "MEASure",  NodeEntry_MEASure ),
    
    // create ':SYSTem:TABLe' sub-system command for SCPI
    DECLARE_TREE_LIST_CNODE( "TABLe",  NodeEntry_TABle ),
    
    // create ':SYSTem:TRIGger' sub-system command for SCPI
    DECLARE_TREE_LIST_CNODE( "TRIGger",  NodeEntry_TRIGger ),
    
    // create ':SYSTem:SERVice' sub-system command for SCPI
    DECLARE_TREE_LIST_CNODE( "SERVice",  NodeEntry_SERVice ),

    // create ':SYSTem:ERRor' query, link @CommandEntrySystemError
    DECLARE_TREE_LIST_CLEAF( "ERRor", &CommandEntrySystemError ),

    // create ':SYSTem:VERSion' query, link @CommandEntrySystemVersion
    DECLARE_TREE_LIST_CLEAF( "VERSion", &CommandEntrySystemVersion ),

    DECLARE_TREE_LIST_LAST() // end-of-list
};

//// @NodeEntry_MEASure
//// ":MEASure:" command node
//static const sTreeList_t NodeEntry_MEASure[] = {
//    
//    // create ':MEASure:TEMPerature' query, link @CommandEntryMeasureTemperature
//    //DECLARE_TREE_LIST_CLEAF( "TEMPerature", &CommandEntryMeasureTemperature ),
//    DECLARE_TREE_LIST_CNODE( "TEMPerature",  NodeEntry_TEMP ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};
//
//// @NodeEntry_POWer
//// ":POWer:" command node
//static const sTreeList_t NodeEntry_POWer[] = {
//    
//    DECLARE_TREE_LIST_CLEAF( "P28Voltage",  &CommandEntryExternalPower ),
//    
//    // Development command list
//    DECLARE_TREE_LIST_CLEAF( "VBUS", &CommandEntryVBUSPower ),
//    
//    DECLARE_TREE_LIST_CLEAF( "EXTernal",  &CommandEntryEXTPower ),
//    
//    DECLARE_TREE_LIST_CLEAF( "MEASurement",  &CommandEntryMeasPower ),
//    
//    DECLARE_TREE_LIST_CNODE( "AMPlifier",  NodeEntry_AMPlifier ),
//   // DECLARE_TREE_LIST_CLEAF( "AMPlifier",  &CommandEntryMeasureIntTemperature ),
//    
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};
//
//// @NodeEntry_INDIcation
//// ":INDIcation:" command node
//static const sTreeList_t NodeEntry_INDication[] = {
//    
//    DECLARE_TREE_LIST_CNODE( "LED",  NodeEntry_LED ),
//    
//    // Development command list
//    DECLARE_TREE_LIST_CLEAF( "WRMP", &CommandEntryWRMP ),
//
//    DECLARE_TREE_LIST_LAST() // end-of-list
//};

// @NodeEntry_INTerface
// ":INTerface:" command node
static const sTreeList_t NodeEntry_INTerface[] = {
    
    // create ':INTerface:SWitch' query, link @CommandEntryInterfaceSwitch
    DECLARE_TREE_LIST_CLEAF( "SWitch", &CommandEntryInterfaceSwitch ),

    DECLARE_TREE_LIST_LAST() // end-of-list
};
// --------------------------------------------------------------------------------------------------------

// @CommandEntryIDN
// *IDN? command entry
static const sScpiCommandHandlerEntry_t CommandEntryIDN = {
    .entry = { &fsqvbl_CommandHandlerIDN }, // connect the IDN handler
    .ctx = NULL
};

// @CommandEntryRST
// *RST command entry
static const sScpiCommandHandlerEntry_t CommandEntryRST = {
    .entry = { &fsqvbl_CommandHandlerRST }, // connect the RST handler
    .ctx = NULL
};

// @CommandEntryESR
// *ESR command entry
static const sScpiCommandHandlerEntry_t CommandEntryESR = {
    .entry = { &fsqvbl_CommandHandlerESRSTB }, // connect the ESR handler
    .ctx = &fsqvbl_CommandHandlerESR_context // grouped handler context
};

// @CommandEntrySTB
// *STB command entry
static const sScpiCommandHandlerEntry_t CommandEntrySTB = {
    .entry = { &fsqvbl_CommandHandlerESRSTB }, // connect the ESR handler
    .ctx = &fsqvbl_CommandHandlerSTB_context // grouped handler context
};

// @CommandEntryESE
// *ESE command/query entry
static const sScpiCommandHandlerEntry_t CommandEntryESE = {
    .entry = { &fsqvbl_CommandHandlerESESRE }, // connect the ESE handler
    .ctx = &fsqvbl_CommandHandlerESE_context // handler context
};

// @CommandEntrySRE
// *SRE command/query entry
static const sScpiCommandHandlerEntry_t CommandEntrySRE = {
    .entry = { &fsqvbl_CommandHandlerESESRE }, // connect the SRE handler
    .ctx = &fsqvbl_CommandHandlerSRE_context // handler context
};

// @CommandEntryCLS
// *CLS command entry
static const sScpiCommandHandlerEntry_t CommandEntryCLS = {
    .entry = { &fsqvbl_CommandHandlerCLS }, // connect the CLS handler
    .ctx = NULL
};

// @CommandEntryOPC
// *OPC command entry
static const sScpiCommandHandlerEntry_t CommandEntryOPC = {
    .entry = { &fsqvbl_CommandHandlerOPC }, // connect the CLS handler
    .ctx = NULL
};

// @CommandEntryTRG
// *TRG command entry
static const sScpiCommandHandlerEntry_t CommandEntryTRG = {
    .entry = { &fsqvbl_CommandHandlerTRG }, // connect the TRG handler
    .ctx = NULL
};
#if 0
// @CommandEntryTEST
// *TEST? command entry
static const sScpiCommandHandlerEntry_t CommandEntryTEST = {
    .entry = { &fsqvbl_CommandHandlerTEST }, // connect the TEST handler
    .ctx = NULL
};
#endif
// ========================================================================================================
// @scpi_commands_root_list
// Contains all supported commands and handlers as a tree.
// Each group of commands shall be implemented as an external
// ... array of sTreeList_t[] and referred by DECLARE_TREE_LIST_NODE.
// Each command shall be implemented as a cell of array using
// ... DECLARE_TREE_LIST_LEAF.
// The command shall not contain question mark character in the 
// ... end for proper operation.
// The command shall not contain colon character in the beginning
// ... for proper operation.
// The command can have either full and short forms in the
// ... same entry while the leading UPPER case characters 
// ... of each mnemonic express the short form and the lower  
// ... case characters in the ending of each mnemonic express
// ... the full form, e.g:
// COMmand1:SUBCommand2 represents short form "COM:SUBC" and
// ... the full one - "COMMAND1:SUBCOMMAND2".
// Operator is free about of combining the forms of each mnemonic,
// ... thus COMMAND1:SUBC is a valid command.
static const sTreeList_t scpi_commands_root_list[] = {

    // create *IDN? command, link @CommandEntryIDN entry 
    DECLARE_TREE_LIST_CLEAF( "*IDN",    &CommandEntryIDN ),

    // create *RST command, link @CommandEntryRST entry
    DECLARE_TREE_LIST_CLEAF( "*RST",    &CommandEntryRST ),

    // create *CLS command, link @CommandEntryRST entry
    DECLARE_TREE_LIST_CLEAF( "*CLS",    &CommandEntryCLS ),

    // create *ESR? query, link @CommandEntryESR entry
    DECLARE_TREE_LIST_CLEAF( "*ESR",    &CommandEntryESR ),

    // create *STB? query, link @CommandEntrySTB entry
    DECLARE_TREE_LIST_CLEAF( "*STB",    &CommandEntrySTB ),

    // create *ESE command/query, link @CommandEntryESR entry
    DECLARE_TREE_LIST_CLEAF( "*ESE",    &CommandEntryESE ),

    // create *SRE command/query, link @CommandEntrySRE entry
    DECLARE_TREE_LIST_CLEAF( "*SRE",    &CommandEntrySRE ),

    // create *OPC command/query, link @CommandEntryOPC entry
    DECLARE_TREE_LIST_CLEAF( "*OPC",    &CommandEntryOPC ),

    // create *TRG command/query, link @CommandEntryTRG entry
    DECLARE_TREE_LIST_CLEAF( "*TRG",    &CommandEntryTRG ),
#if 0
    // create *TEST? query, link @CommandEntryTEST entry
    DECLARE_TREE_LIST_CLEAF( "*TEST",   &CommandEntryTEST ),
#endif
    // create 'SYSTem' sub-system command for SCPI
    DECLARE_TREE_LIST_CNODE( "[SYSTem]", NodeEntry_SYSTem ),
    
//    // create 'SYSTem' sub-system command for SCPI
//    DECLARE_TREE_LIST_CNODE( "TABle", NodeEntry_TABle ),

//    // create ':MEMory' sub-system command for SCPI
//    DECLARE_TREE_LIST_CNODE( "MEMory",  NodeEntry_MEMory ),

    // create ':MEASure' sub-system command for SCPI
    //DECLARE_TREE_LIST_CNODE( "MEASure",  NodeEntry_MEASure ),
    
    // create ':POWer' sub-system command for SCPI
    //DECLARE_TREE_LIST_CNODE( "POWer",  NodeEntry_POWer ),
    
    // create ':INDication' sub-system command for SCPI
    //DECLARE_TREE_LIST_CNODE( "INDIcation",  NodeEntry_INDication ),

    // create ':INTerface' sub-system command for SCPI
    DECLARE_TREE_LIST_CNODE( "INTerface",NodeEntry_INTerface ),

    DECLARE_TREE_LIST_LAST() // end-of-list
};
 
// ========================================================================================================
// @scpi_commands_root_node
// Entire the supported SCPI commands tree (global root branch)
const sTreeList_t scpi_commands_root_node = DECLARE_TREE_LIST_CNODE( "/",  scpi_commands_root_list );

// ========================================================================================================

void scpi_command_test()
{
    const char * command = "*idn?"; // "MeMoRy:TABL:DATA?" "MeM:TABLe:DATA?"
    const char * shead = command;
    const char * stail = shead + strlen(command);

    const sTreeList_t * branch = NULL;

    const sScpiCommandHandlerEntry_t * cmd = scpiSearchCommandHandler( &branch, shead, stail, eScpiEntityTypeCmpQueryProgHdr, NULL, false );

    (void)cmd;

    asm( "bkpt #0" );

    command = "mem:table:data?"; // "MeMoRy:TABL:DATA?" "MeM:TABLe:DATA?"
    shead = command;
    stail = shead + strlen(command);

    cmd = scpiSearchCommandHandler( &branch, shead, stail, eScpiEntityTypeCmpQueryProgHdr, NULL, false );

    (void)cmd;

    asm( "bkpt #0" );
}