<commit_before>//===- unittest/Tooling/ToolingTest.cpp - Tooling unit tests --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclGroup.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/config.h"
#include "gtest/gtest.h"
#include <string>

namespace clang {
namespace tooling {

namespace {
/// Takes an ast consumer and returns it from CreateASTConsumer. This only
/// works with single translation unit compilations.
class TestAction : public clang::ASTFrontendAction {
 public:
  /// Takes ownership of TestConsumer.
  explicit TestAction(clang::ASTConsumer *TestConsumer)
      : TestConsumer(TestConsumer) {}

 protected:
  virtual clang::ASTConsumer* CreateASTConsumer(
      clang::CompilerInstance& compiler, StringRef dummy) {
    /// TestConsumer will be deleted by the framework calling us.
    return TestConsumer;
  }

 private:
  clang::ASTConsumer * const TestConsumer;
};

class FindTopLevelDeclConsumer : public clang::ASTConsumer {
 public:
  explicit FindTopLevelDeclConsumer(bool *FoundTopLevelDecl)
      : FoundTopLevelDecl(FoundTopLevelDecl) {}
  virtual bool HandleTopLevelDecl(clang::DeclGroupRef DeclGroup) {
    *FoundTopLevelDecl = true;
    return true;
  }
 private:
  bool * const FoundTopLevelDecl;
};
} // end namespace

TEST(runToolOnCode, FindsNoTopLevelDeclOnEmptyCode) {
  bool FoundTopLevelDecl = false;
  EXPECT_TRUE(runToolOnCode(
      new TestAction(new FindTopLevelDeclConsumer(&FoundTopLevelDecl)), ""));
  EXPECT_FALSE(FoundTopLevelDecl);
}

namespace {
class FindClassDeclXConsumer : public clang::ASTConsumer {
 public:
  FindClassDeclXConsumer(bool *FoundClassDeclX)
      : FoundClassDeclX(FoundClassDeclX) {}
  virtual bool HandleTopLevelDecl(clang::DeclGroupRef GroupRef) {
    if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>(
            *GroupRef.begin())) {
      if (Record->getName() == "X") {
        *FoundClassDeclX = true;
      }
    }
    return true;
  }
 private:
  bool *FoundClassDeclX;
};
bool FindClassDeclX(ASTUnit *AST) {
  for (std::vector<Decl *>::iterator i = AST->top_level_begin(),
                                     e = AST->top_level_end();
       i != e; ++i) {
    if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>(*i)) {
      if (Record->getName() == "X") {
        return true;
      }
    }
  }
  return false;
}
} // end namespace

TEST(runToolOnCode, FindsClassDecl) {
  bool FoundClassDeclX = false;
  EXPECT_TRUE(runToolOnCode(new TestAction(
      new FindClassDeclXConsumer(&FoundClassDeclX)), "class X;"));
  EXPECT_TRUE(FoundClassDeclX);

  FoundClassDeclX = false;
  EXPECT_TRUE(runToolOnCode(new TestAction(
      new FindClassDeclXConsumer(&FoundClassDeclX)), "class Y;"));
  EXPECT_FALSE(FoundClassDeclX);
}

TEST(buildASTFromCode, FindsClassDecl) {
  std::unique_ptr<ASTUnit> AST(buildASTFromCode("class X;"));
  ASSERT_TRUE(AST.get());
  EXPECT_TRUE(FindClassDeclX(AST.get()));

  AST.reset(buildASTFromCode("class Y;"));
  ASSERT_TRUE(AST.get());
  EXPECT_FALSE(FindClassDeclX(AST.get()));
}

TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromType) {
  std::unique_ptr<FrontendActionFactory> Factory(
      newFrontendActionFactory<SyntaxOnlyAction>());
  std::unique_ptr<FrontendAction> Action(Factory->create());
  EXPECT_TRUE(Action.get() != NULL);
}

struct IndependentFrontendActionCreator {
  ASTConsumer *newASTConsumer() {
    return new FindTopLevelDeclConsumer(NULL);
  }
};

TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromFactoryType) {
  IndependentFrontendActionCreator Creator;
  std::unique_ptr<FrontendActionFactory> Factory(
      newFrontendActionFactory(&Creator));
  std::unique_ptr<FrontendAction> Action(Factory->create());
  EXPECT_TRUE(Action.get() != NULL);
}

TEST(ToolInvocation, TestMapVirtualFile) {
  IntrusiveRefCntPtr<clang::FileManager> Files(
      new clang::FileManager(clang::FileSystemOptions()));
  std::vector<std::string> Args;
  Args.push_back("tool-executable");
  Args.push_back("-Idef");
  Args.push_back("-fsyntax-only");
  Args.push_back("test.cpp");
  clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
                                            Files.getPtr());
  Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
  Invocation.mapVirtualFile("def/abc", "\n");
  EXPECT_TRUE(Invocation.run());
}

TEST(ToolInvocation, TestVirtualModulesCompilation) {
  // FIXME: Currently, this only tests that we don't exit with an error if a
  // mapped module.map is found on the include path. In the future, expand this
  // test to run a full modules enabled compilation, so we make sure we can
  // rerun modules compilations with a virtual file system.
  IntrusiveRefCntPtr<clang::FileManager> Files(
      new clang::FileManager(clang::FileSystemOptions()));
  std::vector<std::string> Args;
  Args.push_back("tool-executable");
  Args.push_back("-Idef");
  Args.push_back("-fsyntax-only");
  Args.push_back("test.cpp");
  clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
                                            Files.getPtr());
  Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
  Invocation.mapVirtualFile("def/abc", "\n");
  // Add a module.map file in the include directory of our header, so we trigger
  // the module.map header search logic.
  Invocation.mapVirtualFile("def/module.map", "\n");
  EXPECT_TRUE(Invocation.run());
}

struct VerifyEndCallback : public SourceFileCallbacks {
  VerifyEndCallback() : BeginCalled(0), EndCalled(0), Matched(false) {}
  virtual bool handleBeginSource(CompilerInstance &CI,
                                 StringRef Filename) override {
    ++BeginCalled;
    return true;
  }
  virtual void handleEndSource() {
    ++EndCalled;
  }
  ASTConsumer *newASTConsumer() {
    return new FindTopLevelDeclConsumer(&Matched);
  }
  unsigned BeginCalled;
  unsigned EndCalled;
  bool Matched;
};

#if !defined(LLVM_ON_WIN32)
TEST(newFrontendActionFactory, InjectsSourceFileCallbacks) {
  VerifyEndCallback EndCallback;

  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
  std::vector<std::string> Sources;
  Sources.push_back("/a.cc");
  Sources.push_back("/b.cc");
  ClangTool Tool(Compilations, Sources);

  Tool.mapVirtualFile("/a.cc", "void a() {}");
  Tool.mapVirtualFile("/b.cc", "void b() {}");

  Tool.run(newFrontendActionFactory(&EndCallback, &EndCallback));

  EXPECT_TRUE(EndCallback.Matched);
  EXPECT_EQ(2u, EndCallback.BeginCalled);
  EXPECT_EQ(2u, EndCallback.EndCalled);
}
#endif

struct SkipBodyConsumer : public clang::ASTConsumer {
  /// Skip the 'skipMe' function.
  virtual bool shouldSkipFunctionBody(Decl *D) {
    FunctionDecl *F = dyn_cast<FunctionDecl>(D);
    return F && F->getNameAsString() == "skipMe";
  }
};

struct SkipBodyAction : public clang::ASTFrontendAction {
  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &Compiler,
                                         StringRef) {
    Compiler.getFrontendOpts().SkipFunctionBodies = true;
    return new SkipBodyConsumer;
  }
};

TEST(runToolOnCode, TestSkipFunctionBody) {
  EXPECT_TRUE(runToolOnCode(new SkipBodyAction,
                            "int skipMe() { an_error_here }"));
  EXPECT_FALSE(runToolOnCode(new SkipBodyAction,
                             "int skipMeNot() { an_error_here }"));
}

TEST(runToolOnCodeWithArgs, TestNoDepFile) {
  llvm::SmallString<32> DepFilePath;
  ASSERT_FALSE(
      llvm::sys::fs::createTemporaryFile("depfile", "d", DepFilePath));
  std::vector<std::string> Args;
  Args.push_back("-MMD");
  Args.push_back("-MT");
  Args.push_back(DepFilePath.str());
  Args.push_back("-MF");
  Args.push_back(DepFilePath.str());
  EXPECT_TRUE(runToolOnCodeWithArgs(new SkipBodyAction, "", Args));
  EXPECT_FALSE(llvm::sys::fs::exists(DepFilePath.str()));
  EXPECT_FALSE(llvm::sys::fs::remove(DepFilePath.str()));
}

struct CheckSyntaxOnlyAdjuster: public ArgumentsAdjuster {
  bool &Found;
  bool &Ran;

  CheckSyntaxOnlyAdjuster(bool &Found, bool &Ran) : Found(Found), Ran(Ran) { }

  virtual CommandLineArguments
  Adjust(const CommandLineArguments &Args) override {
    Ran = true;
    for (unsigned I = 0, E = Args.size(); I != E; ++I) {
      if (Args[I] == "-fsyntax-only") {
        Found = true;
        break;
      }
    }
    return Args;
  }
};

TEST(ClangToolTest, ArgumentAdjusters) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());

  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
  Tool.mapVirtualFile("/a.cc", "void a() {}");

  bool Found = false;
  bool Ran = false;
  Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
  Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
  EXPECT_TRUE(Ran);
  EXPECT_TRUE(Found);

  Ran = Found = false;
  Tool.clearArgumentsAdjusters();
  Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
  Tool.appendArgumentsAdjuster(new ClangSyntaxOnlyAdjuster());
  Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
  EXPECT_TRUE(Ran);
  EXPECT_FALSE(Found);
}

#ifndef LLVM_ON_WIN32
TEST(ClangToolTest, BuildASTs) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());

  std::vector<std::string> Sources;
  Sources.push_back("/a.cc");
  Sources.push_back("/b.cc");
  ClangTool Tool(Compilations, Sources);

  Tool.mapVirtualFile("/a.cc", "void a() {}");
  Tool.mapVirtualFile("/b.cc", "void b() {}");

  std::vector<ASTUnit *> ASTs;
  EXPECT_EQ(0, Tool.buildASTs(ASTs));
  EXPECT_EQ(2u, ASTs.size());

  llvm::DeleteContainerPointers(ASTs);
}

