Bug Summary

File:OMOptim/OMOptim/build/../Core/OpenModelica/OpenModelica.cpp
Warning:line 501, column 14
Value stored to 'ok' during its initialization is never read

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1// $Id$
2/**
3 * This file is part of OpenModelica.
4 *
5 * Copyright (c) 1998-CurrentYear, Open Source Modelica Consortium (OSMC),
6 * c/o Linköpings universitet, Department of Computer and Information Science,
7 * SE-58183 Linköping, Sweden.
8 *
9 * All rights reserved.
10 *
11 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR
12 * THIS OSMC PUBLIC LICENSE (OSMC-PL).
13 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
14 * OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the Open Source Modelica
17 * Consortium (OSMC) Public License (OSMC-PL) are obtained
18 * from OSMC, either from the above address,
19 * from the URLs: http://www.ida.liu.se/projects/OpenModelica or
20 * http://www.openmodelica.org, and in the OpenModelica distribution.
21 * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
22 *
23 * This program is distributed WITHOUT ANY WARRANTY; without
24 * even the implied warranty of MERCHANTABILITY or FITNESS
25 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
26 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
27 *
28 * See the full OSMC Public License conditions for more details.
29 *
30 * Main contributor 2010, Hubert Thierot, CEP - ARMINES (France)
31 * Main contributor 2010, Hubert Thierot, CEP - ARMINES (France)
32
33@file OpenModelica.cpp
34@brief Comments for file documentation.
35@author Hubert Thieriot, hubert.thieriot@mines-paristech.fr
36Company : CEP - ARMINES (France)
37http://www-cep.ensmp.fr/english/
38@version
39
40
41*/
42
43
44
45#include "OpenModelica.h"
46#include "ModPlusOMCtrl.h"
47#include "VariableType.h"
48#include "LowTools.h"
49#include "OpenModelicaParameters.h"
50#include "omc_config.h"
51#include "Utilities.h"
52
53// for .mat reading
54extern "C" {
55#include "omc_file.h"
56#include "omc_file.c"
57#include "read_matlab4.h"
58#include "read_matlab4.c"
59}
60
61OpenModelica::OpenModelica()
62{
63
64}
65
66OpenModelica::~OpenModelica(void)
67{
68}
69
70bool OpenModelica::compile(MOomc *_omc,QFileInfo moFile,QString modelToConsider,QDir storeFolder,const QFileInfoList & moDeps, QFileInfoList neededFiles, QFileInfoList neededFolders)
71{
72 // check if model already loaded
73 QFileInfo loadedMoFile = _omc->getFileOfClass(modelToConsider);
74
75 bool loadOk;
76 QString loadError;
77
78 // load moDependencies if not already loaded
79 // forceLoad = false
80 for(int i=0;i<moDeps.size();i++)
81 _omc->loadModel(moDeps.at(i).absoluteFilePath(),false,loadOk,loadError);
82
83 // if not already loaded, reload
84 if(loadedMoFile != moFile)
85 {
86 _omc->loadModel(moFile.absoluteFilePath(),true,loadOk,loadError);
87 }
88
89 // Create working dir
90 QString tmpPath = _omc->getWorkingDirectory();
91
92 // if(workDir.exists())
93 // LowTools::removeDirContents(tmpPath);
94 // else
95 // {
96 // QDir dir;
97 // dir.mkpath(tmpPath);
98 // }
99
100
101 if(!QDir(tmpPath).exists())
102 QDir().mkpath(tmpPath);
103 QDir workDir(tmpPath);
104
105 // Copy file and folder
106 LowTools::copyFilesInFolder(neededFiles,workDir.absolutePath());
107
108 _omc->changeDirectory(tmpPath);
109
110 QString exeFile;
111 QString initFile;
112 bool success = _omc->buildModel(modelToConsider,exeFile,initFile);
113
114 QFileInfoList filesToCopy;
115 filesToCopy << QFileInfo(exeFile) << QFileInfo(initFile);
116
117 LowTools::copyFilesInFolder(filesToCopy,storeFolder);
118 return success;
119}
120
121void OpenModelica::getInputVariablesFromTxtFile(MOomc *_omc,QString filePath, MOVector<Variable> * variables,QString _modelName)
122{
123 variables->clear();
124 QFileInfo fileinfo = QFileInfo(filePath);
125
126 if (fileinfo.exists())
127 {
128 QFile file(fileinfo.filePath());
129 file.open(QIODevice::ReadOnly);
130 QTextStream* in = new QTextStream(&file);
131 getInputVariablesFromTxtFile(_omc,in, variables,_modelName);
132 file.close();
133 }
134}
135void OpenModelica::getInputVariablesFromTxtFile(MOomc *_omc,QTextStream * text, MOVector<Variable> * variables,QString _modelName)
136{
137 variables->clear();
138 QString line;
139 QStringList linefields;
140
141 Variable *newVariable;
142 text->seek(0);
143
144 // Get variables' names
145 line = text->readLine();
146 QRegExp rx("^(\\S+)\\s*//(\\S+)\\s*$");
147 QRegExp rxDefault("^(\\S+)\\s*//[\\w||\\s]+//(\\S+)\\s*$");
148 QStringList fields;
149 while (!line.isEmpty()){
150 if(rx.indexIn(line)>-1)
151 {
152 fields = rx.capturedTexts();
153 newVariable = new Variable();
154 newVariable->setName(rx.cap(2));
155 newVariable->setModel(_modelName);
156 newVariable->setValue(rx.cap(1).toDouble());
157 variables->addItem(newVariable);
158 //get datatype
159 newVariable->setDataType(_omc->getPrimitiveDataType(newVariable->name()));
160 }
161 else if(rxDefault.indexIn(line)>-1)
162 {
163 fields = rxDefault.capturedTexts();
164 newVariable = new Variable();
165 newVariable->setName(rxDefault.cap(2));
166 newVariable->setModel(_modelName);
167 newVariable->setValue(rxDefault.cap(1).toDouble());
168 variables->addItem(newVariable);
169 //get datatype
170 newVariable->setDataType(_omc->getPrimitiveDataType(newVariable->name()));
171 }
172
173 line=text->readLine();
174 }
175}
176
177bool OpenModelica::getInputVariablesFromXmlFile(MOomc *omc,QString filePath, QString modModelName, MOVector<Variable> * variables)
178{
179 variables->clear();
180 QString error;
181
182 QDomDocument doc;
183 QFile file(filePath);
184 if( !file.open( QIODevice::ReadOnly ) )
185 {
186 // InfoSender::instance()->send( Info(ListInfo::PROBLEMFILENOTEXISTS,filePath));
187 return false;
188 }
189 else if( !doc.setContent(&file,&error) )
190 {
191 file.close();
192 // InfoSender::instance()->send( Info(ListInfo::PROBLEMFILECORRUPTED,error,filePath));
193 return false;
194 }
195 file.close();
196
197 // create problem
198 return getInputVariablesFromXmlFile(omc,doc,modModelName,variables);
199
200
201}
202bool OpenModelica::getInputVariablesFromXmlFile(MOomc *omc,const QDomDocument & doc , QString modModelName,MOVector<Variable> * variables)
203{
204 variables->clear();
205
206 QDomElement xfmi = doc.firstChildElement("fmiModelDescription");
207 QDomElement xModelVars = xfmi.firstChildElement("ModelVariables");
208 QDomNodeList listScalarVars = xModelVars.elementsByTagName("ScalarVariable");
209
210 bool ok;
211 bool allok = true;
212 for(int i=0;i<listScalarVars.size();i++)
213 {
214 Variable* newVar = variableFromFmi(listScalarVars.at(i).toElement(),modModelName,ok);
215 if(ok)
216 variables->addItem(newVar);
217 allok = allok && ok;
218 }
219
220 return allok;
221}
222
223Variable* OpenModelica::variableFromFmi(const QDomElement & el,QString modelName, bool & ok)
224{
225 ok = true;
226 QString name = el.attribute("name");
227 if(name.isEmpty())
228 {
229 ok = false;
230 return NULL__null;
231 }
232
233 Variable* newVar = new Variable();
234 newVar->setName(name);
235 newVar->setModel(modelName);
236 newVar->setDescription(el.attribute("description"));
237
238 //look for type
239 QDomElement elType = el.firstChildElement("Real");
240 if(!elType.isNull())
241 {
242 newVar->setDataType(OMREAL);
243 newVar->setValue(elType.attribute("start").toDouble(&ok));
244 }
245 elType = el.firstChildElement("Integer");
246 if(!elType.isNull())
247 {
248 newVar->setDataType(OMINTEGER);
249 newVar->setValue(elType.attribute("start").toInt(&ok));
250 }
251 elType = el.firstChildElement("Boolean");
252 if(!elType.isNull())
253 {
254 newVar->setDataType(OMBOOLEAN);
255 newVar->setValue(elType.attribute("start")=="true");
256 }
257
258 //look for causality
259 newVar->setCausality(varCausality(el));
260
261 if(!ok)
262 {
263 delete newVar;
264 return NULL__null;
265 }
266 else
267 return newVar;
268}
269
270VariableCausality OpenModelica::varCausality(const QDomElement & el)
271{
272 QString variability = el.attribute("variability");
273 QString causality = el.attribute("causality");
274
275 if(!variability.compare("parameter") || !causality.compare("input") )
276 return OMINPUT;
277 else
278 return OMOUTPUT;
279}
280
281bool OpenModelica::getFinalVariablesFromFile(QString fileName_, MOVector<Variable> *variables,QString _modelName)
282{
283 variables->clear();
284 QFileInfo fileinfo = QFileInfo(fileName_);
285
286 if (fileinfo.exists())
287 {
288 QFile file(fileinfo.filePath());
289 file.open(QIODevice::ReadOnly);
290 QTextStream* in = new QTextStream(&file);
291 bool ok = getFinalVariablesFromFile(in, variables,_modelName);
292 file.close();
293 delete in;
294 return ok;
295 }
296 else
297 return true;
298}
299
300
301/**
302 * Uses OpenModelica functions to read from .mat files : faster than csv (both writing and reading)
303 * @note : don't forget to free reader (omc_free_matlab4_reader()) in order to let files writable
304 */
305bool OpenModelica::getFinalVariablesFromMatFile(QString fileName, MOVector<Variable> * variables,QString _modelName)
306{
307
308 ModelicaMatReader reader;
309 ModelicaMatVariable_t *var;
310 const char* msg;
311 double value;
312 bool varOk;
313 int status ;
314 Variable* newVar;
315
316 //Read in mat file
317 if(0 != (msg = omc_new_matlab4_reader(fileName.toStdString().c_str(), &reader)))
318 {
319 InfoSender::instance()->sendError("Unable to read .mat file: "+QString(msg));
320
321#ifdef WIN32 // don't know why sigabrt on linux. Should look for.
322 delete[] msg;
323#endif
324 return false;
325 }
326
327 // delete[] msg;
328 //Read in timevector
329 double stopTime = omc_matlab4_stopTime(&reader);
330
331 if (reader.nvar < 1)
332 {
333 InfoSender::instance()->sendError("Unable to read .mat file : no variable inside");
334 omc_free_matlab4_reader(&reader);
335 return false;
336 }
337
338 // read in all values
339 for (int i = 0; i < reader.nall; i++)
340 {
341 newVar = new Variable();
342 QString name(reader.allInfo[i].name);
343 newVar->setName(name);
344 newVar->setModel(_modelName);
345
346
347 // read the variable final value
348 var = omc_matlab4_find_var(&reader, reader.allInfo[i].name);
349
350
351 if (!var->isParam)
352 {
353 status = omc_matlab4_val(&value,&reader,var,stopTime);
354 }
355 // if variable is a parameter then take at first step
356 else
357 {
358 status = omc_matlab4_val(&value,&reader,var,0.0);
359 }
360
361
362 varOk = (status==0);
363 if(!varOk && reader.nrows>0)
364 {
365 double *vals = omc_matlab4_read_vals(&reader,var->index);
366 value = vals[reader.nrows-1];
367 varOk = true;
368 }
369 newVar->setValue(value);
370
371
372 if(varOk)
373 variables->addItem(newVar);
374 else
375 {
376 InfoSender::instance()->debug("Couldn't find value of variable in .mat file :" + newVar->name());
377 delete newVar;
378 }
379 }
380
381
382 omc_free_matlab4_reader(&reader);
383 return true;
384}
385bool OpenModelica::getFinalVariablesFromFile(QTextStream *text, MOVector<Variable> * variables,QString _modelName)
386{
387 variables->clear();
388 QString line;
389 QStringList varNames;
390 QStringList varValues;
391
392 Variable *newVar;
393 text->seek(0);
394 QString str = text->readLine();
395
396 str.remove("\"");
397 varNames = str.split(",",QString::SkipEmptyParts);
398
399 while(!text->atEnd())
400 line=text->readLine();
401
402 varValues = line.split(",",QString::SkipEmptyParts);
403
404 if(varValues.size()!=varNames.size())
405 return false;
406
407 for(int i=0;i<varValues.size();i++)
408 {
409 newVar = new Variable();
410 newVar->setName(varNames.at(i));
411 newVar->setModel(_modelName);
412 newVar->setValue(varValues.at(i).toDouble());
413 variables->addItem(newVar);
414 }
415 return true;
416}
417
418void OpenModelica::setInputVariablesTxt(QString fileName, MOVector<Variable> *variables,QString modModelName,MOParameters *parameters)
419{
420 QFileInfo fileinfo = QFileInfo(fileName);
421 if (fileinfo.exists())
422 {
423 QFile file(fileinfo.filePath());
424 file.open(QIODevice::ReadOnly);
425 QTextStream textRead(&file);
426 QString allText = textRead.readAll();
427 file.close();
428 // change variable values
429 QRegExp rxLine;
430 int index=0;
431 QString newLine;
432 QString varName;
433 int iCurVar;
434 Variable* curVar;
435 QStringList fields;
436
437 for(int iV=0;iV<variables->size();iV++)
438 {
439 curVar = variables->at(iV);
440 varName = curVar->name(Variable::SHORT);
441 //varName = varName.remove(modModelName+".");
442 rxLine.setPattern(sciNumRx()+"\\s*(//[\\w*|\\s*]*//|//)\\s*"+varName);
443 index = rxLine.indexIn(allText);
444
445 if(index>-1)
446 {
447 fields = rxLine.capturedTexts();
448 newLine = curVar->getFieldValue(Variable::VALUE).toString() +"\t";
449 newLine += fields.at(2)+varName;
450 allText = allText.replace(rxLine.cap(0),newLine);
451 }
452 else
453 {
454 InfoSender::instance()->send(Info("Warning : unable to set variable value (not found in init file):"+varName,ListInfo::ERROR2));
455 }
456 }
457
458 // Parameters to write in init file
459 /// @deprecated Now OM uses xml input.
460 if(parameters)
461 {
462 QList<OpenModelicaParameters::Parameters> initParameters; // parameters to specify in init file
463 initParameters << OpenModelicaParameters::STOPTIME;
464
465 QStringList paramIndicators;
466 paramIndicators << "stop value";
467
468
469 QVariant paramValue;
470 QString paramName;
471 MOParameter * curParam;
472 int iP;
473 for(int i=0;i<initParameters.size();i++)
474 {
475 curParam = parameters->findItem(OpenModelicaParameters::str(initParameters.at(i)));
476 if(curParam)
477 {
478 paramName = paramIndicators.at(i);
479 paramValue = curParam->getFieldValue(MOParameter::VALUE);
480 rxLine.setPattern(sciNumRx()+"\\s*(//[\\w*|\\s*]*//|//)\\s*"+paramName);
481 index = rxLine.indexIn(allText);
482
483 if(index>-1)
484 {
485 fields = rxLine.capturedTexts();
486 newLine = paramValue.toString() +"\t";
487 newLine += fields.at(2)+paramName;
488 allText = allText.replace(rxLine.cap(0),newLine);
489 }
490 else
491 {
492 InfoSender::instance()->send(Info("Warning : unable to set parameter value (not found in init file):"+paramName,ListInfo::ERROR2));
493 }
494 }
495 }
496 }
497
498
499 fileinfo.setFile(fileName);
500 file.setFileName(fileinfo.filePath());
501 bool ok = file.open(QIODevice::WriteOnly);
Value stored to 'ok' during its initialization is never read
502 QTextStream textWrite(&file);
503 textWrite<<allText;
504 file.close();
505 }
506}
507
508bool OpenModelica::setInputXml(QString fileName, MOVector<Variable> *variables, QString modelName, MOParameters* parameters)
509{
510 QString error;
511 bool ok;
512 QDomDocument doc;
513 QFile file(fileName);
514 if( !file.open( QIODevice::ReadOnly ) )
515 {
516 InfoSender::instance()->debug("Model input file (xml) load failed");
517 return false;
518 }
519 else if( !doc.setContent(&file,&error) )
520 {
521 InfoSender::instance()->sendError("Model input file (xml) is corrupted ! ["+error+"]");
522 file.close();
523 return false;
524 }
525
526 // updates variables
527 setInputVariablesXml(doc,modelName,variables);
528
529 // updates parameters
530 if(parameters)
531 setInputParametersXml(doc,parameters);
532
533 //Writing in .min file
534 if(file.exists())
535 {
536 file.remove();
537 }
538
539 ok = file.open(QIODevice::WriteOnly);
540 QTextStream ts( &file );
541 ts << doc.toString();
542 file.close();
543
544 return ok;
545}
546
547
548
549void OpenModelica::setInputVariablesXml(QDomDocument & doc, QString modelName, MOVector<Variable> *variables)
550{
551 QDomElement xfmi = doc.firstChildElement("fmiModelDescription");
552 QDomElement oldxfmi = xfmi;
553
554 QDomElement xModelVars = xfmi.firstChildElement("ModelVariables");
555 QDomElement oldxModelVars = xModelVars;
556
557 QDomNodeList listScalarVars = xModelVars.elementsByTagName("ScalarVariable");
558
559
560 // filling map
561 QMap<QString,int> mapScalarVars; //<name,index in listScalarVars>
562 QMap<QDomElement,QDomElement> mapNewScalarVars; // <old node,new node>
563 QDomElement curVar;
564 QDomElement oldVar;
565 QDomElement newVar;
566 int index;
567 QDomElement oldType;
568 QDomElement newType;
569 QString localVarName;
570
571 // create map for index looking
572 for(int i=0;i<listScalarVars.size();i++)
573 {
574 curVar = listScalarVars.at(i).toElement();
575 mapScalarVars.insert(curVar.attribute("name"),i);
576 }
577
578 // change variables values
579 for(int i=0;i<variables->size();i++)
580 {
581 // getting local var name (name in init file does not contain model name)
582 localVarName = variables->at(i)->name(Variable::SHORT);
583 //localVarName = localVarName.remove(modelName+".");
584
585 index = mapScalarVars.value(localVarName,-1);
586 if(index>-1)
587 {
588 oldVar = listScalarVars.at(index).toElement();
589 newVar = oldVar;
590
591 oldType = newVar.firstChildElement("Real");
592 if(oldType.isNull())
593 oldType = newVar.firstChildElement("Integer");
594 if(oldType.isNull())
595 oldType = newVar.firstChildElement("Boolean");
596
597 if(!oldType.isNull())
598 {
599 newType = oldType;
600 newType.setAttribute("start",variables->at(i)->value().toString());
601 newVar.replaceChild(newType,oldType);
602 xModelVars.replaceChild(newVar,oldVar);
603 }
604 xModelVars.replaceChild(newVar,oldVar);
605 }
606 }
607
608 // update xfmi with new vars
609 xfmi.replaceChild(xModelVars,oldxModelVars);
610 doc.replaceChild(xfmi,oldxfmi);
611}
612
613
614void OpenModelica::setInputParametersXml(QDomDocument &doc,MOParameters *parameters)
615{
616 QDomElement xfmi = doc.firstChildElement("fmiModelDescription");
617 QDomElement oldxfmi = xfmi;
618
619 QDomElement xExp = xfmi.firstChildElement("DefaultExperiment");
620 QDomElement oldxExp = xExp;
621
622
623 double starttime = parameters->value(OpenModelicaParameters::str(OpenModelicaParameters::STARTTIME),0).toDouble();
624 double stoptime = parameters->value(OpenModelicaParameters::str(OpenModelicaParameters::STOPTIME),1).toDouble();
625 int nbIntervals = parameters->value(OpenModelicaParameters::str(OpenModelicaParameters::NBINTERVALS),2).toInt();
626 double stepSize = (stoptime-starttime)/nbIntervals;
627
628
629 MOParameter * curParam;
630 MOParameterListed* curParamListed;
631 for(int i=0;i<parameters->size();i++)
632 {
633 curParam = parameters->at(i);
634
635 if(!curParam->name().contains(" ")) // remove old parameters, temporary
636 {
637 if(curParam->name()==OpenModelicaParameters::str(OpenModelicaParameters::SOLVER))
638 {
639 curParamListed = dynamic_cast<MOParameterListed*>(curParam);
640 xExp.setAttribute(curParamListed->name(),curParamListed->strValue());
641 }
642 else if(curParam->name()==OpenModelicaParameters::str(OpenModelicaParameters::OUTPUT))
643 {
644 curParamListed = dynamic_cast<MOParameterListed*>(curParam);
645 xExp.setAttribute(curParamListed->name(),curParamListed->strValue());
646 }
647 else if (curParam->name()==OpenModelicaParameters::str(OpenModelicaParameters::NBINTERVALS))
648 {
649 xExp.setAttribute("stepSize",QString::number(stepSize));
650 }
651 else
652 {
653 xExp.setAttribute(curParam->name(),curParam->value().toString());
654 }
655 }
656 }
657
658 // update xfmi with new vars
659 xfmi.replaceChild(xExp,oldxExp);
660 doc.replaceChild(xfmi,oldxfmi);
661}
662
663
664bool OpenModelica::start(QString exeFile,QString &errMsg,int maxnsec)
665{
666
667 QFileInfo exeFileInfo(exeFile);
668 QString exeDir = exeFileInfo.absolutePath();
669 if(!QFile::exists(exeFile))
670 {
671 errMsg = "Cannot find model executable file : " + exeFile;
672 return false;
673 }
674
675 QProcess simProcess;
676 simProcess.setWorkingDirectory(exeDir);
677
678
679#ifdef WIN32
680 QString appPath = "\""+exeFile+"\"";
681 // add OM path in PATH
682 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
683 QString mingw = Utilities::getMinGWBinPath();
684 QString om = Utilities::getOMBinPath();
685 env.insert("PATH", env.value("PATH") + ";"+om+";"+mingw);
686
687 simProcess.setProcessEnvironment(env);
688
689 //start process
690 simProcess.start(appPath, QStringList());
691#else
692 QStringList arguments;
693 arguments << "-c";
694 arguments << "./"+exeFileInfo.fileName() << " > log.txt";
695 simProcess.start("sh", arguments);
696#endif
697
698 int nmsec;
699 if(maxnsec==-1)
700 nmsec = -1;
701 else
702 nmsec = maxnsec*1000;
703 bool ok = simProcess.waitForFinished(nmsec);
704 if(!ok)
705 {
706 errMsg = "Simulation process failed or time limit reached";
707 simProcess.close();
708 return false;
709 }
710
711 QString output(simProcess.readAllStandardOutput());
712 InfoSender::instance()->send(Info(output,ListInfo::OMCNORMAL2));
713 return ok;
714}
715
716QString OpenModelica::sciNumRx()
717{
718 QString rx = "([+-]?[0-9]*\\.?[0-9]+|[+-]?[0-9]+\\.?[0-9]*[eE][+-]?[0-9]+)";
719 return rx;
720}
721
722
723QString OpenModelica::home()
724{
725 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
726 QString omHome = env.value("OPENMODELICAHOME");
727 return omHome;
728}
729
730/**
731 * Tries to find library path corresponding to version set as parameter.
732 * If not found return newest library path.
733 */
734QString OpenModelica::getLibraryPath(QString version)
735{
736 const char *omlibrary = getenv("OPENMODELICALIBRARY");
737 QString omLibraryFolder(omlibrary);
738
739 QDir omLibDir(omlibrary);
740 QStringList omLibDirs = omLibDir.entryList(QDir::AllDirs| QDir::NoDotAndDotDot);
741 omLibDirs = omLibDirs.filter(QRegExp("^Modelica .*"));
742 if(omLibDirs.isEmpty())
743 return QString();
744 else
745 {
746 int iVersion = omLibDirs.indexOf("Modelica "+version);
747 if(iVersion>-1)
748 return omLibDir.absoluteFilePath(omLibDirs.at(iVersion)+QDir::separator()+"package.mo");
749
750 else
751 {
752 omLibDirs.sort();
753 return omLibDir.absoluteFilePath(omLibDirs.last()+QDir::separator()+"package.mo");
754 }
755 }
756}