<commit_before>/**
*  Copyright (C) 2016 3D Repo Ltd
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Affero General Public License as
*  published by the Free Software Foundation, either version 3 of the
*  License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Affero General Public License for more details.
*
*  You should have received a copy of the GNU Affero General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <cstdlib>

#include <gtest/gtest.h>

#include <repo/core/model/bson/repo_node_transformation.h>
#include <repo/core/model/bson/repo_bson_builder.h>
#include "../../../../repo_test_utils.h"

using namespace repo::core::model;

std::vector<float> identity =
{ 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };

std::vector<float> notId =
{ 1, 2, 3, 4,
5, 6, 7, 8,
9, 0.3f, 10, 11,
5342, 31, 0.6f, 12 };

std::vector<float> idInBoundary =
{ 1, 0, 0, 0,
0, 1, 0, (float)1e-6,
0, 0, 1, 0,
0, (float)1e-6, (float)1e-6, 1 };

std::vector<float> notIdInBoundary = { 1, 0, 0, 0,
0, 1, 0, (float)2e-5,
0, 0, 2, 0,
0, (float)2e-5, (float)2e-5, 1 };

TransformationNode makeTransformationNode(
	const std::vector<float> &matrix)
{
	RepoBSONBuilder bsonBuilder;
	RepoBSONBuilder rows;
	for (uint32_t i = 0; i < 4; ++i)
	{
		RepoBSONBuilder columns;
		for (uint32_t j = 0; j < 4; ++j){
			columns << std::to_string(j) << matrix[i * 4 + j];
		}
		rows.appendArray(std::to_string(i), columns.obj());
	}
	bsonBuilder.appendArray(REPO_NODE_LABEL_MATRIX, rows.obj());

	return bsonBuilder.obj();
}

TEST(RepoTransformationNodeTest, Constructor)
{
	auto empty = TransformationNode();

	EXPECT_TRUE(empty.isEmpty());
	EXPECT_EQ(NodeType::TRANSFORMATION, empty.getTypeAsEnum());

	auto repoBson = RepoBSON(BSON("test" << "blah" << "test2" << 2));

	auto fromRepoBSON = TransformationNode(repoBson);
	EXPECT_EQ(NodeType::TRANSFORMATION, fromRepoBSON.getTypeAsEnum());
	EXPECT_EQ(fromRepoBSON.nFields(), repoBson.nFields());
	EXPECT_EQ(0, fromRepoBSON.getFileList().size());
}

TEST(RepoTransformationNodeTest, IdentityTest)
{
	auto empty = TransformationNode();
	EXPECT_TRUE(empty.isIdentity());

	EXPECT_TRUE(makeTransformationNode(identity).isIdentity());
	EXPECT_TRUE(makeTransformationNode(idInBoundary).isIdentity());
	EXPECT_FALSE(makeTransformationNode(notId).isIdentity());
	EXPECT_FALSE(makeTransformationNode(notIdInBoundary).isIdentity());
}

TEST(RepoTransformationNodeTest, IdentityTest2)
{
	auto identity = TransformationNode::identityMat();

	ASSERT_EQ(4, identity.size());
	for (int i = 0; i < 4; ++i)
	{
		ASSERT_EQ(4, identity[i].size());
		for (int j = 0; j < 4; ++j)
		{
			float expectedOutcome = i % 4 == j ? 1 : 0;
			EXPECT_EQ(expectedOutcome, identity[i][j]);
		}
	}
}

TEST(RepoTransformationNodeTest, TypeTest)
{
	TransformationNode node = TransformationNode();

	EXPECT_EQ(REPO_NODE_TYPE_TRANSFORMATION, node.getType());
	EXPECT_EQ(NodeType::TRANSFORMATION, node.getTypeAsEnum());
}

TEST(RepoTransformationNodeTest, PositionDependantTest)
{
	TransformationNode node = TransformationNode();
	//transformation node should always be position dependant
	EXPECT_TRUE(node.positionDependant());
}

TEST(RepoTransformationNodeTest, SEqualTest)
{
	auto empty1 = TransformationNode();
	auto empty2 = TransformationNode();

	auto notEmpty1 = makeTransformationNode(notId);
	auto notEmpty2 = makeTransformationNode(notId);
	auto notEmpty3 = makeTransformationNode(identity);

	EXPECT_TRUE(empty1.sEqual(empty2));
	EXPECT_TRUE(empty2.sEqual(empty1));
	EXPECT_TRUE(empty1.sEqual(empty1));
	EXPECT_TRUE(notEmpty1.sEqual(notEmpty2));
	EXPECT_TRUE(notEmpty2.sEqual(notEmpty1));
	EXPECT_FALSE(notEmpty1.sEqual(empty2));
	EXPECT_TRUE(notEmpty3.sEqual(notEmpty3));
	EXPECT_FALSE(notEmpty3.sEqual(notEmpty2));
	EXPECT_FALSE(empty1.sEqual(notEmpty2));
}

TEST(RepoTransformationNodeTest, CloneAndApplyTransformationTest)
{
	auto empty = TransformationNode();

	TransformationNode modifiedEmpty = empty.cloneAndApplyTransformation(notId);

	EXPECT_EQ(empty.getTransMatrix(false), identity);
	EXPECT_EQ(modifiedEmpty.getTransMatrix(false), notId);

	auto filled = makeTransformationNode(notId);
	TransformationNode modifiedFilled = filled.cloneAndApplyTransformation(std::vector<float>());

	EXPECT_EQ(modifiedFilled.getTransMatrix(false), notId);
}

TEST(RepoTransformationNodeTest, GetTransMatrixTest)
{
	TransformationNode empty = TransformationNode();
	EXPECT_EQ(identity, empty.getTransMatrix(false));

	TransformationNode notEmpty = makeTransformationNode(notId);
	EXPECT_EQ(notId, notEmpty.getTransMatrix(false));

	//check transpose is done correctly
	auto notIdTransposed = notEmpty.getTransMatrix(true);

	auto notIdTransData = notIdTransposed.getData();
	ASSERT_EQ(notId.size(), notIdTransData.size());
	for (int i = 0; i < 4; ++i)
	{
		for (int j = 0; j < 4; ++j)
		{
			int index = i * 4 + j;
			int transIndex = j * 4 + i;
			EXPECT_EQ(notId[index], notIdTransData[transIndex]);
		}
	}
}<commit_msg>#48 diagnose travis<commit_after>/**
*  Copyright (C) 2016 3D Repo Ltd
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Affero General Public License as
*  published by the Free Software Foundation, either version 3 of the
*  License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Affero General Public License for more details.
*
*  You should have received a copy of the GNU Affero General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <cstdlib>

#include <gtest/gtest.h>

#include <repo/core/model/bson/repo_node_transformation.h>
#include <repo/core/model/bson/repo_bson_builder.h>
#include "../../../../repo_test_utils.h"

using namespace repo::core::model;

std::vector<float> identity =
{ 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };

std::vector<float> notId =
{ 1, 2, 3, 4,
5, 6, 7, 8,
9, 0.3f, 10, 11,
5342, 31, 0.6f, 12 };

std::vector<float> idInBoundary =
{ 1, 0, 0, 0,
0, 1, 0, (float)1e-6,
0, 0, 1, 0,
0, (float)1e-6, (float)1e-6, 1 };

std::vector<float> notIdInBoundary = { 1, 0, 0, 0,
0, 1, 0, (float)2e-5,
0, 0, 2, 0,
0, (float)2e-5, (float)2e-5, 1 };

TransformationNode makeTransformationNode(
	const std::vector<float> &matrix)
{
	RepoBSONBuilder bsonBuilder;
	RepoBSONBuilder rows;
	for (uint32_t i = 0; i < 4; ++i)
	{
		RepoBSONBuilder columns;
		for (uint32_t j = 0; j < 4; ++j){
			columns << std::to_string(j) << matrix[i * 4 + j];
		}
		rows.appendArray(std::to_string(i), columns.obj());
	}
	bsonBuilder.appendArray(REPO_NODE_LABEL_MATRIX, rows.obj());

	return bsonBuilder.obj();
}

TEST(RepoTransformationNodeTest, Constructor)
{
	auto empty = TransformationNode();

	EXPECT_TRUE(empty.isEmpty());
	EXPECT_EQ(NodeType::TRANSFORMATION, empty.getTypeAsEnum());

	auto repoBson = RepoBSON(BSON("test" << "blah" << "test2" << 2));

	auto fromRepoBSON = TransformationNode(repoBson);
	EXPECT_EQ(NodeType::TRANSFORMATION, fromRepoBSON.getTypeAsEnum());
	EXPECT_EQ(fromRepoBSON.nFields(), repoBson.nFields());
	EXPECT_EQ(0, fromRepoBSON.getFileList().size());
}

TEST(RepoTransformationNodeTest, IdentityTest)
{
	auto empty = TransformationNode();
	EXPECT_TRUE(empty.isIdentity());

	EXPECT_TRUE(makeTransformationNode(identity).isIdentity());
	EXPECT_TRUE(makeTransformationNode(idInBoundary).isIdentity());
	EXPECT_FALSE(makeTransformationNode(notId).isIdentity());
	EXPECT_FALSE(makeTransformationNode(notIdInBoundary).isIdentity());
}

TEST(RepoTransformationNodeTest, IdentityTest2)
{
	auto identity = TransformationNode::identityMat();

	ASSERT_EQ(4, identity.size());
	for (int i = 0; i < 4; ++i)
	{
		ASSERT_EQ(4, identity[i].size());
		for (int j = 0; j < 4; ++j)
		{
			float expectedOutcome = i % 4 == j ? 1 : 0;
			EXPECT_EQ(expectedOutcome, identity[i][j]);
		}
	}
}

TEST(RepoTransformationNodeTest, TypeTest)
{
	TransformationNode node = TransformationNode();

	EXPECT_EQ(REPO_NODE_TYPE_TRANSFORMATION, node.getType());
	EXPECT_EQ(NodeType::TRANSFORMATION, node.getTypeAsEnum());
}

TEST(RepoTransformationNodeTest, PositionDependantTest)
{
	TransformationNode node = TransformationNode();
	//transformation node should always be position dependant
	EXPECT_TRUE(node.positionDependant());
}

TEST(RepoTransformationNodeTest, SEqualTest)
{
	auto empty1 = TransformationNode();
	auto empty2 = TransformationNode();

	auto notEmpty1 = makeTransformationNode(notId);
	auto notEmpty2 = makeTransformationNode(notId);
	auto notEmpty3 = makeTransformationNode(identity);

	EXPECT_TRUE(empty1.sEqual(empty2));
	EXPECT_TRUE(empty2.sEqual(empty1));
	EXPECT_TRUE(empty1.sEqual(empty1));
	EXPECT_TRUE(notEmpty1.sEqual(notEmpty2));
	EXPECT_TRUE(notEmpty2.sEqual(notEmpty1));
	EXPECT_FALSE(notEmpty1.sEqual(empty2));
	EXPECT_TRUE(notEmpty3.sEqual(notEmpty3));
	EXPECT_FALSE(notEmpty3.sEqual(notEmpty2));
	EXPECT_FALSE(empty1.sEqual(notEmpty2));
}

TEST(RepoTransformationNodeTest, CloneAndApplyTransformationTest)
{
	auto empty = TransformationNode();

	TransformationNode modifiedEmpty = empty.cloneAndApplyTransformation(notId);

	EXPECT_EQ(empty.getTransMatrix(false), identity);
	EXPECT_EQ(modifiedEmpty.getTransMatrix(false), notId);

	auto filled = makeTransformationNode(notId);
	TransformationNode modifiedFilled = filled.cloneAndApplyTransformation(std::vector<float>());

	EXPECT_EQ(modifiedFilled.getTransMatrix(false).getData(), notId);
}

TEST(RepoTransformationNodeTest, GetTransMatrixTest)
{
	TransformationNode empty = TransformationNode();
	EXPECT_EQ(identity, empty.getTransMatrix(false));

	TransformationNode notEmpty = makeTransformationNode(notId);
	EXPECT_EQ(notId, notEmpty.getTransMatrix(false));

	//check transpose is done correctly
	auto notIdTransposed = notEmpty.getTransMatrix(true);

	auto notIdTransData = notIdTransposed.getData();
	ASSERT_EQ(notId.size(), notIdTransData.size());
	for (int i = 0; i < 4; ++i)
	{
		for (int j = 0; j < 4; ++j)
		{
			int index = i * 4 + j;
			int transIndex = j * 4 + i;
			EXPECT_EQ(notId[index], notIdTransData[transIndex]);
		}
	}
}<|endoftext|>


<commit_before>#include "Destruct.h"

namespace dale
{
namespace Operation
{
Function *
getDestructor(Context *ctx, Type *type)
{
    std::vector<Type *> types;
    types.push_back(ctx->tr->getPointerType(type));
    Function *fn = ctx->getFunction("destroy", &types, NULL, 0);
    return fn;
}

bool
destructArray(Context *ctx, ParseResult *pr, ParseResult *pr_ret,
              llvm::IRBuilder<> *builder, bool value_is_ptr)
{
    Type *array_type = pr->type->array_type;
    llvm::BasicBlock *block = pr->block;
    llvm::Value *array_value = pr->value;

    if (!array_value) {
        return true;
    }
    if (!array_value->getType()) {
        return true;
    }

    if (!array_type->is_array) {
        Function *fn = getDestructor(ctx, array_type);
        if (!fn) {
            return true;
        }
    }

    llvm::Type *llvm_array_type = ctx->toLLVMType(pr->type, NULL, false);

    /* Array literals are stored in the variable table as actual
     * arrays, rather than pointers to arrays.  This should be fixed at
     * some point, but for now, if this value is not a pointer, then
     * store it in a temporary location. */

    if (!pr->value->getType()->isPointerTy()) {
        array_value = llvm::cast<llvm::Value>(
            builder->CreateAlloca(llvm_array_type)
        );
        builder->CreateStore(pr->value, array_value);
    }

    for (int i = (pr->type->array_size - 1); i >= 0; i--) {
        ParseResult temp;
        temp.type  = array_type;
        temp.block = block;
        std::vector<llvm::Value *> indices;
        STL::push_back2(&indices,
                        ctx->nt->getLLVMZero(),
                        llvm::cast<llvm::Value>(
                            llvm::ConstantInt::get(
                                ctx->nt->getNativeIntType(), i
                            )
                        ));
        ParseResult mnew;

        llvm::Value *res = builder->Insert(
                                llvm::GetElementPtrInst::Create(
                                    array_value,
                                    llvm::ArrayRef<llvm::Value*>(indices)
                                ),
                                "asdf"
                            );
        if (!array_type->is_array) {
            temp.value = builder->CreateLoad(res);
        } else {
            temp.value = res;
        }
        Destruct(ctx, &temp, &mnew, builder);
    }

    pr_ret->block = block;
    return true;
}