struct TestDiagnosticConsumer : public DiagnosticConsumer {
  TestDiagnosticConsumer() : NumDiagnosticsSeen(0) {}
  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                                const Diagnostic &Info) {
    ++NumDiagnosticsSeen;
  }
  unsigned NumDiagnosticsSeen;
};

TEST(ClangToolTest, InjectDiagnosticConsumer) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
  Tool.mapVirtualFile("/a.cc", "int x = undeclared;");
  TestDiagnosticConsumer Consumer;
  Tool.setDiagnosticConsumer(&Consumer);
  Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
  EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
}

TEST(ClangToolTest, InjectDiagnosticConsumerInBuildASTs) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
  Tool.mapVirtualFile("/a.cc", "int x = undeclared;");
  TestDiagnosticConsumer Consumer;
  Tool.setDiagnosticConsumer(&Consumer);
  std::vector<ASTUnit*> ASTs;
  Tool.buildASTs(ASTs);
  EXPECT_EQ(1u, ASTs.size());
  EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
}
#endif

} // end namespace tooling
} // end namespace clang
<commit_msg>Fix four more test-only leaks found by LSan.<commit_after>//===- unittest/Tooling/ToolingTest.cpp - Tooling unit tests --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclGroup.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/config.h"
#include "gtest/gtest.h"
#include <string>

namespace clang {
namespace tooling {

namespace {
/// Takes an ast consumer and returns it from CreateASTConsumer. This only
/// works with single translation unit compilations.
class TestAction : public clang::ASTFrontendAction {
 public:
  /// Takes ownership of TestConsumer.
  explicit TestAction(clang::ASTConsumer *TestConsumer)
      : TestConsumer(TestConsumer) {}

 protected:
  virtual clang::ASTConsumer* CreateASTConsumer(
      clang::CompilerInstance& compiler, StringRef dummy) {
    /// TestConsumer will be deleted by the framework calling us.
    return TestConsumer;
  }

 private:
  clang::ASTConsumer * const TestConsumer;
};

class FindTopLevelDeclConsumer : public clang::ASTConsumer {
 public:
  explicit FindTopLevelDeclConsumer(bool *FoundTopLevelDecl)
      : FoundTopLevelDecl(FoundTopLevelDecl) {}
  virtual bool HandleTopLevelDecl(clang::DeclGroupRef DeclGroup) {
    *FoundTopLevelDecl = true;
    return true;
  }
 private:
  bool * const FoundTopLevelDecl;
};
} // end namespace

TEST(runToolOnCode, FindsNoTopLevelDeclOnEmptyCode) {
  bool FoundTopLevelDecl = false;
  EXPECT_TRUE(runToolOnCode(
      new TestAction(new FindTopLevelDeclConsumer(&FoundTopLevelDecl)), ""));
  EXPECT_FALSE(FoundTopLevelDecl);
}

namespace {
class FindClassDeclXConsumer : public clang::ASTConsumer {
 public:
  FindClassDeclXConsumer(bool *FoundClassDeclX)
      : FoundClassDeclX(FoundClassDeclX) {}
  virtual bool HandleTopLevelDecl(clang::DeclGroupRef GroupRef) {
    if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>(
            *GroupRef.begin())) {
      if (Record->getName() == "X") {
        *FoundClassDeclX = true;
      }
    }
    return true;
  }
 private:
  bool *FoundClassDeclX;
};
bool FindClassDeclX(ASTUnit *AST) {
  for (std::vector<Decl *>::iterator i = AST->top_level_begin(),
                                     e = AST->top_level_end();
       i != e; ++i) {
    if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>(*i)) {
      if (Record->getName() == "X") {
        return true;
      }
    }
  }
  return false;
}
} // end namespace

TEST(runToolOnCode, FindsClassDecl) {
  bool FoundClassDeclX = false;
  EXPECT_TRUE(runToolOnCode(new TestAction(
      new FindClassDeclXConsumer(&FoundClassDeclX)), "class X;"));
  EXPECT_TRUE(FoundClassDeclX);

  FoundClassDeclX = false;
  EXPECT_TRUE(runToolOnCode(new TestAction(
      new FindClassDeclXConsumer(&FoundClassDeclX)), "class Y;"));
  EXPECT_FALSE(FoundClassDeclX);
}

TEST(buildASTFromCode, FindsClassDecl) {
  std::unique_ptr<ASTUnit> AST(buildASTFromCode("class X;"));
  ASSERT_TRUE(AST.get());
  EXPECT_TRUE(FindClassDeclX(AST.get()));

  AST.reset(buildASTFromCode("class Y;"));
  ASSERT_TRUE(AST.get());
  EXPECT_FALSE(FindClassDeclX(AST.get()));
}

TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromType) {
  std::unique_ptr<FrontendActionFactory> Factory(
      newFrontendActionFactory<SyntaxOnlyAction>());
  std::unique_ptr<FrontendAction> Action(Factory->create());
  EXPECT_TRUE(Action.get() != NULL);
}

struct IndependentFrontendActionCreator {
  ASTConsumer *newASTConsumer() {
    return new FindTopLevelDeclConsumer(NULL);
  }
};

TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromFactoryType) {
  IndependentFrontendActionCreator Creator;
  std::unique_ptr<FrontendActionFactory> Factory(
      newFrontendActionFactory(&Creator));
  std::unique_ptr<FrontendAction> Action(Factory->create());
  EXPECT_TRUE(Action.get() != NULL);
}

TEST(ToolInvocation, TestMapVirtualFile) {
  IntrusiveRefCntPtr<clang::FileManager> Files(
      new clang::FileManager(clang::FileSystemOptions()));
  std::vector<std::string> Args;
  Args.push_back("tool-executable");
  Args.push_back("-Idef");
  Args.push_back("-fsyntax-only");
  Args.push_back("test.cpp");
  clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
                                            Files.getPtr());
  Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
  Invocation.mapVirtualFile("def/abc", "\n");
  EXPECT_TRUE(Invocation.run());
}

TEST(ToolInvocation, TestVirtualModulesCompilation) {
  // FIXME: Currently, this only tests that we don't exit with an error if a
  // mapped module.map is found on the include path. In the future, expand this
  // test to run a full modules enabled compilation, so we make sure we can
  // rerun modules compilations with a virtual file system.
  IntrusiveRefCntPtr<clang::FileManager> Files(
      new clang::FileManager(clang::FileSystemOptions()));
  std::vector<std::string> Args;
  Args.push_back("tool-executable");
  Args.push_back("-Idef");
  Args.push_back("-fsyntax-only");
  Args.push_back("test.cpp");
  clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
                                            Files.getPtr());
  Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
  Invocation.mapVirtualFile("def/abc", "\n");
  // Add a module.map file in the include directory of our header, so we trigger
  // the module.map header search logic.
  Invocation.mapVirtualFile("def/module.map", "\n");
  EXPECT_TRUE(Invocation.run());
}

struct VerifyEndCallback : public SourceFileCallbacks {
  VerifyEndCallback() : BeginCalled(0), EndCalled(0), Matched(false) {}
  virtual bool handleBeginSource(CompilerInstance &CI,
                                 StringRef Filename) override {
    ++BeginCalled;
    return true;
  }
  virtual void handleEndSource() {
    ++EndCalled;
  }
  ASTConsumer *newASTConsumer() {
    return new FindTopLevelDeclConsumer(&Matched);
  }
  unsigned BeginCalled;
  unsigned EndCalled;
  bool Matched;
};

#if !defined(LLVM_ON_WIN32)
TEST(newFrontendActionFactory, InjectsSourceFileCallbacks) {
  VerifyEndCallback EndCallback;

  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
  std::vector<std::string> Sources;
  Sources.push_back("/a.cc");
  Sources.push_back("/b.cc");
  ClangTool Tool(Compilations, Sources);

  Tool.mapVirtualFile("/a.cc", "void a() {}");
  Tool.mapVirtualFile("/b.cc", "void b() {}");

  std::unique_ptr<FrontendActionFactory> Action(
      newFrontendActionFactory(&EndCallback, &EndCallback));
  Tool.run(Action.get());

  EXPECT_TRUE(EndCallback.Matched);
  EXPECT_EQ(2u, EndCallback.BeginCalled);
  EXPECT_EQ(2u, EndCallback.EndCalled);
}
#endif

struct SkipBodyConsumer : public clang::ASTConsumer {
  /// Skip the 'skipMe' function.
  virtual bool shouldSkipFunctionBody(Decl *D) {
    FunctionDecl *F = dyn_cast<FunctionDecl>(D);
    return F && F->getNameAsString() == "skipMe";
  }
};

struct SkipBodyAction : public clang::ASTFrontendAction {
  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &Compiler,
                                         StringRef) {
    Compiler.getFrontendOpts().SkipFunctionBodies = true;
    return new SkipBodyConsumer;
  }
};

TEST(runToolOnCode, TestSkipFunctionBody) {
  EXPECT_TRUE(runToolOnCode(new SkipBodyAction,
                            "int skipMe() { an_error_here }"));
  EXPECT_FALSE(runToolOnCode(new SkipBodyAction,
                             "int skipMeNot() { an_error_here }"));
}

TEST(runToolOnCodeWithArgs, TestNoDepFile) {
  llvm::SmallString<32> DepFilePath;
  ASSERT_FALSE(
      llvm::sys::fs::createTemporaryFile("depfile", "d", DepFilePath));
  std::vector<std::string> Args;
  Args.push_back("-MMD");
  Args.push_back("-MT");
  Args.push_back(DepFilePath.str());
  Args.push_back("-MF");
  Args.push_back(DepFilePath.str());
  EXPECT_TRUE(runToolOnCodeWithArgs(new SkipBodyAction, "", Args));
  EXPECT_FALSE(llvm::sys::fs::exists(DepFilePath.str()));
  EXPECT_FALSE(llvm::sys::fs::remove(DepFilePath.str()));
}

struct CheckSyntaxOnlyAdjuster: public ArgumentsAdjuster {
  bool &Found;
  bool &Ran;

  CheckSyntaxOnlyAdjuster(bool &Found, bool &Ran) : Found(Found), Ran(Ran) { }

