<commit_before>#include "ncurses.hh"

#include "display_buffer.hh"
#include "register_manager.hh"

#include "utf8_iterator.hh"
#include "event_manager.hh"

#include <map>

#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <fcntl.h>

namespace Kakoune
{

static void set_attribute(int attribute, bool on)
{
    if (on)
        attron(attribute);
    else
        attroff(attribute);
}

static int nc_color(Color color)
{
    switch (color)
    {
    case Color::Black:   return COLOR_BLACK;
    case Color::Red:     return COLOR_RED;
    case Color::Green:   return COLOR_GREEN;
    case Color::Yellow:  return COLOR_YELLOW;
    case Color::Blue:    return COLOR_BLUE;
    case Color::Magenta: return COLOR_MAGENTA;
    case Color::Cyan:    return COLOR_CYAN;
    case Color::White:   return COLOR_WHITE;

    case Color::Default:
    default:
        return -1;
    }
}

static int get_color_pair(Color fg_color, Color bg_color)
{
    static std::map<std::pair<Color, Color>, int> colorpairs;
    static int next_pair = 1;

    std::pair<Color, Color> colorpair(fg_color, bg_color);

    auto it = colorpairs.find(colorpair);
    if (it != colorpairs.end())
        return it->second;
    else
    {
        init_pair(next_pair, nc_color(fg_color), nc_color(bg_color));
        colorpairs[colorpair] = next_pair;
        return next_pair++;
    }
}

static void set_color(Color fg_color, Color bg_color)
{
    static int current_pair = -1;

    if (current_pair != -1)
        attroff(COLOR_PAIR(current_pair));

    if (fg_color != Color::Default or bg_color != Color::Default)
    {
        current_pair = get_color_pair(fg_color, bg_color);
        attron(COLOR_PAIR(current_pair));
    }
}

static NCursesUI* signal_ui = nullptr;
void on_term_resize(int)
{
    int fd = open("/dev/tty", O_RDWR);
    winsize ws;
    if (fd == 0 or ioctl(fd, TIOCGWINSZ, (void*)&ws) != 0)
        return;
    close(fd);
    resizeterm(ws.ws_row, ws.ws_col);
    ungetch(KEY_RESIZE);
    signal_ui->update_dimensions();
    EventManager::instance().force_signal(0);
}

NCursesUI::NCursesUI()
{
    //setlocale(LC_CTYPE, "");
    initscr();
    cbreak();
    noecho();
    nonl();
    intrflush(stdscr, false);
    keypad(stdscr, true);
    curs_set(0);
    start_color();
    use_default_colors();
    ESCDELAY=25;

    m_menu_fg = get_color_pair(Color::Blue, Color::Cyan);
    m_menu_bg = get_color_pair(Color::Cyan, Color::Blue);

    update_dimensions();

    assert(signal_ui == nullptr);
    signal_ui = this;
    signal(SIGWINCH, on_term_resize);
}

NCursesUI::~NCursesUI()
{
    endwin();
}

static void redraw(WINDOW* menu_win)
{
    wnoutrefresh(stdscr);
    if (menu_win)
    {
        redrawwin(menu_win);
        wnoutrefresh(menu_win);
    }
    doupdate();
}
using Utf8Policy = utf8::InvalidBytePolicy::Pass;
using Utf8Iterator = utf8::utf8_iterator<String::iterator, Utf8Policy>;
void addutf8str(Utf8Iterator begin, Utf8Iterator end)
{
    while (begin != end)
        addch(*begin++);
}

void NCursesUI::update_dimensions()
{
    int max_x,max_y;
    getmaxyx(stdscr, max_y, max_x);
    max_y -= 1;
    m_dimensions = { max_y, max_x };
}

void NCursesUI::draw(const DisplayBuffer& display_buffer,
                     const String& status_line)
{
    LineCount line_index = 0;
    for (const DisplayLine& line : display_buffer.lines())
    {
        move((int)line_index, 0);
        clrtoeol();
        CharCount col_index = 0;
        for (const DisplayAtom& atom : line)
        {
            set_attribute(A_UNDERLINE, atom.attribute & Underline);
            set_attribute(A_REVERSE, atom.attribute & Reverse);
            set_attribute(A_BLINK, atom.attribute & Blink);
            set_attribute(A_BOLD, atom.attribute & Bold);

            set_color(atom.fg_color, atom.bg_color);

            String content = atom.content.content();
            if (content[content.length()-1] == '\n' and
                content.char_length() - 1 < m_dimensions.column - col_index)
            {
                addutf8str(Utf8Iterator(content.begin()), Utf8Iterator(content.end())-1);
                addch(' ');
            }
            else
            {
                Utf8Iterator begin(content.begin()), end(content.end());
                if (end - begin > m_dimensions.column - col_index)
                    end = begin + m_dimensions.column - col_index;
                addutf8str(begin, end);
                col_index += end - begin;
            }
        }
        ++line_index;
    }

    set_attribute(A_UNDERLINE, 0);
    set_attribute(A_REVERSE, 0);
    set_attribute(A_BLINK, 0);
    set_attribute(A_BOLD, 0);
    set_color(Color::Blue, Color::Black);
    for (;line_index < m_dimensions.line; ++line_index)
    {
        move((int)line_index, 0);
        clrtoeol();
        addch('~');
    }

    set_color(Color::Cyan, Color::Black);
    static int last_status_length = 0;
    move((int)m_dimensions.line, (int)(m_dimensions.column - last_status_length));
    clrtoeol();
    move((int)m_dimensions.line, (int)(m_dimensions.column - status_line.char_length()));
    addstr(status_line.c_str());
    last_status_length = (int)status_line.length();

    redraw(m_menu_win);
}

struct getch_iterator
{
    int operator*() { return getch(); }
    getch_iterator& operator++() { return *this; }
    getch_iterator& operator++(int) { return *this; }
};

bool NCursesUI::is_key_available()
{
    timeout(0);
    const int c = getch();
    if (c != ERR)
        ungetch(c);
    timeout(-1);
    return c != ERR;
}

Key NCursesUI::get_key()
{
    const unsigned c = getch();
    if (c > 0 and c < 27)
    {
        return {Key::Modifiers::Control, c - 1 + 'a'};
    }
    else if (c == 27)
    {
        timeout(0);
        const Codepoint new_c = getch();
        timeout(-1);
        if (new_c != ERR)
            return {Key::Modifiers::Alt, new_c};
        else
            return Key::Escape;
    }
    else switch (c)
    {
    case KEY_BACKSPACE: return Key::Backspace;
    case KEY_UP: return Key::Up;
    case KEY_DOWN: return Key::Down;
    case KEY_LEFT: return Key::Left;
    case KEY_RIGHT: return Key::Right;
    case KEY_PPAGE: return Key::PageUp;
    case KEY_NPAGE: return Key::PageDown;
    case KEY_BTAB: return Key::BackTab;
    }

    if (c < 256)
    {
       ungetch(c);
       return utf8::codepoint(getch_iterator{});
    }
    return Key::Invalid;
}

void NCursesUI::print_status(const String& status, CharCount cursor_pos)
{
    int x,y;
    getmaxyx(stdscr, y, x);
    move(y-1, 0);
    clrtoeol();
    if (cursor_pos == -1)
       addutf8str(status.begin(), status.end());
    else
    {
        auto cursor_it = utf8::advance(status.begin(), status.end(), (int)cursor_pos);
        auto end = status.end();
        addutf8str(status.begin(), cursor_it);
        set_attribute(A_REVERSE, 1);
        addch((cursor_it == end) ? ' ' : utf8::codepoint<Utf8Policy>(cursor_it));
        set_attribute(A_REVERSE, 0);
        if (cursor_it != end)
            addutf8str(utf8::next(cursor_it), end);
    }
    redraw(m_menu_win);
}

void NCursesUI::menu_show(const memoryview<String>& choices,
                          const DisplayCoord& anchor, MenuStyle style)
{
    assert(m_menu == nullptr);
    assert(m_menu_win == nullptr);
    m_choices = std::vector<String>(choices.begin(), choices.end());
    CharCount longest = 0;
    for (int i = 0; i < m_choices.size(); ++i)
    {
        m_items.push_back(new_item(m_choices[i].c_str(), ""));
        longest = std::max(longest, m_choices[i].char_length());
    }
    m_items.push_back(nullptr);
    longest += 1;

    int max_x,max_y;
    getmaxyx(stdscr, max_y, max_x);
    max_x -= (int)anchor.column;

    int columns = (style == MenuStyle::Prompt) ?
                  (max_x / std::min(max_x, (int)longest)) : 1;
    int lines = std::min(10, (int)ceilf((float)m_choices.size()/columns));

    m_menu_pos = { anchor.line+1, anchor.column };
    if (m_menu_pos.line + lines >= max_y)
        m_menu_pos.line = anchor.line - lines;
    m_menu_size = { lines, columns == 1 ? longest : max_x };

    m_menu = new_menu(&m_items[0]);
    m_menu_win = newwin((int)m_menu_size.line, (int)m_menu_size.column,
                        (int)m_menu_pos.line,  (int)m_menu_pos.column);
    set_menu_win(m_menu, m_menu_win);
    set_menu_format(m_menu, lines, columns);
    set_menu_mark(m_menu, nullptr);
    set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
    set_menu_back(m_menu, COLOR_PAIR(m_menu_bg));
    post_menu(m_menu);
}

void NCursesUI::menu_select(int selected)
{
    // last item in m_items is the nullptr, hence the - 1
    if (selected >= 0 and selected < m_items.size() - 1)
    {
        set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
        set_current_item(m_menu, m_items[selected]);
    }
    else
        set_menu_fore(m_menu, COLOR_PAIR(m_menu_bg));
}

void NCursesUI::menu_hide()
{
    if (not m_menu)
        return;
    unpost_menu(m_menu);
    free_menu(m_menu);
    for (auto item : m_items)
       if (item)
           free_item(item);
    m_menu = nullptr;
    delwin(m_menu_win);
    m_menu_win = nullptr;
    m_items.clear();
}

DisplayCoord NCursesUI::dimensions()
{
    return m_dimensions;
}

}
<commit_msg>NCurses: fix long lines handling<commit_after>#include "ncurses.hh"

#include "display_buffer.hh"
#include "register_manager.hh"

#include "utf8_iterator.hh"
#include "event_manager.hh"

#include <map>

#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <fcntl.h>

