Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

autodep.cpp

00001 #include <fstream>
00002 #include <iostream>
00003 #include <locale>
00004 #include <set>
00005 #include <string>
00006 
00007 using namespace std;
00008 
00009 static
00010 string
00011 baseName(const string& filename)
00012 {
00013     return filename.substr(0, filename.rfind('.'));
00014 }
00015 
00016 static
00017 int
00018 writeMakefile(const string& dstdir, const set<string>& depFilenames)
00019 {
00020     string makeFilename = dstdir + "\\deps.mak";
00021     ofstream makeFile(makeFilename.c_str());
00022     if (!makeFile) {
00023         cerr << "Can't open '" << makeFilename << "' for writing" << endl;
00024         return 1;
00025     }
00026 
00027     for (set<string>::const_iterator i = depFilenames.begin();
00028             i != depFilenames.end(); ++i) {
00029         makeFile << "!if EXIST(\"" << *i << "\")" << endl;
00030         makeFile << "!include \"" << *i << "\"" << endl;
00031         makeFile << "!endif" << endl;
00032     }
00033 
00034     return 0;
00035 }
00036 
00037 static
00038 void
00039 writeDependencies(
00040     const string& filename,
00041     const string& srcdir,
00042     const string& dstdir,
00043     const set<string>& paths)
00044 {
00045     string basename = baseName(filename);
00046     string depFilename = dstdir + "\\" + basename + ".d";
00047     ofstream depFile(depFilename.c_str());
00048     if (!depFile) {
00049         cerr << "Can't open '" << depFilename << "' for writing" << endl;
00050         return;
00051     }
00052 
00053     // Write dependencies rule for filename
00054     depFile << "\"" << dstdir << "\\" << basename << ".obj\": \"" <<
00055         srcdir << "\\" << filename << "\" \\" << endl;
00056     for (set<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
00057         depFile << "\t\"" << *i << "\" \\" << endl;
00058     }
00059     depFile << "\t$(NULL)" << endl;
00060 }
00061 
00062 static
00063 int
00064 writeDepfiles(const string& srcdir, const string& dstdir)
00065 {
00066     const string includeLine = "Note: including file:";
00067 
00068     // Parse stdin
00069     string line;
00070     string filename;
00071     set<string> paths;
00072     locale loc = locale::classic();
00073     const ctype<char>& ct = use_facet<ctype<char> >(loc);
00074     while (getline(cin, line)) {
00075         bool echo = true;
00076 
00077         // Check for include line
00078         if (line.compare(0, includeLine.length(), includeLine) == 0) {
00079             // Strip includeLine and leading spaces
00080             line.erase(0, line.find_first_not_of(" ", includeLine.length()));
00081             if (line.length() == 0) {
00082                 continue;
00083             }
00084 
00085             // Uppercase all drive letters
00086             if (line.length() > 2 && line[1] == ':') {
00087                 line[0] = ct.toupper(line[0]);
00088             }
00089 
00090             // Record path
00091             paths.insert(line);
00092             echo = false;
00093         }
00094 
00095         // Maybe a source filename
00096         else if (line.rfind(".cpp") == line.length() - 4) {
00097             // Write dependencies for previous source file
00098             if (filename.length() != 0) {
00099                 writeDependencies(filename, srcdir, dstdir, paths);
00100                 paths.clear();
00101             }
00102             filename = line;
00103         }
00104 
00105         // Otherwise other output
00106         else {
00107             // do nothing
00108         }
00109 
00110         if (echo) {
00111             cout << line << endl;
00112         }
00113     }
00114 
00115     // Write dependencies for last source file
00116     if (filename.length() != 0) {
00117         writeDependencies(filename, srcdir, dstdir, paths);
00118         paths.clear();
00119     }
00120 
00121     return 0;
00122 }
00123 
00124 int
00125 main(int argc, char** argv)
00126 {
00127     if (argc < 3) {
00128         cerr <<  "usage: " << argv[0] <<
00129             " <src-directory> <dst-directory> [<depfiles>]" << endl;
00130         return 1;
00131     }
00132     string srcdir = argv[1];
00133     string dstdir = argv[2];
00134 
00135     // If depfiles were supplied then create a makefile in outdir to load
00136     // all of them.
00137     int result;
00138     if (argc > 3) {
00139         set<string> depFilenames(argv + 3, argv + argc);
00140         result = writeMakefile(dstdir, depFilenames);
00141     }
00142 
00143     // Otherwise parse stdin and create a depfile for each listed file
00144     else {
00145         result = writeDepfiles(srcdir, dstdir);
00146     }
00147 
00148     return result;
00149 }

Generated on Fri Nov 6 00:21:13 2009 for synergy-plus by  doxygen 1.3.9.1