<commit_before>/*
For more information, please see: http://software.sci.utah.edu

The MIT License

Copyright (c) 2012 Scientific Computing and Imaging Institute,
University of Utah.

License for the specific language governing rights and limitations under
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/

#include <Interface/Modules/BrainStimulator/GenerateROIStatisticsDialog.h>
#include <Core/Algorithms/BrainStimulator/GenerateROIStatisticsAlgorithm.h>
#include <Core/Datatypes/DenseMatrix.h>
#include <boost/foreach.hpp>
#include <boost/assign/std/vector.hpp>

using namespace SCIRun::Gui;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Core::Algorithms::BrainStimulator;
using namespace SCIRun::Core::Algorithms;
using namespace SCIRun::Core::Datatypes;
using namespace boost::assign;

GenerateROIStatisticsDialog::GenerateROIStatisticsDialog(const std::string& name, ModuleStateHandle state,
  QWidget* parent /* = 0 */)
  : ModuleDialogGeneric(state, parent)
{
  setupUi(this);
  setWindowTitle(QString::fromStdString(name));
  fixSize();

  QStringList tableHeader1;  /// set default GUI parameter for upper table
  tableHeader1<<" ROI "<<" Avr. " << " Std. " << " Min. " << " Max. " << " # ";
  StatisticsOutput_tableWidget->setHorizontalHeaderLabels(tableHeader1);
  StatisticsOutput_tableWidget->setItem(0, 0, 0);
  StatisticsOutput_tableWidget->setItem(0, 1, 0);
  StatisticsOutput_tableWidget->setItem(0, 2, 0);
  StatisticsOutput_tableWidget->setItem(0, 3, 0);
  StatisticsOutput_tableWidget->setItem(0, 4, 0);
  StatisticsOutput_tableWidget->setItem(0, 5, 0);

  QStringList tableHeader2; /// set default GUI parameter for lower table
  tableHeader2<<" X "<<" Y " << " Z " << " Atlas Material # " << " Radius ";
  SpecifyROI_tabWidget->setHorizontalHeaderLabels(tableHeader2);
  SpecifyROI_tabWidget->setItem(0, 0, new QTableWidgetItem("0"));
  SpecifyROI_tabWidget->setItem(0, 1, new QTableWidgetItem("0"));
  SpecifyROI_tabWidget->setItem(0, 2, new QTableWidgetItem("0"));
  SpecifyROI_tabWidget->setItem(0, 3, new QTableWidgetItem(" "));
  SpecifyROI_tabWidget->setItem(0, 4, new QTableWidgetItem(" 0 "));

  connect(StatisticsOutput_tableWidget, SIGNAL(cellChanged(int,int)), this, SLOT(push()));
  connect(SpecifyROI_tabWidget, SIGNAL(cellChanged(int,int)), this, SLOT(push()));
}

void GenerateROIStatisticsDialog::push()
{
  if (!pulling_)
  {
    QPalette* palette = new QPalette();
    palette->setColor(QPalette::Text,Qt::red);
    StatisticsTableGroupBox->setPalette(*palette);

    /// get user specified ROI data, put it in a DenseMatrix and ship it to state
    auto X = SpecifyROI_tabWidget->item(0,0)->text().toDouble();
    auto Y = SpecifyROI_tabWidget->item(0,1)->text().toDouble();
    auto Z = SpecifyROI_tabWidget->item(0,2)->text().toDouble();
    auto material = SpecifyROI_tabWidget->item(0,3)->text().toDouble();
    auto radius = SpecifyROI_tabWidget->item(0,4)->text().toDouble();
    DenseMatrixHandle specROI(new DenseMatrix(5,1));
    (*specROI) << X, Y, Z, material, radius;

    state_->setTransientValue(GenerateROIStatisticsAlgorithm::SpecifyROI, specROI);
  }
}

void GenerateROIStatisticsDialog::pull()
{
  Pulling p(this);
  auto all_elc_values = optional_any_cast_or_default<Variable>(state_->getTransientValue(Parameters::StatisticsTableValues)).toVector();
  StatisticsOutput_tableWidget->setRowCount(static_cast<int>(all_elc_values.size()));

  //TODO: use this example to improve Variable::List syntactical sugar

  /// get the result data from the algorithm and put it in the GUI table
  for (int i=0; i<all_elc_values.size(); i++)
  {
    auto col = (all_elc_values[i]).toVector();

    int j = 0;
    BOOST_FOREACH(const AlgorithmParameter& ap, col)
    {
      auto tmpstr = ap.toString();

      auto item = new QTableWidgetItem(QString::fromStdString(tmpstr));
      item->setFlags(item->flags() & ~Qt::ItemIsEditable);
      StatisticsOutput_tableWidget->setItem(i, j, item);
      ++j;
    }
  }

  /// get the strings PhysicalUnit / CoordinateSpaceLabel from state (directly from module level) and show it above GUI tables
  std::string PhysicalUnitString = optional_any_cast_or_default<std::string>(state_->getTransientValue(Parameters::PhysicalUnitStr.name()));  /// change GUI Labels due to physical unit and used coordinate space
  if(!PhysicalUnitString.empty())
  {
    StatisticsTableGroupBox->setTitle("Statistics for ROIs: " + QString::fromStdString(PhysicalUnitString));
  }

  std::string CoordinateSpaceLabelStr = optional_any_cast_or_default<std::string>(state_->getTransientValue(Parameters::CoordinateSpaceLabelStr.name()));  /// change GUI Labels due to physical unit and used coordinate space
  if(!CoordinateSpaceLabelStr.empty())
  {
    ROITableGroupBox->setTitle("Specify ROI: " + QString::fromStdString(CoordinateSpaceLabelStr));
  }
}

<commit_msg>Fix bug with transient value casting<commit_after>/*
For more information, please see: http://software.sci.utah.edu

The MIT License

Copyright (c) 2012 Scientific Computing and Imaging Institute,
University of Utah.

License for the specific language governing rights and limitations under
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/

#include <Interface/Modules/BrainStimulator/GenerateROIStatisticsDialog.h>
#include <Core/Algorithms/BrainStimulator/GenerateROIStatisticsAlgorithm.h>
#include <Core/Datatypes/DenseMatrix.h>
#include <boost/foreach.hpp>
#include <boost/assign/std/vector.hpp>

using namespace SCIRun::Gui;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Core::Algorithms::BrainStimulator;
using namespace SCIRun::Core::Algorithms;
using namespace SCIRun::Core::Datatypes;
using namespace boost::assign;

GenerateROIStatisticsDialog::GenerateROIStatisticsDialog(const std::string& name, ModuleStateHandle state,
  QWidget* parent /* = 0 */)
  : ModuleDialogGeneric(state, parent)
{
  setupUi(this);
  setWindowTitle(QString::fromStdString(name));
  fixSize();

  QStringList tableHeader1;  /// set default GUI parameter for upper table
  tableHeader1<<" ROI "<<" Avr. " << " Std. " << " Min. " << " Max. " << " # ";
  StatisticsOutput_tableWidget->setHorizontalHeaderLabels(tableHeader1);
  StatisticsOutput_tableWidget->setItem(0, 0, 0);
  StatisticsOutput_tableWidget->setItem(0, 1, 0);
  StatisticsOutput_tableWidget->setItem(0, 2, 0);
  StatisticsOutput_tableWidget->setItem(0, 3, 0);
  StatisticsOutput_tableWidget->setItem(0, 4, 0);
  StatisticsOutput_tableWidget->setItem(0, 5, 0);

  QStringList tableHeader2; /// set default GUI parameter for lower table
  tableHeader2<<" X "<<" Y " << " Z " << " Atlas Material # " << " Radius ";
  SpecifyROI_tabWidget->setHorizontalHeaderLabels(tableHeader2);
  SpecifyROI_tabWidget->setItem(0, 0, new QTableWidgetItem("0"));
  SpecifyROI_tabWidget->setItem(0, 1, new QTableWidgetItem("0"));
  SpecifyROI_tabWidget->setItem(0, 2, new QTableWidgetItem("0"));
  SpecifyROI_tabWidget->setItem(0, 3, new QTableWidgetItem(" "));
  SpecifyROI_tabWidget->setItem(0, 4, new QTableWidgetItem(" 0 "));

  connect(StatisticsOutput_tableWidget, SIGNAL(cellChanged(int,int)), this, SLOT(push()));
  connect(SpecifyROI_tabWidget, SIGNAL(cellChanged(int,int)), this, SLOT(push()));
}

void GenerateROIStatisticsDialog::push()
{
  if (!pulling_)
  {
    QPalette* palette = new QPalette();
    palette->setColor(QPalette::Text,Qt::red);
    StatisticsTableGroupBox->setPalette(*palette);

    /// get user specified ROI data, put it in a DenseMatrix and ship it to state
    auto X = SpecifyROI_tabWidget->item(0,0)->text().toDouble();
    auto Y = SpecifyROI_tabWidget->item(0,1)->text().toDouble();
    auto Z = SpecifyROI_tabWidget->item(0,2)->text().toDouble();
    auto material = SpecifyROI_tabWidget->item(0,3)->text().toDouble();
    auto radius = SpecifyROI_tabWidget->item(0,4)->text().toDouble();
    DenseMatrixHandle specROI(new DenseMatrix(5,1));
    (*specROI) << X, Y, Z, material, radius;

    state_->setTransientValue(GenerateROIStatisticsAlgorithm::SpecifyROI, specROI);
  }
}

void GenerateROIStatisticsDialog::pull()
{
  Pulling p(this);
  auto tableHandle = optional_any_cast_or_default<VariableHandle>(state_->getTransientValue(Parameters::StatisticsTableValues));

  if (tableHandle)
  {
    auto all_elc_values = tableHandle->toVector();
    StatisticsOutput_tableWidget->setRowCount(static_cast<int>(all_elc_values.size()));

    //TODO: use this example to improve Variable::List syntactical sugar

    /// get the result data from the algorithm and put it in the GUI table
    for (int i=0; i<all_elc_values.size(); i++)
    {
      auto col = (all_elc_values[i]).toVector();

      int j = 0;
      BOOST_FOREACH(const AlgorithmParameter& ap, col)
      {
        auto tmpstr = ap.toString();

        auto item = new QTableWidgetItem(QString::fromStdString(tmpstr));
        item->setFlags(item->flags() & ~Qt::ItemIsEditable);
        StatisticsOutput_tableWidget->setItem(i, j, item);
        ++j;
      }
    }
  }
  else
  {
    // ?? log a message ? unsure.
  }

  /// get the strings PhysicalUnit / CoordinateSpaceLabel from state (directly from module level) and show it above GUI tables
  std::string PhysicalUnitString = optional_any_cast_or_default<std::string>(state_->getTransientValue(Parameters::PhysicalUnitStr));  /// change GUI Labels due to physical unit and used coordinate space
  if (!PhysicalUnitString.empty())
  {
    StatisticsTableGroupBox->setTitle("Statistics for ROIs: " + QString::fromStdString(PhysicalUnitString));
  }

  std::string CoordinateSpaceLabelStr = optional_any_cast_or_default<std::string>(state_->getTransientValue(Parameters::CoordinateSpaceLabelStr));  /// change GUI Labels due to physical unit and used coordinate space
  if (!CoordinateSpaceLabelStr.empty())
  {
    ROITableGroupBox->setTitle("Specify ROI: " + QString::fromStdString(CoordinateSpaceLabelStr));
  }
}

<|endoftext|>


<commit_before>#include <RcppArmadilloExtensions/sample.h>
using namespace Rcpp;

// [[Rcpp::depends("RcppArmadillo")]]