namespace Kakoune
{

static void set_attribute(int attribute, bool on)
{
    if (on)
        attron(attribute);
    else
        attroff(attribute);
}

static int nc_color(Color color)
{
    switch (color)
    {
    case Color::Black:   return COLOR_BLACK;
    case Color::Red:     return COLOR_RED;
    case Color::Green:   return COLOR_GREEN;
    case Color::Yellow:  return COLOR_YELLOW;
    case Color::Blue:    return COLOR_BLUE;
    case Color::Magenta: return COLOR_MAGENTA;
    case Color::Cyan:    return COLOR_CYAN;
    case Color::White:   return COLOR_WHITE;

    case Color::Default:
    default:
        return -1;
    }
}

static int get_color_pair(Color fg_color, Color bg_color)
{
    static std::map<std::pair<Color, Color>, int> colorpairs;
    static int next_pair = 1;

    std::pair<Color, Color> colorpair(fg_color, bg_color);

    auto it = colorpairs.find(colorpair);
    if (it != colorpairs.end())
        return it->second;
    else
    {
        init_pair(next_pair, nc_color(fg_color), nc_color(bg_color));
        colorpairs[colorpair] = next_pair;
        return next_pair++;
    }
}

static void set_color(Color fg_color, Color bg_color)
{
    static int current_pair = -1;

    if (current_pair != -1)
        attroff(COLOR_PAIR(current_pair));

    if (fg_color != Color::Default or bg_color != Color::Default)
    {
        current_pair = get_color_pair(fg_color, bg_color);
        attron(COLOR_PAIR(current_pair));
    }
}

static NCursesUI* signal_ui = nullptr;
void on_term_resize(int)
{
    int fd = open("/dev/tty", O_RDWR);
    winsize ws;
    if (fd == 0 or ioctl(fd, TIOCGWINSZ, (void*)&ws) != 0)
        return;
    close(fd);
    resizeterm(ws.ws_row, ws.ws_col);
    ungetch(KEY_RESIZE);
    signal_ui->update_dimensions();
    EventManager::instance().force_signal(0);
}

NCursesUI::NCursesUI()
{
    //setlocale(LC_CTYPE, "");
    initscr();
    cbreak();
    noecho();
    nonl();
    intrflush(stdscr, false);
    keypad(stdscr, true);
    curs_set(0);
    start_color();
    use_default_colors();
    ESCDELAY=25;

    m_menu_fg = get_color_pair(Color::Blue, Color::Cyan);
    m_menu_bg = get_color_pair(Color::Cyan, Color::Blue);

    update_dimensions();

    assert(signal_ui == nullptr);
    signal_ui = this;
    signal(SIGWINCH, on_term_resize);
}

NCursesUI::~NCursesUI()
{
    endwin();
}

static void redraw(WINDOW* menu_win)
{
    wnoutrefresh(stdscr);
    if (menu_win)
    {
        redrawwin(menu_win);
        wnoutrefresh(menu_win);
    }
    doupdate();
}
using Utf8Policy = utf8::InvalidBytePolicy::Pass;
using Utf8Iterator = utf8::utf8_iterator<String::iterator, Utf8Policy>;
void addutf8str(Utf8Iterator begin, Utf8Iterator end)
{
    assert(begin <= end);
    while (begin != end)
        addch(*begin++);
}

void NCursesUI::update_dimensions()
{
    int max_x,max_y;
    getmaxyx(stdscr, max_y, max_x);
    max_y -= 1;
    m_dimensions = { max_y, max_x };
}

void NCursesUI::draw(const DisplayBuffer& display_buffer,
                     const String& status_line)
{
    LineCount line_index = 0;
    for (const DisplayLine& line : display_buffer.lines())
    {
        move((int)line_index, 0);
        clrtoeol();
        CharCount col_index = 0;
        for (const DisplayAtom& atom : line)
        {
            set_attribute(A_UNDERLINE, atom.attribute & Underline);
            set_attribute(A_REVERSE, atom.attribute & Reverse);
            set_attribute(A_BLINK, atom.attribute & Blink);
            set_attribute(A_BOLD, atom.attribute & Bold);

            set_color(atom.fg_color, atom.bg_color);

            String content = atom.content.content();
            if (content[content.length()-1] == '\n' and
                content.char_length() - 1 < m_dimensions.column - col_index)
            {
                addutf8str(Utf8Iterator(content.begin()), Utf8Iterator(content.end())-1);
                addch(' ');
            }
            else
            {
                Utf8Iterator begin(content.begin()), end(content.end());
                if (end - begin > m_dimensions.column - col_index)
                    end = begin + (m_dimensions.column - col_index);
                addutf8str(begin, end);
                col_index += end - begin;
            }
        }
        ++line_index;
    }

    set_attribute(A_UNDERLINE, 0);
    set_attribute(A_REVERSE, 0);
    set_attribute(A_BLINK, 0);
    set_attribute(A_BOLD, 0);
    set_color(Color::Blue, Color::Black);
    for (;line_index < m_dimensions.line; ++line_index)
    {
        move((int)line_index, 0);
        clrtoeol();
        addch('~');
    }

    set_color(Color::Cyan, Color::Black);
    static int last_status_length = 0;
    move((int)m_dimensions.line, (int)(m_dimensions.column - last_status_length));
    clrtoeol();
    move((int)m_dimensions.line, (int)(m_dimensions.column - status_line.char_length()));
    addstr(status_line.c_str());
    last_status_length = (int)status_line.length();

    redraw(m_menu_win);
}

struct getch_iterator
{
    int operator*() { return getch(); }
    getch_iterator& operator++() { return *this; }
    getch_iterator& operator++(int) { return *this; }
};

bool NCursesUI::is_key_available()
{
    timeout(0);
    const int c = getch();
    if (c != ERR)
        ungetch(c);
    timeout(-1);
    return c != ERR;
}

Key NCursesUI::get_key()
{
    const unsigned c = getch();
    if (c > 0 and c < 27)
    {
        return {Key::Modifiers::Control, c - 1 + 'a'};
    }
    else if (c == 27)
    {
        timeout(0);
        const Codepoint new_c = getch();
        timeout(-1);
        if (new_c != ERR)
            return {Key::Modifiers::Alt, new_c};
        else
            return Key::Escape;
    }
    else switch (c)
    {
    case KEY_BACKSPACE: return Key::Backspace;
    case KEY_UP: return Key::Up;
    case KEY_DOWN: return Key::Down;
    case KEY_LEFT: return Key::Left;
    case KEY_RIGHT: return Key::Right;
    case KEY_PPAGE: return Key::PageUp;
    case KEY_NPAGE: return Key::PageDown;
    case KEY_BTAB: return Key::BackTab;
    }

    if (c < 256)
    {
       ungetch(c);
       return utf8::codepoint(getch_iterator{});
    }
    return Key::Invalid;
}

void NCursesUI::print_status(const String& status, CharCount cursor_pos)
{
    int x,y;
    getmaxyx(stdscr, y, x);
    move(y-1, 0);
    clrtoeol();
    if (cursor_pos == -1)
       addutf8str(status.begin(), status.end());
    else
    {
        auto cursor_it = utf8::advance(status.begin(), status.end(), (int)cursor_pos);
        auto end = status.end();
        addutf8str(status.begin(), cursor_it);
        set_attribute(A_REVERSE, 1);
        addch((cursor_it == end) ? ' ' : utf8::codepoint<Utf8Policy>(cursor_it));
        set_attribute(A_REVERSE, 0);
        if (cursor_it != end)
            addutf8str(utf8::next(cursor_it), end);
    }
    redraw(m_menu_win);
}

void NCursesUI::menu_show(const memoryview<String>& choices,
                          const DisplayCoord& anchor, MenuStyle style)
{
    assert(m_menu == nullptr);
    assert(m_menu_win == nullptr);
    m_choices = std::vector<String>(choices.begin(), choices.end());
    CharCount longest = 0;
    for (int i = 0; i < m_choices.size(); ++i)
    {
        m_items.push_back(new_item(m_choices[i].c_str(), ""));
        longest = std::max(longest, m_choices[i].char_length());
    }
    m_items.push_back(nullptr);
    longest += 1;

    int max_x,max_y;
    getmaxyx(stdscr, max_y, max_x);
    max_x -= (int)anchor.column;

    int columns = (style == MenuStyle::Prompt) ?
                  (max_x / std::min(max_x, (int)longest)) : 1;
    int lines = std::min(10, (int)ceilf((float)m_choices.size()/columns));

    m_menu_pos = { anchor.line+1, anchor.column };
    if (m_menu_pos.line + lines >= max_y)
        m_menu_pos.line = anchor.line - lines;
    m_menu_size = { lines, columns == 1 ? longest : max_x };

    m_menu = new_menu(&m_items[0]);
    m_menu_win = newwin((int)m_menu_size.line, (int)m_menu_size.column,
                        (int)m_menu_pos.line,  (int)m_menu_pos.column);
    set_menu_win(m_menu, m_menu_win);
    set_menu_format(m_menu, lines, columns);
    set_menu_mark(m_menu, nullptr);
    set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
    set_menu_back(m_menu, COLOR_PAIR(m_menu_bg));
    post_menu(m_menu);
}

void NCursesUI::menu_select(int selected)
{
    // last item in m_items is the nullptr, hence the - 1
    if (selected >= 0 and selected < m_items.size() - 1)
    {
        set_menu_fore(m_menu, COLOR_PAIR(m_menu_fg));
        set_current_item(m_menu, m_items[selected]);
    }
    else
        set_menu_fore(m_menu, COLOR_PAIR(m_menu_bg));
}

void NCursesUI::menu_hide()
{
    if (not m_menu)
        return;
    unpost_menu(m_menu);
    free_menu(m_menu);
    for (auto item : m_items)
       if (item)
           free_item(item);
    m_menu = nullptr;
    delwin(m_menu_win);
    m_menu_win = nullptr;
    m_items.clear();
}

DisplayCoord NCursesUI::dimensions()
{
    return m_dimensions;
}

}
<|endoftext|>


<commit_before>// Copyright 2015 Toggl Desktop developers.

#include "../src/netconf.h"

#include <string>
#include <sstream>

#include "./https_client.h"

#include "Poco/Environment.h"
#include "Poco/Logger.h"
#include "Poco/Net/HTTPCredentials.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/URI.h"

#ifdef __MACH__
#include <CoreFoundation/CoreFoundation.h>  // NOLINT
#include <CoreServices/CoreServices.h>  // NOLINT
#endif

#ifdef _WIN32
#include <winhttp.h>
#endif