  virtual CommandLineArguments
  Adjust(const CommandLineArguments &Args) override {
    Ran = true;
    for (unsigned I = 0, E = Args.size(); I != E; ++I) {
      if (Args[I] == "-fsyntax-only") {
        Found = true;
        break;
      }
    }
    return Args;
  }
};

TEST(ClangToolTest, ArgumentAdjusters) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());

  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
  Tool.mapVirtualFile("/a.cc", "void a() {}");

  std::unique_ptr<FrontendActionFactory> Action(
      newFrontendActionFactory<SyntaxOnlyAction>());

  bool Found = false;
  bool Ran = false;
  Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
  Tool.run(Action.get());
  EXPECT_TRUE(Ran);
  EXPECT_TRUE(Found);

  Ran = Found = false;
  Tool.clearArgumentsAdjusters();
  Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
  Tool.appendArgumentsAdjuster(new ClangSyntaxOnlyAdjuster());
  Tool.run(Action.get());
  EXPECT_TRUE(Ran);
  EXPECT_FALSE(Found);
}

#ifndef LLVM_ON_WIN32
TEST(ClangToolTest, BuildASTs) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());

  std::vector<std::string> Sources;
  Sources.push_back("/a.cc");
  Sources.push_back("/b.cc");
  ClangTool Tool(Compilations, Sources);

  Tool.mapVirtualFile("/a.cc", "void a() {}");
  Tool.mapVirtualFile("/b.cc", "void b() {}");

  std::vector<ASTUnit *> ASTs;
  EXPECT_EQ(0, Tool.buildASTs(ASTs));
  EXPECT_EQ(2u, ASTs.size());

  llvm::DeleteContainerPointers(ASTs);
}

struct TestDiagnosticConsumer : public DiagnosticConsumer {
  TestDiagnosticConsumer() : NumDiagnosticsSeen(0) {}
  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                                const Diagnostic &Info) {
    ++NumDiagnosticsSeen;
  }
  unsigned NumDiagnosticsSeen;
};

TEST(ClangToolTest, InjectDiagnosticConsumer) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
  Tool.mapVirtualFile("/a.cc", "int x = undeclared;");
  TestDiagnosticConsumer Consumer;
  Tool.setDiagnosticConsumer(&Consumer);
  std::unique_ptr<FrontendActionFactory> Action(
      newFrontendActionFactory<SyntaxOnlyAction>());
  Tool.run(Action.get());
  EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
}

TEST(ClangToolTest, InjectDiagnosticConsumerInBuildASTs) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
  Tool.mapVirtualFile("/a.cc", "int x = undeclared;");
  TestDiagnosticConsumer Consumer;
  Tool.setDiagnosticConsumer(&Consumer);
  std::vector<ASTUnit*> ASTs;
  Tool.buildASTs(ASTs);
  EXPECT_EQ(1u, ASTs.size());
  EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
}
#endif

} // end namespace tooling
} // end namespace clang
<|endoftext|>


<commit_before>// MediaInfo_Internal - All info about media files
// Copyright (C) 2002-2010 MediaArea.net SARL, Info@MediaArea.net
//
// This library is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library. If not, see <http://www.gnu.org/licenses/>.
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//---------------------------------------------------------------------------
// For user: you can disable or enable it
//#define MEDIAINFO_DEBUG
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// Compilation conditions
#include "MediaInfo/Setup.h"
#ifdef __BORLANDC__
    #pragma hdrstop
#endif
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#include "MediaInfo/Reader/Reader_File.h"
#include "MediaInfo/File__Analyze.h"
#include "ZenLib/FileName.h"
#include "ZenLib/File.h"
using namespace ZenLib;
using namespace std;
//---------------------------------------------------------------------------
// Debug stuff
#ifdef MEDIAINFO_DEBUG
    int64u Reader_File_Offset=0;
    int64u Reader_File_BytesRead_Total=0;
    int64u Reader_File_BytesRead=0;
    int64u Reader_File_Count=1;
    #include <iostream>
#endif // MEDIAINFO_DEBUG
//---------------------------------------------------------------------------

namespace MediaInfoLib
{

const size_t Buffer_NormalSize=/*188*7;//*/64*1024;
const size_t Buffer_NoJump=128*1024;

//---------------------------------------------------------------------------
size_t Reader_File::Format_Test(MediaInfo_Internal* MI, const String &File_Name)
{
    //With Parser MultipleParsing
    /*
    MI->Open_Buffer_Init((int64u)-1, File_Name);
    if (Format_Test_PerParser(MI, File_Name))
         return 1;
    return 0; //There is a problem
    */

    //Get the Extension
    Ztring Extension=FileName::Extension_Get(File_Name);
    Extension.MakeLowerCase();

    //Search the theorical format from extension
    InfoMap &FormatList=MediaInfoLib::Config.Format_Get();
    InfoMap::iterator Format=FormatList.begin();
    while (Format!=FormatList.end())
    {
        const Ztring &Extensions=FormatList.Get(Format->first, InfoFormat_Extensions);
        if (Extensions.find(Extension)!=Error)
        {
            if(Extension.size()==Extensions.size())
                break; //Only one extenion in the list
            if(Extensions.find(Extension+_T(" "))!=Error
            || Extensions.find(_T(" ")+Extension)!=Error)
                break;
        }
        Format++;
    }
    if (Format!=FormatList.end())
    {
        const Ztring &Parser=Format->second(InfoFormat_Parser);
        if (MI->SelectFromExtension(Parser))
        {
            //Test the theorical format
            if (Format_Test_PerParser(MI, File_Name)>0)
                 return 1;
        }
    }

    size_t ToReturn=MI->ListFormats(File_Name);
    return ToReturn;
}

//---------------------------------------------------------------------------
size_t Reader_File::Format_Test_PerParser(MediaInfo_Internal* MI, const String &File_Name)
{
    //Opening the file
    File F;
    F.Open(File_Name);
    if (!F.Opened_Get())
        return 0;

    //Buffer
    size_t Buffer_Size_Max=Buffer_NormalSize;
    int8u* Buffer=new int8u[Buffer_Size_Max];

    //Parser
    MI->Open_Buffer_Init(F.Size_Get(), File_Name);

    //Test the format with buffer
    bool StopAfterFilled=MI->Config.File_StopAfterFilled_Get();
    std::bitset<32> Status;
    do
    {
        //Seek (if needed)
        if (MI->Open_Buffer_Continue_GoTo_Get()!=(int64u)-1)
        {
            #ifdef MEDIAINFO_DEBUG
                std::cout<<std::hex<<Reader_File_Offset<<" - "<<Reader_File_Offset+Reader_File_BytesRead<<" : "<<std::dec<<Reader_File_BytesRead<<" bytes"<<std::endl;
                Reader_File_Offset=MI->Open_Buffer_Continue_GoTo_Get();
                Reader_File_BytesRead=0;
                Reader_File_Count++;
            #endif //MEDIAINFO_DEBUG

            if (MI->Open_Buffer_Continue_GoTo_Get()>=F.Size_Get())
                break; //Seek requested, but on a file bigger in theory than what is in the real file, we can't do this
            if (!(MI->Open_Buffer_Continue_GoTo_Get()>F.Position_Get() && MI->Open_Buffer_Continue_GoTo_Get()<F.Position_Get()+Buffer_NoJump)) //No smal jumps
            {
                 if (!F.GoTo(MI->Open_Buffer_Continue_GoTo_Get()))
                    break; //File is not seekable

                MI->Open_Buffer_Init((int64u)-1, F.Position_Get());
            }
        }

        //Buffering
        size_t Buffer_Size=F.Read(Buffer, Buffer_Size_Max);
        if (Buffer_Size==0)
            break; //Problem while reading

        #ifdef MEDIAINFO_DEBUG
            Reader_File_BytesRead_Total+=Buffer_Size;
            Reader_File_BytesRead+=Buffer_Size;
        #endif //MEDIAINFO_DEBUG

        //Parser
        Status=MI->Open_Buffer_Continue(Buffer, Buffer_Size);

        //Threading
        if (MI->IsTerminating())
            break; //Termination is requested
    }
    while (!(Status[File__Analyze::IsFinished] || (StopAfterFilled && Status[File__Analyze::IsFilled])));
    if (F.Size_Get()==0) //If Size==0, Status is never updated
        Status=MI->Open_Buffer_Continue(NULL, 0);

    #ifdef MEDIAINFO_DEBUG
        std::cout<<std::hex<<Reader_File_Offset<<" - "<<Reader_File_Offset+Reader_File_BytesRead<<" : "<<std::dec<<Reader_File_BytesRead<<" bytes"<<std::endl;
        std::cout<<"Total: "<<std::dec<<Reader_File_BytesRead_Total<<" bytes in "<<Reader_File_Count<<" blocks"<<std::endl;
    #endif //MEDIAINFO_DEBUG

    //File
    F.Close();

    //Buffer
    delete[] Buffer; //Buffer=NULL;

    //Is this file detected?
    if (!Status[File__Analyze::IsAccepted])
        return 0;

    MI->Open_Buffer_Finalize();
    return 1;
}

} //NameSpace

<commit_msg><commit_after>// MediaInfo_Internal - All info about media files
// Copyright (C) 2002-2010 MediaArea.net SARL, Info@MediaArea.net
//
// This library is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library. If not, see <http://www.gnu.org/licenses/>.
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//---------------------------------------------------------------------------
// For user: you can disable or enable it
//#define MEDIAINFO_DEBUG
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// Compilation conditions
#include "MediaInfo/Setup.h"
#ifdef __BORLANDC__
    #pragma hdrstop
#endif
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#include "MediaInfo/Reader/Reader_File.h"
#include "MediaInfo/File__Analyze.h"
#include "ZenLib/FileName.h"
#include "ZenLib/File.h"
using namespace ZenLib;
using namespace std;
//---------------------------------------------------------------------------
// Debug stuff
#ifdef MEDIAINFO_DEBUG
    int64u Reader_File_Offset=0;
    int64u Reader_File_BytesRead_Total=0;
    int64u Reader_File_BytesRead=0;
    int64u Reader_File_Count=1;
    #include <iostream>
#endif // MEDIAINFO_DEBUG
//---------------------------------------------------------------------------

