#
#
# add_file "asciik.cc"
# content [15bbf1e5ab445db62490e945beb160c0d3f2cf51]
#
# set "asciik.cc"
# attr "mtn:execute"
# value "true"
#
============================================================
--- asciik.cc 15bbf1e5ab445db62490e945beb160c0d3f2cf51
+++ asciik.cc 15bbf1e5ab445db62490e945beb160c0d3f2cf51
@@ -0,0 +1,201 @@
+// Copyright (C) 2007 Lapo Luchini
+// Copyright (C) 2007 Gabriele Dini Ciacci
+//
+// This program is made available under the GNU GPL version 2.0 or
+// greater. See the accompanying file COPYING for details.
+//
+// This program is distributed WITHOUT ANY WARRANTY; without even the
+// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE.
+
+#include
+#include
+#include
+#include
+#include
+
+#include "cmd.hh"
+#include "revision.hh"
+
+using std::cout;
+using std::pair;
+using std::set;
+using std::vector;
+using std::ostream_iterator;
+
+//namespace asciik { }
+
+/**
+ * Prints an ASCII-k chunk using the given revisions.
+ */
+//void asciik::print(set ids) {
+// database::get_revision_parents(revision_id const & id, set & parents)
+// for (iterator id = ids.begin(); id != ids.end(); ++id)
+// os << "Work on: " << id << "\n";
+//}
+
+static revision_id ghost; // valid but empty revision_id to be used as ghost value
+
+CMD(asciik, N_("tree"), N_("SELECTOR"),
+ N_("prints ASCII-art tree representation"), options::opts::none)
+{
+ N(args.size() == 1,
+ F("wrong argument count"));
+
+ vector >
+ sels(selectors::parse_selector(args[0](), app));
+
+ // we jam through an "empty" selection on sel_ident type
+ set completions;
+ //set> completions;
+ selectors::selector_type ty = selectors::sel_ident;
+ selectors::complete_selector("", sels, ty, completions, app);
+
+ set revs;
+ for (set::const_iterator i = completions.begin();
+ i != completions.end(); ++i)
+ {
+ revision_id rid(*i);
+ revs.insert(rid);
+ }
+ vector sorted;
+ toposort(revs, sorted, app);
+ vector curr_row;
+ reverse(sorted.begin(), sorted.end()); //TODO: faster to use a reverse_iterator I guess, but that seems to give some problems
+ for (vector::const_iterator rev = sorted.begin();
+ rev != sorted.end(); ++rev)
+//* for (vector::const_reverse_iterator rev = sorted.rbegin();
+//* rev != sorted.rend(); ++rev)
+ {
+ // print row
+
+//p if curr_rev not in curr_row:
+//p curr_row.append(curr_rev)
+ if (find(curr_row.begin(), curr_row.end(), *rev) == curr_row.end())
+ curr_row.push_back(*rev);
+
+//p curr_loc = curr_row.index(curr_rev)
+ //iterator_traits::iterator>::difference_type
+ int curr_loc = distance(curr_row.begin(),
+ find(curr_row.begin(), curr_row.end(), *rev));
+ //assert(curr_loc < size()); as it is surely found
+
+//p new_revs = []
+//p for p in parents:
+//p if p not in curr_row:
+//p new_revs.append(p)
+ set parents;
+ app.db.get_revision_parents(*rev, parents);
+
+ set new_revs;
+ for (set::const_iterator parent = parents.begin();
+ parent != parents.end(); )
+ if (find(curr_row.begin(), curr_row.end(), *parent) == curr_row.end())
+ new_revs.insert(*parent);
+//#2 set new_revs;
+//#2 app.db.get_revision_parents(*rev, new_revs);
+//#2 for (set::const_iterator parent = new_revs.begin();
+//#2 parent != new_revs.end(); )
+//#2 if (find(curr_row.begin(), curr_row.end(), *parent) != curr_row.end())
+//#2 new_revs.erase(parent++);
+//#2 else
+//#2 ++parent;
+
+//p next_row = list(curr_row)
+//p next_row[curr_loc:curr_loc + 1] = new_revs
+ vector next_row(curr_row);
+ next_row.insert(
+ next_row.erase(next_row.begin() + curr_loc),
+ new_revs.begin(), new_revs.end());
+
+ //TODO:remove test print
+ cout << "curr_row: ";
+ copy(curr_row.begin(), curr_row.end(), ostream_iterator(cout, " "));
+ cout << "\nnext_row: ";
+ copy(next_row.begin(), next_row.end(), ostream_iterator(cout, " "));
+ cout << "\n";
+
+//p # now next_row contains exactly the revisions it needs to, except that no
+//p # ghost handling has been done.
+
+//p no_ghost = without_a_ghost(next_row)
+ vector no_ghost(curr_row);
+ vector::iterator i_ghost = find(no_ghost.begin(),
+ no_ghost.end(), ghost);
+ if (i_ghost != no_ghost.end())
+ no_ghost.erase(i_ghost);
+//p
+//p if try_draw(curr_row, no_ghost, curr_loc, parents):
+//p return no_ghost
+//p if try_draw(curr_row, next_row, curr_loc, parents):
+//p return next_row
+//p if not new_revs: # this line has disappeared
+//p extra_ghost = with_a_ghost_added(next_row, curr_loc)
+//p if try_draw(curr_row, extra_ghost, curr_loc, parents):
+//p return extra_ghost
+//p assert False
+ }
+}
+
+bool try_draw(const vector curr_row,
+ const vector next_row, int curr_loc, set parents)
+{
+//p curr_items = len(curr_row)
+//p next_items = len(next_row)
+ size_t curr_items = curr_row.size();
+ size_t next_items = next_row.size();
+
+//p curr_ghosts = []
+//p for i in xrange(curr_items):
+//p if curr_row[i] is None:
+//p curr_ghosts.append(i)
+ vector curr_ghosts;
+ for (size_t i = 0; i < curr_items; ++i)
+ if (curr_row[i] == ghost)
+ curr_ghosts.insert(i);
+
+//p preservation_links = []
+//p have_shift = False
+ vector > preservation_links;
+ bool have_shift = false;
+
+//p for rev in curr_row:
+//p if rev is not None and rev in next_row:
+//p i = curr_row.index(rev)
+//p j = next_row.index(rev)
+//p if i != j:
+//p have_shift = True
+//p if abs(i - j) > 1:
+//p return False
+//p preservation_links.append((i, j))
+ for (size_t i = 0; i < curr_items; ++i) {
+ if (idx(curr_row, i) != ghost) {
+ int j = distance(next_row.begin(), find(next_row.begin(), next_row.end(), curr_row[i]));
+ if (j < news_row.size()) {
+ int d = abs(i - j);
+ if (d > 1)
+ return false;
+ if (d != 0)
+ have_shift = true;
+ preservation_links.insert(pair(i, j));
+ }
+ }
+ }
+
+//p parent_links = []
+//p for p in parents:
+//p i = curr_loc
+//p j = next_row.index(p)
+//p if abs(i - j) > 1 and have_shift:
+//p return False
+//p parent_links.append((i, j))
+//p
+//p preservation_crosses = links_cross(preservation_links)
+//p parent_crosses = links_cross(parent_links)
+//p if preservation_crosses.intersection(parent_crosses):
+//p return False
+//p
+//p links = preservation_links + parent_links
+//p draw(curr_items, next_items, curr_loc, links, curr_ghosts, curr_row[curr_loc])
+//p return True
+}