--- /dev/null
+#include "muscle.h"\r
+#include "pwpath.h"\r
+\r
+#define TRACE 0\r
+\r
+static char XlatEdgeType(char c)\r
+ {\r
+ if ('E' == c)\r
+ return 'D';\r
+ if ('J' == c)\r
+ return 'I';\r
+ return c;\r
+ }\r
+\r
+static const char *BitsToStr(char Bits)\r
+ {\r
+ static char Str[] = "xM xD xI";\r
+\r
+ switch (Bits & BIT_xM)\r
+ {\r
+ case BIT_MM:\r
+ Str[0] = 'M';\r
+ break;\r
+ case BIT_DM:\r
+ Str[0] = 'D';\r
+ break;\r
+ case BIT_IM:\r
+ Str[0] = 'I';\r
+ break;\r
+ }\r
+\r
+ switch (Bits & BIT_xD)\r
+ {\r
+ case BIT_MD:\r
+ Str[3] = 'M';\r
+ break;\r
+ case BIT_DD:\r
+ Str[3] = 'D';\r
+ break;\r
+ }\r
+\r
+ switch (Bits & BIT_xI)\r
+ {\r
+ case BIT_MI:\r
+ Str[6] = 'M';\r
+ break;\r
+ case BIT_II:\r
+ Str[6] = 'I';\r
+ break;\r
+ }\r
+\r
+ return Str;\r
+ }\r
+\r
+static inline char XChar(char Bits, char cType)\r
+ {\r
+ switch (cType)\r
+ {\r
+ case 'M':\r
+ {\r
+ switch (Bits & BIT_xM)\r
+ {\r
+ case BIT_MM:\r
+ return 'M';\r
+ case BIT_DM:\r
+ return 'D';\r
+ case BIT_IM:\r
+ return 'I';\r
+#if DOUBLE_AFFINE\r
+ case BIT_EM:\r
+ return 'E';\r
+ case BIT_JM:\r
+ return 'J';\r
+#endif\r
+ }\r
+ Quit("Huh!?");\r
+ return '?';\r
+ }\r
+ case 'D':\r
+ {\r
+ switch (Bits & BIT_xD)\r
+ {\r
+ case BIT_MD:\r
+ return 'M';\r
+ case BIT_DD:\r
+ return 'D';\r
+ }\r
+ Quit("Huh!?");\r
+ return '?';\r
+ }\r
+ case 'I':\r
+ {\r
+ switch (Bits & BIT_xI)\r
+ {\r
+ case BIT_MI:\r
+ return 'M';\r
+ case BIT_II:\r
+ return 'I';\r
+ }\r
+ Quit("Huh!?");\r
+ return '?';\r
+ }\r
+#if DOUBLE_AFFINE\r
+ case 'E':\r
+ {\r
+ switch (Bits & BIT_xE)\r
+ {\r
+ case BIT_ME:\r
+ return 'M';\r
+ case BIT_EE:\r
+ return 'E';\r
+ }\r
+ Quit("Huh!?");\r
+ return '?';\r
+ }\r
+ case 'J':\r
+ {\r
+ switch (Bits & BIT_xJ)\r
+ {\r
+ case BIT_MJ:\r
+ return 'M';\r
+ case BIT_JJ:\r
+ return 'J';\r
+ }\r
+ Quit("Huh!?");\r
+ return '?';\r
+ }\r
+#endif\r
+ default:\r
+ Quit("Huh?");\r
+ return '?';\r
+ }\r
+ }\r
+\r
+void BitTraceBack(char **TraceBack, unsigned uLengthA, unsigned uLengthB,\r
+ char LastEdge, PWPath &Path)\r
+ {\r
+#if TRACE\r
+ Log("BitTraceBack\n");\r
+#endif\r
+ Path.Clear();\r
+\r
+ PWEdge Edge;\r
+ Edge.uPrefixLengthA = uLengthA;\r
+ Edge.uPrefixLengthB = uLengthB;\r
+ char Bits = TraceBack[uLengthA][uLengthB];\r
+ Edge.cType = LastEdge;\r
+ for (;;)\r
+ {\r
+#if TRACE\r
+ Log("Prepend %c%d.%d\n", Edge.cType, Edge.uPrefixLengthA, Edge.uPrefixLengthB);\r
+#endif\r
+ char cSave = Edge.cType;\r
+ Edge.cType = XlatEdgeType(cSave);\r
+ Path.PrependEdge(Edge);\r
+ Edge.cType = cSave;\r
+\r
+ unsigned PLA = Edge.uPrefixLengthA;\r
+ unsigned PLB = Edge.uPrefixLengthB;\r
+ char Bits = TraceBack[PLA][PLB];\r
+ char NextEdgeType = XChar(Bits, Edge.cType);\r
+#if TRACE\r
+ Log("XChar(%s, %c) = %c\n", BitsToStr(Bits), Edge.cType, NextEdgeType);\r
+#endif\r
+ switch (Edge.cType)\r
+ {\r
+ case 'M':\r
+ {\r
+ if (Edge.uPrefixLengthA == 0)\r
+ Quit("BitTraceBack MA=0");\r
+ if (Edge.uPrefixLengthB == 0)\r
+ Quit("BitTraceBack MA=0");\r
+ --(Edge.uPrefixLengthA);\r
+ --(Edge.uPrefixLengthB);\r
+ break;\r
+ }\r
+ case 'D':\r
+ case 'E':\r
+ {\r
+ if (Edge.uPrefixLengthA == 0)\r
+ Quit("BitTraceBack DA=0");\r
+ --(Edge.uPrefixLengthA);\r
+ break;\r
+ }\r
+ case 'I':\r
+ case 'J':\r
+ {\r
+ if (Edge.uPrefixLengthB == 0)\r
+ Quit("BitTraceBack IB=0");\r
+ --(Edge.uPrefixLengthB);\r
+ break;\r
+ }\r
+ default:\r
+ Quit("BitTraceBack: Invalid edge %c", Edge);\r
+ }\r
+\r
+ if (0 == Edge.uPrefixLengthA && 0 == Edge.uPrefixLengthB)\r
+ break;\r
+\r
+ Edge.cType = NextEdgeType;\r
+ }\r
+\r
+#if TRACE\r
+ Path.LogMe();\r
+#endif\r
+ }\r