// multivariate normal density
// based on code by Ahmadou Dicko (http://gallery.rcpp.org/articles/dmvnorm_arma/)
// [[Rcpp::export]]
arma::vec dmvnrm_arma(arma::mat x,
                      arma::rowvec mean,
                      arma::mat sigma) {
  const double log2pi = std::log(2.0 * M_PI);
  int n = x.n_rows;
  int xdim = x.n_cols;
  arma::vec out(n);
  arma::mat rooti = arma::trans(arma::inv(trimatu(arma::chol(sigma))));
  double rootisum = arma::sum(log(rooti.diag()));
  double constants = -(static_cast<double>(xdim)/2.0) * log2pi;

  for (int i=0; i < n; i++) {
    arma::vec z = rooti * arma::trans( x.row(i) - mean) ;
    out(i)      = constants - 0.5 * arma::sum(z%z) + rootisum;
  }
  out = exp(out);
  return(out);
}

// multivariate normal random number generator
// by Ahmadou Dicko (http://gallery.rcpp.org/articles/simulate-multivariate-normal/)
// [[Rcpp::export]]
arma::mat mvrnorm_arma(int n, arma::vec mu, arma::mat sigma) {
   int ncols = sigma.n_cols;
   arma::mat Y = arma::randn(n, ncols);
   return arma::repmat(mu, 1, n).t() + Y * arma::chol(sigma);
}

// Calculate the variance covariance matrix of the full posterior assuming
// multivariate normal sub-posteriors
// [[Rcpp::export(post_vcm)]]
arma::mat post_vcm(List post_list, int d, int M) {
  arma::mat vcm_post = arma::zeros(d, d);
  for(int i = 0; i < M; ++i) {
    arma::mat post = post_list[i];
    arma::mat vcm_m = arma::cov(post);
    arma::mat vcm_m_i = arma::inv(vcm_m);
    vcm_post += vcm_m_i;
  }
  arma::mat out = arma::inv(vcm_post);
  return(out);
}

// Calculate the mean vector of the full posterior assuming
// multivariate normal sub-posteriors
// [[Rcpp::export(post_mean)]]
arma::vec post_mean(List post_list, arma::mat post_vcm, int d, int M) {
  arma::vec w_sig = arma::zeros(d, 1);
  for(int i = 0; i < M; ++i) {
    arma::mat post = post_list[i];
    arma::mat vcm_m = arma::cov(post);
    arma::rowvec mu_m = mean(post, 0);
    w_sig += inv(vcm_m) * trans(mu_m);
  }
  arma::mat out = post_vcm * w_sig;
  return(out);
}

// [[Rcpp::export(.theta_bar)]]
arma::vec theta_bar(arma::vec t, List post_list, double h, int d, int M) {
  arma::mat sel(M, d);
  for(int i = 0; i < M; ++i) {
    arma::mat postmat = post_list[i];
    sel.row(i) = postmat.row(t[i]);
  }
  arma::rowvec theta_bar = arma::mean(sel, 0);
  return trans(theta_bar);
}

// [[Rcpp::export(.mix_weight)]]
double mix_weight(arma::vec t,
                  List post_list,
                  double h,
                  int d,
                  int M,
                  arma::vec theta_b) {
  arma::mat sel(M, d);
  for(int i = 0; i < M; ++i) {
    arma::mat postmat = post_list[i];
    sel.row(i) = postmat.row(t[i]);
  }
  arma::mat sigma = arma::eye(d, d) * pow(h, 2);
  arma::vec dens = dmvnrm_arma(sel, trans(theta_b), sigma);
  double out = prod(dens);
  return out;
}

//' Non-parametric Combination of Sub-posteriors
//'
//' @param post_list A list containing the sub-posterior samples, stored in matrices
//' @return A matrix containing the samples from the sub-posterior product function
//' @export
// [[Rcpp::export]]
arma::mat combine_np(List post_list) {
  arma::mat exmpl = post_list[0];
  int d = exmpl.n_cols;
  int T = exmpl.n_rows;
  int M = post_list.size();
  arma::vec Ts(T);
  for(int i = 0; i < T; i++) {
    Ts[i] = i;
  }
  arma::vec t_dot = RcppArmadillo::sample(Ts, M, TRUE);
  arma::vec c_dot = t_dot;
  arma::vec urand = RcppArmadillo::sample(Ts, (M * T), TRUE);
  int icount = 0;
  arma::mat out(T, d);
  for(int i = 0; i < T; ++i) {
    double h = pow(i, (- 1 / (4 + d)));
    for(int m = 0; m < M; ++m) {
      c_dot = t_dot;
      c_dot[m] = urand[icount];

      arma::vec theta_b = theta_bar(c_dot, post_list, h, d, M);
      double w_c_dot = mix_weight(c_dot, post_list, h, d, M, theta_b);

      theta_b = theta_bar(t_dot, post_list, h, d, M);
      double w_t_dot = mix_weight(t_dot, post_list, h, d, M, theta_b);

      double ratio = w_c_dot / w_t_dot;
      NumericVector u = runif(1);
      bool b = all(u < ratio).is_true();
      if(b) {
        t_dot = c_dot;
      }
      icount += 1;
    }
    arma::mat sigma = arma::eye(d, d) * pow(h, 2) / M;
    arma::vec mu = theta_bar(t_dot, post_list, h, d, M);
    arma::mat draws = mvrnorm_arma(1, mu, sigma);
    out.row(i) = draws;
  }
  return(out);
}

// Component weight function for semi parametric combination
// [[Rcpp::export(.mix_weight_sp)]]
arma::vec mix_weight_sp(arma::vec t,
                     arma::mat sig_M,
                     arma::vec mu_M,
                     double w_t_dot,
                     List post_list,
                     double h,
                     int d,
                     int M,
                     List post_means,
                     List post_vcms,
                     arma::vec theta_b) {
  arma::mat theta_b_mat(1, d);
  theta_b_mat.row(0) = trans(theta_b);
  arma::mat sig = sig_M + arma::eye(d, d) * h / M;
  arma::vec num = w_t_dot * dmvnrm_arma(theta_b_mat, trans(mu_M), sig);
  arma::vec den = arma::ones(1);
  for(int m = 0; m < M; ++m) {
    arma::mat post = post_list[m];
    arma::rowvec theta_tm = post.row(t[m]);
    arma::rowvec mu_m = post_means[m];
    arma::mat vcm_m = post_vcms[m];
    arma::vec d = dmvnrm_arma(theta_tm, mu_m, vcm_m);
    den = den * d;
  }
  arma::vec out = num / den;
  return out;
}

//' Semi-parametric Combination of Sub-posteriors
//'
//' @param post_list A list containing the sub-posterior samples, stored in matrices
//' @return A matrix containing the samples from the sub-posterior product function
//' @export
// [[Rcpp::export]]
arma::mat combine_sp(List post_list) {
  arma::mat exmpl = post_list[0];
  int d = exmpl.n_cols;
  int T = exmpl.n_rows;
  int M = post_list.size();
  arma::vec Ts(T);
  for(int i = 0; i < T; i++) {
    Ts[i] = i;
  }
  arma::vec t_dot = RcppArmadillo::sample(Ts, M, TRUE);
  arma::vec c_dot = t_dot;
  arma::vec urand = RcppArmadillo::sample(Ts, (M * T), TRUE);
  int icount = 0;
  arma::mat out(T, d);
  arma::mat sig_M = post_vcm(post_list, d, M);
  arma::vec mu_M  = post_mean(post_list, sig_M, d, M);
  arma::vec sm_prod = sig_M.i() * mu_M;
  List post_means(M);
  List post_vcms(M);
  for(int m = 0; m < M; ++m) {
    arma::mat post = post_list[m];
    post_means[m] = mean(post);
    post_vcms[m] = arma::cov(post);
  }
  for(int i = 0; i < T; ++i) {
    double h = pow(i, (- 1 / (4 + d)));
    for(int m = 0; m < M; ++m) {
      c_dot = t_dot;
      c_dot[m] = urand[icount];

      arma::vec theta_b = theta_bar(c_dot, post_list, h, d, M);
      double w_c_dot = mix_weight(c_dot, post_list, h, d, M, theta_b);
      arma::vec W_c_dot = mix_weight_sp(c_dot, sig_M, mu_M, w_c_dot, post_list,
                                        h, d, M, post_means, post_vcms, theta_b);

      theta_b = theta_bar(t_dot, post_list, h, d, M);
      double w_t_dot = mix_weight(t_dot, post_list, h, d, M, theta_b);
      arma::vec W_t_dot = mix_weight_sp(t_dot, sig_M, mu_M, w_t_dot, post_list,
                                        h, d, M, post_means, post_vcms, theta_b);
      arma::vec ratio_v = W_c_dot / W_t_dot;
      double ratio = ratio_v[0];
      NumericVector u_v = runif(1);
      double u = u_v[0];
      if(u < ratio) {
        t_dot = c_dot;
      }
      icount += 1;
    }
    arma::mat sig_t_dot = inv(arma::eye(d, d) * M / h + inv(sig_M));
    arma::vec theta_b = theta_bar(t_dot, post_list, h, d, M);
    arma::vec A = (M / h) * arma::eye(d, d) * theta_b + inv(sig_M) * mu_M;
    arma::vec mu_t_dot = sig_t_dot * A;
    arma::mat draws = mvrnorm_arma(1, mu_t_dot, sig_t_dot);
    out.row(i) = draws;
  }
  return(out);
}<commit_msg>comment c++ code<commit_after>#include <RcppArmadilloExtensions/sample.h>
using namespace Rcpp;

// [[Rcpp::depends("RcppArmadillo")]]

// Where appropriate I reference to Neiswanger et al. 2014
// e.g. eq 3.1 refers to equation 3.1 in the paper
//		p 3 refers to page 3

// multivariate normal density
// Returns a scalar density for each row of X
// given mean vector 'mean' and variance covariance matrix 'sigma'
// based on code by Ahmadou Dicko (http://gallery.rcpp.org/articles/dmvnorm_arma/)
// [[Rcpp::export]]
arma::vec dmvnrm_arma(arma::mat x,
                      arma::rowvec mean,
                      arma::mat sigma) {
  const double log2pi = std::log(2.0 * M_PI);
  int n = x.n_rows;
  int xdim = x.n_cols;
  arma::vec out(n);
  arma::mat rooti = arma::trans(arma::inv(trimatu(arma::chol(sigma))));
  double rootisum = arma::sum(log(rooti.diag()));
  double constants = -(static_cast<double>(xdim)/2.0) * log2pi;

  for (int i=0; i < n; i++) {
    arma::vec z = rooti * arma::trans( x.row(i) - mean) ;
    out(i)      = constants - 0.5 * arma::sum(z%z) + rootisum;
  }
  out = exp(out);
  return(out);
}

// Multivariate normal random number generator
// Returns n random vectors of size mu from the multivariate normal
// with mean mu and variance covariance matrix sigma
// by Ahmadou Dicko (http://gallery.rcpp.org/articles/simulate-multivariate-normal/)
// [[Rcpp::export]]
arma::mat mvrnorm_arma(int n, arma::vec mu, arma::mat sigma) {
   int ncols = sigma.n_cols;
   arma::mat Y = arma::randn(n, ncols);
   return arma::repmat(mu, 1, n).t() + Y * arma::chol(sigma);
}

// Calculate the variance covariance matrix of the full posterior assuming
// multivariate normal sub-posteriors
// eq 3.1
// Input:
// post_list: List of M sub-posteriors (n*d matrices)
// M: Number of sub posteriors
// d: dimensionality of the posteriors
// [[Rcpp::export(post_vcm)]]
arma::mat post_vcm(List post_list, int d, int M) {
  arma::mat vcm_post = arma::zeros(d, d);
  for(int i = 0; i < M; ++i) {
    arma::mat post = post_list[i];
    arma::mat vcm_m = arma::cov(post); // calculate variance covariance matrix
    arma::mat vcm_m_i = arma::inv(vcm_m); // invert it
    vcm_post += vcm_m_i;
  }
  arma::mat out = arma::inv(vcm_post);
  return(out);
}

// Calculate the mean vector of the full posterior assuming
// multivariate normal sub-posteriors
// eq. 3.2
// Input:
// post_list: List of M sub-posteriors (n*d matrices)
// M: Number of sub posteriors
// d: dimensionality of the posteriors
// post_vcm: combined variance covariance matrix (output of post_vcm())
// [[Rcpp::export(post_mean)]]
arma::vec post_mean(List post_list, arma::mat post_vcm, int d, int M) {
  arma::vec w_sig = arma::zeros(d, 1);
  for(int i = 0; i < M; ++i) {
    arma::mat post = post_list[i];
    arma::mat vcm_m = arma::cov(post);
    arma::rowvec mu_m = mean(post, 0);
    w_sig += inv(vcm_m) * trans(mu_m);
  }
  arma::mat out = post_vcm * w_sig;
  return(out);
}

// Calculate the mean vector for selected sample in iteration of sampler for
// non- and semi-parametric combination
// eq 3.4
// Input:
// t: indices of currently selected samples
// post_list: List of sub-posteriors
// h: Bandwidth parameter in the current state
// d: dimensionality of the posterior (parameters in the model)
// M: number of sub-posteriors
// [[Rcpp::export(.theta_bar)]]
arma::vec theta_bar(arma::vec t, List post_list, double h, int d, int M) {
  // Create matrix of selected samples
  arma::mat sel(M, d);
  for(int i = 0; i < M; ++i) {
    arma::mat postmat = post_list[i];
    sel.row(i) = postmat.row(t[i]);
  }
  arma::rowvec theta_bar = arma::mean(sel, 0);
  return trans(theta_bar);
}

// Calculates mixture weights of current component
// for semi and non parametric combination
// eq 3.5
// Input:
// t: indices of currently selected samples
// post_list: List of sub-posteriors
// h: Bandwidth parameter in the current state
// d: dimensionality of the posterior (parameters in the model)
// M: number of sub-posteriors
// [[Rcpp::export(.mix_weight)]]
double mix_weight(arma::vec t,
                  List post_list,
                  double h,
                  int d,
                  int M,
                  arma::vec theta_b) {

  // Create matrix of selected samples
  arma::mat sel(M, d);
  for(int i = 0; i < M; ++i) {
    arma::mat postmat = post_list[i];
    sel.row(i) = postmat.row(t[i]);
  }
  arma::mat sigma = arma::eye(d, d) * pow(h, 2);
  // Calculate density of selected samples
  arma::vec dens = dmvnrm_arma(sel, trans(theta_b), sigma);
  double out = prod(dens);
  return out;
}

// Algorithm 1 on page 5

// This stuff is for the R Package documentation (Roxygen2):

//' Non-parametric Combination of Sub-posteriors
//' @param post_list A list containing the sub-posterior samples, stored in matrices
//' @return A matrix containing the samples from the sub-posterior product function
//' @export
// [[Rcpp::export]]
arma::mat combine_np(List post_list) {
  // Get number of dimensions , sub-posteriors, etc...
  arma::mat exmpl = post_list[0];
  int d = exmpl.n_cols; // dimensions
  int T = exmpl.n_rows; // # of mcmc iterations per sub-posterior
  int M = post_list.size(); // # of sub-posteriors
  arma::vec Ts(T);
  // This just creates a sequence from 1 to T
  for(int i = 0; i < T; i++) {
    Ts[i] = i;
  }
  // sample first set of indices
  arma::vec t_dot = RcppArmadillo::sample(Ts, M, TRUE);
  arma::vec c_dot = t_dot;
  // sample uniform random numbers to generate new selection indices
  arma::vec urand = RcppArmadillo::sample(Ts, (M * T), TRUE);
  int icount = 0; //index to loop through urand
  arma::mat out(T, d); // output matrix

  // Gibbs loop
  for(int i = 0; i < T; ++i) {
    double h = pow(i, (- 1 / (4 + d))); // bandwidth parameter

    // Metropolis Loop
    for(int m = 0; m < M; ++m) {

      c_dot = t_dot;
      // change one index for proposal
      c_dot[m] = urand[icount];

      // calculate mixture weight of proposal
      arma::vec theta_b = theta_bar(c_dot, post_list, h, d, M);
      double w_c_dot = mix_weight(c_dot, post_list, h, d, M, theta_b);

      // calculate old mixture weight (this step migt be avoidable by carrying
      // the weight calculated above to the next iteration)
      theta_b = theta_bar(t_dot, post_list, h, d, M);
      double w_t_dot = mix_weight(t_dot, post_list, h, d, M, theta_b);

      // get density ratio of proposal / last iteration
      double ratio = w_c_dot / w_t_dot;
      NumericVector u = runif(1);

      // Metropolis stochastic acceptance step
      bool b = all(u < ratio).is_true();
      if(b) {
        t_dot = c_dot;
      }
      icount += 1;
    }
    // Draw from mixture in gibbs step
    arma::mat sigma = arma::eye(d, d) * pow(h, 2) / M;
    arma::vec mu = theta_bar(t_dot, post_list, h, d, M);
    arma::mat draws = mvrnorm_arma(1, mu, sigma);
    out.row(i) = draws;
  }
  return(out);
}

// Component weight function for semi parametric combination
// as described on p 6 (W_t_dot)
// Input:
// t: current selection
// sig_M: Parametric approximation to variance-covariance matrix of posterior
//  (see function post_vcm() above)
// mu_M: Parametric approxiation to posterior mean (see function post_mean() above)
// w_t_dot: component weight (see function mix_weight())
// h, d, M: as in functions above
// post_means: list of mean vectors of sub-posteriors
// post_vcms: Variance covariance matrices of sub-posteriors
// theta_b: Mean vector in current iteration
// [[Rcpp::export(.mix_weight_sp)]]
arma::vec mix_weight_sp(arma::vec t,
                     arma::mat sig_M,
                     arma::vec mu_M,
                     double w_t_dot,
                     List post_list,
                     double h,
                     int d,
                     int M,
                     List post_means,
                     List post_vcms,
                     arma::vec theta_b) {
  arma::mat theta_b_mat(1, d);
  theta_b_mat.row(0) = trans(theta_b);
  arma::mat sig = sig_M + arma::eye(d, d) * h / M;
  arma::vec num = w_t_dot * dmvnrm_arma(theta_b_mat, trans(mu_M), sig);
  arma::vec den = arma::ones(1);
  for(int m = 0; m < M; ++m) {
    arma::mat post = post_list[m];
    arma::rowvec theta_tm = post.row(t[m]);
    arma::rowvec mu_m = post_means[m];
    arma::mat vcm_m = post_vcms[m];
    arma::vec d = dmvnrm_arma(theta_tm, mu_m, vcm_m);
    den = den * d;
  }
  arma::vec out = num / den;
  return out;
}

// Semi parametric combination as described in section 3.3. Very similar to
// non-parametric combination.

// This stuff is for R package documentation:
//' Semi-parametric Combination of Sub-posteriors
//'
//' @param post_list A list containing the sub-posterior samples, stored in matrices
//' @return A matrix containing the samples from the sub-posterior product function
//' @export
// [[Rcpp::export]]
arma::mat combine_sp(List post_list) {
  arma::mat exmpl = post_list[0];
  int d = exmpl.n_cols;
  int T = exmpl.n_rows;
  int M = post_list.size();
  arma::vec Ts(T);
  for(int i = 0; i < T; i++) {
    Ts[i] = i;
  }
  arma::vec t_dot = RcppArmadillo::sample(Ts, M, TRUE);
  arma::vec c_dot = t_dot;
  arma::vec urand = RcppArmadillo::sample(Ts, (M * T), TRUE);
  int icount = 0;
  arma::mat out(T, d);

  // Calculate parametric approximations of full posterior and vcm
  arma::mat sig_M = post_vcm(post_list, d, M);
  arma::vec mu_M  = post_mean(post_list, sig_M, d, M);
  arma::vec sm_prod = sig_M.i() * mu_M;

  // Calculate means and vcms for sub-posteriors to avoid doing it in each iteration
  List post_means(M);
  List post_vcms(M);
  for(int m = 0; m < M; ++m) {
    arma::mat post = post_list[m];
    post_means[m] = mean(post);
    post_vcms[m] = arma::cov(post);
  }

  // Gibbs Loop
  for(int i = 0; i < T; ++i) {
    double h = pow(i, (- 1 / (4 + d)));

    // Metropolis Loop
    for(int m = 0; m < M; ++m) {
      c_dot = t_dot;
      // Proposal
      c_dot[m] = urand[icount];

      // Mixture weight for proposal
      arma::vec theta_b = theta_bar(c_dot, post_list, h, d, M);
      double w_c_dot = mix_weight(c_dot, post_list, h, d, M, theta_b);
      arma::vec W_c_dot = mix_weight_sp(c_dot, sig_M, mu_M, w_c_dot, post_list,
                                        h, d, M, post_means, post_vcms, theta_b);

      // Mixture weight for last step (again can be avoided by using above calculated
      // weight from the last iteration?)
      theta_b = theta_bar(t_dot, post_list, h, d, M);
      double w_t_dot = mix_weight(t_dot, post_list, h, d, M, theta_b);
      arma::vec W_t_dot = mix_weight_sp(t_dot, sig_M, mu_M, w_t_dot, post_list,
                                        h, d, M, post_means, post_vcms, theta_b);
      // Density ratio
      arma::vec ratio_v = W_c_dot / W_t_dot;

      // acceptance step
      double ratio = ratio_v[0];
      NumericVector u_v = runif(1);
      double u = u_v[0];
      if(u < ratio) {
        t_dot = c_dot;
      }
      icount += 1;
    }

    // Draw Gibbs samples
    arma::mat sig_t_dot = inv(arma::eye(d, d) * M / h + inv(sig_M));
    arma::vec theta_b = theta_bar(t_dot, post_list, h, d, M);
    arma::vec A = (M / h) * arma::eye(d, d) * theta_b + inv(sig_M) * mu_M;
    arma::vec mu_t_dot = sig_t_dot * A;
    arma::mat draws = mvrnorm_arma(1, mu_t_dot, sig_t_dot);
    out.row(i) = draws;
  }
  return(out);
}<|endoftext|>


<commit_before>#include "qts3.h"
#include "qts3_p.h"

QPM_BEGIN_NAMESPACE(com, github, msorvig, s3)

QtS3ReplyBase::QtS3ReplyBase(QtS3ReplyPrivate *replyPrivate) : d(replyPrivate) {}
// error handling
bool QtS3ReplyBase::isSuccess() { return d->isSuccess(); }

QNetworkReply::NetworkError QtS3ReplyBase::networkError() { return d->networkError(); }

QString QtS3ReplyBase::networkErrorString() { return d->networkErrorString(); }

QtS3ReplyBase::S3Error QtS3ReplyBase::s3Error() { return d->s3Error(); }

QString QtS3ReplyBase::s3ErrorString() { return d->s3ErrorString(); }

QString QtS3ReplyBase::anyErrorString() { return d->anyErrorString(); }

QByteArray QtS3ReplyBase::replyData() { return d->bytearrayValue(); }

template <> void QtS3Reply<void>::value() {}
template <> bool QtS3Reply<bool>::value() { return d->boolValue(); }
template <> int QtS3Reply<int>::value() { return d->intValue(); }
template <> QByteArray QtS3Reply<QByteArray>::value() { return d->bytearrayValue(); }