bool
destruct_(Context *ctx, ParseResult *pr, ParseResult *pr_ret,
          llvm::IRBuilder<> *builder, bool value_is_ptr)
{
    pr->copyTo(pr_ret);

    if (pr->do_not_destruct) {
        return true;
    }

    assert(pr->type);

    /* If it's an array with a known size, call this function for
     * each element in the array, in order from last to first. */
    if (pr->type->is_array && pr->type->array_size) {
        return destructArray(ctx, pr, pr_ret, builder, value_is_ptr);
    }

    Function *fn = getDestructor(ctx, pr->type);
    if (!fn) {
        /* If this is a struct, call Destruct on each of the elements,
         * in the absence of a destructor for the struct as a whole.
         * */
        Type *type = pr->type;
        if (type->struct_name.size()) {
            Struct *st = ctx->getStruct(type->struct_name.c_str(),
                                                 &(type->namespaces));
            std::vector<Type*> *st_types = &(st->member_types);
            int i = 0;
            llvm::Value *array_value = pr->value;

            if (!value_is_ptr) {
                array_value = llvm::cast<llvm::Value>(
                        builder->CreateAlloca(
                            ctx->toLLVMType(pr->type, NULL, false))
                        );
                builder->CreateStore(pr->value, array_value);
            }

            for (std::vector<Type*>::iterator
                    b = st_types->begin(),
                    e = st_types->end();
                    b != e;
                    ++b) {
                ParseResult element;
                ParseResult mnew;
                std::string ts;
                (*b)->toString(&ts);
                element.set(pr->block, *b, array_value);
                std::vector<llvm::Value *> indices;
                STL::push_back2(&indices,
                                ctx->nt->getLLVMZero(),
                                llvm::cast<llvm::Value>(
                                    llvm::ConstantInt::get(
                                        ctx->nt->getNativeIntType(),
                                        i++
                                    )
                                ));
                element.value =
                    builder->Insert(
                        llvm::GetElementPtrInst::Create(
                            array_value,
                            llvm::ArrayRef<llvm::Value*>(indices)
                        ),
                        "asdf"
                    );
                Destruct(ctx, &element, &mnew, builder, true);
            }
        }
        return true;
    }
    std::vector<llvm::Value *> call_args;
    llvm::Value *new_ptr2;
    if (value_is_ptr) {
        new_ptr2 = pr->value;
    } else {
        new_ptr2 = llvm::cast<llvm::Value>(
            builder->CreateAlloca(ctx->toLLVMType(pr->type, NULL, false))
        );
        builder->CreateStore(pr->value, new_ptr2);
    }

    call_args.push_back(new_ptr2);
    builder->CreateCall(
        fn->llvm_function,
        llvm::ArrayRef<llvm::Value*>(call_args));
    return true;
}

bool
Destruct(Context *ctx, ParseResult *pr, ParseResult *pr_ret,
         llvm::IRBuilder<> *builder, bool value_is_ptr)
{
    bool res;

    if (!builder) {
        llvm::IRBuilder<> internal_builder(pr->block);
        res = destruct_(ctx, pr, pr_ret, &internal_builder, value_is_ptr);
    } else {
        res = destruct_(ctx, pr, pr_ret, builder, value_is_ptr);
    }

    return res;
}
}
}
<commit_msg>[master] tidying<commit_after>#include "Destruct.h"

namespace dale
{
namespace Operation
{
Function *
getDestructor(Context *ctx, Type *type)
{
    std::vector<Type *> types;
    types.push_back(ctx->tr->getPointerType(type));
    Function *fn = ctx->getFunction("destroy", &types, NULL, 0);
    return fn;
}

bool
destructArray(Context *ctx, ParseResult *pr, ParseResult *pr_ret,
              llvm::IRBuilder<> *builder, bool value_is_ptr)
{
    Type *array_type = pr->type->array_type;
    llvm::BasicBlock *block = pr->block;
    llvm::Value *array_value = pr->value;

    if (!array_value) {
        return true;
    }
    if (!array_value->getType()) {
        return true;
    }

    if (!array_type->is_array) {
        Function *fn = getDestructor(ctx, array_type);
        if (!fn) {
            return true;
        }
    }

    llvm::Type *llvm_array_type = ctx->toLLVMType(pr->type, NULL, false);

    /* Array literals are stored in the variable table as actual
     * arrays, rather than pointers to arrays.  This should be fixed at
     * some point, but for now, if this value is not a pointer, then
     * store it in a temporary location. */

    if (!pr->value->getType()->isPointerTy()) {
        array_value = llvm::cast<llvm::Value>(
            builder->CreateAlloca(llvm_array_type)
        );
        builder->CreateStore(pr->value, array_value);
    }

    for (int i = (pr->type->array_size - 1); i >= 0; i--) {
        ParseResult temp;
        temp.type  = array_type;
        temp.block = block;
        std::vector<llvm::Value *> indices;
        STL::push_back2(
            &indices,
            ctx->nt->getLLVMZero(),
            llvm::cast<llvm::Value>(
                llvm::ConstantInt::get(ctx->nt->getNativeIntType(), i)
            )
        );
        ParseResult mnew;

        llvm::Value *res =
            builder->Insert(
                llvm::GetElementPtrInst::Create(
                    array_value, llvm::ArrayRef<llvm::Value*>(indices)
                ),
                "ap"
            );
        if (!array_type->is_array) {
            temp.value = builder->CreateLoad(res);
        } else {
            temp.value = res;
        }
        Destruct(ctx, &temp, &mnew, builder);
    }

    pr_ret->block = block;
    return true;
}

bool
destructStruct(Context *ctx, ParseResult *pr, ParseResult *pr_ret,
               llvm::IRBuilder<> *builder, bool value_is_ptr)
{
    ParseResult unused;

    Struct *st = ctx->getStruct(pr->type);
    std::vector<Type*> *st_types = &(st->member_types);

    llvm::Value *struct_value;
    if (value_is_ptr) {
        struct_value = pr->value;
    } else {
        struct_value = llvm::cast<llvm::Value>(
            builder->CreateAlloca(
                ctx->toLLVMType(pr->type, NULL, false))
            );
        builder->CreateStore(pr->value, struct_value);
    }

    int i = 0;
    for (std::vector<Type*>::iterator b = st_types->begin(),
                                      e = st_types->end();
            b != e;
            ++b) {
        ParseResult element;
        element.set(pr->block, *b, struct_value);
        std::vector<llvm::Value *> indices;
        STL::push_back2(
            &indices,
            ctx->nt->getLLVMZero(),
            llvm::cast<llvm::Value>(
                llvm::ConstantInt::get(ctx->nt->getNativeIntType(), i++)
            )
        );
        element.value =
            builder->Insert(
                llvm::GetElementPtrInst::Create(
                    struct_value,
                    llvm::ArrayRef<llvm::Value*>(indices)
                ),
                "sp"
            );
        Destruct(ctx, &element, &unused, builder, true);
    }

    return true;
}

bool
destruct_(Context *ctx, ParseResult *pr, ParseResult *pr_ret,
          llvm::IRBuilder<> *builder, bool value_is_ptr)
{
    pr->copyTo(pr_ret);

    if (pr->do_not_destruct) {
        return true;
    }

    if (pr->type->is_array && pr->type->array_size) {
        return destructArray(ctx, pr, pr_ret, builder, value_is_ptr);
    }

    Function *fn = getDestructor(ctx, pr->type);
    if (!fn) {
        if (pr->type->struct_name.size()) {
            destructStruct(ctx, pr, pr_ret, builder, value_is_ptr);
        }
        return true;
    }

    std::vector<llvm::Value *> call_args;
    llvm::Value *value_ptr;
    if (value_is_ptr) {
        value_ptr = pr->value;
    } else {
        value_ptr = llvm::cast<llvm::Value>(
            builder->CreateAlloca(ctx->toLLVMType(pr->type, NULL, false))
        );
        builder->CreateStore(pr->value, value_ptr);
    }

    call_args.push_back(value_ptr);
    builder->CreateCall(
        fn->llvm_function,
        llvm::ArrayRef<llvm::Value*>(call_args)
    );

    return true;
}

bool
Destruct(Context *ctx, ParseResult *pr, ParseResult *pr_ret,
         llvm::IRBuilder<> *builder, bool value_is_ptr)
{
    bool res;

    if (!builder) {
        llvm::IRBuilder<> internal_builder(pr->block);
        res = destruct_(ctx, pr, pr_ret, &internal_builder, value_is_ptr);
    } else {
        res = destruct_(ctx, pr, pr_ret, builder, value_is_ptr);
    }

    return res;
}
}
}
<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/trajectory/CTimeSeries.cpp,v $
   $Revision: 1.11 $
   $Name:  $
   $Author: shoops $
   $Date: 2006/08/10 19:49:49 $
   End CVS Header */

