]> granicus.if.org Git - icinga2/blobdiff - tools/mkclass/classcompiler.cpp
Implement include guards for mkclass
[icinga2] / tools / mkclass / classcompiler.cpp
index 725c185a5c8ca94e5d1494dda79e14a0ea235bf4..203e90f803cd4cbb26a90d80de254380e66e81e1 100644 (file)
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
  ******************************************************************************/
 
-#include "classcompiler.h"
+#include "classcompiler.hpp"
 #include <iostream>
 #include <fstream>
 #include <stdexcept>
 #include <map>
 #include <vector>
+#include <cstring>
 
 using namespace icinga;
 
@@ -53,28 +54,28 @@ size_t ClassCompiler::ReadInput(char *buffer, size_t max_size)
        return static_cast<size_t>(m_Input->gcount());
 }
 
-void ClassCompiler::HandleInclude(const std::string& path, const ClassDebugInfo& locp)
+void ClassCompiler::HandleInclude(const std::string& path, const ClassDebugInfo&)
 {
        std::cout << "#include \"" << path << "\"" << std::endl << std::endl;
 }
 
-void ClassCompiler::HandleAngleInclude(const std::string& path, const ClassDebugInfo& locp)
+void ClassCompiler::HandleAngleInclude(const std::string& path, const ClassDebugInfo&)
 {
        std::cout << "#include <" << path << ">" << std::endl << std::endl;
 }
 
-void ClassCompiler::HandleNamespaceBegin(const std::string& name, const ClassDebugInfo& locp)
+void ClassCompiler::HandleNamespaceBegin(const std::string& name, const ClassDebugInfo&)
 {
        std::cout << "namespace " << name << std::endl
                          << "{" << std::endl << std::endl;
 }
 
-void ClassCompiler::HandleNamespaceEnd(const ClassDebugInfo& locp)
+void ClassCompiler::HandleNamespaceEnd(const ClassDebugInfo&)
 {
        std::cout << "}" << std::endl;
 }
 
-void ClassCompiler::HandleCode(const std::string& code, const ClassDebugInfo& locp)
+void ClassCompiler::HandleCode(const std::string& code, const ClassDebugInfo&)
 {
        std::cout << code << std::endl;
 }
@@ -100,7 +101,7 @@ unsigned long ClassCompiler::SDBM(const std::string& str, size_t len = std::stri
         return hash;
 }
 
-void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo& locp)
+void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
 {
        std::vector<Field>::const_iterator it;
 
@@ -111,8 +112,13 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo& locp)
        /* TypeImpl */
        std::cout << "template<>" << std::endl
                << "class TypeImpl<" << klass.Name << ">"
-               << " : public Type" << std::endl
-               << "{" << std::endl
+               << " : public Type";
+       
+       if (!klass.TypeBase.empty())
+               std::cout << ", public " + klass.TypeBase;
+
+       std::cout << std::endl
+               << " {" << std::endl
                << "public:" << std::endl;
 
        /* GetName */
@@ -477,17 +483,55 @@ void ClassCompiler::CompileFile(const std::string& path)
        return CompileStream(path, &stream);
 }
 
+std::string ClassCompiler::BaseName(const  std::string& path)
+{
+       char *dir = strdup(path.c_str());
+       std::string result;
+
+       if (dir == NULL)
+               throw std::bad_alloc();
+
+#ifndef _WIN32
+       result = basename(dir);
+#else /* _WIN32 */
+       result = PathFindFileName(dir);
+#endif /* _WIN32 */
+
+       free(dir);
+
+       return result;
+}
+
+std::string ClassCompiler::FileNameToGuardName(const std::string& fname)
+{
+       std::string result = fname;
+
+       for (int i = 0; i < result.size(); i++) {
+               result[i] = toupper(result[i]);
+
+               if (result[i] == '.')
+                       result[i] = '_';
+       }
+
+       return result;
+}
+
 void ClassCompiler::CompileStream(const std::string& path, std::istream *stream)
 {
        stream->exceptions(std::istream::badbit);
 
-       std::cout << "#include \"base/object.h\"" << std::endl
-                         << "#include \"base/type.h\"" << std::endl
-                         << "#include \"base/debug.h\"" << std::endl
-                         << "#include \"base/value.h\"" << std::endl
-                         << "#include \"base/array.h\"" << std::endl
-                         << "#include \"base/dictionary.h\"" << std::endl
-                         << "#include \"base/utility.h\"" << std::endl << std::endl
+       std::string guard_name = FileNameToGuardName(BaseName(path));
+
+       std::cout << "#ifndef " << guard_name << std::endl
+                         << "#define " << guard_name << std::endl << std::endl;
+
+       std::cout << "#include \"base/object.hpp\"" << std::endl
+                         << "#include \"base/type.hpp\"" << std::endl
+                         << "#include \"base/debug.hpp\"" << std::endl
+                         << "#include \"base/value.hpp\"" << std::endl
+                         << "#include \"base/array.hpp\"" << std::endl
+                         << "#include \"base/dictionary.hpp\"" << std::endl
+                         << "#include \"base/utility.hpp\"" << std::endl << std::endl
                          << "#ifdef _MSC_VER" << std::endl
                          << "#pragma warning( push )" << std::endl
                          << "#pragma warning( disable : 4244 )" << std::endl
@@ -500,4 +544,6 @@ void ClassCompiler::CompileStream(const std::string& path, std::istream *stream)
        std::cout << "#ifdef _MSC_VER" << std::endl
                          << "#pragma warning ( pop )" << std::endl
                          << "#endif /* _MSC_VER */" << std::endl;
+
+       std::cout << "#endif /* " << guard_name << " */" << std::endl;
 }