<commit_before>#include "debug.h"

#include <QDateTime>
#include <QFileInfo>
#include <QMessageBox>
#include <QMutex>
#include <QThread>

#ifdef Q_OS_WIN
#include <io.h>
#else
#include <unistd.h>
#endif

namespace
{
QMutex mutex;
QString fileName;
int realStdout{};
int realStderr{};
FILE *logFile{};

void handler(QtMsgType type, const QMessageLogContext &context,
             const QString &msg)
{
  const auto typeName = QMap<QtMsgType, QByteArray>{{QtDebugMsg, " DEBUG "},
                                                    {QtInfoMsg, " INFO "},
                                                    {QtWarningMsg, " WARN "},
                                                    {QtCriticalMsg, " CRIT "},
                                                    {QtFatalMsg, " FATAL "}}
                            .value(type);

  const auto message =
      QDateTime::currentDateTime().toString(Qt::ISODate).toUtf8() + ' ' +
      QByteArray::number(qintptr(QThread::currentThreadId())) + ' ' +
      QFileInfo(context.file).fileName().toUtf8() + ':' +
      QByteArray::number(context.line) + typeName + msg.toUtf8() + '\n';

  if (logFile)
    write(fileno(logFile), message.data(), message.size());
  if (realStderr > 0)
    write(realStderr, message.data(), message.size());
}

void toDefaults()
{
  qInstallMessageHandler(nullptr);

  if (realStdout > 0) {
    dup2(realStdout, fileno(stdout));
    realStdout = -1;
  }

  if (realStderr > 0) {
    dup2(realStderr, fileno(stderr));
    realStderr = -1;
  }

  if (logFile) {
    fclose(logFile);
    logFile = nullptr;
  }

  fileName.clear();
}
}  // namespace

namespace debug
{
std::atomic_bool isTrace = false;

QString traceFileName()
{
  QMutexLocker locker(&mutex);
  return fileName;
}

bool setTraceFileName(const QString &fileName)
{
  QMutexLocker locker(&mutex);

  toDefaults();

  if (fileName.isEmpty())
    return true;

  logFile = fopen(qPrintable(fileName), "w");
  if (!logFile)
    return false;

  realStdout = dup(fileno(stdout));
  realStderr = dup(fileno(stderr));

  const auto fd = fileno(logFile);
  dup2(fd, fileno(stdout));
  dup2(fd, fileno(stderr));

  ::fileName = fileName;
  qInstallMessageHandler(handler);

  return true;
}

}  // namespace debug
<commit_msg>Add mutex in log handler<commit_after>#include "debug.h"

#include <QDateTime>
#include <QFileInfo>
#include <QMessageBox>
#include <QMutex>
#include <QThread>

#ifdef Q_OS_WIN
#include <io.h>
#else
#include <unistd.h>
#endif

namespace
{
QMutex mutex;
QString fileName;
int realStdout{};
int realStderr{};
FILE *logFile{};

void handler(QtMsgType type, const QMessageLogContext &context,
             const QString &msg)
{
  const auto typeName = QMap<QtMsgType, QByteArray>{{QtDebugMsg, " DEBUG "},
                                                    {QtInfoMsg, " INFO "},
                                                    {QtWarningMsg, " WARN "},
                                                    {QtCriticalMsg, " CRIT "},
                                                    {QtFatalMsg, " FATAL "}}
                            .value(type);

  const auto message =
      QDateTime::currentDateTime().toString(Qt::ISODate).toUtf8() + ' ' +
      QByteArray::number(qintptr(QThread::currentThreadId())) + ' ' +
      QFileInfo(context.file).fileName().toUtf8() + ':' +
      QByteArray::number(context.line) + typeName + msg.toUtf8() + '\n';

  QMutexLocker locker(&mutex);
  if (logFile)
    write(fileno(logFile), message.data(), message.size());
  if (realStderr > 0)
    write(realStderr, message.data(), message.size());
}

void toDefaults()
{
  qInstallMessageHandler(nullptr);

  if (realStdout > 0) {
    dup2(realStdout, fileno(stdout));
    realStdout = -1;
  }

  if (realStderr > 0) {
    dup2(realStderr, fileno(stderr));
    realStderr = -1;
  }

  if (logFile) {
    fclose(logFile);
    logFile = nullptr;
  }

  fileName.clear();
}
}  // namespace

namespace debug
{
std::atomic_bool isTrace = false;

QString traceFileName()
{
  QMutexLocker locker(&mutex);
  return fileName;
}

bool setTraceFileName(const QString &fileName)
{
  QMutexLocker locker(&mutex);

  toDefaults();

  if (fileName.isEmpty())
    return true;

  logFile = fopen(qPrintable(fileName), "w");
  if (!logFile)
    return false;

  realStdout = dup(fileno(stdout));
  realStderr = dup(fileno(stderr));

  const auto fd = fileno(logFile);
  dup2(fd, fileno(stdout));
  dup2(fd, fileno(stderr));

  ::fileName = fileName;
  qInstallMessageHandler(handler);

  return true;
}

}  // namespace debug
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) Yorik van Havre (yorik@uncreated.net) 2015              *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
#endif

#include "DraftDxf.h"

#include <gp_Circ.hxx>
#include <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Elips.hxx>
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Shape.hxx>

#include <Base/Parameter.h>
#include <Base/Matrix.h>
#include <Base/Vector3D.h>
#include <Base/Interpreter.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Annotation.h>
#include <Mod/Part/App/PartFeature.h>

using namespace DraftUtils;

DraftDxfRead::DraftDxfRead(std::string filepath, App::Document *pcDoc) : CDxfRead(filepath.c_str())
{
    document = pcDoc;
    ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Draft");
    optionGroupLayers = hGrp->GetBool("groupLayers",false);
    optionImportAnnotations = hGrp->GetBool("dxftext",false);
    optionScaling = hGrp->GetFloat("dxfScaling",1.0);
}

gp_Pnt DraftDxfRead::makePoint(const double* p)
{
    double sp1(p[0]);
    double sp2(p[1]);
    double sp3(p[2]);
    if (optionScaling != 1.0) {
        sp1 = sp1 * optionScaling;
        sp2 = sp2 * optionScaling;
        sp3 = sp3 * optionScaling;
    }
    return gp_Pnt(sp1,sp2,sp3);
}

void DraftDxfRead::OnReadLine(const double* s, const double* e, bool /*hidden*/)
{
    gp_Pnt p0 = makePoint(s);
    gp_Pnt p1 = makePoint(e);
    if (p0.IsEqual(p1,0.00000001))
        return;
    BRepBuilderAPI_MakeEdge makeEdge(p0, p1);
    TopoDS_Edge edge = makeEdge.Edge();
    AddObject(new Part::TopoShape(edge));
}

void DraftDxfRead::OnReadPoint(const double* s)
{
    BRepBuilderAPI_MakeVertex makeVertex(makePoint(s));
    TopoDS_Vertex vertex = makeVertex.Vertex();
    AddObject(new Part::TopoShape(vertex));
}

void DraftDxfRead::OnReadArc(const double* s, const double* e, const double* c, bool dir, bool /*hidden*/)
{
    gp_Pnt p0 = makePoint(s);
    gp_Pnt p1 = makePoint(e);
    gp_Dir up(0, 0, 1);
    if (!dir)
        up = -up;
    gp_Pnt pc = makePoint(c);
    gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc));
    BRepBuilderAPI_MakeEdge makeEdge(circle, p0, p1);
    TopoDS_Edge edge = makeEdge.Edge();
    AddObject(new Part::TopoShape(edge));
}

void DraftDxfRead::OnReadCircle(const double* s, const double* c, bool dir, bool /*hidden*/)
{
    gp_Pnt p0 = makePoint(s);
    gp_Dir up(0, 0, 1);
    if (!dir)
        up = -up;
    gp_Pnt pc = makePoint(c);
    gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc));
    BRepBuilderAPI_MakeEdge makeEdge(circle);
    TopoDS_Edge edge = makeEdge.Edge();
    AddObject(new Part::TopoShape(edge));
}

void DraftDxfRead::OnReadSpline(struct SplineData& /*sd*/)
{
    // not yet implemented
}

void DraftDxfRead::OnReadEllipse(const double* c, double major_radius, double minor_radius, double rotation, double /*start_angle*/, double /*end_angle*/, bool dir)
{
    gp_Dir up(0, 0, 1);
    if(!dir)
        up = -up;
    gp_Pnt pc = makePoint(c);
    gp_Elips ellipse(gp_Ax2(pc, up), major_radius * optionScaling, minor_radius * optionScaling);
    ellipse.Rotate(gp_Ax1(pc,up),rotation);
    BRepBuilderAPI_MakeEdge makeEdge(ellipse);
    TopoDS_Edge edge = makeEdge.Edge();
    AddObject(new Part::TopoShape(edge));
}

void DraftDxfRead::OnReadText(const double *point, const double /*height*/, const char* text)
{
    if (optionImportAnnotations) {
        Base::Vector3d pt(point[0] * optionScaling, point[1] * optionScaling, point[2] * optionScaling);
        if(LayerName().substr(0, 6) != "BLOCKS") {
            App::Annotation *pcFeature = (App::Annotation *)document->addObject("App::Annotation", "Text");
            pcFeature->LabelText.setValue(Deformat(text));
            pcFeature->Position.setValue(pt);
        }
        //else std::cout << "skipped text in block: " << LayerName() << std::endl;
    }
}

void DraftDxfRead::OnReadInsert(const double* point, const double* scale, const char* name, double rotation)
{
    //std::cout << "Inserting block " << name << " rotation " << rotation << " pos " << point[0] << "," << point[1] << "," << point[2] << " scale " << scale[0] << "," << scale[1] << "," << scale[2] << std::endl;
    for(std::map<std::string,std::vector<Part::TopoShape*> > ::const_iterator i = layers.begin(); i != layers.end(); ++i) {
        std::string k = i->first;
        std::string prefix = "BLOCKS ";
        prefix += name;
        prefix += " ";
        if(k.substr(0, prefix.size()) == prefix) {
            BRep_Builder builder;
            TopoDS_Compound comp;
            builder.MakeCompound(comp);
            std::vector<Part::TopoShape*> v = i->second;
            for(std::vector<Part::TopoShape*>::const_iterator j = v.begin(); j != v.end(); ++j) {
                const TopoDS_Shape& sh = (*j)->getShape();
                if (!sh.IsNull())
                    builder.Add(comp, sh);
            }
            if (!comp.IsNull()) {
                Part::TopoShape* pcomp = new Part::TopoShape(comp);
                Base::Matrix4D mat;
                mat.scale(scale[0],scale[1],scale[2]);
                mat.rotZ(rotation);
                mat.move(point[0]*optionScaling,point[1]*optionScaling,point[2]*optionScaling);
                pcomp->transformShape(mat,true);
                AddObject(pcomp);
            }
        }
    }
}

