<commit_before>#pragma ident "$Id: //depot/msn/main/wonky/gpstkplot/lib/plot/Splitter.cpp#4 $"

/// @file Splitter.cpp Used to help with splitting sets of points. Class
/// definitions.

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk 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 Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Copyright 2004, The University of Texas at Austin
//
//============================================================================

#include "Splitter.hpp"

using namespace std;
using namespace vdraw;

namespace vplot
{
  pair<list<Path*>*, list<Path*>*> Splitter::splith(double splitter, Path* p, bool top, bool bottom, bool continuous)
  {
    if(!(top || bottom) || p->empty())
      return pair<list<Path* >*, list<Path*>*>(0, 0);

    list<Path*> *tl, *bl;
    if(top)
      tl = new list<Path*> ();
    if(bottom)
      bl = new list<Path*> ();

    Path* current = new Path(0,0);

    Path::iterator i=p->begin(),j=(Path::iterator)0;
    bool above = i->second > splitter;

    if(above && top) current->addPointAbsolute(i->first, i->second);
    else if(!above && bottom) current->addPointAbsolute(i->first, i->second);

    i++;

    double tdouble = 0;
    for (;i != p->end(); i++)
    {
      if (above && (i->second < splitter))
      {
        if(top)
        {
          if(continuous)
          {
            j = i;
            j--;
            tdouble = intersecth(splitter,*i,*j);
            current->addPointAbsolute(tdouble,splitter);
          }

          if(!current->empty()) tl->push_back(current);
          current = new Path(0,0);

          if(continuous)
            current->addPointAbsolute(tdouble,splitter);
        }
        above = false;
      }
      else if(!above && (i->second > splitter))
      {
        if(bottom)
        {
          if(continuous)
          {
            j = i;
            j--;
            tdouble = intersecth(splitter,*i,*j);
            current->addPointAbsolute(tdouble,splitter);
          }

          if(!current->empty()) bl->push_back(current);
          current = new Path(0,0);

          if(continuous)
            current->addPointAbsolute(tdouble,splitter);
        }
        above = true;
      }
      else if(i->second == splitter)
      {
        Path::iterator j=i;
        j++;

        /*
         * Only add, push, and make a new path if it doesn't "bounce" off of the
         * splitter.
         * So we do a lookahead of one with j.
         * We will _skip_ this area iff:
         * - j is at the end of p
         * - (i-1) is above and j is below
         * - (i-1) is below and j is above
         */
        if( (j != p->end()) &&
            ((above && (j->second < splitter)) ||
             (!above && (j->second > splitter))) )
        {
          current->addPointAbsolute(i->first, i->second);
          if (above && top)
            tl->push_back(current);
          else if(!above && bottom)
            bl->push_back(current);
          current = new Path(0,0);
          above = !above;
        }
      }
      if ((above && top) || (!above && bottom))
        current->addPointAbsolute(i->first, i->second);
    }

    if(!current->empty())
    {
      if(above && top) tl->push_back(current);
      else if(!above && bottom) bl->push_back(current);
    }

    return pair<list<Path*>*, list<Path*>*>(tl, bl);
  }

  list<Path*>* Splitter::splitvgap(double gap, Path* p)
  {
    if((p==0)||(p->empty()))
      return 0;

    list<Path*> *paths = new list<Path*> ();

    Path* current = new Path(0,0);

    Path::iterator i=p->begin();
    Path::iterator last=i;
    current->addPointAbsolute(i->first, i->second);
    i++;

    gap = (gap<0?-gap:gap);

    for (;i != p->end(); i++, last++)
    {
      double dist = i->first - last->first;
      dist = (dist<0?-dist:dist);
      if (dist >= gap)
      {
        paths->push_back(current);
        current = new Path(0,0);
      }
      current->addPointAbsolute(i->first, i->second);
    }

    if(!current->empty())
      paths->push_back(current);

    return paths;
  }

  std::pair<double,double> Splitter::intersectBox(
      const std::pair<double,double> inside, const std::pair<double,double> outside,
      double minX, double maxX, double minY, double maxY)
  {
    double x,y;
    if(outside.first < minX)
    {
      x = minX;
      y = intersectv(x, inside, outside);
      if(y>minY && y<maxY) return std::pair<double,double>(x,y);
    }
    else if(outside.first > maxX)
    {
      x = maxX;
      y = intersectv(x, inside, outside);
      if(y>minY && y<maxY) return std::pair<double,double>(x,y);
    }

    if(outside.second < minY)
    {
      y = minY;
      x = intersecth(y, inside, outside);
      return std::pair<double,double>(x,y);
    }
    else if(outside.second > maxY)
    {
      y = maxY;
      x = intersecth(y, inside, outside);
      return std::pair<double,double>(x,y);
    }

    // outside isn't out of the box, maybe inside is...
    if(!inBox(inside,minX,maxX,minY,maxY))
      return intersectBox(outside,inside,minX,maxX,minY,maxY);

    // Neither outside nor inside are out of the box.  Just give back one of
    // the points (the first)
    return inside;
  }

  std::auto_ptr< std::list< vdraw::Path > > Splitter::interpToBox(double minX, double maxX, double minY, double maxY, const vdraw::Path& p)
  {
    using namespace vdraw;
    Path::const_iterator i=p.begin(),j=p.begin();
    bool inside = inBox(*i,minX,maxX,minY,maxY);
    bool lastinside = inside;

    double cx, cy;
    p.getOrigin(cx,cy);

    std::auto_ptr< std::list< Path > > thelist(new std::list<Path>());
    Path current(cx,cy);
    if(inside)
      current.push_back(*i);
    i++;

    for(;i!=p.end();i++,j++,lastinside=inside)
    {
      inside = inBox(*i,minX,maxX,minY,maxY);
      if(!inside && lastinside)
      {
        current.push_back(intersectBox(*j,*i,minX,maxX,minY,maxY));
        thelist->push_back(current);
        current = Path(cx,cy);
      }
      else if(inside && !lastinside)
      {
        current.push_back(intersectBox(*i,*j,minX,maxX,minY,maxY));
        current.push_back(*i);
      }
      else if(inside)
      {
        current.push_back(*i);
      }
    }

    if(current.size() != 0)
      thelist->push_back(current);

    return thelist;
  }

  std::auto_ptr< vdraw::Path > Splitter::cropToBox(double minX, double maxX, double minY, double maxY, const vdraw::Path& p)
  {
    using namespace vdraw;
    Path::const_iterator i=p.begin();
    bool inside = inBox(*i,minX,maxX,minY,maxY);
    std::auto_ptr< Path >  newpath(new Path(0,0,p.size()));
    if(inside) newpath->push_back(*i);
    i++;
    for(;i!=p.end();i++)
    {
      inside = inBox(*i,minX,maxX,minY,maxY);
      if(inside) newpath->push_back(*i);
    }
    newpath->tighten();
    return newpath;
  }
}
<commit_msg>Another Windows compile fix.<commit_after>#pragma ident "$Id: //depot/msn/main/wonky/gpstkplot/lib/plot/Splitter.cpp#4 $"

/// @file Splitter.cpp Used to help with splitting sets of points. Class
/// definitions.

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk 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 Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Copyright 2004, The University of Texas at Austin
//
//============================================================================

#include "Splitter.hpp"

using namespace std;
using namespace vdraw;

namespace vplot
{
  pair<list<Path*>*, list<Path*>*> Splitter::splith(double splitter, Path* p, bool top, bool bottom, bool continuous)
  {
    if(!(top || bottom) || p->empty())
      return pair<list<Path* >*, list<Path*>*>(0, 0);

    list<Path*> *tl, *bl;
    if(top)
      tl = new list<Path*> ();
    if(bottom)
      bl = new list<Path*> ();

    Path* current = new Path(0,0);

    Path::iterator i=p->begin();
    bool above = i->second > splitter;

    if(above && top) current->addPointAbsolute(i->first, i->second);
    else if(!above && bottom) current->addPointAbsolute(i->first, i->second);

    i++;

    double tdouble = 0;
    for (;i != p->end(); i++)
    {
      if (above && (i->second < splitter))
      {
        if(top)
        {
          if(continuous)
          {
            Path::iterator j = i;
            j--;
            tdouble = intersecth(splitter,*i,*j);
            current->addPointAbsolute(tdouble,splitter);
          }

          if(!current->empty()) tl->push_back(current);
          current = new Path(0,0);

          if(continuous)
            current->addPointAbsolute(tdouble,splitter);
        }
        above = false;
      }
      else if(!above && (i->second > splitter))
      {
        if(bottom)
        {
          if(continuous)
          {
            Path::iterator j = i;
            j--;
            tdouble = intersecth(splitter,*i,*j);
            current->addPointAbsolute(tdouble,splitter);
          }

          if(!current->empty()) bl->push_back(current);
          current = new Path(0,0);

          if(continuous)
            current->addPointAbsolute(tdouble,splitter);
        }
        above = true;
      }
      else if(i->second == splitter)
      {
        Path::iterator j=i;
        j++;

        /*
         * Only add, push, and make a new path if it doesn't "bounce" off of the
         * splitter.
         * So we do a lookahead of one with j.
         * We will _skip_ this area iff:
         * - j is at the end of p
         * - (i-1) is above and j is below
         * - (i-1) is below and j is above
         */
        if( (j != p->end()) &&
            ((above && (j->second < splitter)) ||
             (!above && (j->second > splitter))) )
        {
          current->addPointAbsolute(i->first, i->second);
          if (above && top)
            tl->push_back(current);
          else if(!above && bottom)
            bl->push_back(current);
          current = new Path(0,0);
          above = !above;
        }
      }
      if ((above && top) || (!above && bottom))
        current->addPointAbsolute(i->first, i->second);
    }

    if(!current->empty())
    {
      if(above && top) tl->push_back(current);
      else if(!above && bottom) bl->push_back(current);
    }

    return pair<list<Path*>*, list<Path*>*>(tl, bl);
  }