// Copyright  2005 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"

#include "CTimeSeries.h"
#include "model/CMetabNameInterface.h"
#include "model/CModel.h"
#include "utilities/CSort.h"

CTimeSeries::CTimeSeries()
    : mIt(begin()),
    mpState(NULL),
    mDummyString(""),
    mDummyFloat(0)
{}

bool CTimeSeries::init(C_INT32 n, CModel * pModel)
{
  //std::cout << n << std::endl;
  mpState = & pModel->getState();

  CStateTemplate & Template = pModel->getStateTemplate();

  CModelEntity **it = Template.getEntities();
  CModelEntity **end = Template.endDependent();

  resize(n + 1);
  mIt = begin();

  C_INT32 i, imax = Template.getNumVariable() + 1;

  mPivot.resize(imax);
  mTitles.resize(imax);
  mFactors.resize(imax);

  C_FLOAT64 Number2QuantityFactor = pModel->getNumber2QuantityFactor();

  CMetab * pMetab;

  for (i = 0; it != end; ++i, ++it)
    {
      if ((pMetab = dynamic_cast<CMetab *>(*it)) != NULL)
        {
          mTitles[i] = CMetabNameInterface::getDisplayName(pModel, *pMetab);
          mFactors[i] =
            Number2QuantityFactor / pMetab->getCompartment()->getValue();
        }
      else
        {
          mTitles[i] = (*it)->getObjectDisplayName();
          mFactors[i] = 1.0;
        }
    }

  mTitles[0] = "Time";

  const unsigned C_INT32 * pUserOrder = Template.getUserOrder().array();
  const unsigned C_INT32 * pUserOrderEnd = pUserOrder + Template.getUserOrder().size();
  it = Template.getEntities();

  for (i = 0; pUserOrder != pUserOrderEnd; ++pUserOrder)
    if (it[*pUserOrder]->isUsed())
      mPivot[i++] = *pUserOrder;

  DebugFile << Template.getUserOrder() << std::endl;
  DebugFile << mPivot << std::endl;

  return true;
}

bool CTimeSeries::add()
{
  //std::cout << mpState->getTime() << std::endl;;
  if (mIt == end())
    {
      C_INT32 dummy = mIt - begin();
      resize(size() + 256);
      mIt = begin() + dummy;
      //std::cout << " resize " << dummy << std::endl;
    }

  *mIt = *mpState;

  ++mIt;

  return true;
}

bool CTimeSeries::finish()
{
  //std::cout << mCounter << std::endl;
  erase(mIt, end());
  return true;
}

//*** the methods to retrieve data from the CTimeSeries *******

unsigned C_INT32 CTimeSeries::getNumSteps() const
  {return mIt - begin();}

unsigned C_INT32 CTimeSeries::getNumVariables() const
  {
    if (mpState)
      return mpState->getNumVariable() + 1;

    return 0;
  }

const C_FLOAT64 & CTimeSeries::getData(unsigned C_INT32 step, unsigned C_INT32 var) const
  {
    if (step >= getNumSteps()) return mDummyFloat;

    if (var < mPivot.size()) return *(&(*this)[step].getTime() + mPivot[var]);

    return mDummyFloat;
  }

C_FLOAT64 CTimeSeries::getConcentrationData(unsigned C_INT32 step, unsigned C_INT32 var) const
  {
    static C_FLOAT64 tmp;

    if (step >= getNumSteps()) return mDummyFloat;

    if (var < mPivot.size())
      return tmp = *(&(*this)[step].getTime() + mPivot[var]) * mFactors[mPivot[var]];

    return mDummyFloat;
  }

const std::string & CTimeSeries::getTitle(unsigned C_INT32 var) const
  {
    if (var < mPivot.size())
      return mTitles[mPivot[var]];
    else
      return mDummyString;
  }

int CTimeSeries::save(const std::string& fileName, bool writeParticleNumbers, const std::string& separator) const
  {
    std::ofstream fileStream(utf8ToLocale(fileName).c_str());
    std::ostringstream* stringStream = new std::ostringstream();
    (*stringStream) << "# ";
    unsigned int counter2;
    unsigned int maxCount2 = this->getNumVariables();
    for (counter2 = 0; counter2 < maxCount2;++counter2)
      {
        (*stringStream) << this->getTitle(counter2) << separator;
      }
    (*stringStream) << std::endl;
    fileStream << stringStream->str();
    if (!fileStream.good()) return 1;
    unsigned int counter;
    unsigned int maxCount = this->getNumSteps();
    for (counter = 0; counter < maxCount;++counter)
      {
        delete stringStream;
        stringStream = new std::ostringstream();
        for (counter2 = 0; counter2 < maxCount2;++counter2)
          {
            C_FLOAT64 value;
            if (writeParticleNumbers)
              {
                value = this->getData(counter, counter2);
              }
            else
              {
                value = this->getConcentrationData(counter, counter2);
              }
            (*stringStream) << value << separator;
          }
        (*stringStream) << std::endl;
        fileStream << stringStream->str();
        if (!fileStream.good()) return 1;
      }
    fileStream.close();
    delete stringStream;
    return 0;
  }
<commit_msg>Removed debug statements.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/trajectory/CTimeSeries.cpp,v $
   $Revision: 1.12 $
   $Name:  $
   $Author: shoops $
   $Date: 2006/08/24 14:39:51 $
   End CVS Header */

// Copyright  2005 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"

#include "CTimeSeries.h"
#include "model/CMetabNameInterface.h"
#include "model/CModel.h"
#include "utilities/CSort.h"

CTimeSeries::CTimeSeries()
    : mIt(begin()),
    mpState(NULL),
    mDummyString(""),
    mDummyFloat(0)
{}

bool CTimeSeries::init(C_INT32 n, CModel * pModel)
{
  //std::cout << n << std::endl;
  mpState = & pModel->getState();

  CStateTemplate & Template = pModel->getStateTemplate();

  CModelEntity **it = Template.getEntities();
  CModelEntity **end = Template.endDependent();

  resize(n + 1);
  mIt = begin();

  C_INT32 i, imax = Template.getNumVariable() + 1;

  mPivot.resize(imax);
  mTitles.resize(imax);
  mFactors.resize(imax);

  C_FLOAT64 Number2QuantityFactor = pModel->getNumber2QuantityFactor();

  CMetab * pMetab;

  for (i = 0; it != end; ++i, ++it)
    {
      if ((pMetab = dynamic_cast<CMetab *>(*it)) != NULL)
        {
          mTitles[i] = CMetabNameInterface::getDisplayName(pModel, *pMetab);
          mFactors[i] =
            Number2QuantityFactor / pMetab->getCompartment()->getValue();
        }
      else
        {
          mTitles[i] = (*it)->getObjectDisplayName();
          mFactors[i] = 1.0;
        }
    }

  mTitles[0] = "Time";

  const unsigned C_INT32 * pUserOrder = Template.getUserOrder().array();
  const unsigned C_INT32 * pUserOrderEnd = pUserOrder + Template.getUserOrder().size();
  it = Template.getEntities();

  for (i = 0; pUserOrder != pUserOrderEnd; ++pUserOrder)
    if (it[*pUserOrder]->isUsed())
      mPivot[i++] = *pUserOrder;

  return true;
}

bool CTimeSeries::add()
{
  //std::cout << mpState->getTime() << std::endl;;
  if (mIt == end())
    {
      C_INT32 dummy = mIt - begin();
      resize(size() + 256);
      mIt = begin() + dummy;
      //std::cout << " resize " << dummy << std::endl;
    }

  *mIt = *mpState;

  ++mIt;

  return true;
}

bool CTimeSeries::finish()
{
  //std::cout << mCounter << std::endl;
  erase(mIt, end());
  return true;
}

//*** the methods to retrieve data from the CTimeSeries *******

unsigned C_INT32 CTimeSeries::getNumSteps() const
  {return mIt - begin();}

unsigned C_INT32 CTimeSeries::getNumVariables() const
  {
    if (mpState)
      return mpState->getNumVariable() + 1;

    return 0;
  }

const C_FLOAT64 & CTimeSeries::getData(unsigned C_INT32 step, unsigned C_INT32 var) const
  {
    if (step >= getNumSteps()) return mDummyFloat;

    if (var < mPivot.size()) return *(&(*this)[step].getTime() + mPivot[var]);

    return mDummyFloat;
  }

C_FLOAT64 CTimeSeries::getConcentrationData(unsigned C_INT32 step, unsigned C_INT32 var) const
  {
    static C_FLOAT64 tmp;

    if (step >= getNumSteps()) return mDummyFloat;

    if (var < mPivot.size())
      return tmp = *(&(*this)[step].getTime() + mPivot[var]) * mFactors[mPivot[var]];

    return mDummyFloat;
  }

const std::string & CTimeSeries::getTitle(unsigned C_INT32 var) const
  {
    if (var < mPivot.size())
      return mTitles[mPivot[var]];
    else
      return mDummyString;
  }

int CTimeSeries::save(const std::string& fileName, bool writeParticleNumbers, const std::string& separator) const
  {
    std::ofstream fileStream(utf8ToLocale(fileName).c_str());
    std::ostringstream* stringStream = new std::ostringstream();
    (*stringStream) << "# ";
    unsigned int counter2;
    unsigned int maxCount2 = this->getNumVariables();
    for (counter2 = 0; counter2 < maxCount2;++counter2)
      {
        (*stringStream) << this->getTitle(counter2) << separator;
      }
    (*stringStream) << std::endl;
    fileStream << stringStream->str();
    if (!fileStream.good()) return 1;
    unsigned int counter;
    unsigned int maxCount = this->getNumSteps();
    for (counter = 0; counter < maxCount;++counter)
      {
        delete stringStream;
        stringStream = new std::ostringstream();
        for (counter2 = 0; counter2 < maxCount2;++counter2)
          {
            C_FLOAT64 value;
            if (writeParticleNumbers)
              {
                value = this->getData(counter, counter2);
              }
            else
              {
                value = this->getConcentrationData(counter, counter2);
              }
            (*stringStream) << value << separator;
          }
        (*stringStream) << std::endl;
        fileStream << stringStream->str();
        if (!fileStream.good()) return 1;
      }
    fileStream.close();
    delete stringStream;
    return 0;
  }
<|endoftext|>


<commit_before>//
//  bootstrap.cpp
//  Parse
//
//  Created by Andrew Hunter on 21/05/2011.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include "bootstrap.h"

#include "Dfa/ndfa_regex.h"
#include "ContextFree/item.h"
#include "Lr/weak_symbols.h"
#include "Lr/ignored_symbols.h"
#include "Lr/lalr_builder.h"

using namespace dfa;
using namespace contextfree;
using namespace lr;
using namespace language;

/// \brief Adds a new terminal item to an NDFA, and to this object
contextfree::item_container bootstrap::add_terminal(dfa::ndfa_regex* ndfa, const std::wstring& name, const std::wstring& regex) {
    // Add to the terminal dictionary
    int termIdentifier = m_Terminals.symbol_for_name(name);

    if (termIdentifier == -1) {
        termIdentifier = m_Terminals.add_symbol(name);
    }

    // Add to the DFA
    ndfa->add_regex(0, regex, termIdentifier);

    // Return a new container
    return item_container(new terminal(termIdentifier), true);
}

