<commit_before>#pragma once
#include <set>
#include <memory>
#include <iomanip>

#include "timing_analyzer_interfaces.hpp"
#include "TimingGraph.hpp"
#include "TimingTags.hpp"

float time_sec(struct timespec start, struct timespec end);

void print_histogram(const std::vector<float>& values, int nbuckets);

float relative_error(float A, float B);
void print_level_histogram(const TimingGraph& tg, int nbuckets);
void print_node_fanin_histogram(const TimingGraph& tg, int nbuckets);
void print_node_fanout_histogram(const TimingGraph& tg, int nbuckets);

void print_timing_graph(std::shared_ptr<const TimingGraph> tg);
void print_levelization(std::shared_ptr<const TimingGraph> tg);

std::set<NodeId> identify_constant_gen_fanout(const TimingGraph& tg);
std::set<NodeId> identify_clock_gen_fanout(const TimingGraph& tg);

void add_ff_clock_to_source_sink_edges(TimingGraph& timing_graph, const std::vector<BlockId> node_logical_blocks, std::vector<float>& edge_delays);
void dump_level_times(std::string fname, const TimingGraph& timing_graph, std::map<std::string,float> serial_prof_data, std::map<std::string,float> parallel_prof_data);

/*
 * Templated function implementations
 */

template<class DelayCalc>
void write_dot_file_setup(std::ostream& os, const TimingGraph& tg, std::shared_ptr<SetupTimingAnalyzer>& analyzer, const DelayCalc& delay_calc) {
    //Write out a dot file of the timing graph
    os << "digraph G {" <<std::endl;
    os << "\tnode[shape=record]" <<std::endl;

    for(const NodeId inode : tg.nodes()) {
        os << "\tnode" << inode;
        os << "[label=\"";
        os << "{#" << inode << " (" << tg.node_type(inode) << ")";
        auto data_tags = analyzer->get_setup_data_tags(inode);
        if(data_tags.num_tags() > 0) {
            for(const TimingTag& tag : data_tags) {
                os << " | {";
                os << "DATA - clk: " << tag.clock_domain();
                os << " launch: " << tag.launch_node();
                os << "\\n";
                os << " arr: " << tag.arr_time().value();
                os << " req: " << tag.req_time().value();
                os << "}";
            }
        }
        auto clock_tags = analyzer->get_setup_clock_tags(inode);
        if(clock_tags.num_tags() > 0) {
            for(const TimingTag& tag : clock_tags) {
                os << " | {";
                os << "CLOCK - clk: " << tag.clock_domain();
                os << " launch: " << tag.launch_node();
                os << "\\n";
                os << " arr: " << tag.arr_time().value();
                os << " req: " << tag.req_time().value();
                os << "}";
            }
        }
        os << "}\"]";
        os <<std::endl;
    }

    //Force drawing to be levelized
    for(const LevelId ilevel : tg.levels()) {
        os << "\t{rank = same;";

        for(NodeId node_id : tg.level(ilevel)) {
            os << " node" << node_id <<";";
        }
        os << "}" <<std::endl;
    }

    //Add edges with delays annoated
    for(const LevelId ilevel : tg.levels()) {
        for(NodeId node_id : tg.level_nodes(ilevel)) {
            for(int edge_idx = 0; edge_idx < tg.num_node_out_edges(node_id); edge_idx++) {
                EdgeId edge_id = tg.node_out_edge(node_id, edge_idx);

                NodeId sink_node_id = tg.edge_sink_node(edge_id);

                os << "\tnode" << node_id << " -> node" << sink_node_id;
                os << " [ label=\"" << delay_calc->max_edge_delay(tg, edge_id) << "\" ]";
                os << ";" <<std::endl;
            }
        }
    }

    os << "}" <<std::endl;
}

template<class DelayCalc>
void write_dot_file_hold(std::ostream& os, const TimingGraph& tg, std::shared_ptr<HoldTimingAnalyzer> analyzer, const DelayCalc& delay_calc) {
    //Write out a dot file of the timing graph
    os << "digraph G {" <<std::endl;
    os << "\tnode[shape=record]" <<std::endl;

    //Declare nodes and annotate tags
    for(const NodeId inode : tg.nodes()) {
        os << "\tnode" << inode;
        os << "[label=\"";
        os << "{#" << inode << " (" << tg.node_type(inode) << ")";
        auto data_tags = analyzer->get_hold_data_tags(inode);
        if(data_tags.num_tags() > 0) {
            for(const TimingTag& tag : data_tags) {
                os << " | {";
                os << "DATA - clk: " << tag.clock_domain();
                os << " launch: " << tag.launch_node();
                os << "\\n";
                os << " arr: " << tag.arr_time().value();
                os << " req: " << tag.req_time().value();
                os << "}";
            }
        }
        auto clock_tags = analyzer->get_hold_clock_tags(inode);
        if(clock_tags.num_tags() > 0) {
            for(const TimingTag& tag : clock_tags) {
                os << " | {";
                os << "CLOCK - clk: " << tag.clock_domain();
                os << " launch: " << tag.launch_node();
                os << "\\n";
                os << " arr: " << tag.arr_time().value();
                os << " req: " << tag.req_time().value();
                os << "}";
            }
        }
        os << "}\"]";
        os <<std::endl;
    }

    //Force drawing to be levelized
    for(const LevelId ilevel : tg.levels()) {
        os << "\t{rank = same;";

        for(NodeId node_id : tg.level_nodes(ilevel)) {
            os << " node" << node_id <<";";
        }
        os << "}" <<std::endl;
    }

    //Add edges with delays annoated
    for(const LevelId ilevel : tg.levels()) {
        for(NodeId node_id : tg.level_nodes(ilevel)) {
            for(int edge_idx = 0; edge_idx < tg.num_node_out_edges(node_id); edge_idx++) {
                EdgeId edge_id = tg.node_out_edge(node_id, edge_idx);

                NodeId sink_node_id = tg.edge_sink_node(edge_id);

                os << "\tnode" << node_id << " -> node" << sink_node_id;
                os << " [ label=\"" << delay_calc->min_edge_delay(tg, edge_id) << "\" ]";
                os << ";" <<std::endl;
            }
        }
    }

    os << "}" <<std::endl;
}

template<class Analyzer>
void print_setup_tags_histogram(const TimingGraph& tg, const std::shared_ptr<Analyzer> analyzer) {
    const int int_width = 8;
    const int flt_width = 2;

    auto totaler = [](int total, const std::map<int,int>::value_type& kv) {
        return total + kv.second;
    };

    std::cout << "Node Data Setup Tag Count Histogram:" << std::endl;
    std::map<int,int> data_tag_cnts;
    for(const NodeId i : tg.nodes()) {
        data_tag_cnts[analyzer->get_setup_data_tags(i).num_tags()]++;
    }

    int total_data_tags = std::accumulate(data_tag_cnts.begin(), data_tag_cnts.end(), 0, totaler);
    for(const auto& kv : data_tag_cnts) {
        std::cout << "\t" << kv.first << " Tags: " << std::setw(int_width) << kv.second << " (" << std::setw(flt_width) << std::fixed << (float) kv.second / total_data_tags << ")" << std::endl;
    }

    std::cout << "Node Clock Setup Tag Count Histogram:" << std::endl;
    std::map<int,int> clock_tag_cnts;
    for(const NodeId i : tg.nodes()) {
        clock_tag_cnts[analyzer->get_setup_clock_tags(i).num_tags()]++;
    }

    int total_clock_tags = std::accumulate(clock_tag_cnts.begin(), clock_tag_cnts.end(), 0, totaler);
    for(const auto& kv : clock_tag_cnts) {
        std::cout << "\t" << kv.first << " Tags: " << std::setw(int_width) << kv.second << " (" << std::setw(flt_width) << std::fixed << (float) kv.second / total_clock_tags << ")" << std::endl;
    }
}

template<class Analyzer>
void print_hold_tags_histogram(const TimingGraph& tg, const std::shared_ptr<Analyzer> analyzer) {
    const int int_width = 8;
    const int flt_width = 2;

    auto totaler = [](int total, const std::map<int,int>::value_type& kv) {
        return total + kv.second;
    };

    std::cout << "Node Data Hold Tag Count Histogram:" << std::endl;
    std::map<int,int> data_tag_cnts;
    for(const NodeId i : tg.nodes()) {
        data_tag_cnts[analyzer->get_hold_data_tags(i).num_tags()]++;
    }

    int total_data_tags = std::accumulate(data_tag_cnts.begin(), data_tag_cnts.end(), 0, totaler);
    for(const auto& kv : data_tag_cnts) {
        std::cout << "\t" << kv.first << " Tags: " << std::setw(int_width) << kv.second << " (" << std::setw(flt_width) << std::fixed << (float) kv.second / total_data_tags << ")" << std::endl;
    }

    std::cout << "Node Clock Hold Tag Count Histogram:" << std::endl;
    std::map<int,int> clock_tag_cnts;
    for(const NodeId i : tg.nodes()) {
        clock_tag_cnts[analyzer->get_hold_clock_tags(i).num_tags()]++;
    }

    int total_clock_tags = std::accumulate(clock_tag_cnts.begin(), clock_tag_cnts.end(), 0, totaler);
    for(const auto& kv : clock_tag_cnts) {
        std::cout << "\t" << kv.first << " Tags: " << std::setw(int_width) << kv.second << " (" << std::setw(flt_width) << std::fixed << (float) kv.second / total_clock_tags << ")" << std::endl;
    }
}

