<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: toolsin.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 00:57:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_tools.hxx"

#define _TOOLS_TOOLSIN_CXX

#include <string.h>

#ifndef _SHL_HXX
#include <shl.hxx>
#endif

#ifndef _DEBUG_HXX
#include <debug.hxx>
#endif
#ifndef _TOOLSIN_HXX
#include <toolsin.hxx>
#endif

#if defined WNT
#include <dll.hxx>
#endif

void ImplDeleteCharTabData();

// =======================================================================

TOOLSINDATA* ImplGetToolsInData()
{
    TOOLSINDATA** ppData = (TOOLSINDATA**)GetAppData( SHL_TOOLS );
    if ( !(*ppData) )
    {
        TOOLSINDATA* pData = new TOOLSINDATA;
        memset( pData, 0, sizeof( TOOLSINDATA ) );
        *ppData = pData;
    }

    return *ppData;
}

// =======================================================================

void InitTools()
{
    DBG_DEBUGSTART();
}

// -----------------------------------------------------------------------

void DeInitTools()
{
    TOOLSINDATA**   ppData = (TOOLSINDATA**)GetAppData( SHL_TOOLS );
    TOOLSINDATA*    pData = *ppData;

    if ( pData )
    {
        ImplDeleteCharTabData();
        delete pData;
        *ppData = NULL;
    }

    DBG_DEBUGEND();
}

// -----------------------------------------------------------------------

void GlobalDeInitTools()
{
    DBG_GLOBALDEBUGEND();

#if defined WNT
    ImpDeInitWinTools();
#endif
}
<commit_msg>INTEGRATION: CWS vgbugs07 (1.6.90); FILE MERGED 2007/06/04 13:32:26 vg 1.6.90.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: toolsin.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 22:14:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_tools.hxx"

#define _TOOLS_TOOLSIN_CXX

#include <string.h>

#ifndef _SHL_HXX
#include <tools/shl.hxx>
#endif

#ifndef _DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _TOOLSIN_HXX
#include <toolsin.hxx>
#endif

#if defined WNT
#include <dll.hxx>
#endif

void ImplDeleteCharTabData();

// =======================================================================

TOOLSINDATA* ImplGetToolsInData()
{
    TOOLSINDATA** ppData = (TOOLSINDATA**)GetAppData( SHL_TOOLS );
    if ( !(*ppData) )
    {
        TOOLSINDATA* pData = new TOOLSINDATA;
        memset( pData, 0, sizeof( TOOLSINDATA ) );
        *ppData = pData;
    }

    return *ppData;
}

// =======================================================================

void InitTools()
{
    DBG_DEBUGSTART();
}

// -----------------------------------------------------------------------

void DeInitTools()
{
    TOOLSINDATA**   ppData = (TOOLSINDATA**)GetAppData( SHL_TOOLS );
    TOOLSINDATA*    pData = *ppData;

    if ( pData )
    {
        ImplDeleteCharTabData();
        delete pData;
        *ppData = NULL;
    }

    DBG_DEBUGEND();
}

// -----------------------------------------------------------------------

void GlobalDeInitTools()
{
    DBG_GLOBALDEBUGEND();

#if defined WNT
    ImpDeInitWinTools();
#endif
}
<|endoftext|>


<commit_before>//===--- LLVMOpt.cpp ------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
///
/// This is a simple reimplementation of opt that includes support for Swift-
/// specific LLVM passes. It is meant to make it easier to handle issues related
/// to transitioning to the new LLVM pass manager (which lacks the dynamism of
/// the old pass manager) and also problems during the code base transition to
/// that pass manager. Additionally it will enable a user to exactly simulate
/// Swift's LLVM pass pipeline by using the same pass pipeline building
/// machinery in IRGen, something not possible with opt.
///
//===----------------------------------------------------------------------===//

#include "swift/Subsystems.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Basic/LLVMContext.h"
#include "swift/AST/IRGenOptions.h"
#include "swift/LLVMPasses/PassesFwd.h"
#include "swift/LLVMPasses/Passes.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/RegionPass.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/LegacyPassNameParser.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/InitializePasses.h"
#include "llvm/LinkAllIR.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

using namespace swift;

//===----------------------------------------------------------------------===//
//                            Option Declarations
//===----------------------------------------------------------------------===//

// The OptimizationList is automatically populated with registered passes by the
// PassNameParser.
//
static llvm::cl::list<const llvm::PassInfo *, bool, llvm::PassNameParser>
    PassList(llvm::cl::desc("Optimizations available:"));

static llvm::cl::opt<bool>
    Optimized("O", llvm::cl::desc("Optimization level O. Similar to swift -O"));

// TODO: I wanted to call this 'verify', but some other pass is using this
// option.
static llvm::cl::opt<bool> VerifyEach(
    "verify-each",
    llvm::cl::desc("Should we spend time verifying that the IR is well "
                   "formed"));

static llvm::cl::opt<std::string>
    TargetTriple("mtriple",
                 llvm::cl::desc("Override target triple for module"));

static llvm::cl::opt<bool>
    PrintStats("print-stats",
               llvm::cl::desc("Should LLVM Statistics be printed"));

static cl::opt<std::string> InputFilename(cl::Positional,
                                          cl::desc("<input file>"),
                                          cl::init("-"),
                                          cl::value_desc("filename"));

static cl::opt<std::string> OutputFilename("o",
                                           cl::desc("Override output filename"),
                                           cl::value_desc("filename"));

static cl::opt<std::string> DefaultDataLayout(
    "default-data-layout",
    cl::desc("data layout string to use if not specified by module"),
    cl::value_desc("layout-string"), cl::init(""));

//===----------------------------------------------------------------------===//
//                               Helper Methods
//===----------------------------------------------------------------------===//

static llvm::CodeGenOpt::Level GetCodeGenOptLevel() {
  // TODO: Is this the right thing to do here?
  if (Optimized)
    return CodeGenOpt::Default;
  return CodeGenOpt::None;
}

// Returns the TargetMachine instance or zero if no triple is provided.
static llvm::TargetMachine *
getTargetMachine(llvm::Triple TheTriple, StringRef CPUStr,
                 StringRef FeaturesStr, const llvm::TargetOptions &Options) {
  std::string Error;
  const auto *TheTarget =
      llvm::TargetRegistry::lookupTarget(MArch, TheTriple, Error);
  // Some modules don't specify a triple, and this is okay.
  if (!TheTarget) {
    return nullptr;
  }

  return TheTarget->createTargetMachine(
      TheTriple.getTriple(), CPUStr, FeaturesStr, Options,
      Optional<Reloc::Model>(RelocModel), CMModel, GetCodeGenOptLevel());
}

static void dumpOutput(llvm::Module &M, llvm::raw_ostream &os) {
  // For now just always dump assembly.
  legacy::PassManager EmitPasses;
  EmitPasses.add(createPrintModulePass(os));
  EmitPasses.run(M);
}

// This function isn't referenced outside its translation unit, but it
// can't use the "static" keyword because its address is used for
// getMainExecutable (since some platforms don't support taking the
// address of main, and some platforms can't implement getMainExecutable
// without being given the address of a function in the main executable).
void anchorForGetMainExecutable() {}

static inline void addPass(legacy::PassManagerBase &PM, Pass *P) {
  // Add the pass to the pass manager...
  PM.add(P);
  if (P->getPassID() == &SwiftAAWrapperPass::ID) {
    PM.add(createExternalAAWrapperPass([](Pass &P, Function &, AAResults &AAR) {
      if (auto *WrapperPass = P.getAnalysisIfAvailable<SwiftAAWrapperPass>())
        AAR.addAAResult(WrapperPass->getResult());
    }));
  }

  // If we are verifying all of the intermediate steps, add the verifier...
  if (VerifyEach)
    PM.add(createVerifierPass());
}

static void runSpecificPasses(StringRef Binary, llvm::Module *M,
                              llvm::TargetMachine *TM,
                              llvm::Triple &ModuleTriple) {
  llvm::legacy::PassManager Passes;
  llvm::TargetLibraryInfoImpl TLII(ModuleTriple);
  Passes.add(new TargetLibraryInfoWrapperPass(TLII));

  const llvm::DataLayout &DL = M->getDataLayout();
  if (DL.isDefault() && !DefaultDataLayout.empty()) {
    M->setDataLayout(DefaultDataLayout);
  }

  // Add internal analysis passes from the target machine.
  Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis()
                                                     : TargetIRAnalysis()));

  for (const llvm::PassInfo *PassInfo : PassList) {
    llvm::Pass *P = nullptr;
    if (PassInfo->getTargetMachineCtor())
      P = PassInfo->getTargetMachineCtor()(TM);
    else if (PassInfo->getNormalCtor())
      P = PassInfo->getNormalCtor()();
    else
      errs() << Binary << ": cannot create pass: " << PassInfo->getPassName()
             << "\n";
    if (P) {
      addPass(Passes, P);
    }
  }

  // Do it.
  Passes.run(*M);
}

//===----------------------------------------------------------------------===//
//                            Main Implementation
//===----------------------------------------------------------------------===//

int main(int argc, char **argv) {
  INITIALIZE_LLVM(argc, argv);

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);
  // For codegen passes, only passes that do IR to IR transformation are
  // supported.
  initializeCodeGenPreparePass(Registry);
  initializeAtomicExpandPass(Registry);
  initializeRewriteSymbolsPass(Registry);
  initializeWinEHPreparePass(Registry);
  initializeDwarfEHPreparePass(Registry);
  initializeSjLjEHPreparePass(Registry);

  // Register Swift Only Passes.
  initializeSwiftAAWrapperPassPass(Registry);
  initializeSwiftRCIdentityPass(Registry);
  initializeSwiftARCOptPass(Registry);
  initializeSwiftARCContractPass(Registry);
  initializeSwiftStackPromotionPass(Registry);
  initializeInlineTreePrinterPass(Registry);
  initializeSwiftMergeFunctionsPass(Registry);

  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift LLVM optimizer\n");

  if (PrintStats)
    llvm::EnableStatistics();

  llvm::SMDiagnostic Err;

  // Load the input module...
  std::unique_ptr<Module> M =
      parseIRFile(InputFilename, Err, getGlobalLLVMContext());

  if (!M) {
    Err.print(argv[0], errs());
    return 1;
  }

  if (verifyModule(*M, &errs())) {
    errs() << argv[0] << ": " << InputFilename
           << ": error: input module is broken!\n";
    return 1;
  }

  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    M->setTargetTriple(llvm::Triple::normalize(TargetTriple));

  // Figure out what stream we are supposed to write to...
  std::unique_ptr<llvm::tool_output_file> Out;
  // Default to standard output.
  if (OutputFilename.empty())
    OutputFilename = "-";

  std::error_code EC;
  Out.reset(
      new llvm::tool_output_file(OutputFilename, EC, llvm::sys::fs::F_None));
  if (EC) {
    errs() << EC.message() << '\n';
    return 1;
  }

  llvm::Triple ModuleTriple(M->getTargetTriple());
  std::string CPUStr, FeaturesStr;
  llvm::TargetMachine *Machine = nullptr;
  const llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();

  if (ModuleTriple.getArch()) {
    CPUStr = getCPUStr();
    FeaturesStr = getFeaturesStr();
    Machine = getTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options);
  }

  std::unique_ptr<llvm::TargetMachine> TM(Machine);

  // Override function attributes based on CPUStr, FeaturesStr, and command line
  // flags.
  setFunctionAttributes(CPUStr, FeaturesStr, *M);

  if (Optimized) {
    IRGenOptions Opts;
    Opts.Optimize = true;

    // Then perform the optimizations.
    performLLVMOptimizations(Opts, M.get(), TM.get());
  } else {
    runSpecificPasses(argv[0], M.get(), TM.get(), ModuleTriple);
  }

  // Finally dump the output.
  dumpOutput(*M, Out->os());

  return 0;
}
<commit_msg>swift-llvm-opt: adjust for SVN r276687<commit_after>//===--- LLVMOpt.cpp ------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
///
/// This is a simple reimplementation of opt that includes support for Swift-
/// specific LLVM passes. It is meant to make it easier to handle issues related
/// to transitioning to the new LLVM pass manager (which lacks the dynamism of
/// the old pass manager) and also problems during the code base transition to
/// that pass manager. Additionally it will enable a user to exactly simulate
/// Swift's LLVM pass pipeline by using the same pass pipeline building
/// machinery in IRGen, something not possible with opt.
///
//===----------------------------------------------------------------------===//

