<commit_before>/*

Copyright (c) 2014, Project OSRM, Felix Guendling
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
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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.

*/

#ifndef MULTI_TARGET_ROUTING_H
#define MULTI_TARGET_ROUTING_H

#include "routing_base.hpp"
#include "../data_structures/search_engine_data.hpp"
#include "../typedefs.h"

#include <boost/assert.hpp>

#include <memory>
#include <vector>

template <class DataFacadeT, bool forward>
class MultiTargetRouting final : public BasicRoutingInterface<DataFacadeT, MultiTargetRouting<DataFacadeT, forward>>
{
    typedef BasicRoutingInterface<DataFacadeT, MultiTargetRouting<DataFacadeT, forward>> super;
    typedef SearchEngineData::QueryHeap QueryHeap;
    SearchEngineData &engine_working_data;

  public:
    MultiTargetRouting(DataFacadeT *facade, SearchEngineData &engine_working_data)
        : super(facade), engine_working_data(engine_working_data)
    {
    }

    ~MultiTargetRouting() {}

    std::shared_ptr<std::vector<std::pair<EdgeWeight, double>>>
    operator()(const PhantomNodeArray &phantom_nodes_array) const
    {
        BOOST_ASSERT(phantom_nodes_array.size() >= 2);

        // Prepare results table:
        // Each target (phantom_nodes_array[1], ..., phantom_nodes_array[n]) has its own index.
        auto results = std::make_shared<std::vector<std::pair<EdgeWeight, double>>>();
        results->reserve(phantom_nodes_array.size() - 1);

        // For readability: some reference variables making it clear,
        // which one is the source and which are the targets.
        const auto &source = phantom_nodes_array[0];
        std::vector<std::reference_wrapper<const std::vector<PhantomNode>>> targets(
            std::next(begin(phantom_nodes_array)), end(phantom_nodes_array));

        engine_working_data.InitializeOrClearFirstThreadLocalStorage(
            super::facade->GetNumberOfNodes());

        // The forward heap keeps the distances from the source.
        // Therefore it will be reused for each target backward search.
        QueryHeap &forward_heap = *(engine_working_data.forward_heap_1);

        // The reverse heap will be cleared after each search from
        // one of the targets to the source.
        QueryHeap &reverse_heap = *(engine_working_data.reverse_heap_1);

        // Fill forward heap with the source location phantom node(s).
        // The source location is located at index 0.
        // The target locations are located at index [1, ..., n].
        EdgeWeight min_edge_offset = 0;
        for (const PhantomNode &phantom_node : source)
        {
            if (SPECIAL_NODEID != phantom_node.forward_node_id)
            {
                EdgeWeight offset = (forward ? -1 : 1) * phantom_node.GetForwardWeightPlusOffset();
                forward_heap.Insert(phantom_node.forward_node_id, offset,
                                    phantom_node.forward_node_id);
                min_edge_offset = std::min(min_edge_offset, offset);
            }
            if (SPECIAL_NODEID != phantom_node.reverse_node_id)
            {
                EdgeWeight offset = (forward ? -1 : 1) * phantom_node.GetReverseWeightPlusOffset();
                forward_heap.Insert(phantom_node.reverse_node_id,
                                    (forward ? -1 : 1) * phantom_node.GetReverseWeightPlusOffset(),
                                    phantom_node.reverse_node_id);
                min_edge_offset = std::min(min_edge_offset, offset);
            }
        }

        for (auto const &target : targets)
        {
            const std::vector<PhantomNode> &phantom_node_vector = target;
            auto result = FindShortestPath(source, phantom_node_vector, forward_heap, reverse_heap,
                                           min_edge_offset);
            results->emplace_back(std::move(result));
        }

        forward_heap.Clear();
        reverse_heap.Clear();

        return results;
    }

    std::pair<EdgeWeight, double> FindShortestPath(const std::vector<PhantomNode> &source,
                                                   const std::vector<PhantomNode> &target,
                                                   QueryHeap &forward_heap,
                                                   QueryHeap &backward_heap,
                                                   EdgeWeight min_edge_offset) const
    {
        NodeID middle = UINT_MAX;
        int local_upper_bound = INT_MAX;

        // Clear backward heap from the entries produced by the search to the last target
        // and initialize heap for this target.
        backward_heap.Clear();
        for (const PhantomNode &phantom_node : target)
        {
            if (SPECIAL_NODEID != phantom_node.forward_node_id)
            {
                EdgeWeight offset = (forward ? 1 : -1) * phantom_node.GetForwardWeightPlusOffset();
                backward_heap.Insert(phantom_node.forward_node_id, offset,
                                     phantom_node.forward_node_id);
                min_edge_offset = std::min(min_edge_offset, offset);
            }

            if (SPECIAL_NODEID != phantom_node.reverse_node_id)
            {
                EdgeWeight offset = (forward ? 1 : -1) * phantom_node.GetReverseWeightPlusOffset();
                backward_heap.Insert(phantom_node.reverse_node_id, offset,
                                     phantom_node.reverse_node_id);
                min_edge_offset = std::min(min_edge_offset, offset);
            }
        }

        // Execute bidirectional Dijkstra shortest path search.
        while (0 < backward_heap.Size() || 0 < forward_heap.Size())
        {
            if (0 < forward_heap.Size())
            {
                super::RoutingStep(forward_heap, backward_heap, &middle, &local_upper_bound,
                                   min_edge_offset, forward, false);
            }
            if (0 < backward_heap.Size())
            {
                super::RoutingStep(backward_heap, forward_heap, &middle, &local_upper_bound,
                                   min_edge_offset, !forward);
            }
        }

        // Check if no path could be found (-> early exit).
        if (INVALID_EDGE_WEIGHT == local_upper_bound)
        {
            return std::make_pair(INVALID_EDGE_WEIGHT, 0);
        }

        // Calculate exact distance in km.
        std::vector<NodeID> packed_path;
        super::RetrievePackedPathFromHeap(forward_heap, backward_heap, middle, packed_path);

        if (!forward)
        {
            std::reverse(begin(packed_path), end(packed_path));
        }

        auto source_phantom_it =
            std::find_if(begin(source), end(source), [&packed_path](PhantomNode const &node)
                         {
                return node.forward_node_id == packed_path[forward ? 0 : packed_path.size() - 1] ||
                       node.reverse_node_id == packed_path[forward ? 0 : packed_path.size() - 1];
            });
        auto target_phantom_it =
            std::find_if(begin(target), end(target), [&packed_path](PhantomNode const &node)
                         {
                return node.forward_node_id == packed_path[forward ? packed_path.size() - 1 : 0] ||
                       node.reverse_node_id == packed_path[forward ? packed_path.size() - 1 : 0];
            });

        BOOST_ASSERT(source_phantom_it != end(source));
        BOOST_ASSERT(target_phantom_it != end(target));

        std::vector<PathData> unpacked_path;
        if (forward)
        {
            super::UnpackPath(packed_path, {*source_phantom_it, *target_phantom_it}, unpacked_path);
        }
        else
        {
            super::UnpackPath(packed_path, {*target_phantom_it, *source_phantom_it}, unpacked_path);
        }

        std::vector<FixedPointCoordinate> coordinates;
        coordinates.reserve(unpacked_path.size() + 2);

        coordinates.emplace_back(forward ? source_phantom_it->location
                                         : target_phantom_it->location);
        for (const auto &path_data : unpacked_path)
        {
            coordinates.emplace_back(super::facade->GetCoordinateOfNode(path_data.node));
        }
        coordinates.emplace_back(forward ? target_phantom_it->location
                                         : source_phantom_it->location);

        double distance = 0.0;
        for (int i = 1; i < coordinates.size(); ++i)
        {
            distance += coordinate_calculation::euclidean_distance(coordinates[i - 1],
                                                                   coordinates[i]);
        }

        return std::make_pair(round(local_upper_bound / 10.), distance);
    }
};

#endif
<commit_msg>fix compiler warning<commit_after>/*

Copyright (c) 2014, Project OSRM, Felix Guendling
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
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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.

*/

#ifndef MULTI_TARGET_ROUTING_H
#define MULTI_TARGET_ROUTING_H

#include "routing_base.hpp"
#include "../data_structures/search_engine_data.hpp"
#include "../typedefs.h"

#include <boost/assert.hpp>

#include <memory>
#include <vector>

template <class DataFacadeT, bool forward>
class MultiTargetRouting final : public BasicRoutingInterface<DataFacadeT, MultiTargetRouting<DataFacadeT, forward>>
{
    typedef BasicRoutingInterface<DataFacadeT, MultiTargetRouting<DataFacadeT, forward>> super;
    typedef SearchEngineData::QueryHeap QueryHeap;
    SearchEngineData &engine_working_data;

  public:
    MultiTargetRouting(DataFacadeT *facade, SearchEngineData &engine_working_data)
        : super(facade), engine_working_data(engine_working_data)
    {
    }

    ~MultiTargetRouting() {}

    std::shared_ptr<std::vector<std::pair<EdgeWeight, double>>>
    operator()(const PhantomNodeArray &phantom_nodes_array) const
    {
        BOOST_ASSERT(phantom_nodes_array.size() >= 2);

        // Prepare results table:
        // Each target (phantom_nodes_array[1], ..., phantom_nodes_array[n]) has its own index.
        auto results = std::make_shared<std::vector<std::pair<EdgeWeight, double>>>();
        results->reserve(phantom_nodes_array.size() - 1);

        // For readability: some reference variables making it clear,
        // which one is the source and which are the targets.
        const auto &source = phantom_nodes_array[0];
        std::vector<std::reference_wrapper<const std::vector<PhantomNode>>> targets(
            std::next(begin(phantom_nodes_array)), end(phantom_nodes_array));

        engine_working_data.InitializeOrClearFirstThreadLocalStorage(
            super::facade->GetNumberOfNodes());

        // The forward heap keeps the distances from the source.
        // Therefore it will be reused for each target backward search.
        QueryHeap &forward_heap = *(engine_working_data.forward_heap_1);

        // The reverse heap will be cleared after each search from
        // one of the targets to the source.
        QueryHeap &reverse_heap = *(engine_working_data.reverse_heap_1);

        // Fill forward heap with the source location phantom node(s).
        // The source location is located at index 0.
        // The target locations are located at index [1, ..., n].
        EdgeWeight min_edge_offset = 0;
        for (const PhantomNode &phantom_node : source)
        {
            if (SPECIAL_NODEID != phantom_node.forward_node_id)
            {
                EdgeWeight offset = (forward ? -1 : 1) * phantom_node.GetForwardWeightPlusOffset();
                forward_heap.Insert(phantom_node.forward_node_id, offset,
                                    phantom_node.forward_node_id);
                min_edge_offset = std::min(min_edge_offset, offset);
            }
            if (SPECIAL_NODEID != phantom_node.reverse_node_id)
            {
                EdgeWeight offset = (forward ? -1 : 1) * phantom_node.GetReverseWeightPlusOffset();
                forward_heap.Insert(phantom_node.reverse_node_id,
                                    (forward ? -1 : 1) * phantom_node.GetReverseWeightPlusOffset(),
                                    phantom_node.reverse_node_id);
                min_edge_offset = std::min(min_edge_offset, offset);
            }
        }

        for (auto const &target : targets)
        {
            const std::vector<PhantomNode> &phantom_node_vector = target;
            auto result = FindShortestPath(source, phantom_node_vector, forward_heap, reverse_heap,
                                           min_edge_offset);
            results->emplace_back(std::move(result));
        }

        forward_heap.Clear();
        reverse_heap.Clear();

        return results;
    }