  list<Path*>* Splitter::splitvgap(double gap, Path* p)
  {
    if((p==0)||(p->empty()))
      return 0;

    list<Path*> *paths = new list<Path*> ();

    Path* current = new Path(0,0);

    Path::iterator i=p->begin();
    Path::iterator last=i;
    current->addPointAbsolute(i->first, i->second);
    i++;

    gap = (gap<0?-gap:gap);

    for (;i != p->end(); i++, last++)
    {
      double dist = i->first - last->first;
      dist = (dist<0?-dist:dist);
      if (dist >= gap)
      {
        paths->push_back(current);
        current = new Path(0,0);
      }
      current->addPointAbsolute(i->first, i->second);
    }

    if(!current->empty())
      paths->push_back(current);

    return paths;
  }

  std::pair<double,double> Splitter::intersectBox(
      const std::pair<double,double> inside, const std::pair<double,double> outside,
      double minX, double maxX, double minY, double maxY)
  {
    double x,y;
    if(outside.first < minX)
    {
      x = minX;
      y = intersectv(x, inside, outside);
      if(y>minY && y<maxY) return std::pair<double,double>(x,y);
    }
    else if(outside.first > maxX)
    {
      x = maxX;
      y = intersectv(x, inside, outside);
      if(y>minY && y<maxY) return std::pair<double,double>(x,y);
    }

    if(outside.second < minY)
    {
      y = minY;
      x = intersecth(y, inside, outside);
      return std::pair<double,double>(x,y);
    }
    else if(outside.second > maxY)
    {
      y = maxY;
      x = intersecth(y, inside, outside);
      return std::pair<double,double>(x,y);
    }

    // outside isn't out of the box, maybe inside is...
    if(!inBox(inside,minX,maxX,minY,maxY))
      return intersectBox(outside,inside,minX,maxX,minY,maxY);

    // Neither outside nor inside are out of the box.  Just give back one of
    // the points (the first)
    return inside;
  }

  std::auto_ptr< std::list< vdraw::Path > > Splitter::interpToBox(double minX, double maxX, double minY, double maxY, const vdraw::Path& p)
  {
    using namespace vdraw;
    Path::const_iterator i=p.begin(),j=p.begin();
    bool inside = inBox(*i,minX,maxX,minY,maxY);
    bool lastinside = inside;

    double cx, cy;
    p.getOrigin(cx,cy);

    std::auto_ptr< std::list< Path > > thelist(new std::list<Path>());
    Path current(cx,cy);
    if(inside)
      current.push_back(*i);
    i++;

    for(;i!=p.end();i++,j++,lastinside=inside)
    {
      inside = inBox(*i,minX,maxX,minY,maxY);
      if(!inside && lastinside)
      {
        current.push_back(intersectBox(*j,*i,minX,maxX,minY,maxY));
        thelist->push_back(current);
        current = Path(cx,cy);
      }
      else if(inside && !lastinside)
      {
        current.push_back(intersectBox(*i,*j,minX,maxX,minY,maxY));
        current.push_back(*i);
      }
      else if(inside)
      {
        current.push_back(*i);
      }
    }

    if(current.size() != 0)
      thelist->push_back(current);

    return thelist;
  }

  std::auto_ptr< vdraw::Path > Splitter::cropToBox(double minX, double maxX, double minY, double maxY, const vdraw::Path& p)
  {
    using namespace vdraw;
    Path::const_iterator i=p.begin();
    bool inside = inBox(*i,minX,maxX,minY,maxY);
    std::auto_ptr< Path >  newpath(new Path(0,0,p.size()));
    if(inside) newpath->push_back(*i);
    i++;
    for(;i!=p.end();i++)
    {
      inside = inBox(*i,minX,maxX,minY,maxY);
      if(inside) newpath->push_back(*i);
    }
    newpath->tighten();
    return newpath;
  }
}
<|endoftext|>


<commit_before><commit_msg>modify XeXe Cuts<commit_after><|endoftext|>


<commit_before>// Catch
#include <catch.hpp>

// C++ Standard Library
#include <cstdlib>
#include <string>

// Armadillo
#include <armadillo>

// Mantella
#include <mantella>

extern std::string testDirectory;

