<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_CSV_UTILS_DATASOURCE_HPP
#define MAPNIK_CSV_UTILS_DATASOURCE_HPP

// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/geometry_correct.hpp>
#include <mapnik/wkt/wkt_factory.hpp>
#include <mapnik/json/geometry_parser.hpp>
#include <mapnik/util/conversions.hpp>
#include <mapnik/csv/csv_grammar.hpp>
#include <mapnik/util/trim.hpp>
#include <mapnik/datasource.hpp>

#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/algorithm/string.hpp>
#pragma GCC diagnostic pop

#include <string>
#include <cstdio>
#include <algorithm>

namespace csv_utils
{

static const mapnik::csv_line_grammar<char const*> line_g;
static const mapnik::csv_white_space_skipper skipper{};

template <typename Iterator>
static mapnik::csv_line parse_line(Iterator start, Iterator end, char separator, char quote, std::size_t num_columns)
{
    mapnik::csv_line values;
    if (num_columns > 0) values.reserve(num_columns);
    if (!boost::spirit::qi::phrase_parse(start, end, (line_g)(separator, quote), skipper, values))
    {
        throw mapnik::datasource_exception("Failed to parse CSV line:\n" + std::string(start, end));
    }
    return values;
}

static inline mapnik::csv_line parse_line(std::string const& line_str, char separator, char quote)
{
    auto start = line_str.c_str();
    auto end   = start + line_str.length();
    return parse_line(start, end, separator, quote, 0);
}

static inline bool is_likely_number(std::string const& value)
{
    return (std::strspn( value.c_str(), "e-.+0123456789" ) == value.size());
}

struct ignore_case_equal_pred
{
    bool operator () (unsigned char a, unsigned char b) const
    {
        return std::tolower(a) == std::tolower(b);
    }
};

inline bool ignore_case_equal(std::string const& s0, std::string const& s1)
{
    return std::equal(s0.begin(), s0.end(),
                      s1.begin(), ignore_case_equal_pred());
}

template <class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>& getline_csv(std::istream& is, std::basic_string<CharT,Traits,Allocator>& s, CharT delim, CharT quote)
{
    typename std::basic_string<CharT,Traits,Allocator>::size_type nread = 0;
    typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
    if (sentry)
    {
        std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
        s.clear();
        bool has_quote = false;
        while (nread < s.max_size())
        {
            int c1 = buf->sbumpc();
            if (Traits::eq_int_type(c1, Traits::eof()))
            {
                is.setstate(std::ios_base::eofbit);
                break;
            }
            else
            {
                ++nread;
                CharT c = Traits::to_char_type(c1);
                if (Traits::eq(c, quote))
                    has_quote = !has_quote;
                if (!Traits::eq(c, delim) || has_quote)
                    s.push_back(c);
                else
                    break;// Character is extracted but not appended.
            }
        }
    }
    if (nread == 0 || nread >= s.max_size())
        is.setstate(std::ios_base::failbit);

    return is;
}

}

namespace detail {

template <typename T>
std::size_t file_length(T & stream)
{
    stream.seekg(0, std::ios::end);
    return stream.tellg();
}

template <typename T>
std::tuple<char, bool, char, char> autodect_csv_flavour(T & stream, std::size_t file_length)
{
    // autodetect newlines/quotes/separators
    char newline = '\n'; // default
    bool has_newline = false;
    bool has_quote = false;
    char quote = '"'; // default
    char separator = ','; // default
    // local counters
    int num_commas = 0;
    int num_tabs = 0;
    int num_pipes = 0;
    int num_semicolons = 0;

    static std::size_t const max_size = 4000;
    std::size_t size = std::min(file_length, max_size);
    std::vector<char> buffer;
    buffer.resize(size);
    stream.read(buffer.data(), size);
    for (auto c : buffer)
    {
        switch (c)
        {
        case '\r':
            newline = '\r';
            has_newline = true;
            break;
        case '\n':
            has_newline = true;
            break;
        case '\'':
        case '"':
            if (!has_quote)
            {
                quote = c;
                has_quote = true;
            }
            break;
        case ',':
            if (!has_newline) ++num_commas;
            break;
        case '\t':
            if (!has_newline) ++num_tabs;
            break;
        case '|':
            if (!has_newline) ++num_pipes;
            break;
        case ';':
            if (!has_newline) ++num_semicolons;
            break;
        }
    }
    // detect separator
    if (num_tabs > 0 && num_tabs > num_commas)
    {
        separator = '\t';
        MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected tab separator";
    }
    else // pipes/semicolons
    {
        if (num_pipes > num_commas)
        {
            separator = '|';
            MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected '|' separator";
        }
        else  if (num_semicolons > num_commas)
        {
            separator = ';';
            MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected ';' separator";
        }
    }

    if (has_newline)
    {
        std::istringstream ss(buffer.data());
        std::size_t num_columns = 0;
        for (std::string line; csv_utils::getline_csv(ss, line, newline, quote) && !ss.eof(); )
        {
            if (line.size() == 0) continue;
            auto columns = csv_utils::parse_line(line, separator, quote);
            if (num_columns > 0 && num_columns != columns.size())
            {
                quote = (quote == '"') ? '\'' : '"';
                break;
            }
            num_columns = columns.size();
        }
    }
    return std::make_tuple(newline, has_newline, separator, quote);
}

struct geometry_column_locator
{
    geometry_column_locator()
        : type(UNKNOWN), index(-1), index2(-1) {}

    enum { UNKNOWN = 0, WKT, GEOJSON, LON_LAT } type;
    std::size_t index;
    std::size_t index2;
};

static inline void locate_geometry_column(std::string const& header, std::size_t index, geometry_column_locator & locator)
{
    std::string lower_val(header);
    std::transform(lower_val.begin(), lower_val.end(), lower_val.begin(), ::tolower);
    if (lower_val == "wkt" || (lower_val.find("geom") != std::string::npos))
    {
        locator.type = geometry_column_locator::WKT;
        locator.index = index;
    }
    else if (lower_val == "geojson")
    {
        locator.type = geometry_column_locator::GEOJSON;
        locator.index = index;
    }
    else if (lower_val == "x" || lower_val == "lon"
             || lower_val == "lng" || lower_val == "long"
             || (lower_val.find("longitude") != std::string::npos))
    {
        locator.index = index;
        locator.type = geometry_column_locator::LON_LAT;
    }

    else if (lower_val == "y"
             || lower_val == "lat"
             || (lower_val.find("latitude") != std::string::npos))
    {
        locator.index2 = index;
        locator.type = geometry_column_locator::LON_LAT;
    }
}

static inline bool valid(geometry_column_locator const& locator, std::size_t max_size)
{
    if (locator.type == geometry_column_locator::UNKNOWN) return false;
    if (locator.index >= max_size) return false;
    if (locator.type == geometry_column_locator::LON_LAT && locator.index2 >= max_size) return false;
    return true;
}

static inline mapnik::geometry::geometry<double> extract_geometry(std::vector<std::string> const& row, geometry_column_locator const& locator)
{
    mapnik::geometry::geometry<double> geom;
    if (locator.type == geometry_column_locator::WKT)
    {
        auto wkt_value = row.at(locator.index);
        if (mapnik::from_wkt(wkt_value, geom))
        {
            // correct orientations ..
            mapnik::geometry::correct(geom);
        }
        else
        {
            throw mapnik::datasource_exception("Failed to parse WKT: '" + wkt_value + "'");
        }
    }
    else if (locator.type == geometry_column_locator::GEOJSON)
    {

        auto json_value = row.at(locator.index);
        if (!mapnik::json::from_geojson(json_value, geom))
        {
            throw mapnik::datasource_exception("Failed to parse GeoJSON: '" + json_value + "'");
        }
    }
    else if (locator.type == geometry_column_locator::LON_LAT)
    {
        double x, y;
        auto long_value = row.at(locator.index);
        auto lat_value = row.at(locator.index2);
        if (!mapnik::util::string2double(long_value,x))
        {
            throw mapnik::datasource_exception("Failed to parse Longitude: '" + long_value + "'");
        }
        if (!mapnik::util::string2double(lat_value,y))
        {
            throw mapnik::datasource_exception("Failed to parse Latitude: '" + lat_value + "'");
        }
        geom = mapnik::geometry::point<double>(x,y);
    }
    return geom;
}

template <typename Feature, typename Headers, typename Values, typename Locator, typename Transcoder>
void process_properties(Feature & feature, Headers const& headers, Values const& values, Locator const& locator, Transcoder const& tr)
{
    auto val_beg = values.begin();
    auto val_end = values.end();
    auto num_headers = headers.size();
    for (std::size_t i = 0; i < num_headers; ++i)
    {
        std::string const& fld_name = headers.at(i);
        if (val_beg == val_end)
        {
            feature.put(fld_name,tr.transcode(""));
            continue;
        }
        std::string value = mapnik::util::trim_copy(*val_beg++);
        int value_length = value.length();

        if (locator.index == i && (locator.type == detail::geometry_column_locator::WKT
                                   || locator.type == detail::geometry_column_locator::GEOJSON)  ) continue;

        bool matched = false;
        bool has_dot = value.find(".") != std::string::npos;
        if (value.empty() ||
            (value_length > 20) ||
            (value_length > 1 && !has_dot && value[0] == '0'))
        {
            matched = true;
            feature.put(fld_name,std::move(tr.transcode(value.c_str())));
        }
        else if (csv_utils::is_likely_number(value))
        {
            bool has_e = value.find("e") != std::string::npos;
            if (has_dot || has_e)
            {
                double float_val = 0.0;
                if (mapnik::util::string2double(value,float_val))
                {
                    matched = true;
                    feature.put(fld_name,float_val);
                }
            }
            else
            {
                mapnik::value_integer int_val = 0;
                if (mapnik::util::string2int(value,int_val))
                {
                    matched = true;
                    feature.put(fld_name,int_val);
                }
            }
        }
        if (!matched)
        {
            if (csv_utils::ignore_case_equal(value, "true"))
            {
                feature.put(fld_name, true);
            }
            else if (csv_utils::ignore_case_equal(value, "false"))
            {
                feature.put(fld_name, false);
            }
            else // fallback to string
            {
                feature.put(fld_name,std::move(tr.transcode(value.c_str())));
            }
        }
    }
}

}// ns detail

#endif // MAPNIK_CSV_UTILS_DATASOURCE_HPP
<commit_msg>csv_utils - fix istringstream initialiser by using explicit iterators pair std::string ctor<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_CSV_UTILS_DATASOURCE_HPP
#define MAPNIK_CSV_UTILS_DATASOURCE_HPP

// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/geometry_correct.hpp>
#include <mapnik/wkt/wkt_factory.hpp>
#include <mapnik/json/geometry_parser.hpp>
#include <mapnik/util/conversions.hpp>
#include <mapnik/csv/csv_grammar.hpp>
#include <mapnik/util/trim.hpp>
#include <mapnik/datasource.hpp>

#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/algorithm/string.hpp>
#pragma GCC diagnostic pop

#include <string>
#include <cstdio>
#include <algorithm>

namespace csv_utils
{

static const mapnik::csv_line_grammar<char const*> line_g;
static const mapnik::csv_white_space_skipper skipper{};

template <typename Iterator>
static mapnik::csv_line parse_line(Iterator start, Iterator end, char separator, char quote, std::size_t num_columns)
{
    mapnik::csv_line values;
    if (num_columns > 0) values.reserve(num_columns);
    if (!boost::spirit::qi::phrase_parse(start, end, (line_g)(separator, quote), skipper, values))
    {
        throw mapnik::datasource_exception("Failed to parse CSV line:\n" + std::string(start, end));
    }
    return values;
}

static inline mapnik::csv_line parse_line(std::string const& line_str, char separator, char quote)
{
    auto start = line_str.c_str();
    auto end   = start + line_str.length();
    return parse_line(start, end, separator, quote, 0);
}

static inline bool is_likely_number(std::string const& value)
{
    return (std::strspn( value.c_str(), "e-.+0123456789" ) == value.size());
}

struct ignore_case_equal_pred
{
    bool operator () (unsigned char a, unsigned char b) const
    {
        return std::tolower(a) == std::tolower(b);
    }
};

inline bool ignore_case_equal(std::string const& s0, std::string const& s1)
{
    return std::equal(s0.begin(), s0.end(),
                      s1.begin(), ignore_case_equal_pred());
}

template <class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>& getline_csv(std::istream& is, std::basic_string<CharT,Traits,Allocator>& s, CharT delim, CharT quote)
{
    typename std::basic_string<CharT,Traits,Allocator>::size_type nread = 0;
    typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
    if (sentry)
    {
        std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
        s.clear();
        bool has_quote = false;
        while (nread < s.max_size())
        {
            int c1 = buf->sbumpc();
            if (Traits::eq_int_type(c1, Traits::eof()))
            {
                is.setstate(std::ios_base::eofbit);
                break;
            }
            else
            {
                ++nread;
                CharT c = Traits::to_char_type(c1);
                if (Traits::eq(c, quote))
                    has_quote = !has_quote;
                if (!Traits::eq(c, delim) || has_quote)
                    s.push_back(c);
                else
                    break;// Character is extracted but not appended.
            }
        }
    }
    if (nread == 0 || nread >= s.max_size())
        is.setstate(std::ios_base::failbit);

    return is;
}

}

namespace detail {

template <typename T>
std::size_t file_length(T & stream)
{
    stream.seekg(0, std::ios::end);
    return stream.tellg();
}

template <typename T>
std::tuple<char, bool, char, char> autodect_csv_flavour(T & stream, std::size_t file_length)
{
    // autodetect newlines/quotes/separators
    char newline = '\n'; // default
    bool has_newline = false;
    bool has_quote = false;
    char quote = '"'; // default
    char separator = ','; // default
    // local counters
    int num_commas = 0;
    int num_tabs = 0;
    int num_pipes = 0;
    int num_semicolons = 0;

    static std::size_t const max_size = 4000;
    std::size_t size = std::min(file_length, max_size);
    std::vector<char> buffer;
    buffer.resize(size);
    stream.read(buffer.data(), size);
    for (auto c : buffer)
    {
        switch (c)
        {
        case '\r':
            newline = '\r';
            has_newline = true;
            break;
        case '\n':
            has_newline = true;
            break;
        case '\'':
        case '"':
            if (!has_quote)
            {
                quote = c;
                has_quote = true;
            }
            break;
        case ',':
            if (!has_newline) ++num_commas;
            break;
        case '\t':
            if (!has_newline) ++num_tabs;
            break;
        case '|':
            if (!has_newline) ++num_pipes;
            break;
        case ';':
            if (!has_newline) ++num_semicolons;
            break;
        }
    }
    // detect separator
    if (num_tabs > 0 && num_tabs > num_commas)
    {
        separator = '\t';
        MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected tab separator";
    }
    else // pipes/semicolons
    {
        if (num_pipes > num_commas)
        {
            separator = '|';
            MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected '|' separator";
        }
        else  if (num_semicolons > num_commas)
        {
            separator = ';';
            MAPNIK_LOG_DEBUG(csv) << "csv_datasource: auto detected ';' separator";
        }
    }

    if (has_newline)
    {
        std::istringstream ss(std::string(buffer.begin(), buffer.end()));
        std::size_t num_columns = 0;
        for (std::string line; csv_utils::getline_csv(ss, line, newline, quote) && !ss.eof(); )
        {
            if (line.size() == 0) continue;
            auto columns = csv_utils::parse_line(line, separator, quote);
            if (num_columns > 0 && num_columns != columns.size())
            {
                quote = (quote == '"') ? '\'' : '"';
                break;
            }
            num_columns = columns.size();
        }
    }
    return std::make_tuple(newline, has_newline, separator, quote);
}

struct geometry_column_locator
{
    geometry_column_locator()
        : type(UNKNOWN), index(-1), index2(-1) {}

    enum { UNKNOWN = 0, WKT, GEOJSON, LON_LAT } type;
    std::size_t index;
    std::size_t index2;
};

static inline void locate_geometry_column(std::string const& header, std::size_t index, geometry_column_locator & locator)
{
    std::string lower_val(header);
    std::transform(lower_val.begin(), lower_val.end(), lower_val.begin(), ::tolower);
    if (lower_val == "wkt" || (lower_val.find("geom") != std::string::npos))
    {
        locator.type = geometry_column_locator::WKT;
        locator.index = index;
    }
    else if (lower_val == "geojson")
    {
        locator.type = geometry_column_locator::GEOJSON;
        locator.index = index;
    }
    else if (lower_val == "x" || lower_val == "lon"
             || lower_val == "lng" || lower_val == "long"
             || (lower_val.find("longitude") != std::string::npos))
    {
        locator.index = index;
        locator.type = geometry_column_locator::LON_LAT;
    }

    else if (lower_val == "y"
             || lower_val == "lat"
             || (lower_val.find("latitude") != std::string::npos))
    {
        locator.index2 = index;
        locator.type = geometry_column_locator::LON_LAT;
    }
}

static inline bool valid(geometry_column_locator const& locator, std::size_t max_size)
{
    if (locator.type == geometry_column_locator::UNKNOWN) return false;
    if (locator.index >= max_size) return false;
    if (locator.type == geometry_column_locator::LON_LAT && locator.index2 >= max_size) return false;
    return true;
}

static inline mapnik::geometry::geometry<double> extract_geometry(std::vector<std::string> const& row, geometry_column_locator const& locator)
{
    mapnik::geometry::geometry<double> geom;
    if (locator.type == geometry_column_locator::WKT)
    {
        auto wkt_value = row.at(locator.index);
        if (mapnik::from_wkt(wkt_value, geom))
        {
            // correct orientations ..
            mapnik::geometry::correct(geom);
        }
        else
        {
            throw mapnik::datasource_exception("Failed to parse WKT: '" + wkt_value + "'");
        }
    }
    else if (locator.type == geometry_column_locator::GEOJSON)
    {

        auto json_value = row.at(locator.index);
        if (!mapnik::json::from_geojson(json_value, geom))
        {
            throw mapnik::datasource_exception("Failed to parse GeoJSON: '" + json_value + "'");
        }
    }
    else if (locator.type == geometry_column_locator::LON_LAT)
    {
        double x, y;
        auto long_value = row.at(locator.index);
        auto lat_value = row.at(locator.index2);
        if (!mapnik::util::string2double(long_value,x))
        {
            throw mapnik::datasource_exception("Failed to parse Longitude: '" + long_value + "'");
        }
        if (!mapnik::util::string2double(lat_value,y))
        {
            throw mapnik::datasource_exception("Failed to parse Latitude: '" + lat_value + "'");
        }
        geom = mapnik::geometry::point<double>(x,y);
    }
    return geom;
}

template <typename Feature, typename Headers, typename Values, typename Locator, typename Transcoder>
void process_properties(Feature & feature, Headers const& headers, Values const& values, Locator const& locator, Transcoder const& tr)
{
    auto val_beg = values.begin();
    auto val_end = values.end();
    auto num_headers = headers.size();
    for (std::size_t i = 0; i < num_headers; ++i)
    {
        std::string const& fld_name = headers.at(i);
        if (val_beg == val_end)
        {
            feature.put(fld_name,tr.transcode(""));
            continue;
        }
        std::string value = mapnik::util::trim_copy(*val_beg++);
        int value_length = value.length();

        if (locator.index == i && (locator.type == detail::geometry_column_locator::WKT
                                   || locator.type == detail::geometry_column_locator::GEOJSON)  ) continue;

        bool matched = false;
        bool has_dot = value.find(".") != std::string::npos;
        if (value.empty() ||
            (value_length > 20) ||
            (value_length > 1 && !has_dot && value[0] == '0'))
        {
            matched = true;
            feature.put(fld_name,std::move(tr.transcode(value.c_str())));
        }
        else if (csv_utils::is_likely_number(value))
        {
            bool has_e = value.find("e") != std::string::npos;
            if (has_dot || has_e)
            {
                double float_val = 0.0;
                if (mapnik::util::string2double(value,float_val))
                {
                    matched = true;
                    feature.put(fld_name,float_val);
                }
            }
            else
            {
                mapnik::value_integer int_val = 0;
                if (mapnik::util::string2int(value,int_val))
                {
                    matched = true;
                    feature.put(fld_name,int_val);
                }
            }
        }
        if (!matched)
        {
            if (csv_utils::ignore_case_equal(value, "true"))
            {
                feature.put(fld_name, true);
            }
            else if (csv_utils::ignore_case_equal(value, "false"))
            {
                feature.put(fld_name, false);
            }
            else // fallback to string
            {
                feature.put(fld_name,std::move(tr.transcode(value.c_str())));
            }
        }
    }
}

}// ns detail

#endif // MAPNIK_CSV_UTILS_DATASOURCE_HPP
<|endoftext|>


<commit_before>#include <queue>
#include <cstring>
#include <iostream>
#include <vector>
#include <string.h>
#include <unistd.h>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;
using namespace boost;

// Cases to test:
// cd Desktop&&ls -a
// cd Desktop&[ENTER] ls -a
// cd Desktop;ls -a
// cd Desktop;ls
// ls;ls;ls;ls
// cd Desktop & ls -a
// cd Desktop;
// ls;
// cd Desktop||ls -a;vim touch.cpp&&[ENTER] ls -a
// cd Desktop
// ; clear
// && ls
// || ls -a
// NOTE: cd will NOT be tested or used!
// Re-read specs if unsure!!