namespace MediaInfoLib
{

const size_t Buffer_NormalSize=/*188*7;//*/64*1024;
const size_t Buffer_NoJump=128*1024;

//---------------------------------------------------------------------------
size_t Reader_File::Format_Test(MediaInfo_Internal* MI, const String &File_Name)
{
    #if MEDIAINFO_EVENTS
        {
            struct MediaInfo_Event_General_Start_0 Event;
            Event.EventCode=MediaInfo_EventCode_Create(MediaInfo_Parser_None, MediaInfo_Event_General_Start, 0);
            Event.Stream_Size=File::Size_Get(File_Name);
            MI->Config.Event_Send((const int8u*)&Event, sizeof(MediaInfo_Event_General_Start_0));
        }
    #endif //MEDIAINFO_EVENTS

    //With Parser MultipleParsing
    /*
    MI->Open_Buffer_Init((int64u)-1, File_Name);
    if (Format_Test_PerParser(MI, File_Name))
         return 1;
    return 0; //There is a problem
    */

    //Get the Extension
    Ztring Extension=FileName::Extension_Get(File_Name);
    Extension.MakeLowerCase();

    //Search the theorical format from extension
    InfoMap &FormatList=MediaInfoLib::Config.Format_Get();
    InfoMap::iterator Format=FormatList.begin();
    while (Format!=FormatList.end())
    {
        const Ztring &Extensions=FormatList.Get(Format->first, InfoFormat_Extensions);
        if (Extensions.find(Extension)!=Error)
        {
            if(Extension.size()==Extensions.size())
                break; //Only one extenion in the list
            if(Extensions.find(Extension+_T(" "))!=Error
            || Extensions.find(_T(" ")+Extension)!=Error)
                break;
        }
        Format++;
    }
    if (Format!=FormatList.end())
    {
        const Ztring &Parser=Format->second(InfoFormat_Parser);
        if (MI->SelectFromExtension(Parser))
        {
            //Test the theorical format
            if (Format_Test_PerParser(MI, File_Name)>0)
                 return 1;
        }
    }

    size_t ToReturn=MI->ListFormats(File_Name);
    return ToReturn;
}

//---------------------------------------------------------------------------
size_t Reader_File::Format_Test_PerParser(MediaInfo_Internal* MI, const String &File_Name)
{
    //Opening the file
    File F;
    F.Open(File_Name);
    if (!F.Opened_Get())
        return 0;

    //Buffer
    size_t Buffer_Size_Max=Buffer_NormalSize;
    int8u* Buffer=new int8u[Buffer_Size_Max];

    //Parser
    MI->Open_Buffer_Init(F.Size_Get(), File_Name);

    //Test the format with buffer
    bool StopAfterFilled=MI->Config.File_StopAfterFilled_Get();
    std::bitset<32> Status;
    do
    {
        //Seek (if needed)
        if (MI->Open_Buffer_Continue_GoTo_Get()!=(int64u)-1)
        {
            #ifdef MEDIAINFO_DEBUG
                std::cout<<std::hex<<Reader_File_Offset<<" - "<<Reader_File_Offset+Reader_File_BytesRead<<" : "<<std::dec<<Reader_File_BytesRead<<" bytes"<<std::endl;
                Reader_File_Offset=MI->Open_Buffer_Continue_GoTo_Get();
                Reader_File_BytesRead=0;
                Reader_File_Count++;
            #endif //MEDIAINFO_DEBUG

            if (MI->Open_Buffer_Continue_GoTo_Get()>=F.Size_Get())
                break; //Seek requested, but on a file bigger in theory than what is in the real file, we can't do this
            if (!(MI->Open_Buffer_Continue_GoTo_Get()>F.Position_Get() && MI->Open_Buffer_Continue_GoTo_Get()<F.Position_Get()+Buffer_NoJump)) //No smal jumps
            {
                 if (!F.GoTo(MI->Open_Buffer_Continue_GoTo_Get()))
                    break; //File is not seekable

                MI->Open_Buffer_Init((int64u)-1, F.Position_Get());
            }
        }

        //Buffering
        size_t Buffer_Size=F.Read(Buffer, Buffer_Size_Max);
        if (Buffer_Size==0)
            break; //Problem while reading

        #ifdef MEDIAINFO_DEBUG
            Reader_File_BytesRead_Total+=Buffer_Size;
            Reader_File_BytesRead+=Buffer_Size;
        #endif //MEDIAINFO_DEBUG

        //Parser
        Status=MI->Open_Buffer_Continue(Buffer, Buffer_Size);

        //Threading
        if (MI->IsTerminating())
            break; //Termination is requested
    }
    while (!(Status[File__Analyze::IsFinished] || (StopAfterFilled && Status[File__Analyze::IsFilled])));
    if (F.Size_Get()==0) //If Size==0, Status is never updated
        Status=MI->Open_Buffer_Continue(NULL, 0);

    #ifdef MEDIAINFO_DEBUG
        std::cout<<std::hex<<Reader_File_Offset<<" - "<<Reader_File_Offset+Reader_File_BytesRead<<" : "<<std::dec<<Reader_File_BytesRead<<" bytes"<<std::endl;
        std::cout<<"Total: "<<std::dec<<Reader_File_BytesRead_Total<<" bytes in "<<Reader_File_Count<<" blocks"<<std::endl;
    #endif //MEDIAINFO_DEBUG

    //File
    F.Close();

    //Buffer
    delete[] Buffer; //Buffer=NULL;

    //Is this file detected?
    if (!Status[File__Analyze::IsAccepted])
        return 0;

    MI->Open_Buffer_Finalize();
    return 1;
}

} //NameSpace

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"
#include "core/html/HTMLSummaryElement.h"

#include "bindings/core/v8/ExceptionStatePlaceholder.h"
#include "core/HTMLNames.h"
#include "core/events/KeyboardEvent.h"
#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLContentElement.h"
#include "core/html/HTMLDetailsElement.h"
#include "core/html/shadow/DetailsMarkerControl.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/rendering/RenderBlockFlow.h"

namespace blink {

using namespace HTMLNames;

PassRefPtrWillBeRawPtr<HTMLSummaryElement> HTMLSummaryElement::create(Document& document)
{
    RefPtrWillBeRawPtr<HTMLSummaryElement> summary = adoptRefWillBeNoop(new HTMLSummaryElement(document));
    summary->ensureUserAgentShadowRoot();
    return summary.release();
}

HTMLSummaryElement::HTMLSummaryElement(Document& document)
    : HTMLElement(summaryTag, document)
{
}

RenderObject* HTMLSummaryElement::createRenderer(RenderStyle*)
{
    return new RenderBlockFlow(this);
}

void HTMLSummaryElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
    RefPtr<DetailsMarkerControl> markerControl = DetailsMarkerControl::create(document());
    markerControl->setIdAttribute(ShadowElementNames::detailsMarker());
    root.appendChild(markerControl);
    root.appendChild(HTMLContentElement::create(document()));
}

HTMLDetailsElement* HTMLSummaryElement::detailsElement() const
{
    Node* parent = NodeRenderingTraversal::parent(*this);
    if (isHTMLDetailsElement(parent))
        return toHTMLDetailsElement(parent);
    return nullptr;
}

Element* HTMLSummaryElement::markerControl()
{
    return ensureUserAgentShadowRoot().getElementById(ShadowElementNames::detailsMarker());
}

bool HTMLSummaryElement::isMainSummary() const
{
    if (HTMLDetailsElement* details = detailsElement())
        return details->findMainSummary() == this;

    return false;
}

static bool isClickableControl(Node* node)
{
    if (!node->isElementNode())
        return false;
    Element* element = toElement(node);
    if (element->isFormControlElement())
        return true;
    Element* host = element->shadowHost();
    return host && host->isFormControlElement();
}

bool HTMLSummaryElement::supportsFocus() const
{
    return isMainSummary();
}

void HTMLSummaryElement::defaultEventHandler(Event* event)
{
    if (isMainSummary() && renderer()) {
        if (event->type() == EventTypeNames::DOMActivate && !isClickableControl(event->target()->toNode())) {
            if (HTMLDetailsElement* details = detailsElement())
                details->toggleOpen();
            event->setDefaultHandled();
            return;
        }

        if (event->isKeyboardEvent()) {
            if (event->type() == EventTypeNames::keydown && toKeyboardEvent(event)->keyIdentifier() == "U+0020") {
                setActive(true);
                // No setDefaultHandled() - IE dispatches a keypress in this case.
                return;
            }
            if (event->type() == EventTypeNames::keypress) {
                switch (toKeyboardEvent(event)->charCode()) {
                case '\r':
                    dispatchSimulatedClick(event);
                    event->setDefaultHandled();
                    return;
                case ' ':
                    // Prevent scrolling down the page.
                    event->setDefaultHandled();
                    return;
                }
            }
            if (event->type() == EventTypeNames::keyup && toKeyboardEvent(event)->keyIdentifier() == "U+0020") {
                if (active())
                    dispatchSimulatedClick(event);
                event->setDefaultHandled();
                return;
            }
        }
    }

    HTMLElement::defaultEventHandler(event);
}