void DraftDxfRead::OnReadDimension(const double* s, const double* e, const double* point, double /*rotation*/)
{
    if (optionImportAnnotations) {
        Base::Interpreter().runString("import Draft");
        Base::Interpreter().runStringArg("p1=FreeCAD.Vector(%f,%f,%f)",s[0]*optionScaling,s[1]*optionScaling,s[2]*optionScaling);
        Base::Interpreter().runStringArg("p2=FreeCAD.Vector(%f,%f,%f)",e[0]*optionScaling,e[1]*optionScaling,e[2]*optionScaling);
        Base::Interpreter().runStringArg("p3=FreeCAD.Vector(%f,%f,%f)",point[0]*optionScaling,point[1]*optionScaling,point[2]*optionScaling);
        Base::Interpreter().runString("Draft.makeDimension(p1,p2,p3)");
    }
}

void DraftDxfRead::AddObject(Part::TopoShape *shape)
{
    //std::cout << "layer:" << LayerName() << std::endl;
    std::vector <Part::TopoShape*> vec;
    if (layers.count(LayerName()))
        vec = layers[LayerName()];
    vec.push_back(shape);
    layers[LayerName()] = vec;
    if (!optionGroupLayers) {
        Part::Feature *pcFeature = (Part::Feature *)document->addObject("Part::Feature", "Shape");
        pcFeature->Shape.setValue(*shape);
    }
}

std::string DraftDxfRead::Deformat(const char* text)
{
    // this function removes DXF formatting from texts
    std::stringstream ss;
    bool escape = false; // turned on when finding an escape character
    bool longescape = false; // turned on for certain escape codes that expect additional chars
    for(unsigned int i = 0; i<strlen(text); i++) {
        if (text[i] == '\\')
            escape = true;
        else if (escape) {
            if (longescape) {
                if (text[i] == ';') {
                    escape = false;
                    longescape = false;
                }
            } else {
                if ( (text[i] == 'H') || (text[i] == 'h') ||
                     (text[i] == 'Q') || (text[i] == 'q') ||
                     (text[i] == 'W') || (text[i] == 'w') ||
                     (text[i] == 'F') || (text[i] == 'f') ||
                     (text[i] == 'A') || (text[i] == 'a') ||
                     (text[i] == 'C') || (text[i] == 'c') ||
                     (text[i] == 'T') || (text[i] == 't') )
                    longescape = true;
                else {
                    if ( (text[i] == 'P') || (text[i] == 'p') )
                        ss << "\n";
                    escape = false;
                }
            }
        }
        else if ( (text[i] != '{') && (text[i] != '}') ) {
            ss << text[i];
        }
    }
    return ss.str();
}

void DraftDxfRead::AddGraphics() const
{
    if (optionGroupLayers) {
        for(std::map<std::string,std::vector<Part::TopoShape*> > ::const_iterator i = layers.begin(); i != layers.end(); ++i) {
            BRep_Builder builder;
            TopoDS_Compound comp;
            builder.MakeCompound(comp);
            std::string k = i->first;
            std::vector<Part::TopoShape*> v = i->second;
            if(k.substr(0, 6) != "BLOCKS") {
                for(std::vector<Part::TopoShape*>::const_iterator j = v.begin(); j != v.end(); ++j) {
                    const TopoDS_Shape& sh = (*j)->getShape();
                    if (!sh.IsNull())
                        builder.Add(comp, sh);
                }
                if (!comp.IsNull()) {
                    Part::Feature *pcFeature = (Part::Feature *)document->addObject("Part::Feature", k.c_str());
                    pcFeature->Shape.setValue(comp);
                }
            }
        }
    }
}

<commit_msg>Draft: Do not import non-instanciated blocks - fixes #2822<commit_after>/***************************************************************************
 *   Copyright (c) Yorik van Havre (yorik@uncreated.net) 2015              *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
#endif

#include "DraftDxf.h"

#include <gp_Circ.hxx>
#include <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Elips.hxx>
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Shape.hxx>

#include <Base/Parameter.h>
#include <Base/Matrix.h>
#include <Base/Vector3D.h>
#include <Base/Interpreter.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Annotation.h>
#include <Mod/Part/App/PartFeature.h>

using namespace DraftUtils;

DraftDxfRead::DraftDxfRead(std::string filepath, App::Document *pcDoc) : CDxfRead(filepath.c_str())
{
    document = pcDoc;
    ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Draft");
    optionGroupLayers = hGrp->GetBool("groupLayers",false);
    optionImportAnnotations = hGrp->GetBool("dxftext",false);
    optionScaling = hGrp->GetFloat("dxfScaling",1.0);
}

gp_Pnt DraftDxfRead::makePoint(const double* p)
{
    double sp1(p[0]);
    double sp2(p[1]);
    double sp3(p[2]);
    if (optionScaling != 1.0) {
        sp1 = sp1 * optionScaling;
        sp2 = sp2 * optionScaling;
        sp3 = sp3 * optionScaling;
    }
    return gp_Pnt(sp1,sp2,sp3);
}

void DraftDxfRead::OnReadLine(const double* s, const double* e, bool /*hidden*/)
{
    gp_Pnt p0 = makePoint(s);
    gp_Pnt p1 = makePoint(e);
    if (p0.IsEqual(p1,0.00000001))
        return;
    BRepBuilderAPI_MakeEdge makeEdge(p0, p1);
    TopoDS_Edge edge = makeEdge.Edge();
    AddObject(new Part::TopoShape(edge));
}

void DraftDxfRead::OnReadPoint(const double* s)
{
    BRepBuilderAPI_MakeVertex makeVertex(makePoint(s));
    TopoDS_Vertex vertex = makeVertex.Vertex();
    AddObject(new Part::TopoShape(vertex));
}

void DraftDxfRead::OnReadArc(const double* s, const double* e, const double* c, bool dir, bool /*hidden*/)
{
    gp_Pnt p0 = makePoint(s);
    gp_Pnt p1 = makePoint(e);
    gp_Dir up(0, 0, 1);
    if (!dir)
        up = -up;
    gp_Pnt pc = makePoint(c);
    gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc));
    BRepBuilderAPI_MakeEdge makeEdge(circle, p0, p1);
    TopoDS_Edge edge = makeEdge.Edge();
    AddObject(new Part::TopoShape(edge));
}

void DraftDxfRead::OnReadCircle(const double* s, const double* c, bool dir, bool /*hidden*/)
{
    gp_Pnt p0 = makePoint(s);
    gp_Dir up(0, 0, 1);
    if (!dir)
        up = -up;
    gp_Pnt pc = makePoint(c);
    gp_Circ circle(gp_Ax2(pc, up), p0.Distance(pc));
    BRepBuilderAPI_MakeEdge makeEdge(circle);
    TopoDS_Edge edge = makeEdge.Edge();
    AddObject(new Part::TopoShape(edge));
}

void DraftDxfRead::OnReadSpline(struct SplineData& /*sd*/)
{
    // not yet implemented
}

void DraftDxfRead::OnReadEllipse(const double* c, double major_radius, double minor_radius, double rotation, double /*start_angle*/, double /*end_angle*/, bool dir)
{
    gp_Dir up(0, 0, 1);
    if(!dir)
        up = -up;
    gp_Pnt pc = makePoint(c);
    gp_Elips ellipse(gp_Ax2(pc, up), major_radius * optionScaling, minor_radius * optionScaling);
    ellipse.Rotate(gp_Ax1(pc,up),rotation);
    BRepBuilderAPI_MakeEdge makeEdge(ellipse);
    TopoDS_Edge edge = makeEdge.Edge();
    AddObject(new Part::TopoShape(edge));
}

void DraftDxfRead::OnReadText(const double *point, const double /*height*/, const char* text)
{
    if (optionImportAnnotations) {
        Base::Vector3d pt(point[0] * optionScaling, point[1] * optionScaling, point[2] * optionScaling);
        if(LayerName().substr(0, 6) != "BLOCKS") {
            App::Annotation *pcFeature = (App::Annotation *)document->addObject("App::Annotation", "Text");
            pcFeature->LabelText.setValue(Deformat(text));
            pcFeature->Position.setValue(pt);
        }
        //else std::cout << "skipped text in block: " << LayerName() << std::endl;
    }
}

void DraftDxfRead::OnReadInsert(const double* point, const double* scale, const char* name, double rotation)
{
    //std::cout << "Inserting block " << name << " rotation " << rotation << " pos " << point[0] << "," << point[1] << "," << point[2] << " scale " << scale[0] << "," << scale[1] << "," << scale[2] << std::endl;
    for(std::map<std::string,std::vector<Part::TopoShape*> > ::const_iterator i = layers.begin(); i != layers.end(); ++i) {
        std::string k = i->first;
        std::string prefix = "BLOCKS ";
        prefix += name;
        prefix += " ";
        if(k.substr(0, prefix.size()) == prefix) {
            BRep_Builder builder;
            TopoDS_Compound comp;
            builder.MakeCompound(comp);
            std::vector<Part::TopoShape*> v = i->second;
            for(std::vector<Part::TopoShape*>::const_iterator j = v.begin(); j != v.end(); ++j) {
                const TopoDS_Shape& sh = (*j)->getShape();
                if (!sh.IsNull())
                    builder.Add(comp, sh);
            }
            if (!comp.IsNull()) {
                Part::TopoShape* pcomp = new Part::TopoShape(comp);
                Base::Matrix4D mat;
                mat.scale(scale[0],scale[1],scale[2]);
                mat.rotZ(rotation);
                mat.move(point[0]*optionScaling,point[1]*optionScaling,point[2]*optionScaling);
                pcomp->transformShape(mat,true);
                AddObject(pcomp);
            }
        }
    }
}

void DraftDxfRead::OnReadDimension(const double* s, const double* e, const double* point, double /*rotation*/)
{
    if (optionImportAnnotations) {
        Base::Interpreter().runString("import Draft");
        Base::Interpreter().runStringArg("p1=FreeCAD.Vector(%f,%f,%f)",s[0]*optionScaling,s[1]*optionScaling,s[2]*optionScaling);
        Base::Interpreter().runStringArg("p2=FreeCAD.Vector(%f,%f,%f)",e[0]*optionScaling,e[1]*optionScaling,e[2]*optionScaling);
        Base::Interpreter().runStringArg("p3=FreeCAD.Vector(%f,%f,%f)",point[0]*optionScaling,point[1]*optionScaling,point[2]*optionScaling);
        Base::Interpreter().runString("Draft.makeDimension(p1,p2,p3)");
    }
}

