<commit_before>#include "gorgone.h"
using namespace cv;
using namespace ofxCv;
int accum = 0;

void gorgone::setup()
{
  ofSetLogLevel(OF_LOG_NOTICE);
  masterIp = "Mac-Pro-de-10-52.local";
  appName = "gorgone-1";
  parseCmdLineOptions();
  vidGrabber.setup(filename);
  svgInterp.setup();
  jamoma.setup((void*) this, appName, masterIp);
  motionDetector.setup(&jamoma);
  irisDetector.setJamomaRef(&jamoma);
  counter = 0;
}

void gorgone::exit(){
  setPwm(0);
#ifdef TARGET_RASPBERRY_PI
  vidGrabber.led.switchOffIR();
#endif
}

void gorgone::update()
{
  ofLogVerbose("gorgone") << ofGetFrameRate() << " fps" << endl;

  vidGrabber.update();

  if ( vidGrabber.isFrameNew() ){
    frame = vidGrabber.getFrame();

    if ( bMotion ){
      motionDetector.update(frame);
    }

    if( bTracking ){

      if ( frame.cols == 0 ) return;

      cv::Mat gray;
      if ( frame.channels() == 1 ){
        gray = frame.clone();
      } else {
        cv::cvtColor(frame, gray, CV_RGB2GRAY);
      }

      ofLogVerbose("gorgone") << "new frame to process : " << gray.cols << "x" << gray.rows << endl;

      irisDetector.updateBool(gray);
    }
  }

  Mat img = irisDetector.getIrisCode();
  if( irisDetector.newCode ) {
    bComputeCode=false;
    jamoma.mComputeIrisCodeParameter.set("value", bComputeCode);

    svgInterp.coeff.clear();
    ofLogNotice("gorgone") << "code image resolution : " << img.cols << "x" << img.rows << endl;
    uchar* p;
    for (int i = 0; i < img.rows; i++ ){
      float avg=0;
      p=img.ptr<uchar>(i);
      for (int j = 0; j < img.cols; j++ ){
        avg+=p[j] / 255.;
      }
      avg/=img.cols;
      svgInterp.coeff.push_back(avg);
    }
    irisDetector.newCode = false;

    TTValue v, w;
    for (int i = 0; i<svgInterp.coeff.size(); i++){
      v.push_back(svgInterp.coeff[i]);
    }
    jamoma.mTrackingIrisCodeReturn.set("value", v);

    w.push_back(irisDetector.blobArea);
    jamoma.mTrackingIrisBlobAreaReturn.set("value",w);
  }

  if (bComputeCode && !irisDetector.isThreadRunning() ) {
    irisDetector.start();
  }
}

void gorgone::draw()
{
  //vidGrabber.draw(0,0);
  drawMat(frame,0,0);
  if ( svgInterp.updateBool() ){
    TTValue x,y;
    ofPolyline line = svgInterp.interpolatedLine;
    // ofLogNotice("gorgone") << "update drawing with " << line.size() << "points" << endl;
    for (int i=0; i<line.size(); i++){
      x.push_back(line[i].x);
      y.push_back(line[i].y);
    }

    jamoma.mDrawingShapeXReturn.set("value", x);
    jamoma.mDrawingShapeYReturn.set("value", y);
  }
  if ( bTracking ) {
    ofDrawBitmapStringHighlight("eye tracking", 10, 400);
    irisDetector.drawEyes();
  }
  if ( bDisplaying ) {
    ofDrawBitmapStringHighlight("laser drawing", 200, 400);
    svgInterp.draw();
  }
  if ( bMotion ){
    ofDrawBitmapStringHighlight("motion detection", 400, 400);
  }
}

void gorgone::keyPressed(int key)
{
  ofLogVerbose("gorgone") << "keypressed : " << key << endl;
  switch (key){
    case 's':
      irisDetector.save();
      break;
    case ' ':
      irisDetector.reset();
      break;
    case 'c':
      bComputeCode=true;
      break;
    case 'm':
      bMotion = !bMotion;
      break;
    case 't':
      bTracking = !bTracking;
      if ( bTracking ) irisDetector.reset();
#ifdef TARGET_RASPBERRY_PI
      if ( bTracking ) vidGrabber.led.switchOnIR();
      else vidGrabber.led.switchOffIR();
#endif
      break;
    case 'd':
      bDisplaying = !bDisplaying;
      break;
#ifdef TARGET_RASPBERRY_PI
    case 'i':
      vidGrabber.led.switchOnIR();
      break;
    case 'o':
      vidGrabber.led.switchOffIR();
      break;
    case 'w':
      vidGrabber.led.switchOnWhite();
      break;
    case 'x':
      vidGrabber.led.switchOffWhite();
      break;
#endif
    case 357 : // arrow up
      svgInterp.selectedId = counter++;
      break;
    case 359: // arrow down
      svgInterp.selectedId = counter--;
      break;
    default :
      break;
  }
}

void gorgone::messageReceived(ofMessage& message)
{
}

void gorgone::parseCmdLineOptions(){
  vector<string> keys = ofxArgParser::allKeys();
  for (int i = 0; i < keys.size(); i++) {
    if ( keys[i] == "f" )   filename   = ofxArgParser::getValue(keys[i]);
    else if ( keys[i] == "name" ) appName =  ofxArgParser::getValue(keys[i]);
    else if ( keys[i] == "masterIp" ) masterIp =  ofxArgParser::getValue(keys[i]);
    else if ( keys[i] == "verbose" ) { // vebose level, value : 0..5, default 1 (OF_LOG_NOTICE)
      int logLevel;
      istringstream( ofxArgParser::getValue(keys[i]) ) >> logLevel;
      ofSetLogLevel((ofLogLevel) logLevel);
    }

    ofLogNotice("gorgone") << "key: " << keys[i] << ", value: " << ofxArgParser::getValue(keys[i]) << endl;
  }
}

void gorgone::setPwm(float pc){
#ifdef TARGET_RASPBERRY_PI
  ofstream file;
  file.open("/dev/servoblaster", ios::in);
  file << "0=" << pc << "%" << endl;
  file.close();
#endif
}
<commit_msg>reduce irisCode size<commit_after>#include "gorgone.h"
using namespace cv;
using namespace ofxCv;
int accum = 0;

void gorgone::setup()
{
  ofSetLogLevel(OF_LOG_NOTICE);
  masterIp = "Mac-Pro-de-10-52.local";
  appName = "gorgone-1";
  parseCmdLineOptions();
  vidGrabber.setup(filename);
  svgInterp.setup();
  jamoma.setup((void*) this, appName, masterIp);
  motionDetector.setup(&jamoma);
  irisDetector.setJamomaRef(&jamoma);
  counter = 0;
}

void gorgone::exit(){
  setPwm(0);
#ifdef TARGET_RASPBERRY_PI
  vidGrabber.led.switchOffIR();
#endif
}

void gorgone::update()
{
  ofLogVerbose("gorgone") << ofGetFrameRate() << " fps" << endl;

  vidGrabber.update();

  if ( vidGrabber.isFrameNew() ){
    frame = vidGrabber.getFrame();

    if ( bMotion ){
      motionDetector.update(frame);
    }

    if( bTracking ){

      if ( frame.cols == 0 ) return;

      cv::Mat gray;
      if ( frame.channels() == 1 ){
        gray = frame.clone();
      } else {
        cv::cvtColor(frame, gray, CV_RGB2GRAY);
      }

      ofLogVerbose("gorgone") << "new frame to process : " << gray.cols << "x" << gray.rows << endl;

      irisDetector.updateBool(gray);
    }
  }

  Mat tmp = irisDetector.getIrisCode();
  Mat img;
  resize(tmp, img, Size(tmp.cols, tmp.rows/4.));
  if( irisDetector.newCode ) {
    bComputeCode=false;
    jamoma.mComputeIrisCodeParameter.set("value", bComputeCode);

    svgInterp.coeff.clear();
    ofLogNotice("gorgone") << "code image resolution : " << img.cols << "x" << img.rows << endl;
    uchar* p;
    for (int i = 0; i < img.rows; i++ ){
      float avg=0;
      p=img.ptr<uchar>(i);
      for (int j = 0; j < img.cols; j++ ){
        avg+=p[j] / 255.;
      }
      avg/=img.cols;
      svgInterp.coeff.push_back(avg);
    }
    irisDetector.newCode = false;

    TTValue v, w;
    for (int i = 0; i<svgInterp.coeff.size(); i++){
      v.push_back(svgInterp.coeff[i]);
    }
    jamoma.mTrackingIrisCodeReturn.set("value", v);

    w.push_back(irisDetector.blobArea);
    jamoma.mTrackingIrisBlobAreaReturn.set("value",w);
  }

  if (bComputeCode && !irisDetector.isThreadRunning() ) {
    irisDetector.start();
  }
}

void gorgone::draw()
{
  //vidGrabber.draw(0,0);
  drawMat(frame,0,0);
  if ( svgInterp.updateBool() ){
    TTValue x,y;
    ofPolyline line = svgInterp.interpolatedLine;
    // ofLogNotice("gorgone") << "update drawing with " << line.size() << "points" << endl;
    for (int i=0; i<line.size(); i++){
      x.push_back(line[i].x);
      y.push_back(line[i].y);
    }

    jamoma.mDrawingShapeXReturn.set("value", x);
    jamoma.mDrawingShapeYReturn.set("value", y);
  }
  if ( bTracking ) {
    ofDrawBitmapStringHighlight("eye tracking", 10, 400);
    irisDetector.drawEyes();
  }
  if ( bDisplaying ) {
    ofDrawBitmapStringHighlight("laser drawing", 200, 400);
    svgInterp.draw();
  }
  if ( bMotion ){
    ofDrawBitmapStringHighlight("motion detection", 400, 400);
  }
}

void gorgone::keyPressed(int key)
{
  ofLogVerbose("gorgone") << "keypressed : " << key << endl;
  switch (key){
    case 's':
      irisDetector.save();
      break;
    case ' ':
      irisDetector.reset();
      break;
    case 'c':
      bComputeCode=true;
      break;
    case 'm':
      bMotion = !bMotion;
      break;
    case 't':
      bTracking = !bTracking;
      if ( bTracking ) irisDetector.reset();
#ifdef TARGET_RASPBERRY_PI
      if ( bTracking ) vidGrabber.led.switchOnIR();
      else vidGrabber.led.switchOffIR();
#endif
      break;
    case 'd':
      bDisplaying = !bDisplaying;
      break;
#ifdef TARGET_RASPBERRY_PI
    case 'i':
      vidGrabber.led.switchOnIR();
      break;
    case 'o':
      vidGrabber.led.switchOffIR();
      break;
    case 'w':
      vidGrabber.led.switchOnWhite();
      break;
    case 'x':
      vidGrabber.led.switchOffWhite();
      break;
#endif
    case 357 : // arrow up
      svgInterp.selectedId = counter++;
      break;
    case 359: // arrow down
      svgInterp.selectedId = counter--;
      break;
    default :
      break;
  }
}

