<commit_before>/*
 *            Copyright 2009-2018 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      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 <iostream>
#include <list>
#include <vector>
#include <algorithm>

#include <votca/tools/edge.h>

namespace votca {
namespace tools {

using namespace std;

Edge::Edge(int ID1, int ID2) {
  vertices_ = vector<int>{min({ID1,ID2}), max({ID1,ID2})};
}

int Edge::getOtherEndPoint(int ver) const {
  if (ver == vertices_.front()) {
    return vertices_.back();
  } else {
    return vertices_.front();
  }
}

bool Edge::contains(int ID) const {
  return (vertices_.front() == ID || vertices_.back() == ID);
}

bool Edge::operator==(const Edge ed) const {
  if (this->vertices_.front() == ed.vertices_.front() &&
      this->vertices_.back() == ed.vertices_.back())
    return true;
  if (this->vertices_.back() == ed.vertices_.front() &&
      this->vertices_.front() == ed.vertices_.back())
    return true;
  return false;
}

bool Edge::operator!=(const Edge ed) const { return !(*this == ed); }

bool Edge::operator<(const Edge ed) const {
  if (this->vertices_.front() < ed.vertices_.front()) return true;
  if (this->vertices_.front() > ed.vertices_.front()) return false;
  if (this->vertices_.back() < ed.vertices_.back()) return true;
  return false;
}

bool Edge::operator<=(const Edge ed) const {
  return (*this < ed || *this == ed);
}

bool Edge::operator>(const Edge ed) const { return !(*this <= ed); }

bool Edge::operator>=(const Edge ed) const { return !(*this < ed); }

ostream& operator<<(ostream& os, const Edge ed) {
  os << "Vertices" << endl;
  os << ed.vertices_.front() << " " << ed.vertices_.back() << endl;
  return os;
}
}
}
<commit_msg>Removed unused list<commit_after>/*
 *            Copyright 2009-2019 The VOTCA Development Team
 *                       (http://www.votca.org)
 *
 *      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 <algorithm>
#include <iostream>
#include <vector>
#include <votca/tools/edge.h>

namespace votca {
namespace tools {

using namespace std;

Edge::Edge(int ID1, int ID2) {
  vertices_ = vector<int>{min({ID1, ID2}), max({ID1, ID2})};
}

int Edge::getOtherEndPoint(int ver) const {
  if (ver == vertices_.front()) {
    return vertices_.back();
  } else {
    return vertices_.front();
  }
}

bool Edge::contains(int ID) const {
  return (vertices_.front() == ID || vertices_.back() == ID);
}

bool Edge::operator==(const Edge ed) const {
  if (this->vertices_.front() == ed.vertices_.front() &&
      this->vertices_.back() == ed.vertices_.back())
    return true;
  if (this->vertices_.back() == ed.vertices_.front() &&
      this->vertices_.front() == ed.vertices_.back())
    return true;
  return false;
}

bool Edge::operator!=(const Edge ed) const { return !(*this == ed); }

bool Edge::operator<(const Edge ed) const {
  if (this->vertices_.front() < ed.vertices_.front()) return true;
  if (this->vertices_.front() > ed.vertices_.front()) return false;
  if (this->vertices_.back() < ed.vertices_.back()) return true;
  return false;
}

bool Edge::operator<=(const Edge ed) const {
  return (*this < ed || *this == ed);
}

bool Edge::operator>(const Edge ed) const { return !(*this <= ed); }

bool Edge::operator>=(const Edge ed) const { return !(*this < ed); }

ostream& operator<<(ostream& os, const Edge ed) {
  os << "Vertices" << endl;
  os << ed.vertices_.front() << " " << ed.vertices_.back() << endl;
  return os;
}
}  // namespace tools
}  // namespace votca
<|endoftext|>


<commit_before>//==- CheckObjCDealloc.cpp - Check ObjC -dealloc implementation --*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines a CheckObjCDealloc, a checker that
//  analyzes an Objective-C class's implementation to determine if it
//  correctly implements -dealloc.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/LocalCheckers.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/LangOptions.h"
#include <sstream>

using namespace clang;

static bool scan_dealloc(Stmt* S, Selector Dealloc) {

  if (ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(S))
    if (ME->getSelector() == Dealloc)
      if (Expr* Receiver = ME->getReceiver()->IgnoreParenCasts())
        if (PredefinedExpr* E = dyn_cast<PredefinedExpr>(Receiver))
          if (E->getIdentType() == PredefinedExpr::ObjCSuper)
            return true;

  // Recurse to children.

  for (Stmt::child_iterator I = S->child_begin(), E= S->child_end(); I!=E; ++I)
    if (*I && scan_dealloc(*I, Dealloc))
      return true;

  return false;
}

void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
                             const LangOptions& LOpts, BugReporter& BR) {

  assert (LOpts.getGCMode() != LangOptions::GCOnly);

  ASTContext& Ctx = BR.getContext();
  ObjCInterfaceDecl* ID = D->getClassInterface();

  // Does the class contain any ivars that are pointers (or id<...>)?
  // If not, skip the check entirely.
  // NOTE: This is motivated by PR 2517:
  //        http://llvm.org/bugs/show_bug.cgi?id=2517

  bool containsPointerIvar = false;

  for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
       I!=E; ++I) {

    ObjCIvarDecl* ID = *I;
    QualType T = ID->getType();

    if (!Ctx.isObjCObjectPointerType(T) ||
        ID->getAttr<IBOutletAttr>()) // Skip IBOutlets.
      continue;

    containsPointerIvar = true;
    break;
  }

  if (!containsPointerIvar)
    return;

  // Determine if the class subclasses NSObject.
  IdentifierInfo* NSObjectII = &Ctx.Idents.get("NSObject");

  for ( ; ID ; ID = ID->getSuperClass())
    if (ID->getIdentifier() == NSObjectII)
      break;

  if (!ID)
    return;

  // Get the "dealloc" selector.
  IdentifierInfo* II = &Ctx.Idents.get("dealloc");
  Selector S = Ctx.Selectors.getSelector(0, &II);
  ObjCMethodDecl* MD = 0;

  // Scan the instance methods for "dealloc".
  for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
       E = D->instmeth_end(); I!=E; ++I) {

    if ((*I)->getSelector() == S) {
      MD = *I;
      break;
    }
  }

  if (!MD) { // No dealloc found.

    const char* name = LOpts.getGCMode() == LangOptions::NonGC
                       ? "missing -dealloc"
                       : "missing -dealloc (Hybrid MM, non-GC)";

    std::ostringstream os;
    os << "Objective-C class '" << D->getName()
       << "' lacks a 'dealloc' instance method";

    BR.EmitBasicReport(name, os.str().c_str(), D->getLocStart());
    return;
  }

  // dealloc found.  Scan for missing [super dealloc].
  if (MD->getBody() && !scan_dealloc(MD->getBody(), S)) {

    const char* name = LOpts.getGCMode() == LangOptions::NonGC
                       ? "missing [super dealloc]"
                       : "missing [super dealloc] (Hybrid MM, non-GC)";

    std::ostringstream os;
    os << "The 'dealloc' instance method in Objective-C class '" << D->getName()
       << "' does not send a 'dealloc' message to its super class"
           " (missing [super dealloc])";

    BR.EmitBasicReport(name, os.str().c_str(), D->getLocStart());
    return;
  }
}

<commit_msg>Patch by Nikita Zhuk:<commit_after>//==- CheckObjCDealloc.cpp - Check ObjC -dealloc implementation --*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines a CheckObjCDealloc, a checker that
//  analyzes an Objective-C class's implementation to determine if it
//  correctly implements -dealloc.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/LocalCheckers.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/LangOptions.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;

static bool scan_dealloc(Stmt* S, Selector Dealloc) {

  if (ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(S))
    if (ME->getSelector() == Dealloc)
      if (Expr* Receiver = ME->getReceiver()->IgnoreParenCasts())
        if (PredefinedExpr* E = dyn_cast<PredefinedExpr>(Receiver))
          if (E->getIdentType() == PredefinedExpr::ObjCSuper)
            return true;

  // Recurse to children.

  for (Stmt::child_iterator I = S->child_begin(), E= S->child_end(); I!=E; ++I)
    if (*I && scan_dealloc(*I, Dealloc))
      return true;

  return false;
}

static bool scan_ivar_release(Stmt* S, ObjCIvarDecl* ID, Selector Release ) {
  if (ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(S))
    if (ME->getSelector() == Release)
      if (Expr* Receiver = ME->getReceiver()->IgnoreParenCasts())
        if (ObjCIvarRefExpr* E = dyn_cast<ObjCIvarRefExpr>(Receiver))
          if (E->getDecl() == ID)
            return true;

  // Recurse to children.
  for (Stmt::child_iterator I = S->child_begin(), E= S->child_end(); I!=E; ++I)
    if (*I && scan_ivar_release(*I, ID, Release))
      return true;

  return false;
}

void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
                             const LangOptions& LOpts, BugReporter& BR) {

  assert (LOpts.getGCMode() != LangOptions::GCOnly);

  ASTContext& Ctx = BR.getContext();
  ObjCInterfaceDecl* ID = D->getClassInterface();

  // Does the class contain any ivars that are pointers (or id<...>)?
  // If not, skip the check entirely.
  // NOTE: This is motivated by PR 2517:
  //        http://llvm.org/bugs/show_bug.cgi?id=2517

  bool containsPointerIvar = false;

  for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
       I!=E; ++I) {

    ObjCIvarDecl* ID = *I;
    QualType T = ID->getType();

    if (!Ctx.isObjCObjectPointerType(T) ||
        ID->getAttr<IBOutletAttr>()) // Skip IBOutlets.
      continue;

    containsPointerIvar = true;
    break;
  }

  if (!containsPointerIvar)
    return;

  // Determine if the class subclasses NSObject.
  IdentifierInfo* NSObjectII = &Ctx.Idents.get("NSObject");

  for ( ; ID ; ID = ID->getSuperClass())
    if (ID->getIdentifier() == NSObjectII)
      break;

  if (!ID)
    return;

  // Get the "dealloc" selector.
  IdentifierInfo* II = &Ctx.Idents.get("dealloc");
  Selector S = Ctx.Selectors.getSelector(0, &II);
  ObjCMethodDecl* MD = 0;

  // Scan the instance methods for "dealloc".
  for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
       E = D->instmeth_end(); I!=E; ++I) {

    if ((*I)->getSelector() == S) {
      MD = *I;
      break;
    }
  }

  if (!MD) { // No dealloc found.

    const char* name = LOpts.getGCMode() == LangOptions::NonGC
                       ? "missing -dealloc"
                       : "missing -dealloc (Hybrid MM, non-GC)";

    std::string buf;
    llvm::raw_string_ostream os(buf);
    os << "Objective-C class '" << D->getName()
       << "' lacks a 'dealloc' instance method";

    BR.EmitBasicReport(name, os.str().c_str(), D->getLocStart());
    return;
  }

  // dealloc found.  Scan for missing [super dealloc].
  if (MD->getBody() && !scan_dealloc(MD->getBody(), S)) {

    const char* name = LOpts.getGCMode() == LangOptions::NonGC
                       ? "missing [super dealloc]"
                       : "missing [super dealloc] (Hybrid MM, non-GC)";

    std::string buf;
    llvm::raw_string_ostream os(buf);
    os << "The 'dealloc' instance method in Objective-C class '" << D->getName()
       << "' does not send a 'dealloc' message to its super class"
           " (missing [super dealloc])";

    BR.EmitBasicReport(name, os.str().c_str(), D->getLocStart());
    return;
  }

  // Get the "release" selector.
  IdentifierInfo* RII = &Ctx.Idents.get("release");
  Selector RS = Ctx.Selectors.getSelector(0, &RII);

  // Scan for missing and extra releases of ivars used by implementations
  // of synthesized properties
  for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
       E = D->propimpl_end(); I!=E; ++I) {

    // We can only check the synthesized properties
    if((*I)->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
      continue;

    ObjCIvarDecl* ID = (*I)->getPropertyIvarDecl();
    if (!ID)
      continue;

    QualType T = ID->getType();
    if (!Ctx.isObjCObjectPointerType(T)) // Skip non-pointer ivars
      continue;

    const ObjCPropertyDecl* PD = (*I)->getPropertyDecl();
    if(!PD)
      continue;

    // ivars cannot be set via read-only properties, so we'll skip them
    if(PD->isReadOnly())
       continue;

    // ivar must be released if and only if the kind of setter was not 'assign'
    bool requiresRelease = PD->getSetterKind() != ObjCPropertyDecl::Assign;
    if(scan_ivar_release(MD->getBody(), ID, RS) != requiresRelease) {
      const char *name;
      const char* category = "Memory (Core Foundation/Objective-C)";

      std::string buf;
      llvm::raw_string_ostream os(buf);

      if(requiresRelease) {
        name = LOpts.getGCMode() == LangOptions::NonGC
               ? "missing ivar release (leak)"
               : "missing ivar release (Hybrid MM, non-GC)";

        os << "The '" << ID->getName()
           << "' instance variable was retained by a synthesized property but "
              "wasn't released in 'dealloc'";
      } else {
        name = LOpts.getGCMode() == LangOptions::NonGC
               ? "extra ivar release (use-after-release)"
               : "extra ivar release (Hybrid MM, non-GC)";

        os << "The '" << ID->getName()
           << "' instance variable was not retained by a synthesized property "
              "but was released in 'dealloc'";
      }

      BR.EmitBasicReport(name, category,
                         os.str().c_str(), (*I)->getLocation());
    }
  }
}

<|endoftext|>


<commit_before>//===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the LLVMTargetMachine class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetMachine.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;

namespace llvm {
  bool EnableFastISel;
}

static cl::opt<bool> DisablePostRA("disable-post-ra", cl::Hidden,
    cl::desc("Disable Post Regalloc"));
static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
    cl::desc("Disable branch folding"));
static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden,
    cl::desc("Disable tail duplication"));
static cl::opt<bool> DisableCodePlace("disable-code-place", cl::Hidden,
    cl::desc("Disable code placement"));
static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
    cl::desc("Disable Stack Slot Coloring"));
static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
    cl::desc("Disable Machine LICM"));
static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden,
    cl::desc("Disable Machine Sinking"));
static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden,
    cl::desc("Disable Loop Strength Reduction Pass"));
static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden,
    cl::desc("Disable Codegen Prepare"));
static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
    cl::desc("Print LLVM IR produced by the loop-reduce pass"));
static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
    cl::desc("Print LLVM IR input to isel pass"));
static cl::opt<bool> PrintEmittedAsm("print-emitted-asm", cl::Hidden,
    cl::desc("Dump emitter generated instructions as assembly"));
static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden,
    cl::desc("Dump garbage collector data"));
static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden,
    cl::desc("Verify generated machine code"),
    cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL));

#if 1
static cl::opt<bool> XX("xx", cl::Hidden);
#endif

// Enable or disable FastISel. Both options are needed, because
// FastISel is enabled by default with -fast, and we wish to be
// able to enable or disable fast-isel independently from -O0.
static cl::opt<cl::boolOrDefault>
EnableFastISelOption("fast-isel", cl::Hidden,
  cl::desc("Enable the \"fast\" instruction selector"));

// Enable or disable an experimental optimization to split GEPs
// and run a special GVN pass which does not examine loads, in
// an effort to factor out redundancy implicit in complex GEPs.
static cl::opt<bool> EnableSplitGEPGVN("split-gep-gvn", cl::Hidden,
    cl::desc("Split GEPs and run no-load GVN"));

static cl::opt<bool> PreAllocTailDup("pre-regalloc-taildup", cl::Hidden,
    cl::desc("Pre-register allocation tail duplication"));

LLVMTargetMachine::LLVMTargetMachine(const Target &T,
                                     const std::string &TargetTriple)
  : TargetMachine(T) {
  AsmInfo = T.createAsmInfo(TargetTriple);
}

// Set the default code model for the JIT for a generic target.
// FIXME: Is small right here? or .is64Bit() ? Large : Small?
void
LLVMTargetMachine::setCodeModelForJIT() {
  setCodeModel(CodeModel::Small);
}

// Set the default code model for static compilation for a generic target.
void
LLVMTargetMachine::setCodeModelForStatic() {
  setCodeModel(CodeModel::Small);
}

FileModel::Model
LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
                                       formatted_raw_ostream &Out,
                                       CodeGenFileType FileType,
                                       CodeGenOpt::Level OptLevel) {
  // Add common CodeGen passes.
  if (addCommonCodeGenPasses(PM, OptLevel))
    return FileModel::Error;

  switch (FileType) {
  default:
    break;
  case TargetMachine::AssemblyFile:
    if (addAssemblyEmitter(PM, OptLevel, getAsmVerbosityDefault(), Out))
      return FileModel::Error;
    return FileModel::AsmFile;
  case TargetMachine::ObjectFile:
    if (getMachOWriterInfo())
      return FileModel::MachOFile;
    else if (getELFWriterInfo())
      return FileModel::ElfFile;
  }

  return FileModel::Error;
}

bool LLVMTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
                                           CodeGenOpt::Level OptLevel,
                                           bool Verbose,
                                           formatted_raw_ostream &Out) {
  FunctionPass *Printer =
    getTarget().createAsmPrinter(Out, *this, getMCAsmInfo(), Verbose);
  if (!Printer)
    return true;

  PM.add(Printer);
  return false;
}

/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
/// be split up (e.g., to add an object writer pass), this method can be used to
/// finish up adding passes to emit the file, if necessary.
bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
                                                  MachineCodeEmitter *MCE,
                                                  CodeGenOpt::Level OptLevel) {
  // Make sure the code model is set.
  setCodeModelForStatic();

  if (MCE)
    addSimpleCodeEmitter(PM, OptLevel, *MCE);
  if (PrintEmittedAsm)
    addAssemblyEmitter(PM, OptLevel, true, ferrs());

  PM.add(createGCInfoDeleter());

  return false; // success!
}

/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
/// be split up (e.g., to add an object writer pass), this method can be used to
/// finish up adding passes to emit the file, if necessary.
bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
                                                  JITCodeEmitter *JCE,
                                                  CodeGenOpt::Level OptLevel) {
  // Make sure the code model is set.
  setCodeModelForJIT();

  if (JCE)
    addSimpleCodeEmitter(PM, OptLevel, *JCE);
  if (PrintEmittedAsm)
    addAssemblyEmitter(PM, OptLevel, true, ferrs());

  PM.add(createGCInfoDeleter());

  return false; // success!
}

/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
/// be split up (e.g., to add an object writer pass), this method can be used to
/// finish up adding passes to emit the file, if necessary.
bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
                                                  ObjectCodeEmitter *OCE,
                                                  CodeGenOpt::Level OptLevel) {
  // Make sure the code model is set.
  setCodeModelForStatic();

  if (OCE)
    addSimpleCodeEmitter(PM, OptLevel, *OCE);
  if (PrintEmittedAsm)
    addAssemblyEmitter(PM, OptLevel, true, ferrs());

  PM.add(createGCInfoDeleter());

  return false; // success!
}

/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted.  This uses a MachineCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
/// of functions.  This method should returns true if machine code emission is
/// not supported.
///
bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
                                                   MachineCodeEmitter &MCE,
                                                   CodeGenOpt::Level OptLevel) {
  // Make sure the code model is set.
  setCodeModelForJIT();

  // Add common CodeGen passes.
  if (addCommonCodeGenPasses(PM, OptLevel))
    return true;

  addCodeEmitter(PM, OptLevel, MCE);
  if (PrintEmittedAsm)
    addAssemblyEmitter(PM, OptLevel, true, ferrs());

  PM.add(createGCInfoDeleter());

  return false; // success!
}

/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted.  This uses a MachineCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
/// of functions.  This method should returns true if machine code emission is
/// not supported.
///
bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
                                                   JITCodeEmitter &JCE,
                                                   CodeGenOpt::Level OptLevel) {
  // Make sure the code model is set.
  setCodeModelForJIT();

  // Add common CodeGen passes.
  if (addCommonCodeGenPasses(PM, OptLevel))
    return true;

  addCodeEmitter(PM, OptLevel, JCE);
  if (PrintEmittedAsm)
    addAssemblyEmitter(PM, OptLevel, true, ferrs());

  PM.add(createGCInfoDeleter());

  return false; // success!
}

static void printAndVerify(PassManagerBase &PM,
                           const char *Banner,
                           bool allowDoubleDefs = false) {
  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(dbgs(), Banner));

  if (VerifyMachineCode)
    PM.add(createMachineVerifierPass(allowDoubleDefs));
}

/// addCommonCodeGenPasses - Add standard LLVM codegen passes used for both
/// emitting to assembly files or machine code output.
///
bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
                                               CodeGenOpt::Level OptLevel) {
  // Standard LLVM-Level Passes.

  // Optionally, tun split-GEPs and no-load GVN.
  if (EnableSplitGEPGVN) {
    PM.add(createGEPSplitterPass());
    PM.add(createGVNPass(/*NoPRE=*/false, /*NoLoads=*/true));
  }

  // Run loop strength reduction before anything else.
  if (OptLevel != CodeGenOpt::None && !DisableLSR) {
    PM.add(createLoopStrengthReducePass(getTargetLowering()));
    if (PrintLSR)
      PM.add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &dbgs()));
  }

  // Turn exception handling constructs into something the code generators can
  // handle.
  switch (getMCAsmInfo()->getExceptionHandlingType())
  {
  case ExceptionHandling::SjLj:
    // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
    PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None));
    PM.add(createSjLjEHPass(getTargetLowering()));
    break;
  case ExceptionHandling::Dwarf:
    PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None));
    break;
  case ExceptionHandling::None:
    PM.add(createLowerInvokePass(getTargetLowering()));
    break;
  }

  PM.add(createGCLoweringPass());

  // Make sure that no unreachable blocks are instruction selected.
  PM.add(createUnreachableBlockEliminationPass());

  if (OptLevel != CodeGenOpt::None && !DisableCGP)
    PM.add(createCodeGenPreparePass(getTargetLowering()));

  PM.add(createStackProtectorPass(getTargetLowering()));

  if (PrintISelInput)
    PM.add(createPrintFunctionPass("\n\n"
                                   "*** Final LLVM Code input to ISel ***\n",
                                   &dbgs()));

  // Standard Lower-Level Passes.

  // Set up a MachineFunction for the rest of CodeGen to work on.
  PM.add(new MachineFunctionAnalysis(*this, OptLevel));

  // Enable FastISel with -fast, but allow that to be overridden.
  if (EnableFastISelOption == cl::BOU_TRUE ||
      (OptLevel == CodeGenOpt::None && EnableFastISelOption != cl::BOU_FALSE))
    EnableFastISel = true;

  // Ask the target for an isel.
  if (addInstSelector(PM, OptLevel))
    return true;

  // Print the instruction selected machine code...
  printAndVerify(PM, "After Instruction Selection",
                 /* allowDoubleDefs= */ true);

  if (OptLevel != CodeGenOpt::None) {
    PM.add(createOptimizeExtsPass());
    if (!DisableMachineLICM)
      PM.add(createMachineLICMPass());
    if (!DisableMachineSink)
      PM.add(createMachineSinkingPass());
    printAndVerify(PM, "After MachineLICM and MachineSinking",
                   /* allowDoubleDefs= */ true);
  }

  // Pre-ra tail duplication.
  if (OptLevel != CodeGenOpt::None &&
      !DisableTailDuplicate && PreAllocTailDup) {
    PM.add(createTailDuplicatePass(true));
    printAndVerify(PM, "After Pre-RegAlloc TailDuplicate",
                   /* allowDoubleDefs= */ true);
  }

  // Run pre-ra passes.
  if (addPreRegAlloc(PM, OptLevel))
    printAndVerify(PM, "After PreRegAlloc passes",
                   /* allowDoubleDefs= */ true);

  // Perform register allocation.
  PM.add(createRegisterAllocator());
  printAndVerify(PM, "After Register Allocation");

  // Perform stack slot coloring.
  if (OptLevel != CodeGenOpt::None && !DisableSSC) {
    // FIXME: Re-enable coloring with register when it's capable of adding
    // kill markers.
    PM.add(createStackSlotColoringPass(false));
    printAndVerify(PM, "After StackSlotColoring");
  }

  // Run post-ra passes.
  if (addPostRegAlloc(PM, OptLevel))
    printAndVerify(PM, "After PostRegAlloc passes");

  PM.add(createLowerSubregsPass());
  printAndVerify(PM, "After LowerSubregs");

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  PM.add(createPrologEpilogCodeInserter());
  printAndVerify(PM, "After PrologEpilogCodeInserter");

  // Run pre-sched2 passes.
  if (addPreSched2(PM, OptLevel))
    printAndVerify(PM, "After PreSched2 passes");

  // Second pass scheduler.
  if (OptLevel != CodeGenOpt::None && !DisablePostRA) {
    PM.add(createPostRAScheduler(OptLevel));
    printAndVerify(PM, "After PostRAScheduler");
  }

  // Branch folding must be run after regalloc and prolog/epilog insertion.
  if (OptLevel != CodeGenOpt::None && !DisableBranchFold) {
    PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
    printAndVerify(PM, "After BranchFolding");
  }

  // Tail duplication.
  if (OptLevel != CodeGenOpt::None && !DisableTailDuplicate) {
    PM.add(createTailDuplicatePass(false));
    printAndVerify(PM, "After TailDuplicate");
  }

  PM.add(createGCMachineCodeAnalysisPass());

  if (PrintGCInfo)
    PM.add(createGCInfoPrinter(dbgs()));

  if (OptLevel != CodeGenOpt::None && !DisableCodePlace) {
    PM.add(createCodePlacementOptPass());
    printAndVerify(PM, "After CodePlacementOpt");
  }

  if (addPreEmitPass(PM, OptLevel))
    printAndVerify(PM, "After PreEmit passes");

  return false;
}
<commit_msg>Remove debug option I accidentally left in.<commit_after>//===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the LLVMTargetMachine class.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetMachine.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;