    std::pair<EdgeWeight, double> FindShortestPath(const std::vector<PhantomNode> &source,
                                                   const std::vector<PhantomNode> &target,
                                                   QueryHeap &forward_heap,
                                                   QueryHeap &backward_heap,
                                                   EdgeWeight min_edge_offset) const
    {
        NodeID middle = UINT_MAX;
        int local_upper_bound = INT_MAX;

        // Clear backward heap from the entries produced by the search to the last target
        // and initialize heap for this target.
        backward_heap.Clear();
        for (const PhantomNode &phantom_node : target)
        {
            if (SPECIAL_NODEID != phantom_node.forward_node_id)
            {
                EdgeWeight offset = (forward ? 1 : -1) * phantom_node.GetForwardWeightPlusOffset();
                backward_heap.Insert(phantom_node.forward_node_id, offset,
                                     phantom_node.forward_node_id);
                min_edge_offset = std::min(min_edge_offset, offset);
            }

            if (SPECIAL_NODEID != phantom_node.reverse_node_id)
            {
                EdgeWeight offset = (forward ? 1 : -1) * phantom_node.GetReverseWeightPlusOffset();
                backward_heap.Insert(phantom_node.reverse_node_id, offset,
                                     phantom_node.reverse_node_id);
                min_edge_offset = std::min(min_edge_offset, offset);
            }
        }

        // Execute bidirectional Dijkstra shortest path search.
        while (0 < backward_heap.Size() || 0 < forward_heap.Size())
        {
            if (0 < forward_heap.Size())
            {
                super::RoutingStep(forward_heap, backward_heap, &middle, &local_upper_bound,
                                   min_edge_offset, forward, false);
            }
            if (0 < backward_heap.Size())
            {
                super::RoutingStep(backward_heap, forward_heap, &middle, &local_upper_bound,
                                   min_edge_offset, !forward);
            }
        }

        // Check if no path could be found (-> early exit).
        if (INVALID_EDGE_WEIGHT == local_upper_bound)
        {
            return std::make_pair(INVALID_EDGE_WEIGHT, 0);
        }

        // Calculate exact distance in km.
        std::vector<NodeID> packed_path;
        super::RetrievePackedPathFromHeap(forward_heap, backward_heap, middle, packed_path);

        if (!forward)
        {
            std::reverse(begin(packed_path), end(packed_path));
        }

        auto source_phantom_it =
            std::find_if(begin(source), end(source), [&packed_path](PhantomNode const &node)
                         {
                return node.forward_node_id == packed_path[forward ? 0 : packed_path.size() - 1] ||
                       node.reverse_node_id == packed_path[forward ? 0 : packed_path.size() - 1];
            });
        auto target_phantom_it =
            std::find_if(begin(target), end(target), [&packed_path](PhantomNode const &node)
                         {
                return node.forward_node_id == packed_path[forward ? packed_path.size() - 1 : 0] ||
                       node.reverse_node_id == packed_path[forward ? packed_path.size() - 1 : 0];
            });

        BOOST_ASSERT(source_phantom_it != end(source));
        BOOST_ASSERT(target_phantom_it != end(target));

        std::vector<PathData> unpacked_path;
        if (forward)
        {
            super::UnpackPath(packed_path, {*source_phantom_it, *target_phantom_it}, unpacked_path);
        }
        else
        {
            super::UnpackPath(packed_path, {*target_phantom_it, *source_phantom_it}, unpacked_path);
        }

        std::vector<FixedPointCoordinate> coordinates;
        coordinates.reserve(unpacked_path.size() + 2);

        coordinates.emplace_back(forward ? source_phantom_it->location
                                         : target_phantom_it->location);
        for (const auto &path_data : unpacked_path)
        {
            coordinates.emplace_back(super::facade->GetCoordinateOfNode(path_data.node));
        }
        coordinates.emplace_back(forward ? target_phantom_it->location
                                         : source_phantom_it->location);

        double distance = 0.0;
        for (size_t i = 1; i < coordinates.size(); ++i)
        {
            distance += coordinate_calculation::euclidean_distance(coordinates[i - 1],
                                                                   coordinates[i]);
        }

        return std::make_pair(round(local_upper_bound / 10.), distance);
    }
};

#endif
<|endoftext|>


<commit_before>#include "mopViewer.h"

mopViewer::mopViewer() {
}
mopViewer::~mopViewer() {
}

void mopViewer::showStats() {
  mopfile = new MopFile();
  mopfile->setFilename("Testing_Project.mop");
  mopfile->openMopfileReader();
  mopstate = new MopState();
  mopstate = mopfile->readCyclingState();
  mopstate = mopfile->readCyclingState();
  std::cout << "Item Count: " << mopstate->getItemCount() << std::endl;
  for (int i = 0; i < mopstate->getItemCount(); i++) {
    std::cout << "Particle "<< i << " X value: " << mopstate->getMopItem(i).x << std::endl;
    std::cout << "Particle "<< i << " Y value: " << mopstate->getMopItem(i).y << std::endl;
    std::cout << "Particle "<< i << " Z value: " << mopstate->getMopItem(i).z << std::endl;
  }
  int x, y, x2, y2, x3, y3;
  nCurses nCurse;
  // nCurse.start(true, true, true, false);sd
  initscr();
  raw();
  nCurse.startColour();
  getmaxyx(stdscr, x, y);
  init_pair(1, COLOR_WHITE, COLOR_BLACK);
  init_pair(2, COLOR_BLACK, COLOR_WHITE);
  wbkgd(stdscr, COLOR_PAIR(1));
  wattron(stdscr, COLOR_PAIR(1));
  nCurse.drawBox(stdscr, ACS_VLINE, ACS_HLINE);

  WINDOW *window1 = newwin(x-4, (y/2)-5, 2, 2);
  wbkgd(window1, COLOR_PAIR(2));
  nCurse.drawBox(window1, ACS_VLINE, ACS_HLINE);

  WINDOW *window2 = newwin(x-4, (y/2)-5, 2, (y/2)+2);
  wbkgd(window2, COLOR_PAIR(2));
  nCurse.drawBox(window2, ACS_VLINE, ACS_HLINE);

  wattron(stdscr, A_BOLD);
  mvwprintw(stdscr, 1, (y/2)-10, "Welcome to Mopviewer");

  getmaxyx(window1, x2, y2);
  getmaxyx(window2, x3, y3);

  //Get the output for sizes of windows, helps me
  std::cout << "Max X: " << x << std::endl;
  std::cout << "Max Y: " << y << std::endl;

  std::cout << "Max X1: " << x2 << std::endl;
  std::cout << "Max Y1: " << y2 << std::endl;

  std::cout << "Max X2: " << x3 << std::endl;
  std::cout << "Max Y2: " << y3 << std::endl;

 //Display the information to screen
  int currentRow = 1;
  int currentRow2 = 1;
  for (int i = 0; i < mopstate->getItemCount(); i++) {
    if(currentRow >= (x2-1)){
        mvwprintw(window2, currentRow2,1, "Particle Number: %d", i);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle X %f", mopstate->getMopItem(i).x);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle Y:  %f", mopstate->getMopItem(i).y);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle Z %f", mopstate->getMopItem(i).z);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle Red:  %d", mopstate->getMopItem(i).red);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle Green %d", mopstate->getMopItem(i).green);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle Blue:  %d", mopstate->getMopItem(i).blue);
        currentRow2+=2;

    }
    else{
      mvwprintw(window1, currentRow,1, "Particle Number:  %d", i);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle X %f", mopstate->getMopItem(i).x);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle Y:  %f", mopstate->getMopItem(i).y);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle Z %f", mopstate->getMopItem(i).z);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle Red:  %d", mopstate->getMopItem(i).red);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle Green %d", mopstate->getMopItem(i).green);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle Blue:  %d", mopstate->getMopItem(i).blue);
      currentRow+=2;
    }
  }

  refresh();
  wrefresh(window1);
  wrefresh(window2);

  std::cout << "Amount per column: " << std::endl;

  getch();
  endwin();
}

void mopViewer::selectGame() {
  int mx = 0, my = 0, mx2 = 0, my2 = 0;
  char welcome[] = "Enter 1 to View Stats and 2 to Open MopViewer: ";
  char exitMessage[] = "Enter anything else to exit";
  // Create inital screen. Better to replace
  // with the single start function from moody
  WINDOW *myWindow = initscr();
  raw();
  cbreak();
  keypad(myWindow, TRUE);
  //   noecho();
  // Enable use of colour on screen
  start_color();
  // Create two colour pairs for the different screens
  init_pair(1, COLOR_BLACK, COLOR_CYAN);
  init_pair(2, COLOR_BLACK, COLOR_RED);
  init_pair(3, COLOR_WHITE, COLOR_BLACK);
  // Set the colour scheme of window 1 to pair 1
  wattron(myWindow, COLOR_PAIR(1));
  // Set background of main window to colour scheme 1
  wbkgd(myWindow, COLOR_PAIR(1));
  // Create a border for the main console screen
  box(myWindow, ACS_BULLET, ACS_BULLET);
  // Make a new window that is a sub window of
  // main window and add a border to it
  getmaxyx(myWindow, mx, my);
  WINDOW *myWindow2 = subwin(myWindow, mx-5, my-5, 3, 3);
  box(myWindow2, ACS_VLINE, ACS_HLINE);
  // Get the max size of both windows for use later on
  getmaxyx(myWindow, mx, my);
  getmaxyx(myWindow2, mx2, my2);
  // Set background and colour shceme of child window
  wattron(myWindow2, COLOR_PAIR(2));
  wbkgd(myWindow2, COLOR_PAIR(2));
  // Add the title string to the main window
  mvaddstr(1, (my2/2)-10, "Welcome to MopViewer!");
  // Print string to second window at the x,y co-ordinates specificed
  mvwprintw(myWindow2, mx2/2, ((my2-std::strlen(welcome))/2), "%s", welcome);
  mvwprintw(myWindow2, (mx2/2)+10, ((my2-std::strlen(exitMessage))/2), "%s", exitMessage);
  wmove(myWindow, (mx2/2)+5, ((my2/2)+std::strlen(welcome)));
  // Refresh main window otherwise background colour won't show for some reason
  wrefresh(myWindow);
  char inputString[1];
  // Get the input into inputString
  wgetstr(myWindow2, inputString);
  mopViewer mopViewers;
  testWindow newWindow;
  if (inputString[0] == '1') {
    clear();
    refresh();
    endwin();
    mopViewers.showStats();
  } else if (inputString[0] == '2') {
      clear();
      refresh();
      endwin();
      newWindow.init();
      mopViewers.selectGame();
  }
    endwin();
}
<commit_msg>Add option to cycle through particles using right arrow<commit_after>#include "mopViewer.h"

mopViewer::mopViewer() {
}
mopViewer::~mopViewer() {
}

