====== CLI parser ====== Data structure is a lookup tree. Each node is structured as such: ^ arg_node ^ | char* full_name | | char* quick_name | | size_t nb_leaves | | bool has_arg | | arg_node **leaves | | callback_t callback | The command parser works as such: typedef void (*callback_t)( const char* command, size_t offset); arg_node cfg_root = ....; arg_node *cfg_cur = cfg_root; void process_cmd( arg_node *cfg_cur, const char* command, size_t offset=0;) { size_t kwd_len=0; size_t arg_len=0; char* keyword = command+offset; char* arg = null; // Search the next argument boundary while( keyword[kwd_len] != '\0' && keyword[kwd_len] != ' ') ++kwd_len; // If we don't have an argument, attempt to call the node's callback method. if( kwd_len == 0 ) { if( cfg_cur->callback != null && cfg_cur->has_arg == false) { cfg_cur->callback( command); } else { Serial.print( F("Incomplete command.\r\n")); } return; } if ( cfg_cur->has_arg == true ) { // This node has an argument. arg = command+offset+kwd_len+1; // Attempt to get the size of the argument while( arg[kwd_len] != '\0' && arg[kwd_len] != ' ' ) ++arg_len; if( arg_len == 0 ) { Serial.print( F("Incomplete command.\r\n")); return; } } if( cfg_cur->leaves != null ) { for( size_t i=0; inb_leaves; ++i) { if( strncmp( cfg_cur->leaves[i]->quick_name, keyword, kwd_len) == 0) { // Positive match process_cmd( cfg_cur->leaves[i], command, offset+kwd_len+1) return; } } } // If we reach here, none of the leaves matched the next argument. Serial.print( F("Unrecognized command.\r\n")); }