<commit_before>#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <math.h>

static const float tol = 0.000000000000001f;

void normalize(double vec[3]){
    float m = magnitude(vec);
    if(tol <= m) m = 1;
    vec[0] /= m;
    vec[1] /= m;
    vec[2] /= m;

    if(fabs(vec[0]) < tol) vec[0] = 0.0f;
    if(fabs(vec[1]) < tol) vec[1] = 0.0f;
    if(fabs(vec[2]) < tol) vec[2] = 0.0f;
}

double magnitude(double vec[3]){
    return sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
}

class ArtificialPotentialField{
public:
    ArtificialPotentialField(const ros::NodeHandle &node) :
        cmd_pub_(node.advertise<geometry_msgs::Twist>("cmd_vel", 10))
    {
        for(int i=0; i < 3; i++) obs_[i] = 0;
    }

    void spin(){
        ros::Duration(1).sleep();
        geometry_msgs::Twist cmd;
        cmd.linear.z = 0.15;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        cmd.linear.z = 0;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        double Fs[3];
        double u[3];
        double obs[3];

        const double A = 0;
        const double B = 3;
        const double n = 1;
        const double m = 1.5;

        const double force = 0.025;

        Fs[0] = Fs[1] = Fs[2] = 0;

        obs[0] = 0.5;
        obs[1] = 0;
        obs[2] = 0;

        u[0] = obs[0];
        u[1] = obs[1];
        u[2] = obs[2];
        normalize(u);

        const double d = magnitude(obs);
        double U = -A/pow(d, n) + B/pow(d, m);

        Fs[0] += U * u[0];
        Fs[1] += U * u[1];
        Fs[2] += U * u[2];

        cmd.linear.x = Fs[0] * force;
        cmd.linear.y = Fs[1] * force;

        ROS_INFO_STREAM("cmd = " << cmd);
        cmd_pub_.publish(cmd);
        ros::Duration(10).sleep();
    }

private:
    void obstacleCallback(const sensor_msgs::ConstPtr &obs_msg){
        double min_obs[3];

        double min_obs[0] = obs_msg->points[0].x;
        double min_obs[1] = obs_msg->points[0].y;
        double min_obs[2] = obs_msg->points[0].z;

        float min_dist = magnitude(obs1);

        for(int i=1; i < obs_msg->get_points_size(); i++){
            double obs[3];
            obs[0] = obs_msg->points[i].x;
            obs[1] = obs_msg->points[i].y;
            obs[2] = obs_msg->points[i].z;

            double dist = magnitude(obs2);
            if(dist < min_dist){
                min_obs[0] = obs[0];
                min_obs[1] = obs[1];
                min_obs[2] = obs[2];
                min_dist = dist;
            }
        }

        obs_[0] = min_obs[0];
        obs_[1] = min_obs[1];
        obs_[2] = min_obs[2];
    }

    double obs_[3];
    ros::Publisher cmd_pub_;
}

int main(int argc, char *argv[]){
    ros::init(argc, argv, "obstacle_avoidance");

    ros::NodeHandle node;
    apf = ArtificialPotentialField(node);
    apf.spin();

    return 0;
}

<commit_msg>Fix error that not found magnitude()<commit_after>#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <math.h>

static const float tol = 0.000000000000001f;

double magnitude(double vec[3]){
    return sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
}

void normalize(double vec[3]){
    float m = magnitude(vec);
    if(tol <= m) m = 1;
    vec[0] /= m;
    vec[1] /= m;
    vec[2] /= m;

    if(fabs(vec[0]) < tol) vec[0] = 0.0f;
    if(fabs(vec[1]) < tol) vec[1] = 0.0f;
    if(fabs(vec[2]) < tol) vec[2] = 0.0f;
}

class ArtificialPotentialField{
public:
    ArtificialPotentialField(const ros::NodeHandle &node) :
        cmd_pub_(node.advertise<geometry_msgs::Twist>("cmd_vel", 10))
    {
        for(int i=0; i < 3; i++) obs_[i] = 0;
    }

    void spin(){
        ros::Duration(1).sleep();
        geometry_msgs::Twist cmd;
        cmd.linear.z = 0.15;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        cmd.linear.z = 0;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        double Fs[3];
        double u[3];
        double obs[3];

        const double A = 0;
        const double B = 3;
        const double n = 1;
        const double m = 1.5;

        const double force = 0.025;

        Fs[0] = Fs[1] = Fs[2] = 0;

        obs[0] = 0.5;
        obs[1] = 0;
        obs[2] = 0;

        u[0] = obs[0];
        u[1] = obs[1];
        u[2] = obs[2];
        normalize(u);

        const double d = magnitude(obs);
        double U = -A/pow(d, n) + B/pow(d, m);

        Fs[0] += U * u[0];
        Fs[1] += U * u[1];
        Fs[2] += U * u[2];

        cmd.linear.x = Fs[0] * force;
        cmd.linear.y = Fs[1] * force;

        ROS_INFO_STREAM("cmd = " << cmd);
        cmd_pub_.publish(cmd);
        ros::Duration(10).sleep();
    }

private:
    void obstacleCallback(const sensor_msgs::ConstPtr &obs_msg){
        double min_obs[3];

        double min_obs[0] = obs_msg->points[0].x;
        double min_obs[1] = obs_msg->points[0].y;
        double min_obs[2] = obs_msg->points[0].z;

        float min_dist = magnitude(obs1);

        for(int i=1; i < obs_msg->get_points_size(); i++){
            double obs[3];
            obs[0] = obs_msg->points[i].x;
            obs[1] = obs_msg->points[i].y;
            obs[2] = obs_msg->points[i].z;

            double dist = magnitude(obs2);
            if(dist < min_dist){
                min_obs[0] = obs[0];
                min_obs[1] = obs[1];
                min_obs[2] = obs[2];
                min_dist = dist;
            }
        }

        obs_[0] = min_obs[0];
        obs_[1] = min_obs[1];
        obs_[2] = min_obs[2];
    }

    double obs_[3];
    ros::Publisher cmd_pub_;
}

int main(int argc, char *argv[]){
    ros::init(argc, argv, "obstacle_avoidance");

    ros::NodeHandle node;
    apf = ArtificialPotentialField(node);
    apf.spin();

    return 0;
}

<|endoftext|>


<commit_before>#include "swift/IDE/CodeCompletion.h"
#include "swift/AST/NameLookup.h"
#include "swift/Basic/LLVM.h"
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/Parse/CodeCompletionCallbacks.h"
#include "swift/Subsystems.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Sema/Lookup.h"
#include <algorithm>
#include <string>

using namespace swift;
using namespace code_completion;

std::string swift::code_completion::removeCodeCompletionTokens(
    StringRef Input, StringRef TokenName, unsigned *CompletionOffset) {
  assert(TokenName.size() >= 1);

  *CompletionOffset = ~0U;

  std::string CleanFile;
  CleanFile.reserve(Input.size());
  const std::string Token = std::string("#^") + TokenName.str() + "^#";

  for (const char *Ptr = Input.begin(), *End = Input.end();
       Ptr != End; ++Ptr) {
    const char C = *Ptr;
    if (C == '#' && Ptr <= End - Token.size() &&
        StringRef(Ptr, Token.size()) == Token) {
      Ptr += Token.size() - 1;
      *CompletionOffset = CleanFile.size() + 1;
      continue;
    }
    if (C == '#' && Ptr <= End - 2 && Ptr[1] == '^') {
      do {
        Ptr++;
      } while(*Ptr != '#');
      continue;
    }
    CleanFile += C;
  }
  return CleanFile;
}

CodeCompletionString::CodeCompletionString(ArrayRef<Chunk> Chunks) {
  Chunk *TailChunks = reinterpret_cast<Chunk *>(this + 1);
  std::copy(Chunks.begin(), Chunks.end(), TailChunks);
  NumChunks = Chunks.size();
}

void CodeCompletionString::print(raw_ostream &OS) const {
  unsigned PrevNestingLevel = 0;
  for (auto C : getChunks()) {
    if (C.getNestingLevel() < PrevNestingLevel) {
      OS << "#}";
    }
    switch (C.getKind()) {
    case Chunk::ChunkKind::Text:
    case Chunk::ChunkKind::LeftParen:
    case Chunk::ChunkKind::RightParen:
    case Chunk::ChunkKind::LeftBracket:
    case Chunk::ChunkKind::RightBracket:
    case Chunk::ChunkKind::Dot:
    case Chunk::ChunkKind::Comma:
    case Chunk::ChunkKind::CallParameterName:
    case Chunk::ChunkKind::CallParameterColon:
    case Chunk::ChunkKind::CallParameterType:
      OS << C.getText();
      break;
    case Chunk::ChunkKind::OptionalBegin:
    case Chunk::ChunkKind::CallParameterBegin:
      OS << "{#";
      break;
    case Chunk::ChunkKind::TypeAnnotation:
      OS << "[#";
      OS << C.getText();
      OS << "#]";
    }
    PrevNestingLevel = C.getNestingLevel();
  }
  while (PrevNestingLevel > 0) {
    OS << "#}";
    PrevNestingLevel--;
  }
}

void CodeCompletionString::dump() const {
  print(llvm::errs());
}

void CodeCompletionResult::print(raw_ostream &OS) const {
  switch (Kind) {
  case ResultKind::SwiftDeclaration:
    OS << "SwiftDecl: ";
    break;
  case ResultKind::ClangDeclaration:
    OS << "ClangDecl: ";
    break;
  case ResultKind::Keyword:
    OS << "Keyword: ";
    break;
  case ResultKind::Pattern:
    OS << "Pattern: ";
    break;
  }
  CompletionString->print(OS);
}

void CodeCompletionResult::dump() const {
  print(llvm::errs());
}

void CodeCompletionResultBuilder::addChunkWithText(
    CodeCompletionString::Chunk::ChunkKind Kind, StringRef Text) {
  Chunks.push_back(CodeCompletionString::Chunk::createWithText(
      Kind, CurrentNestingLevel, Context.copyString(Text)));
}

CodeCompletionResult *CodeCompletionResultBuilder::takeResult() {
  void *Mem = Context.Allocator
      .Allocate(sizeof(CodeCompletionResult) +
                    Chunks.size() * sizeof(CodeCompletionString::Chunk),
                llvm::alignOf<CodeCompletionString>());
  switch (Kind) {
  case CodeCompletionResult::ResultKind::SwiftDeclaration:
    return new (Context.Allocator)
        CodeCompletionResult(new (Mem) CodeCompletionString(Chunks),
                             AssociatedDecl.get<const Decl *>());
  case CodeCompletionResult::ResultKind::ClangDeclaration:
    return new (Context.Allocator)
        CodeCompletionResult(new (Mem) CodeCompletionString(Chunks),
                             AssociatedDecl.get<const clang::Decl *>());
  case CodeCompletionResult::ResultKind::Keyword:
  case CodeCompletionResult::ResultKind::Pattern:
    return new (Context.Allocator)
        CodeCompletionResult(Kind, new (Mem) CodeCompletionString(Chunks));
  }
}