void DraftDxfRead::AddObject(Part::TopoShape *shape)
{
    //std::cout << "layer:" << LayerName() << std::endl;
    std::vector <Part::TopoShape*> vec;
    if (layers.count(LayerName()))
        vec = layers[LayerName()];
    vec.push_back(shape);
    layers[LayerName()] = vec;
    if (!optionGroupLayers) {
        if(LayerName().substr(0, 6) != "BLOCKS") {
            Part::Feature *pcFeature = (Part::Feature *)document->addObject("Part::Feature", "Shape");
            pcFeature->Shape.setValue(shape->getShape());
        }
    }
}

std::string DraftDxfRead::Deformat(const char* text)
{
    // this function removes DXF formatting from texts
    std::stringstream ss;
    bool escape = false; // turned on when finding an escape character
    bool longescape = false; // turned on for certain escape codes that expect additional chars
    for(unsigned int i = 0; i<strlen(text); i++) {
        if (text[i] == '\\')
            escape = true;
        else if (escape) {
            if (longescape) {
                if (text[i] == ';') {
                    escape = false;
                    longescape = false;
                }
            } else {
                if ( (text[i] == 'H') || (text[i] == 'h') ||
                     (text[i] == 'Q') || (text[i] == 'q') ||
                     (text[i] == 'W') || (text[i] == 'w') ||
                     (text[i] == 'F') || (text[i] == 'f') ||
                     (text[i] == 'A') || (text[i] == 'a') ||
                     (text[i] == 'C') || (text[i] == 'c') ||
                     (text[i] == 'T') || (text[i] == 't') )
                    longescape = true;
                else {
                    if ( (text[i] == 'P') || (text[i] == 'p') )
                        ss << "\n";
                    escape = false;
                }
            }
        }
        else if ( (text[i] != '{') && (text[i] != '}') ) {
            ss << text[i];
        }
    }
    return ss.str();
}

void DraftDxfRead::AddGraphics() const
{
    if (optionGroupLayers) {
        for(std::map<std::string,std::vector<Part::TopoShape*> > ::const_iterator i = layers.begin(); i != layers.end(); ++i) {
            BRep_Builder builder;
            TopoDS_Compound comp;
            builder.MakeCompound(comp);
            std::string k = i->first;
            std::vector<Part::TopoShape*> v = i->second;
            if(k.substr(0, 6) != "BLOCKS") {
                for(std::vector<Part::TopoShape*>::const_iterator j = v.begin(); j != v.end(); ++j) {
                    const TopoDS_Shape& sh = (*j)->getShape();
                    if (!sh.IsNull())
                        builder.Add(comp, sh);
                }
                if (!comp.IsNull()) {
                    Part::Feature *pcFeature = (Part::Feature *)document->addObject("Part::Feature", k.c_str());
                    pcFeature->Shape.setValue(comp);
                }
            }
        }
    }
}

<|endoftext|>


<commit_before>#include "Graphics/Shader.hpp"
#include "Core/Logger.hpp"

#include <GL/glew.h>
#ifdef _WIN32
#include <GL/wglew.h>
#endif

#include <fstream>

namespace dm {

ProgramShader::ProgramShader() : m_linked(false), m_id(0) {}
ProgramShader::~ProgramShader() { this->unload_shaders(); }

bool ProgramShader::link() {
    Log::progress("debug", "Linking shader %d", m_id);

    assert(!m_shaders.empty());

    glLinkProgram(m_id);

    GLint linked;
    glGetProgramiv(m_id, GL_LINK_STATUS, &linked);

    if (linked == GL_FALSE) {
        GLint length, lengthRead = 0;
        glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &length);

        char* log = new char[length];
        glGetProgramInfoLog(m_id, length, &lengthRead, log);

        Log::result(Log::Result::ERROR);
        Log::debug("Error log: %s", log);

        delete[] log;
        return false;
    }

    Log::result(Log::Result::OK);

    m_linked = true;

    return true;
}

void ProgramShader::unload_shaders() {
    for (Shader& s : m_shaders) {
        if (s.compiled) {
            glDeleteShader(s.id);
            s.compiled = false;
            s.id = 0;
        }
    }
}

void ProgramShader::bind() {
    assert(m_id != 0);
    glUseProgram(m_id);
}

bool ProgramShader::load(const char* filename, Shader::Type type) {
    assert(m_linked == false);

    /* Create the program */
    if (m_id == 0) {
        m_id = glCreateProgram();
    }

    int size = 0;
    char* data = nullptr;
    std::ifstream file(filename, std::ios::in);

    if (!file.is_open()) {
        return false;
    }

    /* Calculate the size needed to store the file */
    file.seekg(0, std::ios::end);
    size = file.tellg();
    file.seekg(0, std::ios::beg);

    data = new char[size+1];

    file.read(data, size);

    /* Check if the whole file was loaded */
    if (file.tellg() != size) {
        delete[] data;
        return false;
    }

    file.close();

    Log::progress("debug", "Compiling shader %s", filename);

    data[size] = '\0';
    const bool result = this->load_source((const char*)data, type);
    delete[] data;
    return result;
}

bool ProgramShader::load_source(const char* data, Shader::Type type) {

    if (m_shaders.size() <= type) {
        m_shaders.resize(type + 1);
    }

    Shader& shader = m_shaders[type];

    if (shader.compiled) {
        glDeleteShader(shader.id);
    }

    shader = Shader{type, 0, false};

    /* TODO: Other shader types */
    shader.id = glCreateShader(
        type == Shader::Type::Vertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);

    if (shader.id == 0) {
        delete[] data;
        return false;
    }

    const GLchar* source = static_cast<const GLchar*>(data);
    Log::info(data);
    // const int sizei = static_cast<const int>(strlen(data));

    glShaderSource(shader.id, 1, static_cast<const GLchar**>(&source),
                   NULL);
    glCompileShader(shader.id);

    GLint compiled = 0;
    glGetShaderiv(shader.id, GL_COMPILE_STATUS, &compiled);

    /* Failed to compile, show the error log and exit */
    if (compiled == GL_FALSE) {
        GLint length, lengthRead = 0;
        glGetShaderiv(shader.id, GL_INFO_LOG_LENGTH, &length);
        char* log = new char[length];
        glGetShaderInfoLog(shader.id, length, &lengthRead, log);

        Log::result(Log::Result::ERROR);
        Log::debug("Error log: %s", log);

        glDeleteShader(shader.id);

        delete[] log;
        return false;
    }

    Log::result(Log::Result::OK);

    shader.compiled = true;

    glAttachShader(m_id, shader.id);

    return true;
}

/* GLSL Uniform setters */
void ProgramShader::set_uniform(int value, const char* name) {
    assert(m_id != 0);
    glUniform1i(glGetUniformLocation(m_id, name), value);
}

void ProgramShader::set_uniform(float value, const char* name) {
    assert(m_id != 0);
    glUniform1f(glGetUniformLocation(m_id, name), value);
}

void ProgramShader::set_uniform(const Matrix4f& value, const char* name) {
    assert(m_id != 0);
    Matrix4f transposed = value.transpose();
    glUniformMatrix4fv(glGetUniformLocation(m_id, name), 1, GL_FALSE,
                       &transposed.m[0]);
}

void ProgramShader::set_uniform(const Vec3f& value, const char* name) {
    assert(m_id != 0);
    glUniform3f(glGetUniformLocation(m_id, name), value.x, value.y, value.z);
}

void ProgramShader::set_uniform(const Vec2f& value, const char* name) {
    assert(m_id != 0);
    glUniform2f(glGetUniformLocation(m_id, name), value.x, value.y);
}

} /* namespace dm */
<commit_msg>fix program shader creation<commit_after>#include "Graphics/Shader.hpp"
#include "Core/Logger.hpp"

#include <GL/glew.h>
#ifdef _WIN32
#include <GL/wglew.h>
#endif

#include <fstream>

namespace dm {

ProgramShader::ProgramShader() : m_linked(false), m_id(0) {}
ProgramShader::~ProgramShader() { this->unload_shaders(); }

bool ProgramShader::link() {
    Log::progress("debug", "Linking shader %d", m_id);

    assert(!m_shaders.empty());

    glLinkProgram(m_id);

    GLint linked;
    glGetProgramiv(m_id, GL_LINK_STATUS, &linked);

    if (linked == GL_FALSE) {
        GLint length, lengthRead = 0;
        glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &length);

        char* log = new char[length];
        glGetProgramInfoLog(m_id, length, &lengthRead, log);

        Log::result(Log::Result::ERROR);
        Log::debug("Error log: %s", log);

        delete[] log;
        return false;
    }

    Log::result(Log::Result::OK);

    m_linked = true;

    return true;
}

void ProgramShader::unload_shaders() {
    for (Shader& s : m_shaders) {
        if (s.compiled) {
            glDeleteShader(s.id);
            s.compiled = false;
            s.id = 0;
        }
    }
}

void ProgramShader::bind() {
    assert(m_id != 0);
    glUseProgram(m_id);
}

bool ProgramShader::load(const char* filename, Shader::Type type) {
    int size = 0;
    char* data = nullptr;
    std::ifstream file(filename, std::ios::in);

    if (!file.is_open()) {
        return false;
    }

    /* Calculate the size needed to store the file */
    file.seekg(0, std::ios::end);
    size = file.tellg();
    file.seekg(0, std::ios::beg);

    data = new char[size+1];

    file.read(data, size);

    /* Check if the whole file was loaded */
    if (file.tellg() != size) {
        delete[] data;
        return false;
    }

    file.close();

    Log::progress("debug", "Compiling shader %s", filename);

    data[size] = '\0';
    const bool result = this->load_source((const char*)data, type);
    delete[] data;
    return result;
}

bool ProgramShader::load_source(const char* data, Shader::Type type) {

    assert(m_linked == false);

    /* Create the program */
    if (m_id == 0) {
        m_id = glCreateProgram();
    }

    if (m_shaders.size() <= type) {
        m_shaders.resize(type + 1);
    }

    Shader& shader = m_shaders[type];

    if (shader.compiled) {
        glDeleteShader(shader.id);
    }

    shader = Shader{type, 0, false};

    /* TODO: Other shader types */
    shader.id = glCreateShader(
        type == Shader::Type::Vertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);

    if (shader.id == 0) {
        delete[] data;
        return false;
    }

    const GLchar* source = static_cast<const GLchar*>(data);

    glShaderSource(shader.id, 1, static_cast<const GLchar**>(&source), NULL);
    glCompileShader(shader.id);

    GLint compiled = 0;
    glGetShaderiv(shader.id, GL_COMPILE_STATUS, &compiled);

    /* Failed to compile, show the error log and exit */
    if (compiled == GL_FALSE) {
        GLint length, lengthRead = 0;
        glGetShaderiv(shader.id, GL_INFO_LOG_LENGTH, &length);
        char* log = new char[length];
        glGetShaderInfoLog(shader.id, length, &lengthRead, log);

        Log::result(Log::Result::ERROR);
        Log::debug("Error log: %s", log);

        glDeleteShader(shader.id);

        delete[] log;
        return false;
    }

    Log::result(Log::Result::OK);

    shader.compiled = true;

    glAttachShader(m_id, shader.id);

    return true;
}

