diff --git a/src/DFSOutputMgr.cpp b/src/DFSOutputMgr.cpp deleted file mode 100644 index be97f2ac5..000000000 --- a/src/DFSOutputMgr.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#include "DFSOutputMgr.h" -#include -#include -#include -#include "CGOptions.h" -#include "Function.h" -#include "Type.h" -#include "VariableSelector.h" - -using namespace std; - -DFSOutputMgr *DFSOutputMgr::instance_ = NULL; - -DFSOutputMgr::DFSOutputMgr() -{ - -} - -DFSOutputMgr::~DFSOutputMgr() -{ - -} - -DFSOutputMgr * -DFSOutputMgr::CreateInstance() -{ - if (DFSOutputMgr::instance_) - return DFSOutputMgr::instance_; - - DFSOutputMgr::instance_ = new DFSOutputMgr(); - std::string s_output = CGOptions::struct_output(); - if (s_output.empty()) - instance_->struct_output_ = DEFAULT_STRUCT_OUTPUT; - else - instance_->struct_output_ = s_output; - - assert(DFSOutputMgr::instance_); - return DFSOutputMgr::instance_; -} - -void -DFSOutputMgr::OutputHeader(int argc, char *argv[], unsigned long seed) -{ - if (!CGOptions::compact_output()) - OutputMgr::OutputHeader(argc, argv, seed); -} - -void -DFSOutputMgr::OutputStructUnions(ostream& /*out*/) -{ - ofstream o_struct(struct_output_.c_str()); - OutputStructUnionDeclarations(o_struct); - o_struct.close(); -} - -void -DFSOutputMgr::Output() -{ - std::ostream &out = get_main_out(); - - OutputGlobalVariables(out); - if (!CGOptions::compact_output()) - OutputForwardDeclarations(out); - OutputFunctions(out); - - if (CGOptions::step_hash_by_stmt()) { - OutputMgr::OutputHashFuncDef(out); - OutputMgr::OutputStepHashFuncDef(out); - } - - if (!CGOptions::compact_output()) - OutputMain(out); -} - -std::ostream & -DFSOutputMgr::get_main_out() -{ - return std::cout; -} - -void -DFSOutputMgr::outputln(ostream &out) -{ - if (!CGOptions::compact_output()) - out << std::endl; -} - -void -DFSOutputMgr::output_comment_line(ostream &out, const std::string &comment) -{ - if (!CGOptions::compact_output()) - OutputMgr::output_comment_line(out, comment); -} - -void -DFSOutputMgr::output_tab(ostream &out, int indent) -{ - if (!CGOptions::compact_output()) - OutputMgr::output_tab(out, indent); -} - diff --git a/src/DFSOutputMgr.h b/src/DFSOutputMgr.h deleted file mode 100644 index 36c983922..000000000 --- a/src/DFSOutputMgr.h +++ /dev/null @@ -1,65 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef DFS_OUTPUT_MGR_H -#define DFS_OUTPUT_MGR_H - -#include "OutputMgr.h" - -#define DEFAULT_STRUCT_OUTPUT "csmith_structs.h" - -class DFSOutputMgr : public OutputMgr { -public: - static DFSOutputMgr *CreateInstance(); - - virtual ~DFSOutputMgr(); - - virtual void OutputHeader(int argc, char *argv[], unsigned long seed); - - virtual void OutputStructUnions(ostream& /*out*/); - - virtual void Output(); - - virtual void outputln(ostream &out); - - virtual void output_comment_line(ostream &out, const std::string &comment); - - virtual void output_tab(ostream &out, int indent); - -private: - DFSOutputMgr(); - - virtual std::ostream &get_main_out(); - - static DFSOutputMgr *instance_; - - std::string struct_output_; -}; - -#endif // DFS_OUTPUT_MGR_H diff --git a/src/DFSProgramGenerator.cpp b/src/DFSProgramGenerator.cpp deleted file mode 100644 index e8be8c38d..000000000 --- a/src/DFSProgramGenerator.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#include "DFSProgramGenerator.h" -#include -#include -#include -#include "RandomNumber.h" -#include "AbsRndNumGenerator.h" -#include "DFSRndNumGenerator.h" -#include "DFSOutputMgr.h" -#include "Finalization.h" -#include "Error.h" -#include "Function.h" -#include "VariableSelector.h" -#include "util.h" -#include "PartialExpander.h" - -using namespace std; - -DFSProgramGenerator::DFSProgramGenerator(int argc, char *argv[], unsigned long seed) - : argc_(argc), - argv_(argv), - seed_(seed), - good_count_(0), - output_mgr_(NULL) -{ - -} - -DFSProgramGenerator::~DFSProgramGenerator() -{ - Finalization::doFinalization(); - delete output_mgr_; -} - -void -DFSProgramGenerator::initialize() -{ - RandomNumber::CreateInstance(rDFSRndNumGenerator, seed_); - output_mgr_ = DFSOutputMgr::CreateInstance(); - assert(output_mgr_); -} - -std::string -DFSProgramGenerator::get_count_prefix(const std::string &name) -{ - std::ostringstream ss; - ss << "p_" << good_count_ << "_" << name; - return ss.str(); -} - -void -DFSProgramGenerator::goGenerator() -{ - DFSRndNumGenerator *impl = - dynamic_cast(RandomNumber::GetRndNumGenerator()); - //unsigned long long count = 0; - GenerateAllTypes(); - output_mgr_->OutputStructUnions(cout); - while(!impl->get_all_done()) { - Error::set_error(SUCCESS); - GenerateFunctions(); - if (Error::get_error() == SUCCESS) { - //count++; - //if (count >= 47376) - //cout << "here" << std::endl; - output_mgr_->OutputHeader(argc_, argv_, seed_); - output_mgr_->Output(); - OutputMgr::really_outputln(cout); - good_count_++; - } - impl->reset_state(); - Function::doFinalization(); - VariableSelector::doFinalization(); - reset_gensym(); - PartialExpander::restore_init_values(); - //cout << "count = " << count << std::endl; - } -} - diff --git a/src/DFSProgramGenerator.h b/src/DFSProgramGenerator.h deleted file mode 100644 index cc613324f..000000000 --- a/src/DFSProgramGenerator.h +++ /dev/null @@ -1,64 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef DFS_PROGRAM_GENERATOR_H -#define DFS_PROGRAM_GENERATOR_H - -#include "AbsProgramGenerator.h" -#include "Common.h" - -class OutputMgr; - -class DFSProgramGenerator : public AbsProgramGenerator { -public: - DFSProgramGenerator(int argc, char *argv[], unsigned long seed); - - virtual ~DFSProgramGenerator(); - - virtual OutputMgr* getOutputMgr() { return output_mgr_; } - - virtual void goGenerator(); - - virtual void initialize(); - - virtual std::string get_count_prefix(const std::string &name); - -private: - int argc_; - - char **argv_; - - unsigned long seed_; - - INT64 good_count_; - - OutputMgr *output_mgr_; -}; - -#endif diff --git a/src/DFSRndNumGenerator.cpp b/src/DFSRndNumGenerator.cpp deleted file mode 100644 index 87d5731d3..000000000 --- a/src/DFSRndNumGenerator.cpp +++ /dev/null @@ -1,494 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#include "DFSRndNumGenerator.h" - -#include -#include -#include - -#include "CGOptions.h" -#include "Filter.h" -#include "SequenceFactory.h" -#include "Sequence.h" -#include "Error.h" -#include "SequenceLineParser.h" - -// Represents the data for each random choice -class DFSRndNumGenerator::SearchState -{ -public: - explicit SearchState(int index); - SearchState(const SearchState &s); - ~SearchState(); - - void initSearchState(bool init, int value, int bound); - void dump(const string &where); - - // getters and setters - bool init() { return init_; } - void set_init(bool init) { init_ = init; } - - int value() { return value_; } - void set_value(int value) { value_ = value; } - void inc_value(void) { ++value_; } - - int bound() { return bound_; } - void set_bound(int bound) { bound_ = bound; } - - int index() { return index_; } - -private: - // Whether this state has been initialized - bool init_; - // Current value from 0...(bound - 1) - int value_; - - int bound_; - - int index_; -}; - -/* - * - */ -DFSRndNumGenerator::SearchState::SearchState(int index) - : init_(false), - value_(0), - bound_(0), - index_(index) -{ - // Nothing to do -} - -DFSRndNumGenerator::SearchState::SearchState(const DFSRndNumGenerator::SearchState &state) - : init_(state.init_), - value_(state.value_), - bound_(state.bound_), - index_(state.index_) -{ - -} -/* - * - */ -DFSRndNumGenerator::SearchState::~SearchState() -{ - // Nothing to do -} - -/* - * - */ -void -DFSRndNumGenerator::SearchState::initSearchState(bool init, int value, int bound) -{ - init_ = init; - value_ = value; - bound_ = bound; -} - -#define DEBUG -#ifdef DEBUG -void DFSRndNumGenerator::SearchState::dump(const string &where) -{ - cout << "[state]" << where << ", index = " << index_ << ", init = " << init_ << ", value = " << value_ << ", bound = " \ - << bound_ << std::endl; -} -#else -void DFSRndNumGenerator::SearchState::dump(const string &) -{ -} -#endif -// ---------------------------------------------------------------------------------------------- - -DFSRndNumGenerator *DFSRndNumGenerator::impl_ = 0; - -DFSRndNumGenerator::DFSRndNumGenerator(Sequence *concrete_seq) - : trace_string_(""), - decision_depth_(-1), - current_pos_(-1), - all_done_(false), - seq_(concrete_seq), - use_debug_sequence_(false) -{ - init_states(CGOptions::max_exhaustive_depth()); -} - -DFSRndNumGenerator::~DFSRndNumGenerator() -{ - std::vector::iterator i; - for (i = states_.begin(); i != states_.end(); ++i) { - delete (*i); - } - states_.clear(); - SequenceFactory::destroy_sequences(); -} - -/* - * Singleton - */ -DFSRndNumGenerator* -DFSRndNumGenerator::make_rndnum_generator() -{ - if (impl_) - return impl_; - - Sequence *seq = SequenceFactory::make_sequence(); - - impl_ = new DFSRndNumGenerator(seq); - - assert(impl_); - - std::string debug_sequence = CGOptions::dfs_debug_sequence(); - if (!debug_sequence.empty()) { - std::vector nums; - if (!SequenceLineParser >::parse_sequence(nums, debug_sequence, SequenceFactory::current_sep_char())) { - assert("dfs debugging sequence error!" && 0); - } - impl_->initialize_sequence(nums); - impl_->use_debug_sequence_ = true; - } - - return impl_; -} - -void -DFSRndNumGenerator::initialize_sequence(const vector &v) -{ - size_t i = 0; - for (i = 0; i < v.size(); i++) { - seq_->add_number(v[i], 0, i); - } -} - -#ifdef DEBUG -void -DFSRndNumGenerator::dumpCurrentState(int bound, const string &where) -{ - cout << "[current]" << where << ", current_pos = " << current_pos_ \ - << ", decision_depth = " << decision_depth_ << " , bound = " \ - << bound << ", all_done = " << all_done_ << std::endl; -} -#else -void -DFSRndNumGenerator::dumpCurrentState(int, const string &) -{ -} -#endif - -/* - * invoked from DepthSpec.cpp. - * returning true means that we do eager backtracking. - */ -bool -DFSRndNumGenerator::eager_backtracking(int depth_needed) -{ - if (current_pos_ <= 0) { - // all_done_ = true; - // Error::set_error(BACKTRACKING_ERROR); - // return true; - return false; - } - - int max_depth = CGOptions::max_exhaustive_depth(); - int remain_depth = max_depth - current_pos_; - if (remain_depth >= depth_needed) - return false; - - if (current_pos_ > decision_depth_) { - Error::set_error(BACKTRACKING_ERROR); - return true; - } - - // reset decision depth - decision_depth_ = current_pos_; - for (int i = current_pos_ + 1; i < max_depth; ++i) - states_[i]->set_init(false); - - Error::set_error(BACKTRACKING_ERROR); - return true; -} - -int -DFSRndNumGenerator::revisit_node(DFSRndNumGenerator::SearchState *state, int local_current_pos, - int bound, const Filter *filter, const string *) -{ - int rv = state->value(); - if (filter) { - if (rv >= bound) { - state->dump(""); - dumpCurrentState(bound, ""); - cout << "rv = " << rv << ", bound = " << bound << std::endl; - assert(0); - } - - filter->filter(rv); - - ERROR_GUARD(-1); - - assert(current_pos_ < CGOptions::max_exhaustive_depth()); - - } - seq_->add_number(rv, bound, local_current_pos); - return rv; -} - -bool -DFSRndNumGenerator::filter_invalid_nums(vector *invalid_nums, int v) -{ - if (!invalid_nums) - return false; - - vector::iterator i = find(invalid_nums->begin(), invalid_nums->end(), v); - return (i != invalid_nums->end()); -} - -int -DFSRndNumGenerator::random_choice (int bound, const Filter *filter, const string *where, vector *invalid_nums) -{ - int err = Error::get_error(); - - if (err == BACKTRACKING_ERROR) { - return -1; - } - else if (err != SUCCESS) { - assert("request random number in an error state. " && 0); - } - - ++current_pos_; - if (use_debug_sequence_) { - int rv = seq_->get_number_by_pos(current_pos_); - if (filter) - filter->filter(rv); - //cout << "current_pos _ = " << current_pos_ << ", length = " << seq_->sequence_length() << std::endl; - if (static_cast(current_pos_) >= seq_->sequence_length() - 1) { - all_done_ = true; - } - return rv; - } - - int local_current_pos = current_pos_; - - if (current_pos_ >= CGOptions::max_exhaustive_depth() || - decision_depth_ >= CGOptions::max_exhaustive_depth()) { - Error::set_error(EXCEED_MAX_DEPTH_ERROR); - return -1; - } - - DFSRndNumGenerator::SearchState *state = states_[current_pos_]; - - state->set_bound(bound); - //dumpCurrentState(bound, ""); - //state->dump(""); - - // Revisit a node - if (current_pos_ < decision_depth_ && state->init()) { - return revisit_node(state, local_current_pos, bound, filter, where); - } - - if (state->init()) { - int v = state->value(); - int local_decision_depth = decision_depth_; - do { // Filter out invalid value - ++v; - state->set_value(v); - current_pos_ = local_current_pos; - decision_depth_ = local_decision_depth; - ERROR_GUARD(-1); - } while (v < bound && ((filter && filter->filter(v)) || filter_invalid_nums(invalid_nums, v))); - - state->set_value(v); - - if (state->value() >= bound) { // backtracking - current_pos_ = local_current_pos; - for (int i = current_pos_; i < CGOptions::max_exhaustive_depth(); ++i) { - states_[i]->set_init(false); - } - --decision_depth_; - if (decision_depth_ < 0) - all_done_ = true; - Error::set_error(BACKTRACKING_ERROR); - return -1; - } - else { // switch branch - ERROR_GUARD(-1); - - int rv = state->value(); - seq_->add_number(rv, bound, local_current_pos); - return rv; - } - } - else { // First time to visit this node - int v = 0; - - ++decision_depth_; - state->initSearchState(true, v, bound); - - while (v < bound && ((filter && (filter->filter(v))) || filter_invalid_nums(invalid_nums, v))) { // Filter out invalid value - for (int i = decision_depth_; i < CGOptions::max_exhaustive_depth(); ++i) { - states_[i]->set_value(0); - } - ERROR_GUARD(-1); - decision_depth_ = current_pos_; - current_pos_ = local_current_pos; - ++v; - } - decision_depth_ = current_pos_; - - if (v >= bound) { - current_pos_ = local_current_pos; - for (int i = current_pos_; i < CGOptions::max_exhaustive_depth(); ++i) { - states_[i]->set_init(false); - } - --decision_depth_; - if (decision_depth_ < 0) - all_done_ = true; - Error::set_error(BACKTRACKING_ERROR); - return -1; - } - - state->set_value(v); - - ERROR_GUARD(-1); - - seq_->add_number(v, bound, local_current_pos); - return v; - } -} - -void -DFSRndNumGenerator::log_depth(int d, const string *where, const char *log) -{ - std::ostringstream ss1; - - if (log) - ss1 << "[" << log << "]"; - - if (where) - ss1 << d << "(" << *where << ", pos = " << current_pos_ << ", current_decision_depth=" << decision_depth_ << ")->"; - else - ss1 << d << "(..., pos = " << current_pos_ << ", current_decision_depth=" << decision_depth_ << ")->"; - trace_string_ += ss1.str(); -} - -void -DFSRndNumGenerator::init_states(int size) -{ - for (int i = 0; i < size; ++i) { - DFSRndNumGenerator::SearchState *state = new SearchState(i); - assert(state && "new SearchState: error!"); - states_.push_back(state); - } -} - -void -DFSRndNumGenerator::reset_state(void) -{ - current_pos_ = -1; - trace_string_ = ""; - seq_->clear(); -} - -/* - * - */ -void -DFSRndNumGenerator::get_sequence(std::string &sequence) -{ - std::ostringstream ss; - seq_->get_sequence(ss); - sequence = ss.str(); -} - -std::string -DFSRndNumGenerator::get_prefixed_name(const std::string &name) -{ - std::ostringstream ss; - ss << "p_"; - seq_->get_sequence(ss); - ss << seq_->get_sep_char() << name; - return ss.str(); -} - -/* - * Print the tracing information for debugging. - */ -std::string & -DFSRndNumGenerator::trace_depth() -{ - return trace_string_; -} - -unsigned int -DFSRndNumGenerator::rnd_upto(const unsigned int n, const Filter *f, const std::string *where) -{ - int x = random_choice(n, f, where); - assert(x == -1 || (x >= 0 && x < static_cast(n))); - return x; -} - -bool -DFSRndNumGenerator::rnd_flipcoin(const unsigned int n, const Filter *f, const std::string *where) -{ - vector invalid; - int y; - if (n == 100) { - invalid.push_back(0); - y = random_choice(2, f, where, &invalid); - } - else if (n == 0) { - invalid.push_back(1); - y = random_choice(2, f, where, &invalid); - } - else { - y = random_choice(2, f, where); - } - assert(y == -1 || (y >= 0 && y < 2)); - return y; -} - -unsigned long -DFSRndNumGenerator::genrand(void) -{ - return AbsRndNumGenerator::genrand(); -} - -std::string -DFSRndNumGenerator::RandomHexDigits( int num ) -{ - return AbsRndNumGenerator::RandomHexDigits(num); -} - -std::string -DFSRndNumGenerator::RandomDigits( int num ) -{ - return AbsRndNumGenerator::RandomDigits(num); -} - diff --git a/src/DFSRndNumGenerator.h b/src/DFSRndNumGenerator.h deleted file mode 100644 index 23cd85d94..000000000 --- a/src/DFSRndNumGenerator.h +++ /dev/null @@ -1,129 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef DFS_RNDNUM_GENERATOR_H -#define DFS_RNDNUM_GENERATOR_H - -#include -#include - -#include "Common.h" -#include "CommonMacros.h" -#include "AbsRndNumGenerator.h" - -class Sequence; -class Filter; - -class DFSRndNumGenerator : public AbsRndNumGenerator -{ -public: - virtual ~DFSRndNumGenerator(); - - static DFSRndNumGenerator *make_rndnum_generator(); - - virtual std::string get_prefixed_name(const std::string &name); - - virtual std::string& trace_depth(); - - virtual void get_sequence(std::string &sequence); - - virtual unsigned int rnd_upto(const unsigned int n, const Filter *f = NULL, const std::string *where = NULL); - - virtual bool rnd_flipcoin(const unsigned int p, const Filter *f = NULL, const std::string *where = NULL); - - virtual std::string RandomHexDigits( int num ); - - virtual std::string RandomDigits( int num ); - - virtual enum RNDNUM_GENERATOR kind() { return rDFSRndNumGenerator; } - - bool eager_backtracking(int depth_needed); - - int get_decision_depth() { return decision_depth_; } - - void reset_state(void); - - int get_current_pos(void) { return current_pos_; } - - void set_current_pos(int pos) { current_pos_ = pos; } - - bool get_all_done(void) { return all_done_; } - -private: - // Forward declaration of nested class SearchState; - class SearchState; - - // ------------------------------------------------------------------------------------------ - DFSRndNumGenerator(Sequence *concrete_seq); - - int revisit_node(SearchState *state, int local_current_pos, - int bound, const Filter *f, const string *where); - - void initialize_sequence(const std::vector &v); - - void dumpCurrentState(int bound, const std::string &where); - - virtual unsigned long genrand(void); - - bool filter_invalid_nums(vector *invalid_nums, int v); - - int random_choice(int bound, const Filter *f = NULL, const std::string *where = NULL, std::vector *invalid_nums = NULL); - - void init_states(int size); - - void log_depth(int d, const std::string *where = NULL, const char *log = NULL); - - // ---------------------------------------------------------------------------------------- - static DFSRndNumGenerator *impl_; - - //static std::string name_prefix; - - std::string trace_string_; - - // The current decision depth which should be less than SEARCH_STATE_SIZE - // It represents the current depth where we are making random choices - int decision_depth_; - - // The current position at states. - int current_pos_; - - bool all_done_; - - Sequence *seq_; - - bool use_debug_sequence_; - - // Holds the vector representation of all DFS nodes. - std::vector states_; - - // disallow copy and assignment constructors - DISALLOW_COPY_AND_ASSIGN(DFSRndNumGenerator); -}; - -#endif //DFS_RNDNUM_GENERATOR_H diff --git a/src/DeltaMonitor.cpp b/src/DeltaMonitor.cpp deleted file mode 100644 index 34a69b4d1..000000000 --- a/src/DeltaMonitor.cpp +++ /dev/null @@ -1,206 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -#ifdef WIN32 -#pragma warning(disable : 4786) /* Disable annoying warning messages */ -#endif - -#include "DeltaMonitor.h" -#include -#include -#include "SequenceFactory.h" -#include "SimpleDeltaSequence.h" -#include "SimpleDeltaRndNumGenerator.h" -#include "random.h" -#include "RandomNumber.h" - -using namespace std; - -DELTA_TYPE DeltaMonitor::delta_type_ = MAX_DELTA_TYPE; - -std::string DeltaMonitor::output_file_ = ""; - -std::string DeltaMonitor::input_file_ = ""; - -bool DeltaMonitor::is_running_ = false; - -bool DeltaMonitor::is_delta_ = false; - -bool DeltaMonitor::no_delta_reduction_ = false; - -Sequence *DeltaMonitor::seq_ = NULL; - -DeltaMonitor::DeltaMonitor() -{ - -} - -DeltaMonitor::~DeltaMonitor() -{ - -} - -Sequence * -DeltaMonitor::GetSequence() -{ - assert(delta_type_ != MAX_DELTA_TYPE); - - switch (DeltaMonitor::delta_type_) { - case dSimpleDelta: - DeltaMonitor::seq_ = SimpleDeltaSequence::CreateInstance(SimpleDeltaSequence::default_sep_char); - break; - default: - assert("DeltaMonitor GetSequence error" && 0); - break; - } - assert(DeltaMonitor::seq_); - return DeltaMonitor::seq_; -} - -char -DeltaMonitor::GetSepChar() -{ - return SimpleDeltaSequence::default_sep_char; -} - -void -DeltaMonitor::CreateRndNumInstance(const unsigned long seed) -{ - assert(!DeltaMonitor::input_file_.empty()); - switch (DeltaMonitor::delta_type_) { - case dSimpleDelta: - RandomNumber::CreateInstance(rSimpleDeltaRndNumGenerator, seed); - break; - default: - assert("DeltaMonitor CreateRndNumInstance error" && 0); - break; - } -} - -bool -DeltaMonitor::set_delta_type(std::string &msg, const std::string &monitor_type) -{ - if (!monitor_type.compare("simple")) { - DeltaMonitor::delta_type_ = dSimpleDelta; - } - else { - msg = "not supported monitor type!"; - return false; - } - DeltaMonitor::is_running_ = true; - return true; -} - -bool -DeltaMonitor::init(std::string &msg, const std::string &monitor_type, const std::string &o_file) -{ - assert(!monitor_type.empty()); - - if (o_file.empty()) { - msg = "please specify the file for delta output by --delta-output [file]"; - return false; - } - DeltaMonitor::output_file_ = o_file; - - if (!DeltaMonitor::set_delta_type(msg, monitor_type)) { - return false; - } - - return true; -} - -bool -DeltaMonitor::init_for_running(std::string &msg, const std::string &monitor_type, - const std::string &o_file, const std::string &i_file, bool no_delta) -{ - assert(!monitor_type.empty()); - - if (i_file.empty()) { - msg = "please specify the file for delta input by --delta-input [file]"; - return false; - } - if (o_file.empty()) { - DeltaMonitor::output_file_ = i_file; - } - else { - DeltaMonitor::output_file_ = o_file; - } - DeltaMonitor::input_file_ = i_file; - - if (!DeltaMonitor::set_delta_type(msg, monitor_type)) { - return false; - } - - DeltaMonitor::is_delta_ = true; - DeltaMonitor::no_delta_reduction_ = no_delta; - return true; -} - -void -DeltaMonitor::OutputStatistics(ostream &out) -{ - switch (DeltaMonitor::delta_type_) { - case dSimpleDelta: - SimpleDeltaRndNumGenerator::OutputStatistics(out); - break; - default: - assert(0); - break; - } -} - -void -DeltaMonitor::Output(ostream &out) -{ - if (!DeltaMonitor::is_running_) - return; - - if (is_delta_) - DeltaMonitor::OutputStatistics(out); - - assert(!output_file_.empty()); - std::string s; - - get_sequence(s); - ofstream *ofile = new ofstream(output_file_.c_str()); - *ofile << s; - ofile->close(); -} - -const std::string & -DeltaMonitor::get_input() -{ - return DeltaMonitor::input_file_; -} - -const std::string & -DeltaMonitor::get_output() -{ - return DeltaMonitor::output_file_; -} - diff --git a/src/DeltaMonitor.h b/src/DeltaMonitor.h deleted file mode 100644 index 792bc87a4..000000000 --- a/src/DeltaMonitor.h +++ /dev/null @@ -1,94 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef DELTA_MONITOR_H -#define DELTA_MONITOR_H - -#include -#include - -class SequenceFactory; -class Sequence; - -enum DELTA_TYPE { - dSimpleDelta, -}; - -#define MAX_DELTA_TYPE ((DELTA_TYPE) (dSimpleDelta+1)) - -class DeltaMonitor { -public: - static Sequence *GetSequence(); - - static char GetSepChar(); - - static void CreateRndNumInstance(const unsigned long seed); - - static bool is_running() { return is_running_; } - - static bool is_delta() { return is_delta_; } - - static bool no_delta_reduction() { return no_delta_reduction_; } - - static bool init(std::string &msg, const std::string &monitor_type, const std::string &o_file); - - static bool init_for_running(std::string &msg, const std::string &monitor_type, - const std::string &o_file, const std::string &i_file, bool no_delta); - - static bool set_delta_type(std::string &msg, const std::string &monitor_type); - - static void Output(std::ostream &out); - - static const std::string &get_input(); - - static const std::string &get_output(); - -private: - DeltaMonitor(); - - ~DeltaMonitor(); - - static void OutputStatistics(std::ostream &out); - - static DELTA_TYPE delta_type_; - - static std::string output_file_; - - static std::string input_file_; - - static bool is_running_; - - static bool is_delta_; - - static bool no_delta_reduction_; - - static Sequence *seq_; -}; - -#endif diff --git a/src/DepthSpec.cpp b/src/DepthSpec.cpp deleted file mode 100644 index 35f0cdce6..000000000 --- a/src/DepthSpec.cpp +++ /dev/null @@ -1,482 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#include "DepthSpec.h" - -#include -#include -#include -#include - -#include "CGOptions.h" -#include "DFSRndNumGenerator.h" -#include "Statement.h" -#include "RandomNumber.h" -#include "SafeOpFlags.h" -#include "VariableSelector.h" -#include "Expression.h" - -using namespace std; - -// Atomic default values -const int DepthSpec::dtVariableSelection_minimal_depth_ = 1; - -const int DepthSpec::dtLoopControl_minimal_depth_ = 3; - -const int DepthSpec::dtTypeNonVoidSimple_minimal_depth_ = 1; - -const int DepthSpec::dtTypeChooseRandom_minimal_depth_ = 1; - -const int DepthSpec::dtChooseRandomPointerType_minimal_depth_ = 1; - -const int DepthSpec::dtConstant_minimal_depth_ = 0; - -const int DepthSpec::dtInitVariable_minimal_depth_ = 1; - -#define DEFINE_DEFAULT_GETTER(type) \ - int \ - DepthSpec::type##_minimal_depth(int) { return type##_minimal_depth_; } \ - -// Don't define a default one if you define your own! -DEFINE_DEFAULT_GETTER(dtLoopControl) -DEFINE_DEFAULT_GETTER(dtTypeNonVoidSimple) -DEFINE_DEFAULT_GETTER(dtTypeChooseRandom) -DEFINE_DEFAULT_GETTER(dtChooseRandomPointerType) -DEFINE_DEFAULT_GETTER(dtVariableSelection) -DEFINE_DEFAULT_GETTER(dtConstant) -DEFINE_DEFAULT_GETTER(dtInitVariable) - -// non-default depth - -#if 0 -int DepthSpec::dtFunction_minimal_depth(int flag) -{ - return flag ? dtFunction_minimal_depth_() : - (dtFunction_minimal_depth_() + dtReturnType_minimal_depth()); -} -#endif - -int DepthSpec::dtFunction_minimal_depth_(int) -{ - return dtGenerateParamList_minimal_depth() + dtFunctionGenerateBody_minimal_depth(); -} - -int DepthSpec::dtFunction_minimal_depth(int) -{ - return dtFunction_minimal_depth_(); -} - -int DepthSpec::dtFirstFunction_minimal_depth(int) -{ - return dtReturnType_minimal_depth() + dtFunctionGenerateBody_minimal_depth(); -} - -int DepthSpec::dtStatement_minimal_depth_(int) -{ -/* - vector vs; - vs.push_back(dtStatementAssign_minimal_depth()); - vs.push_back(dtStatementFor_minimal_depth()); - vs.push_back(dtStatementIf_minimal_depth()); - vs.push_back(dtStatementExpr_minimal_depth()); - vs.push_back(dtStatementReturn_minimal_depth()); - - return *max_element(vs.begin(), vs.end()); -*/ - return dtStatementReturn_minimal_depth() + 1; -} - -int DepthSpec::dtBlock_minimal_depth(int) -{ - return dtStatement_minimal_depth_() + 1; -} - -int DepthSpec::dtStatement_minimal_depth(int flag) -{ - return (flag == MAX_STATEMENT_TYPE) ? (dtStatement_minimal_depth_() + 1) : dtStatement_minimal_depth_(); -} - -int DepthSpec::dtStatementAssign_minimal_depth(int) -{ - int extra = 0; - if (CGOptions::compound_assignment()) - extra = 1; - return dtSelectLValue_minimal_depth() + dtExpression_minimal_depth() + - dtLhs_minimal_depth() + dtSafeOpFlags_minimal_depth() + extra; -} - -int DepthSpec::dtStatementFor_minimal_depth(int) -{ - return (dtSelectLValue_minimal_depth() - + dtLoopControl_minimal_depth() - + dtSafeOpFlags_minimal_depth() - + dtFunctionInvocationBinary_minimal_depth() - + dtSafeOpFlags_minimal_depth() - + ATOMIC_DEPTH_INCR - + dtBlock_minimal_depth()); -} - -int DepthSpec::dtStatementIf_minimal_depth(int) -{ - return (dtExpression_minimal_depth() + 2 * dtBlock_minimal_depth()); -} - -int DepthSpec::dtStatementExpr_minimal_depth(int) -{ - return dtFunctionInvocationRandom_minimal_depth(); -} - -int DepthSpec::dtStatementReturn_minimal_depth(int) -{ - return dtExpressionVariable_minimal_depth(); -} - -int DepthSpec::dtFunctionInvocationUnary_minimal_depth(int) -{ - return dtSafeOpFlags_minimal_depth(); -} - -int DepthSpec::dtFunctionInvocationBinary_minimal_depth(int) -{ - return dtSafeOpFlags_minimal_depth(); -} - -int DepthSpec::dtFunctionInvocationRandomUnary_minimal_depth(int) -{ - return ATOMIC_DEPTH_INCR + dtSafeOpFlags_minimal_depth() - + dtExpression_minimal_depth(); -} - -int DepthSpec::dtFunctionInvocationRandomRegularBinary_minimal_depth(int) -{ - return ATOMIC_DEPTH_INCR + dtSafeOpFlags_minimal_depth() - + 2 * + dtExpression_minimal_depth(); -} - -int DepthSpec::dtFunctionInvocationRandomBinaryPointer_minimal_depth(int) -{ - return 1 + dtSafeOpFlags_minimal_depth() + - dtChooseRandomPointerType_minimal_depth() + - 2 * dtExpression_minimal_depth(); - -} - -int DepthSpec::dtFunctionInvocationRandomBinary_minimal_depth(int) -{ - vector vs; - vs.push_back(dtFunctionInvocationRandomRegularBinary_minimal_depth()); - vs.push_back(dtFunctionInvocationRandomBinaryPointer_minimal_depth()); - return 1 + *min_element(vs.begin(), vs.end()); -} - -int DepthSpec::dtFunctionUserBuildInvocation_minimal_depth(int flag) -{ - return dtExpressionRandomParam_minimal_depth(flag); -} - -int DepthSpec::dtFunctionInvocationStdFunc_minimal_depth(int) -{ - vector vs; - vs.push_back(dtFunctionInvocationRandomUnary_minimal_depth()); - vs.push_back(dtFunctionInvocationRandomBinary_minimal_depth()); - - return *min_element(vs.begin(), vs.end()) + 1; -} - -int DepthSpec::dtFunctionInvocationRandom_minimal_depth(int) -{ - vector vs; - vs.push_back(dtFunctionInvocationRandomUnary_minimal_depth()); - vs.push_back(dtFunctionInvocationRandomBinary_minimal_depth()); - vs.push_back(dtFunctionUserBuildInvocation_minimal_depth()); - - return *min_element(vs.begin(), vs.end()); -} - -int DepthSpec::dtExpressionRandomParam_minimal_depth(int flag) -{ - int rv = dtConstant_minimal_depth(flag); - return (flag == MAX_TERM_TYPES) ? (rv + 1) : rv; -} - -int DepthSpec::dtExpression_minimal_depth(int flag) -{ - int rv = dtConstant_minimal_depth(flag); - return (flag == MAX_TERM_TYPES) ? (rv + 1) : rv; - //vector vs; - //vs.push_back(dtConstant_minimal_depth()); - //vs.push_back(dtExpressionVariable_minimal_depth()); - //vs.push_back(dtExpressionFuncall_minimal_depth()); - - //return (*max_element(vs.begin(), vs.end()) + 1); -} - -int DepthSpec::dtExpressionVariable_minimal_depth(int) -{ - return dtSelectVariable_minimal_depth(); -} - -int DepthSpec::dtExpressionFuncall_minimal_depth(int) -{ - return dtFunctionInvocationRandom_minimal_depth(); -} - -int DepthSpec::dtLhs_minimal_depth(int) -{ - return 1; -} - -int DepthSpec::dtReturnType_minimal_depth(int) -{ - return dtTypeChooseRandom_minimal_depth(); -} - -int DepthSpec::dtRandomTypeFromType_minimal_depth(int) -{ - return dtTypeChooseRandom_minimal_depth(); -} - -int DepthSpec::dtFunctionGenerateBody_minimal_depth(int) -{ - return dtBlock_minimal_depth(); -} - -int DepthSpec::dtGenerateParamList_minimal_depth(int) -{ - return ATOMIC_DEPTH_INCR + dtSelectVariable_minimal_depth(); -} - -int DepthSpec::dtTypeChooseSimple_minimal_depth(int flag) -{ - return dtTypeNonVoidSimple_minimal_depth(flag); -} - -int DepthSpec::dtSelectLValue_minimal_depth(int flag) -{ - return dtSelectVariable_minimal_depth(flag); -} - -int DepthSpec::dtSelectVariable_minimal_depth(int flag) -{ - return (flag == MAX_VAR_SCOPE) ? dtVariableSelection_minimal_depth(flag) + 1 : - dtVariableSelection_minimal_depth(flag); -} - -int DepthSpec::dtSelectDerefPointer_minimal_depth(int) -{ - return 0; -} - -int DepthSpec::dtSelectExistingVariable_minimal_depth(int flag) -{ - return dtVariableSelection_minimal_depth(flag); -} - -int dtGenerateNewGlobal_minimal_depth_(int flag) -{ - - return DepthSpec::dtInitVariable_minimal_depth(flag); -} - -int DepthSpec::dtSelectGlobal_minimal_depth(int flag) -{ - return dtInitVariable_minimal_depth(flag) + dtGenerateNewGlobal_minimal_depth_(flag); -} - -int DepthSpec::dtGenerateNewGlobal_minimal_depth(int flag) -{ - - return 1 + dtGenerateNewGlobal_minimal_depth_(flag); -} - -int DepthSpec::dtSelectParentLocal_minimal_depth(int flag) -{ - return 1 + dtRandomTypeFromType_minimal_depth(flag); -} - -int dtGenerateNewParentLocal_minimal_depth_(int flag) -{ - return DepthSpec::dtInitVariable_minimal_depth(flag); -} - -int DepthSpec::dtGenerateNewParentLocal_minimal_depth(int flag) -{ - return 2 + dtGenerateNewParentLocal_minimal_depth_(flag); -} - -int DepthSpec::dtGenerateNewVariable_minimal_depth(int) -{ - int depth = dtGenerateNewParentLocal_minimal_depth() <= dtGenerateNewGlobal_minimal_depth() - ? dtGenerateNewParentLocal_minimal_depth() : dtGenerateNewGlobal_minimal_depth(); - return depth + 1; -} - -int DepthSpec::dtInitPointerValue_minimal_depth(int) -{ - int depth = dtGenerateNewParentLocal_minimal_depth() <= dtGenerateNewGlobal_minimal_depth() - ? dtGenerateNewParentLocal_minimal_depth() : dtGenerateNewGlobal_minimal_depth(); - return dtRandomTypeFromType_minimal_depth() + depth; -} - -int -DepthSpec::dtSafeOpFlags_minimal_depth(int flag) -{ - return (flag == sOpBinary) ? 2 : 3; -} - -//cout << "max_depth = " << max_depth << ", cur_depth = " << cur_depth << ", minimal = " << type##_minimal_depth(flag) << std::endl; -#define DEPTH_GUARD_CASE(type, flag) case type: \ - { \ - assert(CGOptions::dfs_exhaustive()); \ - int depth_needed = type##_minimal_depth(flag); \ - return DepthSpec::backtracking(depth_needed); \ - } - -int -DepthSpec::backtracking(int depth_needed) -{ - DFSRndNumGenerator *impl = dynamic_cast(RandomNumber::GetRndNumGenerator()); - if(impl->eager_backtracking(depth_needed)) - return BAD_DEPTH; - else - return GOOD_DEPTH; -} - -int -DepthSpec::depth_guard_by_depth(int depth_needed) -{ - if (!CGOptions::dfs_exhaustive()) { - return GOOD_DEPTH; - } - return DepthSpec::backtracking(depth_needed); -} - -int DepthSpec::depth_guard_by_type(enum dType ty, int extra_flag) -{ - if (!CGOptions::dfs_exhaustive()) { - return GOOD_DEPTH; - } - - switch (ty) { - DEPTH_GUARD_CASE(dtFunction, extra_flag) - DEPTH_GUARD_CASE(dtFirstFunction, extra_flag) - DEPTH_GUARD_CASE(dtBlock, extra_flag) - DEPTH_GUARD_CASE(dtStatement, extra_flag) - DEPTH_GUARD_CASE(dtStatementAssign, extra_flag) - DEPTH_GUARD_CASE(dtStatementFor, extra_flag) - DEPTH_GUARD_CASE(dtStatementIf, extra_flag) - DEPTH_GUARD_CASE(dtStatementExpr, extra_flag) - DEPTH_GUARD_CASE(dtStatementReturn, extra_flag) - DEPTH_GUARD_CASE(dtFunctionInvocationUnary, extra_flag) - DEPTH_GUARD_CASE(dtFunctionInvocationBinary, extra_flag) - DEPTH_GUARD_CASE(dtFunctionInvocationRandomUnary, extra_flag) - DEPTH_GUARD_CASE(dtFunctionInvocationRandomBinary, extra_flag) - DEPTH_GUARD_CASE(dtFunctionInvocationRandom, extra_flag) - DEPTH_GUARD_CASE(dtFunctionInvocationStdFunc, extra_flag) - DEPTH_GUARD_CASE(dtFunctionUserBuildInvocation, extra_flag) - DEPTH_GUARD_CASE(dtExpression, extra_flag) - DEPTH_GUARD_CASE(dtExpressionRandomParam, extra_flag) - DEPTH_GUARD_CASE(dtExpressionVariable, extra_flag) - DEPTH_GUARD_CASE(dtExpressionFuncall, extra_flag) - DEPTH_GUARD_CASE(dtLhs, extra_flag) - DEPTH_GUARD_CASE(dtReturnType, extra_flag) - DEPTH_GUARD_CASE(dtRandomTypeFromType, extra_flag) - DEPTH_GUARD_CASE(dtFunctionGenerateBody, extra_flag) - DEPTH_GUARD_CASE(dtGenerateParamList, extra_flag) - DEPTH_GUARD_CASE(dtTypeChooseSimple, extra_flag) - DEPTH_GUARD_CASE(dtSelectLValue, extra_flag) - DEPTH_GUARD_CASE(dtSelectVariable, extra_flag) - DEPTH_GUARD_CASE(dtSelectDerefPointer, extra_flag) - DEPTH_GUARD_CASE(dtSelectExistingVariable, extra_flag) - DEPTH_GUARD_CASE(dtInitVariable, extra_flag) - DEPTH_GUARD_CASE(dtSelectGlobal, extra_flag) - DEPTH_GUARD_CASE(dtGenerateNewGlobal, extra_flag) - DEPTH_GUARD_CASE(dtSelectParentLocal, extra_flag) - DEPTH_GUARD_CASE(dtGenerateNewParentLocal, extra_flag) - DEPTH_GUARD_CASE(dtGenerateNewVariable, extra_flag) - DEPTH_GUARD_CASE(dtInitPointerValue, extra_flag) - DEPTH_GUARD_CASE(dtSafeOpFlags, extra_flag) - default: - assert(0); - break; - } - - return GOOD_DEPTH; -} - -#define PRTDEPTH(type) \ - cout << #type << " : size = " << type##_minimal_depth() << endl; - -void DepthSpec::depth_print() -{ - PRTDEPTH(dtSafeOpFlags); - PRTDEPTH(dtLoopControl); - PRTDEPTH(dtTypeNonVoidSimple); - PRTDEPTH(dtTypeChooseRandom); - PRTDEPTH(dtChooseRandomPointerType); - PRTDEPTH(dtVariableSelection); - PRTDEPTH(dtConstant); - - PRTDEPTH(dtFirstFunction) - PRTDEPTH(dtFunction) - PRTDEPTH(dtBlock) - PRTDEPTH(dtStatement) - PRTDEPTH(dtStatementAssign) - PRTDEPTH(dtStatementFor) - PRTDEPTH(dtStatementIf) - PRTDEPTH(dtStatementExpr) - PRTDEPTH(dtStatementReturn) - PRTDEPTH(dtFunctionInvocationUnary) - PRTDEPTH(dtFunctionInvocationBinary) - PRTDEPTH(dtFunctionInvocationRandomUnary) - PRTDEPTH(dtFunctionInvocationRandomBinary) - PRTDEPTH(dtFunctionInvocationRandom) - PRTDEPTH(dtFunctionInvocationStdFunc) - PRTDEPTH(dtFunctionUserBuildInvocation) - PRTDEPTH(dtExpression) - PRTDEPTH(dtExpressionRandomParam) - PRTDEPTH(dtExpressionVariable) - PRTDEPTH(dtExpressionFuncall) - PRTDEPTH(dtLhs) - PRTDEPTH(dtReturnType) - PRTDEPTH(dtRandomTypeFromType) - PRTDEPTH(dtFunctionGenerateBody) - PRTDEPTH(dtGenerateParamList) - PRTDEPTH(dtTypeChooseSimple) - PRTDEPTH(dtSelectLValue) - PRTDEPTH(dtSelectDerefPointer) - PRTDEPTH(dtSelectExistingVariable) - PRTDEPTH(dtInitVariable) - PRTDEPTH(dtGenerateNewGlobal) - PRTDEPTH(dtSelectGlobal) - PRTDEPTH(dtGenerateNewParentLocal) - PRTDEPTH(dtSelectParentLocal) - PRTDEPTH(dtGenerateNewVariable) - PRTDEPTH(dtInitPointerValue) -} diff --git a/src/DepthSpec.h b/src/DepthSpec.h deleted file mode 100644 index 8c0dc5488..000000000 --- a/src/DepthSpec.h +++ /dev/null @@ -1,209 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef DEPTH_SPEC_H -#define DEPTH_SPEC_H - -// Specify depth for each term -// They are all under change - -#define ATOMIC_DEPTH_INCR 1 - -#define GOOD_DEPTH 0 -#define BAD_DEPTH -1 - -enum dType { - dtFirstFunction, - dtFunction, - dtBlock, - dtStatement, - dtStatementAssign, - dtStatementFor, - dtStatementIf, - dtStatementExpr, - dtStatementReturn, - dtFunctionInvocationUnary, - dtFunctionInvocationBinary, - dtFunctionInvocationRandomUnary, - dtFunctionInvocationRandomRegularBinary, - dtFunctionInvocationRandomBinaryPointer, - dtFunctionInvocationRandomBinary, - dtFunctionInvocationRandom, - dtFunctionInvocationStdFunc, - dtFunctionUserBuildInvocation, - dtExpression, - dtExpressionRandomParam, - dtExpressionFuncall, - dtExpressionVariable, - dtLhs, - dtReturnType, - dtRandomTypeFromType, - dtFunctionGenerateBody, - dtGenerateParamList, - dtTypeChooseSimple, - dtSelectLValue, - dtSelectVariable, - dtSelectDerefPointer, - dtSelectExistingVariable, - dtInitVariable, - dtSelectGlobal, - dtGenerateNewGlobal, - dtSelectParentLocal, - dtGenerateNewParentLocal, - dtGenerateNewVariable, - dtInitPointerValue, - dtSafeOpFlags, -}; - -#define DEPTH_GUARD_BY_DEPTH_NORETURN(d) \ - if (DepthSpec::depth_guard_by_depth(d) != GOOD_DEPTH) \ - return; - -#define DEPTH_GUARD_BY_DEPTH_RETURN(d, rv) \ - if (DepthSpec::depth_guard_by_depth(d) != GOOD_DEPTH) \ - return rv; - -#define DEPTH_GUARD_BY_DEPTH_RETURN_DEL1(d, t1, rv) \ - if (DepthSpec::depth_guard_by_depth(d) != GOOD_DEPTH) { \ - if (t1) delete t1; \ - return rv; \ - } - -#define DEPTH_GUARD_BY_DEPTH_RETURN_DEL2(d, t1, t2, rv) \ - if (DepthSpec::depth_guard_by_depth(d) != GOOD_DEPTH) { \ - if (t1) delete t1; \ - if (t2) delete t2; \ - return rv; \ - } - -#define DPETH_GUARD_BY_TYPE_NORETURN(t) \ - if (DepthSpec::depth_guard_by_type(t) != GOOD_DEPTH) \ - return; - -#define DPETH_GUARD_BY_TYPE_NORETURN_WITH_FLAG(t, flag) \ - if (DepthSpec::depth_guard_by_type(t, flag) != GOOD_DEPTH) \ - return; - -#define DEPTH_GUARD_BY_TYPE_RETURN(t, rv) \ - if (DepthSpec::depth_guard_by_type(t) != GOOD_DEPTH) \ - return rv; - -#define DEPTH_GUARD_BY_TYPE_RETURN_WITH_FLAG(t, flag, rv) \ - if (DepthSpec::depth_guard_by_type(t, flag) != GOOD_DEPTH) \ - return rv; - -#define GETTER_DECL(type) \ - static int \ - type##_minimal_depth(int flag = -1); - -class DepthSpec -{ -public: - static int depth_guard_by_type(enum dType ty, int extra_flag = 0); - - static int depth_guard_by_depth(int depth_needed); - - static void depth_print(); - -//private: - - const static int dtVariableSelection_minimal_depth_; - - const static int dtLoopControl_minimal_depth_; - - const static int dtTypeNonVoidSimple_minimal_depth_; - - const static int dtTypeChooseRandom_minimal_depth_; - - const static int dtChooseRandomPointerType_minimal_depth_; - - const static int dtConstant_minimal_depth_; - - const static int dtInitVariable_minimal_depth_; - - static int dtFunction_minimal_depth_(int flag = 0); - static int dtStatement_minimal_depth_(int flag = 0); - - GETTER_DECL(dtLoopControl) - GETTER_DECL(dtTypeNonVoidSimple) - GETTER_DECL(dtTypeChooseRandom) - GETTER_DECL(dtChooseRandomPointerType) - GETTER_DECL(dtVariableSelection) - GETTER_DECL(dtConstant) - GETTER_DECL(dtInitVariable) - - GETTER_DECL(dtFirstFunction) - GETTER_DECL(dtFunction) - GETTER_DECL(dtBlock) - GETTER_DECL(dtStatement) - GETTER_DECL(dtStatementAssign) - GETTER_DECL(dtStatementFor) - GETTER_DECL(dtStatementIf) - GETTER_DECL(dtStatementExpr) - GETTER_DECL(dtStatementReturn) - GETTER_DECL(dtFunctionInvocationUnary) - GETTER_DECL(dtFunctionInvocationBinary) - GETTER_DECL(dtFunctionInvocationRandomUnary) - GETTER_DECL(dtFunctionInvocationRandomRegularBinary) - GETTER_DECL(dtFunctionInvocationRandomBinaryPointer) - GETTER_DECL(dtFunctionInvocationRandomBinary) - GETTER_DECL(dtFunctionInvocationRandom) - GETTER_DECL(dtFunctionInvocationStdFunc) - GETTER_DECL(dtFunctionUserBuildInvocation) - GETTER_DECL(dtExpression) - GETTER_DECL(dtExpressionRandomParam) - GETTER_DECL(dtExpressionVariable) - GETTER_DECL(dtExpressionFuncall) - GETTER_DECL(dtLhs) - GETTER_DECL(dtReturnType) - GETTER_DECL(dtRandomTypeFromType) - GETTER_DECL(dtFunctionGenerateBody) - GETTER_DECL(dtGenerateParamList) - GETTER_DECL(dtTypeChooseSimple) - GETTER_DECL(dtSelectLValue) - GETTER_DECL(dtSelectVariable) - GETTER_DECL(dtSelectDerefPointer) - GETTER_DECL(dtSelectExistingVariable) - GETTER_DECL(dtSelectGlobal) - GETTER_DECL(dtGenerateNewGlobal) - GETTER_DECL(dtSelectParentLocal) - GETTER_DECL(dtGenerateNewParentLocal) - GETTER_DECL(dtGenerateNewVariable) - GETTER_DECL(dtInitPointerValue) - GETTER_DECL(dtSafeOpFlags) - -private: - DepthSpec() {} - - ~DepthSpec() {} - - static int backtracking(int depth_needed); -}; - -#endif //DEPTH_SPEC_H diff --git a/src/Error.cpp b/src/Error.cpp deleted file mode 100644 index e99a727f5..000000000 --- a/src/Error.cpp +++ /dev/null @@ -1,43 +0,0 @@ - -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#include "Error.h" - -int Error::r_error_ = SUCCESS; - -Error::Error() -{ - -} - -Error::~Error() -{ - -} diff --git a/src/Error.h b/src/Error.h deleted file mode 100644 index 99a31ce9f..000000000 --- a/src/Error.h +++ /dev/null @@ -1,98 +0,0 @@ - -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef ERROR_H -#define ERROR_H - -#include "CommonMacros.h" - -#define SUCCESS 0 -#define ERROR -1 -#define EXCEED_MAX_DEPTH_ERROR -2 -#define FILTER_ERROR -3 -#define BACKTRACKING_ERROR -4 -#define COMPATIBLE_CHECK_ERROR -5 -#define INVALID_SIMPLE_DELTA_SEQUENCE -6 - -#define ERROR_RETURN() \ - if (Error::get_error() != SUCCESS) \ - return;\ - -#define ERROR_GUARD(rv) \ - if (Error::get_error() != SUCCESS) \ - return rv; \ - -#define ERROR_GUARD_AND_DEL1(rv, p) \ - if (Error::get_error() != SUCCESS) {\ - delete p; \ - return rv; \ - } \ - -#define ERROR_GUARD_AND_DEL2(rv, p1, p2) \ - if (Error::get_error() != SUCCESS) {\ - delete p1; \ - delete p2; \ - return rv; \ - } \ - -#define ERROR_GUARD_AND_DEL3(rv, p1, p2, p3) \ - if (Error::get_error() != SUCCESS) {\ - delete p1; \ - delete p2; \ - delete p3; \ - return rv; \ - } \ - -#define ERROR_GUARD_AND_DEL4(rv, p1, p2, p3, p4) \ - if (Error::get_error() != SUCCESS) {\ - delete p1; \ - delete p2; \ - delete p3; \ - delete p4; \ - return rv; \ - } \ - - -#define PRT_ERROR(msg) \ - cout << "error: " << msg << ", errorno: " << Error::get_error() << std::endl; \ - -class Error { -public: - static int get_error() { return Error::r_error_; } - static void set_error(int error) { Error::r_error_ = error; } -private: - Error(); - ~Error(); - static int r_error_; - - DISALLOW_COPY_AND_ASSIGN(Error); -}; - -#endif // ERROR_H diff --git a/src/OutputMgr.cpp b/src/OutputMgr.cpp index 6a13214c1..ac8b09bf3 100644 --- a/src/OutputMgr.cpp +++ b/src/OutputMgr.cpp @@ -44,7 +44,7 @@ #include "ArrayVariable.h" #include "random.h" #include "util.h" -#define PACKAGE_STRING "csmith 3.0.0" +//#define PACKAGE_STRING "csmith 3.0.0" const char *OutputMgr::hash_func_name = "csmith_compute_hash"; diff --git a/src/RandomProgramGenerator.cpp b/src/RandomProgramGenerator.cpp index cea32eadf..9c626d7d5 100644 --- a/src/RandomProgramGenerator.cpp +++ b/src/RandomProgramGenerator.cpp @@ -93,7 +93,7 @@ Random C/C++ Program Generator using namespace std; -#define PACKAGE_STRING "csmith 3.0.0" +//#define PACKAGE_STRING "csmith 3.0.0" /////////////////////////////////////////////////////////////////////////////// // ---------------------------------------------------------------------------- diff --git a/src/Reducer.cpp b/src/Reducer.cpp deleted file mode 100644 index ef0743c19..000000000 --- a/src/Reducer.cpp +++ /dev/null @@ -1,1414 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifdef WIN32 -#pragma warning(disable : 4786) /* Disable annoying warning messages */ -#endif - -#include "Reducer.h" -#include -#include -#include -#include -#include "StringUtils.h" -#include "Function.h" -#include "FunctionInvocationUser.h" -#include "FunctionInvocationBinary.h" -#include "Block.h" -#include "Statement.h" -#include "StatementExpr.h" -#include "StatementIf.h" -#include "StatementFor.h" -#include "StatementGoto.h" -#include "StatementArrayOp.h" -#include "StatementReturn.h" -#include "Lhs.h" -#include "Variable.h" -#include "VariableSelector.h" -#include "ArrayVariable.h" -#include "Expression.h" -#include "ExpressionVariable.h" -#include "ExpressionFuncall.h" -#include "ExpressionAssign.h" -#include "ExpressionComma.h" -#include "Lhs.h" -#include "Constant.h" -#include "CVQualifiers.h" -#include "FactMgr.h" - -Reducer::Reducer(string fname) -: dump_block_entry(false), - dump_all_block_info(false), - dump_monitored_var(false), - dump_dropped_params(false), - drop_params(false), - rewrite_calls_inside(NULL), - reduce_binaries(false), - output_if_ids(false), - monitored_var(NULL), - monitored_func(NULL), - monitored_call_id(""), - dump_stms_in_blocks(NULL), - configured(false), - fname_(fname) -{ - // nothing else to do -} - -Reducer::~Reducer(void) -{ -} - -void -Reducer::configure(void) -{ - ifstream conf(fname_.c_str()); - std::string line; - // default: use the first function as mian - main = GetFirstFunction(); - while(!conf.eof()) { - getline(conf, line); - if (StringUtils::empty_line(line)) - continue; - if (dump_dropped_params) { - // if "dropped parameters" is not the last setting, means we are done with parameter dropping - dump_dropped_params = false; - } - // find the variable that caused diff. checksums - if (line.find("focus variable") == 0) { - getline(conf, line); - StringUtils::chop(line); - // make sure the focus var is marked as used var - const Variable* key = VariableSelector::find_var_by_name(line); - if (key == NULL) { - // it's possible an array variable that is not specifically itemized in the - // program that is the focus var. we manually itemize it here - vector strs; - StringUtils::split_string(line, strs, "[]"); - const Variable* ary = VariableSelector::find_var_by_name(strs[0]); - assert(ary && ary->isArray); - const ArrayVariable* av = (const ArrayVariable*)ary; - vector indices; - for (size_t k=0; kget_dimension(); k++) { - assert(k + 1 < strs.size()); - indices.push_back(StringUtils::str2int(strs[k+1])); - } - av->itemize(indices); - } - key = VariableSelector::find_var_by_name(line); - assert(key); - monitored_var = key; - used_vars.push_back(key->get_named_var()); - } - // find the line that crashed a compiler - else if (line.find("crc lines") == 0) { - getline(conf, line); - StringUtils::chop(line); - // find the global variables in CRC statements, and mark them as used - vector strs; - StringUtils::split_string(line, strs, "(),[."); - for (size_t i=0; i vnames; - StringUtils::split_string(line, vnames, ", "); - for (size_t i=0; i::const_iterator iter; - for(iter = map_active_blks.begin(); iter != map_active_blks.end(); ++iter) { - const Block* b = iter->first; - for (j=0; jstms.size(); j++) { - if (b->stms[j]->stm_id == stm_id) { - return b->stms[j]; - } - } - } - return NULL; -} - -bool -Reducer::is_ptr_written_in_stm(const Statement* stm) -{ - size_t i; - FactMgr* fm = get_fact_mgr_for_func(stm->func); - const vector& write_vars = fm->map_stm_effect[stm].get_write_vars(); - for (i=0; iis_pointer()) { - const Block* blk = (stm->eType == eBlock) ? (const Block*)stm : stm->parent; - if (wvar->is_visible(blk) && is_var_used(wvar)) { - return true; - } - } - } - return false; -} - -bool -Reducer::is_exp_replaced(const Expression* e) -{ - if (e->term_type == eVariable || e->term_type == eLhs) { - return map_reduced_vars.find(e) != map_reduced_vars.end(); - } - if (e->term_type == eFunction) { - const FunctionInvocation* fi = e->get_invoke(); - assert(fi); - return map_reduced_invocations.find(fi) != map_reduced_invocations.end(); - } - return false; -} - -bool -Reducer::is_var_init_reduced(const Variable* v) -{ - return map_reduced_var_inits.find(v) != map_reduced_var_inits.end(); -} - -bool -Reducer::is_label_used(const string l) -{ - if (l == "") return false; - return std::find(used_labels.begin(), used_labels.end(), l) != used_labels.end(); -} - -string -Reducer::find_jump_label(const Statement* stm) -{ - string label = stm->find_jump_label(); - return (is_label_used(label)) ? label : ""; -} - -int -Reducer::find_required_labels(const Statement* stm, vector& labels) -{ - string label = find_jump_label(stm); - if (label != "") { - labels.push_back(label); - } - - vector blks; - size_t i, j; - stm->get_blocks(blks); - for (i=0; istms.size(); j++) { - const Statement* s = blks[i]->stms[j]; - find_required_labels(s, labels); - } - } - } - return labels.size(); -} - -int -Reducer::find_missing_labels(const Statement* stm, const Statement* alt_stm, vector& labels) -{ - labels.clear(); - vector labels1, labels2; - stm->find_contained_labels(labels1); - if (alt_stm) { - alt_stm->find_contained_labels(labels2); - } - size_t i; - for (i=0; i& work_blks, vector& work_funcs, std::ostream& out) -{ - size_t i, j; - vector blks; - vector funcalls; - vector uniq_funcs; - out << "****** block: " << blk->stm_id << " ******" << endl; - for (i=0; istms.size(); i++) { - const Statement* stm = blk->stms[i]; - funcalls.clear(); - uniq_funcs.clear(); - stm->get_called_funcs(funcalls); - stm->get_blocks(blks); - out << stm->stm_id; - if (funcalls.size() > 0) { - // find the unique functions that was called - for (j=0; jget_func(); - if (find_function_in_set(uniq_funcs, f) == -1) { - uniq_funcs.push_back(f); - } - } - // print the unique functions, add them to work list if necessary - out << "("; - for (j=0; j 0) { - out << ", "; - } - const Function* f = uniq_funcs[j]; - if (find_function_in_set(work_funcs, f) == -1) { - work_funcs.push_back(f); - } - out << f->name; - } - out << ")"; - } - if (blks.size() > 0) { - out << "{"; - for (j=0; j 0) { - out << ", "; - } - work_blks.push_back(blks[j]); - out << blks[j]->stm_id; - } - out << "}"; - } - out << endl; - } -} - -bool -Reducer::is_blk_deleted(const Block* b) const -{ - // if active_blks is not initialized, we assume all functions are to be kept - if (map_active_blks.size() == 0) return false; - return map_active_blks.find(b) == map_active_blks.end(); -} - -bool -Reducer::is_stm_deleted(const Statement* stm) const -{ - const Statement* s = stm; - while (s && replaced_stms.find(s) == replaced_stms.end() && !is_blk_deleted(s->parent)) { - s = s->find_container_stm(); - } - // s = NULL means the statement is not reduced - return !(s == NULL); -} - -bool -Reducer::is_param_dropped(const Function* f, int i) -{ - // assume all parameters are not dropped during configuration - if (!drop_params || !configured) return false; - return !is_var_used(f->param[i]); -} - -void -Reducer::replace_stm(const Statement* stm, const Statement* new_stm, string pre_stm) -{ - replaced_stms[stm] = new_stm; - if (!pre_stm.empty()) { - map_pre_stm_assigns[stm] = pre_stm; - map_str_effects[pre_stm] = find_used_vars(pre_stm); - } -} - -void -Reducer::delete_stms_after(const Statement* stm, bool include_parent_blks) -{ - const Block* parent = stm->parent; - size_t i, j; - bool begin_delete = false; - const Statement* return_stm = stm->func->body->get_last_stm(); - assert(return_stm); - for (i=0; istms.size(); i++) { - const Statement* s = parent->stms[i]; - vector labels; - - if (begin_delete) { - if (find_required_labels(s, labels)==0 && s != return_stm) { - // don't delete statements that contains add-back blocks (those has 0 count in map_active_blks) - vector blks; - s->get_blocks(blks); - bool must_dump = false; - for (j=0; jfind_container_stm(); - if (s) { - delete_stms_after(s, include_parent_blks); - } - } -} - -// find local variables that have to be lifted to global, most likely because -// they are used via pointer in a callee function at the bottom of a call chain -int -Reducer::find_local_vars_to_lift(vector& vars) -{ - size_t i; - vars.clear(); - if (monitored_func) { - for (i=0; ifeffect.is_read(v) || monitored_func->feffect.is_written(v)) { - // if there is a variable that is read by the function externally, - // but is neither a global or a parameter, this must be a local variable - // of one of the functions in the call chain - - // Note this can not handle parameters not belong to monitored function, - // so taking address of parameters and passing into a function call is forbidden - // see ExpressionVariable::make_random - if (!v->is_global() && !v->is_argument()) { - vars.push_back(v); - break; - } - } - } - } - return vars.size(); -} - -void -Reducer::expand_used_vars(void) -{ - size_t i, j; - for (i=0; i init_values; - if (v->isArray) { - const ArrayVariable* av = dynamic_cast(v); - init_values = av->get_init_values(); - } - init_values.push_back(v->init); - - for (j=0; jterm_type == eVariable) { - const ExpressionVariable* ev = (const ExpressionVariable*)(init); - if (ev->get_indirect_level() < 0) { - string dummy; - const Variable* addr_var = ev->get_var()->get_array(dummy); - // if not an array ... - if (addr_var == 0) { - addr_var = ev->get_var(); - } - // if addr_var is a field, get the container var - addr_var = addr_var->get_named_var(); - if (!is_var_used(addr_var)) { - used_vars.push_back(addr_var); - } - } - } - } - } -} - -bool -Reducer::is_replaced_var(const ExpressionVariable* ev, string& str_out) -{ - if (map_reduced_vars.find(ev) != map_reduced_vars.end()) { - str_out = map_reduced_vars[ev]; - return true; - } - return false; -} - -const Expression* -Reducer::get_replaced_invocation(const FunctionInvocation* fi) -{ - if (map_reduced_invocations.find(fi) != map_reduced_invocations.end()) { - return map_reduced_invocations[fi]; - } - return NULL; -} - -void -Reducer::get_used_vars_and_funcs_and_labels(const FunctionInvocation* fi, vector& vars, vector& funcs, vector& labels) -{ - const Expression* replace = get_replaced_invocation(fi); - bool must_visit = std::find(must_use_var_invocations.begin(), must_use_var_invocations.end(), fi) != must_use_var_invocations.end(); - if (replace != NULL && !must_visit) { - get_used_vars_and_funcs_and_labels(replace, vars, funcs, labels); - return; - } - size_t i; - if (fi->invoke_type == eFuncCall) { - const FunctionInvocationUser* call = (const FunctionInvocationUser*)(fi); - if (find_function_in_set(funcs, call->get_func()) == -1) { - // special case: if the body of function is never entered, means this - // function is never invoked, mostly due to a && or || shortcut, we - // replace the function call with a constant 0. In fact it's not evaluated - // anyway, so which constant we use doesn't matter - if (is_blk_deleted(call->get_func()->body)) { - if (call->get_type().is_aggregate()) { - // it's not a real constant, but we don't want to go through the trouble - // of creating an ExpressionVariable - string vname = add_artificial_globals(&call->get_type()); - map_reduced_invocations[fi] = new Constant(&call->get_type(), vname); - } - else { - map_reduced_invocations[fi] = new Constant(&fi->get_type(), "0"); - } - return; - } - // recursively find used vars and functions - const Function* f = call->get_func(); - - get_used_vars_and_funcs_and_labels(f->body, vars, funcs, labels); - funcs.push_back(f); - // remember the parameters we dropped - for (i=0; iparam.size(); i++) { - if (is_param_dropped(f, i)) { - dropped_params.push_back(f->param[i]); - } - } - } - // only visit the parameters that are not dropped - for (i=0; iparam_value.size(); i++) { - if (!is_param_dropped(call->get_func(), i)) { - get_used_vars_and_funcs_and_labels(fi->param_value[i], vars, funcs, labels); - } - } - } - else { - for (i=0; iparam_value.size(); i++) { - get_used_vars_and_funcs_and_labels(fi->param_value[i], vars, funcs, labels); - } - } -} - -void -Reducer::get_used_vars_and_funcs_and_labels(const Expression* e, vector& vars, vector& funcs, vector& labels) -{ - string tmp; - switch (e->term_type) { - case eLhs: { - const Lhs* lhs = (const Lhs*)e; - add_variable_to_set(vars, lhs->get_var()->get_named_var()); - break; - } - case eConstant: { - const Constant* cst = (const Constant*)e; - const Variable* v = find_addressed_var(cst->get_value()); - if (v) { - add_variable_to_set(vars, v); - } - break; - } - // check if the variable is replaced by a constant - case eVariable: { - const ExpressionVariable* ev = (const ExpressionVariable*)e; - if (!is_replaced_var(ev, tmp) && !ev->get_var()->is_tmp_var()) { - add_variable_to_set(vars, ev->get_var()->get_named_var()); - } - break; - } - // check if invocation is replaced by a variable or constant - case eFunction: { - const ExpressionFuncall* funcall = (const ExpressionFuncall*)e; - get_used_vars_and_funcs_and_labels(funcall->get_invoke(), vars, funcs, labels); - break; - } - case eAssignment: { - const ExpressionAssign* ea = (const ExpressionAssign*)e; - get_used_vars_and_funcs_and_labels(ea->get_lhs(), vars, funcs, labels); - get_used_vars_and_funcs_and_labels(ea->get_rhs(), vars, funcs, labels); - break; - } - case eCommaExpr: { - const ExpressionComma* ec = (const ExpressionComma*)e; - get_used_vars_and_funcs_and_labels(ec->get_lhs(), vars, funcs, labels); - get_used_vars_and_funcs_and_labels(ec->get_rhs(), vars, funcs, labels); - break; - } - default: break; - } -} - -void -Reducer::find_called_funcs(const FunctionInvocation* fi, string id, vector& funcs, vector& ids) -{ - // analyze reduced expression instead if there is one - if (map_reduced_invocations.find(fi) != map_reduced_invocations.end()) { - const Expression* e = map_reduced_invocations[fi]; - const FunctionInvocation* invoke = e->get_invoke(); - if (invoke) { - find_called_funcs(invoke, id, funcs, ids); - } - return; - } - - const FunctionInvocationUser* func_call = NULL; - if (fi->invoke_type == eFuncCall) { - func_call = (const FunctionInvocationUser*)fi; - funcs.push_back(func_call); - ids.push_back(id); - } - // find calls in parameters, skip dropped parameters - for (size_t i=0; iparam_value.size(); i++) { - const Expression* value = fi->param_value[i]; - if (func_call==NULL || !is_param_dropped(func_call->get_func(), i)) { - const FunctionInvocation* fi = value->get_invoke(); - if (fi) { - find_called_funcs(fi, id + "_" + StringUtils::int2str(i), funcs, ids); - } - } - } -} - -int -Reducer::reduce_const_binary_op(const FunctionInvocationBinary* fib) -{ - const Expression* op1 = fib->param_value[0]; - const Expression* op2 = fib->param_value[1]; - if (op1->get_invoke() != NULL && map_reduced_invocations.find(op1->get_invoke()) != map_reduced_invocations.end()) { - op1 = map_reduced_invocations[op1->get_invoke()]; - } - if (op2->get_invoke() != NULL && map_reduced_invocations.find(op2->get_invoke()) != map_reduced_invocations.end()) { - op2 = map_reduced_invocations[op2->get_invoke()]; - } - if (op1->term_type == eConstant || map_reduced_vars.find(op1) != map_reduced_vars.end()) { - string str1 = (op1->term_type == eConstant) ? ((const Constant*)op1)->get_value() : map_reduced_vars[op1]; - if (op2->term_type == eConstant || map_reduced_vars.find(op2) != map_reduced_vars.end()) { - string str2 = (op2->term_type == eConstant) ? ((const Constant*)op2)->get_value() : map_reduced_vars[op2]; - INT64 result = 0; - INT64 v1 = StringUtils::str2longlong(str1); - INT64 v2 = StringUtils::str2longlong(str2); - switch (fib->get_operation()) { - case eAdd: result = v1 + v2; break; - case eSub: result = v1 - v2; break; - case eMul: result = v1 * v2; break; - case eDiv: result = v2 ? v1 / v2 : v1; break; - case eMod: result = v2 ? v1 % v2 : v1; break; - case eCmpGt: result = v1 > v2; break; - case eCmpLt: result = v1 < v2; break; - case eCmpGe: result = v1 >= v2; break; - case eCmpLe: result = v1 <= v2; break; - case eCmpEq: result = v1 == v2; break; - case eCmpNe: result = v1 != v2; break; - case eAnd: result = v1 && v2; break; - case eOr: result = v1 || v2; break; - case eBitXor: result = v1 ^ v2; break; - case eBitAnd: result = v1 & v2; break; - case eBitOr: result = v1 | v2; break; - case eRShift: result = (v2 > 0) ? v1 >> v2 : v1; break; - case eLShift: result = (v2 > 0) ? v1 << v2 : v1; break; - } - Constant* cst = new Constant(&fib->get_type(), StringUtils::longlong2str(result)); - map_reduced_invocations[fib] = cst; - return 1; - } - } - return 0; -} - -void -Reducer::reduce_const_binary_ops(vector& ops) -{ - size_t i; - size_t len = ops.size(); - for (i=0; i& ops, vector& ids, bool no_ptr_cmp) -{ - int cnt = 0; - vector exprs; - stm->get_exprs(exprs); - for (size_t i=0; i& ops, vector& ids, bool no_ptr_cmp) -{ - const FunctionInvocation* fi = exp->get_invoke(); - if (fi) { - // analyze reduced expression instead if there is one - if (map_reduced_invocations.find(fi) != map_reduced_invocations.end()) { - return find_binary_operations(map_reduced_invocations[fi], ops, ids, no_ptr_cmp); - } - - if (fi->invoke_type == eBinaryPrim) { - const FunctionInvocationBinary* fib = (const FunctionInvocationBinary*)fi; - if (!reduce_const_binary_op(fib)) { - if (!no_ptr_cmp || !fib->ptr_cmp) { - ops.push_back(fib); - ids.push_back(exp->expr_id); - } - } - } - const FunctionInvocationUser* func_call = NULL; - if (fi->invoke_type == eFuncCall) { - func_call = (const FunctionInvocationUser*)fi; - } - // find binary operations in parameters, skip dropped parameters - for (size_t i=0; iparam_value.size(); i++) { - const Expression* param = fi->param_value[i]; - if (func_call==NULL || !is_param_dropped(func_call->get_func(), i)) { - find_binary_operations(param, ops, ids, no_ptr_cmp); - } - } - } - return ops.size(); -} - -const FunctionInvocation* -Reducer::find_invoke_by_eid(const Statement* s, int id) const -{ - size_t i; - vector exprs; - s->get_exprs(exprs); - for (i=0; iget_invoke(); - if (e->expr_id == id) { - return fi; - } - if (fi) { - for (size_t i=0; iparam_value.size(); i++) { - const Expression* param = fi->param_value[i]; - const FunctionInvocation* tmp = find_invoke_by_eid(param, id); - if (tmp) { - return tmp; - } - } - } - return NULL; -} - -void -Reducer::build_left_right_binary_trees(vector& ops, vector& left_trees, vector& right_trees) -{ - size_t i, j, k; - vector sub_ops; - vector dummy, covered; - left_trees.clear(); - right_trees.clear(); - for (i=0; iparam_value[0], sub_ops, dummy, true); - for (j=0; jparam_value[1], sub_ops, dummy, true); - for (j=0; j& vars, vector& funcs, vector& labels) -{ - if (stm == NULL) return; - // for if statements with both branches deleted - if (stm->eType == eIfElse) { - const StatementIf* si = (const StatementIf*)stm; - if (is_blk_deleted(si->get_true_branch()) && is_blk_deleted(si->get_false_branch())) { - replace_stm(si, NULL, ""); - delete_stms_after(si, false); - } - } - // for goto statement whose target is deleted - else if (stm->eType == eGoto) { - const StatementGoto* sg = (const StatementGoto*)stm; - if (is_blk_deleted(sg->dest->parent)) { - bool keep = false; - // special case: if goto jump into a for-loop that use the monitored variable as - // induction variable, we keep the jump, for seed 355297830 - const Statement* s = sg->dest->find_container_stm(); - if (s && s->eType == eFor) { - const StatementFor* sf = (const StatementFor*)s; - if (sf->get_init()->get_lhs()->get_var() == this->monitored_var) { - keep = true; - if (std::find(labels.begin(), labels.end(), sg->label) == labels.end()) { - labels.push_back(sg->label); - } - } - } - if (!keep) { - replace_stm(sg, NULL, ""); - } - } else { - if (std::find(labels.begin(), labels.end(), sg->label) == labels.end()) { - labels.push_back(sg->label); - } - } - } - // include used variables from pre-statement assignments - if (map_pre_stm_assigns.find(stm) != map_pre_stm_assigns.end()) { - const string& assigns = map_pre_stm_assigns[stm]; - add_variables_to_set(vars, map_str_effects[assigns]); - } - // used replacement for replaced statements - bool must_visit = std::find(must_use_var_stms.begin(), must_use_var_stms.end(), stm) != must_use_var_stms.end(); - if (!must_visit && replaced_stms.find(stm) != replaced_stms.end()) { - get_used_vars_and_funcs_and_labels(replaced_stms[stm], vars, funcs, labels); - return; - } - - string label = stm->find_jump_label(); - if (!label.empty()) { - labels.push_back(label); - } - size_t i, j; - //stm->Output(cout); - vector exps; - stm->get_exprs(exps); - for (i=0; ieType == eArrayOp) { - const StatementArrayOp* sa = (const StatementArrayOp*)stm; - for (i=0; ictrl_vars.size(); i++) { - add_variable_to_set(vars, sa->ctrl_vars[i]->get_named_var()); - } - // JYTODO: detect the case when initializer is not invoked - if (sa->init_value) { - add_variable_to_set(vars, sa->array_var->get_named_var()); - } - } - vector blks; - stm->get_blocks(blks); - for (i=0; istms.size(); j++) { - const Statement* s = blks[i]->stms[j]; - get_used_vars_and_funcs_and_labels(s, vars, funcs, labels); - } - if (std::find(all_blks.begin(), all_blks.end(), blks[i]->stm_id) == all_blks.end()) { - all_blks.push_back(blks[i]->stm_id); - } - } -} - -int -Reducer::configure_diff_active_blks(string line, int first_bid) -{ - vector ids; - StringUtils::split_int_string(line, ids, ",()"); - size_t i; - assert(!ids.empty()); - const Block* one_branch = find_block_by_id(first_bid); - assert(one_branch); - const Statement* stm = one_branch->find_container_stm(); - if (stm && stm->eType == eIfElse) { - for (i=0; iget_false_branch()) ? si->get_true_branch() : si->get_false_branch(); - map_active_blks[other_branch] = map_active_blks[one_branch]; - assert(!used_vars.empty()); - - // replace both branches with direct conflicting assignments - string vname = monitored_var->name; - string assign1 = vname + " = 0;"; - string assign2 = vname + " = 1;"; - replace_stm(one_branch, NULL, assign1); - replace_stm(other_branch, NULL, assign2); - - // delete all statement following this if-else statement - delete_stms_after(si, true); - return 1; - } - else return 0; -} - -void -Reducer::config_active_blks(string cmd) -{ - size_t i; - vector tmp_strs; - if (cmd == "poll") { - dump_block_entry = true; - } else if (cmd == "blind poll") { - dump_all_block_info = true; - } - else { - tmp_strs.clear(); - bool take_diff_branch = false; - if (cmd.find("||") != string::npos) { - StringUtils::split_string(cmd, tmp_strs, "|"); - assert(tmp_strs.size() == 2); - cmd = tmp_strs[0]; - int blkid = StringUtils::str2int(tmp_strs[1]); - take_diff_branch = configure_diff_active_blks(cmd, blkid); - } - if (!take_diff_branch) { - StringUtils::split_string(cmd, tmp_strs, ",()"); - for (i=0; iparent; b != NULL; b = b->parent) { - if (map_active_blks.find(b) != map_active_blks.end()) { - break; - } - map_active_blks[b] = 0; - } - } - } - } - } -} - -void -Reducer::config_call_chain_shortcut(string cmd) -{ - if (cmd == "poll") { - dump_monitored_var = true; - add_artificial_globals(get_int_type(), "global_call_id"); - } - else { - vector strs; - StringUtils::split_string(cmd, strs, ":"); - assert(strs.size() == 2 || strs.size() == 3); - if (strs.size() == 2) { - dump_monitored_var = true; - add_artificial_globals(get_int_type(), "global_call_id"); - monitored_func = find_function_by_name(strs[0]); - assert(monitored_func); - monitored_call_id = strs[1]; - } - else { - main = find_function_by_name(strs[0]); - assert(main); - main_str = strs[2]; - } - } -} - -void -Reducer::config_stm_reduction(string cmd) -{ - size_t i, j; - if (cmd.find(":") == string::npos) { - size_t pos = cmd.find(" blind"); - if (pos != string::npos) { - cmd = cmd.substr(0, pos); - if (cmd == "main") cmd = "func_1"; - const Function* f = find_function_by_name(cmd); - assert(f); - dump_stms_in_blocks = f; - } - else { - // the reducer treats func_1 as main - if (cmd == "main") cmd = "func_1"; - const Function* f = find_function_by_name(cmd); - assert(f); - for (i=0; iblocks.size(); i++) { - const Block* b = f->blocks[i]; - if (!is_blk_deleted(b) && map_active_blks[b] == 1) { - for (j=0; jstms.size(); j++) { - const Statement* s = b->stms[j]; - if (!s->must_jump()) { - dump_value_before.push_back(s); - dump_value_after.push_back(s); - } - } - } - } - } - } - else { - vector strs; - StringUtils::split_string(cmd, strs, ":"); - assert(strs.size() == 2 || strs.size() == 3); - string assigns = strs.size()==3 ? strs[2] : ""; - reduce_stms_with_assigns(StringUtils::str2int(strs[0]), StringUtils::str2int(strs[1]), assigns); - } -} - -void -Reducer::config_expr_reduction(string cmd) -{ - if (cmd.find(":") == string::npos) { - // the reducer treats func_1 as main - if (cmd == "main") cmd = "func_1"; - const Function* f = find_function_by_name(cmd); - assert(f); - rewrite_calls_inside = f; - } - else { - vector strs; - StringUtils::split_string(cmd, strs, ":"); - assert(strs.size() == 2 || strs.size() == 3); - string assigns = strs.size()==3 ? strs[2] : ""; - reduce_call_with_assigns(strs[0], strs[1], assigns); - } -} - -void -Reducer::config_binary_reduction(string cmd) -{ - if (cmd.find(":") == string::npos) { - // the reducer treats func_1 as main - reduce_binaries = (cmd == "all"); - } - else { - size_t i; - // for rollback, ignore this reduction if ends with a '-', keep vars as used_vars if ends with '+' - char last = cmd[cmd.length()-1]; - if (last == '-') return; - if (last == '+') { - cmd = cmd.substr(0, cmd.length()-1); - } - vector ints; - StringUtils::split_int_string(cmd, ints, "[:]"); - assert(ints.size() >= 2); - const Statement* stm = find_stm_by_id(ints[0]); - assert(stm); - ints.erase(ints.begin()); - // must be pairs of ":" where choice is 1 (select left) or 2 (select right) - assert(ints.size() % 2 == 0); - - for (i = 0; i < ints.size(); i += 2) { - // special case: reduce if (...) to if (1) - if (ints[i] == 0) { - assert(ints[i+1] == -1); - assert(stm->eType == eIfElse); - const FunctionInvocation* fi = stm->get_direct_invocation(); - assert(fi); - map_reduced_invocations[fi] = new Constant(&fi->get_type(), "1"); - break; - } - const FunctionInvocation* fi = find_invoke_by_eid(stm, ints[i]); - assert(fi && fi->invoke_type == eBinaryPrim); - int choice = ints[i+1] - 1; - assert(choice == 0 || choice == 1); - const Expression* op = fi->param_value[choice]; - if (last == '+') { - must_use_var_invocations.push_back(fi); - } - map_reduced_invocations[fi] = op; - } - } -} - -void -Reducer::config_if_reduction(string cmd) -{ - if (cmd.find(",") == string::npos) { - // the reducer treats func_1 as main - output_if_ids = (cmd == "poll"); - } - else { - size_t i; - vector strs; - StringUtils::split_string(cmd, strs, ","); - for (i=0; ieType == eIfElse); - const StatementIf* si = (const StatementIf*)stm; - if (is_blk_deleted(si->get_false_branch())) { - replace_stm(si, si->get_true_branch(), ""); - } - else if (is_blk_deleted(si->get_true_branch())) { - replace_stm(si, si->get_false_branch(), ""); - } - // at least one branch should be deleted - else assert(0); - - if (rollback) { - must_use_var_stms.push_back(stm); - } - } - } -} - -void -Reducer::config_var_init_reduction(string cmd) -{ - vector strs; - StringUtils::split_string(cmd, strs, ":"); - assert(strs.size() == 2); - - const Variable* v = VariableSelector::find_var_by_name(strs[0]); - assert(v); - map_reduced_var_inits[v] = strs[1]; -} - -string -Reducer::add_artificial_globals(const Type* t, string name) -{ - static int cnt = 0; - ostringstream oss; - t->Output(oss); - if (name == "") { - name = "tmp_" + StringUtils::int2str(cnt++); - } - artificial_globals.push_back(oss.str() + " " + name); - return name; -} - -const Variable* -Reducer::find_addressed_var(string addr) -{ - if (addr.find("&") == 0) { - string addr_var = addr.substr(1); - size_t dotbracket = StringUtils::find_any_char(addr_var, 0, "[."); - if (dotbracket != string::npos) { - addr_var = addr_var.substr(0, dotbracket); - } - const Variable* addr_v = VariableSelector::find_var_by_name(addr_var); - assert(addr_v); - return addr_v; - } - return NULL; -} - -vector -Reducer::find_used_vars(string assigns) -{ - size_t i; - vector vars; - vector vnames, values; - StringUtils::breakup_assigns(assigns, vnames, values); - - // parse the assignment string - for (i=0; ieType == eIfElse) { - const Block* if_true = ((const StatementIf*)stm)->get_true_branch(); - const Block* if_false = ((const StatementIf*)stm)->get_false_branch(); - const Block* b = is_blk_deleted(if_true) ? if_false : if_true; - assert(b); - replace_stm(stm, b, ""); - } else { - replace_stm(stm, NULL, ""); - } - return 0; - } - - // find invocation based on id - vector calls; - vector ids; - const FunctionInvocation* invoke = NULL; - const FunctionInvocation* fi = stm->get_direct_invocation(); - assert(fi); - find_called_funcs(fi, tmp_name.substr(0, dash), calls, ids); - size_t i; - for (i=0; iget_type()); - Constant* cst = new Constant(type, value); - // record this reduction - map_reduced_invocations[invoke] = cst; //tmp_ev; - if (!extra_assigns.empty()) { - map_pre_stm_assigns[stm] = extra_assigns; - map_str_effects[extra_assigns] = find_used_vars(extra_assigns); - } - return 0; -} - -int -Reducer::reduce_stms_with_assigns(int id1, int id2, const string& assigns) -{ - const Statement* stm = find_stm_by_id(id1); - assert(stm); - const Block* blk = stm->parent; - assert(blk); - - size_t i; - int begin = -1; - int end = -1; - for (i=0; istms.size(); i++) { - const Statement* s = blk->stms[i]; - if (s == stm) { - begin = i; - end = i; - } - if (s->stm_id == id2) { - assert(begin != -1); - end = i; - break; - } - } - - if (begin != -1 && end != -1) { - for (int i=begin+1; i<=end; i++) { - replace_stm(blk->stms[i], NULL, ""); - } - replace_stm(blk->stms[begin], NULL, assigns); - } - return 0; -} - -int -Reducer::output_expr(const Expression* e, std::ostream &out) -{ - string tmp; - if (e->term_type == eVariable) { - const ExpressionVariable* ev = (const ExpressionVariable*)e; - if (is_replaced_var(ev, tmp)) { - out << tmp; - return 1; - } - } - // check if invocation is replaced by a variable or constant - else if (e->term_type == eFunction) { - const ExpressionFuncall* funcall = (const ExpressionFuncall*)e; - const FunctionInvocation* invoke = funcall->get_invoke(); - const Expression* exp = get_replaced_invocation(invoke); - if (exp) { - exp->Output(out); - return 1; - } else { - if (invoke->invoke_type == eFuncCall) { - const FunctionInvocationUser* call = (const FunctionInvocationUser*)(invoke); - const Function* func = call->get_func(); - out << func->name << "("; - size_t i; - bool first = true; - for (i=0; iparam.size(); i++) { - if (!is_param_dropped(func, i)) { - if (!first) { - out << ", "; - } - call->param_value[i]->Output(out); - first = false; - } - } - out << ")"; - return 1; - } - } - } - else if (e->term_type == eAssignment) { - const ExpressionAssign* ea = dynamic_cast(e); - ostringstream oss; - // if RHS can be simplified, print the simplified version - if (output_expr(ea->get_rhs(), oss)) { - out << "("; - ea->get_lhs()->Output(out); - out << " "; - ea->get_stm_assign()->output_op(out); - out << " "; - out << oss.str(); - out << ")"; - return 1; - } - } - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// - -// Local Variables: -// c-basic-offset: 4 -// tab-width: 4 -// End: - -// End of file. diff --git a/src/Reducer.h b/src/Reducer.h deleted file mode 100644 index 1c90bb23f..000000000 --- a/src/Reducer.h +++ /dev/null @@ -1,172 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef REDUCER_H -#define REDUCER_H - -#include -#include -#include -#include -#include "Effect.h" -#include "util.h" -using namespace std; - -class Function; -class Block; -class Statement; -class Variable; -class Expression; -class ExpressionVariable; -class FactMgr; -class Type; -class FunctionInvocation; -class FunctionInvocationUser; -class FunctionInvocationBinary; - -/* - * - */ -class Reducer -{ -public: - Reducer(string fname); - virtual ~Reducer(void); - void configure(void); - - bool is_blk_deleted(const Block* b) const; - bool is_stm_deleted(const Statement* stm) const; - bool is_var_used(const Variable* v); - bool is_param_dropped(const Function* f, int i); - bool is_replaced_var(const ExpressionVariable* ev, string& str_out); - const Expression* get_replaced_invocation(const FunctionInvocation* fi); - bool is_ptr_written_in_stm(const Statement* stm); - bool is_exp_replaced(const Expression* e); - bool is_label_used(const string l); - bool is_var_init_reduced(const Variable* v); - string find_jump_label(const Statement* stm); - int find_required_labels(const Statement* stm, vector& labels); - int find_missing_labels(const Statement* stm, const Statement* alt_stm, vector& labels); - - // for effect analysis and variable dropping - vector find_used_vars(string assigns); - const Variable* find_addressed_var(string addr); - void find_called_funcs(const FunctionInvocation* fi, string id, vector& funcs, vector& ids); - void get_used_vars_and_funcs_and_labels(const FunctionInvocation* fi, vector& vars, vector& funcs, vector& labels); - void get_used_vars_and_funcs_and_labels(const Expression* e, vector& vars, vector& funcs, vector& labels); - void get_used_vars_and_funcs_and_labels(const Statement* stm, vector& vars, vector& funcs, vector& labels); - void expand_used_vars(void); - const FunctionInvocation* find_invoke_by_eid(const Statement* s, int id) const; - const FunctionInvocation* find_invoke_by_eid(const Expression* e, int id) const; - int find_binary_operations(const Statement* stm, vector& ops, vector& ids, bool no_ptr_cmp=false); - int find_binary_operations(const Expression* exp, vector& ops, vector& ids, bool no_ptr_cmp=false); - void build_left_right_binary_trees(vector& ops, vector& left_trees, vector& right_trees); - int reduce_const_binary_op(const FunctionInvocationBinary* fib); - void reduce_const_binary_ops(vector& ops); - - // for function dropping - int reduce_call_with_assigns(const string& tmp_name, const string& value, const string& extra_assigns); - - // for statement reduction - void replace_stm(const Statement* stm, const Statement* new_stm, string pre_stm); - void delete_stms_after(const Statement* stm, bool include_parent_blks); - int reduce_stms_with_assigns(int id1, int id2, const string& assigns); - - string add_artificial_globals(const Type* t, string name=""); - - // for outputing - void output_block_skeleton(const Block* blk, vector& work_blks, vector& work_funcs, std::ostream& out); - int output_expr(const Expression* e, std::ostream &out); - - // for interaction with reduction config file - void config_active_blks(string cmd); - int configure_diff_active_blks(string line, int first_bid); - void config_call_chain_shortcut(string cmd); - void config_stm_reduction(string cmd); - void config_expr_reduction(string cmd); - void config_binary_reduction(string cmd); - void config_if_reduction(string cmd); - void config_var_init_reduction(string cmd); - - bool dump_block_entry; - bool dump_all_block_info; - bool dump_monitored_var; - bool dump_dropped_params; - bool drop_params; - const Function* rewrite_calls_inside; - bool reduce_binaries; - bool output_if_ids; - const Variable* monitored_var; - const Function* monitored_func; - string monitored_call_id; - string crc_lines; - - std::map map_active_blks; - vector all_blks; - vector dropped_params; - - // for statement reduction - std::map replaced_stms; - std::vector dump_value_before; - std::vector dump_value_after; - std::map > map_str_effects; - const Function* dump_stms_in_blocks; - - // for expression reduction - std::map map_reduced_vars; - std::map map_reduced_invocations; - std::map map_pre_stm_assigns; - std::map map_reduced_var_inits; - std::vector must_use_var_invocations; - std::vector must_use_var_stms; - - vector used_funcs; - vector used_vars; - vector used_labels; - vector artificial_globals; - const Function* main; - string main_str; - bool configured; - -private: - string fname_; - const Statement* find_stm_by_id(int stm_id); - int find_local_vars_to_lift(vector& vars); -}; - -/////////////////////////////////////////////////////////////////////////////// - -#endif // REDUCER_H - -// Local Variables: -// c-basic-offset: 4 -// tab-width: 4 -// End: - -// End of file. diff --git a/src/ReducerOutputMgr.cpp b/src/ReducerOutputMgr.cpp deleted file mode 100644 index 766898007..000000000 --- a/src/ReducerOutputMgr.cpp +++ /dev/null @@ -1,1017 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011, 2013 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#include "ReducerOutputMgr.h" - -#include -#include -#include "Common.h" -#include "CGOptions.h" -#include "platform.h" -#include "Bookkeeper.h" -#include "Function.h" -#include "FunctionInvocation.h" -#include "FunctionInvocationUser.h" -#include "ExpressionFuncall.h" -#include "ExpressionVariable.h" -#include "CGContext.h" -#include "ArrayVariable.h" -#include "VariableSelector.h" -#include "Type.h" -#include "random.h" -#include "DeltaMonitor.h" -#include "Error.h" -#include "Reducer.h" -#include "Block.h" -#include "Statement.h" -#include "StatementIf.h" -#include "StatementFor.h" -#include "StatementArrayOp.h" -#include "StatementGoto.h" -#include "StringUtils.h" -#include "FactMgr.h" - -using namespace std; - -#define BINARY_REDUCTION_LIMIT 18 - -struct binary_reduced_stm { - string cmd; - string stm; - int len; -}; - -std::ostream & -ReducerOutputMgr::get_main_out() -{ - if (ofile_) return *ofile_; - if (!CGOptions::output_file().empty()) { - ofile_ = new ofstream(CGOptions::output_file().c_str()); - return *ofile_; - } - else { - return std::cout; - } -} - -ReducerOutputMgr::ReducerOutputMgr() -: ofile_(NULL) -{ - reducer = CGOptions::get_reducer(); - assert(reducer); -} - -ReducerOutputMgr::~ReducerOutputMgr() -{ - if (ofile_) { - ofile_->close(); - delete ofile_; - } -} - -void -ReducerOutputMgr::OutputHeader(int argc, char *argv[], unsigned long /*seed*/) -{ - // output shortened header: csmith options + random_inc.h include - ostream& out = get_main_out(); - out << "// Options: "; - if (argc <= 1) { - out << " (none)"; - } else { - for (int i = 1; i < argc; ++i) { - out << " " << argv[i]; - } - } - out << endl; - out << "#include \"csmith.h\"" << endl << endl; -} - -void -ReducerOutputMgr::output_var(const Variable* v, std::ostream &out, int indent) -{ - if (!reducer->is_var_init_reduced(v)) { - v->OutputDef(out, indent); - } - else { - string init = reducer->map_reduced_var_inits[v]; - output_tab(out, indent); - v->OutputDecl(out); - out << " = " << init << ";" << endl; - } -} - -void -ReducerOutputMgr::output_vars(const vector &vars, std::ostream &out, int indent) -{ - size_t i; - int dimen = 0; - vector avs; - // print used vars, and find the max dimension of all array variables - for (i=0; iis_var_used(v)) continue; - output_var((const ArrayVariable*)v, out, indent); - if (v->isArray) { - const ArrayVariable* av = (const ArrayVariable*)(v); - if (!av->no_loop_initializer()) { - if (av->get_dimension() > (size_t)dimen) { - dimen = av->get_dimension(); - } - avs.push_back(av); - } - } - } - // output array initializers - if (dimen > 0) { - vector &ctrl_vars = Variable::get_new_ctrl_vars(); - OutputArrayCtrlVars(ctrl_vars, out, dimen, indent); - for (i=0; ioutput_init(out, av->init, ctrl_vars, indent); - } - } -} - -int -ReducerOutputMgr::output_block(const Block* blk, std::ostream& out, int indent, bool no_bracelet) -{ - size_t i; - if (reducer->is_blk_deleted(blk)) { - output_tab(out, indent + 1); - out << ";" << endl; - return 0; - } - // see Reducer::config_diff_active_blks - if (reducer->replaced_stms.find(blk) != reducer->replaced_stms.end() && reducer->replaced_stms[blk] == NULL) { - output_tab(out, indent + 1); - out << reducer->map_pre_stm_assigns[blk] << endl; - return 0; - } - - if (!no_bracelet) { - output_open_encloser("{", out, indent); - } - // add support for "--math-notmp" - if (CGOptions::math_notmp()) { - blk->OutputTmpVariableList(out, indent); - } - output_vars(blk->local_vars, out, indent); - - // dump global state for top level block if necessary - if (blk->parent == NULL) { - output_global_state_for_func(blk->func, out, indent); - } - // dump "entering block ..." information - output_block_entry_msg(blk, out, indent); - if (reducer->dump_stms_in_blocks == blk->func) { - string fname = blk->func->name; - if (fname == "func_1") fname = "main"; - string s = "// " + fname + " block " + StringUtils::int2str(blk->stm_id) + " ["; - for (i=0; istms.size(); i++) { - if (i > 0) { - s += ":"; - } - s += StringUtils::int2str(blk->stms[i]->stm_id); - } - s += "]"; - output_tab(out, indent); - out << s << endl; - } - - FactMgr* fm = get_fact_mgr_for_func(blk->func); - for (i=0; istms.size(); i++) { - const Statement* stm = blk->stms[i]; - output_stm(stm, out, fm, indent); - } - - if (!no_bracelet) { - output_close_encloser("}", out, indent, true); - } - outputln(out); - return 0; -} - -int -ReducerOutputMgr::output_func_header(const Function* f, std::ostream& out) -{ - // output function header - out << "static "; - f->rv->qfer.output_qualified_type(f->return_type, out); - out << " " << f->name << "("; - size_t i; - bool first = true; - for (i=0; iparam.size(); i++) { - const Variable* var = f->param[i]; - if (!reducer->is_param_dropped(f, i)) { - if (!first) { - out << ", "; - } - var->output_qualified_type(out); - out << " " << var->name; - first = false; - } - } - out << ")"; - return 0; -} - -void -ReducerOutputMgr::output_crc_lines(std::ostream& out) -{ - // declare loop variables if they are used in crc lines - for (char c = 'i'; c <= 'z'; c++) { - string pattern = string("; ") + c + "++)"; - if (reducer->crc_lines.find(pattern) != string::npos) { - output_tab(out, 1); - out << "int " << c << " = 0;" << endl; - } - } - if (reducer->crc_lines.find("print_hash_value") != string::npos) { - output_tab(out, 1); - out << "int print_hash_value = 0;" << endl; - } - // print the real CRC lines - output_tab(out, 1); - out << reducer->crc_lines << endl; -} - -int -ReducerOutputMgr::output_main_func(std::ostream& out) -{ - size_t i; - const Function* f = reducer->main; - if (f->param.size() == 0 && (reducer->main_str == "" || reducer->main_str.find("func_")==0)) { - out << "int main(void)" << endl; - if (reducer->is_blk_deleted(f->body)) { - out << "{" << endl; - if (!reducer->crc_lines.empty()) { - output_crc_lines(out); - } - output_tab(out, 1); - out << "return 0;" << endl; - out << "}" << endl; - } - else { - output_block(f->body, out, 0); - } - } - else { - output_func(f, out); - out << endl << "int main(void) {" << endl; - output_tab(out, 1); - // break up function call and parameters, and skip parameters that are reduced - vector strs; - StringUtils::split_string(reducer->main_str, strs, "();"); - assert(strs.size() == 2 || strs.size() == 1); - string func_name = strs[0]; - out << func_name << "("; - if (strs.size() == 2) { - const Function* f = find_function_by_name(func_name); - assert(f); - string params = strs[1]; - strs.clear(); - StringUtils::split_string(params, strs, ","); - bool first = true; - for (i=0; iis_param_dropped(f, i)) { - if (!first) { - out << ", "; - } - out << strs[i]; - first = false; - } - } - } - out << ");" << endl; - output_tab(out, 1); - out << "return 0;" << endl << "}"; - outputln(out); - } - return 0; -} -int -ReducerOutputMgr::output_func(const Function* f, std::ostream& out) -{ - output_func_header(f, out); - out << endl; - output_block(f->body, out, 0); - return 0; -} - -void -ReducerOutputMgr::output_pre_stm_assigns(const Statement* stm, std::ostream &out, int indent) -{ - if (reducer->map_pre_stm_assigns.find(stm) != reducer->map_pre_stm_assigns.end()) { - string assigns = reducer->map_pre_stm_assigns[stm]; - output_tab(out, indent); - out << assigns; - outputln(out); - } -} - -void -ReducerOutputMgr::output_block_entry_msg(const Block* blk, std::ostream &out, int indent) -{ - if (reducer->dump_block_entry) { - const Statement* s = blk->find_container_stm(); - if (s && s->eType == eFor) { - output_tab(out, indent); - out << "static int cnt = 0;" << endl; - output_tab(out, indent++); - out << "if (cnt++ < 1000) {" << endl; - } - string msg = "entering " + blk->func->name + "@" + StringUtils::int2str(blk->stm_id) + "\\n"; - output_print_str(out, msg, "", indent); - outputln(out); - if (s && s->eType == eFor) { - output_tab(out, --indent); - out << "}" << endl; - } - } -} - -void -ReducerOutputMgr::output_pre_stm_values(const Statement* stm, std::ostream &out, FactMgr* fm, int indent) -{ - if (find_stm_in_set(reducer->dump_value_before, stm) != -1) { - assert(stm->parent); - string blkid = StringUtils::int2str(stm->parent->stm_id); - string id = StringUtils::int2str(stm->stm_id); - out << "/* replacing " << blkid << " " << id << " before" << endl; - output_write_var_values("values before " + id + "...\\n", stm, out, fm, indent, true); - out << "*/" << endl; - } -} - -void -ReducerOutputMgr::output_post_stm_values(const Statement* stm, std::ostream &out, FactMgr* fm, int indent) -{ - // print value of variables that may have been written by the statement - if (find_stm_in_set(reducer->dump_value_after, stm) != -1) { - assert(stm->parent); - string blkid = StringUtils::int2str(stm->parent->stm_id); - string id = StringUtils::int2str(stm->stm_id); - out << "/* replacing " << blkid << " " << id << " after" << endl; - output_write_var_values("values after " + id + "...\\n", stm, out, fm, indent, true); - output_memory_addrs(stm, out, indent); - out << "*/" << endl; - } -} - -/* - * compute the real "meaningful" length of statement or expression - * anything not affecting the program complexity is ignored - */ -int real_length(string exp) -{ - int len = 0; - size_t i; - for (i=1; i= '0' && exp[i] <= '9') { - len -= 1; - } - if (((exp[i-1] >= '0' && exp[i-1] <= '9') || (exp[i-1] >= 'A' && exp[i-1] <= 'F')) && - ((exp[i] >= '0' && exp[i] <= '9') || (exp[i] >= 'A' && exp[i] <= 'F'))) { - len -= 1; - } - len++; - } - return len; -} - -/* - * insert an output for a binary reduced statement into the ordered array - */ -void insert_alt_stm_cmd(vector& stms, const string& cmd, const string& stm) -{ - int len = real_length(stm); - struct binary_reduced_stm alt = {cmd, stm, len}; - for (size_t i=0; i& binarys, vector& ids) -{ - int s; - while (binarys.size() > BINARY_REDUCTION_LIMIT) { - for (s = binarys.size() - 1; s>=0; s--) { - const FunctionInvocationBinary* fib = binarys[s]; - vector dummy1; - vector dummy2; - if (reducer->find_binary_operations(fib->param_value[0], dummy1, dummy2, true) == 0 && - reducer->find_binary_operations(fib->param_value[1], dummy1, dummy2, true) == 0) { - binarys.erase(binarys.begin() + s); - ids.erase(ids.begin() + s); - break; - } - } - } - // if still more than limit, delete the last few binary operations - if (binarys.size() > BINARY_REDUCTION_LIMIT) { - int extra = binarys.size() - BINARY_REDUCTION_LIMIT; - for (s=0; sreduce_binaries || stm->get_direct_invocation() == NULL) return; - vector binarys; - vector ids; - reducer->find_binary_operations(stm, binarys, ids, true); - assert(ids.size() == binarys.size()); - - // reduce runtime by limiting the number of binary operations we try to reduce - limit_binarys(binarys, ids); - vector combinations; - vector left_trees, right_trees; - - reducer->build_left_right_binary_trees(binarys, left_trees, right_trees); - assert(binarys.size() == left_trees.size() && binarys.size() == right_trees.size()); - - // special case: output "if (1)" for if conditions - if (stm->eType == eIfElse) { - output_tab(out, indent); - out << "// [" << StringUtils::int2str(stm->stm_id) << ":0:-1] " << "if (1)" << endl; - } - // output the selections at single points - for (i=0; istm_id); - const Expression* op = fi->param_value[j]; - reducer->map_reduced_invocations[fi] = op; - out << ":" + StringUtils::int2str(ids[i]) << ":" << StringUtils::int2str(j+1) << "] "; - stm->eType == eIfElse ? ((const StatementIf*)stm)->output_condition(out, 0, 0) : stm->Output(out, 0, 0); - reducer->map_reduced_invocations.erase(fi); - } - } - if (binarys.size()) { - output_tab(out, indent); - out << "// end of single choices" << endl; - } - intvec orig; - for (i=0; i alt_stms; - for (i=1; istm_id); - vector reduced_invokes; - for (j=0; jparam_value[choice - 1]; - reducer->map_reduced_invocations[fi] = op; - cmd += ":" + StringUtils::int2str(ids[j]) + ":" + StringUtils::int2str(choice); - reduced_invokes.push_back(fi); - } - } - cmd += "]"; - ostringstream oss; - stm->eType == eIfElse ? ((const StatementIf*)stm)->output_condition(oss, 0, 0) : stm->Output(oss, 0, 0); - insert_alt_stm_cmd(alt_stms, cmd, oss.str()); - // impose an artificial upper limit on number of alternatives so reducer can finish quicker - if (alt_stms.size() >= 10000) { - break; - } - - for (j=0; jmap_reduced_invocations.erase(reduced_invokes[j]); - } - } - for (i=0; iis_blk_deleted(si->get_true_branch()) && reducer->is_blk_deleted(si->get_false_branch())) { - assert(0); // should have been taken care in get_used_vars_and_funcs_and_labels - } - else if (reducer->is_blk_deleted(si->get_false_branch())) { - if (reducer->replaced_stms.find(si) != reducer->replaced_stms.end() && reducer->replaced_stms[si] == si->get_true_branch()) { - output_block(si->get_true_branch(), out, indent, true); - } else { - if (reducer->output_if_ids) { - out << "/* if reduction candidate: " << StringUtils::int2str(si->stm_id) << " */" << endl; - } - si->output_condition(out, 0, indent); - output_block(si->get_true_branch(), out, indent); - } - } - else if (reducer->is_blk_deleted(si->get_true_branch())) { - if (reducer->replaced_stms.find(si) != reducer->replaced_stms.end() && reducer->replaced_stms[si] == si->get_false_branch()) { - output_block(si->get_false_branch(), out, indent, true); - } else { - if (reducer->output_if_ids) { - out << "/* if reduction candidate: " << StringUtils::int2str(si->stm_id) << " */" << endl; - } - // special case: if condition is replaced, don't flip it by outputting "!" - if (reducer->is_exp_replaced(si->get_test())) { - si->output_condition(out, 0, indent); - } - else { - output_tab(out, indent); - out << "if (!("; - si->get_test()->Output(out); - out << "))" << endl; - } - output_block(si->get_false_branch(), out, indent); - } - } - else { - si->output_condition(out, 0, indent); - output_block(si->get_true_branch(), out, indent); - output_tab(out, indent); - out << "else" << endl; - output_block(si->get_false_branch(), out, indent); - } - } - -void -ReducerOutputMgr::output_reduced_stm(const Statement* stm, std::ostream &out, int indent) -{ - vector blks; - stm->get_blocks(blks); - if (blks.empty()) { - // insert printing value for focus variable - if (stm->eType == eReturn) { - // output value(s) of monitor variable(s) before return - if (reducer->dump_monitored_var && stm->func->feffect.is_written_partially(reducer->monitored_var)) { - output_tab(out, indent); - string vname = reducer->monitored_var->name; - out <<"printf(\" " << vname << " = %d\", " << vname <<");"; - outputln(out); - output_tab(out, indent); - out << "printf(\" before leaving " << stm->func->name << ":%d\\n\", call_id);"; - outputln(out); - } - // output value of key variable for the main function before return - else if (stm->func == reducer->main) { - if (reducer->monitored_var) { - ostringstream oss; - const Variable* key = reducer->monitored_var; - oss << "checksum " << key->get_actual_name() << " = "; - key->output_runtime_value(out, oss.str(), "\\n", indent, 0); - outputln(out); - } - } - if (stm->func == GetFirstFunction()) { - // output crc lines if they are required - if (!reducer->crc_lines.empty()) { - output_crc_lines(out); - } - output_tab(out, indent); - out << "return 0;" << endl; - return; - } - } - else if (stm->eType == eGoto && reducer->dump_block_entry) { - const StatementGoto* sg = (const StatementGoto*)stm; - output_tab(out, indent); - out << "if ("; - sg->test.Output(out); - out << ")" << endl; - output_open_encloser("{", out, indent); - output_block_entry_msg(sg->dest->parent, out, indent); - output_tab(out, indent); - out << "goto " << sg->label << ";" << endl; - output_close_encloser("}", out, indent); - return; - } - stm->Output(out, 0, indent); - return; - } - - switch (stm->eType) { - case eIfElse: - output_if_stm((const StatementIf*)stm, out, indent); - break; - case eFor: { - const StatementFor* sf = (const StatementFor*)stm; - if (reducer->is_blk_deleted(sf->get_body())) { - bool keep_body = false; - const Variable* cv = sf->get_init()->get_lhs()->get_var(); - if (cv == reducer->monitored_var) { - vector labels, req_labels; - if (sf->get_body()->find_contained_labels(labels)) { - size_t i; - for (i=0; iis_label_used(labels[i])) { - req_labels.push_back(labels[i]); - } - } - if (req_labels.size() > 0) { - sf->output_header(out, indent); - for (i=0; iget_init()->Output(out, 0, indent); - } - } - else { - sf->output_header(out, indent); - output_block(sf->get_body(), out, indent); - } - break; - } - case eArrayOp: { - const StatementArrayOp* sa = (const StatementArrayOp*)stm; - if (reducer->is_blk_deleted(sa->body)) { - break; - } - sa->output_header(out, indent); - output_block(sa->body, out, indent); - break; - } - default: break; - } -} -void -ReducerOutputMgr::output_stm(const Statement* stm, std::ostream &out, FactMgr* fm, int indent) -{ - string str_out; - // print pre-statement assignments - output_pre_stm_assigns(stm, out, indent); - output_pre_stm_values(stm, out, fm, indent); - - if (reducer->replaced_stms.find(stm) != reducer->replaced_stms.end()) { - const Statement* alt_stm = reducer->replaced_stms[stm]; - vector labels; - // special case for goto target: if the jump source is still around, we have to keep the label somehow - if (reducer->find_missing_labels(stm, alt_stm, labels)) { - for (size_t i=0; ieType == eBlock) { - output_block((const Block*)alt_stm, out, indent, true); - } else if (alt_stm) { - output_stm(reducer->replaced_stms[stm], out, fm, indent); - } - return; - } - - if (stm->func == reducer->rewrite_calls_inside) { - rewrite_func_calls(stm, out, indent); - } - // print lable for jump detination - string label = reducer->find_jump_label(stm); - label.empty() ? (out << "") : (out << label << ":" << endl); - - output_alt_exprs(stm, out, indent); - - output_reduced_stm(stm, out, indent); - - output_post_stm_values(stm, out, fm, indent); -} - -void -ReducerOutputMgr::rewrite_func_call(const Statement* stm, const FunctionInvocation* invoke, string tmp_id, std::ostream& out, int indent) -{ - // output pre-values - FactMgr* fm = get_fact_mgr_for_func(stm->func); - output_write_var_values("begin of values before rewrite...\\n", stm, out, fm, indent); - // output " t1 = " - const Type* type = &(invoke->get_type());; - Expression* tmp_call = new ExpressionFuncall(*(invoke->clone())); - CVQualifiers qfer = CVQualifiers::random_qualifiers(type, 0, 0); - Variable* tmp_var = Variable::CreateVariable(tmp_id, type, tmp_call, &qfer); - tmp_var->OutputDef(out, indent); - - // output the value of the tmp variable - ostringstream oss; - oss << "<" << tmp_id << " = "; - tmp_var->output_runtime_value(out, oss.str(), ">\\n", indent); - outputln(out); - - // output post values - output_write_var_values("begin of values after rewrite...\\n", stm, out, fm, indent); - if (reducer->is_ptr_written_in_stm(stm)) { - output_memory_addrs(stm, out, indent); - } - ExpressionVariable* tmp_ev = new ExpressionVariable(*tmp_var); - reducer->map_reduced_invocations[invoke] = tmp_ev; - // output stm with call replaced with tmp_id - (stm->eType == eIfElse) ? ((const StatementIf*)stm)->output_condition(out, 0, indent) : stm->Output(out, 0, indent); - - // clean up - reducer->map_reduced_invocations.erase(invoke); - delete tmp_ev; - delete tmp_var; -} - -int -ReducerOutputMgr::rewrite_func_calls(const Statement* stm, std::ostream &out, int indent) -{ - vector calls; - const FunctionInvocation* fi = stm->get_direct_invocation(); - if (fi) { - vector ids; - string init_name = "t" + StringUtils::int2str(stm->stm_id); - reducer->find_called_funcs(fi, init_name, calls, ids); - if (!calls.empty()) { - size_t i; - for (i=0; iget_type().is_aggregate()) { - continue; - } - output_tab(out, indent); - out << "/* " << "replacing " << ids[i] << endl; - rewrite_func_call(stm, calls[i], ids[i], out, indent); - output_tab(out, indent); - out << "*/" << endl; - } - } - } - return calls.size(); -} - -/* - * dumping global states at the function entry point for path shortcutting purpose - */ -void -ReducerOutputMgr::output_global_state_for_func(const Function* f, std::ostream &out, int indent) -{ - if (!reducer->dump_monitored_var) return; - size_t i; - if (reducer->monitored_func && f == reducer->main) { - output_global_values("values before main\\n", out, indent); - } - // output statement to increment call counter for delta purpose - if (f->feffect.is_written(reducer->monitored_var)) { - output_tab(out, indent); - out <<"int call_id = ++global_call_id;"; - outputln(out); - - // output global state if we are interested in this particular function call - if (f == reducer->monitored_func) { - assert(reducer->monitored_call_id != ""); - output_tab(out, indent); - out << "if (call_id == " << reducer->monitored_call_id << ")" << endl; - output_open_encloser("{", out, indent); - - // dump addresses of global variables - output_memory_addrs(f->body, out, indent); - - // dump global state at the beginning of this call - output_global_values("values after main and before " + f->name + "\\n", out, indent); - - // output parameter values for this call - output_print_str(out, "\\n", "", indent); - output_print_str(out, f->name + "(", "", indent); - bool first = true; - for (i=0; iparam.size(); i++) { - const Variable* v = f->param[i]; - if (reducer->is_var_used(v)) { - if (!first) { - output_print_str(out, ", ", "", 0); - } - v->output_runtime_value(out, "", "", 0); - first = false; - } - } - output_print_str(out, ");\\n", "", indent); - output_close_encloser("}", out, indent); - outputln(out); - } - } -} - -void -ReducerOutputMgr::output_write_var_values(string title, const Statement* stm, std::ostream &out, FactMgr* fm, int indent, bool cover_block_writes) -{ - output_print_str(out, title, "", indent); - outputln(out); - size_t i; - const Statement* s = stm; - if (cover_block_writes) { - s = stm->parent; - assert(s); - } - const vector& write_vars = fm->map_stm_effect[s].get_write_vars(); - for (i=0; iis_visible(stm->parent) && reducer->is_var_used(wvar)) { - // output printf statements to record the type of the variable - ostringstream oss; - //wvar->OutputDecl(oss); - string dimen = StringUtils::int2str(wvar->get_dimension()); - oss << "<" << wvar->get_actual_name() << "(" << dimen << ")" << " = "; - wvar->output_runtime_value(out, oss.str(), ">\\n", indent); - outputln(out); - } - } - output_print_str(out, "end of values\\n", "", indent); - outputln(out); -} - -void -ReducerOutputMgr::output_memory_addrs(const Statement* stm, std::ostream& out, int indent) -{ - size_t i; - vector all_vars = VariableSelector::find_all_visible_vars(stm->parent); - //combine_variable_sets(beffect.get_read_vars(), beffect.get_write_vars(), all_vars); - //remove_field_vars(all_vars); - output_print_str(out, "begin memory dump \\n", "", indent); - outputln(out); - for (i=0; iis_var_used(v)) { - v->output_addressable_name(out, indent); - } - } - output_print_str(out, "end memory dump \\n", "", indent); - outputln(out); -} - -void -ReducerOutputMgr::output_global_values(string header, std::ostream& out, int indent) -{ - size_t i; - // dump values of global variables - // "begin global vars entering main \\n" - output_print_str(out, header, "", indent); - outputln(out); - for (i=0; iused_vars.size(); i++) { - const Variable* v = reducer->used_vars[i]; - if (v->is_global()) { - ostringstream oss; - string dimen = StringUtils::int2str(v->get_dimension()); - oss << "<" << v->get_actual_name() << "(" << dimen << ")" << " = "; - v->output_runtime_value(out, oss.str(), ">\\n", indent); - outputln(out); - } - } - output_print_str(out, "end of values\\n", "", indent); - outputln(out); -} - -void -ReducerOutputMgr::OutputStructUnions(ostream& out) -{ - size_t i; - for (i=0; iused_vars.size(); i++) { - const Type* t = reducer->used_vars[i]->type; - if (t->is_aggregate()) { - Type* type = Type::find_type(t); - assert(type); - OutputStructUnion(type, out); - } - } -} - -void -ReducerOutputMgr::output_artificial_globals(ostream& out) -{ - for (size_t i=0; iartificial_globals.size(); i++) { - out << reducer->artificial_globals[i] << ";" << endl; - } -} - -void -ReducerOutputMgr::output_tail(ostream& out) -{ - size_t i; - if (reducer->dump_block_entry || reducer->dump_all_block_info) { - out << "// all blocks: "; - // print from backward so the leaf blocks will be printed last - for (i=reducer->all_blks.size(); i>0; i--) { - out << StringUtils::int2str(reducer->all_blks[i-1]) << ", "; - } - out << endl; - } - if (reducer->drop_params && reducer->dump_dropped_params) { - out << "// all dropped parameters: "; - for (i=0; idropped_params.size(); i++) { - out << reducer->dropped_params[i]->name << ", "; - } - out << endl; - } -} - -void -ReducerOutputMgr::Output() -{ - // configure reducer - reducer->configure(); - - // find all the functions and variables that are used after reductions - const Function* main = reducer->main; - reducer->get_used_vars_and_funcs_and_labels(main->body, reducer->used_vars, reducer->used_funcs, reducer->used_labels); - reducer->expand_used_vars(); - - std::ostream &out = get_main_out(); - OutputStructUnions(out); - output_vars(*VariableSelector::GetGlobalVariables(), out, 0); - output_artificial_globals(out); - size_t i; - for (i=0; iused_funcs.size(); i++) { - output_func_header(reducer->used_funcs[i], out); - out << ";" << endl; - } - for (int j=reducer->used_funcs.size(); j>0; j--) { - const Function* f = reducer->used_funcs[j-1]; - outputln(out); - output_func(f, out); - outputln(out); - } - outputln(out); - output_main_func(out); - output_tail(out); -} - diff --git a/src/ReducerOutputMgr.h b/src/ReducerOutputMgr.h deleted file mode 100644 index 94807aec1..000000000 --- a/src/ReducerOutputMgr.h +++ /dev/null @@ -1,98 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef REDUCER_OUTPUT_MGR_H -#define REDUCER_OUTPUT_MGR_H - -#include -#include -#include -#include -#include "OutputMgr.h" -#include "util.h" - -class Reducer; -class FactMgr; -class Block; -class Function; -class Statement; -class StatementIf; -class Expression; -class FunctionInvocation; -class FunctionInvocationBinary; - -using namespace std; - -class ReducerOutputMgr : public OutputMgr { -public: - ReducerOutputMgr(); - virtual ~ReducerOutputMgr(); - virtual void OutputHeader(int argc, char *argv[], unsigned long seed); - virtual void Output(); - - virtual std::ostream &get_main_out(); - - void rewrite_func_call(const Statement* stm, const FunctionInvocation* invoke, string id, std::ostream& out, int indent); - int rewrite_func_calls(const Statement* stm, std::ostream &out, int indent); - void output_alt_exprs(const Statement* stm, std::ostream &out, int indent); - - void output_write_var_values(string title, const Statement* stm, std::ostream &out, FactMgr* fm, int indent, bool cover_block_writes=false); - void output_memory_addrs(const Statement* stm, std::ostream& out, int indent); - void output_global_values(string header, std::ostream& out, int indent); - void output_tail(ostream& out); - void output_crc_lines(std::ostream& out); - - void output_vars(const vector &vars, std::ostream &out, int indent); - void output_var(const Variable* v, std::ostream &out, int indent); - int output_func_header(const Function* f, std::ostream& out); - int output_main_func(std::ostream& out); - int output_func(const Function* f, std::ostream& out); - int output_funcs(std::ostream& out); - int output_block(const Block* blk, std::ostream& out, int indent, bool no_bracelet=false); - void output_if_stm(const StatementIf* si, std::ostream &out, int indent); - void output_reduced_stm(const Statement* stm, std::ostream &out, int indent); - void output_stm(const Statement* stm, std::ostream &out, FactMgr* fm, int indent); - void output_pre_stm_assigns(const Statement* stm, std::ostream &out, int indent); - void output_block_entry_msg(const Block* blk, std::ostream &out, int indent); - void output_pre_stm_values(const Statement* stm, std::ostream &out, FactMgr* fm, int indent); - void output_post_stm_values(const Statement* stm, std::ostream &out, FactMgr* fm, int indent); - void output_global_state_for_func(const Function* f, std::ostream &out, int indent); - void output_artificial_globals(ostream& out); - - virtual void OutputStructUnions(ostream& out); - void OutputGlobals(ostream& out); - -private: - void OutputGlobals(); - void limit_binarys(vector& binarys, vector& ids); - std::ofstream *ofile_; - Reducer* reducer; -}; - -#endif // REDUCER_OUTPUT_MGR_H diff --git a/src/SimpleDeltaRndNumGenerator.cpp b/src/SimpleDeltaRndNumGenerator.cpp deleted file mode 100644 index 6599dbf90..000000000 --- a/src/SimpleDeltaRndNumGenerator.cpp +++ /dev/null @@ -1,228 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -#ifdef WIN32 -#pragma warning(disable : 4786) /* Disable annoying warning messages */ -#endif -#include "SimpleDeltaRndNumGenerator.h" - -#include -#include -#include - -#include "CGOptions.h" -#include "Filter.h" -#include "SequenceFactory.h" -#include "Sequence.h" -#include "Error.h" -#include "RandomNumber.h" -#include "DefaultRndNumGenerator.h" -#include "DeltaMonitor.h" - -SimpleDeltaRndNumGenerator *SimpleDeltaRndNumGenerator::impl_ = 0; - -SimpleDeltaRndNumGenerator::SimpleDeltaRndNumGenerator(Sequence *concrete_seq) - : rand_depth_(0), - random_point_(0), - filter_depth_(0), - trace_string_(""), - seq_(concrete_seq) -{ - -} - -SimpleDeltaRndNumGenerator::~SimpleDeltaRndNumGenerator() -{ - SequenceFactory::destroy_sequences(); -} - -/* - * Singleton - */ -SimpleDeltaRndNumGenerator* -SimpleDeltaRndNumGenerator::make_rndnum_generator(const unsigned long /*seed*/) -{ - if (impl_) - return impl_; - - Sequence *seq = SequenceFactory::make_sequence(); - - seq->init_sequence(); - - impl_ = new SimpleDeltaRndNumGenerator(seq); - - //srand48(seed); - - impl_->random_point_ = SimpleDeltaRndNumGenerator::pure_rnd_upto(seq->sequence_length()); - - assert(impl_); - - return impl_; -} - -int -SimpleDeltaRndNumGenerator::random_choice (int bound, const Filter *f, const string *) -{ - assert(seq_); - - int rv = seq_->get_number(bound); - ++rand_depth_; - - if (rv == -1) { - Error::set_error(INVALID_SIMPLE_DELTA_SEQUENCE); - return -1; - } - - if (f) { - ++filter_depth_; - if (f->filter(rv)) { - Error::set_error(FILTER_ERROR); - return -1; - } - --filter_depth_; - } - switch_to_default_generator(); - return rv; -} - -/* - * - */ -void -SimpleDeltaRndNumGenerator::get_sequence(std::string &sequence) -{ - std::ostringstream ss; - seq_->get_sequence(ss); - sequence = ss.str(); -} - -std::string -SimpleDeltaRndNumGenerator::get_prefixed_name(const std::string &name) -{ - return name; -} - -/* - * Print the tracing information for debugging. - */ -std::string & -SimpleDeltaRndNumGenerator::trace_depth() -{ - return trace_string_; -} - -unsigned int -SimpleDeltaRndNumGenerator::rnd_upto(const unsigned int n, const Filter *f, const std::string *where) -{ - int x = random_choice(n, f, where); - assert(x == -1 || (x >= 0 && x < static_cast(n))); - return x; -} - -bool -SimpleDeltaRndNumGenerator::rnd_flipcoin(const unsigned int, const Filter *f, const std::string *where) -{ - int y = random_choice(2, f, where); - assert(y == -1 || (y >= 0 && y < 2)); - return y; -} - -unsigned long -SimpleDeltaRndNumGenerator::genrand(void) -{ - return AbsRndNumGenerator::genrand(); -} - -std::string -SimpleDeltaRndNumGenerator::RandomHexDigits( int num ) -{ - std::string str; - const char* hex1 = AbsRndNumGenerator::get_hex1(); - while (num--) { - int x = random_choice(16, NULL, NULL); - str += hex1[x]; - } - return str; -} - -std::string -SimpleDeltaRndNumGenerator::RandomDigits( int num ) -{ - std::string str; - const char* dec1 = AbsRndNumGenerator::get_dec1(); - while ( num-- ) - { - int x = random_choice(10, NULL, NULL); - str += dec1[x]; - } - - return str; -} - -unsigned int -SimpleDeltaRndNumGenerator::pure_rnd_upto(const unsigned int bound) -{ - assert(impl_); - return impl_->genrand() % bound; -} - -bool -SimpleDeltaRndNumGenerator::pure_rnd_flipcoin(const unsigned int p) -{ - assert(impl_); - bool rv = (impl_->genrand() % 100) < p; - return rv; -} - -void -SimpleDeltaRndNumGenerator::switch_to_default_generator() -{ - if (DeltaMonitor::no_delta_reduction() || rand_depth_ < impl_->random_point_ || impl_->filter_depth_ != 0) - return; - - //RNDNUM_GENERATOR old; - //old = RandomNumber::SwitchRndNumGenerator(rDefaultRndNumGenerator); - RandomNumber::SwitchRndNumGenerator(rDefaultRndNumGenerator); - DefaultRndNumGenerator *generator = dynamic_cast(RandomNumber::GetRndNumGenerator()); - generator->set_rand_depth(impl_->rand_depth_); -} - -void -SimpleDeltaRndNumGenerator::OutputStatistics(ostream &out) -{ - assert(impl_); - assert(impl_->seq_); - out << "/*" << std::endl; - out << "** This program was reduced by the simple delta reduction algorithm" << std::endl; -#ifdef WIN32 - out << "** at a random point " << (unsigned int)impl_->random_point_ << " with the sequence of length " << (unsigned int)impl_->seq_->sequence_length() << "." << std::endl; -#else - out << "** at a random point " << impl_->random_point_ << " with the sequence of length " << impl_->seq_->sequence_length() << "." << std::endl; -#endif - out << "*/" << std::endl; -} diff --git a/src/SimpleDeltaRndNumGenerator.h b/src/SimpleDeltaRndNumGenerator.h deleted file mode 100644 index 9e1b9eba7..000000000 --- a/src/SimpleDeltaRndNumGenerator.h +++ /dev/null @@ -1,99 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef SIMPLE_DELTA_RNDNUM_GENERATOR_H -#define SIMPLE_DELTA_RNDNUM_GENERATOR_H - -#include -#include - -#include "Common.h" -#include "CommonMacros.h" -#include "AbsRndNumGenerator.h" - -class Sequence; -class Filter; - -class SimpleDeltaRndNumGenerator : public AbsRndNumGenerator -{ -public: - virtual ~SimpleDeltaRndNumGenerator(); - - static SimpleDeltaRndNumGenerator *make_rndnum_generator(const unsigned long seed); - - static void OutputStatistics(ostream &out); - - virtual std::string get_prefixed_name(const std::string &name); - - virtual std::string& trace_depth(); - - virtual void get_sequence(std::string &sequence); - - virtual unsigned int rnd_upto(const unsigned int n, const Filter *f = NULL, const std::string *where = NULL); - - virtual bool rnd_flipcoin(const unsigned int p, const Filter *f = NULL, const std::string *where = NULL); - - virtual std::string RandomHexDigits( int num ); - - virtual std::string RandomDigits( int num ); - - virtual enum RNDNUM_GENERATOR kind() { return rSimpleDeltaRndNumGenerator; } - -private: - // ------------------------------------------------------------------------------------------ - SimpleDeltaRndNumGenerator(Sequence *concrete_seq); - - virtual unsigned long genrand(void); - - int random_choice(int bound, const Filter *f = NULL, const std::string *where = NULL); - - static unsigned int pure_rnd_upto(const unsigned int bound); - - static bool pure_rnd_flipcoin(const unsigned int p); - - void switch_to_default_generator(); - - // ---------------------------------------------------------------------------------------- - static SimpleDeltaRndNumGenerator *impl_; - - unsigned INT64 rand_depth_; - - unsigned INT64 random_point_; - - unsigned int filter_depth_; - - std::string trace_string_; - - Sequence *seq_; - - // disallow copy and assignment constructors - DISALLOW_COPY_AND_ASSIGN(SimpleDeltaRndNumGenerator); -}; - -#endif //SIMPLE_DELTA_RNDNUM_GENERATOR_H diff --git a/src/SimpleDeltaSequence.cpp b/src/SimpleDeltaSequence.cpp deleted file mode 100644 index e39a4feb1..000000000 --- a/src/SimpleDeltaSequence.cpp +++ /dev/null @@ -1,214 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#include "SimpleDeltaSequence.h" - -#include -#include -#include -#include -#include "SequenceLineParser.h" -#include "DeltaMonitor.h" -#include "CGOptions.h" - -using namespace std; - -// Represent the pair -class SimpleDeltaSequence::ValuePair -{ -public: - ValuePair(int value, int bound); - - ~ValuePair(); - - int get_value() const { return value_; } - - int get_bound() const { return bound_; } - - void set_value(int value) { value_ = value; } - - void set_bound(int bound) { bound_ = bound; } - - void set_value_bound(int value, int bound) { - value_ = value; - bound_ = bound; - } - -private: - int value_; - - int bound_; -}; - -SimpleDeltaSequence::ValuePair::ValuePair(int value, int bound) - : value_(value), - bound_(bound) -{ - -} - -SimpleDeltaSequence::ValuePair::~ValuePair( ) -{ - -} - -/////////////////////////////////////////////////////////////////// -const char SimpleDeltaSequence::default_sep_char = ','; - -SimpleDeltaSequence *SimpleDeltaSequence::impl_ = NULL; - -SimpleDeltaSequence::SimpleDeltaSequence(const char sep_char) - : sep_char_(sep_char), - current_pos_(0) -{ - // Nothing to do -} - -SimpleDeltaSequence::~SimpleDeltaSequence() -{ - // Nothing to do -} - -/* - * Create singleton instance. - */ -SimpleDeltaSequence* -SimpleDeltaSequence::CreateInstance(const char sep_char) -{ - if (impl_) - return impl_; - - impl_ = new SimpleDeltaSequence(sep_char); - assert(impl_); - - return impl_; -} - -/* - * - */ -bool -SimpleDeltaSequence::empty_line(const std::string &line) -{ - if (line.empty()) - return true; - size_t found = line.find_first_not_of("\t\n "); - return (found == string::npos); -} - -void -SimpleDeltaSequence::init_sequence() -{ - const std::string &fname = DeltaMonitor::get_input(); - assert(!fname.empty()); - - std::string line; - ifstream seqf(fname.c_str()); - assert("fail to open simple delta input file!" && seqf.is_open()); - - int i = 0; - while (!seqf.eof()) { - getline(seqf, line); - if (empty_line(line)) - continue; - std::vector v; - if(!SequenceLineParser >::parse_sequence(v, line, sep_char_)) - assert("bad simple delta input sequence!" && 0); - assert(v.size() == 2); - SimpleDeltaSequence::ValuePair *p = new SimpleDeltaSequence::ValuePair(v[0], v[1]); - sequence_[i] = p; - i++; - } - seqf.close(); -} - -void -SimpleDeltaSequence::add_number(int v, int bound, int k) -{ - SimpleDeltaSequence::ValuePair *p = new SimpleDeltaSequence::ValuePair(v, bound); - seq_map_[k] = p; -} - -int -SimpleDeltaSequence::get_number_by_pos(int /*pos*/) -{ - assert(0); - return 0; -} - -int -SimpleDeltaSequence::get_number(int bound) -{ - - SimpleDeltaSequence::ValuePair *p = sequence_[current_pos_]; - assert("SimpleDeltaSequence: get_number p is NULL!" && p); - int b = p->get_bound(); - assert("SimpleDeltaSequence: bound doesn't match!" && bound == b); - seq_map_[current_pos_] = p; - ++current_pos_; - return p->get_value(); -} - -void -SimpleDeltaSequence::clear() -{ - std::map::iterator i; - for (i = seq_map_.begin(); i != seq_map_.end(); ++i) { - assert((*i).second); - delete ((*i).second); - } - seq_map_.clear(); -} - -void SimpleDeltaSequence::output_one(ostream &out, - const SimpleDeltaSequence::ValuePair *p) -{ - assert(p); - int value = p->get_value(); - int bound = p->get_bound(); - out << value << sep_char_ << bound; - out << std::endl; -} - -void -SimpleDeltaSequence::get_sequence(ostream &out) -{ - assert(!seq_map_.empty()); - - std::map::iterator i; - for (i = seq_map_.begin(); i != seq_map_.end(); ++i) { - output_one(out, (*i).second); - } -} - -unsigned INT64 -SimpleDeltaSequence::sequence_length() -{ - return sequence_.size(); -} diff --git a/src/SimpleDeltaSequence.h b/src/SimpleDeltaSequence.h deleted file mode 100644 index d0ccc84ca..000000000 --- a/src/SimpleDeltaSequence.h +++ /dev/null @@ -1,84 +0,0 @@ -// -*- mode: C++ -*- -// -// Copyright (c) 2007, 2008, 2009, 2010, 2011 The University of Utah -// All rights reserved. -// -// This file is part of `csmith', a random generator of C programs. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef SIMPLE_DELTA_SEQUENCE_H -#define SIMPLE_DELTA_SEQUENCE_H - -#include -#include -#include -#include -#include "Common.h" -#include "Sequence.h" - -class SimpleDeltaSequence : public Sequence { -public: - static SimpleDeltaSequence *CreateInstance(const char sep_char); - - virtual ~SimpleDeltaSequence(); - - virtual void init_sequence(); - - virtual unsigned INT64 sequence_length(); - - virtual void add_number(int v, int bound, int k); - - virtual int get_number(int bound); - - virtual int get_number_by_pos(int pos); - - virtual void clear(); - - virtual void get_sequence(std::ostream &); - - virtual char get_sep_char() const { return sep_char_; } - - static const char default_sep_char; - -private: - class ValuePair; - - explicit SimpleDeltaSequence(const char sep_char); - - bool empty_line(const std::string &line); - - void output_one(std::ostream &out, const ValuePair *p); - - std::map seq_map_; - - std::map sequence_; - - static SimpleDeltaSequence *impl_; - - const char sep_char_; - - unsigned INT64 current_pos_; -}; - -#endif // SIMPLE_DELTA_SEQUENCE_H