template<class Analyzer>
void print_setup_tags(const TimingGraph& tg, const std::shared_ptr<Analyzer> analyzer) {
    std::cout << std::endl;
    std::cout << "Setup Tags:" << std::endl;
    std::cout << std::scientific;
    for(const LevelId level_id : tg.levels()) {
        std::cout << "Level: " << level_id << std::endl;
        for(NodeId node_id : tg.level_nodes(level_id)) {
            std::cout << "Node: " << node_id << " (" << tg.node_type(node_id) << ")" << std::endl;;
            for(const TimingTag& tag : analyzer->get_setup_data_tags(node_id)) {
                std::cout << "\tData : ";
                std::cout << "  clk: " << tag.clock_domain();
                std::cout << "  Arr: " << tag.arr_time().value();
                std::cout << "  Req: " << tag.req_time().value();
                std::cout << std::endl;
            }
            for(const TimingTag& tag : analyzer->get_setup_clock_tags(node_id)) {
                std::cout << "\tClock: ";
                std::cout << "  clk: " << tag.clock_domain();
                std::cout << "  Arr: " << tag.arr_time().value();
                std::cout << "  Req: " << tag.req_time().value();
                std::cout << std::endl;
            }
        }
    }
    std::cout << std::endl;
}

template<class Analyzer>
void print_hold_tags(const TimingGraph& tg, const std::shared_ptr<Analyzer> analyzer) {
    std::cout << std::endl;
    std::cout << "Hold Tags:" << std::endl;
    std::cout << std::scientific;
    for(const LevelId level_id : tg.levels()) {
        std::cout << "Level: " << level_id << std::endl;
        for(NodeId node_id : tg.level_nodes(level_id)) {
            std::cout << "Node: " << node_id << " (" << tg.node_type(node_id) << ")" << std::endl;;
            for(const TimingTag& tag : analyzer->get_hold_data_tags(node_id)) {
                std::cout << "\tData : ";
                std::cout << "  clk: " << tag.clock_domain();
                std::cout << "  Arr: " << tag.arr_time().value();
                std::cout << "  Req: " << tag.req_time().value();
                std::cout << std::endl;
            }
            for(const TimingTag& tag : analyzer->get_hold_clock_tags(node_id)) {
                std::cout << "\tClock: ";
                std::cout << "  clk: " << tag.clock_domain();
                std::cout << "  Arr: " << tag.arr_time().value();
                std::cout << "  Req: " << tag.req_time().value();
                std::cout << std::endl;
            }
        }
    }
    std::cout << std::endl;
}

<commit_msg>Fix graph dot writer<commit_after>#pragma once
#include <set>
#include <memory>
#include <iomanip>

#include "timing_analyzer_interfaces.hpp"
#include "TimingGraph.hpp"
#include "TimingTags.hpp"

float time_sec(struct timespec start, struct timespec end);

void print_histogram(const std::vector<float>& values, int nbuckets);

float relative_error(float A, float B);
void print_level_histogram(const TimingGraph& tg, int nbuckets);
void print_node_fanin_histogram(const TimingGraph& tg, int nbuckets);
void print_node_fanout_histogram(const TimingGraph& tg, int nbuckets);

void print_timing_graph(std::shared_ptr<const TimingGraph> tg);
void print_levelization(std::shared_ptr<const TimingGraph> tg);

std::set<NodeId> identify_constant_gen_fanout(const TimingGraph& tg);
std::set<NodeId> identify_clock_gen_fanout(const TimingGraph& tg);

void add_ff_clock_to_source_sink_edges(TimingGraph& timing_graph, const std::vector<BlockId> node_logical_blocks, std::vector<float>& edge_delays);
void dump_level_times(std::string fname, const TimingGraph& timing_graph, std::map<std::string,float> serial_prof_data, std::map<std::string,float> parallel_prof_data);

/*
 * Templated function implementations
 */

template<class DelayCalc>
void write_dot_file_setup(std::ostream& os, const TimingGraph& tg, std::shared_ptr<SetupTimingAnalyzer>& analyzer, const DelayCalc& delay_calc) {
    //Write out a dot file of the timing graph
    os << "digraph G {" <<std::endl;
    os << "\tnode[shape=record]" <<std::endl;

    for(const NodeId inode : tg.nodes()) {
        os << "\tnode" << size_t(inode);
        os << "[label=\"";
        os << "{#" << inode << " (" << tg.node_type(inode) << ")";
        auto data_tags = analyzer->get_setup_data_tags(inode);
        if(data_tags.num_tags() > 0) {
            for(const TimingTag& tag : data_tags) {
                os << " | {";
                os << "DATA - clk: " << tag.clock_domain();
                os << " launch: " << tag.launch_node();
                os << "\\n";
                os << " arr: " << tag.arr_time().value();
                os << " req: " << tag.req_time().value();
                os << "}";
            }
        }
        auto clock_tags = analyzer->get_setup_clock_tags(inode);
        if(clock_tags.num_tags() > 0) {
            for(const TimingTag& tag : clock_tags) {
                os << " | {";
                os << "CLOCK - clk: " << tag.clock_domain();
                os << " launch: " << tag.launch_node();
                os << "\\n";
                os << " arr: " << tag.arr_time().value();
                os << " req: " << tag.req_time().value();
                os << "}";
            }
        }
        os << "}\"]";
        os <<std::endl;
    }

    //Force drawing to be levelized
    for(const LevelId ilevel : tg.levels()) {
        os << "\t{rank = same;";

        for(NodeId node_id : tg.level(ilevel)) {
            os << " node" << size_t(node_id) <<";";
        }
        os << "}" <<std::endl;
    }

    //Add edges with delays annoated
    for(const LevelId ilevel : tg.levels()) {
        for(NodeId node_id : tg.level_nodes(ilevel)) {
            for(int edge_idx = 0; edge_idx < tg.num_node_out_edges(node_id); edge_idx++) {
                EdgeId edge_id = tg.node_out_edge(node_id, edge_idx);

                NodeId sink_node_id = tg.edge_sink_node(edge_id);

                os << "\tnode" << size_t(node_id) << " -> node" << size_t(sink_node_id);
                os << " [ label=\"" << delay_calc->max_edge_delay(tg, edge_id) << "\" ]";
                os << ";" <<std::endl;
            }
        }
    }

    os << "}" <<std::endl;
}

template<class DelayCalc>
void write_dot_file_hold(std::ostream& os, const TimingGraph& tg, std::shared_ptr<HoldTimingAnalyzer> analyzer, const DelayCalc& delay_calc) {
    //Write out a dot file of the timing graph
    os << "digraph G {" <<std::endl;
    os << "\tnode[shape=record]" <<std::endl;

    //Declare nodes and annotate tags
    for(const NodeId inode : tg.nodes()) {
        os << "\tnode" << size_t(inode);
        os << "[label=\"";
        os << "{#" << inode << " (" << tg.node_type(inode) << ")";
        auto data_tags = analyzer->get_hold_data_tags(inode);
        if(data_tags.num_tags() > 0) {
            for(const TimingTag& tag : data_tags) {
                os << " | {";
                os << "DATA - clk: " << tag.clock_domain();
                os << " launch: " << tag.launch_node();
                os << "\\n";
                os << " arr: " << tag.arr_time().value();
                os << " req: " << tag.req_time().value();
                os << "}";
            }
        }
        auto clock_tags = analyzer->get_hold_clock_tags(inode);
        if(clock_tags.num_tags() > 0) {
            for(const TimingTag& tag : clock_tags) {
                os << " | {";
                os << "CLOCK - clk: " << tag.clock_domain();
                os << " launch: " << tag.launch_node();
                os << "\\n";
                os << " arr: " << tag.arr_time().value();
                os << " req: " << tag.req_time().value();
                os << "}";
            }
        }
        os << "}\"]";
        os <<std::endl;
    }

    //Force drawing to be levelized
    for(const LevelId ilevel : tg.levels()) {
        os << "\t{rank = same;";

        for(NodeId node_id : tg.level_nodes(ilevel)) {
            os << " node" << size_t(node_id) <<";";
        }
        os << "}" <<std::endl;
    }

    //Add edges with delays annoated
    for(const LevelId ilevel : tg.levels()) {
        for(NodeId node_id : tg.level_nodes(ilevel)) {
            for(int edge_idx = 0; edge_idx < tg.num_node_out_edges(node_id); edge_idx++) {
                EdgeId edge_id = tg.node_out_edge(node_id, edge_idx);

                NodeId sink_node_id = tg.edge_sink_node(edge_id);

                os << "\tnode" << size_t(node_id) << " -> node" << size_t(sink_node_id);
                os << " [ label=\"" << delay_calc->min_edge_delay(tg, edge_id) << "\" ]";
                os << ";" <<std::endl;
            }
        }
    }

    os << "}" <<std::endl;
}

