<commit_before>// Copyright (c) Burator 2014-2015
#include <QDir>
#include <QFile>
#include <QImage>
#include <QDebug>
#include <QString>
#include <QFileInfo>
#include <QByteArray>
#include <QStringList>
#include <QCoreApplication>
#include <QCommandLineParser>

#include "Util.h"
#include "Types.h"
#include "Global.h"
#include "Version.h"
#include "FaceDetector.h"

B_USE_NAMESPACE

// Show console output.
static const bool showOutput = true;

// Show debug/info output.
static const bool showDebug = true;

void msgHandler(QtMsgType type, const QMessageLogContext &ctx,
                const QString &msg);

int main(int argc, char **argv) {
	QCoreApplication app(argc, argv);
	QCoreApplication::setApplicationName("Blurator");
	QCoreApplication::setApplicationVersion(versionString());

  qInstallMessageHandler(msgHandler);

  QCommandLineParser parser;
  parser.setApplicationDescription("Blur license plates and faces.");
  parser.addHelpOption();
  parser.addVersionOption();
  parser.addPositionalArgument("paths", "Paths to images.", "paths..");

  // Face detection option
  QCommandLineOption detectFaces(QStringList() << "f" << "faces",
                                 "Detect faces.");
  parser.addOption(detectFaces);

  // License plate detection option
  QCommandLineOption detectPlates(QStringList() << "p" << "plates",
                                  "Detect license plates.");
  parser.addOption(detectPlates);

  // Reply "yes" to everything option
  QCommandLineOption replyYes(QStringList() << "y" << "yes",
                              "Automatically reply \"yes\" to all questions.");
  parser.addOption(replyYes);

  // Reply "no" to everything option
  QCommandLineOption replyNo(QStringList() << "n" << "no",
                             "Automatically reply \"no\" to all questions.");
  parser.addOption(replyNo);

  // No-backup file option
  QCommandLineOption noBackupFile(QStringList() << "no-backup",
                                 "Don't store a backup of the original image.");
  parser.addOption(noBackupFile);

  parser.process(app);
  const QStringList args = parser.positionalArguments();

  // Check optional command line options
  bool dFaces = parser.isSet(detectFaces);
  bool dPlates = parser.isSet(detectPlates);
  bool rYes = parser.isSet(replyYes);
  bool rNo = parser.isSet(replyNo);
  bool noBackup = parser.isSet(noBackupFile);

  // Ensure the arguments are passed.
  if (args.isEmpty()) {
  	qCritical() << "Must provide paths to images!";
  	return -1;
  }

  if (!dPlates && !dFaces) {
    qCritical() << "Must choose to detect plates and/or faces!";
    return -1;
  }

  if (rYes && rNo) {
    qCritical() << "Can't both say yes and no to everything!";
    return -1;
  }

  // If non-null then the boolean value means reply "yes" for true and
  // "no" for false.
  BoolPtr autoReplyYes(nullptr);
  if (rYes || rNo) {
    autoReplyYes.reset(new bool);
    *autoReplyYes = rYes;
  }

  // Find all images from the arguments.
  QStringList images;
  foreach (const QString &path, args) {
    QFileInfo fi(path);
    if (!fi.exists()) {
      qWarning() << "Ignoring nonexistent file" << path;
      continue;
    }

    if (fi.isFile() && Util::isSupportedImage(path)) {
      images << path;
    }
    else if (fi.isDir()) {
      qWarning() << "Ignoring folder" << path;
    }
  }

  if (images.isEmpty()) {
    qCritical() << "Found no supported images to process!";
    return -1;
  }

  if (noBackup) {
    qWarning() << "Warning no backup files will be created!";
  }

  const int size = images.size();
  for (int i = 0; i < size; i++) {
    const QString &path = images[i];
    qDebug() <<
      qPrintable(QString("[%1/%2] Processing %3").arg(i+1).arg(size).arg(path));

    if (dFaces) {
      QFile f(path);
      if (!f.open(QIODevice::ReadOnly)) {
        qCritical() << "Could not read from image file!";
        return -1;
      }
      QByteArray imageData = f.readAll();
      f.close();

      MatPtr image = Util::imageToMat(imageData);
      if (image == nullptr) {
        qCritical() << "Invalid image!";
        return -1;
      }

      FaceDetector detector;
      if (!detector.isValid()) {
        qCritical() << "Could not setup facial detector.";
        return -1;
      }

      QList<FacePtr> faces = detector.detect(image);
      if (faces.isEmpty()) {
        continue;
      }

      qDebug() << "Found" << faces.size() << "face(s).";
      qDebug() << faces;

      // Render face overlays to an image file to visualize the result.
      if (!faces.isEmpty()) {
        QImage overlay = QImage::fromData(imageData);
        Util::drawFaces(overlay, faces);

        // Save original to backup file.
        if (!noBackup) {
          QString bpath = Util::getBackupPath(path);
          if (QFile::copy(path, bpath)) {
            qDebug() << "Saved backup to" << bpath;
          }
          else {
            qWarning() << "Could not save backup to" << bpath;
            if (!Util::askProceed("Do you want to proceed?", autoReplyYes.get())) {
              qWarning() << "Aborting..";
              return -1;
            }
          }
        }

        if (overlay.save(path)) {
          qDebug() << "Saved face overlays to" << path;
        }
        else {
          qCritical() << "Could not save overlays";
        }
      }
    }

    // TODO: Plate detection
    if (dPlates) {
      qCritical() << "Plate detection not implemented yet!";
      return -1;
    }
  }

  return 0;
}

void msgHandler(QtMsgType type, const QMessageLogContext &ctx,
                const QString &msg) {
  if (!showOutput) return;

  QTextStream stream(stdout);

  switch (type) {
  case QtDebugMsg:
    if (showDebug) {
      if (QString(msg) == "") {
        stream << endl;
        return;
      }
      stream << "(I) " << msg << endl;
    }
    break;

  case QtWarningMsg:
    stream << "(W) " << msg << endl;
    break;

  case QtCriticalMsg:
    stream << "(E) " << msg << endl;
    break;

  case QtFatalMsg:
    stream << "(F) " << msg << endl;
    abort();
  }
}
<commit_msg>Removed (I) for normal info/debug and only show (W), (E), and (F).<commit_after>// Copyright (c) Burator 2014-2015
#include <QDir>
#include <QFile>
#include <QImage>
#include <QDebug>
#include <QString>
#include <QFileInfo>
#include <QByteArray>
#include <QStringList>
#include <QCoreApplication>
#include <QCommandLineParser>

#include "Util.h"
#include "Types.h"
#include "Global.h"
#include "Version.h"
#include "FaceDetector.h"

B_USE_NAMESPACE

// Show console output.
static const bool showOutput = true;

// Show debug/info output.
static const bool showDebug = true;

void msgHandler(QtMsgType type, const QMessageLogContext &ctx,
                const QString &msg);

int main(int argc, char **argv) {
	QCoreApplication app(argc, argv);
	QCoreApplication::setApplicationName("Blurator");
	QCoreApplication::setApplicationVersion(versionString());

  qInstallMessageHandler(msgHandler);

  QCommandLineParser parser;
  parser.setApplicationDescription("Blur license plates and faces.");
  parser.addHelpOption();
  parser.addVersionOption();
  parser.addPositionalArgument("paths", "Paths to images.", "paths..");

  // Face detection option
  QCommandLineOption detectFaces(QStringList() << "f" << "faces",
                                 "Detect faces.");
  parser.addOption(detectFaces);

  // License plate detection option
  QCommandLineOption detectPlates(QStringList() << "p" << "plates",
                                  "Detect license plates.");
  parser.addOption(detectPlates);

  // Reply "yes" to everything option
  QCommandLineOption replyYes(QStringList() << "y" << "yes",
                              "Automatically reply \"yes\" to all questions.");
  parser.addOption(replyYes);

  // Reply "no" to everything option
  QCommandLineOption replyNo(QStringList() << "n" << "no",
                             "Automatically reply \"no\" to all questions.");
  parser.addOption(replyNo);

  // No-backup file option
  QCommandLineOption noBackupFile(QStringList() << "no-backup",
                                 "Don't store a backup of the original image.");
  parser.addOption(noBackupFile);

  parser.process(app);
  const QStringList args = parser.positionalArguments();

  // Check optional command line options
  bool dFaces = parser.isSet(detectFaces);
  bool dPlates = parser.isSet(detectPlates);
  bool rYes = parser.isSet(replyYes);
  bool rNo = parser.isSet(replyNo);
  bool noBackup = parser.isSet(noBackupFile);

  // Ensure the arguments are passed.
  if (args.isEmpty()) {
  	qCritical() << "Must provide paths to images!";
  	return -1;
  }

  if (!dPlates && !dFaces) {
    qCritical() << "Must choose to detect plates and/or faces!";
    return -1;
  }

  if (rYes && rNo) {
    qCritical() << "Can't both say yes and no to everything!";
    return -1;
  }

  // If non-null then the boolean value means reply "yes" for true and
  // "no" for false.
  BoolPtr autoReplyYes(nullptr);
  if (rYes || rNo) {
    autoReplyYes.reset(new bool);
    *autoReplyYes = rYes;
  }

  // Find all images from the arguments.
  QStringList images;
  foreach (const QString &path, args) {
    QFileInfo fi(path);
    if (!fi.exists()) {
      qWarning() << "Ignoring nonexistent file" << path;
      continue;
    }

    if (fi.isFile() && Util::isSupportedImage(path)) {
      images << path;
    }
    else if (fi.isDir()) {
      qWarning() << "Ignoring folder" << path;
    }
  }

  if (images.isEmpty()) {
    qCritical() << "Found no supported images to process!";
    return -1;
  }

  if (noBackup) {
    qWarning() << "Warning no backup files will be created!";
  }

  const int size = images.size();
  for (int i = 0; i < size; i++) {
    const QString &path = images[i];
    qDebug() <<
      qPrintable(QString("[%1/%2] Processing %3").arg(i+1).arg(size).arg(path));

    if (dFaces) {
      QFile f(path);
      if (!f.open(QIODevice::ReadOnly)) {
        qCritical() << "Could not read from image file!";
        return -1;
      }
      QByteArray imageData = f.readAll();
      f.close();

      MatPtr image = Util::imageToMat(imageData);
      if (image == nullptr) {
        qCritical() << "Invalid image!";
        return -1;
      }

      FaceDetector detector;
      if (!detector.isValid()) {
        qCritical() << "Could not setup facial detector.";
        return -1;
      }

      QList<FacePtr> faces = detector.detect(image);
      if (faces.isEmpty()) {
        continue;
      }

      qDebug() << "Found" << faces.size() << "face(s).";
      qDebug() << faces;

      // Render face overlays to an image file to visualize the result.
      if (!faces.isEmpty()) {
        QImage overlay = QImage::fromData(imageData);
        Util::drawFaces(overlay, faces);

        // Save original to backup file.
        if (!noBackup) {
          QString bpath = Util::getBackupPath(path);
          if (QFile::copy(path, bpath)) {
            qDebug() << "Saved backup to" << bpath;
          }
          else {
            qWarning() << "Could not save backup to" << bpath;
            if (!Util::askProceed("Do you want to proceed?", autoReplyYes.get())) {
              qWarning() << "Aborting..";
              return -1;
            }
          }
        }

        if (overlay.save(path)) {
          qDebug() << "Saved face overlays to" << path;
        }
        else {
          qCritical() << "Could not save overlays";
        }
      }
    }

    // TODO: Plate detection
    if (dPlates) {
      qCritical() << "Plate detection not implemented yet!";
      return -1;
    }
  }

  return 0;
}