namespace llvm {
  bool EnableFastISel;
}

static cl::opt<bool> DisablePostRA("disable-post-ra", cl::Hidden,
    cl::desc("Disable Post Regalloc"));
static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
    cl::desc("Disable branch folding"));
static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden,
    cl::desc("Disable tail duplication"));
static cl::opt<bool> DisableCodePlace("disable-code-place", cl::Hidden,
    cl::desc("Disable code placement"));
static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
    cl::desc("Disable Stack Slot Coloring"));
static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
    cl::desc("Disable Machine LICM"));
static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden,
    cl::desc("Disable Machine Sinking"));
static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden,
    cl::desc("Disable Loop Strength Reduction Pass"));
static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden,
    cl::desc("Disable Codegen Prepare"));
static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
    cl::desc("Print LLVM IR produced by the loop-reduce pass"));
static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
    cl::desc("Print LLVM IR input to isel pass"));
static cl::opt<bool> PrintEmittedAsm("print-emitted-asm", cl::Hidden,
    cl::desc("Dump emitter generated instructions as assembly"));
static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden,
    cl::desc("Dump garbage collector data"));
static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden,
    cl::desc("Verify generated machine code"),
    cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL));

// Enable or disable FastISel. Both options are needed, because
// FastISel is enabled by default with -fast, and we wish to be
// able to enable or disable fast-isel independently from -O0.
static cl::opt<cl::boolOrDefault>
EnableFastISelOption("fast-isel", cl::Hidden,
  cl::desc("Enable the \"fast\" instruction selector"));