bool HTMLSummaryElement::willRespondToMouseClickEvents()
{
    if (isMainSummary() && renderer())
        return true;

    return HTMLElement::willRespondToMouseClickEvents();
}

}
<commit_msg>Oilpan: Build fix after r186445<commit_after>/*
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "config.h"
#include "core/html/HTMLSummaryElement.h"

#include "bindings/core/v8/ExceptionStatePlaceholder.h"
#include "core/HTMLNames.h"
#include "core/events/KeyboardEvent.h"
#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLContentElement.h"
#include "core/html/HTMLDetailsElement.h"
#include "core/html/shadow/DetailsMarkerControl.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/rendering/RenderBlockFlow.h"

namespace blink {

using namespace HTMLNames;

PassRefPtrWillBeRawPtr<HTMLSummaryElement> HTMLSummaryElement::create(Document& document)
{
    RefPtrWillBeRawPtr<HTMLSummaryElement> summary = adoptRefWillBeNoop(new HTMLSummaryElement(document));
    summary->ensureUserAgentShadowRoot();
    return summary.release();
}

HTMLSummaryElement::HTMLSummaryElement(Document& document)
    : HTMLElement(summaryTag, document)
{
}

RenderObject* HTMLSummaryElement::createRenderer(RenderStyle*)
{
    return new RenderBlockFlow(this);
}

void HTMLSummaryElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
    RefPtrWillBeRawPtr<DetailsMarkerControl> markerControl = DetailsMarkerControl::create(document());
    markerControl->setIdAttribute(ShadowElementNames::detailsMarker());
    root.appendChild(markerControl);
    root.appendChild(HTMLContentElement::create(document()));
}

HTMLDetailsElement* HTMLSummaryElement::detailsElement() const
{
    Node* parent = NodeRenderingTraversal::parent(*this);
    if (isHTMLDetailsElement(parent))
        return toHTMLDetailsElement(parent);
    return nullptr;
}

Element* HTMLSummaryElement::markerControl()
{
    return ensureUserAgentShadowRoot().getElementById(ShadowElementNames::detailsMarker());
}

bool HTMLSummaryElement::isMainSummary() const
{
    if (HTMLDetailsElement* details = detailsElement())
        return details->findMainSummary() == this;

    return false;
}

static bool isClickableControl(Node* node)
{
    if (!node->isElementNode())
        return false;
    Element* element = toElement(node);
    if (element->isFormControlElement())
        return true;
    Element* host = element->shadowHost();
    return host && host->isFormControlElement();
}

bool HTMLSummaryElement::supportsFocus() const
{
    return isMainSummary();
}

void HTMLSummaryElement::defaultEventHandler(Event* event)
{
    if (isMainSummary() && renderer()) {
        if (event->type() == EventTypeNames::DOMActivate && !isClickableControl(event->target()->toNode())) {
            if (HTMLDetailsElement* details = detailsElement())
                details->toggleOpen();
            event->setDefaultHandled();
            return;
        }

        if (event->isKeyboardEvent()) {
            if (event->type() == EventTypeNames::keydown && toKeyboardEvent(event)->keyIdentifier() == "U+0020") {
                setActive(true);
                // No setDefaultHandled() - IE dispatches a keypress in this case.
                return;
            }
            if (event->type() == EventTypeNames::keypress) {
                switch (toKeyboardEvent(event)->charCode()) {
                case '\r':
                    dispatchSimulatedClick(event);
                    event->setDefaultHandled();
                    return;
                case ' ':
                    // Prevent scrolling down the page.
                    event->setDefaultHandled();
                    return;
                }
            }
            if (event->type() == EventTypeNames::keyup && toKeyboardEvent(event)->keyIdentifier() == "U+0020") {
                if (active())
                    dispatchSimulatedClick(event);
                event->setDefaultHandled();
                return;
            }
        }
    }

    HTMLElement::defaultEventHandler(event);
}

bool HTMLSummaryElement::willRespondToMouseClickEvents()
{
    if (isMainSummary() && renderer())
        return true;

    return HTMLElement::willRespondToMouseClickEvents();
}

}
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>
#include <string>
#include <memory>
#include <chrono>

#include <windows.h>
#include <psapi.h> //GetModuleFileNameEx
#include <TlHelp32.h>

// Setting DLL access controls
#include <AccCtrl.h>
#include <Aclapi.h>
#include <Sddl.h>

// UWP
#include <atlbase.h>
#include <appmodel.h>

// IPC
#include <UWP/DumperIPC.hpp>

const wchar_t* DLLFile = L"UWPDumper.dll";

void SetAccessControl(
	const std::wstring& ExecutableName,
	const wchar_t* AccessString
);

bool DLLInjectRemote(uint32_t ProcessID, const std::wstring& DLLpath);

std::wstring GetRunningDirectory();

using ThreadCallback = bool(*)(
	std::uint32_t ThreadID,
	void* Data
);

void IterateThreads(ThreadCallback ThreadProc, std::uint32_t ProcessID, void* Data)
{
	void* hSnapShot = CreateToolhelp32Snapshot(
		TH32CS_SNAPTHREAD,
		ProcessID
	);

	if( hSnapShot == INVALID_HANDLE_VALUE )
	{
		return;
	}

	THREADENTRY32 ThreadEntry = { 0 };
	ThreadEntry.dwSize = sizeof(THREADENTRY32);
	Thread32First(hSnapShot, &ThreadEntry);
	do
	{
		if( ThreadEntry.th32OwnerProcessID == ProcessID )
		{
			const bool Continue = ThreadProc(
				ThreadEntry.th32ThreadID,
				Data
			);
			if( Continue == false )
			{
				break;
			}
		}
	}
	while( Thread32Next(hSnapShot, &ThreadEntry) );

	CloseHandle(hSnapShot);
}

int main()
{
	// Enable VT100
	const auto Handle = GetStdHandle(STD_OUTPUT_HANDLE);
	DWORD ConsoleMode;
	GetConsoleMode(
		Handle,
		&ConsoleMode
	);
	SetConsoleMode(
		Handle,
		ConsoleMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING
	);
	SetConsoleOutputCP(437);

	std::wcout << "\033[92mUWPInjector Build date (" << __DATE__ << " : " << __TIME__ << ')' << std::endl;
	std::wcout << "\033[96m\t-https://github.com/Wunkolo/UWPDumper\n";
	std::wcout << "\033[95m" << std::wstring(80, '-') << std::endl;

	std::uint32_t ProcessID = 0;

	IPC::SetClientProcess(GetCurrentProcessId());

	std::cout << "\033[93mCurrently running UWP Apps:" << std::endl;
	void* ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32 ProcessEntry;
	ProcessEntry.dwSize = sizeof(PROCESSENTRY32);

	if( Process32First(ProcessSnapshot, &ProcessEntry) )
	{
		while( Process32Next(ProcessSnapshot, &ProcessEntry) )
		{
			void* ProcessHandle = OpenProcess(
				PROCESS_QUERY_LIMITED_INFORMATION,
				false,
				ProcessEntry.th32ProcessID
			);
			if( ProcessHandle )
			{
				std::uint32_t NameLength = 0;
				std::int32_t ProcessCode = GetPackageFamilyName(
					ProcessHandle,
					&NameLength,
					nullptr
				);
				if( NameLength )
				{
					std::wcout
						<< "\033[92m"
						<< std::setw(12)
						<< ProcessEntry.th32ProcessID;

					std::wcout
						<< "\033[96m"
						<< " | "
						<< ProcessEntry.szExeFile << " :\n\t\t-";
					std::unique_ptr<wchar_t[]> PackageName(new wchar_t[NameLength]());

					ProcessCode = GetPackageFamilyName(
						ProcessHandle,
						&NameLength,
						PackageName.get()
					);

					if( ProcessCode != ERROR_SUCCESS )
					{
						std::wcout << "GetPackageFamilyName Error: " << ProcessCode;
					}

					std::wcout << PackageName.get() << std::endl;

					PackageName.reset();
				}
			}
			CloseHandle(ProcessHandle);
		}
	}
	else
	{
		std::cout << "\033[91mUnable to iterate active processes" << std::endl;
		system("pause");
		return EXIT_FAILURE;
	}
	std::cout << "\033[93mEnter ProcessID: \033[92m";
	std::cin >> ProcessID;

	SetAccessControl(GetRunningDirectory() + L'\\' + DLLFile, L"S-1-15-2-1");

	IPC::SetTargetProcess(ProcessID);

	std::cout << "\033[93mInjecting into remote process: ";
	if( !DLLInjectRemote(ProcessID, GetRunningDirectory() + L'\\' + DLLFile) )
	{
		std::cout << "\033[91mFailed" << std::endl;
		system("pause");
		return EXIT_FAILURE;
	}
	std::cout << "\033[92mSuccess!" << std::endl;

	std::cout << "\033[93mWaiting for remote thread IPC:" << std::endl;
	std::chrono::high_resolution_clock::time_point ThreadTimeout = std::chrono::high_resolution_clock::now() + std::chrono::seconds(5);
	while( IPC::GetTargetThread() == IPC::InvalidThread )
	{
		if( std::chrono::high_resolution_clock::now() >= ThreadTimeout )
		{
			std::cout << "\033[91mRemote thread wait timeout: Unable to find target thread" << std::endl;
			system("pause");
			return EXIT_FAILURE;
		}
	}

	std::cout << "Remote Dumper thread found: 0x" << std::hex << IPC::GetTargetThread() << std::endl;

	std::cout << "\033[0m" << std::flush;
	while( IPC::GetTargetThread() != IPC::InvalidThread )
	{
		while( IPC::MessageCount() > 0 )
		{
			std::wcout << IPC::PopMessage() << "\033[0m";
		}
	}
	system("pause");
	return EXIT_SUCCESS;
}

void SetAccessControl(const std::wstring& ExecutableName, const wchar_t* AccessString)
{
	PSECURITY_DESCRIPTOR SecurityDescriptor = nullptr;
	EXPLICIT_ACCESSW ExplicitAccess = { 0 };

	ACL* AccessControlCurrent = nullptr;
	ACL* AccessControlNew = nullptr;

	SECURITY_INFORMATION SecurityInfo = DACL_SECURITY_INFORMATION;
	PSID SecurityIdentifier = nullptr;

	if( GetNamedSecurityInfoW(
		ExecutableName.c_str(),
		SE_FILE_OBJECT,
		DACL_SECURITY_INFORMATION,
		nullptr,
		nullptr,
		&AccessControlCurrent,
		nullptr,
		&SecurityDescriptor) == ERROR_SUCCESS
	)
	{
		ConvertStringSidToSidW(AccessString, &SecurityIdentifier);
		if( SecurityIdentifier != nullptr )
		{
			ExplicitAccess.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE;
			ExplicitAccess.grfAccessMode = SET_ACCESS;
			ExplicitAccess.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
			ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
			ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
			ExplicitAccess.Trustee.ptstrName = reinterpret_cast<wchar_t*>(SecurityIdentifier);

			if( SetEntriesInAclW(
				1,
				&ExplicitAccess,
				AccessControlCurrent,
				&AccessControlNew) == ERROR_SUCCESS )
			{
				SetNamedSecurityInfoW(
					const_cast<wchar_t*>(ExecutableName.c_str()),
					SE_FILE_OBJECT,
					SecurityInfo,
					nullptr,
					nullptr,
					AccessControlNew,
					nullptr
				);
			}
		}
	}
	if( SecurityDescriptor )
	{
		LocalFree(reinterpret_cast<HLOCAL>(SecurityDescriptor));
	}
	if( AccessControlNew )
	{
		LocalFree(reinterpret_cast<HLOCAL>(AccessControlNew));
	}
}

bool DLLInjectRemote(uint32_t ProcessID, const std::wstring& DLLpath)
{
	const std::size_t DLLPathSize = ((DLLpath.size() + 1) * sizeof(wchar_t));
	std::uint32_t Result;
	if( !ProcessID )
	{
		std::wcout << "Invalid Process ID: " << ProcessID << std::endl;
		return false;
	}

	if( GetFileAttributesW(DLLpath.c_str()) == INVALID_FILE_ATTRIBUTES )
	{
		std::wcout << "DLL file: " << DLLpath << " does not exists" << std::endl;
		return false;
	}

	SetAccessControl(DLLpath, L"S-1-15-2-1");

	void* ProcLoadLibrary = reinterpret_cast<void*>(
		GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW"));

	if( !ProcLoadLibrary )
	{
		std::wcout << "Unable to find LoadLibraryW procedure" << std::endl;
		return false;
	}

	void* Process = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID);
	if( Process == nullptr )
	{
		std::wcout << "Unable to open process ID" << ProcessID << " for writing" << std::endl;
		return false;
	}
	void* VirtualAlloc = reinterpret_cast<void*>(
		VirtualAllocEx(
			Process,
			nullptr,
			DLLPathSize,
			MEM_RESERVE | MEM_COMMIT,
			PAGE_READWRITE
		)
	);

	if( VirtualAlloc == nullptr )
	{
		std::wcout << "Unable to remotely allocate memory" << std::endl;
		CloseHandle(Process);
		return false;
	}

	std::size_t BytesWritten = 0;
	Result = WriteProcessMemory(
		Process,
		VirtualAlloc,
		DLLpath.data(),
		DLLPathSize,
		&BytesWritten
	);

	if( Result == 0 )
	{
		std::wcout << "Unable to write process memory" << std::endl;
		CloseHandle(Process);
		return false;
	}

	if( BytesWritten != DLLPathSize )
	{
		std::wcout << "Failed to write remote DLL path name" << std::endl;
		CloseHandle(Process);
		return false;
	}

	void* RemoteThread =
		CreateRemoteThread(
			Process,
			nullptr,
			0,
			reinterpret_cast<LPTHREAD_START_ROUTINE>(ProcLoadLibrary),
			VirtualAlloc,
			0,
			nullptr
		);

	// Wait for remote thread to finish
	if( RemoteThread )
	{
		// Explicitly wait for LoadLibraryW to complete before releasing memory
		// avoids causing a remote memory leak
		WaitForSingleObject(RemoteThread, INFINITE);
		CloseHandle(RemoteThread);
	}
	else
	{
		// Failed to create thread
		std::wcout << "Unable to create remote thread" << std::endl;
	}

	VirtualFreeEx(Process, VirtualAlloc, 0, MEM_RELEASE);
	CloseHandle(Process);
	return true;
}

std::wstring GetRunningDirectory()
{
	wchar_t RunPath[MAX_PATH];
	GetModuleFileNameW(GetModuleHandleW(nullptr), RunPath, MAX_PATH);
	PathRemoveFileSpecW(RunPath);
	return std::wstring(RunPath);
}
<commit_msg>Add VT100 line drawing characters<commit_after>#include <iostream>
#include <iomanip>
#include <string>
#include <memory>
#include <chrono>

#include <windows.h>
#include <psapi.h> //GetModuleFileNameEx
#include <TlHelp32.h>

// Setting DLL access controls
#include <AccCtrl.h>
#include <Aclapi.h>
#include <Sddl.h>

// UWP
#include <atlbase.h>
#include <appmodel.h>

// IPC
#include <UWP/DumperIPC.hpp>

const wchar_t* DLLFile = L"UWPDumper.dll";

void SetAccessControl(
	const std::wstring& ExecutableName,
	const wchar_t* AccessString
);

bool DLLInjectRemote(uint32_t ProcessID, const std::wstring& DLLpath);

std::wstring GetRunningDirectory();

using ThreadCallback = bool(*)(
	std::uint32_t ThreadID,
	void* Data
);

void IterateThreads(ThreadCallback ThreadProc, std::uint32_t ProcessID, void* Data)
{
	void* hSnapShot = CreateToolhelp32Snapshot(
		TH32CS_SNAPTHREAD,
		ProcessID
	);

	if( hSnapShot == INVALID_HANDLE_VALUE )
	{
		return;
	}

	THREADENTRY32 ThreadEntry = { 0 };
	ThreadEntry.dwSize = sizeof(THREADENTRY32);
	Thread32First(hSnapShot, &ThreadEntry);
	do
	{
		if( ThreadEntry.th32OwnerProcessID == ProcessID )
		{
			const bool Continue = ThreadProc(
				ThreadEntry.th32ThreadID,
				Data
			);
			if( Continue == false )
			{
				break;
			}
		}
	}
	while( Thread32Next(hSnapShot, &ThreadEntry) );

	CloseHandle(hSnapShot);
}

int main()
{
	// Enable VT100
	DWORD ConsoleMode;
	GetConsoleMode(
		GetStdHandle(STD_OUTPUT_HANDLE),
		&ConsoleMode
	);
	SetConsoleMode(
		GetStdHandle(STD_OUTPUT_HANDLE),
		ConsoleMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING
	);
	SetConsoleOutputCP(437);

	std::wcout << "\033[92mUWPInjector Build date (" << __DATE__ << " : " << __TIME__ << ')' << std::endl;
	std::wcout << "\033[96m\t\033(0m\033(Bhttps://github.com/Wunkolo/UWPDumper\n";
	std::wcout << "\033[95m\033(0" << std::wstring(80, 'q') << "\033(B" << std::endl;

	std::uint32_t ProcessID = 0;

	IPC::SetClientProcess(GetCurrentProcessId());

	std::cout << "\033[93mCurrently running UWP Apps:" << std::endl;
	void* ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32 ProcessEntry;
	ProcessEntry.dwSize = sizeof(PROCESSENTRY32);

	if( Process32First(ProcessSnapshot, &ProcessEntry) )
	{
		while( Process32Next(ProcessSnapshot, &ProcessEntry) )
		{
			void* ProcessHandle = OpenProcess(
				PROCESS_QUERY_LIMITED_INFORMATION,
				false,
				ProcessEntry.th32ProcessID
			);
			if( ProcessHandle )
			{
				std::uint32_t NameLength = 0;
				std::int32_t ProcessCode = GetPackageFamilyName(
					ProcessHandle,
					&NameLength,
					nullptr
				);
				if( NameLength )
				{
					std::wcout
						<< "\033[92m"
						<< std::setw(12)
						<< ProcessEntry.th32ProcessID;

					std::wcout
						<< "\033[96m"
						<< " \033(0x\033(B "
						<< ProcessEntry.szExeFile << " :\n\t\t\033(0m\033(B";
					std::unique_ptr<wchar_t[]> PackageName(new wchar_t[NameLength]());

					ProcessCode = GetPackageFamilyName(
						ProcessHandle,
						&NameLength,
						PackageName.get()
					);

					if( ProcessCode != ERROR_SUCCESS )
					{
						std::wcout << "GetPackageFamilyName Error: " << ProcessCode;
					}

					std::wcout << PackageName.get() << std::endl;

					PackageName.reset();
				}
			}
			CloseHandle(ProcessHandle);
		}
	}
	else
	{
		std::cout << "\033[91mUnable to iterate active processes" << std::endl;
		system("pause");
		return EXIT_FAILURE;
	}
	std::cout << "\033[93mEnter ProcessID: \033[92m";
	std::cin >> ProcessID;

	SetAccessControl(GetRunningDirectory() + L'\\' + DLLFile, L"S-1-15-2-1");

	IPC::SetTargetProcess(ProcessID);

	std::cout << "\033[93mInjecting into remote process: ";
	if( !DLLInjectRemote(ProcessID, GetRunningDirectory() + L'\\' + DLLFile) )
	{
		std::cout << "\033[91mFailed" << std::endl;
		system("pause");
		return EXIT_FAILURE;
	}
	std::cout << "\033[92mSuccess!" << std::endl;

	std::cout << "\033[93mWaiting for remote thread IPC:" << std::endl;
	std::chrono::high_resolution_clock::time_point ThreadTimeout = std::chrono::high_resolution_clock::now() + std::chrono::seconds(5);
	while( IPC::GetTargetThread() == IPC::InvalidThread )
	{
		if( std::chrono::high_resolution_clock::now() >= ThreadTimeout )
		{
			std::cout << "\033[91mRemote thread wait timeout: Unable to find target thread" << std::endl;
			system("pause");
			return EXIT_FAILURE;
		}
	}

	std::cout << "Remote Dumper thread found: 0x" << std::hex << IPC::GetTargetThread() << std::endl;

	std::cout << "\033[0m" << std::flush;
	while( IPC::GetTargetThread() != IPC::InvalidThread )
	{
		while( IPC::MessageCount() > 0 )
		{
			std::wcout << IPC::PopMessage() << "\033[0m";
		}
	}
	system("pause");
	return EXIT_SUCCESS;
}

void SetAccessControl(const std::wstring& ExecutableName, const wchar_t* AccessString)
{
	PSECURITY_DESCRIPTOR SecurityDescriptor = nullptr;
	EXPLICIT_ACCESSW ExplicitAccess = { 0 };

	ACL* AccessControlCurrent = nullptr;
	ACL* AccessControlNew = nullptr;

	SECURITY_INFORMATION SecurityInfo = DACL_SECURITY_INFORMATION;
	PSID SecurityIdentifier = nullptr;

	if(
		GetNamedSecurityInfoW(
			ExecutableName.c_str(),
			SE_FILE_OBJECT,
			DACL_SECURITY_INFORMATION,
			nullptr,
			nullptr,
			&AccessControlCurrent,
			nullptr,
			&SecurityDescriptor
		) == ERROR_SUCCESS
	)
	{
		ConvertStringSidToSidW(AccessString, &SecurityIdentifier);
		if( SecurityIdentifier != nullptr )
		{
			ExplicitAccess.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE;
			ExplicitAccess.grfAccessMode = SET_ACCESS;
			ExplicitAccess.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
			ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
			ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
			ExplicitAccess.Trustee.ptstrName = reinterpret_cast<wchar_t*>(SecurityIdentifier);

			if(
				SetEntriesInAclW(
					1,
					&ExplicitAccess,
					AccessControlCurrent,
					&AccessControlNew
				) == ERROR_SUCCESS
			)
			{
				SetNamedSecurityInfoW(
					const_cast<wchar_t*>(ExecutableName.c_str()),
					SE_FILE_OBJECT,
					SecurityInfo,
					nullptr,
					nullptr,
					AccessControlNew,
					nullptr
				);
			}
		}
	}
	if( SecurityDescriptor )
	{
		LocalFree(reinterpret_cast<HLOCAL>(SecurityDescriptor));
	}
	if( AccessControlNew )
	{
		LocalFree(reinterpret_cast<HLOCAL>(AccessControlNew));
	}
}

bool DLLInjectRemote(uint32_t ProcessID, const std::wstring& DLLpath)
{
	const std::size_t DLLPathSize = ((DLLpath.size() + 1) * sizeof(wchar_t));
	std::uint32_t Result;
	if( !ProcessID )
	{
		std::wcout << "Invalid Process ID: " << ProcessID << std::endl;
		return false;
	}

	if( GetFileAttributesW(DLLpath.c_str()) == INVALID_FILE_ATTRIBUTES )
	{
		std::wcout << "DLL file: " << DLLpath << " does not exists" << std::endl;
		return false;
	}

	SetAccessControl(DLLpath, L"S-1-15-2-1");

	void* ProcLoadLibrary = reinterpret_cast<void*>(
		GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW")
	);

	if( !ProcLoadLibrary )
	{
		std::wcout << "Unable to find LoadLibraryW procedure" << std::endl;
		return false;
	}

	void* Process = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID);
	if( Process == nullptr )
	{
		std::wcout << "Unable to open process ID" << ProcessID << " for writing" << std::endl;
		return false;
	}
	void* VirtualAlloc = reinterpret_cast<void*>(
		VirtualAllocEx(
			Process,
			nullptr,
			DLLPathSize,
			MEM_RESERVE | MEM_COMMIT,
			PAGE_READWRITE
		)
	);

	if( VirtualAlloc == nullptr )
	{
		std::wcout << "Unable to remotely allocate memory" << std::endl;
		CloseHandle(Process);
		return false;
	}

	std::size_t BytesWritten = 0;
	Result = WriteProcessMemory(
		Process,
		VirtualAlloc,
		DLLpath.data(),
		DLLPathSize,
		&BytesWritten
	);

	if( Result == 0 )
	{
		std::wcout << "Unable to write process memory" << std::endl;
		CloseHandle(Process);
		return false;
	}

	if( BytesWritten != DLLPathSize )
	{
		std::wcout << "Failed to write remote DLL path name" << std::endl;
		CloseHandle(Process);
		return false;
	}

	void* RemoteThread =
		CreateRemoteThread(
			Process,
			nullptr,
			0,
			reinterpret_cast<LPTHREAD_START_ROUTINE>(ProcLoadLibrary),
			VirtualAlloc,
			0,
			nullptr
		);

	// Wait for remote thread to finish
	if( RemoteThread )
	{
		// Explicitly wait for LoadLibraryW to complete before releasing memory
		// avoids causing a remote memory leak
		WaitForSingleObject(RemoteThread, INFINITE);
		CloseHandle(RemoteThread);
	}
	else
	{
		// Failed to create thread
		std::wcout << "Unable to create remote thread" << std::endl;
	}

	VirtualFreeEx(Process, VirtualAlloc, 0, MEM_RELEASE);
	CloseHandle(Process);
	return true;
}

std::wstring GetRunningDirectory()
{
	wchar_t RunPath[MAX_PATH];
	GetModuleFileNameW(GetModuleHandleW(nullptr), RunPath, MAX_PATH);
	PathRemoveFileSpecW(RunPath);
	return std::wstring(RunPath);
}
<|endoftext|>


<commit_before>// **********************************************************************************
// OLED display management source file for remora project
// **********************************************************************************
// Creative Commons Attrib Share-Alike License
// You are free to use/extend but please abide with the CC-BY-SA license:
// http://creativecommons.org/licenses/by-sa/4.0/
//
// Written by Charles-Henri Hallard (http://hallard.me)
//
// History : V1.00 2015-01-22 - First release
//
// 15/09/2015 Charles-Henri Hallard : Ajout compatibilité ESP8266
//
// All text above must be included in any redistribution.
// **********************************************************************************
#include "display.h"

// Instantiate OLED (no reset pin)
Adafruit_SSD1306 display(-1);

// Différents état de l'affichage possible
const char * screen_name[] = {"RF", "System", "Teleinfo"};
screen_e screen_state;

/* ======================================================================
Function: displaySplash
Purpose : display setup splash screen OLED screen
Input   : -
Output  : -
Comments: -
====================================================================== */
void display_splash(void)
{
  display.clearDisplay() ;
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.setTextSize(2);
  display.print("  REMORA\n");
  display.print("Fil Pilote");
  display.display();
}