void mopViewer::showStats() {
  mopfile = new MopFile();
  mopfile->setFilename("Testing_Project.mop");
  mopfile->openMopfileReader();
  mopstate = new MopState();
  mopstate = mopfile->readCyclingState();
  mopstate = mopfile->readCyclingState();
  std::cout << "Item Count: " << mopstate->getItemCount() << std::endl;
  for (int i = 0; i < mopstate->getItemCount(); i++) {
    std::cout << "Particle "<< i << " X value: " << mopstate->getMopItem(i).x << std::endl;
    std::cout << "Particle "<< i << " Y value: " << mopstate->getMopItem(i).y << std::endl;
    std::cout << "Particle "<< i << " Z value: " << mopstate->getMopItem(i).z << std::endl;
  }
  int x, y, x2, y2, x3, y3;
  nCurses nCurse;
  // nCurse.start(true, true, true, false);sd
  initscr();
  raw();
  nCurse.startColour();
  getmaxyx(stdscr, x, y);
  init_pair(1, COLOR_WHITE, COLOR_BLACK);
  init_pair(2, COLOR_BLACK, COLOR_WHITE);
  wbkgd(stdscr, COLOR_PAIR(1));
  wattron(stdscr, COLOR_PAIR(1));
  nCurse.drawBox(stdscr, ACS_VLINE, ACS_HLINE);

  WINDOW *window1 = newwin(x-4, (y/2)-5, 2, 2);
  wbkgd(window1, COLOR_PAIR(2));
  nCurse.drawBox(window1, ACS_VLINE, ACS_HLINE);

  WINDOW *window2 = newwin(x-4, (y/2)-5, 2, (y/2)+2);
  wbkgd(window2, COLOR_PAIR(2));
  nCurse.drawBox(window2, ACS_VLINE, ACS_HLINE);

  wattron(stdscr, A_BOLD);
  mvwprintw(stdscr, 1, (y/2)-10, "Welcome to Mopviewer");

  getmaxyx(window1, x2, y2);
  getmaxyx(window2, x3, y3);

  //Get the output for sizes of windows, helps me
  std::cout << "Max X: " << x << std::endl;
  std::cout << "Max Y: " << y << std::endl;

  std::cout << "Max X1: " << x2 << std::endl;
  std::cout << "Max Y1: " << y2 << std::endl;

  std::cout << "Max X2: " << x3 << std::endl;
  std::cout << "Max Y2: " << y3 << std::endl;

  float maxitems = (x2-2)/8;
  float maxremainder = ((x2-2)%8);
  std::cout << "Max amount of items per column: " << maxitems << std::endl;
  std::cout << "Max amount of remainders per column: " << maxremainder << std::endl;

 //Display the information to screen
  int currentRow = 1;
  int currentRow2 = 1;
  int currentitem = 0;
  for (int i = 0; i < (2*maxitems); i++) {
    if((currentRow >= (8*maxitems))){
        mvwprintw(window2, currentRow2,1, "Particle Number: %d", currentitem);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle X %f", mopstate->getMopItem(currentitem).x);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle Y:  %f", mopstate->getMopItem(currentitem).y);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle Z %f", mopstate->getMopItem(currentitem).z);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle Red:  %d", mopstate->getMopItem(currentitem).red);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle Green %d", mopstate->getMopItem(currentitem).green);
        currentRow2++;
        mvwprintw(window2, currentRow2,1, "Particle Blue:  %d", mopstate->getMopItem(currentitem).blue);
        currentRow2+=2;
        currentitem++;

    }
    else{
      mvwprintw(window1, currentRow,1, "Particle Number:  %d", currentitem);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle X %f", mopstate->getMopItem(currentitem).x);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle Y:  %f", mopstate->getMopItem(currentitem).y);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle Z %f", mopstate->getMopItem(currentitem).z);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle Red:  %d", mopstate->getMopItem(currentitem).red);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle Green %d", mopstate->getMopItem(currentitem).green);
      currentRow++;
      mvwprintw(window1, currentRow,1, "Particle Blue:  %d", mopstate->getMopItem(currentitem).blue);
      currentRow+=2;
      currentitem++;
    }
  }

  refresh();
  wrefresh(window1);
  wrefresh(window2);

  int ch;
  while((ch = getch()) != GLFW_KEY_2)
	{	switch(ch) {
      case KEY_RIGHT:
      currentRow = 1;
      currentRow2 = 1;
      for (int i = 0; i < (2*maxitems); i++) {
        if((currentRow >= (8*maxitems)) && (currentitem <= mopstate->getItemCount())){
            mvwprintw(window2, currentRow2,1, "Particle Number: %d", currentitem);
            currentRow2++;
            mvwprintw(window2, currentRow2,1, "Particle X %f", mopstate->getMopItem(currentitem).x);
            currentRow2++;
            mvwprintw(window2, currentRow2,1, "Particle Y:  %f", mopstate->getMopItem(currentitem).y);
            currentRow2++;
            mvwprintw(window2, currentRow2,1, "Particle Z %f", mopstate->getMopItem(currentitem).z);
            currentRow2++;
            mvwprintw(window2, currentRow2,1, "Particle Red:  %d", mopstate->getMopItem(currentitem).red);
            currentRow2++;
            mvwprintw(window2, currentRow2,1, "Particle Green %d", mopstate->getMopItem(currentitem).green);
            currentRow2++;
            mvwprintw(window2, currentRow2,1, "Particle Blue:  %d", mopstate->getMopItem(currentitem).blue);
            currentRow2+=2;
            currentitem++;

        }
        else if (currentitem <= mopstate->getItemCount()){
          mvwprintw(window1, currentRow,1, "Particle Number:  %d", currentitem);
          currentRow++;
          mvwprintw(window1, currentRow,1, "Particle X %f", mopstate->getMopItem(currentitem).x);
          currentRow++;
          mvwprintw(window1, currentRow,1, "Particle Y:  %f", mopstate->getMopItem(currentitem).y);
          currentRow++;
          mvwprintw(window1, currentRow,1, "Particle Z %f", mopstate->getMopItem(currentitem).z);
          currentRow++;
          mvwprintw(window1, currentRow,1, "Particle Red:  %d", mopstate->getMopItem(currentitem).red);
          currentRow++;
          mvwprintw(window1, currentRow,1, "Particle Green %d", mopstate->getMopItem(currentitem).green);
          currentRow++;
          mvwprintw(window1, currentRow,1, "Particle Blue:  %d", mopstate->getMopItem(currentitem).blue);
          currentRow+=2;
          currentitem++;
        }
      }
      refresh();
      wrefresh(window1);
      wrefresh(window2);
    break;

    }
  }
  refresh();
  wrefresh(window1);
  wrefresh(window2);
  //getch();
  endwin();
}

void mopViewer::selectGame() {
  int mx = 0, my = 0, mx2 = 0, my2 = 0;
  char welcome[] = "Enter 1 to View Stats and 2 to Open MopViewer: ";
  char exitMessage[] = "Enter anything else to exit";
  // Create inital screen. Better to replace
  // with the single start function from moody
  WINDOW *myWindow = initscr();
  raw();
  cbreak();
  keypad(myWindow, TRUE);
  //   noecho();
  // Enable use of colour on screen
  start_color();
  // Create two colour pairs for the different screens
  init_pair(1, COLOR_BLACK, COLOR_CYAN);
  init_pair(2, COLOR_BLACK, COLOR_RED);
  init_pair(3, COLOR_WHITE, COLOR_BLACK);
  // Set the colour scheme of window 1 to pair 1
  wattron(myWindow, COLOR_PAIR(1));
  // Set background of main window to colour scheme 1
  wbkgd(myWindow, COLOR_PAIR(1));
  // Create a border for the main console screen
  box(myWindow, ACS_BULLET, ACS_BULLET);
  // Make a new window that is a sub window of
  // main window and add a border to it
  getmaxyx(myWindow, mx, my);
  WINDOW *myWindow2 = subwin(myWindow, mx-5, my-5, 3, 3);
  box(myWindow2, ACS_VLINE, ACS_HLINE);
  // Get the max size of both windows for use later on
  getmaxyx(myWindow, mx, my);
  getmaxyx(myWindow2, mx2, my2);
  // Set background and colour shceme of child window
  wattron(myWindow2, COLOR_PAIR(2));
  wbkgd(myWindow2, COLOR_PAIR(2));
  // Add the title string to the main window
  mvaddstr(1, (my2/2)-10, "Welcome to MopViewer!");
  // Print string to second window at the x,y co-ordinates specificed
  mvwprintw(myWindow2, mx2/2, ((my2-std::strlen(welcome))/2), "%s", welcome);
  mvwprintw(myWindow2, (mx2/2)+10, ((my2-std::strlen(exitMessage))/2), "%s", exitMessage);
  wmove(myWindow, (mx2/2)+5, ((my2/2)+std::strlen(welcome)));
  // Refresh main window otherwise background colour won't show for some reason
  wrefresh(myWindow);
  char inputString[1];
  // Get the input into inputString
  wgetstr(myWindow2, inputString);
  mopViewer mopViewers;
  testWindow newWindow;
  if (inputString[0] == '1') {
    clear();
    refresh();
    endwin();
    mopViewers.showStats();
  } else if (inputString[0] == '2') {
      clear();
      refresh();
      endwin();
      newWindow.init();
      mopViewers.selectGame();
  }
    endwin();
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-CHROMIUM file.

#include "browser/browser_main_parts.h"

#include "browser/browser_context.h"
#include "browser/devtools_manager_delegate.h"
#include "browser/web_ui_controller_factory.h"
#include "common/main_delegate.h"

#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "media/base/localized_strings.h"
#include "net/proxy/proxy_resolver_v8.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/material_design/material_design_controller.h"

#if defined(USE_AURA)
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/views/widget/desktop_aura/desktop_screen.h"
#include "ui/wm/core/wm_state.h"
#endif

#if defined(TOOLKIT_VIEWS)
#include "browser/views/views_delegate.h"
#endif

#if defined(USE_X11)
#include "base/environment.h"
#include "base/path_service.h"
#include "base/nix/xdg_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "browser/brightray_paths.h"
#include "chrome/browser/ui/libgtkui/gtk_ui.h"
#include "ui/base/x/x11_util.h"
#include "ui/base/x/x11_util_internal.h"
#include "ui/views/linux_ui/linux_ui.h"
#endif

#if defined(OS_WIN)
#include "ui/base/cursor/cursor_loader_win.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/gfx/platform_font_win.h"
#endif

#if defined(OS_LINUX)
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/dbus/dbus_bluez_manager_wrapper_linux.h"
#endif

namespace brightray {

namespace {

#if defined(OS_WIN)
// gfx::Font callbacks
void AdjustUIFont(LOGFONT* logfont) {
  l10n_util::AdjustUIFont(logfont);
}

int GetMinimumFontSize() {
  return 10;
}
#endif

#if defined(USE_X11)
// Indicates that we're currently responding to an IO error (by shutting down).
bool g_in_x11_io_error_handler = false;

// Number of seconds to wait for UI thread to get an IO error if we get it on
// the background thread.
const int kWaitForUIThreadSeconds = 10;

void OverrideLinuxAppDataPath() {
  base::FilePath path;
  if (PathService::Get(DIR_APP_DATA, &path))
    return;
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  path = base::nix::GetXDGDirectory(env.get(),
                                    base::nix::kXdgConfigHomeEnvVar,
                                    base::nix::kDotConfigDir);
  PathService::Override(DIR_APP_DATA, path);
}

int BrowserX11ErrorHandler(Display* d, XErrorEvent* error) {
  if (!g_in_x11_io_error_handler) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::Bind(&ui::LogErrorEventDescription, d, *error));
  }
  return 0;
}

// This function is used to help us diagnose crash dumps that happen
// during the shutdown process.
NOINLINE void WaitingForUIThreadToHandleIOError() {
  // Ensure function isn't optimized away.
  asm("");
  sleep(kWaitForUIThreadSeconds);
}

int BrowserX11IOErrorHandler(Display* d) {
  if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
    // Wait for the UI thread (which has a different connection to the X server)
    // to get the error. We can't call shutdown from this thread without
    // tripping an error. Doing it through a function so that we'll be able
    // to see it in any crash dumps.
    WaitingForUIThreadToHandleIOError();
    return 0;
  }

  // If there's an IO error it likely means the X server has gone away.
  // If this CHECK fails, then that means SessionEnding() below triggered some
  // code that tried to talk to the X server, resulting in yet another error.
  CHECK(!g_in_x11_io_error_handler);

  g_in_x11_io_error_handler = true;
  LOG(ERROR) << "X IO error received (X server probably went away)";
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());

  return 0;
}

int X11EmptyErrorHandler(Display* d, XErrorEvent* error) {
  return 0;
}