template<class Analyzer>
void print_setup_tags_histogram(const TimingGraph& tg, const std::shared_ptr<Analyzer> analyzer) {
    const int int_width = 8;
    const int flt_width = 2;

    auto totaler = [](int total, const std::map<int,int>::value_type& kv) {
        return total + kv.second;
    };

    std::cout << "Node Data Setup Tag Count Histogram:" << std::endl;
    std::map<int,int> data_tag_cnts;
    for(const NodeId i : tg.nodes()) {
        data_tag_cnts[analyzer->get_setup_data_tags(i).num_tags()]++;
    }

    int total_data_tags = std::accumulate(data_tag_cnts.begin(), data_tag_cnts.end(), 0, totaler);
    for(const auto& kv : data_tag_cnts) {
        std::cout << "\t" << kv.first << " Tags: " << std::setw(int_width) << kv.second << " (" << std::setw(flt_width) << std::fixed << (float) kv.second / total_data_tags << ")" << std::endl;
    }

    std::cout << "Node Clock Setup Tag Count Histogram:" << std::endl;
    std::map<int,int> clock_tag_cnts;
    for(const NodeId i : tg.nodes()) {
        clock_tag_cnts[analyzer->get_setup_clock_tags(i).num_tags()]++;
    }

    int total_clock_tags = std::accumulate(clock_tag_cnts.begin(), clock_tag_cnts.end(), 0, totaler);
    for(const auto& kv : clock_tag_cnts) {
        std::cout << "\t" << kv.first << " Tags: " << std::setw(int_width) << kv.second << " (" << std::setw(flt_width) << std::fixed << (float) kv.second / total_clock_tags << ")" << std::endl;
    }
}

template<class Analyzer>
void print_hold_tags_histogram(const TimingGraph& tg, const std::shared_ptr<Analyzer> analyzer) {
    const int int_width = 8;
    const int flt_width = 2;

    auto totaler = [](int total, const std::map<int,int>::value_type& kv) {
        return total + kv.second;
    };

    std::cout << "Node Data Hold Tag Count Histogram:" << std::endl;
    std::map<int,int> data_tag_cnts;
    for(const NodeId i : tg.nodes()) {
        data_tag_cnts[analyzer->get_hold_data_tags(i).num_tags()]++;
    }

    int total_data_tags = std::accumulate(data_tag_cnts.begin(), data_tag_cnts.end(), 0, totaler);
    for(const auto& kv : data_tag_cnts) {
        std::cout << "\t" << kv.first << " Tags: " << std::setw(int_width) << kv.second << " (" << std::setw(flt_width) << std::fixed << (float) kv.second / total_data_tags << ")" << std::endl;
    }

    std::cout << "Node Clock Hold Tag Count Histogram:" << std::endl;
    std::map<int,int> clock_tag_cnts;
    for(const NodeId i : tg.nodes()) {
        clock_tag_cnts[analyzer->get_hold_clock_tags(i).num_tags()]++;
    }

    int total_clock_tags = std::accumulate(clock_tag_cnts.begin(), clock_tag_cnts.end(), 0, totaler);
    for(const auto& kv : clock_tag_cnts) {
        std::cout << "\t" << kv.first << " Tags: " << std::setw(int_width) << kv.second << " (" << std::setw(flt_width) << std::fixed << (float) kv.second / total_clock_tags << ")" << std::endl;
    }
}

template<class Analyzer>
void print_setup_tags(const TimingGraph& tg, const std::shared_ptr<Analyzer> analyzer) {
    std::cout << std::endl;
    std::cout << "Setup Tags:" << std::endl;
    std::cout << std::scientific;
    for(const LevelId level_id : tg.levels()) {
        std::cout << "Level: " << level_id << std::endl;
        for(NodeId node_id : tg.level_nodes(level_id)) {
            std::cout << "Node: " << node_id << " (" << tg.node_type(node_id) << ")" << std::endl;;
            for(const TimingTag& tag : analyzer->get_setup_data_tags(node_id)) {
                std::cout << "\tData : ";
                std::cout << "  clk: " << tag.clock_domain();
                std::cout << "  Arr: " << tag.arr_time().value();
                std::cout << "  Req: " << tag.req_time().value();
                std::cout << std::endl;
            }
            for(const TimingTag& tag : analyzer->get_setup_clock_tags(node_id)) {
                std::cout << "\tClock: ";
                std::cout << "  clk: " << tag.clock_domain();
                std::cout << "  Arr: " << tag.arr_time().value();
                std::cout << "  Req: " << tag.req_time().value();
                std::cout << std::endl;
            }
        }
    }
    std::cout << std::endl;
}

template<class Analyzer>
void print_hold_tags(const TimingGraph& tg, const std::shared_ptr<Analyzer> analyzer) {
    std::cout << std::endl;
    std::cout << "Hold Tags:" << std::endl;
    std::cout << std::scientific;
    for(const LevelId level_id : tg.levels()) {
        std::cout << "Level: " << level_id << std::endl;
        for(NodeId node_id : tg.level_nodes(level_id)) {
            std::cout << "Node: " << node_id << " (" << tg.node_type(node_id) << ")" << std::endl;;
            for(const TimingTag& tag : analyzer->get_hold_data_tags(node_id)) {
                std::cout << "\tData : ";
                std::cout << "  clk: " << tag.clock_domain();
                std::cout << "  Arr: " << tag.arr_time().value();
                std::cout << "  Req: " << tag.req_time().value();
                std::cout << std::endl;
            }
            for(const TimingTag& tag : analyzer->get_hold_clock_tags(node_id)) {
                std::cout << "\tClock: ";
                std::cout << "  clk: " << tag.clock_domain();
                std::cout << "  Arr: " << tag.arr_time().value();
                std::cout << "  Req: " << tag.req_time().value();
                std::cout << std::endl;
            }
        }
    }
    std::cout << std::endl;
}

<|endoftext|>