/// \brief Creates the lexer for the language
dfa::ndfa* bootstrap::create_dfa() {
    // Create the NDFA (which we'll eventually turn into the lexer)
    ndfa_regex* languageNdfa = new ndfa_regex();

    // The weak keywords
    t.language          = add_terminal(languageNdfa, L"language", L"language");
    t.grammar           = add_terminal(languageNdfa, L"grammar", L"grammar");
    t.lexersymbols      = add_terminal(languageNdfa, L"lexer-symbols", L"lexer-symbols");
    t.lexer             = add_terminal(languageNdfa, L"lexer", L"lexer");
    t.weaklexer         = add_terminal(languageNdfa, L"weaklexer", L"weaklexer");
    t.ignore            = add_terminal(languageNdfa, L"ignore", L"ignore");
    t.keywords          = add_terminal(languageNdfa, L"keywords", L"keywords");

    // Single character elements (these are also weak)
	t.equals            = add_terminal(languageNdfa, L"'='", L"\\=");
    t.question          = add_terminal(languageNdfa, L"'?'", L"\\?");
    t.plus              = add_terminal(languageNdfa, L"'+'", L"\\+");
    t.star              = add_terminal(languageNdfa, L"'*'", L"\\*");
    t.colon             = add_terminal(languageNdfa, L"':'", L"\\:");
    t.openparen         = add_terminal(languageNdfa, L"'('", L"\\(");
    t.closeparen        = add_terminal(languageNdfa, L"')'", L"\\)");
    t.opencurly         = add_terminal(languageNdfa, L"'{'", L"\\{");
    t.closecurly        = add_terminal(languageNdfa, L"'}'", L"\\}");
    t.dot               = add_terminal(languageNdfa, L"'.'", L"\\.");
    t.pipe              = add_terminal(languageNdfa, L"'|'", L"\\|");

    // The lexical constructs
    t.identifier        = add_terminal(languageNdfa, L"identifier", L"[A-Za-z\\-][A-Za-z\\-0-9]*");
    t.nonterminal       = add_terminal(languageNdfa, L"nonterminal", L"\\<[A-Za-z\\-][A-Za-z\\-0-9]*\\>");
    //t.regex             = add_terminal(languageNdfa, L"regex", L"/([^/]|(\\\\/))*/");
    //t.string            = add_terminal(languageNdfa, L"string", L"\"([^\"]|(\\\"))*\"");
    //t.character         = add_terminal(languageNdfa, L"character", L"'(.|(\\.))'");
    t.character         = add_terminal(languageNdfa, L"character", L"'.'");

    // Ignored elements
    t.newline           = add_terminal(languageNdfa, L"newline", L"[\n\r]");
    t.whitespace        = add_terminal(languageNdfa, L"whitespace", L"[ ]");
    t.comment           = add_terminal(languageNdfa, L"comment", L"//[^\n\r]*");

    // Build into a DFA
    ndfa* uniqueSyms = languageNdfa->to_ndfa_with_unique_symbols();
    delete languageNdfa;

    ndfa* result = uniqueSyms->to_dfa();
    delete uniqueSyms;

    return result;
}

/// \brief Creates the grammar for the language
contextfree::grammar* bootstrap::create_grammar() {
    // Create a new grammar
    grammar* result = new grammar();

    // Generate nonterminals
    nt.parser_language          = result->get_nonterminal(L"Parser-Language");
    nt.toplevel_block           = result->get_nonterminal(L"TopLevel-Block");
    nt.language_block           = result->get_nonterminal(L"Language-Block");
    nt.language_inherits        = result->get_nonterminal(L"Language-Inherits");
    nt.language_definition      = result->get_nonterminal(L"Language-Definition");
    nt.lexer_symbols_definition = result->get_nonterminal(L"Lexer-Symbols-Definition");
    nt.lexer_definition         = result->get_nonterminal(L"Lexer-Definition");
    nt.ignore_definition        = result->get_nonterminal(L"Ignore-Definition");
    nt.keywords_definition      = result->get_nonterminal(L"Keywords-Definition");
    nt.keyword_definition       = result->get_nonterminal(L"Keyword-Definition");
    nt.weak_symbols_definition  = result->get_nonterminal(L"Weak-Symbols-Definition");
    nt.lexeme_definition        = result->get_nonterminal(L"Lexeme-Definition");
    nt.grammar_definition       = result->get_nonterminal(L"Grammar-Definition");
    nt.nonterminal_definition   = result->get_nonterminal(L"Nonterminal-Definition");
    nt.production               = result->get_nonterminal(L"Production");
    nt.ebnf_item                = result->get_nonterminal(L"Ebnf-Item");
    nt.simple_ebnf_item         = result->get_nonterminal(L"Simple-Ebnf-Item");
    nt.nonterminal              = result->get_nonterminal(L"Nonterminal");
    nt.terminal                 = result->get_nonterminal(L"Terminal");
    nt.basic_terminal           = result->get_nonterminal(L"Basic-Terminal");

    // Generate productions
    ebnf_repeating_optional listToplevel;
    (*listToplevel.get_rule()) << nt.toplevel_block;
    ((*result) += L"Parser-Language") << listToplevel;

    // Top level block (language)
    ((*result) += L"TopLevel-Block") << nt.language_block;

    // Language block ('language x (: y) { ... }
    ebnf_optional           optionalLanguageInherits;
    ebnf_repeating_optional listLanguageDefinition;
    (*optionalLanguageInherits.get_rule()) << nt.language_inherits;
    (*listLanguageDefinition.get_rule()) << nt.language_definition;
    ((*result) += L"Language-Block") << t.language << t.identifier << optionalLanguageInherits << t.opencurly << listLanguageDefinition << t.closecurly;

    ((*result) += L"Language-Inherits") << t.colon << t.identifier;

    // Types of definition within a language block
    ((*result) += L"Language-Definition") << nt.lexer_symbols_definition;
    ((*result) += L"Language-Definition") << nt.lexer_definition;
    ((*result) += L"Language-Definition") << nt.ignore_definition;
    ((*result) += L"Language-Definition") << nt.weak_symbols_definition;
    ((*result) += L"Language-Definition") << nt.keywords_definition;
    ((*result) += L"Language-Definition") << nt.grammar_definition;

    // Some simple definitions
    ebnf_repeating_optional lexemeList;
    ebnf_repeating_optional keywordDefinitionList;
    ebnf_repeating_optional lexemeOrIdentifierList;
    ebnf_alternate          lexemeOrIdentifier;

    (*lexemeList.get_rule()) << nt.lexeme_definition;
    (*lexemeOrIdentifier.get_rule()) << nt.lexeme_definition;
    (*lexemeOrIdentifier.add_rule()) << t.identifier;
    (*lexemeOrIdentifierList.get_rule()) << lexemeOrIdentifier;
    (*keywordDefinitionList.get_rule()) << nt.keyword_definition;

    ((*result) += L"Lexer-Symbols-Definition") << t.lexersymbols << t.opencurly << lexemeList << t.closecurly;
    ((*result) += L"Lexer-Definition") << t.lexer << t.opencurly << lexemeList << t.closecurly;
    ((*result) += L"Ignore-Definition") << t.ignore << t.opencurly << lexemeOrIdentifierList << t.closecurly;
    ((*result) += L"Keywords-Definition") << t.keywords << t.opencurly << keywordDefinitionList << t.closecurly;
    ((*result) += L"Keyword-Definition") << t.identifier;
    ((*result) += L"Keyword-Definition") << t.identifier << t.equals << t.string;
    ((*result) += L"Keyword-Definition") << t.identifier << t.equals << t.character;
    ((*result) += L"Weak-Symbols-Definition") << t.weaklexer << t.opencurly << lexemeList << t.closecurly;
    ((*result) += L"Lexeme-Definition") << t.identifier << t.equals << t.regex;
    ((*result) += L"Lexeme-Definition") << t.identifier << t.equals << t.identifier << t.dot << t.identifier;

    // Definitions for a grammar
    ebnf_repeating_optional nonterminalDefinitionList;
    ebnf_repeating_optional orProductionList;
    ebnf_repeating_optional ebnfItemList;
    ebnf_repeating_optional simpleEbnfItemList;

    (*nonterminalDefinitionList.get_rule()) << nt.nonterminal_definition;
    (*orProductionList.get_rule()) << t.pipe << nt.production;
    (*ebnfItemList.get_rule()) << nt.ebnf_item;
    (*simpleEbnfItemList.get_rule()) << nt.simple_ebnf_item;

    ((*result) += L"Grammar-Definition") << t.grammar << t.opencurly << nonterminalDefinitionList << t.closecurly;

    ((*result) += L"Nonterminal-Definition") << t.nonterminal << t.equals << nt.production << orProductionList;
    // (Not supporting the inheritance forms of these in the bootstrap language)

    // Productions
    ((*result) += L"Production") << simpleEbnfItemList;

    ((*result) += L"Ebnf-Item") << nt.simple_ebnf_item;
    ((*result) += L"Ebnf-Item") << nt.simple_ebnf_item << t.pipe << nt.simple_ebnf_item;

    ((*result) += L"Simple-Ebnf-Item") << nt.nonterminal;
    ((*result) += L"Simple-Ebnf-Item") << nt.terminal;
    ((*result) += L"Simple-Ebnf-Item") << nt.simple_ebnf_item << t.star;
    ((*result) += L"Simple-Ebnf-Item") << nt.simple_ebnf_item << t.plus;
    ((*result) += L"Simple-Ebnf-Item") << nt.simple_ebnf_item << t.question;
    ((*result) += L"Simple-Ebnf-Item") << t.openparen << ebnfItemList << t.closeparen;

    ((*result) += L"Nonterminal") << t.nonterminal;

    ((*result) += L"Terminal") << nt.basic_terminal;
    ((*result) += L"Basic-Terminal") << t.identifier;
    ((*result) += L"Basic-Terminal") << t.string;
    ((*result) += L"Basic-Terminal") << t.character;

    // Return the new grammar
    return result;
}

/// \brief Constructs the bootstrap language
bootstrap::bootstrap() {
    // Create the DFA for this language
    ndfa* dfa = create_dfa();

    // Create the grammar for this language
    m_Grammar = create_grammar();

    // Set up the list of 'weak symbols'
    weak_symbols weak;

    // All of the keywords are weak
    item_set weaklings;

    weaklings.insert(t.language);
    weaklings.insert(t.grammar);
    weaklings.insert(t.lexersymbols);
    weaklings.insert(t.lexer);
    weaklings.insert(t.ignore);
    weaklings.insert(t.keywords);

    weak.add_symbols(*dfa, weaklings, m_Terminals);

    // Set up the list of ignored symbols
    ignored_symbols ignore;

    ignore.add_item(t.newline);
    ignore.add_item(t.whitespace);
    ignore.add_item(t.comment);

    // Create the lexer for this language
    m_Lexer = new dfa::lexer(*dfa);

    // No longer need the DFA at this point
    delete dfa;

    // Build the parser
    m_Builder = new lalr_builder(*m_Grammar, m_Terminals);

    m_Builder->add_rewriter(weak);
    m_Builder->add_rewriter(ignore);

    m_Builder->add_initial_state(nt.parser_language);

    // Finish up the parser
    m_Builder->complete_parser();

    // TODO: log information about shift/reduce and reduce/reduce conflicts

    // Turn into the finished parser
    m_Parser = new ast_parser(*m_Builder);
}

/// \brief Destructor
bootstrap::~bootstrap() {
    delete m_Lexer;
    delete m_Grammar;
    delete m_Builder;
    delete m_Parser;
}
<commit_msg>Changed character definition to use a character set. It works, problem here is the '.' character, maybe?<commit_after>//
//  bootstrap.cpp
//  Parse
//
//  Created by Andrew Hunter on 21/05/2011.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#include "bootstrap.h"

#include "Dfa/ndfa_regex.h"
#include "ContextFree/item.h"
#include "Lr/weak_symbols.h"
#include "Lr/ignored_symbols.h"
#include "Lr/lalr_builder.h"