void CodeCompletionResultBuilder::finishResult() {
  Context.CurrentCompletionResults.push_back(takeResult());
}

StringRef CodeCompletionContext::copyString(StringRef String) {
  char *Mem = Allocator.Allocate<char>(String.size());
  std::copy(String.begin(), String.end(), Mem);
  return StringRef(Mem, String.size());
}

ArrayRef<CodeCompletionResult *> CodeCompletionContext::takeResults() {
  const size_t Count = CurrentCompletionResults.size();
  CodeCompletionResult **Results =
      Allocator.Allocate<CodeCompletionResult *>(Count);
  std::copy(CurrentCompletionResults.begin(), CurrentCompletionResults.end(),
            Results);
  CurrentCompletionResults.clear();
  return llvm::makeArrayRef(Results, Count);
}

namespace {
class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
  CodeCompletionContext &CompletionContext;
  CodeCompletionConsumer &Consumer;
  TranslationUnit *const TU;

  void typecheckExpr(Expr *&E) {
    assert(E && "should have an expression");

    DEBUG(llvm::dbgs() << "\nparsed:\n";
          E->print(llvm::dbgs());
          llvm::dbgs() << "\n");

    if (!typeCheckCompletionContextExpr(TU, E))
      return;

    DEBUG(llvm::dbgs() << "\type checked:\n";
          E->print(llvm::dbgs());
          llvm::dbgs() << "\n");
  }

public:
  CodeCompletionCallbacksImpl(Parser &P,
                              CodeCompletionContext &CompletionContext,
                              CodeCompletionConsumer &Consumer)
      : CodeCompletionCallbacks(P), CompletionContext(CompletionContext),
        Consumer(Consumer), TU(P.TU) {
  }

  void completeExpr() override;
  void completeDotExpr(Expr *E) override;
  void completePostfixExpr(Expr *E) override;
};
} // end unnamed namespace

void CodeCompletionCallbacksImpl::completeExpr() {
  Parser::ParserPositionRAII RestorePosition(P);
  P.restoreParserPosition(ExprBeginPosition);

  // FIXME: implement fallback code completion.

  Consumer.handleResults(CompletionContext.takeResults());
}

namespace {
/// Build completions by doing visible decl lookup from a context.
class CompletionLookup : swift::VisibleDeclConsumer,
                         clang::VisibleDeclConsumer
{
  CodeCompletionContext &CompletionContext;
  ASTContext &SwiftContext;

  enum class LookupKind {
    ValueExpr,
    DeclContext
  };

  LookupKind Kind;
  Type ExprType;
  bool HaveDot = false;

public:
  CompletionLookup(CodeCompletionContext &CompletionContext,
                   ASTContext &SwiftContext)
      : CompletionContext(CompletionContext), SwiftContext(SwiftContext) {
  }

  void setHaveDot() {
    HaveDot = true;
  }

  void addSwiftVarDeclRef(const VarDecl *VD) {
    StringRef Name = VD->getName().get();
    assert(!Name.empty() && "name should not be empty");

    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::SwiftDeclaration);
    Builder.setAssociatedSwiftDecl(VD);
    if (!HaveDot)
      Builder.addDot();
    Builder.addTextChunk(Name);
    Builder.addTypeAnnotation(VD->getType().getString());
  }

  void addTuplePatternParameters(CodeCompletionResultBuilder &Builder,
                                 const TuplePattern *TP) {
    bool NeedComma = false;
    for (auto TupleElt : TP->getFields()) {
      if (NeedComma)
        Builder.addComma(", ");
      Builder.addCallParameter(TupleElt.getPattern()->getBoundName().str(),
                               TupleElt.getPattern()->getType().getString());
      NeedComma = true;
    }
  }

  void addSwiftMethodCall(const FuncDecl *FD) {
    StringRef Name = FD->getName().get();
    assert(!Name.empty() && "name should not be empty");

    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::SwiftDeclaration);
    Builder.setAssociatedSwiftDecl(FD);
    if (!HaveDot)
      Builder.addDot();
    Builder.addTextChunk(Name);
    Builder.addLeftParen();
    auto *FE = FD->getBody();
    auto Patterns = FE->getArgParamPatterns();
    unsigned FirstIndex = 0;
    if (Patterns[0]->isImplicit())
      FirstIndex = 1;
    addTuplePatternParameters(Builder, cast<TuplePattern>(Patterns[FirstIndex]));
    Builder.addRightParen();
    // FIXME: Pattern should pretty-print itself.
    llvm::SmallString<32> Type;
    for (unsigned i = FirstIndex + 1, e = Patterns.size(); i != e; ++i) {
      Type += "(";
      for (auto TupleElt : cast<TuplePattern>(Patterns[i])->getFields()) {
        Type += TupleElt.getPattern()->getBoundName().str();
        Type += ": ";
        Type += TupleElt.getPattern()->getType().getString();
      }
      Type += ") -> ";
    }
    Type += FE->getResultType(SwiftContext).getString();
    Builder.addTypeAnnotation(Type);

    // TODO: skip arguments with default parameters?
  }

  void addSwiftConstructorCall(const ConstructorDecl *CD) {
    assert(!HaveDot && "can not add a constructor call after a dot");
    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::SwiftDeclaration);
    Builder.setAssociatedSwiftDecl(CD);
    Builder.addLeftParen();
    addTuplePatternParameters(Builder, cast<TuplePattern>(CD->getArguments()));
    Builder.addRightParen();
    Builder.addTypeAnnotation(CD->getResultType().getString());
  }

  void addSwiftSubscriptCall(const SubscriptDecl *SD) {
    assert(!HaveDot && "can not add a subscript after a dot");
    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::SwiftDeclaration);
    Builder.setAssociatedSwiftDecl(SD);
    Builder.addLeftBracket();
    addTuplePatternParameters(Builder, cast<TuplePattern>(SD->getIndices()));
    Builder.addRightBracket();
    Builder.addTypeAnnotation(SD->getElementType().getString());
  }

  void addClangDecl(const clang::NamedDecl *ND) {
    // FIXME: Eventually, we'll import the Clang Decl and format it as a Swift
    // declaration.  Right now we don't do this because of performance reasons.
    StringRef Name = ND->getName();
    if (Name.empty())
      return;
    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::ClangDeclaration);
    Builder.setAssociatedClangDecl(ND);
    Builder.addTextChunk(Name);
  }

  void addKeyword(StringRef Name, Type TypeAnnotation) {
    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::Keyword);
    if (!HaveDot)
      Builder.addDot();
    Builder.addTextChunk(Name);
    if (!TypeAnnotation.isNull())
      Builder.addTypeAnnotation(TypeAnnotation.getString());
  }

  // Implement swift::VisibleDeclConsumer
  void foundDecl(ValueDecl *D) override {
    if (Kind == LookupKind::ValueExpr) {
      if (auto *VD = dyn_cast<VarDecl>(D)) {
        // Swift does not have class variables.
        // FIXME: add code completion results when class variables are added.
        if (ExprType->is<MetaTypeType>())
          return;
        addSwiftVarDeclRef(VD);
        return;
      }

      if (auto *FD = dyn_cast<FuncDecl>(D)) {
        // We can not call getters or setters.  We use VarDecls and
        // SubscriptDecls to produce completions that refer to getters and
        // setters.
        if (FD->isGetterOrSetter())
          return;

        // Don't complete class methods of instances; don't complete instance
        // methods of metatypes.
        if (FD->isStatic() != ExprType->is<MetaTypeType>())
          return;
        addSwiftMethodCall(FD);
        return;
      }

      if (HaveDot)
        return;

      // FIXME: super.constructor
      if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
        if (!ExprType->is<MetaTypeType>())
          return;
        addSwiftConstructorCall(CD);
        return;
      }

      if (auto *SD = dyn_cast<SubscriptDecl>(D)) {
        if (ExprType->is<MetaTypeType>())
          return;
        addSwiftSubscriptCall(SD);
        return;
      }
    }
  }

  // Implement clang::VisibleDeclConsumer
  void FoundDecl(clang::NamedDecl *ND, clang::NamedDecl *Hiding,
                 clang::DeclContext *Ctx,
                 bool InBaseClass) override {
    addClangDecl(ND);
  }

  void getValueExprCompletions(Type ExprType) {
    Kind = LookupKind::ValueExpr;
    this->ExprType = ExprType;
    if (ExprType->is<AnyFunctionType>()) {
      // FIXME: produce a call.
    } else {
      lookupVisibleDecls(*this, ExprType);
    }
    // Add the special qualified keyword 'metatype' so that, for example,
    // 'Int.metatype' can be completed.
    addKeyword("metatype", ExprType);
  }

  void getCompletionsInDeclContext(DeclContext *DC, SourceLoc Loc) {
    Kind = LookupKind::DeclContext;
    lookupVisibleDecls(*this, DC, Loc);

    if (auto Importer = SwiftContext.getClangModuleLoader())
      static_cast<ClangImporter&>(*Importer).lookupVisibleDecls(*this);
  }
};

} // end unnamed namespace

void CodeCompletionCallbacksImpl::completeDotExpr(Expr *E) {
  typecheckExpr(E);

  CompletionLookup Lookup(CompletionContext, TU->Ctx);
  Lookup.setHaveDot();
  Lookup.getValueExprCompletions(E->getType());

  Consumer.handleResults(CompletionContext.takeResults());
}

void CodeCompletionCallbacksImpl::completePostfixExpr(Expr *E) {
  typecheckExpr(E);

  CompletionLookup Lookup(CompletionContext, TU->Ctx);
  Lookup.getValueExprCompletions(E->getType());

  Consumer.handleResults(CompletionContext.takeResults());
}

void PrintingCodeCompletionConsumer::handleResults(
    ArrayRef<CodeCompletionResult *> Results) {
  OS << "Begin completions\n";
  for (auto Result : Results) {
    Result->print(OS);
    OS << "\n";
  }
  OS << "End completions\n";
}

namespace {
class CodeCompletionCallbacksFactoryImpl
    : public CodeCompletionCallbacksFactory {
  CodeCompletionContext &CompletionContext;
  CodeCompletionConsumer &Consumer;

public:
  CodeCompletionCallbacksFactoryImpl(CodeCompletionContext &CompletionContext,
                                     CodeCompletionConsumer &Consumer)
      : CompletionContext(CompletionContext), Consumer(Consumer) {}

  CodeCompletionCallbacks *createCodeCompletionCallbacks(Parser &P) override {
    return new CodeCompletionCallbacksImpl(P, CompletionContext, Consumer);
  }
};
} // end unnamed namespace

CodeCompletionCallbacksFactory *
swift::code_completion::makeCodeCompletionCallbacksFactory(
    CodeCompletionContext &CompletionContext,
    CodeCompletionConsumer &Consumer) {
  return new CodeCompletionCallbacksFactoryImpl(CompletionContext, Consumer);
}