// Enable or disable an experimental optimization to split GEPs
// and run a special GVN pass which does not examine loads, in
// an effort to factor out redundancy implicit in complex GEPs.
static cl::opt<bool> EnableSplitGEPGVN("split-gep-gvn", cl::Hidden,
    cl::desc("Split GEPs and run no-load GVN"));

static cl::opt<bool> PreAllocTailDup("pre-regalloc-taildup", cl::Hidden,
    cl::desc("Pre-register allocation tail duplication"));

LLVMTargetMachine::LLVMTargetMachine(const Target &T,
                                     const std::string &TargetTriple)
  : TargetMachine(T) {
  AsmInfo = T.createAsmInfo(TargetTriple);
}

// Set the default code model for the JIT for a generic target.
// FIXME: Is small right here? or .is64Bit() ? Large : Small?
void
LLVMTargetMachine::setCodeModelForJIT() {
  setCodeModel(CodeModel::Small);
}

// Set the default code model for static compilation for a generic target.
void
LLVMTargetMachine::setCodeModelForStatic() {
  setCodeModel(CodeModel::Small);
}

FileModel::Model
LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
                                       formatted_raw_ostream &Out,
                                       CodeGenFileType FileType,
                                       CodeGenOpt::Level OptLevel) {
  // Add common CodeGen passes.
  if (addCommonCodeGenPasses(PM, OptLevel))
    return FileModel::Error;

  switch (FileType) {
  default:
    break;
  case TargetMachine::AssemblyFile:
    if (addAssemblyEmitter(PM, OptLevel, getAsmVerbosityDefault(), Out))
      return FileModel::Error;
    return FileModel::AsmFile;
  case TargetMachine::ObjectFile:
    if (getMachOWriterInfo())
      return FileModel::MachOFile;
    else if (getELFWriterInfo())
      return FileModel::ElfFile;
  }

  return FileModel::Error;
}