namespace toggl {

error Netconf::autodetectProxy(
    const std::string &encoded_url,
    std::string *proxy_url) {

    *proxy_url = "";

    // Inspired from Stack Overflow
    // http://stackoverflow.com/questions/202547/how-do-i-find-out-the-browsers-proxy-settings
#ifdef _WIN32
	/*
	if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig)) {
        if (ieProxyConfig.fAutoDetect) {
            fAutoProxy = TRUE;
        }

        if (ieProxyConfig.lpszAutoConfigUrl != NULL) {
            fAutoProxy = TRUE;
            autoProxyOptions.lpszAutoConfigUrl =
                ieProxyConfig.lpszAutoConfigUrl;
        }
    } else {
        // use autoproxy
        fAutoProxy = TRUE;
    }

    if (fAutoProxy) {
        if (autoProxyOptions.lpszAutoConfigUrl != NULL) {
            autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
        } else {
            autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
            autoProxyOptions.dwAutoDetectFlags =
                WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
        }

        // basic flags you almost always want
        autoProxyOptions.fAutoLogonIfChallenged = TRUE;

        // here we reset fAutoProxy in case an auto-proxy isn't actually
        // configured for this url
        fAutoProxy = WinHttpGetProxyForUrl(
            hiOpen, pwszUrl, &autoProxyOptions, &autoProxyInfo);
    }

    if (fAutoProxy) {
        // set proxy options for libcurl based on autoProxyInfo
    } else {
        if (ieProxyConfig.lpszProxy != NULL) {
            // IE has an explicit proxy. set proxy options for libcurl here
            // based on ieProxyConfig
            //
            // note that sometimes IE gives just a single or double colon
            // for proxy or bypass list, which means "no proxy"
        } else {
            // there is no auto proxy and no manually configured proxy
        }
    }
	*/
#endif

    // Inspider by VLC source code
    // https://github.com/videolan/vlc/blob/master/src/darwin/netconf.c
#ifdef __MACH__
    CFDictionaryRef dicRef = CFNetworkCopySystemProxySettings();
    if (NULL != dicRef) {
        const CFStringRef proxyCFstr = (const CFStringRef)CFDictionaryGetValue(
            dicRef, (const void*)kCFNetworkProxiesHTTPProxy);
        const CFNumberRef portCFnum = (const CFNumberRef)CFDictionaryGetValue(
            dicRef, (const void*)kCFNetworkProxiesHTTPPort);
        if (NULL != proxyCFstr && NULL != portCFnum) {
            int port = 0;
            if (!CFNumberGetValue(portCFnum, kCFNumberIntType, &port)) {
                CFRelease(dicRef);
                return noError;
            }

            const std::size_t kBufsize(4096);
            char host_buffer[kBufsize];
            memset(host_buffer, 0, sizeof(host_buffer));
            if (CFStringGetCString(proxyCFstr, host_buffer, sizeof(host_buffer)
                                   - 1, kCFStringEncodingUTF8)) {
                char buffer[kBufsize];
                snprintf(buffer, kBufsize, "%s:%d", host_buffer, port);
                *proxy_url = std::string(buffer);
            }
        }

        CFRelease(dicRef);
    }
#endif

    return noError;
}

void Netconf::ConfigureProxy(
    const std::string encoded_url,
    Poco::Net::HTTPSClientSession *session) {

    Poco::Logger &logger = Poco::Logger::get("ConfigureProxy");

    std::string proxy_url("");
    if (HTTPSClient::Config.AutodetectProxy) {
        if (Poco::Environment::has("HTTP_PROXY")) {
            proxy_url = Poco::Environment::get("HTTP_PROXY");
        }
        if (proxy_url.empty()) {
            error err = autodetectProxy(encoded_url, &proxy_url);
        }
        if (proxy_url.find("://") == std::string::npos) {
            proxy_url = "http://" + proxy_url;
        }
        Poco::URI proxy_uri(proxy_url);

        std::stringstream ss;
        ss << "Proxy detected URI=" + proxy_uri.toString()
           << " host=" << proxy_uri.getHost()
           << " port=" << proxy_uri.getPort();
        logger.debug(ss.str());

        session->setProxy(
            proxy_uri.getHost(),
            proxy_uri.getPort());

        if (!proxy_uri.getUserInfo().empty()) {
            Poco::Net::HTTPCredentials credentials;
            credentials.fromUserInfo(proxy_uri.getUserInfo());
            session->setProxyCredentials(
                credentials.getUsername(),
                credentials.getPassword());

            logger.debug("Proxy credentials detected username="
                         + credentials.getUsername());
        }
    }

    // Try to use user-configured proxy
    if (proxy_url.empty() && HTTPSClient::Config.UseProxy &&
            HTTPSClient::Config.ProxySettings.IsConfigured()) {
        session->setProxy(
            HTTPSClient::Config.ProxySettings.Host(),
            static_cast<Poco::UInt16>(
                HTTPSClient::Config.ProxySettings.Port()));

        std::stringstream ss;
        ss << "Proxy configured "
           << " host=" << HTTPSClient::Config.ProxySettings.Host()
           << " port=" << HTTPSClient::Config.ProxySettings.Port();
        logger.debug(ss.str());

        if (HTTPSClient::Config.ProxySettings.HasCredentials()) {
            session->setProxyCredentials(
                HTTPSClient::Config.ProxySettings.Username(),
                HTTPSClient::Config.ProxySettings.Password());

            logger.debug("Proxy credentials configured username="
                         + HTTPSClient::Config.ProxySettings.Username());
        }
    }
}

}   // namespace toggl
<commit_msg>Comment out  winhhtp include as it's throwing errors (win)<commit_after>// Copyright 2015 Toggl Desktop developers.

#include "../src/netconf.h"

#include <string>
#include <sstream>

#include "./https_client.h"

#include "Poco/Environment.h"
#include "Poco/Logger.h"
#include "Poco/Net/HTTPCredentials.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/URI.h"

#ifdef __MACH__
#include <CoreFoundation/CoreFoundation.h>  // NOLINT
#include <CoreServices/CoreServices.h>  // NOLINT
#endif

#ifdef _WIN32
//#include <winhttp.h>
#endif

namespace toggl {

error Netconf::autodetectProxy(
    const std::string &encoded_url,
    std::string *proxy_url) {

    *proxy_url = "";

    // Inspired from Stack Overflow
    // http://stackoverflow.com/questions/202547/how-do-i-find-out-the-browsers-proxy-settings
#ifdef _WIN32
	/*
	if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig)) {
        if (ieProxyConfig.fAutoDetect) {
            fAutoProxy = TRUE;
        }

        if (ieProxyConfig.lpszAutoConfigUrl != NULL) {
            fAutoProxy = TRUE;
            autoProxyOptions.lpszAutoConfigUrl =
                ieProxyConfig.lpszAutoConfigUrl;
        }
    } else {
        // use autoproxy
        fAutoProxy = TRUE;
    }

    if (fAutoProxy) {
        if (autoProxyOptions.lpszAutoConfigUrl != NULL) {
            autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
        } else {
            autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
            autoProxyOptions.dwAutoDetectFlags =
                WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
        }

        // basic flags you almost always want
        autoProxyOptions.fAutoLogonIfChallenged = TRUE;

        // here we reset fAutoProxy in case an auto-proxy isn't actually
        // configured for this url
        fAutoProxy = WinHttpGetProxyForUrl(
            hiOpen, pwszUrl, &autoProxyOptions, &autoProxyInfo);
    }

    if (fAutoProxy) {
        // set proxy options for libcurl based on autoProxyInfo
    } else {
        if (ieProxyConfig.lpszProxy != NULL) {
            // IE has an explicit proxy. set proxy options for libcurl here
            // based on ieProxyConfig
            //
            // note that sometimes IE gives just a single or double colon
            // for proxy or bypass list, which means "no proxy"
        } else {
            // there is no auto proxy and no manually configured proxy
        }
    }
	*/
#endif

    // Inspider by VLC source code
    // https://github.com/videolan/vlc/blob/master/src/darwin/netconf.c
#ifdef __MACH__
    CFDictionaryRef dicRef = CFNetworkCopySystemProxySettings();
    if (NULL != dicRef) {
        const CFStringRef proxyCFstr = (const CFStringRef)CFDictionaryGetValue(
            dicRef, (const void*)kCFNetworkProxiesHTTPProxy);
        const CFNumberRef portCFnum = (const CFNumberRef)CFDictionaryGetValue(
            dicRef, (const void*)kCFNetworkProxiesHTTPPort);
        if (NULL != proxyCFstr && NULL != portCFnum) {
            int port = 0;
            if (!CFNumberGetValue(portCFnum, kCFNumberIntType, &port)) {
                CFRelease(dicRef);
                return noError;
            }

            const std::size_t kBufsize(4096);
            char host_buffer[kBufsize];
            memset(host_buffer, 0, sizeof(host_buffer));
            if (CFStringGetCString(proxyCFstr, host_buffer, sizeof(host_buffer)
                                   - 1, kCFStringEncodingUTF8)) {
                char buffer[kBufsize];
                snprintf(buffer, kBufsize, "%s:%d", host_buffer, port);
                *proxy_url = std::string(buffer);
            }
        }

        CFRelease(dicRef);
    }
#endif

    return noError;
}

void Netconf::ConfigureProxy(
    const std::string encoded_url,
    Poco::Net::HTTPSClientSession *session) {

    Poco::Logger &logger = Poco::Logger::get("ConfigureProxy");

    std::string proxy_url("");
    if (HTTPSClient::Config.AutodetectProxy) {
        if (Poco::Environment::has("HTTP_PROXY")) {
            proxy_url = Poco::Environment::get("HTTP_PROXY");
        }
        if (proxy_url.empty()) {
            error err = autodetectProxy(encoded_url, &proxy_url);
        }
        if (proxy_url.find("://") == std::string::npos) {
            proxy_url = "http://" + proxy_url;
        }
        Poco::URI proxy_uri(proxy_url);

        std::stringstream ss;
        ss << "Proxy detected URI=" + proxy_uri.toString()
           << " host=" << proxy_uri.getHost()
           << " port=" << proxy_uri.getPort();
        logger.debug(ss.str());

        session->setProxy(
            proxy_uri.getHost(),
            proxy_uri.getPort());

        if (!proxy_uri.getUserInfo().empty()) {
            Poco::Net::HTTPCredentials credentials;
            credentials.fromUserInfo(proxy_uri.getUserInfo());
            session->setProxyCredentials(
                credentials.getUsername(),
                credentials.getPassword());

            logger.debug("Proxy credentials detected username="
                         + credentials.getUsername());
        }
    }

    // Try to use user-configured proxy
    if (proxy_url.empty() && HTTPSClient::Config.UseProxy &&
            HTTPSClient::Config.ProxySettings.IsConfigured()) {
        session->setProxy(
            HTTPSClient::Config.ProxySettings.Host(),
            static_cast<Poco::UInt16>(
                HTTPSClient::Config.ProxySettings.Port()));

        std::stringstream ss;
        ss << "Proxy configured "
           << " host=" << HTTPSClient::Config.ProxySettings.Host()
           << " port=" << HTTPSClient::Config.ProxySettings.Port();
        logger.debug(ss.str());

        if (HTTPSClient::Config.ProxySettings.HasCredentials()) {
            session->setProxyCredentials(
                HTTPSClient::Config.ProxySettings.Username(),
                HTTPSClient::Config.ProxySettings.Password());

            logger.debug("Proxy credentials configured username="
                         + HTTPSClient::Config.ProxySettings.Username());
        }
    }
}

}   // namespace toggl
<|endoftext|>