using namespace dfa;
using namespace contextfree;
using namespace lr;
using namespace language;

/// \brief Adds a new terminal item to an NDFA, and to this object
contextfree::item_container bootstrap::add_terminal(dfa::ndfa_regex* ndfa, const std::wstring& name, const std::wstring& regex) {
    // Add to the terminal dictionary
    int termIdentifier = m_Terminals.symbol_for_name(name);

    if (termIdentifier == -1) {
        termIdentifier = m_Terminals.add_symbol(name);
    }

    // Add to the DFA
    ndfa->add_regex(0, regex, termIdentifier);

    // Return a new container
    return item_container(new terminal(termIdentifier), true);
}

/// \brief Creates the lexer for the language
dfa::ndfa* bootstrap::create_dfa() {
    // Create the NDFA (which we'll eventually turn into the lexer)
    ndfa_regex* languageNdfa = new ndfa_regex();

    // The weak keywords
    t.language          = add_terminal(languageNdfa, L"language", L"language");
    t.grammar           = add_terminal(languageNdfa, L"grammar", L"grammar");
    t.lexersymbols      = add_terminal(languageNdfa, L"lexer-symbols", L"lexer-symbols");
    t.lexer             = add_terminal(languageNdfa, L"lexer", L"lexer");
    t.weaklexer         = add_terminal(languageNdfa, L"weaklexer", L"weaklexer");
    t.ignore            = add_terminal(languageNdfa, L"ignore", L"ignore");
    t.keywords          = add_terminal(languageNdfa, L"keywords", L"keywords");

    // Single character elements (these are also weak)
	t.equals            = add_terminal(languageNdfa, L"'='", L"\\=");
    t.question          = add_terminal(languageNdfa, L"'?'", L"\\?");
    t.plus              = add_terminal(languageNdfa, L"'+'", L"\\+");
    t.star              = add_terminal(languageNdfa, L"'*'", L"\\*");
    t.colon             = add_terminal(languageNdfa, L"':'", L"\\:");
    t.openparen         = add_terminal(languageNdfa, L"'('", L"\\(");
    t.closeparen        = add_terminal(languageNdfa, L"')'", L"\\)");
    t.opencurly         = add_terminal(languageNdfa, L"'{'", L"\\{");
    t.closecurly        = add_terminal(languageNdfa, L"'}'", L"\\}");
    t.dot               = add_terminal(languageNdfa, L"'.'", L"\\.");
    t.pipe              = add_terminal(languageNdfa, L"'|'", L"\\|");

    // The lexical constructs
    t.identifier        = add_terminal(languageNdfa, L"identifier", L"[A-Za-z\\-][A-Za-z\\-0-9]*");
    t.nonterminal       = add_terminal(languageNdfa, L"nonterminal", L"\\<[A-Za-z\\-][A-Za-z\\-0-9]*\\>");
    //t.regex             = add_terminal(languageNdfa, L"regex", L"/([^/]|(\\\\/))*/");
    //t.string            = add_terminal(languageNdfa, L"string", L"\"([^\"]|(\\\"))*\"");
    //t.character         = add_terminal(languageNdfa, L"character", L"'(.|(\\.))'");
    t.character         = add_terminal(languageNdfa, L"character", L"'[a-z]'");

    // Ignored elements
    t.newline           = add_terminal(languageNdfa, L"newline", L"[\n\r]");
    t.whitespace        = add_terminal(languageNdfa, L"whitespace", L"[ ]");
    t.comment           = add_terminal(languageNdfa, L"comment", L"//[^\n\r]*");

    // Build into a DFA
    ndfa* uniqueSyms = languageNdfa->to_ndfa_with_unique_symbols();
    delete languageNdfa;

    ndfa* result = uniqueSyms->to_dfa();
    delete uniqueSyms;

    return result;
}

/// \brief Creates the grammar for the language
contextfree::grammar* bootstrap::create_grammar() {
    // Create a new grammar
    grammar* result = new grammar();

    // Generate nonterminals
    nt.parser_language          = result->get_nonterminal(L"Parser-Language");
    nt.toplevel_block           = result->get_nonterminal(L"TopLevel-Block");
    nt.language_block           = result->get_nonterminal(L"Language-Block");
    nt.language_inherits        = result->get_nonterminal(L"Language-Inherits");
    nt.language_definition      = result->get_nonterminal(L"Language-Definition");
    nt.lexer_symbols_definition = result->get_nonterminal(L"Lexer-Symbols-Definition");
    nt.lexer_definition         = result->get_nonterminal(L"Lexer-Definition");
    nt.ignore_definition        = result->get_nonterminal(L"Ignore-Definition");
    nt.keywords_definition      = result->get_nonterminal(L"Keywords-Definition");
    nt.keyword_definition       = result->get_nonterminal(L"Keyword-Definition");
    nt.weak_symbols_definition  = result->get_nonterminal(L"Weak-Symbols-Definition");
    nt.lexeme_definition        = result->get_nonterminal(L"Lexeme-Definition");
    nt.grammar_definition       = result->get_nonterminal(L"Grammar-Definition");
    nt.nonterminal_definition   = result->get_nonterminal(L"Nonterminal-Definition");
    nt.production               = result->get_nonterminal(L"Production");
    nt.ebnf_item                = result->get_nonterminal(L"Ebnf-Item");
    nt.simple_ebnf_item         = result->get_nonterminal(L"Simple-Ebnf-Item");
    nt.nonterminal              = result->get_nonterminal(L"Nonterminal");
    nt.terminal                 = result->get_nonterminal(L"Terminal");
    nt.basic_terminal           = result->get_nonterminal(L"Basic-Terminal");

    // Generate productions
    ebnf_repeating_optional listToplevel;
    (*listToplevel.get_rule()) << nt.toplevel_block;
    ((*result) += L"Parser-Language") << listToplevel;

    // Top level block (language)
    ((*result) += L"TopLevel-Block") << nt.language_block;

    // Language block ('language x (: y) { ... }
    ebnf_optional           optionalLanguageInherits;
    ebnf_repeating_optional listLanguageDefinition;
    (*optionalLanguageInherits.get_rule()) << nt.language_inherits;
    (*listLanguageDefinition.get_rule()) << nt.language_definition;
    ((*result) += L"Language-Block") << t.language << t.identifier << optionalLanguageInherits << t.opencurly << listLanguageDefinition << t.closecurly;

    ((*result) += L"Language-Inherits") << t.colon << t.identifier;

    // Types of definition within a language block
    ((*result) += L"Language-Definition") << nt.lexer_symbols_definition;
    ((*result) += L"Language-Definition") << nt.lexer_definition;
    ((*result) += L"Language-Definition") << nt.ignore_definition;
    ((*result) += L"Language-Definition") << nt.weak_symbols_definition;
    ((*result) += L"Language-Definition") << nt.keywords_definition;
    ((*result) += L"Language-Definition") << nt.grammar_definition;

    // Some simple definitions
    ebnf_repeating_optional lexemeList;
    ebnf_repeating_optional keywordDefinitionList;
    ebnf_repeating_optional lexemeOrIdentifierList;
    ebnf_alternate          lexemeOrIdentifier;

    (*lexemeList.get_rule()) << nt.lexeme_definition;
    (*lexemeOrIdentifier.get_rule()) << nt.lexeme_definition;
    (*lexemeOrIdentifier.add_rule()) << t.identifier;
    (*lexemeOrIdentifierList.get_rule()) << lexemeOrIdentifier;
    (*keywordDefinitionList.get_rule()) << nt.keyword_definition;

    ((*result) += L"Lexer-Symbols-Definition") << t.lexersymbols << t.opencurly << lexemeList << t.closecurly;
    ((*result) += L"Lexer-Definition") << t.lexer << t.opencurly << lexemeList << t.closecurly;
    ((*result) += L"Ignore-Definition") << t.ignore << t.opencurly << lexemeOrIdentifierList << t.closecurly;
    ((*result) += L"Keywords-Definition") << t.keywords << t.opencurly << keywordDefinitionList << t.closecurly;
    ((*result) += L"Keyword-Definition") << t.identifier;
    ((*result) += L"Keyword-Definition") << t.identifier << t.equals << t.string;
    ((*result) += L"Keyword-Definition") << t.identifier << t.equals << t.character;
    ((*result) += L"Weak-Symbols-Definition") << t.weaklexer << t.opencurly << lexemeList << t.closecurly;
    ((*result) += L"Lexeme-Definition") << t.identifier << t.equals << t.regex;
    ((*result) += L"Lexeme-Definition") << t.identifier << t.equals << t.identifier << t.dot << t.identifier;

    // Definitions for a grammar
    ebnf_repeating_optional nonterminalDefinitionList;
    ebnf_repeating_optional orProductionList;
    ebnf_repeating_optional ebnfItemList;
    ebnf_repeating_optional simpleEbnfItemList;

    (*nonterminalDefinitionList.get_rule()) << nt.nonterminal_definition;
    (*orProductionList.get_rule()) << t.pipe << nt.production;
    (*ebnfItemList.get_rule()) << nt.ebnf_item;
    (*simpleEbnfItemList.get_rule()) << nt.simple_ebnf_item;

    ((*result) += L"Grammar-Definition") << t.grammar << t.opencurly << nonterminalDefinitionList << t.closecurly;

    ((*result) += L"Nonterminal-Definition") << t.nonterminal << t.equals << nt.production << orProductionList;
    // (Not supporting the inheritance forms of these in the bootstrap language)

    // Productions
    ((*result) += L"Production") << simpleEbnfItemList;

    ((*result) += L"Ebnf-Item") << nt.simple_ebnf_item;
    ((*result) += L"Ebnf-Item") << nt.simple_ebnf_item << t.pipe << nt.simple_ebnf_item;

    ((*result) += L"Simple-Ebnf-Item") << nt.nonterminal;
    ((*result) += L"Simple-Ebnf-Item") << nt.terminal;
    ((*result) += L"Simple-Ebnf-Item") << nt.simple_ebnf_item << t.star;
    ((*result) += L"Simple-Ebnf-Item") << nt.simple_ebnf_item << t.plus;
    ((*result) += L"Simple-Ebnf-Item") << nt.simple_ebnf_item << t.question;
    ((*result) += L"Simple-Ebnf-Item") << t.openparen << ebnfItemList << t.closeparen;

    ((*result) += L"Nonterminal") << t.nonterminal;

    ((*result) += L"Terminal") << nt.basic_terminal;
    ((*result) += L"Basic-Terminal") << t.identifier;
    ((*result) += L"Basic-Terminal") << t.string;
    ((*result) += L"Basic-Terminal") << t.character;

    // Return the new grammar
    return result;
}

/// \brief Constructs the bootstrap language
bootstrap::bootstrap() {
    // Create the DFA for this language
    ndfa* dfa = create_dfa();

    // Create the grammar for this language
    m_Grammar = create_grammar();

    // Set up the list of 'weak symbols'
    weak_symbols weak;

    // All of the keywords are weak
    item_set weaklings;

    weaklings.insert(t.language);
    weaklings.insert(t.grammar);
    weaklings.insert(t.lexersymbols);
    weaklings.insert(t.lexer);
    weaklings.insert(t.ignore);
    weaklings.insert(t.keywords);

    weak.add_symbols(*dfa, weaklings, m_Terminals);

    // Set up the list of ignored symbols
    ignored_symbols ignore;

    ignore.add_item(t.newline);
    ignore.add_item(t.whitespace);
    ignore.add_item(t.comment);

    // Create the lexer for this language
    m_Lexer = new dfa::lexer(*dfa);

    // No longer need the DFA at this point
    delete dfa;

    // Build the parser
    m_Builder = new lalr_builder(*m_Grammar, m_Terminals);

    m_Builder->add_rewriter(weak);
    m_Builder->add_rewriter(ignore);

    m_Builder->add_initial_state(nt.parser_language);

    // Finish up the parser
    m_Builder->complete_parser();

    // TODO: log information about shift/reduce and reduce/reduce conflicts

    // Turn into the finished parser
    m_Parser = new ast_parser(*m_Builder);
}