<commit_before>/*
 *            Copyright 2009-2016 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      Licensed under the Apache License, Version 2.0 (the "License")
 *
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *              http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <votca/xtp/threecenters.h>

using namespace votca::tools;

namespace votca {
    namespace xtp {
        namespace ub = boost::numeric::ublas;

        /*
         * Cleaning TCMatrix_dft data and free memory
         */
        void TCMatrix_dft::Cleanup() {

            for (unsigned _i = 0; _i < _matrix.size(); _i++) {
                _matrix[ _i ].resize(0, 0, false);
            }
            _matrix.clear();

        } // TCMatrix_dft::Cleanup

        void TCMatrix_dft::Fill(AOBasis& _auxbasis, AOBasis& _dftbasis) {

            for (int i=0; i< _auxbasis._AOBasisSize; i++){
                _matrix.push_back(ub::symmetric_matrix<double>(_dftbasis._AOBasisSize));

                for(unsigned k=0;k<_matrix[i].size1();k++){
                    for(unsigned j=0;j<_matrix[i].size2();j++){

                    _matrix[i](k,j)=0.0;
                }
                }
            }
            // loop over all shells in the GW basis and get _Mmn for that shell
            #pragma omp parallel for //private(_block)
            for ( unsigned _is= 0; _is <  _auxbasis._aoshells.size() ; _is++ ){
            // for (std::vector< AOShell* >::iterator _is = _gwbasis.firstShell(); _is != _gwbasis.lastShell(); _is++) {
                //cout << " act threads: " << omp_get_thread_num( ) << " total threads " << omp_get_num_threads( ) << " max threads " << omp_get_max_threads( ) <<endl;
                AOShell* _shell = _auxbasis.getShell(_is);

                // Fill block for this shell (3-center overlap with _dft_basis )
                FillBlock(_shell, _dftbasis);

            } // shells of aux basis set
            //for (int i=0;i<_matrix.size();i++){
                  //  cout<< "Matrix(" << i<<"):\n"<<_matrix[i]<< endl;

                //}
        } // TCMatrix_dft::Fill

        /*
         * Determines the 3-center integrals for a given shell in the aux basis
         * by calculating the 3-center overlap integral of the functions in the
         * aux shell with ALL functions in the DFT basis set (FillThreeCenterOLBlock)
         */

        void TCMatrix_dft::FillBlock(AOShell* _shell, AOBasis& dftbasis) {
	  //void TCMatrix_dft::FillBlock(std::vector< ub::matrix<float> >& _block, AOShell* _shell, AOBasis& dftbasis, ub::matrix<double>& _dft_orbitals) {

           int _start=_shell->getStartIndex();
           //cout << " FB start " << _start << endl;
            // alpha-loop over the "left" DFT basis function
            for (std::vector< AOShell* >::iterator _row = dftbasis.firstShell(); _row != dftbasis.lastShell(); _row++) {
                AOShell* _shell_row = dftbasis.getShell(_row);
                int _row_start = _shell_row->getStartIndex();
                //int _row_end = _row_start + _shell_row->getNumFunc();

                // gamma-loop over the "right" DFT basis function
                for (std::vector< AOShell* >::iterator _col = dftbasis.firstShell(); _col != dftbasis.lastShell(); _col++) {
                    AOShell* _shell_col = dftbasis.getShell(_col);
                    int _col_start = _shell_col->getStartIndex();
                    //int _col_end = _col_start + _shell_col->getNumFunc();

                    //symmetry
                    //if(_shell_col>_shell_row){ continue;}
                    // get 3-center overlap directly as _subvector
                    ub::matrix<double> _subvector = ub::zero_matrix<double>(_shell_row->getNumFunc(), _shell->getNumFunc() * _shell_col->getNumFunc());
                    //ub::matrix<float> _subvector = ub::zero_matrix<float>(_shell_row->getNumFunc(), _shell->getNumFunc() * _shell_col->getNumFunc());

                    //bool nonzero = FillThreeCenterOLBlock(_subvector, _shell, _shell_row, _shell_col);
                    bool nonzero=FillThreeCenterRepBlock(_subvector, _shell, _shell_row, _shell_col);

                    if (nonzero) {
                        // and put it into the block it belongs to
                        // functions in ONE AUXshell
                        for (int _aux = 0; _aux < _shell->getNumFunc(); _aux++) {
                                // column in ONE DFTshell
                                //for (int _i_col = 0; _i_col < _shell_col->getNumFunc(); _i_col++) {
                for (int _col = 0; _col < _shell_col->getNumFunc(); _col++) {
                                    //int _index=_shell_col->getNumFunc() * _aux + _i_col;
                                    int _index=_shell_col->getNumFunc() * _aux + _col;

                                             //for (int _i_row = 0; _i_row < _shell_row->getNumFunc(); _i_row++) {
                    for (int _row = 0; _row < _shell_row->getNumFunc(); _row++) {
                        //symmetry
                       // if(_col_start + _col>_row_start + _row){continue;}
                                                //cout << "MAGIC " << _start+_aux << " : " << _row_start + _i_row << " : " << _col_start + _i_col << endl;
                                                _matrix[_start+_aux](_row_start + _row, _col_start + _col) = _subvector(_row, _index);

                                                } // ROW copy
                                } // COL copy
                        } // AUX copy
                   }
                } // DFT col
            } // DFT row

        } // TCMatrix_dft::FillBlock

    }
}<commit_msg>symmetrie threecenter checked<commit_after>/*
 *            Copyright 2009-2016 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      Licensed under the Apache License, Version 2.0 (the "License")
 *
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *              http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <votca/xtp/threecenters.h>

using namespace votca::tools;

namespace votca {
    namespace xtp {
        namespace ub = boost::numeric::ublas;

        /*
         * Cleaning TCMatrix_dft data and free memory
         */
        void TCMatrix_dft::Cleanup() {

            for (unsigned _i = 0; _i < _matrix.size(); _i++) {
                _matrix[ _i ].resize(0, 0, false);
            }
            _matrix.clear();

        } // TCMatrix_dft::Cleanup

        void TCMatrix_dft::Fill(AOBasis& _auxbasis, AOBasis& _dftbasis) {

            for (int i=0; i< _auxbasis._AOBasisSize; i++){
                _matrix.push_back(ub::symmetric_matrix<double>(_dftbasis._AOBasisSize));

                for(unsigned k=0;k<_matrix[i].size1();k++){
                    for(unsigned j=0;j<_matrix[i].size2();j++){

                    _matrix[i](k,j)=0.0;
                }
                }
            }
            // loop over all shells in the GW basis and get _Mmn for that shell
            #pragma omp parallel for //private(_block)
            for ( unsigned _is= 0; _is <  _auxbasis._aoshells.size() ; _is++ ){
            // for (std::vector< AOShell* >::iterator _is = _gwbasis.firstShell(); _is != _gwbasis.lastShell(); _is++) {
                //cout << " act threads: " << omp_get_thread_num( ) << " total threads " << omp_get_num_threads( ) << " max threads " << omp_get_max_threads( ) <<endl;
                AOShell* _shell = _auxbasis.getShell(_is);

                // Fill block for this shell (3-center overlap with _dft_basis )
                FillBlock(_shell, _dftbasis);

            } // shells of aux basis set
            //for (int i=0;i<_matrix.size();i++){
                  //  cout<< "Matrix(" << i<<"):\n"<<_matrix[i]<< endl;
            for (unsigned i=0;i<_matrix.size();i++){
                 cout <<_matrix[i](0,1)<<" vs "<<_matrix[i](1,0)<<endl;
            }
                //}
        } // TCMatrix_dft::Fill

        /*
         * Determines the 3-center integrals for a given shell in the aux basis
         * by calculating the 3-center overlap integral of the functions in the
         * aux shell with ALL functions in the DFT basis set (FillThreeCenterOLBlock)
         */

        void TCMatrix_dft::FillBlock(AOShell* _shell, AOBasis& dftbasis) {
	  //void TCMatrix_dft::FillBlock(std::vector< ub::matrix<float> >& _block, AOShell* _shell, AOBasis& dftbasis, ub::matrix<double>& _dft_orbitals) {

           int _start=_shell->getStartIndex();
           //cout << " FB start " << _start << endl;
            // alpha-loop over the "left" DFT basis function
            for (std::vector< AOShell* >::iterator _row = dftbasis.firstShell(); _row != dftbasis.lastShell(); _row++) {
                AOShell* _shell_row = dftbasis.getShell(_row);
                int _row_start = _shell_row->getStartIndex();
                //int _row_end = _row_start + _shell_row->getNumFunc();

                // gamma-loop over the "right" DFT basis function
                for (std::vector< AOShell* >::iterator _col = dftbasis.firstShell(); _col != dftbasis.lastShell(); _col++) {
                    AOShell* _shell_col = dftbasis.getShell(_col);
                    int _col_start = _shell_col->getStartIndex();
                    //int _col_end = _col_start + _shell_col->getNumFunc();

                    //symmetry
                    if(_col>_row){continue;}
                    // get 3-center overlap directly as _subvector
                    ub::matrix<double> _subvector = ub::zero_matrix<double>(_shell_row->getNumFunc(), _shell->getNumFunc() * _shell_col->getNumFunc());
                    //ub::matrix<float> _subvector = ub::zero_matrix<float>(_shell_row->getNumFunc(), _shell->getNumFunc() * _shell_col->getNumFunc());

                    //bool nonzero = FillThreeCenterOLBlock(_subvector, _shell, _shell_row, _shell_col);
                    bool nonzero=FillThreeCenterRepBlock(_subvector, _shell, _shell_row, _shell_col);

                    if (nonzero) {
                        // and put it into the block it belongs to
                        // functions in ONE AUXshell
                        for (int _aux = 0; _aux < _shell->getNumFunc(); _aux++) {
                                // column in ONE DFTshell
                                //for (int _i_col = 0; _i_col < _shell_col->getNumFunc(); _i_col++) {
                for (int _col = 0; _col < _shell_col->getNumFunc(); _col++) {
                                    //int _index=_shell_col->getNumFunc() * _aux + _i_col;
                                    int _index=_shell_col->getNumFunc() * _aux + _col;

                                             //for (int _i_row = 0; _i_row < _shell_row->getNumFunc(); _i_row++) {
                    for (int _row = 0; _row < _shell_row->getNumFunc(); _row++) {
                        //symmetry
                        if((_col_start + _col)>(_row_start + _row)){continue;}
                                                //cout << "MAGIC " << _start+_aux << " : " << _row_start + _i_row << " : " << _col_start + _i_col << endl;
                                                _matrix[_start+_aux](_row_start + _row, _col_start + _col) = _subvector(_row, _index);

                                                } // ROW copy
                                } // COL copy
                        } // AUX copy
                   }
                } // DFT col
            } // DFT row

        } // TCMatrix_dft::FillBlock

    }
}<|endoftext|>


<commit_before>#include <cstdint>
#include <iostream>

#include "blip.h"
#include "chip8.h"
#include "qsfmlcanvas.h"
#include "emulatorcanvas.h"

EmulatorCanvas::EmulatorCanvas(QWidget* Parent, const QPoint& Position, const QSize& wSize, std::string filename) :
  QSFMLCanvas(Parent, Position, wSize),
  filename(filename)
  {
  }

void EmulatorCanvas::OnInit()
  {
    // graphics
    shape.setSize(sf::Vector2<float>(10, 10));
    shape.setFillColor(sf::Color::Green);

    // sound
    if (!buffer.loadFromMemory(blip.data(), blip.size()))
      std::cerr << "Could not load audio resources, continuing without!" << std::endl;
    sound.setBuffer(buffer);

    // rom data
    if (!emu.loadGame(filename)) {
      std::cerr << "File " << filename << " does not exist!" << std::endl;
      //return 1;
    }
  }

  void EmulatorCanvas::OnUpdate()
  {
    // poll events
    sf::Event event;
    while (sf::Window::pollEvent(event)) {
        if (event.type == sf::Event::Closed)
            sf::Window::close();
    }

    // get keys
    std::array<std::uint8_t, 16> keys;
    for (int i = 0; i < 16; i++)
      if (sf::Keyboard::isKeyPressed(layout[i]))
        keys[i] = 1;
      else
        keys[i] = 0;
    emu.setKeys(keys);

    // do cpu cycles
    emu.emulateCycle();

    // draw
    if (emu.drawFlag) {
      emu.drawFlag = false;
      sf::RenderWindow::clear(sf::Color(0,0,0,255));
      for (int x = 0; x < 64; x++)
        for (int y = 0; y < 32; y++)
          if (emu.gfx[x + y*64]) {
            shape.setPosition(x*10, y*10);
            sf::RenderWindow::draw(shape);
          }
    }

    // audio
    if(emu.beep)
      sound.play();
  }