int X11EmptyIOErrorHandler(Display* d) {
  return 0;
}
#endif

base::string16 MediaStringProvider(media::MessageId id) {
  switch (id) {
    case media::DEFAULT_AUDIO_DEVICE_NAME:
      return base::ASCIIToUTF16("Default");
#if defined(OS_WIN)
    case media::COMMUNICATIONS_AUDIO_DEVICE_NAME:
      return base::ASCIIToUTF16("Communications");
#endif
    default:
      return base::string16();
  }
}

}  // namespace

BrowserMainParts::BrowserMainParts() {
}

BrowserMainParts::~BrowserMainParts() {
}

void BrowserMainParts::PreEarlyInitialization() {
  std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
  feature_list->InitializeFromCommandLine("", "");
  base::FeatureList::SetInstance(std::move(feature_list));

#if defined(USE_X11)
  views::LinuxUI::SetInstance(BuildGtk2UI());
  OverrideLinuxAppDataPath();

  // Installs the X11 error handlers for the browser process used during
  // startup. They simply print error messages and exit because
  // we can't shutdown properly while creating and initializing services.
  ui::SetX11ErrorHandlers(nullptr, nullptr);
#endif
}

void BrowserMainParts::ToolkitInitialized() {
  ui::MaterialDesignController::Initialize();

#if defined(USE_AURA) && defined(USE_X11)
  views::LinuxUI::instance()->Initialize();
#endif

#if defined(USE_AURA)
  wm_state_.reset(new wm::WMState);
#endif

#if defined(TOOLKIT_VIEWS)
  views_delegate_.reset(new ViewsDelegate);
#endif

#if defined(OS_WIN)
  gfx::PlatformFontWin::adjust_font_callback = &AdjustUIFont;
  gfx::PlatformFontWin::get_minimum_font_size_callback = &GetMinimumFontSize;

  wchar_t module_name[MAX_PATH] = { 0 };
  if (GetModuleFileName(NULL, module_name, MAX_PATH))
    ui::CursorLoaderWin::SetCursorResourceModule(module_name);
#endif
}

void BrowserMainParts::PreMainMessageLoopStart() {
#if defined(OS_MACOSX)
  l10n_util::OverrideLocaleWithCocoaLocale();
#endif
  InitializeResourceBundle("");
#if defined(OS_MACOSX)
  InitializeMainNib();
#endif
  media::SetLocalizedStringProvider(MediaStringProvider);
}

void BrowserMainParts::PreMainMessageLoopRun() {
  content::WebUIControllerFactory::RegisterFactory(
      WebUIControllerFactory::GetInstance());

  // --remote-debugging-port
  auto command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kRemoteDebuggingPort))
    DevToolsManagerDelegate::StartHttpHandler();
}

void BrowserMainParts::PostMainMessageLoopStart() {
#if defined(USE_X11)
  // Installs the X11 error handlers for the browser process after the
  // main message loop has started. This will allow us to exit cleanly
  // if X exits before us.
  ui::SetX11ErrorHandlers(BrowserX11ErrorHandler, BrowserX11IOErrorHandler);
#endif
#if defined(OS_LINUX)
  bluez::DBusBluezManagerWrapperLinux::Initialize();
#endif
}

void BrowserMainParts::PostMainMessageLoopRun() {
#if defined(USE_X11)
  // Unset the X11 error handlers. The X11 error handlers log the errors using a
  // |PostTask()| on the message-loop. But since the message-loop is in the
  // process of terminating, this can cause errors.
  ui::SetX11ErrorHandlers(X11EmptyErrorHandler, X11EmptyIOErrorHandler);
#endif
}

int BrowserMainParts::PreCreateThreads() {
#if defined(USE_AURA)
  display::Screen* screen = views::CreateDesktopScreen();
  display::Screen::SetScreenInstance(screen);
#if defined(USE_X11)
  views::LinuxUI::instance()->UpdateDeviceScaleFactor();
#endif
#endif
  return 0;
}

void BrowserMainParts::PostDestroyThreads() {
#if defined(OS_LINUX)
  device::BluetoothAdapterFactory::Shutdown();
  bluez::DBusBluezManagerWrapperLinux::Shutdown();
#endif
}

}  // namespace brightray
<commit_msg>Fix building on Linux<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-CHROMIUM file.

#include "browser/browser_main_parts.h"

#include "browser/browser_context.h"
#include "browser/devtools_manager_delegate.h"
#include "browser/web_ui_controller_factory.h"
#include "common/main_delegate.h"

#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "media/base/localized_strings.h"
#include "net/proxy/proxy_resolver_v8.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/material_design/material_design_controller.h"

#if defined(USE_AURA)
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/views/widget/desktop_aura/desktop_screen.h"
#include "ui/wm/core/wm_state.h"
#endif

#if defined(TOOLKIT_VIEWS)
#include "browser/views/views_delegate.h"
#endif

#if defined(USE_X11)
#include "base/environment.h"
#include "base/path_service.h"
#include "base/nix/xdg_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "browser/brightray_paths.h"
#include "chrome/browser/ui/libgtkui/gtk_ui.h"
#include "ui/base/x/x11_util.h"
#include "ui/base/x/x11_util_internal.h"
#include "ui/views/linux_ui/linux_ui.h"
#endif

#if defined(OS_WIN)
#include "ui/base/cursor/cursor_loader_win.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/gfx/platform_font_win.h"
#endif

#if defined(OS_LINUX)
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/dbus/dbus_bluez_manager_wrapper_linux.h"
#endif

namespace brightray {

namespace {

#if defined(OS_WIN)
// gfx::Font callbacks
void AdjustUIFont(LOGFONT* logfont) {
  l10n_util::AdjustUIFont(logfont);
}

int GetMinimumFontSize() {
  return 10;
}
#endif

#if defined(USE_X11)
// Indicates that we're currently responding to an IO error (by shutting down).
bool g_in_x11_io_error_handler = false;

// Number of seconds to wait for UI thread to get an IO error if we get it on
// the background thread.
const int kWaitForUIThreadSeconds = 10;

void OverrideLinuxAppDataPath() {
  base::FilePath path;
  if (PathService::Get(DIR_APP_DATA, &path))
    return;
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  path = base::nix::GetXDGDirectory(env.get(),
                                    base::nix::kXdgConfigHomeEnvVar,
                                    base::nix::kDotConfigDir);
  PathService::Override(DIR_APP_DATA, path);
}

int BrowserX11ErrorHandler(Display* d, XErrorEvent* error) {
  if (!g_in_x11_io_error_handler) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::Bind(&ui::LogErrorEventDescription, d, *error));
  }
  return 0;
}

// This function is used to help us diagnose crash dumps that happen
// during the shutdown process.
NOINLINE void WaitingForUIThreadToHandleIOError() {
  // Ensure function isn't optimized away.
  asm("");
  sleep(kWaitForUIThreadSeconds);
}

int BrowserX11IOErrorHandler(Display* d) {
  if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
    // Wait for the UI thread (which has a different connection to the X server)
    // to get the error. We can't call shutdown from this thread without
    // tripping an error. Doing it through a function so that we'll be able
    // to see it in any crash dumps.
    WaitingForUIThreadToHandleIOError();
    return 0;
  }

  // If there's an IO error it likely means the X server has gone away.
  // If this CHECK fails, then that means SessionEnding() below triggered some
  // code that tried to talk to the X server, resulting in yet another error.
  CHECK(!g_in_x11_io_error_handler);

  g_in_x11_io_error_handler = true;
  LOG(ERROR) << "X IO error received (X server probably went away)";
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());

  return 0;
}

int X11EmptyErrorHandler(Display* d, XErrorEvent* error) {
  return 0;
}

int X11EmptyIOErrorHandler(Display* d) {
  return 0;
}
#endif

base::string16 MediaStringProvider(media::MessageId id) {
  switch (id) {
    case media::DEFAULT_AUDIO_DEVICE_NAME:
      return base::ASCIIToUTF16("Default");
#if defined(OS_WIN)
    case media::COMMUNICATIONS_AUDIO_DEVICE_NAME:
      return base::ASCIIToUTF16("Communications");
#endif
    default:
      return base::string16();
  }
}

}  // namespace

BrowserMainParts::BrowserMainParts() {
}

BrowserMainParts::~BrowserMainParts() {
}

void BrowserMainParts::PreEarlyInitialization() {
  std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
  feature_list->InitializeFromCommandLine("", "");
  base::FeatureList::SetInstance(std::move(feature_list));

#if defined(USE_X11)
  views::LinuxUI::SetInstance(BuildGtkUi());
  OverrideLinuxAppDataPath();

  // Installs the X11 error handlers for the browser process used during
  // startup. They simply print error messages and exit because
  // we can't shutdown properly while creating and initializing services.
  ui::SetX11ErrorHandlers(nullptr, nullptr);
#endif
}

void BrowserMainParts::ToolkitInitialized() {
  ui::MaterialDesignController::Initialize();

#if defined(USE_AURA) && defined(USE_X11)
  views::LinuxUI::instance()->Initialize();
#endif

#if defined(USE_AURA)
  wm_state_.reset(new wm::WMState);
#endif

#if defined(TOOLKIT_VIEWS)
  views_delegate_.reset(new ViewsDelegate);
#endif

#if defined(OS_WIN)
  gfx::PlatformFontWin::adjust_font_callback = &AdjustUIFont;
  gfx::PlatformFontWin::get_minimum_font_size_callback = &GetMinimumFontSize;

  wchar_t module_name[MAX_PATH] = { 0 };
  if (GetModuleFileName(NULL, module_name, MAX_PATH))
    ui::CursorLoaderWin::SetCursorResourceModule(module_name);
#endif
}

void BrowserMainParts::PreMainMessageLoopStart() {
#if defined(OS_MACOSX)
  l10n_util::OverrideLocaleWithCocoaLocale();
#endif
  InitializeResourceBundle("");
#if defined(OS_MACOSX)
  InitializeMainNib();
#endif
  media::SetLocalizedStringProvider(MediaStringProvider);
}

void BrowserMainParts::PreMainMessageLoopRun() {
  content::WebUIControllerFactory::RegisterFactory(
      WebUIControllerFactory::GetInstance());

  // --remote-debugging-port
  auto command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kRemoteDebuggingPort))
    DevToolsManagerDelegate::StartHttpHandler();
}

void BrowserMainParts::PostMainMessageLoopStart() {
#if defined(USE_X11)
  // Installs the X11 error handlers for the browser process after the
  // main message loop has started. This will allow us to exit cleanly
  // if X exits before us.
  ui::SetX11ErrorHandlers(BrowserX11ErrorHandler, BrowserX11IOErrorHandler);
#endif
#if defined(OS_LINUX)
  bluez::DBusBluezManagerWrapperLinux::Initialize();
#endif
}

void BrowserMainParts::PostMainMessageLoopRun() {
#if defined(USE_X11)
  // Unset the X11 error handlers. The X11 error handlers log the errors using a
  // |PostTask()| on the message-loop. But since the message-loop is in the
  // process of terminating, this can cause errors.
  ui::SetX11ErrorHandlers(X11EmptyErrorHandler, X11EmptyIOErrorHandler);
#endif
}

int BrowserMainParts::PreCreateThreads() {
#if defined(USE_AURA)
  display::Screen* screen = views::CreateDesktopScreen();
  display::Screen::SetScreenInstance(screen);
#if defined(USE_X11)
  views::LinuxUI::instance()->UpdateDeviceScaleFactor();
#endif
#endif
  return 0;
}

void BrowserMainParts::PostDestroyThreads() {
#if defined(OS_LINUX)
  device::BluetoothAdapterFactory::Shutdown();
  bluez::DBusBluezManagerWrapperLinux::Shutdown();
#endif
}

}  // namespace brightray
<|endoftext|>