<commit_msg>Produce correct type annotations for '.metatype' completion strings<commit_after>#include "swift/IDE/CodeCompletion.h"
#include "swift/AST/NameLookup.h"
#include "swift/Basic/LLVM.h"
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/Parse/CodeCompletionCallbacks.h"
#include "swift/Subsystems.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Sema/Lookup.h"
#include <algorithm>
#include <string>

using namespace swift;
using namespace code_completion;

std::string swift::code_completion::removeCodeCompletionTokens(
    StringRef Input, StringRef TokenName, unsigned *CompletionOffset) {
  assert(TokenName.size() >= 1);

  *CompletionOffset = ~0U;

  std::string CleanFile;
  CleanFile.reserve(Input.size());
  const std::string Token = std::string("#^") + TokenName.str() + "^#";

  for (const char *Ptr = Input.begin(), *End = Input.end();
       Ptr != End; ++Ptr) {
    const char C = *Ptr;
    if (C == '#' && Ptr <= End - Token.size() &&
        StringRef(Ptr, Token.size()) == Token) {
      Ptr += Token.size() - 1;
      *CompletionOffset = CleanFile.size() + 1;
      continue;
    }
    if (C == '#' && Ptr <= End - 2 && Ptr[1] == '^') {
      do {
        Ptr++;
      } while(*Ptr != '#');
      continue;
    }
    CleanFile += C;
  }
  return CleanFile;
}

CodeCompletionString::CodeCompletionString(ArrayRef<Chunk> Chunks) {
  Chunk *TailChunks = reinterpret_cast<Chunk *>(this + 1);
  std::copy(Chunks.begin(), Chunks.end(), TailChunks);
  NumChunks = Chunks.size();
}

void CodeCompletionString::print(raw_ostream &OS) const {
  unsigned PrevNestingLevel = 0;
  for (auto C : getChunks()) {
    if (C.getNestingLevel() < PrevNestingLevel) {
      OS << "#}";
    }
    switch (C.getKind()) {
    case Chunk::ChunkKind::Text:
    case Chunk::ChunkKind::LeftParen:
    case Chunk::ChunkKind::RightParen:
    case Chunk::ChunkKind::LeftBracket:
    case Chunk::ChunkKind::RightBracket:
    case Chunk::ChunkKind::Dot:
    case Chunk::ChunkKind::Comma:
    case Chunk::ChunkKind::CallParameterName:
    case Chunk::ChunkKind::CallParameterColon:
    case Chunk::ChunkKind::CallParameterType:
      OS << C.getText();
      break;
    case Chunk::ChunkKind::OptionalBegin:
    case Chunk::ChunkKind::CallParameterBegin:
      OS << "{#";
      break;
    case Chunk::ChunkKind::TypeAnnotation:
      OS << "[#";
      OS << C.getText();
      OS << "#]";
    }
    PrevNestingLevel = C.getNestingLevel();
  }
  while (PrevNestingLevel > 0) {
    OS << "#}";
    PrevNestingLevel--;
  }
}

void CodeCompletionString::dump() const {
  print(llvm::errs());
}

void CodeCompletionResult::print(raw_ostream &OS) const {
  switch (Kind) {
  case ResultKind::SwiftDeclaration:
    OS << "SwiftDecl: ";
    break;
  case ResultKind::ClangDeclaration:
    OS << "ClangDecl: ";
    break;
  case ResultKind::Keyword:
    OS << "Keyword: ";
    break;
  case ResultKind::Pattern:
    OS << "Pattern: ";
    break;
  }
  CompletionString->print(OS);
}

void CodeCompletionResult::dump() const {
  print(llvm::errs());
}

void CodeCompletionResultBuilder::addChunkWithText(
    CodeCompletionString::Chunk::ChunkKind Kind, StringRef Text) {
  Chunks.push_back(CodeCompletionString::Chunk::createWithText(
      Kind, CurrentNestingLevel, Context.copyString(Text)));
}

CodeCompletionResult *CodeCompletionResultBuilder::takeResult() {
  void *Mem = Context.Allocator
      .Allocate(sizeof(CodeCompletionResult) +
                    Chunks.size() * sizeof(CodeCompletionString::Chunk),
                llvm::alignOf<CodeCompletionString>());
  switch (Kind) {
  case CodeCompletionResult::ResultKind::SwiftDeclaration:
    return new (Context.Allocator)
        CodeCompletionResult(new (Mem) CodeCompletionString(Chunks),
                             AssociatedDecl.get<const Decl *>());
  case CodeCompletionResult::ResultKind::ClangDeclaration:
    return new (Context.Allocator)
        CodeCompletionResult(new (Mem) CodeCompletionString(Chunks),
                             AssociatedDecl.get<const clang::Decl *>());
  case CodeCompletionResult::ResultKind::Keyword:
  case CodeCompletionResult::ResultKind::Pattern:
    return new (Context.Allocator)
        CodeCompletionResult(Kind, new (Mem) CodeCompletionString(Chunks));
  }
}

void CodeCompletionResultBuilder::finishResult() {
  Context.CurrentCompletionResults.push_back(takeResult());
}

StringRef CodeCompletionContext::copyString(StringRef String) {
  char *Mem = Allocator.Allocate<char>(String.size());
  std::copy(String.begin(), String.end(), Mem);
  return StringRef(Mem, String.size());
}

ArrayRef<CodeCompletionResult *> CodeCompletionContext::takeResults() {
  const size_t Count = CurrentCompletionResults.size();
  CodeCompletionResult **Results =
      Allocator.Allocate<CodeCompletionResult *>(Count);
  std::copy(CurrentCompletionResults.begin(), CurrentCompletionResults.end(),
            Results);
  CurrentCompletionResults.clear();
  return llvm::makeArrayRef(Results, Count);
}

namespace {
class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
  CodeCompletionContext &CompletionContext;
  CodeCompletionConsumer &Consumer;
  TranslationUnit *const TU;

  void typecheckExpr(Expr *&E) {
    assert(E && "should have an expression");

    DEBUG(llvm::dbgs() << "\nparsed:\n";
          E->print(llvm::dbgs());
          llvm::dbgs() << "\n");

    if (!typeCheckCompletionContextExpr(TU, E))
      return;

    DEBUG(llvm::dbgs() << "\type checked:\n";
          E->print(llvm::dbgs());
          llvm::dbgs() << "\n");
  }

public:
  CodeCompletionCallbacksImpl(Parser &P,
                              CodeCompletionContext &CompletionContext,
                              CodeCompletionConsumer &Consumer)
      : CodeCompletionCallbacks(P), CompletionContext(CompletionContext),
        Consumer(Consumer), TU(P.TU) {
  }

  void completeExpr() override;
  void completeDotExpr(Expr *E) override;
  void completePostfixExpr(Expr *E) override;
};
} // end unnamed namespace

void CodeCompletionCallbacksImpl::completeExpr() {
  Parser::ParserPositionRAII RestorePosition(P);
  P.restoreParserPosition(ExprBeginPosition);

  // FIXME: implement fallback code completion.

  Consumer.handleResults(CompletionContext.takeResults());
}

namespace {
/// Build completions by doing visible decl lookup from a context.
class CompletionLookup : swift::VisibleDeclConsumer,
                         clang::VisibleDeclConsumer
{
  CodeCompletionContext &CompletionContext;
  ASTContext &SwiftContext;

  enum class LookupKind {
    ValueExpr,
    DeclContext
  };

  LookupKind Kind;
  Type ExprType;
  bool HaveDot = false;

public:
  CompletionLookup(CodeCompletionContext &CompletionContext,
                   ASTContext &SwiftContext)
      : CompletionContext(CompletionContext), SwiftContext(SwiftContext) {
  }

  void setHaveDot() {
    HaveDot = true;
  }

  void addSwiftVarDeclRef(const VarDecl *VD) {
    StringRef Name = VD->getName().get();
    assert(!Name.empty() && "name should not be empty");

    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::SwiftDeclaration);
    Builder.setAssociatedSwiftDecl(VD);
    if (!HaveDot)
      Builder.addDot();
    Builder.addTextChunk(Name);
    Builder.addTypeAnnotation(VD->getType().getString());
  }

  void addTuplePatternParameters(CodeCompletionResultBuilder &Builder,
                                 const TuplePattern *TP) {
    bool NeedComma = false;
    for (auto TupleElt : TP->getFields()) {
      if (NeedComma)
        Builder.addComma(", ");
      Builder.addCallParameter(TupleElt.getPattern()->getBoundName().str(),
                               TupleElt.getPattern()->getType().getString());
      NeedComma = true;
    }
  }

  void addSwiftMethodCall(const FuncDecl *FD) {
    StringRef Name = FD->getName().get();
    assert(!Name.empty() && "name should not be empty");

    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::SwiftDeclaration);
    Builder.setAssociatedSwiftDecl(FD);
    if (!HaveDot)
      Builder.addDot();
    Builder.addTextChunk(Name);
    Builder.addLeftParen();
    auto *FE = FD->getBody();
    auto Patterns = FE->getArgParamPatterns();
    unsigned FirstIndex = 0;
    if (Patterns[0]->isImplicit())
      FirstIndex = 1;
    addTuplePatternParameters(Builder, cast<TuplePattern>(Patterns[FirstIndex]));
    Builder.addRightParen();
    // FIXME: Pattern should pretty-print itself.
    llvm::SmallString<32> Type;
    for (unsigned i = FirstIndex + 1, e = Patterns.size(); i != e; ++i) {
      Type += "(";
      for (auto TupleElt : cast<TuplePattern>(Patterns[i])->getFields()) {
        Type += TupleElt.getPattern()->getBoundName().str();
        Type += ": ";
        Type += TupleElt.getPattern()->getType().getString();
      }
      Type += ") -> ";
    }
    Type += FE->getResultType(SwiftContext).getString();
    Builder.addTypeAnnotation(Type);