/*
    \class QtS3
    \brief The QtS3 class provides a synchronous API for accessing Amazon S3 content.

    The QtS3 class provides a functions for uploading and downloading S3 bucket content,
    as well as functons for querying metadata such as size and object existence.

    The API is synchronous (blocking) and thread-safe.
*/

/*!
    Constructs a QtS3 object with the given \a accessKeyId and \a secretAccessKey.
*/
QtS3::QtS3(const QString &accessKeyId, const QString &secretAccessKey)
    : d(new QtS3Private(accessKeyId.toLatin1(), secretAccessKey.toLatin1()))
{
}

/*!
    Constructs a QtS3 object with the given \a accessKeyIdProvider and \a secretAccessKeyProvider.

    Using this constructor allows QtS3 to load the secret access key on
    demand and keep it out of main memory when not used. The providers must
    be callable with the signature "QByteArray fn()".

    The secret access key is required when generating a signing key. QtS3 uses one
    signing key per accessed AWS region. The signing keys expire and are
    regenerated at regular intervals - \a secretAccessKeyProvider may be called
    during any call to the s3 operation functions. The key expiry time is
    several hours.
*/

QtS3::QtS3(std::function<QByteArray()> accessKeyIdProvider,
           std::function<QByteArray()> secretAccessKeyProvider)
: d(new QtS3Private(accessKeyIdProvider, secretAccessKeyProvider))
{
}

/*!
    Returns the region for the \a bucketName bucket. Example values are
    "us-east-1" and "eu-west-1".
*/
QtS3Reply<QByteArray> QtS3::location(const QByteArray &bucket)
{
    return QtS3Reply<QByteArray>(d->location(bucket));
}

/*!
    Uploads the given \a content to \a path in \a bucket. \a headers may
    contain optional request headers.
*/
QtS3Reply<void> QtS3::put(const QByteArray &bucket, const QString &path,
                          const QByteArray &content, const QStringList &headers)
{
    return QtS3Reply<void>(d->put(bucket, path, content, headers));
}

/*!
    Checks if the given \a path in \a bucket exists.
*/
QtS3Reply<bool> QtS3::exists(const QByteArray &bucket, const QString &path)
{
    return QtS3Reply<bool>(d->exists(bucket, path));
}

/*!
    Returns the size of the object at \a path in \a bucket. If the object
    does not exist the reply will have an error condition set.
*/
QtS3Reply<int> QtS3::size(const QByteArray &bucket, const QString &path)
{
    return QtS3Reply<int>(d->size(bucket, path));
}

/*!
    Uploads the given \a content  to \a path in \a bucket. \a headers may
    contain optional request headers.
*/
QtS3Reply<QByteArray> QtS3::get(const QByteArray &bucket, const QString &path)
{
    return QtS3Reply<QByteArray>(d->get(bucket, path));
}

/*!
    Deletes the content for the given \a path in \a bucket.
*/
QtS3Reply<void> QtS3::remove(const QByteArray &bucket, const QString &path)
{
    return QtS3Reply<void>(d->remove(bucket, path));
}

/*!
    Clear internal caches such as the bucket region cache. Call this
    function if/when a bucket region changes.
*/
void QtS3::clearCaches()
{
    d->clearCaches();
}

/*!
    Returns the accessKeyId for the QtS3 object.
*/
QByteArray QtS3::accessKeyId()
{
    return d->accessKeyId();
}

/*!
    Returns the secretAccessKey for the QtS3 object.
*/
QByteArray QtS3::secretAccessKey()
{
    return d->secretAccessKey();
}

QPM_END_NAMESPACE(com, github, msorvig, s3)
<commit_msg>Fixup “get” docs.<commit_after>#include "qts3.h"
#include "qts3_p.h"

QPM_BEGIN_NAMESPACE(com, github, msorvig, s3)

QtS3ReplyBase::QtS3ReplyBase(QtS3ReplyPrivate *replyPrivate) : d(replyPrivate) {}
// error handling
bool QtS3ReplyBase::isSuccess() { return d->isSuccess(); }

QNetworkReply::NetworkError QtS3ReplyBase::networkError() { return d->networkError(); }

QString QtS3ReplyBase::networkErrorString() { return d->networkErrorString(); }

QtS3ReplyBase::S3Error QtS3ReplyBase::s3Error() { return d->s3Error(); }

QString QtS3ReplyBase::s3ErrorString() { return d->s3ErrorString(); }

QString QtS3ReplyBase::anyErrorString() { return d->anyErrorString(); }

QByteArray QtS3ReplyBase::replyData() { return d->bytearrayValue(); }

template <> void QtS3Reply<void>::value() {}
template <> bool QtS3Reply<bool>::value() { return d->boolValue(); }
template <> int QtS3Reply<int>::value() { return d->intValue(); }
template <> QByteArray QtS3Reply<QByteArray>::value() { return d->bytearrayValue(); }

/*
    \class QtS3
    \brief The QtS3 class provides a synchronous API for accessing Amazon S3 content.

    The QtS3 class provides a functions for uploading and downloading S3 bucket content,
    as well as functons for querying metadata such as size and object existence.

    The API is synchronous (blocking) and thread-safe.
*/

/*!
    Constructs a QtS3 object with the given \a accessKeyId and \a secretAccessKey.
*/
QtS3::QtS3(const QString &accessKeyId, const QString &secretAccessKey)
    : d(new QtS3Private(accessKeyId.toLatin1(), secretAccessKey.toLatin1()))
{
}

/*!
    Constructs a QtS3 object with the given \a accessKeyIdProvider and \a secretAccessKeyProvider.

    Using this constructor allows QtS3 to load the secret access key on
    demand and keep it out of main memory when not used. The providers must
    be callable with the signature "QByteArray fn()".

    The secret access key is required when generating a signing key. QtS3 uses one
    signing key per accessed AWS region. The signing keys expire and are
    regenerated at regular intervals - \a secretAccessKeyProvider may be called
    during any call to the s3 operation functions. The key expiry time is
    several hours.
*/

QtS3::QtS3(std::function<QByteArray()> accessKeyIdProvider,
           std::function<QByteArray()> secretAccessKeyProvider)
: d(new QtS3Private(accessKeyIdProvider, secretAccessKeyProvider))
{
}

/*!
    Returns the region for the \a bucketName bucket. Example values are
    "us-east-1" and "eu-west-1".
*/
QtS3Reply<QByteArray> QtS3::location(const QByteArray &bucket)
{
    return QtS3Reply<QByteArray>(d->location(bucket));
}

/*!
    Uploads the given \a content to \a path in \a bucket. \a headers may
    contain optional request headers.
*/
QtS3Reply<void> QtS3::put(const QByteArray &bucket, const QString &path,
                          const QByteArray &content, const QStringList &headers)
{
    return QtS3Reply<void>(d->put(bucket, path, content, headers));
}

/*!
    Checks if the given \a path in \a bucket exists.
*/
QtS3Reply<bool> QtS3::exists(const QByteArray &bucket, const QString &path)
{
    return QtS3Reply<bool>(d->exists(bucket, path));
}

/*!
    Returns the size of the object at \a path in \a bucket. If the object
    does not exist the reply will have an error condition set.
*/
QtS3Reply<int> QtS3::size(const QByteArray &bucket, const QString &path)
{
    return QtS3Reply<int>(d->size(bucket, path));
}

/*!
    Downloads the content for the given \a path in \a bucket.
*/
QtS3Reply<QByteArray> QtS3::get(const QByteArray &bucket, const QString &path)
{
    return QtS3Reply<QByteArray>(d->get(bucket, path));
}

/*!
    Deletes the content for the given \a path in \a bucket.
*/
QtS3Reply<void> QtS3::remove(const QByteArray &bucket, const QString &path)
{
    return QtS3Reply<void>(d->remove(bucket, path));
}

/*!
    Clear internal caches such as the bucket region cache. Call this
    function if/when a bucket region changes.
*/
void QtS3::clearCaches()
{
    d->clearCaches();
}

/*!
    Returns the accessKeyId for the QtS3 object.
*/
QByteArray QtS3::accessKeyId()
{
    return d->accessKeyId();
}

/*!
    Returns the secretAccessKey for the QtS3 object.
*/
QByteArray QtS3::secretAccessKey()
{
    return d->secretAccessKey();
}

QPM_END_NAMESPACE(com, github, msorvig, s3)
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: hfi_linklist.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: np $ $Date: 2002-11-14 18:01:56 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <precomp.h>
#include "hfi_linklist.hxx"

// NOT FULLY DEFINED SERVICES
#include <ary/idl/i_ce.hxx>
#include <ary/idl/i_gate.hxx>
#include <ary/idl/ip_ce.hxx>
#include <ary/idl/ip_type.hxx>
#include <ary_i/codeinf2.hxx>
#include <toolkit/hf_docentry.hxx>
#include <toolkit/hf_title.hxx>
#include "hfi_doc.hxx"
#include "hfi_tag.hxx"
#include "hfi_typetext.hxx"
#include "hi_ary.hxx"
#include "hi_env.hxx"

//*******************           HF_CommentedLink_Table         **********************************//

HF_CommentedLink_Table::HF_CommentedLink_Table( Environment  &          io_rEnv,
                                                Xml::Element &          o_rOut,
                                                const String &          i_sTitle,
                                                const String &          i_sLabel,
                                                bool                    i_bBorder )
    :    HtmlFactory_Idl(io_rEnv,&o_rOut),
         pTable( new Html::Table( (i_bBorder ? "1" : "0"), "100%", "5", "0") ),
         pCurLinkColumn(0),
         pCurCommentColumn(0)
{
    CurOut()
        >> *new Html::Label(i_sLabel)
           << new Html::LineBreak;
    CurOut()
        << pTable;
//    HF_SubTitle aTitle(*pTable);
//    aTitle.Produce_it(i_sTitle);
}

HF_CommentedLink_Table::~HF_CommentedLink_Table()
{
}

void
HF_CommentedLink_Table::Add_Line()
{
    Html::TableRow &
        rRow = pTable->AddRow();

    pCurLinkColumn = & (rRow.AddCell()
                            << new Html::WidthAttr("30%")
                            << new Xml::AnAttribute("valign","top") );
    pCurCommentColumn  = & rRow.AddCell();
}

Xml::Element &
HF_CommentedLink_Table::Cur_LinkColumn()
{
    csv_assert(pCurLinkColumn != 0);
    return *pCurLinkColumn;
}

Xml::Element &
HF_CommentedLink_Table::Cur_CommentColumn()
{
    csv_assert(pCurCommentColumn != 0);
    return *pCurCommentColumn;
}

//*******************           HF_MemberTable         **********************************//

HF_MemberTable::HF_MemberTable( Environment  &      io_rEnv,
                                Xml::Element &      o_rOut,
                                const String &      i_sTitle,
                                const String &      i_sLabel,
                                bool                i_bInline )
    :    HtmlFactory_Idl(io_rEnv,&o_rOut),
         pTable( new Html::Table("1", "100%", "5", "0") ),
         pCurDeclaration(0),
         pCurDescription(0),
         bInline(i_bInline)
{
    CurOut()
        >> *new Html::Label(i_sLabel)
           << new Html::LineBreak;
    CurOut()
        << pTable;
//    HF_SubTitle aTitle(*pTable);
//    aTitle.Produce_it(i_sTitle);
}

HF_MemberTable::~HF_MemberTable()
{
}

void
HF_MemberTable::Add_Line()
{
    if (bInline)
    {
        Html::TableRow & rRow = pTable->AddRow();

        pCurDeclaration = &( rRow.AddCell()
                                << new Xml::AnAttribute("valign","top")
                                << new Html::WidthAttr("30%") );
        pCurDescription = & rRow.AddCell();
    }
    else
    {
        Html::DefList *
            pMemberSpace = new Html::DefList;
        *pMemberSpace
            << new Html::ClassAttr("member");

        pTable->AddRow().AddCell() << pMemberSpace;

        pCurDeclaration =
            & ( *pMemberSpace
                    >> *new Html::DefListTerm
                        << new Html::ClassAttr("member") );
        pCurDescription =
            & ( *pMemberSpace
                    >> *new Html::DefListDefinition()
                        << new Html::ClassAttr("member") );
    }
}

