<commit_before>/*-------------neuralnet.cpp--------------------------------------------------//
*
*              Neural Net -- A computational model of a neural network
*
* Purpose: Before building a purely analog circuit with the BIAS project, we
*          decided to first develop a computational model of how we expect the
*          circuit to work in a very algorithmic way.
*
*   Notes: Even though this logic will later be used by the primary BIAS code,
*          very little analog logic was used in the following script. Rather,
*          this script was meant to strengthen our own understanding of our
*          neural system.
*
*          Please let me know if you need any further information!
*              James Schloss
*
*-----------------------------------------------------------------------------*/

#include <iostream>
#include <vector>
#include <time.h>
#include <cstdlib>
#include <cmath>

/*----------------------------------------------------------------------------//
* STRUCTURES / FUNCTIONS
*-----------------------------------------------------------------------------*/

using namespace std;

const int n = 5, tw = 10;

// structure for synaptic crossbars
struct grid{
    double weight[n][n];
    vector <vector <bool> > prefire;
    vector <vector <bool> > postfire;
};

// function for filling our synaptic crossbar
grid fill_grid();

// function for hebbian learning / weight alteration
grid hebbian(grid data, double timestep, double tau);

// function for neuron charge collection
grid neurosum(grid data, vector <double> thresh, double tau,
                       double timestep);

/*----------------------------------------------------------------------------//
* MAIN
*-----------------------------------------------------------------------------*/

int main(void){

    srand(time(NULL));

    vector <double> thresh;

    double tau = 0.2, timestep = 0.1;

    grid data = fill_grid();

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            cout << data.weight[i][j] << '\t';
        }
        cout << endl << endl;

        for (int k = 0; k < tw; k++){
            cout << data.prefire[i][k];
        }
        cout << endl;

    }

    for (int i = 0; i < n; i ++){
        thresh.push_back((rand() % 1000 * 0.001) * 10 * n);
    }

    data = neurosum(data, thresh, tau, timestep);

    cout << "Here are our sums: " << endl;
    for (int i = 0; i < n; i++){
        cout << data.postfire[0][i] << endl;
    }

    return 0;
}

/*----------------------------------------------------------------------------//
* SUBROUTINES
*-----------------------------------------------------------------------------*/

// function for filling our synaptic crossbar
grid fill_grid(){
    grid data;
    vector<bool> rn(n,false);

    // creating initial weights and firing pattern in time window
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            data.weight[i][j] = rand() % 1000 * 0.005;
        }
    }

    for (int i = 0; i < tw; i++){
        for (int j = 0; j < n; j++){
            rn[j] = round(rand() % 10 / 10.0);
        }
        data.prefire.push_back(rn);
    }

    return data;
}

// function for hebbian learning / weight alteration
// For now, we will assume that each output neuron is attached directly to
// its corresponding row. Sure, this is not an ideal situation, but... meh.
//
// The initial firing pattern of everything will be random.
// Because of the way hebbian learning works, we will update the weights twice:
//     Once after the postsynaptic neuron fires (+weight change)
//     Again after the presynaptic neuron fires (-weight change)

grid hebbian(grid data, double timestep, double tau){
    double history[n][n];
    vector <bool> rn(n,false);

    // Following above, positive first, then negative

        for (int i = 0; i < n; i++){
            for (int j = 0; j < n; j++){

                history[i][j] = 0;

                // positive
                if (data.postfire[i][data.postfire[i].size()] == 1){
                    for (int k = 0; k < tw; k++){
                        if (data.prefire[i][k] == 1){
                            history[i][j] += tw - k;
                        }
                    }
                }

                // Here we are updating the prefire, we will need to change the
                // weights negatively.
                rn[i] = round(rand() % 10 / 10.0);
                }
            }

    data.prefire.erase(data.prefire.begin());
    data.prefire.push_back(rn);

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            if (rn[i] == 1){
                for (int k = 0; k < tw; k++){
                    if (data.postfire[i][k] == 1){
                        history[i][j] -= tw - k;
                    }
                }
            }
        }
    }

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            data.weight[i][j] = exp(history[i][j]);
        }
    }

    return data;
}

// function for neuron charge collection
grid neurosum(grid data, vector <double> thresh, double tau,
                       double timestep){

    vector <bool> sum(tw, false);
    vector<double> cumulative(n, false);
    double pt_cumulative = 0, t;

    for (int i = 0; i < n; i++){

        cumulative[i] = 0;

        for (int j = 0; j < n; j++){

            pt_cumulative = 0;

            for (unsigned int k = 0; k < data.prefire.size(); k++){
                t = k * timestep;
                pt_cumulative += data.prefire[i][k] * exp(-(t * tau));
            }

            cumulative[i] += pt_cumulative;

        }
    }

    for (int i = 0; i < n; i++){
        if (cumulative[i] > thresh[i]) {
            sum[i] = 1;
        }
        else{
            sum[i] = 0;
        }

    }

    data.postfire.push_back(sum);

    return data;
}
<commit_msg>updated hebbian function. Indices bacwards on preand postfire. Added Learning Rate (LR)<commit_after>/*-------------neuralnet.cpp--------------------------------------------------//
*
*              Neural Net -- A computational model of a neural network
*
* Purpose: Before building a purely analog circuit with the BIAS project, we
*          decided to first develop a computational model of how we expect the
*          circuit to work in a very algorithmic way.
*
*   Notes: Even though this logic will later be used by the primary BIAS code,
*          very little analog logic was used in the following script. Rather,
*          this script was meant to strengthen our own understanding of our
*          neural system.
*
*          Please let me know if you need any further information!
*              James Schloss
*
*-----------------------------------------------------------------------------*/

#include <iostream>
#include <vector>
#include <time.h>
#include <cstdlib>
#include <cmath>

/*----------------------------------------------------------------------------//
* STRUCTURES / FUNCTIONS
*-----------------------------------------------------------------------------*/

using namespace std;

const int n = 5, tw = 10;

// structure for synaptic crossbars
struct grid{
    double weight[n][n];
    vector <vector <bool> > prefire;
    vector <vector <bool> > postfire;
};

// function for filling our synaptic crossbar
grid fill_grid();

// function for hebbian learning / weight alteration
grid hebbian(grid data, double timestep, double LR);

// function for neuron charge collection
grid neurosum(grid data, vector <double> thresh, double tau,
                       double timestep);

/*----------------------------------------------------------------------------//
* MAIN
*-----------------------------------------------------------------------------*/

int main(void){

    srand(time(NULL));

    vector <double> thresh;

    double tau = 0.2, timestep = 0.1;

    grid data = fill_grid();

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            cout << data.weight[i][j] << '\t';
        }
        cout << endl << endl;

        for (int k = 0; k < tw; k++){
            cout << data.prefire[i][k];
        }
        cout << endl;

    }

    for (int i = 0; i < n; i ++){
        thresh.push_back((rand() % 1000 * 0.001) * 10 * n);
    }

    data = neurosum(data, thresh, tau, timestep);

    cout << "Here are our sums: " << endl;
    for (int i = 0; i < n; i++){
        cout << data.postfire[0][i] << endl;
    }

    cout << data.postfire[0].size();

    data = hebbian(data, timestep, 0.001);

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            cout << data.weight[i][j] << '\t';
        }
        cout << endl << endl;
    }

    return 0;
}

/*----------------------------------------------------------------------------//
* SUBROUTINES
*-----------------------------------------------------------------------------*/

// function for filling our synaptic crossbar
grid fill_grid(){
    grid data;
    vector<bool> rn(n,false);

    // creating initial weights and firing pattern in time window
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            data.weight[i][j] = rand() % 1000 * 0.005;
        }
    }

    for (int i = 0; i < tw; i++){
        for (int j = 0; j < n; j++){
            rn[j] = round(rand() % 10 / 10.0);
        }
        data.prefire.push_back(rn);
    }

    return data;
}

// function for hebbian learning / weight alteration
// We need to update the weights twice, once after the postsynaptic firing,
// and again after the presynaptic firing.

grid hebbian(grid data, double timestep, double LR){

    double history[n][n] = {}, delta = 0.001;
    vector <bool> rn(n,false);
    cout << "check " <<  data.postfire[0].size() << endl;

    // Updating the weights positively by checking the last postsynaptic firing
    // and adding it to our history from the presynaptc firings
    for (int i = 0; i < n; i++){
        cout << i << endl;
        for (int j = 0; j < n; j++){

            if (data.postfire[data.postfire.size() - 1][i] == 1){
                for (int k = 0; k < tw; k++){
                    if (data.prefire[i][k] == 1){
                        history[i][j] += 1 / ((k + delta) * timestep);
                        cout << history[i][j] << endl;
                    }
                }
            }

        }
        rn[i] = round(rand() % 10 / 10.0);
        cout << rn[i] << endl;

    }

    data.prefire.erase(data.prefire.begin());
    data.prefire.push_back(rn);

    cout << endl << endl;

    // Updating the weights negatively through a similar mechanism as above
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            if (data.prefire[data.prefire.size() - 1][i] == 1){
                for (int k = 0; k < tw; k++){
                    history[i][j] += -1 / ((k + delta) * timestep);
                   cout << history[i][j] << endl;

                }
            }

        }
    }

    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            data.weight[i][j] += LR * history[i][j];
        }
    }

    return data;
}

// function for neuron charge collection
grid neurosum(grid data, vector <double> thresh, double tau,
                       double timestep){

    vector <bool> sum(n, false);
    vector<double> cumulative(n, false);
    double pt_cumulative = 0, t;

    for (int i = 0; i < n; i++){

        cumulative[i] = 0;

        for (int j = 0; j < n; j++){

            pt_cumulative = 0;

            for (unsigned int k = 0; k < data.prefire.size(); k++){
                t = k * timestep;
                pt_cumulative += data.prefire[i][k] * exp(-(t * tau));
            }

            cumulative[i] += pt_cumulative;

        }
    }

    for (int i = 0; i < n; i++){
        if (cumulative[i] > thresh[i]) {
            sum[i] = 1;
        }
        else{
            sum[i] = 0;
        }

    }

    data.postfire.push_back(sum);

    return data;
}
<|endoftext|>


<commit_before>//===- llvm-cov.cpp - LLVM coverage tool ----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// llvm-cov is a command line tools to analyze and report coverage information.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/GCOV.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/system_error.h"
using namespace llvm;

static cl::opt<std::string> SourceFile(cl::Positional, cl::Required,
                                       cl::desc("SOURCEFILE"));

static cl::opt<bool>
DumpGCOV("dump", cl::init(false), cl::desc("dump gcov file"));

static cl::opt<std::string>
InputGCNO("gcno", cl::desc("<input gcno file>"), cl::init(""));