<commit_msg>Some more code improvements in widgets<commit_after>#include <cstdint>
#include <iostream>

#include "res/blip.h"
#include "chip8.h"
#include "qsfmlcanvas.h"
#include "emulatorcanvas.h"

EmulatorCanvas::EmulatorCanvas(QWidget* Parent, const QPoint& Position, const QSize& wSize, std::string filename) :
  QSFMLCanvas(Parent, Position, wSize),
  filename(filename)
  {
  }

void EmulatorCanvas::OnInit()
  {
    // graphics
    shape.setSize(sf::Vector2<float>(10, 10));
    shape.setFillColor(sf::Color::Green);

    // sound
    if (!buffer.loadFromMemory(blip.data(), blip.size()))
      std::cerr << "Could not load audio resources, continuing without!" << std::endl;
    sound.setBuffer(buffer);

    // rom data
    if (!emu.loadGame(filename)) {
      std::cerr << "File " << filename << " does not exist!" << std::endl;
      //return 1;
    }
  }

  void EmulatorCanvas::OnUpdate()
  {
    // poll events
    sf::Event event;
    while (this->pollEvent(event)) {
      if (event.type == sf::Event::Closed) {
        this->sf::RenderWindow::close();
        return;
      }
    }

    // get keys
    std::array<std::uint8_t, 16> keys;
    for (int i = 0; i < 16; i++)
      if (sf::Keyboard::isKeyPressed(layout[i]))
        keys[i] = 1;
      else
        keys[i] = 0;
    emu.setKeys(keys);

    // do cpu cycles
    emu.emulateCycle();

    // draw
    if (emu.drawFlag) {
      emu.drawFlag = false;
      this->clear(sf::Color(0,0,0,255));
      for (int x = 0; x < 64; x++)
        for (int y = 0; y < 32; y++)
          if (emu.gfx[x + y*64]) {
            shape.setPosition(x*10, y*10);
            this->draw(shape);
          }
    }

    // audio
    if(emu.beep)
      sound.play();
  }
<|endoftext|>


<commit_before>/*
    Copyright 2012 Joe Hermaszewski. All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice,
    this list of conditions and the following disclaimer.

    2. 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 JOE HERMASZEWSKI "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 JOE HERMASZEWSKI 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.

    The views and conclusions contained in the software and documentation are
    those of the authors and should not be interpreted as representing official
    policies, either expressed or implied, of Joe Hermaszewski.
*/

#pragma once

#include <functional>
#include <memory>
#include <string>
#include <vector>

namespace JoeLang
{

class Effect;
class StateBase;

//TODO implement error collection
//TODO compile joemath to bc and call that
class Context
{
public:
    Context();
    ~Context();

    Effect* CreateEffectFromString( const std::string& string );
    Effect* CreateEffectFromFile(   const std::string& file_name );

    bool AddState( StateBase* state );
    const StateBase* GetNamedState( const std::string& name ) const;

    void SetErrorCallback( std::function<void(std::string)> error_callback );
    const std::function<void(std::string)>& GetErrorCallback() const;
private:
    std::vector<StateBase*>              m_states;
    std::vector<std::unique_ptr<Effect>> m_effects;

    std::function<void(std::string)>     m_errorCallback;
};

} // namespace JoeLang
<commit_msg>[~] whitespace<commit_after>/*
    Copyright 2012 Joe Hermaszewski. All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice,
    this list of conditions and the following disclaimer.

    2. 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 JOE HERMASZEWSKI "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 JOE HERMASZEWSKI 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.

    The views and conclusions contained in the software and documentation are
    those of the authors and should not be interpreted as representing official
    policies, either expressed or implied, of Joe Hermaszewski.
*/

#pragma once

#include <functional>
#include <memory>
#include <string>
#include <vector>

namespace JoeLang
{

class Effect;
class StateBase;

//TODO implement error collection
//TODO compile joemath to bc and call that
class Context
{
public:
    Context();
    ~Context();

    Effect* CreateEffectFromString( const std::string& string );
    Effect* CreateEffectFromFile(   const std::string& file_name );

    bool AddState( StateBase* state );
    const StateBase* GetNamedState( const std::string& name ) const;

    void SetErrorCallback( std::function<void(std::string)> error_callback );
    const std::function<void(std::string)>& GetErrorCallback() const;
private:
    std::vector<StateBase*>               m_states;
    std::vector<std::unique_ptr<Effect> > m_effects;

    std::function<void(std::string)>      m_errorCallback;
};

} // namespace JoeLang
<|endoftext|>


<commit_before>//
//#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <ctime>
#include <algorithm>
#include <cmath>
#include "GPIOClass.h"

using namespace std;

void Pulse(GPIOClass* pin, double cycles);
void Wait(double seconds);
clock_t timer;
double time_to_complete;
double resolution = 10000;

#define PI 4*atan(1)

int main (int argc, char *argv[]) {
	string type = argv[1];
	transform(type.begin(), type.end(), type.begin(), :: tolower);
	// lets assume that the way to run this is
	// pwm.exe [rising/falling/sine/constant]
	if (argc != 2) {
		cout << "Usage: pwm [rising/falling/sine/constant/blink]" << endl;
		return -1;
	}

	while (time_to_complete <= 0) {
		cout << "Input How Long To Run (in seconds)" << endl;
		cin >> time_to_complete;
	}

	GPIOClass* out1 = new GPIOClass("4");
	GPIOClass* in2 = new GPIOClass("17");

	out1->export_gpio();
	in2->export_gpio();

	out1->setdir_gpio("out");
	in2->setdir_gpio("in");

	cout << "Pins are setup." << endl;
	// avoiding flickering will be at 100hz
	// aka turn on and off 100 times a sec
	// a cycle of 0 is off
	// a cycle of 100 is on

	if (type == "rising") {
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		double t = time_to_complete;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
				t -= 1;
				//cout << sin((PI/2) * (1/t)) << endl;
				Pulse(out1, sin((PI/2) * (1/t)));
				Wait(sin((PI/2) * (1/t)));
		}
	}
	if (type == "falling") {

	}
	if (type == "sine") {

	}
	if (type == "constant") {
		out1->setval_gpio("1"); // turn the pin on
		Wait(time_to_complete); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		out1->setval_gpio("0"); // turn the pin off
	}
	if (type == "blink") { // aka. TESTR
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
			Pulse(out1, 1 * resolution);
			Wait(0.5);
		}
	}
	cout << "Done." << endl;
}

//1 cycle is 1/100th of a second
//100 cycles is 1 sec
void Pulse(GPIOClass* pin, double cycles) {
	bool running = true;
	while (running) {
		pin->setval_gpio("1"); // turn the pin on
		Wait(cycles / resolution); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		pin->setval_gpio("0"); // turn the pin off
		running = false; // this is unnessesary but could be useful if modified a bit.
	}
}

void Wait ( double seconds )
{
	clock_t endwait;
	endwait = clock () + seconds * CLOCKS_PER_SEC ;
	while (clock() < endwait) {}
}
<commit_msg>Update pwm.cpp<commit_after>//
//#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <ctime>
#include <algorithm>
#include <cmath>
#include "GPIOClass.h"

using namespace std;

void Pulse(GPIOClass* pin, double cycles);
void Wait(double seconds);
clock_t timer;
double time_to_complete;
double resolution = 100;

#define PI 4*atan(1)

int main (int argc, char *argv[]) {
	string type = argv[1];
	transform(type.begin(), type.end(), type.begin(), :: tolower);
	// lets assume that the way to run this is
	// pwm.exe [rising/falling/sine/constant]
	if (argc != 2) {
		cout << "Usage: pwm [rising/falling/sine/constant/blink]" << endl;
		return -1;
	}

	while (time_to_complete <= 0) {
		cout << "Input How Long To Run (in seconds)" << endl;
		cin >> time_to_complete;
	}

	GPIOClass* out1 = new GPIOClass("4");
	GPIOClass* in2 = new GPIOClass("17");

	out1->export_gpio();
	in2->export_gpio();

	out1->setdir_gpio("out");
	in2->setdir_gpio("in");

	cout << "Pins are setup." << endl;
	// avoiding flickering will be at 100hz
	// aka turn on and off 100 times a sec
	// a cycle of 0 is off
	// a cycle of 100 is on

	if (type == "rising") {
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		double t = time_to_complete;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
				t -= 1;
				//cout << sin((PI/2) * (1/t)) << endl;
				Pulse(out1, sin((PI/2) * (1/t)));
				Wait(sin((PI/2) * (1/t)));
		}
	}
	if (type == "falling") {

	}
	if (type == "sine") {

	}
	if (type == "constant") {
		out1->setval_gpio("1"); // turn the pin on
		Wait(time_to_complete); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		out1->setval_gpio("0"); // turn the pin off
	}
	if (type == "blink") { // aka. TESTR
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
			Pulse(out1, 1 * resolution);
			Wait(0.5);
		}
	}
	cout << "Done." << endl;
}