Xml::Element &
HF_MemberTable::Cur_Declaration()
{
    csv_assert(pCurDeclaration != 0);
    return *pCurDeclaration;
}

Xml::Element &
HF_MemberTable::Cur_Description()
{
    csv_assert(pCurDescription != 0);
    return *pCurDescription;
}

//*******************           HF_IdlLinkList         **********************************//

HF_IdlLinkList::HF_IdlLinkList( Environment  &   io_rEnv,
                                Xml::Element *   o_pOut )
    :    HtmlFactory_Idl(io_rEnv,o_pOut)
{
}

HF_IdlLinkList::~HF_IdlLinkList()
{
}

void
HF_IdlLinkList::Produce_NamespaceMembers( const String &                        i_sTitle,
                                          const String &                        i_sLabel,
                                          const std::vector<ary::idl::Ce_id> &  i_rList,
                                          bool                                  i_bNestedNamespaces ) const
{
    HF_CommentedLink_Table
        aTableMaker( Env(), CurOut(),
                     i_sTitle, i_sLabel,
                     true );

    std::vector<ary::idl::Ce_id>::const_iterator itEnd = i_rList.end();
    for ( std::vector<ary::idl::Ce_id>::const_iterator it = i_rList.begin();
          it != itEnd;
          ++it )
    {
        static String   sEntryName;
        static String   sEntryLink;
        const ce_info *
                        pDocu = 0;
        Get_EntryData_NamespaceMembers( sEntryName, sEntryLink, pDocu, *it, i_bNestedNamespaces );
        aTableMaker.Add_Line();

        aTableMaker.Cur_LinkColumn()
           >> *new Html::Link(sEntryLink)
              << sEntryName;

        if ( pDocu != 0 )
        {
            HF_IdlShortDocu
                aTextDisplay(Env(), aTableMaker.Cur_CommentColumn() );
            aTextDisplay.Produce_byData( pDocu );
        }
    }   // end for
}

void
HF_IdlLinkList::Produce_GlobalLinks( const String &      i_sTitle,
                                     const String &      i_sLabel,
                                     ce_list &           i_rList ) const
{
    HF_CommentedLink_Table
        aTableMaker( Env(), CurOut(),
                     i_sTitle, i_sLabel,
                     true );

    for ( ; i_rList; ++i_rList )
    {
        aTableMaker.Add_Line();
        HF_IdlTypeText
            aLinkText( Env(), aTableMaker.Cur_LinkColumn(), true );
        aLinkText.Produce_byData(*i_rList);

        const ce_info *
            pDocu = Get_EntryDocu(*i_rList);
        if ( pDocu != 0 )
        {
            HF_IdlShortDocu
                aTextDisplay(Env(), aTableMaker.Cur_CommentColumn() );
            aTextDisplay.Produce_byData( pDocu, *i_rList );
        }
    }
}

void
HF_IdlLinkList::Produce_GlobalCommentedLinks( const String &          i_sTitle,
                                              const String &          i_sLabel,
                                              comref_list &           i_rList ) const
{
    HF_CommentedLink_Table
        aTableMaker( Env(), CurOut(),
                     i_sTitle, i_sLabel,
                     true );
/*
    for ( ; i_rList; ++i_rList )
    {
        aTableMaker.Add_Line();
        HF_IdlTypeText
            aLinkText( Env(), aTableMaker.Cur_LinkColumn(), true );
        aLinkText.Produce_byData( (*i_rList).first );

        HF_DocEntryList
            aDocList( aTableMaker.Cur_CommentColumn() );
        if ( (*i_rList).second != 0 )
        {
            HF_IdlDocu
                aDocuDisplay( Env(), aDocList );
            aDocuDisplay.Produce_byData( (*i_rList).second );
        }
        else
        {
            const ce_info *
                pShort = Get_EntryDocu(
                            Env().Gate().Types().Search_CeRelatedTo(
                                            (*i_rList).first) );
            if ( pShort != 0 )
            {
                if (pShort->IsDeprecated())
                {
                    aDocList.Produce_Term()
                        << "[ DEPRECATED ]";
                }
                if (pShort->IsOptional())
                {
                    aDocList.Produce_Term()
                        << "[ OPTIONAL ]";
                }

                aDocList.Produce_Term()
                    << "Description";

                HF_IdlDocuTextDisplay
                    aShortDisplay( Env(), &aDocList.Produce_Definition() );
                aShortDisplay.Set_CurScopeTo(
                        Env().Gate().Types().Search_CeRelatedTo((*i_rList).first) );
                pShort->Short().DisplayAt(aShortDisplay);
            }
        }
    }
*/
}

void
HF_IdlLinkList::Produce_MemberLinks( const String &     i_sTitle,
                                     const String &     i_sLabel,
                                     ce_list &          i_rList ) const
{
    HF_CommentedLink_Table
        aTableMaker( Env(), CurOut(),
                     i_sTitle, i_sLabel,
                     true );

/*
    for ( ; i_rList; ++i_rList )
    {
        const ary::idl::CodeEntity &
            rCe = Env().Gate().Ces().Find_Ce(*i_rList);

        aTableMaker.Add_Line();
        aTableMaker.Cur_LinkColumn()
            >> *new Html::Link(
                    StreamLock(200)() << "#" << rCe.LocalName() << c_str)
               << rCe.LocalName();

        const ce_info *
            pDocu = rCe.Docu();
        if ( pDocu != 0 )
        {
            HF_IdlShortDocu
                aTextDisplay(Env(), aTableMaker.Cur_CommentColumn() );
            aTextDisplay.Produce_byData( *pDocu );
        }
    }   // end for
*/
}

void
HF_IdlLinkList::Get_EntryData_NamespaceMembers(
                            String &                o_sEntryName,
                            String &                o_sEntryLink,
                            const ce_info * &       o_pDocu,
                            ce_id                   i_nMemberId,
                            bool                    i_bIsNestedNamespace  ) const
{
    const ary::idl::CodeEntity &
        rCe = Env().Data().Find_Ce(i_nMemberId);

    o_sEntryName = rCe.LocalName();
    o_sEntryLink = StreamLock(200)() << rCe.LocalName()
                                     << ( i_bIsNestedNamespace
                                                ?   "/module-ix"
                                                :   "" )
                                     << ".html"
                                     << c_str;
    o_pDocu = rCe.Docu();
}

const ary::info::CodeInformation *
HF_IdlLinkList::Get_EntryDocu(ce_id i_nMemberId) const
{
    if (i_nMemberId.IsValid())
        return Env().Data().Find_Ce(i_nMemberId).Docu();
    else
        return 0;
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.132); FILE MERGED 2005/09/05 13:10:55 rt 1.2.132.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: hfi_linklist.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 17:42:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <precomp.h>
#include "hfi_linklist.hxx"

// NOT FULLY DEFINED SERVICES
#include <ary/idl/i_ce.hxx>
#include <ary/idl/i_gate.hxx>
#include <ary/idl/ip_ce.hxx>
#include <ary/idl/ip_type.hxx>
#include <ary_i/codeinf2.hxx>
#include <toolkit/hf_docentry.hxx>
#include <toolkit/hf_title.hxx>
#include "hfi_doc.hxx"
#include "hfi_tag.hxx"
#include "hfi_typetext.hxx"
#include "hi_ary.hxx"
#include "hi_env.hxx"

//*******************           HF_CommentedLink_Table         **********************************//

HF_CommentedLink_Table::HF_CommentedLink_Table( Environment  &          io_rEnv,
                                                Xml::Element &          o_rOut,
                                                const String &          i_sTitle,
                                                const String &          i_sLabel,
                                                bool                    i_bBorder )
    :    HtmlFactory_Idl(io_rEnv,&o_rOut),
         pTable( new Html::Table( (i_bBorder ? "1" : "0"), "100%", "5", "0") ),
         pCurLinkColumn(0),
         pCurCommentColumn(0)
{
    CurOut()
        >> *new Html::Label(i_sLabel)
           << new Html::LineBreak;
    CurOut()
        << pTable;
//    HF_SubTitle aTitle(*pTable);
//    aTitle.Produce_it(i_sTitle);
}

HF_CommentedLink_Table::~HF_CommentedLink_Table()
{
}

void
HF_CommentedLink_Table::Add_Line()
{
    Html::TableRow &
        rRow = pTable->AddRow();

    pCurLinkColumn = & (rRow.AddCell()
                            << new Html::WidthAttr("30%")
                            << new Xml::AnAttribute("valign","top") );
    pCurCommentColumn  = & rRow.AddCell();
}

Xml::Element &
HF_CommentedLink_Table::Cur_LinkColumn()
{
    csv_assert(pCurLinkColumn != 0);
    return *pCurLinkColumn;
}

Xml::Element &
HF_CommentedLink_Table::Cur_CommentColumn()
{
    csv_assert(pCurCommentColumn != 0);
    return *pCurCommentColumn;
}

//*******************           HF_MemberTable         **********************************//

HF_MemberTable::HF_MemberTable( Environment  &      io_rEnv,
                                Xml::Element &      o_rOut,
                                const String &      i_sTitle,
                                const String &      i_sLabel,
                                bool                i_bInline )
    :    HtmlFactory_Idl(io_rEnv,&o_rOut),
         pTable( new Html::Table("1", "100%", "5", "0") ),
         pCurDeclaration(0),
         pCurDescription(0),
         bInline(i_bInline)
{
    CurOut()
        >> *new Html::Label(i_sLabel)
           << new Html::LineBreak;
    CurOut()
        << pTable;
//    HF_SubTitle aTitle(*pTable);
//    aTitle.Produce_it(i_sTitle);
}

HF_MemberTable::~HF_MemberTable()
{
}

void
HF_MemberTable::Add_Line()
{
    if (bInline)
    {
        Html::TableRow & rRow = pTable->AddRow();

        pCurDeclaration = &( rRow.AddCell()
                                << new Xml::AnAttribute("valign","top")
                                << new Html::WidthAttr("30%") );
        pCurDescription = & rRow.AddCell();
    }
    else
    {
        Html::DefList *
            pMemberSpace = new Html::DefList;
        *pMemberSpace
            << new Html::ClassAttr("member");

        pTable->AddRow().AddCell() << pMemberSpace;

        pCurDeclaration =
            & ( *pMemberSpace
                    >> *new Html::DefListTerm
                        << new Html::ClassAttr("member") );
        pCurDescription =
            & ( *pMemberSpace
                    >> *new Html::DefListDefinition()
                        << new Html::ClassAttr("member") );
    }
}

Xml::Element &
HF_MemberTable::Cur_Declaration()
{
    csv_assert(pCurDeclaration != 0);
    return *pCurDeclaration;
}

Xml::Element &
HF_MemberTable::Cur_Description()
{
    csv_assert(pCurDescription != 0);
    return *pCurDescription;
}

//*******************           HF_IdlLinkList         **********************************//

HF_IdlLinkList::HF_IdlLinkList( Environment  &   io_rEnv,
                                Xml::Element *   o_pOut )
    :    HtmlFactory_Idl(io_rEnv,o_pOut)
{
}

HF_IdlLinkList::~HF_IdlLinkList()
{
}