<commit_before>#include "command.hh"
#include "common-args.hh"
#include "shared.hh"
#include "store-api.hh"
#include "derivations.hh"
#include "local-store.hh"
#include "finally.hh"
#include "fs-accessor.hh"
#include "progress-bar.hh"

#if __linux__
#include <sys/mount.h>
#endif

using namespace nix;

std::string chrootHelperName = "__run_in_chroot";

struct CmdRun : InstallablesCommand
{
    Strings command = { "bash" };
    StringSet keep, unset;
    bool ignoreEnvironment = false;

    CmdRun()
    {
        mkFlag()
            .longName("command")
            .shortName('c')
            .description("command and arguments to be executed; defaults to 'bash'")
            .arity(ArityAny)
            .labels({"command", "args"})
            .handler([&](Strings ss) {
                if (ss.empty()) throw UsageError("--command requires at least one argument");
                command = ss;
            });

        mkFlag()
            .longName("ignore-environment")
            .shortName('i')
            .description("clear the entire environment (except those specified with --keep)")
            .handler([&](Strings ss) { ignoreEnvironment = true; });

        mkFlag()
            .longName("keep")
            .shortName('k')
            .description("keep specified environment variable")
            .arity(1)
            .labels({"name"})
            .handler([&](Strings ss) { keep.insert(ss.front()); });

        mkFlag()
            .longName("unset")
            .shortName('u')
            .description("unset specified environment variable")
            .arity(1)
            .labels({"name"})
            .handler([&](Strings ss) { unset.insert(ss.front()); });
    }

    std::string name() override
    {
        return "run";
    }

    std::string description() override
    {
        return "run a shell in which the specified packages are available";
    }

    void run(ref<Store> store) override
    {
        auto outPaths = toStorePaths(store, Build);

        auto accessor = store->getFSAccessor();

        if (ignoreEnvironment) {

            if (!unset.empty())
                throw UsageError("--unset does not make sense with --ignore-environment");

            std::map<std::string, std::string> kept;
            for (auto & var : keep) {
                auto s = getenv(var.c_str());
                if (s) kept[var] = s;
            }

            clearenv();

            for (auto & var : kept)
                setenv(var.first.c_str(), var.second.c_str(), 1);

        } else {

            if (!keep.empty())
                throw UsageError("--keep does not make sense without --ignore-environment");

            for (auto & var : unset)
                unsetenv(var.c_str());
        }

        auto unixPath = tokenizeString<Strings>(getEnv("PATH"), ":");
        for (auto & path : outPaths)
            if (accessor->stat(path + "/bin").type != FSAccessor::tMissing)
                unixPath.push_front(path + "/bin");
        setenv("PATH", concatStringsSep(":", unixPath).c_str(), 1);

        std::string cmd = *command.begin();
        Strings args = command;

        stopProgressBar();

        /* If this is a diverted store (i.e. its "logical" location
           (typically /nix/store) differs from its "physical" location
           (e.g. /home/eelco/nix/store), then run the command in a
           chroot. For non-root users, this requires running it in new
           mount and user namespaces. Unfortunately,
           unshare(CLONE_NEWUSER) doesn't work in a multithreaded
           program (which "nix" is), so we exec() a single-threaded
           helper program (chrootHelper() below) to do the work. */
        auto store2 = store.dynamic_pointer_cast<LocalStore>();

        if (store2 && store->storeDir != store2->realStoreDir) {
            Strings helperArgs = { chrootHelperName, store->storeDir, store2->realStoreDir, cmd };
            for (auto & arg : args) helperArgs.push_back(arg);

            execv(readLink("/proc/self/exe").c_str(), stringsToCharPtrs(helperArgs).data());

            throw SysError("could not execute chroot helper");
        }

        execvp(cmd.c_str(), stringsToCharPtrs(args).data());

        throw SysError("unable to exec '%s'", cmd);
    }
};

static RegisterCommand r1(make_ref<CmdRun>());

void chrootHelper(int argc, char * * argv)
{
    int p = 1;
    std::string storeDir = argv[p++];
    std::string realStoreDir = argv[p++];
    std::string cmd = argv[p++];
    Strings args;
    while (p < argc)
        args.push_back(argv[p++]);

#if __linux__
    uid_t uid = getuid();
    uid_t gid = getgid();

    if (unshare(CLONE_NEWUSER | CLONE_NEWNS) == -1)
        throw SysError("setting up a private mount namespace");

    /* Bind-mount realStoreDir on /nix/store. If the latter mount
       point doesn't already exists, we have to create a chroot
       environment containing the mount point and bind mounts for the
       children of /. Would be nice if we could use overlayfs here,
       but that doesn't work in a user namespace yet (Ubuntu has a
       patch for this:
       https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1478578). */
    if (true /* !pathExists(storeDir) */) {
        // FIXME: Use overlayfs?

        Path tmpDir = createTempDir();

        createDirs(tmpDir + storeDir);

        if (mount(realStoreDir.c_str(), (tmpDir + storeDir).c_str(), "", MS_BIND, 0) == -1)
            throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir);

        for (auto entry : readDirectory("/")) {
            Path dst = tmpDir + "/" + entry.name;
            if (pathExists(dst)) continue;
            if (mkdir(dst.c_str(), 0700) == -1)
                throw SysError(format("creating directory '%s'") % dst);
            if (mount(("/" + entry.name).c_str(), dst.c_str(), "", MS_BIND | MS_REC, 0) == -1)
                throw SysError(format("mounting '%s' on '%s'") %  ("/" + entry.name) % dst);
        }

        char * cwd = getcwd(0, 0);
        if (!cwd) throw SysError("getting current directory");
        Finally freeCwd([&]() { free(cwd); });

        if (chroot(tmpDir.c_str()) == -1)
            throw SysError(format("chrooting into '%s'") % tmpDir);

        if (chdir(cwd) == -1)
            throw SysError(format("chdir to '%s' in chroot") % cwd);
    } else
        if (mount(realStoreDir.c_str(), storeDir.c_str(), "", MS_BIND, 0) == -1)
            throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir);

    writeFile("/proc/self/setgroups", "deny");
    writeFile("/proc/self/uid_map", fmt("%d %d %d", uid, uid, 1));
    writeFile("/proc/self/gid_map", fmt("%d %d %d", gid, gid, 1));

    execvp(cmd.c_str(), stringsToCharPtrs(args).data());

    throw SysError("unable to exec '%s'", cmd);

#else
    throw Error("mounting the Nix store on '%s' is not supported on this platform", >storeDir);
#endif
}
<commit_msg>Fix build failure on non-Linux<commit_after>#include "command.hh"
#include "common-args.hh"
#include "shared.hh"
#include "store-api.hh"
#include "derivations.hh"
#include "local-store.hh"
#include "finally.hh"
#include "fs-accessor.hh"
#include "progress-bar.hh"

#if __linux__
#include <sys/mount.h>
#endif

using namespace nix;

std::string chrootHelperName = "__run_in_chroot";

struct CmdRun : InstallablesCommand
{
    Strings command = { "bash" };
    StringSet keep, unset;
    bool ignoreEnvironment = false;

    CmdRun()
    {
        mkFlag()
            .longName("command")
            .shortName('c')
            .description("command and arguments to be executed; defaults to 'bash'")
            .arity(ArityAny)
            .labels({"command", "args"})
            .handler([&](Strings ss) {
                if (ss.empty()) throw UsageError("--command requires at least one argument");
                command = ss;
            });

        mkFlag()
            .longName("ignore-environment")
            .shortName('i')
            .description("clear the entire environment (except those specified with --keep)")
            .handler([&](Strings ss) { ignoreEnvironment = true; });

        mkFlag()
            .longName("keep")
            .shortName('k')
            .description("keep specified environment variable")
            .arity(1)
            .labels({"name"})
            .handler([&](Strings ss) { keep.insert(ss.front()); });

        mkFlag()
            .longName("unset")
            .shortName('u')
            .description("unset specified environment variable")
            .arity(1)
            .labels({"name"})
            .handler([&](Strings ss) { unset.insert(ss.front()); });
    }

    std::string name() override
    {
        return "run";
    }

    std::string description() override
    {
        return "run a shell in which the specified packages are available";
    }

    void run(ref<Store> store) override
    {
        auto outPaths = toStorePaths(store, Build);

        auto accessor = store->getFSAccessor();

        if (ignoreEnvironment) {

            if (!unset.empty())
                throw UsageError("--unset does not make sense with --ignore-environment");

            std::map<std::string, std::string> kept;
            for (auto & var : keep) {
                auto s = getenv(var.c_str());
                if (s) kept[var] = s;
            }

            clearenv();

            for (auto & var : kept)
                setenv(var.first.c_str(), var.second.c_str(), 1);

        } else {

            if (!keep.empty())
                throw UsageError("--keep does not make sense without --ignore-environment");

            for (auto & var : unset)
                unsetenv(var.c_str());
        }

        auto unixPath = tokenizeString<Strings>(getEnv("PATH"), ":");
        for (auto & path : outPaths)
            if (accessor->stat(path + "/bin").type != FSAccessor::tMissing)
                unixPath.push_front(path + "/bin");
        setenv("PATH", concatStringsSep(":", unixPath).c_str(), 1);

        std::string cmd = *command.begin();
        Strings args = command;

        stopProgressBar();

        /* If this is a diverted store (i.e. its "logical" location
           (typically /nix/store) differs from its "physical" location
           (e.g. /home/eelco/nix/store), then run the command in a
           chroot. For non-root users, this requires running it in new
           mount and user namespaces. Unfortunately,
           unshare(CLONE_NEWUSER) doesn't work in a multithreaded
           program (which "nix" is), so we exec() a single-threaded
           helper program (chrootHelper() below) to do the work. */
        auto store2 = store.dynamic_pointer_cast<LocalStore>();

        if (store2 && store->storeDir != store2->realStoreDir) {
            Strings helperArgs = { chrootHelperName, store->storeDir, store2->realStoreDir, cmd };
            for (auto & arg : args) helperArgs.push_back(arg);

            execv(readLink("/proc/self/exe").c_str(), stringsToCharPtrs(helperArgs).data());

            throw SysError("could not execute chroot helper");
        }

        execvp(cmd.c_str(), stringsToCharPtrs(args).data());

        throw SysError("unable to exec '%s'", cmd);
    }
};

static RegisterCommand r1(make_ref<CmdRun>());