// prints user and machine info
void pcmd_prompt() {
    string login(getlogin());
    struct utsname hostname;
    uname(&hostname);
    string nodeName(hostname.nodename);
    cout << login << "@" << nodeName << "$ ";
}

// parses input into queue for execution
void parse_into_queue(queue<string> &l, const string &s) {
    char_separator<char> delim(" ", ";&|#") ;
    tokenizer<char_separator<char>> mytok(s, delim);

    for (auto i = mytok.begin(); i != mytok.end(); ++i) {
        l.push(*i);
    }
}

// for testing purposes
void print_queue (queue<string> q) {
    if (q.empty()) {
        return;
    }
    while (!q.empty()) {
        cout << "[" << q.front() << "] ";
        q.pop();
    }
    cout << endl;
}

// for testing purposes
void qinfo(queue<string> q) {
    cout << "Size: " << q.size() << endl;
    print_queue(q);
}

// reinitializes v with q until connector
void parse_connectors(vector<string> &v, queue<string> &q) {
    while (!q.empty() && q.front() != "&" && q.front() != "|" && q.front() != ";") {
        v.push_back(q.front());
        q.pop();
    }
}

bool cmd_exit(vector<string> &v) {
    if (iequals(v.at(0), "exit")) {
        return true;
    }
    return false;
}

void to_arr_cstring(vector<string> &s, vector<char*> &cs) {
    for (auto i = 0; i != s.size(); ++i) {
        cs[i] = &s[i][0];
    }
}

// exec cmd and if success
bool begin_exec(vector<char*> &cs) {
    int status;
    int pid = fork();
    if (pid < 0) { // error
        perror("FORK");
        _exit(-1);
    }
    else if (pid == 0) { // child
        cout << "child process" << endl;
        if (-1 == execvp(cs[0], cs.data())) {
            perror("EXEC");
            _exit(-1);
        }
        _exit(0);
    }
    else if (pid > 0) { // parent
        if (-1 == wait(&status)) {
            perror("WAIT");
        }
        if (status != 0) {
            return false;
        }
    }
    return true;
}

// checks connector logic
bool connect_success(bool status, queue<string> &q) {
    if (!q.empty() && q.front() == "&") {
        q.pop();
        if (!q.empty() && q.front() == "&") {
            q.pop();
            if (!status) {
                cout << "prev cmd fail - ending" << endl;
                return false;
            }
            else {
                return true;
            }
        }
        else if (q.empty()) {
            cout << "error with connector \"&\"" << endl;
            return false;
        }
        else {
             cout << "&" << q.front() << " is not a connector!" << endl;
             return false;
        }
    }
    else if (!q.empty() && q.front() == "|") {
        q.pop();
        if (!q.empty() && q.front() == "|") {
            q.pop();
            if (status) {
                cout << "prev cmd success - ending" << endl;
                return false;
            }
            else {
                return true;
            }
        }
        else if (q.empty()) {
            cout << "error with connector \"|\"" << endl;
            return false;
        }
        else {
            cout << "|" << q.front() << " is not a connector!" << endl;
            return false;
        }
    }
    else if (!q.empty() && q.front() == ";") {
        q.pop();
        return true;
    }
    else if (!q.empty())  {
        cout << q.front() <<  " is not a connector!" << endl;
        return false;
    }
    else {
        cout << "queue size: " << q.size() << endl;
        print_queue(q);
        cout << "something MIGHT be wrong!" << endl;
        return false;
    }
}

int main(int argc, char* argv[]) {
    while (1) {
        string cmd_input;
        queue<string> list;
        pcmd_prompt();
        getline(cin, cmd_input);
        parse_into_queue(list, cmd_input);
        vector<string> cmd;
        while (!list.empty()) {
            qinfo(list); // debugger
            bool exec_success = false;
            parse_connectors(cmd, list);
            if (cmd.size() == 0) {
                cout << "ERROR!" << endl;
                break;
            }
            else if (cmd_exit(cmd)) {
                cout << "Exiting RShell" << endl;
                return 0;
            }
            else {
                vector<char*> cmd_cstring(cmd.size() + 1);
                to_arr_cstring(cmd, cmd_cstring);
                exec_success = begin_exec(cmd_cstring);
            }
            if (!connect_success(exec_success, list)) {
                break;
            }
            cmd.clear();
        }
    }
    return 0;
}
<commit_msg>Added comment support<commit_after>#include <queue>
#include <cstring>
#include <iostream>
#include <vector>
#include <string.h>
#include <unistd.h>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;
using namespace boost;

// Cases to test:
// cd Desktop&&ls -a
// cd Desktop&[ENTER] ls -a
// cd Desktop;ls -a
// cd Desktop;ls
// ls;ls;ls;ls
// cd Desktop & ls -a
// cd Desktop;
// ls;
// cd Desktop||ls -a;vim touch.cpp&&[ENTER] ls -a
// cd Desktop
// ; clear
// && ls
// || ls -a
// NOTE: cd will NOT be tested or used!
// Re-read specs if unsure!!

// prints user and machine info
void pcmd_prompt() {
    string login(getlogin());
    struct utsname hostname;
    uname(&hostname);
    string nodeName(hostname.nodename);
    cout << login << "@" << nodeName << "$ ";
}

// parses input into queue for execution
void parse_into_queue(queue<string> &l, const string &s) {
    char_separator<char> delim(" ", ";&|#") ;
    tokenizer<char_separator<char>> mytok(s, delim);

    for (auto i = mytok.begin(); i != mytok.end(); ++i) {
        l.push(*i);
    }
}

// for testing purposes
void print_queue (queue<string> q) {
    if (q.empty()) {
        return;
    }
    while (!q.empty()) {
        cout << "[" << q.front() << "] ";
        q.pop();
    }
    cout << endl;
}

// for testing purposes
void qinfo(queue<string> q) {
    cout << "Size: " << q.size() << endl;
    print_queue(q);
}

// reinitializes v with q until connector
void parse_connectors(vector<string> &v, queue<string> &q) {
    while (!q.empty() && q.front() != "&" && q.front() != "|" && q.front() != ";" && q.front() != "#")
    {
        v.push_back(q.front());
        q.pop();
    }
}

bool cmd_exit(vector<string> &v) {
    if (iequals(v.at(0), "exit")) {
        return true;
    }
    return false;
}

void to_arr_cstring(vector<string> &s, vector<char*> &cs) {
    for (auto i = 0; i != s.size(); ++i) {
        cs[i] = &s[i][0];
    }
}

// exec cmd and if success
bool begin_exec(vector<char*> &cs) {
    int status;
    int pid = fork();
    if (pid < 0) { // error
        perror("FORK");
        _exit(-1);
    }
    else if (pid == 0) { // child
        cout << "child process" << endl;
        if (-1 == execvp(cs[0], cs.data())) {
            perror("EXEC");
            _exit(-1);
        }
        _exit(0);
    }
    else if (pid > 0) { // parent
        if (-1 == wait(&status)) {
            perror("WAIT");
        }
        if (status != 0) {
            return false;
        }
    }
    return true;
}

// checks connector logic
bool connect_success(bool status, queue<string> &q) {
    if (!q.empty() && q.front() == "&") {
        q.pop();
        if (!q.empty() && q.front() == "&") {
            q.pop();
            if (!status) {
                cout << "prev cmd fail - ending" << endl;
                return false;
            }
            else {
                return true;
            }
        }
        else if (q.empty()) {
            cout << "Syntax error: incorrect usage of \"&&\"" << endl;
            return false;
        }
        else {
            cout << "Syntax error: incorrect usage of \"&&\"" << endl;
            return false;
        }
    }
    else if (!q.empty() && q.front() == "|") {
        q.pop();
        if (!q.empty() && q.front() == "|") {
            q.pop();
            if (status) {
                cout << "prev cmd success - ending" << endl;
                return false;
            }
            else {
                return true;
            }
        }
        else if (q.empty()) {
            cout << "Syntax error: incorrect usage of \"||\"" << endl;
            return false;
        }
        else {
            cout << "Syntax error: incorrect usage of \"||\"" << endl;
            return false;
        }
    }
    else if (!q.empty() && q.front() == ";") {
        q.pop();
        return true;
    }
    else if (!q.empty() && q.front() == "#") {
        return false;
    }
    else if (!q.empty())  {
        cout << "Syntax error: " << q.front() <<  " is not a valid connector!" << endl;
        return false;
    }
    else {
        cout << "done" << endl;
        return false;
    }
}