TEST_CASE("bbob::AttractiveSectorFunction", "") {
  for (const auto& numberOfDimensions : {2, 40}) {
    mant::bbob::AttractiveSectorFunction<> attractiveSectorFunction(numberOfDimensions);

    arma::Mat<double> parameters;
    CHECK( parameters.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/_parameters_" + std::to_string(numberOfDimensions) +"x10.input") );

    arma::Col<double> translation;
    CHECK( translation.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/_translation_" + std::to_string(numberOfDimensions) +"x1.input") );

    arma::Mat<double> rotationR;
    CHECK( rotationR.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/_randomRotationMatrix_" + std::to_string(numberOfDimensions) + "x" + std::to_string(numberOfDimensions) + "_2.input") );

    arma::Mat<double> rotationQ;
    CHECK( rotationQ.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/_randomRotationMatrix_" + std::to_string(numberOfDimensions) + "x" + std::to_string(numberOfDimensions) + "_1.input") );

    arma::Col<double> expected;
    CHECK( expected.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/bbob_attractiveSectorFunction_dim" + std::to_string(numberOfDimensions) +".expected") );

    attractiveSectorFunction.setObjectiveValueTranslation(0);
    attractiveSectorFunction.setParameterTranslation(translation);
    attractiveSectorFunction.setParameterRotation(rotationR);
    attractiveSectorFunction.setRotationQ(rotationQ);

    for (std::size_t n = 0; n < parameters.n_cols; ++n) {
      CHECK(attractiveSectorFunction.getObjectiveValue(parameters.col(n)) == Approx(expected.at(n)));
    }
  }

  SECTION("Returns the specified class name.") {
    CHECK(mant::bbob::AttractiveSectorFunction<>(5).toString() == "bbob_attractive_sector_function");
  }
}

<commit_msg>Updated code format<commit_after>// Catch
#include <catch.hpp>

// C++ Standard Library
#include <cstdlib>
#include <string>

// Armadillo
#include <armadillo>

// Mantella
#include <mantella>

extern std::string testDirectory;

TEST_CASE("bbob::AttractiveSectorFunction", "") {
  for (const auto& numberOfDimensions : {2, 40}) {
    mant::bbob::AttractiveSectorFunction<> attractiveSectorFunction(numberOfDimensions);

    arma::Mat<double> parameters;
    CHECK( parameters.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/_parameters_" + std::to_string(numberOfDimensions) + "x10.input") );

    arma::Col<double> translation;
    CHECK( translation.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/_translation_" + std::to_string(numberOfDimensions) + "x1.input") );

    arma::Mat<double> rotationR;
    CHECK( rotationR.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/_randomRotationMatrix_" + std::to_string(numberOfDimensions) + "x" + std::to_string(numberOfDimensions) + "_2.input") );

    arma::Mat<double> rotationQ;
    CHECK( rotationQ.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/_randomRotationMatrix_" + std::to_string(numberOfDimensions) + "x" + std::to_string(numberOfDimensions) + "_1.input") );

    arma::Col<double> expected;
    CHECK( expected.load(testDirectory + "/data/optimisationProblem/blackBoxOptimisationBenchmark/bbob_attractiveSectorFunction_dim" + std::to_string(numberOfDimensions) + ".expected") );

    attractiveSectorFunction.setObjectiveValueTranslation(0);
    attractiveSectorFunction.setParameterTranslation(translation);
    attractiveSectorFunction.setParameterRotation(rotationR);
    attractiveSectorFunction.setRotationQ(rotationQ);

    for (std::size_t n = 0; n < parameters.n_cols; ++n) {
      CHECK(attractiveSectorFunction.getObjectiveValue(parameters.col(n)) == Approx(expected.at(n)));
    }
  }

  SECTION("Returns the specified class name.") {
    CHECK(mant::bbob::AttractiveSectorFunction<>(5).toString() == "bbob_attractive_sector_function");
  }
}

<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"

namespace {

class OptionsUITest : public UITest {
 public:
  OptionsUITest() {
    dom_automation_enabled_ = true;
    // TODO(csilv): Remove when dom-ui options is enabled by default.
    launch_arguments_.AppendSwitch(switches::kEnableTabbedOptions);
  }

  void AssertIsOptionsPage(TabProxy* tab) {
    std::wstring title;
    ASSERT_TRUE(tab->GetTabTitle(&title));
    ASSERT_EQ(L"Chromium Options", title);
  }
};

TEST_F(OptionsUITest, LoadOptionsByURL) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // Go to the options tab via URL.
  NavigateToURL(GURL(chrome::kChromeUIOptionsURL));
  AssertIsOptionsPage(tab);
}

TEST_F(OptionsUITest, CommandOpensOptionsTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up the options tab via command.
  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());
  AssertIsOptionsPage(tab);
}

// TODO(csilv): Investigate why this fails and fix. http://crbug.com/48521
TEST_F(OptionsUITest, FAILS_CommandAgainGoesBackToOptionsTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up the options tab via command.
  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());
  AssertIsOptionsPage(tab);

  // Switch to first tab and run command again.
  ASSERT_TRUE(browser->ActivateTab(0));
  ASSERT_TRUE(browser->WaitForTabToBecomeActive(0, action_max_timeout_ms()));
  ASSERT_TRUE(browser->RunCommandAsync(IDC_OPTIONS));

  // Ensure the options ui tab is active.
  ASSERT_TRUE(browser->WaitForTabToBecomeActive(1, action_max_timeout_ms()));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
}

// TODO(csilv): Investigate why this fails (sometimes) on 10.5 and fix.
// http://crbug.com/48521
TEST_F(OptionsUITest, FLAKY_TwoCommandsOneTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->RunCommandAsync(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
}

}  // namespace
<commit_msg>Make product name dynamic in DOMUI pref unit tests<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "app/l10n_util.h"
#include "base/command_line.h"
#include "chrome/app/chrome_dll_resource.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"

#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"

namespace {

class OptionsUITest : public UITest {
 public:
  OptionsUITest() {
    dom_automation_enabled_ = true;
    // TODO(csilv): Remove when dom-ui options is enabled by default.
    launch_arguments_.AppendSwitch(switches::kEnableTabbedOptions);
  }

  void AssertIsOptionsPage(TabProxy* tab) {
    std::wstring title;
    ASSERT_TRUE(tab->GetTabTitle(&title));
    std::wstring expected_title =
        l10n_util::GetStringF(IDS_OPTIONS_DIALOG_TITLE,
            l10n_util::GetString(IDS_PRODUCT_NAME));
    ASSERT_EQ(expected_title, title);
  }
};

TEST_F(OptionsUITest, LoadOptionsByURL) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());

  // Go to the options tab via URL.
  NavigateToURL(GURL(chrome::kChromeUIOptionsURL));
  AssertIsOptionsPage(tab);
}

TEST_F(OptionsUITest, CommandOpensOptionsTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up the options tab via command.
  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());
  AssertIsOptionsPage(tab);
}

// TODO(csilv): Investigate why this fails and fix. http://crbug.com/48521
TEST_F(OptionsUITest, FAILS_CommandAgainGoesBackToOptionsTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  // Bring up the options tab via command.
  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);

  scoped_refptr<TabProxy> tab = browser->GetActiveTab();
  ASSERT_TRUE(tab.get());
  AssertIsOptionsPage(tab);

  // Switch to first tab and run command again.
  ASSERT_TRUE(browser->ActivateTab(0));
  ASSERT_TRUE(browser->WaitForTabToBecomeActive(0, action_max_timeout_ms()));
  ASSERT_TRUE(browser->RunCommandAsync(IDC_OPTIONS));

  // Ensure the options ui tab is active.
  ASSERT_TRUE(browser->WaitForTabToBecomeActive(1, action_max_timeout_ms()));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
}

// TODO(csilv): Investigate why this fails (sometimes) on 10.5 and fix.
// http://crbug.com/48521
TEST_F(OptionsUITest, FLAKY_TwoCommandsOneTab) {
  scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get());

  int tab_count = -1;
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(1, tab_count);

  ASSERT_TRUE(browser->RunCommand(IDC_OPTIONS));
  ASSERT_TRUE(browser->RunCommandAsync(IDC_OPTIONS));
  ASSERT_TRUE(browser->GetTabCount(&tab_count));
  ASSERT_EQ(2, tab_count);
}

}  // namespace
<|endoftext|>


<commit_before><commit_msg>Disabling a couple of UI tests while I investigate.<commit_after><|endoftext|>


<commit_before><commit_msg>Don't reload whole chrome://extensions page when interacting with single extension (disable/enable...).<commit_after><|endoftext|>


<commit_before><commit_msg>Small "fix" to make window deallocation similar to window allocation.<commit_after><|endoftext|>


<commit_before>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <iostream>

#include "tokenan.h"
#include "ident.h"

TokenAn::TokenAn( const char *filename)
{
    read_file_contents( filename);
}

void TokenAn::init_file_length( const char *filename)
{
    FILE *f = fopen( filename, "r");
    fseek( f, 0, SEEK_END);
    filelength = ftell( f);
    fclose( f);
}

void TokenAn::read_file_contents( const char *filename)
{
    init_file_length( filename);

    data = new char[filelength + 1];
    data[filelength] = '\0';

    FILE *f = fopen( filename, "r");
    if ( fread( data, 1, filelength, f) != filelength)
        throw;

    fclose( f);

//    for ( int i = 0; i < filelength; i ++)
//        printf( "f[%d] = %d\n", i, (int)data[i]);
}

std::vector<TokenAn::Token *> TokenAn::run()
{
    ptr = data;
    std::vector<TokenAn::Token *> res;

    while ( *ptr != '\0')
    {
        skip_spaces();

        if ( *ptr == '%' || isidstart( *ptr))
        {
            char *id_start = ptr ++;
            while ( isidchar( *ptr))
                ptr ++;

            res.push_back( TokenAn::Token::createId(
                std::string( id_start, ptr - id_start)));
        }
        else if ( *ptr == ',')
        {
            res.push_back( TokenAn::Token::createScalar( TOKEN_COMMA));
            ptr ++;
        }
        else if ( *ptr == '(')
        {
            res.push_back( TokenAn::Token::createScalar( TOKEN_LBRACKET));
            ptr ++;
        }
        else if ( *ptr == ')')
        {
            res.push_back( TokenAn::Token::createScalar( TOKEN_RBRACKET));
            ptr ++;
        }
        else if ( *ptr == ':')
        {
            res.push_back( TokenAn::Token::createScalar( TOKEN_COLON));
            ptr ++;
        }
        else if ( *ptr == '$' && isdigit( ptr[1]))
        {
            ptr ++;

            int iVal = 0;
            sscanf( ptr, "%d", &iVal);
            res.push_back( TokenAn::Token::createConstInt( iVal));

            while ( isdigit( *ptr))
                ptr ++;
        }
        else if ( *ptr == '\n')
        {
            res.push_back( TokenAn::Token::createEos());
            ptr ++;
        }
        else if ( *ptr == '\0')
        {
            res.push_back( TokenAn::Token::createEos());
//            res.push_back( TokenAn::Token::createScalar( TOKEN_EOF));
        }
        else
        {
            std::cerr << "bad char: " << *ptr <<
                " (code: " << (int)*ptr << ")" << std::endl;
            assert(0);
        }
    }

    return res;
}

void TokenAn::skip_spaces()
{
    while ( *ptr != '\0' && isblank( *ptr))
        ptr ++;
}

TokenAn::Token *TokenAn::Token::createId( const std::string id_string)
{
    TokenAn::Token *res = new TokenAn::Token;
    res->type = TOKEN_ID;
    res->sVal = id_string;

    return res;
}

TokenAn::Token *TokenAn::Token::createConstInt( int iVal)
{
    TokenAn::Token *res = new TokenAn::Token;
    res->type = TOKEN_CONST_INT;
    res->iVal = iVal;

    return res;
}

TokenAn::Token *TokenAn::Token::createScalar( enum TOKEN_TYPE type)
{
    TokenAn::Token *res = new TokenAn::Token;
    res->type = type;

    return res;
}

TokenAn::Token *TokenAn::Token::createEos() // end of line
{
    return createScalar( TOKEN_EOS);
}

void TokenAn::Token::dump()
{
    switch ( type)
    {
    case TOKEN_ID:        std::cout << sVal; break;
    case TOKEN_EOS:       std::cout << "--------------- (\\n)"; break;
    case TOKEN_COMMA:     std::cout << ","; break;
    case TOKEN_LBRACKET:  std::cout << "("; break;
    case TOKEN_RBRACKET:  std::cout << ")"; break;
    case TOKEN_CONST_INT: std::cout << iVal; break;
    case TOKEN_COLON:     std::cout << ":"; break;
    default: throw;
    }
}

<commit_msg>support DOS- and Mac-style line breaks<commit_after>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <iostream>

#include "tokenan.h"
#include "ident.h"

TokenAn::TokenAn( const char *filename)
{
    read_file_contents( filename);
}

void TokenAn::init_file_length( const char *filename)
{
    FILE *f = fopen( filename, "r");
    fseek( f, 0, SEEK_END);
    filelength = ftell( f);
    fclose( f);
}

void TokenAn::read_file_contents( const char *filename)
{
    init_file_length( filename);

    data = new char[filelength + 1];
    data[filelength] = '\0';

    FILE *f = fopen( filename, "r");
    if ( fread( data, 1, filelength, f) != filelength)
        throw;

    fclose( f);

//    for ( int i = 0; i < filelength; i ++)
//        printf( "f[%d] = %d\n", i, (int)data[i]);
}

std::vector<TokenAn::Token *> TokenAn::run()
{
    ptr = data;
    std::vector<TokenAn::Token *> res;

    while ( *ptr != '\0')
    {
        skip_spaces();

        if ( *ptr == '%' || isidstart( *ptr))
        {
            char *id_start = ptr ++;
            while ( isidchar( *ptr))
                ptr ++;

            res.push_back( TokenAn::Token::createId(
                std::string( id_start, ptr - id_start)));
        }
        else if ( *ptr == ',')
        {
            res.push_back( TokenAn::Token::createScalar( TOKEN_COMMA));
            ptr ++;
        }
        else if ( *ptr == '(')
        {
            res.push_back( TokenAn::Token::createScalar( TOKEN_LBRACKET));
            ptr ++;
        }
        else if ( *ptr == ')')
        {
            res.push_back( TokenAn::Token::createScalar( TOKEN_RBRACKET));
            ptr ++;
        }
        else if ( *ptr == ':')
        {
            res.push_back( TokenAn::Token::createScalar( TOKEN_COLON));
            ptr ++;
        }
        else if ( *ptr == '$' && isdigit( ptr[1]))
        {
            ptr ++;

            int iVal = 0;
            sscanf( ptr, "%d", &iVal);
            res.push_back( TokenAn::Token::createConstInt( iVal));

            while ( isdigit( *ptr))
                ptr ++;
        }
        else if ( *ptr == '\r' && ptr[1] == '\n') // DOS
        {
            res.push_back( TokenAn::Token::createEos());
            ptr += 2;
        }
        else if ( *ptr == '\n' || *ptr == '\r') // Unix, Mac
        {
            res.push_back( TokenAn::Token::createEos());
            ptr ++;
        }
        else if ( *ptr == '\0')
        {
            res.push_back( TokenAn::Token::createEos());
//            res.push_back( TokenAn::Token::createScalar( TOKEN_EOF));
        }
        else
        {
            std::cerr << "bad char: " << *ptr <<
                " (code: " << (int)*ptr << ")" << std::endl;
            assert(0);
        }
    }

    return res;
}

void TokenAn::skip_spaces()
{
    while ( *ptr != '\0' && isblank( *ptr))
        ptr ++;
}

TokenAn::Token *TokenAn::Token::createId( const std::string id_string)
{
    TokenAn::Token *res = new TokenAn::Token;
    res->type = TOKEN_ID;
    res->sVal = id_string;

    return res;
}

TokenAn::Token *TokenAn::Token::createConstInt( int iVal)
{
    TokenAn::Token *res = new TokenAn::Token;
    res->type = TOKEN_CONST_INT;
    res->iVal = iVal;

    return res;
}

TokenAn::Token *TokenAn::Token::createScalar( enum TOKEN_TYPE type)
{
    TokenAn::Token *res = new TokenAn::Token;
    res->type = type;

    return res;
}

TokenAn::Token *TokenAn::Token::createEos() // end of line
{
    return createScalar( TOKEN_EOS);
}

void TokenAn::Token::dump()
{
    switch ( type)
    {
    case TOKEN_ID:        std::cout << sVal; break;
    case TOKEN_EOS:       std::cout << "--------------- (\\n)"; break;
    case TOKEN_COMMA:     std::cout << ","; break;
    case TOKEN_LBRACKET:  std::cout << "("; break;
    case TOKEN_RBRACKET:  std::cout << ")"; break;
    case TOKEN_CONST_INT: std::cout << iVal; break;
    case TOKEN_COLON:     std::cout << ":"; break;
    default: throw;
    }
}

<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/filerepository.h"
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/random.h"
#include "fnord-base/thread/eventloop.h"
#include "fnord-base/thread/threadpool.h"
#include "fnord-base/wallclock.h"
#include "fnord-base/VFS.h"
#include "fnord-rpc/ServerGroup.h"
#include "fnord-rpc/RPC.h"
#include "fnord-rpc/RPCClient.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-json/json.h"
#include "fnord-json/jsonrpc.h"
#include "fnord-http/httprouter.h"
#include "fnord-http/httpserver.h"
#include "fnord-http/VFSFileServlet.h"
#include "fnord-feeds/FeedService.h"
#include "fnord-feeds/RemoteFeedFactory.h"
#include "fnord-feeds/RemoteFeedReader.h"
#include "fnord-base/stats/statsdagent.h"
#include "fnord-sstable/SSTableServlet.h"
#include "fnord-eventdb/EventDBServlet.h"
#include "fnord-eventdb/TableRepository.h"
#include "fnord-eventdb/TableJanitor.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "analytics/AnalyticsServlet.h"
#include "analytics/CTRByPageServlet.h"
#include "analytics/CTRStatsServlet.h"
#include "analytics/CTRByPositionQuery.h"
#include "analytics/CTRByPageQuery.h"
#include "analytics/TopSearchQueriesQuery.h"
#include "analytics/DiscoveryKPIQuery.h"
#include "analytics/DiscoveryCategoryStatsQuery.h"
#include "analytics/AnalyticsQueryEngine.h"
#include "analytics/AnalyticsQueryEngine.h"

using namespace fnord;

std::atomic<bool> shutdown_sig;
fnord::thread::EventLoop ev;

void quit(int n) {
  shutdown_sig = true;
  fnord::logInfo("cm.repotserver", "Shutting down...");
  // FIXPAUL: wait for http server stop...
  ev.shutdown();
}

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  /* shutdown hook */
  shutdown_sig = false;
  struct sigaction sa;
  memset(&sa, 0, sizeof(struct sigaction));
  sa.sa_handler = quit;
  sigaction(SIGTERM, &sa, NULL);
  sigaction(SIGQUIT, &sa, NULL);
  sigaction(SIGINT, &sa, NULL);

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "http_port",
      fnord::cli::FlagParser::T_INTEGER,
      false,
      NULL,
      "8000",
      "Start the public http server on this port",
      "<port>");

  flags.defineFlag(
      "replica",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "replica id",
      "<id>");

  flags.defineFlag(
      "artifacts",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "artifacts path",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  WhitelistVFS vfs;

  /* start http server */
  fnord::thread::ThreadPool tpool;
  fnord::http::HTTPRouter http_router;
  fnord::http::HTTPServer http_server(&http_router, &ev);
  http_server.listen(flags.getInt("http_port"));

  /* sstable servlet */
  sstable::SSTableServlet sstable_servlet("/sstable", &vfs);
  http_router.addRouteByPrefixMatch("/sstable", &sstable_servlet);

  /* file servlet */
  http::VFSFileServlet file_servlet("/file", &vfs);
  http_router.addRouteByPrefixMatch("/file", &file_servlet);

  /* add all files to whitelist vfs */
  auto dir = flags.getString("artifacts");
  FileUtil::ls(dir, [&vfs, &dir] (const String& file) -> bool {
    vfs.registerFile(file, FileUtil::joinPaths(dir, file));
    fnord::logInfo("cm.reportserver", "[VFS] Adding file: $0", file);
    return true;
  });

  /* eventdb */
  auto replica = flags.getString("replica");

  eventdb::TableRepository table_repo;
  table_repo.addTable(
      eventdb::Table::open(
          "dawanda_joined_sessions",
          replica,
          dir,
          joinedSessionsSchema()));

  eventdb::TableJanitor table_janitor(&table_repo);
  table_janitor.start();

  eventdb::EventDBServlet eventdb_servlet(&table_repo);

  /* analytics */
  cm::AnalyticsQueryEngine analytics(8, dir);
  cm::AnalyticsServlet analytics_servlet(&analytics);
  http_router.addRouteByPrefixMatch("/analytics", &analytics_servlet, &tpool);
  http_router.addRouteByPrefixMatch("/eventdb", &eventdb_servlet, &tpool);

  analytics.registerQueryFactory("ctr_by_position", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::CTRByPositionQuery(scan, segments);
  });

  analytics.registerQueryFactory("ctr_by_page", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::CTRByPageQuery(scan, segments);
  });

  analytics.registerQueryFactory("discovery_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryKPIQuery(
        scan,
        segments,
        query.start_time,
        query.end_time);
  });

  analytics.registerQueryFactory("discovery_category0_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category1",
        "queries.category1",
        params);
  });

  analytics.registerQueryFactory("discovery_category1_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category1",
        "queries.category2",
        params);
  });

  analytics.registerQueryFactory("discovery_category2_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category2",
        "queries.category3",
        params);
  });

  analytics.registerQueryFactory("discovery_category3_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category3",
        "queries.category3",
        params);
  });

  analytics.registerQueryFactory("top_search_queries", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::TopSearchQueriesQuery(scan, segments, params);
  });

  ev.run();

  table_janitor.stop();
  table_janitor.check();
  fnord::logInfo("cm.repotserver", "Exiting...");

  return 0;
}