void chrootHelper(int argc, char * * argv)
{
    int p = 1;
    std::string storeDir = argv[p++];
    std::string realStoreDir = argv[p++];
    std::string cmd = argv[p++];
    Strings args;
    while (p < argc)
        args.push_back(argv[p++]);

#if __linux__
    uid_t uid = getuid();
    uid_t gid = getgid();

    if (unshare(CLONE_NEWUSER | CLONE_NEWNS) == -1)
        throw SysError("setting up a private mount namespace");

    /* Bind-mount realStoreDir on /nix/store. If the latter mount
       point doesn't already exists, we have to create a chroot
       environment containing the mount point and bind mounts for the
       children of /. Would be nice if we could use overlayfs here,
       but that doesn't work in a user namespace yet (Ubuntu has a
       patch for this:
       https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1478578). */
    if (true /* !pathExists(storeDir) */) {
        // FIXME: Use overlayfs?

        Path tmpDir = createTempDir();

        createDirs(tmpDir + storeDir);

        if (mount(realStoreDir.c_str(), (tmpDir + storeDir).c_str(), "", MS_BIND, 0) == -1)
            throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir);

        for (auto entry : readDirectory("/")) {
            Path dst = tmpDir + "/" + entry.name;
            if (pathExists(dst)) continue;
            if (mkdir(dst.c_str(), 0700) == -1)
                throw SysError(format("creating directory '%s'") % dst);
            if (mount(("/" + entry.name).c_str(), dst.c_str(), "", MS_BIND | MS_REC, 0) == -1)
                throw SysError(format("mounting '%s' on '%s'") %  ("/" + entry.name) % dst);
        }

        char * cwd = getcwd(0, 0);
        if (!cwd) throw SysError("getting current directory");
        Finally freeCwd([&]() { free(cwd); });

        if (chroot(tmpDir.c_str()) == -1)
            throw SysError(format("chrooting into '%s'") % tmpDir);

        if (chdir(cwd) == -1)
            throw SysError(format("chdir to '%s' in chroot") % cwd);
    } else
        if (mount(realStoreDir.c_str(), storeDir.c_str(), "", MS_BIND, 0) == -1)
            throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir);

    writeFile("/proc/self/setgroups", "deny");
    writeFile("/proc/self/uid_map", fmt("%d %d %d", uid, uid, 1));
    writeFile("/proc/self/gid_map", fmt("%d %d %d", gid, gid, 1));

    execvp(cmd.c_str(), stringsToCharPtrs(args).data());

    throw SysError("unable to exec '%s'", cmd);

#else
    throw Error("mounting the Nix store on '%s' is not supported on this platform", storeDir);
#endif
}
<|endoftext|>


<commit_before>#include "dDNNF.h"

#include <unordered_map>

double dDNNF::dDNNFEvaluation(unsigned g) const
{
  static std::unordered_map<unsigned, double> cache;

  auto it = cache.find(g);
  if(it!=cache.end())
    return it->second;

  double result;

  if(gates[g]==BooleanGate::IN)
    result = prob[g];
  else if(gates[g]==BooleanGate::NOT)
    result = 1-prob[wires[g][0]];
  else {
    result=(gates[g]==BooleanGate::AND?1:0);
    for(auto s: wires[g]) {
      double d = dDNNFEvaluation(s);
      if(gates[g]==BooleanGate::AND)
        result*=d;
      else
        result+=d;
    }
  }

  cache[g]=result;
  return result;
}

<commit_msg>More robust<commit_after>#include "dDNNF.h"

#include <unordered_map>

double dDNNF::dDNNFEvaluation(unsigned g) const
{
  static std::unordered_map<unsigned, double> cache;

  auto it = cache.find(g);
  if(it!=cache.end())
    return it->second;

  double result;

  if(gates[g]==BooleanGate::IN)
    result = prob[g];
  else if(gates[g]==BooleanGate::NOT)
    result = 1-prob[*wires[g].begin()];
  else {
    result=(gates[g]==BooleanGate::AND?1:0);
    for(auto s: wires[g]) {
      double d = dDNNFEvaluation(s);
      if(gates[g]==BooleanGate::AND)
        result*=d;
      else
        result+=d;
    }
  }

  cache[g]=result;
  return result;
}

<|endoftext|>


<commit_before>
#ifdef DAGMC

#include "dagmc.h"
#include "openmc/error.h"

#include <string>
#include <algorithm>

moab::DagMC* DAG;

#define TOLOWER(S) std::transform(S.begin(), S.end(), S.begin(), ::tolower)

void load_dagmc_geometry_c()
{
  if(!DAG) {
    DAG = new moab::DagMC();
  }

  int32_t dagmc_univ_id = 0; // universe is always 0 for DAGMC

  moab::ErrorCode rval = DAG->load_file("dagmc.h5m");
  MB_CHK_ERR_CONT(rval);

  rval = DAG->init_OBBTree();
  MB_CHK_ERR_CONT(rval);

  std::vector< std::string > prop_keywords;
  prop_keywords.push_back("mat");
  prop_keywords.push_back("boundary");

  std::map<std::string, std::string> ph;
  DAG->parse_properties(prop_keywords, ph, ":");
  MB_CHK_ERR_CONT(rval);

  // initialize cell objects
  openmc::n_cells = DAG->num_entities(3);
  for(int i = 0; i < openmc::n_cells; i++)
    {
      moab::EntityHandle vol_handle = DAG->entity_by_index(3, i+1);

      // set cell ids using global IDs
      openmc::DAGCell* c = new openmc::DAGCell();
      c->id_ = DAG->id_by_index(3, i+1);
      c->dagmc_ptr = DAG;
      c->universe_ = dagmc_univ_id; // set to zero for now
      c->fill_ = openmc::C_NONE; // no fill, single universe

      openmc::cells.push_back(c);
      openmc::cell_map[c->id_] = c->id_;

      // Populate the Universe vector and dict
      auto it = openmc::universe_map.find(dagmc_univ_id);
      if (it == openmc::universe_map.end()) {
	openmc::universes.push_back(new openmc::Universe());
	openmc::universes.back()-> id_ = dagmc_univ_id;
	openmc::universes.back()->cells_.push_back(i);
	openmc::universe_map[dagmc_univ_id] = openmc::universes.size() - 1;
      }
      else {
	openmc::universes[it->second]->cells_.push_back(i);
      }

      if(DAG->is_implicit_complement(vol_handle)) {
	// assuming implicit complement is void for now
        c->material_.push_back(openmc::MATERIAL_VOID);
	continue;
      }

      if(DAG->has_prop(vol_handle, "mat")){
	std::string mat_value;
	rval = DAG->prop_value(vol_handle, "mat", mat_value);
	MB_CHK_ERR_CONT(rval);
	TOLOWER(mat_value);

	if(mat_value == "void" || mat_value == "vacuum") {
	  c->material_.push_back(openmc::MATERIAL_VOID);
	}
	else {
	  c->material_.push_back(std::stoi(mat_value));
	}
      }
      else {
	std::cout << c->id_ << std::endl;
	openmc::fatal_error("A volume without a material was found.");
      }
    }

  // initialize surface objects
  openmc::n_surfaces = DAG->num_entities(2);
  openmc::surfaces.resize(openmc::n_surfaces);

  for(int i = 0; i < openmc::n_surfaces; i++)
    {
      moab::EntityHandle surf_handle = DAG->entity_by_index(2, i+1);

      // set cell ids using global IDs
      openmc::DAGSurface* s = new openmc::DAGSurface();
      s->id_ = DAG->id_by_index(2, i+1);
      s->dagmc_ptr = DAG;

      if(DAG->has_prop(surf_handle, "boundary")) {
	std::string bc_value;
	rval = DAG->prop_value(surf_handle, "boundary", bc_value);
	MB_CHK_ERR_CONT(rval);
	TOLOWER(bc_value);

	if(bc_value == "transmit" || bc_value == "transmission") {
	  s->bc_ = openmc::BC_TRANSMIT;
	}
	else if(bc_value == "vacuum") {
	  s->bc_ = openmc::BC_VACUUM;
	}
	else if(bc_value == "reflective" || bc_value == "reflect" || bc_value == "reflecting") {
	  s->bc_ = openmc::BC_REFLECT;
	}
	else if(bc_value == "periodic") {
	  openmc::fatal_error("Periodic boundary condition not supported in DAGMC.");
	}
	else {
	  std::stringstream err_msg;
	  err_msg << "Unknown boundary condition \"" << s->bc_
		  << "\" specified on surface " << s->id_;
	  openmc::fatal_error(err_msg);
	}
      }
      // if no BC property is found, set to transmit
      else {
	s->bc_ = openmc::BC_TRANSMIT;
      }

      // add to global array and map
      openmc::surfaces[i] = s;
      openmc::surface_map[s->id_] = s->id_;
    }

  return;
}

void free_memory_dagmc_c()
{
  delete DAG;
}

#endif
<commit_msg>Indentation and formatting updates.<commit_after>
#ifdef DAGMC

#include "dagmc.h"
#include "openmc/error.h"

#include <string>
#include <algorithm>

moab::DagMC* DAG;

#define TOLOWER(S) std::transform(S.begin(), S.end(), S.begin(), ::tolower)