void gorgone::messageReceived(ofMessage& message)
{
}

void gorgone::parseCmdLineOptions(){
  vector<string> keys = ofxArgParser::allKeys();
  for (int i = 0; i < keys.size(); i++) {
    if ( keys[i] == "f" )   filename   = ofxArgParser::getValue(keys[i]);
    else if ( keys[i] == "name" ) appName =  ofxArgParser::getValue(keys[i]);
    else if ( keys[i] == "masterIp" ) masterIp =  ofxArgParser::getValue(keys[i]);
    else if ( keys[i] == "verbose" ) { // vebose level, value : 0..5, default 1 (OF_LOG_NOTICE)
      int logLevel;
      istringstream( ofxArgParser::getValue(keys[i]) ) >> logLevel;
      ofSetLogLevel((ofLogLevel) logLevel);
    }

    ofLogNotice("gorgone") << "key: " << keys[i] << ", value: " << ofxArgParser::getValue(keys[i]) << endl;
  }
}

void gorgone::setPwm(float pc){
#ifdef TARGET_RASPBERRY_PI
  ofstream file;
  file.open("/dev/servoblaster", ios::in);
  file << "0=" << pc << "%" << endl;
  file.close();
#endif
}
<|endoftext|>


<commit_before>//===---- IncludeInserterTest.cpp - clang-tidy ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "../clang-tidy/IncludeInserter.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "ClangTidyTest.h"
#include "gtest/gtest.h"

namespace clang {
namespace tidy {
namespace {

class IncludeInserterCheckBase : public ClangTidyCheck {
public:
  using ClangTidyCheck::ClangTidyCheck;
  void registerPPCallbacks(CompilerInstance &Compiler) override {
    Inserter.reset(new IncludeInserter(Compiler.getSourceManager(),
                                       Compiler.getLangOpts(),
                                       IncludeSorter::IS_Google));
    Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
  }

  void registerMatchers(ast_matchers::MatchFinder *Finder) override {
    Finder->addMatcher(ast_matchers::declStmt().bind("stmt"), this);
  }

  void check(const ast_matchers::MatchFinder::MatchResult &Result) override {
    auto Fixit =
        Inserter->CreateIncludeInsertion(Result.SourceManager->getMainFileID(),
                                         HeaderToInclude(), IsAngledInclude());
    if (Fixit) {
      diag(Result.Nodes.getStmtAs<DeclStmt>("stmt")->getLocStart(), "foo, bar")
          << *Fixit;
    }
    // Second include should yield no Fixit.
    Fixit =
        Inserter->CreateIncludeInsertion(Result.SourceManager->getMainFileID(),
                                         HeaderToInclude(), IsAngledInclude());
    EXPECT_FALSE(Fixit);
  }

  virtual StringRef HeaderToInclude() const = 0;
  virtual bool IsAngledInclude() const = 0;

  std::unique_ptr<IncludeInserter> Inserter;
};

class NonSystemHeaderInserterCheck : public IncludeInserterCheckBase {
public:
  using IncludeInserterCheckBase::IncludeInserterCheckBase;
  StringRef HeaderToInclude() const override { return "path/to/header.h"; }
  bool IsAngledInclude() const override { return false; }
};

class CXXSystemIncludeInserterCheck : public IncludeInserterCheckBase {
public:
  using IncludeInserterCheckBase::IncludeInserterCheckBase;
  StringRef HeaderToInclude() const override { return "set"; }
  bool IsAngledInclude() const override { return true; }
};

template <typename Check>
std::string runCheckOnCode(StringRef Code, StringRef Filename,
                           size_t NumWarningsExpected) {
  std::vector<ClangTidyError> Errors;
  return test::runCheckOnCode<Check>(Code, &Errors, Filename, None,
                                     ClangTidyOptions(),
                                     {// Main file include
                                      {"devtools/cymbal/clang_tidy/tests/"
                                       "insert_includes_test_header.h",
                                       "\n"},
                                      // Non system headers
                                      {"path/to/a/header.h", "\n"},
                                      {"path/to/z/header.h", "\n"},
                                      {"path/to/header.h", "\n"},
                                      // Fake system headers.
                                      {"stdlib.h", "\n"},
                                      {"unistd.h", "\n"},
                                      {"list", "\n"},
                                      {"map", "\n"},
                                      {"set", "\n"},
                                      {"vector", "\n"}});
  EXPECT_EQ(NumWarningsExpected, Errors.size());
}

TEST(IncludeInserterTest, InsertAfterLastNonSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"
#include "path/to/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_input2.cc",
                          1));
}

TEST(IncludeInserterTest, InsertBeforeFirstNonSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/z/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/header.h"
#include "path/to/z/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_input2.cc",
                          1));
}

TEST(IncludeInserterTest, InsertBetweenNonSystemIncludes) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"
#include "path/to/z/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"
#include "path/to/header.h"
#include "path/to/z/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_input2.cc",
                          1));
}

TEST(IncludeInserterTest, NonSystemIncludeAlreadyIncluded) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"
#include "path/to/header.h"
#include "path/to/z/header.h"

void foo() {
  int a = 0;
})";
  EXPECT_EQ(PreCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                         PreCode, "devtools/cymbal/clang_tidy/tests/"
                                  "insert_includes_test_input2.cc",
                         0));
}

TEST(IncludeInserterTest, InsertNonSystemIncludeAfterLastCXXSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertNonSystemIncludeAfterMainFileInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include "path/to/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertCXXSystemIncludeAfterLastCXXSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>
#include <set>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertCXXSystemIncludeBeforeFirstCXXSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <vector>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <set>
#include <vector>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertCXXSystemIncludeBetweenCXXSystemIncludes) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <map>
#include <vector>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <map>
#include <set>
#include <vector>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertCXXSystemIncludeAfterMainFileInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <set>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertCXXSystemIncludeAfterCSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <stdlib.h>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <stdlib.h>

#include <set>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

} // namespace
} // namespace tidy
} // namespace clang
<commit_msg>Do not use inheriting constructors.<commit_after>//===---- IncludeInserterTest.cpp - clang-tidy ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "../clang-tidy/IncludeInserter.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "ClangTidyTest.h"
#include "gtest/gtest.h"

namespace clang {
namespace tidy {
namespace {

class IncludeInserterCheckBase : public ClangTidyCheck {
public:
  IncludeInserterCheckBase(StringRef CheckName, ClangTidyContext *Context)
      : ClangTidyCheck(CheckName, Context) {}
  void registerPPCallbacks(CompilerInstance &Compiler) override {
    Inserter.reset(new IncludeInserter(Compiler.getSourceManager(),
                                       Compiler.getLangOpts(),
                                       IncludeSorter::IS_Google));
    Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
  }

  void registerMatchers(ast_matchers::MatchFinder *Finder) override {
    Finder->addMatcher(ast_matchers::declStmt().bind("stmt"), this);
  }

  void check(const ast_matchers::MatchFinder::MatchResult &Result) override {
    auto Fixit =
        Inserter->CreateIncludeInsertion(Result.SourceManager->getMainFileID(),
                                         HeaderToInclude(), IsAngledInclude());
    if (Fixit) {
      diag(Result.Nodes.getStmtAs<DeclStmt>("stmt")->getLocStart(), "foo, bar")
          << *Fixit;
    }
    // Second include should yield no Fixit.
    Fixit =
        Inserter->CreateIncludeInsertion(Result.SourceManager->getMainFileID(),
                                         HeaderToInclude(), IsAngledInclude());
    EXPECT_FALSE(Fixit);
  }

  virtual StringRef HeaderToInclude() const = 0;
  virtual bool IsAngledInclude() const = 0;

  std::unique_ptr<IncludeInserter> Inserter;
};

class NonSystemHeaderInserterCheck : public IncludeInserterCheckBase {
public:
  NonSystemHeaderInserterCheck(StringRef CheckName, ClangTidyContext *Context)
      : IncludeInserterCheckBase(CheckName, Context) {}
  StringRef HeaderToInclude() const override { return "path/to/header.h"; }
  bool IsAngledInclude() const override { return false; }
};

class CXXSystemIncludeInserterCheck : public IncludeInserterCheckBase {
public:
  CXXSystemIncludeInserterCheck(StringRef CheckName, ClangTidyContext *Context)
      : IncludeInserterCheckBase(CheckName, Context) {}
  StringRef HeaderToInclude() const override { return "set"; }
  bool IsAngledInclude() const override { return true; }
};

template <typename Check>
std::string runCheckOnCode(StringRef Code, StringRef Filename,
                           size_t NumWarningsExpected) {
  std::vector<ClangTidyError> Errors;
  return test::runCheckOnCode<Check>(Code, &Errors, Filename, None,
                                     ClangTidyOptions(),
                                     {// Main file include
                                      {"devtools/cymbal/clang_tidy/tests/"
                                       "insert_includes_test_header.h",
                                       "\n"},
                                      // Non system headers
                                      {"path/to/a/header.h", "\n"},
                                      {"path/to/z/header.h", "\n"},
                                      {"path/to/header.h", "\n"},
                                      // Fake system headers.
                                      {"stdlib.h", "\n"},
                                      {"unistd.h", "\n"},
                                      {"list", "\n"},
                                      {"map", "\n"},
                                      {"set", "\n"},
                                      {"vector", "\n"}});
  EXPECT_EQ(NumWarningsExpected, Errors.size());
}

TEST(IncludeInserterTest, InsertAfterLastNonSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"
#include "path/to/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_input2.cc",
                          1));
}

TEST(IncludeInserterTest, InsertBeforeFirstNonSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/z/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/header.h"
#include "path/to/z/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_input2.cc",
                          1));
}

TEST(IncludeInserterTest, InsertBetweenNonSystemIncludes) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"
#include "path/to/z/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"
#include "path/to/header.h"
#include "path/to/z/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_input2.cc",
                          1));
}

TEST(IncludeInserterTest, NonSystemIncludeAlreadyIncluded) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"
#include "path/to/header.h"
#include "path/to/z/header.h"

