/** Check that given edge is in current sector */ bool NodeNav::isEdgeInSector( GEdge * edge) const { GNode *n = otherEnd( edge); /* item corresponding to other (than node_priv) node */ if ( isNullP( n) || sector() == UNDEF_SECTOR) return false; NodeItem *item = n->item(); // Both points in current node's coordinates QPointF p_center = node_priv->item()->boundingRect().center(); QPointF s_center = node_priv->item()->mapFromItem( item, item->boundingRect().center()); qreal angle = QLineF( p_center, s_center).angle(); qreal max_angle = sectorMaxAngle(); qreal min_angle = sectorMinAngle(); if ( angle > 270 && sector() == RIGHT_SECTOR) { max_angle +=360; } if ( angle < 90 && sector() == RIGHT_SECTOR) { min_angle -=360; } if ( angle <= max_angle && angle >= min_angle) return true; return false; }
/** Get edge to the left of given edge */ GEdge * NodeNav::edgeInDir( GEdge * edge, NavDirection dir) const { /* Applicable only for top and bottom sectors */ if ( !isDirApplicable( dir, sector())) { return NULL; } GNode *n = otherEnd( edge); /* item corresponding to other (than node_priv) node */ if ( isNullP( n)) return NULL; NodeItem *item = n->item(); // in current node's coordinates QPointF edge_point = node()->item()->mapFromItem( item, item->boundingRect().center()); GEdge *res = NULL; qreal min_delta = 0; /** For each edge */ for ( Node::EdgeIter e_iter = node()->edgesBegin(), e_end = node()->edgesEnd(); e_iter != e_end; e_iter++ ) { GEdge *e = static_cast<GEdge *>( e_iter.edge()); if ( isEdgeInSector( e) && areNotEqP( e, edge)) { NodeItem *p_item = static_cast<GNode *>( e_iter.node())->item(); QPointF point = node()->item()->mapFromItem( p_item, p_item->boundingRect().center()); if ( isPointInDir( point, edge_point, dir)) { qreal delta = deltaInDir( point, edge_point, dir); if ( isNullP( res) || delta < min_delta) // for selection of closest edge { res = e; min_delta = delta; } } } } return res; }
void CFNode<MdesType>::prepend( Operation<MdesType> *oper) { IR_ASSERTD( isNotNullP( oper)); if ( isNullP( first)) { IR_ASSERTD( isNullP( last)); // Node must be empty if there is no last operation oper->detachFromSeq(); first = oper; last = oper; } else { oper->insertBefore( first); first = oper; } oper->setNode( this); }
/** * Test configuration and options parsing */ bool uTestConf() { Conf *conf = new Conf(); /** Create some example options */ conf->addOption( new Option( OPT_STRING, "o", "output", "output file name( string option example)")); conf->addOption( new Option( OPT_BOOL, "b", "boolean", "boolean option example")); conf->addOption( new Option( OPT_INT, "i", "integer", "integer option example")); conf->addOption( new Option( OPT_FLOAT, "f", "float", "float option example")); conf->printOpts(); // Print them to console /** Check that created options can be accessed */ assert( isNullP( conf->option( "file"))); assert( isNotNullP( conf->option("output"))); assert( isNotNullP( conf->shortOption( "o"))); assert( isNullP( conf->shortOption( "output"))); assert( isNotNullP( conf->longOption("output"))); /** Create array of arguments */ char *args[ 8]; args[ 0] = (char*)"string";// treated args[ 1] = (char*)"--output"; args[ 2] = (char*)"file"; args[ 3] = (char*)"-a"; args[ 4] = (char*)"--b"; args[ 5] = (char*)"-b"; args[ 6] = (char*)"-i"; args[ 7] = (char*)"80"; /** Read arguments from array and parse them */ conf->readArgs( 8, args); /** Check options values */ assert( conf->unknownOptsNum() == 2); // Check number of unknown arguments assert( !(conf->option( "output")->string().compare("file"))); Option *int_opt = conf->option( "integer"); assert( int_opt->isDefined()); assert( int_opt->intVal()== 80); assert( conf->option( "b")->isSet()); delete conf; return true; }
/** Get edge to the bottom of current node */ GEdge * NodeNav::firstEdgeInSector() const { GEdge *res = NULL; qreal min_delta = 0; /** For each edge */ for ( Node::EdgeIter e_iter = node()->edgesBegin(), e_end = node()->edgesEnd(); e_iter != e_end; e_iter++ ) { GEdge *e = static_cast<GEdge *>( e_iter.edge()); if ( isEdgeInSector( e)) { NodeItem *p_item = static_cast<GNode *>( e_iter.node())->item(); QPointF center = node()->item()->boundingRect().center(); QPointF point = node()->item()->mapFromItem( p_item, p_item->boundingRect().center()); qreal delta; if ( sector() == TOP_SECTOR || sector() == BOTTOM_SECTOR) { delta = abs<qreal>( center.x() - point.x()); } else { delta = abs<qreal>( center.y() - point.y()); } if ( isNullP( res) || delta < min_delta) // for selection of closest edge { res = e; min_delta = delta; } } } return res; }
/** MList testing */ static bool uTestMList() { B *obj1 = new B(); B *obj2 = new B(); B *obj3 = new B(); obj1->attach( LIST_ONE, obj2); obj1->attach( LIST_TWO, obj3); ASSERT( areEqP( obj1->next( LIST_ONE), obj2)); ASSERT( areEqP( obj1->next( LIST_TWO), obj3)); ASSERT( isNullP( obj1->prev( LIST_ONE))); ASSERT( isNullP( obj1->prev( LIST_TWO))); ASSERT( areEqP( obj2->prev( LIST_ONE), obj1)); ASSERT( areEqP( obj3->prev( LIST_TWO), obj1)); ASSERT( isNullP( obj3->prev( LIST_ONE))); ASSERT( isNullP( obj2->prev( LIST_TWO))); ASSERT( isNullP( obj2->next( LIST_ONE))); ASSERT( isNullP( obj3->next( LIST_TWO))); obj2->detachAll(); delete obj2; delete obj1; delete obj3; return true; }
Numeration CFG<MdesType>::makeTopologicalNumeration() { /** * The algorithm makes an RPO numeration of nodes by * doing the depth-first search on the CFG and assigning numbers * to a node AFTER all successors of the node have been visited. */ Marker m = MarkerManager::newMarker(); Numeration num = NumManager::newNum(); GraphNum i = this->numNodes() - 1; /* * We use while loop instead of recursive implementation just to show off :) * So we will need a stack for saving temporary values. We save the edge to * be processed on the stack. If the edge is last unprocessed successor of some node * than node is considered done and a number is assigned to it. */ std::list< CFEdge< MdesType> *> stack; if ( isNotNullP( this->startNode()->firstSucc()) ) { stack.push_back( this->startNode()->firstSucc()); this->startNode()->mark( m); this->startNode()->firstSucc()->succ()->mark( m); while ( stack.size() != 0) { CFEdge< MdesType> *edge = stack.back(); /* * Add next succ to the stack, if it needs to be processed */ if ( isNotNullP( edge->nextSucc()) ) { CFEdge< MdesType> *succ = edge->nextSucc(); stack.pop_back(); while ( isNotNullP( succ)) { if ( !succ->succ()->isMarked( m)) { break; } else if ( isNullP( succ->nextSucc()) ) { succ->mark( m); break; } succ = succ->nextSucc(); } if ( isNotNullP( succ)) { stack.push_back( edge->nextSucc()); edge->nextSucc()->succ()->mark( m); } } /* * Check if the predecessor node is done. I.e. the current edge * is already processed and it is the last successor edge */ if ( edge->isMarked( m) && isNullP( edge->nextSucc()) ) { CFNode< MdesType> *pred = edge->pred(); pred->setNumber( num, i); IR_ASSERTD( pred->isMarked( m)); //cout << "RPO trav " << pred->id() << " is numbered " << i << endl; i--; stack.pop_back(); continue; } /** Add all successor edges of successor node to the stack */ bool succ_found = false; CFEdge< MdesType> *succ = edge->succ()->firstSucc(); while ( isNotNullP( succ)) { CFNode< MdesType> *succ_node = succ->succ(); if ( !succ_node->isMarked( m) ) { succ_node->mark( m); stack.push_back( succ); succ_found = true; break; } succ = succ->nextSucc(); } if ( !succ_found) { CFNode< MdesType> * succ = edge->succ(); succ->setNumber( num, i); IR_ASSERTD( succ->isMarked( m)); //cout << "RPO trav " << succ->id() << " is numbered " << i << endl; i--; } edge->mark( m); } } /* Number the rest of CFG nodes */ for ( CFNode< MdesType> *node = this->firstNode(); isNotNullP( node); node = node->nextNode() ) { //cout << "Checking " << node->id() << " " << ( node->isMarked( m)? "marked": "non-marked") << endl; if ( !node->isMarked( m) ) { node->setNumber( num, i); //cout << "RPO trav " << node->id() << " is numbered " << i << endl; i--; } } this->freeMarker( m); return num; }