void load_dagmc_geometry_c()
{
  if(!DAG) {
    DAG = new moab::DagMC();
  }

  int32_t dagmc_univ_id = 0; // universe is always 0 for DAGMC

  moab::ErrorCode rval = DAG->load_file("dagmc.h5m");
  MB_CHK_ERR_CONT(rval);

  rval = DAG->init_OBBTree();
  MB_CHK_ERR_CONT(rval);

  std::vector< std::string > prop_keywords;
  prop_keywords.push_back("mat");
  prop_keywords.push_back("boundary");

  std::map<std::string, std::string> ph;
  DAG->parse_properties(prop_keywords, ph, ":");
  MB_CHK_ERR_CONT(rval);

  // initialize cell objects
  openmc::n_cells = DAG->num_entities(3);
  for(int i = 0; i < openmc::n_cells; i++) {
    moab::EntityHandle vol_handle = DAG->entity_by_index(3, i+1);

    // set cell ids using global IDs
    openmc::DAGCell* c = new openmc::DAGCell();
    c->id_ = DAG->id_by_index(3, i+1);
    c->dagmc_ptr = DAG;
    c->universe_ = dagmc_univ_id; // set to zero for now
    c->fill_ = openmc::C_NONE; // no fill, single universe

    openmc::cells.push_back(c);
    openmc::cell_map[c->id_] = c->id_;

    // Populate the Universe vector and dict
    auto it = openmc::universe_map.find(dagmc_univ_id);
    if (it == openmc::universe_map.end()) {
      openmc::universes.push_back(new openmc::Universe());
      openmc::universes.back()-> id_ = dagmc_univ_id;
      openmc::universes.back()->cells_.push_back(i);
      openmc::universe_map[dagmc_univ_id] = openmc::universes.size() - 1;
    }
    else {
      openmc::universes[it->second]->cells_.push_back(i);
    }

    if(DAG->is_implicit_complement(vol_handle)) {
      // assuming implicit complement is void for now
      c->material_.push_back(openmc::MATERIAL_VOID);
      continue;
    }

    if(DAG->has_prop(vol_handle, "mat")){
      std::string mat_value;
      rval = DAG->prop_value(vol_handle, "mat", mat_value);
      MB_CHK_ERR_CONT(rval);
      TOLOWER(mat_value);

      if(mat_value == "void" || mat_value == "vacuum") {
	c->material_.push_back(openmc::MATERIAL_VOID);
      }
      else {
	c->material_.push_back(std::stoi(mat_value));
      }
    }
    else {
      std::cout << c->id_ << std::endl;
      openmc::fatal_error("A volume without a material was found.");
    }
  }

  // initialize surface objects
  openmc::n_surfaces = DAG->num_entities(2);
  openmc::surfaces.resize(openmc::n_surfaces);

  for(int i = 0; i < openmc::n_surfaces; i++) {
    moab::EntityHandle surf_handle = DAG->entity_by_index(2, i+1);

    // set cell ids using global IDs
    openmc::DAGSurface* s = new openmc::DAGSurface();
    s->id_ = DAG->id_by_index(2, i+1);
    s->dagmc_ptr = DAG;

    if(DAG->has_prop(surf_handle, "boundary")) {
      std::string bc_value;
      rval = DAG->prop_value(surf_handle, "boundary", bc_value);
      MB_CHK_ERR_CONT(rval);
      TOLOWER(bc_value);

      if(bc_value == "transmit" || bc_value == "transmission") {
	s->bc_ = openmc::BC_TRANSMIT;
      }
      else if(bc_value == "vacuum") {
	s->bc_ = openmc::BC_VACUUM;
      }
      else if(bc_value == "reflective" || bc_value == "reflect" || bc_value == "reflecting") {
	s->bc_ = openmc::BC_REFLECT;
      }
      else if(bc_value == "periodic") {
	openmc::fatal_error("Periodic boundary condition not supported in DAGMC.");
      }
      else {
	std::stringstream err_msg;
	err_msg << "Unknown boundary condition \"" << s->bc_
		<< "\" specified on surface " << s->id_;
	openmc::fatal_error(err_msg);
      }
    }
    // if no BC property is found, set to transmit
    else {
      s->bc_ = openmc::BC_TRANSMIT;
    }

    // add to global array and map
    openmc::surfaces[i] = s;
    openmc::surface_map[s->id_] = s->id_;
  }

  return;
}

void free_memory_dagmc_c()
{
  delete DAG;
}

#endif
<|endoftext|>


<commit_before>// =============================================================================
// File Name: Elevator.cpp
// Description: Provides an interface for the robot's elevator
// Author: FRC Team 3512, Spartatroniks
// =============================================================================

#include "Elevator.hpp"
#include <Solenoid.h>
#include <DigitalInput.h>
#include <CANTalon.h>