bool LLVMTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
                                           CodeGenOpt::Level OptLevel,
                                           bool Verbose,
                                           formatted_raw_ostream &Out) {
  FunctionPass *Printer =
    getTarget().createAsmPrinter(Out, *this, getMCAsmInfo(), Verbose);
  if (!Printer)
    return true;

  PM.add(Printer);
  return false;
}

/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
/// be split up (e.g., to add an object writer pass), this method can be used to
/// finish up adding passes to emit the file, if necessary.
bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
                                                  MachineCodeEmitter *MCE,
                                                  CodeGenOpt::Level OptLevel) {
  // Make sure the code model is set.
  setCodeModelForStatic();

  if (MCE)
    addSimpleCodeEmitter(PM, OptLevel, *MCE);
  if (PrintEmittedAsm)
    addAssemblyEmitter(PM, OptLevel, true, ferrs());

  PM.add(createGCInfoDeleter());

  return false; // success!
}

/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
/// be split up (e.g., to add an object writer pass), this method can be used to
/// finish up adding passes to emit the file, if necessary.
bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
                                                  JITCodeEmitter *JCE,
                                                  CodeGenOpt::Level OptLevel) {
  // Make sure the code model is set.
  setCodeModelForJIT();

  if (JCE)
    addSimpleCodeEmitter(PM, OptLevel, *JCE);
  if (PrintEmittedAsm)
    addAssemblyEmitter(PM, OptLevel, true, ferrs());

  PM.add(createGCInfoDeleter());

  return false; // success!
}

/// addPassesToEmitFileFinish - If the passes to emit the specified file had to
/// be split up (e.g., to add an object writer pass), this method can be used to
/// finish up adding passes to emit the file, if necessary.
bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
                                                  ObjectCodeEmitter *OCE,
                                                  CodeGenOpt::Level OptLevel) {
  // Make sure the code model is set.
  setCodeModelForStatic();

  if (OCE)
    addSimpleCodeEmitter(PM, OptLevel, *OCE);
  if (PrintEmittedAsm)
    addAssemblyEmitter(PM, OptLevel, true, ferrs());

  PM.add(createGCInfoDeleter());

  return false; // success!
}

/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted.  This uses a MachineCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
/// of functions.  This method should returns true if machine code emission is
/// not supported.
///
bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
                                                   MachineCodeEmitter &MCE,
                                                   CodeGenOpt::Level OptLevel) {
  // Make sure the code model is set.
  setCodeModelForJIT();

  // Add common CodeGen passes.
  if (addCommonCodeGenPasses(PM, OptLevel))
    return true;

  addCodeEmitter(PM, OptLevel, MCE);
  if (PrintEmittedAsm)
    addAssemblyEmitter(PM, OptLevel, true, ferrs());

  PM.add(createGCInfoDeleter());

  return false; // success!
}

/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted.  This uses a MachineCodeEmitter object to handle
/// actually outputting the machine code and resolving things like the address
/// of functions.  This method should returns true if machine code emission is
/// not supported.
///
bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
                                                   JITCodeEmitter &JCE,
                                                   CodeGenOpt::Level OptLevel) {
  // Make sure the code model is set.
  setCodeModelForJIT();

  // Add common CodeGen passes.
  if (addCommonCodeGenPasses(PM, OptLevel))
    return true;

  addCodeEmitter(PM, OptLevel, JCE);
  if (PrintEmittedAsm)
    addAssemblyEmitter(PM, OptLevel, true, ferrs());

  PM.add(createGCInfoDeleter());

  return false; // success!
}

static void printAndVerify(PassManagerBase &PM,
                           const char *Banner,
                           bool allowDoubleDefs = false) {
  if (PrintMachineCode)
    PM.add(createMachineFunctionPrinterPass(dbgs(), Banner));

  if (VerifyMachineCode)
    PM.add(createMachineVerifierPass(allowDoubleDefs));
}

/// addCommonCodeGenPasses - Add standard LLVM codegen passes used for both
/// emitting to assembly files or machine code output.
///
bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
                                               CodeGenOpt::Level OptLevel) {
  // Standard LLVM-Level Passes.

  // Optionally, tun split-GEPs and no-load GVN.
  if (EnableSplitGEPGVN) {
    PM.add(createGEPSplitterPass());
    PM.add(createGVNPass(/*NoPRE=*/false, /*NoLoads=*/true));
  }

  // Run loop strength reduction before anything else.
  if (OptLevel != CodeGenOpt::None && !DisableLSR) {
    PM.add(createLoopStrengthReducePass(getTargetLowering()));
    if (PrintLSR)
      PM.add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &dbgs()));
  }

  // Turn exception handling constructs into something the code generators can
  // handle.
  switch (getMCAsmInfo()->getExceptionHandlingType())
  {
  case ExceptionHandling::SjLj:
    // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
    PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None));
    PM.add(createSjLjEHPass(getTargetLowering()));
    break;
  case ExceptionHandling::Dwarf:
    PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None));
    break;
  case ExceptionHandling::None:
    PM.add(createLowerInvokePass(getTargetLowering()));
    break;
  }

  PM.add(createGCLoweringPass());

  // Make sure that no unreachable blocks are instruction selected.
  PM.add(createUnreachableBlockEliminationPass());

  if (OptLevel != CodeGenOpt::None && !DisableCGP)
    PM.add(createCodeGenPreparePass(getTargetLowering()));

  PM.add(createStackProtectorPass(getTargetLowering()));

  if (PrintISelInput)
    PM.add(createPrintFunctionPass("\n\n"
                                   "*** Final LLVM Code input to ISel ***\n",
                                   &dbgs()));

  // Standard Lower-Level Passes.

  // Set up a MachineFunction for the rest of CodeGen to work on.
  PM.add(new MachineFunctionAnalysis(*this, OptLevel));

  // Enable FastISel with -fast, but allow that to be overridden.
  if (EnableFastISelOption == cl::BOU_TRUE ||
      (OptLevel == CodeGenOpt::None && EnableFastISelOption != cl::BOU_FALSE))
    EnableFastISel = true;

  // Ask the target for an isel.
  if (addInstSelector(PM, OptLevel))
    return true;

  // Print the instruction selected machine code...
  printAndVerify(PM, "After Instruction Selection",
                 /* allowDoubleDefs= */ true);

  if (OptLevel != CodeGenOpt::None) {
    PM.add(createOptimizeExtsPass());
    if (!DisableMachineLICM)
      PM.add(createMachineLICMPass());
    if (!DisableMachineSink)
      PM.add(createMachineSinkingPass());
    printAndVerify(PM, "After MachineLICM and MachineSinking",
                   /* allowDoubleDefs= */ true);
  }

  // Pre-ra tail duplication.
  if (OptLevel != CodeGenOpt::None &&
      !DisableTailDuplicate && PreAllocTailDup) {
    PM.add(createTailDuplicatePass(true));
    printAndVerify(PM, "After Pre-RegAlloc TailDuplicate",
                   /* allowDoubleDefs= */ true);
  }

  // Run pre-ra passes.
  if (addPreRegAlloc(PM, OptLevel))
    printAndVerify(PM, "After PreRegAlloc passes",
                   /* allowDoubleDefs= */ true);

  // Perform register allocation.
  PM.add(createRegisterAllocator());
  printAndVerify(PM, "After Register Allocation");

  // Perform stack slot coloring.
  if (OptLevel != CodeGenOpt::None && !DisableSSC) {
    // FIXME: Re-enable coloring with register when it's capable of adding
    // kill markers.
    PM.add(createStackSlotColoringPass(false));
    printAndVerify(PM, "After StackSlotColoring");
  }

  // Run post-ra passes.
  if (addPostRegAlloc(PM, OptLevel))
    printAndVerify(PM, "After PostRegAlloc passes");

  PM.add(createLowerSubregsPass());
  printAndVerify(PM, "After LowerSubregs");

  // Insert prolog/epilog code.  Eliminate abstract frame index references...
  PM.add(createPrologEpilogCodeInserter());
  printAndVerify(PM, "After PrologEpilogCodeInserter");

  // Run pre-sched2 passes.
  if (addPreSched2(PM, OptLevel))
    printAndVerify(PM, "After PreSched2 passes");

  // Second pass scheduler.
  if (OptLevel != CodeGenOpt::None && !DisablePostRA) {
    PM.add(createPostRAScheduler(OptLevel));
    printAndVerify(PM, "After PostRAScheduler");
  }

  // Branch folding must be run after regalloc and prolog/epilog insertion.
  if (OptLevel != CodeGenOpt::None && !DisableBranchFold) {
    PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
    printAndVerify(PM, "After BranchFolding");
  }

  // Tail duplication.
  if (OptLevel != CodeGenOpt::None && !DisableTailDuplicate) {
    PM.add(createTailDuplicatePass(false));
    printAndVerify(PM, "After TailDuplicate");
  }

  PM.add(createGCMachineCodeAnalysisPass());

  if (PrintGCInfo)
    PM.add(createGCInfoPrinter(dbgs()));

  if (OptLevel != CodeGenOpt::None && !DisableCodePlace) {
    PM.add(createCodePlacementOptPass());
    printAndVerify(PM, "After CodePlacementOpt");
  }

  if (addPreEmitPass(PM, OptLevel))
    printAndVerify(PM, "After PreEmit passes");

  return false;
}
<|endoftext|>


<commit_before>// kmmsgpart.cpp

#include <qdir.h>

#include "kmmsgpart.h"
#include "kmmessage.h"
#include <kmimemagic.h>
#include <kapp.h>
#include <kconfig.h>
#include <kglobal.h>
#include <kstddirs.h>

#include <mimelib/enum.h>
#include <mimelib/body.h>
#include <mimelib/bodypart.h>
#include <mimelib/utility.h>

//-----------------------------------------------------------------------------
KMMessagePart::KMMessagePart() :
  mType("text"), mSubtype("plain"), mCte("7bit"), mContentDescription(),
  mContentDisposition(), mBody(), mName()
{
  mBodySize = 0;
}

//-----------------------------------------------------------------------------
KMMessagePart::~KMMessagePart()
{
}

//-----------------------------------------------------------------------------
int KMMessagePart::size(void) const
{
  if (mBodySize < 0)
  {
    ((KMMessagePart*)this)->mBodySize =
      bodyDecoded().size() - 1;
  }
  return mBodySize;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setBody(const QString aStr)
{
  int encoding = contentTransferEncoding();

  mBody = aStr.copy();

  if (encoding!=DwMime::kCteQuotedPrintable &&
      encoding!=DwMime::kCteBase64)
  {
    mBodySize = mBody.size() - 1;
  }
  else mBodySize = -1;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setBodyEncoded(const QByteArray& aStr)
{
  DwString dwResult, dwSrc;
  int encoding = contentTransferEncoding();
  int len;

  mBodySize = aStr.size() - 1;

  switch (encoding)
  {
  case DwMime::kCteQuotedPrintable:
    dwSrc = DwString(aStr.data(), aStr.size()-1);
    DwEncodeQuotedPrintable(dwSrc, dwResult);
    len = dwResult.size();
    mBody.truncate(len);
    memcpy(mBody.data(), dwResult.c_str(), len+1);
    break;
  case DwMime::kCteBase64:
    dwSrc = DwString(aStr.data(), aStr.size()-1);
    DwEncodeBase64(dwSrc, dwResult);
    len = dwResult.size();
    mBody.truncate(len);
    memcpy(mBody.data(), dwResult.c_str(), len+1);
    break;
    len = aStr.size()-1;
    dwSrc = DwString(aStr.data(), len);
    DwEncodeBase64(dwSrc, dwResult);
    mBody = QString(dwResult.c_str());
    break;
  default:
    debug("WARNING -- unknown encoding `%s'. Assuming 8bit.",
	  (const char*)cteStr());
  case DwMime::kCte7bit:
  case DwMime::kCte8bit:
  case DwMime::kCteBinary:
    mBody = aStr;
    break;
  }
}

//-----------------------------------------------------------------------------
QByteArray KMMessagePart::bodyDecoded(void) const
{
  DwString dwResult, dwSrc;
  QByteArray result;
  int encoding = contentTransferEncoding();
  int len;

  switch (encoding)
  {
  case DwMime::kCteQuotedPrintable:
    dwSrc = DwString(mBody.data(), mBody.size());
    DwDecodeQuotedPrintable(dwSrc, dwResult);
    len = dwResult.size();
    result.resize(len);
    memcpy((void*)result.data(), (void*)dwResult.c_str(), len);
    break;
  case DwMime::kCteBase64:
    dwSrc = DwString(mBody.data(), mBody.size());
    DwDecodeBase64(dwSrc, dwResult);
    len = dwResult.size();
    result.resize(len);
    memcpy((void*)result.data(), (void*)dwResult.c_str(), len);
    break;
  default:
    debug("WARNING -- unknown encoding `%s'. Assuming 8bit.",
	  (const char*)cteStr());
  case DwMime::kCte7bit:
  case DwMime::kCte8bit:
  case DwMime::kCteBinary:
    len = mBody.length();
    result.resize(len);
    memcpy((void*)result.data(), (void*)mBody.data(), len);
    break;
  }

  return result;
}

//-----------------------------------------------------------------------------
void KMMessagePart::magicSetType(bool aAutoDecode)
{
  QString mimetype;
  QByteArray body;
  KMimeMagicResult *result;

  int sep;

  KMimeMagic::self()->setFollowLinks(TRUE); // is it necessary ?

  if (aAutoDecode)
    body = bodyDecoded();
  else
    body = mBody;

  result = KMimeMagic::self()->findBufferType( body );
  mimetype = result->mimeType();
  sep = mimetype.find('/');
  mType = mimetype.left(sep);
  mSubtype = mimetype.mid(sep+1, 64);
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::iconName(void) const
{
  QString fileName, icon;
  QDir dir;

  fileName = locate("mime", mType.lower() + "/" + mSubtype.lower() + ".desktop");

  if (!(fileName.isEmpty()) && dir.exists(fileName))
  {
    KConfig config(fileName);
    config.setDesktopGroup();
    icon = config.readEntry("Icon");
    if(icon.isEmpty()) // If no icon specified.
      icon = "mimetypes/unknown";
  }
  else
  {
    // not found, use default
    icon = "mimetypes/unknown";
  }

  return locate( "icon", "large/hicolor/" + icon + ".png" );
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::typeStr(void) const
{
  return mType;
}

//-----------------------------------------------------------------------------
int KMMessagePart::type(void) const
{
  int type = DwTypeStrToEnum(DwString(mType));
  return type;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setTypeStr(const QString aStr)
{
  mType = aStr.copy();
}

//-----------------------------------------------------------------------------
void KMMessagePart::setType(int aType)
{
  DwString dwType;
  DwTypeEnumToStr(aType, dwType);
  mType = dwType.c_str();

}

//-----------------------------------------------------------------------------
const QString KMMessagePart::subtypeStr(void) const
{
  return mSubtype;
}

//-----------------------------------------------------------------------------
int KMMessagePart::subtype(void) const
{
  int subtype = DwSubtypeStrToEnum(DwString(mSubtype));
  return subtype;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setSubtypeStr(const QString aStr)
{
  mSubtype = aStr;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setSubtype(int aSubtype)
{
  DwString dwSubtype;
  DwSubtypeEnumToStr(aSubtype, dwSubtype);
  mSubtype = dwSubtype.c_str();

}

//-----------------------------------------------------------------------------
const QString KMMessagePart::contentTransferEncodingStr(void) const
{
  return mCte;
}

//-----------------------------------------------------------------------------
int KMMessagePart::contentTransferEncoding(void) const
{
  int cte = DwCteStrToEnum(DwString(mCte));
  return cte;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setContentTransferEncodingStr(const QString aStr)
{
  mCte = aStr.copy();
}

//-----------------------------------------------------------------------------
void KMMessagePart::setContentTransferEncoding(int aCte)
{
  DwString dwCte;
  DwCteEnumToStr(aCte, dwCte);
  mCte = dwCte.c_str();

}

//-----------------------------------------------------------------------------
const QString KMMessagePart::contentDescription(void) const
{
  return mContentDescription;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setContentDescription(const QString aStr)
{
  mContentDescription = aStr.copy();
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::fileName(void) const
{
  int i, j, len;
  QString str;

  i = mContentDisposition.find("filename=", 0, FALSE);
  if (i < 0) return QString::null;
  j = mContentDisposition.find(';', i+9);

  if (j < 0) j = 32767;
  str = mContentDisposition.mid(i+9, j-i-9).stripWhiteSpace();

  len = str.length();
  if (str[0]=='"' && str[len-1]=='"') return str.mid(1, len-2);
  return str;
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::contentDisposition(void) const
{
  return mContentDisposition;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setContentDisposition(const QString aStr)
{
  mContentDisposition = aStr.copy();
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::body(void) const
{
  return mBody;
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::name(void) const
{
  return mName;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setName(const QString aStr)
{
  mName = aStr.copy();
}
#if defined CHARSETS
//-----------------------------------------------------------------------------
const QString KMMessagePart::charset(void) const
{

   return mCharset;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setCharset(const QString aStr)
{

  mCharset=aStr;
}
#endif

<commit_msg>Decode the names of the attachment before displaying the (file-)name. This fixes all my Umlaut-problems with attachments I get from Windows-Users... NB: I think, this fix should go into KDE_1_1_BRANCH too ....<commit_after>// kmmsgpart.cpp

#include <qdir.h>

#include "kmmsgpart.h"
#include "kmmessage.h"
#include <kmimemagic.h>
#include <kapp.h>
#include <kconfig.h>
#include <kglobal.h>
#include <kstddirs.h>

#include <mimelib/enum.h>
#include <mimelib/body.h>
#include <mimelib/bodypart.h>
#include <mimelib/utility.h>

//-----------------------------------------------------------------------------
KMMessagePart::KMMessagePart() :
  mType("text"), mSubtype("plain"), mCte("7bit"), mContentDescription(),
  mContentDisposition(), mBody(), mName()
{
  mBodySize = 0;
}

//-----------------------------------------------------------------------------
KMMessagePart::~KMMessagePart()
{
}

//-----------------------------------------------------------------------------
int KMMessagePart::size(void) const
{
  if (mBodySize < 0)
  {
    ((KMMessagePart*)this)->mBodySize =
      bodyDecoded().size() - 1;
  }
  return mBodySize;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setBody(const QString aStr)
{
  int encoding = contentTransferEncoding();

  mBody = aStr.copy();

  if (encoding!=DwMime::kCteQuotedPrintable &&
      encoding!=DwMime::kCteBase64)
  {
    mBodySize = mBody.size() - 1;
  }
  else mBodySize = -1;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setBodyEncoded(const QByteArray& aStr)
{
  DwString dwResult, dwSrc;
  int encoding = contentTransferEncoding();
  int len;

  mBodySize = aStr.size() - 1;

  switch (encoding)
  {
  case DwMime::kCteQuotedPrintable:
    dwSrc = DwString(aStr.data(), aStr.size()-1);
    DwEncodeQuotedPrintable(dwSrc, dwResult);
    len = dwResult.size();
    mBody.truncate(len);
    memcpy(mBody.data(), dwResult.c_str(), len+1);
    break;
  case DwMime::kCteBase64:
    dwSrc = DwString(aStr.data(), aStr.size()-1);
    DwEncodeBase64(dwSrc, dwResult);
    len = dwResult.size();
    mBody.truncate(len);
    memcpy(mBody.data(), dwResult.c_str(), len+1);
    break;
    len = aStr.size()-1;
    dwSrc = DwString(aStr.data(), len);
    DwEncodeBase64(dwSrc, dwResult);
    mBody = QString(dwResult.c_str());
    break;
  default:
    debug("WARNING -- unknown encoding `%s'. Assuming 8bit.",
	  (const char*)cteStr());
  case DwMime::kCte7bit:
  case DwMime::kCte8bit:
  case DwMime::kCteBinary:
    mBody = aStr;
    break;
  }
}

//-----------------------------------------------------------------------------
QByteArray KMMessagePart::bodyDecoded(void) const
{
  DwString dwResult, dwSrc;
  QByteArray result;
  int encoding = contentTransferEncoding();
  int len;

  switch (encoding)
  {
  case DwMime::kCteQuotedPrintable:
    dwSrc = DwString(mBody.data(), mBody.size());
    DwDecodeQuotedPrintable(dwSrc, dwResult);
    len = dwResult.size();
    result.resize(len);
    memcpy((void*)result.data(), (void*)dwResult.c_str(), len);
    break;
  case DwMime::kCteBase64:
    dwSrc = DwString(mBody.data(), mBody.size());
    DwDecodeBase64(dwSrc, dwResult);
    len = dwResult.size();
    result.resize(len);
    memcpy((void*)result.data(), (void*)dwResult.c_str(), len);
    break;
  default:
    debug("WARNING -- unknown encoding `%s'. Assuming 8bit.",
	  (const char*)cteStr());
  case DwMime::kCte7bit:
  case DwMime::kCte8bit:
  case DwMime::kCteBinary:
    len = mBody.length();
    result.resize(len);
    memcpy((void*)result.data(), (void*)mBody.data(), len);
    break;
  }

  return result;
}

//-----------------------------------------------------------------------------
void KMMessagePart::magicSetType(bool aAutoDecode)
{
  QString mimetype;
  QByteArray body;
  KMimeMagicResult *result;

  int sep;

  KMimeMagic::self()->setFollowLinks(TRUE); // is it necessary ?

  if (aAutoDecode)
    body = bodyDecoded();
  else
    body = mBody;

  result = KMimeMagic::self()->findBufferType( body );
  mimetype = result->mimeType();
  sep = mimetype.find('/');
  mType = mimetype.left(sep);
  mSubtype = mimetype.mid(sep+1, 64);
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::iconName(void) const
{
  QString fileName, icon;
  QDir dir;

  fileName = locate("mime", mType.lower() + "/" + mSubtype.lower() + ".desktop");

  if (!(fileName.isEmpty()) && dir.exists(fileName))
  {
    KConfig config(fileName);
    config.setDesktopGroup();
    icon = config.readEntry("Icon");
    if(icon.isEmpty()) // If no icon specified.
      icon = "mimetypes/unknown";
  }
  else
  {
    // not found, use default
    icon = "mimetypes/unknown";
  }

  return locate( "icon", "large/hicolor/" + icon + ".png" );
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::typeStr(void) const
{
  return mType;
}

//-----------------------------------------------------------------------------
int KMMessagePart::type(void) const
{
  int type = DwTypeStrToEnum(DwString(mType));
  return type;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setTypeStr(const QString aStr)
{
  mType = aStr.copy();
}

//-----------------------------------------------------------------------------
void KMMessagePart::setType(int aType)
{
  DwString dwType;
  DwTypeEnumToStr(aType, dwType);
  mType = dwType.c_str();

}

//-----------------------------------------------------------------------------
const QString KMMessagePart::subtypeStr(void) const
{
  return mSubtype;
}

//-----------------------------------------------------------------------------
int KMMessagePart::subtype(void) const
{
  int subtype = DwSubtypeStrToEnum(DwString(mSubtype));
  return subtype;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setSubtypeStr(const QString aStr)
{
  mSubtype = aStr;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setSubtype(int aSubtype)
{
  DwString dwSubtype;
  DwSubtypeEnumToStr(aSubtype, dwSubtype);
  mSubtype = dwSubtype.c_str();

}

//-----------------------------------------------------------------------------
const QString KMMessagePart::contentTransferEncodingStr(void) const
{
  return mCte;
}

//-----------------------------------------------------------------------------
int KMMessagePart::contentTransferEncoding(void) const
{
  int cte = DwCteStrToEnum(DwString(mCte));
  return cte;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setContentTransferEncodingStr(const QString aStr)
{
  mCte = aStr.copy();
}

//-----------------------------------------------------------------------------
void KMMessagePart::setContentTransferEncoding(int aCte)
{
  DwString dwCte;
  DwCteEnumToStr(aCte, dwCte);
  mCte = dwCte.c_str();

}

//-----------------------------------------------------------------------------
const QString KMMessagePart::contentDescription(void) const
{
  return mContentDescription;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setContentDescription(const QString aStr)
{
  mContentDescription = aStr.copy();
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::fileName(void) const
{
  int i, j, len;
  QString str;

  i = mContentDisposition.find("filename=", 0, FALSE);
  if (i < 0) return QString::null;
  j = mContentDisposition.find(';', i+9);

  if (j < 0) j = 32767;
  str = mContentDisposition.mid(i+9, j-i-9).stripWhiteSpace();

  len = str.length();
  if (str[0]=='"' && str[len-1]=='"')
      str = str.mid(1, len-2);

  str = KMMsgBase::decodeQuotedPrintableString(str);

  return str;
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::contentDisposition(void) const
{
  return mContentDisposition;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setContentDisposition(const QString aStr)
{
  mContentDisposition = aStr.copy();
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::body(void) const
{
  return mBody;
}

//-----------------------------------------------------------------------------
const QString KMMessagePart::name(void) const
{
  return mName;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setName(const QString aStr)
{
  mName = KMMsgBase::decodeQuotedPrintableString(aStr);
}

#if defined CHARSETS
//-----------------------------------------------------------------------------
const QString KMMessagePart::charset(void) const
{

   return mCharset;
}

//-----------------------------------------------------------------------------
void KMMessagePart::setCharset(const QString aStr)
{

  mCharset=aStr;
}
#endif

<|endoftext|>


<commit_before>
#include "ksp_plugin/part.hpp"

#include <list>
#include <string>

#include "base/array.hpp"
#include "base/hexadecimal.hpp"
#include "base/not_null.hpp"

namespace principia {
namespace ksp_plugin {
namespace internal_part {

using base::Array;
using base::HexadecimalEncode;
using base::make_not_null_unique;
using base::UniqueBytes;

Part::Part(
    PartId const part_id,
    std::string const& name,
    Mass const& mass,
    DegreesOfFreedom<Barycentric> const& degrees_of_freedom,
    std::function<void()> deletion_callback)
    : part_id_(part_id),
      name_(name),
      mass_(mass),
      degrees_of_freedom_(degrees_of_freedom),
      prehistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()),
      subset_node_(make_not_null_unique<Subset<Part>::Node>()),
      deletion_callback_(std::move(deletion_callback)) {
  CHECK_GT(mass_, Mass{}) << ShortDebugString();
  prehistory_->Append(astronomy::InfinitePast,
                      {Barycentric::origin, Velocity<Barycentric>()});
  history_ = prehistory_->NewForkAtLast();
}

Part::~Part() {
  LOG(INFO) << "Destroying part " << ShortDebugString();
  if (deletion_callback_ != nullptr) {
    deletion_callback_();
  }
}

PartId Part::part_id() const {
  return part_id_;
}

void Part::set_mass(Mass const& mass) {
  CHECK_GT(mass, Mass{}) << ShortDebugString();
  mass_ = mass;
}

Mass const& Part::mass() const {
  return mass_;
}

void Part::clear_intrinsic_force() {
  intrinsic_force_ = Vector<Force, Barycentric>{};
}

void Part::increment_intrinsic_force(
    Vector<Force, Barycentric> const& intrinsic_force) {
  intrinsic_force_ += intrinsic_force;
}

Vector<Force, Barycentric> const& Part::intrinsic_force() const {
  return intrinsic_force_;
}

void Part::set_degrees_of_freedom(
    DegreesOfFreedom<Barycentric> const& degrees_of_freedom) {
  degrees_of_freedom_ = degrees_of_freedom;
}

DegreesOfFreedom<Barycentric> const&
Part::degrees_of_freedom() const {
  return degrees_of_freedom_;
}

DiscreteTrajectory<Barycentric>::Iterator Part::history_begin() {
  // Make sure that we skip the point of the prehistory.
  auto it = history_->Fork();
  return ++it;
}

DiscreteTrajectory<Barycentric>::Iterator Part::history_end() {
  return history_->End();
}

DiscreteTrajectory<Barycentric>::Iterator Part::psychohistory_begin() {
  if (psychohistory_ == nullptr) {
    psychohistory_ = history_->NewForkAtLast();
  }
  // Make sure that we skip the fork, which may be the point of the prehistory.
  auto it = psychohistory_->Fork();
  return ++it;
}

DiscreteTrajectory<Barycentric>::Iterator Part::psychohistory_end() {
  if (psychohistory_ == nullptr) {
    psychohistory_ = history_->NewForkAtLast();
  }
  return psychohistory_->End();
}

void Part::AppendToHistory(
    Instant const& time,
    DegreesOfFreedom<Barycentric> const& degrees_of_freedom) {
  if (psychohistory_ != nullptr) {
    history_->DeleteFork(psychohistory_);
  }
  history_->Append(time, degrees_of_freedom);
}

void Part::AppendToPsychohistory(
    Instant const& time,
    DegreesOfFreedom<Barycentric> const& degrees_of_freedom) {
  if (psychohistory_ == nullptr) {
    psychohistory_ = history_->NewForkAtLast();
  }
  psychohistory_->Append(time, degrees_of_freedom);
}

void Part::ClearHistory() {
  if (psychohistory_ != nullptr) {
    history_->DeleteFork(psychohistory_);
  }
  prehistory_->DeleteFork(history_);
  history_ = prehistory_->NewForkAtLast();
}

void Part::set_containing_pile_up(
    not_null<std::shared_ptr<PileUp>> const& pile_up) {
  CHECK(!is_piled_up());
  LOG(INFO) << "Adding part " << ShortDebugString() << " to the pile up at "
            << pile_up;
  containing_pile_up_ = static_cast<std::shared_ptr<PileUp>>(pile_up);
}

PileUp* Part::containing_pile_up() const {
  return containing_pile_up_.get();
}

bool Part::is_piled_up() const {
  return containing_pile_up_ != nullptr;
}

void Part::reset_containing_pile_up() {
  LOG_IF(INFO, containing_pile_up_ != nullptr)
      << "Removing part " << ShortDebugString() << " from its pile up at "
      << containing_pile_up_;
  containing_pile_up_.reset();
}

void Part::WriteToMessage(not_null<serialization::Part*> const message,
                          PileUp::SerializationIndexForPileUp const&
                              serialization_index_for_pile_up) const {
  message->set_part_id(part_id_);
  message->set_name(name_);
  mass_.WriteToMessage(message->mutable_mass());
  intrinsic_force_.WriteToMessage(message->mutable_intrinsic_force());
  if (containing_pile_up_) {
    message->set_containing_pile_up(
        serialization_index_for_pile_up(containing_pile_up_.get()));
  }
  degrees_of_freedom_.WriteToMessage(message->mutable_degrees_of_freedom());
  prehistory_->WriteToMessage(message->mutable_prehistory(),
                              /*forks=*/{history_, psychohistory_});
}

not_null<std::unique_ptr<Part>> Part::ReadFromMessage(
    serialization::Part const& message,
    std::function<void()> deletion_callback) {
  bool const is_pre_cesàro = message.has_tail_is_authoritative();
  not_null<std::unique_ptr<Part>> part =
      make_not_null_unique<Part>(message.part_id(),
                                 message.name(),
                                 Mass::ReadFromMessage(message.mass()),
                                 DegreesOfFreedom<Barycentric>::ReadFromMessage(
                                     message.degrees_of_freedom()),
                                 std::move(deletion_callback));
  part->increment_intrinsic_force(
      Vector<Force, Barycentric>::ReadFromMessage(message.intrinsic_force()));
  if (is_pre_cesàro) {
    auto tail = DiscreteTrajectory<Barycentric>::ReadFromMessage(
        message.prehistory(),
        /*forks=*/{});
    // The |prehistory_| and |history_| have been created by the constructor
    // above.  Construct the various trajectories from the |tail|.
    for (auto it = tail->Begin(); it != tail->End(); ++it) {
      if (it == tail->last() && !message.tail_is_authoritative()) {
        part->AppendToPsychohistory(it.time(), it.degrees_of_freedom());
      } else {
        part->AppendToHistory(it.time(), it.degrees_of_freedom());
      }
    }
  } else {
    part->history_ = nullptr;
    part->prehistory_ = DiscreteTrajectory<Barycentric>::ReadFromMessage(
        message.prehistory(),
        /*forks=*/{&part->history_, &part->psychohistory_});
  }
  return part;
}

void Part::FillContainingPileUpFromMessage(
    serialization::Part const& message,
    PileUp::PileUpForSerializationIndex const&
        pile_up_for_serialization_index) {
  if (message.has_containing_pile_up()) {
    containing_pile_up_ =
        pile_up_for_serialization_index(message.containing_pile_up());
  }
}

std::string Part::ShortDebugString() const {
  UniqueBytes hex_id(sizeof(part_id_) * 2 + 1);
  Array<std::uint8_t const> id_bytes(
      reinterpret_cast<std::uint8_t const*>(&part_id_), sizeof(part_id_));
  HexadecimalEncode(id_bytes, hex_id.get());
  hex_id.data[sizeof(part_id_) * 2] = '\0';
  return name_ + " (" + reinterpret_cast<char const*>(hex_id.data.get()) + ")";
}

std::ostream& operator<<(std::ostream& out, Part const& part) {
  return out << "{"
             << part.part_id() << ", "
             << part.mass() << "}";
}

}  // namespace internal_part
}  // namespace ksp_plugin
}  // namespace principia
<commit_msg>The right cast.<commit_after>
#include "ksp_plugin/part.hpp"

#include <list>
#include <string>

#include "base/array.hpp"
#include "base/hexadecimal.hpp"
#include "base/not_null.hpp"

namespace principia {
namespace ksp_plugin {
namespace internal_part {

using base::Array;
using base::HexadecimalEncode;
using base::make_not_null_unique;
using base::UniqueBytes;

Part::Part(
    PartId const part_id,
    std::string const& name,
    Mass const& mass,
    DegreesOfFreedom<Barycentric> const& degrees_of_freedom,
    std::function<void()> deletion_callback)
    : part_id_(part_id),
      name_(name),
      mass_(mass),
      degrees_of_freedom_(degrees_of_freedom),
      prehistory_(make_not_null_unique<DiscreteTrajectory<Barycentric>>()),
      subset_node_(make_not_null_unique<Subset<Part>::Node>()),
      deletion_callback_(std::move(deletion_callback)) {
  CHECK_GT(mass_, Mass{}) << ShortDebugString();
  prehistory_->Append(astronomy::InfinitePast,
                      {Barycentric::origin, Velocity<Barycentric>()});
  history_ = prehistory_->NewForkAtLast();
}

Part::~Part() {
  LOG(INFO) << "Destroying part " << ShortDebugString();
  if (deletion_callback_ != nullptr) {
    deletion_callback_();
  }
}

PartId Part::part_id() const {
  return part_id_;
}

void Part::set_mass(Mass const& mass) {
  CHECK_GT(mass, Mass{}) << ShortDebugString();
  mass_ = mass;
}

Mass const& Part::mass() const {
  return mass_;
}

void Part::clear_intrinsic_force() {
  intrinsic_force_ = Vector<Force, Barycentric>{};
}

void Part::increment_intrinsic_force(
    Vector<Force, Barycentric> const& intrinsic_force) {
  intrinsic_force_ += intrinsic_force;
}

Vector<Force, Barycentric> const& Part::intrinsic_force() const {
  return intrinsic_force_;
}

void Part::set_degrees_of_freedom(
    DegreesOfFreedom<Barycentric> const& degrees_of_freedom) {
  degrees_of_freedom_ = degrees_of_freedom;
}

DegreesOfFreedom<Barycentric> const&
Part::degrees_of_freedom() const {
  return degrees_of_freedom_;
}

DiscreteTrajectory<Barycentric>::Iterator Part::history_begin() {
  // Make sure that we skip the point of the prehistory.
  auto it = history_->Fork();
  return ++it;
}

DiscreteTrajectory<Barycentric>::Iterator Part::history_end() {
  return history_->End();
}

DiscreteTrajectory<Barycentric>::Iterator Part::psychohistory_begin() {
  if (psychohistory_ == nullptr) {
    psychohistory_ = history_->NewForkAtLast();
  }
  // Make sure that we skip the fork, which may be the point of the prehistory.
  auto it = psychohistory_->Fork();
  return ++it;
}

DiscreteTrajectory<Barycentric>::Iterator Part::psychohistory_end() {
  if (psychohistory_ == nullptr) {
    psychohistory_ = history_->NewForkAtLast();
  }
  return psychohistory_->End();
}

void Part::AppendToHistory(
    Instant const& time,
    DegreesOfFreedom<Barycentric> const& degrees_of_freedom) {
  if (psychohistory_ != nullptr) {
    history_->DeleteFork(psychohistory_);
  }
  history_->Append(time, degrees_of_freedom);
}

void Part::AppendToPsychohistory(
    Instant const& time,
    DegreesOfFreedom<Barycentric> const& degrees_of_freedom) {
  if (psychohistory_ == nullptr) {
    psychohistory_ = history_->NewForkAtLast();
  }
  psychohistory_->Append(time, degrees_of_freedom);
}

void Part::ClearHistory() {
  if (psychohistory_ != nullptr) {
    history_->DeleteFork(psychohistory_);
  }
  prehistory_->DeleteFork(history_);
  history_ = prehistory_->NewForkAtLast();
}

void Part::set_containing_pile_up(
    not_null<std::shared_ptr<PileUp>> const& pile_up) {
  CHECK(!is_piled_up());
  LOG(INFO) << "Adding part " << ShortDebugString() << " to the pile up at "
            << pile_up;
  containing_pile_up_ = static_cast<std::shared_ptr<PileUp> const&>(pile_up);
}

PileUp* Part::containing_pile_up() const {
  return containing_pile_up_.get();
}

bool Part::is_piled_up() const {
  return containing_pile_up_ != nullptr;
}

void Part::reset_containing_pile_up() {
  LOG_IF(INFO, containing_pile_up_ != nullptr)
      << "Removing part " << ShortDebugString() << " from its pile up at "
      << containing_pile_up_;
  containing_pile_up_.reset();
}

void Part::WriteToMessage(not_null<serialization::Part*> const message,
                          PileUp::SerializationIndexForPileUp const&
                              serialization_index_for_pile_up) const {
  message->set_part_id(part_id_);
  message->set_name(name_);
  mass_.WriteToMessage(message->mutable_mass());
  intrinsic_force_.WriteToMessage(message->mutable_intrinsic_force());
  if (containing_pile_up_) {
    message->set_containing_pile_up(
        serialization_index_for_pile_up(containing_pile_up_.get()));
  }
  degrees_of_freedom_.WriteToMessage(message->mutable_degrees_of_freedom());
  prehistory_->WriteToMessage(message->mutable_prehistory(),
                              /*forks=*/{history_, psychohistory_});
}

not_null<std::unique_ptr<Part>> Part::ReadFromMessage(
    serialization::Part const& message,
    std::function<void()> deletion_callback) {
  bool const is_pre_cesàro = message.has_tail_is_authoritative();
  not_null<std::unique_ptr<Part>> part =
      make_not_null_unique<Part>(message.part_id(),
                                 message.name(),
                                 Mass::ReadFromMessage(message.mass()),
                                 DegreesOfFreedom<Barycentric>::ReadFromMessage(
                                     message.degrees_of_freedom()),
                                 std::move(deletion_callback));
  part->increment_intrinsic_force(
      Vector<Force, Barycentric>::ReadFromMessage(message.intrinsic_force()));
  if (is_pre_cesàro) {
    auto tail = DiscreteTrajectory<Barycentric>::ReadFromMessage(
        message.prehistory(),
        /*forks=*/{});
    // The |prehistory_| and |history_| have been created by the constructor
    // above.  Construct the various trajectories from the |tail|.
    for (auto it = tail->Begin(); it != tail->End(); ++it) {
      if (it == tail->last() && !message.tail_is_authoritative()) {
        part->AppendToPsychohistory(it.time(), it.degrees_of_freedom());
      } else {
        part->AppendToHistory(it.time(), it.degrees_of_freedom());
      }
    }
  } else {
    part->history_ = nullptr;
    part->prehistory_ = DiscreteTrajectory<Barycentric>::ReadFromMessage(
        message.prehistory(),
        /*forks=*/{&part->history_, &part->psychohistory_});
  }
  return part;
}

void Part::FillContainingPileUpFromMessage(
    serialization::Part const& message,
    PileUp::PileUpForSerializationIndex const&
        pile_up_for_serialization_index) {
  if (message.has_containing_pile_up()) {
    containing_pile_up_ =
        pile_up_for_serialization_index(message.containing_pile_up());
  }
}

std::string Part::ShortDebugString() const {
  UniqueBytes hex_id(sizeof(part_id_) * 2 + 1);
  Array<std::uint8_t const> id_bytes(
      reinterpret_cast<std::uint8_t const*>(&part_id_), sizeof(part_id_));
  HexadecimalEncode(id_bytes, hex_id.get());
  hex_id.data[sizeof(part_id_) * 2] = '\0';
  return name_ + " (" + reinterpret_cast<char const*>(hex_id.data.get()) + ")";
}

std::ostream& operator<<(std::ostream& out, Part const& part) {
  return out << "{"
             << part.part_id() << ", "
             << part.mass() << "}";
}

}  // namespace internal_part
}  // namespace ksp_plugin
}  // namespace principia
<|endoftext|>


<commit_before>#include <grpc_cb/channel.h>  // for Channel
#include <grpc_cb/completion_queue_for_next_sptr.h>  // for CompletionQueueForNextSptr
#include <grpc_cb/service_stub.h>  // for ServiceStub
#include <grpc_cb/status.h>  // for Status

#include <LuaIntf/LuaIntf.h>

#include <iostream>

using namespace LuaIntf;
using std::string;

namespace LuaIntf
{
    LUA_USING_SHARED_PTR_TYPE(std::shared_ptr)
}

namespace {

void test()
{
    std::cout << "test...\n";
}

// Blocking request.
// Return (response_string, nil, nil) or
//   (nil, error_string, grpc_status_code).
std::tuple<LuaRef, LuaRef, LuaRef>
BlockingRequest(lua_State* L, grpc_cb::ServiceStub* pServiceStub,
    const string& sMethod, const string& sRequest)
{
    assert(L);
    assert(pServiceStub);
    string sResponse;
    grpc_cb::Status status = pServiceStub->BlockingRequest(
        sMethod, sRequest, sResponse);
    const LuaRef NIL(L, nullptr);
    if (status.ok())
        return std::make_tuple(LuaRef::fromValue(L, sResponse), NIL, NIL);
    return std::make_tuple(NIL,
        LuaRef::fromValue(L, status.GetDetails()),
        LuaRef::fromValue(L, status.GetCode()));
}

void AsyncRequest(grpc_cb::ServiceStub* pServiceStub,
    const string& sMethod, const string& sRequest,
    const LuaRef& on_response_str, const LuaRef& on_error)
{
    // XXX
}

}  // namespace

extern "C"
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)
__declspec(dllexport)
#endif
int luaopen_grpc_lua_c(lua_State* L)
{
    assert(L);

    using namespace grpc_cb;
    LuaRef mod = LuaRef::createTable(L);
    LuaBinding(mod)
        .addFunction("test", &test)

        .beginClass<Channel>("Channel")
            .addConstructor(LUA_SP(ChannelSptr), LUA_ARGS(const string&))
        .endClass()  // Channel

        .beginClass<ServiceStub>("ServiceStub")
            .addConstructor(LUA_ARGS(const ChannelSptr&,
                _opt<CompletionQueueForNextSptr>))
            .addFunction("blocking_request",
                [L](ServiceStub* pServiceStub, const string& sMethod,
                        const string& sRequest) {
                    return BlockingRequest(L, pServiceStub, sMethod, sRequest);
                })
            .addFunction("async_request", &AsyncRequest)
            .addFunction("blocking_run", &grpc_cb::ServiceStub::BlockingRun)
        .endClass()  // ServiceStub
        ;
    mod.pushToStack();
    return 1;
}
<commit_msg>Add async request.<commit_after>#include <grpc_cb/channel.h>  // for Channel
#include <grpc_cb/completion_queue_for_next_sptr.h>  // for CompletionQueueForNextSptr
#include <grpc_cb/service_stub.h>  // for ServiceStub
#include <grpc_cb/status.h>  // for Status

#include <LuaIntf/LuaIntf.h>

#include <iostream>

using namespace LuaIntf;
using std::string;

namespace LuaIntf
{
    LUA_USING_SHARED_PTR_TYPE(std::shared_ptr)
}

namespace {

void test()
{
    std::cout << "test...\n";
}

// Blocking request.
// Return (response_string, nil, nil) or
//   (nil, error_string, grpc_status_code).
std::tuple<LuaRef, LuaRef, LuaRef>
BlockingRequest(lua_State* L, grpc_cb::ServiceStub* pServiceStub,
    const string& sMethod, const string& sRequest)
{
    assert(L);
    assert(pServiceStub);
    string sResponse;
    grpc_cb::Status status = pServiceStub->BlockingRequest(
        sMethod, sRequest, sResponse);
    const LuaRef NIL(L, nullptr);
    if (status.ok())
        return std::make_tuple(LuaRef::fromValue(L, sResponse), NIL, NIL);
    return std::make_tuple(NIL,
        LuaRef::fromValue(L, status.GetDetails()),
        LuaRef::fromValue(L, status.GetCode()));
}  // BlockingRequest()

void AsyncRequest(grpc_cb::ServiceStub* pServiceStub,
    const string& sMethod, const string& sRequest,
    const LuaRef& luaOnResponse, const LuaRef& luaOnError)
{
    assert(pServiceStub);
    grpc_cb::ServiceStub::OnResponse onResponse;  // function<void (const string&)>
    if (luaOnResponse)
    {
        luaOnResponse.checkFunction();  // void (string)
        onResponse = [luaOnResponse](const string& sResponse) {
            luaOnResponse.call(sResponse);
        };
    }
    grpc_cb::ErrorCallback onError;  // function<void (const Status& status)>
    if (luaOnError)
    {
        luaOnError.checkFunction();  // void (string, int)
        onError = [luaOnError](const grpc_cb::Status& status) {
            luaOnError.call(status.GetDetails(), status.GetCode());
        };
    }
    pServiceStub->AsyncRequest(sMethod, sRequest, onResponse, onError);
}  // AsyncRequest()

}  // namespace

extern "C"
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)
__declspec(dllexport)
#endif
int luaopen_grpc_lua_c(lua_State* L)
{
    assert(L);

    using namespace grpc_cb;
    LuaRef mod = LuaRef::createTable(L);
    LuaBinding(mod)
        .addFunction("test", &test)

        .beginClass<Channel>("Channel")
            .addConstructor(LUA_SP(ChannelSptr), LUA_ARGS(const string&))
        .endClass()  // Channel

        .beginClass<ServiceStub>("ServiceStub")
            .addConstructor(LUA_ARGS(const ChannelSptr&,
                _opt<CompletionQueueForNextSptr>))
            .addFunction("blocking_request",
                [L](ServiceStub* pServiceStub, const string& sMethod,
                        const string& sRequest) {
                    return BlockingRequest(L, pServiceStub, sMethod, sRequest);
                })
            .addFunction("async_request", &AsyncRequest)
            .addFunction("blocking_run", &grpc_cb::ServiceStub::BlockingRun)
        .endClass()  // ServiceStub
        ;
    mod.pushToStack();
    return 1;
}  // luaopen_grpc_lua_c()
<|endoftext|>