void printTreeNode(void * node) { if(node == NULL) { std::cout << "TreeNode - NULL" << std::endl; return; } TreeNode * data = (TreeNode *)node; std::cout << "TreeNode" << std::endl; std::cout << " |lineno: " << data->lineno; std::cout << " |numChildren: " << data->numChildren; std::cout << " |isArray: " << data->isArray; std::cout << " |isIndex: " << data->isIndex; std::cout << " |isStatic: " << data->isStatic; std::cout << std::endl; std::cout << " |nodekind: " << nodekindToStr(data->nodekind); std::cout << " |kind: " << data->kind; std::cout << " |nodetype: " << typeToStr(data->nodetype); std::cout << std::endl; // TODO: print children? if( data->sibling != NULL ) { std::cout << " |Sibling: " << data->sibling->svalue != NULL ? data->sibling->svalue : ""; std::cout << std::endl; } std::cout << " |svalue: " << data->svalue != NULL ? data->svalue : ""; std::cout << "\n\n" << std::endl; printTokenData(data->token); }
//------------------------------------------------------------------------------ //! String Event::toStr() const { String tmp; tmp += "{"; tmp += typeToStr(type()); tmp += ","; tmp += String().format("t=%f", timestamp()); tmp += ","; switch( type() ) { case POINTER_PRESS : case POINTER_RELEASE: case POINTER_MOVE : case POINTER_ENTER : case POINTER_LEAVE : case POINTER_CHANGE : case POINTER_SCROLL : case POINTER_DELETE : case POINTER_CANCEL : { tmp += String().format( "ptrID=%d", pointerID() ); tmp += ","; tmp += String().format( "val=%d", value() ); tmp += ","; tmp += String().format( "pos=(%f,%f)", position().x, position().y ); tmp += ","; tmp += String().format( "cnt=%d", count() ); } break; case KEY_PRESS: case KEY_RELEASE: case CHAR: { tmp += String().format( "val=%d", value() ); tmp += ","; tmp += String().format( "cnt=%d", count() ); } break; case HID_EVENT: { tmp += String().format( "devTypeID=%d", deviceTypeID() ); tmp += ","; tmp += String().format( "devID=%d", deviceID() ); tmp += ","; tmp += String().format( "ctrlID=%d", controlID() ); tmp += ","; tmp += String().format( "val=%f", valueFloat() ); } break; case ACCELERATE: { tmp += String().format( "(%f,%f,%f", dx(), dy(), dz() ); } break; default: break; } tmp += "}"; return tmp; }
static gchar* buildColInfo( packet_info *pinfo, guint8 payloadLen, guint8 dataType, MySensors_Command commandType, guint8 reqack, guint8 isack, guint8 type, guint8 sensor, tvbuff_t* tvb_data ) { static gchar buff[100]; gchar* s = buff; s += sprintf( s, "Cmd:%s, ReqAck:%d, IsAck:%d, Type:%s, Sns:%d", val_to_str(commandType, command_types, "%d"), reqack, isack, typeToStr(commandType, type), sensor ); if (payloadLen > 0) { s += sprintf( s, ", Data:%s [%s]", payloadToStr(dataType, tvb_data, payloadLen), val_to_str(dataType, payload_types, "%d") ); } return buff; }
bool parse32( FILE * fh ) { Elf32_Ehdr hdr; unsigned size = sizeof(Elf32_Ehdr)-offsetof(Elf32_Ehdr, e_type); if( 1 != fread( &hdr.e_type, size, 1, fh ) ) { fprintf( stderr, "Failed to read header\n" ); return false; } printf( "type =%s\n", typeToStr(hdr.e_type) ); printf( "machine =%s\n", machineToStr(hdr.e_machine) ); printf( "version =%u\n", hdr.e_version ); printf( "entry pt virt addr: %u\n", hdr.e_entry ); printf( "prog hdr tbl file off: %u\n", hdr.e_phoff ); printf( "sect hdr tbl file off: %u\n", hdr.e_shoff ); printf( "proc spec flags: %u\n", hdr.e_flags ); printf( "elf hdr size (bytes): %u\n", hdr.e_ehsize ); printf( "prog hdr tbl ent size: %u\n", hdr.e_phentsize ); printf( "prog hdr tbl ent cnt: %u\n", hdr.e_phnum ); printf( "sect hdr tbl ent size: %u\n", hdr.e_shentsize ); printf( "sect hdr tbl ent cnt: %u\n", hdr.e_shnum ); printf( "sect hdr str tbl ndx %u\n", hdr.e_shstrndx ); std::vector<Elf32_Phdr> pHeaders; bool rc = parse32ProgHeaderTable( fh, hdr.e_phoff, hdr.e_phentsize, hdr.e_phnum, pHeaders ); std::vector<Elf32_Shdr> sHeaders; rc &= parse32SectHeaderTable( fh, hdr.e_shoff, hdr.e_shentsize, hdr.e_shnum, hdr.e_shstrndx, sHeaders ); return true; }
std::string CardStat::getTypes() const { std::string result = (supertypes ? typeToStr(SuperType(supertypes)) + " " : "") + typeToStr(CardType(cardTypes)) + (artifactType ? std::string(" ") + typeToStr(artifactType) : "") + (enchantmentType ? std::string(" ") + typeToStr(enchantmentType) : "") + (spellType ? std::string(" ") + typeToStr(spellType) : "") + (tribalType ? std::string(" ") + typeToStr(tribalType) : "") + (planeswalker ? std::string(" ") + typeToStr(planeswalker->type) : "") ; if( land ) { result += fetchTypes(land->types,&typeToStr<LandType>); } if( creature ) { result += fetchTypes(creature->types,&typeToStr<CreatureType>); } return result; }
bool parse64( FILE * fh ) { Elf64_Ehdr hdr; unsigned size = sizeof(Elf64_Ehdr)-offsetof(Elf64_Ehdr, e_type); if( 1 != fread( &hdr.e_type, size, 1, fh ) ) { fprintf( stderr, "Failed to read header\n" ); return false; } printf( "type =%s\n", typeToStr(hdr.e_type) ); printf( "machine =%s\n", machineToStr(hdr.e_machine) ); printf( "version =%u\n", hdr.e_version ); printf( "entry pt virt addr: %lu\n", hdr.e_entry ); printf( "prog hdr tbl file off: %lu\n", hdr.e_phoff ); printf( "sect hdr tbl file off: %lu\n", hdr.e_shoff ); printf( "proc spec flags: %u\n", hdr.e_flags ); printf( "elf hdr size (bytes): %u\n", hdr.e_ehsize ); printf( "prog hdr tbl ent size: %u\n", hdr.e_phentsize ); printf( "prog hdr tbl ent cnt: %u\n", hdr.e_phnum ); printf( "sect hdr tbl ent size: %u\n", hdr.e_shentsize ); printf( "sect hdr tbl ent cnt: %u\n", hdr.e_shnum ); printf( "sect hdr str tbl ndx %u\n", hdr.e_shstrndx ); std::vector<Elf64_Phdr> pHeaders; bool rc = parse64ProgHeaderTable( fh, hdr.e_phoff, hdr.e_phentsize, hdr.e_phnum, pHeaders ); std::vector<Elf64_Shdr> sHeaders; rc &= parse64SectHeaderTable( fh, hdr.e_shoff, hdr.e_shentsize, hdr.e_shnum, hdr.e_shstrndx, sHeaders ); if(rc) { auto i = sHeaders.begin(); auto e = sHeaders.end(); while( i != e ) { const auto & hdr = *i; std::unique_ptr<char> buff; if( hdr.sh_size ) { buff.reset(new char[hdr.sh_size]); if(fseek ( fh, hdr.sh_offset, SEEK_SET )) { fprintf( stderr, "Failed to seek to section at %lu\n", hdr.sh_offset ); return false; } else if(1 != fread( buff.get(), hdr.sh_size, 1, fh )) { fprintf( stderr, "Failed to read section at %lu\n", hdr.sh_offset ); return false; } } switch(hdr.sh_type) { case SHT_NULL: break; case SHT_PROGBITS: if( hdr.sh_flags & SHF_EXECINSTR ) { dump(buff.get(), hdr.sh_size); disassemble( buff.get(), buff.get()+hdr.sh_size ); } else { TODO printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_SYMTAB: { auto & ss = sHeaders[hdr.sh_link]; std::unique_ptr<char> strings; strings.reset(new char[ss.sh_size]); if(fseek ( fh, ss.sh_offset, SEEK_SET ) || (1 != fread( strings.get(), ss.sh_size, 1, fh ))) { fprintf( stderr, "Failed to read string section at %lu\n", ss.sh_offset ); return false; } else { SymbolTable st( buff.get(), hdr.sh_size, hdr.sh_entsize, true, strings ); } break; } case SHT_STRTAB: { StringTable st(i-sHeaders.begin(), buff.get(), hdr.sh_size); st.dump(); break; } case SHT_RELA: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_HASH: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_DYNAMIC: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_NOTE: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_NOBITS: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_REL: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_SHLIB: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_DYNSYM: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_INIT_ARRAY: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_FINI_ARRAY: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_PREINIT_ARRAY: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_GROUP: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_SYMTAB_SHNDX: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_GNU_ATTRIBUTES: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_GNU_HASH: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_GNU_LIBLIST: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_CHECKSUM: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_SUNW_move: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_SUNW_COMDAT: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_SUNW_syminfo: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_GNU_verdef: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_GNU_verneed: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; case SHT_GNU_versym: TODO { printf( "\n%lu:%lu\n", hdr.sh_offset, hdr.sh_size ); dump(buff.get(), hdr.sh_size); } break; } ++i; } } return true; }
static void printToken(scpi_token_t * token) { printf("Token:\r\n"); printf("\t->type = %s\r\n", typeToStr(token->type)); printf("\t->ptr = %p (\"%.*s\")\r\n", token->ptr, token->len, token->ptr); printf("\t->len = %d\r\n", token->len); }
const char *p7ContentInfoTypeStr( NSS_P7_CI_Type type) { return typeToStr(type, p7CITypeNames); }
const char *p12BagTypeStr( NSS_P12_SB_Type type) { return typeToStr(type, p12BagTypeNames); }
// content format static void dissect_mysensors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { // your variable definitions go here int bitoffset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "mysensors"); // Clear out stuff in the info column col_clear(pinfo->cinfo,COL_INFO); if (tree) { // in case that someone wants to know some details of our protocol // spawn a subtree and cut the sequence in readable parts proto_item *pi = NULL; proto_item *ti = NULL; proto_tree *mysensors_tree = NULL; tvbuff_t* tvb_next; guint8 payloadLen, dataType, type, sensor, sender, last, dest, reqack, isack; MySensors_Command commandType; gchar* info; ti = proto_tree_add_item(tree, proto_mysensors, tvb, 0 /*start*/, -1 /*to end*/, ENC_NA); mysensors_tree = proto_item_add_subtree(ti, ett_mysensors); proto_tree_add_item(mysensors_tree, hf_mysensors_last, tvb, bitoffset>>3, 1, encoding); last = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; proto_tree_add_item(mysensors_tree, hf_mysensors_sender, tvb, bitoffset>>3, 1, encoding); sender = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; proto_tree_add_item(mysensors_tree, hf_mysensors_dest, tvb, bitoffset>>3, 1, encoding); dest = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_length, tvb, bitoffset, 5, encoding); payloadLen = tvb_get_bits8(tvb, bitoffset, 5); bitoffset += 5; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_version, tvb, bitoffset, 3, encoding); bitoffset += 3; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_datatype, tvb, bitoffset, 3, encoding); dataType = tvb_get_bits8(tvb, bitoffset, 3); // Type of payload bitoffset += 3; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_isack, tvb, bitoffset, 1, encoding); isack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1); bitoffset += 1; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_reqack, tvb, bitoffset, 1, encoding); reqack = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 1); bitoffset += 1; proto_tree_add_bits_item(mysensors_tree, hf_mysensors_commandtype, tvb, bitoffset, 3, encoding); commandType = (MySensors_Command)tvb_get_bits8(tvb, bitoffset, 3); bitoffset += 3; type = tvb_get_guint8(tvb, bitoffset>>3); proto_tree_add_uint_format_value(mysensors_tree, hf_mysensors_type, tvb, bitoffset>>3, 1, type, "%s (%d)", typeToStr(commandType, type), (guint8)type); bitoffset += 8; proto_tree_add_item(mysensors_tree, hf_mysensors_sensor, tvb, bitoffset>>3, 1, encoding); sensor = tvb_get_guint8(tvb, bitoffset>>3); bitoffset += 8; // Create tvb for the payload. tvb_next = tvb_new_subset(tvb, bitoffset>>3, payloadLen, payloadLen); info = buildColInfo( pinfo, payloadLen, dataType, commandType, reqack, isack, type, sensor, tvb_next ); col_add_str(pinfo->cinfo, COL_INFO, info); proto_item_append_text(ti, " - %s", info); col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "%d", sender); col_add_fstr(pinfo->cinfo, COL_DEF_DST, "%d", dest); // Pass payload to generic data dissector call_dissector(data_handle, tvb_next, pinfo, mysensors_tree); } }
// Prints the Annotated Syntax Tree // TODO: put into a class, seperate codegen and other steps. template functions? // TODO: combine print tree functions, pass an enum 'flag' to turn on different printing features void printAnnotatedTree ( TreeNode * og, int indent_count ) { TreeNode * tree = og; int sibling_count = 0; // Keeps track of siblings std::string outstr; // Output buffer // Prints all nodes of the tree while (tree != NULL) { if ( sibling_count > 0 ) { outstr.append("|Sibling: "); outstr.append(std::to_string(sibling_count)); outstr.append(" "); std::cout << applyIndents(outstr, indent_count); std::cout.flush(); outstr.clear(); } switch (tree->kind) { case OpK: outstr += "Op: "; outstr += opToStr(tree->token); outstr += (" Type: "); outstr += typeToStr(tree->nodetype); break; case UnaryK: outstr.append("Op: "); outstr.append(svalResolve(tree)); outstr += (" Type: "); outstr += typeToStr(tree->nodetype); break; case ConstK: outstr.append("Const: "); if ( tree->nodetype == Boolean ) { outstr.append(iboolToString(tree->token->ivalue)); } else if ( tree->nodetype == Integer ) { outstr.append(std::to_string(tree->token->ivalue)); } else if ( tree->nodetype == Character ) { if ( tree->token->svalue != NULL ) { outstr += '"'; outstr += tree->token->svalue; outstr += '"'; } else { outstr += '\''; outstr += tree->token->cvalue; outstr += '\''; } } outstr.append(" Type: "); if ( tree->isArray ) { outstr.append("is array of "); } outstr.append(typeToStr(tree->nodetype)); break; case IdK: outstr.append("Id: "); outstr.append(svalResolve(tree)); outstr += (" Type: "); if ( tree->isArray ) { outstr.append("is array of "); } outstr += typeToStr(tree->nodetype); break; case AssignK: outstr.append("Assign: "); outstr += opToStr(tree->token); outstr += (" Type: "); if ( tree->isArray ) { outstr.append("is array of "); } outstr += typeToStr(tree->nodetype); break; case IfK: outstr.append("If"); break; case CompoundK: outstr.append("Compound"); outstr += " with size "; outstr += std::to_string(tree->size); outstr += " at end of it's declarations"; break; case ForeachK: outstr.append("Foreach"); break; case WhileK: outstr.append("While"); break; case ReturnK: outstr.append("Return"); break; case BreakK: outstr.append("Break"); break; case VarK: outstr.append("Var "); outstr.append(svalResolve(tree)); if ( tree->isArray ) { outstr.append(" is array of"); } outstr += " "; outstr.append(typeToStr(tree->nodetype)); outstr += " allocated as "; if( tree->offsetReg == global ) outstr += "Global"; else outstr += "Local"; if(tree->isStatic) outstr += "Static"; outstr += " of size "; outstr += std::to_string(tree->size); outstr += " and data location "; outstr += std::to_string(tree->location); break; case ParamK: outstr.append("Param "); outstr.append(svalResolve(tree)); if ( tree->isArray ) { outstr.append(" is array of"); } outstr += " "; outstr.append(typeToStr(tree->nodetype)); outstr += " allocated as "; outstr += "Parameter"; outstr += " of size "; outstr += std::to_string(tree->size); outstr += " and data location "; outstr += std::to_string(tree->location); break; case FunK: outstr.append("Func "); outstr.append(svalResolve(tree)); outstr.append(" returns type "); outstr.append(typeToStr(tree->nodetype)); outstr += " allocated as "; if( tree->offsetReg == global ) outstr += "Global"; else outstr += "Local"; outstr += " of size -"; outstr += std::to_string(tree->size); outstr += " and exec location "; outstr += std::to_string(tree->location); break; case CallK: outstr.append("Call: "); outstr.append(svalResolve(tree)); outstr += (" Type: "); outstr += typeToStr(tree->nodetype); break; default: outstr.append("\nWe shouldn't get here\n"); break; } // end switch std::cout << outstr << " [line: " << tree->lineno << "]" << std::endl; std::cout.flush(); outstr.clear(); // Check if there are children if ( tree->numChildren > 0 ) { for (int i = 0; i < tree->numChildren; i++) { if ( tree->child[i] != NULL ) { outstr.append("| Child: "); outstr.append(std::to_string(i)); outstr.append(" "); std::cout << applyIndents(outstr, indent_count); std::cout.flush(); outstr.clear(); printAnnotatedTree(tree->child[i], indent_count + 1); } } } tree = tree->sibling; // Jump to the next sibling sibling_count++; } // end while }
// Recursively prints the abstract syntax tree // TODO: null characters in char and string consts, store/print properly (check treeParse for solution, make function) void printAbstractTree ( TreeNode * og, int indent_count ) { TreeNode * tree = og; int sibling_count = 0; // Keeps track of siblings // TODO: string stream better option? std::string outstr; // Output buffer // Prints all nodes of the tree while (tree != NULL) { if ( sibling_count > 0 ) { outstr.append("|Sibling: "); outstr.append(std::to_string(sibling_count)); outstr.append(" "); std::cout << applyIndents(outstr, indent_count); std::cout.flush(); outstr.clear(); } switch (tree->kind) { case OpK: outstr += "Op: "; outstr += svalResolve(tree); break; case UnaryK: outstr.append("Op: "); outstr.append(svalResolve(tree)); break; case ConstK: outstr.append("Const: "); if ( tree->nodetype == Boolean ) { outstr.append(iboolToString(tree->token->ivalue)); } else if ( tree->nodetype == Integer ) { outstr.append(std::to_string(tree->token->ivalue)); } else if ( tree->nodetype == Character ) { if ( tree->token->svalue != NULL ) { // could use isArray here for stringconsts outstr += '"'; outstr += tree->token->svalue; //fwrite( tree->token->svalue, sizeof(char), sizeof(tree->token->svalue), stdout); outstr += '"'; } else { outstr += '\''; outstr += tree->token->cvalue; outstr += '\''; } } break; case IdK: outstr.append("Id: "); outstr.append(svalResolve(tree)); break; case AssignK: outstr.append("Assign: "); if ( tree->nodetype == Void ) { outstr.append(svalResolve(tree)); } if ( tree->nodetype == Integer ) { outstr += svalResolve(tree); } break; case IfK: outstr.append("If"); break; case CompoundK: outstr.append("Compound"); break; case ForeachK: outstr.append("Foreach"); break; case WhileK: outstr.append("While"); break; case ReturnK: outstr.append("Return"); break; case BreakK: outstr.append("Break"); break; case VarK: case ParamK: if ( tree->kind == VarK ) { outstr.append("Var "); } else { outstr.append("Param "); } outstr.append(svalResolve(tree)); if ( tree->isArray ) { outstr.append("is array"); } outstr.append(" of type "); outstr.append(typeToStr(tree->nodetype)); break; case FunK: outstr.append("Func "); outstr.append(svalResolve(tree)); outstr.append(" returns type "); outstr.append(typeToStr(tree->nodetype)); break; case CallK: outstr.append("Call: "); outstr.append(svalResolve(tree)); break; default: outstr.append("\nWe shouldn't get here\n"); break; } // end switch std::cout << outstr << " [line: " << tree->lineno << "]" << std::endl; std::cout.flush(); outstr.clear(); // Check if there are children if ( tree->numChildren > 0 ) { for (int i = 0; i < tree->numChildren; i++) { if ( tree->child[i] != NULL ) { outstr.append("| Child: "); outstr.append(std::to_string(i)); outstr.append(" "); std::cout << applyIndents(outstr, indent_count); std::cout.flush(); outstr.clear(); printAbstractTree(tree->child[i], indent_count + 1); } } } tree = tree->sibling; // Jump to the next sibling sibling_count++; } // end while }