/*========================================================================= Library: CTK Copyright (c) Kitware Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.txt Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =========================================================================*/ // CTK includes #include // STD includes #include #include #include #include #include #include #include #include using namespace std; //---------------------------------------------------------------------------- std::string help(const std::string& progName) { std::string msg = std::string("Usage: ") + progName + std::string(" [-paths Label | -sort Label]"); return msg; } //---------------------------------------------------------------------------- void displayError(const std::string& progName, const std::string& msg) { std::cerr << progName << std::endl << msg << std::endl << help(progName) << std::endl; } std::vector< std::string > splitString(const std::string& string) { std::vector results; std::stringstream stringStream; stringStream << string; do { std::string nextString; stringStream >> nextString; size_t found = nextString.find_first_not_of(" "); if (found != string::npos) { results.push_back(nextString.substr(found)); } } while (!stringStream.eof()); return results; } std::string listToString(const std::list& list) { std::stringstream stream; if (list.size() == 0) { stream << "empty"; } else { unsigned int counter = 0; std::list::const_iterator iterator; for (iterator = list.begin(); iterator != list.end(); iterator++) { stream << *iterator; counter++; if (counter != list.size()) { stream << " "; } } } return stream.str(); } int getLastElement(const std::list& list) { int result = -1; if (list.size() > 0) { std::list::const_reverse_iterator iterator; iterator = list.rend(); result = *iterator; } return result; } //---------------------------------------------------------------------------- int getOrGenerateId(std::map& vertexIdToLabel, std::map& vertexLabelToId, const std::string& label) { // If needed, generate vertex id int vertexId = -1; if (vertexLabelToId.find(label) == vertexLabelToId.end()) { vertexId = vertexLabelToId.size() + 1; vertexLabelToId[label] = vertexId; vertexIdToLabel[vertexId] = label; } else { vertexId = vertexLabelToId[label]; } return vertexId; } //---------------------------------------------------------------------------- int main(int argc, char** argv) { bool verbose = false; bool outputTopologicalOrder = true; // a graph file is expected if (argc < 2) { displayError(argv[0], std::string("Missing one argument")); return EXIT_FAILURE; } bool outputPath = false; bool outputSort = false; std::string label; if (argc == 3) { displayError(argv[0], std::string("Wrong argument")); return EXIT_FAILURE; } if (argc == 4) { std::string arg2 = std::string(argv[2]); if (arg2.compare("-paths")!=0 && arg2.compare("-sort")!=0) { displayError(argv[0], std::string("Wrong argument: ") + arg2); return EXIT_FAILURE; } label = std::string(argv[3]); outputTopologicalOrder = false; if (arg2.compare("-paths") == 0) { outputPath = true; } else { outputSort = true; } if (verbose) { std::cout << "label:" << label << std::endl; } } // Open File. std::string filepath = std::string(argv[1]); if (verbose) { std::cout << "filename:" << filepath << std::endl; } std::ifstream data; data.open(filepath.c_str(), ifstream::in); if (!data.is_open()) { displayError(argv[0], std::string("Failed to open file '") + filepath + "' !"); return EXIT_FAILURE; } // Read first line, called the header. std::string header; std::getline (data, header); if (verbose) { std::cout << "header:" << header << std::endl; } if (header.length() == 0) { displayError(argv[0], std::string("Failed to read Header line in file '") + filepath + "' !"); return EXIT_FAILURE; } // Extract two integers int numberOfVertices = -1; int numberOfEdges = -1; std::stringstream stringStream; stringStream << header; stringStream >> numberOfVertices; stringStream >> numberOfEdges; if (numberOfVertices == -1 || numberOfEdges == -1) { displayError(argv[0], std::string("Error in file '") + filepath + "' - First line should look like: <#Vertices> <#Edges>"); return EXIT_FAILURE; } if (verbose) { std::cout << "#Vertices:" << numberOfVertices << " #Edges:" << numberOfEdges << std::endl; } // Init dependency graph, and maps. ctkDependencyGraph mygraph(numberOfVertices); mygraph.setVerbose(verbose); std::map vertexIdToLabel; std::map vertexLabelToId; // Repeatedly read lines containing labels. std::string line; int lineNumber = 2; std::getline(data, line); do { // Skip empty line or commented line if (line.length() == 0 || line[0] == '#') { std::getline(data, line); continue; } // Extract two strings stringStream.clear(); stringStream << line; std::vector strings = splitString(line); if (strings.size() < 1 || strings.size() > 2) { stringStream << "Error in file '" << filepath << "' - line:" << lineNumber << " - Expected format is: