text:
/*
 * Copyright 2016-2019 Aaron Barany
 *
 * 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 <MSL/Compile/Target.h>
#include <MSL/Compile/CompiledResult.h>
#include <MSL/Compile/Output.h>

#include "Compiler.h"
#include "ExecuteCommand.h"
#include "Parser.h"
#include "Preprocessor.h"
#include "SpirVProcessor.h"

#include "StandAlone/ResourceLimits.h"

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <sstream>
#include <unordered_map>

namespace msl
{

using namespace compile;

static Target::FeatureInfo featureInfos[] =
{
	// Types
	{"Integers", "HAS_INTEGERS", "Integer types."},
	{"Doubles", "HAS_DOUBLES", "Double types."},
	{"NonSquareMatrices", "HAS_NON_SQUARE_MATRICES", "Non-square matrices, such as mat3x4."},
	{"Texture3D", "HAS_TEXTURE3D", "3D textures."},
	{"TextureArrays", "HAS_TEXTURE_ARRAYS", "Texture arrays."},
	{"ShadowSamplers", "HAS_SHADOW_SAMPLERS", "Shadow texture samplers."},
	{"MultisampledTextures", "HAS_MULTISAMPLED_TEXTURES", "Multisampled texture samplers."},
	{"IntegerTextures", "HAS_INTEGER_TEXTURES", "Integer texture samplers."},
	{"Images", "HAS_IMAGES", "Image types."},

	// Storage
	{"UniformBlocks", "HAS_UNIFORM_BLOCKS",
		"Uniform blocks. If disabled, uniform buffers will be in the push constant section. "
		"(equivalent to individual uniforms)"},
	{"Buffers", "HAS_BUFFERS", "Shader storage buffers."},
	{"Std140", "HAS_STD140", "std140 block layout."},
	{"Std430", "HAS_STD430", "std430 block layout."},
	{"BindingPoints", "HAS_BINDING_POINTS", "Allows setting the binding index in the layout."},
	{"DescriptorSets", "HAS_DESCRIPTOR_SETS",
		"Allows setting the descriptor set index in the layout."},

	// Pipeline stages
	{"TessellationStages", "HAS_TESSELLATION_STAGES",
		"Tessellation control and evaluation stages."},
	{"GeometryStage", "HAS_GEOMETRY_STAGE", "Geometry stage."},
	{"ComputeStage", "HAS_COMPUTE_STAGE", "Compute stage."},

	// Fragment shader outputs
	{"MultipleRenderTargets", "HAS_MULTIPLE_RENDER_TARGETS",
		"Supports writing to more than one render target."},
	{"DualSourceBlending", "HAS_DUAL_SOURCE_BLENDING",
		"Supports outputting two colors to the same output."},
	{"DepthHints", "HAS_DEPTH_HINTS", "Allow hints to be given about the depth output."},

	// Other functionality
	{"Derivatives", "HAS_DERIVATIVES", "dFdx() an dFdy() functions."},
	{"AdvancedDerivatives", "HAS_ADVANCED_DERIVATIVES",
		"Coarse and fine versions of dFdx() and dFdy()."},
	{"MemoryBarriers", "HAS_MEMORY_BARRIERS", "Memory barrier functions."},
	{"PrimitiveStreams", "HAS_PRIMITIVE_STREAMS", "Primitive streams for geometry shaders."},
	{"InterpolationFunctions", "HAS_INTERPOLATION_FUNCTIONS",
		"Interpolation functions for centroid, sample, and offset."},
	{"TextureGather", "HAS_TEXTURE_GATHER", "textureGather() functions."},
	{"TexelFetch", "HAS_TEXEL_FETCH", "texelFetch() functions."},
	{"TextureSize", "HAS_TEXTURE_SIZE", "textureSize() functions."},
	{"TextureQueryLod", "HAS_TEXTURE_QUERY_LOD", "texureQueryLod() functions."},
	{"TextureQueryLevels", "HAS_TEXTURE_QUERY_LEVELS", "textureQueryLevels() functions."},
	{"TextureSamples", "HAS_TEXTURE_SAMPLES", "textureSamples() functions."},
	{"BitFunctions", "HAS_BIT_FUNCTIONS",
		"Integer functions such as bitfieldInsert() and findMSB()."},
	{"PackingFunctions", "HAS_PACKING_FUNCTIONS",
		"Packing and unpacking functions such as packUnorm2x16()."},
	{"SubpassInputs", "HAS_SUBPASS_INPUTS",
		"Subpass inputs for reading directly from framebuffers."},
	{"ClipDistance", "HAS_CLIP_DISTANCE", "Support for gl_ClipDistance array."},
	{"CullDistance", "HAS_CULL_DISTANCE", "Support for gl_CullDistance array."},
	{"EarlyFragmentTests", "HAS_EARLY_FRAGMENT_TESTS",
		"Support for explicitly enabling early fragment tests."},
};

static_assert(sizeof(featureInfos)/sizeof(*featureInfos) == Target::featureCount,
	"Not all features are in the featureInfos array.");

static std::string readLine(std::istream& stream)
{
	std::string line;
	int c;
	while (stream)
	{
		c = stream.get();
		if (c == std::char_traits<char>::eof() || c == '\n')
			break;

		line.push_back(static_cast<char>(c));
	}
	return line;
}

// Adapted from glslang validator. Don't use their version directly because we want to store the
// output in the Output class and strtok isn't thread-safe.
static bool decodeResourceLimits(Output& output, TBuiltInResource& resources, std::istream& stream,
	const std::string& fileName)
{
	std::vector<std::string> splitStrings;
	std::size_t lineNumber = 0;
	while (stream)
	{
		++lineNumber;
		std::string line = readLine(stream);
		boost::algorithm::trim(line);
		if (line.empty() || line[0] == '#')
			continue;

		splitStrings.clear();
		boost::algorithm::split(splitStrings, line, boost::algorithm::is_space(),
			boost::algorithm::token_compress_on);
		const char* token = nullptr;
		const char* valueStr = nullptr;
		if (splitStrings.size() >= 1)
			token = splitStrings[0].c_str();
		if (splitStrings.size() >= 2)
			valueStr = splitStrings[1].c_str();
		if (valueStr == 0 || ! (valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9')))
		{
			output.addMessage(Output::Level::Error, fileName, lineNumber, 0, false,
				"resource configuration syntax error: each name must be followed by one number");
			return false;
		}
		int value = atoi(valueStr);

		if (strcmp(token, "MaxLights") == 0)
			resources.maxLights = value;
		else if (strcmp(token, "MaxClipPlanes") == 0)
			resources.maxClipPlanes = value;
		else if (strcmp(token, "MaxTextureUnits") == 0)
			resources.maxTextureUnits = value;
		else if (strcmp(token, "MaxTextureCoords") == 0)
			resources.maxTextureCoords = value;
		else if (strcmp(token, "MaxVertexAttribs") == 0)
			resources.maxVertexAttribs = value;
		else if (strcmp(token, "MaxVertexUniformComponents") == 0)
			resources.maxVertexUniformComponents = value;
		else if (strcmp(token, "MaxVaryingFloats") == 0)
			resources.maxVaryingFloats = value;
		else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
			resources.maxVertexTextureImageUnits = value;
		else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
			resources.maxCombinedTextureImageUnits = value;
		else if (strcmp(token, "MaxTextureImageUnits") == 0)
			resources.maxTextureImageUnits = value;
		else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
			resources.maxFragmentUniformComponents = value;
		else if (strcmp(token, "MaxDrawBuffers") == 0)
			resources.maxDrawBuffers = value;
		else if (strcmp(token, "MaxVertexUniformVectors") == 0)
			resources.maxVertexUniformVectors = value;
		else if (strcmp(token, "MaxVaryingVectors") == 0)
			resources.maxVaryingVectors = value;
		else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
			resources.maxFragmentUniformVectors = value;
		else if (strcmp(token, "MaxVertexOutputVectors") == 0)
			resources.maxVertexOutputVectors = value;
		else if (strcmp(token, "MaxFragmentInputVectors") == 0)
			resources.maxFragmentInputVectors = value;
		else if (strcmp(token, "MinProgramTexelOffset") == 0)
			resources.minProgramTexelOffset = value;
		else if (strcmp(token, "MaxProgramTexelOffset") == 0)
			resources.maxProgramTexelOffset = value;
		else if (strcmp(token, "MaxClipDistances") == 0)
			resources.maxClipDistances = value;
		else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
			resources.maxComputeWorkGroupCountX = value;
		else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
			resources.maxComputeWorkGroupCountY = value;
		else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
			resources.maxComputeWorkGroupCountZ = value;
		else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
			resources.maxComputeWorkGroupSizeX = value;
		else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
			resources.maxComputeWorkGroupSizeY = value;
		else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
			resources.maxComputeWorkGroupSizeZ = value;
		else if (strcmp(token, "MaxComputeUniformComponents") == 0)
			resources.maxComputeUniformComponents = value;
		else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
			resources.maxComputeTextureImageUnits = value;
		else if (strcmp(token, "MaxComputeImageUniforms") == 0)
			resources.maxComputeImageUniforms = value;
		else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
			resources.maxComputeAtomicCounters = value;
		else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
			resources.maxComputeAtomicCounterBuffers = value;
		else if (strcmp(token, "MaxVaryingComponents") == 0)
			resources.maxVaryingComponents = value;
		else if (strcmp(token, "MaxVertexOutputComponents") == 0)
			resources.maxVertexOutputComponents = value;
		else if (strcmp(token, "MaxGeometryInputComponents") == 0)
			resources.maxGeometryInputComponents = value;
		else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
			resources.maxGeometryOutputComponents = value;
		else if (strcmp(token, "MaxFragmentInputComponents") == 0)
			resources.maxFragmentInputComponents = value;
		else if (strcmp(token, "MaxImageUnits") == 0)
			resources.maxImageUnits = value;
		else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
			resources.maxCombinedImageUnitsAndFragmentOutputs = value;
		else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
			resources.maxCombinedShaderOutputResources = value;
		else if (strcmp(token, "MaxImageSamples") == 0)
			resources.maxImageSamples = value;
		else if (strcmp(token, "MaxVertexImageUniforms") == 0)
			resources.maxVertexImageUniforms = value;
		else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
			resources.maxTessControlImageUniforms = value;
		else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
			resources.maxTessEvaluationImageUniforms = value;
		else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
			resources.maxGeometryImageUniforms = value;
		else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
			resources.maxFragmentImageUniforms = value;
		else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
			resources.maxCombinedImageUniforms = value;
		else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
			resources.maxGeometryTextureImageUnits = value;
		else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
			resources.maxGeometryOutputVertices = value;
		else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
			resources.maxGeometryTotalOutputComponents = value;
		else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
			resources.maxGeometryUniformComponents = value;
		else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
			resources.maxGeometryVaryingComponents = value;
		else if (strcmp(token, "MaxTessControlInputComponents") == 0)
			resources.maxTessControlInputComponents = value;
		else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
			resources.maxTessControlOutputComponents = value;
		else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
			resources.maxTessControlTextureImageUnits = value;
		else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
			resources.maxTessControlUniformComponents = value;
		else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
			resources.maxTessControlTotalOutputComponents = value;
		else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
			resources.maxTessEvaluationInputComponents = value;
		else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
			resources.maxTessEvaluationOutputComponents = value;
		else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
			resources.maxTessEvaluationTextureImageUnits = value;
		else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
			resources.maxTessEvaluationUniformComponents = value;
		else if (strcmp(token, "MaxTessPatchComponents") == 0)
			resources.maxTessPatchComponents = value;
		else if (strcmp(token, "MaxPatchVertices") == 0)
			resources.maxPatchVertices = value;
		else if (strcmp(token, "MaxTessGenLevel") == 0)
			resources.maxTessGenLevel = value;
		else if (strcmp(token, "MaxViewports") == 0)
			resources.maxViewports = value;
		else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
			resources.maxVertexAtomicCounters = value;
		else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
			resources.maxTessControlAtomicCounters = value;
		else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
			resources.maxTessEvaluationAtomicCounters = value;
		else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
			resources.maxGeometryAtomicCounters = value;
		else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
			resources.maxFragmentAtomicCounters = value;
		else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
			resources.maxCombinedAtomicCounters = value;
		else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
			resources.maxAtomicCounterBindings = value;
		else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
			resources.maxVertexAtomicCounterBuffers = value;
		else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
			resources.maxTessControlAtomicCounterBuffers = value;
		else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
			resources.maxTessEvaluationAtomicCounterBuffers = value;
		else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
			resources.maxGeometryAtomicCounterBuffers = value;
		else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
			resources.maxFragmentAtomicCounterBuffers = value;
		else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
			resources.maxCombinedAtomicCounterBuffers = value;
		else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
			resources.maxAtomicCounterBufferSize = value;
		else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
			resources.maxTransformFeedbackBuffers = value;
		else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
			resources.maxTransformFeedbackInterleavedComponents = value;
		else if (strcmp(token, "MaxCullDistances") == 0)
			resources.maxCullDistances = value;
		else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
			resources.maxCombinedClipAndCullDistances = value;
		else if (strcmp(token, "MaxSamples") == 0)
			resources.maxSamples = value;

		else if (strcmp(token, "nonInductiveForLoops") == 0)
			resources.limits.nonInductiveForLoops = (value != 0);
		else if (strcmp(token, "whileLoops") == 0)
			resources.limits.whileLoops = (value != 0);
		else if (strcmp(token, "doWhileLoops") == 0)
			resources.limits.doWhileLoops = (value != 0);
		else if (strcmp(token, "generalUniformIndexing") == 0)
			resources.limits.generalUniformIndexing = (value != 0);
		else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
			resources.limits.generalAttributeMatrixVectorIndexing = (value != 0);
		else if (strcmp(token, "generalVaryingIndexing") == 0)
			resources.limits.generalVaryingIndexing = (value != 0);
		else if (strcmp(token, "generalSamplerIndexing") == 0)
			resources.limits.generalSamplerIndexing = (value != 0);
		else if (strcmp(token, "generalVariableIndexing") == 0)
			resources.limits.generalVariableIndexing = (value != 0);
		else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
			resources.limits.generalConstantMatrixVectorIndexing = (value != 0);
		else
		{
			output.addMessage(Output::Level::Warning, fileName, lineNumber, 0, false,
				"unrecognized resource type: " + splitStrings[0]);
		}
	}

	return true;
}

static std::uint32_t addStruct(Pipeline& pipeline, const std::vector<Struct>& structs,
	const Struct& addedStruct)
{
	for (std::size_t i = 0; i < pipeline.structs.size(); ++i)
	{
		if (pipeline.structs[i].name == addedStruct.name)
			return static_cast<std::uint32_t>(i);
	}

	std::uint32_t structIndex = static_cast<std::uint32_t>(pipeline.structs.size());
	pipeline.structs.push_back(addedStruct);

	// Recursively add struct members.
	for (StructMember& member : pipeline.structs.back().members)
	{
		if (member.type == Type::Struct)
			member.structIndex = addStruct(pipeline, structs, structs[member.structIndex]);
	}

	return structIndex;
}

static void addUniforms(Pipeline& pipeline, Stage stage, const SpirVProcessor& processor)
{
	std::vector<std::uint32_t>& uniformIds =
		pipeline.shaders[static_cast<unsigned int>(stage)].uniformIds;
	const std::size_t notFound = std::size_t(-1);
	for (std::size_t i = 0; i < processor.uniforms.size(); ++i)
	{
		std::size_t foundIndex = notFound;
		for (std::size_t j = 0; j < pipeline.uniforms.size(); ++j)
		{
			if (processor.uniforms[i].name == pipeline.uniforms[j].name)
			{
				assert(processor.uniforms[i].type == pipeline.uniforms[j].type);
				foundIndex = j;
				break;
			}
		}

		if (foundIndex != notFound)
		{
			if (uniformIds.size() <= foundIndex)
				uniformIds.resize(foundIndex + 1, unknown);
			uniformIds[foundIndex] = processor.uniformIds[i];
			continue;
		}

		pipeline.uniforms.push_back(processor.uniforms[i]);
		if (processor.uniforms[i].type == Type::Struct)
		{
			pipeline.uniforms.back().structIndex =
				addStruct(pipeline, processor.structs,
				processor.structs[processor.uniforms[i].structIndex]);
		}

		if (uniformIds.size() < pipeline.uniforms.size())
			uniformIds.resize(pipeline.uniforms.size(), unknown);
		uniformIds[pipeline.uniforms.size() - 1] = processor.uniformIds[i];
	}
}

bool operator==(const SamplerState& s1, const SamplerState& s2)
{
	return s1.minFilter == s2.minFilter && s1.magFilter == s2.magFilter &&
		s1.mipFilter == s2.mipFilter && s1.addressModeU == s2.addressModeU &&
		s1.addressModeV == s2.addressModeV && s1.addressModeW == s2.addressModeW &&
		s1.mipLodBias == s2.mipLodBias && s1.maxAnisotropy == s2.maxAnisotropy &&
		s1.minLod == s2.minLod && s1.maxLod == s2.maxLod && s1.borderColor == s2.borderColor &&
		s1.compareOp == s2.compareOp;
}

static std::uint32_t addSampler(Pipeline& pipeline, const SamplerState& sampler)
{
	for (std::uint32_t i = 0; i < pipeline.samplerStates.size(); ++i)
	{
		if (pipeline.samplerStates[i] == sampler)
			return i;
	}

	pipeline.samplerStates.push_back(sampler);
	return static_cast<std::uint32_t>(pipeline.samplerStates.size() - 1);
}

const Target::FeatureInfo& Target::getFeatureInfo(Target::Feature feature)
{
	return featureInfos[static_cast<unsigned int>(feature)];
}

Target::Target()
	: m_remapVariables(false)
	, m_stripDebug(false)
	, m_dummyBindings(false)
	, m_adjustableBindings(false)
	, m_optimize(Optimize::None)
{
	Compiler::initialize();
	m_featureStates.fill(State::Default);
}

Target::~Target()
{
	Compiler::shutdown();
}

bool Target::isFeatureOverridden(Feature feature) const
{
	return m_featureStates[static_cast<unsigned int>(feature)] != State::Default;
}

void Target::overrideFeature(Feature feature, bool enabled)
{
	m_featureStates[static_cast<unsigned int>(feature)] =
		enabled ? State::Enabled : State::Disabled;
}

void Target::clearOverride(Feature feature)
{
	m_featureStates[static_cast<unsigned int>(feature)] = State::Default;
}

bool Target::featureEnabled(Feature feature) const
{
	State state = m_featureStates[static_cast<unsigned int>(feature)];
	if (state == State::Default)
		return featureSupported(feature);

	return state == State::Enabled;
}

void Target::addIncludePath(std::string path)
{
	m_includePaths.push_back(std::move(path));
}

const std::vector<std::string>& Target::getIncludePaths() const
{
	return m_includePaths;
}

void Target::clearIncludePaths()
{
	m_includePaths.clear();
}

void Target::addDefine(std::string name, std::string value)
{
	m_defines.emplace_back(std::move(name), std::move(value));
}

const std::vector<std::pair<std::string, std::string>>& Target::getDefines() const
{
	return m_defines;
}

std::vector<std::pair<std::string, std::string>> Target::getExtraDefines() const
{
	return std::vector<std::pair<std::string, std::string>>();
}

void Target::clearDefines()
{
	m_defines.clear();
}

void Target::addPreHeaderLine(std::string header)
{
	m_preHeaderLines.push_back(std::move(header));
}

const std::vector<std::string>& Target::getPreHeaderLines() const
{
	return m_preHeaderLines;
}

void Target::clearPreHeaderLines()
{
	for (auto& headerLines : m_preHeaderLines)
		headerLines.clear();
}

const std::string& Target::getSpirVToolCommand() const
{
	return m_spirVToolCommand;
}

void Target::setSpirVToolCommand(std::string command)
{
	m_spirVToolCommand = std::move(command);
}

bool Target::getRemapVariables() const
{
	return m_remapVariables;
}

void Target::setRemapVariables(bool remap)
{
	m_remapVariables = remap;
}

Target::Optimize Target::getOptimize() const
{
	return m_optimize;
}

void Target::setOptimize(Optimize optimize)
{
	m_optimize = optimize;
}

bool Target::getStripDebug() const
{
	return m_stripDebug;
}

void Target::setStripDebug(bool strip)
{
	m_stripDebug = strip;
}

bool Target::getDummyBindings() const
{
	return m_dummyBindings;
}

void Target::setDummyBindings(bool dummy)
{
	m_dummyBindings = dummy;
}

bool Target::getAdjustableBindings() const
{
	return m_adjustableBindings;
}

void Target::setAdjustableBindings(bool adjustable)
{
	m_adjustableBindings = adjustable;
}

const std::string& Target::getResourcesFileName() const
{
	return m_resourcesFile;
}

void Target::setResourcesFileName(std::string fileName)
{
	m_resourcesFile = std::move(fileName);
}

bool Target::compile(CompiledResult& result, Output& output, const std::string& fileName)
{
	willCompile();

	Preprocessor preprocessor;
	setupPreprocessor(preprocessor);

	Parser parser;
	if (!preprocessor.preprocess(parser.getTokens(), output, fileName, m_preHeaderLines))
		return false;

	return compileImpl(result, output, parser, fileName);
}

bool Target::compile(CompiledResult& result, Output& output, std::istream& stream,
	const std::string& fileName)
{
	willCompile();

	Preprocessor preprocessor;
	setupPreprocessor(preprocessor);

	Parser parser;
	if (!preprocessor.preprocess(parser.getTokens(), output, stream, fileName, m_preHeaderLines))
		return false;

	return compileImpl(result, output, parser, fileName);
}

bool Target::finish(CompiledResult& result, Output& output)
{
	if (result.m_target != this)
	{
		output.addMessage(Output::Level::Error, "<finish>", 0, 0, false,
			"internal error: targets don't match in compiled result");
		return false;
	}

	result.m_sharedData.clear();
	if (!getSharedData(result.m_sharedData, output))
		return false;

	return true;
}

bool Target::needsReflectionNames() const
{
	return true;
}

void Target::willCompile()
{
}

bool Target::getSharedData(std::vector<std::uint8_t>&, Output&)
{
	return true;
}

void Target::setupPreprocessor(Preprocessor& preprocessor) const
{
	preprocessor.setSupportsUniformBlocks(featureEnabled(Feature::UniformBlocks));

	for (const std::string& include : m_includePaths)
		preprocessor.addIncludePath(include);

	for (const auto& define : m_defines)
		preprocessor.addDefine(define.first, define.second);

	for (auto& define : getExtraDefines())
		preprocessor.addDefine(std::move(define.first), std::move(define.second));

	for (unsigned int i = 0; i < featureCount; ++i)
	{
		if (featureEnabled(static_cast<Feature>(i)))
			preprocessor.addDefine(featureInfos[i].define, "1");
		else
			preprocessor.addDefine(featureInfos[i].define, "0");
	}
}

bool Target::compileImpl(CompiledResult& result, Output& output, Parser& parser,
	const std::string& fileName)
{
	int options = 0;
	if (!featureEnabled(Feature::UniformBlocks))
		options |= Parser::RemoveUniformBlocks;
	bool hasEarlyFragmentTests = featureEnabled(Feature::EarlyFragmentTests);

	if (!parser.parse(output, options))
		return false;

	// Set the target info on the result.
	if (!result.m_target)
		result.m_target = this;
	else if (result.m_target != this)
	{
		output.addMessage(Output::Level::Error, fileName, 0, 0, false,
			"internal error: targets don't match in compiled result");
		return false;
	}

	// Read in the resource limits.
	TBuiltInResource resources = glslang::DefaultTBuiltInResource;
	if (!m_resourcesFile.empty())
	{
		std::ifstream stream(m_resourcesFile);
		if (stream.is_open())
		{
			if (!decodeResourceLimits(output, resources, stream, m_resourcesFile))
				return false;
		}
		else
		{
			output.addMessage(Output::Level::Error, fileName, 0, 0, false,
				"cannot read resources file: " + m_resourcesFile);
			return false;
		}
	}

	// Compile the pipelines.
	int processOptions = 0;
	if (m_remapVariables)
		processOptions |= Compiler::RemapVariables;
	switch (m_optimize)
	{
		case Optimize::None:
			break;
		case Optimize::Minimal:
			processOptions |= Compiler::DeadCodeElimination;
			break;
		case Optimize::Full:
			processOptions |= Compiler::DeadCodeElimination | Compiler::Optimize;
			break;
	}

	SpirVProcessor::Strip strip;
	if (m_stripDebug)
	{
		if (needsReflectionNames())
			strip = SpirVProcessor::Strip::AllButReflection;
		else
			strip = SpirVProcessor::Strip::All;
	}
	else
		strip = SpirVProcessor::Strip::None;

	std::vector<char> tempData;
	std::vector<std::uint8_t> shaderData;
	std::vector<Parser::LineMapping> lineMappings;
	for (const Parser::Pipeline& pipeline : parser.getPipelines())
	{
		// Add the current pipeline to the result.
		auto addPair = result.m_pipelines.emplace(pipeline.name, Pipeline());
		if (!addPair.second)
		{
			output.addMessage(Output::Level::Error, pipeline.token->fileName, pipeline.token->line,
				pipeline.token->column, false, "pipeline already declared: " + pipeline.name);
			output.addMessage(Output::Level::Error, addPair.first->second.file,
				addPair.first->second.line, addPair.first->second.column, true,
				"see previous declaration");
			return false;
		}

		Pipeline& addedPipeline = addPair.first->second;
		addedPipeline.file = pipeline.token->fileName;
		addedPipeline.line = pipeline.token->line;
		addedPipeline.column = pipeline.token->column;

		// Compile the stages.
		Compiler::Stages stages;
		for (unsigned int i = 0; i < stageCount; ++i)
		{
			auto stage = static_cast<Stage>(i);
			if (pipeline.entryPoints[i].value.empty())
				continue;

			std::string glsl = parser.createShaderString(lineMappings, output, pipeline, stage,
				false, hasEarlyFragmentTests &&
					pipeline.renderState.earlyFragmentTests == Bool::True);
			if (glsl.empty())
				return false;
			if (!Compiler::compile(stages, output, fileName, glsl, lineMappings, stage, resources))
				return false;
		}

		// Link the program.
		Compiler::Program program;
		if (!Compiler::link(program, output, pipeline, stages))
			return false;

		// Compile the stages to SPIR-V.
		std::array<Compiler::SpirV, stageCount> spirv;
		std::array<SpirVProcessor, stageCount> processors;
		for (unsigned int i = 0; i < stageCount; ++i)
		{
			auto stage = static_cast<Stage>(i);
			if (!stages.shaders[i])
				continue;

			// Create SPIR-V.
			spirv[i] = Compiler::assemble(output, program, stage, pipeline);
			if (spirv[i].empty())
				return false;

			// Process the SPIR-V first so that remapping IDs doesn't mess up our mappings.
			Compiler::process(spirv[i], processOptions);
			if (!processors[i].extract(output, pipeline.token->fileName, pipeline.token->line,
				pipeline.token->column, spirv[i], stage))
			{
				return false;
			}
		}

		// Link the SPIR-V stages and process them.
		std::array<bool, compile::stageCount> pipelineStages;
		pipelineStages.fill(false);
		const SpirVProcessor* lastStage = nullptr;
		addedPipeline.pushConstantStruct = unknown;
		for (unsigned int i = 0; i < stageCount; ++i)
		{
			auto stage = static_cast<Stage>(i);
			if (!stages.shaders[i])
				continue;

			// Make sure that the uniforms are compatible.
			for (unsigned int j = i + 1; j < stageCount; ++j)
			{
				if (!stages.shaders[j])
					continue;

				if (!processors[i].uniformsCompatible(output, processors[j]))
					return false;
			}

			// Outputs
			if (!processors[i].assignOutputs(output))
				return false;

			// Inputs
			if (lastStage)
			{
				if (!processors[i].linkInputs(output, *lastStage))
					return false;
			}
			else if (stage == Stage::Vertex && !processors[i].assignInputs(output))
				return false;

			// Add uniforms.
			addUniforms(addedPipeline, stage, processors[i]);
			if (addedPipeline.pushConstantStruct == unknown &&
				processors[i].pushConstantStruct != unknown)
			{
				addedPipeline.pushConstantStruct = addStruct(addedPipeline, processors[i].structs,
					processors[i].structs[processors[i].pushConstantStruct]);
			}

			// Proces the SPIR-V.
			spirv[i] = processors[i].process(strip, m_dummyBindings || m_adjustableBindings);
			lastStage = &processors[i];
			pipelineStages[i] = true;

			if (stage == Stage::Compute)
				addedPipeline.computeLocalSize = processors[i].computeLocalSize;
		}

		// Make sure all of the uniform ID vectors are the same size.
		for (unsigned int i = 0; i < stageCount; ++i)
		{
			if (!stages.shaders[i])
				continue;

			assert(addedPipeline.shaders[i].uniformIds.size() <= addedPipeline.uniforms.size());
			addedPipeline.shaders[i].uniformIds.resize(addedPipeline.uniforms.size(), unknown);
		}

		// Add vertex attributes.
		if (stages.shaders[static_cast<unsigned int>(Stage::Vertex)])
		{
			const SpirVProcessor& vertexProcessor =
				processors[static_cast<unsigned int>(Stage::Vertex)];
			const Token& entryPoint =
				pipeline.entryPoints[static_cast<unsigned int>(Stage::Fragment)];
			addedPipeline.attributes.resize(vertexProcessor.inputs.size());
			for (std::size_t i = 0; i < vertexProcessor.inputs.size(); ++i)
			{
				addedPipeline.attributes[i].name = vertexProcessor.inputs[i].name;
				if (vertexProcessor.inputs[i].type == Type::Struct)
				{
					output.addMessage(Output::Level::Error, entryPoint.fileName,
						entryPoint.line, entryPoint.column, false,
						"linker error: vertex inputs may not use interface blocks");
					return false;
				}
				addedPipeline.attributes[i].type = vertexProcessor.inputs[i].type;
				addedPipeline.attributes[i].arrayElements = vertexProcessor.inputs[i].arrayElements;
				addedPipeline.attributes[i].location = vertexProcessor.inputs[i].location;
				addedPipeline.attributes[i].component = vertexProcessor.inputs[i].component;
			}
		}

		// Add fragment outputs.
		if (stages.shaders[static_cast<unsigned int>(Stage::Fragment)])
		{
			const SpirVProcessor& fragmentProcessor =
				processors[static_cast<unsigned int>(Stage::Fragment)];
			const Token& entryPoint =
				pipeline.entryPoints[static_cast<unsigned int>(Stage::Fragment)];
			addedPipeline.fragmentOutputs.resize(fragmentProcessor.outputs.size());
			for (std::size_t i = 0; i < fragmentProcessor.outputs.size(); ++i)
			{
				addedPipeline.fragmentOutputs[i].name = fragmentProcessor.outputs[i].name;
				if (fragmentProcessor.outputs[i].type == Type::Struct)
				{
					output.addMessage(Output::Level::Error, entryPoint.fileName,
						entryPoint.line, entryPoint.column, false,
						"linker error: fragment outputs may not use interface blocks");
					return false;
				}
				addedPipeline.fragmentOutputs[i].location = fragmentProcessor.outputs[i].location;
			}
		}

		// Cross-compile the stages.
		for (unsigned int i = 0; i < stageCount; ++i)
		{
			auto stage = static_cast<Stage>(i);
			if (!stages.shaders[i])
			{
				addedPipeline.shaders[i].shader = unknown;
				continue;
			}

			// Use external command if set.
			if (!m_spirVToolCommand.empty())
			{
				ExecuteCommand command;
				command.getInput().write(reinterpret_cast<const char*>(spirv[i].data()),
					spirv[i].size()*sizeof(std::uint32_t));
				if (!command.execute(output, m_spirVToolCommand))
					return false;

				tempData.assign(std::istreambuf_iterator<char>(command.getOutput().rdbuf()),
					std::istreambuf_iterator<char>());
				if ((tempData.size() % sizeof(std::uint32_t)) != 0)
				{
					output.addMessage(Output::Level::Error, fileName, 0, 0, false,
						"command output invalid spir-v: " + m_spirVToolCommand);
					return false;
				}

				spirv[i].reserve(tempData.size()/sizeof(std::uint32_t));
				std::memcpy(spirv[i].data(), tempData.data(), tempData.size());
			}

			shaderData.clear();
			const Token& entryPoint = pipeline.entryPoints[i];
			if (!crossCompile(shaderData, output, entryPoint.fileName, entryPoint.line,
					entryPoint.column, pipelineStages, stage, spirv[i], entryPoint.value,
					addedPipeline.uniforms, addedPipeline.shaders[i].uniformIds))
			{
				return false;
			}

			addedPipeline.shaders[i].shader = result.addShader(std::move(shaderData),
				processors[i].pushConstantStruct != unknown, m_adjustableBindings);
		}

		// Set the render and sampler states.
		addedPipeline.renderState = pipeline.renderState;
		for (const SpirVProcessor& processor : processors)
		{
			addedPipeline.renderState.clipDistanceCount = std::max(
				addedPipeline.renderState.clipDistanceCount, processor.clipDistanceCount);
			addedPipeline.renderState.cullDistanceCount = std::max(
				addedPipeline.renderState.cullDistanceCount, processor.cullDistanceCount);
		}
		for (std::size_t i = 0; i < addedPipeline.uniforms.size(); ++i)
		{
			if (addedPipeline.uniforms[i].uniformType != UniformType::SampledImage)
				continue;

			const std::vector<Parser::Sampler>& samplers = parser.getSamplers();
			for (std::size_t j = 0; j < samplers.size(); ++j)
			{
				if (samplers[j].name == addedPipeline.uniforms[i].name)
				{
					addedPipeline.uniforms[i].samplerIndex = addSampler(addedPipeline,
						samplers[j].state);
					break;
				}
			}
		}
	}

	return true;
}

} // namespace


text:
#define BOOST_TEST_MODULE "root_name"
// #define BOOST_TEST_MAIN

// note we only test CalibratorSample.
#include "CalibratorSample.h"

#include <boost/test/unit_test.hpp>
#include <boost/shared_ptr.hpp>

#include <random>
#include <iostream>

// this bitpacker is only used in the unittests, so doesn't need to be fast.
struct BitPacker
{
    void clear()
    {
        m_val = 0;
    }

    void setCoarse(uint16_t c)
    {
        uint16_t mask = 0x001f;
        c <<= 0;
        c &= mask;
        m_val &= ~mask;
        m_val |= c;
    }
    void setFine(uint16_t f)
    {
        uint16_t mask = 0x1fe0;
        f <<= 5;
        f &= mask;
        m_val &= ~mask;
        m_val |= f;
    }
    void setGain(uint16_t g)
    {
        uint16_t mask = 0x6000;
        g <<= 13;
        g &= mask;
        m_val &= ~mask;
        m_val |= g;
    }
    uint16_t getBits()
    {
        return m_val;
    }
    void setBits(uint16_t val)
    {
        m_val = val;
    }
    uint16_t m_val = 0;
};

// note there are two versions of the same function: processFrameRowSIMD and processFrameRow
// These unit-tests should pass on BOTH, but our strategy is to test one of them, and then
// check they both produce the same results. Although we can also do a search-replace.
// recall the equation we are testing is:
// res = IdOf + Gc * (c-Oc) + Gf * (f-Of)

// these k values should be non-zero
static const float k1 = 1.1f;
static const float k2 = 2.2f;
static const float k3 = 3.4f;
static const float k4 = 4.8f;
static const float k5 = 5.2f;
static const float k6 = 6.5f;
static const float k7 = 7.8f;
static const float k8 = 8.3f;
static const float smallPercent = 0.001f;
static const float idealOffset = 128.0 * 32.0f;

BOOST_AUTO_TEST_CASE(CalibratorCreateAndDestroy)
{
    CalibratorSample calibrator;

    BOOST_CHECK_CLOSE(1000.0F, 1000.001f, smallPercent);
    // alignment check
    BOOST_CHECK((uint64_t)calibrator.m_Gc.data()%32 == 0);
}

// this one checks that IdOf is ok.
BOOST_AUTO_TEST_CASE(CalibratorIdealOffset)
{
    int rows=1, cols=8;
    CalibratorSample calibrator(rows,cols);

    calibrator.m_Gc.at(0,0) = 0.0;
    calibrator.m_Oc.at(0,0) = k2;
    calibrator.m_Gf.at(0,0) = 0.0;
    calibrator.m_Of.at(0,0) = k4;
    calibrator.m_Gain0.at(0,0) = 1.0;

    BitPacker bp;
    bp.clear();
    bp.setCoarse(4); // random value
    bp.setFine(4);
    bp.setGain(0);

    MemBlockI16 input;
    MemBlockF output;

    input.init(rows,cols);
    output.init(rows,cols);

    input.at(0,0) = bp.getBits();

    calibrator.processFrameRow(input, output, 0);
    BOOST_CHECK_CLOSE(output.at(0,0), idealOffset, smallPercent);
}

// this one checks that the coarse value is processed ok
// then it checks that the fine value is processed ok
// then it checks the complete sum works out ok
// also known as ADC stage
BOOST_AUTO_TEST_CASE(CalibratorCoarseAndFine)
{
    int rows=1, cols=8;
    CalibratorSample calibrator(rows,cols);

    calibrator.m_Gc.at(0,0) = k1;
    calibrator.m_Oc.at(0,0) = k2;
    calibrator.m_Gf.at(0,0) = k3;
    calibrator.m_Of.at(0,0) = k4;
    calibrator.m_Gain0.at(0,0) = 1.0;

    BitPacker bp;
    bp.clear();
    bp.setCoarse(8);
    bp.setFine(150);
    bp.setGain(0);

    MemBlockI16 input;
    MemBlockF output;

    input.init(rows,cols);
    output.init(rows,cols);

    input.at(0,0) = bp.getBits();

    // check coarse alone
    calibrator.m_Gf.at(0,0) = 0.0;
    calibrator.processFrameRow(input, output, 0);
    BOOST_CHECK_CLOSE(output.at(0,0), idealOffset + k1 * (8.0f - k2), smallPercent);

    // check fine alone
    input.at(0,0) = bp.getBits();
    calibrator.m_Gc.at(0,0) = 0.0;
    calibrator.m_Gf.at(0,0) = k3;
    calibrator.processFrameRow(input, output, 0);
    BOOST_CHECK_CLOSE(output.at(0,0), idealOffset + k3 * (150.0f - k4), smallPercent);

    // now do both together:
    input.at(0,0) = bp.getBits();
    calibrator.m_Gc.at(0,0) = k1;
    calibrator.processFrameRow(input, output, 0);
    BOOST_CHECK_CLOSE(output.at(0,0), idealOffset + k1 * (8.0f - k2) + k3 * (150.0f - k4), smallPercent);
}

// this one checks that the cds-stage = subtract reset frame, is ok
BOOST_AUTO_TEST_CASE(CalibratorReset)
{
    int rows=1, cols=8;
    CalibratorSample calibrator(rows,cols);

    calibrator.m_Gc.at(0,0) = 0.0;
    calibrator.m_Gf.at(0,0) = 0.0;
    calibrator.m_Gc.at(0,1) = 0.0;
    calibrator.m_Gf.at(0,1) = 0.0;
    calibrator.m_resetFrame.at(0,0) = k8;

    BitPacker bp;
    bp.clear();
    bp.setGain(0);

    MemBlockI16 input;
    MemBlockF output;

    input.init(rows,cols);
    output.init(rows,cols);

    input.at(0,0) = bp.getBits();
    bp.setGain(1);
    input.at(0,1) = bp.getBits();

    float idOf = 128.0f * 32.0f;
    // check reset frame is subtracted
    calibrator.processFrameRow(input, output, 0);
    BOOST_CHECK_CLOSE(output.at(0,0), idOf - k8, smallPercent);
    // but not when gain = 1
    BOOST_CHECK_CLOSE(output.at(0,1), idOf, smallPercent);
}

// this one checks the Lat stage: subtract Ped and multiply
BOOST_AUTO_TEST_CASE(CalibratorLatPedGain)
{
    int rows=1, cols=8;
    CalibratorSample calibrator(rows,cols);

    calibrator.m_Gc.at(0,0) = 0.0;
    calibrator.m_Gf.at(0,0) = 0.0;
    calibrator.m_Gc.at(0,1) = 0.0;
    calibrator.m_Gf.at(0,1) = 0.0;
    calibrator.m_Ped0.at(0,0) = k1;
    calibrator.m_Ped1.at(0,1) = k2;
    calibrator.m_Ped2.at(0,2) = k3;
    calibrator.m_Gain0.at(0,0) = k4;
    calibrator.m_Gain1.at(0,1) = k5;
    calibrator.m_Gain2.at(0,2) = k6;

    BitPacker bp;
    bp.clear();
    bp.setGain(0);

    MemBlockI16 input;
    MemBlockF output;

    input.init(rows,cols);
    output.init(rows,cols);

    input.at(0,0) = bp.getBits();
    bp.setGain(1);
    input.at(0,1) = bp.getBits();
    bp.setGain(2);
    input.at(0,2) = bp.getBits();
    bp.setGain(3);
    input.at(0,3) = bp.getBits();

    float idOf = 128.0f * 32.0f;
    // check right things subtracted in each case
    calibrator.processFrameRow(input, output, 0);
    BOOST_CHECK_CLOSE(output.at(0,0), k4 * (idOf - k1), smallPercent);
    BOOST_CHECK_CLOSE(output.at(0,1), k5 * (idOf - k2), smallPercent);
    BOOST_CHECK_CLOSE(output.at(0,2), k6 * (idOf - k3), smallPercent);
    BOOST_CHECK(isnan(output.at(0,3)));

}

BOOST_AUTO_TEST_CASE(CalibratorAlgNanOk)
{
    int rows=1, cols=24;
    CalibratorSample calibrator(rows,cols);

    MemBlockI16 input;
    input.init(rows,cols);

    for(int c=0;c<cols;++c)
    {
        calibrator.m_Gc.at(0,c) = k1;
        calibrator.m_Oc.at(0,c) = k2;
        calibrator.m_Gf.at(0,c) = k3;
        calibrator.m_Of.at(0,c) = k4;
        calibrator.m_Gain0.at(0,c) = k5;
        calibrator.m_Gain1.at(0,c) = k6;
        calibrator.m_Gain2.at(0,c) = k7;
        calibrator.m_Gain3 = k8;

        input.at(0,c) = rand();
    }

    BitPacker bp;
    bp.clear();
    bp.setCoarse(1);
    bp.setFine(1);
    bp.setGain(0);

    input.at(0,0) = bp.getBits();
    calibrator.m_Gain0.at(0,0) = std::numeric_limits<float>::quiet_NaN();

    calibrator.m_Gc.at(0,1) = std::numeric_limits<float>::quiet_NaN();

    MemBlockF output1;
    output1.init(rows,cols);
    calibrator.processFrameRow(input, output1, 0);

    float lastOne = 0.0f;
    for(int c=0;c<cols;++c)
    {
        if( c==0 || c==1 )
        {
            BOOST_CHECK( isnan(output1.at(0,c)) );
        }
        else
        {
            BOOST_CHECK( !isnan(output1.at(0,c)) );
        }
    }
}

// this tests it when the cma value is not nan (all g0 on cma cols)
BOOST_AUTO_TEST_CASE(CalibratorCMA_real)
{
    int rows=1, cols=64;
    int col1 = 40;
    CalibratorSample calibrator(rows,cols);
    calibrator.setCMA(true, 0);

    MemBlockF pic;
    MemBlockI16 gain;
    pic.init(rows,cols);
    gain.init(rows,cols);
    gain.setAll(0);
    gain.at(0, col1) = 1;

    for(int c=0;c<cols;++c)
    {
        pic.at(0,c) = static_cast<float>(c);
    }

    calibrator.applyCMA(gain, pic, 0);

    for(int c=0;c<cols;++c)
    {
        if(c==col1)
        {
            // cma value not subtracted here cos G1
            BOOST_CHECK_CLOSE(pic.at(0,c), c, smallPercent);
        }
        else
        {
            BOOST_CHECK_CLOSE(pic.at(0,c), c - (31.0f/2.0f), smallPercent);
        }
    }
}

// this tests it when the cma value is nan (not G0 on cma cols)
BOOST_AUTO_TEST_CASE(CalibratorCMA_nan)
{
    int rows=1, cols=64;
    int col1 = 40, col2 = 0;
    CalibratorSample calibrator(rows,cols);
    calibrator.setCMA(true, 0);

    MemBlockF pic;
    MemBlockI16 gain;
    pic.init(rows,cols);
    gain.init(rows,cols);
    gain.setAll(0);
    gain.at(0, col2) = 2;
    gain.at(0, col1) = 1;

    for(int c=0;c<cols;++c)
    {
        pic.at(0,c) = static_cast<float>(c);
    }

    calibrator.applyCMA(gain, pic, 0);

    for(int c=0;c<cols;++c)
    {
        if(c==col1 || c==col2)
        {
            // cma value not subtracted here cos G1
            BOOST_CHECK_CLOSE(pic.at(0,c), c, smallPercent);
        }
        else
        {
            BOOST_CHECK(isnan(pic.at(0,c)));
        }
    }
}

// this one tests processFrameRowSIMD produces the same as processFrameRow for
// some random data. If they agree, they are both right because they are on
// different code paths. We can't test CMA because it requires gain 0 on its row.
BOOST_AUTO_TEST_CASE(CalibratorAlgSIMDSameAsNormal)
{
    const float percentDiff = 0.2;
    int rows=1, cols=24;
    CalibratorSample calibrator(rows,cols);

    MemBlockI16 input, input2;
    input.init(rows,cols);

    calibrator.m_resetFrame.setAll(k4);

    for(int c=0;c<cols;++c)
    {
        calibrator.m_Gc.at(0,c) = k1;
        calibrator.m_Oc.at(0,c) = k2;
        calibrator.m_Gf.at(0,c) = k3;
        calibrator.m_Of.at(0,c) = k4;

        calibrator.m_Ped0.at(0,c) = k3;
        calibrator.m_Ped1.at(0,c) = k6;
        calibrator.m_Ped2.at(0,c) = k7;

        calibrator.m_Gain0.at(0,c) = k5;
        calibrator.m_Gain1.at(0,c) = k6;
        calibrator.m_Gain2.at(0,c) = k7;
        calibrator.m_Gain3 = k8;

        input.at(0,c) = rand();
    }

    input2.clone(input);

    MemBlockF output1, output2;
    output1.init(rows,cols);
    output2.init(rows,cols);

    calibrator.processFrameRowSIMD(input, output1, 0);
    calibrator.processFrameRow(input2, output2, 0);

    float lastOne = 0.0f;
    for(int c=0;c<cols;++c)
    {
        {
            BOOST_CHECK_CLOSE(output1.at(0,c), output2.at(0,c), percentDiff);
            BOOST_CHECK(input.at(0,c) == input2.at(0,c));
            // just check it's not all the same garbage data
            BOOST_CHECK(lastOne != output1.at(0,c));
            lastOne = output1.at(0,c);
        }
    }
}

ext: cpp

max_stars_repo_name: karmagh/percival-detector

max_issues_repo_name: karmagh/percival-detector

max_forks_repo_name: karmagh/percival-detector


text:
//  (C) Copyright Gennadiy Rozental 2001-2008.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision: 63640 $
//
//  Description : simple implementation for Unit Test Framework parameter
//  handling routines. May be rewritten in future to use some kind of
//  command-line arguments parsing facility and environment variable handling
//  facility
// ***************************************************************************

#ifndef BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER
#define BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER

// Boost.Test
#include <boost/test/detail/unit_test_parameters.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/utils/fixed_mapping.hpp>
#include <boost/test/debug.hpp>
#include <boost/test/framework.hpp>

// Boost.Runtime.Param
#include <boost/test/utils/runtime/cla/dual_name_parameter.hpp>
#include <boost/test/utils/runtime/cla/parser.hpp>

namespace rt  = boost::runtime;
namespace cla = rt::cla;

#ifndef UNDER_CE
#include <boost/test/utils/runtime/env/variable.hpp>

namespace env = rt::env;
#endif

// Boost
#include <boost/config.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/detail/enable_warnings.hpp>

// STL
#include <map>
#include <cstdlib>
#include <iostream>
#include <fstream>

#include <boost/test/detail/suppress_warnings.hpp>

//____________________________________________________________________________//

# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::getenv; using ::strncmp; using ::strcmp; }
# endif

namespace boost {

namespace unit_test {

// ************************************************************************** //
// **************    input operations for unit_test's enums    ************** //
// ************************************************************************** //

std::istream&
operator>>( std::istream& in, unit_test::log_level& ll )
{
    static fixed_mapping<const_string,unit_test::log_level,case_ins_less<char const> > log_level_name(
        "all"           , log_successful_tests,
        "success"       , log_successful_tests,
        "test_suite"    , log_test_units,
        "unit_scope"    , log_test_units,
        "message"       , log_messages,
        "warning"       , log_warnings,
        "error"         , log_all_errors,
        "cpp_exception" , log_cpp_exception_errors,
        "system_error"  , log_system_errors,
        "fatal_error"   , log_fatal_errors,
        "nothing"       , log_nothing,

        invalid_log_level
        );

    std::string val;
    in >> val;

    ll = log_level_name[val];
    BOOST_TEST_SETUP_ASSERT( ll != unit_test::invalid_log_level, "invalid log level " + val );

    return in;
}

//____________________________________________________________________________//

std::istream&
operator>>( std::istream& in, unit_test::report_level& rl )
{
    fixed_mapping<const_string,unit_test::report_level,case_ins_less<char const> > report_level_name (
        "confirm",  CONFIRMATION_REPORT,
        "short",    SHORT_REPORT,
        "detailed", DETAILED_REPORT,
        "no",       NO_REPORT,

        INV_REPORT_LEVEL
        );

    std::string val;
    in >> val;

    rl = report_level_name[val];
    BOOST_TEST_SETUP_ASSERT( rl != INV_REPORT_LEVEL, "invalid report level " + val );

    return in;
}

//____________________________________________________________________________//

std::istream&
operator>>( std::istream& in, unit_test::output_format& of )
{
    fixed_mapping<const_string,unit_test::output_format,case_ins_less<char const> > output_format_name (
        "HRF", unit_test::CLF,
        "CLF", unit_test::CLF,
        "XML", unit_test::XML,

        unit_test::INV_OF
        );

    std::string val;
    in >> val;

    of = output_format_name[val];
    BOOST_TEST_SETUP_ASSERT( of != unit_test::INV_OF, "invalid output format " + val );

    return in;
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                 runtime_config               ************** //
// ************************************************************************** //

namespace runtime_config {

namespace {

// framework parameters and corresponding command-line arguments
std::string AUTO_START_DBG    = "auto_start_dbg";
std::string BREAK_EXEC_PATH   = "break_exec_path";
std::string BUILD_INFO        = "build_info";
std::string CATCH_SYS_ERRORS  = "catch_system_errors";
std::string DETECT_FP_EXCEPT  = "detect_fp_exceptions";
std::string DETECT_MEM_LEAKS  = "detect_memory_leaks";
std::string LOG_FORMAT        = "log_format";
std::string LOG_LEVEL         = "log_level";
std::string LOG_SINK          = "log_sink";
std::string OUTPUT_FORMAT     = "output_format";
std::string RANDOM_SEED       = "random";
std::string REPORT_FORMAT     = "report_format";
std::string REPORT_LEVEL      = "report_level";
std::string REPORT_SINK       = "report_sink";
std::string RESULT_CODE       = "result_code";
std::string TESTS_TO_RUN      = "run_test";
std::string SAVE_TEST_PATTERN = "save_pattern";
std::string SHOW_PROGRESS     = "show_progress";
std::string USE_ALT_STACK     = "use_alt_stack";

fixed_mapping<const_string,const_string> parameter_2_env_var(
    AUTO_START_DBG    , "BOOST_TEST_AUTO_START_DBG",
    BREAK_EXEC_PATH   , "BOOST_TEST_BREAK_EXEC_PATH",
    BUILD_INFO        , "BOOST_TEST_BUILD_INFO",
    CATCH_SYS_ERRORS  , "BOOST_TEST_CATCH_SYSTEM_ERRORS",
    DETECT_FP_EXCEPT  , "BOOST_TEST_DETECT_FP_EXCEPTIONS",
    DETECT_MEM_LEAKS  , "BOOST_TEST_DETECT_MEMORY_LEAK",
    LOG_FORMAT        , "BOOST_TEST_LOG_FORMAT",
    LOG_LEVEL         , "BOOST_TEST_LOG_LEVEL",
    LOG_SINK          , "BOOST_TEST_LOG_SINK",
    OUTPUT_FORMAT     , "BOOST_TEST_OUTPUT_FORMAT",
    RANDOM_SEED       , "BOOST_TEST_RANDOM",
    REPORT_FORMAT     , "BOOST_TEST_REPORT_FORMAT",
    REPORT_LEVEL      , "BOOST_TEST_REPORT_LEVEL",
    REPORT_SINK       , "BOOST_TEST_REPORT_SINK",
    RESULT_CODE       , "BOOST_TEST_RESULT_CODE",
    TESTS_TO_RUN      , "BOOST_TESTS_TO_RUN",
    SAVE_TEST_PATTERN , "BOOST_TEST_SAVE_PATTERN",
    SHOW_PROGRESS     , "BOOST_TEST_SHOW_PROGRESS",
    USE_ALT_STACK     , "BOOST_TEST_USE_ALT_STACK",

    ""
);

//____________________________________________________________________________//

// storage for the CLAs
cla::parser     s_cla_parser;
std::string     s_empty;

output_format   s_report_format;
output_format   s_log_format;

//____________________________________________________________________________//

template<typename T>
T
retrieve_parameter( const_string parameter_name, cla::parser const& s_cla_parser, T const& default_value = T(), T const& optional_value = T() )
{
    rt::const_argument_ptr arg = s_cla_parser[parameter_name];
    if( arg ) {
        if( rtti::type_id<T>() == rtti::type_id<bool>() ||
            !static_cast<cla::parameter const&>( arg->p_formal_parameter.get() ).p_optional_value )
            return s_cla_parser.get<T>( parameter_name );

        optional<T> val = s_cla_parser.get<optional<T> >( parameter_name );
        if( val )
            return *val;
        else
            return optional_value;
    }

    boost::optional<T> v;

#ifndef UNDER_CE
    env::get( parameter_2_env_var[parameter_name], v );
#endif

    if( v )
        return *v;
    else
        return default_value;
}

//____________________________________________________________________________//

} // local namespace

void
init( int& argc, char** argv )
{
    using namespace cla;

    try {
        s_cla_parser - cla::ignore_mismatch
          << cla::dual_name_parameter<bool>( AUTO_START_DBG + "|d" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Automatically starts debugger if system level error (signal) occurs")
          << cla::named_parameter<std::string>( BREAK_EXEC_PATH )
            - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
               cla::description = "For the exception safety testing allows to break at specific execution path")
          << cla::dual_name_parameter<bool>( BUILD_INFO + "|i" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Shows library build information" )
          << cla::dual_name_parameter<bool>( CATCH_SYS_ERRORS + "|s" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Allows to switch between catching and ignoring system errors (signals)")
          << cla::named_parameter<bool>( DETECT_FP_EXCEPT )
            - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
               cla::description = "Allows to switch between catching and ignoring floating point exceptions")
          << cla::named_parameter<long>( DETECT_MEM_LEAKS )
            - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
               cla::description = "Allows to switch between catching and ignoring memory leaks")
          << cla::dual_name_parameter<unit_test::output_format>( LOG_FORMAT + "|f" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Specifies log format")
          << cla::dual_name_parameter<unit_test::log_level>( LOG_LEVEL + "|l" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Specifies log level")
          << cla::dual_name_parameter<std::string>( LOG_SINK + "|k" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Specifies log sink:stdout(default),stderr or file name")
          << cla::dual_name_parameter<unit_test::output_format>( OUTPUT_FORMAT + "|o" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Specifies output format (both log and report)")
          << cla::dual_name_parameter<int>( RANDOM_SEED + "|a" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,cla::optional_value,
               cla::description = "Allows to switch between sequential and random order of test units execution.\n"
                                  "Optionally allows to specify concrete seed for random number generator")
          << cla::dual_name_parameter<unit_test::output_format>( REPORT_FORMAT + "|m" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Specifies report format")
          << cla::dual_name_parameter<unit_test::report_level>(REPORT_LEVEL + "|r")
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Specifies report level")
          << cla::dual_name_parameter<std::string>( REPORT_SINK + "|e" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Specifies report sink:stderr(default),stdout or file name")
          << cla::dual_name_parameter<bool>( RESULT_CODE + "|c" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Allows to disable test modules's result code generation")
          << cla::dual_name_parameter<std::string>( TESTS_TO_RUN + "|t" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Allows to filter which test units to run")
          << cla::named_parameter<bool>( SAVE_TEST_PATTERN )
            - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
               cla::description = "Allows to switch between saving and matching against test pattern file")
          << cla::dual_name_parameter<bool>( SHOW_PROGRESS + "|p" )
            - (cla::prefix = "--|-",cla::separator = "=| ",cla::guess_name,cla::optional,
               cla::description = "Turns on progress display")
          << cla::named_parameter<bool>( USE_ALT_STACK )
            - (cla::prefix = "--",cla::separator = "=",cla::guess_name,cla::optional,
               cla::description = "Turns on/off usage of an alternative stack for signal handling")

          << cla::dual_name_parameter<bool>( "help|?" )
            - (cla::prefix = "--|-",cla::separator = "=",cla::guess_name,cla::optional,
               cla::description = "this help message")
            ;

        s_cla_parser.parse( argc, argv );

        if( s_cla_parser["help"] ) {
            s_cla_parser.help( std::cout );
            throw framework::nothing_to_test();
        }

        s_report_format     = retrieve_parameter( REPORT_FORMAT, s_cla_parser, unit_test::CLF );
        s_log_format        = retrieve_parameter( LOG_FORMAT, s_cla_parser, unit_test::CLF );

        unit_test::output_format of = retrieve_parameter( OUTPUT_FORMAT, s_cla_parser, unit_test::INV_OF );

        if( of != unit_test::INV_OF )
            s_report_format = s_log_format = of;
    }
    catch( rt::logic_error const& ex ) {
        std::ostringstream err;

        err << "Fail to process runtime parameters: " << ex.msg() << std::endl;
        s_cla_parser.usage( err );

        throw framework::setup_error( err.str() );
    }
}

//____________________________________________________________________________//

unit_test::log_level
log_level()
{
    return retrieve_parameter( LOG_LEVEL, s_cla_parser, unit_test::log_all_errors );
}

//____________________________________________________________________________//

bool
no_result_code()
{
    return !retrieve_parameter( RESULT_CODE, s_cla_parser, true );
}

//____________________________________________________________________________//

unit_test::report_level
report_level()
{
    return retrieve_parameter( REPORT_LEVEL, s_cla_parser, unit_test::CONFIRMATION_REPORT );
}

//____________________________________________________________________________//

const_string
test_to_run()
{
    static std::string s_test_to_run = retrieve_parameter( TESTS_TO_RUN, s_cla_parser, s_empty );

    return s_test_to_run;
}

//____________________________________________________________________________//

const_string
break_exec_path()
{
    static std::string s_break_exec_path = retrieve_parameter( BREAK_EXEC_PATH, s_cla_parser, s_empty );

    return s_break_exec_path;
}

//____________________________________________________________________________//

bool
save_pattern()
{
    return retrieve_parameter( SAVE_TEST_PATTERN, s_cla_parser, false );
}

//____________________________________________________________________________//

bool
show_progress()
{
    return retrieve_parameter( SHOW_PROGRESS, s_cla_parser, false );
}

//____________________________________________________________________________//

bool
show_build_info()
{
    return retrieve_parameter( BUILD_INFO, s_cla_parser, false );
}

//____________________________________________________________________________//

bool
catch_sys_errors()
{
    return retrieve_parameter( CATCH_SYS_ERRORS, s_cla_parser,
#ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP
        false
#else
        true
#endif
        );
}

//____________________________________________________________________________//

bool
auto_start_dbg()
{
    // !! set debugger as an option
    return retrieve_parameter( AUTO_START_DBG, s_cla_parser, false );
;
}

//____________________________________________________________________________//

bool
use_alt_stack()
{
    return retrieve_parameter( USE_ALT_STACK, s_cla_parser, true );
}

//____________________________________________________________________________//

bool
detect_fp_exceptions()
{
    return retrieve_parameter( DETECT_FP_EXCEPT, s_cla_parser, false );
}

//____________________________________________________________________________//

output_format
report_format()
{
    return s_report_format;
}

//____________________________________________________________________________//

output_format
log_format()
{
    return s_log_format;
}

//____________________________________________________________________________//

std::ostream*
report_sink()
{
    std::string sink_name = retrieve_parameter( REPORT_SINK, s_cla_parser, s_empty );

    if( sink_name.empty() || sink_name == "stderr" )
        return &std::cerr;

    if( sink_name == "stdout" )
        return &std::cout;

    static std::ofstream log_file( sink_name.c_str() );
    return &log_file;
}

//____________________________________________________________________________//

std::ostream*
log_sink()
{
    std::string sink_name = retrieve_parameter( LOG_SINK, s_cla_parser, s_empty );

    if( sink_name.empty() || sink_name == "stdout" )
        return &std::cout;

    if( sink_name == "stderr" )
        return &std::cerr;

    static std::ofstream report_file( sink_name.c_str() );
    return &report_file;
}

//____________________________________________________________________________//

long
detect_memory_leaks()
{
    return retrieve_parameter( DETECT_MEM_LEAKS, s_cla_parser, static_cast<long>(1) );
}

//____________________________________________________________________________//

int
random_seed()
{
    return retrieve_parameter( RANDOM_SEED, s_cla_parser, 0, 1 );
}

//____________________________________________________________________________//

} // namespace runtime_config

} // namespace unit_test

} // namespace boost

//____________________________________________________________________________//

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER

ext: ipp


text:
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------

// This example shows what need to be done to customize data_type of ptree.
//
// It creates my_ptree type, which is a basic_ptree having boost::any as its data
// container (instead of std::string that standard ptree has).

#include <boost/property_tree/ptree.hpp>
#include <boost/any.hpp>
#include <list>
#include <string>
#include <iostream>

// Custom translator that works with boost::any instead of std::string
template <class Ext, class Int = boost::any>
struct variant_translator
{
    typedef Ext external_type;
    typedef Int internal_type;

    external_type
    get_value(const internal_type &value) const
    {
        return boost::any_cast<external_type>(value);
    }
    internal_type
    put_value(const external_type &value) const
    {
        return value;
    }
};

int main()
{

    using namespace boost::property_tree;

    // Property_tree with boost::any as data type
    // Key type:        std::string
    // Data type:       boost::any
    // Key comparison:  default (std::less<std::string>)
    typedef basic_ptree<std::string, boost::any> my_ptree;
    my_ptree pt;

    // Put/get int value
    typedef variant_translator<int> int_tran;
    pt.put("int value", 3, int_tran());
    int int_value = pt.get<int>("int value", int_tran());
    std::cout << "Int value: " << int_value << "\n";

    // Put/get string value
    typedef variant_translator<std::string> string_tran;
    pt.put<std::string>("string value", "foo bar", string_tran());
    std::string string_value = pt.get<std::string>(
        "string value"
      , string_tran()
    );
    std::cout << "String value: " << string_value << "\n";

    // Put/get list<int> value
    typedef std::list<int> intlist;
    typedef variant_translator<intlist> intlist_tran;
    int list_data[] = { 1, 2, 3, 4, 5 };
    pt.put<intlist>(
        "list value"
      , intlist(
            list_data
          , list_data + sizeof(list_data) / sizeof(*list_data)
        )
      , intlist_tran()
    );
    intlist list_value = pt.get<intlist>(
        "list value"
      , intlist_tran()
    );
    std::cout << "List value: ";
    for (intlist::iterator it = list_value.begin(); it != list_value.end(); ++it)
        std::cout << *it << ' ';
    std::cout << '\n';
}


text:
/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 *
 *************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbui.hxx"

#ifndef DBACCESS_SOURCE_UI_MISC_DEFAULTOBJECTNAMECHECK_HXX
#include "defaultobjectnamecheck.hxx"
#endif

#ifndef _DBU_MISC_HRC_
#include "dbu_misc.hrc"
#endif

#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif

/** === begin UNO includes === **/
#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_XQUERIESSUPPLIER_HPP_
#include <com/sun/star/sdb/XQueriesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_COMMANDTYPE_HPP_
#include <com/sun/star/sdb/CommandType.hpp>
#endif
#ifndef _COM_SUN_STAR_SDB_TOOLS_XCONNECTIONTOOLS_HPP_
#include <com/sun/star/sdb/tools/XConnectionTools.hpp>
#endif
/** === end UNO includes === **/