/* GLSL Uniform setters */
void ProgramShader::set_uniform(int value, const char* name) {
    assert(m_id != 0);
    glUniform1i(glGetUniformLocation(m_id, name), value);
}

void ProgramShader::set_uniform(float value, const char* name) {
    assert(m_id != 0);
    glUniform1f(glGetUniformLocation(m_id, name), value);
}

void ProgramShader::set_uniform(const Matrix4f& value, const char* name) {
    assert(m_id != 0);
    Matrix4f transposed = value.transpose();
    glUniformMatrix4fv(glGetUniformLocation(m_id, name), 1, GL_FALSE,
                       &transposed.m[0]);
}

void ProgramShader::set_uniform(const Vec3f& value, const char* name) {
    assert(m_id != 0);
    glUniform3f(glGetUniformLocation(m_id, name), value.x, value.y, value.z);
}

void ProgramShader::set_uniform(const Vec2f& value, const char* name) {
    assert(m_id != 0);
    glUniform2f(glGetUniformLocation(m_id, name), value.x, value.y);
}

} /* namespace dm */
<|endoftext|>


<commit_before>#include <algorithm>
#include <cctype>
#include <chrono>
#include <cstdlib>
#include <cstdio>
#include <exception>
#include <iostream>
#include <fstream>
#include <random>
#include <string>
#include <unordered_map>

#include "boost/algorithm/string.hpp"
#include "boost/date_time/gregorian/gregorian.hpp"

#include "snap.h"
#include "StringHasher.h"

const std::string prefix = "Data/";
const std::string output_path = "../tmp/";
const std::string suffix = "-Combined.txt";
const int max_input_size = 1000000;

// hashing parameters
const int A = 3;
const int M = 65071;
const int LEFT_HASH_WIDTH = 15;
const int RIGHT_HASH_WIDTH = 25;

void print_column_headers() {
  std::cout << "mt_cxt = matching_contexts_cnt" << '\n';
  std::cout << "mt_prg = matching_programs_cnt" << '\n';
  std::cout << "tot_mt = total_matches_cnt" << '\n';
  std::cout << "sel_prg = selected_programs_cnt" << '\n';
  std::cout << "tot_prg = total_programs_cnt" << '\n';
  std::cout << "dt        \tmt_cxt\tmt_prg\ttot_mt\tsel_prg\ttot_prg" << std::endl;
}

int main() {
  clock_t start_time = std::clock();
  srand(time(NULL));
  std::string random_id = std::to_string(rand());

  snap::web::print_header();

  // get user input
  int content_length = atoi(getenv("CONTENT_LENGTH"));
  char *input = new char[content_length+1];
  fgets(input, content_length+1, stdin);
  std::string query_string(input);
  delete[] input;

  // process user input
  std::map<std::string, std::string> arguments = snap::web::parse_query_string(query_string);
  std::string search_string = snap::web::decode_uri(boost::algorithm::trim_copy(arguments["search-string"]));
  boost::gregorian::date from_date, to_date;
  try {
    from_date = snap::date::string_to_date(arguments["from-date"]);
    to_date = snap::date::string_to_date(arguments["to-date"]);
  } catch (snap::date::InvalidDateException &e) {
    std::cout << "" << e.what() << "" << std::endl;
    exit(-1);
  }
  int num_excerpts = stoi(arguments["num-excerpts"]);
  int excerpt_size = stoi(arguments["excerpt-size"]);
  bool random = arguments["random"] == "on";

  std::vector<std::string> file_list = snap::io::generate_file_names(from_date, to_date, prefix, suffix);
  if (random) {
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    std::shuffle(file_list.begin(), file_list.end(), std::default_random_engine(seed));
  }
  std::vector<snap::Expression> expressions;
  try {
    expressions.emplace_back(search_string);
  } catch(snap::ExpressionSyntaxError &e) {
    const char *error_msg = e.what();
    std::cout << "" << error_msg << "" << std::endl;
    delete[] error_msg;
    exit(-1);
  }

  // display user input
  std::cout << "
" << std::endl;
  std::cout << "Search string: " << search_string << "
" << std::endl;
  std::cout << "From (inclusive): " << arguments["from-date"] << "
" << std::endl;
  std::cout << "To (inclusive): " << arguments["to-date"] << "
" << std::endl;
  std::cout << "Number of Excerpts: " << arguments["num-excerpts"] << "
" << std::endl;
  std::cout << "Excerpt Size: " << arguments["excerpt-size"] << "
" << std::endl;
  std::cout << "
" << std::endl;

  // set up excerpt file
  std::string output_excerpt_file_name = output_path + snap::date::date_to_string(from_date) + "_excerpts_" + random_id + ".csv";
  std::ofstream output_excerpt_file(output_excerpt_file_name);
  output_excerpt_file << "\"dt\",\"program\",\"excerpt\"" << std::endl;

  // begin to iteratively process files
  std::unordered_map<int, int> left_total_match_hashes;
  std::unordered_map<int, int> right_total_match_hashes;
  int matching_contexts_sum = 0;
  int matching_programs_sum = 0;
  int total_matches_sum = 0;
  int selected_programs_sum = 0;
  int total_programs_sum = 0;
  std::vector<std::vector<std::string>> search_results;
  std::vector<std::string> corrupt_files;
  std::vector<std::string> missing_files;
  std::vector<snap::Excerpt> excerpts;
  if (!random) {
    std::cout << "
" << std::endl;
    print_column_headers();
  }
  snap::StringHasher hasher("", M, A);
  for (auto it = file_list.begin();
       it != file_list.end();
       ++it) {
    boost::gregorian::date current_date = snap::date::string_to_date((*it).substr(prefix.length(), 10));
    if (snap::io::file_exists(*it)) {
      std::vector<snap::Program> programs;
      try {
        programs = snap::io::parse_programs(*it);
      } catch (snap::io::CorruptFileException &e) {
        programs.clear();
        corrupt_files.push_back(*it);
        continue;
      }
      int matching_contexts = 0; // context is distinct hash AND distinct program
      int matching_programs = 0;
      int total_matches = 0;
      if (random) {
        unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
        std::shuffle(programs.begin(), programs.end(), std::default_random_engine(seed));
      }
      std::unordered_map<int, int> left_match_hashes;
      std::unordered_map<int, int> right_match_hashes;
      for (auto p = programs.begin(); p != programs.end(); ++p) {
        std::map<std::string, std::vector<int>> raw_match_positions = snap::find(expressions.back().patterns, p -> lower_text);
        std::map<std::string, std::vector<int>> match_positions = snap::evaluate_expressions(expressions, raw_match_positions);
        hasher.load_text(p -> lower_text);
        if (match_positions[search_string].size() > 0) {
          ++matching_programs;
          total_matches += match_positions[search_string].size();
          bool total_context_added = false;
          bool context_added = false;
          for (auto it = match_positions[search_string].begin(); it != match_positions[search_string].end(); ++it) {
            int left_match_hash = hasher.hash(*it - LEFT_HASH_WIDTH, *it);
            int right_match_hash = hasher.hash(*it, *it + RIGHT_HASH_WIDTH);
            int left_hash_cnt = left_match_hashes[left_match_hash]++;
            int right_hash_cnt = right_match_hashes[right_match_hash]++;
            int left_total_hash_cnt = left_total_match_hashes[left_match_hash]++;
            int right_total_hash_cnt = right_total_match_hashes[right_match_hash]++;
            if (left_hash_cnt == 0 && right_hash_cnt == 0) {
              // only add if new hash is encountered
              if (!context_added) { // only add once per program
                context_added = true;
                ++matching_contexts;
              }
              // only add excerpts with new completely new hashes
              if (left_total_hash_cnt == 0 && right_total_hash_cnt == 0) {
                if (!total_context_added) {
                  total_context_added = true;
                  ++matching_contexts_sum;
                }
                excerpts.emplace_back(*p, *it-excerpt_size, *it+excerpt_size);
                output_excerpt_file << '"' << excerpts.back().date << "\",\""
                                    << excerpts.back().program_title << "\",\""
                                    << boost::replace_all_copy(excerpts.back().text, "\"", "\"\"") << '"'
                                    << std::endl;
                for (auto pattern = expressions.back().patterns.begin(); pattern != expressions.back().patterns.end(); ++pattern) {
                  excerpts.back().highlight_word(*pattern);
                }
                if (random && excerpts.size() <= num_excerpts) {
                  snap::web::print_excerpt(excerpts.back());
                }
              }
            }
          }
        }
        match_positions.clear();
      }
      matching_programs_sum += matching_programs;
      total_matches_sum += total_matches;
      selected_programs_sum += programs.size();
      total_programs_sum += programs.size();
      search_results.push_back(std::vector<std::string>());
      search_results.back().push_back(snap::date::date_to_string(current_date));
      search_results.back().push_back(std::to_string(matching_contexts));
      search_results.back().push_back(std::to_string(matching_programs));
      search_results.back().push_back(std::to_string(total_matches));
      search_results.back().push_back(std::to_string(programs.size()));
      search_results.back().push_back(std::to_string(programs.size()));
      if (!random) {
        std::copy(search_results.back().begin(), search_results.back().end() - 1, std::ostream_iterator<std::string>(std::cout, "\t"));
        std::cout << search_results.back().back() << std::endl;
      }
      programs.clear();
    } else {
      missing_files.push_back(*it);
    }
  }
  sort(search_results.begin(), search_results.end(),
       [](std::vector<std::string> a, std::vector<std::string> b) -> bool { return a.front() < b.front(); });
  if (random) {
    std::cout << "
" << std::endl;
    print_column_headers();
    for (auto it = search_results.begin(); it != search_results.end(); ++it) {
      std::copy(it -> begin(), it -> end() - 1, std::ostream_iterator<std::string>(std::cout, "\t"));
      std::cout << it -> back() << std::endl;
    }
  }
  std::cout << "Grand Total:";
  std::cout << '\t' << matching_contexts_sum;
  std::cout << '\t' << matching_programs_sum;
  std::cout << '\t' << total_matches_sum;
  std::cout << '\t' << selected_programs_sum;
  std::cout << '\t' << total_programs_sum << std::endl;
  std::cout << "
" << std::endl;

  // output file
  std::string output_file_name = output_path + search_results.front().front() + "_" + random_id + ".csv";
  std::ofstream output_file(output_file_name);
  output_file << "dt,matching_contexts_cnt,matching_programs_cnt,total_matches_cnt,selected_programs_cnt,total_programs_cnt" << std::endl;
  for (auto it = search_results.begin(); it != search_results.end(); ++it) {
    std::copy(it -> begin(), it -> end() - 1, std::ostream_iterator<std::string>(output_file, ","));
    output_file << it -> back() << '\n';
  }
  output_file.close();
  output_excerpt_file.close();

  std::cout << "Output CSV
" << std::endl;
  std::cout << "Excerpt CSV
" << std::endl;

  std::cout << "
";
  std::cout << "
" << std::endl;
  snap::web::print_missing_files(missing_files);
  std::cout << "
" << std::endl;
  snap::web::print_corrupt_files(corrupt_files);
  std::cout << "
" << std::endl;

  if (!random) snap::web::print_excerpts(excerpts, num_excerpts, true);

  double duration = (std::clock() - start_time) / (double) CLOCKS_PER_SEC;
  std::cout << "
Time taken (seconds): " << duration << "
" << std::endl;

  snap::web::close_html();
  return 0;
}
<commit_msg>added smaller random excerpt file<commit_after>#include <algorithm>
#include <cctype>
#include <chrono>
#include <cstdlib>
#include <cstdio>
#include <exception>
#include <iostream>
#include <fstream>
#include <random>
#include <string>
#include <unordered_map>