Elevator::Elevator() : TrapezoidProfile(0.0, 0.0) {
    m_elevatorGrabber = std::make_unique<Solenoid>(3);
    m_containerGrabber = std::make_unique<Solenoid>(4);

    m_intakeStower = std::make_unique<Solenoid>(1);
    m_intakeGrabber = std::make_unique<Solenoid>(2);
    m_intakeWheelLeft = std::make_unique<CANTalon>(3);
    m_intakeWheelRight = std::make_unique<CANTalon>(6);
    m_intakeState = S_STOPPED;

    // For CANTalon PID loop
    m_liftGrbx = std::make_unique<GearBox<CANTalon>>(-1, 7, 2);
    m_liftGrbx->setEncoderReversed(true);
    m_liftGrbx->setDistancePerPulse(70.5 / 5090.0);

    m_liftGrbx->setProfile(false);
    m_liftGrbx->setIZone(80);
    m_liftGrbx->setCloseLoopRampRate(1.0);

    m_liftGrbx->setProfile(true);
    m_liftGrbx->setIZone(80);
    m_liftGrbx->setCloseLoopRampRate(1.0);

    m_profileTimer = std::make_unique<Timer>();
    m_grabTimer = std::make_unique<Timer>();

    m_profileUpdater = new std::thread([this] {
        double height = 0.0;
        while (m_updateProfile) {
            if (!atGoal()) {
                height = updateSetpoint(m_profileTimer->Get());
            }
            else {
                height = m_setpoint;
            }
            setHeight(height);

            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
    });

    // Load motion profile constants from the configuration file
    m_maxv_a = m_settings->getDouble("EV_MAX_VELOCITY_PROFILE_A");
    m_ttmaxv_a = m_settings->getDouble("EV_TIME_TO_MAX_VELOCITY_PROFILE_A");
    m_maxv_b = m_settings->getDouble("EV_MAX_VELOCITY_PROFILE_B");
    m_ttmaxv_b = m_settings->getDouble("EV_TIME_TO_MAX_VELOCITY_PROFILE_B");

    // Load elevator levels from the configuration file
    m_maxHeight = m_settings->getDouble("EV_MAX_HEIGHT");
    m_toteHeights["EV_GROUND"] = m_settings->getDouble("EV_GROUND");

    double height = 0;
    for (int i = 1; i <= 6; i++) {
        height = m_settings->getDouble("EV_TOTE_" + std::to_string(i));
        m_toteHeights["EV_TOTE_" + std::to_string(i)] = height;
    }

    m_toteHeights["EV_STEP"] = m_settings->getDouble("EV_STEP");
    m_toteHeights["EV_HALF_TOTE_OFFSET"] = m_settings->getDouble(
        "EV_HALF_TOTE_OFFSET");
    m_toteHeights["EV_GARBAGECAN_LEVEL"] = m_settings->getDouble(
        "EV_GARBAGECAN_LEVEL");
    m_toteHeights["EV_AUTO_DROP_LENGTH"] = m_settings->getDouble(
        "EV_AUTO_DROP_LENGTH");

    State* state = new State("IDLE");
    state->initFunc = [this] { m_startAutoStacking = false; };
    state->advanceFunc = [this] {
        if (m_startAutoStacking) {
            return "WAIT_INITIAL_HEIGHT";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);
    m_autoStackSM.setState("IDLE");

    state = new State("WAIT_INITIAL_HEIGHT");
    state->initFunc = [this] {
        setProfileHeight(m_toteHeights["EV_TOTE_1"]);
    };
    state->advanceFunc = [this] {
        if (atGoal()) {
            return "SEEK_DROP_TOTES";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("SEEK_DROP_TOTES");
    state->initFunc = [this] {
        setProfileHeight(getGoal() - m_toteHeights["EV_AUTO_DROP_LENGTH"]);
    };
    state->advanceFunc = [this] {
        if (atGoal()) {
            return "RELEASE";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("RELEASE");
    state->initFunc = [this] {
        m_grabTimer->Reset();
        m_grabTimer->Start();
        elevatorGrab(false);
    };
    state->advanceFunc = [this] {
        if (m_grabTimer->HasPeriodPassed(0.2)) {
            return "SEEK_GROUND";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("SEEK_GROUND");
    state->initFunc = [this] {
        setProfileHeight(m_toteHeights["EV_GROUND"]);
    };
    state->advanceFunc = [this] {
        if (atGoal()) {
            return "GRAB";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("GRAB");
    state->initFunc = [this] {
        m_grabTimer->Reset();
        m_grabTimer->Start();
        elevatorGrab(true);
    };
    state->advanceFunc = [this] {
        if (m_grabTimer->HasPeriodPassed(0.4)) {
            return "SEEK_HALF_TOTE";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("SEEK_HALF_TOTE");
    state->initFunc = [this] {
        setProfileHeight(m_toteHeights["EV_TOTE_1"]);
    };
    state->advanceFunc = [this] {
        if (atGoal()) {
            return "INTAKE_IN";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("INTAKE_IN");
    state->initFunc = [this] {
        m_grabTimer->Reset();
        m_grabTimer->Start();
        intakeGrab(true);
    };
    state->advanceFunc = [this] {
        if (m_grabTimer->HasPeriodPassed(0.2)) {
            return "IDLE";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    // Reload PID constants from the configuration file
    reloadPID();
}

Elevator::~Elevator() {
    m_updateProfile = false;
    if (m_profileUpdater != nullptr) {
        m_profileUpdater->join();
        delete m_profileUpdater;
    }
}

void Elevator::elevatorGrab(bool state) {
    m_elevatorGrabber->Set(!state);
}

bool Elevator::isElevatorGrabbed() const {
    return !m_elevatorGrabber->Get();
}

void Elevator::intakeGrab(bool state) {
    m_intakeGrabber->Set(state);
}

bool Elevator::isIntakeGrabbed() const {
    return m_intakeGrabber->Get();
}

void Elevator::stowIntake(bool state) {
    m_intakeStower->Set(!state);
}

bool Elevator::isIntakeStowed() const {
    return !m_intakeStower->Get();
}

void Elevator::containerGrab(bool state) {
    m_containerGrabber->Set(!state);
}

bool Elevator::isContainerGrabbed() const {
    return !m_containerGrabber->Get();
}

void Elevator::setIntakeDirectionLeft(IntakeMotorState state) {
    m_intakeState = state;

    if (state == S_STOPPED) {
        m_intakeWheelLeft->Set(0);
    }
    else if (state == S_FORWARD) {
        m_intakeWheelLeft->Set(1);
    }
    else if (state == S_REVERSE) {
        m_intakeWheelLeft->Set(-1);
    }
    else if (state == S_ROTATE_CCW) {
        m_intakeWheelLeft->Set(-1);
    }
    else if (state == S_ROTATE_CW) {
        m_intakeWheelLeft->Set(1);
    }
}

void Elevator::setIntakeDirectionRight(IntakeMotorState state) {
    m_intakeState = state;

    if (state == S_STOPPED) {
        m_intakeWheelRight->Set(0);
    }
    else if (state == S_FORWARD) {
        m_intakeWheelRight->Set(-1);
    }
    else if (state == S_REVERSE) {
        m_intakeWheelRight->Set(1);
    }
    else if (state == S_ROTATE_CCW) {
        m_intakeWheelRight->Set(-1);
    }
    else if (state == S_ROTATE_CW) {
        m_intakeWheelRight->Set(1);
    }
}

Elevator::IntakeMotorState Elevator::getIntakeDirection() const {
    return m_intakeState;
}

void Elevator::setManualLiftSpeed(double value) {
    if (m_manual) {
        m_liftGrbx->setManual(value);
    }
}

double Elevator::getManualLiftSpeed() const {
    if (m_manual) {
        return m_liftGrbx->get(Grbx::Raw);
    }

    return 0.0;
}

void Elevator::setManualMode(bool on) {
    if (on != m_manual) {
        m_manual = on;

        if (m_manual) {
            // Stop any auto-stacking when we switch to manual mode
            m_autoStackSM.setState("IDLE");
        }
        else {
            setProfileHeight(getHeight());
        }
    }
}

bool Elevator::isManualMode() const {
    return m_manual;
}

void Elevator::setHeight(double height) {
    if (m_manual == false) {
        m_liftGrbx->setSetpoint(height);
    }
}

double Elevator::getHeight() const {
    return m_liftGrbx->get(Grbx::Position);
}

void Elevator::reloadPID() {
    m_settings->update();

    // First profile
    double p = 0.f;
    double i = 0.f;
    double d = 0.f;
    double f = 0.f;

    // Set elevator PID
    p = m_settings->getDouble("PID_ELEVATOR_DOWN_P");
    i = m_settings->getDouble("PID_ELEVATOR_DOWN_I");
    d = m_settings->getDouble("PID_ELEVATOR_DOWN_D");
    f = m_settings->getDouble("PID_ELEVATOR_DOWN_F");

    m_liftGrbx->setProfile(false);
    m_liftGrbx->setPID(p, i, d);
    m_liftGrbx->setF(f);

    // Set elevator PID
    p = m_settings->getDouble("PID_ELEVATOR_UP_P");
    i = m_settings->getDouble("PID_ELEVATOR_UP_I");
    d = m_settings->getDouble("PID_ELEVATOR_UP_D");
    f = m_settings->getDouble("PID_ELEVATOR_UP_F");

    m_liftGrbx->setProfile(true);
    m_liftGrbx->setPID(p, i, d);
    m_liftGrbx->setF(f);
}

void Elevator::resetEncoders() {
    m_liftGrbx->resetEncoder();
}

void Elevator::pollLiftLimitSwitches() {
    // Check encoder reset limit switch
    if (m_liftGrbx->isRevLimitSwitchClosed()) {
        m_liftGrbx->resetEncoder();
    }
}

void Elevator::raiseElevator(std::string level) {
    size_t op = 0;
    size_t pos = 0;
    size_t nextPos = 0;
    double height = 0;
    decltype(m_toteHeights)::iterator it;

    bool firstNumber = true;
    while (pos != std::string::npos) {
        if (!firstNumber) {
            op = level.find_first_of("+-", pos);
            if (op == std::string::npos) {
                break;
            }
        }
        else {
            /* There is no operator associated with the first number, so keep
             * 'op' 0. This special case will be checked below so the number
             * is added to the total
             */
            firstNumber = false;
        }

        pos = level.find_first_not_of("+- ", op);
        if (pos == std::string::npos) {
            break;
        }
        nextPos = level.find_first_of("+- ", pos);

        it = m_toteHeights.find(level.substr(pos, nextPos - pos));
        if (it != m_toteHeights.end()) {
            if (level[op] == '+' || op == 0) {
                height += it->second;
            }
            else if (level[op] == '-') {
                height -= it->second;
            }
        }

        pos = nextPos;
    }

    /* Only allow changing the elevator height manually if not currently
     * auto-stacking
     */
    if (!isStacking()) {
        std::cout << "Seeking to " << height << std::endl;

        setProfileHeight(height);
    }
}

void Elevator::setProfileHeight(double height) {
    // Don't try to seek anywhere if we're already at setpoint
    /* if (height == getHeight()) {
     *   return;
     *  } */

    if (height > m_maxHeight) {
        height = m_maxHeight;
    }

    // Set PID constant profile
    if (height > getHeight()) {
        // Going up.
        setMaxVelocity(88.0);
        setTimeToMaxV(0.4);
        m_liftGrbx->setProfile(true);
    }
    else {
        // Going down.
        if (height != 0.0) {
            setMaxVelocity(91.26);
        }
        else {
            setMaxVelocity(45.63);
        }
        setTimeToMaxV(0.4);
        m_liftGrbx->setProfile(false);
    }

    m_profileTimer->Reset();
    m_profileTimer->Start();

    setGoal(m_profileTimer->Get(), height, getHeight());
}

double Elevator::getLevelHeight(std::string level) const {
    auto height = m_toteHeights.find(level);

    if (height == m_toteHeights.end()) {
        return 0.0;
    }
    else {
        return height->second;
    }
}

void Elevator::stackTotes() {
    setManualMode(false);
    m_startAutoStacking = true;
}

bool Elevator::isStacking() const {
    return m_autoStackSM.getState() != "IDLE";
}

void Elevator::cancelStack() {
    m_autoStackSM.setState("IDLE");
}

void Elevator::updateState() {
    m_autoStackSM.run();
}

void Elevator::manualChangeSetpoint(double delta) {
    double newSetpoint = delta + m_setpoint;

    if (newSetpoint > m_maxHeight) {
        newSetpoint = m_maxHeight;
    }

    // Set PID constant profile
    if (newSetpoint > m_setpoint) {
        // Going up.
        setMaxVelocity(m_maxv_a);
        setTimeToMaxV(m_ttmaxv_a);
        m_liftGrbx->setProfile(true);
    }
    else {
        // Going down.
        setMaxVelocity(m_maxv_b);
        setTimeToMaxV(m_ttmaxv_b);
        m_liftGrbx->setProfile(false);
    }

    m_setpoint = newSetpoint;
}

<commit_msg>Set elevator-zeroing setpoint to an arbitrarily large number so the maximum velocity is obeyed until the limit switch is pressed<commit_after>// =============================================================================
// File Name: Elevator.cpp
// Description: Provides an interface for the robot's elevator
// Author: FRC Team 3512, Spartatroniks
// =============================================================================

#include "Elevator.hpp"
#include <Solenoid.h>
#include <DigitalInput.h>
#include <CANTalon.h>

Elevator::Elevator() : TrapezoidProfile(0.0, 0.0) {
    m_elevatorGrabber = std::make_unique<Solenoid>(3);
    m_containerGrabber = std::make_unique<Solenoid>(4);

    m_intakeStower = std::make_unique<Solenoid>(1);
    m_intakeGrabber = std::make_unique<Solenoid>(2);
    m_intakeWheelLeft = std::make_unique<CANTalon>(3);
    m_intakeWheelRight = std::make_unique<CANTalon>(6);
    m_intakeState = S_STOPPED;

    // For CANTalon PID loop
    m_liftGrbx = std::make_unique<GearBox<CANTalon>>(-1, 7, 2);
    m_liftGrbx->setEncoderReversed(true);
    m_liftGrbx->setDistancePerPulse(70.5 / 5090.0);

    m_liftGrbx->setProfile(false);
    m_liftGrbx->setIZone(80);
    m_liftGrbx->setCloseLoopRampRate(1.0);

    m_liftGrbx->setProfile(true);
    m_liftGrbx->setIZone(80);
    m_liftGrbx->setCloseLoopRampRate(1.0);

    m_profileTimer = std::make_unique<Timer>();
    m_grabTimer = std::make_unique<Timer>();

    m_profileUpdater = new std::thread([this] {
        double height = 0.0;
        while (m_updateProfile) {
            if (!atGoal()) {
                height = updateSetpoint(m_profileTimer->Get());
            }
            else {
                height = m_setpoint;
            }
            setHeight(height);

            if (m_liftGrbx->isRevLimitSwitchClosed()) {
                m_liftGrbx->resetEncoder();
                height = 0.0;
                setGoal(m_profileTimer->Get(), height, getHeight());
            }

            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }
    });

    // Load motion profile constants from the configuration file
    m_maxv_a = m_settings->getDouble("EV_MAX_VELOCITY_PROFILE_A");
    m_ttmaxv_a = m_settings->getDouble("EV_TIME_TO_MAX_VELOCITY_PROFILE_A");
    m_maxv_b = m_settings->getDouble("EV_MAX_VELOCITY_PROFILE_B");
    m_ttmaxv_b = m_settings->getDouble("EV_TIME_TO_MAX_VELOCITY_PROFILE_B");

    // Load elevator levels from the configuration file
    m_maxHeight = m_settings->getDouble("EV_MAX_HEIGHT");
    m_toteHeights["EV_GROUND"] = m_settings->getDouble("EV_GROUND");

    double height = 0;
    for (int i = 1; i <= 6; i++) {
        height = m_settings->getDouble("EV_TOTE_" + std::to_string(i));
        m_toteHeights["EV_TOTE_" + std::to_string(i)] = height;
    }

    m_toteHeights["EV_STEP"] = m_settings->getDouble("EV_STEP");
    m_toteHeights["EV_HALF_TOTE_OFFSET"] = m_settings->getDouble(
        "EV_HALF_TOTE_OFFSET");
    m_toteHeights["EV_GARBAGECAN_LEVEL"] = m_settings->getDouble(
        "EV_GARBAGECAN_LEVEL");
    m_toteHeights["EV_AUTO_DROP_LENGTH"] = m_settings->getDouble(
        "EV_AUTO_DROP_LENGTH");

    State* state = new State("IDLE");
    state->initFunc = [this] { m_startAutoStacking = false; };
    state->advanceFunc = [this] {
        if (m_startAutoStacking) {
            return "WAIT_INITIAL_HEIGHT";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);
    m_autoStackSM.setState("IDLE");

    state = new State("WAIT_INITIAL_HEIGHT");
    state->initFunc = [this] {
        setProfileHeight(m_toteHeights["EV_TOTE_1"]);
    };
    state->advanceFunc = [this] {
        if (atGoal()) {
            return "SEEK_DROP_TOTES";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("SEEK_DROP_TOTES");
    state->initFunc = [this] {
        setProfileHeight(getGoal() - m_toteHeights["EV_AUTO_DROP_LENGTH"]);
    };
    state->advanceFunc = [this] {
        if (atGoal()) {
            return "RELEASE";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("RELEASE");
    state->initFunc = [this] {
        m_grabTimer->Reset();
        m_grabTimer->Start();
        elevatorGrab(false);
    };
    state->advanceFunc = [this] {
        if (m_grabTimer->HasPeriodPassed(0.2)) {
            return "SEEK_GROUND";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("SEEK_GROUND");
    state->initFunc = [this] {
        setProfileHeight(m_toteHeights["EV_GROUND"]);
    };
    state->advanceFunc = [this] {
        if (atGoal()) {
            return "GRAB";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("GRAB");
    state->initFunc = [this] {
        m_grabTimer->Reset();
        m_grabTimer->Start();
        elevatorGrab(true);
    };
    state->advanceFunc = [this] {
        if (m_grabTimer->HasPeriodPassed(0.4)) {
            return "SEEK_HALF_TOTE";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("SEEK_HALF_TOTE");
    state->initFunc = [this] {
        setProfileHeight(m_toteHeights["EV_TOTE_1"]);
    };
    state->advanceFunc = [this] {
        if (atGoal()) {
            return "INTAKE_IN";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    state = new State("INTAKE_IN");
    state->initFunc = [this] {
        m_grabTimer->Reset();
        m_grabTimer->Start();
        intakeGrab(true);
    };
    state->advanceFunc = [this] {
        if (m_grabTimer->HasPeriodPassed(0.2)) {
            return "IDLE";
        }
        else {
            return "";
        }
    };
    m_autoStackSM.addState(state);

    // Reload PID constants from the configuration file
    reloadPID();
}

Elevator::~Elevator() {
    m_updateProfile = false;
    if (m_profileUpdater != nullptr) {
        m_profileUpdater->join();
        delete m_profileUpdater;
    }
}

void Elevator::elevatorGrab(bool state) {
    m_elevatorGrabber->Set(!state);
}

bool Elevator::isElevatorGrabbed() const {
    return !m_elevatorGrabber->Get();
}

void Elevator::intakeGrab(bool state) {
    m_intakeGrabber->Set(state);
}

bool Elevator::isIntakeGrabbed() const {
    return m_intakeGrabber->Get();
}

void Elevator::stowIntake(bool state) {
    m_intakeStower->Set(!state);
}

bool Elevator::isIntakeStowed() const {
    return !m_intakeStower->Get();
}

void Elevator::containerGrab(bool state) {
    m_containerGrabber->Set(!state);
}

bool Elevator::isContainerGrabbed() const {
    return !m_containerGrabber->Get();
}

void Elevator::setIntakeDirectionLeft(IntakeMotorState state) {
    m_intakeState = state;

    if (state == S_STOPPED) {
        m_intakeWheelLeft->Set(0);
    }
    else if (state == S_FORWARD) {
        m_intakeWheelLeft->Set(1);
    }
    else if (state == S_REVERSE) {
        m_intakeWheelLeft->Set(-1);
    }
    else if (state == S_ROTATE_CCW) {
        m_intakeWheelLeft->Set(-1);
    }
    else if (state == S_ROTATE_CW) {
        m_intakeWheelLeft->Set(1);
    }
}

void Elevator::setIntakeDirectionRight(IntakeMotorState state) {
    m_intakeState = state;

    if (state == S_STOPPED) {
        m_intakeWheelRight->Set(0);
    }
    else if (state == S_FORWARD) {
        m_intakeWheelRight->Set(-1);
    }
    else if (state == S_REVERSE) {
        m_intakeWheelRight->Set(1);
    }
    else if (state == S_ROTATE_CCW) {
        m_intakeWheelRight->Set(-1);
    }
    else if (state == S_ROTATE_CW) {
        m_intakeWheelRight->Set(1);
    }
}

Elevator::IntakeMotorState Elevator::getIntakeDirection() const {
    return m_intakeState;
}

void Elevator::setManualLiftSpeed(double value) {
    if (m_manual) {
        m_liftGrbx->setManual(value);
    }
}

double Elevator::getManualLiftSpeed() const {
    if (m_manual) {
        return m_liftGrbx->get(Grbx::Raw);
    }

    return 0.0;
}

void Elevator::setManualMode(bool on) {
    if (on != m_manual) {
        m_manual = on;

        if (m_manual) {
            // Stop any auto-stacking when we switch to manual mode
            m_autoStackSM.setState("IDLE");
        }
        else {
            setProfileHeight(getHeight());
        }
    }
}

bool Elevator::isManualMode() const {
    return m_manual;
}

void Elevator::setHeight(double height) {
    if (m_manual == false) {
        m_liftGrbx->setSetpoint(height);
    }
}

double Elevator::getHeight() const {
    return m_liftGrbx->get(Grbx::Position);
}

void Elevator::reloadPID() {
    m_settings->update();

    // First profile
    double p = 0.f;
    double i = 0.f;
    double d = 0.f;
    double f = 0.f;

    // Set elevator PID
    p = m_settings->getDouble("PID_ELEVATOR_DOWN_P");
    i = m_settings->getDouble("PID_ELEVATOR_DOWN_I");
    d = m_settings->getDouble("PID_ELEVATOR_DOWN_D");
    f = m_settings->getDouble("PID_ELEVATOR_DOWN_F");

    m_liftGrbx->setProfile(false);
    m_liftGrbx->setPID(p, i, d);
    m_liftGrbx->setF(f);

    // Set elevator PID
    p = m_settings->getDouble("PID_ELEVATOR_UP_P");
    i = m_settings->getDouble("PID_ELEVATOR_UP_I");
    d = m_settings->getDouble("PID_ELEVATOR_UP_D");
    f = m_settings->getDouble("PID_ELEVATOR_UP_F");

    m_liftGrbx->setProfile(true);
    m_liftGrbx->setPID(p, i, d);
    m_liftGrbx->setF(f);
}

void Elevator::resetEncoders() {
    m_liftGrbx->resetEncoder();
}

void Elevator::pollLiftLimitSwitches() {
    // Check encoder reset limit switch
    if (m_liftGrbx->isRevLimitSwitchClosed()) {
        m_liftGrbx->resetEncoder();
    }
}

void Elevator::raiseElevator(std::string level) {
    size_t op = 0;
    size_t pos = 0;
    size_t nextPos = 0;
    double height = 0;
    decltype(m_toteHeights)::iterator it;

    bool firstNumber = true;
    while (pos != std::string::npos) {
        if (!firstNumber) {
            op = level.find_first_of("+-", pos);
            if (op == std::string::npos) {
                break;
            }
        }
        else {
            /* There is no operator associated with the first number, so keep
             * 'op' 0. This special case will be checked below so the number
             * is added to the total
             */
            firstNumber = false;
        }

        pos = level.find_first_not_of("+- ", op);
        if (pos == std::string::npos) {
            break;
        }
        nextPos = level.find_first_of("+- ", pos);

        it = m_toteHeights.find(level.substr(pos, nextPos - pos));
        if (it != m_toteHeights.end()) {
            if (level[op] == '+' || op == 0) {
                height += it->second;
            }
            else if (level[op] == '-') {
                height -= it->second;
            }
        }

        pos = nextPos;
    }

    /* Only allow changing the elevator height manually if not currently
     * auto-stacking
     */
    if (!isStacking()) {
        std::cout << "Seeking to " << height << std::endl;

        setProfileHeight(height);
    }
}

void Elevator::setProfileHeight(double height) {
    // Don't try to seek anywhere if we're already at setpoint
    /* if (height == getHeight()) {
     *   return;
     *  } */

    if (height > m_maxHeight) {
        height = m_maxHeight;
    }

    // Set PID constant profile
    if (height > getHeight()) {
        // Going up.
        setMaxVelocity(88.0);
        setTimeToMaxV(0.4);
        m_liftGrbx->setProfile(true);
    }
    else {
        // Going down.
        if (height > 0.0) {
            setMaxVelocity(91.26);
        }
        else {
            setMaxVelocity(45.63);
            height = -100.0;
        }
        setTimeToMaxV(0.4);
        m_liftGrbx->setProfile(false);
    }

    m_profileTimer->Reset();
    m_profileTimer->Start();

    setGoal(m_profileTimer->Get(), height, getHeight());
}

double Elevator::getLevelHeight(std::string level) const {
    auto height = m_toteHeights.find(level);

    if (height == m_toteHeights.end()) {
        return 0.0;
    }
    else {
        return height->second;
    }
}

void Elevator::stackTotes() {
    setManualMode(false);
    m_startAutoStacking = true;
}

bool Elevator::isStacking() const {
    return m_autoStackSM.getState() != "IDLE";
}

void Elevator::cancelStack() {
    m_autoStackSM.setState("IDLE");
}

void Elevator::updateState() {
    m_autoStackSM.run();
}

void Elevator::manualChangeSetpoint(double delta) {
    double newSetpoint = delta + m_setpoint;

    if (newSetpoint > m_maxHeight) {
        newSetpoint = m_maxHeight;
    }

    // Set PID constant profile
    if (newSetpoint > m_setpoint) {
        // Going up.
        setMaxVelocity(m_maxv_a);
        setTimeToMaxV(m_ttmaxv_a);
        m_liftGrbx->setProfile(true);
    }
    else {
        // Going down.
        setMaxVelocity(m_maxv_b);
        setTimeToMaxV(m_ttmaxv_b);
        m_liftGrbx->setProfile(false);
    }

    m_setpoint = newSetpoint;
}

<|endoftext|>


<commit_before>// RUN: %clangxx -O0 %s -o %t && %run %t
// UNSUPPORTED: android

#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(int argc, char **argv) {
  int mount_id;
  struct file_handle *handle = reinterpret_cast<struct file_handle *>(
      malloc(sizeof(*handle) + MAX_HANDLE_SZ));

  handle->handle_bytes = MAX_HANDLE_SZ;
  int res = name_to_handle_at(AT_FDCWD, argv[0], handle, &mount_id, 0);
  assert(!res);

  free(handle);
  return 0;
}
<commit_msg>[compiler-rt] Fix name_to_handle_at.cc test on Overlay2 (for Docker)<commit_after>// RUN: %clangxx -O0 %s -o %t && %run %t
// UNSUPPORTED: android

#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(int argc, char **argv) {
  int mount_id;
  struct file_handle *handle = reinterpret_cast<struct file_handle *>(
      malloc(sizeof(*handle) + MAX_HANDLE_SZ));

  handle->handle_bytes = MAX_HANDLE_SZ;
  int res = name_to_handle_at(AT_FDCWD, "/dev/null", handle, &mount_id, 0);
  assert(!res);

  free(handle);
  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2020 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include "common.hh"
#include "harness.hh"
#include "lexer.hh"

TADPOLE_TEST(TadpoleLexer) {
}
<commit_msg>:white_check_mark: test(lexer): updated the test for lexer<commit_after>// Copyright (c) 2020 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include "common.hh"
#include "harness.hh"
#include "lexer.hh"

TADPOLE_TEST(TadpoleLexer) {
  using TK = tadpole::TokenKind;
#define TESTEQ(k) TADPOLE_CHECK_EQ(lex.next_token().kind(), k)
#define DUMPLEX() do {\
    for (;;) {\
      auto t = lex.next_token();\
      std::fprintf(stdout, "%-24s | %-32s | %d\n",\
          tadpole::get_kind_name(t.kind()),\
          t.as_cstring(),\
          t.lineno());\
      if (t.kind() == TK::TK_EOF)\
        break;\
    }\
  } while (false)

  {
    std::string s =
      "print(\"Welcome to Tadpole !!!\");\nvar v = 34 * 45 - 56 / 23.4 + (89.1 - 67)";
    tadpole::Lexer lex(s);
    DUMPLEX();
  }
}
<|endoftext|>