void foo() {
  int a = 0;
})";
  EXPECT_EQ(PreCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                         PreCode, "devtools/cymbal/clang_tidy/tests/"
                                  "insert_includes_test_input2.cc",
                         0));
}

TEST(IncludeInserterTest, InsertNonSystemIncludeAfterLastCXXSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertNonSystemIncludeAfterMainFileInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include "path/to/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<NonSystemHeaderInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertCXXSystemIncludeAfterLastCXXSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <list>
#include <map>
#include <set>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertCXXSystemIncludeBeforeFirstCXXSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <vector>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <set>
#include <vector>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertCXXSystemIncludeBetweenCXXSystemIncludes) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <map>
#include <vector>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <map>
#include <set>
#include <vector>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertCXXSystemIncludeAfterMainFileInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <set>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

TEST(IncludeInserterTest, InsertCXXSystemIncludeAfterCSystemInclude) {
  const char *PreCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <stdlib.h>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";
  const char *PostCode = R"(
#include "devtools/cymbal/clang_tidy/tests/insert_includes_test_header.h"

#include <stdlib.h>

#include <set>

#include "path/to/a/header.h"

void foo() {
  int a = 0;
})";

  EXPECT_EQ(PostCode, runCheckOnCode<CXXSystemIncludeInserterCheck>(
                          PreCode, "devtools/cymbal/clang_tidy/tests/"
                                   "insert_includes_test_header.cc",
                          1));
}

} // namespace
} // namespace tidy
} // namespace clang
<|endoftext|>


<commit_before>#include <arpc.h>

#include <modlogger.h>
#include <misc_utils.h>

#include <dhash_types.h>
#include <dhash_common.h>
#include <merkle_sync_prot.h>

#include <merkle.h>

#include <maint_prot.h>
#include "maint_policy.h"

// {{{ Globals
static char *logfname;
static char *localdatapath;

static vec<ptr<maintainer> > maintainers;

enum maint_mode_t {
  MAINT_CARBONITE,
  MAINT_PASSINGTONE,
} maint_mode;
struct maint_mode_desc {
  maint_mode_t m;
  char *cmdline;
  maintainer_producer_t producer;
} maint_modes[] = {
  { MAINT_CARBONITE, "carbonite",
    wrap (carbonite::produce_maintainer) },
  { MAINT_PASSINGTONE, "passingtone",
    wrap (passingtone::produce_maintainer) }
};

enum sync_mode_t {
  SYNC_MERKLE,
  SYNC_TIME
} sync_mode;
struct sync_mode_desc {
  sync_mode_t m;
  char *cmdline;
  syncer_producer_t producer;
} sync_modes[] = {
  { SYNC_MERKLE, "merkle",
    wrap (merkle_sync::produce_syncer) }
};
// }}}

// {{{ General utility functions
template<class VS, class S>
static S
select_mode (const char *arg, const VS *modes, int nmodes)
{
  int i;
  S m = modes[0].m;
  for (i = 0; i < nmodes; i++) {
    if (strcmp (arg, modes[i].cmdline) == 0) {
      m = modes[i].m;
      break;
    }
  }
  if (i == nmodes) {
    strbuf s;
    for (i = 0; i < nmodes; i++)
      s << " " << modes[i].cmdline;
    fatal << "allowed modes are" << s << "\n";
  }
  return m;
}

static void
halt ()
{
  warnx << "Exiting on command.\n";
  while (maintainers.size ()) {
    maintainers.pop_back ();
  }
  exit (0);
}

void
start_logs ()
{
  static int logfd (-1);
  // XXX please don't call setlogfd or change errfd anywhere else...

  if (logfname) {
    if (logfd >= 0)
      close (logfd);
    logfd = open (logfname, O_RDWR | O_CREAT, 0666);
    if (logfd < 0)
      fatal << "Could not open log file " << logfd << " for appending.\n";
    lseek (logfd, 0, SEEK_END);
    errfd = logfd;
    modlogger::setlogfd (logfd);
  }
}

static void
usage ()
{
  warnx << "Usage: " << progname
	<< "\t[-C maintd-ctlsock]\n"
	<< "\t[-d localdatapath]\n"
        << "\t[-L logfilename]\n"
	<< "\t[-m maintmode]\n"
	<< "\t[-s syncmode]\n"
	<< "\t[-t]\n";
  exit (1);
}
// }}}
// {{{ Remote-side RPC handling
static void srvaccept (int fd);
static void sync_dispatch (ptr<asrv> srv, svccb *sbp);

static void
init_remote_server (const net_address &addr)
{
  in_addr laddr;
  inet_aton (addr.hostname, &laddr);
  int tcpfd = inetsocket (SOCK_STREAM, addr.port-1,
      ntohl (laddr.s_addr));
  if (tcpfd < 0)
    fatal ("binding TCP addr %s port %d: %m\n",
	addr.hostname.cstr (), addr.port-1);
  int ret = listen (tcpfd, 5);
  if (ret < 0)
    fatal ("listen (%d, 5): %m\n", tcpfd);
  fdcb (tcpfd, selread, wrap (&srvaccept, tcpfd));
  warn << "Listening for sync requests on "
       << addr.hostname << ":" << addr.port-1 << ".\n";
}

static void
srvaccept (int lfd)
{
  sockaddr_un sun;
  bzero (&sun, sizeof (sun));
  socklen_t sunlen = sizeof (sun);
  int fd = accept (lfd, reinterpret_cast<sockaddr *> (&sun), &sunlen);
  if (fd < 0) {
    warn ("accept: unexpected EOF: %m\n");
    return;
  }
  ref<axprt_stream> c = axprt_stream::alloc (fd, 1024*1025);
  // XXX should accept for whatever the chosen syncmode wants.
  ptr<asrv> s = asrv::alloc (c, merklesync_program_1);
  s->setcb (wrap (&sync_dispatch, s));
}

static void
sync_dispatch (ptr<asrv> srv, svccb *sbp)
{
  if (!sbp) {
    srv->setcb (NULL);
    srv = NULL;
    return;
  }
  bool ok = false;
  syncdest_t *discrim = sbp->Xtmpl getarg<syncdest_t> ();
  for (size_t i = 0; i < maintainers.size (); i++) {
    // maintainer takes some time to get local db info from adbd;
    // must check for valid localtree before dispatching
    if (maintainers[i]->sync->sync_program ().progno == sbp->prog () &&
	maintainers[i]->sync->ctype == discrim->ctype &&
	maintainers[i]->host.vnode_num == (int) discrim->vnode &&
	maintainers[i]->localtree () != NULL)
    {
      ok = true;
      ptr<merkle_tree> t = maintainers[i]->localtree ();
      maintainers[i]->sync->dispatch (t, sbp);
      break;
    }
  }
  if (!ok)
    sbp->reject (PROC_UNAVAIL);
}
// }}}
// {{{ Control-side RPC execution
void
do_setmaint (svccb *sbp)
{
  maint_setmaintarg *arg = sbp->Xtmpl getarg<maint_setmaintarg> ();
  for (unsigned int i = 0; i < maintainers.size (); i++) {
    if (arg->enable) {
      maintainers[i]->start (arg->delay);
    } else {
      maintainers[i]->stop ();
    }
  }
  sbp->replyref (arg->enable);
}

void
do_initspace (svccb *sbp)
{
  maint_dhashinfo_t *arg = sbp->Xtmpl getarg<maint_dhashinfo_t> ();
  maint_status res (MAINTPROC_OK);

  chord_node host = arg->host;
  dhash_ctype ctype = arg->ctype;

  // Check that we don't already have a maintainer for this host/ctype
  for (unsigned int i = 0; i < maintainers.size (); i++) {
    if (maintainers[i]->host.r.hostname == host.r.hostname &&
	maintainers[i]->host.r.port     == host.r.port &&
	maintainers[i]->host.vnode_num  == host.vnode_num &&
	maintainers[i]->ctype == ctype)
    {
      res = MAINTPROC_ERR;
      sbp->replyref (res);
      return;
    }
  }

  ptr<syncer> s = sync_modes[sync_mode].producer (ctype);
  ptr<maintainer> m = maint_modes[maint_mode].producer (localdatapath, arg, s);
  maintainers.push_back (m);

  sbp->replyref (res);
}

void
do_listen (svccb *sbp)
{
  static bool initialized (false);
  maint_status res (MAINTPROC_OK);
  net_address *addr = sbp->Xtmpl getarg<net_address> ();
  if (!initialized) {
    init_remote_server (*addr);
    initialized = true;
  } else {
    res = MAINTPROC_ERR;
  }
  sbp->replyref (res);
}

void
do_getrepairs (svccb *sbp)
{
  maint_getrepairsarg *arg = sbp->Xtmpl getarg<maint_getrepairsarg> ();
  maint_getrepairsres *res = sbp->Xtmpl getarg<maint_getrepairsres> ();

  chord_node host = arg->host;
  dhash_ctype ctype = arg->ctype;
  ptr<maintainer> m = NULL;

  for (unsigned int i = 0; i < maintainers.size (); i++) {
    if (maintainers[i]->host.r.hostname == host.r.hostname &&
	maintainers[i]->host.r.port     == host.r.port &&
	maintainers[i]->host.vnode_num  == host.vnode_num &&
	maintainers[i]->ctype == ctype)
    {
      m = maintainers[i];
    }
  }
  if (!m) {
    res->status = MAINTPROC_ERR;
    sbp->reply (res);
    return;
  }

  m->getrepairs (arg->start, arg->thresh, arg->count, res->repairs);
  sbp->reply (res);
}
// }}}
// {{{ Control-side RPC accept and dispatch
static void accept_cb (int lfd);
void dispatch (ref<axprt_stream> s, ptr<asrv> a, svccb *sbp);
static void
listen_unix (str sock_name)
{
  unlink (sock_name);
  int clntfd = unixsocket (sock_name);
  if (clntfd < 0)
    fatal << "Error creating socket (UNIX)" << strerror (errno) << "\n";

  if (listen (clntfd, 128) < 0) {
    fatal ("Error from listen: %m\n");
    close (clntfd);
  } else {
    fdcb (clntfd, selread, wrap (accept_cb, clntfd));
  }
}

static void
accept_cb (int lfd)
{
  sockaddr_un sun;
  bzero (&sun, sizeof (sun));
  socklen_t sunlen = sizeof (sun);
  int fd = accept (lfd, reinterpret_cast<sockaddr *> (&sun), &sunlen);
  if (fd < 0)
    fatal ("EOF\n");

  ref<axprt_stream> x = axprt_stream::alloc (fd, 1024*1025);

  ptr<asrv> a = asrv::alloc (x, maint_program_1);
  a->setcb (wrap (dispatch, x, a));
}