#include "boost/algorithm/string.hpp"
#include "boost/date_time/gregorian/gregorian.hpp"

#include "snap.h"
#include "StringHasher.h"

const std::string prefix = "Data/";
const std::string output_path = "../tmp/";
const std::string suffix = "-Combined.txt";
const int max_input_size = 1000000;

// hashing parameters
const int A = 3;
const int M = 65071;
const int LEFT_HASH_WIDTH = 15;
const int RIGHT_HASH_WIDTH = 25;

void print_column_headers() {
  std::cout << "mt_cxt = matching_contexts_cnt" << '\n';
  std::cout << "mt_prg = matching_programs_cnt" << '\n';
  std::cout << "tot_mt = total_matches_cnt" << '\n';
  std::cout << "sel_prg = selected_programs_cnt" << '\n';
  std::cout << "tot_prg = total_programs_cnt" << '\n';
  std::cout << "dt        \tmt_cxt\tmt_prg\ttot_mt\tsel_prg\ttot_prg" << std::endl;
}

int main() {
  clock_t start_time = std::clock();
  srand(time(NULL));
  std::string random_id = std::to_string(rand());

  snap::web::print_header();

  // get user input
  int content_length = atoi(getenv("CONTENT_LENGTH"));
  char *input = new char[content_length+1];
  fgets(input, content_length+1, stdin);
  std::string query_string(input);
  delete[] input;

  // process user input
  std::map<std::string, std::string> arguments = snap::web::parse_query_string(query_string);
  std::string search_string = snap::web::decode_uri(boost::algorithm::trim_copy(arguments["search-string"]));
  boost::gregorian::date from_date, to_date;
  try {
    from_date = snap::date::string_to_date(arguments["from-date"]);
    to_date = snap::date::string_to_date(arguments["to-date"]);
  } catch (snap::date::InvalidDateException &e) {
    std::cout << "" << e.what() << "" << std::endl;
    exit(-1);
  }
  int num_excerpts = stoi(arguments["num-excerpts"]);
  int excerpt_size = stoi(arguments["excerpt-size"]);
  bool random = arguments["random"] == "on";

  std::vector<std::string> file_list = snap::io::generate_file_names(from_date, to_date, prefix, suffix);
  unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  if (random) {
    std::shuffle(file_list.begin(), file_list.end(), std::default_random_engine(seed));
  }
  std::vector<snap::Expression> expressions;
  try {
    expressions.emplace_back(search_string);
  } catch(snap::ExpressionSyntaxError &e) {
    const char *error_msg = e.what();
    std::cout << "" << error_msg << "" << std::endl;
    delete[] error_msg;
    exit(-1);
  }

  // display user input
  std::cout << "
" << std::endl;
  std::cout << "Search string: " << search_string << "
" << std::endl;
  std::cout << "From (inclusive): " << arguments["from-date"] << "
" << std::endl;
  std::cout << "To (inclusive): " << arguments["to-date"] << "
" << std::endl;
  std::cout << "Number of Excerpts: " << arguments["num-excerpts"] << "
" << std::endl;
  std::cout << "Excerpt Size: " << arguments["excerpt-size"] << "
" << std::endl;
  std::cout << "
" << std::endl;

  // set up excerpt files
  std::string output_excerpt_file_name = output_path + snap::date::date_to_string(from_date) + "_all_excerpts_" + random_id + ".csv";
  std::string output_random_excerpt_file_name = output_path + snap::date::date_to_string(from_date) + "_random_excerpts_" + random_id + ".csv";
  std::ofstream output_excerpt_file(output_excerpt_file_name);
  std::ofstream output_random_excerpt_file(output_random_excerpt_file_name);
  output_excerpt_file << "\"dt\",\"program\",\"excerpt\"" << std::endl;
  output_random_excerpt_file << "\"dt\",\"program\",\"excerpt\"" << std::endl;

  // begin to iteratively process files
  std::unordered_map<int, int> left_total_match_hashes;
  std::unordered_map<int, int> right_total_match_hashes;
  int matching_contexts_sum = 0;
  int matching_programs_sum = 0;
  int total_matches_sum = 0;
  int selected_programs_sum = 0;
  int total_programs_sum = 0;
  std::vector<std::vector<std::string>> search_results;
  std::vector<std::string> corrupt_files;
  std::vector<std::string> missing_files;
  std::vector<snap::Excerpt> excerpts;
  if (!random) {
    std::cout << "
" << std::endl;
    print_column_headers();
  }
  snap::StringHasher hasher("", M, A);
  for (auto it = file_list.begin();
       it != file_list.end();
       ++it) {
    boost::gregorian::date current_date = snap::date::string_to_date((*it).substr(prefix.length(), 10));
    if (snap::io::file_exists(*it)) {
      std::vector<snap::Program> programs;
      try {
        programs = snap::io::parse_programs(*it);
      } catch (snap::io::CorruptFileException &e) {
        programs.clear();
        corrupt_files.push_back(*it);
        continue;
      }
      int matching_contexts = 0; // context is distinct hash AND distinct program
      int matching_programs = 0;
      int total_matches = 0;
      if (random) {
        seed = std::chrono::system_clock::now().time_since_epoch().count();
        std::shuffle(programs.begin(), programs.end(), std::default_random_engine(seed));
      }
      std::unordered_map<int, int> left_match_hashes;
      std::unordered_map<int, int> right_match_hashes;
      for (auto p = programs.begin(); p != programs.end(); ++p) {
        std::map<std::string, std::vector<int>> raw_match_positions = snap::find(expressions.back().patterns, p -> lower_text);
        std::map<std::string, std::vector<int>> match_positions = snap::evaluate_expressions(expressions, raw_match_positions);
        hasher.load_text(p -> lower_text);
        if (match_positions[search_string].size() > 0) {
          ++matching_programs;
          total_matches += match_positions[search_string].size();
          bool total_context_added = false;
          bool context_added = false;
          for (auto it = match_positions[search_string].begin(); it != match_positions[search_string].end(); ++it) {
            int left_match_hash = hasher.hash(*it - LEFT_HASH_WIDTH, *it);
            int right_match_hash = hasher.hash(*it, *it + RIGHT_HASH_WIDTH);
            int left_hash_cnt = left_match_hashes[left_match_hash]++;
            int right_hash_cnt = right_match_hashes[right_match_hash]++;
            int left_total_hash_cnt = left_total_match_hashes[left_match_hash]++;
            int right_total_hash_cnt = right_total_match_hashes[right_match_hash]++;
            if (left_hash_cnt == 0 && right_hash_cnt == 0) {
              // only add if new hash is encountered
              if (!context_added) { // only add once per program
                context_added = true;
                ++matching_contexts;
              }
              // only add excerpts with new completely new hashes
              if (left_total_hash_cnt == 0 && right_total_hash_cnt == 0) {
                if (!total_context_added) {
                  total_context_added = true;
                  ++matching_contexts_sum;
                }
                excerpts.emplace_back(*p, *it-excerpt_size, *it+excerpt_size);
                output_excerpt_file << '"' << excerpts.back().date << "\",\""
                                    << excerpts.back().program_title << "\",\""
                                    << boost::replace_all_copy(excerpts.back().get_raw_text(), "\"", "\"\"") << '"'
                                    << std::endl;
                for (auto pattern = expressions.back().patterns.begin(); pattern != expressions.back().patterns.end(); ++pattern) {
                  excerpts.back().highlight_word(*pattern);
                }
                if (random && excerpts.size() <= num_excerpts) {
                  snap::web::print_excerpt(excerpts.back());
                  output_random_excerpt_file << '"' << excerpts.back().date << "\",\""
                                             << excerpts.back().program_title << "\",\""
                                             << boost::replace_all_copy(excerpts.back().get_raw_text(), "\"", "\"\"") << '"'
                                             << std::endl;
                }
              }
            }
          }
        }
        match_positions.clear();
      }
      matching_programs_sum += matching_programs;
      total_matches_sum += total_matches;
      selected_programs_sum += programs.size();
      total_programs_sum += programs.size();
      search_results.push_back(std::vector<std::string>());
      search_results.back().push_back(snap::date::date_to_string(current_date));
      search_results.back().push_back(std::to_string(matching_contexts));
      search_results.back().push_back(std::to_string(matching_programs));
      search_results.back().push_back(std::to_string(total_matches));
      search_results.back().push_back(std::to_string(programs.size()));
      search_results.back().push_back(std::to_string(programs.size()));
      if (!random) {
        std::copy(search_results.back().begin(), search_results.back().end() - 1, std::ostream_iterator<std::string>(std::cout, "\t"));
        std::cout << search_results.back().back() << std::endl;
      }
      programs.clear();
    } else {
      missing_files.push_back(*it);
    }
  }
  sort(search_results.begin(), search_results.end(),
       [](std::vector<std::string> a, std::vector<std::string> b) -> bool { return a.front() < b.front(); });
  if (random) {
    std::cout << "
" << std::endl;
    print_column_headers();
    for (auto it = search_results.begin(); it != search_results.end(); ++it) {
      std::copy(it -> begin(), it -> end() - 1, std::ostream_iterator<std::string>(std::cout, "\t"));
      std::cout << it -> back() << std::endl;
    }
  } else {
    // shuffle excerpts
    seed = std::chrono::system_clock::now().time_since_epoch().count();
    std::shuffle(excerpts.begin(), excerpts.end(), std::default_random_engine(seed));
    for (int i = 0; i < num_excerpts && i < excerpts.size(); ++i) {
      output_random_excerpt_file << '"' << excerpts[i].date << "\",\""
                                 << excerpts[i].program_title << "\",\""
                                 << boost::replace_all_copy(excerpts[i].get_raw_text(), "\"", "\"\"") << '"'
                                 << std::endl;
    }
  }
  std::cout << "Grand Total:";
  std::cout << '\t' << matching_contexts_sum;
  std::cout << '\t' << matching_programs_sum;
  std::cout << '\t' << total_matches_sum;
  std::cout << '\t' << selected_programs_sum;
  std::cout << '\t' << total_programs_sum << std::endl;
  std::cout << "
" << std::endl;

  // output file
  std::string output_file_name = output_path + search_results.front().front() + "_" + random_id + ".csv";
  std::ofstream output_file(output_file_name);
  output_file << "dt,matching_contexts_cnt,matching_programs_cnt,total_matches_cnt,selected_programs_cnt,total_programs_cnt" << std::endl;
  for (auto it = search_results.begin(); it != search_results.end(); ++it) {
    std::copy(it -> begin(), it -> end() - 1, std::ostream_iterator<std::string>(output_file, ","));
    output_file << it -> back() << '\n';
  }
  output_file.close();
  output_excerpt_file.close();

  std::cout << "Output CSV
" << std::endl;
  std::cout << "All Excerpts CSV
" << std::endl;
  std::cout << "Random Excerpts CSV
" << std::endl;

  std::cout << "
";
  std::cout << "
" << std::endl;
  snap::web::print_missing_files(missing_files);
  std::cout << "
" << std::endl;
  snap::web::print_corrupt_files(corrupt_files);
  std::cout << "
" << std::endl;

  if (!random) snap::web::print_excerpts(excerpts, num_excerpts, false);

  double duration = (std::clock() - start_time) / (double) CLOCKS_PER_SEC;
  std::cout << "
Time taken (seconds): " << duration << "
" << std::endl;

  snap::web::close_html();
  return 0;
}
<|endoftext|>