    // TODO: skip arguments with default parameters?
  }

  void addSwiftConstructorCall(const ConstructorDecl *CD) {
    assert(!HaveDot && "can not add a constructor call after a dot");
    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::SwiftDeclaration);
    Builder.setAssociatedSwiftDecl(CD);
    Builder.addLeftParen();
    addTuplePatternParameters(Builder, cast<TuplePattern>(CD->getArguments()));
    Builder.addRightParen();
    Builder.addTypeAnnotation(CD->getResultType().getString());
  }

  void addSwiftSubscriptCall(const SubscriptDecl *SD) {
    assert(!HaveDot && "can not add a subscript after a dot");
    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::SwiftDeclaration);
    Builder.setAssociatedSwiftDecl(SD);
    Builder.addLeftBracket();
    addTuplePatternParameters(Builder, cast<TuplePattern>(SD->getIndices()));
    Builder.addRightBracket();
    Builder.addTypeAnnotation(SD->getElementType().getString());
  }

  void addClangDecl(const clang::NamedDecl *ND) {
    // FIXME: Eventually, we'll import the Clang Decl and format it as a Swift
    // declaration.  Right now we don't do this because of performance reasons.
    StringRef Name = ND->getName();
    if (Name.empty())
      return;
    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::ClangDeclaration);
    Builder.setAssociatedClangDecl(ND);
    Builder.addTextChunk(Name);
  }

  void addKeyword(StringRef Name, Type TypeAnnotation) {
    CodeCompletionResultBuilder Builder(
        CompletionContext,
        CodeCompletionResult::ResultKind::Keyword);
    if (!HaveDot)
      Builder.addDot();
    Builder.addTextChunk(Name);
    if (!TypeAnnotation.isNull())
      Builder.addTypeAnnotation(TypeAnnotation.getString());
  }

  // Implement swift::VisibleDeclConsumer
  void foundDecl(ValueDecl *D) override {
    if (Kind == LookupKind::ValueExpr) {
      if (auto *VD = dyn_cast<VarDecl>(D)) {
        // Swift does not have class variables.
        // FIXME: add code completion results when class variables are added.
        if (ExprType->is<MetaTypeType>())
          return;
        addSwiftVarDeclRef(VD);
        return;
      }

      if (auto *FD = dyn_cast<FuncDecl>(D)) {
        // We can not call getters or setters.  We use VarDecls and
        // SubscriptDecls to produce completions that refer to getters and
        // setters.
        if (FD->isGetterOrSetter())
          return;

        // Don't complete class methods of instances; don't complete instance
        // methods of metatypes.
        if (FD->isStatic() != ExprType->is<MetaTypeType>())
          return;
        addSwiftMethodCall(FD);
        return;
      }

      if (HaveDot)
        return;

      // FIXME: super.constructor
      if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
        if (!ExprType->is<MetaTypeType>())
          return;
        addSwiftConstructorCall(CD);
        return;
      }

      if (auto *SD = dyn_cast<SubscriptDecl>(D)) {
        if (ExprType->is<MetaTypeType>())
          return;
        addSwiftSubscriptCall(SD);
        return;
      }
    }
  }

  // Implement clang::VisibleDeclConsumer
  void FoundDecl(clang::NamedDecl *ND, clang::NamedDecl *Hiding,
                 clang::DeclContext *Ctx,
                 bool InBaseClass) override {
    addClangDecl(ND);
  }

  void getValueExprCompletions(Type ExprType) {
    Kind = LookupKind::ValueExpr;
    this->ExprType = ExprType;
    if (ExprType->is<AnyFunctionType>()) {
      // FIXME: produce a call.
    } else {
      lookupVisibleDecls(*this, ExprType);
    }
    // Add the special qualified keyword 'metatype' so that, for example,
    // 'Int.metatype' can be completed.
    // Use the canonical type as a type annotation because looking at the
    // '.metatype' in the IDE is a way to understand what type the expression
    // has.
    addKeyword(
        "metatype",
        MetaTypeType::get(ExprType, SwiftContext)->getCanonicalType());
  }

  void getCompletionsInDeclContext(DeclContext *DC, SourceLoc Loc) {
    Kind = LookupKind::DeclContext;
    lookupVisibleDecls(*this, DC, Loc);

    if (auto Importer = SwiftContext.getClangModuleLoader())
      static_cast<ClangImporter&>(*Importer).lookupVisibleDecls(*this);
  }
};

} // end unnamed namespace

void CodeCompletionCallbacksImpl::completeDotExpr(Expr *E) {
  typecheckExpr(E);

  CompletionLookup Lookup(CompletionContext, TU->Ctx);
  Lookup.setHaveDot();
  Lookup.getValueExprCompletions(E->getType());

  Consumer.handleResults(CompletionContext.takeResults());
}

void CodeCompletionCallbacksImpl::completePostfixExpr(Expr *E) {
  typecheckExpr(E);

  CompletionLookup Lookup(CompletionContext, TU->Ctx);
  Lookup.getValueExprCompletions(E->getType());

  Consumer.handleResults(CompletionContext.takeResults());
}

void PrintingCodeCompletionConsumer::handleResults(
    ArrayRef<CodeCompletionResult *> Results) {
  OS << "Begin completions\n";
  for (auto Result : Results) {
    Result->print(OS);
    OS << "\n";
  }
  OS << "End completions\n";
}

namespace {
class CodeCompletionCallbacksFactoryImpl
    : public CodeCompletionCallbacksFactory {
  CodeCompletionContext &CompletionContext;
  CodeCompletionConsumer &Consumer;

public:
  CodeCompletionCallbacksFactoryImpl(CodeCompletionContext &CompletionContext,
                                     CodeCompletionConsumer &Consumer)
      : CompletionContext(CompletionContext), Consumer(Consumer) {}

  CodeCompletionCallbacks *createCodeCompletionCallbacks(Parser &P) override {
    return new CodeCompletionCallbacksImpl(P, CompletionContext, Consumer);
  }
};
} // end unnamed namespace

CodeCompletionCallbacksFactory *
swift::code_completion::makeCodeCompletionCallbacksFactory(
    CodeCompletionContext &CompletionContext,
    CodeCompletionConsumer &Consumer) {
  return new CodeCompletionCallbacksFactoryImpl(CompletionContext, Consumer);
}

<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011,2012 Preferred Networks and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_
#define JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_

#include <sys/types.h>
#include <unistd.h>

#include <map>
#include <string>
#include "jubatus/util/lang/bind.h"
#include "jubatus/util/lang/shared_ptr.h"
#include "jubatus/util/system/sysstat.h"
#include "jubatus/util/system/time_util.h"

#include "jubatus/core/common/jsonconfig.hpp"
#include "mixer/mixer.hpp"
#include "server_util.hpp"
#include "../../config.hpp"
#include "../common/lock_service.hpp"
#include "../common/mprpc/rpc_server.hpp"
#include "../common/signals.hpp"
#include "../common/config.hpp"
#include "../common/logger/logger.hpp"

using jubatus::util::system::time::clock_time;
using jubatus::util::system::time::get_clock_time;

namespace jubatus {
namespace server {
namespace framework {

class server_helper_impl {
 public:
  explicit server_helper_impl(const server_argv& a);
  ~server_helper_impl();

  void prepare_for_start(const server_argv& a, bool use_cht);
  void prepare_for_run(const server_argv& a, bool use_cht);
  void get_config_lock(const server_argv& a, int retry);
  void prepare_for_stop(const server_argv& a);

  jubatus::util::lang::shared_ptr<common::lock_service> zk() const {
    return zk_;
  }

 private:
  jubatus::util::lang::shared_ptr<common::lock_service> zk_;
  jubatus::util::lang::shared_ptr<common::try_lockable> zk_config_lock_;
};

template<typename Server>
class server_helper {
 public:
  typedef typename Server::status_t status_t;

  explicit server_helper(const server_argv& a, bool use_cht = false)
      : impl_(a),
        start_time_(get_clock_time()),
        use_cht_(use_cht) {
    impl_.prepare_for_start(a, use_cht);
    server_.reset(new Server(a, impl_.zk()));

    impl_.get_config_lock(a, 3);

    try {
      server_->set_config(get_conf(a));
    } catch (const core::common::jsonconfig::cast_check_error& e) {
      core::common::config_exception config_error;
      const core::common::jsonconfig::config_error_list& errors = e.errors();
      for (core::common::jsonconfig::config_error_list::const_iterator
          it = errors.begin(), end = errors.end(); it != end; ++it) {
        config_error << core::common::exception::error_message((*it)->what());
      }
      // send error message to caller
      throw JUBATUS_EXCEPTION(config_error);
    } catch (const jubatus::util::lang::parse_error& e) {
      // exit immediately on JSON parse error with exit-code 1
      std::string msg =
          std::string("syntax error in configuration: ") +
          (a.is_standalone() ?
           a.configpath :
           std::string("<zookeeper>")) + ":" +
          jubatus::util::lang::lexical_cast<std::string>(e.lineno()) + ":" +
          jubatus::util::lang::lexical_cast<std::string>(e.pos()) + " " +
          e.msg();

      LOG(ERROR) << msg;
      exit(1);
    }

    try {
      // standalone only, is it desirable?
      if (a.is_standalone() && !a.modelpath.empty()) {
        server_->load_file(a.modelpath);
      }
    } catch (const std::runtime_error& e) {
      exit(1);
    }
  }

  std::map<std::string, std::string> get_loads() const {
    std::map<std::string, std::string> result;
    {
      jubatus::util::system::sysstat::sysstat_ret sys;
      get_sysstat(sys);
      result["loadavg"] =
          jubatus::util::lang::lexical_cast<std::string>(sys.loadavg);
      result["total_memory"] = jubatus::util::lang::lexical_cast<std::string>(
          sys.total_memory);
      result["free_memory"] = jubatus::util::lang::lexical_cast<std::string>(
          sys.free_memory);
    }
    return result;
  }

  std::map<std::string, status_t> get_status() const {
    std::map<std::string, status_t> status;
    const server_argv& a = server_->argv();
    status_t& data = status[get_server_identifier(a)];

    const clock_time ct = get_clock_time();
    data["clock_time"] =
       jubatus::util::lang::lexical_cast<std::string>(ct.sec);
    data["start_time"] =
       jubatus::util::lang::lexical_cast<std::string>(start_time_.sec);
    data["uptime"] =
       jubatus::util::lang::lexical_cast<std::string>((ct - start_time_).sec);

    common::machine_status_t mt;
    common::get_machine_status(mt);
    data["VIRT"] =
        jubatus::util::lang::lexical_cast<std::string>(mt.vm_size);
    data["RSS"] =
        jubatus::util::lang::lexical_cast<std::string>(mt.vm_resident);
    data["SHR"] =
        jubatus::util::lang::lexical_cast<std::string>(mt.vm_share);

    data["timeout"] = jubatus::util::lang::lexical_cast<std::string>(a.timeout);
    data["threadnum"] =
        jubatus::util::lang::lexical_cast<std::string>(a.threadnum);
    data["datadir"] = a.datadir;
    data["is_standalone"] = jubatus::util::lang::lexical_cast<std::string>(
        a.is_standalone());
    data["VERSION"] = JUBATUS_VERSION;
    data["PROGNAME"] = a.program_name;
    data["type"] = a.type;
    data["logdir"] = a.logdir;
    data["log_config"] = a.log_config;

    std::string configpath;
    if (a.is_standalone()) {
      configpath = a.configpath;
    } else {
#ifdef HAVE_ZOOKEEPER_H
      // return zookeeper node name
      jubatus::server::common::build_config_path(configpath, a.type, a.name);
#endif
    }
    data["configpath"] = configpath;

    data["pid"] =
        jubatus::util::lang::lexical_cast<std::string>(getpid());
    data["user"] = jubatus::server::common::get_user_name();

    data["update_count"] = jubatus::util::lang::lexical_cast<std::string>(
        server_->update_count());

    data["last_saved"] =
        jubatus::util::lang::lexical_cast<std::string>
        (server_->last_saved_sec());
    data["last_saved_path"] = server_->last_saved_path();
    data["last_loaded"] =
        jubatus::util::lang::lexical_cast<std::string>
        (server_->last_loaded_sec());
    data["last_loaded_path"] = server_->last_loaded_path();

    server_->get_status(data);

    // distributed mode only
    if (!a.is_standalone()) {
      data["zk"] = a.z;
      data["name"] = a.name;
      data["interval_sec"] =
          jubatus::util::lang::lexical_cast<std::string>(a.interval_sec);
      data["interval_count"] = jubatus::util::lang::lexical_cast<std::string>(
          a.interval_count);
      data["zookeeper_timeout"] =
          jubatus::util::lang::lexical_cast<std::string>(a.zookeeper_timeout);
      data["interconnect_timeout"] =
          jubatus::util::lang::lexical_cast<std::string>
          (a.interconnect_timeout);
      data["connected_zookeeper"] = impl_.zk()->get_connected_host_and_port();
      data["use_cht"] = jubatus::util::lang::lexical_cast<std::string>(
          use_cht_);

      data["mixer"] = a.mixer;
      server_->get_mixer()->get_status(data);
    }

    return status;
  }