<commit_before>#include "specifyGenerationRulesDialog.h"
#include "ui_specifyGenerationRulesDialog.h"

using namespace qReal;
using namespace gui;

SpecifyGenerationRulesDialog::SpecifyGenerationRulesDialog(MainWindow &mainWindow
		, EditorManagerInterface &interpreterEditorManager
		, Id const &id) :
	QDialog(&mainWindow)
	, mUi(new Ui::SpecifyGenerationRulesDialog)
	, mInterpreterEditorManager(interpreterEditorManager)
	, mId(id)
{
	mUi->setupUi(this);

	addPropertiesList();
	connect(mUi->propertiesView, &QListWidget::itemDoubleClicked, this
			&SpecifyGenerationRulesDialog::insertPropertyIntoCode);
}

SpecifyGenerationRulesDialog::~SpecifyGenerationRulesDialog()
{
	delete mUi;
}

void SpecifyGenerationRulesDialog::insertPropertyIntoCode(QListWidgetItem* property)
{
	QString const propertyName = property->text();
	mUi->codeArea->insertPlainText(propertyName);
}

void SpecifyGenerationRulesDialog::addPropertiesList()
{
	mPropertiesNames = mInterpreterEditorManager.propertyNames(mId);
	QStringList const propertiesDisplayedNames = propertiesDisplayedNamesList(mPropertiesNames);
	mUi->propertiesView->clear();
	mUi->propertiesView->addItems(propertiesDisplayedNames);
}

QStringList SpecifyGenerationRulesDialog::propertiesDisplayedNamesList(QStringList const &propertiesNames)
{
	QStringList propertiesDisplayedNames;
	for (QString const &propertyName : propertiesNames) {
		propertiesDisplayedNames << mInterpreterEditorManager.propertyDisplayedName(mId, propertyName);
	}

	return propertiesDisplayedNames;
}
<commit_msg>added comma<commit_after>#include "specifyGenerationRulesDialog.h"
#include "ui_specifyGenerationRulesDialog.h"

using namespace qReal;
using namespace gui;

SpecifyGenerationRulesDialog::SpecifyGenerationRulesDialog(MainWindow &mainWindow
		, EditorManagerInterface &interpreterEditorManager
		, Id const &id) :
	QDialog(&mainWindow)
	, mUi(new Ui::SpecifyGenerationRulesDialog)
	, mInterpreterEditorManager(interpreterEditorManager)
	, mId(id)
{
	mUi->setupUi(this);

	addPropertiesList();
	connect(mUi->propertiesView, &QListWidget::itemDoubleClicked, this
			, &SpecifyGenerationRulesDialog::insertPropertyIntoCode);
}

SpecifyGenerationRulesDialog::~SpecifyGenerationRulesDialog()
{
	delete mUi;
}

void SpecifyGenerationRulesDialog::insertPropertyIntoCode(QListWidgetItem* property)
{
	QString const propertyName = property->text();
	mUi->codeArea->insertPlainText(propertyName);
}

void SpecifyGenerationRulesDialog::addPropertiesList()
{
	mPropertiesNames = mInterpreterEditorManager.propertyNames(mId);
	QStringList const propertiesDisplayedNames = propertiesDisplayedNamesList(mPropertiesNames);
	mUi->propertiesView->clear();
	mUi->propertiesView->addItems(propertiesDisplayedNames);
}

QStringList SpecifyGenerationRulesDialog::propertiesDisplayedNamesList(QStringList const &propertiesNames)
{
	QStringList propertiesDisplayedNames;
	for (QString const &propertyName : propertiesNames) {
		propertiesDisplayedNames << mInterpreterEditorManager.propertyDisplayedName(mId, propertyName);
	}

	return propertiesDisplayedNames;
}
<|endoftext|>


<commit_before>/*
 *    Copyright (c) <2002-2006> <Jean-Philippe Barrette-LaPierre>
 *
 *    Permission is hereby granted, free of charge, to any person obtaining
 *    a copy of this software and associated documentation files
 *    (cURLpp), to deal in the Software without restriction,
 *    including without limitation the rights to use, copy, modify, merge,
 *    publish, distribute, sublicense, and/or sell copies of the Software,
 *    and to permit persons to whom the Software is furnished to do so,
 *    subject to the following conditions:
 *
 *    The above copyright notice and this permission notice shall be included
 *    in all copies or substantial portions of the Software.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 *    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 *    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 *    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 *    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef CURLPP_INFO_HPP
#define CURLPP_INFO_HPP

#include "dllfct.h"
#include "Easy.hpp"

namespace cURLpp
{
  /**
   * This class is responsible of retreiving the Info from
   * a handle. This is the class you use when you want to do
   * so.
   */
  template< CURLINFO info, typename T >
  struct Info
  {
    static void get(cURLpp::Easy &handle, T &value);
    static T get(cURLpp::Easy &handle);
  };

  /**
   * This class is used when an info is not available for the
   * current libcURL version.
   */
  template< CURLINFO info, typename T >
  struct NotAvailableInfo : Info< info, T >
  {
    static void get(cURLpp::Easy &handle, T &value);
    static T get(cURLpp::Easy &handle);
  };

  /**
   * This is the class you need to specialize if you use
   * a special type that libcURL is not aware of. This class
   * need to call cURLpp::InfoGetter::get function. See
   * cURLpp::InfoGetter for more information.
   */
  template< typename T >
  struct InfoTypeConverter
  {
    static void get(cURLpp::Easy &handle, CURLINFO info, T &value);
  };

  template< >
  void InfoTypeConverter< std::string >::get(cURLpp::Easy &handle,
					     CURLINFO info,
					     std::string &value);

  template< >
  void InfoTypeConverter< std::list< std::string > >::get(cURLpp::Easy & handle,
							  CURLINFO info,
							  std::list< std::string > &value);

  template< >
  void InfoTypeConverter< long >::get(cURLpp::Easy &handle,
				      CURLINFO info,
				      long &value);

  template< >
  void InfoTypeConverter< double >::get(cURLpp::Easy &handle,
					CURLINFO info,
					double &value);

  /**
   * This is the only class that is authorized to retreive
   * info from a cURLpp::Easy class. So, this is the class
   * you need to use when you specialize the class
   * cURLpp::InfoTypeConverter. This class is in fact used
   * as a proxy, just to be sure that nobody access cURLpp::Easy's
   * private data.
   */
  struct InfoGetter
  {
    template< typename T >
    static void get(cURLpp::Easy &handle, CURLINFO info, T &value);
  };
}

#include "Info.inl"

#endif
<commit_msg>Allowed curlpp to be built in a dynamic library (Win32: VC8 & VC9)<commit_after>/*
 *    Copyright (c) <2002-2006> <Jean-Philippe Barrette-LaPierre>
 *
 *    Permission is hereby granted, free of charge, to any person obtaining
 *    a copy of this software and associated documentation files
 *    (cURLpp), to deal in the Software without restriction,
 *    including without limitation the rights to use, copy, modify, merge,
 *    publish, distribute, sublicense, and/or sell copies of the Software,
 *    and to permit persons to whom the Software is furnished to do so,
 *    subject to the following conditions:
 *
 *    The above copyright notice and this permission notice shall be included
 *    in all copies or substantial portions of the Software.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 *    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 *    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 *    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 *    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef CURLPP_INFO_HPP
#define CURLPP_INFO_HPP

#include "dllfct.h"
#include "Easy.hpp"

namespace cURLpp
{
  /**
   * This class is responsible of retreiving the Info from
   * a handle. This is the class you use when you want to do
   * so.
   */
  template< CURLINFO info, typename T >
  struct Info
  {
    static void get(cURLpp::Easy &handle, T &value);
    static T get(cURLpp::Easy &handle);
  };

  /**
   * This class is used when an info is not available for the
   * current libcURL version.
   */
  template< CURLINFO info, typename T >
  struct NotAvailableInfo : Info< info, T >
  {
    static void get(cURLpp::Easy &handle, T &value);
    static T get(cURLpp::Easy &handle);
  };

  /**
   * This is the class you need to specialize if you use
   * a special type that libcURL is not aware of. This class
   * need to call cURLpp::InfoGetter::get function. See
   * cURLpp::InfoGetter for more information.
   */
  template< typename T >
  struct InfoTypeConverter
  {
    static void get(cURLpp::Easy &handle, CURLINFO info, T &value);
  };

  template< >
  void CURLPPAPI InfoTypeConverter< std::string >::get(cURLpp::Easy &handle,
					     CURLINFO info,
					     std::string &value);

  template< >
  void CURLPPAPI InfoTypeConverter< std::list< std::string > >::get(cURLpp::Easy & handle,
							  CURLINFO info,
							  std::list< std::string > &value);

  template< >
  void CURLPPAPI InfoTypeConverter< long >::get(cURLpp::Easy &handle,
				      CURLINFO info,
				      long &value);

  template< >
  void CURLPPAPI InfoTypeConverter< double >::get(cURLpp::Easy &handle,
					CURLINFO info,
					double &value);

  /**
   * This is the only class that is authorized to retreive
   * info from a cURLpp::Easy class. So, this is the class
   * you need to use when you specialize the class
   * cURLpp::InfoTypeConverter. This class is in fact used
   * as a proxy, just to be sure that nobody access cURLpp::Easy's
   * private data.
   */
  struct InfoGetter
  {
    template< typename T >
    static void get(cURLpp::Easy &handle, CURLINFO info, T &value);
  };
}

#include "Info.inl"

#endif
<|endoftext|>


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

#include "miscellaniousPage.h"
#include "ui_miscellaniousPage.h"

#include <qrkernel/settingsManager.h>
#include <qrutils/widgets/qRealFileDialog.h>

using namespace qReal;

PreferencesMiscellaniousPage::PreferencesMiscellaniousPage(QWidget *parent)
		: PreferencesPage(parent)
		, mUi(new Ui::PreferencesMiscellaniousPage)
{
	mUi->setupUi(this);
	setObjectName("preferencesMiscellaniousPage");
	setWindowIcon(QIcon(":/preferencesDialog/images/miscellaneous.png"));

	connect(mUi->imagesPathBrowseButton, SIGNAL(clicked()), this, SLOT(browseImagesPath()));
	connect(mUi->toolbarSizeSlider, &QSlider::valueChanged
			, [=](int value ) { SettingsManager::setValue("toolbarSize", value); });

	restoreSettings();
}

PreferencesMiscellaniousPage::~PreferencesMiscellaniousPage()
{
	delete mUi;
}

void PreferencesMiscellaniousPage::changeEvent(QEvent *e)
{
	switch (e->type()) {
	case QEvent::LanguageChange:
		mUi->retranslateUi(this);
		break;
	default:
		break;
	}
}

void PreferencesMiscellaniousPage::browseImagesPath()
{
	const QString path = utils::QRealFileDialog::getExistingDirectory("OpenImagesOnMiscellaniousPage"
			, this, tr("Open Directory")).replace("\\", "/");
	if (!path.isEmpty()) {
		mUi->imagesPathEdit->setText(path);
	}
}

void PreferencesMiscellaniousPage::save()
{
	SettingsManager::setValue("Splashscreen", mUi->splashScreenCheckBox->isChecked());
	SettingsManager::setValue("Antialiasing", mUi->antialiasingCheckBox->isChecked());

	SettingsManager::setValue("pathToImages", mUi->imagesPathEdit->text());
	SettingsManager::setValue("recentProjectsLimit", mUi->recentProjectsLimitSpinBox->value());

	SettingsManager::setValue("toolbarSize", mUi->toolbarSizeSlider->value());
}