static cl::opt<std::string>
InputGCDA("gcda", cl::desc("<input gcda file>"), cl::init(""));

static cl::opt<bool>
AllBlocks("a", cl::init(false), cl::desc("display all block info"));

static cl::opt<bool>
BranchInfo("b", cl::init(false), cl::desc("display branch info"));

static cl::opt<bool>
BranchCount("c", cl::init(false), cl::desc("display branch counts instead of \
                                            probabilities (requires -b)"));

static cl::opt<bool>
FuncCoverage("f", cl::init(false), cl::desc("output function coverage"));

static cl::opt<bool>
UncondBranch("u", cl::init(false), cl::desc("display unconditional branch info \
                                             (requires -b)"));

//===----------------------------------------------------------------------===//
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  cl::ParseCommandLineOptions(argc, argv, "llvm coverage tool\n");

  if (InputGCNO.empty())
    InputGCNO = SourceFile.substr(0, SourceFile.rfind(".")) + ".gcno";
  if (InputGCDA.empty())
    InputGCDA = SourceFile.substr(0, SourceFile.rfind(".")) + ".gcda";

  GCOVFile GF;

  OwningPtr<MemoryBuffer> GCNO_Buff;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCNO, GCNO_Buff)) {
    errs() << InputGCNO << ": " << ec.message() << "\n";
    return 1;
  }
  GCOVBuffer GCNO_GB(GCNO_Buff.get());
  if (!GF.readGCNO(GCNO_GB)) {
    errs() << "Invalid .gcno File!\n";
    return 1;
  }

  OwningPtr<MemoryBuffer> GCDA_Buff;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCDA, GCDA_Buff)) {
    errs() << InputGCDA << ": " << ec.message() << "\n";
    return 1;
  }
  GCOVBuffer GCDA_GB(GCDA_Buff.get());
  if (!GF.readGCDA(GCDA_GB)) {
    errs() << "Invalid .gcda File!\n";
    return 1;
  }

  if (DumpGCOV)
    GF.dump();

  GCOVOptions Options(AllBlocks, BranchInfo, BranchCount, FuncCoverage,
                      UncondBranch);
  FileInfo FI(Options);
  GF.collectLineCounts(FI);
  FI.print(InputGCNO, InputGCDA);
  return 0;
}
<commit_msg>llvm-cov: Improve help message text<commit_after>//===- llvm-cov.cpp - LLVM coverage tool ----------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// llvm-cov is a command line tools to analyze and report coverage information.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/GCOV.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/system_error.h"
using namespace llvm;

static cl::opt<std::string> SourceFile(cl::Positional, cl::Required,
                                       cl::desc("SOURCEFILE"));

static cl::opt<bool> AllBlocks("a", cl::init(false),
                               cl::desc("Display all basic blocks"));

static cl::opt<bool> BranchProb("b", cl::init(false),
                                cl::desc("Display branch probabilities"));

static cl::opt<bool> BranchCount("c", cl::init(false),
                                 cl::desc("Display branch counts instead "
                                           "of percentages (requires -b)"));

static cl::opt<bool> FuncSummary("f", cl::init(false),
                                 cl::desc("Show coverage for each function"));

static cl::opt<bool> UncondBranch("u", cl::init(false),
                                  cl::desc("Display unconditional branch info "
                                           "(requires -b)"));

static cl::OptionCategory DebugCat("Internal and debugging options");
static cl::opt<bool> DumpGCOV("dump", cl::init(false), cl::cat(DebugCat),
                              cl::desc("Dump the gcov file to stderr"));
static cl::opt<std::string> InputGCNO("gcno", cl::cat(DebugCat), cl::init(""),
                                      cl::desc("Override inferred gcno file"));
static cl::opt<std::string> InputGCDA("gcda", cl::cat(DebugCat), cl::init(""),
                                      cl::desc("Override inferred gcda file"));

//===----------------------------------------------------------------------===//
int main(int argc, char **argv) {
  // Print a stack trace if we signal out.
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");

  if (InputGCNO.empty())
    InputGCNO = SourceFile.substr(0, SourceFile.rfind(".")) + ".gcno";
  if (InputGCDA.empty())
    InputGCDA = SourceFile.substr(0, SourceFile.rfind(".")) + ".gcda";

  GCOVFile GF;

  OwningPtr<MemoryBuffer> GCNO_Buff;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCNO, GCNO_Buff)) {
    errs() << InputGCNO << ": " << ec.message() << "\n";
    return 1;
  }
  GCOVBuffer GCNO_GB(GCNO_Buff.get());
  if (!GF.readGCNO(GCNO_GB)) {
    errs() << "Invalid .gcno File!\n";
    return 1;
  }

  OwningPtr<MemoryBuffer> GCDA_Buff;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCDA, GCDA_Buff)) {
    errs() << InputGCDA << ": " << ec.message() << "\n";
    return 1;
  }
  GCOVBuffer GCDA_GB(GCDA_Buff.get());
  if (!GF.readGCDA(GCDA_GB)) {
    errs() << "Invalid .gcda File!\n";
    return 1;
  }

  if (DumpGCOV)
    GF.dump();

  GCOVOptions Options(AllBlocks, BranchProb, BranchCount, FuncSummary,
                      UncondBranch);
  FileInfo FI(Options);
  GF.collectLineCounts(FI);
  FI.print(InputGCNO, InputGCDA);
  return 0;
}
<|endoftext|>


<commit_before><commit_msg>So assume SwUiWriterTest::testEmbeddedDataSource works on MACOSX now too<commit_after><|endoftext|>


<commit_before>//
// Author: NagaChaitanya Vellanki
//
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>

static float LINE_LENGTH = 10.0f;

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
  if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
    glfwSetWindowShouldClose(window, GL_TRUE);
  }
}

// Alphabet : A, B
// Constants : F + -
// Axiom : A
// Production rules:
// A → - B F + A F A + F B -
// B → + A F - B F B - F A +
// - turn left by 90 degrees
// + turn right by 90 degrees
std::string hilbertCurveLSystemRepresentation() {
  std::string current("FA");
  int generation = 0;

  while(generation < 7) {
    std::string next;
    for(std::string::iterator it = current.begin(); it != current.end(); it++) {
      switch(*it) {
        case 'A':
          next.append("-BF+AFA+FB-");
          break;
        case 'B':
          next.append("+AF-BFB-FA+");
          break;
        case '-':
          next.append("-");
          break;
        case '+':
          next.append("+");
          break;
        case 'F':
          next.append("F");
          break;
      };
    }

    current = next;
    generation++;
    //std::cout << "Generation: " <<  " " << current << std::endl;
  }

  return current;
}

void drawHilbertCurve(float x, float y, std::string lrep) {
  glClear(GL_COLOR_BUFFER_BIT);
  glPushMatrix();
  for(std::string::iterator it = lrep.begin(); it != lrep.end(); it++) {
    if(*it == 'F') {
      glColor4f(0.5f, 1.0f, 0.0f, 1.0f);
      glLineWidth(2.0f);
      glBegin(GL_LINES);
      glVertex2f(x, y);
      x = x + LINE_LENGTH;
      glVertex2f(x, y);
      glEnd();
    }
    if(*it == '-' || *it == '+') {
      glTranslatef(x, y, 0.0f);
      x = 0.0f;
      y = 0.0f;
      float angle = ((*it == '-') ? 90.0f : -90.0f);
      glRotatef(angle, 0.0f, 0.0f, 1.0f);
    }
  }
  glPopMatrix();
}

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

  if(!glfwInit()) {
    return -1;
  }

  GLFWmonitor* monitor  = glfwGetPrimaryMonitor();
  const GLFWvidmode* vidmode = glfwGetVideoMode(monitor);

  window = glfwCreateWindow(vidmode->width, vidmode->height, "Hilbert Curve", monitor, NULL);
  if(!window) {
    glfwTerminate();
    return -1;
  }

  glfwSetKeyCallback(window, key_callback);
  glfwMakeContextCurrent(window);

  int width, height;
  glfwGetFramebufferSize(window, &width, &height);
  float x;
  float y;

  glViewport(0, 0, width, height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0.0f, width, 0.0f, height, 0.0, 1.0f);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  std::string lrep = hilbertCurveLSystemRepresentation();
  while(!glfwWindowShouldClose(window)) {
    drawHilbertCurve(width / 4, 20.0f, lrep);
    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  glfwTerminate();
  return 0;
}
<commit_msg>Increase line width<commit_after>//
// Author: NagaChaitanya Vellanki
//
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>

static float LINE_LENGTH = 10.0f;

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
  if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
    glfwSetWindowShouldClose(window, GL_TRUE);
  }
}

// Alphabet : A, B
// Constants : F + -
// Axiom : A
// Production rules:
// A → - B F + A F A + F B -
// B → + A F - B F B - F A +
// - turn left by 90 degrees
// + turn right by 90 degrees
std::string hilbertCurveLSystemRepresentation() {
  std::string current("FA");
  int generation = 0;

  while(generation < 7) {
    std::string next;
    for(std::string::iterator it = current.begin(); it != current.end(); it++) {
      switch(*it) {
        case 'A':
          next.append("-BF+AFA+FB-");
          break;
        case 'B':
          next.append("+AF-BFB-FA+");
          break;
        case '-':
          next.append("-");
          break;
        case '+':
          next.append("+");
          break;
        case 'F':
          next.append("F");
          break;
      };
    }

    current = next;
    generation++;
    //std::cout << "Generation: " <<  " " << current << std::endl;
  }

  return current;
}