void
dispatch (ref<axprt_stream> s, ptr<asrv> a, svccb *sbp)
{
  if (sbp == NULL) {
    warn << "EOF from client\n";
    a = NULL;
    return;
  }

  switch (sbp->proc ()) {
  case MAINTPROC_NULL:
    sbp->reply (NULL);
    break;
  case MAINTPROC_SETMAINT:
    do_setmaint (sbp);
    break;
  case MAINTPROC_INITSPACE:
    do_initspace (sbp);
    break;
  case MAINTPROC_LISTEN:
    do_listen (sbp);
    break;
  case MAINTPROC_GETREPAIRS:
    do_getrepairs (sbp);
    break;
  default:
    warn << "unknown procedure: " << sbp->proc () << "\n";
    sbp->reject (PROC_UNAVAIL);
  }

  return;
}
// }}}

int
main (int argc, char **argv)
{
  str ctlsock = "/tmp/maint-sock";
  char ch;

  setprogname (argv[0]);
  random_init ();

  localdatapath = "./maintdata/";
  maint_mode = MAINT_CARBONITE;
  sync_mode = SYNC_MERKLE;

  while ((ch = getopt (argc, argv, "C:d:L:m:s:t"))!=-1)
    switch (ch) {
    case 'C':
      ctlsock = optarg;
      break;
    case 'd':
      localdatapath = optarg;
      break;
    case 'L':
      logfname = optarg;
      break;
    case 'm':
      maint_mode = select_mode<maint_mode_desc, maint_mode_t> (optarg, maint_modes, sizeof (maint_modes)/sizeof (maint_modes[0]));
      break;
    case 's':
      sync_mode = select_mode<sync_mode_desc, sync_mode_t> (optarg, sync_modes, sizeof (sync_modes)/sizeof (sync_modes[0]));
      break;
    case 't':
      modlogger::setmaxprio (modlogger::TRACE);
      break;
    default:
      usage ();
      break;
    }

  start_logs ();

  warn << "Starting up " << maint_modes[maint_mode].cmdline
       << " maintenance, syncing with "
       << sync_modes[sync_mode].cmdline << ".\n";

  {
    struct stat sb;
    if (stat (localdatapath, &sb) < 0) {
      if (errno != ENOENT ||
	  (mkdir (localdatapath, 0755) < 0 && errno != EEXIST))
	fatal ("%s: %m\n", localdatapath);
      if (stat (localdatapath, &sb) < 0)
	fatal ("stat (%s): %m\n", localdatapath);
      warn << "Created " << localdatapath << " for maintenance state.\n";
    }
    if (!S_ISDIR (sb.st_mode))
      fatal ("%s: not a directory\n", localdatapath);
  }

  listen_unix (ctlsock);

  sigcb (SIGHUP, wrap (&start_logs));
  sigcb (SIGINT, wrap (&halt));
  sigcb (SIGTERM, wrap (&halt));

  amain ();
}

// vim: foldmethod=marker
<commit_msg>Correct initialization of maint_getrepairsres in maintd.<commit_after>#include <arpc.h>

#include <modlogger.h>
#include <misc_utils.h>

#include <dhash_types.h>
#include <dhash_common.h>
#include <merkle_sync_prot.h>

#include <merkle.h>

#include <maint_prot.h>
#include "maint_policy.h"

// {{{ Globals
static char *logfname;
static char *localdatapath;

static vec<ptr<maintainer> > maintainers;

enum maint_mode_t {
  MAINT_CARBONITE,
  MAINT_PASSINGTONE,
} maint_mode;
struct maint_mode_desc {
  maint_mode_t m;
  char *cmdline;
  maintainer_producer_t producer;
} maint_modes[] = {
  { MAINT_CARBONITE, "carbonite",
    wrap (carbonite::produce_maintainer) },
  { MAINT_PASSINGTONE, "passingtone",
    wrap (passingtone::produce_maintainer) }
};

enum sync_mode_t {
  SYNC_MERKLE,
  SYNC_TIME
} sync_mode;
struct sync_mode_desc {
  sync_mode_t m;
  char *cmdline;
  syncer_producer_t producer;
} sync_modes[] = {
  { SYNC_MERKLE, "merkle",
    wrap (merkle_sync::produce_syncer) }
};
// }}}

// {{{ General utility functions
template<class VS, class S>
static S
select_mode (const char *arg, const VS *modes, int nmodes)
{
  int i;
  S m = modes[0].m;
  for (i = 0; i < nmodes; i++) {
    if (strcmp (arg, modes[i].cmdline) == 0) {
      m = modes[i].m;
      break;
    }
  }
  if (i == nmodes) {
    strbuf s;
    for (i = 0; i < nmodes; i++)
      s << " " << modes[i].cmdline;
    fatal << "allowed modes are" << s << "\n";
  }
  return m;
}

static void
halt ()
{
  warnx << "Exiting on command.\n";
  while (maintainers.size ()) {
    maintainers.pop_back ();
  }
  exit (0);
}

void
start_logs ()
{
  static int logfd (-1);
  // XXX please don't call setlogfd or change errfd anywhere else...

  if (logfname) {
    if (logfd >= 0)
      close (logfd);
    logfd = open (logfname, O_RDWR | O_CREAT, 0666);
    if (logfd < 0)
      fatal << "Could not open log file " << logfd << " for appending.\n";
    lseek (logfd, 0, SEEK_END);
    errfd = logfd;
    modlogger::setlogfd (logfd);
  }
}

static void
usage ()
{
  warnx << "Usage: " << progname
	<< "\t[-C maintd-ctlsock]\n"
	<< "\t[-d localdatapath]\n"
        << "\t[-L logfilename]\n"
	<< "\t[-m maintmode]\n"
	<< "\t[-s syncmode]\n"
	<< "\t[-t]\n";
  exit (1);
}
// }}}
// {{{ Remote-side RPC handling
static void srvaccept (int fd);
static void sync_dispatch (ptr<asrv> srv, svccb *sbp);

static void
init_remote_server (const net_address &addr)
{
  in_addr laddr;
  inet_aton (addr.hostname, &laddr);
  int tcpfd = inetsocket (SOCK_STREAM, addr.port-1,
      ntohl (laddr.s_addr));
  if (tcpfd < 0)
    fatal ("binding TCP addr %s port %d: %m\n",
	addr.hostname.cstr (), addr.port-1);
  int ret = listen (tcpfd, 5);
  if (ret < 0)
    fatal ("listen (%d, 5): %m\n", tcpfd);
  fdcb (tcpfd, selread, wrap (&srvaccept, tcpfd));
  warn << "Listening for sync requests on "
       << addr.hostname << ":" << addr.port-1 << ".\n";
}

static void
srvaccept (int lfd)
{
  sockaddr_un sun;
  bzero (&sun, sizeof (sun));
  socklen_t sunlen = sizeof (sun);
  int fd = accept (lfd, reinterpret_cast<sockaddr *> (&sun), &sunlen);
  if (fd < 0) {
    warn ("accept: unexpected EOF: %m\n");
    return;
  }
  ref<axprt_stream> c = axprt_stream::alloc (fd, 1024*1025);
  // XXX should accept for whatever the chosen syncmode wants.
  ptr<asrv> s = asrv::alloc (c, merklesync_program_1);
  s->setcb (wrap (&sync_dispatch, s));
}

static void
sync_dispatch (ptr<asrv> srv, svccb *sbp)
{
  if (!sbp) {
    srv->setcb (NULL);
    srv = NULL;
    return;
  }
  bool ok = false;
  syncdest_t *discrim = sbp->Xtmpl getarg<syncdest_t> ();
  for (size_t i = 0; i < maintainers.size (); i++) {
    // maintainer takes some time to get local db info from adbd;
    // must check for valid localtree before dispatching
    if (maintainers[i]->sync->sync_program ().progno == sbp->prog () &&
	maintainers[i]->sync->ctype == discrim->ctype &&
	maintainers[i]->host.vnode_num == (int) discrim->vnode &&
	maintainers[i]->localtree () != NULL)
    {
      ok = true;
      ptr<merkle_tree> t = maintainers[i]->localtree ();
      maintainers[i]->sync->dispatch (t, sbp);
      break;
    }
  }
  if (!ok)
    sbp->reject (PROC_UNAVAIL);
}
// }}}
// {{{ Control-side RPC execution
void
do_setmaint (svccb *sbp)
{
  maint_setmaintarg *arg = sbp->Xtmpl getarg<maint_setmaintarg> ();
  for (unsigned int i = 0; i < maintainers.size (); i++) {
    if (arg->enable) {
      maintainers[i]->start (arg->delay);
    } else {
      maintainers[i]->stop ();
    }
  }
  sbp->replyref (arg->enable);
}

void
do_initspace (svccb *sbp)
{
  maint_dhashinfo_t *arg = sbp->Xtmpl getarg<maint_dhashinfo_t> ();
  maint_status res (MAINTPROC_OK);

  chord_node host = arg->host;
  dhash_ctype ctype = arg->ctype;

  // Check that we don't already have a maintainer for this host/ctype
  for (unsigned int i = 0; i < maintainers.size (); i++) {
    if (maintainers[i]->host.r.hostname == host.r.hostname &&
	maintainers[i]->host.r.port     == host.r.port &&
	maintainers[i]->host.vnode_num  == host.vnode_num &&
	maintainers[i]->ctype == ctype)
    {
      res = MAINTPROC_ERR;
      sbp->replyref (res);
      return;
    }
  }

  ptr<syncer> s = sync_modes[sync_mode].producer (ctype);
  ptr<maintainer> m = maint_modes[maint_mode].producer (localdatapath, arg, s);
  maintainers.push_back (m);

  sbp->replyref (res);
}

void
do_listen (svccb *sbp)
{
  static bool initialized (false);
  maint_status res (MAINTPROC_OK);
  net_address *addr = sbp->Xtmpl getarg<net_address> ();
  if (!initialized) {
    init_remote_server (*addr);
    initialized = true;
  } else {
    res = MAINTPROC_ERR;
  }
  sbp->replyref (res);
}

