void validate_node( TEMPLATE_NODE& node ) { switch ( node.type ) { case NODE_TYPE_CONTENT: { assert( node.child_nodes.size() == 0 ); break; } case NODE_TYPE_BEGIN_TEMPLATE: { for ( unsigned int i=0; i<node.child_nodes.size(); i++ ) validate_node( node.child_nodes[i] ); break; } case NODE_TYPE_IF: { int child_cnt = node.child_nodes.size(); assert( child_cnt == 1 || node.child_nodes.size() == 2 ); if ( child_cnt == 1 ) { assert( node.child_nodes[0].type == NODE_TYPE_IF_TRUE_BRANCHE || node.child_nodes[0].type == NODE_TYPE_IF_FALSE_BRANCHE ); } else { assert( node.child_nodes[0].type == NODE_TYPE_IF_TRUE_BRANCHE ); assert( node.child_nodes[1].type == NODE_TYPE_IF_FALSE_BRANCHE ); } for ( unsigned int i=0; i<node.child_nodes.size(); i++ ) validate_node( node.child_nodes[i] ); break; } case NODE_TYPE_ASSERT: { int child_cnt = node.child_nodes.size(); assert( child_cnt == 0 ); break; } case NODE_TYPE_FOR_EACH_OF_MEMBERS: case NODE_TYPE_IF_TRUE_BRANCHE: case NODE_TYPE_IF_FALSE_BRANCHE: { for ( unsigned int i=0; i<node.child_nodes.size(); i++ ) validate_node( node.child_nodes[i] ); break; } case NODE_TYPE_INCLUDE: { assert( 0 == "ERROR: NOT IMPLEMENTED" ); break; } } }
rmw_ret_t rmw_get_service_names_and_types( const rmw_node_t * node, rcutils_allocator_t * allocator, rmw_names_and_types_t * service_names_and_types) { rmw_ret_t ret = validate_node(node, allocator); if (ret != RMW_RET_OK) { return ret; } ret = rmw_names_and_types_check_zero(service_names_and_types); if (ret != RMW_RET_OK) { return ret; } auto node_info = static_cast<OpenSpliceStaticNodeInfo *>(node->data); // combine publisher and subscriber information std::map<std::string, std::set<std::string>> services; node_info->publisher_listener->fill_service_names_and_types(services); node_info->subscriber_listener->fill_service_names_and_types(services); rmw_ret_t rmw_ret; rmw_ret = copy_services_to_names_and_types(services, allocator, service_names_and_types); if (rmw_ret != RMW_RET_OK) { return rmw_ret; } return RMW_RET_OK; }
void validate_node(std_config_node_t node) { const struct test_config_node *test_node_ptr=NULL; std_config_node_t child_node; int attr_id=0; const char *attr_name; test_node_ptr=&(test_config_data[node_id]); printf("%s:%d node_id: %d names: expected:%s found %s\n", __FUNCTION__, __LINE__, node_id, std_config_name_get(node), test_node_ptr->name); ASSERT_EQ(strcmp(std_config_name_get(node), test_node_ptr->name), 0); for(; (attr_id<TEST_MAX_ATTRS) && (test_node_ptr->attrs[attr_id].name != NULL); attr_id++) { attr_name=test_node_ptr->attrs[attr_id].name; printf("%s:%d attribute %s: expected:%s found %s\n", __FUNCTION__, __LINE__, attr_name, test_node_ptr->attrs[attr_id].value, std_config_attr_get(node, attr_name)); ASSERT_EQ(strcmp(test_node_ptr->attrs[attr_id].value, std_config_attr_get(node, attr_name)), 0); } /* Check the child nodes */ for (child_node=std_config_get_child(node); (child_node != NULL); child_node=std_config_next_node(child_node)) { node_id++; validate_node(child_node); } }
/* * 0 Valid * -1 Invalid Field Name * -2 Type Mismatch */ int validate_filter(node_t *root, fielddefset_t *fields) { int valid; if (!root) { return 1; } valid = validate_node(root, fields); if (!valid) { return 0; } return (validate_filter(root->left_child, fields) && validate_filter(root->right_child, fields)); }
TEST(std_config_node_test, walk_elements_attributes) { std_config_hdl_t file_hdl; file_hdl=std_config_load(fname); ASSERT_NE((uintptr_t)file_hdl, (uintptr_t)NULL); std_config_node_t node=std_config_get_root(file_hdl); node_id=0; validate_node(node); std_config_unload(file_hdl); }
int load_template( FILE* ft, ANY_TEMPLATE_ROOT& _root_node, int* current_line_num ) { if ( ft == NULL ) { printf( "error: no input file\n" ); return FAILED_INTERNAL; } TEMPLATE_NODES nodes; // it is assumed here that starting from a current position in a file any content other than the beginning and the rest of template can be safely ignored bool start_found = false; unsigned int content_start = 0; bool end_found = false; for( ;;) // through all nodes, find template beginning { std::string line; if ( !read_line( ft, line, content_start, current_line_num ) ) break; if ( content_start == line.size() ) continue; // no content if ( line[content_start] == '@' && content_start + 1 < line.size() && line[content_start+1] == '@' ) // this is only what we expect at the beginning of any service line { content_start += 2; while ( content_start < line.size() && (line[content_start] == ' ' || line[content_start] == '\t')) content_start++; if ( line.compare( content_start, sizeof(PARAM_STRING_BEGIN_TEMPLATE)-1, PARAM_STRING_BEGIN_TEMPLATE ) == 0 ) { content_start += sizeof(PARAM_STRING_BEGIN_TEMPLATE)-1; while ( content_start < line.size() && (line[content_start] == ' ' || line[content_start] == '\t')) content_start++; // read name while ( content_start < line.size() && (!(line[content_start] == ' ' || line[content_start] == '\t'))) _root_node.name.push_back( line[content_start++] ); while ( content_start < line.size() && (line[content_start] == ' ' || line[content_start] == '\t')) content_start++; if ( line.compare( content_start, sizeof(PARAM_STRING_TYPE)-1, PARAM_STRING_TYPE ) != 0 ) { printf( "line %d: error: no \"%s\" after \"%s\"\n", *current_line_num, PARAM_STRING_TYPE, PARAM_STRING_BEGIN_TEMPLATE ); return FAILED_ERROR; // TODO: make sure the decision is correct in all cases + error analysis and reporting } content_start += sizeof(PARAM_STRING_TYPE)-1; while ( content_start < line.size() && (line[content_start] == ' ' || line[content_start] == '\t')) content_start++; if ( content_start < line.size() && line[content_start] != '=' ) { printf( "line %d: error: no \"%s\" after \"%s\"\n", *current_line_num, "=", PARAM_STRING_TYPE ); return FAILED_ERROR; // TODO: make sure the decision is correct in all cases + error analysis and reporting } content_start++; while ( content_start < line.size() && (line[content_start] == ' ' || line[content_start] == '\t')) content_start++; // read type while ( content_start < line.size() && (!(line[content_start] == ' ' || line[content_start] == '\t'))) _root_node.type.push_back( line[content_start++] ); while ( content_start < line.size() && (line[content_start] == ' ' || line[content_start] == '\t')) content_start++; if ( !( content_start == line.size() ) ) { printf( "line %d: error: unexpected tokens\n", *current_line_num ); return FAILED_ERROR; // TODO: make sure the decision is correct in all cases + error analysis and reporting } start_found = true; break; } } // at this point a template has started... } if ( !start_found ) { if ( nodes.size() ) { printf( "line %d: error: no no template has been found\n", *current_line_num ); return FAILED_ERROR; // TODO: make sure the decision is correct in all cases + error analysis and reporting } else { return NO_MORE_TEMPLATES; } } // go through other nodes for( ;;) // through all nodes, find template beginning { TEMPLATE_NODE tl; std::string line; if ( !read_line( ft, line, content_start, current_line_num ) ) break; bool is_content = line.compare( content_start, 2, "@@" ) != 0; if ( is_content ) // an empty line => not ctr line => content line => keep "as is" { tl.src_line_num = *current_line_num; tl.type = NODE_TYPE_CONTENT; parse_line_content( line, tl.line_parts, NODE_TYPE_CONTENT, 0 ); // tl.content = line; nodes.push_back( tl ); continue; } int kwd = parse_main_keyword( line, content_start ); // unexpected template start if ( kwd == NODE_TYPE_BEGIN_TEMPLATE ) { printf( "line %d: error: \"%s\" is unexpected\n", *current_line_num, PARAM_STRING_BEGIN_TEMPLATE ); return FAILED_ERROR; } // is template end? if ( kwd == NODE_TYPE_END_TEMPLATE ) { // read name std::string end_name; while ( content_start < line.size() && (!(line[content_start] == ' ' || line[content_start] == '\t'))) end_name.push_back( line[content_start++] ); if ( end_name != _root_node.name ) { printf( "line %d: error: name does not match that at template beginning\n", *current_line_num ); return FAILED_ERROR; } while ( content_start < line.size() && (line[content_start] == ' ' || line[content_start] == '\t')) content_start++; if ( !( content_start == line.size() || ( content_start + 1 == line.size() || line[content_start] == '\r' ) ) ) { printf( "line %d: error: unexpected tokens\n", *current_line_num ); return FAILED_ERROR; // TODO: make sure the decision is correct in all cases + error analysis and reporting } end_found = true; break; } // other control nodes tl.src_line_num = *current_line_num; tl.type = kwd; switch ( kwd ) { case NODE_TYPE_IF: case NODE_TYPE_ELIF: case NODE_TYPE_ASSERT: { parse_if_condition( std::string( line.begin() + content_start, line.end() ), tl.line_parts, NODE_TYPE_CONTENT, 0 ); break; } case NODE_TYPE_FOR_EACH_OF_MEMBERS: { unsigned int content_start_1 = 0; std::string remaining = std::string( line.begin() + content_start, line.end() ); int param = parse_param( remaining, content_start_1 ); bool good_param = param == PARAM_BEGIN || param == PARAM_END; if ( !good_param ) { printf( "line %d: error: \"%s\" or \"%s\" is expected after \"%s\"\n", *current_line_num, PARAM_STRING_BEGIN, PARAM_STRING_END, KEYWORD_STRING_FOR_EACH_OF_MEMBERS ); return FAILED_ERROR; } LINE_PART part; part.type = param; tl.line_parts.push_back( part ); skip_spaces( remaining, content_start ); if ( content_start < remaining.size() ) { printf( "line %d: error: unexpected token(s) \"%s\"\n", *current_line_num, std::string( remaining.begin() + content_start, remaining.end() ) ); return FAILED_ERROR; } break; } default: { LINE_PART part; part.type = LINE_PART_VERBATIM; part.verbatim = std::string( line.begin() + content_start, line.end() ); tl.line_parts.push_back( part ); } } nodes.push_back( tl ); } if ( !end_found ) { printf( "line %d: error: \"%s\" not found\n", *current_line_num, PARAM_STRING_END_TEMPLATE ); return FAILED_ERROR; // TODO: make sure the decision is correct in all cases + error analysis and reporting } _root_node.type = NODE_TYPE_BEGIN_TEMPLATE; _root_node.root.type = NODE_TYPE_TEMPLATE_ROOT; bool tree_ok = make_node_tree( _root_node.root, nodes.begin(), nodes.end() ); if ( !tree_ok ) { printf( "line %d: error: building tree failed\n", _root_node.src_line_num ); return FAILED_BUID_TREE_ERROR; // TODO: make sure the decision is correct in all cases + error analysis and reporting } validate_node( _root_node.root ); return OK; }