void drawHilbertCurve(float x, float y, std::string lrep) {
  glClear(GL_COLOR_BUFFER_BIT);
  glPushMatrix();
  for(std::string::iterator it = lrep.begin(); it != lrep.end(); it++) {
    if(*it == 'F') {
      glColor4f(0.5f, 1.0f, 0.0f, 1.0f);
      glLineWidth(4.0f);
      glBegin(GL_LINES);
      glVertex2f(x, y);
      x = x + LINE_LENGTH;
      glVertex2f(x, y);
      glEnd();
    }
    if(*it == '-' || *it == '+') {
      glTranslatef(x, y, 0.0f);
      x = 0.0f;
      y = 0.0f;
      float angle = ((*it == '-') ? 90.0f : -90.0f);
      glRotatef(angle, 0.0f, 0.0f, 1.0f);
    }
  }
  glPopMatrix();
}

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

  if(!glfwInit()) {
    return -1;
  }

  GLFWmonitor* monitor  = glfwGetPrimaryMonitor();
  const GLFWvidmode* vidmode = glfwGetVideoMode(monitor);

  window = glfwCreateWindow(vidmode->width, vidmode->height, "Hilbert Curve", monitor, NULL);
  if(!window) {
    glfwTerminate();
    return -1;
  }

  glfwSetKeyCallback(window, key_callback);
  glfwMakeContextCurrent(window);

  int width, height;
  glfwGetFramebufferSize(window, &width, &height);
  float x;
  float y;

  glViewport(0, 0, width, height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0.0f, width, 0.0f, height, 0.0, 1.0f);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  std::string lrep = hilbertCurveLSystemRepresentation();
  while(!glfwWindowShouldClose(window)) {
    drawHilbertCurve(width / 4, 20.0f, lrep);
    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  glfwTerminate();
  return 0;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2008-2019 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#ifdef MRTRIX_MACOSX
#include <malloc/malloc.h>
#else
#include <malloc.h>
#endif

#include "command.h"
#include "exception.h"
#include "ordered_thread_queue.h"
#include "timer.h"

using namespace MR;
using namespace App;

#ifdef MRTRIX_MACOSX
#define MALLOC_SIZE(ptr) malloc_size(ptr)
#else
#define MALLOC_SIZE(ptr) malloc_usable_size(ptr)
#endif

#define START(msg) { Timer timer; CONSOLE(std::string("testing ") + msg + " queue..."); memory_usage = peak_memory_usage = num_items = 0

#define END(enforce) CONSOLE("done in " + str(timer.elapsed(), 4) + " seconds"); \
  if (sample_size_received != sample_size) throw Exception("sample size mismatch"); \
  if (out_of_order) { \
    if (enforce) throw Exception ("order mismatch"); \
    else CONSOLE ("order mismatch"); \
  } else { \
    CONSOLE ("order correct"); \
  } } \
  CONSOLE ("peak memory usage = " + str(peak_memory_usage/1024) + " kb (leaked: " + str(memory_usage/1024 ) + " kb)"); \
  CONSOLE ("allocated a total of " + str(num_items) + " items"); \
  std::cerr << "\n"

// to track memory usage:

size_t memory_usage = 0;
size_t peak_memory_usage = 0;
size_t num_items;
std::mutex malloc_mutex;

void * operator new(decltype(sizeof(0)) n)
{
  std::lock_guard<std::mutex> lock (malloc_mutex);
  void * p = malloc (n);
  memory_usage += MALLOC_SIZE(p);
  peak_memory_usage = std::max (memory_usage, peak_memory_usage);
  return p;
}
void operator delete(void * p) noexcept
{
  std::lock_guard<std::mutex> lock (malloc_mutex);
  memory_usage -= MALLOC_SIZE(p);
  free (p);
}

void usage ()
{
  AUTHOR = "J-Donald Tournier (jdtournier@gmail.com)";
  SYNOPSIS = "test Thread::run_ordered_queue() functions";
  REQUIRES_AT_LEAST_ONE_ARGUMENT = false;
}

struct Item {
  Item() { num_items++; }
  size_t value;
};

const size_t sample_size = 1e6;
size_t sample_size_received, out_of_order;

struct SourceFunctor { NOMEMALIGN
  SourceFunctor () : count (0), value (0) { }
  ~SourceFunctor () { std::cerr << "source sent " << count << " items\n"; }
  bool operator() (Item& item) {
    if (++value > sample_size) return false;
    ++count;
    item.value = value;
    return true;
  };
  size_t count;
  size_t value;
};

struct PipeFunctor { NOMEMALIGN
  bool operator() (const Item& in, Item& out) {
    out = in;
    return true;
  }
};

struct SinkFunctor { NOMEMALIGN
  SinkFunctor () : value (0) { sample_size_received = 0; out_of_order = 0; }
  ~SinkFunctor () { std::cerr << "received " << sample_size_received << " items with " << out_of_order << " items out of order\n"; }
  bool operator() (const Item& item) {
    ++sample_size_received;
    if (item.value <= value)
      ++out_of_order;
    value = item.value;
    return true;
  }
  size_t value;
};

void run ()
{
  using namespace Thread;

  START ("regular 2-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      SinkFunctor());
  END(true);

  START ("batched 2-stage");
  run_queue (
      SourceFunctor(),
      batch (Item()),
      SinkFunctor());
  END(true);

  START ("regular 3-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(false);

  START ("batched-unbatched 3-stage");
  run_queue (
      SourceFunctor(),
      batch (Item()),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(false);

  START ("unbatched-batched 3-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      batch (Item()),
      SinkFunctor());
  END(false);

  START ("batched-batched regular 3-stage");
  run_queue (
      SourceFunctor(),
      batch (Item()),
      multi (PipeFunctor()),
      batch (Item()),
      SinkFunctor());
  END(false);

  START ("regular 4-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      Item(),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(false);

  START ("batched-unbatched-unbatched 4-stage");
  run_queue (
      SourceFunctor(),
      batch (Item()),
      multi (PipeFunctor()),
      Item(),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(false);

  START ("unbatched-batched-unbatched 4-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      batch (Item()),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(false);

  START ("unbatched-unbatched-batched regular 4-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      Item(),
      multi (PipeFunctor()),
      batch (Item()),
      SinkFunctor());
  END(false);

  START ("ordered unbatched 3-stage");
  run_ordered_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(true);

  START ("ordered batched-batched 3-stage");
  run_ordered_queue (
      SourceFunctor(),
      batch (Item()),
      multi (PipeFunctor()),
      batch (Item()),
      SinkFunctor());
  END(true);

  START ("unbatched 4-stage");
  run_ordered_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      Item(),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(true);

  START ("ordered batched-batched-batched 4-stage");
  run_ordered_queue (
      SourceFunctor(),
      batch (Item()),
      multi (PipeFunctor()),
      batch (Item()),
      multi (PipeFunctor()),
      batch (Item()),
      SinkFunctor());
  END(true);

}
<commit_msg>remove memory usage tracking from ordered_queue tests<commit_after>/* Copyright (c) 2008-2019 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "command.h"
#include "exception.h"
#include "ordered_thread_queue.h"
#include "timer.h"

using namespace MR;
using namespace App;

size_t num_items;

#define START(msg) { Timer timer; CONSOLE(std::string("testing ") + msg + " queue..."); num_items = 0

#define END(enforce) CONSOLE("done in " + str(timer.elapsed(), 4) + " seconds"); \
  if (sample_size_received != sample_size) throw Exception("sample size mismatch"); \
  if (out_of_order) { \
    if (enforce) throw Exception ("order mismatch"); \
    else CONSOLE ("order mismatch"); \
  } else { \
    CONSOLE ("order correct"); \
  } } \
  CONSOLE ("allocated a total of " + str(num_items) + " items"); \
  std::cerr << "\n"

void usage ()
{
  AUTHOR = "J-Donald Tournier (jdtournier@gmail.com)";
  SYNOPSIS = "test Thread::run_ordered_queue() functions";
  REQUIRES_AT_LEAST_ONE_ARGUMENT = false;
}

struct Item {
  Item() { num_items++; }
  size_t value;
};

const size_t sample_size = 1e6;
size_t sample_size_received, out_of_order;

struct SourceFunctor { NOMEMALIGN
  SourceFunctor () : count (0), value (0) { }
  ~SourceFunctor () { std::cerr << "source sent " << count << " items\n"; }
  bool operator() (Item& item) {
    if (++value > sample_size) return false;
    ++count;
    item.value = value;
    return true;
  };
  size_t count;
  size_t value;
};

struct PipeFunctor { NOMEMALIGN
  bool operator() (const Item& in, Item& out) {
    out = in;
    return true;
  }
};

struct SinkFunctor { NOMEMALIGN
  SinkFunctor () : value (0) { sample_size_received = 0; out_of_order = 0; }
  ~SinkFunctor () { std::cerr << "received " << sample_size_received << " items with " << out_of_order << " items out of order\n"; }
  bool operator() (const Item& item) {
    ++sample_size_received;
    if (item.value <= value)
      ++out_of_order;
    value = item.value;
    return true;
  }
  size_t value;
};

void run ()
{
  using namespace Thread;

  START ("regular 2-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      SinkFunctor());
  END(true);

  START ("batched 2-stage");
  run_queue (
      SourceFunctor(),
      batch (Item()),
      SinkFunctor());
  END(true);

  START ("regular 3-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(false);

  START ("batched-unbatched 3-stage");
  run_queue (
      SourceFunctor(),
      batch (Item()),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(false);

  START ("unbatched-batched 3-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      batch (Item()),
      SinkFunctor());
  END(false);

  START ("batched-batched regular 3-stage");
  run_queue (
      SourceFunctor(),
      batch (Item()),
      multi (PipeFunctor()),
      batch (Item()),
      SinkFunctor());
  END(false);

  START ("regular 4-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      Item(),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(false);

  START ("batched-unbatched-unbatched 4-stage");
  run_queue (
      SourceFunctor(),
      batch (Item()),
      multi (PipeFunctor()),
      Item(),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(false);

  START ("unbatched-batched-unbatched 4-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      batch (Item()),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(false);

  START ("unbatched-unbatched-batched regular 4-stage");
  run_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      Item(),
      multi (PipeFunctor()),
      batch (Item()),
      SinkFunctor());
  END(false);

  START ("ordered unbatched 3-stage");
  run_ordered_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(true);

  START ("ordered batched-batched 3-stage");
  run_ordered_queue (
      SourceFunctor(),
      batch (Item()),
      multi (PipeFunctor()),
      batch (Item()),
      SinkFunctor());
  END(true);

  START ("unbatched 4-stage");
  run_ordered_queue (
      SourceFunctor(),
      Item(),
      multi (PipeFunctor()),
      Item(),
      multi (PipeFunctor()),
      Item(),
      SinkFunctor());
  END(true);

  START ("ordered batched-batched-batched 4-stage");
  run_ordered_queue (
      SourceFunctor(),
      batch (Item()),
      multi (PipeFunctor()),
      batch (Item()),
      multi (PipeFunctor()),
      batch (Item()),
      SinkFunctor());
  END(true);

}
<|endoftext|>


<commit_before>//===-- scudo_tls_linux.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// Scudo thread local structure implementation for platforms supporting
/// thread_local.
///
//===----------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_platform.h"

#if SANITIZER_LINUX && !SANITIZER_ANDROID

#include "scudo_tls.h"

#include <limits.h>
#include <pthread.h>

namespace __scudo {

static pthread_once_t GlobalInitialized = PTHREAD_ONCE_INIT;
static pthread_key_t PThreadKey;

__attribute__((tls_model("initial-exec")))
THREADLOCAL ThreadState ScudoThreadState = ThreadNotInitialized;
__attribute__((tls_model("initial-exec")))
THREADLOCAL ScudoThreadContext ThreadLocalContext;

static void teardownThread(void *Ptr) {
  uptr Iteration = reinterpret_cast<uptr>(Ptr);
  // The glibc POSIX thread-local-storage deallocation routine calls user
  // provided destructors in a loop of PTHREAD_DESTRUCTOR_ITERATIONS.
  // We want to be called last since other destructors might call free and the
  // like, so we wait until PTHREAD_DESTRUCTOR_ITERATIONS before draining the
  // quarantine and swallowing the cache.
  if (Iteration < PTHREAD_DESTRUCTOR_ITERATIONS) {
    pthread_setspecific(PThreadKey, reinterpret_cast<void *>(Iteration + 1));
    return;
  }
  ThreadLocalContext.commitBack();
  ScudoThreadState = ThreadTornDown;
}

static void initOnce() {
  CHECK_EQ(pthread_key_create(&PThreadKey, teardownThread), 0);
  initScudo();
}

void initThread() {
  pthread_once(&GlobalInitialized, initOnce);
  pthread_setspecific(PThreadKey, reinterpret_cast<void *>(1));
  ThreadLocalContext.init();
  ScudoThreadState = ThreadInitialized;
}

}  // namespace __scudo

#endif  // SANITIZER_LINUX && !SANITIZER_ANDROID
<commit_msg>[scudo] Check the return values of the pthread_* functions<commit_after>//===-- scudo_tls_linux.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// Scudo thread local structure implementation for platforms supporting
/// thread_local.
///
//===----------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_platform.h"

#if SANITIZER_LINUX && !SANITIZER_ANDROID

#include "scudo_tls.h"

#include <pthread.h>

namespace __scudo {

static pthread_once_t GlobalInitialized = PTHREAD_ONCE_INIT;
static pthread_key_t PThreadKey;

__attribute__((tls_model("initial-exec")))
THREADLOCAL ThreadState ScudoThreadState = ThreadNotInitialized;
__attribute__((tls_model("initial-exec")))
THREADLOCAL ScudoThreadContext ThreadLocalContext;

static void teardownThread(void *Ptr) {
  uptr I = reinterpret_cast<uptr>(Ptr);
  // The glibc POSIX thread-local-storage deallocation routine calls user
  // provided destructors in a loop of PTHREAD_DESTRUCTOR_ITERATIONS.
  // We want to be called last since other destructors might call free and the
  // like, so we wait until PTHREAD_DESTRUCTOR_ITERATIONS before draining the
  // quarantine and swallowing the cache.
  if (I > 1) {
    // If pthread_setspecific fails, we will go ahead with the teardown.
    if (LIKELY(pthread_setspecific(PThreadKey,
                                   reinterpret_cast<void *>(I - 1)) == 0))
      return;
  }
  ThreadLocalContext.commitBack();
  ScudoThreadState = ThreadTornDown;
}

static void initOnce() {
  CHECK_EQ(pthread_key_create(&PThreadKey, teardownThread), 0);
  initScudo();
}

void initThread() {
  CHECK_EQ(pthread_once(&GlobalInitialized, initOnce), 0);
  CHECK_EQ(pthread_setspecific(PThreadKey, reinterpret_cast<void *>(
      GetPthreadDestructorIterations())), 0);
  ThreadLocalContext.init();
  ScudoThreadState = ThreadInitialized;
}

}  // namespace __scudo

#endif  // SANITIZER_LINUX && !SANITIZER_ANDROID
<|endoftext|>


<commit_before>/* Copyright 2012-present Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 */

#include "watchman.h"
#include <folly/Synchronized.h>

namespace {
struct config_state {
  json_ref global_cfg;
  w_string global_config_file_path;
  json_ref arg_cfg;
};
folly::Synchronized<config_state> configState;
}

/* Called during shutdown to free things so that we run cleanly
 * under valgrind */
void cfg_shutdown(void)
{
  auto state = configState.wlock();
  state->global_cfg.reset();
  state->arg_cfg.reset();
}

w_string cfg_get_global_config_file_path(void) {
  return configState.rlock()->global_config_file_path;
}

void cfg_load_global_config_file(void)
{
  json_error_t err;

  const char *cfg_file = getenv("WATCHMAN_CONFIG_FILE");
#ifdef WATCHMAN_CONFIG_FILE
  if (!cfg_file) {
    cfg_file = WATCHMAN_CONFIG_FILE;
  }
#endif
  if (!cfg_file || cfg_file[0] == '\0') {
    return;
  }

  if (!w_path_exists(cfg_file)) {
    return;
  }

  auto config = json_load_file(cfg_file, 0, &err);
  if (!config) {
    w_log(W_LOG_ERR, "failed to parse json from %s: %s\n",
          cfg_file, err.text);
    return;
  }

  auto lockedState = configState.wlock();
  lockedState->global_cfg = config;
  lockedState->global_config_file_path = cfg_file;
}

void cfg_set_arg(const char* name, const json_ref& val) {
  auto state = configState.wlock();
  if (!state->arg_cfg) {
    state->arg_cfg = json_object();
  }

  state->arg_cfg.set(name, json_ref(val));
}

void cfg_set_global(const char* name, const json_ref& val) {
  auto state = configState.wlock();
  if (!state->global_cfg) {
    state->global_cfg = json_object();
  }

  state->global_cfg.set(name, json_ref(val));
}

static json_ref cfg_get_raw(const char* name, const json_ref* optr) {
  json_ref val;

  if (*optr) {
    val = optr->get_default(name);
  }
  return val;
}

json_ref cfg_get_json(const char* name) {
  json_ref val;
  auto state = configState.rlock();

  // Highest precedence: command line arguments
  val = cfg_get_raw(name, &state->arg_cfg);
  // then: global config options
  if (!val) {
    val = cfg_get_raw(name, &state->global_cfg);
  }
  return val;
}

const char* cfg_get_string(const char* name, const char* defval) {
  auto val = cfg_get_json(name);

  if (val) {
    if (!val.isString()) {
      w_log(W_LOG_FATAL, "Expected config value %s to be a string\n", name);
    }
    return json_string_value(val);
  }

  return defval;
}

// Return true if the json ref is an array of string values
static bool is_array_of_strings(const json_ref& ref) {
  uint32_t i;

  if (!ref.isArray()) {
    return false;
  }

  for (i = 0; i < json_array_size(ref); i++) {
    if (!json_array_get(ref, i).isString()) {
      return false;
    }
  }
  return true;
}

// Given an array of string values, if that array does not contain
// a ".watchmanconfig" entry, prepend it
static void prepend_watchmanconfig_to_array(json_ref& ref) {
  const char *val;

  if (json_array_size(ref) == 0) {
    // json_array_insert_new at index can fail when the array is empty,
    // so just append in this case.
    json_array_append_new(ref, typed_string_to_json(".watchmanconfig",
          W_STRING_UNICODE));
    return;
  }

  val = json_string_value(json_array_get(ref, 0));
  if (!strcmp(val, ".watchmanconfig")) {
    return;
  }
  json_array_insert_new(ref, 0, typed_string_to_json(".watchmanconfig",
        W_STRING_UNICODE));
}

// Compute the effective value of the root_files configuration and
// return a json reference.  The caller must decref the ref when done
// (we may synthesize this value).   Sets enforcing to indicate whether
// we will only allow watches on the root_files.
// The array returned by this function (if not NULL) is guaranteed to
// list .watchmanconfig as its zeroth element.
json_ref cfg_compute_root_files(bool* enforcing) {
  *enforcing = false;

  json_ref ref = cfg_get_json("enforce_root_files");
  if (ref) {
    if (!ref.isBool()) {
      w_log(W_LOG_FATAL,
          "Expected config value enforce_root_files to be boolean\n");
    }
    *enforcing = ref.asBool();
  }

  ref = cfg_get_json("root_files");
  if (ref) {
    if (!is_array_of_strings(ref)) {
      w_log(W_LOG_FATAL,
          "global config root_files must be an array of strings\n");
      *enforcing = false;
      return nullptr;
    }
    prepend_watchmanconfig_to_array(ref);

    return ref;
  }

  // Try legacy root_restrict_files configuration
  ref = cfg_get_json("root_restrict_files");
  if (ref) {
    if (!is_array_of_strings(ref)) {
      w_log(W_LOG_FATAL, "deprecated global config root_restrict_files "
          "must be an array of strings\n");
      *enforcing = false;
      return nullptr;
    }
    prepend_watchmanconfig_to_array(ref);
    *enforcing = true;
    return ref;
  }

  // Synthesize our conservative default value.
  // .watchmanconfig MUST be first
  return json_array({typed_string_to_json(".watchmanconfig"),
                     typed_string_to_json(".hg"),
                     typed_string_to_json(".git"),
                     typed_string_to_json(".svn")});
}

// Produces a string like:  "`foo`, `bar`, and `baz`"
std::string cfg_pretty_print_root_files(const json_ref& root_files) {
  std::string result;
  for (unsigned int i = 0; i < root_files.array().size(); ++i) {
    const auto& r = root_files.array()[i];
    if (i > 1 && i == root_files.array().size() - 1) {
      // We are last in a list of multiple items
      result.append(", and ");
    } else if (i > 0) {
      result.append(", ");
    }
    result.append("`");
    result.append(json_string_value(r));
    result.append("`");
  }
  return result;
}

json_int_t cfg_get_int(const char* name, json_int_t defval) {
  auto val = cfg_get_json(name);

  if (val) {
    if (!val.isInt()) {
      w_log(W_LOG_FATAL, "Expected config value %s to be an integer\n", name);
    }
    return json_integer_value(val);
  }

  return defval;
}

bool cfg_get_bool(const char* name, bool defval) {
  auto val = cfg_get_json(name);

  if (val) {
    if (!val.isBool()) {
      w_log(W_LOG_FATAL, "Expected config value %s to be a boolean\n", name);
    }
    return val.asBool();
  }

  return defval;
}

double cfg_get_double(const char* name, double defval) {
  auto val = cfg_get_json(name);

  if (val) {
    if (!val.isNumber()) {
      w_log(W_LOG_FATAL, "Expected config value %s to be a number\n", name);
    }
    return json_real_value(val);
  }

  return defval;
}

#ifndef _WIN32
#define MAKE_GET_PERM(PROP, SUFFIX)                                 \
  static mode_t get_##PROP##_perm(                                  \
      const char* name,                                             \
      const json_ref& val,                                          \
      bool write_bits,                                              \
      bool execute_bits) {                                          \
    mode_t ret = 0;                                                 \
    auto perm = val.get_default(#PROP);                             \
    if (perm) {                                                     \
      if (!perm.isBool()) {                                         \
        w_log(                                                      \
            W_LOG_FATAL,                                            \
            "Expected config value %s." #PROP " to be a boolean\n", \
            name);                                                  \
      }                                                             \
      if (perm.asBool()) {                                          \
        ret |= S_IR##SUFFIX;                                        \
        if (write_bits) {                                           \
          ret |= S_IW##SUFFIX;                                      \
        }                                                           \
        if (execute_bits) {                                         \
          ret |= S_IX##SUFFIX;                                      \
        }                                                           \
      }                                                             \
    }                                                               \
    return ret;                                                     \
  }

MAKE_GET_PERM(group, GRP)
MAKE_GET_PERM(others, OTH)

/**
 * This function expects the config to be an object containing the keys 'group'
 * and 'others', each a bool.
 */
mode_t cfg_get_perms(const char* name, bool write_bits, bool execute_bits) {
  auto val = cfg_get_json(name);
  mode_t ret = S_IRUSR | S_IWUSR;
  if (execute_bits) {
    ret |= S_IXUSR;
  }

  if (val) {
    if (!val.isObject()) {
      w_log(W_LOG_FATAL, "Expected config value %s to be an object\n", name);
    }

    ret |= get_group_perm(name, val, write_bits, execute_bits);
    ret |= get_others_perm(name, val, write_bits, execute_bits);
  }

  return ret;
}
#endif

const char *cfg_get_trouble_url(void) {
  return cfg_get_string(
      "troubleshooting_url",
      "https://facebook.github.io/watchman/docs/troubleshooting.html");
}

Configuration::Configuration(const json_ref& local) : local_(local) {}

json_ref Configuration::get(const char* name) const {
  // Highest precedence: options set locally
  json_ref val;
  if (local_) {
    val = local_.get_default(name);
    if (val) {
      return val;
    }
  }
  auto state = configState.rlock();

  // then: command line arguments
  if (!val) {
    val = cfg_get_raw(name, &state->arg_cfg);
  }
  // then: global config options
  if (!val) {
    val = cfg_get_raw(name, &state->global_cfg);
  }
  return val;
}

const char* Configuration::getString(const char* name, const char* defval)
    const {
  auto val = get(name);

  if (val) {
    if (!val.isString()) {
      w_log(W_LOG_FATAL, "Expected config value %s to be a string\n", name);
    }
    return json_string_value(val);
  }

  return defval;
}

json_int_t Configuration::getInt(const char* name, json_int_t defval) const {
  auto val = get(name);

  if (val) {
    if (!val.isInt()) {
      w_log(W_LOG_FATAL, "Expected config value %s to be an integer\n", name);
    }
    return json_integer_value(val);
  }

  return defval;
}

bool Configuration::getBool(const char* name, bool defval) const {
  auto val = get(name);

  if (val) {
    if (!val.isBool()) {
      w_log(W_LOG_FATAL, "Expected config value %s to be a boolean\n", name);
    }
    return val.asBool();
  }

  return defval;
}

double Configuration::getDouble(const char* name, double defval) const {
  auto val = get(name);

  if (val) {
    if (!val.isNumber()) {
      w_log(W_LOG_FATAL, "Expected config value %s to be a number\n", name);
    }
    return json_real_value(val);
  }

  return defval;
}

/* vim:ts=2:sw=2:et:
 */
<commit_msg>Add more tests for facebook saved state<commit_after>/* Copyright 2012-present Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 */

#include "watchman.h"
#include <folly/Synchronized.h>

namespace {
struct config_state {
  json_ref global_cfg;
  w_string global_config_file_path;
  json_ref arg_cfg;
};
folly::Synchronized<config_state> configState;
}

/* Called during shutdown to free things so that we run cleanly
 * under valgrind */
void cfg_shutdown(void)
{
  auto state = configState.wlock();
  state->global_cfg.reset();
  state->arg_cfg.reset();
}

w_string cfg_get_global_config_file_path(void) {
  return configState.rlock()->global_config_file_path;
}

void cfg_load_global_config_file(void)
{
  json_error_t err;

  const char *cfg_file = getenv("WATCHMAN_CONFIG_FILE");
#ifdef WATCHMAN_CONFIG_FILE
  if (!cfg_file) {
    cfg_file = WATCHMAN_CONFIG_FILE;
  }
#endif
  if (!cfg_file || cfg_file[0] == '\0') {
    return;
  }

  if (!w_path_exists(cfg_file)) {
    return;
  }

  auto config = json_load_file(cfg_file, 0, &err);
  if (!config) {
    w_log(W_LOG_ERR, "failed to parse json from %s: %s\n",
          cfg_file, err.text);
    return;
  }

  auto lockedState = configState.wlock();
  lockedState->global_cfg = config;
  lockedState->global_config_file_path = cfg_file;
}

void cfg_set_arg(const char* name, const json_ref& val) {
  auto state = configState.wlock();
  if (!state->arg_cfg) {
    state->arg_cfg = json_object();
  }

  state->arg_cfg.set(name, json_ref(val));
}

void cfg_set_global(const char* name, const json_ref& val) {
  auto state = configState.wlock();
  if (!state->global_cfg) {
    state->global_cfg = json_object();
  }

  state->global_cfg.set(name, json_ref(val));
}

static json_ref cfg_get_raw(const char* name, const json_ref* optr) {
  json_ref val;

  if (*optr) {
    val = optr->get_default(name);
  }
  return val;
}

json_ref cfg_get_json(const char* name) {
  json_ref val;
  auto state = configState.rlock();

  // Highest precedence: command line arguments
  val = cfg_get_raw(name, &state->arg_cfg);
  // then: global config options
  if (!val) {
    val = cfg_get_raw(name, &state->global_cfg);
  }
  return val;
}

const char* cfg_get_string(const char* name, const char* defval) {
  auto val = cfg_get_json(name);

  if (val) {
    if (!val.isString()) {
      throw std::runtime_error(watchman::to<std::string>(
          "Expected config value ", name, " to be a string"));
    }
    return json_string_value(val);
  }

  return defval;
}

// Return true if the json ref is an array of string values
static bool is_array_of_strings(const json_ref& ref) {
  uint32_t i;

  if (!ref.isArray()) {
    return false;
  }

  for (i = 0; i < json_array_size(ref); i++) {
    if (!json_array_get(ref, i).isString()) {
      return false;
    }
  }
  return true;
}

// Given an array of string values, if that array does not contain
// a ".watchmanconfig" entry, prepend it
static void prepend_watchmanconfig_to_array(json_ref& ref) {
  const char *val;

  if (json_array_size(ref) == 0) {
    // json_array_insert_new at index can fail when the array is empty,
    // so just append in this case.
    json_array_append_new(ref, typed_string_to_json(".watchmanconfig",
          W_STRING_UNICODE));
    return;
  }

  val = json_string_value(json_array_get(ref, 0));
  if (!strcmp(val, ".watchmanconfig")) {
    return;
  }
  json_array_insert_new(ref, 0, typed_string_to_json(".watchmanconfig",
        W_STRING_UNICODE));
}

// Compute the effective value of the root_files configuration and
// return a json reference.  The caller must decref the ref when done
// (we may synthesize this value).   Sets enforcing to indicate whether
// we will only allow watches on the root_files.
// The array returned by this function (if not NULL) is guaranteed to
// list .watchmanconfig as its zeroth element.
json_ref cfg_compute_root_files(bool* enforcing) {
  *enforcing = false;

  json_ref ref = cfg_get_json("enforce_root_files");
  if (ref) {
    if (!ref.isBool()) {
      w_log(W_LOG_FATAL,
          "Expected config value enforce_root_files to be boolean\n");
    }
    *enforcing = ref.asBool();
  }

  ref = cfg_get_json("root_files");
  if (ref) {
    if (!is_array_of_strings(ref)) {
      w_log(W_LOG_FATAL,
          "global config root_files must be an array of strings\n");
      *enforcing = false;
      return nullptr;
    }
    prepend_watchmanconfig_to_array(ref);

    return ref;
  }

  // Try legacy root_restrict_files configuration
  ref = cfg_get_json("root_restrict_files");
  if (ref) {
    if (!is_array_of_strings(ref)) {
      w_log(W_LOG_FATAL, "deprecated global config root_restrict_files "
          "must be an array of strings\n");
      *enforcing = false;
      return nullptr;
    }
    prepend_watchmanconfig_to_array(ref);
    *enforcing = true;
    return ref;
  }

  // Synthesize our conservative default value.
  // .watchmanconfig MUST be first
  return json_array({typed_string_to_json(".watchmanconfig"),
                     typed_string_to_json(".hg"),
                     typed_string_to_json(".git"),
                     typed_string_to_json(".svn")});
}

// Produces a string like:  "`foo`, `bar`, and `baz`"
std::string cfg_pretty_print_root_files(const json_ref& root_files) {
  std::string result;
  for (unsigned int i = 0; i < root_files.array().size(); ++i) {
    const auto& r = root_files.array()[i];
    if (i > 1 && i == root_files.array().size() - 1) {
      // We are last in a list of multiple items
      result.append(", and ");
    } else if (i > 0) {
      result.append(", ");
    }
    result.append("`");
    result.append(json_string_value(r));
    result.append("`");
  }
  return result;
}

json_int_t cfg_get_int(const char* name, json_int_t defval) {
  auto val = cfg_get_json(name);

  if (val) {
    if (!val.isInt()) {
      throw std::runtime_error(watchman::to<std::string>(
          "Expected config value ", name, " to be an integer"));
    }
    return json_integer_value(val);
  }

  return defval;
}

bool cfg_get_bool(const char* name, bool defval) {
  auto val = cfg_get_json(name);

  if (val) {
    if (!val.isBool()) {
      throw std::runtime_error(watchman::to<std::string>(
          "Expected config value ", name, " to be a boolean"));
    }
    return val.asBool();
  }

  return defval;
}

double cfg_get_double(const char* name, double defval) {
  auto val = cfg_get_json(name);

  if (val) {
    if (!val.isNumber()) {
      throw std::runtime_error(watchman::to<std::string>(
          "Expected config value ", name, " to be a number"));
    }
    return json_real_value(val);
  }

  return defval;
}

#ifndef _WIN32
#define MAKE_GET_PERM(PROP, SUFFIX)                                 \
  static mode_t get_##PROP##_perm(                                  \
      const char* name,                                             \
      const json_ref& val,                                          \
      bool write_bits,                                              \
      bool execute_bits) {                                          \
    mode_t ret = 0;                                                 \
    auto perm = val.get_default(#PROP);                             \
    if (perm) {                                                     \
      if (!perm.isBool()) {                                         \
        w_log(                                                      \
            W_LOG_FATAL,                                            \
            "Expected config value %s." #PROP " to be a boolean\n", \
            name);                                                  \
      }                                                             \
      if (perm.asBool()) {                                          \
        ret |= S_IR##SUFFIX;                                        \
        if (write_bits) {                                           \
          ret |= S_IW##SUFFIX;                                      \
        }                                                           \
        if (execute_bits) {                                         \
          ret |= S_IX##SUFFIX;                                      \
        }                                                           \
      }                                                             \
    }                                                               \
    return ret;                                                     \
  }

MAKE_GET_PERM(group, GRP)
MAKE_GET_PERM(others, OTH)

/**
 * This function expects the config to be an object containing the keys 'group'
 * and 'others', each a bool.
 */
mode_t cfg_get_perms(const char* name, bool write_bits, bool execute_bits) {
  auto val = cfg_get_json(name);
  mode_t ret = S_IRUSR | S_IWUSR;
  if (execute_bits) {
    ret |= S_IXUSR;
  }

  if (val) {
    if (!val.isObject()) {
      w_log(W_LOG_FATAL, "Expected config value %s to be an object\n", name);
    }

    ret |= get_group_perm(name, val, write_bits, execute_bits);
    ret |= get_others_perm(name, val, write_bits, execute_bits);
  }

  return ret;
}
#endif

const char *cfg_get_trouble_url(void) {
  return cfg_get_string(
      "troubleshooting_url",
      "https://facebook.github.io/watchman/docs/troubleshooting.html");
}

Configuration::Configuration(const json_ref& local) : local_(local) {}

json_ref Configuration::get(const char* name) const {
  // Highest precedence: options set locally
  json_ref val;
  if (local_) {
    val = local_.get_default(name);
    if (val) {
      return val;
    }
  }
  auto state = configState.rlock();

  // then: command line arguments
  if (!val) {
    val = cfg_get_raw(name, &state->arg_cfg);
  }
  // then: global config options
  if (!val) {
    val = cfg_get_raw(name, &state->global_cfg);
  }
  return val;
}

const char* Configuration::getString(const char* name, const char* defval)
    const {
  auto val = get(name);

  if (val) {
    if (!val.isString()) {
      throw std::runtime_error(watchman::to<std::string>(
          "Expected config value ", name, " to be a string"));
    }
    return json_string_value(val);
  }

  return defval;
}

json_int_t Configuration::getInt(const char* name, json_int_t defval) const {
  auto val = get(name);

  if (val) {
    if (!val.isInt()) {
      throw std::runtime_error(watchman::to<std::string>(
          "Expected config value ", name, " to be an integer"));
    }
    return json_integer_value(val);
  }

  return defval;
}

bool Configuration::getBool(const char* name, bool defval) const {
  auto val = get(name);

  if (val) {
    if (!val.isBool()) {
      throw std::runtime_error(watchman::to<std::string>(
          "Expected config value ", name, " to be a boolean"));
    }
    return val.asBool();
  }

  return defval;
}

double Configuration::getDouble(const char* name, double defval) const {
  auto val = get(name);

  if (val) {
    if (!val.isNumber()) {
      throw std::runtime_error(watchman::to<std::string>(
          "Expected config value ", name, " to be a number"));
    }
    return json_real_value(val);
  }

  return defval;
}

/* vim:ts=2:sw=2:et:
 */
<|endoftext|>


<commit_before><commit_msg>coverity#1130385 Missing break in switch<commit_after><|endoftext|>


<commit_before>#include <cpp-pcp-client/connector/client_metadata.hpp>
#include <cpp-pcp-client/connector/errors.hpp>

#define LEATHERMAN_LOGGING_NAMESPACE CPP_PCP_CLIENT_LOGGING_PREFIX".client_metadata"

#include <leatherman/logging/logging.hpp>

#include <openssl/x509v3.h>
#include <openssl/ssl.h>

#include <stdio.h>  // std::fopen

namespace PCPClient {

// Get rid of OSX 10.7 and greater deprecation warnings.
#if defined(__APPLE__) && defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif

static const std::string PCP_URI_SCHEME { "pcp://" };

std::string getCommonNameFromCert(const std::string& client_crt_path) {
    LOG_INFO("Retrieving the common name from certificate %1%", client_crt_path);

    std::unique_ptr<std::FILE, int(*)(std::FILE*)> fp {
        std::fopen(client_crt_path.data(), "r"), std::fclose };

    if (fp == nullptr) {
        throw connection_config_error { "certificate file '" + client_crt_path
                                        + "' does not exist" };
    }

    std::unique_ptr<X509, void(*)(X509*)> cert {
        PEM_read_X509(fp.get(), NULL, NULL, NULL), X509_free };

    if (cert == nullptr) {
        throw connection_config_error { "certificate file '" + client_crt_path
                                        + "' is invalid" };
    }

    X509_NAME* subj = X509_get_subject_name(cert.get());
    X509_NAME_ENTRY* name_entry = X509_NAME_get_entry(subj, 0);

    if (name_entry == nullptr) {
        throw connection_config_error { "failed to retrieve the client common "
                                        "name from " + client_crt_path };
    }

    ASN1_STRING* asn1_name = X509_NAME_ENTRY_get_data(name_entry);
    unsigned char* name_ptr = ASN1_STRING_data(asn1_name);
    int name_size = ASN1_STRING_length(asn1_name);

    return std::string { name_ptr, name_ptr + name_size };
}

#if defined(__APPLE__) && defined(__clang__)
#pragma clang diagnostic pop
#endif

ClientMetadata::ClientMetadata(const std::string& _client_type,
                               const std::string& _ca,
                               const std::string& _crt,
                               const std::string& _key)
        : ca { _ca },
          crt { _crt },
          key { _key },
          client_type { _client_type },
          common_name { getCommonNameFromCert(crt) },
          uri { PCP_URI_SCHEME + common_name + "/" + client_type } {
    LOG_INFO("Retrieved common name from the certificate and determined "
             "the client URI: %1%", uri);
}

}  // namespace PCPClient
<commit_msg>CTH-247 use auto instead of X509_NAME<commit_after>#include <cpp-pcp-client/connector/client_metadata.hpp>
#include <cpp-pcp-client/connector/errors.hpp>

#define LEATHERMAN_LOGGING_NAMESPACE CPP_PCP_CLIENT_LOGGING_PREFIX".client_metadata"

#include <leatherman/logging/logging.hpp>

#include <openssl/x509v3.h>
#include <openssl/ssl.h>

#include <stdio.h>  // std::fopen

namespace PCPClient {

// Get rid of OSX 10.7 and greater deprecation warnings.
#if defined(__APPLE__) && defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif

static const std::string PCP_URI_SCHEME { "pcp://" };

std::string getCommonNameFromCert(const std::string& client_crt_path) {
    LOG_INFO("Retrieving the common name from certificate %1%", client_crt_path);

    std::unique_ptr<std::FILE, int(*)(std::FILE*)> fp {
        std::fopen(client_crt_path.data(), "r"), std::fclose };

    if (fp == nullptr) {
        throw connection_config_error { "certificate file '" + client_crt_path
                                        + "' does not exist" };
    }

    std::unique_ptr<X509, void(*)(X509*)> cert {
        PEM_read_X509(fp.get(), NULL, NULL, NULL), X509_free };

    if (cert == nullptr) {
        throw connection_config_error { "certificate file '" + client_crt_path
                                        + "' is invalid" };
    }

    auto subj = X509_get_subject_name(cert.get());
    auto name_entry = X509_NAME_get_entry(subj, 0);

    if (name_entry == nullptr) {
        throw connection_config_error { "failed to retrieve the client common "
                                        "name from " + client_crt_path };
    }

    ASN1_STRING* asn1_name = X509_NAME_ENTRY_get_data(name_entry);
    unsigned char* name_ptr = ASN1_STRING_data(asn1_name);
    int name_size = ASN1_STRING_length(asn1_name);

    return std::string { name_ptr, name_ptr + name_size };
}

#if defined(__APPLE__) && defined(__clang__)
#pragma clang diagnostic pop
#endif

ClientMetadata::ClientMetadata(const std::string& _client_type,
                               const std::string& _ca,
                               const std::string& _crt,
                               const std::string& _key)
        : ca { _ca },
          crt { _crt },
          key { _key },
          client_type { _client_type },
          common_name { getCommonNameFromCert(crt) },
          uri { PCP_URI_SCHEME + common_name + "/" + client_type } {
    LOG_INFO("Retrieved common name from the certificate and determined "
             "the client URI: %1%", uri);
}

}  // namespace PCPClient
<|endoftext|>


<commit_before>#include"../header/QCOstream.hpp"
#include<ostream>
#include<memory>
#include"../header/CQCircuit.hpp"
#include"../header/IQBit.hpp"
using namespace std;

namespace
{
	inline void print_space(ostream &os)
	{
		os<<"@";
	}

	inline void print_column(ostream &os)
	{
		os<<"x";
	}

	void print_IQBit_or_space(ostream &os,const unique_ptr<const nQCircuit::IQBit> &qbit)
	{
		if(qbit)
			os<<*qbit;
		else
			print_space(os);
	}

	inline void print_row(ostream &os)
	{
		os<<"w";
	}
}

namespace nQCircuit
{
	void print(ostream &os,const CQGate &gate)
	{
		print_IQBit_or_space(os,gate[0]);
		for(size_t i{1};i!=gate.gate_size();++i)
		{
			print_row(os);
			print_IQBit_or_space(os,gate[i]);
		}
		os<<endl;
	}

	void print(ostream &os,const CQCircuit &circuit)
	{
		if(circuit.size())
		{
			print(os,circuit[0]);
			for(size_t i{1};i!=circuit.size();++i)
			{
				print_column(os);
				for(size_t j{1};j!=circuit.gate_size();++j)
				{
					print_space(os);
					print_column(os);
				}
				os<<endl;
				print(os,circuit[i]);
			}
		}
	}

	void print_t(ostream &os,const CQGate &gate)
	{
		print_IQBit_or_space(os,gate[0]);
		for(size_t i{1};i!=gate.gate_size();++i)
		{
			os<<endl;
			print_column(os);
			os<<endl;
			print_IQBit_or_space(os,gate[i]);
		}
		os<<endl;
	}

	void print_t(ostream &os,const CQCircuit &circuit)
	{
		auto print_circuit_row{[&](ostream &os,const size_t i){
			print_IQBit_or_space(os,circuit[0][i]);
			for(size_t j{1};j!=circuit.size();++j)
			{
				print_row(os);
				print_IQBit_or_space(os,circuit[j][i]);
			}
			os<<endl;
		}};
		if(circuit.size())
		{
			print_circuit_row(os,0);
			for(size_t i{1};i!=circuit.gate_size();++i)
			{
				print_column(os);
				for(size_t j{1};j!=circuit.size();++j)
				{
					print_space(os);
					print_column(os);
				}
				os<<endl;
				print_circuit_row(os,i);
			}
		}
	}
}<commit_msg>use unicode<commit_after>#include"../header/QCOstream.hpp"
#include<ostream>
#include<memory>
#include"../header/CQCircuit.hpp"
#include"../header/IQBit.hpp"
using namespace std;

namespace
{
	inline void print_space(ostream &os)
	{
		os<<"\u3000";
	}

	inline void print_column(ostream &os)
	{
		os<<"\u2502";
	}

	void print_IQBit_or_space(ostream &os,const unique_ptr<const nQCircuit::IQBit> &qbit)
	{
		if(qbit)
			os<<*qbit;
		else
			print_space(os);
	}

	inline void print_row(ostream &os)
	{
		os<<"\u2500";
	}
}

namespace nQCircuit
{
	void print(ostream &os,const CQGate &gate)
	{
		print_IQBit_or_space(os,gate[0]);
		for(size_t i{1};i!=gate.gate_size();++i)
		{
			print_row(os);
			print_IQBit_or_space(os,gate[i]);
		}
		os<<endl;
	}

	void print(ostream &os,const CQCircuit &circuit)
	{
		if(circuit.size())
		{
			print(os,circuit[0]);
			for(size_t i{1};i!=circuit.size();++i)
			{
				print_column(os);
				for(size_t j{1};j!=circuit.gate_size();++j)
				{
					print_space(os);
					print_column(os);
				}
				os<<endl;
				print(os,circuit[i]);
			}
		}
	}

	void print_t(ostream &os,const CQGate &gate)
	{
		print_IQBit_or_space(os,gate[0]);
		for(size_t i{1};i!=gate.gate_size();++i)
		{
			os<<endl;
			print_column(os);
			os<<endl;
			print_IQBit_or_space(os,gate[i]);
		}
		os<<endl;
	}

	void print_t(ostream &os,const CQCircuit &circuit)
	{
		auto print_circuit_row{[&](ostream &os,const size_t i){
			print_IQBit_or_space(os,circuit[0][i]);
			for(size_t j{1};j!=circuit.size();++j)
			{
				print_row(os);
				print_IQBit_or_space(os,circuit[j][i]);
			}
			os<<endl;
		}};
		if(circuit.size())
		{
			print_circuit_row(os,0);
			for(size_t i{1};i!=circuit.gate_size();++i)
			{
				print_column(os);
				for(size_t j{1};j!=circuit.size();++j)
				{
					print_space(os);
					print_column(os);
				}
				os<<endl;
				print_circuit_row(os,i);
			}
		}
	}
}<|endoftext|>


<commit_before>//Copyright (C) 2013 David Braam
//Copyright (c) 2016 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include "SkirtBrim.h"
#include "support.h"

namespace cura
{

void SkirtBrim::getFirstLayerOutline(SliceDataStorage& storage, const unsigned int primary_line_count, const int primary_extruder_skirt_brim_line_width, const bool is_skirt, const bool outside_only, Polygons& first_layer_outline)
{
    bool external_only = is_skirt; // whether to include holes or not
    const int layer_nr = 0;
    if (is_skirt)
    {
        const bool include_helper_parts = true;
        first_layer_outline = storage.getLayerOutlines(layer_nr, include_helper_parts, external_only);
        first_layer_outline = first_layer_outline.approxConvexHull();
    }
    else
    { // add brim underneath support by removing support where there's brim around the model
        const bool include_helper_parts = false; // include manually below
        first_layer_outline = storage.getLayerOutlines(layer_nr, include_helper_parts, external_only);
        first_layer_outline = first_layer_outline.unionPolygons();
        Polygons first_layer_empty_holes;
        if (outside_only)
        {
            first_layer_empty_holes = first_layer_outline.getEmptyHoles();
            first_layer_outline = first_layer_outline.removeEmptyHoles();
        }
        if (storage.support.generated && primary_line_count > 0)
        { // remove model-brim from support
            // avoid gap in the middle
            //    V
            //  +---+     +----+
            //  |+-+|     |+--+|
            //  || ||     ||[]|| > expand to fit an extra brim line
            //  |+-+|     |+--+|
            //  +---+     +----+
            Polygons model_brim_covered_area = first_layer_outline.offset(primary_extruder_skirt_brim_line_width * (primary_line_count + primary_line_count % 2), ClipperLib::jtRound); // always leave a gap of an even number of brim lines, so that it fits if it's generating brim from both sides
            if (outside_only)
            { // don't remove support within empty holes where no brim is generated.
                model_brim_covered_area.add(first_layer_empty_holes);
            }
            SupportLayer& support_layer = storage.support.supportLayers[0];
            support_layer.supportAreas = support_layer.supportAreas.difference(model_brim_covered_area);
            first_layer_outline.add(support_layer.supportAreas);
            first_layer_outline.add(support_layer.skin);
        }
        if (storage.primeTower.enabled)
        {
            first_layer_outline.add(storage.primeTower.ground_poly); // don't remove parts of the prime tower, but make a brim for it
        }
    }
    constexpr int join_distance = 20;
    first_layer_outline = first_layer_outline.offset(join_distance).offset(-join_distance); // merge adjacent models into single polygon
    constexpr int smallest_line_length = 200;
    constexpr int largest_error_of_removed_point = 50;
    first_layer_outline.simplify(smallest_line_length, largest_error_of_removed_point); // simplify for faster processing of the brim lines
}

int SkirtBrim::generatePrimarySkirtBrimLines(SliceDataStorage& storage, int start_distance, unsigned int primary_line_count, const int primary_extruder_skirt_brim_line_width, const int64_t primary_extruder_minimal_length, const Polygons& first_layer_outline, Polygons& skirt_brim_primary_extruder)
{

    int offset_distance = start_distance - primary_extruder_skirt_brim_line_width / 2;
    for (unsigned int skirt_brim_number = 0; skirt_brim_number < primary_line_count; skirt_brim_number++)
    {
        offset_distance += primary_extruder_skirt_brim_line_width;

        Polygons outer_skirt_brim_line = first_layer_outline.offset(offset_distance, ClipperLib::jtRound);

        //Remove small inner skirt and brim holes. Holes have a negative area, remove anything smaller then 100x extrusion "area"
        for (unsigned int n = 0; n < outer_skirt_brim_line.size(); n++)
        {
            double area = outer_skirt_brim_line[n].area();
            if (area < 0 && area > -primary_extruder_skirt_brim_line_width * primary_extruder_skirt_brim_line_width * 100)
            {
                outer_skirt_brim_line.remove(n--);
            }
        }

        skirt_brim_primary_extruder.add(outer_skirt_brim_line);

        int length = skirt_brim_primary_extruder.polygonLength();
        if (skirt_brim_number + 1 >= primary_line_count && length > 0 && length < primary_extruder_minimal_length) //Make brim or skirt have more lines when total length is too small.
        {
            primary_line_count++;
        }
    }
    return offset_distance;
}

void SkirtBrim::generate(SliceDataStorage& storage, int start_distance, unsigned int primary_line_count, bool outside_only)
{
    const bool is_skirt = start_distance > 0;

    const int adhesion_extruder_nr = storage.getSettingAsIndex("adhesion_extruder_nr");
    const ExtruderTrain* adhesion_extruder = storage.meshgroup->getExtruderTrain(adhesion_extruder_nr);
    const int primary_extruder_skirt_brim_line_width = adhesion_extruder->getSettingInMicrons("skirt_brim_line_width");
    const int64_t primary_extruder_minimal_length = adhesion_extruder->getSettingInMicrons("skirt_brim_minimal_length");

    Polygons& skirt_brim_primary_extruder = storage.skirt_brim[adhesion_extruder_nr];

    Polygons first_layer_outline;
    getFirstLayerOutline(storage, primary_line_count, primary_extruder_skirt_brim_line_width, is_skirt, outside_only, first_layer_outline);

    const bool has_ooze_shield = storage.oozeShield.size() > 0 && storage.oozeShield[0].size() > 0;
    const bool has_draft_shield = storage.draft_protection_shield.size() > 0;

    if (is_skirt && (has_ooze_shield || has_draft_shield))
    { // make sure we don't generate skirt through draft / ooze shield
        first_layer_outline = first_layer_outline.offset(start_distance - primary_extruder_skirt_brim_line_width / 2, ClipperLib::jtRound).unionPolygons(storage.draft_protection_shield);
        if (has_ooze_shield)
        {
            first_layer_outline = first_layer_outline.unionPolygons(storage.oozeShield[0]);
        }
        first_layer_outline = first_layer_outline.approxConvexHull();
        start_distance = primary_extruder_skirt_brim_line_width / 2;
    }

    int offset_distance = generatePrimarySkirtBrimLines(storage, start_distance, primary_line_count, primary_extruder_skirt_brim_line_width, primary_extruder_minimal_length, first_layer_outline, skirt_brim_primary_extruder);

    // generate brim for ooze shield and draft shield
    if (!is_skirt && (has_ooze_shield || has_draft_shield))
    {
        // generate areas where to make extra brim for the shields
        // avoid gap in the middle
        //    V
        //  +---+     +----+
        //  |+-+|     |+--+|
        //  || ||     ||[]|| > expand to fit an extra brim line
        //  |+-+|     |+--+|
        //  +---+     +----+
        const int64_t primary_skirt_brim_width = (primary_line_count + primary_line_count % 2) * primary_extruder_skirt_brim_line_width; // always use an even number, because we will fil the area from both sides

        Polygons shield_brim;
        if (has_ooze_shield)
        {
            shield_brim = storage.oozeShield[0].difference(storage.oozeShield[0].offset(-primary_skirt_brim_width - primary_extruder_skirt_brim_line_width));
        }
        if (has_draft_shield)
        {
            shield_brim = shield_brim.unionPolygons(storage.draft_protection_shield.difference(storage.draft_protection_shield.offset(-primary_skirt_brim_width - primary_extruder_skirt_brim_line_width)));
        }
        const Polygons outer_primary_brim = first_layer_outline.offset(offset_distance, ClipperLib::jtRound);
        shield_brim = shield_brim.difference(outer_primary_brim.offset(primary_extruder_skirt_brim_line_width));

        // generate brim within shield_brim
        skirt_brim_primary_extruder.add(shield_brim);
        while (shield_brim.size() > 0)
        {
            shield_brim = shield_brim.offset(-primary_extruder_skirt_brim_line_width);
            skirt_brim_primary_extruder.add(shield_brim);
        }

        // update parameters to generate secondary skirt around
        first_layer_outline = outer_primary_brim;
        if (has_draft_shield)
        {
            first_layer_outline = first_layer_outline.unionPolygons(storage.draft_protection_shield);
        }
        if (has_ooze_shield)
        {
            first_layer_outline = first_layer_outline.unionPolygons(storage.oozeShield[0]);
        }

        offset_distance = 0;
    }

    { // process other extruders' brim/skirt (as one brim line around the old brim)
        int last_width = primary_extruder_skirt_brim_line_width;
        for (int extruder = 0; extruder < storage.meshgroup->getExtruderCount(); extruder++)
        {
            if (extruder == adhesion_extruder_nr || !storage.meshgroup->getExtruderTrain(extruder)->getIsUsed())
            {
                continue;
            }
            const ExtruderTrain* train = storage.meshgroup->getExtruderTrain(extruder);
            const int width = train->getSettingInMicrons("skirt_brim_line_width");
            const int64_t minimal_length = train->getSettingInMicrons("skirt_brim_minimal_length");
            offset_distance += last_width / 2 + width/2;
            last_width = width;
            while (storage.skirt_brim[extruder].polygonLength() < minimal_length)
            {
                storage.skirt_brim[extruder].add(first_layer_outline.offset(offset_distance, ClipperLib::jtRound));
                offset_distance += width;
            }
        }
    }
}

}//namespace cura
<commit_msg>Add documentation of why this union is necessary<commit_after>//Copyright (C) 2013 David Braam
//Copyright (c) 2016 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include "SkirtBrim.h"
#include "support.h"

namespace cura
{

void SkirtBrim::getFirstLayerOutline(SliceDataStorage& storage, const unsigned int primary_line_count, const int primary_extruder_skirt_brim_line_width, const bool is_skirt, const bool outside_only, Polygons& first_layer_outline)
{
    bool external_only = is_skirt; // whether to include holes or not
    const int layer_nr = 0;
    if (is_skirt)
    {
        const bool include_helper_parts = true;
        first_layer_outline = storage.getLayerOutlines(layer_nr, include_helper_parts, external_only);
        first_layer_outline = first_layer_outline.approxConvexHull();
    }
    else
    { // add brim underneath support by removing support where there's brim around the model
        const bool include_helper_parts = false; // include manually below
        first_layer_outline = storage.getLayerOutlines(layer_nr, include_helper_parts, external_only);
        first_layer_outline = first_layer_outline.unionPolygons(); //To guard against overlapping outlines, which would produce holes according to the even-odd rule.
        Polygons first_layer_empty_holes;
        if (outside_only)
        {
            first_layer_empty_holes = first_layer_outline.getEmptyHoles();
            first_layer_outline = first_layer_outline.removeEmptyHoles();
        }
        if (storage.support.generated && primary_line_count > 0)
        { // remove model-brim from support
            // avoid gap in the middle
            //    V
            //  +---+     +----+
            //  |+-+|     |+--+|
            //  || ||     ||[]|| > expand to fit an extra brim line
            //  |+-+|     |+--+|
            //  +---+     +----+
            Polygons model_brim_covered_area = first_layer_outline.offset(primary_extruder_skirt_brim_line_width * (primary_line_count + primary_line_count % 2), ClipperLib::jtRound); // always leave a gap of an even number of brim lines, so that it fits if it's generating brim from both sides
            if (outside_only)
            { // don't remove support within empty holes where no brim is generated.
                model_brim_covered_area.add(first_layer_empty_holes);
            }
            SupportLayer& support_layer = storage.support.supportLayers[0];
            support_layer.supportAreas = support_layer.supportAreas.difference(model_brim_covered_area);
            first_layer_outline.add(support_layer.supportAreas);
            first_layer_outline.add(support_layer.skin);
        }
        if (storage.primeTower.enabled)
        {
            first_layer_outline.add(storage.primeTower.ground_poly); // don't remove parts of the prime tower, but make a brim for it
        }
    }
    constexpr int join_distance = 20;
    first_layer_outline = first_layer_outline.offset(join_distance).offset(-join_distance); // merge adjacent models into single polygon
    constexpr int smallest_line_length = 200;
    constexpr int largest_error_of_removed_point = 50;
    first_layer_outline.simplify(smallest_line_length, largest_error_of_removed_point); // simplify for faster processing of the brim lines
}

int SkirtBrim::generatePrimarySkirtBrimLines(SliceDataStorage& storage, int start_distance, unsigned int primary_line_count, const int primary_extruder_skirt_brim_line_width, const int64_t primary_extruder_minimal_length, const Polygons& first_layer_outline, Polygons& skirt_brim_primary_extruder)
{

    int offset_distance = start_distance - primary_extruder_skirt_brim_line_width / 2;
    for (unsigned int skirt_brim_number = 0; skirt_brim_number < primary_line_count; skirt_brim_number++)
    {
        offset_distance += primary_extruder_skirt_brim_line_width;

        Polygons outer_skirt_brim_line = first_layer_outline.offset(offset_distance, ClipperLib::jtRound);

        //Remove small inner skirt and brim holes. Holes have a negative area, remove anything smaller then 100x extrusion "area"
        for (unsigned int n = 0; n < outer_skirt_brim_line.size(); n++)
        {
            double area = outer_skirt_brim_line[n].area();
            if (area < 0 && area > -primary_extruder_skirt_brim_line_width * primary_extruder_skirt_brim_line_width * 100)
            {
                outer_skirt_brim_line.remove(n--);
            }
        }

        skirt_brim_primary_extruder.add(outer_skirt_brim_line);

        int length = skirt_brim_primary_extruder.polygonLength();
        if (skirt_brim_number + 1 >= primary_line_count && length > 0 && length < primary_extruder_minimal_length) //Make brim or skirt have more lines when total length is too small.
        {
            primary_line_count++;
        }
    }
    return offset_distance;
}

void SkirtBrim::generate(SliceDataStorage& storage, int start_distance, unsigned int primary_line_count, bool outside_only)
{
    const bool is_skirt = start_distance > 0;

    const int adhesion_extruder_nr = storage.getSettingAsIndex("adhesion_extruder_nr");
    const ExtruderTrain* adhesion_extruder = storage.meshgroup->getExtruderTrain(adhesion_extruder_nr);
    const int primary_extruder_skirt_brim_line_width = adhesion_extruder->getSettingInMicrons("skirt_brim_line_width");
    const int64_t primary_extruder_minimal_length = adhesion_extruder->getSettingInMicrons("skirt_brim_minimal_length");

    Polygons& skirt_brim_primary_extruder = storage.skirt_brim[adhesion_extruder_nr];

    Polygons first_layer_outline;
    getFirstLayerOutline(storage, primary_line_count, primary_extruder_skirt_brim_line_width, is_skirt, outside_only, first_layer_outline);

    const bool has_ooze_shield = storage.oozeShield.size() > 0 && storage.oozeShield[0].size() > 0;
    const bool has_draft_shield = storage.draft_protection_shield.size() > 0;

    if (is_skirt && (has_ooze_shield || has_draft_shield))
    { // make sure we don't generate skirt through draft / ooze shield
        first_layer_outline = first_layer_outline.offset(start_distance - primary_extruder_skirt_brim_line_width / 2, ClipperLib::jtRound).unionPolygons(storage.draft_protection_shield);
        if (has_ooze_shield)
        {
            first_layer_outline = first_layer_outline.unionPolygons(storage.oozeShield[0]);
        }
        first_layer_outline = first_layer_outline.approxConvexHull();
        start_distance = primary_extruder_skirt_brim_line_width / 2;
    }

    int offset_distance = generatePrimarySkirtBrimLines(storage, start_distance, primary_line_count, primary_extruder_skirt_brim_line_width, primary_extruder_minimal_length, first_layer_outline, skirt_brim_primary_extruder);

    // generate brim for ooze shield and draft shield
    if (!is_skirt && (has_ooze_shield || has_draft_shield))
    {
        // generate areas where to make extra brim for the shields
        // avoid gap in the middle
        //    V
        //  +---+     +----+
        //  |+-+|     |+--+|
        //  || ||     ||[]|| > expand to fit an extra brim line
        //  |+-+|     |+--+|
        //  +---+     +----+
        const int64_t primary_skirt_brim_width = (primary_line_count + primary_line_count % 2) * primary_extruder_skirt_brim_line_width; // always use an even number, because we will fil the area from both sides

        Polygons shield_brim;
        if (has_ooze_shield)
        {
            shield_brim = storage.oozeShield[0].difference(storage.oozeShield[0].offset(-primary_skirt_brim_width - primary_extruder_skirt_brim_line_width));
        }
        if (has_draft_shield)
        {
            shield_brim = shield_brim.unionPolygons(storage.draft_protection_shield.difference(storage.draft_protection_shield.offset(-primary_skirt_brim_width - primary_extruder_skirt_brim_line_width)));
        }
        const Polygons outer_primary_brim = first_layer_outline.offset(offset_distance, ClipperLib::jtRound);
        shield_brim = shield_brim.difference(outer_primary_brim.offset(primary_extruder_skirt_brim_line_width));

        // generate brim within shield_brim
        skirt_brim_primary_extruder.add(shield_brim);
        while (shield_brim.size() > 0)
        {
            shield_brim = shield_brim.offset(-primary_extruder_skirt_brim_line_width);
            skirt_brim_primary_extruder.add(shield_brim);
        }

        // update parameters to generate secondary skirt around
        first_layer_outline = outer_primary_brim;
        if (has_draft_shield)
        {
            first_layer_outline = first_layer_outline.unionPolygons(storage.draft_protection_shield);
        }
        if (has_ooze_shield)
        {
            first_layer_outline = first_layer_outline.unionPolygons(storage.oozeShield[0]);
        }

        offset_distance = 0;
    }

    { // process other extruders' brim/skirt (as one brim line around the old brim)
        int last_width = primary_extruder_skirt_brim_line_width;
        for (int extruder = 0; extruder < storage.meshgroup->getExtruderCount(); extruder++)
        {
            if (extruder == adhesion_extruder_nr || !storage.meshgroup->getExtruderTrain(extruder)->getIsUsed())
            {
                continue;
            }
            const ExtruderTrain* train = storage.meshgroup->getExtruderTrain(extruder);
            const int width = train->getSettingInMicrons("skirt_brim_line_width");
            const int64_t minimal_length = train->getSettingInMicrons("skirt_brim_minimal_length");
            offset_distance += last_width / 2 + width/2;
            last_width = width;
            while (storage.skirt_brim[extruder].polygonLength() < minimal_length)
            {
                storage.skirt_brim[extruder].add(first_layer_outline.offset(offset_distance, ClipperLib::jtRound));
                offset_distance += width;
            }
        }
    }
}

}//namespace cura
<|endoftext|>