<commit_before>/**
 *  @author        Ryan Huang <ryanhuang@cs.ucsd.edu>
 *  @organization  University of California, San Diego
 *
 * JNI helper functions
 *
 */

#include "JNIHelper.h"
#include "Util.h"

#include <stdio.h>
#include <map>

JNIEnv* globalEnv = NULL;

typedef std::map<const char *, void *> HashMap;
typedef std::map<const char *, void *>::iterator MapIter;
typedef std::pair<const char *, void *> KVPair;

HashMap globalClsMap;

void * mapGet(HashMap& map, const char * key)
{
  MapIter it = map.find(key);
  if (it == map.end()) {
    return NULL;
  }
  return it->second;
}

void mapPut(HashMap& map, const char * key, void * value)
{
  map.insert(KVPair(key, value));
}

// Create a JNI env.
//
// Reference: http://www.inonit.com/cygwin/jni/invocationApi/c.html
JNIEnv* createJNIEnv()
{
  JavaVM* jvm;
  JNIEnv* env;

  JavaVMInitArgs args;
  JavaVMOption options[1];

  const char *classpath_prefix = "-Djava.class.path=";
  char *classpath;
  char *classpath_arg;

  jint err = 0;

  args.version = JNI_VERSION_1_2;
  args.nOptions = 1;
  classpath = getenv("CLASSPATH"); // read CLASSPATH env variable
  if (classpath == NULL) {
    die("CLASSPATH env variable is not set!");
  }
  classpath_arg = concat(classpath_prefix, classpath);
  if (classpath_arg == NULL) {
    die("fail to allocate classpath arg string");
  }
  options[0].optionString = classpath_arg;
  args.options = options;

  err = JNI_CreateJavaVM(&jvm, (void **) &env, &args);

  // before checking return value, we should free the allocated string
  free(classpath_arg);

  if (err != 0) {
    die("fail to create JVM");
  }
  return env;
}

// TODO: not thread-safe
JNIEnv* getJNIEnv()
{
  if (globalEnv == NULL) {
    globalEnv = createJNIEnv();
  }
  return globalEnv;
}

jthrowable getAndClearException(JNIEnv *env)
{
  jthrowable exception = env->ExceptionOccurred();
  if (!exception)
    return NULL;
  env->ExceptionClear();
  return exception;
}

jthrowable getMethodId(JNIEnv *env, jmethodID *methodIdOut, const char *className,
                const char *methodName, const char *methodSignature, bool isStatic)
{
  jclass cls;
  jthrowable exception;
  jmethodID mid;

  exception = getClass(env, &cls, className);
  if (exception != NULL)
    return exception;
  if (isStatic) {
    // find the static method
    mid = env->GetStaticMethodID(cls, methodName, methodSignature);
  } else {
    // find the instance method
    mid = env->GetMethodID(cls, methodName, methodSignature);
  }
  if (mid == 0) {
    exception = getAndClearException(env);
  } else {
    *methodIdOut = mid;
    exception = NULL;
  }
  return exception;
}

jthrowable getClass(JNIEnv *env, jclass *clsOut, const char *className)
{
  jthrowable exception = NULL;
  jclass cls = NULL;

  cls = (jclass) mapGet(globalClsMap, className);
  if (cls != NULL) { // found in cache
    *clsOut = cls;
    return exception;
  } else {
    // not in cache, find from env
    cls = env->FindClass(className);
    if (cls == NULL) {
      // still can't find from env
      exception = getAndClearException(env);
    } else {
      // find in env, update cache
      mapPut(globalClsMap, className, cls);
      *clsOut = cls;
    }
  }
  return exception;
}

jthrowable newClassObject(JNIEnv *env, jobject *objOut, const char *className,
              const char *ctorSignature, ...)
{
  va_list args;
  jthrowable exception;
  jclass cls; // need class for new object
  jmethodID mid;
  jobject obj;

  exception = getClass(env, &cls, className);
  if (exception != NULL) {
    return exception;
  }

  exception = getMethodId(env, &mid, className, CTORNAME, ctorSignature, false);
  if (exception != NULL) {
    return exception;
  }

  va_start(args, ctorSignature);
  obj = env->NewObjectV(cls, mid, args);
  va_end(args);

  if (obj == NULL) {
    exception = getAndClearException(env);
  } else {
    *objOut = obj;
    exception = NULL;
  }
  return exception;
}

bool getMethodRetType(char * rettOut, const char *methodSignature)
{
  if (rettOut == NULL)
    return false;
  char t = findNext(methodSignature, ')');
  if (t == '\0') {
    // invalid signature
    return false;
  }
  *rettOut = t;
  return true;
}

void printException(JNIEnv *env, jthrowable exception)
{
  jclass cls;
  jclass basecls;
  jobject obj;
  jmethodID mid;

  jstring jClsName;
  jstring jMsg;

  cls = env->GetObjectClass(exception);
  mid = env->GetMethodID(cls, "getClass", "()Ljava/lang/Class;");
  obj = env->CallObjectMethod(exception, mid);
  basecls = env->GetObjectClass(obj);
  mid = env->GetMethodID(basecls, "getName", "()Ljava/lang/String;");
  jClsName = (jstring) env->CallObjectMethod(obj, mid);

  mid = env->GetMethodID(cls, "getMessage", "()Ljava/lang/String;");
  jMsg = (jstring) env->CallObjectMethod(exception, mid);

  const char *clsName = env->GetStringUTFChars(jClsName, 0);
  const char *msg = env->GetStringUTFChars(jMsg, 0);

  printf("exception in %s: %s\n", clsName, msg);
  env->ReleaseStringUTFChars(jClsName, clsName);
  env->ReleaseStringUTFChars(jMsg, msg);
}

jthrowable callMethod(JNIEnv *env, jvalue *retOut, jobject obj,
                const char *className, const char *methodName,
                const char * methodSignature, bool isStatic, ...)
{
  va_list args;
  jthrowable exception;
  jclass cls;
  jmethodID mid;

  exception = getClass(env, &cls, className);
  if (exception != NULL)
    return exception;

  exception = getMethodId(env, &mid, className, methodName,
                          methodSignature, isStatic);
  if (exception != NULL)
    return exception;

  va_start(args, isStatic);
  char retType;
  getMethodRetType(&retType, methodSignature);
  switch (retType) {
    case J_BOOL:
        if (isStatic)
          exception = callStaticBooleanMethod(env, retOut, cls, mid, args);
        else
          exception = callBooleanMethod(env, retOut, obj, mid, args);
        break;
    case J_BYTE:
        if (isStatic)
          exception = callStaticByteMethod(env, retOut, cls, mid, args);
        else
          exception = callByteMethod(env, retOut, obj, mid, args);
        break;
    case J_CHAR:
        if (isStatic)
          exception = callStaticCharMethod(env, retOut, cls, mid, args);
        else
          exception = callCharMethod(env, retOut, obj, mid, args);
        break;
    case J_SHORT:
        if (isStatic)
          exception = callStaticShortMethod(env, retOut, cls, mid, args);
        else
          exception = callShortMethod(env, retOut, obj, mid, args);
        break;
    case J_INT:
        if (isStatic)
          exception = callStaticIntMethod(env, retOut, cls, mid, args);
        else
          exception = callIntMethod(env, retOut, obj, mid, args);
        break;
    case J_LONG:
        if (isStatic)
          exception = callStaticLongMethod(env, retOut, cls, mid, args);
        else
          exception = callLongMethod(env, retOut, obj, mid, args);
        break;
    case J_FLOAT:
        if (isStatic)
          exception = callStaticFloatMethod(env, retOut, cls, mid, args);
        else
          exception = callFloatMethod(env, retOut, obj, mid, args);
        break;
    case J_DOUBLE:
        if (isStatic)
          exception = callStaticDoubleMethod(env, retOut, cls, mid, args);
        else
          exception = callDoubleMethod(env, retOut, obj, mid, args);
        break;
    case J_VOID:
        if (isStatic)
          exception = callStaticVoidMethod(env, cls, mid, args);
        else
          exception = callVoidMethod(env, obj, mid, args);
        break;
    case J_OBJ:
    case J_ARRAY:
        if (isStatic)
          exception = callStaticObjectMethod(env, retOut, cls, mid, args);
        else
          exception = callObjectMethod(env, retOut, obj, mid, args);
        break;
    default:
        // TODO: throw a new exception to handle unrecognized return type
        break;
  }
  va_end(args);
  return exception;
}

/* vim: set ts=4 sw=4 : */
<commit_msg>make global reference for finding class<commit_after>/**
 *  @author        Ryan Huang <ryanhuang@cs.ucsd.edu>
 *  @organization  University of California, San Diego
 *
 * JNI helper functions
 *
 */

#include "JNIHelper.h"
#include "Util.h"

#include <stdio.h>
#include <map>

JNIEnv* globalEnv = NULL;

