aboutsummaryrefslogtreecommitdiffstats
path: root/3rdparty/python-console/ColumnFormatter.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/python-console/ColumnFormatter.cpp')
-rw-r--r--3rdparty/python-console/ColumnFormatter.cpp141
1 files changed, 141 insertions, 0 deletions
diff --git a/3rdparty/python-console/ColumnFormatter.cpp b/3rdparty/python-console/ColumnFormatter.cpp
new file mode 100644
index 00000000..adbda96a
--- /dev/null
+++ b/3rdparty/python-console/ColumnFormatter.cpp
@@ -0,0 +1,141 @@
+/**
+Copyright (c) 2014 Alex Tsui
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), 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.
+*/
+#include "ColumnFormatter.h"
+#include <iomanip>
+#include <iostream>
+#include <list>
+#include <string>
+#include <sstream>
+#include <fstream>
+#include <vector>
+#include <cstdlib>
+
+bool ColumnFormatter::load(const std::string& fn)
+{
+ items.clear();
+ std::ifstream ifs(fn.c_str());
+ if (!ifs.is_open())
+ return false;
+ std::string str;
+ while (!ifs.eof())
+ {
+ std::getline( ifs, str );
+ if (!ifs.eof())
+ items.push_back(str);
+ }
+ return true;
+}
+
+int ColumnFormatter::solve(int width)
+{
+ bool fits = true;
+ int i = 1;
+ while (fits)
+ {
+ ++i;
+ std::vector<int> widths = divideItems(i);
+ int columnWidth = width / i;
+ for (int j = 0; j < widths.size(); ++j)
+ {
+ fits &= (widths[j] < columnWidth);
+ }
+ if (!fits)
+ {
+ --i;
+ }
+ }
+ return i;
+}
+
+std::vector<int> ColumnFormatter::divideItems(int numColumns)
+{
+ columns.clear();
+ for (int i = 0; i < numColumns; ++i)
+ columns.push_back(std::list<std::string>());
+ for (int i = 0; i < items.size(); ++i)
+ {
+ columns[i % numColumns].push_back(items[i]);
+ }
+
+ // count the fattest item in each column
+ std::vector<int> res(numColumns);
+ for (int i = 0; i < numColumns; ++i)
+ {
+ for (std::list<std::string>::const_iterator it =
+ columns[i].begin(); it != columns[i].end(); ++it)
+ {
+ if (res[i] < it->size())
+ res[i] = it->size();
+ }
+ }
+
+ return res;
+}
+
+void ColumnFormatter::format(int width)
+{
+ m_formattedOutput.clear();
+ int cols = solve(width);
+ std::vector<int> colWidths(cols, width / cols);
+ int rem = width % cols;
+ for (int i = 0; i < rem; ++i)
+ {
+ colWidths[i]++;
+ }
+ divideItems(cols);
+ std::vector< std::list<std::string>::const_iterator > its;
+ std::vector< std::list<std::string>::const_iterator > it_ends;
+ for (int i = 0; i < columns.size(); ++i)
+ {
+ its.push_back(columns[i].begin());
+ it_ends.push_back(columns[i].end());
+ }
+ bool done = false;
+ while (!done)
+ {
+ std::stringstream row_ss;
+ for (int i = 0; i < columns.size(); ++i)
+ {
+ std::stringstream item_ss;
+ std::string item;
+ if (its[i] != it_ends[i])
+ {
+ item = *its[i];
+ ++its[i];
+ }
+ item_ss << std::left << std::setw(colWidths[i]) << item;
+ row_ss << item_ss.str();
+ }
+ m_formattedOutput.push_back(row_ss.str());
+
+ done = true;
+ for (int i = 0; i < columns.size(); ++i)
+ {
+ done &= (its[i] == it_ends[i]);
+ }
+ }
+}
+
+const std::list<std::string>& ColumnFormatter::formattedOutput() const
+{
+ return m_formattedOutput;
+}