| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 | /*=============================================================================  Library: CTK  Copyright (c) German Cancer Research Center,    Division of Medical and Biological Informatics  Licensed under the Apache License, Version 2.0 (the "License");  you may not use this file except in compliance with the License.  You may obtain a copy of the License at    http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software  distributed under the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and  limitations under the License.=============================================================================*/#include <ctkCommandLineParser.h>#include <QCoreApplication>#include <QTextStream>#include <QFile>#include <QDebug>#include <QTime>#include <cstdlib>#ifdef Q_OS_WIN#include <windows.h>#else#include <time.h>#endifvoid sleep_ms(int ms){#ifdef Q_OS_WIN  Sleep(ms);#else  struct timespec nanostep;  nanostep.tv_sec = static_cast<time_t>(ms / 1000);  nanostep.tv_nsec = ((ms % 1000) * 1000.0 * 1000.0);  nanosleep(&nanostep, NULL);#endif}int main(int argc, char* argv[]){  QCoreApplication app(argc, argv);  // This is used by QSettings  QCoreApplication::setOrganizationName("CommonTK");  QCoreApplication::setApplicationName("CmdLineModuleTestBed");  ctkCommandLineParser parser;  // Use Unix-style argument names  parser.setArgumentPrefix("--", "-");  // Add command line argument names  parser.addArgument("help", "h", QVariant::Bool, "Show this help text");  parser.addArgument("xml", "", QVariant::Bool, "Print a XML description of this modules command line interface");  parser.addArgument("runtime", "", QVariant::Int, "Runtime in seconds", 1);  parser.addArgument("numOutputs", "", QVariant::Int, "Number of outpusts", 0);  parser.addArgument("exitCode", "", QVariant::Int, "Exit code", 0);  parser.addArgument("exitCrash", "", QVariant::Bool, "Force crash", false);  parser.addArgument("exitTime", "", QVariant::Int, "Exit time", 0);  parser.addArgument("errorText", "", QVariant::String, "Error text printed at the end");  QTextStream out(stdout, QIODevice::WriteOnly | QIODevice::Text);  QTextStream err(stderr, QIODevice::WriteOnly | QIODevice::Text);  // Parse the command line arguments  bool ok = false;  QHash<QString, QVariant> parsedArgs = parser.parseArguments(QCoreApplication::arguments(), &ok);  if (!ok)  {    err << "Error parsing arguments:" << parser.errorString() << endl;    return EXIT_FAILURE;  }  // Show a help message  if (parsedArgs.contains("help") || parsedArgs.contains("h"))  {    out << parser.helpText();    out.setFieldWidth(parser.fieldWidth());    out.setFieldAlignment(QTextStream::AlignLeft);    out << "  <output-path>" << "Path to the output image" << endl;    return EXIT_SUCCESS;  }  if (parsedArgs.contains("xml"))  {    sleep_ms(2000);    QFile xmlDescription(":/ctkCmdLineModuleTestBed.xml");    xmlDescription.open(QIODevice::ReadOnly);    out << xmlDescription.readAll();    return EXIT_SUCCESS;  }  if (parser.unparsedArguments().isEmpty())  {    err << "Error parsing arguments: <output-path> argument missing" << endl;    return EXIT_FAILURE;  }  // Do something  float runtime = parsedArgs["runtime"].toFloat();  int numOutputs = parsedArgs["numOutputs"].toInt();  float exitTime = parsedArgs["exitTime"].toFloat();  int exitTimeMillis = static_cast<long>(exitTime/2.0 * 1000.0);  int exitCode = parsedArgs["exitCode"].toInt();  bool exitCrash = parsedArgs["exitCrash"].toBool();  QString errorText = parsedArgs["errorText"].toString();  QString imageOutput = parser.unparsedArguments().at(0);  err << "A superficial error message." << endl;  // sleep 500ms to give the "errorReady" signal a chance  sleep_ms(500);  QStringList outputs;  for (int i = 0; i < numOutputs; ++i)  {    outputs << "Output " + QString::number(i+1);  }  float stepTime = outputs.size() ? runtime / static_cast<float>(outputs.size()) : runtime;  QTime time;  time.start();  out << "<filter-start>\n";  out << "<filter-name>Test Filter</filter-name>\n";  out << "<filter-comment>Does nothing useful</filter-comment>\n";  out << "</filter-start>" << endl;  if (outputs.empty())  {    outputs.push_back("dummy");  }  float progressStep = 1.0f / static_cast<float>(outputs.size());  for(int i = 0; i < outputs.size(); ++i)  {    QString output = outputs[i];    if (exitTimeMillis != 0 && exitTimeMillis < time.elapsed())    {      if (exitCrash)      {        int* crash = 0;        *crash = 5;      }      if (exitCode != 0 && !errorText.isEmpty())      {        err << errorText;      }      return exitCode;    }    // simulate some work    sleep_ms(stepTime*1000);    // print the first output    if (output != "dummy")    {      out << output << endl;      // report progress      out << QString("<filter-progress-text progress=\"%1\">").arg((i+1)*progressStep)          << "Calculating output " << (i+2) << "...</filter-progress-text>" << endl;      // report the current output number as a result      out << "<filter-result name=\"resultNumberOutput\">" << (i+1) << "</filter-result>" << endl;    }  }  // sleep 500ms to avoid squashing the last progress event with the finished event  sleep_ms(500);  if (!errorText.isEmpty())  {    err << errorText;    out << "<filter-result name=\"errorMsgOutput\">" << errorText << "</filter-result>" << endl;  }  else  {    out << "<filter-result name=\"imageOutput\">" << imageOutput << "</filter-result>" << endl;  }  out << "<filter-result name=\"exitStatusOutput\">";  if (exitCrash)  {    out << "Crashed</filter-result>" << endl;    int* crash = 0;    *crash = 5;  }  else  {    out << "Normal exit</filter-result>" << endl;    sleep_ms(100);    out << "<filter-progress>1</filter-progress>" << endl;    sleep_ms(100);    out << "<filter-end><filter-comment>Finished successfully.</filter-comment></filter-end>" << endl;    sleep_ms(100);  }  return exitCode;}
 |