void PreferencesMiscellaniousPage::restoreSettings()
{
	mUi->antialiasingCheckBox->setChecked(SettingsManager::value("Antialiasing").toBool());
	mUi->splashScreenCheckBox->setChecked(SettingsManager::value("Splashscreen").toBool());

	mUi->toolbarSizeSlider->setValue(SettingsManager::value("toolbarSize").toInt());

	mUi->imagesPathEdit->setText(SettingsManager::value("pathToImages").toString());
}
<commit_msg>fix missed save step in miscellanious page<commit_after>/* Copyright 2007-2015 QReal Research Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "miscellaniousPage.h"
#include "ui_miscellaniousPage.h"

#include <qrkernel/settingsManager.h>
#include <qrutils/widgets/qRealFileDialog.h>

using namespace qReal;

PreferencesMiscellaniousPage::PreferencesMiscellaniousPage(QWidget *parent)
		: PreferencesPage(parent)
		, mUi(new Ui::PreferencesMiscellaniousPage)
{
	mUi->setupUi(this);
	setObjectName("preferencesMiscellaniousPage");
	setWindowIcon(QIcon(":/preferencesDialog/images/miscellaneous.png"));

	connect(mUi->imagesPathBrowseButton, SIGNAL(clicked()), this, SLOT(browseImagesPath()));
	connect(mUi->toolbarSizeSlider, &QSlider::valueChanged
			, [=](int value ) { SettingsManager::setValue("toolbarSize", value); });

	restoreSettings();
}

PreferencesMiscellaniousPage::~PreferencesMiscellaniousPage()
{
	delete mUi;
}

void PreferencesMiscellaniousPage::changeEvent(QEvent *e)
{
	switch (e->type()) {
	case QEvent::LanguageChange:
		mUi->retranslateUi(this);
		break;
	default:
		break;
	}
}

void PreferencesMiscellaniousPage::browseImagesPath()
{
	const QString path = utils::QRealFileDialog::getExistingDirectory("OpenImagesOnMiscellaniousPage"
			, this, tr("Open Directory")).replace("\\", "/");
	if (!path.isEmpty()) {
		mUi->imagesPathEdit->setText(path);
	}
}

void PreferencesMiscellaniousPage::save()
{
	SettingsManager::setValue("Splashscreen", mUi->splashScreenCheckBox->isChecked());
	SettingsManager::setValue("Antialiasing", mUi->antialiasingCheckBox->isChecked());

	SettingsManager::setValue("pathToImages", mUi->imagesPathEdit->text());
	SettingsManager::setValue("recentProjectsLimit", mUi->recentProjectsLimitSpinBox->value());

	SettingsManager::setValue("toolbarSize", mUi->toolbarSizeSlider->value());
}

void PreferencesMiscellaniousPage::restoreSettings()
{
	mUi->antialiasingCheckBox->setChecked(SettingsManager::value("Antialiasing").toBool());
	mUi->splashScreenCheckBox->setChecked(SettingsManager::value("Splashscreen").toBool());

	mUi->recentProjectsLimitSpinBox->setValue(SettingsManager::value("recentProjectsLimit").toInt());

	mUi->toolbarSizeSlider->setValue(SettingsManager::value("toolbarSize").toInt());

	mUi->imagesPathEdit->setText(SettingsManager::value("pathToImages").toString());
}
<|endoftext|>


<commit_before>#include "i2c_interface.h"

I2CInterface::I2CInterface(const std::string& deviceFile, uint8_t slaveAddress)
    : m_deviceFile(deviceFile),
      m_slaveAddress(slaveAddress),
      m_fileDescriptor(0)
{
}

I2CInterface::~I2CInterface()
{
    closeFileDescriptor();
}

I2CInterface::RET_CODE I2CInterface::init()
{
    return openFileDescriptor();
}

I2CInterface::RET_CODE I2CInterface::openFileDescriptor()
{
    if(m_fileDescriptor)
    {
        closeFileDescriptor();
    }

    //Try to open the file descriptor
    m_fileDescriptor = open(m_deviceFile.c_str(), O_RDWR);
    if(m_fileDescriptor < 0)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_OPEN_FILE_DESCRIPTOR;
    }

    //Init input output control
    if(ioctl(m_fileDescriptor, I2C_SLAVE, m_slaveAddress) < 0)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_INIT_INPUT_OUTPUT_CONTROL;
    }
    return RET_CODE::SUCCESS;
}

void I2CInterface::closeFileDescriptor()
{
    if(m_fileDescriptor)
    {
        close(m_fileDescriptor);
        m_fileDescriptor = 0;
    }
}

I2CInterface::RET_CODE I2CInterface::setSlaveAddress(const uint8_t slaveAddress)
{
    m_slaveAddress = slaveAddress;
    return openFileDescriptor();
}

uint8_t I2CInterface::getSlaveAddress() const
{
    return m_slaveAddress;
}

I2CInterface::RET_CODE I2CInterface::send(uint8_t registerAddress, uint8_t* txBuffer, int length)
{
    //check for a null buffer pointer
    if(txBuffer == nullptr)
    {
        std::cout << "i2c error: received null transmit buffer." << std::endl;
        return RET_CODE::NULL_TRANSMIT_BUFFER;
    }

    //Check for an invalid length
    if(length < 1)
    {
        std::cout << "i2c error: invalid send buffer length" << std::endl;
        return RET_CODE::INVALID_TRANSMIT_BUFFER_LENGTH;
    }

    //Create the buffer
    //Payload length plus zeroth element for register
    uint8_t buffer[length + 1];
    buffer[0] = registerAddress;

    //Pack the buffer
    for(size_t i = 0; i < length; ++i)
    {
        buffer[i+1] = txBuffer[i];
    }

    //Write the data
    if(write(m_fileDescriptor, buffer, length) != length)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_I2C_WRITE;
    }

    return RET_CODE::SUCCESS;
}

I2CInterface::RET_CODE I2CInterface::sendByte(uint8_t registerAddress, uint8_t data)
{
    uint8_t buffer[2];
    buffer[0] = registerAddress;
    buffer[1] = data;

    //Write the data
    if(write(m_fileDescriptor, buffer, 2) != 2)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_I2C_WRITE;
    }

    return RET_CODE::SUCCESS;

}

I2CInterface::RET_CODE I2CInterface::readFromRegister(uint8_t registerAddress, uint8_t* rxBuffer, int length)
{

    if(write(m_fileDescriptor, registerAddress, 1) != 1)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_I2C_WRITE;
    }

    if(read(m_fileDescriptor, rxBuffer, length) != length)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_I2C_READ;
    }

    return RET_CODE::SUCCESS;
}<commit_msg>Added updated read<commit_after>#include "i2c_interface.h"

I2CInterface::I2CInterface(const std::string& deviceFile, uint8_t slaveAddress)
    : m_deviceFile(deviceFile),
      m_slaveAddress(slaveAddress),
      m_fileDescriptor(0)
{
}

I2CInterface::~I2CInterface()
{
    closeFileDescriptor();
}

I2CInterface::RET_CODE I2CInterface::init()
{
    return openFileDescriptor();
}

I2CInterface::RET_CODE I2CInterface::openFileDescriptor()
{
    if(m_fileDescriptor)
    {
        closeFileDescriptor();
    }

    //Try to open the file descriptor
    m_fileDescriptor = open(m_deviceFile.c_str(), O_RDWR);
    if(m_fileDescriptor < 0)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_OPEN_FILE_DESCRIPTOR;
    }

    //Init input output control
    if(ioctl(m_fileDescriptor, I2C_SLAVE, m_slaveAddress) < 0)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_INIT_INPUT_OUTPUT_CONTROL;
    }
    return RET_CODE::SUCCESS;
}

void I2CInterface::closeFileDescriptor()
{
    if(m_fileDescriptor)
    {
        close(m_fileDescriptor);
        m_fileDescriptor = 0;
    }
}

I2CInterface::RET_CODE I2CInterface::setSlaveAddress(const uint8_t slaveAddress)
{
    m_slaveAddress = slaveAddress;
    return openFileDescriptor();
}

uint8_t I2CInterface::getSlaveAddress() const
{
    return m_slaveAddress;
}

I2CInterface::RET_CODE I2CInterface::send(uint8_t registerAddress, uint8_t* txBuffer, int length)
{
    //check for a null buffer pointer
    if(txBuffer == nullptr)
    {
        std::cout << "i2c error: received null transmit buffer." << std::endl;
        return RET_CODE::NULL_TRANSMIT_BUFFER;
    }

    //Check for an invalid length
    if(length < 1)
    {
        std::cout << "i2c error: invalid send buffer length" << std::endl;
        return RET_CODE::INVALID_TRANSMIT_BUFFER_LENGTH;
    }

    //Create the buffer
    //Payload length plus zeroth element for register
    uint8_t buffer[length + 1];
    buffer[0] = registerAddress;

    //Pack the buffer
    for(size_t i = 0; i < length; ++i)
    {
        buffer[i+1] = txBuffer[i];
    }

    //Write the data
    if(write(m_fileDescriptor, buffer, length) != length)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_I2C_WRITE;
    }

    return RET_CODE::SUCCESS;
}

I2CInterface::RET_CODE I2CInterface::sendByte(uint8_t registerAddress, uint8_t data)
{
    uint8_t buffer[2];
    buffer[0] = registerAddress;
    buffer[1] = data;

    //Write the data
    if(write(m_fileDescriptor, buffer, 2) != 2)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_I2C_WRITE;
    }

    return RET_CODE::SUCCESS;

}

I2CInterface::RET_CODE I2CInterface::readFromRegister(uint8_t registerAddress, uint8_t* rxBuffer, int length)
{
    uint8_t buffer[1];
    buffer[0] = registerAddress;

    if(write(m_fileDescriptor, buffer, 1) != 1)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_I2C_WRITE;
    }

    if(read(m_fileDescriptor, rxBuffer, length) != length)
    {
        std::cout << "i2c error: " << std::strerror(errno) << std::endl;
        return RET_CODE::FAILED_I2C_READ;
    }

    return RET_CODE::SUCCESS;
}<|endoftext|>


<commit_before>#include <clang-c/Index.h>
#include <cstdio>

#include <array>
#include <iostream>
#include <vector>

namespace {

    const unsigned int indent_spaces = 4;
    const std::string indentation(indent_spaces, ' ');

}

CXCursor tu_cursor;

struct client_data
{
    CXTranslationUnit tu;
    std::vector<CXCursor> current_namespaces;
    CXCursor current_struct;
    // function signature, forwarding call arguments, optional return
    // keyword, and function name
    std::vector<std::array<std::string, 4>> member_functions;
    bool printed_headers;
    const char* filename;
};

std::pair<CXToken*, unsigned int>
get_tokens (CXTranslationUnit tu, CXCursor cursor)
{
    CXSourceRange range = clang_getCursorExtent(cursor);
    CXSourceLocation start = clang_getRangeStart(range);
    CXSourceLocation end = clang_getRangeEnd(range);
    unsigned int start_offset, end_offset;

    std::pair<CXToken*, unsigned int> retval(0, 0);
    clang_tokenize(tu, range, &retval.first, &retval.second);

    return retval;
}

void
free_tokens (CXTranslationUnit tu, std::pair<CXToken*, unsigned int> tokens)
{ clang_disposeTokens(tu, tokens.first, tokens.second); }

void print_tokens (CXTranslationUnit tu, CXCursor cursor)
{
    std::pair<CXToken*, unsigned int> tokens = get_tokens(tu, cursor);

    for (unsigned int i = 0; i < tokens.second; ++i) {
        if (i)
            std::cout << " ";
        CXString spelling = clang_getTokenSpelling(tu, tokens.first[i]);
        std::cout << clang_getCString(spelling);
    }
    std::cout << "\n";

    free_tokens(tu, tokens);
}

bool struct_kind (CXCursorKind kind)
{
    switch (kind) {
    case CXCursor_ClassDecl:
    case CXCursor_StructDecl:
    case CXCursor_ClassTemplate:
    case CXCursor_ClassTemplatePartialSpecialization:
        return true;
    }
    return false;
}

std::string indent (const client_data & data)
{
    std::size_t size = data.current_namespaces.size();
    return std::string(size * indent_spaces, ' ');
}

void print_lines (const client_data & data,
                  const char** lines,
                  std::size_t num_lines)
{
    for (unsigned int i = 0; i < num_lines; ++i) {
        if (lines[i])
            std::cout << indent(data) << indentation << lines[i] << "\n";
        else
            std::cout << "\n";
    }
}

void print_headers (client_data & data)
{
    if (data.printed_headers)
        return;

    std::cout << "#include <algorithm>\n"
              << "#include <functional>\n"
              << "#include <memory>\n"
              << "#include <type_traits>\n"
              << "#include <utility>\n"
              << "\n";

    data.printed_headers = true;
}

void open_struct (const client_data & data, CXCursor struct_cursor)
{
    std::pair<CXToken*, unsigned int> tokens =
        get_tokens(data.tu, struct_cursor);

    std::cout << "\n" << indent(data);

    const std::string open_brace = "{";
    const std::string struct_ = "struct";
    const std::string class_ = "class";

    for (unsigned int i = 0; i < tokens.second; ++i) {
        CXString spelling = clang_getTokenSpelling(data.tu, tokens.first[i]);

        const char* c_str = clang_getCString(spelling);

        if (c_str == open_brace)
            break;

        if (c_str == struct_ || c_str == class_) {
            std::cout << "\n" << indent(data);
        } else if (i) {
            std::cout << " ";
        }

        std::cout << c_str;
    }

    free_tokens(data.tu, tokens);

    std::cout << "\n"
              << indent(data) << "{\n"
              << indent(data) << "public:\n";

    const char* public_interface[] = {
        0,
        "any_printable () = default;",
        0,
        "template <typename T_T__>",
        "any_printable (T_T__ value) :",
        "    handle_ (",
        "        std::make_shared<",
        "            handle<typename std::remove_reference<T_T__>::type>",
        "        >(std::forward<T_T__>(value))",
        "    )",
        "{}",
        0,
        "any_printable (any_printable && rhs) noexcept = default;",
        0,
        "template <typename T_T__>",
        "any_printable & operator= (T_T__ value)",
        "{",
        "    if (handle_.unique())",
        "        *handle_ = std::forward<T_T__>(value);",
        "    else if (!handle_)",
        "        handle_ = std::make_shared<T_T__>(std::forward<T_T__>(value));",
        "    return *this;",
        "}",
        0,
        "any_printable & operator= (any_printable && rhs) noexcept = default;"
    };

    print_lines(data,
                public_interface,
                sizeof(public_interface) / sizeof(const char*));
}

void close_struct (const client_data & data)
{
    std::cout << "\n"
              << indent(data) << "private:\n";

    const char* handle_base_preamble[] = {
        0,
        "struct handle_base",
        "{",
        "    virtual ~handle_base () {}",
        "    virtual std::shared_ptr<handle_base> close () const = 0;",
        0
    };

    print_lines(data,
                handle_base_preamble,
                sizeof(handle_base_preamble) / sizeof(const char*));

    for (auto & member : data.member_functions) {
        std::cout << indent(data) << indentation << indentation
                  << "virtual " << member[0] << " = 0;\n";
    }

    const char* handle_preamble[] = {
        0,
        "};",
        0,
        "template <typename T_T__>",
        "struct handle :",
        "    handle_base",
        "{",
        "    template <typename T_T__>",
        "    handle (T_T__ value,",
        "            typename std::enable_if<",
        "                std::is_reference<U_U__>::value",
        "            >::type* = 0) :",
        "        value_ (value)",
        "    {}",
        0,
        "    template <typename U_U__ = T_T__>",
        "    handle (T_T__ value,",
        "            typename std::enable_if<",
        "                !std::is_reference<U_U__>::value,",
        "                int",
        "            >::type* = 0) noexcept :",
        "        value_ (std::move(value))",
        "    {}",
        0,
        "    virtual std::shared_ptr<handle_base> clone () const",
        "    { return std::make_shared<handle>(value_); }"
    };

    print_lines(data,
                handle_preamble,
                sizeof(handle_preamble) / sizeof(const char*));

    for (auto & member : data.member_functions) {
        std::cout << "\n"
                  << indent(data) << indentation << indentation
                  << "virtual " << member[0] << "\n"
                  << indent(data) << indentation << indentation
                  << "{ " << member[2] << "value_." << member[3]
                  << "( " << member[1] << " ); }\n";
    }

    const char* handle_postamble[] = {
        0,
        "    T_T__ value_;",
        "};",
        0,
        "template <typename T_T__>",
        "struct handle<std::reference_wrapper<T_T__>> :",
        "    handle<T_T__ &>",
        "{",
        "    handle (std::reference_wrapper<T_T__> ref) :",
        "        handle<T_T__ &> (ref.get())",
        "    {}",
        "};",
        0,
        "const handle_base & read () const",
        "{ return *handle_; }",
        0,
        "handle_base & write ()",
        "{",
        "    if (!handle_.unique())",
        "        handle_ = handle_->clone();",
        "    return *handle_;",
        "}",
        0,
        "std::shared_ptr<handle_base> handle_;"
    };

    print_lines(data,
                handle_postamble,
                sizeof(handle_postamble) / sizeof(const char*));

    std::cout << "\n"
              << indent(data) << "};\n";
}

void print_member_function (const client_data & data, CXCursor cursor)
{
    std::cout << "\n"
              << std::string(indent_spaces, ' ') << indent(data)
              << data.member_functions.back()[0];

    std::cout << "\n" << std::string(indent_spaces, ' ') << indent(data)
              << "{ assert(handle_); " << data.member_functions.back()[2]
              << "handle_->"
              << clang_getCString(clang_getCursorSpelling(cursor))
              << "( " << data.member_functions.back()[1] << " ); }\n";
}

void open_namespace (const client_data & data, CXCursor namespace_)
{
    std::cout
        << "\n"
        << indent(data)
        << "namespace "
        << clang_getCString(clang_getCursorSpelling(namespace_))
        << " {";
}

void close_namespace (const client_data & data)
{ std::cout << "\n" << indent(data) << "}\n"; }

CXChildVisitResult
visitor (CXCursor cursor, CXCursor parent, CXClientData data_)
{
    client_data & data = *static_cast<client_data*>(data_);

    CXCursor null_cursor = clang_getNullCursor();

    // close open namespaces we have left
    CXCursor enclosing_namespace = parent;
    while (!clang_equalCursors(enclosing_namespace, tu_cursor) &&
           clang_getCursorKind(enclosing_namespace) != CXCursor_Namespace) {
        enclosing_namespace =
            clang_getCursorSemanticParent(enclosing_namespace);
    }
    if (!clang_equalCursors(enclosing_namespace, tu_cursor) &&
        clang_getCursorKind(enclosing_namespace) == CXCursor_Namespace) {
        while (!data.current_namespaces.empty() &&
               !clang_equalCursors(enclosing_namespace,
                                   data.current_namespaces.back())) {
            data.current_namespaces.pop_back();
            close_namespace(data);
        }
    }

    // close open struct if we have left it
    CXCursor enclosing_struct = parent;
    while (!clang_equalCursors(enclosing_struct, tu_cursor) &&
           !struct_kind(clang_getCursorKind(enclosing_struct))) {
        enclosing_struct = clang_getCursorSemanticParent(enclosing_struct);
    }
    if (!clang_Cursor_isNull(data.current_struct) &&
        !clang_equalCursors(enclosing_struct, data.current_struct)) {
        data.current_struct = null_cursor;
        close_struct(data);
        data.member_functions.clear();
    }

    CXCursorKind kind = clang_getCursorKind(cursor);
    if (kind == CXCursor_Namespace) {
        CXSourceLocation location = clang_getCursorLocation(cursor);
        const bool from_main_file = clang_Location_isFromMainFile(location);
        if (from_main_file) {
            print_headers(data);
            open_namespace(data, cursor);
            data.current_namespaces.push_back(cursor);
        }
        return CXChildVisit_Recurse;
    } else if (struct_kind(kind)) {
        if (clang_Cursor_isNull(data.current_struct)) {
            print_headers(data);
            data.current_struct = cursor;
            open_struct(data, cursor);
            return CXChildVisit_Recurse;
        }
    } else if (kind == CXCursor_CXXMethod) {
        std::pair<CXToken*, unsigned int> tokens = get_tokens(data.tu, cursor);

        const std::string open_brace = "{";
        const std::string semicolon = ";";

        std::string str;

        for (unsigned int i = 0; i < tokens.second; ++i) {
            CXString spelling =
                clang_getTokenSpelling(data.tu, tokens.first[i]);

            const char* c_str = clang_getCString(spelling);

            if (c_str == open_brace || c_str == semicolon)
                break;

            if (i)
                str += " ";

            str += c_str;
        }

        std::string args;

        const int num_args = clang_Cursor_getNumArguments(cursor);
        for (int i = 0; i < num_args; ++i) {
            if (i)
                args += ", ";
            CXCursor arg_cursor = clang_Cursor_getArgument(cursor, i);
            args += clang_getCString(clang_getCursorSpelling(arg_cursor));
        }

        const char* return_str =
            clang_getCursorResultType(cursor).kind == CXType_Void ?
            "" :
            "return ";

        const char* function_name =
            clang_getCString(clang_getCursorSpelling(cursor));

        free_tokens(data.tu, tokens);

        data.member_functions.push_back({str, args, return_str, function_name});

        print_member_function(data, cursor);
    }

    return CXChildVisit_Continue;
}

int main (int argc, char* argv[])
{
    CXIndex index = clang_createIndex(0, 1);
    CXTranslationUnit tu = clang_parseTranslationUnit(
        index,
        0,
        argv,
        argc,
        0,
        0,
        CXTranslationUnit_DetailedPreprocessingRecord
    );

    const char* filename =
        clang_getCString(clang_getTranslationUnitSpelling(tu));

    client_data data = {tu, {}, clang_getNullCursor(), {}, false, filename};

    tu_cursor = clang_getTranslationUnitCursor(tu);
    clang_visitChildren(tu_cursor, visitor, &data);

    if (!clang_Cursor_isNull(data.current_struct))
        close_struct(data);

    while (!data.current_namespaces.empty()) {
        data.current_namespaces.pop_back();
        close_namespace(data);
    }

    clang_disposeTranslationUnit(tu);
    clang_disposeIndex(index);

    return 0;
}
<commit_msg>Only process structs that originate in the TU's main file.<commit_after>#include <clang-c/Index.h>
#include <cstdio>

#include <array>
#include <iostream>
#include <vector>

namespace {

    const unsigned int indent_spaces = 4;
    const std::string indentation(indent_spaces, ' ');

}

CXCursor tu_cursor;

struct client_data
{
    CXTranslationUnit tu;
    std::vector<CXCursor> current_namespaces;
    CXCursor current_struct;
    // function signature, forwarding call arguments, optional return
    // keyword, and function name
    std::vector<std::array<std::string, 4>> member_functions;
    bool printed_headers;
    const char* filename;
};

std::pair<CXToken*, unsigned int>
get_tokens (CXTranslationUnit tu, CXCursor cursor)
{
    CXSourceRange range = clang_getCursorExtent(cursor);
    CXSourceLocation start = clang_getRangeStart(range);
    CXSourceLocation end = clang_getRangeEnd(range);
    unsigned int start_offset, end_offset;

    std::pair<CXToken*, unsigned int> retval(0, 0);
    clang_tokenize(tu, range, &retval.first, &retval.second);

    return retval;
}

void
free_tokens (CXTranslationUnit tu, std::pair<CXToken*, unsigned int> tokens)
{ clang_disposeTokens(tu, tokens.first, tokens.second); }

void print_tokens (CXTranslationUnit tu, CXCursor cursor)
{
    std::pair<CXToken*, unsigned int> tokens = get_tokens(tu, cursor);

    for (unsigned int i = 0; i < tokens.second; ++i) {
        if (i)
            std::cout << " ";
        CXString spelling = clang_getTokenSpelling(tu, tokens.first[i]);
        std::cout << clang_getCString(spelling);
    }
    std::cout << "\n";

    free_tokens(tu, tokens);
}

bool struct_kind (CXCursorKind kind)
{
    switch (kind) {
    case CXCursor_ClassDecl:
    case CXCursor_StructDecl:
    case CXCursor_ClassTemplate:
    case CXCursor_ClassTemplatePartialSpecialization:
        return true;
    }
    return false;
}

std::string indent (const client_data & data)
{
    std::size_t size = data.current_namespaces.size();
    return std::string(size * indent_spaces, ' ');
}

void print_lines (const client_data & data,
                  const char** lines,
                  std::size_t num_lines)
{
    for (unsigned int i = 0; i < num_lines; ++i) {
        if (lines[i])
            std::cout << indent(data) << indentation << lines[i] << "\n";
        else
            std::cout << "\n";
    }
}

void print_headers (client_data & data)
{
    if (data.printed_headers)
        return;

    std::cout << "#include <algorithm>\n"
              << "#include <functional>\n"
              << "#include <memory>\n"
              << "#include <type_traits>\n"
              << "#include <utility>\n"
              << "\n";

    data.printed_headers = true;
}

void open_struct (const client_data & data, CXCursor struct_cursor)
{
    std::pair<CXToken*, unsigned int> tokens =
        get_tokens(data.tu, struct_cursor);

    std::cout << "\n" << indent(data);

    const std::string open_brace = "{";
    const std::string struct_ = "struct";
    const std::string class_ = "class";

    for (unsigned int i = 0; i < tokens.second; ++i) {
        CXString spelling = clang_getTokenSpelling(data.tu, tokens.first[i]);

        const char* c_str = clang_getCString(spelling);

        if (c_str == open_brace)
            break;

        if (c_str == struct_ || c_str == class_) {
            std::cout << "\n" << indent(data);
        } else if (i) {
            std::cout << " ";
        }

        std::cout << c_str;
    }

    free_tokens(data.tu, tokens);

    std::cout << "\n"
              << indent(data) << "{\n"
              << indent(data) << "public:\n";

    const char* public_interface[] = {
        0,
        "any_printable () = default;",
        0,
        "template <typename T_T__>",
        "any_printable (T_T__ value) :",
        "    handle_ (",
        "        std::make_shared<",
        "            handle<typename std::remove_reference<T_T__>::type>",
        "        >(std::forward<T_T__>(value))",
        "    )",
        "{}",
        0,
        "any_printable (any_printable && rhs) noexcept = default;",
        0,
        "template <typename T_T__>",
        "any_printable & operator= (T_T__ value)",
        "{",
        "    if (handle_.unique())",
        "        *handle_ = std::forward<T_T__>(value);",
        "    else if (!handle_)",
        "        handle_ = std::make_shared<T_T__>(std::forward<T_T__>(value));",
        "    return *this;",
        "}",
        0,
        "any_printable & operator= (any_printable && rhs) noexcept = default;"
    };

    print_lines(data,
                public_interface,
                sizeof(public_interface) / sizeof(const char*));
}

void close_struct (const client_data & data)
{
    std::cout << "\n"
              << indent(data) << "private:\n";

    const char* handle_base_preamble[] = {
        0,
        "struct handle_base",
        "{",
        "    virtual ~handle_base () {}",
        "    virtual std::shared_ptr<handle_base> close () const = 0;",
        0
    };

    print_lines(data,
                handle_base_preamble,
                sizeof(handle_base_preamble) / sizeof(const char*));

    for (auto & member : data.member_functions) {
        std::cout << indent(data) << indentation << indentation
                  << "virtual " << member[0] << " = 0;\n";
    }

    const char* handle_preamble[] = {
        0,
        "};",
        0,
        "template <typename T_T__>",
        "struct handle :",
        "    handle_base",
        "{",
        "    template <typename T_T__>",
        "    handle (T_T__ value,",
        "            typename std::enable_if<",
        "                std::is_reference<U_U__>::value",
        "            >::type* = 0) :",
        "        value_ (value)",
        "    {}",
        0,
        "    template <typename U_U__ = T_T__>",
        "    handle (T_T__ value,",
        "            typename std::enable_if<",
        "                !std::is_reference<U_U__>::value,",
        "                int",
        "            >::type* = 0) noexcept :",
        "        value_ (std::move(value))",
        "    {}",
        0,
        "    virtual std::shared_ptr<handle_base> clone () const",
        "    { return std::make_shared<handle>(value_); }"
    };

    print_lines(data,
                handle_preamble,
                sizeof(handle_preamble) / sizeof(const char*));

    for (auto & member : data.member_functions) {
        std::cout << "\n"
                  << indent(data) << indentation << indentation
                  << "virtual " << member[0] << "\n"
                  << indent(data) << indentation << indentation
                  << "{ " << member[2] << "value_." << member[3]
                  << "( " << member[1] << " ); }\n";
    }

    const char* handle_postamble[] = {
        0,
        "    T_T__ value_;",
        "};",
        0,
        "template <typename T_T__>",
        "struct handle<std::reference_wrapper<T_T__>> :",
        "    handle<T_T__ &>",
        "{",
        "    handle (std::reference_wrapper<T_T__> ref) :",
        "        handle<T_T__ &> (ref.get())",
        "    {}",
        "};",
        0,
        "const handle_base & read () const",
        "{ return *handle_; }",
        0,
        "handle_base & write ()",
        "{",
        "    if (!handle_.unique())",
        "        handle_ = handle_->clone();",
        "    return *handle_;",
        "}",
        0,
        "std::shared_ptr<handle_base> handle_;"
    };

    print_lines(data,
                handle_postamble,
                sizeof(handle_postamble) / sizeof(const char*));

    std::cout << "\n"
              << indent(data) << "};\n";
}

void print_member_function (const client_data & data, CXCursor cursor)
{
    std::cout << "\n"
              << std::string(indent_spaces, ' ') << indent(data)
              << data.member_functions.back()[0];

    std::cout << "\n" << std::string(indent_spaces, ' ') << indent(data)
              << "{ assert(handle_); " << data.member_functions.back()[2]
              << "handle_->"
              << clang_getCString(clang_getCursorSpelling(cursor))
              << "( " << data.member_functions.back()[1] << " ); }\n";
}

void open_namespace (const client_data & data, CXCursor namespace_)
{
    std::cout
        << "\n"
        << indent(data)
        << "namespace "
        << clang_getCString(clang_getCursorSpelling(namespace_))
        << " {";
}

void close_namespace (const client_data & data)
{ std::cout << "\n" << indent(data) << "}\n"; }

CXChildVisitResult
visitor (CXCursor cursor, CXCursor parent, CXClientData data_)
{
    client_data & data = *static_cast<client_data*>(data_);

    CXCursor null_cursor = clang_getNullCursor();

    // close open namespaces we have left
    CXCursor enclosing_namespace = parent;
    while (!clang_equalCursors(enclosing_namespace, tu_cursor) &&
           clang_getCursorKind(enclosing_namespace) != CXCursor_Namespace) {
        enclosing_namespace =
            clang_getCursorSemanticParent(enclosing_namespace);
    }
    if (!clang_equalCursors(enclosing_namespace, tu_cursor) &&
        clang_getCursorKind(enclosing_namespace) == CXCursor_Namespace) {
        while (!data.current_namespaces.empty() &&
               !clang_equalCursors(enclosing_namespace,
                                   data.current_namespaces.back())) {
            data.current_namespaces.pop_back();
            close_namespace(data);
        }
    }

    // close open struct if we have left it
    CXCursor enclosing_struct = parent;
    while (!clang_equalCursors(enclosing_struct, tu_cursor) &&
           !struct_kind(clang_getCursorKind(enclosing_struct))) {
        enclosing_struct = clang_getCursorSemanticParent(enclosing_struct);
    }
    if (!clang_Cursor_isNull(data.current_struct) &&
        !clang_equalCursors(enclosing_struct, data.current_struct)) {
        data.current_struct = null_cursor;
        close_struct(data);
        data.member_functions.clear();
    }

    CXSourceLocation location = clang_getCursorLocation(cursor);
    const bool from_main_file = clang_Location_isFromMainFile(location);

    CXCursorKind kind = clang_getCursorKind(cursor);
    if (kind == CXCursor_Namespace) {
        if (from_main_file) {
            print_headers(data);
            open_namespace(data, cursor);
            data.current_namespaces.push_back(cursor);
        }
        return CXChildVisit_Recurse;
    } else if (!from_main_file) {
        return CXChildVisit_Continue;
    } else if (struct_kind(kind)) {
        if (clang_Cursor_isNull(data.current_struct)) {
            print_headers(data);
            data.current_struct = cursor;
            open_struct(data, cursor);
            return CXChildVisit_Recurse;
        }
    } else if (kind == CXCursor_CXXMethod) {
        std::pair<CXToken*, unsigned int> tokens = get_tokens(data.tu, cursor);

        const std::string open_brace = "{";
        const std::string semicolon = ";";

        std::string str;

        for (unsigned int i = 0; i < tokens.second; ++i) {
            CXString spelling =
                clang_getTokenSpelling(data.tu, tokens.first[i]);

            const char* c_str = clang_getCString(spelling);

            if (c_str == open_brace || c_str == semicolon)
                break;

            if (i)
                str += " ";

            str += c_str;
        }

        std::string args;

        const int num_args = clang_Cursor_getNumArguments(cursor);
        for (int i = 0; i < num_args; ++i) {
            if (i)
                args += ", ";
            CXCursor arg_cursor = clang_Cursor_getArgument(cursor, i);
            args += clang_getCString(clang_getCursorSpelling(arg_cursor));
        }

        const char* return_str =
            clang_getCursorResultType(cursor).kind == CXType_Void ?
            "" :
            "return ";

        const char* function_name =
            clang_getCString(clang_getCursorSpelling(cursor));

        free_tokens(data.tu, tokens);

        data.member_functions.push_back({str, args, return_str, function_name});

        print_member_function(data, cursor);
    }

    return CXChildVisit_Continue;
}

int main (int argc, char* argv[])
{
    CXIndex index = clang_createIndex(0, 1);
    CXTranslationUnit tu = clang_parseTranslationUnit(
        index,
        0,
        argv,
        argc,
        0,
        0,
        CXTranslationUnit_DetailedPreprocessingRecord
    );

    const char* filename =
        clang_getCString(clang_getTranslationUnitSpelling(tu));

    client_data data = {tu, {}, clang_getNullCursor(), {}, false, filename};

    tu_cursor = clang_getTranslationUnitCursor(tu);
    clang_visitChildren(tu_cursor, visitor, &data);

    if (!clang_Cursor_isNull(data.current_struct))
        close_struct(data);

    while (!data.current_namespaces.empty()) {
        data.current_namespaces.pop_back();
        close_namespace(data);
    }

    clang_disposeTranslationUnit(tu);
    clang_disposeIndex(index);

    return 0;
}
<|endoftext|>