void
HF_IdlLinkList::Produce_NamespaceMembers( const String &                        i_sTitle,
                                          const String &                        i_sLabel,
                                          const std::vector<ary::idl::Ce_id> &  i_rList,
                                          bool                                  i_bNestedNamespaces ) const
{
    HF_CommentedLink_Table
        aTableMaker( Env(), CurOut(),
                     i_sTitle, i_sLabel,
                     true );

    std::vector<ary::idl::Ce_id>::const_iterator itEnd = i_rList.end();
    for ( std::vector<ary::idl::Ce_id>::const_iterator it = i_rList.begin();
          it != itEnd;
          ++it )
    {
        static String   sEntryName;
        static String   sEntryLink;
        const ce_info *
                        pDocu = 0;
        Get_EntryData_NamespaceMembers( sEntryName, sEntryLink, pDocu, *it, i_bNestedNamespaces );
        aTableMaker.Add_Line();

        aTableMaker.Cur_LinkColumn()
           >> *new Html::Link(sEntryLink)
              << sEntryName;

        if ( pDocu != 0 )
        {
            HF_IdlShortDocu
                aTextDisplay(Env(), aTableMaker.Cur_CommentColumn() );
            aTextDisplay.Produce_byData( pDocu );
        }
    }   // end for
}

void
HF_IdlLinkList::Produce_GlobalLinks( const String &      i_sTitle,
                                     const String &      i_sLabel,
                                     ce_list &           i_rList ) const
{
    HF_CommentedLink_Table
        aTableMaker( Env(), CurOut(),
                     i_sTitle, i_sLabel,
                     true );

    for ( ; i_rList; ++i_rList )
    {
        aTableMaker.Add_Line();
        HF_IdlTypeText
            aLinkText( Env(), aTableMaker.Cur_LinkColumn(), true );
        aLinkText.Produce_byData(*i_rList);

        const ce_info *
            pDocu = Get_EntryDocu(*i_rList);
        if ( pDocu != 0 )
        {
            HF_IdlShortDocu
                aTextDisplay(Env(), aTableMaker.Cur_CommentColumn() );
            aTextDisplay.Produce_byData( pDocu, *i_rList );
        }
    }
}

void
HF_IdlLinkList::Produce_GlobalCommentedLinks( const String &          i_sTitle,
                                              const String &          i_sLabel,
                                              comref_list &           i_rList ) const
{
    HF_CommentedLink_Table
        aTableMaker( Env(), CurOut(),
                     i_sTitle, i_sLabel,
                     true );
/*
    for ( ; i_rList; ++i_rList )
    {
        aTableMaker.Add_Line();
        HF_IdlTypeText
            aLinkText( Env(), aTableMaker.Cur_LinkColumn(), true );
        aLinkText.Produce_byData( (*i_rList).first );

        HF_DocEntryList
            aDocList( aTableMaker.Cur_CommentColumn() );
        if ( (*i_rList).second != 0 )
        {
            HF_IdlDocu
                aDocuDisplay( Env(), aDocList );
            aDocuDisplay.Produce_byData( (*i_rList).second );
        }
        else
        {
            const ce_info *
                pShort = Get_EntryDocu(
                            Env().Gate().Types().Search_CeRelatedTo(
                                            (*i_rList).first) );
            if ( pShort != 0 )
            {
                if (pShort->IsDeprecated())
                {
                    aDocList.Produce_Term()
                        << "[ DEPRECATED ]";
                }
                if (pShort->IsOptional())
                {
                    aDocList.Produce_Term()
                        << "[ OPTIONAL ]";
                }

                aDocList.Produce_Term()
                    << "Description";

                HF_IdlDocuTextDisplay
                    aShortDisplay( Env(), &aDocList.Produce_Definition() );
                aShortDisplay.Set_CurScopeTo(
                        Env().Gate().Types().Search_CeRelatedTo((*i_rList).first) );
                pShort->Short().DisplayAt(aShortDisplay);
            }
        }
    }
*/
}

void
HF_IdlLinkList::Produce_MemberLinks( const String &     i_sTitle,
                                     const String &     i_sLabel,
                                     ce_list &          i_rList ) const
{
    HF_CommentedLink_Table
        aTableMaker( Env(), CurOut(),
                     i_sTitle, i_sLabel,
                     true );

/*
    for ( ; i_rList; ++i_rList )
    {
        const ary::idl::CodeEntity &
            rCe = Env().Gate().Ces().Find_Ce(*i_rList);

        aTableMaker.Add_Line();
        aTableMaker.Cur_LinkColumn()
            >> *new Html::Link(
                    StreamLock(200)() << "#" << rCe.LocalName() << c_str)
               << rCe.LocalName();

        const ce_info *
            pDocu = rCe.Docu();
        if ( pDocu != 0 )
        {
            HF_IdlShortDocu
                aTextDisplay(Env(), aTableMaker.Cur_CommentColumn() );
            aTextDisplay.Produce_byData( *pDocu );
        }
    }   // end for
*/
}

void
HF_IdlLinkList::Get_EntryData_NamespaceMembers(
                            String &                o_sEntryName,
                            String &                o_sEntryLink,
                            const ce_info * &       o_pDocu,
                            ce_id                   i_nMemberId,
                            bool                    i_bIsNestedNamespace  ) const
{
    const ary::idl::CodeEntity &
        rCe = Env().Data().Find_Ce(i_nMemberId);

    o_sEntryName = rCe.LocalName();
    o_sEntryLink = StreamLock(200)() << rCe.LocalName()
                                     << ( i_bIsNestedNamespace
                                                ?   "/module-ix"
                                                :   "" )
                                     << ".html"
                                     << c_str;
    o_pDocu = rCe.Docu();
}

const ary::info::CodeInformation *
HF_IdlLinkList::Get_EntryDocu(ce_id i_nMemberId) const
{
    if (i_nMemberId.IsValid())
        return Env().Data().Find_Ce(i_nMemberId).Docu();
    else
        return 0;
}

<|endoftext|>


<commit_before>#include <yuni/yuni.h>
#include "details/pass/build-ast-to-ir/scope.h"
#include "details/utils/check-for-valid-identifier-name.h"
#include "libnany-config.h"

using namespace Yuni;

namespace Nany
{
namespace IR
{
namespace Producer
{

	bool Scope::visitASTExprClosure(const AST::Node& node, uint32_t& localvar)
	{
		assert(node.rule == AST::rgFunction);
		AST::Node* body = nullptr;
		AST::Node* rettype = nullptr;
		AST::Node* params = nullptr;

		for (auto& childptr: node.children)
		{
			auto& child = *childptr;
			switch (child.rule)
			{
				case AST::rgFuncBody:
				{
					body = &child;
					break;
				}
				case AST::rgFuncParams:
				{
					params = &child;
					break;
				}
				case AST::rgFuncReturnType:
				{
					rettype = &child;
					break;
				}
				case AST::rgFunctionKind:
				{
					if (child.children.size() != 1 or child.children[0]->rule != AST::rgFunctionKindFunction)
						return error(child) << "only function definition is allowed for closure";
					break;
				}
				default:
					return unexpectedNode(child, "[closure]");
			}
		}

		if (unlikely(!body))
			return error(node) << "empty body not allowed in closures";

		if (!context.reuse.closure.node)
			context.prepareReuseForClosures();

		emitDebugpos(node);
		auto& expr = *context.reuse.closure.node;
		auto& targetBody = *context.reuse.closure.funcbody;
		targetBody.children = body->children;

		if (params)
			*context.reuse.closure.params = *params;
		else
			context.reuse.closure.params->children.clear();

		if (rettype)
			*context.reuse.closure.rettype = *rettype;
		else
			context.reuse.closure.rettype->children.clear();

		return visitASTExpr(expr, localvar);
	}

} // namespace Producer
} // namespace IR
} // namespace Nany
<commit_msg>ast2ir: closures: clear some containers to avoid invalid values in gdb<commit_after>#include <yuni/yuni.h>
#include "details/pass/build-ast-to-ir/scope.h"
#include "details/utils/check-for-valid-identifier-name.h"
#include "libnany-config.h"

using namespace Yuni;

namespace Nany
{
namespace IR
{
namespace Producer
{

	bool Scope::visitASTExprClosure(const AST::Node& node, uint32_t& localvar)
	{
		assert(node.rule == AST::rgFunction);
		AST::Node* body = nullptr;
		AST::Node* rettype = nullptr;
		AST::Node* params = nullptr;

		for (auto& childptr: node.children)
		{
			auto& child = *childptr;
			switch (child.rule)
			{
				case AST::rgFuncBody:
				{
					body = &child;
					break;
				}
				case AST::rgFuncParams:
				{
					params = &child;
					break;
				}
				case AST::rgFuncReturnType:
				{
					rettype = &child;
					break;
				}
				case AST::rgFunctionKind:
				{
					if (child.children.size() != 1 or child.children[0]->rule != AST::rgFunctionKindFunction)
						return error(child) << "only function definition is allowed for closure";
					break;
				}
				default:
					return unexpectedNode(child, "[closure]");
			}
		}

		if (unlikely(!body))
			return error(node) << "empty body not allowed in closures";

		if (!context.reuse.closure.node)
			context.prepareReuseForClosures();

		emitDebugpos(node);
		auto& expr = *context.reuse.closure.node;
		auto& targetBody = *context.reuse.closure.funcbody;
		targetBody.children = body->children;

		if (params)
			*context.reuse.closure.params = *params;
		else
			context.reuse.closure.params->children.clear();

		if (rettype)
			*context.reuse.closure.rettype = *rettype;
		else
			context.reuse.closure.rettype->children.clear();

		bool success = visitASTExpr(expr, localvar);

		// avoid crap in the debugger
		context.reuse.closure.params->children.clear();
		context.reuse.closure.rettype->children.clear();
		targetBody.children.clear();
		return success;
	}

} // namespace Producer
} // namespace IR
} // namespace Nany
<|endoftext|>


<commit_before>// This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
#include "testing.hh"
#include <algorithm>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sfi/randomhash.hh>

#define TDEBUG(...)     Bse::debug ("Test", __VA_ARGS__)