void msgHandler(QtMsgType type, const QMessageLogContext &ctx,
                const QString &msg) {
  if (!showOutput) return;

  QTextStream stream(stdout);

  switch (type) {
  case QtDebugMsg:
    if (showDebug) {
      if (QString(msg) == "") {
        stream << endl;
        return;
      }
      stream << msg << endl;
    }
    break;

  case QtWarningMsg:
    stream << "(W) " << msg << endl;
    break;

  case QtCriticalMsg:
    stream << "(E) " << msg << endl;
    break;

  case QtFatalMsg:
    stream << "(F) " << msg << endl;
    abort();
  }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>

#include "main.h"

using namespace std;
using namespace cv;
using namespace proj;
using namespace proj_transform;

namespace {

Mat tmpImage;
Transform *img;

} // namespace

int main(int argc, char **argv)
{
  // Read image given by user
  if (argc < 2) {
    usage();
    exit(EXIT_FAILURE);
  }
  int width = 420, height = 594;
  if (argc == 4) {
    width  = atoi(argv[2]);
    height = atoi(argv[3]);
    cout << width << ", " << height << endl;
  }
  const Mat inputImage = imread(argv[1]);
  inputImage.copyTo(tmpImage);

  // initialize output image
  Mat outputImage = Mat::zeros( Size(width, height), inputImage.type() );
  // create instance for image transformation
  img = new Transform(inputImage, &outputImage);
  // create a window and register a callback function for mouse events
  namedWindow("Input image", 0);
  setMouseCallback("Input image", onMouse);
  imshow("Input image", tmpImage);

  cout << "\nSelect corners clockwise from the upper left.\n";
  cout << "Press any key to exit." << endl;
  if (waitKey()) {
    return 1;
  }
}
namespace proj {

// **********************************************************
// proj::usage()
// ----------------------------------------------------------
// Usage: proj input_image [width] [height]
//
void usage() {
  cout << "Usage:\tproj input_image [output_width] [output_height]" << endl;
}
// **********************************************************
// proj::onMouse()
// ----------------------------------------------------------
// Draw circle when mouse will clicked.
// If there are 4 circles, then transformation will start.
//
void onMouse (int event, int x, int y, int flags, void *param = NULL)
{
  static unsigned int edge = 0;
  static vector<Point3d> inputPoints;

  // get mouse events
  switch (event) {
  case CV_EVENT_LBUTTONDOWN:
    inputPoints.push_back(Point3d(x, y, 1));
    edge++;
    break;
  default:
    return;
  }
  // draw a circle in mouse coord.
  Point center(x, y);
  const unsigned int radius = 20;
  const unsigned int thickness = 5;
  circle(tmpImage, center, radius, CV_RGB(255, 255, 255), thickness);
  imshow("Input image", tmpImage);
  if (edge == 4) {
    img->setInputPoints(inputPoints);
    img->myPerspectiveTransform();
  }
}

} // namespace proj
<commit_msg>fix a grammatical error<commit_after>#include <iostream>
#include <vector>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>

#include "main.h"

using namespace std;
using namespace cv;
using namespace proj;
using namespace proj_transform;

namespace {

Mat tmpImage;
Transform *img;

} // namespace

int main(int argc, char **argv)
{
  // Read image given by user
  if (argc < 2) {
    usage();
    exit(EXIT_FAILURE);
  }
  int width = 420, height = 594;
  if (argc == 4) {
    width  = atoi(argv[2]);
    height = atoi(argv[3]);
    cout << width << ", " << height << endl;
  }
  const Mat inputImage = imread(argv[1]);
  inputImage.copyTo(tmpImage);

  // initialize output image
  Mat outputImage = Mat::zeros( Size(width, height), inputImage.type() );
  // create instance for image transformation
  img = new Transform(inputImage, &outputImage);
  // create a window and register a callback function for mouse events
  namedWindow("Input image", 0);
  setMouseCallback("Input image", onMouse);
  imshow("Input image", tmpImage);

  cout << "\nSelect corners clockwise from the upper left.\n";
  cout << "Press any key to exit." << endl;
  if (waitKey()) {
    return 1;
  }
}
namespace proj {

// **********************************************************
// proj::usage()
// ----------------------------------------------------------
// Usage: proj input_image [width] [height]
//
void usage() {
  cout << "Usage:\tproj input_image [output_width] [output_height]" << endl;
}
// **********************************************************
// proj::onMouse()
// ----------------------------------------------------------
// Draw a circle when click the right mouse button.
//
void onMouse (int event, int x, int y, int flags, void *param = NULL)
{
  static unsigned int edge = 0;
  static vector<Point3d> inputPoints;

  // get mouse events
  switch (event) {
  case CV_EVENT_LBUTTONDOWN:
    inputPoints.push_back(Point3d(x, y, 1));
    edge++;
    break;
  default:
    return;
  }
  // draw a circle in mouse coord.
  Point center(x, y);
  const unsigned int radius = 20;
  const unsigned int thickness = 5;
  circle(tmpImage, center, radius, CV_RGB(255, 255, 255), thickness);
  imshow("Input image", tmpImage);
  if (edge == 4) {
    img->setInputPoints(inputPoints);
    img->myPerspectiveTransform();
  }
}

} // namespace proj
<|endoftext|>


<commit_before>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
	printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.galFile.c_str());
    std::vector<int> count;
    count=count_galaxies(G);
    for(int i=0;i<8;i++){printf ("   %d  \n",count[i]);}
    // make MTL
    MTL M=make_MTL(G,F);
    for(int i=0;i<M.priority_list.size();++i){
        printf(" priority   %d",M.priority_list[i]);
    }
    printf(" \n");
    assign_priority_class(M);
    //find available SS and SF galaxies on each petal

    std::vector <int> count_class(M.priority_list.size(),0);
    for(int i;i<M.size();++i){
        count_class[M[i].priority_class]+=1;
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

    printf(" number of MTL galaxies  %d\n",M.size());
    printf("Read fiber center positions and compute related things\n");
	PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    printf("spectrometer has to be identified from 0 to F.Npetal-1\n");
	F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
    printf("get neighbors of each fiber;\n");
                                                //for each spectrometer, get list of fibers

    printf("Read plates in order they are to be observed\n ");

	Plates P_original = read_plate_centers(F);
    F.Nplate=P_original.size();
    printf("This takes the place of Opsim or NextFieldSelector; will be replaced by appropriate code\n");
    Plates P;
    P.resize(F.Nplate);
    List permut = random_permut(F.Nplate);
    for (int jj=0; jj<F.Nplate; jj++){
        P[jj]=P_original[permut[jj]];
    }

	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
	collect_galaxies_for_all(M,T,P,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf("before assignment\n");
	Assignment A(M,F);
	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
	//new_assign_fibers(G,P,pp,F,A); // Plans whole survey without sky fibers, standard stars
                                   // assumes maximum number of observations needed for QSOs, LRGs
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);

    simple_assign(M,P,pp,F,A);
    diagnostic(M,G,F,A);
    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs
                                    // Want to have even distribution of unused fibers
                                    // so we can put in sky fibers and standard stars

	// Smooth out distribution of free fibers, and increase the number of assignments
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {                           // more iterations will improve performance slightly
		improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);

	// Still not updated, so all QSO targets have multiple observations etc
	// Apply and update the plan --------------------------------------
	init_time_at(time,"# Begin real time assignment",t);
	for (int jj=0; jj<F.Nplate; jj++) {
		int j = A.next_plate;

		//assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation
		//assign_unused(j,M,P,pp,F,A);
		//if (j%2000==0) pyplotTile(j,"doc/figs",G,P,pp,F,A); // Picture of positioners, galaxies

		//printf(" %s not as - ",format(5,f(A.unused_f(j,F))).c_str()); fl();
		// Update corrects all future occurrences of wrong QSOs etc and tries to observe something else

		if (0<=j-F.Analysis) update_plan_from_one_obs(G,M,P,pp,F,A,F.Nplate-1); else printf("\n");

		A.next_plate++;
		// Redistribute and improve on various occasions  add more times if desired

		if ( j==1000 || j==4000) {
			redistribute_tf(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
			improve(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
            //diagnostic(M,G,F,A);
		}
	}
	print_time(time,"# ... took :");

	// Results -------------------------------------------------------
	if (F.Output) for (int j=0; j<F.Nplate; j++) write_FAtile_ascii(j,F.outDir,M,P,pp,F,A); // Write output
	display_results("doc/figs/",M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<commit_msg>fix display results in main<commit_after>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
	printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.galFile.c_str());
    std::vector<int> count;
    count=count_galaxies(G);
    for(int i=0;i<8;i++){printf ("   %d  \n",count[i]);}
    // make MTL
    MTL M=make_MTL(G,F);
    for(int i=0;i<M.priority_list.size();++i){
        printf(" priority   %d",M.priority_list[i]);
    }
    printf(" \n");
    assign_priority_class(M);
    //find available SS and SF galaxies on each petal

    std::vector <int> count_class(M.priority_list.size(),0);
    for(int i;i<M.size();++i){
        count_class[M[i].priority_class]+=1;
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

    printf(" number of MTL galaxies  %d\n",M.size());
    printf("Read fiber center positions and compute related things\n");
	PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    printf("spectrometer has to be identified from 0 to F.Npetal-1\n");
	F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
    printf("get neighbors of each fiber;\n");
                                                //for each spectrometer, get list of fibers

    printf("Read plates in order they are to be observed\n ");

	Plates P_original = read_plate_centers(F);
    F.Nplate=P_original.size();
    printf("This takes the place of Opsim or NextFieldSelector; will be replaced by appropriate code\n");
    Plates P;
    P.resize(F.Nplate);
    List permut = random_permut(F.Nplate);
    for (int jj=0; jj<F.Nplate; jj++){
        P[jj]=P_original[permut[jj]];
    }

	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
	collect_galaxies_for_all(M,T,P,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
    printf("before assignment\n");
	Assignment A(M,F);
	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
	//new_assign_fibers(G,P,pp,F,A); // Plans whole survey without sky fibers, standard stars
                                   // assumes maximum number of observations needed for QSOs, LRGs
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);

    simple_assign(M,P,pp,F,A);
    diagnostic(M,G,F,A);
    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs
                                    // Want to have even distribution of unused fibers
                                    // so we can put in sky fibers and standard stars

	// Smooth out distribution of free fibers, and increase the number of assignments
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {                           // more iterations will improve performance slightly
		improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);

	// Still not updated, so all QSO targets have multiple observations etc
	// Apply and update the plan --------------------------------------
	init_time_at(time,"# Begin real time assignment",t);
	for (int jj=0; jj<F.Nplate; jj++) {
		int j = A.next_plate;

		//assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation
		//assign_unused(j,M,P,pp,F,A);
		//if (j%2000==0) pyplotTile(j,"doc/figs",G,P,pp,F,A); // Picture of positioners, galaxies

		//printf(" %s not as - ",format(5,f(A.unused_f(j,F))).c_str()); fl();
		// Update corrects all future occurrences of wrong QSOs etc and tries to observe something else

		if (0<=j-F.Analysis) update_plan_from_one_obs(G,M,P,pp,F,A,F.Nplate-1); else printf("\n");

		A.next_plate++;
		// Redistribute and improve on various occasions  add more times if desired

		if ( j==1000 || j==4000) {
			redistribute_tf(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
			improve(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
            //diagnostic(M,G,F,A);
		}
	}
	print_time(time,"# ... took :");

	// Results -------------------------------------------------------
	if (F.Output) for (int j=0; j<F.Nplate; j++) write_FAtile_ascii(j,F.outDir,M,P,pp,F,A); // Write output
	display_results("doc/figs/",G,M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<|endoftext|>


<commit_before>#include <chrono>
#include <iostream>
#include <vector>
#include <utility> // std::pair

#include <armadillo>

#include "AudioFFT.h"

using std::chrono::high_resolution_clock;
using std::chrono::duration;
using AudioVec = std::vector<float>;
using audiofft::AudioFFT;
using FftwData = std::tuple<AudioFFT& // fft class
                           ,AudioVec& // input vector
						   ,AudioVec& // real vector
						   ,AudioVec& // imag vector
						   ,AudioVec&>; // output vector

namespace {
	uint32_t num = 1;
	uint32_t fft_size = 48000;
	uint32_t conv_ir_size = 72000;
	uint32_t conv_sig_size = 5760000;
}

std::pair<duration<double>, arma::fvec> Convolution(arma::fvec sig, arma::fvec ir) {
	size_t size = (::conv_sig_size+::conv_ir_size-1);
	ir = arma::flipud(ir);
	arma::fvec sig_new = arma::zeros<arma::fvec>(::conv_sig_size + 2*(::conv_ir_size-1));
	sig_new.subvec(::conv_ir_size - 1, ::conv_sig_size + ::conv_ir_size -2) = sig;
	arma::fvec output (::conv_sig_size + ::conv_ir_size - 1, arma::fill::zeros);

	auto begin = high_resolution_clock::now();
	for (uint32_t cnt=0;cnt<::num;++cnt) {
		for (uint32_t sample_cnt=0;sample_cnt<size;++sample_cnt) {
			for (uint32_t ir_cnt=0;ir_cnt<::conv_ir_size;++ir_cnt) {
				output[sample_cnt] += sig_new[sample_cnt+ir_cnt] * ir[ir_cnt];
			}
		}
	}
	AudioVec output_copy = arma::conv_to<AudioVec>::from(output);
	auto end = high_resolution_clock::now();

	return std::make_pair(end - begin, output);
}

std::pair<duration<double>, arma::fvec> ArmadilloConv(arma::fvec sig, arma::fvec ir) {
	arma::fvec output;

	auto begin = high_resolution_clock::now();
	for (uint32_t cnt=0;cnt<::num;++cnt) {
		output = arma::conv(sig, ir);
	}
	AudioVec output_copy = arma::conv_to<AudioVec>::from(output);
	auto end = high_resolution_clock::now();

	return std::make_pair(end - begin, output);
}

duration<double> FftwConv(FftwData sig, FftwData ir) {
	auto sig_in = std::get<1>(sig);
	auto sig_re = std::get<2>(sig);
	auto sig_im = std::get<3>(sig);
	auto ir_in = std::get<1>(ir);
	auto ir_re = std::get<2>(ir);
	auto ir_im = std::get<3>(ir);
	AudioVec re (sig_re.size());
	AudioVec im (sig_re.size());

	auto begin = high_resolution_clock::now();
	std::get<0>(sig).fft(sig_in.data(), sig_re.data(), sig_im.data());
	std::get<0>(ir).fft(ir_in.data(), ir_re.data(), ir_im.data());
	for (size_t cnt=0;cnt<sig_re.size();++cnt) {
		re[cnt] = sig_re[cnt]*ir_re[cnt] - sig_im[cnt]*ir_im[cnt];
		im[cnt] = sig_re[cnt]*ir_im[cnt] + sig_im[cnt]*ir_re[cnt];
	}
	std::get<0>(sig).ifft(std::get<4>(sig).data(), re.data(), im.data());
	auto end = high_resolution_clock::now();

	return end - begin;
}

std::pair<duration<double>, arma::fvec> ArmadilloFftConv(arma::fvec sig, arma::fvec ir) {
	arma::cx_fvec output;
	size_t size = sig.size() + ir.size() - 1;

	auto begin = high_resolution_clock::now();
	for (uint32_t cnt=0;cnt<::num;++cnt) {
		output = arma::ifft(arma::fft(sig, size) % arma::fft(ir, size));
	}
	AudioVec output_copy = arma::conv_to<AudioVec>::from(arma::real(output));
	auto end = high_resolution_clock::now();

	return std::make_pair(end - begin, arma::real(output));
}

std::pair<duration<double>, arma::fvec> ArmadilloFftPow2Conv(arma::fvec sig, arma::fvec ir) {
	uint32_t size = pow(2,ceil(log2(::conv_sig_size + ::conv_ir_size - 1)));
	arma::cx_fvec output;

	auto begin = high_resolution_clock::now();
	for (uint32_t cnt=0;cnt<::num;++cnt) {
		output = arma::ifft(arma::fft(sig,size) % arma::fft(ir,size));
	}
	AudioVec output_copy = arma::conv_to<AudioVec>::from(arma::real(output));
	auto end = high_resolution_clock::now();

	return std::make_pair(end - begin, arma::real(output.subvec(0, ::conv_sig_size + ::conv_ir_size - 2)));
}

std::pair<duration<double>,arma::fvec> ArmadilloFft(arma::fvec input) {
	arma::cx_fvec output_fd;
	arma::cx_fvec output_td;

	auto begin = high_resolution_clock::now();
	for (uint32_t cnt=0;cnt<::num;++cnt) {
		output_fd = arma::fft(input);
		output_td = arma::ifft(output_fd);

	}
	AudioVec output_copy = arma::conv_to<AudioVec>::from(arma::real(output_td));
	auto end = high_resolution_clock::now();

	return std::make_pair(end - begin,arma::real(output_td));
}

int main(int argc, char* argv[]) {

	// generate input signals
	arma::fvec sig {arma::randn<arma::fvec>(::conv_sig_size)};
	arma::fvec ir {arma::randn<arma::fvec>(::conv_ir_size)};

	// init FFTW
	size_t fft_size (pow(2,ceil(log2(::conv_sig_size + ::conv_ir_size - 1))));
	AudioVec sig_vec  (fft_size, 0);
	std::copy_n(sig_vec.begin(), ::conv_sig_size, sig.begin());
	AudioVec ir_vec (fft_size, 0);
	std::copy_n(ir_vec.begin(), ::conv_ir_size, ir.begin());
	AudioVec sig_re(AudioFFT::ComplexSize(fft_size));
	AudioVec ir_re(AudioFFT::ComplexSize(fft_size));
	AudioVec sig_im(AudioFFT::ComplexSize(fft_size));
	AudioVec ir_im(AudioFFT::ComplexSize(fft_size));
	AudioVec output(fft_size);
	AudioFFT fft_sig;
	fft_sig.init(fft_size);
	AudioFFT fft_ir;
	fft_ir.init(fft_size);
	FftwData sig_data = std::forward_as_tuple(fft_sig, sig_vec, sig_re, sig_im, output);
	FftwData ir_data = std::forward_as_tuple(fft_ir, ir_vec, ir_re, ir_im, output);

	auto result_arma_fft = ArmadilloFft(sig);
	std::cout << "Armadillo FFT: " << result_arma_fft.first.count() << std::endl;

	// normal convolution, this is our reference output
	auto result_conv = Convolution(sig, ir);
	std::cout << "convolution: " << result_conv.first.count()
			  << std::endl;

	auto result_arma_fft_pow2_conv = ArmadilloFftPow2Conv(sig, ir);
	auto result_fftw_pow2_conv = FftwConv( sig_data, ir_data);
	std::cout << "Armadillo FFT-Pow2-convolution: "
		      << result_arma_fft_pow2_conv.first.count()
			  << "\n\tmaximum difference of result: "
			  << arma::abs(result_conv.second - result_arma_fft_pow2_conv.second).max()
			  << std::endl;
	std::cout << "FFTW Pow2-convolution: "
		      << result_fftw_pow2_conv.count()
			  << std::endl;

	auto result_arma_fft_conv = ArmadilloFftConv(sig, ir);
	std::cout << "Armadillo FFT-convolution: "
		      << result_arma_fft_conv.first.count()
			  << "\n\tmaximum difference of result: "
			  << arma::abs(result_conv.second - result_arma_fft_conv.second).max()
			  << std::endl;

	auto result_arma_conv = ArmadilloConv(sig, ir);
	std::cout << "Armadillo convolution: "
		      << result_arma_conv.first.count()
			  << "\n\tmaximum difference of result: "
			  << arma::abs(result_conv.second - result_arma_conv.second).max()
			  << std::endl;
}
<commit_msg>verify result<commit_after>#include <chrono>
#include <iostream>
#include <vector>
#include <utility> // std::pair
#include <algorithm> // std::max_element()
#include <string> // std::to_string()

#include <armadillo>

#include "AudioFFT.h"

using std::chrono::high_resolution_clock;
using std::chrono::duration;
using AudioVec = std::vector<float>;
using audiofft::AudioFFT;
using FftwData = std::tuple<AudioFFT& // fft class
                           ,AudioVec& // input vector
						   ,AudioVec& // real vector
						   ,AudioVec& // imag vector
						   ,AudioVec&>; // output vector

namespace {
	uint32_t num = 1;
	uint32_t fft_size = 48000;
	uint32_t conv_ir_size = 72000;
	uint32_t conv_sig_size = 5760000;
}

std::pair<duration<double>, arma::fvec> Convolution(arma::fvec sig, arma::fvec ir) {
	size_t size = (::conv_sig_size+::conv_ir_size-1);
	ir = arma::flipud(ir);
	arma::fvec sig_new = arma::zeros<arma::fvec>(::conv_sig_size + 2*(::conv_ir_size-1));
	sig_new.subvec(::conv_ir_size - 1, ::conv_sig_size + ::conv_ir_size -2) = sig;
	arma::fvec output (::conv_sig_size + ::conv_ir_size - 1, arma::fill::zeros);

	auto begin = high_resolution_clock::now();
	for (uint32_t cnt=0;cnt<::num;++cnt) {
		for (uint32_t sample_cnt=0;sample_cnt<size;++sample_cnt) {
			for (uint32_t ir_cnt=0;ir_cnt<::conv_ir_size;++ir_cnt) {
				output[sample_cnt] += sig_new[sample_cnt+ir_cnt] * ir[ir_cnt];
			}
		}
	}
	AudioVec output_copy = arma::conv_to<AudioVec>::from(output);
	auto end = high_resolution_clock::now();

	return std::make_pair(end - begin, output);
}

std::pair<duration<double>, arma::fvec> ArmadilloConv(arma::fvec sig, arma::fvec ir) {
	arma::fvec output;

	auto begin = high_resolution_clock::now();
	for (uint32_t cnt=0;cnt<::num;++cnt) {
		output = arma::conv(sig, ir);
	}
	AudioVec output_copy = arma::conv_to<AudioVec>::from(output);
	auto end = high_resolution_clock::now();

	return std::make_pair(end - begin, output);
}

duration<double> FftwConv(FftwData sig, FftwData ir) {
	auto sig_in = std::get<1>(sig);
	auto sig_re = std::get<2>(sig);
	auto sig_im = std::get<3>(sig);
	auto ir_in = std::get<1>(ir);
	auto ir_re = std::get<2>(ir);
	auto ir_im = std::get<3>(ir);
	AudioVec re (sig_re.size());
	AudioVec im (sig_re.size());

	auto begin = high_resolution_clock::now();
	std::get<0>(sig).fft(sig_in.data(), sig_re.data(), sig_im.data());
	std::get<0>(ir).fft(ir_in.data(), ir_re.data(), ir_im.data());
	for (size_t cnt=0;cnt<sig_re.size();++cnt) {
		re[cnt] = sig_re[cnt]*ir_re[cnt] - sig_im[cnt]*ir_im[cnt];
		im[cnt] = sig_re[cnt]*ir_im[cnt] + sig_im[cnt]*ir_re[cnt];
	}
	std::get<0>(sig).ifft(std::get<4>(sig).data(), re.data(), im.data());
	auto end = high_resolution_clock::now();

	return end - begin;
}

std::pair<duration<double>, arma::fvec> ArmadilloFftConv(arma::fvec sig, arma::fvec ir) {
	arma::cx_fvec output;
	size_t size = sig.size() + ir.size() - 1;

	auto begin = high_resolution_clock::now();
	for (uint32_t cnt=0;cnt<::num;++cnt) {
		output = arma::ifft(arma::fft(sig, size) % arma::fft(ir, size));
	}
	AudioVec output_copy = arma::conv_to<AudioVec>::from(arma::real(output));
	auto end = high_resolution_clock::now();

	return std::make_pair(end - begin, arma::real(output));
}

std::pair<duration<double>, arma::fvec> ArmadilloFftPow2Conv(arma::fvec sig, arma::fvec ir) {
	uint32_t size = pow(2,ceil(log2(::conv_sig_size + ::conv_ir_size - 1)));
	arma::cx_fvec output;

	auto begin = high_resolution_clock::now();
	for (uint32_t cnt=0;cnt<::num;++cnt) {
		output = arma::ifft(arma::fft(sig,size) % arma::fft(ir,size));
	}
	AudioVec output_copy = arma::conv_to<AudioVec>::from(arma::real(output));
	auto end = high_resolution_clock::now();

	return std::make_pair(end - begin, arma::real(output.subvec(0, ::conv_sig_size + ::conv_ir_size - 2)));
}

std::pair<duration<double>,arma::fvec> ArmadilloFft(arma::fvec input) {
	arma::cx_fvec output_fd;
	arma::cx_fvec output_td;

	auto begin = high_resolution_clock::now();
	for (uint32_t cnt=0;cnt<::num;++cnt) {
		output_fd = arma::fft(input);
		output_td = arma::ifft(output_fd);

	}
	AudioVec output_copy = arma::conv_to<AudioVec>::from(arma::real(output_td));
	auto end = high_resolution_clock::now();

	return std::make_pair(end - begin,arma::real(output_td));
}

int main(int argc, char* argv[]) {

	// generate input signals
	arma::fvec sig {arma::randn<arma::fvec>(::conv_sig_size)};
	arma::fvec ir {arma::randn<arma::fvec>(::conv_ir_size)};

	// init FFTW
	size_t fft_size (pow(2,ceil(log2(::conv_sig_size + ::conv_ir_size - 1))));
	AudioVec sig_vec  (fft_size, 0);
	std::copy_n(sig_vec.begin(), ::conv_sig_size, sig.begin());
	AudioVec ir_vec (fft_size, 0);
	std::copy_n(ir_vec.begin(), ::conv_ir_size, ir.begin());
	AudioVec sig_re(AudioFFT::ComplexSize(fft_size));
	AudioVec ir_re(AudioFFT::ComplexSize(fft_size));
	AudioVec sig_im(AudioFFT::ComplexSize(fft_size));
	AudioVec ir_im(AudioFFT::ComplexSize(fft_size));
	AudioVec output(fft_size);
	AudioFFT fft_sig;
	fft_sig.init(fft_size);
	AudioFFT fft_ir;
	fft_ir.init(fft_size);
	FftwData sig_data = std::forward_as_tuple(fft_sig, sig_vec, sig_re, sig_im, output);
	FftwData ir_data = std::forward_as_tuple(fft_ir, ir_vec, ir_re, ir_im, output);

	auto result_arma_fft = ArmadilloFft(sig);
	std::cout << "Armadillo FFT: " << result_arma_fft.first.count() << std::endl;

	// normal convolution, this is our reference output
	auto result_conv = Convolution(sig, ir);
	std::cout << "convolution: " << result_conv.first.count()
			  << std::endl;

	auto result_arma_fft_pow2_conv = ArmadilloFftPow2Conv(sig, ir);
	auto result_fftw_pow2_conv = FftwConv( sig_data, ir_data);
	AudioVec diff;
	std::transform(
			result_conv.second.begin()
			, result_conv.second.end()
			, std::get<4>(sig_data).begin()
			, std::back_inserter(diff)
			, [](float a, float b) { return fabs(a-b); }
			);
	std::cout << "Armadillo FFT-Pow2-convolution: "
		      << result_arma_fft_pow2_conv.first.count()
			  << "\n\tmaximum difference of result: "
			  << arma::abs(result_conv.second - result_arma_fft_pow2_conv.second).max()
			  << std::endl;
	std::cout << "FFTW Pow2-convolution: "
		      << result_fftw_pow2_conv.count()
			  << "\n\tmaximum difference of result: "
			  << std::to_string(*std::max_element(diff.begin(), diff.end()))
			  << std::endl;

	auto result_arma_fft_conv = ArmadilloFftConv(sig, ir);
	std::cout << "Armadillo FFT-convolution: "
		      << result_arma_fft_conv.first.count()
			  << "\n\tmaximum difference of result: "
			  << arma::abs(result_conv.second - result_arma_fft_conv.second).max()
			  << std::endl;

	auto result_arma_conv = ArmadilloConv(sig, ir);
	std::cout << "Armadillo convolution: "
		      << result_arma_conv.first.count()
			  << "\n\tmaximum difference of result: "
			  << arma::abs(result_conv.second - result_arma_conv.second).max()
			  << std::endl;
}
<|endoftext|>


<commit_before>#include <tclap/CmdLine.h>
#include <llvm/IR/Module.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/Interpreter.h>
#include <llvm/Support/TargetSelect.h>

#include "utils/util.hpp"
#include "utils/error.hpp"
#include "lexer.hpp"
#include "parser/tokenParser.hpp"
#include "llvm/globalTypes.hpp"
#include "llvm/compiler.hpp"
#include "interpreter/interpreter.hpp"

enum ExitCodes: int {
  NORMAL_EXIT = 0, // Everything is OK
  TCLAP_ERROR = 11, // TCLAP did something bad, should not happen
  CLI_ERROR = 1, // The user is retar-- uh I mean the user used a wrong option
  USER_PROGRAM_ERROR = 2, // The thing we had to lex/parse/run has an issue
  INTERNAL_ERROR = 3 // Unrecoverable error in this program, almost always a bug
};

int main(int argc, const char* argv[]) {
  try {
    TCLAP::CmdLine cmd("test-lang", ' ', "pre-release");

    TCLAP::SwitchArg printTokens("", "tokens", "Print token list", cmd);
    TCLAP::SwitchArg printAST("", "ast", "Print AST (if applicable)", cmd);
    TCLAP::SwitchArg printIR("", "ir", "Print LLVM IR (if applicable)", cmd);

    TCLAP::SwitchArg doNotParse("", "no-parse", "Don't parse the token list", cmd);
    TCLAP::SwitchArg doNotRun("", "no-run", "Don't execute the AST", cmd);

    std::vector<std::string> runnerValues {"llvm-lli", "llvm-llc", "tree-walk"};
    TCLAP::ValuesConstraint<std::string> runnerConstraint(runnerValues);
    TCLAP::ValueArg<std::string> runner("r", "runner", "How to run this code", false, "llvm-lli", &runnerConstraint, cmd);

    TCLAP::ValueArg<std::string> code("e", "eval", "Code to evaluate", false, std::string(), "string", cmd);
    TCLAP::ValueArg<std::string> filePath("f", "file", "Load code from this file", false, std::string(), "path", cmd);
    cmd.parse(argc, argv);

    if (code.getValue().empty() && filePath.getValue().empty()) {
      TCLAP::ArgException arg("Must specify either option -e or -f");
      cmd.getOutput()->failure(cmd, arg);
    }

    auto lx = Lexer();
    lx.tokenize(code.getValue());
    if (printTokens.getValue()) for (auto tok : lx.getTokens()) println(tok);

    if (doNotParse.getValue()) return NORMAL_EXIT;
    auto px = TokenParser();
    px.parse(lx.getTokens());
    if (printAST.getValue()) px.getTree().print();

    if (doNotRun.getValue()) return NORMAL_EXIT;

    if (runner.getValue() == "tree-walk") {
      auto in = TreeWalkInterpreter();
      in.interpret(px.getTree());
      return NORMAL_EXIT;
    }

    CompileVisitor::Link v = CompileVisitor::create(globalContext, "Command Line Module", px.getTree());
    v->visit();
    if (printIR.getValue()) v->getModule()->dump();

    if (runner.getValue() == "llvm-lli") {
      llvm::InitializeNativeTarget();
      llvm::InitializeNativeTargetAsmPrinter();
      llvm::InitializeNativeTargetAsmParser();

      std::string onError = "";
      auto eb = new llvm::EngineBuilder(std::unique_ptr<llvm::Module>(v->getModule()));
      llvm::ExecutionEngine* ee = eb
        ->setEngineKind(llvm::EngineKind::Interpreter)
        .setErrorStr(&onError)
        .create();
      auto main = v->getEntryPoint();
      if (onError != "") throw InternalError("ExecutionEngine error", {
        METADATA_PAIRS,
        {"supplied error string", onError}
      });
      return ee->runFunctionAsMain(main, {}, {});
    } else if (runner.getValue() == "llvm-llc") {
      println("Not yet implemented!");
      // TODO
    }
  } catch (const TCLAP::ExitException& arg) {
    return CLI_ERROR;
  } catch (const TCLAP::ArgException& arg) {
    println("TCLAP error", arg.error(), "for", arg.argId());
    return TCLAP_ERROR;
  } catch (const Error& err) {
    println(err.what());
    return USER_PROGRAM_ERROR;
  }
  // If we're debugging, crash the program on InternalError
  #ifndef CRASH_ON_INTERNAL_ERROR
  catch (const InternalError& err) {
    println(err.what());
    return INTERNAL_ERROR;
  }
  #endif
  return 0;
}
<commit_msg>IR is still dumped even on error (with --ir)<commit_after>#include <tclap/CmdLine.h>
#include <llvm/IR/Module.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/Interpreter.h>
#include <llvm/Support/TargetSelect.h>

#include "utils/util.hpp"
#include "utils/error.hpp"
#include "lexer.hpp"
#include "parser/tokenParser.hpp"
#include "llvm/globalTypes.hpp"
#include "llvm/compiler.hpp"
#include "interpreter/interpreter.hpp"

enum ExitCodes: int {
  NORMAL_EXIT = 0, // Everything is OK
  TCLAP_ERROR = 11, // TCLAP did something bad, should not happen
  CLI_ERROR = 1, // The user is retar-- uh I mean the user used a wrong option
  USER_PROGRAM_ERROR = 2, // The thing we had to lex/parse/run has an issue
  INTERNAL_ERROR = 3 // Unrecoverable error in this program, almost always a bug
};

int main(int argc, const char* argv[]) {
  try {
    TCLAP::CmdLine cmd("test-lang", ' ', "pre-release");

    TCLAP::SwitchArg printTokens("", "tokens", "Print token list", cmd);
    TCLAP::SwitchArg printAST("", "ast", "Print AST (if applicable)", cmd);
    TCLAP::SwitchArg printIR("", "ir", "Print LLVM IR (if applicable)", cmd);

    TCLAP::SwitchArg doNotParse("", "no-parse", "Don't parse the token list", cmd);
    TCLAP::SwitchArg doNotRun("", "no-run", "Don't execute the AST", cmd);

    std::vector<std::string> runnerValues {"llvm-lli", "llvm-llc", "tree-walk"};
    TCLAP::ValuesConstraint<std::string> runnerConstraint(runnerValues);
    TCLAP::ValueArg<std::string> runner("r", "runner", "How to run this code", false, "llvm-lli", &runnerConstraint, cmd);

    TCLAP::ValueArg<std::string> code("e", "eval", "Code to evaluate", false, std::string(), "string", cmd);
    TCLAP::ValueArg<std::string> filePath("f", "file", "Load code from this file", false, std::string(), "path", cmd);
    cmd.parse(argc, argv);

    if (code.getValue().empty() && filePath.getValue().empty()) {
      TCLAP::ArgException arg("Must specify either option -e or -f");
      cmd.getOutput()->failure(cmd, arg);
    }

    auto lx = Lexer();
    lx.tokenize(code.getValue());
    if (printTokens.getValue()) for (auto tok : lx.getTokens()) println(tok);

    if (doNotParse.getValue()) return NORMAL_EXIT;
    auto px = TokenParser();
    px.parse(lx.getTokens());
    if (printAST.getValue()) px.getTree().print();

    if (doNotRun.getValue()) return NORMAL_EXIT;

    if (runner.getValue() == "tree-walk") {
      auto in = TreeWalkInterpreter();
      in.interpret(px.getTree());
      return NORMAL_EXIT;
    }

    CompileVisitor::Link v = CompileVisitor::create(globalContext, "Command Line Module", px.getTree());
    try {
      v->visit();
    } catch (const InternalError& err) {
      if (printIR.getValue()) v->getModule()->dump();
      throw err;
    }

    if (runner.getValue() == "llvm-lli") {
      llvm::InitializeNativeTarget();
      llvm::InitializeNativeTargetAsmPrinter();
      llvm::InitializeNativeTargetAsmParser();

      std::string onError = "";
      auto eb = new llvm::EngineBuilder(std::unique_ptr<llvm::Module>(v->getModule()));
      llvm::ExecutionEngine* ee = eb
        ->setEngineKind(llvm::EngineKind::Interpreter)
        .setErrorStr(&onError)
        .create();
      auto main = v->getEntryPoint();
      if (onError != "") throw InternalError("ExecutionEngine error", {
        METADATA_PAIRS,
        {"supplied error string", onError}
      });
      return ee->runFunctionAsMain(main, {}, {});
    } else if (runner.getValue() == "llvm-llc") {
      println("Not yet implemented!");
      // TODO
    }
  } catch (const TCLAP::ExitException& arg) {
    return CLI_ERROR;
  } catch (const TCLAP::ArgException& arg) {
    println("TCLAP error", arg.error(), "for", arg.argId());
    return TCLAP_ERROR;
  } catch (const Error& err) {
    println(err.what());
    return USER_PROGRAM_ERROR;
  }
  // If we're debugging, crash the program on InternalError
  #ifndef CRASH_ON_INTERNAL_ERROR
  catch (const InternalError& err) {
    println(err.what());
    return INTERNAL_ERROR;
  }
  #endif
  return 0;
}
<|endoftext|>


<commit_before>/*ibnu.yahya@toroo.org*/
#include <QtWidgets/QApplication>
#include "ignsdk.h"
#include <QtWebKitWidgets/QWebView>
#include <QFileDialog>
#include <iostream>
#include "version.h"
#include <QCommandLineParser>

using namespace std;

int main(int argc, char *argv[]){
    QApplication app(argc, argv);
    ign ignsdk;

    QString url = NULL;
    bool file = false;
    QString optional;

    QCommandLineParser cmd_parser;
    cmd_parser.setApplicationDescription("IGOS Nusantara Software Development Kit");

    QCommandLineOption cmd_project(QStringList() << "p" << "project", "Specify project directory", "directory");
    cmd_parser.addOption(cmd_project);
    QCommandLineOption cmd_file(QStringList() << "f" << "file", "Load specific HTML file instead of index.html", "file");
    cmd_parser.addOption(cmd_file);
    QCommandLineOption cmd_dev(QStringList() << "d" << "development", "Activate development mode");
    cmd_parser.addOption(cmd_dev);
    QCommandLineOption cmd_remote(QStringList() << "r" << "remote", "Activate remote debugging", "port");
    cmd_parser.addOption(cmd_remote);
    QCommandLineOption cmd_version(QStringList() << "v" << "version", "Show version");
    cmd_parser.addOption(cmd_version);
    cmd_parser.addHelpOption();

    cmd_parser.process(app);

    if (cmd_parser.isSet(cmd_version)){
        printf("IGNSDK version %s (%s). Compiled on %s %s. Maintained by %s.\n", IGNSDK_VERSION, IGNSDK_CODENAME, __DATE__, __TIME__, IGNSDK_MAINTAINER);
        exit(0);
    }

    url = cmd_parser.value(cmd_project);

    if (cmd_parser.isSet(cmd_remote)){
        ignsdk.setDevRemote(cmd_parser.value(cmd_remote).toInt());
    }

    if (cmd_parser.isSet(cmd_file)){
        if (cmd_parser.isSet(cmd_project)){
            file = true;
            optional = cmd_parser.value(cmd_file);
        } else {
            qDebug() << "Error: Project directory must be specified.";
            exit(1);
        }
    }

    if (cmd_parser.isSet(cmd_dev)){
        ignsdk.setDev(true);
    }

    QString opt = url;
    QString path = url;

    if (!opt.isEmpty()){
        ignsdk.pathApp = opt;
        app.setWindowIcon(QIcon(path + "/icons/app.png"));

        if (file){
            opt += "/";
            opt += optional;
        } else {
            opt += "/index.html";
        }

        if (QFile::exists(opt)){
            ignsdk.config(url);
            ignsdk.render(opt);
            ignsdk.show();
        } else {
            qDebug() << "Error:" << opt << "is not exist.";
            exit(1);
        }

    } else {
        QFileDialog *fileDialog = new QFileDialog;
#ifdef Linux
        QTreeView *tree = fileDialog->findChild <QTreeView*>();
        tree->setRootIsDecorated(true);
        tree->setItemsExpandable(true);
#endif
        fileDialog->setFileMode(QFileDialog::Directory);
        fileDialog->setOption(QFileDialog::ShowDirsOnly);
        fileDialog->setViewMode(QFileDialog::Detail);
        int result = fileDialog->exec();
        QString directory;

        if (result){
            directory = fileDialog->selectedFiles()[0];

            if (QFile::exists(directory + "/index.html"))
            {
                ignsdk.config(directory);
                ignsdk.render(directory + "/index.html");
                ignsdk.show();
            } else {
                qDebug() << "Error:" << (directory + "/index.html") << "is not exist.";
                exit(1);
            }
        } else {
            exit(1);
        }
    }

    return app.exec();
}
<commit_msg>src/main.cpp: Fix app icon not shown when project was selected from dialog<commit_after>/*ibnu.yahya@toroo.org*/
#include <QtWidgets/QApplication>
#include "ignsdk.h"
#include <QtWebKitWidgets/QWebView>
#include <QFileDialog>
#include <iostream>
#include "version.h"
#include <QCommandLineParser>

using namespace std;

int main(int argc, char *argv[]){
    QApplication app(argc, argv);
    ign ignsdk;

    QString url = NULL;
    bool file = false;
    QString optional;

    QCommandLineParser cmd_parser;
    cmd_parser.setApplicationDescription("IGOS Nusantara Software Development Kit");

    QCommandLineOption cmd_project(QStringList() << "p" << "project", "Specify project directory", "directory");
    cmd_parser.addOption(cmd_project);
    QCommandLineOption cmd_file(QStringList() << "f" << "file", "Load specific HTML file instead of index.html", "file");
    cmd_parser.addOption(cmd_file);
    QCommandLineOption cmd_dev(QStringList() << "d" << "development", "Activate development mode");
    cmd_parser.addOption(cmd_dev);
    QCommandLineOption cmd_remote(QStringList() << "r" << "remote", "Activate remote debugging", "port");
    cmd_parser.addOption(cmd_remote);
    QCommandLineOption cmd_version(QStringList() << "v" << "version", "Show version");
    cmd_parser.addOption(cmd_version);
    cmd_parser.addHelpOption();

    cmd_parser.process(app);

    if (cmd_parser.isSet(cmd_version)){
        printf("IGNSDK version %s (%s). Compiled on %s %s. Maintained by %s.\n", IGNSDK_VERSION, IGNSDK_CODENAME, __DATE__, __TIME__, IGNSDK_MAINTAINER);
        exit(0);
    }

    url = cmd_parser.value(cmd_project);

    if (cmd_parser.isSet(cmd_remote)){
        ignsdk.setDevRemote(cmd_parser.value(cmd_remote).toInt());
    }

    if (cmd_parser.isSet(cmd_file)){
        if (cmd_parser.isSet(cmd_project)){
            file = true;
            optional = cmd_parser.value(cmd_file);
        } else {
            qDebug() << "Error: Project directory must be specified.";
            exit(1);
        }
    }

    if (cmd_parser.isSet(cmd_dev)){
        ignsdk.setDev(true);
    }

    QString opt = url;
    QString path = url;

    if (!opt.isEmpty()){
        ignsdk.pathApp = opt;
        app.setWindowIcon(QIcon(path + "/icons/app.png"));

        if (file){
            opt += "/";
            opt += optional;
        } else {
            opt += "/index.html";
        }

        if (QFile::exists(opt)){
            ignsdk.config(url);
            ignsdk.render(opt);
            ignsdk.show();
        } else {
            qDebug() << "Error:" << opt << "is not exist.";
            exit(1);
        }

    } else {
        QFileDialog *fileDialog = new QFileDialog;
#ifdef Linux
        QTreeView *tree = fileDialog->findChild <QTreeView*>();
        tree->setRootIsDecorated(true);
        tree->setItemsExpandable(true);
#endif
        fileDialog->setFileMode(QFileDialog::Directory);
        fileDialog->setOption(QFileDialog::ShowDirsOnly);
        fileDialog->setViewMode(QFileDialog::Detail);
        int result = fileDialog->exec();
        QString directory;

        if (result){
            directory = fileDialog->selectedFiles()[0];

            if (QFile::exists(directory + "/index.html"))
            {
                app.setWindowIcon(QIcon(directory + "/icons/app.png"));
                ignsdk.config(directory);
                ignsdk.render(directory + "/index.html");
                ignsdk.show();
            } else {
                qDebug() << "Error:" << (directory + "/index.html") << "is not exist.";
                exit(1);
            }
        } else {
            exit(1);
        }
    }

    return app.exec();
}
<|endoftext|>


<commit_before>#include <time.h>

#include "../include/PSATsolver.hpp"
#include "../include/TestGenerator.hpp"

using namespace std;
using namespace arma;

int main(int argc, char** argv)
{
    bool v = false;

    if (argc < 2)
    {
        std::cout << "I need a input file " << "\n";
        return -1;
    }

    if((string) argv[1] == "--test")
    {
        TestGenerator t(atoi(argv[2]));
        t.createAll(atoi(argv[3]),
                    atoi(argv[4]),
                    atoi(argv[5]),
                    atof(argv[6]),
                    atoi(argv[7]),
                    atoi(argv[8]),
                    argv[9]);
        return 1;
    }

    if (argc < 2)
    {
        std::cout << "I need a input file " << "\n";
        return -1;
    }

    //if (argc == 3 && argv[2][1] == 'v' && argv[2][0] == '-')
      //  v = true;

    int** m;
    int**& M = m;
    vector<double> pi;
    double time;
    int n;

    for(int i = 1; i < argc; i++)
    {
        n = PSATsolver::solve(M, pi, &time, argv[i], v);
        cout << argv[i] << ": " << time << "\n";
    }

    return 1;
}
<commit_msg>main shows the file<commit_after>#include <time.h>

#include "../include/PSATsolver.hpp"
#include "../include/TestGenerator.hpp"

using namespace std;
using namespace arma;

int main(int argc, char** argv)
{
    bool v = true;

    if (argc < 2)
    {
        std::cout << "I need a input file " << "\n";
        return -1;
    }

    if((string) argv[1] == "--test")
    {
        TestGenerator t(atoi(argv[2]));
        t.createAll(atoi(argv[3]),
                    atoi(argv[4]),
                    atoi(argv[5]),
                    atof(argv[6]),
                    atoi(argv[7]),
                    atoi(argv[8]),
                    argv[9]);
        return 1;
    }

    if (argc < 2)
    {
        std::cout << "I need a input file " << "\n";
        return -1;
    }

    //if (argc == 3 && argv[2][1] == 'v' && argv[2][0] == '-')
      //  v = true;

    int** m;
    int**& M = m;
    vector<double> pi;
    double time;
    int n;

    for(int i = 1; i < argc; i++)
    {
        n = PSATsolver::solve(M, pi, &time, argv[i], v);
        cout << argv[i] << ": " << time << "\n";
    }

    return 1;
}
<|endoftext|>


<commit_before>/*
 * wiring-skeleton.cpp
 *
 *  Created on: 15.03.2017
 *      Author: niklausd
 */

#include <Arduino.h>

// PlatformIO libraries
#include <SerialCommand.h>  // pio lib install 173, lib details see https://github.com/kroimon/Arduino-SerialCommand
#include <Timer.h>          // pio lib install 1699, lib details see https://github.com/dniklaus/wiring-timer

// private libraries
#include <DbgCliNode.h>
#include <DbgCliTopic.h>
#include <DbgCliCommand.h>
#include <DbgTracePort.h>
#include <DbgTraceContext.h>
#include <DbgTraceOut.h>
#include <DbgPrintConsole.h>
#include <DbgTraceLevel.h>
#include <AppDebug.h>
#include <ProductDebug.h>
#include <RamUtils.h>

#ifndef BUILTIN_LED
#define BUILTIN_LED 13
#endif

SerialCommand* sCmd = 0;

void setup()
{
  pinMode(BUILTIN_LED, OUTPUT);
  digitalWrite(BUILTIN_LED, 0);

  setupProdDebugEnv();
}

void loop()
{
  if (0 != sCmd)
  {
    sCmd->readSerial();     // process serial commands
  }
  yield();                  // process Timers
}
<commit_msg>call scheduleTimers() instead of yield() in the main loop (in order to be more portable)<commit_after>/*
 * wiring-skeleton.cpp
 *
 *  Created on: 15.03.2017
 *      Author: niklausd
 */

#include <Arduino.h>

// PlatformIO libraries
#include <SerialCommand.h>  // pio lib install 173, lib details see https://github.com/kroimon/Arduino-SerialCommand
#include <Timer.h>          // pio lib install 1699, lib details see https://github.com/dniklaus/wiring-timer

// private libraries
#include <DbgCliNode.h>
#include <DbgCliTopic.h>
#include <DbgCliCommand.h>
#include <DbgTracePort.h>
#include <DbgTraceContext.h>
#include <DbgTraceOut.h>
#include <DbgPrintConsole.h>
#include <DbgTraceLevel.h>
#include <AppDebug.h>
#include <ProductDebug.h>
#include <RamUtils.h>

#ifndef BUILTIN_LED
#define BUILTIN_LED 13
#endif

SerialCommand* sCmd = 0;

void setup()
{
  pinMode(BUILTIN_LED, OUTPUT);
  digitalWrite(BUILTIN_LED, 0);

  setupProdDebugEnv();
}

void loop()
{
  if (0 != sCmd)
  {
    sCmd->readSerial();     // process serial commands
  }
  scheduleTimers();         // process Timers
}
<|endoftext|>


<commit_before>#include <chrono>
#include <future>
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>

#include "json.hpp"
#include "process.hpp"

namespace {

    using json = nlohmann::json;

    using TimeoutType = unsigned;
    using DurationType = unsigned;
    using PortType = unsigned;

    static const TimeoutType kDefaultTimeout = 5;

    json read_json_file(const std::string& path) {
        std::ifstream filestream(path);
        if (!filestream.is_open()) {
            throw std::runtime_error("Can't open config file");
        }
        json data;
        filestream >> data;
        return data;
    }

    template <typename StringType>
    StringType trim(const StringType& s) {
        auto it = s.begin();
        while (it != s.end() && isspace(*it)) {
            it++;
        }
        auto rit = s.rbegin();
        while (rit.base() != it && isspace(*rit)) {
            rit++;
        }
        return {it, rit.base()};
    }

    class Task {
    public:
        Task(const std::string& command)
        : cmd_(command)
        {
        }

        int run() {
            const auto read_stdout = [this](const char *bytes, size_t n) {
                stdout_.append(bytes, n);
            };
            const auto read_stderr = [this](const char *bytes, size_t n) {
                stderr_.append(bytes, n);
            };
            Process process(cmd_, {}, read_stdout, read_stderr);
            return process.get_exit_status();
        }

        const std::string& out() const {
            return stdout_;
        }

        const std::string err() const {
            return stderr_;
        }

    private:
        const std::string cmd_;
        std::string stdout_;
        std::string stderr_;
    };
}

class ElapsedTime {
public:
    using ClockType = std::chrono::high_resolution_clock;

    void start() {
        start_ = ClockType::now();
    }

    void stop() {
        const auto end = ClockType::now();
        duration_ = static_cast<DurationType>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start_).count());
    }

    DurationType duration() const {
        return duration_;
    }
private:
    ClockType::time_point start_;
    DurationType duration_;
};

class Monitor {
public:
    Monitor(TimeoutType timeout)
        : timeout_(timeout)
    {
    }

    bool run() {
        elapsedTime_.start();
        const bool result = execute();
        elapsedTime_.stop();
        return result;
    }

    TimeoutType timeout() const {
        return timeout_;
    }

    const std::string& errorMessage() const {
        return errorMessage_;
    }

    DurationType duration() const {
        return elapsedTime_.duration();
    }

protected:
    virtual bool execute() = 0;

    std::string errorMessage_;

private:
    const TimeoutType timeout_;
    ElapsedTime elapsedTime_;
};

class WebsiteMonitor : public Monitor {
public:
    WebsiteMonitor(const std::string& url, TimeoutType timeout)
        : Monitor(timeout)
        , url_(url)
    {
    }

    virtual bool execute() override {
        extern bool HttpHead(const std::string& url, TimeoutType timeout, std::string& errorMessage);
        return HttpHead(url_, timeout(), errorMessage_);
    }

private:
    const std::string url_;
};

class ServiceMonitor : public Monitor {
public:
    ServiceMonitor(const std::string& host, PortType port, TimeoutType timeout)
        : Monitor(timeout)
        , host_(host)
        , port_(std::to_string(port))
    {
    }

    virtual bool execute() override {
        struct ::addrinfo hints = {};
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;

        struct ::addrinfo *res = nullptr;
        const int getaddrinfo_error = ::getaddrinfo(host_.c_str(), port_.c_str(), &hints, &res);
        if (getaddrinfo_error != 0) {
            errorMessage_ = "Can't get address: " + std::string(::gai_strerror(getaddrinfo_error));
            return false;
        }

        struct Socket {
            int value = -1;
            ~Socket() {
                if (value > 0) {
                    (void)::close(value);
                }
            }
        };

        Socket socket;
        socket.value = ::socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if (socket.value < 0) {
            errorMessage_ = "Can't create socket: " + std::string(::strerror(errno));
            return false;
        }

        if (::fcntl(socket.value, F_SETFL, O_NONBLOCK) != 0) {
            errorMessage_ = "Can't set to non-blocking: " + std::string(::strerror(errno));
            return false;
        }

        if (::connect(socket.value, res->ai_addr, res->ai_addrlen) == 0) {
            return true;
        }

        if (errno != EINPROGRESS) {
            errorMessage_ = "Can't connect: " + std::string(::strerror(errno));
            return false;
        }

        ::fd_set rfds;
        FD_ZERO(&rfds);
        FD_SET(socket.value, &rfds);

        struct ::timeval tv;
        tv.tv_sec = timeout();
        tv.tv_usec = 0;

        const int retval = ::select(socket.value+1, nullptr, &rfds, nullptr, &tv);
        if (retval == -1) {
            errorMessage_ = "Select failed: " + std::string(::strerror(errno));
            return false;
        } else if (retval) {
            return FD_ISSET(socket.value, &rfds) != 0;
        }

        errorMessage_ = "Timed out";
        return false;
    }

private:
    const std::string host_;
    const std::string port_;
};

class PingMonitor : public Monitor {
public:
    PingMonitor(const std::string& host, TimeoutType timeout)
        : Monitor(timeout)
        , host_(host)
    {
    }

    virtual bool execute() override {
        Task task{"ping -t " + std::to_string(timeout()) + " -c 1 \"" + host_ + "\""};
        const int status = task.run();
        if (status != 0) {
            const auto& stdout_str = task.out();
            const auto& stderr_str = task.err();
            const auto ping_output = trim(stdout_str + stderr_str);
            if (!ping_output.empty()) {
                errorMessage_ = ping_output;
            } else {
                errorMessage_ = "ping failed with exit code " + std::to_string(status);
            }
            return false;
        }
        return true;
    }

private:
    const std::string host_;
};

class Server {
public:
    using MonitorPtr = std::unique_ptr<Monitor>;

    Server(const std::string& name, MonitorPtr monitor, const std::string& action)
        : name_(name)
        , monitor_(std::move(monitor))
        , action_(action)
        , result_(false)
    {
    }

    const std::string& name() const {
        return name_;
    }

    const MonitorPtr& monitor() const {
        return monitor_;
    }

    const std::string& action() const {
        return action_;
    }

    void setResult(bool result) {
        result_ = result;
    }

    bool result() const {
        return result_;
    }

    Server(const Server&) = delete;
    Server& operator=(const Server&) = delete;

    Server(Server&& other) = default;
    Server& operator=(Server&&) = default;

private:
    std::string name_;
    MonitorPtr monitor_;
    std::string action_;
    bool result_;
};

std::string replace_variables(const std::string& input, const Server& server) {
    std::string str{input};
    const std::unordered_map<std::string, std::string> map{
        {"name", server.name()},
        {"status", server.result() ? "up" : "down"},
        {"Status", server.result() ? "Up" : "Down"},
        {"STATUS", server.result() ? "UP" : "DOWN"},
    };
    for (const auto& item : map) {
        std::string what = "{{" + item.first + "}}";
        std::string::size_type pos;
        while ((pos = str.find(what)) != std::string::npos) {
            str.replace(pos, what.size(), item.second);
        }
    }
    return str;
}

class Action {
public:
    virtual void run(const Server& server) = 0;
};

class CommandAction : public Action {
public:
    CommandAction(const std::string& command)
    : cmd_(command)
    {
    }

    virtual void run(const Server& server) override {
        Task task{replace_variables(cmd_, server)};
        (void)task.run();
    }

private:
    const std::string cmd_;
};

class ServerMonitor {
public:
    ServerMonitor(const json& config, const std::string& status_path)
        : config_(config)
        , status_path_(status_path)
    {
    }

    void run() {
        const json status_prev{read_json_file(status_path_)};

        const auto config_end = config_.end();

        using ActionPtr = std::unique_ptr<Action>;
        std::unordered_map<std::string, ActionPtr> actions;
        const auto actions_iter = config_.find("actions");
        if (actions_iter != config_end && actions_iter->is_object()) {
            for (auto it = (*actions_iter).cbegin(); it != (*actions_iter).cend(); ++it) {
                const auto& value = it.value();
                if (value.is_object()) {
                    const std::string name = it.key();

                    const auto end = value.end();

                    const auto cmd_iter = value.find("cmd");
                    if (cmd_iter != end) {
                        actions[name] = std::make_unique<CommandAction>(cmd_iter.value().get<std::string>());
                        continue;
                    }

                    throw std::runtime_error("Invalid action entry");
                }
            }
        }

        TimeoutType global_timeout = kDefaultTimeout;
        const auto global_timeout_iter = config_.find("timeout");
        if (global_timeout_iter != config_end) {
            global_timeout = global_timeout_iter->get<TimeoutType>();
        }

        const auto serversiter = config_.find("servers");
        if (serversiter == config_end) {
            throw std::runtime_error("Missing \"servers\" field");
        }

        std::vector<Server> servers;
        std::unordered_set<std::string> names;

        for (const auto& server : *serversiter) {
            const auto end = server.end();

            const auto name_iter = server.find("name");
            if (name_iter == end) {
                throw std::runtime_error("Missing required \"name\" field");
            }

            const auto name = name_iter->get<std::string>();
            if (names.find(name) != names.end()) {
                throw std::runtime_error("Name \"" + name + "\" is already used");
            }
            names.insert(name);

            TimeoutType timeout = global_timeout;
            const auto timeout_iter = server.find("timeout");
            if (timeout_iter != end) {
                timeout = timeout_iter->get<TimeoutType>();
            }

            std::string action;
            const auto action_iter = server.find("action");
            if (action_iter != end) {
                action = action_iter->get<std::string>();
                if (actions.find(action) == actions.end()) {
                    throw std::runtime_error("Unknown action \"" + action + "\"");
                }
            }

            const auto url = server.find("url");
            if (url != end) {
                servers.emplace_back(name, std::make_unique<WebsiteMonitor>(url->get<std::string>(), timeout), action);
                continue;
            }

            const auto host = server.find("host");
            const auto port = server.find("port");
            if (host != end && port != end) {
                servers.emplace_back(name, std::make_unique<ServiceMonitor>(host->get<std::string>(), port->get<PortType>(), timeout), action);
                continue;
            }

            const auto ping_host = server.find("ping");
            if (ping_host != end) {
                servers.emplace_back(name, std::make_unique<PingMonitor>(ping_host->get<std::string>(), timeout), action);
                continue;
            }

            throw std::runtime_error("Invalid server entry for \"" + name + "\"");
        }

        std::vector<std::future<void>> futures;

        ElapsedTime elapsedTime;

        elapsedTime.start();

        for (auto& server : servers) {
            futures.push_back(std::async(std::launch::async, [&server](){
                server.setResult(server.monitor()->run());
            }));
        }

        for (auto& future : futures) {
            future.get();
        }

        elapsedTime.stop();

        json status;

        for (const auto& server : servers) {
            const auto& monitor = server.monitor();
            const auto name = server.name();
            const bool result = server.result();
            if (result) {
                std::cout << name << ": UP";
            } else {
                std::cout << name << ": DOWN - " << monitor->errorMessage();
            }
            std::cout << " (" << monitor->duration() << " ms)" << std::endl;
            status[name] = result;

            const auto status_prev_it = status_prev.find(name);
            if (status_prev_it != status_prev.end() && status_prev_it->is_boolean() && status_prev_it->get<bool>() != result) {
                std::cout << "  Handle " << (result ? "UP" : "DOWN") << std::endl;
                if (!server.action().empty()) {
                    const auto action_iter = actions.find(server.action());
                    if (action_iter != actions.end()) {
                        action_iter->second->run(server);
                    }
                }
            }
        }

        std::cout << "Total time: " << elapsedTime.duration() << " ms" << std::endl;

        std::ofstream output_file{status_path_};
        if (!output_file.is_open()) {
            throw std::runtime_error("Can't open status file");
        }
        output_file << status.dump(4) << std::endl;
    }

private:
    const json config_;
    const std::string status_path_;
};

int main(int argc, const char * argv[]) {
    try {
        if (argc != 3) {
            throw std::invalid_argument("Invalid arguments");
        }

        const std::string config_path{argv[1]};
        const std::string status_path{argv[2]};

        const json config{read_json_file(config_path)};

        ServerMonitor mon(config, status_path);
        mon.run();

        return EXIT_SUCCESS;
    } catch (const std::exception& ex) {
        std::cout << "ERROR: " << ex.what() << std::endl;
        return EXIT_FAILURE;
    }
}
<commit_msg>Fix indentation<commit_after>#include <chrono>
#include <future>
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>

#include "json.hpp"
#include "process.hpp"

namespace {

    using json = nlohmann::json;

    using TimeoutType = unsigned;
    using DurationType = unsigned;
    using PortType = unsigned;

    static const TimeoutType kDefaultTimeout = 5;

    json read_json_file(const std::string& path) {
        std::ifstream filestream(path);
        if (!filestream.is_open()) {
            throw std::runtime_error("Can't open config file");
        }
        json data;
        filestream >> data;
        return data;
    }

    template <typename StringType>
    StringType trim(const StringType& s) {
        auto it = s.begin();
        while (it != s.end() && isspace(*it)) {
            it++;
        }
        auto rit = s.rbegin();
        while (rit.base() != it && isspace(*rit)) {
            rit++;
        }
        return {it, rit.base()};
    }

    class Task {
    public:
        Task(const std::string& command)
        : cmd_(command)
        {
        }

        int run() {
            const auto read_stdout = [this](const char *bytes, size_t n) {
                stdout_.append(bytes, n);
            };
            const auto read_stderr = [this](const char *bytes, size_t n) {
                stderr_.append(bytes, n);
            };
            Process process(cmd_, {}, read_stdout, read_stderr);
            return process.get_exit_status();
        }

        const std::string& out() const {
            return stdout_;
        }

        const std::string err() const {
            return stderr_;
        }

    private:
        const std::string cmd_;
        std::string stdout_;
        std::string stderr_;
    };
}

class ElapsedTime {
public:
    using ClockType = std::chrono::high_resolution_clock;

    void start() {
        start_ = ClockType::now();
    }

    void stop() {
        const auto end = ClockType::now();
        duration_ = static_cast<DurationType>(std::chrono::duration_cast<std::chrono::milliseconds>(end - start_).count());
    }

    DurationType duration() const {
        return duration_;
    }
private:
    ClockType::time_point start_;
    DurationType duration_;
};

class Monitor {
public:
    Monitor(TimeoutType timeout)
        : timeout_(timeout)
    {
    }

    bool run() {
        elapsedTime_.start();
        const bool result = execute();
        elapsedTime_.stop();
        return result;
    }

    TimeoutType timeout() const {
        return timeout_;
    }

    const std::string& errorMessage() const {
        return errorMessage_;
    }

    DurationType duration() const {
        return elapsedTime_.duration();
    }

protected:
    virtual bool execute() = 0;

    std::string errorMessage_;

private:
    const TimeoutType timeout_;
    ElapsedTime elapsedTime_;
};

class WebsiteMonitor : public Monitor {
public:
    WebsiteMonitor(const std::string& url, TimeoutType timeout)
        : Monitor(timeout)
        , url_(url)
    {
    }

    virtual bool execute() override {
        extern bool HttpHead(const std::string& url, TimeoutType timeout, std::string& errorMessage);
        return HttpHead(url_, timeout(), errorMessage_);
    }

private:
    const std::string url_;
};

class ServiceMonitor : public Monitor {
public:
    ServiceMonitor(const std::string& host, PortType port, TimeoutType timeout)
        : Monitor(timeout)
        , host_(host)
        , port_(std::to_string(port))
    {
    }

    virtual bool execute() override {
        struct ::addrinfo hints = {};
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;

        struct ::addrinfo *res = nullptr;
        const int getaddrinfo_error = ::getaddrinfo(host_.c_str(), port_.c_str(), &hints, &res);
        if (getaddrinfo_error != 0) {
            errorMessage_ = "Can't get address: " + std::string(::gai_strerror(getaddrinfo_error));
            return false;
        }

        struct Socket {
            int value = -1;
            ~Socket() {
                if (value > 0) {
                    (void)::close(value);
                }
            }
        };

        Socket socket;
        socket.value = ::socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if (socket.value < 0) {
            errorMessage_ = "Can't create socket: " + std::string(::strerror(errno));
            return false;
        }

        if (::fcntl(socket.value, F_SETFL, O_NONBLOCK) != 0) {
            errorMessage_ = "Can't set to non-blocking: " + std::string(::strerror(errno));
            return false;
        }

        if (::connect(socket.value, res->ai_addr, res->ai_addrlen) == 0) {
            return true;
        }

        if (errno != EINPROGRESS) {
            errorMessage_ = "Can't connect: " + std::string(::strerror(errno));
            return false;
        }

        ::fd_set rfds;
        FD_ZERO(&rfds);
        FD_SET(socket.value, &rfds);

        struct ::timeval tv;
        tv.tv_sec = timeout();
        tv.tv_usec = 0;

        const int retval = ::select(socket.value+1, nullptr, &rfds, nullptr, &tv);
        if (retval == -1) {
            errorMessage_ = "Select failed: " + std::string(::strerror(errno));
            return false;
        } else if (retval) {
            return FD_ISSET(socket.value, &rfds) != 0;
        }

        errorMessage_ = "Timed out";
        return false;
    }

private:
    const std::string host_;
    const std::string port_;
};

class PingMonitor : public Monitor {
public:
    PingMonitor(const std::string& host, TimeoutType timeout)
        : Monitor(timeout)
        , host_(host)
    {
    }

    virtual bool execute() override {
        Task task{"ping -t " + std::to_string(timeout()) + " -c 1 \"" + host_ + "\""};
        const int status = task.run();
        if (status != 0) {
            const auto& stdout_str = task.out();
            const auto& stderr_str = task.err();
            const auto ping_output = trim(stdout_str + stderr_str);
            if (!ping_output.empty()) {
                errorMessage_ = ping_output;
            } else {
                errorMessage_ = "ping failed with exit code " + std::to_string(status);
            }
            return false;
        }
        return true;
    }

private:
    const std::string host_;
};

class Server {
public:
    using MonitorPtr = std::unique_ptr<Monitor>;

    Server(const std::string& name, MonitorPtr monitor, const std::string& action)
        : name_(name)
        , monitor_(std::move(monitor))
        , action_(action)
        , result_(false)
    {
    }

    const std::string& name() const {
        return name_;
    }

    const MonitorPtr& monitor() const {
        return monitor_;
    }

    const std::string& action() const {
        return action_;
    }

    void setResult(bool result) {
        result_ = result;
    }

    bool result() const {
        return result_;
    }

    Server(const Server&) = delete;
    Server& operator=(const Server&) = delete;

    Server(Server&& other) = default;
    Server& operator=(Server&&) = default;

private:
    std::string name_;
    MonitorPtr monitor_;
    std::string action_;
    bool result_;
};

std::string replace_variables(const std::string& input, const Server& server) {
    std::string str{input};
    const std::unordered_map<std::string, std::string> map{
        {"name", server.name()},
        {"status", server.result() ? "up" : "down"},
        {"Status", server.result() ? "Up" : "Down"},
        {"STATUS", server.result() ? "UP" : "DOWN"},
    };
    for (const auto& item : map) {
        std::string what = "{{" + item.first + "}}";
        std::string::size_type pos;
        while ((pos = str.find(what)) != std::string::npos) {
            str.replace(pos, what.size(), item.second);
        }
    }
    return str;
}

class Action {
public:
    virtual void run(const Server& server) = 0;
};

class CommandAction : public Action {
public:
    CommandAction(const std::string& command)
        : cmd_(command)
    {
    }

    virtual void run(const Server& server) override {
        Task task{replace_variables(cmd_, server)};
        (void)task.run();
    }

private:
    const std::string cmd_;
};

class ServerMonitor {
public:
    ServerMonitor(const json& config, const std::string& status_path)
        : config_(config)
        , status_path_(status_path)
    {
    }

    void run() {
        const json status_prev{read_json_file(status_path_)};

        const auto config_end = config_.end();

        using ActionPtr = std::unique_ptr<Action>;
        std::unordered_map<std::string, ActionPtr> actions;
        const auto actions_iter = config_.find("actions");
        if (actions_iter != config_end && actions_iter->is_object()) {
            for (auto it = (*actions_iter).cbegin(); it != (*actions_iter).cend(); ++it) {
                const auto& value = it.value();
                if (value.is_object()) {
                    const std::string name = it.key();

                    const auto end = value.end();

                    const auto cmd_iter = value.find("cmd");
                    if (cmd_iter != end) {
                        actions[name] = std::make_unique<CommandAction>(cmd_iter.value().get<std::string>());
                        continue;
                    }

                    throw std::runtime_error("Invalid action entry");
                }
            }
        }

        TimeoutType global_timeout = kDefaultTimeout;
        const auto global_timeout_iter = config_.find("timeout");
        if (global_timeout_iter != config_end) {
            global_timeout = global_timeout_iter->get<TimeoutType>();
        }

        const auto serversiter = config_.find("servers");
        if (serversiter == config_end) {
            throw std::runtime_error("Missing \"servers\" field");
        }

        std::vector<Server> servers;
        std::unordered_set<std::string> names;

        for (const auto& server : *serversiter) {
            const auto end = server.end();

            const auto name_iter = server.find("name");
            if (name_iter == end) {
                throw std::runtime_error("Missing required \"name\" field");
            }

            const auto name = name_iter->get<std::string>();
            if (names.find(name) != names.end()) {
                throw std::runtime_error("Name \"" + name + "\" is already used");
            }
            names.insert(name);

            TimeoutType timeout = global_timeout;
            const auto timeout_iter = server.find("timeout");
            if (timeout_iter != end) {
                timeout = timeout_iter->get<TimeoutType>();
            }

            std::string action;
            const auto action_iter = server.find("action");
            if (action_iter != end) {
                action = action_iter->get<std::string>();
                if (actions.find(action) == actions.end()) {
                    throw std::runtime_error("Unknown action \"" + action + "\"");
                }
            }

            const auto url = server.find("url");
            if (url != end) {
                servers.emplace_back(name, std::make_unique<WebsiteMonitor>(url->get<std::string>(), timeout), action);
                continue;
            }

            const auto host = server.find("host");
            const auto port = server.find("port");
            if (host != end && port != end) {
                servers.emplace_back(name, std::make_unique<ServiceMonitor>(host->get<std::string>(), port->get<PortType>(), timeout), action);
                continue;
            }

            const auto ping_host = server.find("ping");
            if (ping_host != end) {
                servers.emplace_back(name, std::make_unique<PingMonitor>(ping_host->get<std::string>(), timeout), action);
                continue;
            }

            throw std::runtime_error("Invalid server entry for \"" + name + "\"");
        }

        std::vector<std::future<void>> futures;

        ElapsedTime elapsedTime;

        elapsedTime.start();

        for (auto& server : servers) {
            futures.push_back(std::async(std::launch::async, [&server](){
                server.setResult(server.monitor()->run());
            }));
        }

        for (auto& future : futures) {
            future.get();
        }

        elapsedTime.stop();

        json status;

        for (const auto& server : servers) {
            const auto& monitor = server.monitor();
            const auto name = server.name();
            const bool result = server.result();
            if (result) {
                std::cout << name << ": UP";
            } else {
                std::cout << name << ": DOWN - " << monitor->errorMessage();
            }
            std::cout << " (" << monitor->duration() << " ms)" << std::endl;
            status[name] = result;

            const auto status_prev_it = status_prev.find(name);
            if (status_prev_it != status_prev.end() && status_prev_it->is_boolean() && status_prev_it->get<bool>() != result) {
                std::cout << "  Handle " << (result ? "UP" : "DOWN") << std::endl;
                if (!server.action().empty()) {
                    const auto action_iter = actions.find(server.action());
                    if (action_iter != actions.end()) {
                        action_iter->second->run(server);
                    }
                }
            }
        }

        std::cout << "Total time: " << elapsedTime.duration() << " ms" << std::endl;

        std::ofstream output_file{status_path_};
        if (!output_file.is_open()) {
            throw std::runtime_error("Can't open status file");
        }
        output_file << status.dump(4) << std::endl;
    }

private:
    const json config_;
    const std::string status_path_;
};

int main(int argc, const char * argv[]) {
    try {
        if (argc != 3) {
            throw std::invalid_argument("Invalid arguments");
        }

        const std::string config_path{argv[1]};
        const std::string status_path{argv[2]};

        const json config{read_json_file(config_path)};

        ServerMonitor mon(config, status_path);
        mon.run();

        return EXIT_SUCCESS;
    } catch (const std::exception& ex) {
        std::cout << "ERROR: " << ex.what() << std::endl;
        return EXIT_FAILURE;
    }
}
<|endoftext|>


<commit_before>#include <Utilities/Common.h>

#include <string>
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

class grid {
	word width;
	word height;
	word start_x;
	word start_y;
	word end_x;
	word end_y;

	vector<vector<word>> cells;

	public:
		grid(string path);

		void print_input(ostream& stream);
		void print_output(ostream& stream);
};

grid::grid(string path) {
	ifstream file(path);

	file >> this->width >> this->height;
	file >> this->start_x >> this->start_y;
	file >> this->end_x >> this->end_y;

	this->cells.resize(this->width);

	for (word x = 0; x < this->width; x++)
		this->cells[x].resize(this->height);

	for (word y = 0; y < this->height; y++)
		for (word x = 0; x < this->width; x++)
			file >> this->cells[x][y];
}

void grid::print_input(ostream& stream) {
	for (word y = 0; y < this->height; y++) {
		for (word x = 0; x < this->width; x++)
			stream << this->cells[x][y] << " ";

		stream << endl;
	}
}

void grid::print_output(ostream& stream) {

}

int main() {
	string path;

	cout << "Filename: ";
	cin >> path;

	grid g(path);

	g.print_input(cout);
	g.print_output(cout);

	return 0;
}
<commit_msg>Changed constructor to use an istream.<commit_after>#include <Utilities/Common.h>

#include <string>
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

class grid {
	word width;
	word height;
	word start_x;
	word start_y;
	word end_x;
	word end_y;

	vector<vector<word>> cells;

	public:
		grid(istream& stream);

		void print_input(ostream& stream);
		void print_output(ostream& stream);
};

grid::grid(istream& stream) {
	stream >> this->width >> this->height;
	stream >> this->start_x >> this->start_y;
	stream >> this->end_x >> this->end_y;

	this->cells.resize(this->width);

	for (word x = 0; x < this->width; x++)
		this->cells[x].resize(this->height);

	for (word y = 0; y < this->height; y++)
		for (word x = 0; x < this->width; x++)
			stream >> this->cells[x][y];
}

void grid::print_input(ostream& stream) {
	for (word y = 0; y < this->height; y++) {
		for (word x = 0; x < this->width; x++)
			stream << this->cells[x][y] << " ";

		stream << endl;
	}
}

void grid::print_output(ostream& stream) {

}

int main() {
	string path;

	cout << "Filename: ";
	cin >> path;

	ifstream file(path);

	grid g(file);

	g.print_input(cout);
	g.print_output(cout);

	return 0;
}
<|endoftext|>