<commit_msg>typo fix<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/filerepository.h"
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/random.h"
#include "fnord-base/thread/eventloop.h"
#include "fnord-base/thread/threadpool.h"
#include "fnord-base/wallclock.h"
#include "fnord-base/VFS.h"
#include "fnord-rpc/ServerGroup.h"
#include "fnord-rpc/RPC.h"
#include "fnord-rpc/RPCClient.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-json/json.h"
#include "fnord-json/jsonrpc.h"
#include "fnord-http/httprouter.h"
#include "fnord-http/httpserver.h"
#include "fnord-http/VFSFileServlet.h"
#include "fnord-feeds/FeedService.h"
#include "fnord-feeds/RemoteFeedFactory.h"
#include "fnord-feeds/RemoteFeedReader.h"
#include "fnord-base/stats/statsdagent.h"
#include "fnord-sstable/SSTableServlet.h"
#include "fnord-eventdb/EventDBServlet.h"
#include "fnord-eventdb/TableRepository.h"
#include "fnord-eventdb/TableJanitor.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "analytics/AnalyticsServlet.h"
#include "analytics/CTRByPageServlet.h"
#include "analytics/CTRStatsServlet.h"
#include "analytics/CTRByPositionQuery.h"
#include "analytics/CTRByPageQuery.h"
#include "analytics/TopSearchQueriesQuery.h"
#include "analytics/DiscoveryKPIQuery.h"
#include "analytics/DiscoveryCategoryStatsQuery.h"
#include "analytics/AnalyticsQueryEngine.h"
#include "analytics/AnalyticsQueryEngine.h"

using namespace fnord;

std::atomic<bool> shutdown_sig;
fnord::thread::EventLoop ev;

void quit(int n) {
  shutdown_sig = true;
  fnord::logInfo("cm.reportserver", "Shutting down...");
  // FIXPAUL: wait for http server stop...
  ev.shutdown();
}

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  /* shutdown hook */
  shutdown_sig = false;
  struct sigaction sa;
  memset(&sa, 0, sizeof(struct sigaction));
  sa.sa_handler = quit;
  sigaction(SIGTERM, &sa, NULL);
  sigaction(SIGQUIT, &sa, NULL);
  sigaction(SIGINT, &sa, NULL);

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "http_port",
      fnord::cli::FlagParser::T_INTEGER,
      false,
      NULL,
      "8000",
      "Start the public http server on this port",
      "<port>");

  flags.defineFlag(
      "replica",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "replica id",
      "<id>");

  flags.defineFlag(
      "artifacts",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "artifacts path",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  WhitelistVFS vfs;

  /* start http server */
  fnord::thread::ThreadPool tpool;
  fnord::http::HTTPRouter http_router;
  fnord::http::HTTPServer http_server(&http_router, &ev);
  http_server.listen(flags.getInt("http_port"));

  /* sstable servlet */
  sstable::SSTableServlet sstable_servlet("/sstable", &vfs);
  http_router.addRouteByPrefixMatch("/sstable", &sstable_servlet);

  /* file servlet */
  http::VFSFileServlet file_servlet("/file", &vfs);
  http_router.addRouteByPrefixMatch("/file", &file_servlet);

  /* add all files to whitelist vfs */
  auto dir = flags.getString("artifacts");
  FileUtil::ls(dir, [&vfs, &dir] (const String& file) -> bool {
    vfs.registerFile(file, FileUtil::joinPaths(dir, file));
    fnord::logInfo("cm.reportserver", "[VFS] Adding file: $0", file);
    return true;
  });

  /* eventdb */
  auto replica = flags.getString("replica");

  eventdb::TableRepository table_repo;
  table_repo.addTable(
      eventdb::Table::open(
          "dawanda_joined_sessions",
          replica,
          dir,
          joinedSessionsSchema()));

  eventdb::TableJanitor table_janitor(&table_repo);
  table_janitor.start();

  eventdb::EventDBServlet eventdb_servlet(&table_repo);

  /* analytics */
  cm::AnalyticsQueryEngine analytics(8, dir);
  cm::AnalyticsServlet analytics_servlet(&analytics);
  http_router.addRouteByPrefixMatch("/analytics", &analytics_servlet, &tpool);
  http_router.addRouteByPrefixMatch("/eventdb", &eventdb_servlet, &tpool);

  analytics.registerQueryFactory("ctr_by_position", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::CTRByPositionQuery(scan, segments);
  });

  analytics.registerQueryFactory("ctr_by_page", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::CTRByPageQuery(scan, segments);
  });

  analytics.registerQueryFactory("discovery_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryKPIQuery(
        scan,
        segments,
        query.start_time,
        query.end_time);
  });

  analytics.registerQueryFactory("discovery_category0_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category1",
        "queries.category1",
        params);
  });

  analytics.registerQueryFactory("discovery_category1_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category1",
        "queries.category2",
        params);
  });

  analytics.registerQueryFactory("discovery_category2_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category2",
        "queries.category3",
        params);
  });

  analytics.registerQueryFactory("discovery_category3_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category3",
        "queries.category3",
        params);
  });

  analytics.registerQueryFactory("top_search_queries", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::TopSearchQueriesQuery(scan, segments, params);
  });

  ev.run();

  table_janitor.stop();
  table_janitor.check();
  fnord::logInfo("cm.reportserver", "Exiting...");

  return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010 Digital Bazaar, Inc. All rights reserved.
 */
#define __STDC_CONSTANT_MACROS

#include <cstdlib>
#include <cstdio>

#include "monarch/app/App.h"
#include "monarch/app/AppPluginFactory.h"
#include "monarch/app/ConfigPlugin.h"
#include "monarch/app/LoggingPlugin.h"
#include "monarch/app/MonarchPlugin.h"
#include "monarch/app/KernelPlugin.h"
#include "monarch/data/json/JsonWriter.h"
#include "monarch/event/EventWaiter.h"
#include "monarch/logging/Logging.h"
#include "monarch/validation/Validation.h"

#include "monarch/app/KernelPlugin.h"

using namespace std;
using namespace monarch::app;
using namespace monarch::config;
using namespace monarch::data::json;
using namespace monarch::event;
using namespace monarch::fiber;
using namespace monarch::io;
using namespace monarch::kernel;
using namespace monarch::logging;
using namespace monarch::modest;
using namespace monarch::net;
using namespace monarch::rt;
namespace v = monarch::validation;

#define PLUGIN_NAME "monarch.app.Kernel"
#define PLUGIN_CL_CFG_ID PLUGIN_NAME ".commandLine"

#define SHUTDOWN_EVENT_TYPE "monarch.kernel.Kernel.shutdown"
#define RESTART_EVENT_TYPE "monarch.kernel.Kernel.restart"

KernelPlugin::KernelPlugin() :
   mState(Stopped),
   mKernel(NULL)
{
}

KernelPlugin::~KernelPlugin()
{
}

bool KernelPlugin::initMetaConfig(Config& meta)
{
   bool rval = monarch::app::AppPlugin::initMetaConfig(meta);

   // defaults
   if(rval)
   {
      Config& c =
         App::makeMetaConfig(meta, PLUGIN_NAME ".defaults", "defaults")
            [ConfigManager::MERGE][PLUGIN_NAME];
      // modulePath is an array of module paths
      c["modulePath"]->setType(Array);
      c["env"] = true;
      c["printModuleVersions"] = false;
      c["maxThreadCount"] = (uint32_t)100;
      c["maxConnectionCount"] = (uint32_t)100;
      // waitEvents is a map of arrays of event ids. The map keys should be
      // unique such as plugin ids. The kernel will wait for all these events
      // to occur before exiting. (Some special kernel events also can cause
      // a quicker exit.)
      c["waitEvents"]->setType(Map);
   }

   // command line options
   if(rval)
   {
      Config& c = App::makeMetaConfig(
         meta, PLUGIN_CL_CFG_ID, "command line", "options")
            [ConfigManager::APPEND][PLUGIN_NAME];
      c["modulePath"]->setType(Array);
   }

   return rval;
}

DynamicObject KernelPlugin::getCommandLineSpecs()
{
   DynamicObject spec;
   spec["help"] =
"Module options:\n"
"  -m, --module-path PATH\n"
"                      A colon separated list of modules or directories where\n"
"                      modules are stored. May be specified multiple times.\n"
"                      Loaded after modules in MONARCH_MODULE_PATH.\n"
"      --no-module-path-env\n"
"                      Disable MONARCH_MODULE_PATH.\n"
"      --module-versions\n"
"                      Prints the module versions.\n"
"\n";

   DynamicObject opt;
   Config& options = getApp()->getMetaConfig()
      ["options"][PLUGIN_CL_CFG_ID][ConfigManager::MERGE];
   Config& configOptions = options[PLUGIN_NAME];

   opt = spec["options"]->append();
   opt["short"] = "-m";
   opt["long"] = "--module-path";
   opt["append"] = configOptions["modulePath"];
   opt["argError"] = "No path specified.";

   opt = spec["options"]->append();
   opt["long"] = "--no-module-path-env";
   opt["setFalse"]["root"] = configOptions;
   opt["setFalse"]["path"] = "env";

   opt = spec["options"]->append();
   opt["long"] = "--module-versions";
   opt["setTrue"]["root"] = configOptions;
   opt["setTrue"]["path"] = "printModuleVersions";

   DynamicObject specs = AppPlugin::getCommandLineSpecs();
   specs->append(spec);
   return specs;
}

/**
 * Validates the wait events.
 *
 * @param waitEvents the wait events.
 *
 * @return true if successful, false if an exception occurred.
 */
static bool _validateWaitEvents(DynamicObject& waitEvents)
{
   bool rval = false;

   // create validator for node configuration
   v::ValidatorRef v = new v::All(
      new v::Type(Array),
      new v::Each(
         new v::Map(
            "id", new v::Type(String),
            "type", new v::Type(String),
            NULL)),
      NULL);

   rval = v->isValid(waitEvents);
   if(!rval)
   {
      ExceptionRef e = new Exception(
         "Invalid AppPlugin wait event configuration.",
         "monarch.app.Kernel.InvalidWaitEvents");
      e->getDetails()["waitEvents"] = waitEvents;
      Exception::push(e);
   }

   return rval;
}

bool KernelPlugin::didParseCommandLine()
{
   bool rval = AppPlugin::didParseCommandLine();

   // process flags
   // only done after bootstrap mode so that all modules info is available
   if(rval && getApp()->getMode() != App::BOOTSTRAP)
   {
      Config& cfg = getApp()->getMetaConfig()
         ["options"][PLUGIN_CL_CFG_ID][ConfigManager::MERGE][PLUGIN_NAME];

      if(cfg->hasMember("printModuleVersions") &&
         cfg["printModuleVersions"]->getBoolean())
      {
         // FIXME: print out module info
         /*
         printf("%s v%s\n", ...);
         // Raise known exit exception.
         ExceptionRef e = new Exception(
            "Module versions printed.",
            "monarch.app.Exit", EXIT_SUCCESS);
         Exception::set(e);
         rval = false;
         */
         ExceptionRef e = new Exception(
            "Not implemented.",
            "monarch.app.NotImplemented", EXIT_FAILURE);
         Exception::set(e);
         rval = false;
      }
   }

   return rval;
}

