📄 genemake.cpp
字号:
// genemake.cpp// Generate a make file#define WANT_STREAM#define WANT_MATH#include "include.h"#include "str.h"#include "gstring.h"#include "commline.h"#include <fstream.h>// *** Classes to customise output for particular compilers and make files ***class CompilerProperties{ String code;public: CompilerProperties(const char* c) : code(c) {} virtual ~CompilerProperties() {} void Preamble() const; virtual void LinkStatement(const String& Name, const String& FN) const = 0; virtual void LinkStatement(const String& Name, const StringList& Libraries) const = 0; virtual void LibStatement(const String& Name) const = 0; virtual char* ObjectType() const = 0; virtual int ObjectSize() const = 0; virtual char* ExeType() const = 0; virtual int ExeSize() const = 0; virtual bool DoLibrary() const { return true; }protected: void LibraryList(char* prefix, const StringList& Libraries, char* suffix) const;};class GnuCompiler : public CompilerProperties{public: GnuCompiler(const char* c) : CompilerProperties(c) {} void LinkStatement(const String& Name, const String& FN) const; void LinkStatement(const String& Name, const StringList& Libraries) const; void LibStatement(const String& Name) const; char* ObjectType() const { return ".o"; } int ObjectSize() const { return 2; } char* ExeType() const { return ""; } int ExeSize() const { return 0; }};class Borland55Compiler : public CompilerProperties{public: Borland55Compiler(const char* c) : CompilerProperties(c) {} void LinkStatement(const String& Name, const String& FN) const; void LinkStatement(const String& Name, const StringList& Libraries) const; void LibStatement(const String& Name) const; char* ObjectType() const { return ".obj"; } int ObjectSize() const { return 4; } char* ExeType() const { return ".exe"; } int ExeSize() const { return 4; }};class Borland50dCompiler : public CompilerProperties{public: Borland50dCompiler(const char* c) : CompilerProperties(c) {} void LinkStatement(const String& Name, const String& FN) const; void LinkStatement(const String& Name, const StringList& Libraries) const {} void LibStatement(const String& Name) const {} char* ObjectType() const { return ".obj"; } int ObjectSize() const { return 4; } char* ExeType() const { return ".exe"; } int ExeSize() const { return 4; } bool DoLibrary() const { return false; } // don't do libraries};class Borland50Compiler : public CompilerProperties{public: Borland50Compiler(const char* c) : CompilerProperties(c) {} void LinkStatement(const String& Name, const String& FN) const; void LinkStatement(const String& Name, const StringList& Libraries) const {} void LibStatement(const String& Name) const {} char* ObjectType() const { return ".obj"; } int ObjectSize() const { return 4; } char* ExeType() const { return ".exe"; } int ExeSize() const { return 4; } bool DoLibrary() const { return false; } // don't do libraries};class Microsoft6Compiler : public CompilerProperties{public: Microsoft6Compiler(const char* c) : CompilerProperties(c) {} void LinkStatement(const String& Name, const String& FN) const; void LinkStatement(const String& Name, const StringList& Libraries) const; void LibStatement(const String& Name) const; char* ObjectType() const { return ".obj"; } int ObjectSize() const { return 4; } char* ExeType() const { return ".exe"; } int ExeSize() const { return 4; }};class Watcom10Compiler : public CompilerProperties{public: Watcom10Compiler(const char* c) : CompilerProperties(c) {} void LinkStatement(const String& Name, const String& FN) const; void LinkStatement(const String& Name, const StringList& Libraries) const {} void LibStatement(const String& Name) const {} char* ObjectType() const { return ".obj"; } int ObjectSize() const { return 4; } char* ExeType() const { return ".exe"; } int ExeSize() const { return 4; } bool DoLibrary() const { return false; } // don't do libraries};// ************* function headers ********************// Does a string list, LS, contain a particular string Sbool Contains(const StringList& LS, const String& S);// search a source file for header and body file names - then// search these files and so on. Return list of header and body// file namesbool SearchHB(const String& SourceFile, StringList& Headers, StringList& Bodies);// search a source file for header file names - then search// these files and so on. Return list of header file namesbool SearchH(const String& SourceFile, StringList& Headers);// find header files in .lfl file then apply SearchHB to these// NewHeaders are the names just in the SourceFile// return false if source files missingbool SearchL(const String& SourceFile, StringList& Headers, StringList& NewHeaders, StringList& Bodies);// find list of libraries required and purged list of headers// return true if any libraries found// no output if libraries not foundbool IdentifyLibraries( const StringList& Headers, // input list of headers const StringList& Libraries, // library files available const StringList& LibraryFiles, // all headers whose body is in library const StringList& LibraryFiles1, // headers which trigger inclusion StringList& LibrariesWanted, // return list of libraries required StringList& PurgedHeaders); // return headers which are not matched// find bodies referenced in a list of header files - no recursionvoid GetBodies(const StringList& Headers, StringList& Bodies);// output n spacesvoid Spaces(int n) { while (n-- > 0) cout << ' '; }// ************* main program section ********************typedef StringList::iterator SLI;typedef StringList::const_iterator SLCI;int main(int argc, char** argv){ CommandLine CL(argc, argv); int N = CL.NumberOfArgs(); if (N <= 0) { cerr << "No targets" << endl; exit(1); } bool WantCompare = CL.HasOption("!"); // compare output with text file // Get compiler type and construct corresponding class CompilerProperties* CP; if (CL.HasOption("G") || CL.HasOption("g")) CP = new GnuCompiler("pre_g.txt"); else if (CL.HasOption("C") || CL.HasOption("c")) CP = new GnuCompiler("pre_c.txt"); else if ((CL.HasOption("B") || CL.HasOption("b")) && (CL.HasOption("D") || CL.HasOption("d")) && CL.HasOption("0")) CP = new Borland50dCompiler("pre_b0d.txt"); else if ((CL.HasOption("B") || CL.HasOption("b")) && CL.HasOption("0")) CP = new Borland50Compiler("pre_b0.txt"); else if ((CL.HasOption("B") || CL.HasOption("b")) && CL.HasOption("5")) CP = new Borland55Compiler("pre_b5.txt"); else if ((CL.HasOption("M") || CL.HasOption("m")) && CL.HasOption("6")) CP = new Microsoft6Compiler("pre_m6.txt"); else if ((CL.HasOption("I") || CL.HasOption("i")) && CL.HasOption("5")) CP = new Microsoft6Compiler("pre_i5.txt"); else if ((CL.HasOption("W") || CL.HasOption("w")) && (CL.HasOption("D") || CL.HasOption("d")) && CL.HasOption("0")) CP = new Watcom10Compiler("pre_w0d.txt"); else if ((CL.HasOption("W") || CL.HasOption("w")) && CL.HasOption("0")) CP = new Watcom10Compiler("pre_w0.txt"); else { cerr << "No compiler option" << endl; exit(1); } // print preamble CP->Preamble(); // get targets; separate out libraries // beginning with @ means argument file StringList Targets; StringList Libraries; cout << "everything: \t"; for (int ni = 1; ni <= N; ++ni) { String s = CL.GetArg(ni); if (s[0] == '@') { ifstream is(String(s,1).c_str()); if (!is) { cerr << "No argument file " << s << endl; } else { StringList Args; is >> Args; for (SLI ai = Args.begin(); ai != Args.end(); ++ai) { uint sf = ai->find(".lfl"); if (sf != String::npos) Libraries.push_back(ai->erase(sf)); else if (ai->find_first_not_of(' ') != String::npos) { Targets.push_back(*ai); if (WantCompare) cout << *ai << ".txx "; else cout << *ai << CP->ExeType() << " "; } } } } else { uint sf = s.find(".lfl"); if (sf != String::npos) Libraries.push_back(s.erase(sf)); else { Targets.push_back( s ); if (WantCompare) cout << s << ".txx "; else cout << s << CP->ExeType() << " "; } } } cout << endl << endl; // find the bodies corresponding to each library // skip DoLibrary returns false StringList Bodies; // to hold names of .cpp files StringList LibraryFiles; StringList LibraryFiles1; if (CP->DoLibrary()) { for (SLI i = Libraries.begin(); i != Libraries.end(); ++i) { SLI j; bool found = true; StringList NB; // Bodies corresponding to this target StringList NH; // Headers including implied headers StringList NH1; // Headers excluding implied headers String Main = *i+".lfl"; if (!SearchL(Main, NH, NH1, NB)) { cerr << "Assume library " << *i << " up-to-date" << endl << endl; cout << "# Assume library " << *i << " up-to-date" << endl << endl; found = false; } cout << *i << "_lobj ="; for (j = NB.begin(); j != NB.end(); ++j) { String object = *j; cout << " " << object.erase(object.find(".cpp")) << CP->ObjectType(); if (!Contains(Bodies,*j)) Bodies.push_back(*j); } cout << endl << endl; String LF = " "; // names of files making up library for (j = NH.begin(); j != NH.end(); ++j) LF += (*j + " "); LibraryFiles.push_back(LF); LF = " "; for (j = NH1.begin(); j != NH1.end(); ++j) LF += (*j + " "); LibraryFiles1.push_back(LF); if (found) CP->LibStatement(*i); } } // find the bodies corresponding to each target SLI i; for (i = Targets.begin(); i != Targets.end(); ++i) { StringList NH; // Headers corresponding to this target StringList NB; // Bodies corresponding to this target StringList L; // Libraries StringList LW; // Libraries wanted StringList PH; // Purged headers String Main = *i + ".cpp"; NB.push_back(Main); SearchHB(Main, NH, NB); // find what libraries we need and what headers are left bool WantLibraries = IdentifyLibraries(NH, Libraries, LibraryFiles, LibraryFiles1, LW, PH); if (WantLibraries) { NB.CleanUp(); NB.push_back(Main); GetBodies(PH, NB); cout << *i << "_obj ="; for (SLI j = NB.begin(); j != NB.end(); ++j) { String object = *j; object.erase(object.find(".cpp")); cout << " " << object << CP->ObjectType(); if (!Contains(Bodies,*j)) Bodies.push_back(*j); } cout << endl << endl; CP->LinkStatement(*i, LW); } else { String FN; // list of file names; may be required by LinkStatement cout << *i << "_obj ="; for (SLI j = NB.begin(); j != NB.end(); ++j) { String object = *j; object.erase(object.find(".cpp")); cout << " " << object << CP->ObjectType(); if (!Contains(Bodies,*j)) Bodies.push_back(*j); FN += (" " + object + CP->ObjectType()); } cout << endl << endl; CP->LinkStatement(*i, FN); } } // find the headers corresponding to each body for (i = Bodies.begin(); i != Bodies.end(); ++i) { String object = *i; object.erase(object.find(".cpp")); StringList Headers; if (SearchH(*i, Headers)) { cout << object << CP->ObjectType() << ":"; Spaces(14 - object.size() - CP->ObjectSize()); cout << "\t" << *i; for (SLI j = Headers.begin(); j != Headers.end(); ++j) cout << " " << *j; cout << endl; } cout << endl; } // lines for checking output of program for (i = Targets.begin(); i != Targets.end(); ++i) { cout << *i << ".txx:"; Spaces(10 - i->size()); cout << "\t" << *i << CP->ExeType() << endl; cout << "\t\t$(PRE)" << *i << " > " << *i << ".txx" << endl; cout << "\t\t$(DIFF) " << *i << ".txt " << *i << ".txx" << endl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -