/* call function */ Value Object::call (const std::string& function, const List& params) const { FunctionList list = mClass->getFunctions (function); /* no function found */ if (list.empty()) throw std::runtime_error ( "Cannot find the function '" + function + "' in the class '" + mClass->getName() + "'."); FunctionList::iterator iter; /* find a function which can handle the parameters */ for (iter = list.begin(); iter != list.end(); ++iter) { Function* func = *iter; /* found match, execute the function */ if (func->getType()->checkParamTypes (params)) return func->call (params); } /* no capable function found */ throw std::runtime_error ( "Cannot find a function capable of handling the provided " "parameters"); }
void QuickOpenFunctionDialog::slotTextChangedDelayed() { QString text = nameEdit->text(); QString txt = text; QStringList parts = QStringList::split("::", text); if(text.endsWith("::") || parts.isEmpty()) { txt = ""; }else{ txt = parts.back(); parts.pop_back(); } QValueList<QRegExp> regExpParts; for( QStringList::const_iterator it = parts.begin(); it != parts.end(); ++it ) { regExpParts << QRegExp( *it, false, true ); } QString scope = parts.join("::"); if( m_scope != scope ) { if( !scope.startsWith(m_scope) ) { ///Not a specialization, so reload all function-definitions fillItemList(); } if(!parts.isEmpty()) { FunctionList accepted; QStringList acceptedItems; FunctionList::iterator it = m_functionDefList.begin(); while(it != m_functionDefList.end()) { QStringList scope = (*it)->scope(); QValueList<QRegExp>::iterator mit = regExpParts.begin(); QStringList::iterator sit = scope.begin(); bool fail = false; while(mit != regExpParts.end()) { while(sit != scope.end() && !(*mit).exactMatch( *sit ) ) ++sit; if(sit == scope.end()) { fail = true; break; } ++mit; } if(!fail) { accepted.append(*it); acceptedItems << (*it)->name(); } ++it; } m_functionDefList = accepted; m_items = acceptedItems; QStringList_unique( m_items ); } m_scope = scope; } itemList->clear(); itemList->insertStringList( wildCardCompletion( txt ) ); itemList->setCurrentItem(0); }
/* get function list */ FunctionList Class::getFunctions () const { FunctionList list; FunctionMap::const_iterator iter; /* merge function lists from the map into a flat list */ for (iter = mFunctions.begin(); iter != mFunctions.end(); ++iter) list.insert (list.end(), iter->second.begin(), iter->second.end()); return list; }
void SerialPlugIn::RemoveDMFunctions( void ) { FunctionList::const_iterator functionPtr; for( functionPtr = fFunctionList.begin(); functionPtr != fFunctionList.end(); ++functionPtr ) { RemoveFunction( *functionPtr ); } }
void refreshFunctions(ClassViewPart *part, KComboView *view, const ClassDom & dom) { view->clear(); view->setCurrentText(EmptyFunctions); FunctionList functions = dom->functionList(); for (FunctionList::const_iterator it = functions.begin(); it != functions.end(); ++it) { FunctionItem *item = new FunctionItem(part, view->listView(), part->languageSupport()->formatModelItem(*it, true), *it); view->addItem(item); item->setOpen(true); } }
FunctionList DSNodeEquivs::getCallees(CallSite &CS) { const Function *CalledFunc = CS.getCalledFunction(); // If the called function is casted from one function type to another, peer // into the cast instruction and pull out the actual function being called. if (ConstantExpr *CExpr = dyn_cast<ConstantExpr>(CS.getCalledValue())) { if (CExpr->getOpcode() == Instruction::BitCast && isa<Function>(CExpr->getOperand(0))) CalledFunc = cast<Function>(CExpr->getOperand(0)); } FunctionList Callees; // Direct calls are simple. if (CalledFunc) { Callees.push_back(CalledFunc); return Callees; } // Okay, indirect call. // Ask the DSCallGraph what this calls... TDDataStructures &TDDS = getAnalysis<TDDataStructures>(); const DSCallGraph &DSCG = TDDS.getCallGraph(); DSCallGraph::callee_iterator CalleeIt = DSCG.callee_begin(CS); DSCallGraph::callee_iterator CalleeItEnd = DSCG.callee_end(CS); for (; CalleeIt != CalleeItEnd; ++CalleeIt) Callees.push_back(*CalleeIt); // If the callgraph doesn't give us what we want, query the DSGraph // ourselves. if (Callees.empty()) { Instruction *Inst = CS.getInstruction(); Function *Parent = Inst->getParent()->getParent(); Value *CalledValue = CS.getCalledValue(); DSNodeHandle &NH = TDDS.getDSGraph(*Parent)->getNodeForValue(CalledValue); if (!NH.isNull()) { DSNode *Node = NH.getNode(); Node->addFullFunctionList(Callees); } } // For debugging, dump out the callsites we are unable to get callees for. DEBUG( if (Callees.empty()) { errs() << "Failed to get callees for callsite:\n"; CS.getInstruction()->dump(); });
Dispatcher::Dispatcher(Module *M, CLData *Cl){ FunctionList *fl = new FunctionList(M,Cl); if(fl != NULL){ fl->runFnPtrValidator(Cl); } else { errs() << "\nError:Creation of FunctionList object failed!\n"; exit(-1); } this->Fl = fl; if(Cl->getMode() == Common::INJECT){ this->populateFaultSites(M,Cl); this->runFaultInjector(M,Cl); } }
void QuickOpenFunctionDialog::gotoFile( QString name ) { FunctionModel *fmodel; FunctionList funcList; FunctionDom fdom; for( FunctionList::ConstIterator it = m_functionDefList.begin() ; it!=m_functionDefList.end() ; ++it ){ fdom = *it; fmodel = fdom.data(); if( fmodel->name() == name ){ funcList.append( fdom ); } } if( funcList.count() == 1 ){ fdom = funcList.first(); fmodel = fdom.data(); QString fileNameStr = fmodel->fileName(); int startline, startcol; fmodel->getStartPosition( &startline, &startcol ); m_part->partController()->editDocument( KURL( fileNameStr), startline, startcol ); selectClassViewItem( ItemDom(&(*fmodel)) ); }else if( funcList.count() > 1 ){ QString fileStr; QuickOpenFunctionChooseForm fdlg( this, name.ascii() ); for( FunctionList::Iterator it = funcList.begin() ; it!=funcList.end() ; ++it ){ fmodel = (*it).data(); fdlg.argBox->insertItem( m_part->languageSupport()->formatModelItem(fmodel) + (fmodel->scope().isEmpty() ? "" : " (in " + fmodel->scope().join("::") + ")")); fileStr = KURL( fmodel->fileName() ).fileName(); KURL full_url( fmodel->fileName() ); KURL base_url( part()->project()->projectDirectory()+"/" ); fdlg.setRelativePath(fdlg.fileBox->count(), KURL::relativeURL( base_url, full_url )); fdlg.fileBox->insertItem(fileStr); } if( fdlg.exec() ){ int id = fdlg.argBox->currentItem(); if( id>-1 && id < (int) funcList.count() ){ FunctionModel *model = funcList[id].data(); int line, col; model->getStartPosition( &line, &col ); selectClassViewItem( ItemDom(&(*model)) ); QString fileNameStr = model->fileName(); m_part->partController()->editDocument( KURL(fileNameStr), line ); } } } else{ KMessageBox::error( this, i18n("Error: cannot find matching name function.") ); } accept(); }
void Navigator::selectFunctionNav(QListViewItem *item) { FunctionNavItem *nav = dynamic_cast<FunctionNavItem*>(item); if (!nav) return; FileDom file = m_part->codeModel()->fileByName(m_part->m_activeFileName); if (!file) return; switch (nav->type()) { case FunctionNavItem::Definition: //jump to definition { FileList files = file->wholeGroup(); FunctionDefinitionList deflist; CodeModelUtils::findFunctionDefinitions(NavOp(this, nav->text(0)), files, deflist); if (deflist.count() < 1) return; FunctionDefinitionDom fun = deflist.first(); if (!fun) return; int startLine = 0, startColumn = 0; fun->getStartPosition(&startLine, &startColumn); m_part->partController()->editDocument(KURL(fun->fileName()), startLine); break; } case FunctionNavItem::Declaration: //jump to declaration { FileList files = file->wholeGroup(); FunctionList declist; CodeModelUtils::findFunctionDeclarations(NavOp(this, nav->text(0)), files, declist); if (declist.count() < 1) return; FunctionDom fun = declist.first(); if (!fun) return; int startLine = 0, startColumn = 0; fun->getStartPosition(&startLine, &startColumn); m_part->partController()->editDocument(KURL(fun->fileName()), startLine); break; } } }
void TypeRegistry::collect_pure_methods(const TypeDesc &td, FunctionList &fl) const { for (BaseTypeList::const_iterator i=td.base_types.begin(); i!=td.base_types.end(); ++i) { const TypeDesc *base = findTypeDescription(i->name); if (base) collect_pure_methods(*base, fl); } FunctionList methods; std::copy(td.methods.begin(), td.methods.end(), std::back_inserter(methods)); std::copy(td.prot_methods.begin(), td.prot_methods.end(), std::back_inserter(methods)); std::copy(td.priv_methods.begin(), td.priv_methods.end(), std::back_inserter(methods)); for (FunctionList::const_iterator i=methods.begin(); i!=methods.end(); ++i) { if (i->is_pure_virtual) { fl.push_back(*i); } else { for (FunctionList::iterator j=fl.begin(); j!=fl.end();) { if (j->get_signature() == i->get_signature()) { fl.erase(j); } else ++j; } } } }
void testFuncParser(char *buf) { printf("===== Testing function parser ======\n"); // time_t start = GetTickCount(); FunctionList li; //fflush(stdout); std::map<std::string, std::string> ignoreTokens; get_functions(buf, li, ignoreTokens); // time_t end = GetTickCount(); for (FunctionList::iterator iter = li.begin(); iter != li.end(); iter++) { //test the var parser on the function argument list: clFunction f = (*iter); f.Print(); //testVarParser((char*)f.m_signature.c_str()); printf("%s\n", f.m_name.c_str()); } // printf("total time: %d\n", end-start); printf("matches found: %d\n", li.size()); }
void refreshFunctions(ClassViewPart *part, KComboView *view, const QString & dom) { view->clear(); view->setCurrentText(EmptyFunctions); NamespaceDom nsdom; if (dom == "::") nsdom = part->codeModel()->globalNamespace(); else { nsdom = namespaceByName(part->codeModel()->globalNamespace(), dom); if (!nsdom) return; } FunctionList functions = nsdom->functionList(); for (FunctionList::const_iterator it = functions.begin(); it != functions.end(); ++it) { FunctionItem *item = new FunctionItem(part, view->listView(), part->languageSupport()->formatModelItem(*it, true), *it); view->addItem(item); item->setOpen(true); } }
void SerialPlugIn::AddDMFunctions( void ) { fFunctionList.push_back( AddFunction( 0, "void SerialOpen(char * port, long baud)", 3, (void *) &SerialOpen ) ); fFunctionList.push_back( AddFunction( 0, "void SerialCheck(char * port)", 3, (void *) &SerialCheck ) ); fFunctionList.push_back( AddFunction( 0, "void SerialClose( void )", 3, (void *) &SerialClose ) ); fFunctionList.push_back( AddFunction( 0, "short RxByte( void )", 3, (void *) &RxByte ) ); fFunctionList.push_back( AddFunction( 0, "void TxByte(short byte)", 3, (void *) &TxByte ) ); fFunctionList.push_back( AddFunction( 0, "void TxInt(unsigned int num)", 3, (void *) &TxInt ) ); }
AddMethodDialog::AddMethodDialog( CppSupportPart* cppSupport, ClassDom klass, QWidget* parent, const char* name, bool modal, WFlags fl ) : AddMethodDialogBase( parent, name, modal, fl ), m_cppSupport( cppSupport ), m_klass( klass ), m_count( 0 ) { QString fileName = m_klass->fileName(); access->insertStringList( QStringList() << "Public" << "Protected" << "Private" << "Signals" << "Public Slots" << "Protected Slots" << "Private Slots" ); storage->insertStringList( QStringList() << "Normal" << "Static" << "Virtual" << "Pure Virtual" << "Friend" ); // setup sourceFile combo QMap<QString, bool> m; #if 0 /// \FIXME ROBE FunctionList l = m_klass->functionList(); { for ( FunctionList::Iterator it = l.begin(); it != l.end(); ++it ) { if ( ( *it ) ->hasImplementation() ) m.insert( ( *it ) ->implementedInFile(), true ); } } #endif { QStringList headers = QStringList::split( ",", "h,H,hh,hxx,hpp,inl,tlh,diff,ui.h" ); QStringList fileList; QMap<QString, bool>::Iterator it = m.begin(); while ( it != m.end() ) { QString ext = QFileInfo( it.key() ).extension(); if ( !headers.contains( ext ) ) sourceFile->insertItem( it.key() ); ++it; } if ( sourceFile->count() == 0 ) { QFileInfo info( fileName ); QString impl = DomUtil::readEntry( *cppSupport->projectDom(), "/cppsupportpart/filetemplates/implementationsuffix", "cpp" ); sourceFile->insertItem( info.dirPath( true ) + "/" + info.baseName() + impl ); } } returnType->setAutoCompletion( true ); returnType->insertStringList( QStringList() << "void" << "char" << "wchar_t" << "bool" << "short" << "int" << "long" << "signed" << "unsigned" << "float" << "double" ); returnType->insertStringList( typeNameList( m_cppSupport->codeModel() ) ); updateGUI(); addMethod(); }
void AddMethodDialog::accept() { m_cppSupport->partController() ->editDocument( KURL( m_klass->fileName() ) ); KTextEditor::EditInterface* editIface = dynamic_cast<KTextEditor::EditInterface*>( m_cppSupport->partController() ->activePart() ); if ( !editIface ) { /// @todo show messagebox QDialog::accept(); return ; } int line, column; m_klass->getEndPosition( &line, &column ); // compute the insertion point map QMap<QString, QPair<int, int> > points; QStringList accessList; const FunctionList functionList = m_klass->functionList(); for ( FunctionList::ConstIterator it = functionList.begin(); it != functionList.end(); ++it ) { int funEndLine, funEndColumn; ( *it ) ->getEndPosition( &funEndLine, &funEndColumn ); QString access = accessID( *it ); QPair<int, int> funEndPoint = qMakePair( funEndLine, funEndColumn ); if ( !points.contains( access ) || points[ access ] < funEndPoint ) { accessList.remove( access ); accessList.push_back( access ); // move 'access' at the end of the list points[ access ] = funEndPoint; } } int insertedLine = 0; accessList += newAccessList( accessList ); for ( QStringList::iterator it = accessList.begin(); it != accessList.end(); ++it ) { QListViewItem* item = methods->firstChild(); while ( item ) { QListViewItem * currentItem = item; item = item->nextSibling(); if ( currentItem->text( 1 ) != *it ) continue; QString access = ( *it ).lower(); bool isInline = currentItem->text( 0 ) == "True"; QString str = isInline ? functionDefinition( currentItem ) : functionDeclaration( currentItem ); QPair<int, int> pt; if ( points.contains( *it ) ) { pt = points[ *it ]; } else { str.prepend( access + ":\n" ); points[ *it ] = qMakePair( line - 1, 0 ); pt = points[ *it ]; // end of class declaration } editIface->insertText( pt.first + insertedLine + 1, 0 /*pt.second*/, str ); insertedLine += str.contains( QChar( '\n' ) ); } } m_cppSupport->backgroundParser() ->addFile( m_klass->fileName() ); QString str; QListViewItem* item = methods->firstChild(); while ( item ) { QListViewItem * currentItem = item; item = item->nextSibling(); QString str = functionDefinition( currentItem ); if ( str.isEmpty() ) continue; QString implementationFile = currentItem->text( 5 ); if ( currentItem->text( 0 ) == "True" ) implementationFile = m_klass->fileName(); QFileInfo fileInfo( implementationFile ); if ( !QFile::exists( fileInfo.absFilePath() ) ) { if ( KDevCreateFile * createFileSupp = m_cppSupport->extension<KDevCreateFile>( "KDevelop/CreateFile" ) ) createFileSupp->createNewFile( fileInfo.extension(), fileInfo.dirPath( true ), fileInfo.baseName() ); } m_cppSupport->partController() ->editDocument( KURL( implementationFile ) ); editIface = dynamic_cast<KTextEditor::EditInterface*>( m_cppSupport->partController() ->activePart() ); if ( !editIface ) continue; bool isInline = currentItem->text( 0 ) == "True"; if ( !isInline ) { editIface->insertLine( editIface->numLines(), QString::fromLatin1( "" ) ); editIface->insertText( editIface->numLines() - 1, 0, str ); m_cppSupport->backgroundParser() ->addFile( implementationFile ); } } QDialog::accept(); }
/* FIXME TODO: error processing. Find out a way to notify the caller of the occurred * error. The "cout" method cannot be used */ IAnjutaIterable * EngineParser::processExpression(const string& stmt, const string& above_text, const string& full_file_path, unsigned long linenum) { ExpressionResult result; string current_token; string op; string type_name; string type_scope; DEBUG_PRINT ("Setting text %s to the tokenizer", stmt.c_str ()); _main_tokenizer->setText (stmt.c_str ()); /* get the first token */ nextMainToken (current_token, op); DEBUG_PRINT ("First main token \"%s\" with op \"%s\"", current_token.c_str (), op.c_str ()); /* parse the current sub-expression of a statement and fill up * ExpressionResult object */ result = parseExpression (current_token); /* fine. Get the type name and type scope given the above result for the first * and most important token. * The type_scope is for instance 'std' in this statement: * (std::foo_util)klass-> */ bool process_res = getTypeNameAndScopeByToken (result, current_token, op, full_file_path, linenum, above_text, type_name, type_scope); if (process_res == false) { DEBUG_PRINT ("Initial statement processing failed. " "I cannot continue. "); return NULL; } DEBUG_PRINT ("Searching for curr_searchable_scope with type_name \"%s\"" " and type_scope \"%s\"", type_name.c_str (), type_scope.c_str ()); /* at this time we're enough ready to issue a first query to our db. * We absolutely need to find the searchable object scope of the first result * type. By this one we can iterate the tree of scopes and reach a result. */ IAnjutaIterable *curr_searchable_scope = getCurrentSearchableScope (type_name, type_scope); if (curr_searchable_scope == NULL) { DEBUG_PRINT ("curr_searchable_scope failed to process, check the problem please"); return NULL; } /* fine. Have we more tokens left? */ while (nextMainToken (current_token, op) == 1) { DEBUG_PRINT("Next main token \"%s\" with op \"%s\"",current_token.c_str (), op.c_str ()); /* parse the current sub-expression of a statement and fill up * ExpressionResult object */ result = parseExpression (current_token); if (process_res == false || curr_searchable_scope == NULL) { DEBUG_PRINT ("No luck with the NEXT token, the NEXT token failed and then " "I cannot continue. "); if (curr_searchable_scope != NULL) g_object_unref (curr_searchable_scope ); return NULL; } /* check if the name of the result is valuable or not */ IAnjutaSymbol *node; IAnjutaIterable * iter; node = IANJUTA_SYMBOL (curr_searchable_scope); iter = ianjuta_symbol_query_search_in_scope (_query_search_in_scope, result.m_name.c_str (), node, NULL); if (iter == NULL) { DEBUG_PRINT ("Warning, the result.m_name %s " "does not belong to scope (id %d)", result.m_name.c_str (), ianjuta_symbol_get_int (node, IANJUTA_SYMBOL_FIELD_ID, NULL)); if (curr_searchable_scope != NULL) g_object_unref (curr_searchable_scope ); return NULL; } else { gchar *sym_kind; DEBUG_PRINT ("Good element %s", result.m_name.c_str ()); node = IANJUTA_SYMBOL (iter); sym_kind = (gchar*)ianjuta_symbol_get_string (node, IANJUTA_SYMBOL_FIELD_KIND, NULL); DEBUG_PRINT (".. it has sym_kind \"%s\"", sym_kind); /* the same check as in the engine-core on sdb_engine_add_new_sym_type () */ if (g_strcmp0 (sym_kind, "member") == 0 || g_strcmp0 (sym_kind, "variable") == 0 || g_strcmp0 (sym_kind, "field") == 0) { iter = switchMemberToContainer (iter); node = IANJUTA_SYMBOL (iter); sym_kind = (gchar*)ianjuta_symbol_get_string (node, IANJUTA_SYMBOL_FIELD_KIND, NULL); } /* check for any typedef */ if (g_strcmp0 (ianjuta_symbol_get_string (node, IANJUTA_SYMBOL_FIELD_KIND, NULL), "typedef") == 0) { iter = switchTypedefToStruct (iter); node = IANJUTA_SYMBOL (iter); sym_kind = (gchar*)ianjuta_symbol_get_string (node, IANJUTA_SYMBOL_FIELD_KIND, NULL); } /* is it a function or a method? */ if (g_strcmp0 (sym_kind, "function") == 0 || g_strcmp0 (sym_kind, "method") == 0 || g_strcmp0 (sym_kind, "prototype") == 0) { string func_ret_type_name = ianjuta_symbol_get_string (node, IANJUTA_SYMBOL_FIELD_RETURNTYPE, NULL); string func_signature = ianjuta_symbol_get_string (node, IANJUTA_SYMBOL_FIELD_SIGNATURE, NULL); func_ret_type_name += " " + result.m_name + func_signature + "{}"; FunctionList li; std::map<std::string, std::string> ignoreTokens; get_functions (func_ret_type_name, li, ignoreTokens); DEBUG_PRINT ("Functions found are..."); /* for (FunctionList::reverse_iterator func_iter = li.rbegin(); func_iter != li.rend(); func_iter++) { Function var = (*func_iter); var.print (); } */ g_object_unref (iter); DEBUG_PRINT ("Going to look for the following function ret type %s", func_ret_type_name.c_str ()); iter = getCurrentSearchableScope (li.front().m_returnValue.m_type, type_scope); } /* remove the 'old' curr_searchable_scope and replace with * this new one */ g_object_unref (curr_searchable_scope); curr_searchable_scope = iter; continue; } } DEBUG_PRINT ("END of expression processing. Returning curr_searchable_scope"); return curr_searchable_scope; }
void html_web_view_open (GtkWidget *viewer, const gchar *uri) { g_debug ("uri = '%s'\n",uri); function_list._html_web_view_open (viewer, uri); }
GtkWidget * html_web_view_new (void) { return function_list._html_web_view_new (); }
int WriteFunctions(const FunctionList &functions) { // separate the master function list into namespaces OutFileMap fileMap; fileMap.insert(std::make_pair("","Globals")); for(obuint32 i = 0; i < functions.size(); ++i) { OutFileMap::iterator it = fileMap.find(functions[i].ClassName); if(it == fileMap.end()) { OutFileMap::_Pairib ins = fileMap.insert(std::make_pair(functions[i].ClassName,NameSpaces(functions[i].ClassName))); it = ins.first; } it->second.Functions.push_back(functions[i]); } // write out each file. for(OutFileMap::iterator it = fileMap.begin(); it != fileMap.end(); ++it) { File outFile; // write out each function const String FileName = Utils::VA("%s.cpp", it->second.FileName.c_str()); if(outFile.OpenForWrite(FileName.c_str(),File::Text,false)) { outFile.Printf("#include \"gmThread.h\"\n\n"); WriteUserTypeVars(outFile,it->second); // write the function implementations WriteFunctionImplementations(outFile,it->second); // write the binding block WriteFunctionBindBlock(outFile,it->second); } } // write table of contents file, where all bindings are registered. File tocFile; if(tocFile.OpenForWrite("ScriptBindAll.cpp",File::Text)) { tocFile.Printf("#include \"gmThread.h\"\n\n"); tocFile.Printf("// declarations\n"); for(OutFileMap::iterator it = fileMap.begin(); it != fileMap.end(); ++it) { if(!it->second.Functions.empty()) { tocFile.Printf("void gmBind%sLib(gmMachine * a_machine);\n",it->second.FileName.c_str()); } } tocFile.Printf("\n\n// bind libraries\n"); tocFile.Printf("void gmBindAllAutogenLibs(gmMachine * a_machine)\n"); tocFile.Printf("{\n"); for(OutFileMap::iterator it = fileMap.begin(); it != fileMap.end(); ++it) { if(!it->second.Functions.empty()) { tocFile.Printf("\tgmBind%sLib(a_machine);\n",it->second.FileName.c_str()); } } tocFile.Printf("}\n"); } return fileMap.size(); }
// An "invalid" list is one whose functions don't match, and therefore has to be animated as a Matrix // The hasBigRotation flag will always return false if isValid is false. Otherwise hasBigRotation is // true if the rotation between any two keyframes is >= 180 degrees. void GraphicsLayer::TransformValueList::makeFunctionList(FunctionList& list, bool& isValid, bool& hasBigRotation) const { list.clear(); isValid = false; hasBigRotation = false; if (m_values.size() < 2) return; // empty transforms match anything, so find the first non-empty entry as the reference size_t firstIndex = 0; for ( ; firstIndex < m_values.size(); ++firstIndex) { if (m_values[firstIndex].value()->operations().size() > 0) break; } if (firstIndex >= m_values.size()) return; const TransformOperations* firstVal = m_values[firstIndex].value(); // see if the keyframes are valid for (size_t i = firstIndex + 1; i < m_values.size(); ++i) { const TransformOperations* val = m_values[i].value(); // a null transform matches anything if (val->operations().isEmpty()) continue; if (firstVal->operations().size() != val->operations().size()) return; for (size_t j = 0; j < firstVal->operations().size(); ++j) { if (!firstVal->operations().at(j)->isSameType(*val->operations().at(j))) return; } } // keyframes are valid, fill in the list isValid = true; double lastRotAngle = 0.0; double maxRotAngle = -1.0; list.resize(firstVal->operations().size()); for (size_t j = 0; j < firstVal->operations().size(); ++j) { TransformOperation::OperationType type = firstVal->operations().at(j)->getOperationType(); list[j] = type; // if this is a rotation entry, we need to see if any angle differences are >= 180 deg if (type == TransformOperation::ROTATE_X || type == TransformOperation::ROTATE_Y || type == TransformOperation::ROTATE_Z || type == TransformOperation::ROTATE_3D) { lastRotAngle = static_cast<RotateTransformOperation*>(firstVal->operations().at(j).get())->angle(); if (maxRotAngle < 0) maxRotAngle = fabs(lastRotAngle); for (size_t i = firstIndex + 1; i < m_values.size(); ++i) { const TransformOperations* val = m_values[i].value(); double rotAngle = val->operations().isEmpty() ? 0 : (static_cast<RotateTransformOperation*>(val->operations().at(j).get())->angle()); double diffAngle = fabs(rotAngle - lastRotAngle); if (diffAngle > maxRotAngle) maxRotAngle = diffAngle; lastRotAngle = rotAngle; } } } hasBigRotation = maxRotAngle >= 180.0; }
int main(int argc,const char **argv) { int returnVal = 0; g_Logger.Start("gmParser.log", true); LOG("gmParser"); if(argc < 2) { PrintUsage(); ERROR_RETURN; } Timer tme, totaltime; const char *FolderIn = argv[1]; //const char *FolderOut = argv[2]; if(!FileSystem::InitRawFileSystem(FolderIn)) { std::cout << "Unable to Initialize File System." << std::endl; ERROR_RETURN; } if(!FileSystem::Mount(FolderIn,"")) { std::cout << "Unable to Mount Root Folder." << std::endl; ERROR_RETURN; } if(!FileSystem::SetWriteDirectory(fs::path(FolderIn,fs::native))) { std::cout << "Unable to Set Write Folder." << std::endl; ERROR_RETURN; } // find all files to parse tme.Reset(); boost::regex ex("test.*.cpp"); DirectoryList dl; FileSystem::FindAllFiles("",dl,ex,true); std::cout << "Found " << dl.size() << " files in " << tme.GetElapsedSeconds() << " seconds." << std::endl;; // parse files tme.Reset(); typedef std::vector<FileParser> FileParserList; FileParserList parsers; parsers.reserve(dl.size()); for(obuint32 i = 0; i < dl.size(); ++i) { parsers.push_back(FileParser(dl[i].string())); } const int numParsers = parsers.size(); #pragma omp parallel for for(int i = 0; i < numParsers; ++i) { parsers[i].ParseFile(); std::cout << "*"; } std::cout << std::endl; std::cout << "Parsed " << numParsers << " files in " << tme.GetElapsedSeconds() << " seconds." << std::endl; // merge all to a master function list FunctionList allFunctions; allFunctions.reserve(2048); for(obuint32 i = 0; i < (obuint32)numParsers; ++i) { allFunctions.insert(allFunctions.end(),parsers[i].Functions.begin(),parsers[i].Functions.end()); for(obuint32 e = 0; e < parsers[i].Info.size(); ++e) { std::cout << parsers[i].Info[e] << std::endl; } } std::cout << "Found " << allFunctions.size() << " functions..." << std::endl; // write the function bindings out to files. tme.Reset(); const int numFiles = WriteFunctions(allFunctions); std::cout << "Wrote " << numFiles << " files in " << tme.GetElapsedSeconds() << " seconds." << std::endl; std::cout << "Finished in " << totaltime.GetElapsedSeconds() << " seconds." << std::endl; return 0; }
// Parse a region of tokens Node *Parser::ParseRegion(Parser::size_type start, Parser::size_type end) { size_type pos; size_type fgopen = (size_type)-1; size_type fgclose = (size_type)-1; size_type assignindex = (size_type)-1; size_type addsubindex = (size_type)-1; size_type muldivindex = (size_type)-1; size_type posnegindex = (size_type)-1; size_type expindex = (size_type)-1; bool multiexpr = false; int plevel = 0; // Check simple syntax if(start > end) throw(SyntaxException()); // Scan through tokens for(pos = start; pos <= end; pos++) { switch(m_tokens[pos].GetType()) { case Token::TypeOpenParenthesis: { plevel++; // Opening of first group? if(plevel == 1 && fgopen == (size_type)-1) fgopen = pos; break; }; case Token::TypeCloseParenthesis: { plevel--; // First group closed? if(plevel == 0 && fgclose == (size_type)-1) fgclose = pos; if(plevel < 0) { UnmatchedParenthesisException e; e.SetStart(m_tokens[pos].GetStart()); e.SetEnd(m_tokens[pos].GetEnd()); throw(e); } break; } case Token::TypeEqual: { if(plevel == 0) { if(assignindex == (size_type)-1) assignindex = pos; } break; } case Token::TypeAsterisk: case Token::TypeForwardSlash: { if(plevel == 0) { muldivindex = pos; } break; } case Token::TypeHat: { if(plevel == 0) { expindex = pos; } break; } case Token::TypePlus: case Token::TypeHyphen: { if(plevel == 0) { if(pos == start) { // Positive or negative sign if(posnegindex == (size_type)-1) posnegindex = pos; } else { // What is before us switch(m_tokens[pos - 1].GetType()) { case Token::TypeEqual: case Token::TypePlus: case Token::TypeHyphen: case Token::TypeAsterisk: case Token::TypeForwardSlash: case Token::TypeHat: // After any of these, we are a positive/negative if(posnegindex == (size_type)-1) posnegindex = pos; break; default: // After any other, we are addition/subtration addsubindex = pos; break; } } } break; } case Token::TypeSemicolon: { if(plevel == 0) { multiexpr = true; } break; } } } // plevel should be 0 if(plevel != 0) { UnmatchedParenthesisException e; e.SetStart(end); e.SetEnd(end); throw(e); } // Parse in certain order to maintain order of operators // Multi-expression first if(multiexpr) { auto_ptr<Node> n(new MultiNode(m_expr)); n->Parse(*this, start, end); return n.release(); } else if(assignindex != (size_type)-1) { // Assignment next auto_ptr<Node> n(new AssignNode(m_expr)); n->Parse(*this, start, end, assignindex); return n.release(); } else if(addsubindex != (size_type)-1) { // Addition/subtraction next if(m_tokens[addsubindex].GetType() == Token::TypePlus) { // Addition auto_ptr<Node> n(new AddNode(m_expr)); n->Parse(*this, start, end, addsubindex); return n.release(); } else { // Subtraction auto_ptr<Node> n(new SubtractNode(m_expr)); n->Parse(*this, start, end, addsubindex); return n.release(); } } else if(muldivindex != (size_type)-1) { // Multiplication/division next if(m_tokens[muldivindex].GetType() == Token::TypeAsterisk) { // Multiplication auto_ptr<Node> n(new MultiplyNode(m_expr)); n->Parse(*this, start, end, muldivindex); return n.release(); } else { // Division auto_ptr<Node> n(new DivideNode(m_expr)); n->Parse(*this, start, end, muldivindex); return n.release(); } } else if(posnegindex == start) { // Positive/negative next, must be at start and check before exponent if(m_tokens[posnegindex].GetType() == Token::TypePlus) { // Positive return ParseRegion(posnegindex + 1, end); } else { auto_ptr<Node> n(new NegateNode(m_expr)); n->Parse(*this, start, end, posnegindex); return n.release(); } } else if(expindex != (size_type)-1) { // Exponent auto_ptr<Node> n(new ExponentNode(m_expr)); n->Parse(*this, start, end, expindex); return n.release(); } else if(posnegindex != (size_type)-1) { // Check pos/neg again. After testing for exponent, a pos/neg // at plevel 0 is syntax error SyntaxException e; e.SetStart(m_tokens[posnegindex].GetStart()); e.SetEnd(m_tokens[posnegindex].GetEnd()); throw(e); } else if(fgopen == start) { // Group parenthesis, make sure something in between them if(fgclose == end && fgclose > fgopen + 1) { return ParseRegion(fgopen + 1, fgclose - 1); } else { SyntaxException e; e.SetStart(m_tokens[fgopen].GetStart()); if(fgclose == (size_type)-1) e.SetEnd(m_tokens[fgopen].GetEnd()); else e.SetEnd(m_tokens[fgclose].GetEnd()); throw(e); } } else if(fgopen == start + 1) { // Function if(fgclose == end) { // Find function list FunctionList *flist = m_expr->GetFunctionList(); if(flist == 0) { NoFunctionListException e; e.SetStart(m_tokens[start].GetStart()); e.SetEnd(m_tokens[start].GetEnd()); throw(e); } // Get name string ident = m_tokens[start].GetIdentifier(); // Create function node auto_ptr<FunctionNode> n(flist->Create(ident, m_expr)); if(n.get()) { n->Parse(*this, fgopen, fgclose); } else { NotFoundException e(ident); e.SetStart(m_tokens[start].GetStart()); e.SetEnd(m_tokens[start].GetEnd()); throw(e); } return n.release(); } else { SyntaxException e; e.SetStart(m_tokens[fgopen].GetStart()); if(fgclose == (size_type)-1) e.SetEnd(m_tokens[fgopen].GetEnd()); else e.SetEnd(m_tokens[fgclose].GetEnd()); throw(e); } } else if(start == end) { // Value, variable, or constant if(m_tokens[start].GetType() == Token::TypeIdentifier) { // Variable/constant auto_ptr<Node> n(new VariableNode(m_expr)); n->Parse(*this, start, end); return n.release(); } else { // Value auto_ptr<Node> n(new ValueNode(m_expr)); n->Parse(*this, start, end); return n.release(); } } else { // Unknown, syntax SyntaxException e; e.SetStart(m_tokens[pos].GetStart()); e.SetEnd(m_tokens[pos].GetEnd()); throw(e); } }