#ifndef _DBHELPER_DBEXCEPTION_HXX_
#include <connectivity/dbexception.hxx>
#endif
#ifndef CONNECTIVITY_INC_CONNECTIVITY_DBMETADATA_HXX
#include <connectivity/dbmetadata.hxx>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

#ifndef TOOLS_DIAGNOSE_EX_H
#include <tools/diagnose_ex.h>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _CPPUHELPER_EXC_HLP_HXX_
#include <cppuhelper/exc_hlp.hxx>
#endif

#include <vector>
#include <boost/shared_ptr.hpp>

//........................................................................
namespace dbaui
{
//........................................................................

	/** === begin UNO using === **/
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::container::XNameAccess;
    using ::com::sun::star::lang::IllegalArgumentException;
    using ::com::sun::star::container::XHierarchicalNameAccess;
    using ::com::sun::star::sdbc::SQLException;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::sdbc::XConnection;
    using ::com::sun::star::sdbcx::XTablesSupplier;
    using ::com::sun::star::sdb::XQueriesSupplier;
    using ::com::sun::star::uno::UNO_QUERY_THROW;
    using ::com::sun::star::uno::makeAny;
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::sdb::tools::XObjectNames;
    using ::com::sun::star::sdb::tools::XConnectionTools;
    using ::com::sun::star::uno::UNO_QUERY;
	/** === end UNO using === **/