//1 cycle is 1/100th of a second
//100 cycles is 1 sec
void Pulse(GPIOClass* pin, double cycles) {
	bool running = true;
	while (running) {
		pin->setval_gpio("1"); // turn the pin on
		Wait(cycles / resolution); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		pin->setval_gpio("0"); // turn the pin off
		running = false; // this is unnessesary but could be useful if modified a bit.
	}
}

void Wait ( double seconds )
{
	clock_t endwait;
	endwait = clock () + seconds * CLOCKS_PER_SEC ;
	while (clock() < endwait) {}
}
<|endoftext|>


<commit_before>// @(#)root/utils:$Id$
// Author: Fons Rademakers   05/12/2003

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

// This program generates a map between class name and shared library.
// Its output is in TEnv format.
// Usage: rlibmap [-f] [-o <mapfile>] -l <sofile> -d <depsofiles>
//                 -c <linkdeffiles>
// -f: output full library path name (not needed when ROOT library
//     search path is used)
// -o: write output to specified file, otherwise to stdout
// -r: replace existing entries in the specified file
// -l: library containing the classes in the specified linkdef files
// -d: libraries on which the -l library depends
// -c: linkdef files containing the list of classes defined in the -l library

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string>
#include <string.h>
#include <vector>
#ifndef WIN32
#   include <unistd.h>
#else
#   define ssize_t int
#   include <io.h>
#   include <sys/types.h>
#endif

#ifdef __APPLE__
#include <AvailabilityMacros.h>
#endif
#if (defined(__FreeBSD__) && (__FreeBSD__ < 4)) || defined(__OpenBSD__) || \
    (defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_10_3) || \
     (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3)))
#include <sys/file.h>
#define lockf(fd, op, sz)   flock((fd), (op))
#ifndef F_LOCK
#define F_LOCK             (LOCK_EX | LOCK_NB)
#endif
#ifndef F_ULOCK
#define F_ULOCK             LOCK_UN
#endif
#endif

#if defined(__CYGWIN__) && defined(__GNUC__)
#define F_LOCK F_WRLCK
#define F_ULOCK F_UNLCK
static int fcntl_lockf(int fd, int op, off_t off)
{
   flock fl;
   fl.l_whence = SEEK_SET;
   fl.l_start  = off;
   fl.l_len    = 0;       // whole file
   fl.l_pid    = getpid();
   fl.l_type   = op;
   return fcntl(fd, F_SETLK, &fl);
}
#define lockf fcntl_lockf
#endif

const char *usage = "Usage: %s [-f] [<-r|-o> <mapfile>] -l <sofile> -d <depsofiles> -c <linkdeffiles>\n";

namespace std {}
using namespace std;

#ifdef WIN32
#include <windows.h>
#include <errno.h>

#define ftruncate(fd, size)  win32_ftruncate(fd, size)

//______________________________________________________________________________
int win32_ftruncate(int fd, ssize_t size)
{
   HANDLE hfile;
   int curpos;

   if (fd < 0) return -1;

   hfile = (HANDLE) _get_osfhandle(fd);
   curpos = ::SetFilePointer(hfile, 0, 0, FILE_CURRENT);
   if (curpos == 0xFFFFFFFF ||
       ::SetFilePointer(hfile, size, 0, FILE_BEGIN) == 0xFFFFFFFF ||
       !::SetEndOfFile(hfile)) {
         int error = ::GetLastError();

      switch (error) {
         case ERROR_INVALID_HANDLE:
            errno = EBADF;
            break;
         default:
            errno = EIO;
         break;
      }
      return -1;
   }
   return 0;
}

#endif // WIN32

//______________________________________________________________________________
char *Compress(const char *str)
{
   // Remove all blanks from the string str. The returned string has to be
   // deleted by the user.

   static const char* composedTypes[] = {"const ", "signed ","unsigned "};
   static unsigned int composedTypesLen[] = {6, 7, 9};

   if (!str) return 0;

   const char *p = str;
   // allocate 20 extra characters in case of eg, vector<vector<T>>
   char *s, *s1 = new char[strlen(str)+20];
   s = s1;

   while (*p) {
      if (*p != ' ') {
         for (unsigned int i = 0; i < sizeof(composedTypes) / sizeof(char*); ++i) {
            if (!strncmp(p, composedTypes[i], composedTypesLen[i])
                && (p == str || !isalnum(p[-1]))) {
               // the last one will be copied after the for loop
               memcpy(s, composedTypes[i], composedTypesLen[i] - 1);
               p += composedTypesLen[i] - 1;
               s += composedTypesLen[i] - 1;
               continue;
            }
         }
         *s++ = *p;
      }
      p++;
   }
   *s = '\0';

   return s1;
}

//______________________________________________________________________________
void UnCompressTemplate(char*& str)
{
   // Replace ">>" by "> >" except for operator>>.
   // str might be changed; the old string gets deleted in here.

   // Even handles cases like "A<B<operator>>()>>::operator >>()".

   char* pos = strstr(str, ">>");
   char* fixed = 0;
   int countgtgt = 0;
   while (pos) {
      // first run: just count, so we can allocate space for fixed
      ++countgtgt;
      pos = strstr(pos+1, ">>");
   }
   if (!countgtgt)
      return;
   pos = strstr(str, ">>");
   while (pos && pos > str) {
      bool isop = false;
      // check that it's not op>>:
      if (pos - str >= 8) {
         char* posop = pos - 1;
         // remove spaces in front of ">>":
         while (posop >= str && *posop == ' ')
            --posop;
         if (!strncmp("operator", posop - 7, 8)) {
            // it is an operator!
            isop = true;
         }
      }
      if (!isop) {
         // not an operator; we need to add a space.
         if (!fixed) {
            fixed = new char[strlen(str) + countgtgt + 1];
            strcpy(fixed, str);
         }
         fixed[pos - str + 1] = ' ';
         strcpy(fixed + (pos - str) + 2, pos + 1);
      }
      pos = strstr(pos + 1, ">>");
   }
   delete [] str;
   str = fixed;
}

//______________________________________________________________________________
int RemoveLib(const string &solib, bool fullpath, FILE *fp)
{
   // Remove entries from the map file for the specified solib.

   fseek(fp, 0, SEEK_SET);

   // get file size
   struct stat sbuf;
   fstat(fileno(fp), &sbuf);
   size_t siz = sbuf.st_size;

   if (!siz) return 0;

   const char *libbase = solib.c_str();
   if (!fullpath) {
      if ((libbase = strrchr(libbase, '/')))
         libbase++;
   }

   // read file and remove lines matching specified libs
   char *fbuf = new char[siz+1];
   char *fptr = fbuf;

   while (fgets(fptr, 1+siz - size_t(fptr-fbuf), fp)) {

      char *line = new char[strlen(fptr)+1];
      strcpy(line, fptr);
      strtok(line, " ");
      char *lib = strtok(0, " \n");
      if (lib && strcmp(lib, libbase)) {
         fptr += strlen(fptr);
         if (*(fptr-1) != '\n') {
            *fptr = '\n';
            fptr++;
         }
      }
      delete [] line;

      // fgets() should return 0 in this case but doesn't
      if ( (siz - size_t(fptr - fbuf)) <= 0)
         break;
   }

   ftruncate(fileno(fp), 0);

   // write remaining lines back
   if (fptr != fbuf) {
      fseek(fp, 0, SEEK_SET);
      fwrite(fbuf, 1, size_t(fptr-fbuf), fp);
   }

   delete [] fbuf;

   fseek(fp, 0, SEEK_END);

   return 0;
}

