浏览代码

[Refs #23][add] comparing two arrays is working. Next step is recursive !

isundil 9 年之前
父节点
当前提交
508bda8797
共有 3 个文件被更改,包括 67 次插入13 次删除
  1. 3 1
      include/curseSplitOutput.hh
  2. 8 8
      include/levenshtein.hpp
  3. 56 4
      src/curseSplitOutput.cpp

+ 3 - 1
include/curseSplitOutput.hh

@@ -69,6 +69,8 @@ class CurseSplitOutput: public CurseOutput
         inputResult nextResult();
         inputResult changeWindow(char, bool);
 
+        void computeDiff();
+
         std::deque<std::string> fileNames;
         std::deque<JSonElement *> roots;
         std::deque<const JSonElement *> selection, select_up, select_down;
@@ -78,7 +80,7 @@ class CurseSplitOutput: public CurseOutput
          * currently searching pattern and its results
         **/
         std::deque<std::list<const JSonElement*> > search_result;
-        std::list<ePath> diffResult;
+        std::map<const JSonElement *, ePath> diffResult;
 
         /**
          * Viewport start

+ 8 - 8
include/levenshtein.hpp

@@ -7,6 +7,14 @@
 
 #define LEVENSHTEIN_SENSIBILITY (0.7f)
 
+enum ePath: char
+{
+    add = '+',
+    rem = '-',
+    mod = '!',
+    equ = '='
+};
+
 float levenshteinPercent(const std::string &a, const std::string &b);
 template<class T> float levenshteinPercent(const std::list<T *> *a, const std::list<T *> *b);
 bool levenshteinStrictCompare(const char &a, const char &b);
@@ -79,14 +87,6 @@ template<class T> float levenshteinPercent(const std::list<T *> *a, const std::l
     return _levenshteinPercent<unsigned int, typename std::list<T *>::const_iterator, T *>(aBegin, aEnd, bBegin, bEnd, lenA, lenB);
 }
 
-enum ePath: char
-{
-    add = '+',
-    rem = '-',
-    mod = '!',
-    equ = '='
-};
-
 template<typename SIZE, class ITERATOR, class SUBTYPE>
 static size_t _levenshteinShortestPath(std::list<ePath> &result, ITERATOR aBegin, ITERATOR aEnd, ITERATOR bBegin, ITERATOR bEnd, size_t lenA, size_t lenB)
 {

+ 56 - 4
src/curseSplitOutput.cpp

@@ -27,10 +27,6 @@ CurseSplitOutput::~CurseSplitOutput()
 
 void CurseSplitOutput::run(const std::deque<std::string> &inputName, const std::deque<JSonElement*> &roots)
 {
-    const JSonArray *a = (const JSonArray*)roots.at(0);
-    const JSonArray *b = (const JSonArray*)roots.at(1);
-
-    levenshteinShortestPath<JSonElement>(diffResult, a, b); // FIXME Will fail if 3 inputs
 
     nbInputs = inputName.size();
     selectedWin = 0;
@@ -50,6 +46,7 @@ void CurseSplitOutput::run(const std::deque<std::string> &inputName, const std::
         search_result.push_back(std::list<const JSonElement *>());
     }
     fileNames = inputName;
+    computeDiff();
     loop();
 }
 
@@ -70,6 +67,50 @@ void CurseSplitOutput::loop()
     }
 }
 
+// FIXME Will fail if 3 inputs
+void CurseSplitOutput::computeDiff()
+{
+    const JSonContainer *a = dynamic_cast<const JSonContainer*>(roots.at(0));
+    const JSonContainer *b = dynamic_cast<const JSonContainer*>(roots.at(1));
+
+    if (!a && !b)
+    {
+        //TODO diff primitives
+    }
+    else if (!a)
+    {
+    }
+    else if (!b)
+    {
+    }
+    else
+    {
+        std::list<ePath> diffList;
+        levenshteinShortestPath<JSonElement>(diffList, a, b);
+
+        JSonContainer::const_iterator it = a->cbegin();
+        for (ePath i : diffList)
+            if (it != a->cend() &&
+                    (i == ePath::equ ||
+                    i == ePath::mod ||
+                    i == ePath::add))
+            {
+                diffResult[*it] = i;
+                it++;
+            }
+        it = b->cbegin();
+        for (ePath i : diffList)
+            if (it != b->cend() &&
+                    (i == ePath::equ ||
+                    i == ePath::mod ||
+                    i == ePath::rem))
+            {
+                diffResult[*it] = i == ePath::rem ? ePath::add : i;
+                it++;
+            }
+    }
+}
+
 inputResult CurseSplitOutput::selectUp()
 {
     selection[selectedWin] = select_up[selectedWin];
@@ -622,6 +663,16 @@ const OutputFlag CurseSplitOutput::getFlag(const JSonElement *item, const JSonEl
 
     res.selected(item == selection);
     res.searched(std::find(search_result[selectedWin].cbegin(), search_result[selectedWin].cend(), item) != search_result[selectedWin].cend());
+
+    try {
+        ePath dr = diffResult.at(item);
+        if (dr == ePath::add)
+            res.type(OutputFlag::TYPE_STRING);
+        else if (dr == ePath::mod)
+            res.type(OutputFlag::TYPE_NUMBER);
+    }
+    catch (std::out_of_range &e) {}
+    /*
     if (dynamic_cast<const JSonPrimitive<std::string> *>(i))
         res.type(OutputFlag::TYPE_STRING);
     else if (dynamic_cast<const JSonPrimitive<bool> *>(i))
@@ -634,6 +685,7 @@ const OutputFlag CurseSplitOutput::getFlag(const JSonElement *item, const JSonEl
         res.type(OutputFlag::TYPE_OBJ);
     else if (dynamic_cast<const JSonArray*>(i))
         res.type(OutputFlag::TYPE_ARR);
+    */
     return res;
 }