    using namespace dbtools;

    namespace CommandType = ::com::sun::star::sdb::CommandType;

	//====================================================================
	//= helper
	//====================================================================
    namespace
    {
        void    lcl_fillNameExistsError( const ::rtl::OUString& _rObjectName, SQLExceptionInfo& _out_rErrorToDisplay )
        {
            String sErrorMessage = String( ModuleRes( STR_NAMED_OBJECT_ALREADY_EXISTS ) );
		    sErrorMessage.SearchAndReplaceAllAscii( "$#$", _rObjectName );
            SQLException aError;
            aError.Message = sErrorMessage;
            _out_rErrorToDisplay = aError;
        }

    }

	//====================================================================
	//= HierarchicalNameCheck_Impl
	//====================================================================
    struct HierarchicalNameCheck_Impl
    {
        Reference< XHierarchicalNameAccess >    xHierarchicalNames;
        ::rtl::OUString                         sRelativeRoot;
    };

    //====================================================================
	//= HierarchicalNameCheck
	//====================================================================
    //--------------------------------------------------------------------
    HierarchicalNameCheck::HierarchicalNameCheck( const Reference< XHierarchicalNameAccess >& _rxNames, const ::rtl::OUString& _rRelativeRoot )
        :m_pImpl( new HierarchicalNameCheck_Impl )
    {
        m_pImpl->xHierarchicalNames = _rxNames;
        m_pImpl->sRelativeRoot = _rRelativeRoot;

        if ( !m_pImpl->xHierarchicalNames.is() )
            throw IllegalArgumentException();
    }