int main(int argc, char* argv[]) {
    while (1) {
        string cmd_input;
        queue<string> list;
        pcmd_prompt();
        getline(cin, cmd_input);
        parse_into_queue(list, cmd_input);
        vector<string> cmd;
        while (!list.empty()) {
            qinfo(list); // debugger
            bool exec_success = false;
            if (list.front() == "#") {
                break;
            }
            parse_connectors(cmd, list);
            if (cmd.size() == 0) {
                cout << "Syntax error: formatting issue in command" << endl;
                break;
            }
            else if (cmd_exit(cmd)) {
                cout << "Exiting RShell" << endl;
                return 0;
            }
            else {
                vector<char*> cmd_cstring(cmd.size() + 1);
                to_arr_cstring(cmd, cmd_cstring);
                exec_success = begin_exec(cmd_cstring);
            }
            if (!connect_success(exec_success, list)) {
                break;
            }
            cmd.clear();
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>#include<iostream>
#include<string.h>
#include<vector>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<cstring>
#include<boost/tokenizer.hpp>
#include<algorithm>
#include<iterator>
#include<sstream>

using namespace std;
using namespace boost;

void parse_line(char c_line[], char *command_line[]);
void run_line(char *command_line[]);

 int main()
{
	string str;
	string arg = "";
	 while(1)
	{
		str = "";
		char userName[100] = "";
		if(getlogin_r(userName, sizeof(userName)-1) != 0) //Getting username, and returns null if cant be found
		{
			perror("Error getting username");
		}
		cout << '['  << userName << '@';
		char hostName[100] = "";
		if(gethostname(hostName, sizeof(hostName)-1) != 0) // Getting host name, returns numm if it cannot be found
		{
			perror("Error getting hostname");
		}
		cout << hostName << ']';
		cout << "$";
		getline(cin,str);  //Gets a command
		if(str == "exit")  //If the command is exit the program stops
		{
			 break;
		}
		if(str.size() != 0 && str.at(0) == '#')
		{
			str = "";
		}
		if(str != "")
		{
			for(int i = 0; i < str.size(); i++)
			{
				if(str.at(i) == ';')  //Looks for semicolons and adds a space in order to make parsing easier
				{
					str.insert(i, " ");
					i++;
				}
				if(str.at(i) == '#')  //Removes all part of the command after the comment
				{
					str = str.substr(0,i);
				}
			}
			char c_line[str.size() + 1];
			char *command_line[64];
			strcpy(c_line,str.c_str());
			c_line[str.size()] = '\0';
			parse_line(c_line, command_line);
			run_line(command_line);
		}

	}
	  return 0;
}

void parse_line(char c_line[], char *command_line[])
{
	while(*c_line != '\0')
	{
		while(*c_line == ' ' || *c_line == '\n')
		{
			*c_line++ = '\0';
		}
		*command_line++ = c_line;
		while(*c_line != '\0' && *c_line != ' ')
		{
			c_line++;
		}
		*command_line = '\0';
	}
}

void run_line(char *command_line[])
{
	pid_t pid;
	int status;
	if((pid = fork()) < 0)
	{
		perror("forking failed");
	}
	else if(pid == 0)
	{
		if(execvp(*command_line,command_line) < 0)
		{
			perror("execvp failed");
			exit(1);
		}
	}
	else
	{
		while(wait(&status) != pid)
		;
	}
	return;
}
<commit_msg>fixed a bug with spaces at end of command<commit_after>#include<iostream>
#include<string.h>
#include<string>
#include<vector>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<cstring>
#include<boost/tokenizer.hpp>
#include<algorithm>
#include<iterator>
#include<sstream>

using namespace std;
using namespace boost;

void parse_line(char c_line[], char *command_line[]);
void run_line(char *command_line[]);

 int main()
{
	string str;
	string arg = "";
	 while(1)
	{
		str = "";
		char userName[100] = "";
		if(getlogin_r(userName, sizeof(userName)-1) != 0) //Getting username, and returns null if cant be found
		{
			perror("Error getting username");
		}
		cout << '['  << userName << '@';
		char hostName[100] = "";
		if(gethostname(hostName, sizeof(hostName)-1) != 0) // Getting host name, returns numm if it cannot be found
		{
			perror("Error getting hostname");
		}
		cout << hostName << ']';
		cout << "$";
		getline(cin,str);  //Gets a command
		if(str == "exit")  //If the command is exit the program stops
		{
			 break;
		}
		if(str.size() != 0 && str.at(0) == '#')
		{
			str = "";
		}
		if(str != "")
		{
			for(int i = 0; i < str.size(); i++)
			{
				if(str.at(i) == ';')  //Looks for semicolons and adds a space in order to make parsing easier
				{
					str.insert(i, " ");
					i++;
				}
				if(str.at(i) == '#')  //Removes all part of the command after the comment
				{
					str = str.substr(0,i);
				}
			}
			while(str.find("  ") != string::npos)
			{
				str.erase(str.find(" "));
			}
			if(str.at(str.size() - 1 ) == ' ')
			{
				str = str.substr(0,str.size()-1);
			}
			char c_line[str.size() + 1];
			char *command_line[64];
			strcpy(c_line,str.c_str());
			c_line[str.size()] = '\0';
			parse_line(c_line, command_line);
			run_line(command_line);
		}

	}
	  return 0;
}

void parse_line(char c_line[], char *command_line[])
{
	while(*c_line != '\0')
	{
		while(*c_line == ' ' || *c_line == '\n' || *c_line == '\t')
		{
			*c_line++ = '\0';
		}
		*command_line++ = c_line;
		while(*c_line != '\0' && *c_line != ' ' && *c_line != '\n' && *c_line != '\t')
		{
			c_line++;
		}
		*command_line = '\0';
	}
	return;
}

void run_line(char *command_line[])
{
	pid_t pid;
	int status;
	if((pid = fork()) < 0)
	{
		perror("forking failed");
	}
	else if(pid == 0)
	{
		if(execvp(*command_line,command_line) < 0)
		{
			perror("execvp failed");
			exit(1);
		}
	}
	else
	{
		while(wait(&status) != pid)
		;
	}
	return;
}
<|endoftext|>


<commit_before>#include "desktop.h"

#define TAB		9

using namespace std;

void open_menu(vector <string>& app_list) {
	Init_MENSTR(menu_panel);

	menu_panel.posX	= 1;
	menu_panel.posY	= 1;

	unsigned int	selected_menu	= menu_winV2(&menu_panel, "", app_list, main_system_color);

	if (selected_menu) {
		app_start(selected_menu, NULL);
	}
	/*DLGSTR		menu_panel	= {};

	bool	cycle			= true;

	int		key;

	menu_panel.xpos			= 1;
	menu_panel.ypos			= 1;
	menu_panel.style		= BLUE_WIN;
	menu_panel.border_menu	= true;

	while (cycle) {
		menu_win(menu_panel, app_list);
		key	= getch();

		switch (key) {
			case 27:		cycle = false;
							break;

			case KEY_UP:	if (menu_panel.selected != 1)
								menu_panel.selected--;
							break;

			case KEY_DOWN:	if (menu_panel.selected != menu_panel.second_border)
								menu_panel.selected++;
							break;

			case '\n':		app_start(menu_panel.selected, NULL);
							return;
							break;
		}
	}*/
}

int draw_desktop(int selected, bool open_label, unsigned int maxX, unsigned int maxY, int color, int sel_color) {
		attron(COLOR_PAIR(color) | A_BOLD);
		for (unsigned int	x	= 0; x < maxX; x++) {
			mvprintw(maxY - 1, x, "-");
			mvprintw(0, x, "-");
		}
		for (unsigned int	y	= 0; y < maxY; y++) {mvprintw(y, 0, "|"); mvprintw(y, maxX - 1, "|");}

		local_time	t_n	= get_time_now();
		mvprintw(0, maxX - 10, "%d:%d:%d", t_n.hours, t_n.min, t_n.sec);
		attroff(COLOR_PAIR(color) | A_BOLD);

		if (selected == 0) attron(COLOR_PAIR(sel_color) | A_BOLD);
		else attron(COLOR_PAIR(color) | A_BOLD);
		mvprintw(0, 1, "Menu");
		if (selected == 0) attroff(COLOR_PAIR(sel_color) | A_BOLD);
		else attroff(COLOR_PAIR(color) | A_BOLD);
		if (selected == 1) attron(COLOR_PAIR(sel_color) | A_BOLD);
		else attron(COLOR_PAIR(color) | A_BOLD);
		mvprintw(0, 6, "Edit");
		if (selected == 1) attroff(COLOR_PAIR(sel_color) | A_BOLD);
		else attroff(COLOR_PAIR(color) | A_BOLD);
		if (selected == 2) attron(COLOR_PAIR(sel_color) | A_BOLD);
		else attron(COLOR_PAIR(color) | A_BOLD);
		mvprintw(0, 11, "Exit");
		if (selected == 2) attroff(COLOR_PAIR(sel_color) | A_BOLD);
		else attroff(COLOR_PAIR(color) | A_BOLD);
	return 0;
}

int work_desktop(vector <string> app_list, string user_name) {
	unsigned int	maxY,
					maxYb		= 0,
					maxX,
					maxXb		= 0;

	bool			cycle		= true,
					open_label	= false;

	int				key_pressed,
					selected	= 0,
					color		= 0,
					sel_color	= 0;

	get_normal_inv_color(conf("system_color", main_config_base), color, sel_color);

	while (cycle) {
		getmaxyx(stdscr, maxY, maxX); // Получение размера терминала

		if ((maxX != maxXb) || (maxY != maxYb)) {
			erase();
		}

		timeout(500);
		draw_desktop(selected, open_label, maxX, maxY, color, sel_color);
		key_pressed = getch();
		switch (key_pressed) {
			case KEY_RIGHT:	if (selected != 2)
								selected++;
							break;

			case KEY_LEFT:	if (selected != 0)
								selected--;
							break;

			case '\n':		switch (selected) {
								case 0:	open_menu(app_list);
										break;

								case 1:	settings(MAIN_SETFILE);
										get_normal_inv_color(conf("system_color", main_config_base), color, sel_color);
										break;

								case 2:	cycle	= false;
										break;
							}
							break;

			case 27:		if (open_label) {
								open_label	= false;
							}
							/*else shutdown_process();*/
							break;

			case TAB:		list_process();
							break;
		}
	}

	return 0;
}

int main_desktop(string user_name/*...*/) {
	vector <string>	app_list;
	get_apps_list(app_list);
	work_desktop(app_list, user_name);
	return 0;
}<commit_msg>Добавлена анимация списка приложений<commit_after>#include "desktop.h"

#define TAB		9

using namespace std;

void open_menu(vector <string>& app_list) {
	Init_MENSTR(menu_panel);

	menu_panel.posX				= 1;
	menu_panel.posY				= 1;
	menu_panel.animation_delay	= 100;

	unsigned int	selected_menu	= menu_winV2(&menu_panel, "", app_list, main_system_color);

	if (selected_menu) {
		app_start(selected_menu, NULL);
	}
}

int draw_desktop(int selected, bool open_label, unsigned int maxX, unsigned int maxY, int color, int sel_color) {
		attron(COLOR_PAIR(color) | A_BOLD);
		for (unsigned int	x	= 0; x < maxX; x++) {
			mvprintw(maxY - 1, x, "-");
			mvprintw(0, x, "-");
		}
		for (unsigned int	y	= 0; y < maxY; y++) {mvprintw(y, 0, "|"); mvprintw(y, maxX - 1, "|");}

		local_time	t_n	= get_time_now();
		mvprintw(0, maxX - 10, "%d:%d:%d", t_n.hours, t_n.min, t_n.sec);
		attroff(COLOR_PAIR(color) | A_BOLD);

		if (selected == 0) attron(COLOR_PAIR(sel_color) | A_BOLD);
		else attron(COLOR_PAIR(color) | A_BOLD);
		mvprintw(0, 1, "Menu");
		if (selected == 0) attroff(COLOR_PAIR(sel_color) | A_BOLD);
		else attroff(COLOR_PAIR(color) | A_BOLD);
		if (selected == 1) attron(COLOR_PAIR(sel_color) | A_BOLD);
		else attron(COLOR_PAIR(color) | A_BOLD);
		mvprintw(0, 6, "Edit");
		if (selected == 1) attroff(COLOR_PAIR(sel_color) | A_BOLD);
		else attroff(COLOR_PAIR(color) | A_BOLD);
		if (selected == 2) attron(COLOR_PAIR(sel_color) | A_BOLD);
		else attron(COLOR_PAIR(color) | A_BOLD);
		mvprintw(0, 11, "Exit");
		if (selected == 2) attroff(COLOR_PAIR(sel_color) | A_BOLD);
		else attroff(COLOR_PAIR(color) | A_BOLD);
	return 0;
}

int work_desktop(vector <string> app_list, string user_name) {
	unsigned int	maxY,
					maxYb		= 0,
					maxX,
					maxXb		= 0;

	bool			cycle		= true,
					open_label	= false;

	int				key_pressed,
					selected	= 0,
					color		= 0,
					sel_color	= 0;

	get_normal_inv_color(conf("system_color", main_config_base), color, sel_color);

	while (cycle) {
		getmaxyx(stdscr, maxY, maxX); // Получение размера терминала

		if ((maxX != maxXb) || (maxY != maxYb)) {
			erase();
		}

		timeout(500);
		draw_desktop(selected, open_label, maxX, maxY, color, sel_color);
		key_pressed = getch();
		switch (key_pressed) {
			case KEY_RIGHT:	if (selected != 2)
								selected++;
							break;

			case KEY_LEFT:	if (selected != 0)
								selected--;
							break;

			case '\n':		switch (selected) {
								case 0:	open_menu(app_list);
										break;

								case 1:	settings(MAIN_SETFILE);
										get_normal_inv_color(conf("system_color", main_config_base), color, sel_color);
										break;

								case 2:	cycle	= false;
										break;
							}
							break;

			case 27:		if (open_label) {
								open_label	= false;
							}
							/*else shutdown_process();*/
							break;

			case TAB:		list_process();
							break;
		}
	}

	return 0;
}

int main_desktop(string user_name/*...*/) {
	vector <string>	app_list;
	get_apps_list(app_list);
	work_desktop(app_list, user_name);
	return 0;
}<|endoftext|>


<commit_before>//===- AsmWriterEmitter.cpp - Generate an assembly writer -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend is emits an assembly printer for the current target.
// Note that this is currently fairly skeletal, but will grow over time.
//
//===----------------------------------------------------------------------===//

#include "AsmWriterEmitter.h"
#include "CodeGenTarget.h"
#include "Record.h"
#include <ostream>
using namespace llvm;

static bool isIdentChar(char C) {
  return (C >= 'a' && C <= 'z') ||
         (C >= 'A' && C <= 'Z') ||
         (C >= '0' && C <= '9') ||
         C == '_';
}

void AsmWriterEmitter::run(std::ostream &O) {
  EmitSourceFileHeader("Assembly Writer Source Fragment", O);
  O << "namespace llvm {\n\n";

  CodeGenTarget Target;

  Record *AsmWriter = Target.getAsmWriter();

  std::string AsmWriterClassName =
    AsmWriter->getValueAsString("AsmWriterClassName");

  O <<
  "/// printInstruction - This method is automatically generated by tablegen\n"
  "/// from the instruction set description.  This method returns true if the\n"
  "/// machine instruction was sufficiently described to print it, otherwise\n"
  "/// it returns false.\n"
    "bool " << Target.getName() << AsmWriterClassName
            << "::printInstruction(const MachineInstr *MI) {\n";
  O << "  switch (MI->getOpcode()) {\n"
       "  default: return false;\n";

  std::string Namespace = Target.inst_begin()->second.Namespace;

  for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
         E = Target.inst_end(); I != E; ++I)
    if (!I->second.AsmString.empty()) {
      const std::string &AsmString = I->second.AsmString;
      O << "  case " << Namespace << "::" << I->first << ": O ";

      std::string::size_type LastEmitted = 0;
      while (LastEmitted != AsmString.size()) {
        std::string::size_type DollarPos = AsmString.find('$', LastEmitted);
        if (DollarPos == std::string::npos) DollarPos = AsmString.size();

        // Emit a constant string fragment.
        if (DollarPos != LastEmitted) {
          // TODO: this should eventually handle escaping.
          O << " << \"" << std::string(AsmString.begin()+LastEmitted,
                                       AsmString.begin()+DollarPos) << "\"";
          LastEmitted = DollarPos;
        } else if (DollarPos+1 != AsmString.size() &&
                   AsmString[DollarPos+1] == '$') {
          O << " << '$'";         // "$$" -> $
        } else {
          // Get the name of the variable.
          // TODO: should eventually handle ${foo}bar as $foo
          std::string::size_type VarEnd = DollarPos+1;
          while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
            ++VarEnd;
          std::string VarName(AsmString.begin()+DollarPos+1,
                              AsmString.begin()+VarEnd);
          if (VarName.empty())
            throw "Stray '$' in '" + I->first +
                  "' asm string, maybe you want $$?";
          unsigned OpNo = I->second.getOperandNamed(VarName);

          // If this is a two-address instruction and we are not accessing the
          // 0th operand, remove an operand.
          unsigned MIOp = I->second.OperandList[OpNo].MIOperandNo;
          if (I->second.isTwoAddress && MIOp != 0) {
            if (MIOp == 1)
              throw "Should refer to operand #0 instead of #1 for two-address"
                    " instruction '" + I->first + "'!";
            --MIOp;
          }

          O << ";  " << I->second.OperandList[OpNo].PrinterMethodName
            << "(MI, " << MIOp << ", MVT::"
            << getName(I->second.OperandList[OpNo].Ty) << "); O ";
          LastEmitted = VarEnd;
        }
      }

      O << " << '\\n'; break;\n";
    }

  O << "  }\n"
       "  return true;\n"
       "}\n";
  O << "} // End llvm namespace \n";
}
<commit_msg>Correctly parse variant notation<commit_after>//===- AsmWriterEmitter.cpp - Generate an assembly writer -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend is emits an assembly printer for the current target.
// Note that this is currently fairly skeletal, but will grow over time.
//
//===----------------------------------------------------------------------===//

#include "AsmWriterEmitter.h"
#include "CodeGenTarget.h"
#include "Record.h"
#include <ostream>
using namespace llvm;

static bool isIdentChar(char C) {
  return (C >= 'a' && C <= 'z') ||
         (C >= 'A' && C <= 'Z') ||
         (C >= '0' && C <= '9') ||
         C == '_';
}

void AsmWriterEmitter::run(std::ostream &O) {
  EmitSourceFileHeader("Assembly Writer Source Fragment", O);
  O << "namespace llvm {\n\n";

  CodeGenTarget Target;
  Record *AsmWriter = Target.getAsmWriter();
  std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
  unsigned Variant = AsmWriter->getValueAsInt("Variant");

  O <<
  "/// printInstruction - This method is automatically generated by tablegen\n"
  "/// from the instruction set description.  This method returns true if the\n"
  "/// machine instruction was sufficiently described to print it, otherwise\n"
  "/// it returns false.\n"
    "bool " << Target.getName() << ClassName
            << "::printInstruction(const MachineInstr *MI) {\n";
  O << "  switch (MI->getOpcode()) {\n"
       "  default: return false;\n";

  std::string Namespace = Target.inst_begin()->second.Namespace;

  bool inVariant = false;  // True if we are inside a {.|.|.} region.

  for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
         E = Target.inst_end(); I != E; ++I)
    if (!I->second.AsmString.empty()) {
      const std::string &AsmString = I->second.AsmString;
      O << "  case " << Namespace << "::" << I->first << ": O ";

      std::string::size_type LastEmitted = 0;
      while (LastEmitted != AsmString.size()) {
        std::string::size_type DollarPos =
          AsmString.find_first_of("${|}", LastEmitted);
        if (DollarPos == std::string::npos) DollarPos = AsmString.size();

        // Emit a constant string fragment.
        if (DollarPos != LastEmitted) {
          // TODO: this should eventually handle escaping.
          O << " << \"" << std::string(AsmString.begin()+LastEmitted,
                                       AsmString.begin()+DollarPos) << "\"";
          LastEmitted = DollarPos;
        } else if (AsmString[DollarPos] == '{') {
          if (inVariant)
            throw "Nested variants found for instruction '" + I->first + "'!";
          LastEmitted = DollarPos+1;
          inVariant = true;   // We are now inside of the variant!
          for (unsigned i = 0; i != Variant; ++i) {
            // Skip over all of the text for an irrelevant variant here.  The
            // next variant starts at |, or there may not be text for this
            // variant if we see a }.
            std::string::size_type NP =
              AsmString.find_first_of("|}", LastEmitted);
            if (NP == std::string::npos)
              throw "Incomplete variant for instruction '" + I->first + "'!";
            LastEmitted = NP+1;
            if (AsmString[NP] == '}') {
              inVariant = false;        // No text for this variant.
              break;
            }
          }
        } else if (AsmString[DollarPos] == '|') {
          if (!inVariant)
            throw "'|' character found outside of a variant in instruction '"
                  + I->first + "'!";
          // Move to the end of variant list.
          std::string::size_type NP = AsmString.find('}', LastEmitted);
          if (NP == std::string::npos)
            throw "Incomplete variant for instruction '" + I->first + "'!";
          LastEmitted = NP+1;
          inVariant = false;
        } else if (AsmString[DollarPos] == '}') {
          if (!inVariant)
            throw "'}' character found outside of a variant in instruction '"
                  + I->first + "'!";
          LastEmitted = DollarPos+1;
          inVariant = false;
        } else if (DollarPos+1 != AsmString.size() &&
                   AsmString[DollarPos+1] == '$') {
          O << " << '$'";         // "$$" -> $
        } else {
          // Get the name of the variable.
          // TODO: should eventually handle ${foo}bar as $foo
          std::string::size_type VarEnd = DollarPos+1;
          while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
            ++VarEnd;
          std::string VarName(AsmString.begin()+DollarPos+1,
                              AsmString.begin()+VarEnd);
          if (VarName.empty())
            throw "Stray '$' in '" + I->first +
                  "' asm string, maybe you want $$?";
          unsigned OpNo = I->second.getOperandNamed(VarName);

          // If this is a two-address instruction and we are not accessing the
          // 0th operand, remove an operand.
          unsigned MIOp = I->second.OperandList[OpNo].MIOperandNo;
          if (I->second.isTwoAddress && MIOp != 0) {
            if (MIOp == 1)
              throw "Should refer to operand #0 instead of #1 for two-address"
                    " instruction '" + I->first + "'!";
            --MIOp;
          }

          O << ";  " << I->second.OperandList[OpNo].PrinterMethodName
            << "(MI, " << MIOp << ", MVT::"
            << getName(I->second.OperandList[OpNo].Ty) << "); O ";
          LastEmitted = VarEnd;
        }
      }

      O << " << '\\n'; break;\n";
    }

  O << "  }\n"
       "  return true;\n"
       "}\n";
  O << "} // End llvm namespace \n";
}
<|endoftext|>


<commit_before>#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string>
using namespace std;

int main(int argc, char** argv){
        char *user = getlogin(); //syscall for getting username
        //perror check for getlogin()
        if(user == NULL){
                perror("getlogin");
                exit(1);
        }

        char hostname[100]; //create a char array for the hostname
        if((gethostname(hostname, sizeof(hostname))) == -1){
                perror("hostname");
                exit(1);
        }

        cout << user << '@' << hostname << '$' <<  endl; //output user and host
        return 0;
}
<commit_msg>added executeCommand function<commit_after>#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <boost/tokenizer.hpp>

using namespace boost;
using namespace std;

void displayPrompt(){
    char *user = getlogin(); //I assign the login name to a user pointer
    if(user == NULL){
        perror("getlogin");
        exit(1);
    }

    char hostname[100]; //I allocate space for the hostname
    if(gethostname(hostname, sizeof(hostname)) == -1){ //checking for errors withostname
        perror("gethostname");
        exit(1);
    }

    cout << user << '@' << hostname << '$' << ' '; //here I output the user and hostanme to the screen.

}

/*void parseCommand(string &cmd){
    char_separator<char> delim;
    tokenizer< char_separator<char> > mytok(cmd, delim);
}*/

void executeCommand(char **argv){
    int pid = fork();

    if(pid == -1){
        perror("There was some error with fork()");
        exit(1);
    }
    else if(pid == 0){
        cout << "We are in the child process!";
        if(-1 == execvp(*argv, argv)){
            perror("There was an error with execvp");
            exit(1);
        }
    }
    else if(pid > 0){
        if(-1 == wait(0)){
            perror("There was an error with wait()");
        }
    }
}

int main(void){
        string cmd;

        while(cmd != "exit"){
            displayPrompt(); //display the username and hostname
            getline(cin, cmd);
        }

        return 0;
}

//notes to try
//------------
// if(strcmp(argv[0], "exit") == 0){
//              exit(0);
//         }
//------------
//execute command needs work
<|endoftext|>


<commit_before>// Copyright (C) 2015, 2016 Pierre-Luc Perrier <pluc-dev@the-pluc.net>
//
// 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.
#ifndef abz_random_random_hpp
#define abz_random_random_hpp

/// @file abz/random/random.hpp
/// Pseudorandom numbers generation.

#include "abz/detail/macros.hpp"

#include <cmath> // std::nextafter
#include <limits>
#include <random>
#include <type_traits>

ABZ_NAMESPACE_BEGIN

/// @cond ABZ_INTERNAL
namespace _ {

/// Returns a per-thread PRNG engine.
/// @return A reference to a thread local instance of Engine.
template <class Engine>
Engine &thread_local_engine()
{
  // TODO random_device can actually throw: "Throws an implementation-defined
  // exception derived from std::exception if a random number could not be
  // generated."
  thread_local Engine g{std::random_device{}()};
  return g;
}

template <class T, class Engine, class Enabled = void>
struct uniform_distribution;

template <class Integral, class Engine>
struct uniform_distribution<Integral,
                            Engine,
                            typename std::enable_if<std::is_integral<Integral>::value>::type> {
  static inline constexpr Integral default_min() { return Integral{0}; }
  static inline constexpr Integral default_max() { return std::numeric_limits<Integral>::max(); }
  static inline Integral get(Engine &g, const Integral a, const Integral b)
  {
    return std::uniform_int_distribution<Integral>{}(
      g, typename std::uniform_int_distribution<Integral>::param_type{a, b});
  }
};

template <class Real, class Engine>
struct uniform_distribution<Real, Engine, typename std::enable_if<std::is_floating_point<Real>::value>::type> {
  static inline constexpr Real default_min() { return Real{0}; }
  static inline constexpr Real default_max() { return Real{1}; }
  static inline Real get(Engine &g, const Real a, const Real b)
  {
    return std::uniform_real_distribution<Real>{}(
      g, typename std::uniform_real_distribution<Real>::param_type{
           a, std::nextafter(b, std::numeric_limits<Real>::max())});
  }
};

} // namespace _
/// @endcond ABZ_INTERNAL

namespace random {

/// @brief Seeds the internal thread local engine with a new value.
///
/// The seed value is generated using std::random_device.
///
/// The library keep a local thread instance of each engine. Multiple calls from the same thread and
/// using the same Engine type will use the same generator. This function seeds the Engine's
/// instance of the calling thread.
///
/// @tparam Engine The type of engine for which the instance will be seeded.
///
/// @see seed(const Engine::result_type) rand
template <class Engine = std::default_random_engine>
inline void seed()
{
  _::thread_local_engine<Engine>().seed(std::random_device{}());
}

/// @overload
///
/// @param value The new seed value
///
/// @see seed rand
template <class Engine = std::default_random_engine>
inline void seed(const typename Engine::result_type value)
{
  _::thread_local_engine<Engine>().seed(value);
}

} // namespace random

/// Gets a (pseudo) random number uniformly distributed on the interval \f$[a, b]\f$.
///
/// Default paramaters are
/// @li \f$\{0, MAX(T)\}\f$ for integral types
/// @li \f$\{0.0, 1.0\}\f$ for floating point types
///
/// Requires that
/// @li \f$a \leq b\f$ for integral types
/// @li \f$(a \leq b) \land (b < MAX(T)) \land ((b - a) < MAX(T))\f$ for floating point
/// types
///
/// @note This functions uses a thread_local instance of the engine. To reinitialize this engine
/// with a new seed, see random::seed.
///
/// @warning For floating point types, some existing implementations have a bug where they may
/// occasionally return b (that is, std::nextafter(b, std::numeric_limits<Real>::max()) for this
/// function). GCC
/// #63176 #LLVM
/// #18767 LWG #2524.
///
/// @see random::seed()
///
/// @param a, b The interval of the generated numbers
///
/// @tparam T The type of number to generate (must be integral or floating point).
/// @tparam Engine The random number generator to use (must satisfy
/// UniformRandomNumberGenerator concept).
template <class T, class Engine = std::default_random_engine>
inline T rand(T a = _::uniform_distribution<T, Engine>::default_min(),
              T b = _::uniform_distribution<T, Engine>::default_max())
{
  return _::uniform_distribution<T, Engine>::get(_::thread_local_engine<Engine>(), a, b);
}

ABZ_NAMESPACE_END

#endif // abz_random_random_hpp
<commit_msg>Add type aliases to uniform_distribution<commit_after>// Copyright (C) 2015, 2016 Pierre-Luc Perrier <pluc-dev@the-pluc.net>
//
// 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.
#ifndef abz_random_random_hpp
#define abz_random_random_hpp

/// @file abz/random/random.hpp
/// Pseudorandom numbers generation.

#include "abz/detail/macros.hpp"

#include <cmath> // std::nextafter
#include <limits>
#include <random>
#include <type_traits>

ABZ_NAMESPACE_BEGIN

/// @cond ABZ_INTERNAL
namespace _ {

/// Returns a per-thread PRNG engine.
/// @return A reference to a thread local instance of Engine.
template <class Engine>
Engine &thread_local_engine()
{
  // NOTE(pluc) random_device can actually throw: "Throws an implementation-defined exception
  // derived from std::exception if a random number could not be generated."
  thread_local Engine g{std::random_device{}()};
  return g;
}

template <class T, class Engine, class Enabled = void>
struct uniform_distribution;

template <class Integral, class Engine>
struct uniform_distribution<Integral, Engine, typename std::enable_if<std::is_integral<Integral>::value>::type> {
  using distribution_type = std::uniform_int_distribution<Integral>;
  using param_type = typename distribution_type::param_type;
  using result_type = Integral;

  static inline constexpr result_type default_min() { return result_type{0}; }
  static inline constexpr result_type default_max()
  {
    return std::numeric_limits<result_type>::max();
  }
  static inline result_type get(Engine &g, const Integral a, const Integral b)
  {
    return distribution_type{}(g, param_type{a, b});
  }
};

template <class Real, class Engine>
struct uniform_distribution<Real, Engine, typename std::enable_if<std::is_floating_point<Real>::value>::type> {
  using distribution_type = std::uniform_real_distribution<Real>;
  using param_type = typename distribution_type::param_type;
  using result_type = Real;

  static inline constexpr result_type default_min() { return Real{0}; }
  static inline constexpr result_type default_max() { return Real{1}; }
  static inline result_type get(Engine &g, const Real a, const Real b)
  {
    return distribution_type{}(
      g, param_type{a, std::nextafter(b, std::numeric_limits<result_type>::max())});
  }
};

} // namespace _
/// @endcond ABZ_INTERNAL

namespace random {

/// @brief Seeds the internal thread local engine with a new value.
///
/// The seed value is generated using std::random_device.
///
/// The library keep a local thread instance of each engine. Multiple calls from the same thread and
/// using the same Engine type will use the same generator. This function seeds the Engine's
/// instance of the calling thread.
///
/// @tparam Engine The type of engine for which the instance will be seeded.
///
/// @see seed(const Engine::result_type) rand
template <class Engine = std::default_random_engine>
inline void seed()
{
  _::thread_local_engine<Engine>().seed(std::random_device{}());
}

/// @overload
///
/// @param value The new seed value
///
/// @see seed rand
template <class Engine = std::default_random_engine>
inline void seed(const typename Engine::result_type value)
{
  _::thread_local_engine<Engine>().seed(value);
}

} // namespace random

/// Gets a (pseudo) random number uniformly distributed on the interval \f$[a, b]\f$.
///
/// Default paramaters are
/// @li \f$\{0, MAX(T)\}\f$ for integral types
/// @li \f$\{0.0, 1.0\}\f$ for floating point types
///
/// Requires that
/// @li \f$a \leq b\f$ for integral types
/// @li \f$(a \leq b) \land (b < MAX(T)) \land ((b - a) < MAX(T))\f$ for floating point
/// types
///
/// @note This functions uses a thread_local instance of the engine. To reinitialize this engine
/// with a new seed, see random::seed.
///
/// @warning For floating point types, some existing implementations have a bug where they may
/// occasionally return b (that is, std::nextafter(b, std::numeric_limits<Real>::max()) for this
/// function). GCC
/// #63176 #LLVM
/// #18767 LWG #2524.
///
/// @see random::seed()
///
/// @param a, b The interval of the generated numbers
///
/// @tparam T The type of number to generate (must be integral or floating point).
/// @tparam Engine The random number generator to use (must satisfy
/// UniformRandomNumberGenerator concept).
template <class T, class Engine = std::default_random_engine>
inline T rand(T a = _::uniform_distribution<T, Engine>::default_min(),
              T b = _::uniform_distribution<T, Engine>::default_max())
{
  return _::uniform_distribution<T, Engine>::get(_::thread_local_engine<Engine>(), a, b);
}

ABZ_NAMESPACE_END

#endif // abz_random_random_hpp
<|endoftext|>


<commit_before>// This is a regression test on debug info to make sure that we can access
// qualified global names.
// RUN: %llvmgcc -S -O0 -g %s -o - | \
// RUN:   llc -disable-cfi --disable-fp-elim -o %t.s -O0
// RUN: %compile_c %t.s -o %t.o
// RUN: %link %t.o -o %t.exe
// RUN: %llvmdsymutil %t.exe
// RUN: echo {break main\nrun\np Pubnames::pubname} > %t.in
// RUN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | grep {\$1 = 10}
//
// XFAIL: alpha,arm

struct Pubnames {
  static int pubname;
};

int Pubnames::pubname = 10;

int main (int argc, char** argv) {
  Pubnames p;
  return 0;
}
<commit_msg>Remove obsolete test.<commit_after><|endoftext|>


<commit_before>// -*- c-basic-offset: 8; indent-tabs: nil -*-
//
// See LICENSE for details.
//
#include <smoke.h>
#include <Qt/qstring.h>
#include <Qt/qstringlist.h>
#include <Qt/qpointer.h>
#include <Qt/qmetaobject.h>
#include <QtCore/qobject.h>
#include <QtGui/qapplication.h>
#include "commonqt.h"

// work around bugs in CCL cdecl callback support
#ifdef COMMONQT_USE_STDCALL
#define MAYBE_STDCALL __stdcall
#else
#define MAYBE_STDCALL
#endif

// #define DEBUG 1

#include <iostream>
#include <string>
#include <stdlib.h>

using namespace std;

typedef void (MAYBE_STDCALL *t_deletion_callback)(void*, void*);
typedef bool (MAYBE_STDCALL *t_callmethod_callback)(void*, short, void*, void*, bool);
typedef void (MAYBE_STDCALL *t_child_callback)(void*, bool, void*);

class ThinBinding : public SmokeBinding
{
public:
        ThinBinding(Smoke* s) : SmokeBinding(s) {}

        t_deletion_callback deletion_callback;
        t_callmethod_callback callmethod_callback;
	t_child_callback child_callback;

        void deleted(Smoke::Index classId, void* obj) {
                deletion_callback(smoke, obj);
        }

        bool callMethod(Smoke::Index method, void* obj,
                Smoke::Stack args, bool isAbstract)
        {
		Smoke::Method* m = &smoke->methods[method];
		const char* name = smoke->methodNames[m->name];
		Smoke::Class* c = &smoke->classes[m->classId];
		if (*name == '~')
			callmethod_callback(smoke, method, obj, args, isAbstract);
		else if (!strcmp(name, "notify")
			 && (!strcmp(c->className, "QApplication")
			    || !strcmp(c->className, "QCoreApplication")))
		{
			QEvent* e = (QEvent*) args[2].s_voidp;
			if (e->type() == QEvent::ChildAdded
			    || e->type() == QEvent::ChildRemoved)
			{
				QChildEvent* f = (QChildEvent*) e;
				child_callback(smoke, f->added(), f->child());
			}
		}
		return false;
	}

        char* className(Smoke::Index classId) {
                return (char*) smoke->classes[classId].className;
        }
};

class FatBinding : public SmokeBinding
{
public:
	FatBinding(Smoke* s) : SmokeBinding(s) {}

        t_deletion_callback deletion_callback;
        t_callmethod_callback callmethod_callback;
	t_child_callback child_callback;

        void deleted(Smoke::Index classId, void* obj) {
                deletion_callback(smoke, obj);
        }

        bool callMethod(Smoke::Index method, void* obj,
                Smoke::Stack args, bool isAbstract)
        {
                return callmethod_callback(smoke, method, obj, args, isAbstract);
        }

        char* className(Smoke::Index classId) {
                return (char*) smoke->classes[classId].className;
        }
};

void
sw_smoke(Smoke* smoke,
	 SmokeData* data,
	 void* deletion_callback,
	 void* method_callback,
	 void* child_callback)
{
        ThinBinding* thinBinding = new ThinBinding(smoke);
        FatBinding* fatBinding = new FatBinding(smoke);

	data->name = smoke->moduleName();

        data->classes = smoke->classes;
        data->numClasses = smoke->numClasses;

        data->methods = smoke->methods;
        data->numMethods = smoke->numMethods;

        data->methodMaps = smoke->methodMaps;
        data->numMethodMaps = smoke->numMethodMaps;

        data->methodNames = smoke->methodNames;
        data->numMethodNames = smoke->numMethodNames;

        data->types = smoke->types;
        data->numTypes = smoke->numTypes;

        data->inheritanceList = smoke->inheritanceList;
        data->argumentList = smoke->argumentList;
        data->ambiguousMethodList = smoke->ambiguousMethodList;
        data->castFn = (void *) smoke->castFn;

	fatBinding->deletion_callback
		= (t_deletion_callback) deletion_callback;

        fatBinding->callmethod_callback
                = (t_callmethod_callback) method_callback;

	fatBinding->child_callback
		= (t_child_callback) child_callback;

	thinBinding->deletion_callback = fatBinding->deletion_callback;
	thinBinding->callmethod_callback = fatBinding->callmethod_callback;
	thinBinding->child_callback = fatBinding->child_callback;

        data->thin = thinBinding;
        data->fat = fatBinding;
}

int
sw_windows_version()
{
#ifdef WINDOWS
	return QSysInfo::windowsVersion();
#else
	return -1;
#endif
}

void*
sw_make_qstring(char *str)
{
        return new QString(str);
}

void*
sw_qstring_to_utf8(void* s)
{
        QString* str = (QString*) s;
        return new QByteArray(str->toUtf8());
}

void
sw_delete_qstring(void *q)
{
        delete (QString*) q;
}

void*
sw_make_qstringlist()
{
        return new QStringList();
}

void
sw_delete_qstringlist(void *q)
{
	delete static_cast<QStringList*>(q);
}

void
sw_qstringlist_append(void *q, char *x)
{
	static_cast<QStringList*>(q)->append(QString(x));
}

void*
sw_make_metaobject(void *p, char *strings, int *d)
{
        QMetaObject* parent = (QMetaObject*) p;
        const uint* data = (const uint*) d;

        QMetaObject tmp = { { parent, strings, data, 0 } };
        QMetaObject* ptr = new QMetaObject;
        *ptr = tmp;
        return ptr;
}

void
sw_delete(void *p)
{
        QObject* q = (QObject*) p;
        delete q;
}

typedef void (*t_ptr_callback)(void *);

// quick hack, to be rewritten once we have QList marshalling support
void
sw_map_children(void *x, void *y)
{
	t_ptr_callback cb = (t_ptr_callback) y;
	QObject* o = (QObject*) x;
	const QList<QObject*> l = o->children();
	for (int i=0; i < l.size(); ++i)
		cb(l.at(i));
}

void*
sw_make_qpointer(void* target)
{
        return new QPointer<QObject>((QObject*) target);
}

bool
sw_qpointer_is_null(void* x)
{
	QPointer<QObject>* ptr = (QPointer<QObject>*) x;
	return ptr->isNull();
}

void
sw_delete_qpointer(void* x)
{
	QPointer<QObject>* ptr = (QPointer<QObject>*) x;
	delete ptr;
}

extern Smoke *qt_Smoke;

void
sw_find_class(char *name, Smoke **smoke, short *index)
{
	Smoke::ModuleIndex mi = qt_Smoke->findClass(name);
	*smoke = mi.smoke;
	*index = mi.index;
}

short
sw_find_name(Smoke *smoke, char *name)
{
	Smoke::ModuleIndex mi = smoke->idMethodName(name);
	return mi.index;
}

short
sw_id_method(Smoke *smoke, short classIndex, short name)
{
	Smoke::ModuleIndex mi = smoke->idMethod(classIndex, name);
	return mi.index;
}

short
sw_id_type(Smoke *smoke, char *name)
{
	return smoke->idType(name);
}
<commit_msg>use qtcore instead of the old qt module<commit_after>// -*- c-basic-offset: 8; indent-tabs: nil -*-
//
// See LICENSE for details.
//
#include <smoke.h>
#include <Qt/qstring.h>
#include <Qt/qstringlist.h>
#include <Qt/qpointer.h>
#include <Qt/qmetaobject.h>
#include <QtCore/qobject.h>
#include <QtGui/qapplication.h>
#include "commonqt.h"

// work around bugs in CCL cdecl callback support
#ifdef COMMONQT_USE_STDCALL
#define MAYBE_STDCALL __stdcall
#else
#define MAYBE_STDCALL
#endif

// #define DEBUG 1

#include <iostream>
#include <string>
#include <stdlib.h>

using namespace std;

typedef void (MAYBE_STDCALL *t_deletion_callback)(void*, void*);
typedef bool (MAYBE_STDCALL *t_callmethod_callback)(void*, short, void*, void*, bool);
typedef void (MAYBE_STDCALL *t_child_callback)(void*, bool, void*);

class ThinBinding : public SmokeBinding
{
public:
        ThinBinding(Smoke* s) : SmokeBinding(s) {}

        t_deletion_callback deletion_callback;
        t_callmethod_callback callmethod_callback;
	t_child_callback child_callback;

        void deleted(Smoke::Index classId, void* obj) {
                deletion_callback(smoke, obj);
        }

        bool callMethod(Smoke::Index method, void* obj,
                Smoke::Stack args, bool isAbstract)
        {
		Smoke::Method* m = &smoke->methods[method];
		const char* name = smoke->methodNames[m->name];
		Smoke::Class* c = &smoke->classes[m->classId];
		if (*name == '~')
			callmethod_callback(smoke, method, obj, args, isAbstract);
		else if (!strcmp(name, "notify")
			 && (!strcmp(c->className, "QApplication")
			    || !strcmp(c->className, "QCoreApplication")))
		{
			QEvent* e = (QEvent*) args[2].s_voidp;
			if (e->type() == QEvent::ChildAdded
			    || e->type() == QEvent::ChildRemoved)
			{
				QChildEvent* f = (QChildEvent*) e;
				child_callback(smoke, f->added(), f->child());
			}
		}
		return false;
	}

        char* className(Smoke::Index classId) {
                return (char*) smoke->classes[classId].className;
        }
};

class FatBinding : public SmokeBinding
{
public:
	FatBinding(Smoke* s) : SmokeBinding(s) {}

        t_deletion_callback deletion_callback;
        t_callmethod_callback callmethod_callback;
	t_child_callback child_callback;

        void deleted(Smoke::Index classId, void* obj) {
                deletion_callback(smoke, obj);
        }

        bool callMethod(Smoke::Index method, void* obj,
                Smoke::Stack args, bool isAbstract)
        {
                return callmethod_callback(smoke, method, obj, args, isAbstract);
        }

        char* className(Smoke::Index classId) {
                return (char*) smoke->classes[classId].className;
        }
};

void
sw_smoke(Smoke* smoke,
	 SmokeData* data,
	 void* deletion_callback,
	 void* method_callback,
	 void* child_callback)
{
        ThinBinding* thinBinding = new ThinBinding(smoke);
        FatBinding* fatBinding = new FatBinding(smoke);

	data->name = smoke->moduleName();

        data->classes = smoke->classes;
        data->numClasses = smoke->numClasses;

        data->methods = smoke->methods;
        data->numMethods = smoke->numMethods;

        data->methodMaps = smoke->methodMaps;
        data->numMethodMaps = smoke->numMethodMaps;

        data->methodNames = smoke->methodNames;
        data->numMethodNames = smoke->numMethodNames;

        data->types = smoke->types;
        data->numTypes = smoke->numTypes;

        data->inheritanceList = smoke->inheritanceList;
        data->argumentList = smoke->argumentList;
        data->ambiguousMethodList = smoke->ambiguousMethodList;
        data->castFn = (void *) smoke->castFn;

	fatBinding->deletion_callback
		= (t_deletion_callback) deletion_callback;

        fatBinding->callmethod_callback
                = (t_callmethod_callback) method_callback;

	fatBinding->child_callback
		= (t_child_callback) child_callback;

	thinBinding->deletion_callback = fatBinding->deletion_callback;
	thinBinding->callmethod_callback = fatBinding->callmethod_callback;
	thinBinding->child_callback = fatBinding->child_callback;

        data->thin = thinBinding;
        data->fat = fatBinding;
}

int
sw_windows_version()
{
#ifdef WINDOWS
	return QSysInfo::windowsVersion();
#else
	return -1;
#endif
}

void*
sw_make_qstring(char *str)
{
        return new QString(str);
}

void*
sw_qstring_to_utf8(void* s)
{
        QString* str = (QString*) s;
        return new QByteArray(str->toUtf8());
}

void
sw_delete_qstring(void *q)
{
        delete (QString*) q;
}

void*
sw_make_qstringlist()
{
        return new QStringList();
}

void
sw_delete_qstringlist(void *q)
{
	delete static_cast<QStringList*>(q);
}

void
sw_qstringlist_append(void *q, char *x)
{
	static_cast<QStringList*>(q)->append(QString(x));
}

void*
sw_make_metaobject(void *p, char *strings, int *d)
{
        QMetaObject* parent = (QMetaObject*) p;
        const uint* data = (const uint*) d;

        QMetaObject tmp = { { parent, strings, data, 0 } };
        QMetaObject* ptr = new QMetaObject;
        *ptr = tmp;
        return ptr;
}

void
sw_delete(void *p)
{
        QObject* q = (QObject*) p;
        delete q;
}

typedef void (*t_ptr_callback)(void *);

// quick hack, to be rewritten once we have QList marshalling support
void
sw_map_children(void *x, void *y)
{
	t_ptr_callback cb = (t_ptr_callback) y;
	QObject* o = (QObject*) x;
	const QList<QObject*> l = o->children();
	for (int i=0; i < l.size(); ++i)
		cb(l.at(i));
}

void*
sw_make_qpointer(void* target)
{
        return new QPointer<QObject>((QObject*) target);
}

bool
sw_qpointer_is_null(void* x)
{
	QPointer<QObject>* ptr = (QPointer<QObject>*) x;
	return ptr->isNull();
}

void
sw_delete_qpointer(void* x)
{
	QPointer<QObject>* ptr = (QPointer<QObject>*) x;
	delete ptr;
}

extern Smoke *qtcore_Smoke;

void
sw_find_class(char *name, Smoke **smoke, short *index)
{
	Smoke::ModuleIndex mi = qtcore_Smoke->findClass(name);
	*smoke = mi.smoke;
	*index = mi.index;
}

short
sw_find_name(Smoke *smoke, char *name)
{
	Smoke::ModuleIndex mi = smoke->idMethodName(name);
	return mi.index;
}

short
sw_id_method(Smoke *smoke, short classIndex, short name)
{
	Smoke::ModuleIndex mi = smoke->idMethod(classIndex, name);
	return mi.index;
}

short
sw_id_type(Smoke *smoke, char *name)
{
	return smoke->idType(name);
}
<|endoftext|>


<commit_before>#pragma once

#include "bdd_model.hpp"
#include "graph_algorithm.hpp"
#include "graph_model.hpp"
#include <vector>

namespace verilog
{

//using namespace bdd;
//using namespace graph;

struct BDD_Builder {
  graph::G & g;
  bdd::BDD & bdds;
  std::vector<bdd::Node*> bdd_nodes;

  BDD_Builder(graph::G & g, bdd::BDD & bdds): g(g), bdds(bdds), bdd_nodes(num_vertices(g.graph)) {

  }

  bdd::Node * sum_nodes_group_ands_and_ors(int node) {
    auto p = in_edges(node, g.graph);

    bdd::Node * sum_or = bdds.zero;
    bdd::Node * sum_and = bdds.one;

    for (auto e = p.first; e != p.second; ++e) {
      bdd::Node * s = bdd_nodes[source(*e, g.graph)];

      if(g.graph[*e] == NegP::Positive) {
        sum_and = bdds.land(sum_and, s);
      }
      else {
        sum_or = bdds.lor(sum_or, s);
      }
      //bdd::Node * s2 = g.graph[*e] == NegP::Positive ? s : bdds.negate(s);
    }
    return bdds.land(sum_and, bdds.negate(sum_or));
  }

  bdd::Node * sum_nodes(int node) {
    auto p = in_edges(node, g.graph);
    bdd::Node * sum = bdds.one;

    for (auto e = p.first; e != p.second; ++e) {
      bdd::Node * s = bdd_nodes[source(*e, g.graph)];

      bdd::Node * s2 = g.graph[*e] == NegP::Positive ? s : bdds.negate(s);

      sum = bdds.land(sum, s);
    }
    return sum;
  }

  bdd::Node * sum_nodes_lor(int node) {
    auto p = in_edges(node, g.graph);
    bdd::Node * sum = bdds.zero;

    for (auto e = p.first; e != p.second; ++e) {
      bdd::Node * s = bdd_nodes[source(*e, g.graph)];

      bdd::Node * s2 = g.graph[*e] == NegP::Positive ? bdds.negate(s) : s;

      sum = bdds.lor(sum, s);
    }
    return bdds.negate(sum);
  }

  void build() {
    auto topo_order = topological_sort(g);

    for (int node : topo_order) {
      if(node == g.zero) {
        bdd_nodes[node] = bdds.zero;
      }
      else if(node == g.one) {
        bdd_nodes[node] = bdds.one;
      }
      else if(in_degree(node, g.graph) == 0) {
        printf("// adding input node %d\n", node);
        bdd_nodes[node] = bdds.add_simple_input(g.graph[node].identifier);
      }
      else {

        //bdd_nodes[node] = sum_nodes_lor(node);
        //bdd_nodes[node] = sum_nodes(node);
        bdd_nodes[node] = sum_nodes_group_ands_and_ors(node);

        if(bdd_nodes[node]->r_t) {
          printf("// replacing representative of node %p: %d -> %d\n", bdd_nodes[node], *bdd_nodes[node]->r_t, node);
        }
        else {
          printf("// adding representative to node %p: %d\n", bdd_nodes[node], node);
        }
        bdd_nodes[node]->r_t = node;
      }
    }
  }

};

}
<commit_msg>Using just nands.<commit_after>#pragma once

#include "bdd_model.hpp"
#include "graph_algorithm.hpp"
#include "graph_model.hpp"
#include <vector>

namespace verilog
{

//using namespace bdd;
//using namespace graph;

struct BDD_Builder {
  graph::G & g;
  bdd::BDD & bdds;
  std::vector<bdd::Node*> bdd_nodes;

  BDD_Builder(graph::G & g, bdd::BDD & bdds): g(g), bdds(bdds), bdd_nodes(num_vertices(g.graph)) {

  }

  bdd::Node * sum_nodes_group_ands_and_ors(int node) {
    auto p = in_edges(node, g.graph);

    bdd::Node * sum_or = bdds.zero;
    bdd::Node * sum_and = bdds.one;

    for (auto e = p.first; e != p.second; ++e) {
      bdd::Node * s = bdd_nodes[source(*e, g.graph)];

      if(g.graph[*e] == NegP::Positive) {
        sum_and = bdds.land(sum_and, s);
      }
      else {
        sum_or = bdds.lor(sum_or, s);
      }
      //bdd::Node * s2 = g.graph[*e] == NegP::Positive ? s : bdds.negate(s);
    }
    return bdds.land(sum_and, bdds.negate(sum_or));
  }

  bdd::Node * sum_nodes(int node) {
    auto p = in_edges(node, g.graph);
    bdd::Node * sum = bdds.one;

    for (auto e = p.first; e != p.second; ++e) {
      bdd::Node * s = bdd_nodes[source(*e, g.graph)];

      bdd::Node * s2 = g.graph[*e] == NegP::Positive ? s : bdds.negate(s);

      sum = bdds.land(sum, s);
    }
    return sum;
  }

  bdd::Node * sum_nodes_lor(int node) {
    auto p = in_edges(node, g.graph);
    bdd::Node * sum = bdds.zero;

    for (auto e = p.first; e != p.second; ++e) {
      bdd::Node * s = bdd_nodes[source(*e, g.graph)];

      bdd::Node * s2 = g.graph[*e] == NegP::Positive ? bdds.negate(s) : s;

      sum = bdds.lor(sum, s);
    }
    return bdds.negate(sum);
  }

  void build() {
    auto topo_order = topological_sort(g);

    for (int node : topo_order) {
      if(node == g.zero) {
        bdd_nodes[node] = bdds.zero;
      }
      else if(node == g.one) {
        bdd_nodes[node] = bdds.one;
      }
      else if(in_degree(node, g.graph) == 0) {
        printf("// adding input node %d\n", node);
        bdd_nodes[node] = bdds.add_simple_input(g.graph[node].identifier);
      }
      else {

        // TODO check which of these 3 is best.
        //bdd_nodes[node] = sum_nodes_lor(node);
        bdd_nodes[node] = sum_nodes(node);
        //bdd_nodes[node] = sum_nodes_group_ands_and_ors(node);

        if(bdd_nodes[node]->r_t) {
          printf("// replacing representative of node %p: %d -> %d\n", bdd_nodes[node], *bdd_nodes[node]->r_t, node);
        }
        else {
          printf("// adding representative to node %p: %d\n", bdd_nodes[node], node);
        }
        bdd_nodes[node]->r_t = node;
      }
    }
  }

};

}
<|endoftext|>