/// \brief Destructor
bootstrap::~bootstrap() {
    delete m_Lexer;
    delete m_Grammar;
    delete m_Builder;
    delete m_Parser;
}
<|endoftext|>


<commit_before>// $Id: SDMolSupplier.cpp 585 2008-03-30 13:36:56Z glandrum $
//
//  Copyright (C) 2009 Greg Landrum
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//

#define NO_IMPORT_ARRAY
#include <boost/python.hpp>
#include <string>

#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/algorithm/string.hpp>

namespace io=boost::iostreams;

//ours
#include <GraphMol/FileParsers/MolSupplier.h>
#include <GraphMol/RDKitBase.h>
#include <RDBoost/Wrap.h>

#include "MolSupplier.h"

namespace python = boost::python;

namespace RDKit {
  // Note that this returns a pointer to the supplier itself, so be careful
  // that it doesn't get deleted by python!
  ForwardSDMolSupplier *MolSupplIter(ForwardSDMolSupplier *suppl){
    return suppl;
  }

  ROMol *MolSupplNext(ForwardSDMolSupplier *suppl){
    ROMol *res=0;
    if (!suppl->atEnd()) {
      try {
        res=suppl->next();
      } catch(...){
        res=0;
      }
    }
    if(!res && suppl->atEnd()) {
      PyErr_SetString(PyExc_StopIteration,"End of supplier hit");
      throw boost::python::error_already_set();
    }
    return res;
  }

  ForwardSDMolSupplier *createForwardSupplier(std::string filename,bool sanitize,
                                              bool removeHs){
    std::vector<std::string> splitName;
    boost::split(splitName,filename,boost::is_any_of("."));
    io::filtering_istream *strm=new io::filtering_istream();
    if(splitName.back()=="sdf"){
    }
    else if(splitName.back()=="gz"){
#ifndef RDK_NOGZIP
      strm->push(io::gzip_decompressor());
#else
      throw_value_error("gzip support not enabled");
#endif
    }
    else if(splitName.back()=="bz2"){
#ifndef RDK_NOBZIP2
      strm->push(io::bzip2_decompressor());
#else
      throw_value_error("bzip2 support not enabled");
#endif
    }
    else {
      std::string errorTxt="Unrecognized extension: "+splitName.back();
      throw_value_error(errorTxt);
    }
    io::file_source fileSource(filename);
    if(!fileSource.is_open()){
      std::string errorTxt="could not open file: "+filename;
      throw_value_error(errorTxt);
    }
    strm->push(fileSource);

    ForwardSDMolSupplier *res=new ForwardSDMolSupplier(strm,true,sanitize,removeHs);
    return res;
  }

  std::string fsdMolSupplierClassDoc="A class which supplies molecules from an SD file.\n \
\n \
  Usage examples:\n \
\n \
    1) Lazy evaluation: the molecules are not constructed until we ask for them:\n \
       >>> suppl = SDMolSupplier('in.smi')\n \
       >>> for mol in suppl:\n \
       ...    mol.GetNumAtoms()\n \
\n \
  Properties in the SD file are used to set properties on each molecule.\n\
  The properties are accessible using the mol.GetProp(propName) method.\n\
\n";
  struct compressedsdmolsup_wrap {
    static void wrap() {
      python::class_<ForwardSDMolSupplier,boost::noncopyable>("ForwardSDMolSupplier",
                                                              fsdMolSupplierClassDoc.c_str(),
                                                              python::no_init)
	.def("__iter__", (ForwardSDMolSupplier *(*)(ForwardSDMolSupplier *))&MolSupplIter,
	     python::return_internal_reference<1>() )
	.def("next", (ROMol *(*)(ForwardSDMolSupplier *))&MolSupplNext,
	     "Returns the next molecule in the file.  Raises _StopIteration_ on EOF.\n",
	     python::return_value_policy<python::manage_new_object>())
	;
      python::def("CompressedSDMolSupplier",createForwardSupplier,
                  (python::arg("fileName"),python::arg("sanitize")=true,
                   python::arg("removeHs")=true),
                  python::return_value_policy<python::manage_new_object>());
    };
  };
}

void wrap_compressedsdsupplier() {
  RDKit::compressedsdmolsup_wrap::wrap();
}
<commit_msg>this should fix issue 3475053<commit_after>// $Id: SDMolSupplier.cpp 585 2008-03-30 13:36:56Z glandrum $
//
//  Copyright (C) 2009 Greg Landrum
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//

#define NO_IMPORT_ARRAY
#include <boost/python.hpp>
#include <string>

#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/algorithm/string.hpp>

namespace io=boost::iostreams;

//ours
#include <GraphMol/FileParsers/MolSupplier.h>
#include <GraphMol/RDKitBase.h>
#include <RDBoost/Wrap.h>

#include "MolSupplier.h"

namespace python = boost::python;

namespace RDKit {
  // Note that this returns a pointer to the supplier itself, so be careful
  // that it doesn't get deleted by python!
  ForwardSDMolSupplier *MolSupplIter(ForwardSDMolSupplier *suppl){
    return suppl;
  }

  ROMol *MolSupplNext(ForwardSDMolSupplier *suppl){
    ROMol *res=0;
    if (!suppl->atEnd()) {
      try {
        res=suppl->next();
      } catch(...){
        res=0;
      }
    }
    if(!res && suppl->atEnd()) {
      PyErr_SetString(PyExc_StopIteration,"End of supplier hit");
      throw boost::python::error_already_set();
    }
    return res;
  }

  ForwardSDMolSupplier *createForwardSupplier(std::string filename,bool sanitize,
                                              bool removeHs){
    std::vector<std::string> splitName;
    boost::split(splitName,filename,boost::is_any_of("."));
    io::filtering_istream *strm=new io::filtering_istream();
    if(splitName.back()=="sdf"){
    }
    else if(splitName.back()=="gz"){
#ifndef RDK_NOGZIP
      strm->push(io::gzip_decompressor());
#else
      throw_value_error("gzip support not enabled");
#endif
    }
    else if(splitName.back()=="bz2"){
#ifndef RDK_NOBZIP2
      strm->push(io::bzip2_decompressor());
#else
      throw_value_error("bzip2 support not enabled");
#endif
    }
    else {
      std::string errorTxt="Unrecognized extension: "+splitName.back();
      throw_value_error(errorTxt);
    }
    io::file_source fileSource(filename);
    if(!fileSource.is_open()){
      std::string errorTxt="could not open file: "+filename;
      throw_value_error(errorTxt);
    }
    strm->push(fileSource);

    ForwardSDMolSupplier *res=new ForwardSDMolSupplier(strm,true,sanitize,removeHs);
    return res;
  }

  std::string csdMolSupplierClassDoc="A class which supplies molecules from an SD file.\n \
\n \
  Usage examples:\n \
\n \
    1) Lazy evaluation: the molecules are not constructed until we ask for them:\n \
       >>> suppl = SDMolSupplier('in.smi')\n \
       >>> for mol in suppl:\n \
       ...    mol.GetNumAtoms()\n \
\n \
  Properties in the SD file are used to set properties on each molecule.\n\
  The properties are accessible using the mol.GetProp(propName) method.\n\
\n";
  struct compressedsdmolsup_wrap {
    static void wrap() {
      python::class_<ForwardSDMolSupplier,boost::noncopyable>("_CompressedSDMolSupplier",
                                                              csdMolSupplierClassDoc.c_str(),
                                                              python::no_init)
	.def("__iter__", (ForwardSDMolSupplier *(*)(ForwardSDMolSupplier *))&MolSupplIter,
	     python::return_internal_reference<1>() )
	.def("next", (ROMol *(*)(ForwardSDMolSupplier *))&MolSupplNext,
	     "Returns the next molecule in the file.  Raises _StopIteration_ on EOF.\n",
	     python::return_value_policy<python::manage_new_object>())
	;
      python::def("CompressedSDMolSupplier",createForwardSupplier,
                  (python::arg("fileName"),python::arg("sanitize")=true,
                   python::arg("removeHs")=true),
                  python::return_value_policy<python::manage_new_object>());
    };
  };
}

void wrap_compressedsdsupplier() {
  RDKit::compressedsdmolsup_wrap::wrap();
}
<|endoftext|>


<commit_before>// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "verilog/analysis/verilog_equivalence.h"

#include <iostream>
#include <memory>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/status/status.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "common/text/token_info.h"
#include "common/util/logging.h"

#undef EXPECT_OK
#define EXPECT_OK(value) EXPECT_TRUE((value).ok())
#undef ASSERT_OK
#define ASSERT_OK(value) ASSERT_TRUE((value).ok())

namespace verilog {
namespace {

static void ExpectCompareWithErrstream(
    std::function<bool(absl::string_view, absl::string_view, std::ostream*)>
        func,
    bool expect_compare, absl::string_view left, absl::string_view right,
    std::ostream* errstream = &std::cout) {
  EXPECT_EQ(func(left, right, errstream), expect_compare)
      << "left:\n"
      << left << "\nright:\n"
      << right;
  {  // commutative comparison check (should be same)
    std::ostringstream errstream;
    EXPECT_EQ(func(right, left, &errstream), expect_compare)
        << "(commutative) " << errstream.str();
  }
}

TEST(FormatEquivalentTest, Spaces) {
  const std::vector<const char*> kTestCases = {
      "",
      " ",
      "\n",
      "\t",
  };
  for (int i = 0; i < kTestCases.size(); ++i) {
    for (int j = i + 1; j < kTestCases.size(); ++j) {
      ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[i],
                                 kTestCases[j]);
    }
  }
}

TEST(FormatEquivalentTest, ShortSequences) {
  const char* kTestCases[] = {
      "1",
      "2",
      "1;",
      "1 ;",
  };
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                             kTestCases[1]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                             kTestCases[2]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                             kTestCases[3]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[1],
                             kTestCases[2]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[1],
                             kTestCases[3]);
  ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[2],
                             kTestCases[3]);
}

TEST(FormatEquivalentTest, Identifiers) {
  const char* kTestCases[] = {
      "foo bar;",
      "   foo\t\tbar    ;   ",
      "foobar;",  // only 2 tokens
      "foo bar\n;\n",
  };
  ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[0],
                             kTestCases[1]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                             kTestCases[2]);
  ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[0],
                             kTestCases[3]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[1],
                             kTestCases[2]);
  ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[1],
                             kTestCases[3]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[2],
                             kTestCases[3]);
}

TEST(FormatEquivalentTest, Keyword) {
  const char* kTestCases[] = {
      "wire foo;",
      "  wire  \n\t\t   foo  ;\n",
  };
  ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[0],
                             kTestCases[1]);
}

TEST(FormatEquivalentTest, Comments) {
  const char* kTestCases[] = {
      "// comment1\n",        //
      "// comment1 \n",       //
      "//    comment1\n",     //
      "   //    comment1\n",  // same as [2]
      "// comment2\n",        //
      "/* comment1 */\n",     //
      "/*  comment1  */\n",   //
  };
  auto span = absl::MakeSpan(kTestCases);
  // At some point in the future when token-reflowing is implemented, these
  // will need to become smarter checks.
  // For now, they only check for exact match.
  for (size_t i = 0; i < span.size(); ++i) {
    for (size_t j = i + 1; j < span.size(); ++j) {
      if (i == 2 && j == 3) {
        ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[i],
                                   kTestCases[j]);
      } else {
        ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[i],
                                   kTestCases[j]);
      }
    }
  }
}