    //--------------------------------------------------------------------
    HierarchicalNameCheck::~HierarchicalNameCheck()
    {
    }

    //--------------------------------------------------------------------
    bool HierarchicalNameCheck::isNameValid( const ::rtl::OUString& _rObjectName, SQLExceptionInfo& _out_rErrorToDisplay ) const
    {
        try
        {
            ::rtl::OUStringBuffer aCompleteName;
			if ( m_pImpl->sRelativeRoot.getLength() )
            {
                aCompleteName.append( m_pImpl->sRelativeRoot );
				aCompleteName.appendAscii( "/" );
            }
            aCompleteName.append( _rObjectName );

            ::rtl::OUString sCompleteName( aCompleteName.makeStringAndClear() );
			if ( !m_pImpl->xHierarchicalNames->hasByHierarchicalName( sCompleteName ) )
                return true;
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }

        lcl_fillNameExistsError( _rObjectName, _out_rErrorToDisplay );
        return false;
    }

    //====================================================================
    //= DynamicTableOrQueryNameCheck_Impl
    //====================================================================
    struct DynamicTableOrQueryNameCheck_Impl
    {
        sal_Int32                   nCommandType;
        Reference< XObjectNames >   xObjectNames;
    };

    //====================================================================
    //= DynamicTableOrQueryNameCheck
    //====================================================================
    //--------------------------------------------------------------------
    DynamicTableOrQueryNameCheck::DynamicTableOrQueryNameCheck( const Reference< XConnection >& _rxSdbLevelConnection, sal_Int32 _nCommandType )
        :m_pImpl( new DynamicTableOrQueryNameCheck_Impl )
    {
        Reference< XConnectionTools > xConnTools( _rxSdbLevelConnection, UNO_QUERY );
        if ( xConnTools.is() )
            m_pImpl->xObjectNames.set( xConnTools->getObjectNames() );
        if ( !m_pImpl->xObjectNames.is() )
            throw IllegalArgumentException();

        if ( ( _nCommandType != CommandType::QUERY ) && ( _nCommandType != CommandType::TABLE ) )
            throw IllegalArgumentException();
        m_pImpl->nCommandType = _nCommandType;
    }