bool KernelPlugin::runApp()
{
   bool rval = true;

   mState = Starting;
   while(mState == Starting || mState == Restarting)
   {
      // [re]start the node
      MO_CAT_INFO(MO_KERNEL_CAT,
         (mState == Restarting) ?
            "Restarting kernel..." : "Starting kernel...");

      // get kernel config
      Config cfg = getApp()->getConfig()[PLUGIN_NAME];
      App* app = new App;

      // create and start kernel
      mKernel = new MicroKernel();
      mKernel->setConfigManager(app->getConfigManager(), false);
      mKernel->setFiberScheduler(new FiberScheduler(), true);
      mKernel->setFiberMessageCenter(new FiberMessageCenter(), true);
      mKernel->setEventController(new EventController(), true);
      mKernel->setEventDaemon(new EventDaemon(), true);
      mKernel->setServer(new Server(), true);

      // set thread and connection limits
      mKernel->setMaxAuxiliaryThreads(cfg["maxThreadCount"]->getUInt32());
      mKernel->setMaxServerConnections(cfg["maxConnectionCount"]->getUInt32());

      rval = mKernel->start();
      if(rval)
      {
         rval =
            mKernel->loadModule(
               createMonarchPluginFactory, freeAppPluginFactory) &&
            mKernel->loadModule(
               createConfigPluginFactory, freeAppPluginFactory) &&
            mKernel->loadModule(
               createLoggingPluginFactory, freeAppPluginFactory) &&
            mKernel->loadModule(
               createKernelPluginFactory, freeAppPluginFactory);

         // FIXME: in did load configs should add env paths to config

         // Collect all module paths so they can be loaded in bulk.
         // This helps to avoid issues with needing to specify load order
         // explicitly.
         FileList modulePaths;
         ConfigIterator mpi = cfg["modulePath"].getIterator();
         while(rval && mpi->hasNext())
         {
            const char* path = mpi->next()->getString();
            FileList pathList = File::parsePath(path);
            modulePaths->concat(*pathList);
         }
         // load all module paths at once
         rval = mKernel->loadModules(modulePaths);

         if(!rval)
         {
            MO_CAT_INFO(MO_KERNEL_CAT, "Stopping kernel due to exception.");
            mKernel->stop();
         }
      }
      mState = Running;

      if(rval)
      {
         MO_CAT_INFO(MO_KERNEL_CAT, "Kernel started.");

         // send ready event
         {
            Event e;
            e["type"] = "monarch.kernel.Kernel.ready";
            mKernel->getEventController()->schedule(e);
         }

         if(rval)
         {
            {
               // create AppPlugins from all loaded AppPluginFactories
               MicroKernel::ModuleApiList factories;
               mKernel->getModuleApisByType(
                  "monarch.app.AppPluginFactory", factories);
               for(MicroKernel::ModuleApiList::iterator i = factories.begin();
                  rval && i != factories.end(); i++)
               {
                  ModuleId id = dynamic_cast<Module*>(*i)->getId();
                  AppPluginFactory* f = dynamic_cast<AppPluginFactory*>(*i);
                  AppPluginRef p = f->createAppPlugin();
                  MO_CAT_INFO(MO_KERNEL_CAT,
                     "Adding AppPlugin to App: %s v%s.", id.name, id.version);
                  rval = app->addPlugin(p);
               }
            }

            // waiter for kernel and plugin events
            // used to wait for plugins to complete or for kernel control events
            EventWaiter waiter(mKernel->getEventController());
            // wait for generic kernel events
            MO_CAT_INFO(MO_KERNEL_CAT,
               "EventWaiter: kernel waiting on \"%s\"", SHUTDOWN_EVENT_TYPE);
            waiter.start(SHUTDOWN_EVENT_TYPE);
            MO_CAT_INFO(MO_KERNEL_CAT,
               "EventWaiter: kernel waiting on \"%s\"", RESTART_EVENT_TYPE);
            waiter.start(RESTART_EVENT_TYPE);

            // make a map of event types to waiting ids
            DynamicObject waitEvents;
            waitEvents->setType(Map);
            {
               // array of events and counts
               DynamicObject appWaitEvents = app->getWaitEvents();
               rval = _validateWaitEvents(appWaitEvents);
               DynamicObjectIterator i = appWaitEvents.getIterator();
               while(rval && i->hasNext())
               {
                  DynamicObject next = i->next();
                  const char* id = next["id"]->getString();
                  const char* type = next["type"]->getString();
                  if(!waitEvents->hasMember(type))
                  {
                     DynamicObject newInfo;
                     newInfo["ids"]->setType(Array);
                     waitEvents[type] = newInfo;
                  }
                  DynamicObject newId;
                  newId = id;
                  waitEvents[type]["ids"]->append(newId);
                  // start waiting for event
                  MO_CAT_INFO(MO_KERNEL_CAT,
                     "EventWaiter: \"%s\" waiting on \"%s\"", id, type);
                  waiter.start(type);
               }
            }

            int status;
            if(rval)
            {
               // run sub app
               status = app->start(getApp()->getCommandLine());
               rval = (status == EXIT_SUCCESS);
            }

            // wait for events if app started successfully
            // checking for exception in case of success with an exit exception
            if(rval && !Exception::isSet())
            {
               while(mState == Running && waitEvents->length() != 0)
               {
                  waiter.waitForEvent();
                  Event e = waiter.popEvent();
                  const char* type = e["type"]->getString();
                  MO_CAT_INFO(MO_KERNEL_CAT,
                     "EventWaiter got event: %s", type);
                  if(strcmp(SHUTDOWN_EVENT_TYPE, type) == 0)
                  {
                     mState = Stopping;
                  }
                  else if(strcmp(RESTART_EVENT_TYPE, type) == 0)
                  {
                     mState = Restarting;
                  }
                  else
                  {
                     if(waitEvents->hasMember(type))
                     {
                        waitEvents->removeMember(type);
                     }
                  }
               }
               mState = Stopping;
            }

            if(!rval)
            {
               getApp()->setExitStatus(app->getExitStatus());
            }
         }

         delete app;
         app = NULL;

         // FIXME: actually stopping microkernel, not just node
         // stop node
         MO_CAT_INFO(MO_KERNEL_CAT,
            (mState == Restarting) ?
               "Stopping kernel for restart..." :
               "Stopping kernel...");
         mKernel->stop();
         MO_CAT_INFO(MO_KERNEL_CAT, "Kernel stopped.");
         // set to stopped unless restarting
         mState = (mState == Stopping) ? Stopped : mState;
      }
      else
      {
         MO_CAT_ERROR(MO_KERNEL_CAT, "Kernel start failed: %s",
            JsonWriter::writeToString(Exception::getAsDynamicObject()).c_str());
      }

      if(app != NULL)
      {
         delete app;
         app = NULL;
      }

      // clean up kernel
      delete mKernel;
      mKernel = NULL;
   }

   return rval;
}

bool KernelPlugin::run()
{
   bool rval = AppPlugin::run();
   if(rval && getApp()->getMode() == App::BOOTSTRAP)
   {
      rval = runApp();
   }
   return rval;
}

class KernelPluginFactory :
   public AppPluginFactory
{
public:
   KernelPluginFactory() :
      AppPluginFactory(PLUGIN_NAME, "1.0")
   {
      addDependency("monarch.app.Config", "1.0");
      addDependency("monarch.app.Logging", "1.0");
   }

   virtual ~KernelPluginFactory() {}

   virtual AppPluginRef createAppPlugin()
   {
      return new KernelPlugin();
   }
};

Module* monarch::app::createKernelPluginFactory()
{
   return new KernelPluginFactory();
}
<commit_msg>Fixed command line option handling.<commit_after>/*
 * Copyright (c) 2010 Digital Bazaar, Inc. All rights reserved.
 */
#define __STDC_CONSTANT_MACROS

#include <cstdlib>
#include <cstdio>

#include "monarch/app/App.h"
#include "monarch/app/AppPluginFactory.h"
#include "monarch/app/ConfigPlugin.h"
#include "monarch/app/LoggingPlugin.h"
#include "monarch/app/MonarchPlugin.h"
#include "monarch/app/KernelPlugin.h"
#include "monarch/data/json/JsonWriter.h"
#include "monarch/event/EventWaiter.h"
#include "monarch/logging/Logging.h"
#include "monarch/validation/Validation.h"

#include "monarch/app/KernelPlugin.h"

using namespace std;
using namespace monarch::app;
using namespace monarch::config;
using namespace monarch::data::json;
using namespace monarch::event;
using namespace monarch::fiber;
using namespace monarch::io;
using namespace monarch::kernel;
using namespace monarch::logging;
using namespace monarch::modest;
using namespace monarch::net;
using namespace monarch::rt;
namespace v = monarch::validation;

#define PLUGIN_NAME "monarch.app.Kernel"
#define PLUGIN_CL_CFG_ID PLUGIN_NAME ".commandLine"

#define SHUTDOWN_EVENT_TYPE "monarch.kernel.Kernel.shutdown"
#define RESTART_EVENT_TYPE "monarch.kernel.Kernel.restart"

KernelPlugin::KernelPlugin() :
   mState(Stopped),
   mKernel(NULL)
{
}

KernelPlugin::~KernelPlugin()
{
}

bool KernelPlugin::initMetaConfig(Config& meta)
{
   bool rval = monarch::app::AppPlugin::initMetaConfig(meta);

   // defaults
   if(rval)
   {
      Config& c =
         App::makeMetaConfig(meta, PLUGIN_NAME ".defaults", "defaults")
            [ConfigManager::MERGE][PLUGIN_NAME];
      // modulePath is an array of module paths
      c["modulePath"]->setType(Array);
      c["env"] = true;
      c["printModuleVersions"] = false;
      c["maxThreadCount"] = (uint32_t)100;
      c["maxConnectionCount"] = (uint32_t)100;
      // waitEvents is a map of arrays of event ids. The map keys should be
      // unique such as plugin ids. The kernel will wait for all these events
      // to occur before exiting. (Some special kernel events also can cause
      // a quicker exit.)
      c["waitEvents"]->setType(Map);
   }

   // command line options
   if(rval)
   {
      Config c = App::makeMetaConfig(
         meta, PLUGIN_CL_CFG_ID, "command line", "options");
      c[ConfigManager::APPEND][PLUGIN_NAME]["modulePath"]->setType(Array);
      c[ConfigManager::MERGE][PLUGIN_NAME]->setType(Map);
   }

   return rval;
}