/* ======================================================================
Function: displaySys
Purpose : display Téléinfo related information on OLED screen
Input   : -
Output  : -
Comments: -
====================================================================== */
void displayTeleinfo(void)
{
  uint percent = 0;

  // Effacer le buffer de l'affichage
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);

  // si en heure pleine inverser le texte sur le compteur HP
  if (ptec == PTEC_HP )
    display.setTextColor(BLACK, WHITE); // 'inverted' text

  display.print("Pleines ");
  display.printf("%09ld\n", myindexHP);
  display.setTextColor(WHITE); // normaltext

  // si en heure creuse inverser le texte sur le compteur HC
  if (ptec == PTEC_HC )
    display.setTextColor(BLACK, WHITE); // 'inverted' text

  display.print("Creuses ");
  display.printf("%09ld\n", myindexHC);
  display.setTextColor(WHITE); // normaltext

  // Poucentrage de la puissance totale
  percent = (uint) myiInst * 100 / myisousc ;

  //Serial.print("myiInst="); Serial.print(myiInst);
  //Serial.print("  myisousc="); Serial.print(myisousc);
  //Serial.print("  percent="); Serial.println(percent);

  // Information additionelles
  display.printf("%d W %d%%  %3d A", mypApp, percent, myiInst);

  // etat des fils pilotes
  display.setCursor(0,32);
  display.setTextSize(2);
  #ifdef SPARK
  display.printf("%02d:%02d:%02d",Time.hour(),Time.minute(),Time.second());
  #endif

  display.setCursor(0,48);
  display.printf("%s  %c", etatFP, etatrelais+'0' );

  // Bargraphe de puissance
  display.drawVerticalBargraph(114,0,12,40,1, percent);

  display.setTextColor(BLACK, WHITE); // 'inverted' text
}

