# # # patch "asciik.cc" # from [d645bb9564d3b4fcfbf1b1e2656d40f40be9edfe] # to [3efb8a95adbaea90cf6eae94c5219395b63aedf3] # ============================================================ --- asciik.cc d645bb9564d3b4fcfbf1b1e2656d40f40be9edfe +++ asciik.cc 3efb8a95adbaea90cf6eae94c5219395b63aedf3 @@ -139,102 +139,6 @@ static revision_id ghost; // valid but e 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; -//* for (vector::const_reverse_iterator rev = sorted.rbegin(); -//* rev != sorted.rend(); ++rev) - 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) - { - // print row - std::cerr << "asciik: foreach sorted\n"; - -//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 - size_t curr_loc = distance(curr_row.begin(), - find(curr_row.begin(), curr_row.end(), *rev)); - //assert(curr_loc < size()); as it is surely found - - std::cerr << "asciik: parents\n"; - set parents; - app.db.get_revision_parents(*rev, parents); -//p new_revs = [] -//p for p in parents: -//p if p not in curr_row: -//p new_revs.append(p) - std::cerr << "asciik: foreach parent\n"; - set new_revs; - for (set::const_iterator parent = parents.begin(); - parent != parents.end(); ++parent) - if (find(curr_row.begin(), curr_row.end(), *parent) == curr_row.end()) - new_revs.insert(*parent); - -//p next_row = list(curr_row) -//p next_row[curr_loc:curr_loc + 1] = new_revs - std::cerr << "asciik: next row\n"; - 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 - } -} - //p def links_cross(links): //p crosses = set() //p for i, j in links: @@ -259,6 +163,7 @@ void draw(const size_t curr_items, const const size_t curr_loc, const set > & links, const set & curr_ghosts, const string & annotation) { + std::cerr << "actual draw\n"; //p line = [" "] * (curr_items * 2 - 1) //p interline = [" "] * (max(curr_items, next_items) * 2 - 1) string line(curr_items * 2 - 1, ' '); @@ -267,16 +172,19 @@ void draw(const size_t curr_items, const //p # first draw the flow-through bars in the line //p for i in xrange(curr_items): //p line[i * 2] = "|" + std::cerr << "some |\n"; for (size_t i = 0; i < curr_items; ++i) line[i * 2] = '|'; //p # but then erase it for ghosts //p for i in curr_ghosts: //p line[i * 2] = " " + std::cerr << "some space\n"; for (set::const_iterator i = curr_ghosts.begin(); i != curr_ghosts.end(); ++i) line[(*i) * 2] = ' '; + std::cerr << "dots\n"; //p # then the links //p dots = set() set dots; @@ -287,10 +195,12 @@ void draw(const size_t curr_items, const size_t i = link->first, j = link->second, start, end, dot; //p if i == j: //p interline[2 * i] = "|" + std::cerr << "foreach link (" << i << ", " << j << ")\n"; if (i == j) interline[2 * i] = '|'; //p else: - else if (j < i) { + else { + if (j < i) { //p if j < i: //p # | .---o //p # |/| | | @@ -302,11 +212,11 @@ void draw(const size_t curr_items, const //p end = 2*i //p dot = start - 1 //p interline[dot - 1] = "/" - start = 2 * j + 3; - end = 2 * i; - dot = start - 1; - interline[dot - 1] = '/'; - } else { + start = 2 * j + 3; + end = 2 * i; + dot = start - 1; + interline[dot - 1] = '/'; + } else { //p else: # i < j //p # o---. //p # | | |\| @@ -318,18 +228,20 @@ void draw(const size_t curr_items, const //p end = 2*j - 2 //p dot = end //p interline[dot + 1] = "\\" - start = 2 * i + 1; - end = 2 * j - 2; - dot = end; - interline[dot + 1] = '\\'; - } + start = 2 * i + 1; + end = 2 * j - 2; + dot = end; + interline[dot + 1] = '\\'; + } //p if end - start >= 1: //p dots.add(dot) //p line[start:end] = "-" * (end - start) - if ((end - start) > 0) - dots.insert(dot); - for (size_t l = start; l < end; ++l) - line[l] = '-'; + if ((end - start) > 0) + dots.insert(dot); + std::cerr << "for with some -\n"; + for (size_t l = start; l < end; ++l) + line[l] = '-'; + } } //p # add any dots (must do this in a second pass, so that if there are //p # cases like: @@ -355,6 +267,7 @@ bool try_draw(const vector const vector & next_row, const size_t curr_loc, const set & parents) { + std::cerr << "try draw\n"; //p curr_items = len(curr_row) //p next_items = len(next_row) size_t curr_items = curr_row.size(); @@ -364,6 +277,7 @@ bool try_draw(const vector //p for i in xrange(curr_items): //p if curr_row[i] is None: //p curr_ghosts.append(i) + std::cerr << "ghosts\n"; set curr_ghosts; for (size_t i = 0; i < curr_items; ++i) if (idx(curr_row, i) == ghost) @@ -380,6 +294,7 @@ bool try_draw(const vector //p if abs(i - j) > 1: //p return False //p preservation_links.append((i, j)) + std::cerr << "pres links\n"; set > preservation_links; bool have_shift = false; for (size_t i = 0; i < curr_items; ++i) { @@ -405,9 +320,10 @@ bool try_draw(const vector //p if abs(i - j) > 1 and have_shift: //p return False //p parent_links.append((i, j)) + std::cerr << "par links\n"; set > parent_links; for (set::const_iterator p = parents.begin(); - p != parents.end(); ) + p != parents.end(); ++p) { size_t i = curr_loc; size_t j = distance(next_row.begin(), @@ -422,6 +338,7 @@ bool try_draw(const vector //p parent_crosses = links_cross(parent_links) //p if preservation_crosses.intersection(parent_crosses): //p return False + std::cerr << "crosses\n"; set preservation_crosses, parent_crosses, intersection_crosses; links_cross(preservation_links, preservation_crosses); links_cross(parent_links, parent_crosses); @@ -443,3 +360,111 @@ bool try_draw(const vector //p return True return true; } + +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; +//* for (vector::const_reverse_iterator rev = sorted.rbegin(); +//* rev != sorted.rend(); ++rev) + 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) + { + // print row + std::cerr << "asciik: foreach sorted\n"; + +//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 + size_t curr_loc = distance(curr_row.begin(), + find(curr_row.begin(), curr_row.end(), *rev)); + //assert(curr_loc < size()); as it is surely found + + std::cerr << "asciik: parents\n"; + set parents; + app.db.get_revision_parents(*rev, parents); +//p new_revs = [] +//p for p in parents: +//p if p not in curr_row: +//p new_revs.append(p) + std::cerr << "asciik: foreach parent\n"; + set new_revs; + for (set::const_iterator parent = parents.begin(); + parent != parents.end(); ++parent) + if (find(curr_row.begin(), curr_row.end(), *parent) == curr_row.end()) + new_revs.insert(*parent); + +//p next_row = list(curr_row) +//p next_row[curr_loc:curr_loc + 1] = new_revs + std::cerr << "asciik: next row\n"; + 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 + std::cerr << "curr_row: "; + copy(curr_row.begin(), curr_row.end(), ostream_iterator(std::cerr, " ")); + std::cerr << "\nnext_row: "; + copy(next_row.begin(), next_row.end(), ostream_iterator(std::cerr, " ")); + std::cerr << "\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); + + std::cerr << "asciik: try draw\n"; +//p if try_draw(curr_row, no_ghost, curr_loc, parents): +//p return no_ghost + if (try_draw(curr_row, no_ghost, curr_loc, parents)) + curr_row = no_ghost; +//p if try_draw(curr_row, next_row, curr_loc, parents): +//p return next_row + else if (try_draw(curr_row, next_row, curr_loc, parents)) + curr_row = 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 + else if (new_revs.size() == 0) { + vector extra_ghost(next_row); + extra_ghost.insert(curr_row.begin() + curr_loc, ghost); + if (!try_draw(curr_row, extra_ghost, curr_loc, parents)) + I(false); + curr_row = extra_ghost; + } + } +}