DynamicObject KernelPlugin::getCommandLineSpecs()
{
   DynamicObject spec;
   spec["help"] =
"Module options:\n"
"  -m, --module-path PATH\n"
"                      A colon separated list of modules or directories where\n"
"                      modules are stored. May be specified multiple times.\n"
"                      Loaded after modules in MONARCH_MODULE_PATH.\n"
"      --no-module-path-env\n"
"                      Disable MONARCH_MODULE_PATH.\n"
"      --module-versions\n"
"                      Prints the module versions.\n"
"\n";

   DynamicObject opt;
   Config& options = getApp()->getMetaConfig()["options"][PLUGIN_CL_CFG_ID];
   Config& oa = options[ConfigManager::APPEND];
   Config& om = options[ConfigManager::MERGE];

   opt = spec["options"]->append();
   opt["short"] = "-m";
   opt["long"] = "--module-path";
   opt["append"]["root"] = oa;
   opt["append"]["path"] = PLUGIN_NAME ".modulePath";
   opt["argError"] = "No path specified.";

   opt = spec["options"]->append();
   opt["long"] = "--no-module-path-env";
   opt["setFalse"]["root"] = om;
   opt["setFalse"]["path"] = PLUGIN_NAME ".env";

   opt = spec["options"]->append();
   opt["long"] = "--module-versions";
   opt["setTrue"]["root"] = om;
   opt["setTrue"]["path"] = PLUGIN_NAME ".printModuleVersions";

   DynamicObject specs = AppPlugin::getCommandLineSpecs();
   specs->append(spec);
   return specs;
}

/**
 * Validates the wait events.
 *
 * @param waitEvents the wait events.
 *
 * @return true if successful, false if an exception occurred.
 */
static bool _validateWaitEvents(DynamicObject& waitEvents)
{
   bool rval = false;

   // create validator for node configuration
   v::ValidatorRef v = new v::All(
      new v::Type(Array),
      new v::Each(
         new v::Map(
            "id", new v::Type(String),
            "type", new v::Type(String),
            NULL)),
      NULL);

   rval = v->isValid(waitEvents);
   if(!rval)
   {
      ExceptionRef e = new Exception(
         "Invalid AppPlugin wait event configuration.",
         "monarch.app.Kernel.InvalidWaitEvents");
      e->getDetails()["waitEvents"] = waitEvents;
      Exception::push(e);
   }

   return rval;
}

bool KernelPlugin::didParseCommandLine()
{
   bool rval = AppPlugin::didParseCommandLine();

   // process flags
   // only done after bootstrap mode so that all modules info is available
   if(rval && getApp()->getMode() != App::BOOTSTRAP)
   {
      Config& cfg = getApp()->getMetaConfig()
         ["options"][PLUGIN_CL_CFG_ID][ConfigManager::MERGE][PLUGIN_NAME];

      if(cfg->hasMember("printModuleVersions") &&
         cfg["printModuleVersions"]->getBoolean())
      {
         // FIXME: print out module info
         /*
         printf("%s v%s\n", ...);
         // Raise known exit exception.
         ExceptionRef e = new Exception(
            "Module versions printed.",
            "monarch.app.Exit", EXIT_SUCCESS);
         Exception::set(e);
         rval = false;
         */
         ExceptionRef e = new Exception(
            "Not implemented.",
            "monarch.app.NotImplemented", EXIT_FAILURE);
         Exception::set(e);
         rval = false;
      }
   }

   return rval;
}

bool KernelPlugin::runApp()
{
   bool rval = true;

   mState = Starting;
   while(mState == Starting || mState == Restarting)
   {
      // [re]start the node
      MO_CAT_INFO(MO_KERNEL_CAT,
         (mState == Restarting) ?
            "Restarting kernel..." : "Starting kernel...");

      // get kernel config
      Config cfg = getApp()->getConfig()[PLUGIN_NAME];
      App* app = new App;

      // create and start kernel
      mKernel = new MicroKernel();
      mKernel->setConfigManager(app->getConfigManager(), false);
      mKernel->setFiberScheduler(new FiberScheduler(), true);
      mKernel->setFiberMessageCenter(new FiberMessageCenter(), true);
      mKernel->setEventController(new EventController(), true);
      mKernel->setEventDaemon(new EventDaemon(), true);
      mKernel->setServer(new Server(), true);

      // set thread and connection limits
      mKernel->setMaxAuxiliaryThreads(cfg["maxThreadCount"]->getUInt32());
      mKernel->setMaxServerConnections(cfg["maxConnectionCount"]->getUInt32());

      rval = mKernel->start();
      if(rval)
      {
         rval =
            mKernel->loadModule(
               createMonarchPluginFactory, freeAppPluginFactory) &&
            mKernel->loadModule(
               createConfigPluginFactory, freeAppPluginFactory) &&
            mKernel->loadModule(
               createLoggingPluginFactory, freeAppPluginFactory) &&
            mKernel->loadModule(
               createKernelPluginFactory, freeAppPluginFactory);

         // FIXME: in did load configs should add env paths to config

         // Collect all module paths so they can be loaded in bulk.
         // This helps to avoid issues with needing to specify load order
         // explicitly.
         FileList modulePaths;
         ConfigIterator mpi = cfg["modulePath"].getIterator();
         while(rval && mpi->hasNext())
         {
            const char* path = mpi->next()->getString();
            FileList pathList = File::parsePath(path);
            modulePaths->concat(*pathList);
         }
         // load all module paths at once
         rval = mKernel->loadModules(modulePaths);

         if(!rval)
         {
            MO_CAT_INFO(MO_KERNEL_CAT, "Stopping kernel due to exception.");
            mKernel->stop();
         }
      }
      mState = Running;

      if(rval)
      {
         MO_CAT_INFO(MO_KERNEL_CAT, "Kernel started.");

         // send ready event
         {
            Event e;
            e["type"] = "monarch.kernel.Kernel.ready";
            mKernel->getEventController()->schedule(e);
         }

         if(rval)
         {
            {
               // create AppPlugins from all loaded AppPluginFactories
               MicroKernel::ModuleApiList factories;
               mKernel->getModuleApisByType(
                  "monarch.app.AppPluginFactory", factories);
               for(MicroKernel::ModuleApiList::iterator i = factories.begin();
                  rval && i != factories.end(); i++)
               {
                  ModuleId id = dynamic_cast<Module*>(*i)->getId();
                  AppPluginFactory* f = dynamic_cast<AppPluginFactory*>(*i);
                  AppPluginRef p = f->createAppPlugin();
                  MO_CAT_INFO(MO_KERNEL_CAT,
                     "Adding AppPlugin to App: %s v%s.", id.name, id.version);
                  rval = app->addPlugin(p);
               }
            }

            // waiter for kernel and plugin events
            // used to wait for plugins to complete or for kernel control events
            EventWaiter waiter(mKernel->getEventController());
            // wait for generic kernel events
            MO_CAT_INFO(MO_KERNEL_CAT,
               "EventWaiter: kernel waiting on \"%s\"", SHUTDOWN_EVENT_TYPE);
            waiter.start(SHUTDOWN_EVENT_TYPE);
            MO_CAT_INFO(MO_KERNEL_CAT,
               "EventWaiter: kernel waiting on \"%s\"", RESTART_EVENT_TYPE);
            waiter.start(RESTART_EVENT_TYPE);

            // make a map of event types to waiting ids
            DynamicObject waitEvents;
            waitEvents->setType(Map);
            {
               // array of events and counts
               DynamicObject appWaitEvents = app->getWaitEvents();
               rval = _validateWaitEvents(appWaitEvents);
               DynamicObjectIterator i = appWaitEvents.getIterator();
               while(rval && i->hasNext())
               {
                  DynamicObject next = i->next();
                  const char* id = next["id"]->getString();
                  const char* type = next["type"]->getString();
                  if(!waitEvents->hasMember(type))
                  {
                     DynamicObject newInfo;
                     newInfo["ids"]->setType(Array);
                     waitEvents[type] = newInfo;
                  }
                  DynamicObject newId;
                  newId = id;
                  waitEvents[type]["ids"]->append(newId);
                  // start waiting for event
                  MO_CAT_INFO(MO_KERNEL_CAT,
                     "EventWaiter: \"%s\" waiting on \"%s\"", id, type);
                  waiter.start(type);
               }
            }

            int status;
            if(rval)
            {
               // run sub app
               status = app->start(getApp()->getCommandLine());
               rval = (status == EXIT_SUCCESS);
            }

            // wait for events if app started successfully
            // checking for exception in case of success with an exit exception
            if(rval && !Exception::isSet())
            {
               while(mState == Running && waitEvents->length() != 0)
               {
                  waiter.waitForEvent();
                  Event e = waiter.popEvent();
                  const char* type = e["type"]->getString();
                  MO_CAT_INFO(MO_KERNEL_CAT,
                     "EventWaiter got event: %s", type);
                  if(strcmp(SHUTDOWN_EVENT_TYPE, type) == 0)
                  {
                     mState = Stopping;
                  }
                  else if(strcmp(RESTART_EVENT_TYPE, type) == 0)
                  {
                     mState = Restarting;
                  }
                  else
                  {
                     if(waitEvents->hasMember(type))
                     {
                        waitEvents->removeMember(type);
                     }
                  }
               }
               mState = Stopping;
            }

            if(!rval)
            {
               getApp()->setExitStatus(app->getExitStatus());
            }
         }

         delete app;
         app = NULL;

         // FIXME: actually stopping microkernel, not just node
         // stop node
         MO_CAT_INFO(MO_KERNEL_CAT,
            (mState == Restarting) ?
               "Stopping kernel for restart..." :
               "Stopping kernel...");
         mKernel->stop();
         MO_CAT_INFO(MO_KERNEL_CAT, "Kernel stopped.");
         // set to stopped unless restarting
         mState = (mState == Stopping) ? Stopped : mState;
      }
      else
      {
         MO_CAT_ERROR(MO_KERNEL_CAT, "Kernel start failed: %s",
            JsonWriter::writeToString(Exception::getAsDynamicObject()).c_str());
      }

      if(app != NULL)
      {
         delete app;
         app = NULL;
      }

      // clean up kernel
      delete mKernel;
      mKernel = NULL;
   }

   return rval;
}