typedef std::map<const char *, void *> HashMap;
typedef std::map<const char *, void *>::iterator MapIter;
typedef std::pair<const char *, void *> KVPair;

HashMap globalClsMap;

void * mapGet(HashMap& map, const char * key)
{
  MapIter it = map.find(key);
  if (it == map.end()) {
    return NULL;
  }
  return it->second;
}

void mapPut(HashMap& map, const char * key, void * value)
{
  map.insert(KVPair(key, value));
}

// Create a JNI env.
//
// Reference: http://www.inonit.com/cygwin/jni/invocationApi/c.html
JNIEnv* createJNIEnv()
{
  JavaVM* jvm;
  JNIEnv* env;

  JavaVMInitArgs args;
  JavaVMOption options[1];

  const char *classpath_prefix = "-Djava.class.path=";
  char *classpath;
  char *classpath_arg;

  jint err = 0;

  args.version = JNI_VERSION_1_2;
  args.nOptions = 1;
  classpath = getenv("CLASSPATH"); // read CLASSPATH env variable
  if (classpath == NULL) {
    die("CLASSPATH env variable is not set!");
  }
  classpath_arg = concat(classpath_prefix, classpath);
  if (classpath_arg == NULL) {
    die("fail to allocate classpath arg string");
  }
  options[0].optionString = classpath_arg;
  args.options = options;

  err = JNI_CreateJavaVM(&jvm, (void **) &env, &args);

  // before checking return value, we should free the allocated string
  free(classpath_arg);

  if (err != 0) {
    die("fail to create JVM");
  }
  return env;
}

// TODO: not thread-safe
JNIEnv* getJNIEnv()
{
  if (globalEnv == NULL) {
    globalEnv = createJNIEnv();
  }
  return globalEnv;
}

jthrowable getAndClearException(JNIEnv *env)
{
  jthrowable exception = env->ExceptionOccurred();
  if (!exception)
    return NULL;
  env->ExceptionClear();
  return exception;
}

jthrowable getMethodId(JNIEnv *env, jmethodID *methodIdOut, const char *className,
                const char *methodName, const char *methodSignature, bool isStatic)
{
  jclass cls;
  jthrowable exception;
  jmethodID mid;

  exception = getClass(env, &cls, className);
  if (exception != NULL)
    return exception;
  if (isStatic) {
    // find the static method
    mid = env->GetStaticMethodID(cls, methodName, methodSignature);
  } else {
    // find the instance method
    mid = env->GetMethodID(cls, methodName, methodSignature);
  }
  if (mid == 0) {
    exception = getAndClearException(env);
  } else {
    *methodIdOut = mid;
    exception = NULL;
  }
  return exception;
}

jthrowable getClass(JNIEnv *env, jclass *clsOut, const char *className)
{
  jthrowable exception = NULL;
  jclass cls = NULL;

  cls = (jclass) mapGet(globalClsMap, className);
  if (cls != NULL) { // found in cache
    *clsOut = cls;
    return exception;
  } else {
    // not in cache, find from env
    cls = env->FindClass(className);
    if (cls == NULL) {
      // still can't find from env
      exception = getAndClearException(env);
    } else {
      // find in env, first create a global reference (otherwise, the reference will be
      // can be dangling), then update cache
      jclass globalCls = (jclass) env->NewGlobalRef(cls);
      if (globalCls == NULL) {
        exception = getAndClearException(env);
      } else {
        mapPut(globalClsMap, className, globalCls);
        *clsOut = globalCls;
        env->DeleteLocalRef(cls); // delete local reference
      }
    }
  }
  return exception;
}

jthrowable newClassObject(JNIEnv *env, jobject *objOut, const char *className,
              const char *ctorSignature, ...)
{
  va_list args;
  jthrowable exception;
  jclass cls; // need class for new object
  jmethodID mid;
  jobject obj;

  exception = getClass(env, &cls, className);
  if (exception != NULL) {
    return exception;
  }

  exception = getMethodId(env, &mid, className, CTORNAME, ctorSignature, false);
  if (exception != NULL) {
    return exception;
  }

  va_start(args, ctorSignature);
  obj = env->NewObjectV(cls, mid, args);
  va_end(args);

  if (obj == NULL) {
    exception = getAndClearException(env);
  } else {
    *objOut = obj;
    exception = NULL;
  }
  return exception;
}

bool getMethodRetType(char * rettOut, const char *methodSignature)
{
  if (rettOut == NULL)
    return false;
  char t = findNext(methodSignature, ')');
  if (t == '\0') {
    // invalid signature
    return false;
  }
  *rettOut = t;
  return true;
}

void printException(JNIEnv *env, jthrowable exception)
{
  jclass cls;
  jclass basecls;
  jobject obj;
  jmethodID mid;

  jstring jClsName;
  jstring jMsg;

  cls = env->GetObjectClass(exception);
  mid = env->GetMethodID(cls, "getClass", "()Ljava/lang/Class;");
  obj = env->CallObjectMethod(exception, mid);
  basecls = env->GetObjectClass(obj);
  mid = env->GetMethodID(basecls, "getName", "()Ljava/lang/String;");
  jClsName = (jstring) env->CallObjectMethod(obj, mid);

  mid = env->GetMethodID(cls, "getMessage", "()Ljava/lang/String;");
  jMsg = (jstring) env->CallObjectMethod(exception, mid);

  const char *clsName = env->GetStringUTFChars(jClsName, 0);
  const char *msg = env->GetStringUTFChars(jMsg, 0);

  printf("exception in %s: %s\n", clsName, msg);
  env->ReleaseStringUTFChars(jClsName, clsName);
  env->ReleaseStringUTFChars(jMsg, msg);
}

jthrowable callMethod(JNIEnv *env, jvalue *retOut, jobject obj,
                const char *className, const char *methodName,
                const char * methodSignature, bool isStatic, ...)
{
  va_list args;
  jthrowable exception;
  jclass cls;
  jmethodID mid;

  exception = getClass(env, &cls, className);
  if (exception != NULL)
    return exception;

  exception = getMethodId(env, &mid, className, methodName,
                          methodSignature, isStatic);
  if (exception != NULL)
    return exception;

  va_start(args, isStatic);
  char retType;
  getMethodRetType(&retType, methodSignature);
  switch (retType) {
    case J_BOOL:
        if (isStatic)
          exception = callStaticBooleanMethod(env, retOut, cls, mid, args);
        else
          exception = callBooleanMethod(env, retOut, obj, mid, args);
        break;
    case J_BYTE:
        if (isStatic)
          exception = callStaticByteMethod(env, retOut, cls, mid, args);
        else
          exception = callByteMethod(env, retOut, obj, mid, args);
        break;
    case J_CHAR:
        if (isStatic)
          exception = callStaticCharMethod(env, retOut, cls, mid, args);
        else
          exception = callCharMethod(env, retOut, obj, mid, args);
        break;
    case J_SHORT:
        if (isStatic)
          exception = callStaticShortMethod(env, retOut, cls, mid, args);
        else
          exception = callShortMethod(env, retOut, obj, mid, args);
        break;
    case J_INT:
        if (isStatic)
          exception = callStaticIntMethod(env, retOut, cls, mid, args);
        else
          exception = callIntMethod(env, retOut, obj, mid, args);
        break;
    case J_LONG:
        if (isStatic)
          exception = callStaticLongMethod(env, retOut, cls, mid, args);
        else
          exception = callLongMethod(env, retOut, obj, mid, args);
        break;
    case J_FLOAT:
        if (isStatic)
          exception = callStaticFloatMethod(env, retOut, cls, mid, args);
        else
          exception = callFloatMethod(env, retOut, obj, mid, args);
        break;
    case J_DOUBLE:
        if (isStatic)
          exception = callStaticDoubleMethod(env, retOut, cls, mid, args);
        else
          exception = callDoubleMethod(env, retOut, obj, mid, args);
        break;
    case J_VOID:
        if (isStatic)
          exception = callStaticVoidMethod(env, cls, mid, args);
        else
          exception = callVoidMethod(env, obj, mid, args);
        break;
    case J_OBJ:
    case J_ARRAY:
        if (isStatic)
          exception = callStaticObjectMethod(env, retOut, cls, mid, args);
        else
          exception = callObjectMethod(env, retOut, obj, mid, args);
        break;
    default:
        // TODO: throw a new exception to handle unrecognized return type
        break;
  }
  va_end(args);
  return exception;
}

/* vim: set ts=4 sw=4 : */
<|endoftext|>


<commit_before>#include <boost/program_options.hpp>
#include <iostream>
#include "data/GraphSerializer.hpp"
#include "data/PathSerializer.hpp"
#include "data/ConfigSerializer.hpp"
#include "genetic/GeneticSolver.hpp"
#include "genetic/GeneticAnalyser.hpp"
#include "utils/Random.hpp"
#include "net/PopulationExchanger.hpp"

namespace po = boost::program_options;

tsp::Graph graph;
tsp::GeneticSolver solver(graph);
tsp::Config cfg;
tsp::PopulationExchanger *ex;

int parseArguments(int argc, char **argv)
{
    po::variables_map vm;
    po::options_description desc("Allowed Options");
    desc.add_options()
    ("help,h", "show help text")
    ("config,c", po::value<std::string>(), "config file")
    ("infile,i", po::value<std::string>(), "graph definition file")
    ("outfile,o", po::value<std::string>(), "path output file")
    ("generations,g", po::value<unsigned int>(),
     "amount of generations to be calculated")
    ("population,p", po::value<unsigned int>(), "population size")
    ("start,s", po::value<unsigned int>(), "start node")
    ("elitism,e", po::value<double>(), "elitism rate")
    ("mutation,m", po::value<double>(), "mutation chance")
    ("fitness,f", po::value<unsigned int>(), "fitness power")
    ("exchange,x", po::value<double>(), "exchange rate")
    ("network,n", "activate MPI network mode")
    ;
    try {
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
    } catch(std::exception &e) {
        std::cout << e.what() << "\n";
        return 1;
    }

    bool hasConfig = vm.count("config");
    bool hasOpt = vm.count("infile") &&
                  vm.count("outfile") &&
                  vm.count("generations") &&
                  vm.count("population") &&
                  vm.count("start") &&
                  vm.count("elitism") &&
                  vm.count("mutation") &&
                  vm.count("fitness");
    bool hasHelp = vm.count("help");
    if(hasHelp || !(hasConfig || hasOpt)) {
        std::cout << desc << "\n";
        return 1;
    }

    if(hasConfig) {
        std::cout << "Loading Config from '" << vm["config"].as<std::string>() <<
                  "' ...";
        std::cout.flush();
        if(!tsp::ConfigSerializer::load(cfg, vm["config"].as<std::string>())) {
            std::cout << " Failed\n";
            return 1;
        }
        std::cout << " Done\n";
    }

    if(vm.count("infile"))
        cfg.graphFile = vm["infile"].as<std::string>();
    if(vm.count("outfile"))
        cfg.pathFile = vm["outfile"].as<std::string>();
    if(vm.count("generations"))
        cfg.generationCount = vm["generations"].as<unsigned int>();
    if(vm.count("population"))
        cfg.gaSettings.populationSize = vm["population"].as<unsigned int>();
    if(vm.count("start"))
        cfg.gaSettings.startNode = vm["start"].as<unsigned int>();
    if(vm.count("elitism"))
        cfg.gaSettings.elitismRate = vm["elitism"].as<double>();
    if(vm.count("mutation"))
        cfg.gaSettings.mutationChance = vm["mutation"].as<double>();
    if(vm.count("fitness"))
        cfg.gaSettings.fitnessPow = vm["fitness"].as<unsigned int>();
    if(vm.count("exchange"))
        cfg.exchangeRate = vm["exchange"].as<double>();
    if(vm.count("network")) {
        ex = new tsp::PopulationExchanger(argc, argv);
        ex->setExchangeCount(cfg.exchangeRate * cfg.gaSettings.populationSize);
    }

    return 0;
}