//______________________________________________________________________________
int LibMap(const string &solib, const vector<string> &solibdeps,
           const vector<string> &linkdefs, bool fullpath, FILE *fp)
{
   // Write libmap. Returns -1 in case of error.

   vector<string> classes;

   vector<string>::const_iterator lk;
   for (lk = linkdefs.begin(); lk != linkdefs.end(); lk++) {
      const char *linkdef = lk->c_str();
      FILE *lfp;
      char pragma[1024];
      if ((lfp = fopen(linkdef, "r"))) {
         while (fgets(pragma, 1024, lfp)) {
            if (strcmp(strtok(pragma, " "), "#pragma")) continue;
            const char* linkOrCreate = strtok(0, " ");
            bool pragmaLink = (!strcmp(linkOrCreate, "link") &&
                               !strcmp(strtok(0, " "), "C++"));
            bool pragmaCreate = (!strcmp(linkOrCreate, "create") &&
                                 !strcmp(strtok(0," "), "TClass"));

            if (pragmaLink || pragmaCreate) {
               const char *type = pragmaLink ? strtok(0, " ") : "class";
               if (!strncmp(type, "option=", 7) || !strncmp(type, "options=", 8)) {
                  if (strstr(type, "nomap"))
                     continue;
                  type = strtok(0, " ");
               }
               //the following statement had to be commented. Currently CINT
               //cannot autoload when executing a typedef (must be fixed!!!)
               //if (!strncmp(type, "class", 5) || !strcmp(type, "typedef")) {
               // handles class, class+protected and class+private
               if (!strncmp(type, "class", 5)) {
                  char *cls = strtok(0, "-!+;");
                  // just in case remove trailing space and tab
                  while (*cls == ' ') cls++;
                  int len = strlen(cls) - 1;
                  while (cls[len] == ' ' || cls[len] == '\t')
                     cls[len--] = '\0';
                  //no space between tmpl arguments allowed
                  cls = Compress(cls);
                  // except for A<B<C> >!
                  UnCompressTemplate(cls);

                  // don't include "vector<string>" and "std::pair<" classes
                  if (!strncmp(cls, "vector<string>", 14) ||
                      !strncmp(cls, "std::pair<", 10))
                     continue;

                  // replace "::" by "@@" since TEnv uses ":" as delimeter
                  char *s = cls;
                  while (*s) {
                     if (*s == ':')
                        *s = '@';
                     else if (*s == ' ')
                        *s = '-';
                     s++;
                  }
                  classes.push_back(cls);
               }
            }
         }
         fclose(lfp);
      } else {
         fprintf(stderr, "cannot open linkdef file %s\n", linkdef);
      }
   }

   const char *libbase = solib.c_str();
   if (!fullpath) {
      if ((libbase = strrchr(libbase, '/')))
         libbase++;
      else
         libbase = solib.c_str();
   }

   vector<string>::const_iterator it;
   for (it = classes.begin(); it != classes.end(); it++) {
      fprintf(fp, "Library.%-35s %s", ((*it)+":").c_str(), libbase);

      if (solibdeps.size() > 0) {
         vector<string>::const_iterator depit;
         for (depit = solibdeps.begin(); depit != solibdeps.end(); depit++) {
            const char *deplib = depit->c_str();
            if (!fullpath) {
               if ((deplib = strrchr(deplib, '/')))
                  deplib++;
               else
                  deplib = depit->c_str();
            }
            fprintf(fp, " %s", deplib);
         }
      }
      fprintf(fp, "\n");
   }

   return 0;
}

//______________________________________________________________________________
int main(int argc, char **argv)
{
   string         solib;
   vector<string> solibdeps;
   vector<string> linkdefs;
   bool fullpath = false;
   bool replace  = false;
   FILE *fp      = stdout;

   if (argc > 1) {
      int ic = 1;
      if (!strcmp(argv[ic], "-?") || !strcmp(argv[ic], "-h")) {
         fprintf(stderr, usage, argv[0]);
         return 1;
      }
      if (!strcmp(argv[ic], "-f")) {
         fullpath = true;
         ic++;
      }
      if (!strcmp(argv[ic], "-o")) {
         ic++;
         fp = fopen(argv[ic], "w");
         if (!fp) {
            fprintf(stderr, "cannot open output file %s\n", argv[ic]);
            return 1;
         }
         ic++;
      }
      if (!strcmp(argv[ic], "-r")) {
         replace = true;
         ic++;
         fp = fopen(argv[ic], "a+");
         if (!fp) {
            fprintf(stderr, "cannot open output file %s\n", argv[ic]);
            return 1;
         }
         ic++;
      }
      if (!strcmp(argv[ic], "-l")) {
         ic++;
         solib = argv[ic];
#ifdef __APPLE__
         string::size_type i = solib.find(".dylib");
         if (i != string::npos)
            solib.replace(i, 6, ".so");
#endif
         ic++;
      }
      if (!strcmp(argv[ic], "-d")) {
         ic++;
         for (int i = ic; i < argc && argv[i][0] != '-'; i++) {
            string dl = argv[i];
#ifdef __APPLE__
            string::size_type j = dl.find(".dylib");
            if (j != string::npos)
               dl.replace(j, 6, ".so");
#endif
            solibdeps.push_back(dl);
            ic++;
         }
      }
      if (!strcmp(argv[ic], "-c")) {
         ic++;
         for (int i = ic; i < argc; i++) {
            linkdefs.push_back(argv[i]);
            ic++;
         }
      }
   } else {
      fprintf(stderr, usage, argv[0]);
      return 1;
   }

   if (replace) {
#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
    !defined(__OpenBSD__)
      // lock file
      if (lockf(fileno(fp), F_LOCK, (off_t)1) == -1) {
         fprintf(stderr, "rlibmap: locking failed, don't use gmake -j\n");
      }
#endif

      // remove entries for solib to be processed
      RemoveLib(solib, fullpath, fp);
   }

   LibMap(solib, solibdeps, linkdefs, fullpath, fp);

   if (replace) {
#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
    !defined(__OpenBSD__)
      // remove lock
      lseek(fileno(fp), 0, SEEK_SET);
      if (lockf(fileno(fp), F_ULOCK, (off_t)1) == -1) {
         //fprintf(stderr, "rlibmap: error unlocking output file\n");
      }
#endif
   }

   if (fp != stdout)
      fclose(fp);

   return 0;
}
<commit_msg>Add #include needed by gcc 3.2<commit_after>// @(#)root/utils:$Id$
// Author: Fons Rademakers   05/12/2003

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

// This program generates a map between class name and shared library.
// Its output is in TEnv format.
// Usage: rlibmap [-f] [-o <mapfile>] -l <sofile> -d <depsofiles>
//                 -c <linkdeffiles>
// -f: output full library path name (not needed when ROOT library
//     search path is used)
// -o: write output to specified file, otherwise to stdout
// -r: replace existing entries in the specified file
// -l: library containing the classes in the specified linkdef files
// -d: libraries on which the -l library depends
// -c: linkdef files containing the list of classes defined in the -l library

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cctype>
#include <string>
#include <string.h>
#include <vector>
#ifndef WIN32
#   include <unistd.h>
#else
#   define ssize_t int
#   include <io.h>
#   include <sys/types.h>
#endif

#ifdef __APPLE__
#include <AvailabilityMacros.h>
#endif
#if (defined(__FreeBSD__) && (__FreeBSD__ < 4)) || defined(__OpenBSD__) || \
    (defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_10_3) || \
     (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3)))
#include <sys/file.h>
#define lockf(fd, op, sz)   flock((fd), (op))
#ifndef F_LOCK
#define F_LOCK             (LOCK_EX | LOCK_NB)
#endif
#ifndef F_ULOCK
#define F_ULOCK             LOCK_UN
#endif
#endif

#if defined(__CYGWIN__) && defined(__GNUC__)
#define F_LOCK F_WRLCK
#define F_ULOCK F_UNLCK
static int fcntl_lockf(int fd, int op, off_t off)
{
   flock fl;
   fl.l_whence = SEEK_SET;
   fl.l_start  = off;
   fl.l_len    = 0;       // whole file
   fl.l_pid    = getpid();
   fl.l_type   = op;
   return fcntl(fd, F_SETLK, &fl);
}
#define lockf fcntl_lockf
#endif

const char *usage = "Usage: %s [-f] [<-r|-o> <mapfile>] -l <sofile> -d <depsofiles> -c <linkdeffiles>\n";

namespace std {}
using namespace std;

#ifdef WIN32
#include <windows.h>
#include <errno.h>

#define ftruncate(fd, size)  win32_ftruncate(fd, size)

//______________________________________________________________________________
int win32_ftruncate(int fd, ssize_t size)
{
   HANDLE hfile;
   int curpos;

   if (fd < 0) return -1;

   hfile = (HANDLE) _get_osfhandle(fd);
   curpos = ::SetFilePointer(hfile, 0, 0, FILE_CURRENT);
   if (curpos == 0xFFFFFFFF ||
       ::SetFilePointer(hfile, size, 0, FILE_BEGIN) == 0xFFFFFFFF ||
       !::SetEndOfFile(hfile)) {
         int error = ::GetLastError();

      switch (error) {
         case ERROR_INVALID_HANDLE:
            errno = EBADF;
            break;
         default:
            errno = EIO;
         break;
      }
      return -1;
   }
   return 0;
}

#endif // WIN32

//______________________________________________________________________________
char *Compress(const char *str)
{
   // Remove all blanks from the string str. The returned string has to be
   // deleted by the user.

   static const char* composedTypes[] = {"const ", "signed ","unsigned "};
   static unsigned int composedTypesLen[] = {6, 7, 9};

   if (!str) return 0;

   const char *p = str;
   // allocate 20 extra characters in case of eg, vector<vector<T>>
   char *s, *s1 = new char[strlen(str)+20];
   s = s1;

   while (*p) {
      if (*p != ' ') {
         for (unsigned int i = 0; i < sizeof(composedTypes) / sizeof(char*); ++i) {
            if (!strncmp(p, composedTypes[i], composedTypesLen[i])
                && (p == str || !isalnum(p[-1]))) {
               // the last one will be copied after the for loop
               memcpy(s, composedTypes[i], composedTypesLen[i] - 1);
               p += composedTypesLen[i] - 1;
               s += composedTypesLen[i] - 1;
               continue;
            }
         }
         *s++ = *p;
      }
      p++;
   }
   *s = '\0';

   return s1;
}