/* ======================================================================
Function: displaySys
Purpose : display system related information on OLED screen
Input   : -
Output  : -
Comments: -
====================================================================== */
void displaySys(void)
{
  // To DO
}

/* ======================================================================
Function: displayRf
Purpose : display RF related information on OLED screen
Input   : -
Output  : -
Comments: -
====================================================================== */
void displayRf(void)
{/*
  int16_t percent;

  display.printf("RF69 G%d I%d", NETWORK_ID, NODE_ID);

  // rssi range 0 (0%) to 115 (100%)
  percent = ((module.rssi+115) * 100) / 115;

  //displayClearline(current_line);
  //display.setCursor(0,current_line);
  //display.print(F("["));
  //display.print(module.size);
  display.printf("G%d I%d %d%%\n", module.groupid, module.nodeid,percent);
  display.printf("[%02X] ", module.size);

  byte n = module.size;
  uint8_t * p = module.data;

  // Max 4 data per line on LCD
  if (n>12)
    n=12;

  for (byte i = 0; i < n; ++i)
    display.printf("%02X ", *p++);

  //display.drawHorizontalBargraph(106,current_line+1, 22, 6, 1, percent);

  display.printf("%d%% ", percent);
  */
}

/* ======================================================================
Function: display_setup
Purpose : prepare and init stuff, configuration, ..
Input   : -
Output  : true if OLED module found, false otherwise
Comments: -
====================================================================== */
bool display_setup(void)
{
  bool ret = false;

  Serial.print("Initializing OLED...");

  // Par defaut affichage des infos de téléinfo
  screen_state = screen_teleinfo;

  // Init et detection des modules I2C
  if (!i2c_detect(OLED_I2C_ADDRESS)) {
    Serial.println("Not found!");
  } else {
    Serial.println("OK!");

    // initialize with the I2C addr for the 128x64
    display.begin(OLED_I2C_ADDRESS);
    display.clearDisplay() ;
    display.display();
    ret = true;
  }

  return (ret);
}

/* ======================================================================
Function: display_loop
Purpose : main loop for OLED display
Input   : -
Output  : -
Comments: -
====================================================================== */
void display_loop(void)
{
  display.setCursor(0,0);

  if (screen_state==screen_sys)
    displaySys();
  else if (screen_state==screen_rf)
    displayRf();
  else if (screen_state==screen_teleinfo)
    displayTeleinfo();

  // Affichage physique sur l'écran
  display.display();
}
<commit_msg>Heartbeat si pas de Teleinfo<commit_after>// **********************************************************************************
// OLED display management source file for remora project
// **********************************************************************************
// Creative Commons Attrib Share-Alike License
// You are free to use/extend but please abide with the CC-BY-SA license:
// http://creativecommons.org/licenses/by-sa/4.0/
//
// Written by Charles-Henri Hallard (http://hallard.me)
//
// History : V1.00 2015-01-22 - First release
//
// 15/09/2015 Charles-Henri Hallard : Ajout compatibilité ESP8266
//
// All text above must be included in any redistribution.
// **********************************************************************************
#include "display.h"

// Instantiate OLED (no reset pin)
Adafruit_SSD1306 display(-1);

// Différents état de l'affichage possible
const char * screen_name[] = {"RF", "System", "Teleinfo"};
screen_e screen_state;