#include "swift/Subsystems.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Basic/LLVMContext.h"
#include "swift/AST/IRGenOptions.h"
#include "swift/LLVMPasses/PassesFwd.h"
#include "swift/LLVMPasses/Passes.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/RegionPass.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/LegacyPassNameParser.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/InitializePasses.h"
#include "llvm/LinkAllIR.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

using namespace swift;

//===----------------------------------------------------------------------===//
//                            Option Declarations
//===----------------------------------------------------------------------===//

// The OptimizationList is automatically populated with registered passes by the
// PassNameParser.
//
static llvm::cl::list<const llvm::PassInfo *, bool, llvm::PassNameParser>
    PassList(llvm::cl::desc("Optimizations available:"));

static llvm::cl::opt<bool>
    Optimized("O", llvm::cl::desc("Optimization level O. Similar to swift -O"));

// TODO: I wanted to call this 'verify', but some other pass is using this
// option.
static llvm::cl::opt<bool> VerifyEach(
    "verify-each",
    llvm::cl::desc("Should we spend time verifying that the IR is well "
                   "formed"));

static llvm::cl::opt<std::string>
    TargetTriple("mtriple",
                 llvm::cl::desc("Override target triple for module"));

static llvm::cl::opt<bool>
    PrintStats("print-stats",
               llvm::cl::desc("Should LLVM Statistics be printed"));

static cl::opt<std::string> InputFilename(cl::Positional,
                                          cl::desc("<input file>"),
                                          cl::init("-"),
                                          cl::value_desc("filename"));

static cl::opt<std::string> OutputFilename("o",
                                           cl::desc("Override output filename"),
                                           cl::value_desc("filename"));

static cl::opt<std::string> DefaultDataLayout(
    "default-data-layout",
    cl::desc("data layout string to use if not specified by module"),
    cl::value_desc("layout-string"), cl::init(""));

//===----------------------------------------------------------------------===//
//                               Helper Methods
//===----------------------------------------------------------------------===//

static llvm::CodeGenOpt::Level GetCodeGenOptLevel() {
  // TODO: Is this the right thing to do here?
  if (Optimized)
    return CodeGenOpt::Default;
  return CodeGenOpt::None;
}

// Returns the TargetMachine instance or zero if no triple is provided.
static llvm::TargetMachine *
getTargetMachine(llvm::Triple TheTriple, StringRef CPUStr,
                 StringRef FeaturesStr, const llvm::TargetOptions &Options) {
  std::string Error;
  const auto *TheTarget =
      llvm::TargetRegistry::lookupTarget(MArch, TheTriple, Error);
  // Some modules don't specify a triple, and this is okay.
  if (!TheTarget) {
    return nullptr;
  }

  return TheTarget->createTargetMachine(
      TheTriple.getTriple(), CPUStr, FeaturesStr, Options,
      Optional<Reloc::Model>(RelocModel), CMModel, GetCodeGenOptLevel());
}

static void dumpOutput(llvm::Module &M, llvm::raw_ostream &os) {
  // For now just always dump assembly.
  legacy::PassManager EmitPasses;
  EmitPasses.add(createPrintModulePass(os));
  EmitPasses.run(M);
}

// This function isn't referenced outside its translation unit, but it
// can't use the "static" keyword because its address is used for
// getMainExecutable (since some platforms don't support taking the
// address of main, and some platforms can't implement getMainExecutable
// without being given the address of a function in the main executable).
void anchorForGetMainExecutable() {}

static inline void addPass(legacy::PassManagerBase &PM, Pass *P) {
  // Add the pass to the pass manager...
  PM.add(P);
  if (P->getPassID() == &SwiftAAWrapperPass::ID) {
    PM.add(createExternalAAWrapperPass([](Pass &P, Function &, AAResults &AAR) {
      if (auto *WrapperPass = P.getAnalysisIfAvailable<SwiftAAWrapperPass>())
        AAR.addAAResult(WrapperPass->getResult());
    }));
  }

  // If we are verifying all of the intermediate steps, add the verifier...
  if (VerifyEach)
    PM.add(createVerifierPass());
}

static void runSpecificPasses(StringRef Binary, llvm::Module *M,
                              llvm::TargetMachine *TM,
                              llvm::Triple &ModuleTriple) {
  llvm::legacy::PassManager Passes;
  llvm::TargetLibraryInfoImpl TLII(ModuleTriple);
  Passes.add(new TargetLibraryInfoWrapperPass(TLII));

  const llvm::DataLayout &DL = M->getDataLayout();
  if (DL.isDefault() && !DefaultDataLayout.empty()) {
    M->setDataLayout(DefaultDataLayout);
  }

  // Add internal analysis passes from the target machine.
  Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis()
                                                     : TargetIRAnalysis()));

  for (const llvm::PassInfo *PassInfo : PassList) {
    llvm::Pass *P = nullptr;
    if (PassInfo->getTargetMachineCtor())
      P = PassInfo->getTargetMachineCtor()(TM);
    else if (PassInfo->getNormalCtor())
      P = PassInfo->getNormalCtor()();
    else
      errs() << Binary << ": cannot create pass: " << PassInfo->getPassName()
             << "\n";
    if (P) {
      addPass(Passes, P);
    }
  }

  // Do it.
  Passes.run(*M);
}

//===----------------------------------------------------------------------===//
//                            Main Implementation
//===----------------------------------------------------------------------===//

int main(int argc, char **argv) {
  INITIALIZE_LLVM(argc, argv);

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);
  // For codegen passes, only passes that do IR to IR transformation are
  // supported.
  initializeCodeGenPreparePass(Registry);
  initializeAtomicExpandPass(Registry);
  initializeRewriteSymbolsLegacyPassPass(Registry);
  initializeWinEHPreparePass(Registry);
  initializeDwarfEHPreparePass(Registry);
  initializeSjLjEHPreparePass(Registry);

  // Register Swift Only Passes.
  initializeSwiftAAWrapperPassPass(Registry);
  initializeSwiftRCIdentityPass(Registry);
  initializeSwiftARCOptPass(Registry);
  initializeSwiftARCContractPass(Registry);
  initializeSwiftStackPromotionPass(Registry);
  initializeInlineTreePrinterPass(Registry);
  initializeSwiftMergeFunctionsPass(Registry);

  llvm::cl::ParseCommandLineOptions(argc, argv, "Swift LLVM optimizer\n");

  if (PrintStats)
    llvm::EnableStatistics();

  llvm::SMDiagnostic Err;

  // Load the input module...
  std::unique_ptr<Module> M =
      parseIRFile(InputFilename, Err, getGlobalLLVMContext());

  if (!M) {
    Err.print(argv[0], errs());
    return 1;
  }

  if (verifyModule(*M, &errs())) {
    errs() << argv[0] << ": " << InputFilename
           << ": error: input module is broken!\n";
    return 1;
  }

  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    M->setTargetTriple(llvm::Triple::normalize(TargetTriple));

  // Figure out what stream we are supposed to write to...
  std::unique_ptr<llvm::tool_output_file> Out;
  // Default to standard output.
  if (OutputFilename.empty())
    OutputFilename = "-";

  std::error_code EC;
  Out.reset(
      new llvm::tool_output_file(OutputFilename, EC, llvm::sys::fs::F_None));
  if (EC) {
    errs() << EC.message() << '\n';
    return 1;
  }

  llvm::Triple ModuleTriple(M->getTargetTriple());
  std::string CPUStr, FeaturesStr;
  llvm::TargetMachine *Machine = nullptr;
  const llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();

  if (ModuleTriple.getArch()) {
    CPUStr = getCPUStr();
    FeaturesStr = getFeaturesStr();
    Machine = getTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options);
  }

  std::unique_ptr<llvm::TargetMachine> TM(Machine);

  // Override function attributes based on CPUStr, FeaturesStr, and command line
  // flags.
  setFunctionAttributes(CPUStr, FeaturesStr, *M);

  if (Optimized) {
    IRGenOptions Opts;
    Opts.Optimize = true;

    // Then perform the optimizations.
    performLLVMOptimizations(Opts, M.get(), TM.get());
  } else {
    runSpecificPasses(argv[0], M.get(), TM.get(), ModuleTriple);
  }

  // Finally dump the output.
  dumpOutput(*M, Out->os());

  return 0;
}
<|endoftext|>