//______________________________________________________________________________
void UnCompressTemplate(char*& str)
{
   // Replace ">>" by "> >" except for operator>>.
   // str might be changed; the old string gets deleted in here.

   // Even handles cases like "A<B<operator>>()>>::operator >>()".

   char* pos = strstr(str, ">>");
   char* fixed = 0;
   int countgtgt = 0;
   while (pos) {
      // first run: just count, so we can allocate space for fixed
      ++countgtgt;
      pos = strstr(pos+1, ">>");
   }
   if (!countgtgt)
      return;
   pos = strstr(str, ">>");
   while (pos && pos > str) {
      bool isop = false;
      // check that it's not op>>:
      if (pos - str >= 8) {
         char* posop = pos - 1;
         // remove spaces in front of ">>":
         while (posop >= str && *posop == ' ')
            --posop;
         if (!strncmp("operator", posop - 7, 8)) {
            // it is an operator!
            isop = true;
         }
      }
      if (!isop) {
         // not an operator; we need to add a space.
         if (!fixed) {
            fixed = new char[strlen(str) + countgtgt + 1];
            strcpy(fixed, str);
         }
         fixed[pos - str + 1] = ' ';
         strcpy(fixed + (pos - str) + 2, pos + 1);
      }
      pos = strstr(pos + 1, ">>");
   }
   delete [] str;
   str = fixed;
}

//______________________________________________________________________________
int RemoveLib(const string &solib, bool fullpath, FILE *fp)
{
   // Remove entries from the map file for the specified solib.

   fseek(fp, 0, SEEK_SET);

   // get file size
   struct stat sbuf;
   fstat(fileno(fp), &sbuf);
   size_t siz = sbuf.st_size;

   if (!siz) return 0;

   const char *libbase = solib.c_str();
   if (!fullpath) {
      if ((libbase = strrchr(libbase, '/')))
         libbase++;
   }

   // read file and remove lines matching specified libs
   char *fbuf = new char[siz+1];
   char *fptr = fbuf;

   while (fgets(fptr, 1+siz - size_t(fptr-fbuf), fp)) {

      char *line = new char[strlen(fptr)+1];
      strcpy(line, fptr);
      strtok(line, " ");
      char *lib = strtok(0, " \n");
      if (lib && strcmp(lib, libbase)) {
         fptr += strlen(fptr);
         if (*(fptr-1) != '\n') {
            *fptr = '\n';
            fptr++;
         }
      }
      delete [] line;

      // fgets() should return 0 in this case but doesn't
      if ( (siz - size_t(fptr - fbuf)) <= 0)
         break;
   }

   ftruncate(fileno(fp), 0);

   // write remaining lines back
   if (fptr != fbuf) {
      fseek(fp, 0, SEEK_SET);
      fwrite(fbuf, 1, size_t(fptr-fbuf), fp);
   }

   delete [] fbuf;

   fseek(fp, 0, SEEK_END);

   return 0;
}

//______________________________________________________________________________
int LibMap(const string &solib, const vector<string> &solibdeps,
           const vector<string> &linkdefs, bool fullpath, FILE *fp)
{
   // Write libmap. Returns -1 in case of error.

   vector<string> classes;

   vector<string>::const_iterator lk;
   for (lk = linkdefs.begin(); lk != linkdefs.end(); lk++) {
      const char *linkdef = lk->c_str();
      FILE *lfp;
      char pragma[1024];
      if ((lfp = fopen(linkdef, "r"))) {
         while (fgets(pragma, 1024, lfp)) {
            if (strcmp(strtok(pragma, " "), "#pragma")) continue;
            const char* linkOrCreate = strtok(0, " ");
            bool pragmaLink = (!strcmp(linkOrCreate, "link") &&
                               !strcmp(strtok(0, " "), "C++"));
            bool pragmaCreate = (!strcmp(linkOrCreate, "create") &&
                                 !strcmp(strtok(0," "), "TClass"));

            if (pragmaLink || pragmaCreate) {
               const char *type = pragmaLink ? strtok(0, " ") : "class";
               if (!strncmp(type, "option=", 7) || !strncmp(type, "options=", 8)) {
                  if (strstr(type, "nomap"))
                     continue;
                  type = strtok(0, " ");
               }
               //the following statement had to be commented. Currently CINT
               //cannot autoload when executing a typedef (must be fixed!!!)
               //if (!strncmp(type, "class", 5) || !strcmp(type, "typedef")) {
               // handles class, class+protected and class+private
               if (!strncmp(type, "class", 5)) {
                  char *cls = strtok(0, "-!+;");
                  // just in case remove trailing space and tab
                  while (*cls == ' ') cls++;
                  int len = strlen(cls) - 1;
                  while (cls[len] == ' ' || cls[len] == '\t')
                     cls[len--] = '\0';
                  //no space between tmpl arguments allowed
                  cls = Compress(cls);
                  // except for A<B<C> >!
                  UnCompressTemplate(cls);

                  // don't include "vector<string>" and "std::pair<" classes
                  if (!strncmp(cls, "vector<string>", 14) ||
                      !strncmp(cls, "std::pair<", 10))
                     continue;

                  // replace "::" by "@@" since TEnv uses ":" as delimeter
                  char *s = cls;
                  while (*s) {
                     if (*s == ':')
                        *s = '@';
                     else if (*s == ' ')
                        *s = '-';
                     s++;
                  }
                  classes.push_back(cls);
               }
            }
         }
         fclose(lfp);
      } else {
         fprintf(stderr, "cannot open linkdef file %s\n", linkdef);
      }
   }

   const char *libbase = solib.c_str();
   if (!fullpath) {
      if ((libbase = strrchr(libbase, '/')))
         libbase++;
      else
         libbase = solib.c_str();
   }

   vector<string>::const_iterator it;
   for (it = classes.begin(); it != classes.end(); it++) {
      fprintf(fp, "Library.%-35s %s", ((*it)+":").c_str(), libbase);

      if (solibdeps.size() > 0) {
         vector<string>::const_iterator depit;
         for (depit = solibdeps.begin(); depit != solibdeps.end(); depit++) {
            const char *deplib = depit->c_str();
            if (!fullpath) {
               if ((deplib = strrchr(deplib, '/')))
                  deplib++;
               else
                  deplib = depit->c_str();
            }
            fprintf(fp, " %s", deplib);
         }
      }
      fprintf(fp, "\n");
   }

   return 0;
}

//______________________________________________________________________________
int main(int argc, char **argv)
{
   string         solib;
   vector<string> solibdeps;
   vector<string> linkdefs;
   bool fullpath = false;
   bool replace  = false;
   FILE *fp      = stdout;

   if (argc > 1) {
      int ic = 1;
      if (!strcmp(argv[ic], "-?") || !strcmp(argv[ic], "-h")) {
         fprintf(stderr, usage, argv[0]);
         return 1;
      }
      if (!strcmp(argv[ic], "-f")) {
         fullpath = true;
         ic++;
      }
      if (!strcmp(argv[ic], "-o")) {
         ic++;
         fp = fopen(argv[ic], "w");
         if (!fp) {
            fprintf(stderr, "cannot open output file %s\n", argv[ic]);
            return 1;
         }
         ic++;
      }
      if (!strcmp(argv[ic], "-r")) {
         replace = true;
         ic++;
         fp = fopen(argv[ic], "a+");
         if (!fp) {
            fprintf(stderr, "cannot open output file %s\n", argv[ic]);
            return 1;
         }
         ic++;
      }
      if (!strcmp(argv[ic], "-l")) {
         ic++;
         solib = argv[ic];
#ifdef __APPLE__
         string::size_type i = solib.find(".dylib");
         if (i != string::npos)
            solib.replace(i, 6, ".so");
#endif
         ic++;
      }
      if (!strcmp(argv[ic], "-d")) {
         ic++;
         for (int i = ic; i < argc && argv[i][0] != '-'; i++) {
            string dl = argv[i];
#ifdef __APPLE__
            string::size_type j = dl.find(".dylib");
            if (j != string::npos)
               dl.replace(j, 6, ".so");
#endif
            solibdeps.push_back(dl);
            ic++;
         }
      }
      if (!strcmp(argv[ic], "-c")) {
         ic++;
         for (int i = ic; i < argc; i++) {
            linkdefs.push_back(argv[i]);
            ic++;
         }
      }
   } else {
      fprintf(stderr, usage, argv[0]);
      return 1;
   }

   if (replace) {
#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
    !defined(__OpenBSD__)
      // lock file
      if (lockf(fileno(fp), F_LOCK, (off_t)1) == -1) {
         fprintf(stderr, "rlibmap: locking failed, don't use gmake -j\n");
      }
#endif

      // remove entries for solib to be processed
      RemoveLib(solib, fullpath, fp);
   }

   LibMap(solib, solibdeps, linkdefs, fullpath, fp);

   if (replace) {
#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
    !defined(__OpenBSD__)
      // remove lock
      lseek(fileno(fp), 0, SEEK_SET);
      if (lockf(fileno(fp), F_ULOCK, (off_t)1) == -1) {
         //fprintf(stderr, "rlibmap: error unlocking output file\n");
      }
#endif
   }

   if (fp != stdout)
      fclose(fp);

   return 0;
}
<|endoftext|>