namespace Bse {

/** The Test namespace offers utilities for unit tests.
 * The Test namespace is made available by  \#include <sfi/testing.hh>

 * See also sfi/testing.hh.
 */
namespace Test {

static void
test_assertion_failed()
{
  void *__p_[BSE_BACKTRACE_MAXDEPTH] = { 0, };
  String btmsg = pretty_backtrace (__p_, backtrace_pointers (__p_, sizeof (__p_) / sizeof (__p_[0])), __FILE__, __LINE__, NULL);
  if (btmsg.size())
    printerr ("%s", btmsg.c_str());
  printerr ("Rapicorn::test_assertion_failed(): aborting...");
  Bse::breakpoint();
  abort();
}

/** Initialize the Bse core for a test program.
 * Initializes Bse to execute unit tests by calling parse_settings_and_args()
 * with args "autonomous=1" and "testing=1" and setting the application name.
 * See also #$BSE_DEBUG.
 */
void
init (int *argcp, char **argv, const StringVector &args)
{
  Aida::assertion_failed_hook (test_assertion_failed);
  unsigned int flags = g_log_set_always_fatal (GLogLevelFlags (G_LOG_FATAL_MASK));
  g_log_set_always_fatal (GLogLevelFlags (flags | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL));
  sfi_init (argcp, argv, Bse::cstrings_to_vector (":autonomous:testing:fatal-warnings:", NULL));
}

Timer::Timer (double deadline_in_secs) :
  deadline_ (deadline_in_secs), test_duration_ (0), n_reps_ (0)
{}

Timer::~Timer ()
{}

double
Timer::bench_time ()
{
  /* timestamp_benchmark() counts nano seconds since program start, so
   * it's not going to exceed the 52bit double mantissa too fast.
   */
  return timestamp_benchmark() / 1000000000.0;
}

#define DEBUG_LOOPS_NEEDED(...) while (0) printerr (__VA_ARGS__)

int64
Timer::loops_needed ()
{
  if (samples_.size() < 3)
    {
      n_reps_ = MAX (1, n_reps_);
      DEBUG_LOOPS_NEEDED ("loops_needed: %d\n", n_reps_);
      return n_reps_;           // force significant number of test runs
    }
  double resolution = timestamp_resolution() / 1000000000.0;
  const double deadline = MAX (deadline_ == 0.0 ? 0.005 : deadline_, resolution * 10000.0);
  if (test_duration_ < deadline * 0.2)
    {
      // increase the number of tests per run to gain more accuracy
      n_reps_ = MAX (n_reps_ + 1, int64 (n_reps_ * 1.5)) | 1;
      DEBUG_LOOPS_NEEDED ("loops_needed: %d\n", n_reps_);
      return n_reps_;
    }
  if (test_duration_ < deadline)
    {
      DEBUG_LOOPS_NEEDED ("loops_needed: %d\n", n_reps_);
      return n_reps_;
    }
  DEBUG_LOOPS_NEEDED ("loops_needed: %d\n", 0);
  return 0;
}

void
Timer::submit (double elapsed, int64 repetitions)
{
  test_duration_ += elapsed;
  double resolution = timestamp_resolution() / 1000000000.0;
  if (elapsed >= resolution * 500.0) // force error below 5%
    samples_.push_back (elapsed / repetitions);
  else
    n_reps_ = (n_reps_ + n_reps_) | 1; // double n_reps_ to yield significant times
}

void
Timer::reset()
{
  samples_.resize (0);
  test_duration_ = 0;
  n_reps_ = 0;
}

double
Timer::min_elapsed () const
{
  double m = DBL_MAX;
  for (size_t i = 0; i < samples_.size(); i++)
    m = MIN (m, samples_[i]);
  return m;
}

double
Timer::max_elapsed () const
{
  double m = 0;
  for (size_t i = 0; i < samples_.size(); i++)
    m = MAX (m, samples_[i]);
  return m;
}

static String
ensure_newline (const String &s)
{
  if (!s.size() || s[s.size()-1] != '\n')
    return s + "\n";
  return s;
}

static __thread String *thread_test_start = NULL;

void
test_output (int kind, const String &msg)
{
  if (!thread_test_start)
    thread_test_start = new String();
  String &test_start = *thread_test_start;
  String prefix, sout;
  bool aborting = false;
  switch (kind)
    {
    case 'S':                   // TSTART()
      if (!test_start.empty())
        return test_output ('F', string_format ("Unfinished Test: %s\n", test_start));
      test_start = msg;
      sout = "  START…   " + ensure_newline (msg);
      break;
    case 'D':                   // TDONE() - test passed
      if (test_start.empty())
        return test_output ('F', "Extraneous TDONE() call");
      test_start = "";
      sout = "  …DONE    " + ensure_newline (msg);
      break;
    case 'I':                   // TNOTE() - verbose test message
      if (verbose())
        sout = "  NOTE     " + ensure_newline (msg);
      break;
    case 'P':
      sout = "  PASS     " + ensure_newline (msg);
      break;
    case 'F':
      sout = "  FAIL     " + ensure_newline (msg);
      aborting = true;
      break;
    default:
      sout = "  INFO     " + ensure_newline (msg);
      break;
    }
  if (!sout.empty())            // test message output
    {
      fflush (stderr);
      fputs (sout.c_str(), stdout);
      fflush (stdout);
    }
  if (aborting)
    {
      breakpoint();
    }
}

bool
slow()
{
  static bool cached_slow = feature_toggle_bool (getenv ("BSE_TEST"), "slow");
  return cached_slow;
}

bool
verbose()
{
  static bool cached_verbose = feature_toggle_bool (getenv ("BSE_TEST"), "verbose");
  return cached_verbose;
}

uint64_t
random_int64 ()
{
  return Bse::random_int64();
}

int64_t
random_irange (int64_t begin, int64_t end)
{
  return Bse::random_irange (begin, end);
}

double
random_float ()
{
  return Bse::random_float();
}

double
random_frange (double begin, double end)
{
  return Bse::random_frange (begin, end);
}

// == TestChain ==
static const TestChain *global_test_chain = NULL;

TestChain::TestChain (std::function<void()> tfunc, const std::string &tname) :
  name_ (tname), func_ (tfunc), next_ (global_test_chain)
{
  assert_return (next_ == global_test_chain);
  global_test_chain = this;
}

void
TestChain::run (ptrdiff_t internal_token)
{
  assert_return (internal_token == ptrdiff_t (global_test_chain));
  for (const TestChain *t = global_test_chain; t; t = t->next_)
    {
      fflush (stderr);
      printout ("  RUN…     %s\n", t->name_);
      fflush (stdout);
      t->func_();
      fflush (stderr);
      printout ("  PASS     %s\n", t->name_);
      fflush (stdout);
    }
}

int
run (void)
{
  TestChain::run (ptrdiff_t (global_test_chain));
  return 0;
}

} } // Bse::Test
<commit_msg>SFI: fix test error message<commit_after>// This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
#include "testing.hh"
#include <algorithm>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sfi/randomhash.hh>

#define TDEBUG(...)     Bse::debug ("Test", __VA_ARGS__)

namespace Bse {

/** The Test namespace offers utilities for unit tests.
 * The Test namespace is made available by  \#include <sfi/testing.hh>

 * See also sfi/testing.hh.
 */
namespace Test {

static void
test_assertion_failed()
{
  void *__p_[BSE_BACKTRACE_MAXDEPTH] = { 0, };
  String btmsg = pretty_backtrace (__p_, backtrace_pointers (__p_, sizeof (__p_) / sizeof (__p_[0])), __FILE__, __LINE__, NULL);
  if (btmsg.size())
    printerr ("%s", btmsg.c_str());
  printerr ("Bse: test assertion failed, aborting...");
  Bse::breakpoint();
  abort();
}

/** Initialize the Bse core for a test program.
 * Initializes Bse to execute unit tests by calling parse_settings_and_args()
 * with args "autonomous=1" and "testing=1" and setting the application name.
 * See also #$BSE_DEBUG.
 */
void
init (int *argcp, char **argv, const StringVector &args)
{
  Aida::assertion_failed_hook (test_assertion_failed);
  unsigned int flags = g_log_set_always_fatal (GLogLevelFlags (G_LOG_FATAL_MASK));
  g_log_set_always_fatal (GLogLevelFlags (flags | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL));
  sfi_init (argcp, argv, Bse::cstrings_to_vector (":autonomous:testing:fatal-warnings:", NULL));
}

Timer::Timer (double deadline_in_secs) :
  deadline_ (deadline_in_secs), test_duration_ (0), n_reps_ (0)
{}

Timer::~Timer ()
{}

double
Timer::bench_time ()
{
  /* timestamp_benchmark() counts nano seconds since program start, so
   * it's not going to exceed the 52bit double mantissa too fast.
   */
  return timestamp_benchmark() / 1000000000.0;
}

#define DEBUG_LOOPS_NEEDED(...) while (0) printerr (__VA_ARGS__)

int64
Timer::loops_needed ()
{
  if (samples_.size() < 3)
    {
      n_reps_ = MAX (1, n_reps_);
      DEBUG_LOOPS_NEEDED ("loops_needed: %d\n", n_reps_);
      return n_reps_;           // force significant number of test runs
    }
  double resolution = timestamp_resolution() / 1000000000.0;
  const double deadline = MAX (deadline_ == 0.0 ? 0.005 : deadline_, resolution * 10000.0);
  if (test_duration_ < deadline * 0.2)
    {
      // increase the number of tests per run to gain more accuracy
      n_reps_ = MAX (n_reps_ + 1, int64 (n_reps_ * 1.5)) | 1;
      DEBUG_LOOPS_NEEDED ("loops_needed: %d\n", n_reps_);
      return n_reps_;
    }
  if (test_duration_ < deadline)
    {
      DEBUG_LOOPS_NEEDED ("loops_needed: %d\n", n_reps_);
      return n_reps_;
    }
  DEBUG_LOOPS_NEEDED ("loops_needed: %d\n", 0);
  return 0;
}

void
Timer::submit (double elapsed, int64 repetitions)
{
  test_duration_ += elapsed;
  double resolution = timestamp_resolution() / 1000000000.0;
  if (elapsed >= resolution * 500.0) // force error below 5%
    samples_.push_back (elapsed / repetitions);
  else
    n_reps_ = (n_reps_ + n_reps_) | 1; // double n_reps_ to yield significant times
}

void
Timer::reset()
{
  samples_.resize (0);
  test_duration_ = 0;
  n_reps_ = 0;
}

double
Timer::min_elapsed () const
{
  double m = DBL_MAX;
  for (size_t i = 0; i < samples_.size(); i++)
    m = MIN (m, samples_[i]);
  return m;
}

double
Timer::max_elapsed () const
{
  double m = 0;
  for (size_t i = 0; i < samples_.size(); i++)
    m = MAX (m, samples_[i]);
  return m;
}

static String
ensure_newline (const String &s)
{
  if (!s.size() || s[s.size()-1] != '\n')
    return s + "\n";
  return s;
}

static __thread String *thread_test_start = NULL;

void
test_output (int kind, const String &msg)
{
  if (!thread_test_start)
    thread_test_start = new String();
  String &test_start = *thread_test_start;
  String prefix, sout;
  bool aborting = false;
  switch (kind)
    {
    case 'S':                   // TSTART()
      if (!test_start.empty())
        return test_output ('F', string_format ("Unfinished Test: %s\n", test_start));
      test_start = msg;
      sout = "  START…   " + ensure_newline (msg);
      break;
    case 'D':                   // TDONE() - test passed
      if (test_start.empty())
        return test_output ('F', "Extraneous TDONE() call");
      test_start = "";
      sout = "  …DONE    " + ensure_newline (msg);
      break;
    case 'I':                   // TNOTE() - verbose test message
      if (verbose())
        sout = "  NOTE     " + ensure_newline (msg);
      break;
    case 'P':
      sout = "  PASS     " + ensure_newline (msg);
      break;
    case 'F':
      sout = "  FAIL     " + ensure_newline (msg);
      aborting = true;
      break;
    default:
      sout = "  INFO     " + ensure_newline (msg);
      break;
    }
  if (!sout.empty())            // test message output
    {
      fflush (stderr);
      fputs (sout.c_str(), stdout);
      fflush (stdout);
    }
  if (aborting)
    {
      breakpoint();
    }
}

bool
slow()
{
  static bool cached_slow = feature_toggle_bool (getenv ("BSE_TEST"), "slow");
  return cached_slow;
}

bool
verbose()
{
  static bool cached_verbose = feature_toggle_bool (getenv ("BSE_TEST"), "verbose");
  return cached_verbose;
}

uint64_t
random_int64 ()
{
  return Bse::random_int64();
}

int64_t
random_irange (int64_t begin, int64_t end)
{
  return Bse::random_irange (begin, end);
}

double
random_float ()
{
  return Bse::random_float();
}

double
random_frange (double begin, double end)
{
  return Bse::random_frange (begin, end);
}

// == TestChain ==
static const TestChain *global_test_chain = NULL;

TestChain::TestChain (std::function<void()> tfunc, const std::string &tname) :
  name_ (tname), func_ (tfunc), next_ (global_test_chain)
{
  assert_return (next_ == global_test_chain);
  global_test_chain = this;
}

void
TestChain::run (ptrdiff_t internal_token)
{
  assert_return (internal_token == ptrdiff_t (global_test_chain));
  for (const TestChain *t = global_test_chain; t; t = t->next_)
    {
      fflush (stderr);
      printout ("  RUN…     %s\n", t->name_);
      fflush (stdout);
      t->func_();
      fflush (stderr);
      printout ("  PASS     %s\n", t->name_);
      fflush (stdout);
    }
}

int
run (void)
{
  TestChain::run (ptrdiff_t (global_test_chain));
  return 0;
}

} } // Bse::Test
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "sandbox/src/target_services.h"