int main(int argc, char **argv)
{
    tsp::Random::shakeRNG();
    ex = NULL;

    int ret = parseArguments(argc, argv);
    if(ret)
        return ret;

    std::cout << "Parameters\n";
    std::cout << "  graph file: " << cfg.graphFile << "\n";
    std::cout << "  path file: " << cfg.pathFile << "\n";
    std::cout << "  generation count: " << cfg.generationCount << "\n";
    std::cout << "  population size: " << cfg.gaSettings.populationSize << "\n";
    std::cout << "  start node: " << cfg.gaSettings.startNode << "\n";
    std::cout << "  elitism rate: " << cfg.gaSettings.elitismRate << "\n";
    std::cout << "  mutation chance: " << cfg.gaSettings.mutationChance << "\n";
    std::cout << "  fitness power: " << cfg.gaSettings.fitnessPow << "\n";

    std::cout << "Loading Graph ...";
    std::cout.flush();
    if(!tsp::GraphSerializer::load(graph, cfg.graphFile)) {
        std::cout << " Failed\n";
        return 1;
    }
    std::cout << " Done\n";

    std::cout << "Initializing solver...";
    std::cout.flush();
    solver.setSettings(cfg.gaSettings);
    solver.init();
    std::cout << " Done\n";

    tsp::GeneticAnalyser analyser(graph);
    for(unsigned int i = 0; i < cfg.generationCount; ++i) {
        std::cout << "Calculating Generation " << i + 1 << "... ";
        std::cout.flush();
        solver.nextGeneration();

        if(ex != NULL) {
            ex->exchange(solver.getPopulation());
            solver.updateFitness();
        }

        std::cout << " Done\n";
        std::cout << "  Best Distance: " << analyser.getBestDistance(
                      solver.getPopulation()) << "\n";
        std::cout << "  Mean Distance: " << analyser.getMeanDistance(
                      solver.getPopulation()) << "\n";
        std::cout << "  Best Fitness: " << analyser.getBestFitness(
                      solver.getPopulation()) << "\n";
        std::cout << "  Mean Fitness: " << analyser.getMeanFitness(
                      solver.getPopulation()) << "\n";
        std::cout << "  Best Norm. Fitness: " << analyser.getBestNormalizedFitness(
                      solver.getPopulation()) << "\n";
    }

    std::cout << "Saving Path ...";
    std::cout.flush();
    tsp::PathSerializer::save(solver.getPopulation().getBestIndividual().getPath(),
                              cfg.pathFile);
    std::cout << " Done\n";

    if(ex != NULL)
        delete ex;

    return 0;
}
<commit_msg>Refactor simplega main<commit_after>#include <boost/program_options.hpp>
#include <iostream>
#include "data/GraphSerializer.hpp"
#include "data/PathSerializer.hpp"
#include "data/ConfigSerializer.hpp"
#include "genetic/GeneticSolver.hpp"
#include "genetic/GeneticAnalyser.hpp"
#include "net/PopulationExchanger.hpp"
#include "utils/Random.hpp"

namespace po = boost::program_options;

tsp::Graph graph;
tsp::GeneticSolver solver(graph);
tsp::Config cfg;
tsp::PopulationExchanger *ex = NULL;

static int parseArguments(int argc, char **argv)
{
    po::variables_map vm;
    po::options_description desc("Allowed Options");
    desc.add_options()
    ("help,h", "show help text")
    ("config,c", po::value<std::string>(), "config file")
    ("infile,i", po::value<std::string>(), "graph definition file")
    ("outfile,o", po::value<std::string>(), "path output file")
    ("generations,g", po::value<unsigned int>(),
     "amount of generations to be calculated")
    ("population,p", po::value<unsigned int>(), "population size")
    ("start,s", po::value<unsigned int>(), "start node")
    ("elitism,e", po::value<double>(), "elitism rate")
    ("mutation,m", po::value<double>(), "mutation chance")
    ("fitness,f", po::value<unsigned int>(), "fitness power")
    ("exchange,x", po::value<double>(), "exchange rate")
    ("network,n", "activate MPI network mode")
    ;
    try {
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
    } catch(std::exception &e) {
        std::cout << e.what() << "\n";
        return 1;
    }

    bool hasConfig = vm.count("config");
    bool hasOpt = vm.count("infile") &&
                  vm.count("outfile") &&
                  vm.count("generations") &&
                  vm.count("population") &&
                  vm.count("start") &&
                  vm.count("elitism") &&
                  vm.count("mutation") &&
                  vm.count("fitness");
    bool hasHelp = vm.count("help");
    if(hasHelp || !(hasConfig || hasOpt)) {
        std::cout << desc << "\n";
        return 1;
    }

    // load config file if specified
    if(hasConfig) {
        std::cout << "Loading Config from '" << vm["config"].as<std::string>() <<
                  "' ...";
        std::cout.flush();
        if(!tsp::ConfigSerializer::load(cfg, vm["config"].as<std::string>())) {
            std::cout << " Failed\n";
            return 1;
        }
        std::cout << " Done\n";
    }

    if(vm.count("exchange"))
        cfg.exchangeRate = vm["exchange"].as<double>();
    if(vm.count("network")) {
        ex = new tsp::PopulationExchanger(argc, argv);
        ex->setExchangeCount(cfg.exchangeRate * cfg.gaSettings.populationSize);
    }
    if(vm.count("infile"))
        cfg.graphFile = vm["infile"].as<std::string>();
    if(vm.count("outfile"))
        cfg.pathFile = vm["outfile"].as<std::string>();
    if(vm.count("generations"))
        cfg.generationCount = vm["generations"].as<unsigned int>();
    if(vm.count("population"))
        cfg.gaSettings.populationSize = vm["population"].as<unsigned int>();
    if(vm.count("start"))
        cfg.gaSettings.startNode = vm["start"].as<unsigned int>();
    if(vm.count("elitism"))
        cfg.gaSettings.elitismRate = vm["elitism"].as<double>();
    if(vm.count("mutation"))
        cfg.gaSettings.mutationChance = vm["mutation"].as<double>();
    if(vm.count("fitness"))
        cfg.gaSettings.fitnessPow = vm["fitness"].as<unsigned int>();

    return 0;
}

static int exchangeConfig()
{
    // TODO Process 0 send config to all other processes
    // only if network is activated
    return 0;
}

static void printParameters()
{
    std::cout << "Parameters\n";
    std::cout << "  graph file: " << cfg.graphFile << "\n";
    std::cout << "  path file: " << cfg.pathFile << "\n";
    std::cout << "  generation count: " << cfg.generationCount << "\n";
    std::cout << "  population size: " << cfg.gaSettings.populationSize << "\n";
    std::cout << "  start node: " << cfg.gaSettings.startNode << "\n";
    std::cout << "  elitism rate: " << cfg.gaSettings.elitismRate << "\n";
    std::cout << "  mutation chance: " << cfg.gaSettings.mutationChance << "\n";
    std::cout << "  fitness power: " << cfg.gaSettings.fitnessPow << "\n";
    std::cout << "  exchange rate: " << cfg.exchangeRate << "\n";
}

static int loadGraph()
{
    std::cout << "Loading Graph ...";
    std::cout.flush();
    if(!tsp::GraphSerializer::load(graph, cfg.graphFile)) {
        std::cout << " Failed\n";
        return 1;
    }
    std::cout << " Done\n";

    return 0;
}

static void runAlgorithm()
{
    std::cout << "Initializing solver...";
    std::cout.flush();
    solver.setSettings(cfg.gaSettings);
    solver.init();
    std::cout << " Done\n";

    tsp::GeneticAnalyser analyser(graph);
    for(unsigned int i = 0; i < cfg.generationCount; ++i) {
        std::cout << "Calculating Generation " << i + 1 << "... ";
        std::cout.flush();
        solver.nextGeneration();

        if(ex != NULL) {
            ex->exchange(solver.getPopulation());
            solver.updateFitness();
        }

        std::cout << " Done\n";
        std::cout << "  Best Distance: " << analyser.getBestDistance(
                      solver.getPopulation()) << "\n";
        std::cout << "  Mean Distance: " << analyser.getMeanDistance(
                      solver.getPopulation()) << "\n";
        std::cout << "  Best Fitness: " << analyser.getBestFitness(
                      solver.getPopulation()) << "\n";
        std::cout << "  Mean Fitness: " << analyser.getMeanFitness(
                      solver.getPopulation()) << "\n";
        std::cout << "  Best Norm. Fitness: " << analyser.getBestNormalizedFitness(
                      solver.getPopulation()) << "\n";
    }
}

static int gatherResults()
{
    // TODO Process 0 should gather best individuals from all processes
    // select best from those
    // only gather if network is activated
    return 0;
}

static int savePath()
{
    std::cout << "Saving Path ...";
    std::cout.flush();
    if(!tsp::PathSerializer::save(solver.getPopulation().getBestIndividual().getPath(),
                              cfg.pathFile))
    {
        std::cout << " Failed\n";
        return 1;
    }

    std::cout << " Done\n";

    return 0;
}

int main(int argc, char **argv)
{
    tsp::Random::shakeRNG();

    int ret = parseArguments(argc, argv);
    if(ret)
        return ret;

    ret = exchangeConfig();
    if(ret)
        return ret;

    printParameters();

    ret = loadGraph();
    if(ret)
        return ret;

    runAlgorithm();

    ret = gatherResults();
    if(ret)
        return ret;

    ret = savePath();
    if(ret)
        return ret;

    if(ex != NULL)
        delete ex;

    return 0;
}
<|endoftext|>