  int start(common::mprpc::rpc_server& serv) {
    const server_argv& a = server_->argv();

    try {
      serv.listen(a.port, a.bind_address);
      LOG(INFO) << "start listening at port " << a.port;

      start_time_ = get_clock_time();
      serv.start(a.threadnum, true);

      // RPC server started, then register group membership
      impl_.prepare_for_run(a, use_cht_);
      LOG(INFO) << common::get_program_name() << " RPC server startup";

      // Stop RPC server when terminate signal is sent
      common::set_action_on_term(
          jubatus::util::lang::bind(
              &server_helper::stop, this, jubatus::util::lang::ref(serv)));

      if (!a.is_standalone()) {
        // Start mixer and register active membership
        server_->get_mixer()->start();
      }

      // wait for termination
      serv.join();

      return 0;
    } catch (const mp::system_error& e) {
      if (e.code == EADDRINUSE) {
        LOG(FATAL) << "server failed to start: any process using port "
            << a.port << "?";
      } else {
        LOG(FATAL) << "server failed to start: " << e.what();
      }
    } catch (jubatus::core::common::exception::jubatus_exception&) {
      throw;
    } catch (const std::exception& e) {
      LOG(FATAL) << "server failed to start: " << e.what();
    }
    return -1;
  }

  void stop(common::mprpc::rpc_server& serv) {
    // stop mixer before RPC server stopped for avoiding mixer RPC call to the
    // server itself
    LOG(INFO) << "stopping mixer thread";
    if (!server_->argv().is_standalone()) {
      server_->get_mixer()->stop();
      impl_.prepare_for_stop(server_->argv());
    }

    LOG(INFO) << "stopping RPC server";
    serv.end();
  }

  jubatus::util::lang::shared_ptr<Server> server() const {
    return server_;
  }

  jubatus::util::concurrent::rw_mutex& rw_mutex() {
    return server_->rw_mutex();
  }

 private:
  jubatus::util::lang::shared_ptr<Server> server_;
  server_helper_impl impl_;
  clock_time start_time_;
  const bool use_cht_;
};

}  // namespace framework
}  // namespace server
}  // namespace jubatus

#define JRLOCK_(p) \
  ::jubatus::util::concurrent::scoped_rlock lk((p)->rw_mutex())

#define JWLOCK_(p) \
  ::jubatus::util::concurrent::scoped_wlock lk((p)->rw_mutex()); \
  (p)->server()->event_model_updated()

#define NOLOCK_(p)

#endif  // JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_
<commit_msg>wrong message `stopping mixer thread` on standalone mode<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011,2012 Preferred Networks and Nippon Telegraph and Telephone Corporation.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#ifndef JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_
#define JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_

#include <sys/types.h>
#include <unistd.h>

#include <map>
#include <string>
#include "jubatus/util/lang/bind.h"
#include "jubatus/util/lang/shared_ptr.h"
#include "jubatus/util/system/sysstat.h"
#include "jubatus/util/system/time_util.h"

#include "jubatus/core/common/jsonconfig.hpp"
#include "mixer/mixer.hpp"
#include "server_util.hpp"
#include "../../config.hpp"
#include "../common/lock_service.hpp"
#include "../common/mprpc/rpc_server.hpp"
#include "../common/signals.hpp"
#include "../common/config.hpp"
#include "../common/logger/logger.hpp"

using jubatus::util::system::time::clock_time;
using jubatus::util::system::time::get_clock_time;

namespace jubatus {
namespace server {
namespace framework {

class server_helper_impl {
 public:
  explicit server_helper_impl(const server_argv& a);
  ~server_helper_impl();

  void prepare_for_start(const server_argv& a, bool use_cht);
  void prepare_for_run(const server_argv& a, bool use_cht);
  void get_config_lock(const server_argv& a, int retry);
  void prepare_for_stop(const server_argv& a);

  jubatus::util::lang::shared_ptr<common::lock_service> zk() const {
    return zk_;
  }

 private:
  jubatus::util::lang::shared_ptr<common::lock_service> zk_;
  jubatus::util::lang::shared_ptr<common::try_lockable> zk_config_lock_;
};

template<typename Server>
class server_helper {
 public:
  typedef typename Server::status_t status_t;

  explicit server_helper(const server_argv& a, bool use_cht = false)
      : impl_(a),
        start_time_(get_clock_time()),
        use_cht_(use_cht) {
    impl_.prepare_for_start(a, use_cht);
    server_.reset(new Server(a, impl_.zk()));

    impl_.get_config_lock(a, 3);

    try {
      server_->set_config(get_conf(a));
    } catch (const core::common::jsonconfig::cast_check_error& e) {
      core::common::config_exception config_error;
      const core::common::jsonconfig::config_error_list& errors = e.errors();
      for (core::common::jsonconfig::config_error_list::const_iterator
          it = errors.begin(), end = errors.end(); it != end; ++it) {
        config_error << core::common::exception::error_message((*it)->what());
      }
      // send error message to caller
      throw JUBATUS_EXCEPTION(config_error);
    } catch (const jubatus::util::lang::parse_error& e) {
      // exit immediately on JSON parse error with exit-code 1
      std::string msg =
          std::string("syntax error in configuration: ") +
          (a.is_standalone() ?
           a.configpath :
           std::string("<zookeeper>")) + ":" +
          jubatus::util::lang::lexical_cast<std::string>(e.lineno()) + ":" +
          jubatus::util::lang::lexical_cast<std::string>(e.pos()) + " " +
          e.msg();

      LOG(ERROR) << msg;
      exit(1);
    }

    try {
      // standalone only, is it desirable?
      if (a.is_standalone() && !a.modelpath.empty()) {
        server_->load_file(a.modelpath);
      }
    } catch (const std::runtime_error& e) {
      exit(1);
    }
  }

  std::map<std::string, std::string> get_loads() const {
    std::map<std::string, std::string> result;
    {
      jubatus::util::system::sysstat::sysstat_ret sys;
      get_sysstat(sys);
      result["loadavg"] =
          jubatus::util::lang::lexical_cast<std::string>(sys.loadavg);
      result["total_memory"] = jubatus::util::lang::lexical_cast<std::string>(
          sys.total_memory);
      result["free_memory"] = jubatus::util::lang::lexical_cast<std::string>(
          sys.free_memory);
    }
    return result;
  }

  std::map<std::string, status_t> get_status() const {
    std::map<std::string, status_t> status;
    const server_argv& a = server_->argv();
    status_t& data = status[get_server_identifier(a)];

    const clock_time ct = get_clock_time();
    data["clock_time"] =
       jubatus::util::lang::lexical_cast<std::string>(ct.sec);
    data["start_time"] =
       jubatus::util::lang::lexical_cast<std::string>(start_time_.sec);
    data["uptime"] =
       jubatus::util::lang::lexical_cast<std::string>((ct - start_time_).sec);

    common::machine_status_t mt;
    common::get_machine_status(mt);
    data["VIRT"] =
        jubatus::util::lang::lexical_cast<std::string>(mt.vm_size);
    data["RSS"] =
        jubatus::util::lang::lexical_cast<std::string>(mt.vm_resident);
    data["SHR"] =
        jubatus::util::lang::lexical_cast<std::string>(mt.vm_share);

    data["timeout"] = jubatus::util::lang::lexical_cast<std::string>(a.timeout);
    data["threadnum"] =
        jubatus::util::lang::lexical_cast<std::string>(a.threadnum);
    data["datadir"] = a.datadir;
    data["is_standalone"] = jubatus::util::lang::lexical_cast<std::string>(
        a.is_standalone());
    data["VERSION"] = JUBATUS_VERSION;
    data["PROGNAME"] = a.program_name;
    data["type"] = a.type;
    data["logdir"] = a.logdir;
    data["log_config"] = a.log_config;

    std::string configpath;
    if (a.is_standalone()) {
      configpath = a.configpath;
    } else {
#ifdef HAVE_ZOOKEEPER_H
      // return zookeeper node name
      jubatus::server::common::build_config_path(configpath, a.type, a.name);
#endif
    }
    data["configpath"] = configpath;

    data["pid"] =
        jubatus::util::lang::lexical_cast<std::string>(getpid());
    data["user"] = jubatus::server::common::get_user_name();

    data["update_count"] = jubatus::util::lang::lexical_cast<std::string>(
        server_->update_count());

    data["last_saved"] =
        jubatus::util::lang::lexical_cast<std::string>
        (server_->last_saved_sec());
    data["last_saved_path"] = server_->last_saved_path();
    data["last_loaded"] =
        jubatus::util::lang::lexical_cast<std::string>
        (server_->last_loaded_sec());
    data["last_loaded_path"] = server_->last_loaded_path();

    server_->get_status(data);

    // distributed mode only
    if (!a.is_standalone()) {
      data["zk"] = a.z;
      data["name"] = a.name;
      data["interval_sec"] =
          jubatus::util::lang::lexical_cast<std::string>(a.interval_sec);
      data["interval_count"] = jubatus::util::lang::lexical_cast<std::string>(
          a.interval_count);
      data["zookeeper_timeout"] =
          jubatus::util::lang::lexical_cast<std::string>(a.zookeeper_timeout);
      data["interconnect_timeout"] =
          jubatus::util::lang::lexical_cast<std::string>
          (a.interconnect_timeout);
      data["connected_zookeeper"] = impl_.zk()->get_connected_host_and_port();
      data["use_cht"] = jubatus::util::lang::lexical_cast<std::string>(
          use_cht_);

      data["mixer"] = a.mixer;
      server_->get_mixer()->get_status(data);
    }

    return status;
  }

  int start(common::mprpc::rpc_server& serv) {
    const server_argv& a = server_->argv();

    try {
      serv.listen(a.port, a.bind_address);
      LOG(INFO) << "start listening at port " << a.port;

      start_time_ = get_clock_time();
      serv.start(a.threadnum, true);

      // RPC server started, then register group membership
      impl_.prepare_for_run(a, use_cht_);
      LOG(INFO) << common::get_program_name() << " RPC server startup";

      // Stop RPC server when terminate signal is sent
      common::set_action_on_term(
          jubatus::util::lang::bind(
              &server_helper::stop, this, jubatus::util::lang::ref(serv)));

      if (!a.is_standalone()) {
        // Start mixer and register active membership
        server_->get_mixer()->start();
      }

      // wait for termination
      serv.join();

      return 0;
    } catch (const mp::system_error& e) {
      if (e.code == EADDRINUSE) {
        LOG(FATAL) << "server failed to start: any process using port "
            << a.port << "?";
      } else {
        LOG(FATAL) << "server failed to start: " << e.what();
      }
    } catch (jubatus::core::common::exception::jubatus_exception&) {
      throw;
    } catch (const std::exception& e) {
      LOG(FATAL) << "server failed to start: " << e.what();
    }
    return -1;
  }