void
do_getrepairs (svccb *sbp)
{
  maint_getrepairsarg *arg = sbp->Xtmpl getarg<maint_getrepairsarg> ();
  maint_getrepairsres *res = sbp->Xtmpl getres<maint_getrepairsres> ();
  res->status = MAINTPROC_OK;

  chord_node host = arg->host;
  dhash_ctype ctype = arg->ctype;
  ptr<maintainer> m = NULL;

  for (unsigned int i = 0; i < maintainers.size (); i++) {
    if (maintainers[i]->host.r.hostname == host.r.hostname &&
	maintainers[i]->host.r.port     == host.r.port &&
	maintainers[i]->host.vnode_num  == host.vnode_num &&
	maintainers[i]->ctype == ctype)
    {
      m = maintainers[i];
    }
  }
  if (!m) {
    res->status = MAINTPROC_ERR;
    sbp->reply (res);
    return;
  }

  m->getrepairs (arg->start, arg->thresh, arg->count, res->repairs);
  sbp->reply (res);
}
// }}}
// {{{ Control-side RPC accept and dispatch
static void accept_cb (int lfd);
void dispatch (ref<axprt_stream> s, ptr<asrv> a, svccb *sbp);
static void
listen_unix (str sock_name)
{
  unlink (sock_name);
  int clntfd = unixsocket (sock_name);
  if (clntfd < 0)
    fatal << "Error creating socket (UNIX)" << strerror (errno) << "\n";

  if (listen (clntfd, 128) < 0) {
    fatal ("Error from listen: %m\n");
    close (clntfd);
  } else {
    fdcb (clntfd, selread, wrap (accept_cb, clntfd));
  }
}

static void
accept_cb (int lfd)
{
  sockaddr_un sun;
  bzero (&sun, sizeof (sun));
  socklen_t sunlen = sizeof (sun);
  int fd = accept (lfd, reinterpret_cast<sockaddr *> (&sun), &sunlen);
  if (fd < 0)
    fatal ("EOF\n");

  ref<axprt_stream> x = axprt_stream::alloc (fd, 1024*1025);

  ptr<asrv> a = asrv::alloc (x, maint_program_1);
  a->setcb (wrap (dispatch, x, a));
}

void
dispatch (ref<axprt_stream> s, ptr<asrv> a, svccb *sbp)
{
  if (sbp == NULL) {
    warn << "EOF from client\n";
    a = NULL;
    return;
  }

  switch (sbp->proc ()) {
  case MAINTPROC_NULL:
    sbp->reply (NULL);
    break;
  case MAINTPROC_SETMAINT:
    do_setmaint (sbp);
    break;
  case MAINTPROC_INITSPACE:
    do_initspace (sbp);
    break;
  case MAINTPROC_LISTEN:
    do_listen (sbp);
    break;
  case MAINTPROC_GETREPAIRS:
    do_getrepairs (sbp);
    break;
  default:
    warn << "unknown procedure: " << sbp->proc () << "\n";
    sbp->reject (PROC_UNAVAIL);
  }

  return;
}
// }}}

int
main (int argc, char **argv)
{
  str ctlsock = "/tmp/maint-sock";
  char ch;

  setprogname (argv[0]);
  random_init ();

  localdatapath = "./maintdata/";
  maint_mode = MAINT_CARBONITE;
  sync_mode = SYNC_MERKLE;

  while ((ch = getopt (argc, argv, "C:d:L:m:s:t"))!=-1)
    switch (ch) {
    case 'C':
      ctlsock = optarg;
      break;
    case 'd':
      localdatapath = optarg;
      break;
    case 'L':
      logfname = optarg;
      break;
    case 'm':
      maint_mode = select_mode<maint_mode_desc, maint_mode_t> (optarg, maint_modes, sizeof (maint_modes)/sizeof (maint_modes[0]));
      break;
    case 's':
      sync_mode = select_mode<sync_mode_desc, sync_mode_t> (optarg, sync_modes, sizeof (sync_modes)/sizeof (sync_modes[0]));
      break;
    case 't':
      modlogger::setmaxprio (modlogger::TRACE);
      break;
    default:
      usage ();
      break;
    }

  start_logs ();

  warn << "Starting up " << maint_modes[maint_mode].cmdline
       << " maintenance, syncing with "
       << sync_modes[sync_mode].cmdline << ".\n";

  {
    struct stat sb;
    if (stat (localdatapath, &sb) < 0) {
      if (errno != ENOENT ||
	  (mkdir (localdatapath, 0755) < 0 && errno != EEXIST))
	fatal ("%s: %m\n", localdatapath);
      if (stat (localdatapath, &sb) < 0)
	fatal ("stat (%s): %m\n", localdatapath);
      warn << "Created " << localdatapath << " for maintenance state.\n";
    }
    if (!S_ISDIR (sb.st_mode))
      fatal ("%s: not a directory\n", localdatapath);
  }

  listen_unix (ctlsock);

  sigcb (SIGHUP, wrap (&start_logs));
  sigcb (SIGINT, wrap (&halt));
  sigcb (SIGTERM, wrap (&halt));

  amain ();
}

// vim: foldmethod=marker
<|endoftext|>


<commit_before>// AdvGfx.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "AdvGfx.h"
#include "objLoader.h"
#include "Raytracer.h"

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

#include <GLM\glm.hpp>
#include <GLM\ext.hpp>

namespace AdvGfxCore
{
	using namespace std;

	void getErrors()
	{
		GLenum error = glGetError();
		while (error)
		{
			cout << gluErrorString(error) << endl;
			error = glGetError();
		}
	}

	static string textFileRead(const char *fileName) {
		string fileString = string(); // A string for storing the file contents
		string line = string(); // A string for holding the current line

		ifstream file(fileName); // Open an input stream with the selected file
		if (file.is_open()) { // If the file opened successfully
			while (!file.eof()) { // While we are not at the end of the file
				getline(file, line); // Get the current line
				fileString.append(line); // Append the line to our file string
				fileString.append("\n"); // Appand a new line character
			}
			file.close(); // Close the file
		}

		return fileString; // Return our string
	}

	static bool validateProgram(GLuint program) {
		const unsigned int BUFFER_SIZE = 512;
		char buffer[BUFFER_SIZE];
		memset(buffer, 0, BUFFER_SIZE);
		GLsizei length = 0;

		glGetProgramInfoLog(program, BUFFER_SIZE, &length, buffer); // Ask OpenGL to give us the log associated with the program
		if (length > 0) // If we have any information to display
		{
			cout << "Program " << program << " link error: " << buffer << endl; // Output the information
			return false;
		}

		glValidateProgram(program); // Get OpenGL to try validating the program
		GLint status;
		glGetProgramiv(program, GL_VALIDATE_STATUS, &status); // Find out if the shader program validated correctly
		if (status == GL_FALSE) // If there was a problem validating
		{
			cout << "Error validating shader " << program << endl; // Output which program had the error
			return false;
		}

		return true;
	}

	glm::vec3 movement;

	GLuint prog;

	GLuint projLoc;
	GLuint viewLoc;
	GLuint modelLoc;

	camera c;

	glm::mat4 modelMatrix;

	float xChange = 0, yChange = 0, zChange = 0;

	clock_t lastDraw = clock();

	Model* model = NULL;
	Model* model2 = NULL;

	GLuint texture;

	void Init(int w, int h)
	{
		glClearColor(.1f, .2f, .3f, 1.f);

		glGenTextures(1, &texture);
		glBindTexture(GL_TEXTURE_2D, texture);

		prog = glCreateProgram();
		GLuint vert = glCreateShader(GL_VERTEX_SHADER);
		GLuint frag = glCreateShader(GL_FRAGMENT_SHADER);

		string v = textFileRead("rayShader.vert");
		string f = textFileRead("rayShader.frag");

		const char* vArr = v.c_str();
		const char* fArr = f.c_str();

		glShaderSource(vert, 1, &vArr, 0);
		glShaderSource(frag, 1, &fArr, 0);

		glCompileShaderARB(vert);
		glCompileShaderARB(frag);

		GLint compiled;

		glGetObjectParameterivARB(vert, GL_COMPILE_STATUS, &compiled);
		if (compiled)
		{
			glGetObjectParameterivARB(frag, GL_COMPILE_STATUS, &compiled);
			if (compiled)
			{
				//continue;
			}
			else
			{
				const unsigned int BUFFER_SIZE = 512;
				char buffer[BUFFER_SIZE];
				memset(buffer, 0, BUFFER_SIZE);
				GLsizei length = 0;

				glGetShaderInfoLog(frag, BUFFER_SIZE, &length, buffer);

				cout << buffer << endl;
			}
		}

		glAttachShader(prog, frag);
		glAttachShader(prog, vert);

		glLinkProgram(prog);

		validateProgram(prog);

		projLoc = glGetUniformLocation(prog, "projection");
		viewLoc = glGetUniformLocation(prog, "view");
		modelLoc = glGetUniformLocation(prog, "model");

		ResetCamera();

		c.projectionMatrix = glm::perspective(60.0f, (float)w / h, 0.1f, 100.f);
		//glm::mat4 viewMatrix = glm::translate(glm::mat4(1.0f), viewVec);
		modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(0.01f, 0.01f, 0.01f));

		glUseProgram(prog);

		glUniformMatrix4fv(projLoc, 1, false, &c.projectionMatrix[0][0]);
		//glUniformMatrix4fv(viewLoc, 1, false, &viewMatrix[0][0]);
		glUniformMatrix4fv(modelLoc, 1, false, &modelMatrix[0][0]);

		glEnable(GL_CULL_FACE);
		glEnable(GL_DEPTH_TEST);

		getErrors();
	}

	void Draw()
	{
		RayTracer r;
		pixel *pixels = r.shootRay(c);

		clock_t startDraw = clock();

		// Draw the pixels
		GLuint quad_vertexArrayID;
		glGenVertexArrays(1, &quad_vertexArrayID);
		glBindVertexArray(quad_vertexArrayID);

		static const GLfloat g_quad_vertex_buffer_data[] = {
			-1.0f, -1.0f, 0.0f,
			1.0f, -1.0f, 0.0f,
			-1.0f,  1.0f, 0.0f,
			-1.0f,  1.0f, 0.0f,
			1.0f, -1.0f, 0.0f,
			1.0f,  1.0f, 0.0f,
		};

		GLuint quad_vertexBuffer;
		glGenBuffers(1, &quad_vertexBuffer);
		glBindBuffer(GL_ARRAY_BUFFER, quad_vertexBuffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW);

		pixel p;
		p.r = 255;
		p.a = 255;
		p.b = 0;
		p.g = 0;

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);

		glDrawArrays(GL_TRIANGLES, 0, 2);

		getErrors();
		/*
		float duration = (startDraw - lastDraw) / (float)CLOCKS_PER_SEC;

		//viewVec += glm::vec3(xChange * duration, yChange * duration, zChange * duration);
		glm::vec3 finalMovement = 10 * duration * movement;
		finalMovement = glm::rotateX(finalMovement, -(c.xRot));
		finalMovement = glm::rotateY(finalMovement, -c.yRot);
		c.viewVec += finalMovement;

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

		c.viewMatrix = glm::mat4(1.0f);
		c.viewMatrix = glm::rotate(c.viewMatrix, c.xRot, glm::vec3(1.f, 0.f, 0.f));
		c.viewMatrix = glm::rotate(c.viewMatrix, c.yRot, glm::vec3(0.f, 1.f, 0.f));
		c.viewMatrix = glm::translate(c.viewMatrix, -(c.viewVec));

		//modelMatrix = glm::rotate(modelMatrix, (float)duration * 50, 0.f, 1.f, 0.f);

		glUniformMatrix4fv(viewLoc, 1, false, &c.viewMatrix[0][0]);
		glUniformMatrix4fv(modelLoc, 1, false, &modelMatrix[0][0]);

		if(model)
			model->draw();

		//getErrors();

		lastDraw = startDraw;

		xChange = yChange = zChange = 0;*/
	}

	void Resize(int width, int height)
	{

		glm::mat4 projectionMatrix = glm::perspective(60.0f, (float)width / height, 0.1f, 100.f);
		glUniformMatrix4fv(projLoc, 1, false, &projectionMatrix[0][0]);

		glViewport(0, 0, width, height);
	}

	void MoveCamera(float x, float y, float z)
	{
		xChange = x;
		yChange = y;
		zChange = z;
	}

	void MoveCamera(Movement m, bool stop)
	{
		switch (m)
		{
		case AdvGfxCore::Up:
			movement.y = (float)((int)!stop) * 1;
			break;
		case AdvGfxCore::Down:
			movement.y = (float)((int)!stop) * -1;
			break;
		case AdvGfxCore::Left:
			movement.x = (float)((int)!stop) * -1;
			break;
		case AdvGfxCore::Right:
			movement.x = (float)((int)!stop) * 1;
			break;
		case AdvGfxCore::Forward:
			movement.z = (float)((int)!stop) * -1;
			break;
		case AdvGfxCore::Backward:
			movement.z = (float)((int)!stop) * 1;
			break;
		}
	}

	void RotateCamera(int x, int y)
	{
		c.xRot -= y;
		c.yRot -= x;
	}

	void ResetCamera()
	{
		c.viewVec = glm::vec3(0.0f, 0.0f, 5.0f);
		c.xRot = 0.f;
		c.yRot = 0.f;
	}

	unsigned int getFileLength(ifstream& file)
	{
		if (!file.good()) return 0;
		int pos = file.tellg();
		file.seekg(0, ios::end);
		int len = file.tellg();
		file.seekg(ios::beg);

		cout << len << '\n';
		return len;
	}

	const char** constructArray(ifstream& file, int length)
	{
		char* arr = new char[length + 1];
		if (file.is_open())
		{
			int i = 0;
			while (file.good())
			{
				arr[i++] = file.get(); // gets char from line
			}
			arr[i] = 0;
		}
		file.close();

		const char* returnArray = arr;
		return &returnArray;
	}

	void load(const char* path)
	{
		if(model)
			delete model;

		model = loadModel(path, prog);
	}
}<commit_msg>niks maar moet committen omdat ie anders moeilijk doet<commit_after>// AdvGfx.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "AdvGfx.h"
#include "objLoader.h"
#include "Raytracer.h"

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

#include <GLM\glm.hpp>
#include <GLM\ext.hpp>

namespace AdvGfxCore
{
	using namespace std;

	void getErrors()
	{
		GLenum error = glGetError();
		while (error)
		{
			cout << gluErrorString(error) << endl;
			error = glGetError();
		}
	}

	static string textFileRead(const char *fileName) {
		string fileString = string(); // A string for storing the file contents
		string line = string(); // A string for holding the current line

		ifstream file(fileName); // Open an input stream with the selected file
		if (file.is_open()) { // If the file opened successfully
			while (!file.eof()) { // While we are not at the end of the file
				getline(file, line); // Get the current line
				fileString.append(line); // Append the line to our file string
				fileString.append("\n"); // Appand a new line character
			}
			file.close(); // Close the file
		}

		return fileString; // Return our string
	}

	static bool validateProgram(GLuint program) {
		const unsigned int BUFFER_SIZE = 512;
		char buffer[BUFFER_SIZE];
		memset(buffer, 0, BUFFER_SIZE);
		GLsizei length = 0;

		glGetProgramInfoLog(program, BUFFER_SIZE, &length, buffer); // Ask OpenGL to give us the log associated with the program
		if (length > 0) // If we have any information to display
		{
			cout << "Program " << program << " link error: " << buffer << endl; // Output the information
			return false;
		}

		glValidateProgram(program); // Get OpenGL to try validating the program
		GLint status;
		glGetProgramiv(program, GL_VALIDATE_STATUS, &status); // Find out if the shader program validated correctly
		if (status == GL_FALSE) // If there was a problem validating
		{
			cout << "Error validating shader " << program << endl; // Output which program had the error
			return false;
		}

		return true;
	}

	glm::vec3 movement;

	GLuint prog;

	GLuint projLoc;
	GLuint viewLoc;
	GLuint modelLoc;

	camera c;

	glm::mat4 modelMatrix;

	float xChange = 0, yChange = 0, zChange = 0;

	clock_t lastDraw = clock();

	Model* model = NULL;
	Model* model2 = NULL;

	GLuint texture;

	void Init(int w, int h)
	{
		glClearColor(.1f, .2f, .3f, 1.f);

		glGenTextures(1, &texture);
		glBindTexture(GL_TEXTURE_2D, texture);

		prog = glCreateProgram();
		GLuint vert = glCreateShader(GL_VERTEX_SHADER);
		GLuint frag = glCreateShader(GL_FRAGMENT_SHADER);

		string v = textFileRead("rayShader.vert");
		string f = textFileRead("rayShader.frag");

		const char* vArr = v.c_str();
		const char* fArr = f.c_str();

		glShaderSource(vert, 1, &vArr, 0);
		glShaderSource(frag, 1, &fArr, 0);

		glCompileShaderARB(vert);
		glCompileShaderARB(frag);

		GLint compiled;

		glGetObjectParameterivARB(vert, GL_COMPILE_STATUS, &compiled);
		if (compiled)
		{
			glGetObjectParameterivARB(frag, GL_COMPILE_STATUS, &compiled);
			if (compiled)
			{
				//continue;
			}
			else
			{
				const unsigned int BUFFER_SIZE = 512;
				char buffer[BUFFER_SIZE];
				memset(buffer, 0, BUFFER_SIZE);
				GLsizei length = 0;

				glGetShaderInfoLog(frag, BUFFER_SIZE, &length, buffer);

				cout << buffer << endl;
			}
		}

		glAttachShader(prog, frag);
		glAttachShader(prog, vert);

		glLinkProgram(prog);

		validateProgram(prog);

		projLoc = glGetUniformLocation(prog, "projection");
		viewLoc = glGetUniformLocation(prog, "view");
		modelLoc = glGetUniformLocation(prog, "model");

		ResetCamera();

		c.projectionMatrix = glm::perspective(60.0f, (float)w / h, 0.1f, 100.f);
		//glm::mat4 viewMatrix = glm::translate(glm::mat4(1.0f), viewVec);
		modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(0.01f, 0.01f, 0.01f));

		glUseProgram(prog);

		glUniformMatrix4fv(projLoc, 1, false, &c.projectionMatrix[0][0]);
		//glUniformMatrix4fv(viewLoc, 1, false, &viewMatrix[0][0]);
		glUniformMatrix4fv(modelLoc, 1, false, &modelMatrix[0][0]);

		glEnable(GL_CULL_FACE);
		glEnable(GL_DEPTH_TEST);

		getErrors();
	}

	void Draw()
	{
		RayTracer r;
		pixel *pixels = r.shootRay(c);

		clock_t startDraw = clock();

		// Draw the pixels
		GLuint quad_vertexArrayID;
		glGenVertexArrays(1, &quad_vertexArrayID);
		glBindVertexArray(quad_vertexArrayID);

		static const GLfloat g_quad_vertex_buffer_data[] = {
			-1.0f, -1.0f, 0.0f,
			1.0f, -1.0f, 0.0f,
			-1.0f,  1.0f, 0.0f,
			-1.0f,  1.0f, 0.0f,
			1.0f, -1.0f, 0.0f,
			1.0f,  1.0f, 0.0f,
		};

		GLuint quad_vertexBuffer;
		glGenBuffers(1, &quad_vertexBuffer);
		glBindBuffer(GL_ARRAY_BUFFER, quad_vertexBuffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW);

		pixel p;
		p.r = 255;
		p.a = 255;
		p.b = 0;
		p.g = 0;

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1280, 720, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

		glDrawArrays(GL_TRIANGLES, 0, 2);

		getErrors();
		/*
		float duration = (startDraw - lastDraw) / (float)CLOCKS_PER_SEC;

		//viewVec += glm::vec3(xChange * duration, yChange * duration, zChange * duration);
		glm::vec3 finalMovement = 10 * duration * movement;
		finalMovement = glm::rotateX(finalMovement, -(c.xRot));
		finalMovement = glm::rotateY(finalMovement, -c.yRot);
		c.viewVec += finalMovement;

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

		c.viewMatrix = glm::mat4(1.0f);
		c.viewMatrix = glm::rotate(c.viewMatrix, c.xRot, glm::vec3(1.f, 0.f, 0.f));
		c.viewMatrix = glm::rotate(c.viewMatrix, c.yRot, glm::vec3(0.f, 1.f, 0.f));
		c.viewMatrix = glm::translate(c.viewMatrix, -(c.viewVec));

		//modelMatrix = glm::rotate(modelMatrix, (float)duration * 50, 0.f, 1.f, 0.f);

		glUniformMatrix4fv(viewLoc, 1, false, &c.viewMatrix[0][0]);
		glUniformMatrix4fv(modelLoc, 1, false, &modelMatrix[0][0]);

		if(model)
			model->draw();

		//getErrors();

		lastDraw = startDraw;

		xChange = yChange = zChange = 0;*/
	}

	void Resize(int width, int height)
	{

		glm::mat4 projectionMatrix = glm::perspective(60.0f, (float)width / height, 0.1f, 100.f);
		glUniformMatrix4fv(projLoc, 1, false, &projectionMatrix[0][0]);

		glViewport(0, 0, width, height);
	}

	void MoveCamera(float x, float y, float z)
	{
		xChange = x;
		yChange = y;
		zChange = z;
	}

	void MoveCamera(Movement m, bool stop)
	{
		switch (m)
		{
		case AdvGfxCore::Up:
			movement.y = (float)((int)!stop) * 1;
			break;
		case AdvGfxCore::Down:
			movement.y = (float)((int)!stop) * -1;
			break;
		case AdvGfxCore::Left:
			movement.x = (float)((int)!stop) * -1;
			break;
		case AdvGfxCore::Right:
			movement.x = (float)((int)!stop) * 1;
			break;
		case AdvGfxCore::Forward:
			movement.z = (float)((int)!stop) * -1;
			break;
		case AdvGfxCore::Backward:
			movement.z = (float)((int)!stop) * 1;
			break;
		}
	}

	void RotateCamera(int x, int y)
	{
		c.xRot -= y;
		c.yRot -= x;
	}

	void ResetCamera()
	{
		c.viewVec = glm::vec3(0.0f, 0.0f, 5.0f);
		c.xRot = 0.f;
		c.yRot = 0.f;
	}

	unsigned int getFileLength(ifstream& file)
	{
		if (!file.good()) return 0;
		int pos = file.tellg();
		file.seekg(0, ios::end);
		int len = file.tellg();
		file.seekg(ios::beg);

		cout << len << '\n';
		return len;
	}

	const char** constructArray(ifstream& file, int length)
	{
		char* arr = new char[length + 1];
		if (file.is_open())
		{
			int i = 0;
			while (file.good())
			{
				arr[i++] = file.get(); // gets char from line
			}
			arr[i] = 0;
		}
		file.close();

		const char* returnArray = arr;
		return &returnArray;
	}

	void load(const char* path)
	{
		if(model)
			delete model;

		model = loadModel(path, prog);
	}
}<|endoftext|>


<commit_before>/* This file is part of Zanshin Todo.

   Copyright 2008 Kevin Ottens <ervin@kde.org>
   Copyright 2008, 2009 Mario Bensi <nef@ipsquad.net>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "mainwindow.h"

#include <akonadi/control.h>

#include <akonadi/itemcreatejob.h>
#include <akonadi/itemmodel.h>

#include <boost/shared_ptr.hpp>

#include <kcal/todo.h>

#include <KDE/KAction>
#include <KDE/KActionCollection>
#include <KDE/KConfigGroup>
#include <KDE/KDebug>
#include <KDE/KIcon>
#include <KDE/KLineEdit>
#include <KDE/KLocale>
#include <KDE/KTabWidget>

#include <QtGui/QDockWidget>
#include <QtGui/QStackedWidget>
#include <QtGui/QHeaderView>
#include <QtGui/QToolBar>
#include <QtGui/QVBoxLayout>

#include "actionlistmodel.h"
#include "actionlistview.h"
#include "configdialog.h"
#include "contextsmodel.h"
#include "globalmodel.h"
#include "globalsettings.h"
#include "librarymodel.h"
#include "projectsmodel.h"
#include "todocategoriesmodel.h"
#include "todoflatmodel.h"
#include "todotreemodel.h"
#include "sidebar.h"

typedef boost::shared_ptr<KCal::Incidence> IncidencePtr;

MainWindow::MainWindow(QWidget *parent)
    : KXmlGuiWindow(parent)
{
    Akonadi::Control::start();

    setupCentralWidget();
    setupSideBar();
    setupActions();

    setupGUI();

    restoreColumnState();
    applySettings();

    actionCollection()->action("project_mode")->trigger();
}

void MainWindow::setupCentralWidget()
{
    QWidget *centralWidget = new QWidget(this);
    centralWidget->setLayout(new QVBoxLayout(centralWidget));

    m_view = new ActionListView(centralWidget);
    centralWidget->layout()->addWidget(m_view);
    m_actionList = new ActionListModel(this);
    m_view->setModel(m_actionList);
    m_actionList->setSourceModel(GlobalModel::todoFlat());

    m_addActionEdit = new KLineEdit(centralWidget);
    centralWidget->layout()->addWidget(m_addActionEdit);
    m_addActionEdit->setClickMessage(i18n("Type and press enter to add an action"));
    m_addActionEdit->setClearButtonShown(true);
    connect(m_addActionEdit, SIGNAL(returnPressed()),
            this, SLOT(onAddActionRequested()));

    setCentralWidget(centralWidget);
}

void MainWindow::setupSideBar()
{
    m_sidebar = new SideBar(this, actionCollection());

    connect(m_sidebar, SIGNAL(projectChanged(const QModelIndex&)),
            this, SLOT(onProjectChanged(const QModelIndex&)));
    connect(m_sidebar, SIGNAL(contextChanged(const QModelIndex&)),
            this, SLOT(onContextChanged(const QModelIndex&)));

    QDockWidget *dock = new QDockWidget(this);
    dock->setObjectName("SideBar");
    dock->setFeatures(dock->features() & ~QDockWidget::DockWidgetClosable);
    dock->setWidget(m_sidebar);
    addDockWidget(Qt::LeftDockWidgetArea, dock);
}

void MainWindow::setupActions()
{
    KActionCollection *ac = actionCollection();

    QActionGroup *modeGroup = new QActionGroup(this);
    modeGroup->setExclusive(true);

    KAction *action = ac->addAction("project_mode", m_sidebar, SLOT(switchToProjectMode()));
    action->setText(i18n("Project Mode"));
    action->setIcon(KIcon("view-pim-tasks"));
    action->setCheckable(true);
    modeGroup->addAction(action);

    action = ac->addAction("context_mode", m_sidebar, SLOT(switchToContextMode()));
    action->setText(i18n("Context Mode"));
    action->setIcon(KIcon("view-pim-notes"));
    action->setCheckable(true);
    modeGroup->addAction(action);

    ac->addAction(KStandardAction::Preferences, this, SLOT(showConfigDialog()));
    ac->addAction(KStandardAction::Quit, this, SLOT(close()));
}

void MainWindow::collectionClicked(const Akonadi::Collection &collection)
{
    GlobalModel::todoFlat()->setCollection(collection);
}

void MainWindow::onProjectChanged(const QModelIndex &current)
{
    delete m_actionList;
    m_actionList = new ActionListModel(this);
    m_view->setModel(m_actionList);
    if (GlobalModel::projectsLibrary()->isInbox(current)) {
        m_actionList->setSourceModel(GlobalModel::todoFlat());
        m_actionList->setMode(ActionListModel::NoProjectMode);
    } else {
        m_actionList->setSourceModel(GlobalModel::todoTree());
        m_actionList->setMode(ActionListModel::ProjectMode);
        QModelIndex projIndex = GlobalModel::projectsLibrary()->mapToSource(current);
        QModelIndex focusIndex = GlobalModel::projects()->mapToSource(projIndex);
        m_actionList->setSourceFocusIndex(focusIndex);
    }
}

void MainWindow::onContextChanged(const QModelIndex &current)
{
    delete m_actionList;
    m_actionList = new ActionListModel(this);
    m_view->setModel(m_actionList);
    if (GlobalModel::contextsLibrary()->isInbox(current)) {
        m_actionList->setSourceModel(GlobalModel::todoFlat());
        m_actionList->setMode(ActionListModel::NoContextMode);
    } else {
        m_actionList->setSourceModel(GlobalModel::todoCategories());
        m_actionList->setMode(ActionListModel::ContextMode);
        QModelIndex catIndex = GlobalModel::contextsLibrary()->mapToSource(current);
        QModelIndex focusIndex = GlobalModel::contexts()->mapToSource(catIndex);
        m_actionList->setSourceFocusIndex(focusIndex);
    }
}

void MainWindow::onAddActionRequested()
{
    QString summary = m_addActionEdit->text().trimmed();
    m_addActionEdit->setText(QString());

    if (summary.isEmpty()) return;

    QModelIndex current = m_actionList->mapToSource(m_view->currentIndex());
    int type = current.sibling(current.row(), TodoFlatModel::RowType).data().toInt();
    if (type==TodoFlatModel::StandardTodo) {
        current = current.parent();
    }

    QString parentRemoteId;
    if (m_actionList->sourceModel()==GlobalModel::todoTree()) {
        QModelIndex parentIndex = current.sibling(current.row(), TodoFlatModel::RemoteId);
        parentRemoteId = GlobalModel::todoTree()->data(parentIndex).toString();
    }

    QString category;
    if (m_actionList->sourceModel()==GlobalModel::todoCategories()) {
        QModelIndex categoryIndex = current.sibling(current.row(), TodoFlatModel::Summary);
        category = GlobalModel::todoCategories()->data(categoryIndex).toString();
    }

    KCal::Todo *todo = new KCal::Todo();
    todo->setSummary(summary);
    if (!parentRemoteId.isEmpty()) {
        todo->setRelatedToUid(parentRemoteId);
    }
    if (!category.isEmpty()) {
        todo->setCategories(category);
    }

    IncidencePtr incidence(todo);
    Akonadi::Item item;
    item.setMimeType("application/x-vnd.akonadi.calendar.todo");
    item.setPayload<IncidencePtr>(incidence);

    Akonadi::Collection collection = GlobalModel::todoFlat()->collection();
    Akonadi::ItemCreateJob *job = new Akonadi::ItemCreateJob(item, collection);
    job->start();
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    saveColumnsState();
    KXmlGuiWindow::closeEvent(event);
}

void MainWindow::saveAutoSaveSettings()
{
    saveColumnsState();
    KXmlGuiWindow::saveAutoSaveSettings();
}

void MainWindow::saveColumnsState()
{
    KConfigGroup cg = autoSaveConfigGroup();
    QByteArray state = m_view->header()->saveState();
    cg.writeEntry("MainHeaderState", state.toBase64());
}

void MainWindow::restoreColumnState()
{
    KConfigGroup cg = autoSaveConfigGroup();
    QByteArray state;
    if (cg.hasKey("MainHeaderState")) {
        state = cg.readEntry("MainHeaderState", state);
        m_view->header()->restoreState(QByteArray::fromBase64(state));
    }
}

void MainWindow::showConfigDialog()
{
    if (KConfigDialog::showDialog("settings")) {
        return;
    }

    ConfigDialog *dialog = new ConfigDialog(this, "settings",
                                            GlobalSettings::self());

    connect(dialog, SIGNAL(settingsChanged(const QString&)),
            this, SLOT(applySettings()));

    dialog->show();
}

void MainWindow::applySettings()
{
    Akonadi::Collection collection(GlobalSettings::collectionId());
    GlobalModel::todoFlat()->setCollection(collection);
}
<commit_msg>Fetch the collection first to be sure all the attributes got properly loaded.<commit_after>/* This file is part of Zanshin Todo.

   Copyright 2008 Kevin Ottens <ervin@kde.org>
   Copyright 2008, 2009 Mario Bensi <nef@ipsquad.net>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "mainwindow.h"

#include <akonadi/control.h>

#include <akonadi/collectionfetchjob.h>
#include <akonadi/itemcreatejob.h>
#include <akonadi/itemmodel.h>

#include <boost/shared_ptr.hpp>

#include <kcal/todo.h>

#include <KDE/KAction>
#include <KDE/KActionCollection>
#include <KDE/KConfigGroup>
#include <KDE/KDebug>
#include <KDE/KIcon>
#include <KDE/KLineEdit>
#include <KDE/KLocale>
#include <KDE/KTabWidget>

#include <QtGui/QDockWidget>
#include <QtGui/QStackedWidget>
#include <QtGui/QHeaderView>
#include <QtGui/QToolBar>
#include <QtGui/QVBoxLayout>

#include "actionlistmodel.h"
#include "actionlistview.h"
#include "configdialog.h"
#include "contextsmodel.h"
#include "globalmodel.h"
#include "globalsettings.h"
#include "librarymodel.h"
#include "projectsmodel.h"
#include "todocategoriesmodel.h"
#include "todoflatmodel.h"
#include "todotreemodel.h"
#include "sidebar.h"

typedef boost::shared_ptr<KCal::Incidence> IncidencePtr;

MainWindow::MainWindow(QWidget *parent)
    : KXmlGuiWindow(parent)
{
    Akonadi::Control::start();

    setupCentralWidget();
    setupSideBar();
    setupActions();

    setupGUI();

    restoreColumnState();
    applySettings();

    actionCollection()->action("project_mode")->trigger();
}

void MainWindow::setupCentralWidget()
{
    QWidget *centralWidget = new QWidget(this);
    centralWidget->setLayout(new QVBoxLayout(centralWidget));

    m_view = new ActionListView(centralWidget);
    centralWidget->layout()->addWidget(m_view);
    m_actionList = new ActionListModel(this);
    m_view->setModel(m_actionList);
    m_actionList->setSourceModel(GlobalModel::todoFlat());

    m_addActionEdit = new KLineEdit(centralWidget);
    centralWidget->layout()->addWidget(m_addActionEdit);
    m_addActionEdit->setClickMessage(i18n("Type and press enter to add an action"));
    m_addActionEdit->setClearButtonShown(true);
    connect(m_addActionEdit, SIGNAL(returnPressed()),
            this, SLOT(onAddActionRequested()));

    setCentralWidget(centralWidget);
}

void MainWindow::setupSideBar()
{
    m_sidebar = new SideBar(this, actionCollection());

    connect(m_sidebar, SIGNAL(projectChanged(const QModelIndex&)),
            this, SLOT(onProjectChanged(const QModelIndex&)));
    connect(m_sidebar, SIGNAL(contextChanged(const QModelIndex&)),
            this, SLOT(onContextChanged(const QModelIndex&)));

    QDockWidget *dock = new QDockWidget(this);
    dock->setObjectName("SideBar");
    dock->setFeatures(dock->features() & ~QDockWidget::DockWidgetClosable);
    dock->setWidget(m_sidebar);
    addDockWidget(Qt::LeftDockWidgetArea, dock);
}

void MainWindow::setupActions()
{
    KActionCollection *ac = actionCollection();

    QActionGroup *modeGroup = new QActionGroup(this);
    modeGroup->setExclusive(true);

    KAction *action = ac->addAction("project_mode", m_sidebar, SLOT(switchToProjectMode()));
    action->setText(i18n("Project Mode"));
    action->setIcon(KIcon("view-pim-tasks"));
    action->setCheckable(true);
    modeGroup->addAction(action);

    action = ac->addAction("context_mode", m_sidebar, SLOT(switchToContextMode()));
    action->setText(i18n("Context Mode"));
    action->setIcon(KIcon("view-pim-notes"));
    action->setCheckable(true);
    modeGroup->addAction(action);

    ac->addAction(KStandardAction::Preferences, this, SLOT(showConfigDialog()));
    ac->addAction(KStandardAction::Quit, this, SLOT(close()));
}

void MainWindow::collectionClicked(const Akonadi::Collection &collection)
{
    GlobalModel::todoFlat()->setCollection(collection);
}

void MainWindow::onProjectChanged(const QModelIndex &current)
{
    delete m_actionList;
    m_actionList = new ActionListModel(this);
    m_view->setModel(m_actionList);
    if (GlobalModel::projectsLibrary()->isInbox(current)) {
        m_actionList->setSourceModel(GlobalModel::todoFlat());
        m_actionList->setMode(ActionListModel::NoProjectMode);
    } else {
        m_actionList->setSourceModel(GlobalModel::todoTree());
        m_actionList->setMode(ActionListModel::ProjectMode);
        QModelIndex projIndex = GlobalModel::projectsLibrary()->mapToSource(current);
        QModelIndex focusIndex = GlobalModel::projects()->mapToSource(projIndex);
        m_actionList->setSourceFocusIndex(focusIndex);
    }
}

void MainWindow::onContextChanged(const QModelIndex &current)
{
    delete m_actionList;
    m_actionList = new ActionListModel(this);
    m_view->setModel(m_actionList);
    if (GlobalModel::contextsLibrary()->isInbox(current)) {
        m_actionList->setSourceModel(GlobalModel::todoFlat());
        m_actionList->setMode(ActionListModel::NoContextMode);
    } else {
        m_actionList->setSourceModel(GlobalModel::todoCategories());
        m_actionList->setMode(ActionListModel::ContextMode);
        QModelIndex catIndex = GlobalModel::contextsLibrary()->mapToSource(current);
        QModelIndex focusIndex = GlobalModel::contexts()->mapToSource(catIndex);
        m_actionList->setSourceFocusIndex(focusIndex);
    }
}

void MainWindow::onAddActionRequested()
{
    QString summary = m_addActionEdit->text().trimmed();
    m_addActionEdit->setText(QString());

    if (summary.isEmpty()) return;

    QModelIndex current = m_actionList->mapToSource(m_view->currentIndex());
    int type = current.sibling(current.row(), TodoFlatModel::RowType).data().toInt();
    if (type==TodoFlatModel::StandardTodo) {
        current = current.parent();
    }

    QString parentRemoteId;
    if (m_actionList->sourceModel()==GlobalModel::todoTree()) {
        QModelIndex parentIndex = current.sibling(current.row(), TodoFlatModel::RemoteId);
        parentRemoteId = GlobalModel::todoTree()->data(parentIndex).toString();
    }

    QString category;
    if (m_actionList->sourceModel()==GlobalModel::todoCategories()) {
        QModelIndex categoryIndex = current.sibling(current.row(), TodoFlatModel::Summary);
        category = GlobalModel::todoCategories()->data(categoryIndex).toString();
    }

    KCal::Todo *todo = new KCal::Todo();
    todo->setSummary(summary);
    if (!parentRemoteId.isEmpty()) {
        todo->setRelatedToUid(parentRemoteId);
    }
    if (!category.isEmpty()) {
        todo->setCategories(category);
    }

    IncidencePtr incidence(todo);
    Akonadi::Item item;
    item.setMimeType("application/x-vnd.akonadi.calendar.todo");
    item.setPayload<IncidencePtr>(incidence);

    Akonadi::Collection collection = GlobalModel::todoFlat()->collection();
    Akonadi::ItemCreateJob *job = new Akonadi::ItemCreateJob(item, collection);
    job->start();
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    saveColumnsState();
    KXmlGuiWindow::closeEvent(event);
}

void MainWindow::saveAutoSaveSettings()
{
    saveColumnsState();
    KXmlGuiWindow::saveAutoSaveSettings();
}

void MainWindow::saveColumnsState()
{
    KConfigGroup cg = autoSaveConfigGroup();
    QByteArray state = m_view->header()->saveState();
    cg.writeEntry("MainHeaderState", state.toBase64());
}

void MainWindow::restoreColumnState()
{
    KConfigGroup cg = autoSaveConfigGroup();
    QByteArray state;
    if (cg.hasKey("MainHeaderState")) {
        state = cg.readEntry("MainHeaderState", state);
        m_view->header()->restoreState(QByteArray::fromBase64(state));
    }
}

void MainWindow::showConfigDialog()
{
    if (KConfigDialog::showDialog("settings")) {
        return;
    }

    ConfigDialog *dialog = new ConfigDialog(this, "settings",
                                            GlobalSettings::self());

    connect(dialog, SIGNAL(settingsChanged(const QString&)),
            this, SLOT(applySettings()));

    dialog->show();
}

void MainWindow::applySettings()
{
    Akonadi::Collection collection(GlobalSettings::collectionId());
    Akonadi::CollectionFetchJob *job =  new Akonadi::CollectionFetchJob(collection, Akonadi::CollectionFetchJob::Base);
    job->exec();
    GlobalModel::todoFlat()->setCollection(job->collections().first());
}
<|endoftext|>


<commit_before>#include <iostream>

class Base {
public:
	virtual void func(int x)
	{
		std::cout << "Base::func(int)" << '\n'
				  << "x = " << x << '\n';
	}
};

class Sub : public Base {
public:
	void func(int x) // <=> virtual void func(int x)
	{
		std::cout << "Sub::func(int)" << '\n'
				  << "x = " << ++x << '\n';
	}
};

void test(Base& x)
{
	x.func(5);
}

int main()
{
	Base bc;
	Sub  sc;
	test(bc);
	test(sc);

	sc.Base::func(10);
	sc.func(10);

	Base& rbc = bc;
	rbc.func(20);
	Sub& rsc = sc;
	rsc.func(20);

	return 0;
}
<commit_msg>derived<commit_after>#include <iostream>

class Base {
public:
	virtual void func(int x)
	{
		std::cout << "Base::func(int)" << '\n'
				  << "x = " << x << '\n';
	}
};

class Sub : public Base {
public:
	void func(int x) // <=> virtual void func(int x)
	{
		std::cout << "Sub::func(int)" << '\n'
				  << "x = " << ++x << '\n';
	}
};

int main()
{
	Base bc;
	Sub  sc;

	Base& rbc = bc;
	Base& rsc = sc;
	rbc.func(20);
	rsc.func(20);

	sc.Base::func(10);
	sc.func(10);

	return 0;
}
<|endoftext|>