瀏覽代碼

Support #pragma once in interrogate

rdb 10 年之前
父節點
當前提交
48208b0f27

+ 5 - 2
dtool/src/cppparser/cppFile.cxx

@@ -26,7 +26,8 @@ CPPFile::
 CPPFile(const Filename &filename, const Filename &filename_as_referenced,
         Source source) :
   _filename(filename), _filename_as_referenced(filename_as_referenced),
-  _source(source)
+  _source(source),
+  _pragma_once(false)
 {
   _filename.set_text();
   _filename_as_referenced.set_text();
@@ -42,7 +43,8 @@ CPPFile::
 CPPFile(const CPPFile &copy) :
   _filename(copy._filename),
   _filename_as_referenced(copy._filename_as_referenced),
-  _source(copy._source)
+  _source(copy._source),
+  _pragma_once(copy._pragma_once)
 {
 }
 
@@ -56,6 +58,7 @@ operator = (const CPPFile &copy) {
   _filename = copy._filename;
   _filename_as_referenced = copy._filename_as_referenced;
   _source = copy._source;
+  _pragma_once = copy._pragma_once;
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 0
dtool/src/cppparser/cppFile.h

@@ -59,6 +59,7 @@ public:
   Filename _filename;
   Filename _filename_as_referenced;
   Source _source;
+  mutable bool _pragma_once;
 };
 
 inline ostream &operator << (ostream &out, const CPPFile &file) {

+ 27 - 2
dtool/src/cppparser/cppPreprocessor.cxx

@@ -620,6 +620,7 @@ push_file(const CPPFile &file) {
     indent(cerr, _files.size() * 2)
       << "Reading " << file << "\n";
   }
+
   _files.push_back(InputFile());
   InputFile &infile = _files.back();
 
@@ -1158,7 +1159,7 @@ process_directive(int c) {
   } else if (command == "include") {
     handle_include_directive(args, first_line, first_col, first_file);
   } else if (command == "pragma") {
-    // Quietly ignore pragmas.
+    handle_pragma_directive(args, first_line, first_col, first_file);
   } else if (command == "ident") {
     // Quietly ignore idents.
   } else if (command == "error") {
@@ -1462,7 +1463,16 @@ handle_include_directive(const string &args, int first_line,
               first_line, first_col, first_file);
     } else {
       _last_c = '\0';
-      if (!push_file(CPPFile(filename, filename_as_referenced, source))) {
+
+      CPPFile file(filename, filename_as_referenced, source);
+
+      // Don't include it if we included it before and it had #pragma once.
+      ParsedFiles::const_iterator it = _parsed_files.find(file);
+      if (it->_pragma_once) {
+        return;
+      }
+
+      if (!push_file(file)) {
         warning("Unable to read " + filename.get_fullpath(),
                 first_line, first_col, first_file);
       }
@@ -1473,6 +1483,21 @@ handle_include_directive(const string &args, int first_line,
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CPPPreprocessor::handle_pragma_directive
+//       Access: Private
+//  Description:
+////////////////////////////////////////////////////////////////////
+void CPPPreprocessor::
+handle_pragma_directive(const string &args, int first_line,
+                        int first_col, const CPPFile &first_file) {
+  if (args == "once") {
+    ParsedFiles::iterator it = _parsed_files.find(first_file);
+    assert(it != _parsed_files.end());
+    it->_pragma_once = true;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CPPPreprocessor::handle_error_directive
 //       Access: Private

+ 2 - 0
dtool/src/cppparser/cppPreprocessor.h

@@ -133,6 +133,8 @@ private:
                            int first_col, const CPPFile &first_file);
   void handle_include_directive(const string &args, int first_line,
                                 int first_col, const CPPFile &first_file);
+  void handle_pragma_directive(const string &args, int first_line,
+                               int first_col, const CPPFile &first_file);
   void handle_error_directive(const string &args, int first_line,
                               int first_col, const CPPFile &first_file);