    //--------------------------------------------------------------------
    DynamicTableOrQueryNameCheck::~DynamicTableOrQueryNameCheck()
    {
    }

    //--------------------------------------------------------------------
    bool DynamicTableOrQueryNameCheck::isNameValid( const ::rtl::OUString& _rObjectName, ::dbtools::SQLExceptionInfo& _out_rErrorToDisplay ) const
    {
        try
        {
            m_pImpl->xObjectNames->checkNameForCreate( m_pImpl->nCommandType, _rObjectName );
            return true;
        }
        catch( const SQLException& )
        {
            _out_rErrorToDisplay = ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() );
        }
        return false;
    }

//........................................................................
} // namespace dbaui
//........................................................................

ext: cxx

max_stars_repo_name: Grosskopf/openoffice

max_issues_repo_name: Grosskopf/openoffice

max_forks_repo_name: Grosskopf/openoffice


text:
#include <iostream>
#include <fstream>
#include <deque>
#include "map"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sstream>
#include <iomanip>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>

using namespace std;
//ofstream OutFile;
FILE * trace;
map<long int, long int> delta_map;

/* ===================================================================== */
/* Main                                                                  */
/* ===================================================================== */

int main(int argc, char * argv[]) {
  ifstream inFile(argv[1]);
  string line;
  uint64_t line_cntr=0;
  uint64_t instr_count=0;
    uint64_t bubble=0;

  ifstream file(argv[1], ios_base::in | ios_base::binary);
  boost::iostreams::filtering_istream in;
  in.push(boost::iostreams::gzip_decompressor());
  in.push(file);

  for(std::string str; std::getline(in, str);) {
    string str_addr;
    uint64_t addr;
    int rw;
    string op;
    istringstream iss(str);
    iss>>bubble>>str_addr>>rw;

    line_cntr++;
    instr_count = instr_count + bubble;
  }
  cout<<" Instructions count "<<instr_count<<endl;
  cout<<" Line Count "<<line_cntr<<"   "<<bubble<<endl;
}