<commit_before>/* Socket
 * Copyright (c) 2015 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "SocketAddress.h"
#include "NetworkInterface.h"
#include <string.h>
#include "mbed.h"

static bool address_is_ipv4(const char *addr)
{
    int i = 0;

    // Check each digit for [0-9.]
    for (; addr[i]; i++) {
        if (!(addr[i] >= '0' && addr[i] <= '9') && addr[i] != '.') {
            return false;
        }
    }

    // Ending with '.' garuntees host
    if (i > 0 && addr[i-1] == '.') {
        return false;
    }

    return true;
}

static bool address_is_ipv6(const char *addr)
{
    // Check each digit for [0-9a-fA-F:]
    for (int i = 0; addr[i]; i++) {
        if (!(addr[i] >= '0' && addr[i] <= '9') &&
            !(addr[i] >= 'a' && addr[i] <= 'f') &&
            !(addr[i] >= 'A' && addr[i] <= 'F') &&
            addr[i] != ':') {
            return false;
        }
    }

    return true;
}

static void address_to_ipv4(uint8_t *bytes, const char *addr)
{
    sscanf(addr, "%hhd.%hhd.%hhd.%hhd", &bytes[0], &bytes[1], &bytes[2], &bytes[3]);
}

static void address_to_ipv6(uint8_t *bytes, const char *addr)
{
    // TODO support short form (::1, 2001::ffee:100a)
    // Use a more intellegent algorithm
    uint16_t shorts[NSAPI_IPv6_BYTES/2];
    sscanf(addr, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
            &shorts[0], &shorts[1], &shorts[2], &shorts[3],
            &shorts[4], &shorts[5], &shorts[6], &shorts[7]);

    for (int i = 0; i < NSAPI_IPv6_BYTES/2; i++) {
        bytes[2*i+0] = (uint8_t)(shorts[i] >> 8);
        bytes[2*i+1] = (uint8_t)(shorts[i] >> 0);
    }
}

static void ipv4_to_address(char *addr, const uint8_t *bytes)
{
    sprintf(addr, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
}

static void ipv6_to_address(char *addr, const uint8_t *bytes)
{
    int pos = 0;
    for (int i = 0; i < NSAPI_IPv6_BYTES; i+=2) {
        int ret = sprintf(&addr[pos], "%02x%02x", bytes[i], bytes[i+1]);
        if (ret < 0) {
            memset(addr, 0, NSAPI_IPv6_SIZE + 1);
            return;
        }
        pos += ret;

        addr[pos++] = ':';
    }
    pos -= 1; // Overwrite last ':'
    addr[pos++] = '\0';
    MBED_ASSERT(NSAPI_IPv6_SIZE == pos);
}

SocketAddress::SocketAddress(NetworkInterface *iface, const char *host, uint16_t port)
{
    // Check for valid IP addresses
    if (host && address_is_ipv4(host)) {
        _ip_version = NSAPI_IPv4;
        address_to_ipv4(_ip_bytes, host);
    } else if (host && address_is_ipv6(host)) {
        _ip_version = NSAPI_IPv6;
        address_to_ipv4(_ip_bytes, host);
    } else {
        // DNS lookup
        int err = iface->gethostbyname(this, host);
        if (!err) {
            set_port(port);
        } else {
            _ip_version = NSAPI_IPv4;
            memset(_ip_bytes, 0, NSAPI_IPv4_BYTES);
            set_port(0);
        }
    }
}

SocketAddress::SocketAddress(const char *addr, uint16_t port)
{
    set_ip_address(addr);
    set_port(port);
}

SocketAddress::SocketAddress(const void *bytes, nsapi_version_t version, uint16_t port)
{
    set_ip_bytes(bytes, version);
    set_port(port);
}

SocketAddress::SocketAddress(const SocketAddress &addr)
{
    set_ip_bytes(addr.get_ip_bytes(), addr.get_ip_version());
    set_port(addr.get_port());
}

void SocketAddress::set_ip_address(const char *addr)
{
    _ip_address[0] = '\0';

    if (addr && address_is_ipv4(addr)) {
        _ip_version = NSAPI_IPv4;
        address_to_ipv4(_ip_bytes, addr);
    } else if (addr && address_is_ipv6(addr)) {
        _ip_version = NSAPI_IPv6;
        address_to_ipv6(_ip_bytes, addr);
    } else {
        _ip_version = NSAPI_IPv4;
        memset(_ip_bytes, 0, NSAPI_IPv4_BYTES);
    }
}

void SocketAddress::set_ip_bytes(const void *bytes, nsapi_version_t version)
{
    _ip_address[0] = '\0';

    if (_ip_version == NSAPI_IPv4) {
        _ip_version = NSAPI_IPv4;
        memcpy(_ip_bytes, bytes, NSAPI_IPv4_BYTES);
    } else if (_ip_version == NSAPI_IPv6) {
        _ip_version = NSAPI_IPv6;
        memcpy(_ip_bytes, bytes, NSAPI_IPv6_BYTES);
    } else {
        _ip_version = NSAPI_IPv4;
        memset(_ip_bytes, 0, NSAPI_IPv4_BYTES);
    }
}

void SocketAddress::set_port(uint16_t port)
{
    _port = port;
}

const char *SocketAddress::get_ip_address() const
{
    char *ip_address = (char *)_ip_address;

    if (!ip_address[0]) {
        if (_ip_version == NSAPI_IPv4) {
            ipv4_to_address(ip_address, _ip_bytes);
        } else if (_ip_version == NSAPI_IPv6) {
            ipv6_to_address(ip_address, _ip_bytes);
        }
    }

    return ip_address;
}

const void *SocketAddress::get_ip_bytes() const
{
    return _ip_bytes;
}

nsapi_version_t SocketAddress::get_ip_version() const
{
    return _ip_version;
}

uint16_t SocketAddress::get_port() const
{
    return _port;
}

SocketAddress::operator bool() const
{
    int count = 0;
    if (_ip_version == NSAPI_IPv4) {
        count = NSAPI_IPv4_BYTES;
    } else if (_ip_version == NSAPI_IPv6) {
        count = NSAPI_IPv6_BYTES;
    }

    for (int i = 0; i < count; i++) {
        if (_ip_bytes[i]) {
            return true;
        }
    }

    return false;
}
<commit_msg>Added support for shortened form ipv6 addresses<commit_after>/* Socket
 * Copyright (c) 2015 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "SocketAddress.h"
#include "NetworkInterface.h"
#include <string.h>
#include "mbed.h"

static bool ipv4_is_valid(const char *addr)
{
    int i = 0;

    // Check each digit for [0-9.]
    for (; addr[i]; i++) {
        if (!(addr[i] >= '0' && addr[i] <= '9') && addr[i] != '.') {
            return false;
        }
    }

    // Ending with '.' garuntees host
    if (i > 0 && addr[i-1] == '.') {
        return false;
    }

    return true;
}

static bool ipv6_is_valid(const char *addr)
{
    // Check each digit for [0-9a-fA-F:]
    for (int i = 0; addr[i]; i++) {
        if (!(addr[i] >= '0' && addr[i] <= '9') &&
            !(addr[i] >= 'a' && addr[i] <= 'f') &&
            !(addr[i] >= 'A' && addr[i] <= 'F') &&
            addr[i] != ':') {
            return false;
        }
    }

    return true;
}

static void ipv4_from_address(uint8_t *bytes, const char *addr)
{
    sscanf(addr, "%hhu.%hhu.%hhu.%hhu", &bytes[0], &bytes[1], &bytes[2], &bytes[3]);
}

static int ipv6_scan_chunk(uint16_t *shorts, const char *chunk) {
    int count = 0;
    int i = 0;

    for (; count < NSAPI_IPv6_BYTES/2; count++) {
        int scanned = sscanf(&chunk[i], "%hx", &shorts[count]);
        if (scanned < 1) {
            return count;
        }

        for (; chunk[i] != ':'; i++) {
            if (!chunk[i]) {
                return count+1;
            }
        }

        i++;
    }

    return count;
}

static void ipv6_from_address(uint8_t *bytes, const char *addr)
{
    // Start with zeroed address
    uint16_t shorts[NSAPI_IPv6_BYTES/2];
    memset(shorts, 0, sizeof shorts);

    int suffix = 0;

    // Find double colons and scan suffix
    for (int i = 0; addr[i]; i++) {
        if (addr[i] == ':' && addr[i+1] == ':') {
            suffix = ipv6_scan_chunk(shorts, &addr[i+2]);
            break;
        }
    }

    // Move suffix to end
    memmove(&shorts[NSAPI_IPv6_BYTES/2-suffix], &shorts[0],
            suffix*sizeof(uint16_t));

    // Scan prefix
    ipv6_scan_chunk(shorts, &addr[0]);

    // Flip bytes
    for (int i = 0; i < NSAPI_IPv6_BYTES/2; i++) {
        bytes[2*i+0] = (uint8_t)(shorts[i] >> 8);
        bytes[2*i+1] = (uint8_t)(shorts[i] >> 0);
    }
}

static void ipv4_to_address(char *addr, const uint8_t *bytes)
{
    sprintf(addr, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
}

static void ipv6_to_address(char *addr, const uint8_t *bytes)
{
    for (int i = 0; i < NSAPI_IPv6_BYTES/2; i++) {
        sprintf(&addr[5*i], "%02x%02x", bytes[2*i], bytes[2*i+1]);
        addr[5*i+4] = ':';
    }
    addr[NSAPI_IPv6_SIZE-1] = '\0';
}

SocketAddress::SocketAddress(NetworkInterface *iface, const char *host, uint16_t port)
{
    // Check for valid IP addresses
    if (host && ipv4_is_valid(host)) {
        _ip_version = NSAPI_IPv4;
        ipv4_from_address(_ip_bytes, host);
    } else if (host && ipv6_is_valid(host)) {
        _ip_version = NSAPI_IPv6;
        ipv4_from_address(_ip_bytes, host);
    } else {
        // DNS lookup
        int err = iface->gethostbyname(this, host);
        if (!err) {
            set_port(port);
        } else {
            _ip_version = NSAPI_IPv4;
            memset(_ip_bytes, 0, NSAPI_IPv4_BYTES);
            set_port(0);
        }
    }
}

SocketAddress::SocketAddress(const char *addr, uint16_t port)
{
    set_ip_address(addr);
    set_port(port);
}

SocketAddress::SocketAddress(const void *bytes, nsapi_version_t version, uint16_t port)
{
    set_ip_bytes(bytes, version);
    set_port(port);
}

SocketAddress::SocketAddress(const SocketAddress &addr)
{
    set_ip_bytes(addr.get_ip_bytes(), addr.get_ip_version());
    set_port(addr.get_port());
}

void SocketAddress::set_ip_address(const char *addr)
{
    _ip_address[0] = '\0';

    if (addr && ipv4_is_valid(addr)) {
        _ip_version = NSAPI_IPv4;
        ipv4_from_address(_ip_bytes, addr);
    } else if (addr && ipv6_is_valid(addr)) {
        _ip_version = NSAPI_IPv6;
        ipv6_from_address(_ip_bytes, addr);
    } else {
        _ip_version = NSAPI_IPv4;
        memset(_ip_bytes, 0, NSAPI_IPv4_BYTES);
    }
}

void SocketAddress::set_ip_bytes(const void *bytes, nsapi_version_t version)
{
    _ip_address[0] = '\0';

    if (_ip_version == NSAPI_IPv4) {
        _ip_version = NSAPI_IPv4;
        memcpy(_ip_bytes, bytes, NSAPI_IPv4_BYTES);
    } else if (_ip_version == NSAPI_IPv6) {
        _ip_version = NSAPI_IPv6;
        memcpy(_ip_bytes, bytes, NSAPI_IPv6_BYTES);
    } else {
        _ip_version = NSAPI_IPv4;
        memset(_ip_bytes, 0, NSAPI_IPv4_BYTES);
    }
}

void SocketAddress::set_port(uint16_t port)
{
    _port = port;
}

const char *SocketAddress::get_ip_address() const
{
    char *ip_address = (char *)_ip_address;

    if (!ip_address[0]) {
        if (_ip_version == NSAPI_IPv4) {
            ipv4_to_address(ip_address, _ip_bytes);
        } else if (_ip_version == NSAPI_IPv6) {
            ipv6_to_address(ip_address, _ip_bytes);
        }
    }

    return ip_address;
}

const void *SocketAddress::get_ip_bytes() const
{
    return _ip_bytes;
}

nsapi_version_t SocketAddress::get_ip_version() const
{
    return _ip_version;
}

uint16_t SocketAddress::get_port() const
{
    return _port;
}

SocketAddress::operator bool() const
{
    int count = 0;
    if (_ip_version == NSAPI_IPv4) {
        count = NSAPI_IPv4_BYTES;
    } else if (_ip_version == NSAPI_IPv6) {
        count = NSAPI_IPv6_BYTES;
    }

    for (int i = 0; i < count; i++) {
        if (_ip_bytes[i]) {
            return true;
        }
    }

    return false;
}
<|endoftext|>


<commit_before>/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/*
  Atomic rename of table;  RENAME TABLE t1 to t2, tmp to t1 [,...]
*/

#include "mysql_priv.h"
#include "sql_trigger.h"

static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
				 bool skip_error);

static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list);

/*
  Every second entry in the table_list is the original name and every
  second entry is the new name.
*/

bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
{
  bool error= 1;
  TABLE_LIST *ren_table= 0;
  DBUG_ENTER("mysql_rename_tables");

  /*
    Avoid problems with a rename on a table that we have locked or
    if the user is trying to to do this in a transcation context
  */

  if (thd->locked_tables || thd->active_transaction())
  {
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
    DBUG_RETURN(1);
  }

  if (wait_if_global_read_lock(thd,0,1))
    DBUG_RETURN(1);
  VOID(pthread_mutex_lock(&LOCK_open));
  if (lock_table_names(thd, table_list))
    goto err;

  error=0;
  if ((ren_table=rename_tables(thd,table_list,0)))
  {
    /* Rename didn't succeed;  rename back the tables in reverse order */
    TABLE_LIST *table;

    /* Reverse the table list */
    table_list= reverse_table_list(table_list);

    /* Find the last renamed table */
    for (table= table_list;
	 table->next_local != ren_table ;
	 table= table->next_local->next_local) ;
    table= table->next_local->next_local;		// Skip error table
    /* Revert to old names */
    rename_tables(thd, table, 1);

    /* Revert the table list (for prepared statements) */
    table_list= reverse_table_list(table_list);

    error= 1;
  }

  /* Lets hope this doesn't fail as the result will be messy */
  if (!error)
  {
    if (mysql_bin_log.is_open())
    {
      thd->clear_error();
      Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
      mysql_bin_log.write(&qinfo);
    }
    send_ok(thd);
  }

  unlock_table_names(thd, table_list, (TABLE_LIST*) 0);

err:
  pthread_mutex_unlock(&LOCK_open);
  start_waiting_global_read_lock(thd);
  DBUG_RETURN(error);
}

/*
  reverse table list

  SYNOPSIS
    reverse_table_list()
    table_list pointer to table _list

  RETURN
    pointer to new (reversed) list
*/
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list)
{
  TABLE_LIST *prev= 0;

  while (table_list)
  {
    TABLE_LIST *next= table_list->next_local;
    table_list->next_local= prev;
    prev= table_list;
    table_list= next;
  }
  return (prev);
}

/*
  Rename a single table or a view

  SYNPOSIS
    do_rename()
      thd               Thread handle
      ren_table         A table/view to be renamed
      new_db            The database to which the table to be moved to
      new_table_name    The new table/view name
      new_table_alias   The new table/view alias
      skip_error        Whether to skip error

  DESCRIPTION
    Rename a single table or a view.

  RETURN
    false     Ok
    true      rename failed
*/

bool
do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
          char *new_table_alias, bool skip_error)
{
  int rc= 1;
  char name[FN_REFLEN];
  const char *new_alias, *old_alias;
  frm_type_enum frm_type;
  db_type table_type;

  DBUG_ENTER("do_rename");

  if (lower_case_table_names == 2)
  {
    old_alias= ren_table->alias;
    new_alias= new_table_alias;
  }
  else
  {
    old_alias= ren_table->table_name;
    new_alias= new_table_name;
  }
  sprintf(name,"%s/%s/%s%s",mysql_data_home,
          new_db, new_alias, reg_ext);
  unpack_filename(name, name);
  if (!access(name,F_OK))
  {
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
    DBUG_RETURN(ren_table);			// This can't be skipped
  }
  sprintf(name,"%s/%s/%s%s",mysql_data_home,
          ren_table->db, old_alias,
          reg_ext);
  unpack_filename(name, name);

  frm_type= mysql_frm_type(thd, name, &table_type);
  switch (frm_type)
  {
    case FRMTYPE_TABLE:
    {
      if (table_type == DB_TYPE_UNKNOWN)
        my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
      else
      {
        if (!(rc= mysql_rename_table(table_type, ren_table->db, old_alias,
                                     new_db, new_alias)))
        {
          if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
                                                          old_alias,
                                                          new_db,
                                                          new_alias)))
          {
            /*
              We've succeeded in renaming table's .frm and in updating
              corresponding handler data, but have failed to update table's
              triggers appropriately. So let us revert operations on .frm
              and handler's data and report about failure to rename table.
            */
            (void) mysql_rename_table(table_type, new_db, new_alias,
                                      ren_table->db, old_alias);
          }
        }
      }
      break;
    }
    case FRMTYPE_VIEW:
      /* change of schema is not allowed */
      if (strcmp(ren_table->db, new_db))
        my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db,
                 new_db);
      else
        rc= mysql_rename_view(thd, new_alias, ren_table);
      break;
    default:
      DBUG_ASSERT(0); // should never happen
    case FRMTYPE_ERROR:
      my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
      break;
  }
  if (rc && !skip_error)
    DBUG_RETURN(1);

  DBUG_RETURN(0);

}
/*
  Rename all tables in list; Return pointer to wrong entry if something goes
  wrong.  Note that the table_list may be empty!
*/

/*
  Rename tables/views in the list

  SYNPOSIS
    rename_tables()
      thd               Thread handle
      table_list        List of tables to rename
      skip_error        Whether to skip errors

  DESCRIPTION
    Take a table/view name from and odd list element and rename it to a
    the name taken from list element+1. Note that the table_list may be
    empty.

  RETURN
    false     Ok
    true      rename failed
*/

static TABLE_LIST *
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
{
  TABLE_LIST *ren_table,*new_table, *tmp_table;

  DBUG_ENTER("rename_tables");

  for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
  {
    new_table= ren_table->next_local;
    if (do_rename(thd, ren_table, new_table->db, new_table->table_name,
                  new_table->alias, skip_error))
      DBUG_RETURN(ren_table);
  }
  DBUG_RETURN(0);
}
<commit_msg>sql_rename.cc:   Cleanup of fix for bug#14959.<commit_after>/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/*
  Atomic rename of table;  RENAME TABLE t1 to t2, tmp to t1 [,...]
*/

#include "mysql_priv.h"
#include "sql_trigger.h"

static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
				 bool skip_error);

static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list);

/*
  Every second entry in the table_list is the original name and every
  second entry is the new name.
*/

bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
{
  bool error= 1;
  TABLE_LIST *ren_table= 0;
  DBUG_ENTER("mysql_rename_tables");

  /*
    Avoid problems with a rename on a table that we have locked or
    if the user is trying to to do this in a transcation context
  */

  if (thd->locked_tables || thd->active_transaction())
  {
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
    DBUG_RETURN(1);
  }

  if (wait_if_global_read_lock(thd,0,1))
    DBUG_RETURN(1);
  VOID(pthread_mutex_lock(&LOCK_open));
  if (lock_table_names(thd, table_list))
    goto err;

  error=0;
  if ((ren_table=rename_tables(thd,table_list,0)))
  {
    /* Rename didn't succeed;  rename back the tables in reverse order */
    TABLE_LIST *table;

    /* Reverse the table list */
    table_list= reverse_table_list(table_list);

    /* Find the last renamed table */
    for (table= table_list;
	 table->next_local != ren_table ;
	 table= table->next_local->next_local) ;
    table= table->next_local->next_local;		// Skip error table
    /* Revert to old names */
    rename_tables(thd, table, 1);

    /* Revert the table list (for prepared statements) */
    table_list= reverse_table_list(table_list);

    error= 1;
  }

  /* Lets hope this doesn't fail as the result will be messy */
  if (!error)
  {
    if (mysql_bin_log.is_open())
    {
      thd->clear_error();
      Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
      mysql_bin_log.write(&qinfo);
    }
    send_ok(thd);
  }

  unlock_table_names(thd, table_list, (TABLE_LIST*) 0);

err:
  pthread_mutex_unlock(&LOCK_open);
  start_waiting_global_read_lock(thd);
  DBUG_RETURN(error);
}

/*
  reverse table list

  SYNOPSIS
    reverse_table_list()
    table_list pointer to table _list

  RETURN
    pointer to new (reversed) list
*/
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list)
{
  TABLE_LIST *prev= 0;

  while (table_list)
  {
    TABLE_LIST *next= table_list->next_local;
    table_list->next_local= prev;
    prev= table_list;
    table_list= next;
  }
  return (prev);
}

/*
  Rename a single table or a view

  SYNPOSIS
    do_rename()
      thd               Thread handle
      ren_table         A table/view to be renamed
      new_db            The database to which the table to be moved to
      new_table_name    The new table/view name
      new_table_alias   The new table/view alias
      skip_error        Whether to skip error

  DESCRIPTION
    Rename a single table or a view.

  RETURN
    false     Ok
    true      rename failed
*/

bool
do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
          char *new_table_alias, bool skip_error)
{
  int rc= 1;
  char name[FN_REFLEN];
  const char *new_alias, *old_alias;
  frm_type_enum frm_type;
  db_type table_type;

  DBUG_ENTER("do_rename");

  if (lower_case_table_names == 2)
  {
    old_alias= ren_table->alias;
    new_alias= new_table_alias;
  }
  else
  {
    old_alias= ren_table->table_name;
    new_alias= new_table_name;
  }
  sprintf(name,"%s/%s/%s%s",mysql_data_home,
          new_db, new_alias, reg_ext);
  unpack_filename(name, name);
  if (!access(name,F_OK))
  {
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
    DBUG_RETURN(1);			// This can't be skipped
  }
  sprintf(name,"%s/%s/%s%s",mysql_data_home,
          ren_table->db, old_alias,
          reg_ext);
  unpack_filename(name, name);

  frm_type= mysql_frm_type(thd, name, &table_type);
  switch (frm_type)
  {
    case FRMTYPE_TABLE:
    {
      if (table_type == DB_TYPE_UNKNOWN)
        my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
      else
      {
        if (!(rc= mysql_rename_table(table_type, ren_table->db, old_alias,
                                     new_db, new_alias)))
        {
          if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
                                                          old_alias,
                                                          new_db,
                                                          new_alias)))
          {
            /*
              We've succeeded in renaming table's .frm and in updating
              corresponding handler data, but have failed to update table's
              triggers appropriately. So let us revert operations on .frm
              and handler's data and report about failure to rename table.
            */
            (void) mysql_rename_table(table_type, new_db, new_alias,
                                      ren_table->db, old_alias);
          }
        }
      }
      break;
    }
    case FRMTYPE_VIEW:
      /* change of schema is not allowed */
      if (strcmp(ren_table->db, new_db))
        my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db,
                 new_db);
      else
        rc= mysql_rename_view(thd, new_alias, ren_table);
      break;
    default:
      DBUG_ASSERT(0); // should never happen
    case FRMTYPE_ERROR:
      my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
      break;
  }
  if (rc && !skip_error)
    DBUG_RETURN(1);

  DBUG_RETURN(0);

}
/*
  Rename all tables in list; Return pointer to wrong entry if something goes
  wrong.  Note that the table_list may be empty!
*/

/*
  Rename tables/views in the list

  SYNPOSIS
    rename_tables()
      thd               Thread handle
      table_list        List of tables to rename
      skip_error        Whether to skip errors

  DESCRIPTION
    Take a table/view name from and odd list element and rename it to a
    the name taken from list element+1. Note that the table_list may be
    empty.

  RETURN
    false     Ok
    true      rename failed
*/

static TABLE_LIST *
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
{
  TABLE_LIST *ren_table,*new_table, *tmp_table;

  DBUG_ENTER("rename_tables");

  for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
  {
    new_table= ren_table->next_local;
    if (do_rename(thd, ren_table, new_table->db, new_table->table_name,
                  new_table->alias, skip_error))
      DBUG_RETURN(ren_table);
  }
  DBUG_RETURN(0);
}
<|endoftext|>


<commit_before>/* Copyright (c) 2012 Stanford University
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <gtest/gtest.h>

#include "Core/Debug.h"
#include "RPC/Address.h"

namespace LogCabin {
namespace RPC {
namespace {

TEST(RPCAddressTest, constructor) {
    EXPECT_EQ(":90 (resolved to Unspecified)",
              Address("", 90).toString());

    // hostname
    Address name("example.com", 80);
    EXPECT_EQ("example.com", name.host);
    EXPECT_EQ("80", name.port);
    EXPECT_EQ("example.com:80", name.originalString);
    Address namePort("example.com:80", 90);
    EXPECT_EQ("example.com", namePort.host);
    EXPECT_EQ("80", namePort.port);
    EXPECT_EQ("example.com:80", namePort.originalString);

    // IPv4
    Address ipv4("1.2.3.4", 80);
    EXPECT_EQ("1.2.3.4", ipv4.host);
    EXPECT_EQ("80", ipv4.port);
    EXPECT_EQ("1.2.3.4:80", ipv4.originalString);
    Address ipv4Port("1.2.3.4:80", 90);
    EXPECT_EQ("1.2.3.4", ipv4Port.host);
    EXPECT_EQ("80", ipv4Port.port);
    EXPECT_EQ("1.2.3.4:80", ipv4Port.originalString);

    // IPv6
    Address ipv6("[1:2:3:4:5:6:7:8]", 80);
    EXPECT_EQ("1:2:3:4:5:6:7:8", ipv6.host);
    EXPECT_EQ("80", ipv6.port);
    EXPECT_EQ("[1:2:3:4:5:6:7:8]:80", ipv6.originalString);
    Address ipv6Port("[1:2:3:4:5:6:7:8]:80", 90);
    EXPECT_EQ("1:2:3:4:5:6:7:8", ipv6Port.host);
    EXPECT_EQ("80", ipv6Port.port);
    EXPECT_EQ("[1:2:3:4:5:6:7:8]:80", ipv6Port.originalString);
    Address ipv6Short("[::1]", 80);
    EXPECT_EQ("::1", ipv6Short.host);
    EXPECT_EQ("80", ipv6Short.port);
    EXPECT_EQ("[::1]:80", ipv6Short.originalString);

}

TEST(RPCAddressTest, constructor_copy) {
    Address a("127.0.0.1", 80);
    Address b(a);
    EXPECT_EQ(a.host, b.host);
    EXPECT_EQ(a.port, b.port);
    EXPECT_EQ(a.len, b.len);
    EXPECT_EQ(a.toString(), b.toString());
    EXPECT_EQ(a.getResolvedString(), b.getResolvedString());
}

TEST(RPCAddressTest, assignment) {
    Address a("127.0.0.1", 80);
    Address b("127.0.0.2", 81);
    b = a;
    EXPECT_EQ(a.host, b.host);
    EXPECT_EQ(a.port, b.port);
    EXPECT_EQ(a.len, b.len);
    EXPECT_EQ(a.toString(), b.toString());
    EXPECT_EQ(a.getResolvedString(), b.getResolvedString());
}

TEST(RPCAddressTest, isValid) {
    Address a("127.0.0.1", 80);
    Address b("qqq", 81);
    EXPECT_TRUE(a.isValid());
    EXPECT_FALSE(b.isValid());
}

TEST(RPCAddressTest, getResolvedString) {
    // getResolvedString is tested adequately in the refresh test.
}

TEST(RPCAddressTest, toString) {
    Address a("127.0.0.1:80", 90);
    a.originalString = "example.org:80";
    EXPECT_EQ("example.org:80 (resolved to 127.0.0.1:80)",
              a.toString());
}

TEST(RPCAddressTest, refresh) {
    // This should be a pretty stable IP address, since it is supposed to be
    // easy to be memorize (at least for IPv4).
    std::string googleDNS =
        Address("google-public-dns-a.google.com", 80).getResolvedString();
    if (googleDNS != "[2001:4860:4860::8888]:80") {
        EXPECT_EQ("8.8.8.8:80", googleDNS)
            << "This test requires connectivity to the Internet for a DNS "
            << "lookup. Alternatively, you can point "
            << "google-public-dns-a.google.com to 8.8.8.8 "
            << "in your /etc/hosts file.";
    }

    // IPv4
    EXPECT_EQ("1.2.3.4:80", Address("1.2.3.4", 80).getResolvedString());
    EXPECT_EQ("0.0.0.0:80", Address("0", 80).getResolvedString())
        << "any address";

    // IPv6
    EXPECT_EQ("[1:2:3:4:5:6:7:8]:80",
              Address("[1:2:3:4:5:6:7:8]", 80).getResolvedString());
    EXPECT_EQ("[::1]:80",
              Address("[::1]", 80).getResolvedString()) << "localhost";
    EXPECT_EQ("[::]:80",
              Address("[::]", 80).getResolvedString()) << "any address";
}

} // namespace LogCabin::RPC::<anonymous>
} // namespace LogCabin::RPC
} // namespace LogCabin
<commit_msg>Add explanation for IPv6 failures<commit_after>/* Copyright (c) 2012 Stanford University
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <gtest/gtest.h>

#include "Core/Debug.h"
#include "RPC/Address.h"

namespace LogCabin {
namespace RPC {
namespace {

TEST(RPCAddressTest, constructor) {
    EXPECT_EQ(":90 (resolved to Unspecified)",
              Address("", 90).toString());

    // hostname
    Address name("example.com", 80);
    EXPECT_EQ("example.com", name.host);
    EXPECT_EQ("80", name.port);
    EXPECT_EQ("example.com:80", name.originalString);
    Address namePort("example.com:80", 90);
    EXPECT_EQ("example.com", namePort.host);
    EXPECT_EQ("80", namePort.port);
    EXPECT_EQ("example.com:80", namePort.originalString);

    // IPv4
    Address ipv4("1.2.3.4", 80);
    EXPECT_EQ("1.2.3.4", ipv4.host);
    EXPECT_EQ("80", ipv4.port);
    EXPECT_EQ("1.2.3.4:80", ipv4.originalString);
    Address ipv4Port("1.2.3.4:80", 90);
    EXPECT_EQ("1.2.3.4", ipv4Port.host);
    EXPECT_EQ("80", ipv4Port.port);
    EXPECT_EQ("1.2.3.4:80", ipv4Port.originalString);

    // IPv6
    Address ipv6("[1:2:3:4:5:6:7:8]", 80);
    EXPECT_EQ("1:2:3:4:5:6:7:8", ipv6.host);
    EXPECT_EQ("80", ipv6.port);
    EXPECT_EQ("[1:2:3:4:5:6:7:8]:80", ipv6.originalString);
    Address ipv6Port("[1:2:3:4:5:6:7:8]:80", 90);
    EXPECT_EQ("1:2:3:4:5:6:7:8", ipv6Port.host);
    EXPECT_EQ("80", ipv6Port.port);
    EXPECT_EQ("[1:2:3:4:5:6:7:8]:80", ipv6Port.originalString);
    Address ipv6Short("[::1]", 80);
    EXPECT_EQ("::1", ipv6Short.host);
    EXPECT_EQ("80", ipv6Short.port);
    EXPECT_EQ("[::1]:80", ipv6Short.originalString);

}

TEST(RPCAddressTest, constructor_copy) {
    Address a("127.0.0.1", 80);
    Address b(a);
    EXPECT_EQ(a.host, b.host);
    EXPECT_EQ(a.port, b.port);
    EXPECT_EQ(a.len, b.len);
    EXPECT_EQ(a.toString(), b.toString());
    EXPECT_EQ(a.getResolvedString(), b.getResolvedString());
}

TEST(RPCAddressTest, assignment) {
    Address a("127.0.0.1", 80);
    Address b("127.0.0.2", 81);
    b = a;
    EXPECT_EQ(a.host, b.host);
    EXPECT_EQ(a.port, b.port);
    EXPECT_EQ(a.len, b.len);
    EXPECT_EQ(a.toString(), b.toString());
    EXPECT_EQ(a.getResolvedString(), b.getResolvedString());
}

TEST(RPCAddressTest, isValid) {
    Address a("127.0.0.1", 80);
    Address b("qqq", 81);
    EXPECT_TRUE(a.isValid());
    EXPECT_FALSE(b.isValid());
}

TEST(RPCAddressTest, getResolvedString) {
    // getResolvedString is tested adequately in the refresh test.
}

TEST(RPCAddressTest, toString) {
    Address a("127.0.0.1:80", 90);
    a.originalString = "example.org:80";
    EXPECT_EQ("example.org:80 (resolved to 127.0.0.1:80)",
              a.toString());
}

TEST(RPCAddressTest, refresh) {
    // This should be a pretty stable IP address, since it is supposed to be
    // easy to be memorize (at least for IPv4).
    std::string googleDNS =
        Address("google-public-dns-a.google.com", 80).getResolvedString();
    if (googleDNS != "[2001:4860:4860::8888]:80") {
        EXPECT_EQ("8.8.8.8:80", googleDNS)
            << "This test requires connectivity to the Internet for a DNS "
            << "lookup. Alternatively, you can point "
            << "google-public-dns-a.google.com to 8.8.8.8 "
            << "in your /etc/hosts file.";
    }

    // IPv4
    EXPECT_EQ("1.2.3.4:80", Address("1.2.3.4", 80).getResolvedString());
    EXPECT_EQ("0.0.0.0:80", Address("0", 80).getResolvedString())
        << "any address";

    // IPv6
    const char* disclaimer = "Failure of this test is normal if no external "
                             "network interface has an IPv6 address set.";
    EXPECT_EQ("[1:2:3:4:5:6:7:8]:80",
              Address("[1:2:3:4:5:6:7:8]", 80).getResolvedString())
              << "random IPv6 address. " << disclaimer;
    EXPECT_EQ("[::1]:80",
              Address("[::1]", 80).getResolvedString())
              << "localhost. " << disclaimer;
    EXPECT_EQ("[::]:80",
              Address("[::]", 80).getResolvedString())
              << "any address. " << disclaimer;
}

} // namespace LogCabin::RPC::<anonymous>
} // namespace LogCabin::RPC
} // namespace LogCabin
<|endoftext|>


<commit_before>#include <pragma/graphics/Mesh.h>
#include <pragma/graphics/import/Parsers.h>
#include <pragma/graphics/Camera.h>
#include <pragma/graphics/MeshCollision.h>

#include <pragma/math/types.h>
#include <pragma/math/functions.h>

#include <pragma/geometry/functions.h>

#include <stdio.h>

#include <pragma/system/clock.h>
#include <pragma/graphics/Material.h>
#include <pragma/image/Image.h>
#include <pragma/image/functions.h>

using namespace pragma;

#define SAMPLES_PER_PIXEL	4
#define IMAGE_SIZE			512
#define INDIRECT_RAYS		400

Point lLigth(0,54,0);

namespace pragma
{
	template <typename T>
	inline T Random()
	{
		return T(T(rand()) / RAND_MAX);
	}

	template <typename T>
	inline T Random(T aMin, T aMax)
	{
		T lVal = T(T(rand()) / RAND_MAX);
		return (lVal * (aMax - aMin)) + aMin;
	}

	Vector RandomVector(const Vector& aNormal)
	{
		Vector lX;
		Vector lY = Normalize(aNormal);
		if(abs(aNormal.x) > abs(aNormal.y))
		{
			if(abs(aNormal.y) > abs(aNormal.z))
			{
				lX.x = lY.y;
				lX.y = lY.x;
				lX.z = lY.z;
			}
			else
			{
				lX.x = lY.z;
				lX.y = lY.y;
				lX.z = lY.x;
			}
		}
		else
		{
			if(abs(aNormal.x) > abs(aNormal.z))
			{
				lX.x = lY.y;
				lX.y = lY.x;
				lX.z = lY.z;
			}
			else
			{
				lX.x = lY.x;
				lX.y = lY.z;
				lX.z = lY.y;
			}
		}
		Vector lZ = CrossProduct(lX, lY);

		Vector lRetVal = Normalize( lX * Random<Real>(-1, 1) +
									aNormal * Random<Real>(0, 2)+
									lZ * Random<Real>(-1,1) );

		return lRetVal;
	}

	class Multisample
	{
	public:
		Multisample(size_t aSamplesPerPixel)
			: mSamplesPerPixel(aSamplesPerPixel)
		{
			mValues.reserve(mSamplesPerPixel);
			size_t lWidth = (size_t)pragma::sqrt<float>((float)mSamplesPerPixel);
			size_t lHeigth = mSamplesPerPixel / lWidth;
			vector2f lOffset( 1.f / (lWidth+1), 1.f / (lHeigth+1));
			vector2f lSample(0,0);
			for(size_t i = 0; i < lHeigth; ++i)
			{
				lSample.y+= lOffset.y;
				for(size_t j = 0; j < lWidth; ++j)
				{
					lSample.x+= lOffset.x;
					mValues.push_back(lSample);
				}
			}
		}

		size_t GetSamplesPerPixel() const { return mSamplesPerPixel; }
		const vector2f GetSampleOffset(size_t aIndex) const
		{
			return mValues[aIndex];

		}

	private:
		size_t mSamplesPerPixel;
		std::vector<vector2f> mValues;
	};

	class Raytracer
	{
	public:
		Raytracer(const Mesh& aMesh, const MaterialLibrary& aMaterialLibrary)
			: mMesh(aMesh)
			, mCollisionMap(mMesh)
			, mMaterialLibrary(aMaterialLibrary)
		{
			mCollisionMap.ResetStats();
		}

		Color Shade(const Point& aPoint, const Vector& aNormal, const Material& aMaterial, size_t aDepth)
		{
			Color lRetVal(0,0,0);

			Vector lToLigth = Normalize(lLigth - aPoint);
			Vector lCollisionPoint = aPoint + lToLigth * (4.f * math::type_traits<Real>::epsilon);
			bool lShadowRayCollision = mCollisionMap.IntersectRay( lCollisionPoint, lLigth );
			if( !lShadowRayCollision )
			{
				// Direct Lighting
				Real lDiffuse = DotProduct(aNormal, Normalize(lLigth-lCollisionPoint));
				if(lDiffuse > 0)
				{
					lRetVal = lRetVal + aMaterial.GetdiffuseColor() * lDiffuse;
				}
			}

			aDepth--;
			if(aDepth == 0)
				return lRetVal;

			// Indirect Lighting
			Color lIndirect(0,0,0);

			for(size_t i = 0; i < INDIRECT_RAYS; ++i)
			{
				Vector lDir = RandomVector(aNormal);
				Vector lPoint = aPoint + lDir * (4.f * math::type_traits<Real>::epsilon);
				lIndirect = lIndirect + (aMaterial.GetdiffuseColor() * ( TraceRay(lPoint, lDir, 1000, aDepth) * DotProduct( aNormal, lDir)));
			}
			lRetVal = lRetVal + ( lIndirect / INDIRECT_RAYS );

			return lRetVal;
		}

		Color TraceCameraRay(const Point& aPosition, const Vector& aDirection, Real aLength)
		{
			return TraceRay(aPosition, aDirection, aLength, 2);
		}

		Color TraceRay(const Point& aPosition, const Vector& aDirection, Real aLength, size_t aDepth)
		{
			Color lRetVal(0,0,0);

			if(aDepth == 0)
				return lRetVal;

			MeshCollision::TResult lResult;

			if( mCollisionMap.IntersectRay( aPosition, aDirection, aLength, lResult ) )
			{
				// Collision, shade point
				size_t lCount;
				const Mesh::TTriangle& lTri = mMesh.GetTriangles(lCount)[lResult.mTriangleIndex];

				Vector lNormal;
				ComputeFromBarycentric( mMesh.GetVertexNormal(lTri.mVertexNormal[0])
									  , mMesh.GetVertexNormal(lTri.mVertexNormal[1])
									  , mMesh.GetVertexNormal(lTri.mVertexNormal[2])
									  , lResult.mBarycentric
									  , lNormal );
				lRetVal = lRetVal + Shade(lResult.mPosition, lNormal, mMaterialLibrary.GetMaterial(lTri.mMaterial), aDepth);
			}

			return lRetVal;
		}

	private:
		const Mesh& mMesh;
		const MaterialLibrary& mMaterialLibrary;
		MeshCollision mCollisionMap;
	};
}

int main(int argc, char* argv[])
{
	// Load ASE file
	TMillisecond lStart = GetTimeMilliseconds();
	pragma::Mesh lMesh;
	MaterialLibrary lMaterialLibrary(32);
	ParseOBJ("scenes/Cornell.obj", lMesh, lMaterialLibrary);
	TMillisecond lEnd = GetTimeMilliseconds();
	printf("Parsed file in %d milliseconds\n", lEnd - lStart);

	Vector lCameraPos(0,27.5,75);
	Camera lCamera;
	lCamera.SetProjection(45, 1, 1.f, 300.f);
	lCamera.SetTransform( lCameraPos, Vector(0,27.5,0), Vector(0,1,0) );

	matrix4x4f lTransform = lCamera.GetProjection() * lCamera.GetTransform();
	lTransform = Inverse(lTransform);

	lStart = GetTimeMilliseconds();
	lEnd = GetTimeMilliseconds();
	printf("Created KdTree in %d milliseconds\n", lEnd - lStart);

	Image lImage(IMAGE_SIZE, IMAGE_SIZE);
	RGBPixel* lIter = lImage.begin();

	lStart = GetTimeMilliseconds();

	Multisample lMultisample(SAMPLES_PER_PIXEL);

	Raytracer lRaytracer(lMesh, lMaterialLibrary);

	int lProgess = 0;

	// Scanline renderer
	for(size_t i = 0; i < IMAGE_SIZE; ++i)
	{
		for(size_t j = 0; j < IMAGE_SIZE; ++j)
		{
			*lIter = Color(0,0,0);
			// Multiple samples per pixel
			for(size_t s = 0; s < lMultisample.GetSamplesPerPixel(); ++s)
			{
				vector2f lOffset = lMultisample.GetSampleOffset(s);
				vector4f lRay((((lOffset.x+j)*2.f)/(IMAGE_SIZE-1))-1, 1-(((lOffset.y+i)*2.f)/(IMAGE_SIZE-1)), 1, 1);
				vector4f lRes = TransformPoint(lTransform, lRay);
				lRes = lRes * (1.f / lRes.w);

				Vector lDir(lRes.x, lRes.y, lRes.z);
				lDir = Normalize(lDir);

				*lIter = *lIter + RGBPixel(lRaytracer.TraceCameraRay( lCameraPos, lDir, 1000 ));
			}
			*lIter = *lIter / lMultisample.GetSamplesPerPixel();
			++lIter;

			int lNewProgress = (i * IMAGE_SIZE + j) * 100 / (IMAGE_SIZE * IMAGE_SIZE);
			if(lProgess != lNewProgress)
			{
				printf("%3d%%\b\b\b\b", lNewProgress);
				lProgess = lNewProgress;
			}
		}
	}
	lEnd = GetTimeMilliseconds();
	//printf("Image rendered in %d milliseconds. Traced %d rays\n", lEnd - lStart, lCollisionMap.TracedRays());

	ExportToTGA(lImage, "out.tga");

	return 0;
}<commit_msg>Subo esto y me voy al mac a hacer unas pruebas<commit_after>#include <pragma/graphics/Mesh.h>
#include <pragma/graphics/import/Parsers.h>
#include <pragma/graphics/Camera.h>
#include <pragma/graphics/MeshCollision.h>

#include <pragma/math/types.h>
#include <pragma/math/functions.h>

#include <pragma/geometry/functions.h>

#include <stdio.h>

#include <pragma/system/clock.h>
#include <pragma/graphics/Material.h>
#include <pragma/image/Image.h>
#include <pragma/image/functions.h>

using namespace pragma;

#define SAMPLES_PER_PIXEL	4
#define IMAGE_SIZE			512
#define INDIRECT_DEPTH		2
#define INDIRECT_RAYS		100

Point lLigth(0,54,0);

namespace pragma
{
	template <typename T>
	inline T Random()
	{
		return T(T(rand()) / RAND_MAX);
	}

	template <typename T>
	inline T Random(T aMin, T aMax)
	{
		T lVal = T(T(rand()) / RAND_MAX);
		return (lVal * (aMax - aMin)) + aMin;
	}

	Vector RandomVector(const Vector& aNormal)
	{
		Vector lX;
		Vector lY = Normalize(aNormal);
		if(abs(aNormal.x) > abs(aNormal.y))
		{
			if(abs(aNormal.y) > abs(aNormal.z))
			{
				lX.x = lY.y;
				lX.y = lY.x;
				lX.z = lY.z;
			}
			else
			{
				lX.x = lY.z;
				lX.y = lY.y;
				lX.z = lY.x;
			}
		}
		else
		{
			if(abs(aNormal.x) > abs(aNormal.z))
			{
				lX.x = lY.y;
				lX.y = lY.x;
				lX.z = lY.z;
			}
			else
			{
				lX.x = lY.x;
				lX.y = lY.z;
				lX.z = lY.y;
			}
		}
		Vector lZ = CrossProduct(lX, lY);

		Vector lRetVal = Normalize( lX * Random<Real>(-1, 1) +
									aNormal * Random<Real>(0, 2)+
									lZ * Random<Real>(-1,1) );

		return lRetVal;
	}

	class Multisample
	{
	public:
		Multisample(size_t aSamplesPerPixel)
			: mSamplesPerPixel(aSamplesPerPixel)
		{
			mValues.reserve(mSamplesPerPixel);
			size_t lWidth = (size_t)pragma::sqrt<float>((float)mSamplesPerPixel);
			size_t lHeigth = mSamplesPerPixel / lWidth;
			vector2f lOffset( 1.f / lWidth, 1.f / lHeigth);
			vector2f lSample = lOffset / 2;
			for(size_t i = 0; i < lHeigth; ++i)
			{
				for(size_t j = 0; j < lWidth; ++j)
				{
					mValues.push_back(lSample);
					lSample.x+= lOffset.x;
				}
				lSample.y+= lOffset.y;
			}
		}

		size_t GetSamplesPerPixel() const { return mSamplesPerPixel; }
		const vector2f GetSampleOffset(size_t aIndex) const
		{
			return mValues[aIndex];

		}

	private:
		size_t mSamplesPerPixel;
		std::vector<vector2f> mValues;
	};

	class Raytracer
	{
	public:
		Raytracer(const Mesh& aMesh, const MaterialLibrary& aMaterialLibrary)
			: mMesh(aMesh)
			, mCollisionMap(mMesh)
			, mMaterialLibrary(aMaterialLibrary)
		{
			mCollisionMap.ResetStats();
		}

		Color Shade(const Point& aPoint, const Vector& aNormal, const Material& aMaterial, size_t aDepth)
		{
			Color lRetVal(0,0,0);

			Vector lToLigth = Normalize(lLigth - aPoint);
			Vector lCollisionPoint = aPoint + lToLigth * (4.f * math::type_traits<Real>::epsilon);
			bool lShadowRayCollision = mCollisionMap.IntersectRay( lCollisionPoint, lLigth );
			if( !lShadowRayCollision )
			{
				// Direct Lighting
				Real lDiffuse = DotProduct(aNormal, Normalize(lLigth-lCollisionPoint));
				if(lDiffuse > 0)
				{
					lRetVal = lRetVal + aMaterial.GetdiffuseColor() * lDiffuse;
				}
			}

			aDepth--;
			if(aDepth == 0)
				return lRetVal;

#if defined INDIRECT_RAYS && INDIRECT_RAYS > 0
			// Indirect Lighting
			Color lIndirect(0,0,0);

			for(size_t i = 0; i < INDIRECT_RAYS; ++i)
			{
				Vector lDir = RandomVector(aNormal);
				Vector lPoint = aPoint + lDir * (4.f * math::type_traits<Real>::epsilon);
				lIndirect = lIndirect + (aMaterial.GetdiffuseColor() * ( TraceRay(lPoint, lDir, 1000, aDepth) * DotProduct( aNormal, lDir)));
			}
			lRetVal = lRetVal + ( lIndirect / INDIRECT_RAYS );
#endif
			return lRetVal;
		}

		size_t TracedRays() const
		{
			return mCollisionMap.TracedRays();
		}

		Color TraceCameraRay(const Point& aPosition, const Vector& aDirection, Real aLength)
		{
			return TraceRay(aPosition, aDirection, aLength, INDIRECT_DEPTH);
		}

		Color TraceRay(const Point& aPosition, const Vector& aDirection, Real aLength, size_t aDepth)
		{
			Color lRetVal(0,0,0);

			if(aDepth == 0)
				return lRetVal;

			MeshCollision::TResult lResult;

			if( mCollisionMap.IntersectRay( aPosition, aDirection, aLength, lResult ) )
			{
				// Collision, shade point
				size_t lCount;
				const Mesh::TTriangle& lTri = mMesh.GetTriangles(lCount)[lResult.mTriangleIndex];

				Vector lNormal;
				ComputeFromBarycentric( mMesh.GetVertexNormal(lTri.mVertexNormal[0])
									  , mMesh.GetVertexNormal(lTri.mVertexNormal[1])
									  , mMesh.GetVertexNormal(lTri.mVertexNormal[2])
									  , lResult.mBarycentric
									  , lNormal );
				lRetVal = lRetVal + Shade(lResult.mPosition, lNormal, mMaterialLibrary.GetMaterial(lTri.mMaterial), aDepth);
			}

			return lRetVal;
		}

	private:
		const Mesh& mMesh;
		const MaterialLibrary& mMaterialLibrary;
		MeshCollision mCollisionMap;
	};
}

int main(int argc, char* argv[])
{
	// Load ASE file
	TMillisecond lStart = GetTimeMilliseconds();
	pragma::Mesh lMesh;
	MaterialLibrary lMaterialLibrary(32);
	ParseOBJ("scenes/Cornell.obj", lMesh, lMaterialLibrary);
	TMillisecond lEnd = GetTimeMilliseconds();
	printf("Parsed file in %d milliseconds\n", lEnd - lStart);

	Vector lCameraPos(0,27.5,75);
	Camera lCamera;
	lCamera.SetProjection(45, 1, 1.f, 300.f);
	lCamera.SetTransform( lCameraPos, Vector(0,27.5,0), Vector(0,1,0) );

	matrix4x4f lTransform = lCamera.GetProjection() * lCamera.GetTransform();
	lTransform = Inverse(lTransform);

	lStart = GetTimeMilliseconds();
	lEnd = GetTimeMilliseconds();
	printf("Created KdTree in %d milliseconds\n", lEnd - lStart);

	Image lImage(IMAGE_SIZE, IMAGE_SIZE);
	RGBPixel* lIter = lImage.begin();

	lStart = GetTimeMilliseconds();

	Multisample lMultisample(SAMPLES_PER_PIXEL);

	Raytracer lRaytracer(lMesh, lMaterialLibrary);

	int lProgess = 0;

	// Scanline renderer
	for(size_t i = 0; i < IMAGE_SIZE; ++i)
	{
		for(size_t j = 0; j < IMAGE_SIZE; ++j)
		{
			*lIter = Color(0,0,0);
			// Multiple samples per pixel
			for(size_t s = 0; s < lMultisample.GetSamplesPerPixel(); ++s)
			{
				vector2f lOffset = lMultisample.GetSampleOffset(s);
				vector4f lRay((((lOffset.x+j)*2.f)/(IMAGE_SIZE-1))-1, 1-(((lOffset.y+i)*2.f)/(IMAGE_SIZE-1)), 1, 1);
				vector4f lRes = TransformPoint(lTransform, lRay);
				lRes = lRes * (1.f / lRes.w);

				Vector lDir(lRes.x, lRes.y, lRes.z);
				lDir = Normalize(lDir);

				*lIter = *lIter + RGBPixel(lRaytracer.TraceCameraRay( lCameraPos, lDir, 1000 ));
			}
			*lIter = *lIter / lMultisample.GetSamplesPerPixel();
			++lIter;

			int lNewProgress = (i * IMAGE_SIZE + j) * 100 / (IMAGE_SIZE * IMAGE_SIZE);
			if(lProgess != lNewProgress)
			{
				printf("%3d%%\b\b\b\b", lNewProgress);
				lProgess = lNewProgress;
			}
		}
	}
	lEnd = GetTimeMilliseconds();
	printf("Image rendered in %d milliseconds. Traced %d rays\n", lEnd - lStart, lRaytracer.TracedRays());

	ExportToTGA(lImage, "out.tga");

	return 0;
}<|endoftext|>


<commit_before>#include <map>
#include "glm/geometric.hpp"
#include "ObjModel.hpp"

namespace
{

class VertexIndexIndexer
{
public:

    VertexIndexIndexer() : _object(0)
    {
    }

    VertexIndexIndexer& operator << (vfm::Object &o)
    {
        if (_object != &o)
        {
            _vertexIndexPtrMap.clear();
            _object = &o;
        }
        return *this;
    }

    vfm::index_t getIndex(const vfm::VertexIndex &vi)
    {
        size_t mapSize = _vertexIndexPtrMap.size();
        vfm::index_t *index = &_vertexIndexPtrMap[vi];
        if (_vertexIndexPtrMap.size() > mapSize)
        {
            *index = mapSize;
            _object->vertexIndices.push_back(vi);
        }
        return *index;
    }

private:
    struct VertexIndexPtrComparator {
        bool operator() (const vfm::VertexIndex &vi1, const vfm::VertexIndex &vi2) const
        {
          if (vi1.vertex == vi2.vertex)
          {
              if(vi1.normal == vi2.normal)
              {
                  return vi1.texture < vi2.texture;
              }
              return vi1.normal < vi2.normal;
          }
          return vi1.vertex < vi2.vertex;
        }
    };
    typedef std::map<vfm::VertexIndex, vfm::index_t, VertexIndexPtrComparator> VertexIndexMap;

    vfm::Object *_object;
    VertexIndexMap _vertexIndexPtrMap;
};

inline std::istream& eatline (std::istream& is)
{
    return is.ignore(std::numeric_limits<long>::max(), '\n');
}

}

vfm::VertexIndex::VertexIndex (index_t vertex, index_t normal, index_t texture)
    : vertex(vertex), normal(normal), texture(texture)
{
}

bool vfm::VertexIndex::operator == (const VertexIndex &vi) const
{
    return this->vertex == vi.vertex && this->normal == vi.normal && this->texture == vi.texture;
}

std::istream & vfm::operator >> (std::istream &is, glm::vec3 &v)
{
    is >> v.x;
    if(is.good())
    {
        is >> v.y;
        if (is.fail())
        {
            v.y = 0;
            v.z = 0;
            is.clear();
        }
        else if(is.good())
        {
            is >> v.z;
            if (is.fail())
            {
                v.z = 0;
                is.clear();
            }
        }
    }
    return is;
}

std::istream & vfm::operator >> (std::istream &is, glm::vec4 &v)
{
    is >> v.x >> v.y >> v.z;
    if (is.good())
    {
        is >> v.w;
        // w is optional, no matter if the stream has not
        // succeeded in reading it
        if (is.fail())
        {
            v.w = 1;
            is.clear();
        }
    }
    return is;
}

std::istream & vfm::operator >> (std::istream &is, VertexIndex &vi)
{
    is >> vi.vertex;
    if (is.good() && is.peek() == '/')
    {
        is.ignore(1);
        if(is.good() && is.peek() != '/')
        {
            is >> vi.texture;
        }
        if(is.good() && is.peek() == '/')
        {
            is.ignore(1);
            is >> vi.normal;
        }
    }
    return is;
}

std::istream & vfm::operator >> (std::istream &is, VertexIndexVector &viv)
{
    bool eol = false;
    while(is.good() && !eol)
    {
        VertexIndex vi;
        is >> vi;
        viv.push_back(vi);
        while (is.good())
        {
            int c = is.peek();
            if (c == '#' || c == '\n')
            {
                is >> eatline;
                eol = true;
                break;
            }
            else if (std::isspace(c))
            {
                is.get();
            }
            else {
                break;
            }
        }
    }
    return is;
}

static void createTriangles(const vfm::IndexVector &polygons, vfm::IndexVector &triangles)
{
    vfm::index_t nbIndices = polygons.size();
    if (nbIndices < 3)
    {
        return;
    }

    vfm::index_t descIndex = nbIndices;
    vfm::index_t ascIndex = 2;

    vfm::index_t previous = polygons[0];
    vfm::index_t current = polygons[1];
    vfm::index_t next = polygons[2];

    for(bool asc = false; ascIndex < descIndex; asc = !asc)
    {
        triangles.push_back(previous);
        triangles.push_back(current);
        triangles.push_back(next);

        if (asc)
        {
            current = next;
            next = polygons[++ascIndex];
        }
        else
        {
            current = previous;
            previous = polygons[--descIndex];
        }
    }
}

std::istream & vfm::operator >> (std::istream &is, ObjModel &model)
{
    std::string token;
    glm::vec4 vec4;
    glm::vec3 vec3;
    VertexIndexIndexer vertexIndexIndexer;
    vfm::IndexVector polygons;
    VertexIndexVector face;
    Object *object = 0;

    while (is >> token)
    {
        if (! token.empty() && token[0] == '#')
        {
            // ignore comments
            is >> eatline;
        }
        else if (token == "o")
        {
            model.objects.push_back(Object());
            object = &model.objects.back();
            vertexIndexIndexer << *object;
            is >> object->name;
        }
        else if (token == "v")
        {
            // read new vertex
            is >> vec4;
            if(!is.fail()) model.vertices.push_back(vec4);
        }
        else if (token == "vt")
        {
            // read texture coordinates
            is >> vec3;
            if (!is.fail()) model.textures.push_back(vec3);
        }
        else if (token == "vn")
        {
            // read normals coordinates
            is >> vec3;
            if (!is.fail()) model.normals.push_back(vec3);
        }
        else if (token == "f")
        {
            if (object == 0)
            {
                model.objects.push_back(Object());
                object = &model.objects.back();
                vertexIndexIndexer << *object;
            }

            face.clear();
            // read faces indices
            is >> face;

            if(!is.fail())
            {
                polygons.clear();
                for(vfm::VertexIndexVector::iterator it = face.begin(); it < face.end(); ++it)
                {
                    polygons.push_back(vertexIndexIndexer.getIndex(*it));
                }

                createTriangles(polygons, object->triangles);
            }
        }
        else
        {
            // ignore line
            is >> eatline;
        }
    }

    return is;
}

void vfm::ObjModel::computeNormals(bool normalized)
{
    this->normals.clear();
    this->normals.resize(this->vertices.size());
    VertexIndex *vertexIndices[3];
    for(ObjectVector::iterator itObj = this->objects.begin(); itObj != this->objects.end(); ++itObj)
    {
        Object *o = &(*itObj);
        for(IndexVector::iterator it = o->triangles.begin(); it != o->triangles.end(); ++it)
        {
            vertexIndices[0] = &o->vertexIndices[*it++];
            vertexIndices[1] = &o->vertexIndices[*it++];
            vertexIndices[2] = &o->vertexIndices[*it];
            glm::vec3 a(this->vertices[vertexIndices[0]->vertex-1]);
            glm::vec3 b(this->vertices[vertexIndices[1]->vertex-1]);
            glm::vec3 c(this->vertices[vertexIndices[2]->vertex-1]);

            glm::vec3 normal = glm::cross(b-a, c-a);
            for (int i = 0; i < 3; ++i)
            {
                index_t vertexIndex = vertexIndices[i]->vertex;
                this->normals[vertexIndex - 1] += normal;
                vertexIndices[i]->normal = vertexIndex;
            }
        }
    }

    if(normalized)
    {
        for(Vec3Vector::iterator itNormal = this->normals.begin(); itNormal != this->normals.end(); ++itNormal)
        {
            *itNormal = glm::normalize(*itNormal);
        }
    }
}
<commit_msg>fixing normalization bug in ObjModel::computeNormals<commit_after>#include <map>
#include "glm/geometric.hpp"
#include "ObjModel.hpp"

namespace
{

class VertexIndexIndexer
{
public:

    VertexIndexIndexer() : _object(0)
    {
    }

    VertexIndexIndexer& operator << (vfm::Object &o)
    {
        if (_object != &o)
        {
            _vertexIndexPtrMap.clear();
            _object = &o;
        }
        return *this;
    }

    vfm::index_t getIndex(const vfm::VertexIndex &vi)
    {
        size_t mapSize = _vertexIndexPtrMap.size();
        vfm::index_t *index = &_vertexIndexPtrMap[vi];
        if (_vertexIndexPtrMap.size() > mapSize)
        {
            *index = mapSize;
            _object->vertexIndices.push_back(vi);
        }
        return *index;
    }

private:
    struct VertexIndexPtrComparator {
        bool operator() (const vfm::VertexIndex &vi1, const vfm::VertexIndex &vi2) const
        {
          if (vi1.vertex == vi2.vertex)
          {
              if(vi1.normal == vi2.normal)
              {
                  return vi1.texture < vi2.texture;
              }
              return vi1.normal < vi2.normal;
          }
          return vi1.vertex < vi2.vertex;
        }
    };
    typedef std::map<vfm::VertexIndex, vfm::index_t, VertexIndexPtrComparator> VertexIndexMap;

    vfm::Object *_object;
    VertexIndexMap _vertexIndexPtrMap;
};

inline std::istream& eatline (std::istream& is)
{
    return is.ignore(std::numeric_limits<long>::max(), '\n');
}

}

vfm::VertexIndex::VertexIndex (index_t vertex, index_t normal, index_t texture)
    : vertex(vertex), normal(normal), texture(texture)
{
}

bool vfm::VertexIndex::operator == (const VertexIndex &vi) const
{
    return this->vertex == vi.vertex && this->normal == vi.normal && this->texture == vi.texture;
}

std::istream & vfm::operator >> (std::istream &is, glm::vec3 &v)
{
    is >> v.x;
    if(is.good())
    {
        is >> v.y;
        if (is.fail())
        {
            v.y = 0;
            v.z = 0;
            is.clear();
        }
        else if(is.good())
        {
            is >> v.z;
            if (is.fail())
            {
                v.z = 0;
                is.clear();
            }
        }
    }
    return is;
}

std::istream & vfm::operator >> (std::istream &is, glm::vec4 &v)
{
    is >> v.x >> v.y >> v.z;
    if (is.good())
    {
        is >> v.w;
        // w is optional, no matter if the stream has not
        // succeeded in reading it
        if (is.fail())
        {
            v.w = 1;
            is.clear();
        }
    }
    return is;
}

std::istream & vfm::operator >> (std::istream &is, VertexIndex &vi)
{
    is >> vi.vertex;
    if (is.good() && is.peek() == '/')
    {
        is.ignore(1);
        if(is.good() && is.peek() != '/')
        {
            is >> vi.texture;
        }
        if(is.good() && is.peek() == '/')
        {
            is.ignore(1);
            is >> vi.normal;
        }
    }
    return is;
}

std::istream & vfm::operator >> (std::istream &is, VertexIndexVector &viv)
{
    bool eol = false;
    while(is.good() && !eol)
    {
        VertexIndex vi;
        is >> vi;
        viv.push_back(vi);
        while (is.good())
        {
            int c = is.peek();
            if (c == '#' || c == '\n')
            {
                is >> eatline;
                eol = true;
                break;
            }
            else if (std::isspace(c))
            {
                is.get();
            }
            else {
                break;
            }
        }
    }
    return is;
}

static void createTriangles(const vfm::IndexVector &polygons, vfm::IndexVector &triangles)
{
    vfm::index_t nbIndices = polygons.size();
    if (nbIndices < 3)
    {
        return;
    }

    vfm::index_t descIndex = nbIndices;
    vfm::index_t ascIndex = 2;

    vfm::index_t previous = polygons[0];
    vfm::index_t current = polygons[1];
    vfm::index_t next = polygons[2];

    for(bool asc = false; ascIndex < descIndex; asc = !asc)
    {
        triangles.push_back(previous);
        triangles.push_back(current);
        triangles.push_back(next);

        if (asc)
        {
            current = next;
            next = polygons[++ascIndex];
        }
        else
        {
            current = previous;
            previous = polygons[--descIndex];
        }
    }
}

std::istream & vfm::operator >> (std::istream &is, ObjModel &model)
{
    std::string token;
    glm::vec4 vec4;
    glm::vec3 vec3;
    VertexIndexIndexer vertexIndexIndexer;
    vfm::IndexVector polygons;
    VertexIndexVector face;
    Object *object = 0;

    while (is >> token)
    {
        if (! token.empty() && token[0] == '#')
        {
            // ignore comments
            is >> eatline;
        }
        else if (token == "o")
        {
            model.objects.push_back(Object());
            object = &model.objects.back();
            vertexIndexIndexer << *object;
            is >> object->name;
        }
        else if (token == "v")
        {
            // read new vertex
            is >> vec4;
            if(!is.fail()) model.vertices.push_back(vec4);
        }
        else if (token == "vt")
        {
            // read texture coordinates
            is >> vec3;
            if (!is.fail()) model.textures.push_back(vec3);
        }
        else if (token == "vn")
        {
            // read normals coordinates
            is >> vec3;
            if (!is.fail()) model.normals.push_back(vec3);
        }
        else if (token == "f")
        {
            if (object == 0)
            {
                model.objects.push_back(Object());
                object = &model.objects.back();
                vertexIndexIndexer << *object;
            }

            face.clear();
            // read faces indices
            is >> face;

            if(!is.fail())
            {
                polygons.clear();
                for(vfm::VertexIndexVector::iterator it = face.begin(); it < face.end(); ++it)
                {
                    polygons.push_back(vertexIndexIndexer.getIndex(*it));
                }

                createTriangles(polygons, object->triangles);
            }
        }
        else
        {
            // ignore line
            is >> eatline;
        }
    }

    return is;
}

void vfm::ObjModel::computeNormals(bool normalized)
{
    this->normals.clear();
    this->normals.resize(this->vertices.size());
    VertexIndex *vertexIndices[3];
    for(ObjectVector::iterator itObj = this->objects.begin(); itObj != this->objects.end(); ++itObj)
    {
        Object *o = &(*itObj);
        for(IndexVector::iterator it = o->triangles.begin(); it != o->triangles.end(); ++it)
        {
            vertexIndices[0] = &o->vertexIndices[*it++];
            vertexIndices[1] = &o->vertexIndices[*it++];
            vertexIndices[2] = &o->vertexIndices[*it];
            glm::vec3 a(this->vertices[vertexIndices[0]->vertex-1]);
            glm::vec3 b(this->vertices[vertexIndices[1]->vertex-1]);
            glm::vec3 c(this->vertices[vertexIndices[2]->vertex-1]);

            glm::vec3 normal = glm::normalize(glm::cross(b-a, c-a));
            for (int i = 0; i < 3; ++i)
            {
                index_t vertexIndex = vertexIndices[i]->vertex;
                this->normals[vertexIndex - 1] += normal;
                vertexIndices[i]->normal = vertexIndex;
            }
        }
    }

    if(normalized)
    {
        for(Vec3Vector::iterator itNormal = this->normals.begin(); itNormal != this->normals.end(); ++itNormal)
        {
            *itNormal = glm::normalize(*itNormal);
        }
    }
}
<|endoftext|>


<commit_before>#include "CommandLineArgs.hpp"
#include "Exception.hpp"

static const int _arg_date_index = 1;

CommandLineArgs::CommandLineArgs(const int argc, char const * argv[])
{
	if (argc != 2)
	{
		throw InvalidArgumentException(
				"Usage: wherewasi [TIME]\n"
				"Time can be in the following formats:\n"
				"  [YYYY-MM-DD]\n"
				"  [YYYY/MM/DD]\n");
	}
	_date = std::string(argv[_arg_date_index]);
}

std::string CommandLineArgs::get_date() const
{
	return _date;
}
<commit_msg>Help description addition<commit_after>#include "CommandLineArgs.hpp"
#include "Exception.hpp"

static const int _arg_date_index = 1;

CommandLineArgs::CommandLineArgs(const int argc, char const * argv[])
{
	if (argc != 2)
	{
		throw InvalidArgumentException(
				"Usage: wherewasi [TIME]\n"
				"Time can be in the following formats:\n"
				"  [YYYY-MM-DD]\n"
				"  [YYYY/MM/DD]\n"
				"\n"
				"Time ranges are read from $HOME/.wherewasi\n");
	}
	_date = std::string(argv[_arg_date_index]);
}

std::string CommandLineArgs::get_date() const
{
	return _date;
}
<|endoftext|>


<commit_before><commit_msg>fix compile error<commit_after><|endoftext|>


<commit_before>#include "stdafx.h"
#include <iostream>
#include <list>
#include <vector>

class Figure {
public:
	virtual void drawStuff() = 0;
};

class Circle : public Figure {
public:
	void drawStuff() {
		std::cout << "Drawing circle." << std::endl;
	}
};

int main()
{
	std::vector<Figure*> myVector;
	// Figure *circle = new Circle();
	myVector.push_back(new Circle());

	for (std::vector<Figure*>::iterator it = myVector.begin(); it != myVector.end(); ++it)
	{
		(*it)->drawStuff();
	}

	return 0;
}

<commit_msg>Delete OOP-17.03.2016.cpp<commit_after><|endoftext|>