text: import os
  import ycm_core
  
  # These are the compilation flags that will be used in case there's no
  # compilation database found.
  FLAGS = [
      '-Wall',
      '-Wextra',
      '-Werror',
      '-Wno-long-long',
      '-Wno-variadic-macros',
      '-fexceptions',
      '-DNDEBUG',
      '-std=c++11',
      '-x',
      'c++',
      '-isystem',
      '../BoostParts',
      '-isystem',
      # This path will only work on OS X, but extra paths that don't exist are not
      # harmful
      '/System/Library/Frameworks/Python.framework/Headers',
      '-isystem',
      '../llvm/include',
      '-isystem',
      '../llvm/tools/clang/include',
      '-I',
      '.',
      '-I',
      './ClangCompleter',
      '-isystem',
      './tests/gmock/gtest',
      '-isystem',
      './tests/gmock/gtest/include',
      '-isystem',
      './tests/gmock',
      '-isystem',
      './tests/gmock/include',
  ]
  
  SOURCE_EXTENSIONS = ['.cpp', '.cxx', '.cc', '.c', '.m', '.mm']
  HEADER_EXTENSIONS = ['.h', '.hxx', '.hpp', '.hh']
  
  
  def GetNearestCompilationDatabase(path):
      json_path = FindNearestFile(path, 'compile_commands.json')
      if not json_path:
          return None
  
      compilation_database_path = os.path.dirname(json_path)
      return ycm_core.CompilationDatabase(compilation_database_path)
  
  
  def FindNearestFile(path, filename):
      candidate = os.path.join(path, filename)
      if os.path.isfile(candidate):
          return candidate
      parent = os.path.dirname(os.path.abspath(path))
  
      # The parent of '/' is '/'.
      if parent == path:
          return None
  
      return FindNearestFile(parent, filename)
  
  
  def DirectoryOfThisScript():
      return os.path.dirname(os.path.abspath(__file__))
  
  
  def GetCompilationInfoForFile(database, filename):
      # The compilation_commands.json file generated by tooling does not have
      # entries for header files. So we do our best by asking the db for flags
      # for a corresponding source file, if any. If one exists, the flags for
      # that file should be good enough.
      if IsHeaderFile(filename):
          basename = os.path.splitext(filename)[0]
          for extension in SOURCE_EXTENSIONS:
              replacement_file = basename + extension
              if os.path.exists(replacement_file):
                  compilation_info = database.GetCompilationInfoForFile(
                      replacement_file)
                  if compilation_info.compiler_flags_:
                      return compilation_info
          return None
      return database.GetCompilationInfoForFile(filename)
  
  
  def IsHeaderFile(filename):
      extension = os.path.splitext(filename)[1]
      return extension in HEADER_EXTENSIONS
  
  
  def AddDefaultIncludes(flags):
      includes = ['-I/usr/include/c++/5']
      try:
          std_idx = next(i for i, flag in enumerate(flags)
                         if flag.startswith('-std=c++'))
          return flags[:std_idx + 1] + includes + flags[std_idx + 1:]
      except:
          # No anchor, so just add it at the end.
          return flags + includes
  
  
  def PruneUnrecognizedFlags(flags):
      unrecognized_flags = ('-fno-canonical-system-headers', )
      return [flag for flag in flags if flag not in unrecognized_flags]
  
  
  def FlagsForFile(filename, **kwargs):
      fallback = {
          'flags': FLAGS,
          'include_paths_relative_to_dir': DirectoryOfThisScript()
      }
  
      path = os.path.realpath(filename)
      database = GetNearestCompilationDatabase(path)
      if not database:
          return fallback
  
      compilation_info = GetCompilationInfoForFile(database, filename)
      if not compilation_info:
          return fallback
  
      # Bear in mind that compilation_info.compiler_flags_ does NOT return a
      # python list, but a "list-like" StringVec object.
      final_flags = list(compilation_info.compiler_flags_)
  
      # Libclang sometimes has problems with standard C++11 includes.
      final_flags = AddDefaultIncludes(final_flags)
      final_flags = PruneUnrecognizedFlags(final_flags)
  
      return {
          'flags': final_flags,
          'include_paths_relative_to_dir': compilation_info.compiler_working_dir_
      }
  