  void stop(common::mprpc::rpc_server& serv) {
    // stop mixer before RPC server stopped for avoiding mixer RPC call to the
    // server itself
    if (!server_->argv().is_standalone()) {
      LOG(INFO) << "stopping mixer thread";
      server_->get_mixer()->stop();
      impl_.prepare_for_stop(server_->argv());
    }

    LOG(INFO) << "stopping RPC server";
    serv.end();
  }

  jubatus::util::lang::shared_ptr<Server> server() const {
    return server_;
  }

  jubatus::util::concurrent::rw_mutex& rw_mutex() {
    return server_->rw_mutex();
  }

 private:
  jubatus::util::lang::shared_ptr<Server> server_;
  server_helper_impl impl_;
  clock_time start_time_;
  const bool use_cht_;
};

}  // namespace framework
}  // namespace server
}  // namespace jubatus

#define JRLOCK_(p) \
  ::jubatus::util::concurrent::scoped_rlock lk((p)->rw_mutex())

#define JWLOCK_(p) \
  ::jubatus::util::concurrent::scoped_wlock lk((p)->rw_mutex()); \
  (p)->server()->event_model_updated()

#define NOLOCK_(p)

#endif  // JUBATUS_SERVER_FRAMEWORK_SERVER_HELPER_HPP_
<|endoftext|>


<commit_before>/* -*- mode: c++; c-basic-offset:4 -*-
    uiserver/decryptverifywizard.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2007 Klarälvdalens Datakonsult AB

    Kleopatra 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.

    Kleopatra 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "decryptverifywizard.h"

#include "decryptverifyoperationwidget.h"
#include "decryptverifyresultwidget.h"
#include "scrollarea.h"

#include <utils/filenamerequester.h>
#include <utils/stl_util.h>

#include <KLocale>

#include <QScrollArea>
#include <QWizardPage>
#include <QLayout>
#include <QLabel>
#include <QEventLoop>
#include <QPointer>
#include <QAbstractButton>
#include <QScrollBar>

#include <boost/bind.hpp>

#include <vector>
#include <cassert>

using namespace Kleo;
using namespace boost;

namespace {

    class HLine : public QFrame {
        Q_OBJECT
    public:
        explicit HLine( QWidget * p=0, Qt::WindowFlags f=0 )
            : QFrame( p, f )
        {
            setFrameStyle( QFrame::HLine|QFrame::Sunken );
        }
    };

    class OperationsPage : public QWizardPage {
        Q_OBJECT
    public:
        explicit OperationsPage( QWidget * p=0 );
        ~OperationsPage();

        void setOutputDirectory( const QString & dir ) {
            m_ui.outputDirectoryFNR.setFileName( dir );
        }

        QString outputDirectory() const {
            return m_ui.outputDirectoryFNR.fileName();
        }

        void ensureIndexAvailable( unsigned int idx );

        DecryptVerifyOperationWidget * widget( unsigned int idx ) {
            return m_widgets.at( idx );
        }

    private:
        std::vector<DecryptVerifyOperationWidget*> m_widgets;

        struct UI {
            QLabel            outputDirectoryLB;
            FileNameRequester outputDirectoryFNR;
            ScrollArea       scrollArea; // ### replace with KDScrollArea when done
            QVBoxLayout     vlay;
            QHBoxLayout      hlay;

            explicit UI( OperationsPage * q );
        } m_ui;
    };

    class ResultPage : public QWizardPage {
        Q_OBJECT
    public:
        explicit ResultPage( QWidget * p=0 );
        ~ResultPage();

        void ensureIndexAvailable( unsigned int idx );

        DecryptVerifyResultWidget * widget( unsigned int idx ) {
            return m_widgets.at( idx );
        }

    private Q_SLOTS:
        void slotMaybeNoMoreProgress() {
            wizard()->button( QWizard::CancelButton )
                ->setEnabled( kdtools::any( m_widgets.begin(), m_widgets.end(),
                                            bind( &DecryptVerifyResultWidget::operationInProgress, _1 ) ) );
        }

    private:
        std::vector<DecryptVerifyResultWidget*> m_widgets;

        struct UI {
            ScrollArea   scrollArea; // ### replace with KDScrollArea when done
            QVBoxLayout vlay;

            explicit UI( ResultPage * q );
        } m_ui;
    };
}

class DecryptVerifyWizard::Private {
    friend class ::Kleo::DecryptVerifyWizard;
    DecryptVerifyWizard * const q;
public:
    Private( DecryptVerifyWizard * qq );
    ~Private();

    void ensureIndexAvailable( unsigned int idx ) {
        operationsPage.ensureIndexAvailable( idx );
        resultPage.ensureIndexAvailable( idx );
    }

private:
    OperationsPage operationsPage;
    ResultPage resultPage;
};

DecryptVerifyWizard::DecryptVerifyWizard( QWidget * p, Qt::WindowFlags f )
    : QWizard( p, f ), d( new Private( this ) )
{

}

DecryptVerifyWizard::~DecryptVerifyWizard() {}

void DecryptVerifyWizard::setOutputDirectory( const QString & dir ) {
    d->operationsPage.setOutputDirectory( dir );
}

QString DecryptVerifyWizard::outputDirectory() const {
    return d->operationsPage.outputDirectory();
}

DecryptVerifyOperationWidget * DecryptVerifyWizard::operationWidget( unsigned int idx ) {
    d->ensureIndexAvailable( idx );
    return d->operationsPage.widget( idx );
}

DecryptVerifyResultWidget * DecryptVerifyWizard::resultWidget( unsigned int idx ) {
    d->ensureIndexAvailable( idx );
    return d->resultPage.widget( idx );
}

bool DecryptVerifyWizard::waitForOperationSelection() {
    if ( !isVisible() )
        return true;

    assert( button( NextButton ) );
    assert( button( CancelButton ) );

    QEventLoop loop;
    QPointer<QObject> that = this;
    connect( this, SIGNAL(currentIdChanged(int)), &loop, SLOT(quit()) );
    connect( this, SIGNAL(finished(int)), &loop, SLOT(quit()) );
    loop.exec();

    return that && currentPage() == &d->resultPage ;
}

DecryptVerifyWizard::Private::Private( DecryptVerifyWizard * qq )
    : q( qq ),
      operationsPage( q ),
      resultPage( q )
{
    q->setOptions( q->options() | NoBackButtonOnStartPage | NoBackButtonOnLastPage );
    q->addPage( &operationsPage );
    q->addPage( &resultPage );
}

DecryptVerifyWizard::Private::~Private() {}

OperationsPage::OperationsPage( QWidget * p )
    : QWizardPage( p ), m_widgets(), m_ui( this )
{
    setTitle( i18n("FIXME Choose operations to be performed") );
    setSubTitle( i18n("FIXME Here, you can check and, if needed, override "
                      "the operations Kleopatra detected for the input given.") );
    setCommitPage( true );
    setButtonText( QWizard::CommitButton, i18n("&Decrypt/Verify") );
}

OperationsPage::~OperationsPage() {}

OperationsPage::UI::UI( OperationsPage * q )
    : outputDirectoryLB( i18n("&Output directory:"), q ),
      outputDirectoryFNR( q ),
      scrollArea( q ),
      vlay( q ),
      hlay()
{
    KDAB_SET_OBJECT_NAME( outputDirectoryLB );
    KDAB_SET_OBJECT_NAME( outputDirectoryFNR );
    KDAB_SET_OBJECT_NAME( scrollArea );

    KDAB_SET_OBJECT_NAME( vlay );
    KDAB_SET_OBJECT_NAME( hlay );

    assert( qobject_cast<QBoxLayout*>(scrollArea.widget()->layout()) );
    static_cast<QBoxLayout*>(scrollArea.widget()->layout())->addStretch( 1 );
    outputDirectoryLB.setBuddy( &outputDirectoryFNR );

    hlay.setMargin( 0 );

    vlay.addWidget( &scrollArea, 1 );
    vlay.addLayout( &hlay );
    hlay.addWidget( &outputDirectoryLB );
    hlay.addWidget( &outputDirectoryFNR );
}

void OperationsPage::ensureIndexAvailable( unsigned int idx ) {

    if ( idx < m_widgets.size() )
        return;

    assert( m_ui.scrollArea.widget() );
    assert( qobject_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() ) );
    QBoxLayout & blay = *static_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() );

    for ( unsigned int i = m_widgets.size() ; i < idx+1 ; ++i ) {
        if ( i )
            blay.insertWidget( blay.count()-1, new HLine( m_ui.scrollArea.widget() ) );
        DecryptVerifyOperationWidget * w = new DecryptVerifyOperationWidget( m_ui.scrollArea.widget() );
        blay.insertWidget( blay.count()-1, w );
        w->show();
        m_widgets.push_back( w );
    }
}

ResultPage::ResultPage( QWidget * p )
    : QWizardPage( p ), m_widgets(), m_ui( this )
{
    setTitle( i18n("Results") );
    setSubTitle( i18n("FIXME") );
    setButtonText( QWizard::FinishButton, i18n("&OK") );
}

ResultPage::~ResultPage() {}

ResultPage::UI::UI( ResultPage * q )
    : scrollArea( q ),
      vlay( q )
{
    KDAB_SET_OBJECT_NAME( scrollArea );
    KDAB_SET_OBJECT_NAME( vlay );

    assert( qobject_cast<QBoxLayout*>(scrollArea.widget()->layout()) );
    static_cast<QBoxLayout*>(scrollArea.widget()->layout())->addStretch( 1 );

    vlay.addWidget( &scrollArea );
}

void ResultPage::ensureIndexAvailable( unsigned int idx ) {

    if ( idx < m_widgets.size() )
        return;

    assert( m_ui.scrollArea.widget() );
    assert( qobject_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() ) );
    QBoxLayout & blay = *static_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() );

    for ( unsigned int i = m_widgets.size() ; i < idx+1 ; ++i ) {
        if ( i )
            blay.insertWidget( blay.count()-1, new HLine( m_ui.scrollArea.widget() ) );
        DecryptVerifyResultWidget * w = new DecryptVerifyResultWidget( m_ui.scrollArea.widget() );
        connect( w, SIGNAL(operationStateChanged()), this, SLOT(slotMaybeNoMoreProgress()) );
        blay.insertWidget( blay.count()-1, w );
        w->show();
        m_widgets.push_back( w );
    }

}

#include "decryptverifywizard.moc"
#include "moc_decryptverifywizard.cpp"
<commit_msg>Remove FIXME from page titles<commit_after>/* -*- mode: c++; c-basic-offset:4 -*-
    uiserver/decryptverifywizard.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2007 Klarälvdalens Datakonsult AB

    Kleopatra 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.

    Kleopatra 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "decryptverifywizard.h"

#include "decryptverifyoperationwidget.h"
#include "decryptverifyresultwidget.h"
#include "scrollarea.h"

#include <utils/filenamerequester.h>
#include <utils/stl_util.h>

#include <KLocale>

#include <QScrollArea>
#include <QWizardPage>
#include <QLayout>
#include <QLabel>
#include <QEventLoop>
#include <QPointer>
#include <QAbstractButton>
#include <QScrollBar>

#include <boost/bind.hpp>

#include <vector>
#include <cassert>

using namespace Kleo;
using namespace boost;

namespace {

    class HLine : public QFrame {
        Q_OBJECT
    public:
        explicit HLine( QWidget * p=0, Qt::WindowFlags f=0 )
            : QFrame( p, f )
        {
            setFrameStyle( QFrame::HLine|QFrame::Sunken );
        }
    };

    class OperationsPage : public QWizardPage {
        Q_OBJECT
    public:
        explicit OperationsPage( QWidget * p=0 );
        ~OperationsPage();

        void setOutputDirectory( const QString & dir ) {
            m_ui.outputDirectoryFNR.setFileName( dir );
        }

        QString outputDirectory() const {
            return m_ui.outputDirectoryFNR.fileName();
        }

        void ensureIndexAvailable( unsigned int idx );

        DecryptVerifyOperationWidget * widget( unsigned int idx ) {
            return m_widgets.at( idx );
        }

    private:
        std::vector<DecryptVerifyOperationWidget*> m_widgets;

        struct UI {
            QLabel            outputDirectoryLB;
            FileNameRequester outputDirectoryFNR;
            ScrollArea       scrollArea; // ### replace with KDScrollArea when done
            QVBoxLayout     vlay;
            QHBoxLayout      hlay;

            explicit UI( OperationsPage * q );
        } m_ui;
    };

    class ResultPage : public QWizardPage {
        Q_OBJECT
    public:
        explicit ResultPage( QWidget * p=0 );
        ~ResultPage();

        void ensureIndexAvailable( unsigned int idx );

        DecryptVerifyResultWidget * widget( unsigned int idx ) {
            return m_widgets.at( idx );
        }

    private Q_SLOTS:
        void slotMaybeNoMoreProgress() {
            wizard()->button( QWizard::CancelButton )
                ->setEnabled( kdtools::any( m_widgets.begin(), m_widgets.end(),
                                            bind( &DecryptVerifyResultWidget::operationInProgress, _1 ) ) );
        }

    private:
        std::vector<DecryptVerifyResultWidget*> m_widgets;

        struct UI {
            ScrollArea   scrollArea; // ### replace with KDScrollArea when done
            QVBoxLayout vlay;

            explicit UI( ResultPage * q );
        } m_ui;
    };
}

class DecryptVerifyWizard::Private {
    friend class ::Kleo::DecryptVerifyWizard;
    DecryptVerifyWizard * const q;
public:
    Private( DecryptVerifyWizard * qq );
    ~Private();

    void ensureIndexAvailable( unsigned int idx ) {
        operationsPage.ensureIndexAvailable( idx );
        resultPage.ensureIndexAvailable( idx );
    }

private:
    OperationsPage operationsPage;
    ResultPage resultPage;
};

DecryptVerifyWizard::DecryptVerifyWizard( QWidget * p, Qt::WindowFlags f )
    : QWizard( p, f ), d( new Private( this ) )
{

}

DecryptVerifyWizard::~DecryptVerifyWizard() {}

void DecryptVerifyWizard::setOutputDirectory( const QString & dir ) {
    d->operationsPage.setOutputDirectory( dir );
}

QString DecryptVerifyWizard::outputDirectory() const {
    return d->operationsPage.outputDirectory();
}

DecryptVerifyOperationWidget * DecryptVerifyWizard::operationWidget( unsigned int idx ) {
    d->ensureIndexAvailable( idx );
    return d->operationsPage.widget( idx );
}

DecryptVerifyResultWidget * DecryptVerifyWizard::resultWidget( unsigned int idx ) {
    d->ensureIndexAvailable( idx );
    return d->resultPage.widget( idx );
}

bool DecryptVerifyWizard::waitForOperationSelection() {
    if ( !isVisible() )
        return true;

    assert( button( NextButton ) );
    assert( button( CancelButton ) );

    QEventLoop loop;
    QPointer<QObject> that = this;
    connect( this, SIGNAL(currentIdChanged(int)), &loop, SLOT(quit()) );
    connect( this, SIGNAL(finished(int)), &loop, SLOT(quit()) );
    loop.exec();

    return that && currentPage() == &d->resultPage ;
}

DecryptVerifyWizard::Private::Private( DecryptVerifyWizard * qq )
    : q( qq ),
      operationsPage( q ),
      resultPage( q )
{
    q->setOptions( q->options() | NoBackButtonOnStartPage | NoBackButtonOnLastPage );
    q->addPage( &operationsPage );
    q->addPage( &resultPage );
}

DecryptVerifyWizard::Private::~Private() {}

OperationsPage::OperationsPage( QWidget * p )
    : QWizardPage( p ), m_widgets(), m_ui( this )
{
    setTitle( i18n("Choose operations to be performed") );
    setSubTitle( i18n("Here you can check and, if needed, override "
                      "the operations Kleopatra detected for the input given.") );
    setCommitPage( true );
    setButtonText( QWizard::CommitButton, i18n("&Decrypt/Verify") );
}

OperationsPage::~OperationsPage() {}

OperationsPage::UI::UI( OperationsPage * q )
    : outputDirectoryLB( i18n("&Output directory:"), q ),
      outputDirectoryFNR( q ),
      scrollArea( q ),
      vlay( q ),
      hlay()
{
    KDAB_SET_OBJECT_NAME( outputDirectoryLB );
    KDAB_SET_OBJECT_NAME( outputDirectoryFNR );
    KDAB_SET_OBJECT_NAME( scrollArea );

    KDAB_SET_OBJECT_NAME( vlay );
    KDAB_SET_OBJECT_NAME( hlay );

    assert( qobject_cast<QBoxLayout*>(scrollArea.widget()->layout()) );
    static_cast<QBoxLayout*>(scrollArea.widget()->layout())->addStretch( 1 );
    outputDirectoryLB.setBuddy( &outputDirectoryFNR );

    hlay.setMargin( 0 );

    vlay.addWidget( &scrollArea, 1 );
    vlay.addLayout( &hlay );
    hlay.addWidget( &outputDirectoryLB );
    hlay.addWidget( &outputDirectoryFNR );
}

void OperationsPage::ensureIndexAvailable( unsigned int idx ) {

    if ( idx < m_widgets.size() )
        return;

    assert( m_ui.scrollArea.widget() );
    assert( qobject_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() ) );
    QBoxLayout & blay = *static_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() );

    for ( unsigned int i = m_widgets.size() ; i < idx+1 ; ++i ) {
        if ( i )
            blay.insertWidget( blay.count()-1, new HLine( m_ui.scrollArea.widget() ) );
        DecryptVerifyOperationWidget * w = new DecryptVerifyOperationWidget( m_ui.scrollArea.widget() );
        blay.insertWidget( blay.count()-1, w );
        w->show();
        m_widgets.push_back( w );
    }
}

ResultPage::ResultPage( QWidget * p )
    : QWizardPage( p ), m_widgets(), m_ui( this )
{
    setTitle( i18n("Results") );
    setSubTitle( i18n("Detailed operation results") );
    setButtonText( QWizard::FinishButton, i18n("&OK") );
}

ResultPage::~ResultPage() {}

ResultPage::UI::UI( ResultPage * q )
    : scrollArea( q ),
      vlay( q )
{
    KDAB_SET_OBJECT_NAME( scrollArea );
    KDAB_SET_OBJECT_NAME( vlay );

    assert( qobject_cast<QBoxLayout*>(scrollArea.widget()->layout()) );
    static_cast<QBoxLayout*>(scrollArea.widget()->layout())->addStretch( 1 );

    vlay.addWidget( &scrollArea );
}

void ResultPage::ensureIndexAvailable( unsigned int idx ) {

    if ( idx < m_widgets.size() )
        return;

    assert( m_ui.scrollArea.widget() );
    assert( qobject_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() ) );
    QBoxLayout & blay = *static_cast<QBoxLayout*>( m_ui.scrollArea.widget()->layout() );

    for ( unsigned int i = m_widgets.size() ; i < idx+1 ; ++i ) {
        if ( i )
            blay.insertWidget( blay.count()-1, new HLine( m_ui.scrollArea.widget() ) );
        DecryptVerifyResultWidget * w = new DecryptVerifyResultWidget( m_ui.scrollArea.widget() );
        connect( w, SIGNAL(operationStateChanged()), this, SLOT(slotMaybeNoMoreProgress()) );
        blay.insertWidget( blay.count()-1, w );
        w->show();
        m_widgets.push_back( w );
    }

}

#include "decryptverifywizard.moc"
#include "moc_decryptverifywizard.cpp"
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/api/chrome_extensions_api_client.h"

#include "chrome/browser/extensions/api/storage/sync_value_store_cache.h"
#include "content/public/browser/browser_context.h"

#if defined(ENABLE_CONFIGURATION_POLICY)
#include "chrome/browser/extensions/api/storage/managed_value_store_cache.h"
#endif

namespace extensions {

ChromeExtensionsAPIClient::ChromeExtensionsAPIClient() {}

ChromeExtensionsAPIClient::~ChromeExtensionsAPIClient() {}

void ChromeExtensionsAPIClient::AddAdditionalValueStoreCaches(
    content::BrowserContext* context,
    const scoped_refptr<SettingsStorageFactory>& factory,
    const scoped_refptr<ObserverListThreadSafe<SettingsObserver> >& observers,
    std::map<settings_namespace::Namespace, ValueStoreCache*>* caches) {
  // Add support for chrome.storage.sync.
  (*caches)[settings_namespace::SYNC] =
      new SyncValueStoreCache(factory, observers, context->GetPath());

#if defined(ENABLE_CONFIGURATION_POLICY)
  // Add support for chrome.storage.managed.
  (*caches)[settings_namespace::MANAGED] =
      new ManagedValueStoreCache(context, factory, observers);
#endif
}

}  // namespace extensions
<commit_msg>Fix for undefined base::FilePath in chrome_extensions_api_client.cc<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/api/chrome_extensions_api_client.h"

#include "base/files/file_path.h"
#include "chrome/browser/extensions/api/storage/sync_value_store_cache.h"
#include "content/public/browser/browser_context.h"

#if defined(ENABLE_CONFIGURATION_POLICY)
#include "chrome/browser/extensions/api/storage/managed_value_store_cache.h"
#endif

namespace extensions {

ChromeExtensionsAPIClient::ChromeExtensionsAPIClient() {}

ChromeExtensionsAPIClient::~ChromeExtensionsAPIClient() {}

void ChromeExtensionsAPIClient::AddAdditionalValueStoreCaches(
    content::BrowserContext* context,
    const scoped_refptr<SettingsStorageFactory>& factory,
    const scoped_refptr<ObserverListThreadSafe<SettingsObserver> >& observers,
    std::map<settings_namespace::Namespace, ValueStoreCache*>* caches) {
  // Add support for chrome.storage.sync.
  (*caches)[settings_namespace::SYNC] =
      new SyncValueStoreCache(factory, observers, context->GetPath());

#if defined(ENABLE_CONFIGURATION_POLICY)
  // Add support for chrome.storage.managed.
  (*caches)[settings_namespace::MANAGED] =
      new ManagedValueStoreCache(context, factory, observers);
#endif
}

}  // namespace extensions
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/autofill/contact_info.h"

#include <stddef.h>
#include <ostream>
#include <string>

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autofill/autofill_type.h"
#include "chrome/browser/autofill/field_types.h"

static const string16 kNameSplitChars = ASCIIToUTF16("-'. ");

static const AutofillFieldType kAutofillNameInfoTypes[] = {
  NAME_FIRST,
  NAME_MIDDLE,
  NAME_LAST
};

static const size_t kAutofillNameInfoLength =
    arraysize(kAutofillNameInfoTypes);

NameInfo::NameInfo() {}

NameInfo::NameInfo(const NameInfo& info) : FormGroup() {
  *this = info;
}

NameInfo::~NameInfo() {}

NameInfo& NameInfo::operator=(const NameInfo& info) {
  if (this == &info)
    return *this;

  first_ = info.first_;
  middle_ = info.middle_;
  last_ = info.last_;
  return *this;
}

void NameInfo::GetSupportedTypes(FieldTypeSet* supported_types) const {
  supported_types->insert(NAME_FIRST);
  supported_types->insert(NAME_MIDDLE);
  supported_types->insert(NAME_LAST);
  supported_types->insert(NAME_MIDDLE_INITIAL);
  supported_types->insert(NAME_FULL);
}

string16 NameInfo::GetInfo(AutofillFieldType type) const {
  if (type == NAME_FIRST)
    return first();

  if (type == NAME_MIDDLE)
    return middle();

  if (type == NAME_LAST)
    return last();

  if (type == NAME_MIDDLE_INITIAL)
    return MiddleInitial();

  if (type == NAME_FULL)
    return FullName();

  return string16();
}

void NameInfo::SetInfo(AutofillFieldType type, const string16& value) {
  DCHECK_EQ(AutofillType::NAME, AutofillType(type).group());
  if (type == NAME_FIRST)
    first_ = value;
  else if (type == NAME_MIDDLE || type == NAME_MIDDLE_INITIAL)
    middle_ = value;
  else if (type == NAME_LAST)
    last_ = value;
  else if (type == NAME_FULL)
    SetFullName(value);
  else
    NOTREACHED();
}

string16 NameInfo::FullName() const {
  if (first_.empty())
    return string16();

  std::vector<string16> full_name;
  full_name.push_back(first_);

  if (!middle_.empty())
    full_name.push_back(middle_);

  if (!last_.empty())
    full_name.push_back(last_);

  return JoinString(full_name, ' ');
}

string16 NameInfo::MiddleInitial() const {
  if (middle_.empty())
    return string16();

  string16 middle_name(middle());
  string16 initial;
  initial.push_back(middle_name[0]);
  return initial;
}

void NameInfo::SetFullName(const string16& full) {
  // Clear the names.
  first_ = string16();
  middle_ = string16();
  last_ = string16();

  std::vector<string16> full_name_tokens;
  Tokenize(full, ASCIIToUTF16(" "), &full_name_tokens);

  // There are four possibilities: empty; first name; first and last names;
  // first, middle (possibly multiple strings) and then the last name.
  if (full_name_tokens.size() > 0) {
    first_ = full_name_tokens[0];
    if (full_name_tokens.size() > 1) {
      last_ = full_name_tokens.back();
      if (full_name_tokens.size() > 2) {
        full_name_tokens.erase(full_name_tokens.begin());
        full_name_tokens.pop_back();
        middle_ = JoinString(full_name_tokens, ' ');
      }
    }
  }
}

EmailInfo::EmailInfo() {}

EmailInfo::EmailInfo(const EmailInfo& info) : FormGroup() {
  *this = info;
}

EmailInfo::~EmailInfo() {}

EmailInfo& EmailInfo::operator=(const EmailInfo& info) {
  if (this == &info)
    return *this;

  email_ = info.email_;
  return *this;
}

void EmailInfo::GetSupportedTypes(FieldTypeSet* supported_types) const {
  supported_types->insert(EMAIL_ADDRESS);
}

string16 EmailInfo::GetInfo(AutofillFieldType type) const {
  if (type == EMAIL_ADDRESS)
    return email_;

  return string16();
}

void EmailInfo::SetInfo(AutofillFieldType type, const string16& value) {
  DCHECK_EQ(EMAIL_ADDRESS, type);
  email_ = value;
}

CompanyInfo::CompanyInfo() {}

CompanyInfo::CompanyInfo(const CompanyInfo& info) : FormGroup() {
  *this = info;
}

CompanyInfo::~CompanyInfo() {}

CompanyInfo& CompanyInfo::operator=(const CompanyInfo& info) {
  if (this == &info)
    return *this;

  company_name_ = info.company_name_;
  return *this;
}

void CompanyInfo::GetSupportedTypes(FieldTypeSet* supported_types) const {
  supported_types->insert(COMPANY_NAME);
}

string16 CompanyInfo::GetInfo(AutofillFieldType type) const {
  if (type == COMPANY_NAME)
    return company_name_;

  return string16();
}

void CompanyInfo::SetInfo(AutofillFieldType type, const string16& value) {
  DCHECK_EQ(COMPANY_NAME, type);
  company_name_ = value;
}
<commit_msg>autofill: Get rid of a static variable of string16 type as it's no longer used.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/autofill/contact_info.h"

#include <stddef.h>
#include <ostream>
#include <string>

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autofill/autofill_type.h"
#include "chrome/browser/autofill/field_types.h"

static const AutofillFieldType kAutofillNameInfoTypes[] = {
  NAME_FIRST,
  NAME_MIDDLE,
  NAME_LAST
};

static const size_t kAutofillNameInfoLength =
    arraysize(kAutofillNameInfoTypes);

NameInfo::NameInfo() {}

NameInfo::NameInfo(const NameInfo& info) : FormGroup() {
  *this = info;
}

NameInfo::~NameInfo() {}

NameInfo& NameInfo::operator=(const NameInfo& info) {
  if (this == &info)
    return *this;

  first_ = info.first_;
  middle_ = info.middle_;
  last_ = info.last_;
  return *this;
}

void NameInfo::GetSupportedTypes(FieldTypeSet* supported_types) const {
  supported_types->insert(NAME_FIRST);
  supported_types->insert(NAME_MIDDLE);
  supported_types->insert(NAME_LAST);
  supported_types->insert(NAME_MIDDLE_INITIAL);
  supported_types->insert(NAME_FULL);
}

string16 NameInfo::GetInfo(AutofillFieldType type) const {
  if (type == NAME_FIRST)
    return first();

  if (type == NAME_MIDDLE)
    return middle();

  if (type == NAME_LAST)
    return last();

  if (type == NAME_MIDDLE_INITIAL)
    return MiddleInitial();

  if (type == NAME_FULL)
    return FullName();

  return string16();
}

void NameInfo::SetInfo(AutofillFieldType type, const string16& value) {
  DCHECK_EQ(AutofillType::NAME, AutofillType(type).group());
  if (type == NAME_FIRST)
    first_ = value;
  else if (type == NAME_MIDDLE || type == NAME_MIDDLE_INITIAL)
    middle_ = value;
  else if (type == NAME_LAST)
    last_ = value;
  else if (type == NAME_FULL)
    SetFullName(value);
  else
    NOTREACHED();
}

string16 NameInfo::FullName() const {
  if (first_.empty())
    return string16();

  std::vector<string16> full_name;
  full_name.push_back(first_);

  if (!middle_.empty())
    full_name.push_back(middle_);

  if (!last_.empty())
    full_name.push_back(last_);

  return JoinString(full_name, ' ');
}

string16 NameInfo::MiddleInitial() const {
  if (middle_.empty())
    return string16();

  string16 middle_name(middle());
  string16 initial;
  initial.push_back(middle_name[0]);
  return initial;
}

void NameInfo::SetFullName(const string16& full) {
  // Clear the names.
  first_ = string16();
  middle_ = string16();
  last_ = string16();

  std::vector<string16> full_name_tokens;
  Tokenize(full, ASCIIToUTF16(" "), &full_name_tokens);

  // There are four possibilities: empty; first name; first and last names;
  // first, middle (possibly multiple strings) and then the last name.
  if (full_name_tokens.size() > 0) {
    first_ = full_name_tokens[0];
    if (full_name_tokens.size() > 1) {
      last_ = full_name_tokens.back();
      if (full_name_tokens.size() > 2) {
        full_name_tokens.erase(full_name_tokens.begin());
        full_name_tokens.pop_back();
        middle_ = JoinString(full_name_tokens, ' ');
      }
    }
  }
}

EmailInfo::EmailInfo() {}

EmailInfo::EmailInfo(const EmailInfo& info) : FormGroup() {
  *this = info;
}

EmailInfo::~EmailInfo() {}

EmailInfo& EmailInfo::operator=(const EmailInfo& info) {
  if (this == &info)
    return *this;

  email_ = info.email_;
  return *this;
}

void EmailInfo::GetSupportedTypes(FieldTypeSet* supported_types) const {
  supported_types->insert(EMAIL_ADDRESS);
}

string16 EmailInfo::GetInfo(AutofillFieldType type) const {
  if (type == EMAIL_ADDRESS)
    return email_;

  return string16();
}

void EmailInfo::SetInfo(AutofillFieldType type, const string16& value) {
  DCHECK_EQ(EMAIL_ADDRESS, type);
  email_ = value;
}

CompanyInfo::CompanyInfo() {}

CompanyInfo::CompanyInfo(const CompanyInfo& info) : FormGroup() {
  *this = info;
}

CompanyInfo::~CompanyInfo() {}

CompanyInfo& CompanyInfo::operator=(const CompanyInfo& info) {
  if (this == &info)
    return *this;

  company_name_ = info.company_name_;
  return *this;
}

void CompanyInfo::GetSupportedTypes(FieldTypeSet* supported_types) const {
  supported_types->insert(COMPANY_NAME);
}

string16 CompanyInfo::GetInfo(AutofillFieldType type) const {
  if (type == COMPANY_NAME)
    return company_name_;

  return string16();
}

void CompanyInfo::SetInfo(AutofillFieldType type, const string16& value) {
  DCHECK_EQ(COMPANY_NAME, type);
  company_name_ = value;
}
<|endoftext|>