Doxygen Doxyfile source scanner.  This should scan the Doxygen file and add
   any files used to generate docs to the list of source files.

def DoxySourceScan(node, env, path):
   """
   Doxygen Doxyfile source scanner.  This should scan the Doxygen file and add
   any files used to generate docs to the list of source files.
   """
   default_file_patterns = [
      '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx',
      '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++',
      '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm',
      '*.py',
   ]

   default_exclude_patterns = [
      '*~',
   ]

   sources = []

   data = DoxyfileParse(node.get_contents())

   if data.get("RECURSIVE", "NO") == "YES":
      recursive = True
   else:
      recursive = False

   file_patterns = data.get("FILE_PATTERNS", default_file_patterns)
   exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns)

   # We're running in the top-level directory, but the doxygen
   # configuration file is in the same directory as node; this means
   # that relative pathnames in node must be adjusted before they can
   # go onto the sources list
   conf_dir = os.path.dirname(str(node))
   
   for node in data.get("INPUT", []):
      if not os.path.isabs(node):
         node = os.path.join(conf_dir, node)
      if os.path.isfile(node):
         sources.append(node)
      elif os.path.isdir(node):
         if recursive:
            for root, dirs, files in os.walk(node):
               for f in files:
                  filename = os.path.join(root, f)

                  pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False)
                  exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True)

                  if pattern_check and not exclude_check:
                     sources.append(filename)
         else:
            for pattern in file_patterns:
               sources.extend(glob.glob("/".join([node, pattern])))

   # Add tagfiles to the list of source files:
   for node in data.get("TAGFILES", []):
      file = node.split("=")[0]
      if not os.path.isabs(file):
         file = os.path.join(conf_dir, file)
      sources.append(file)
   
   # Add additional files to the list of source files:
   def append_additional_source(option):
      file = data.get(option, "")
      if file != "":
         if not os.path.isabs(file):
            file = os.path.join(conf_dir, file)
         if os.path.isfile(file):
            sources.append(file)

   append_additional_source("HTML_STYLESHEET")
   append_additional_source("HTML_HEADER")
   append_additional_source("HTML_FOOTER")

   sources = map( lambda path: env.File(path), sources )
   return sources