bool KernelPlugin::run()
{
   bool rval = AppPlugin::run();
   if(rval && getApp()->getMode() == App::BOOTSTRAP)
   {
      rval = runApp();
   }
   return rval;
}

class KernelPluginFactory :
   public AppPluginFactory
{
public:
   KernelPluginFactory() :
      AppPluginFactory(PLUGIN_NAME, "1.0")
   {
      addDependency("monarch.app.Config", "1.0");
      addDependency("monarch.app.Logging", "1.0");
   }

   virtual ~KernelPluginFactory() {}

   virtual AppPluginRef createAppPlugin()
   {
      return new KernelPlugin();
   }
};

Module* monarch::app::createKernelPluginFactory()
{
   return new KernelPluginFactory();
}
<|endoftext|>


<commit_before>#include <QColorDialog>

#include <qlayout/qeffectdescription.h>
#include <qlayout/qeffectdescriptionedit.h>

QEffectDescriptionEdit::QEffectDescriptionEdit(QWidget* parent, Qt::WindowFlags f)
  : QWidget(parent, f)
{
  setupUi(this);
}

QEffectDescriptionEdit::~QEffectDescriptionEdit()
{
}

void setColor(QLabel *widget, const QColor& color)
{
  QPalette palette(color);
  palette.setColor(QPalette::Base, color);
  palette.setColor(QPalette::Background, color);
  palette.setColor(QPalette::Window, color);
  palette.setColor(QPalette::Foreground, color);
  widget->setPalette(palette);
  QImage image(widget->rect().size(), QImage::Format_ARGB32);
  image.fill(color);
  QPixmap pix = QPixmap::fromImage(image);
  widget->setPixmap(pix);

}

void QEffectDescriptionEdit::initFrom(const QEffectDescription* other, bool multiple)
{
  setColor(txtColorEnd, other->getEndColor());
  setColor(txtColorStart, other->getStartColor());

  if (multiple)
    txtObjectName->setText("");
  else
    txtObjectName->setText(other->getCN().c_str());

  txtScaleStart->setText(QString::number(other->getScaleStart()));
  txtScaleEnd->setText(QString::number(other->getScaleEnd()));

  switch(other->getMode())
  {
  case QEffectDescription::Colorize:
    radColorize->setChecked(true);
    break;
  case QEffectDescription::DropShadow:
    radShadow->setChecked(true);
    break;
  default:
  case QEffectDescription::Scale:
    radScale->setChecked(true);
    break;
  }

}

void QEffectDescriptionEdit::saveTo(QEffectDescription* other, bool /* multiple*/)
{
  other->setStartColor(txtColorStart->palette().color(QPalette::Background));
  other->setEndColor(txtColorEnd->palette().color(QPalette::Background));
  other->setScaleStart(txtScaleStart->text().toDouble());
  other->setScaleEnd(txtScaleEnd->text().toDouble());

  if (radColorize->isChecked())
    other->setMode(QEffectDescription::Colorize);
  else if (radShadow->isChecked())
    other->setMode(QEffectDescription::DropShadow);
  else
    other->setMode(QEffectDescription::Scale);

}

QEffectDescription* QEffectDescriptionEdit::toDescription() const
{
  QEffectDescription *result = new QEffectDescription(txtObjectName->text().toStdString());

  result->setStartColor(txtColorStart->palette().color(QPalette::Background));
  result->setEndColor(txtColorEnd->palette().color(QPalette::Background));
  result->setScaleStart(txtScaleStart->text().toDouble());
  result->setScaleEnd(txtScaleEnd->text().toDouble());

  if (radColorize->isChecked())
    result->setMode(QEffectDescription::Colorize);
  else if (radShadow->isChecked())
    result->setMode(QEffectDescription::DropShadow);
  else
    result->setMode(QEffectDescription::Scale);

  return result;
}

void QEffectDescriptionEdit::slotModeChanged()
{
}

void QEffectDescriptionEdit::slotScaleEndChanged(QString)
{
}

void QEffectDescriptionEdit::slotScaleStartChanged(QString)
{
}

void QEffectDescriptionEdit::slotSelectObject()
{
}

void QEffectDescriptionEdit::slotSelectColorEnd()
{
  setColor(txtColorEnd, QColorDialog::getColor(txtColorEnd->palette().color(QPalette::Background), this));
}

void QEffectDescriptionEdit::slotSelectColorStart()
{
  setColor(txtColorStart, QColorDialog::getColor(txtColorStart->palette().color(QPalette::Background), this));
}
<commit_msg>- fix compile error on qt 4.7<commit_after>// Copyright (C) 2013 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include <QColorDialog>

#include <qlayout/qeffectdescription.h>
#include <qlayout/qeffectdescriptionedit.h>

#if QT_VERSION < 40800
#include <QPainter>
#endif

QEffectDescriptionEdit::QEffectDescriptionEdit(QWidget* parent, Qt::WindowFlags f)
  : QWidget(parent, f)
{
  setupUi(this);
}

QEffectDescriptionEdit::~QEffectDescriptionEdit()
{
}

void setColor(QLabel *widget, const QColor& color)
{
  QPalette palette(color);
  palette.setColor(QPalette::Base, color);
  palette.setColor(QPalette::Background, color);
  palette.setColor(QPalette::Window, color);
  palette.setColor(QPalette::Foreground, color);
  widget->setPalette(palette);
  QImage image(widget->rect().size(), QImage::Format_ARGB32);

#if QT_VERSION >= 40800
  image.fill(color);
#else
  QPainter painter(&image);
  painter.fillRect(widget->rect(), color);
#endif

  QPixmap pix = QPixmap::fromImage(image);
  widget->setPixmap(pix);
}

void QEffectDescriptionEdit::initFrom(const QEffectDescription* other, bool multiple)
{
  setColor(txtColorEnd, other->getEndColor());
  setColor(txtColorStart, other->getStartColor());

  if (multiple)
    txtObjectName->setText("");
  else
    txtObjectName->setText(other->getCN().c_str());

  txtScaleStart->setText(QString::number(other->getScaleStart()));
  txtScaleEnd->setText(QString::number(other->getScaleEnd()));

  switch (other->getMode())
    {
      case QEffectDescription::Colorize:
        radColorize->setChecked(true);
        break;

      case QEffectDescription::DropShadow:
        radShadow->setChecked(true);
        break;

      default:
      case QEffectDescription::Scale:
        radScale->setChecked(true);
        break;
    }
}

void QEffectDescriptionEdit::saveTo(QEffectDescription* other, bool /* multiple*/)
{
  other->setStartColor(txtColorStart->palette().color(QPalette::Background));
  other->setEndColor(txtColorEnd->palette().color(QPalette::Background));
  other->setScaleStart(txtScaleStart->text().toDouble());
  other->setScaleEnd(txtScaleEnd->text().toDouble());

  if (radColorize->isChecked())
    other->setMode(QEffectDescription::Colorize);
  else if (radShadow->isChecked())
    other->setMode(QEffectDescription::DropShadow);
  else
    other->setMode(QEffectDescription::Scale);
}

QEffectDescription* QEffectDescriptionEdit::toDescription() const
{
  QEffectDescription *result = new QEffectDescription(txtObjectName->text().toStdString());

  result->setStartColor(txtColorStart->palette().color(QPalette::Background));
  result->setEndColor(txtColorEnd->palette().color(QPalette::Background));
  result->setScaleStart(txtScaleStart->text().toDouble());
  result->setScaleEnd(txtScaleEnd->text().toDouble());

  if (radColorize->isChecked())
    result->setMode(QEffectDescription::Colorize);
  else if (radShadow->isChecked())
    result->setMode(QEffectDescription::DropShadow);
  else
    result->setMode(QEffectDescription::Scale);

  return result;
}

void QEffectDescriptionEdit::slotModeChanged()
{
}

void QEffectDescriptionEdit::slotScaleEndChanged(QString)
{
}

void QEffectDescriptionEdit::slotScaleStartChanged(QString)
{
}

void QEffectDescriptionEdit::slotSelectObject()
{
}

void QEffectDescriptionEdit::slotSelectColorEnd()
{
  setColor(txtColorEnd, QColorDialog::getColor(txtColorEnd->palette().color(QPalette::Background), this));
}

void QEffectDescriptionEdit::slotSelectColorStart()
{
  setColor(txtColorStart, QColorDialog::getColor(txtColorStart->palette().color(QPalette::Background), this));
}
<|endoftext|>