#include <process.h>

#include "base/basictypes.h"
#include "sandbox/src/crosscall_client.h"
#include "sandbox/src/handle_closer_agent.h"
#include "sandbox/src/ipc_tags.h"
#include "sandbox/src/restricted_token_utils.h"
#include "sandbox/src/sandbox.h"
#include "sandbox/src/sandbox_types.h"
#include "sandbox/src/sharedmem_ipc_client.h"
#include "sandbox/src/sandbox_nt_util.h"

namespace {

// Flushing a cached key is triggered by just opening the key and closing the
// resulting handle. RegDisablePredefinedCache() is the documented way to flush
// HKCU so do not use it with this function.
bool FlushRegKey(HKEY root) {
  HKEY key;
  if (ERROR_SUCCESS == ::RegOpenKeyExW(root, NULL, 0, MAXIMUM_ALLOWED, &key)) {
    if (ERROR_SUCCESS != ::RegCloseKey(key))
      return false;
  }
  return true;
}

// This function forces advapi32.dll to release some internally cached handles
// that were made during calls to RegOpenkey and RegOpenKeyEx if it is called
// with a more restrictive token. Returns true if the flushing is succesful
// although this behavior is undocumented and there is no guarantee that in
// fact this will happen in future versions of windows.
bool FlushCachedRegHandles() {
  return (FlushRegKey(HKEY_LOCAL_MACHINE) &&
          FlushRegKey(HKEY_CLASSES_ROOT) &&
          FlushRegKey(HKEY_USERS));
}

// Checks if we have handle entries pending and runs the closer.
bool CloseOpenHandles() {
  if (sandbox::HandleCloserAgent::NeedsHandlesClosed()) {
    sandbox::HandleCloserAgent handle_closer;

    handle_closer.InitializeHandlesToClose();
    if (!handle_closer.CloseHandles())
      return false;
  }

  return true;
}

}  // namespace

namespace sandbox {

SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level =
    INTEGRITY_LEVEL_LAST;

TargetServicesBase::TargetServicesBase() {
}

ResultCode TargetServicesBase::Init() {
  process_state_.SetInitCalled();
  return SBOX_ALL_OK;
}

// Failure here is a breach of security so the process is terminated.
void TargetServicesBase::LowerToken() {
  if (ERROR_SUCCESS !=
      SetProcessIntegrityLevel(g_shared_delayed_integrity_level))
    ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_INTEGRITY);
  process_state_.SetRevertedToSelf();
  // If the client code as called RegOpenKey, advapi32.dll has cached some
  // handles. The following code gets rid of them.
  if (!::RevertToSelf())
    ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_DROPTOKEN);
  if (!FlushCachedRegHandles())
    ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_FLUSHANDLES);
  if (ERROR_SUCCESS != ::RegDisablePredefinedCache())
    ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CACHEDISABLE);
  if (!CloseOpenHandles())
    ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CLOSEHANDLES);
}

ProcessState* TargetServicesBase::GetState() {
  return &process_state_;
}

TargetServicesBase* TargetServicesBase::GetInstance() {
  static TargetServicesBase instance;
  return &instance;
}

// The broker services a 'test' IPC service with the IPC_PING_TAG tag.
bool TargetServicesBase::TestIPCPing(int version) {
  void* memory = GetGlobalIPCMemory();
  if (NULL == memory) {
    return false;
  }
  SharedMemIPCClient ipc(memory);
  CrossCallReturn answer = {0};

  if (1 == version) {
    uint32 tick1 = ::GetTickCount();
    uint32 cookie = 717115;
    ResultCode code = CrossCall(ipc, IPC_PING1_TAG, cookie, &answer);

    if (SBOX_ALL_OK != code) {
      return false;
    }
    // We should get two extended returns values from the IPC, one is the
    // tick count on the broker and the other is the cookie times two.
    if ((answer.extended_count != 2)) {
      return false;
    }
    // We test the first extended answer to be within the bounds of the tick
    // count only if there was no tick count wraparound.
    uint32 tick2 = ::GetTickCount();
    if (tick2 >= tick1) {
      if ((answer.extended[0].unsigned_int < tick1) ||
          (answer.extended[0].unsigned_int > tick2)) {
        return false;
      }
    }

    if (answer.extended[1].unsigned_int != cookie * 2) {
      return false;
    }
  } else if (2 == version) {
    uint32 cookie = 717111;
    InOutCountedBuffer counted_buffer(&cookie, sizeof(cookie));
    ResultCode code = CrossCall(ipc, IPC_PING2_TAG, counted_buffer, &answer);

    if (SBOX_ALL_OK != code) {
      return false;
    }
    if (cookie != 717111 * 3) {
      return false;
    }
  } else {
    return false;
  }
  return true;
}

bool ProcessState::IsKernel32Loaded() {
  return process_state_ != 0;
}

bool ProcessState::InitCalled() {
  return process_state_ > 1;
}

bool ProcessState::RevertedToSelf() {
  return process_state_ > 2;
}

void ProcessState::SetKernel32Loaded() {
  if (!process_state_)
    process_state_ = 1;
}

void ProcessState::SetInitCalled() {
  if (process_state_ < 2)
    process_state_ = 2;
}

void ProcessState::SetRevertedToSelf() {
  if (process_state_ < 3)
    process_state_ = 3;
}

}  // namespace sandbox
<commit_msg>Prevent the renderer from dying if launched under App-V/SoftGrid.<commit_after>// Copyright (c) 2011 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 "sandbox/src/target_services.h"

#include <process.h>

#include "base/basictypes.h"
#include "sandbox/src/crosscall_client.h"
#include "sandbox/src/handle_closer_agent.h"
#include "sandbox/src/ipc_tags.h"
#include "sandbox/src/restricted_token_utils.h"
#include "sandbox/src/sandbox.h"
#include "sandbox/src/sandbox_types.h"
#include "sandbox/src/sharedmem_ipc_client.h"
#include "sandbox/src/sandbox_nt_util.h"

namespace {

// Flushing a cached key is triggered by just opening the key and closing the
// resulting handle. RegDisablePredefinedCache() is the documented way to flush
// HKCU so do not use it with this function.
bool FlushRegKey(HKEY root) {
  HKEY key;
  if (ERROR_SUCCESS == ::RegOpenKeyExW(root, NULL, 0, MAXIMUM_ALLOWED, &key)) {
    if (ERROR_SUCCESS != ::RegCloseKey(key))
      return false;
  }
  return true;
}

// This function forces advapi32.dll to release some internally cached handles
// that were made during calls to RegOpenkey and RegOpenKeyEx if it is called
// with a more restrictive token. Returns true if the flushing is succesful
// although this behavior is undocumented and there is no guarantee that in
// fact this will happen in future versions of windows.
bool FlushCachedRegHandles() {
  return (FlushRegKey(HKEY_LOCAL_MACHINE) &&
          FlushRegKey(HKEY_CLASSES_ROOT) &&
          FlushRegKey(HKEY_USERS));
}

// Checks if we have handle entries pending and runs the closer.
bool CloseOpenHandles() {
  if (sandbox::HandleCloserAgent::NeedsHandlesClosed()) {
    sandbox::HandleCloserAgent handle_closer;

    handle_closer.InitializeHandlesToClose();
    if (!handle_closer.CloseHandles())
      return false;
  }

  return true;
}

}  // namespace

namespace sandbox {

SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level =
    INTEGRITY_LEVEL_LAST;

TargetServicesBase::TargetServicesBase() {
}

ResultCode TargetServicesBase::Init() {
  process_state_.SetInitCalled();
  return SBOX_ALL_OK;
}

// Failure here is a breach of security so the process is terminated.
void TargetServicesBase::LowerToken() {
  DWORD error_code = SetProcessIntegrityLevel(g_shared_delayed_integrity_level);
  // Here we don't terminate the process if the error is ERROR_INVALID_HANDLE,
  // this is because this error is not possible in normal circumstances, unless
  // it is hooked by sftldr_wow64.dll, in which case we prefer to keep running.
  // See http://crbug.com/95888.
  if (ERROR_SUCCESS != error_code && ERROR_INVALID_HANDLE != error_code)
    ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_INTEGRITY);
  process_state_.SetRevertedToSelf();
  // If the client code as called RegOpenKey, advapi32.dll has cached some
  // handles. The following code gets rid of them.
  if (!::RevertToSelf())
    ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_DROPTOKEN);
  if (!FlushCachedRegHandles())
    ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_FLUSHANDLES);
  if (ERROR_SUCCESS != ::RegDisablePredefinedCache())
    ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CACHEDISABLE);
  if (!CloseOpenHandles())
    ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CLOSEHANDLES);
}

ProcessState* TargetServicesBase::GetState() {
  return &process_state_;
}

TargetServicesBase* TargetServicesBase::GetInstance() {
  static TargetServicesBase instance;
  return &instance;
}

// The broker services a 'test' IPC service with the IPC_PING_TAG tag.
bool TargetServicesBase::TestIPCPing(int version) {
  void* memory = GetGlobalIPCMemory();
  if (NULL == memory) {
    return false;
  }
  SharedMemIPCClient ipc(memory);
  CrossCallReturn answer = {0};

  if (1 == version) {
    uint32 tick1 = ::GetTickCount();
    uint32 cookie = 717115;
    ResultCode code = CrossCall(ipc, IPC_PING1_TAG, cookie, &answer);

    if (SBOX_ALL_OK != code) {
      return false;
    }
    // We should get two extended returns values from the IPC, one is the
    // tick count on the broker and the other is the cookie times two.
    if ((answer.extended_count != 2)) {
      return false;
    }
    // We test the first extended answer to be within the bounds of the tick
    // count only if there was no tick count wraparound.
    uint32 tick2 = ::GetTickCount();
    if (tick2 >= tick1) {
      if ((answer.extended[0].unsigned_int < tick1) ||
          (answer.extended[0].unsigned_int > tick2)) {
        return false;
      }
    }

    if (answer.extended[1].unsigned_int != cookie * 2) {
      return false;
    }
  } else if (2 == version) {
    uint32 cookie = 717111;
    InOutCountedBuffer counted_buffer(&cookie, sizeof(cookie));
    ResultCode code = CrossCall(ipc, IPC_PING2_TAG, counted_buffer, &answer);

    if (SBOX_ALL_OK != code) {
      return false;
    }
    if (cookie != 717111 * 3) {
      return false;
    }
  } else {
    return false;
  }
  return true;
}

bool ProcessState::IsKernel32Loaded() {
  return process_state_ != 0;
}

bool ProcessState::InitCalled() {
  return process_state_ > 1;
}

bool ProcessState::RevertedToSelf() {
  return process_state_ > 2;
}

void ProcessState::SetKernel32Loaded() {
  if (!process_state_)
    process_state_ = 1;
}

void ProcessState::SetInitCalled() {
  if (process_state_ < 2)
    process_state_ = 2;
}

void ProcessState::SetRevertedToSelf() {
  if (process_state_ < 3)
    process_state_ = 3;
}

}  // namespace sandbox
<|endoftext|>


<commit_before>#define REFRESHRATE 16
#include "HelloBasic3D.h"

int main(int argc, char* argv[])
{
	HelloBasic3D * firstScene = new HelloBasic3D(argc, argv);
	return 0;
}<commit_msg>Update main.cpp<commit_after>#include "HelloBasic3D.h"

int main(int argc, char* argv[])
{
	HelloBasic3D * firstScene = new HelloBasic3D(argc, argv);
	return 0;
}
<|endoftext|>