+// Pass input file through the chain until we bump into a Join node or
+// a node that says that it is the last.
+const Tool* CompilationGraph::PassThroughGraph (sys::Path& In,
+ sys::Path Out,
+ const sys::Path& TempDir,
+ PathVector& JoinList) const {
+ bool Last = false;
+ const Tool* ret = 0;
+
+ // Get to the head of the toolchain.
+ const tools_vector_type& TV = getToolsVector(getLanguage(In));
+ if (TV.empty())
+ throw std::runtime_error("Tool names vector is empty!");
+ const Node* N = &getNode(*TV.begin());
+
+ while(!Last) {
+ const Tool* CurTool = N->ToolPtr.getPtr();
+
+ if (CurTool->IsJoin()) {
+ JoinList.push_back(In);
+ ret = CurTool;
+ break;
+ }
+
+ // Is this the last tool?
+ if (!N->HasChildren() || CurTool->IsLast()) {
+ // Check if the first tool is also the last
+ if (Out.empty())
+ Out.set(In.getBasename());
+ else
+ Out.appendComponent(In.getBasename());
+ Out.appendSuffix(CurTool->OutputSuffix());
+ Last = true;
+ }
+ else {
+ Out = TempDir;
+ Out.appendComponent(In.getBasename());
+ Out.appendSuffix(CurTool->OutputSuffix());
+ Out.makeUnique(true, NULL);
+ Out.eraseFromDisk();
+ }
+
+ if (CurTool->GenerateAction(In, Out).Execute() != 0)
+ throw std::runtime_error("Tool returned error code!");
+
+ N = &getNode(N->ChooseEdge()->ToolName());
+ In = Out; Out.clear();
+ }
+
+ return ret;
+}
+