TEST(FormatEquivalentTest, DiagnosticLength) {
  const char* kTestCases[] = {
      "module foo\n",
      "module foo;\n",
  };
  {
    std::ostringstream errs;
    ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                               kTestCases[1], &errs);
    EXPECT_TRUE(absl::StartsWith(
        errs.str(), "Mismatch in token sequence lengths: 3 vs. 4"));
    EXPECT_TRUE(absl::StrContains(errs.str(), "First mismatched token [2]:"));
  }
  {
    std::ostringstream errs;
    ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[1],
                               kTestCases[0], &errs);
    EXPECT_TRUE(absl::StartsWith(
        errs.str(), "Mismatch in token sequence lengths: 4 vs. 3"));
    EXPECT_TRUE(absl::StrContains(errs.str(), "First mismatched token [2]:"));
  }
}

TEST(FormatEquivalentTest, DiagnosticMismatch) {
  const char* kTestCases[] = {
      "module foo;\n",
      "module bar;\n",
      "module foo,\n",
  };
  {
    std::ostringstream errs;
    ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                               kTestCases[1], &errs);
    EXPECT_TRUE(absl::StartsWith(errs.str(), "First mismatched token [1]:"));
  }
  {
    std::ostringstream errs;
    ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                               kTestCases[2], &errs);
    EXPECT_TRUE(absl::StartsWith(errs.str(), "First mismatched token [2]:"));
  }
}

TEST(FormatEquivalentTest, LexErrorOnLeft) {
  std::ostringstream errs;
  ExpectCompareWithErrstream(FormatEquivalent, false, "hello 123badid\n",
                             "hello good_id", &errs);
  EXPECT_TRUE(absl::StrContains(errs.str(), "Error lexing left text"));
  EXPECT_TRUE(absl::StrContains(errs.str(), "123badid"));
}

TEST(FormatEquivalentTest, LexErrorOnRight) {
  std::ostringstream errs;
  ExpectCompareWithErrstream(FormatEquivalent, false, "hello good_id\n",
                             "hello 432_bad_id", &errs);
  EXPECT_TRUE(absl::StrContains(errs.str(), "Error lexing right text"));
  EXPECT_TRUE(absl::StrContains(errs.str(), "432_bad_id"));
}

struct ObfuscationTestCase {
  absl::string_view before;
  absl::string_view after;
  bool expect_match;
};

TEST(ObfuscationEquivalentTest, Various) {
  const ObfuscationTestCase kTestCases[] = {
      {"", "", true},
      {"\n", "\n", true},
      {"\n", "\n\n", false},
      {"\n", "\t", false},  // whitespace must match to be be equivalent
      {"  ", "\t", false},  // whitespace must match to be be equivalent
      {" ", "\t", false},   // whitespace must match to be be equivalent
      {" ", "\n", false},   // whitespace must match to be be equivalent
      {"aabbcc\n", "doremi\n", true},
      {"aabbcc\n", "dorem\n", false},
      {"11\n", "22\n", false},
      {"\"11\"\n", "\"22\"\n", false},
      {"wire\n", "wire\n", true},
      {"wire\n", "logic\n", false},
      {"wire w;\n", "wire w;\n", true},
      {"wire w;", "wire w;\n", false},
      {"wire xxx;\n", "wire yyy;\n", true},  // identifiers changed
      {"$zzz;\n", "$yyy;\n", true},          // identifiers changed
      {"$zzz();\n", "$yyy();\n", true},      // identifiers changed
      {"$zzz;\n", "$yyyy;\n", false},
      {"ff(gg, hh) + ii\n", "pp(qq, rr) + ss\n", true},
      {"ff(gg, hh) + ii\n", "pp(qq, rr) - ss\n", false},
      {"ff(gg, hh) + ii\n", "pp[qq, rr] + ss\n", false},
      {"ff(gg, hh) + ii\n", "pp(qq,  rr) + ss\n", false},
      {"ff(gg, hh) + ii\n", "pp(qq, rrr) + ss\n", false},
      {"ff(gg, hh) + ii\n", "pp(12, rr) + ss\n", false},
      {"ff(gg, hh) + ii\n", "pp(qq, rr)+ss\n", false},
      {"`define FOO\n", "`define BAR\n", true},
      {"`define FOO\n", "`define BARR\n", false},
      {"`define FOO\n", "`define  BAR\n", false},
      {"`define FOO\n", "`define BAR \n", false},
      {"`define FOO xx\n", "`define BAR yy\n", true},
      {"`define FOO xx\n", "`define BAR yyz\n", false},
      {"`define FOO \\\nxx\n", "`define BAR \\\nyy\n", true},
      {"`define FOO \\\nxxx\n", "`define BAR \\\nyy\n", false},
      {"`define FOO \\\nxx\n", "`define BAR \\\n\tyy\n", false},
      {"`define FOO \\\nxx\n", "`define BAR \\\n\nyy\n", false},
      {"`define FOO \\\nxx\n", "`define BAR \\\nyy\n\n", false},
      /* TODO(b/150174736): recursive lexing looks erroneous
      {"`define FOO \\\n`define INNERFOO \\\nxx\n\n",  // `define inside `define
       "`define BAR \\\n`define INNERBAR \\\nyy\n\n", true},
       */
      {"`ifdef FOO\n`endif\n", "`ifdef BAR\n`endif\n", true},
      {"`ifndef FOO\n`endif\n", "`ifndef BAR\n`endif\n", true},
      {"`ifdef FOO\n`endif\n", "`ifndef BAR\n`endif\n", false},
      {"`ifdef FOO\n`elsif BLEH\n`endif\n", "`ifdef BAR\n`elsif BLAH\n`endif\n",
       true},
      {"`ifdef FOOO\n`endif\n", "`ifdef BAR\n`endif\n", false},
      {"`ifdef FOO\n`elsif BLEH\n`endif\n",
       "`ifdef BAR\n`elsif BLAHH\n`endif\n", false},
      {"`FOO\n", "`BAR\n", true},
      {"`FOO;\n", "`BAR;\n", true},
      {"`FOO()\n", "`BAR()\n", true},
      {"`FOO(77)\n", "`BAR(77)\n", true},
      {"`FOO();\n", "`BAR();\n", true},
      {"`FOO()\n", "`BAAR()\n", false},
      {"`FOO()\n", " `BAR()\n", false},
      {"`FOO()\n", "`BAR ()\n", false},
      {"`FOO()\n", "`BAR( )\n", false},
      {"`FOO(77)\n", "`BAR(78)\n", false},
      {"`FOO(`BLAH)\n", "`BAR(`BLEH)\n", true},
      {"`FOO(`BLAH)\n", "`BAR(`BLE)\n", false},
      {"`FOO(`BLAH + `BLIPP)\n", "`BAR(`BLEH + `BLOOP)\n", true},
      {"`FOO(`BLAH + `BLIPP)\n", "`BAR(`BLEH +`BLOOP)\n", false},
      {"`FOO(`BLAH + `BLIPP)\n", "`BAR(`BLEH + `BLOP)\n", false},
      {"`FOO(`BLAH + `BLIPP)\n", "`BAR(`BLEH * `BLOOP)\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR(`BLEH(`BLOOP))\n", true},
      {"`FOO(`BLAH(`BLIP))\n", "`BAR(`BLEH(`BLOOP))\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR(`BLEH(`BLOOP ))\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR(`BLEH( `BLOOP))\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR(`BLEH (`BLOOP))\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR( `BLEH(`BLOOP))\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR(`BLEH(`BLOOP) )\n", false},
      {"\\FOO;!@#$% ", "\\BAR;%$#@! ", true},  // escaped identifier
      {"\\FOO;!@#$% ", "\\BARR;%$#@! ",
       false},  // escaped identifier (!= length)
  };
  for (const auto& test : kTestCases) {
    ExpectCompareWithErrstream(ObfuscationEquivalent, test.expect_match,
                               test.before, test.after);
  }
}

TEST(ObfuscationEquivalentTest, LexErrorOnLeft) {
  std::ostringstream errs;
  ExpectCompareWithErrstream(ObfuscationEquivalent, false, "hello 123badid\n",
                             "hello good_id", &errs);
  EXPECT_TRUE(absl::StrContains(errs.str(), "Error lexing left text"));
  EXPECT_TRUE(absl::StrContains(errs.str(), "123badid"));
}

TEST(ObfuscationEquivalentTest, LexErrorOnRight) {
  std::ostringstream errs;
  ExpectCompareWithErrstream(ObfuscationEquivalent, false, "hello good_id\n",
                             "hello 432_bad_id", &errs);
  EXPECT_TRUE(absl::StrContains(errs.str(), "Error lexing right text"));
  EXPECT_TRUE(absl::StrContains(errs.str(), "432_bad_id"));
}

}  // namespace
}  // namespace verilog
<commit_msg>Use the right unsigned type for a loop through a vector.<commit_after>// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "verilog/analysis/verilog_equivalence.h"

#include <iostream>
#include <memory>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/status/status.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "common/text/token_info.h"
#include "common/util/logging.h"

#undef EXPECT_OK
#define EXPECT_OK(value) EXPECT_TRUE((value).ok())
#undef ASSERT_OK
#define ASSERT_OK(value) ASSERT_TRUE((value).ok())

namespace verilog {
namespace {

static void ExpectCompareWithErrstream(
    std::function<bool(absl::string_view, absl::string_view, std::ostream*)>
        func,
    bool expect_compare, absl::string_view left, absl::string_view right,
    std::ostream* errstream = &std::cout) {
  EXPECT_EQ(func(left, right, errstream), expect_compare)
      << "left:\n"
      << left << "\nright:\n"
      << right;
  {  // commutative comparison check (should be same)
    std::ostringstream errstream;
    EXPECT_EQ(func(right, left, &errstream), expect_compare)
        << "(commutative) " << errstream.str();
  }
}

TEST(FormatEquivalentTest, Spaces) {
  const std::vector<const char*> kTestCases = {
      "",
      " ",
      "\n",
      "\t",
  };
  for (size_t i = 0; i < kTestCases.size(); ++i) {
    for (size_t j = i + 1; j < kTestCases.size(); ++j) {
      ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[i],
                                 kTestCases[j]);
    }
  }
}

TEST(FormatEquivalentTest, ShortSequences) {
  const char* kTestCases[] = {
      "1",
      "2",
      "1;",
      "1 ;",
  };
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                             kTestCases[1]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                             kTestCases[2]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                             kTestCases[3]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[1],
                             kTestCases[2]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[1],
                             kTestCases[3]);
  ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[2],
                             kTestCases[3]);
}

TEST(FormatEquivalentTest, Identifiers) {
  const char* kTestCases[] = {
      "foo bar;",
      "   foo\t\tbar    ;   ",
      "foobar;",  // only 2 tokens
      "foo bar\n;\n",
  };
  ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[0],
                             kTestCases[1]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                             kTestCases[2]);
  ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[0],
                             kTestCases[3]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[1],
                             kTestCases[2]);
  ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[1],
                             kTestCases[3]);
  ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[2],
                             kTestCases[3]);
}

TEST(FormatEquivalentTest, Keyword) {
  const char* kTestCases[] = {
      "wire foo;",
      "  wire  \n\t\t   foo  ;\n",
  };
  ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[0],
                             kTestCases[1]);
}

TEST(FormatEquivalentTest, Comments) {
  const char* kTestCases[] = {
      "// comment1\n",        //
      "// comment1 \n",       //
      "//    comment1\n",     //
      "   //    comment1\n",  // same as [2]
      "// comment2\n",        //
      "/* comment1 */\n",     //
      "/*  comment1  */\n",   //
  };
  auto span = absl::MakeSpan(kTestCases);
  // At some point in the future when token-reflowing is implemented, these
  // will need to become smarter checks.
  // For now, they only check for exact match.
  for (size_t i = 0; i < span.size(); ++i) {
    for (size_t j = i + 1; j < span.size(); ++j) {
      if (i == 2 && j == 3) {
        ExpectCompareWithErrstream(FormatEquivalent, true, kTestCases[i],
                                   kTestCases[j]);
      } else {
        ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[i],
                                   kTestCases[j]);
      }
    }
  }
}

TEST(FormatEquivalentTest, DiagnosticLength) {
  const char* kTestCases[] = {
      "module foo\n",
      "module foo;\n",
  };
  {
    std::ostringstream errs;
    ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                               kTestCases[1], &errs);
    EXPECT_TRUE(absl::StartsWith(
        errs.str(), "Mismatch in token sequence lengths: 3 vs. 4"));
    EXPECT_TRUE(absl::StrContains(errs.str(), "First mismatched token [2]:"));
  }
  {
    std::ostringstream errs;
    ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[1],
                               kTestCases[0], &errs);
    EXPECT_TRUE(absl::StartsWith(
        errs.str(), "Mismatch in token sequence lengths: 4 vs. 3"));
    EXPECT_TRUE(absl::StrContains(errs.str(), "First mismatched token [2]:"));
  }
}

TEST(FormatEquivalentTest, DiagnosticMismatch) {
  const char* kTestCases[] = {
      "module foo;\n",
      "module bar;\n",
      "module foo,\n",
  };
  {
    std::ostringstream errs;
    ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                               kTestCases[1], &errs);
    EXPECT_TRUE(absl::StartsWith(errs.str(), "First mismatched token [1]:"));
  }
  {
    std::ostringstream errs;
    ExpectCompareWithErrstream(FormatEquivalent, false, kTestCases[0],
                               kTestCases[2], &errs);
    EXPECT_TRUE(absl::StartsWith(errs.str(), "First mismatched token [2]:"));
  }
}

TEST(FormatEquivalentTest, LexErrorOnLeft) {
  std::ostringstream errs;
  ExpectCompareWithErrstream(FormatEquivalent, false, "hello 123badid\n",
                             "hello good_id", &errs);
  EXPECT_TRUE(absl::StrContains(errs.str(), "Error lexing left text"));
  EXPECT_TRUE(absl::StrContains(errs.str(), "123badid"));
}

TEST(FormatEquivalentTest, LexErrorOnRight) {
  std::ostringstream errs;
  ExpectCompareWithErrstream(FormatEquivalent, false, "hello good_id\n",
                             "hello 432_bad_id", &errs);
  EXPECT_TRUE(absl::StrContains(errs.str(), "Error lexing right text"));
  EXPECT_TRUE(absl::StrContains(errs.str(), "432_bad_id"));
}

struct ObfuscationTestCase {
  absl::string_view before;
  absl::string_view after;
  bool expect_match;
};

TEST(ObfuscationEquivalentTest, Various) {
  const ObfuscationTestCase kTestCases[] = {
      {"", "", true},
      {"\n", "\n", true},
      {"\n", "\n\n", false},
      {"\n", "\t", false},  // whitespace must match to be be equivalent
      {"  ", "\t", false},  // whitespace must match to be be equivalent
      {" ", "\t", false},   // whitespace must match to be be equivalent
      {" ", "\n", false},   // whitespace must match to be be equivalent
      {"aabbcc\n", "doremi\n", true},
      {"aabbcc\n", "dorem\n", false},
      {"11\n", "22\n", false},
      {"\"11\"\n", "\"22\"\n", false},
      {"wire\n", "wire\n", true},
      {"wire\n", "logic\n", false},
      {"wire w;\n", "wire w;\n", true},
      {"wire w;", "wire w;\n", false},
      {"wire xxx;\n", "wire yyy;\n", true},  // identifiers changed
      {"$zzz;\n", "$yyy;\n", true},          // identifiers changed
      {"$zzz();\n", "$yyy();\n", true},      // identifiers changed
      {"$zzz;\n", "$yyyy;\n", false},
      {"ff(gg, hh) + ii\n", "pp(qq, rr) + ss\n", true},
      {"ff(gg, hh) + ii\n", "pp(qq, rr) - ss\n", false},
      {"ff(gg, hh) + ii\n", "pp[qq, rr] + ss\n", false},
      {"ff(gg, hh) + ii\n", "pp(qq,  rr) + ss\n", false},
      {"ff(gg, hh) + ii\n", "pp(qq, rrr) + ss\n", false},
      {"ff(gg, hh) + ii\n", "pp(12, rr) + ss\n", false},
      {"ff(gg, hh) + ii\n", "pp(qq, rr)+ss\n", false},
      {"`define FOO\n", "`define BAR\n", true},
      {"`define FOO\n", "`define BARR\n", false},
      {"`define FOO\n", "`define  BAR\n", false},
      {"`define FOO\n", "`define BAR \n", false},
      {"`define FOO xx\n", "`define BAR yy\n", true},
      {"`define FOO xx\n", "`define BAR yyz\n", false},
      {"`define FOO \\\nxx\n", "`define BAR \\\nyy\n", true},
      {"`define FOO \\\nxxx\n", "`define BAR \\\nyy\n", false},
      {"`define FOO \\\nxx\n", "`define BAR \\\n\tyy\n", false},
      {"`define FOO \\\nxx\n", "`define BAR \\\n\nyy\n", false},
      {"`define FOO \\\nxx\n", "`define BAR \\\nyy\n\n", false},
      /* TODO(b/150174736): recursive lexing looks erroneous
      {"`define FOO \\\n`define INNERFOO \\\nxx\n\n",  // `define inside `define
       "`define BAR \\\n`define INNERBAR \\\nyy\n\n", true},
       */
      {"`ifdef FOO\n`endif\n", "`ifdef BAR\n`endif\n", true},
      {"`ifndef FOO\n`endif\n", "`ifndef BAR\n`endif\n", true},
      {"`ifdef FOO\n`endif\n", "`ifndef BAR\n`endif\n", false},
      {"`ifdef FOO\n`elsif BLEH\n`endif\n", "`ifdef BAR\n`elsif BLAH\n`endif\n",
       true},
      {"`ifdef FOOO\n`endif\n", "`ifdef BAR\n`endif\n", false},
      {"`ifdef FOO\n`elsif BLEH\n`endif\n",
       "`ifdef BAR\n`elsif BLAHH\n`endif\n", false},
      {"`FOO\n", "`BAR\n", true},
      {"`FOO;\n", "`BAR;\n", true},
      {"`FOO()\n", "`BAR()\n", true},
      {"`FOO(77)\n", "`BAR(77)\n", true},
      {"`FOO();\n", "`BAR();\n", true},
      {"`FOO()\n", "`BAAR()\n", false},
      {"`FOO()\n", " `BAR()\n", false},
      {"`FOO()\n", "`BAR ()\n", false},
      {"`FOO()\n", "`BAR( )\n", false},
      {"`FOO(77)\n", "`BAR(78)\n", false},
      {"`FOO(`BLAH)\n", "`BAR(`BLEH)\n", true},
      {"`FOO(`BLAH)\n", "`BAR(`BLE)\n", false},
      {"`FOO(`BLAH + `BLIPP)\n", "`BAR(`BLEH + `BLOOP)\n", true},
      {"`FOO(`BLAH + `BLIPP)\n", "`BAR(`BLEH +`BLOOP)\n", false},
      {"`FOO(`BLAH + `BLIPP)\n", "`BAR(`BLEH + `BLOP)\n", false},
      {"`FOO(`BLAH + `BLIPP)\n", "`BAR(`BLEH * `BLOOP)\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR(`BLEH(`BLOOP))\n", true},
      {"`FOO(`BLAH(`BLIP))\n", "`BAR(`BLEH(`BLOOP))\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR(`BLEH(`BLOOP ))\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR(`BLEH( `BLOOP))\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR(`BLEH (`BLOOP))\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR( `BLEH(`BLOOP))\n", false},
      {"`FOO(`BLAH(`BLIPP))\n", "`BAR(`BLEH(`BLOOP) )\n", false},
      {"\\FOO;!@#$% ", "\\BAR;%$#@! ", true},  // escaped identifier
      {"\\FOO;!@#$% ", "\\BARR;%$#@! ",
       false},  // escaped identifier (!= length)
  };
  for (const auto& test : kTestCases) {
    ExpectCompareWithErrstream(ObfuscationEquivalent, test.expect_match,
                               test.before, test.after);
  }
}

TEST(ObfuscationEquivalentTest, LexErrorOnLeft) {
  std::ostringstream errs;
  ExpectCompareWithErrstream(ObfuscationEquivalent, false, "hello 123badid\n",
                             "hello good_id", &errs);
  EXPECT_TRUE(absl::StrContains(errs.str(), "Error lexing left text"));
  EXPECT_TRUE(absl::StrContains(errs.str(), "123badid"));
}

TEST(ObfuscationEquivalentTest, LexErrorOnRight) {
  std::ostringstream errs;
  ExpectCompareWithErrstream(ObfuscationEquivalent, false, "hello good_id\n",
                             "hello 432_bad_id", &errs);
  EXPECT_TRUE(absl::StrContains(errs.str(), "Error lexing right text"));
  EXPECT_TRUE(absl::StrContains(errs.str(), "432_bad_id"));
}

}  // namespace
}  // namespace verilog
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: AxisIndexDefines.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 18:11:59 $
 *
 *  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
 *
 ************************************************************************/
#ifndef CHART2_AXISINDEX_HXX
#define CHART2_AXISINDEX_HXX

namespace chart
{

const sal_Int32 MAIN_AXIS_INDEX = 0;
const sal_Int32 SECONDARY_AXIS_INDEX = 1;

} //  namespace chart

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.2.126); FILE MERGED 2008/03/28 16:43:51 rt 1.2.126.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: AxisIndexDefines.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef CHART2_AXISINDEX_HXX
#define CHART2_AXISINDEX_HXX

namespace chart
{

const sal_Int32 MAIN_AXIS_INDEX = 0;
const sal_Int32 SECONDARY_AXIS_INDEX = 1;

} //  namespace chart

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2012 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 "chrome/browser/ui/browser_list.h"

#include "base/command_line.h"
#include "chrome/common/chrome_switches.h"

// static
void BrowserList::HandleAppExitingForPlatform() {
#if defined(OS_CHROMEOS)
  if (!CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kDisableZeroBrowsersOpenForTests)) {
    // App is exiting, call EndKeepAlive() on behalf of Aura Shell.
    BrowserList::EndKeepAlive();
  }
#endif // OS_CHROMEOS
}
<commit_msg>Call NotifyAndTerminate from BrowserList::HandleAppExitingForPlatform<commit_after>// Copyright (c) 2012 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 "chrome/browser/ui/browser_list.h"

#include "base/command_line.h"
#include "chrome/common/chrome_switches.h"

// static
void BrowserList::HandleAppExitingForPlatform() {
#if defined(OS_CHROMEOS)
  if (!CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kDisableZeroBrowsersOpenForTests)) {
    // App is exiting, call EndKeepAlive() on behalf of Aura Shell.
    BrowserList::EndKeepAlive();
    // Make sure we have notified the session manager that we are exiting.
    // This might be called from FastShutdown() or CloseAllBrowsers(), but not
    // if something prevents a browser from closing before SetTryingToQuit()
    // gets called (e.g. browser->TabsNeedBeforeUnloadFired() is true).
    // NotifyAndTerminate does nothing if called more than once.
    BrowserList::NotifyAndTerminate(true);
  }
#endif // OS_CHROMEOS
}
<|endoftext|>