/* ======================================================================
Function: displaySplash
Purpose : display setup splash screen OLED screen
Input   : -
Output  : -
Comments: -
====================================================================== */
void display_splash(void)
{
  display.clearDisplay() ;
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.setTextSize(2);
  display.print("  REMORA\n");
  display.print("Fil Pilote");
  display.display();
}

/* ======================================================================
Function: displaySys
Purpose : display Téléinfo related information on OLED screen
Input   : -
Output  : -
Comments: -
====================================================================== */
void displayTeleinfo(void)
{
  uint percent = 0;

  // Effacer le buffer de l'affichage
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);

  // si en heure pleine inverser le texte sur le compteur HP
  if (ptec == PTEC_HP )
    display.setTextColor(BLACK, WHITE); // 'inverted' text

  display.print("Pleines ");
  display.printf("%09ld\n", myindexHP);
  display.setTextColor(WHITE); // normaltext

  // si en heure creuse inverser le texte sur le compteur HC
  if (ptec == PTEC_HC )
    display.setTextColor(BLACK, WHITE); // 'inverted' text

  display.print("Creuses ");
  display.printf("%09ld\n", myindexHC);
  display.setTextColor(WHITE); // normaltext

  // Poucentrage de la puissance totale
  percent = (uint) myiInst * 100 / myisousc ;

  //Serial.print("myiInst="); Serial.print(myiInst);
  //Serial.print("  myisousc="); Serial.print(myisousc);
  //Serial.print("  percent="); Serial.println(percent);

  // Information additionelles
  display.printf("%d W %d%%  %3d A", mypApp, percent, myiInst);

  // etat des fils pilotes
  display.setCursor(0,32);
  display.setTextSize(2);
  #ifdef SPARK
  display.printf("%02d:%02d:%02d",Time.hour(),Time.minute(),Time.second());
  #endif

  display.setCursor(0,48);
  display.printf("%s  %c", etatFP, etatrelais+'0' );

  // Bargraphe de puissance
  display.drawVerticalBargraph(114,0,12,40,1, percent);

  display.setTextColor(BLACK, WHITE); // 'inverted' text
}

/* ======================================================================
Function: displaySys
Purpose : display system related information on OLED screen
Input   : -
Output  : -
Comments: -
====================================================================== */
void displaySys(void)
{
  // To DO
}

/* ======================================================================
Function: displayRf
Purpose : display RF related information on OLED screen
Input   : -
Output  : -
Comments: -
====================================================================== */
void displayRf(void)
{/*
  int16_t percent;

  display.printf("RF69 G%d I%d", NETWORK_ID, NODE_ID);

  // rssi range 0 (0%) to 115 (100%)
  percent = ((module.rssi+115) * 100) / 115;

  //displayClearline(current_line);
  //display.setCursor(0,current_line);
  //display.print(F("["));
  //display.print(module.size);
  display.printf("G%d I%d %d%%\n", module.groupid, module.nodeid,percent);
  display.printf("[%02X] ", module.size);

  byte n = module.size;
  uint8_t * p = module.data;

  // Max 4 data per line on LCD
  if (n>12)
    n=12;

  for (byte i = 0; i < n; ++i)
    display.printf("%02X ", *p++);

  //display.drawHorizontalBargraph(106,current_line+1, 22, 6, 1, percent);

  display.printf("%d%% ", percent);
  */
}

/* ======================================================================
Function: display_setup
Purpose : prepare and init stuff, configuration, ..
Input   : -
Output  : true if OLED module found, false otherwise
Comments: -
====================================================================== */
bool display_setup(void)
{
  bool ret = false;

  Serial.print("Initializing OLED...");

  // Par defaut affichage des infos de téléinfo
  screen_state = screen_teleinfo;

  // Init et detection des modules I2C
  if (!i2c_detect(OLED_I2C_ADDRESS)) {
    Serial.println("Not found!");
  } else {
    Serial.println("OK!");

    // initialize with the I2C addr for the 128x64
    display.begin(OLED_I2C_ADDRESS);
    display.clearDisplay() ;
    display.display();
    ret = true;
  }

  return (ret);
}

/* ======================================================================
Function: display_loop
Purpose : main loop for OLED display
Input   : -
Output  : -
Comments: -
====================================================================== */
void display_loop(void)
{
  // Si pas de heartbeat via la teleinfo, le faire
  // via l'affichage
  #ifndef MOD_TELEINFO
    LedRGBON(COLOR_BLUE);
  #endif

  display.setCursor(0,0);

  if (screen_state==screen_sys)
    displaySys();
  else if (screen_state==screen_rf)
    displayRf();
  else if (screen_state==screen_teleinfo)
    displayTeleinfo();

  // Affichage physique sur l'écran
  display.display();

  #ifndef MOD_TELEINFO
    LedRGBOFF();
  #endif

}
<|endoftext|>


<commit_before>#include "clock.h"

#include <errno.h>
#include <time.h>

namespace RPiClock {

    int32_t setDelayNs(const int32_t durationNs) {
        const int32_t startNs = getNowNs();

        if (startNs == -1) {
            return -1;
        }

        while (1) {
            int32_t stopNs = getNowNs();

            if (stopNs == -1) {
                return -1;
            }

            if (getDurationNs(startNs, stopNs) >= durationNs) {
                break;
            }
        }

        return 0;
    }

    int32_t getDurationNs(const int32_t startNs, const int32_t stopNs) {
        int32_t durationNs = stopNs - startNs;

        if (durationNs < 0) {
            durationNs += 1000000000;
        }

        return durationNs;
    }

    int32_t getNowNs(void) {
#ifndef __MACH__
        struct timespec now;

        if (clock_gettime(CLOCK_REALTIME, &now) == -1) {
            return -1;
        }

        return now.tv_nsec;
#else
        errno = EPERM;

        return -1;
#endif
    }
}
<commit_msg>Update src/clock.cc<commit_after>#include "clock.h"

#include <time.h>

#ifdef __MACH__

#include <errno.h>

#endif

namespace RPiClock {

    int32_t setDelayNs(const int32_t durationNs) {
        const int32_t startNs = getNowNs();

        if (startNs == -1) {
            return -1;
        }

        while (1) {
            int32_t stopNs = getNowNs();

            if (stopNs == -1) {
                return -1;
            }

            if (getDurationNs(startNs, stopNs) >= durationNs) {
                break;
            }
        }

        return 0;
    }

    int32_t getDurationNs(const int32_t startNs, const int32_t stopNs) {
        int32_t durationNs = stopNs - startNs;

        if (durationNs < 0) {
            durationNs += 1000000000;
        }

        return durationNs;
    }

    int32_t getNowNs(void) {
        #ifndef __MACH__

        struct timespec now;

        if (clock_gettime(CLOCK_REALTIME, &now) == -1) {
            return -1;
        }

        return now.tv_nsec;

        #else

        errno = EPERM;

        return -1;

        #endif
    }
}
<|endoftext|>


<commit_before>// Print each number in the range specified by two integers.

#include <iostream>

int main()
{
	int val_small = 0, val_big = 0;
	std::cout << "please input two integers:";
	std::cin >> val_small >> val_big;

	if (val_small > val_big) {
		std::swap(val_small,val_big);
	}

	int temp = val_small;	// preserve the value of val_small!
	while (temp <= val_big) {
		std::cout << temp++ << std::endl;
	}

	return 0;
}
<commit_msg>Update ex1_11.cpp<commit_after>// Print each number in the range specified by two integers.

#include <iostream>

int main()
{
    int small = 0, big = 0;
    std::cout << "please input two integers:\n";
    std::cin >> small >> big;
    if (small > big)
        std::swap(small, big);

    for (int curr = small; curr != big; ++curr)
        std::cout << curr;

    return 0;
}
<|endoftext|>


<commit_before>/*

@Copyright Barrett Adair 2015-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

*/

#ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_CONST_HPP
#define BOOST_CLBL_TRTS_REMOVE_MEMBER_CONST_HPP

#include <boost/callable_traits/detail/core.hpp>

namespace boost { namespace callable_traits {

//[ remove_member_const_hpp
/*`
[section:ref_remove_member_const remove_member_const]
[heading Header]
``#include <boost/callable_traits/remove_member_const.hpp>``
[heading Definition]
*/

template<typename T>
using remove_member_const_t = //see below
//<-
    detail::try_but_fail_if_invalid<
        typename detail::traits<T>::remove_member_const,
        member_qualifiers_are_illegal_for_this_type>;

namespace detail {

    template<typename T, typename = std::false_type>
    struct remove_member_const_impl {};

    template<typename T>
    struct remove_member_const_impl <T, typename std::is_same<
        remove_member_const_t<T>, detail::dummy>::type>
    {
        using type = remove_member_const_t<T>;
    };
}

//->

template<typename T>
struct remove_member_const : detail::remove_member_const_impl<T> {};

//<-
}} // namespace boost::callable_traits
//->

/*`
[heading Constraints]
* `T` must be a function type or a member function pointer type
* If `T` is a pointer, it may not be cv/ref qualified

[heading Behavior]
* A substitution failure occurs if the constraints are violated.
* Removes the member `const` qualifier from `T`, if present.

[heading Input/Output Examples]
[table
    [[`T`]                              [`remove_member_const_t<T>`]]
    [[`int() const`]                    [`int()`]]
    [[`int(foo::*)() const`]            [`int(foo::*)()`]]
    [[`int(foo::*)() const &`]          [`int(foo::*)() &`]]
    [[`int(foo::*)() const &&`]         [`int(foo::*)() &&`]]
    [[`int(foo::*)() const`]            [`int(foo::*)()`]]
    [[`int(foo::*)() const volatile`]   [`int(foo::*)() volatile`]]
    [[`int`]                            [(substitution failure)]]
    [[`int (&)()`]                      [(substitution failure)]]
    [[`int (*)()`]                      [(substitution failure)]]
    [[`int foo::*`]                     [(substitution failure)]]
    [[`int (foo::* const)()`]           [(substitution failure)]]
]

[heading Example Program]
[import ../example/remove_member_const.cpp]
[remove_member_const]
[endsect]
*/
//]

#endif // #ifndef BOOST_CLBL_TRTS_REMOVE_MEMBER_CONST_HPP
<commit_msg>Delete remove_member_const.hpp<commit_after><|endoftext|>