<commit_before>//
// synthaway.cpp
// synthaway
//
// Copyright (c) 2012 Inkling Systems, Inc.
//
// 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 <clang/AST/ASTConsumer.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/Attr.h>
#include <clang/AST/DeclObjc.h>
#include <clang/AST/ExprObjc.h>
#include <clang/AST/Stmt.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Lex/Lexer.h>
#include <clang/Lex/Preprocessor.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>
#include <llvm/Support/CommandLine.h>
#include <set>

#pragma clang diagnostic ignored "-Wc++11-extensions"

using namespace clang;
using namespace clang::tooling;

static const char *kMoreHelpText =
  "\tSee README.markdown for details.\n"
  "\n";

class SynthesizeRemovalConsumer : public ASTConsumer {
public:
  SynthesizeRemovalConsumer(CompilerInstance &CI);
  virtual void HandleTranslationUnit(ASTContext &) override;

protected:
  void removeSynthesizeDirectives(DeclContext *DC);
  void processDeclContext(DeclContext *DC);
  void processStmt(Stmt *S, DeclContext *DC);

  CompilerInstance *compilerInstance;
  Preprocessor *preprocessor;
  Rewriter rewriter;
  ASTContext *astContext;

  std::set<ObjCPropertyImplDecl *> removeSet;
  std::set<Expr *> renameSet;

protected:
  // utility methods
  std::string loc(SourceLocation L);
  std::string range(SourceRange R);
  bool shouldIgnore(SourceLocation L);
  void renameLocation(SourceLocation L, std::string& N);
};

SynthesizeRemovalConsumer::SynthesizeRemovalConsumer(CompilerInstance &CI)
  : compilerInstance(&CI)
  , preprocessor(&CI.getPreprocessor()) {
  rewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
}

void SynthesizeRemovalConsumer::HandleTranslationUnit(ASTContext &C)
{
  if (compilerInstance->getDiagnostics().hasErrorOccurred()) {
    return;
  }

  astContext = &C;
  auto TUD = C.getTranslationUnitDecl();
  removeSynthesizeDirectives(TUD);
  processDeclContext(TUD);

  if (removeSet.empty()) {
    // nothing is removed
    llvm::errs() << "nothing to remove.\n";
    return;
  }

  SourceManager &SM = rewriter.getSourceMgr();
  FileID FID = SM.getMainFileID();
  const FileEntry* F = SM.getFileEntryForID(FID);

  // backup the source
  std::string backupFilename = std::string(F->getName()) + ".bak";
  std::string errInfo;
  llvm::raw_fd_ostream backupStream(backupFilename.c_str(), errInfo,
    llvm::sys::fs::F_Binary);
  if (!errInfo.empty()) {
    llvm::errs() << "Cannot write backup file: " << backupFilename <<
      ", error info: " << errInfo << "\n";
    return;
  }
  backupStream << SM.getBufferData(FID);
  backupStream.flush();

  // write the output
  llvm::raw_fd_ostream outStream(F->getName(), errInfo,
    llvm::sys::fs::F_Binary);
  if (!errInfo.empty()) {
    llvm::errs() << "Cannot write output file: " << F->getName() <<
      ", error info: " << errInfo << "\n";
    return;
  }

  const RewriteBuffer *RB = rewriter.getRewriteBufferFor(FID);
  RB->write(outStream);
  outStream.flush();
}

void SynthesizeRemovalConsumer::removeSynthesizeDirectives(DeclContext *DC)
{
  for(auto I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {

    // encounters @implementatian
    if (auto D = dyn_cast<ObjCImplDecl>(*I)) {

      // iterate through all the @synthesize / @dynamic directives
      for (auto PI = D->propimpl_begin(), PE = D->propimpl_end(); PI != PE;
        ++PI) {
        auto P = *PI;

        auto SR = P->getSourceRange();

        // ignore if it's already an automatic @synthesize
        if (SR.getBegin().isInvalid()) {
          continue;
        }

        // ignore @dynamic
        if (P->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) {
          continue;
        }

        // if the ivar is not declared in the place where @synthesize is
        // (i.e. it is backed by some real ivar declared in @interface),
        // don't remove it
        auto PID = P->getPropertyIvarDecl();
        if (P->getPropertyIvarDeclLoc() != PID->getLocation()) {
          continue;
        }

        // get the context in which the @property resides
        auto PD = P->getPropertyDecl();
        auto PDC = PD->getDeclContext();
        auto ID = dyn_cast<ObjCInterfaceDecl>(PDC);

        if (!ID) {
          continue;
        }

        // see if it's an @interface definition; this is false for @protocol
        // and we can only remove the synthesize decl for properties
        // declared within an @interface and not in @protocol
        if (!ID->isThisDeclarationADefinition()) {
          continue;
        }

        // check if the interface has the attribute
        // __attribute__((objc_requires_property_definitions)); if yes, the
        // directive cannot be removed
        bool attrObjCRequiresPropertyDefs = false;
        for (auto AI = ID->attr_begin(), AE = ID->attr_end();
          AI != AE; ++AI) {
          if ((*AI)->getKind() == attr::ObjCRequiresPropertyDefs) {
            attrObjCRequiresPropertyDefs = true;
            break;
          }
        }

        if (attrObjCRequiresPropertyDefs) {
          continue;
        }

        // if there is both a manual getter *and* setter, it's equivalent to
        // a @dynamic, so we have to skip it
        auto GD = D->getInstanceMethod(PD->getGetterName());
        auto SD = D->getInstanceMethod(PD->getSetterName());
        if (GD && SD) {
          continue;
        }

        // another case for read-only properties
        if (GD && PD->isReadOnly()) {
          continue;
        }

        // scan past the ; token, get the end location
        SourceLocation EL = Lexer::findLocationAfterToken(SR.getEnd(),
          tok::semi, astContext->getSourceManager(),
          astContext->getLangOpts(), false);

        // probably run into a comma (compound directive)
        if (EL.isInvalid()) {
          continue;
        }

        // if it's a sub-directive after the comma, scan from the
        // beginning of the @synthesize token
        bool isCompoundDirective = false;
        const char *BCD = astContext->getSourceManager()
          .getCharacterData(SR.getBegin());
        const char *ECD = astContext->getSourceManager()
          .getCharacterData(EL);

        while (BCD != ECD) {
          if (*BCD == ',') {
            isCompoundDirective = true;
            break;
          }
          ++BCD;
        }

        if (isCompoundDirective) {
          continue;
        }

        // check if the synthesized ivar name is not the same
        // as the property's name plus underscore
        std::string PIDN = PID->getNameAsString();
        std::string PDN = PD->getNameAsString();

        // handle the case where it's not @synthesize x = _x;
        std::string underscored = std::string("_") + PDN;
        if (PIDN != PDN) {
          if (PIDN != underscored) {
            continue;
          }
        }

        // see if the property is actually an ivar name of
        // some parent class!
        auto IF = preprocessor->getIdentifierInfo(underscored);
        if (IF) {
          auto IVDL = ID->lookupInstanceVariable(IF);
          if (IVDL && IVDL->getContainingInterface() != ID) {
            continue;
          }
        }

        // if parent class also have a property of the same name,
        // but of a different type, we can't remove it
        bool isOverridingProperty = false;
        auto S = ID->getSuperClass();
        while (S) {
          auto SP = S->FindPropertyVisibleInPrimaryClass(
            PD->getIdentifier());

          if (SP && (SP != PD)) {
            isOverridingProperty = true;
            break;
          }

          S = S->getSuperClass();
        }

        if (isOverridingProperty) {
          continue;
        }

        // do the removal: record the removed directive
        removeSet.insert(P);

        // we want to remove the entire line if it becomes empty
        Rewriter::RewriteOptions RO;
        RO.RemoveLineIfEmpty = true;

        // and remove the @synthesize
        SourceRange RSR(SR.getBegin(), EL);
        rewriter.RemoveText(RSR, RO);
      } // PI
    } // D

    // descend into the next level (namespace, etc.)
    if (auto innerDC = dyn_cast<DeclContext>(*I)) {
      removeSynthesizeDirectives(innerDC);
    }
  } // DC
}

void SynthesizeRemovalConsumer::processDeclContext(DeclContext *DC)
{
  for(auto I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
    if (auto D = dyn_cast<ObjCMethodDecl>(*I)) {
      // handle methods
      if (auto B = D->getBody()) {
        processStmt(B, D);
      }
    }
    else if (auto D = dyn_cast<BlockDecl>(*I)) {
      // handle blocks in a method; find the parent context first
      DeclContext *P = D->getParent();
      while (P) {
        if (dyn_cast<ObjCMethodDecl>(P)) {
          break;
        }
        P = P->getParent();
      }

      // only when P is a ObjCMethodDecl can me proceed
      if (P) {
        if (auto B = D->getBody()) {
          processStmt(B, P);
        }
      }
    }

    // descend into the next level (for namespace, blocks, etc.)
    if (auto innerDC = dyn_cast<DeclContext>(*I)) {
      processDeclContext(innerDC);
    }
  }
}

void SynthesizeRemovalConsumer::processStmt(Stmt *S, DeclContext *DC)
{
  if (!S) {
    return;
  }

  if (auto OPE = dyn_cast<OpaqueValueExpr>(S)) {
    // descend into an opaque expr's source exrp
    if (auto E = OPE->getSourceExpr()) {
      processStmt(E, DC);
    }
  }
  else if (auto E = dyn_cast<ObjCIvarRefExpr>(S)) {
    // handle ivar ref expressions: see if we have renamed this before
    if (renameSet.find(E) == renameSet.end()) {
      // the statement is in the method context
      auto M = dyn_cast<ObjCMethodDecl>(DC);

      // get the ivar decl of the ref expr
      auto IVD = E->getDecl();

      // get the @implementatian
      auto IMPL = dyn_cast<ObjCImplDecl>(M->getParent());

      if (M && IVD && IMPL) {
        auto PD = IMPL->FindPropertyImplIvarDecl(IVD->getIdentifier());
        bool inRemoveSet = removeSet.find(PD) != removeSet.end();
        if (PD && inRemoveSet) {
          std::string name = IVD->getNameAsString();

          // if it dosen't have the '_' prefix, rename it
          if (name.length() > 0 && name[0] != '_') {
            std::string replName = std::string("_") + name;
            renameLocation(E->getLocation(), replName);

            // and add to the rename set
            renameSet.insert(E);
          }
        }
      }
    }
  }

  for (auto I = S->child_begin(), E = S->child_end(); I != E; ++I) {
    processStmt(*I, DC);
  }
}

std::string SynthesizeRemovalConsumer::loc(SourceLocation L) {
  std::string src;
  llvm::raw_string_ostream sst(src);
  L.print(sst, astContext->getSourceManager());
  return sst.str();
}

std::string SynthesizeRemovalConsumer::range(SourceRange R) {
  std::string src;
  llvm::raw_string_ostream sst(src);
  sst << "(";
  R.getBegin().print(sst, astContext->getSourceManager());
  sst << ", ";
  R.getEnd().print(sst, astContext->getSourceManager());
  sst << ")";
  return sst.str();
}

bool SynthesizeRemovalConsumer::shouldIgnore(SourceLocation L) {
  if (!L.isValid()) {
    return true;
  }

  SourceManager &SM = astContext->getSourceManager();
  FullSourceLoc FSL(L, SM);
  const FileEntry *FE = SM.getFileEntryForID(FSL.getFileID());
  if (!FE) {
    // attempt to get the spelling location
    auto SL = SM.getSpellingLoc(L);
    if (!SL.isValid()) {
      return true;
    }

    FullSourceLoc FSL2(SL, SM);
    FE = SM.getFileEntryForID(FSL2.getFileID());
    if (!FE) {
      return true;
    }
  }

  return false;
}

void SynthesizeRemovalConsumer::renameLocation(SourceLocation L,
  std::string& N) {
  if (L.isMacroID()) {
    // TODO: emit error using diagnostics
    SourceManager &SM = astContext->getSourceManager();
    if (SM.isMacroArgExpansion(L) || SM.isInSystemMacro(L)) {
      // see if it's the macro expansion we can handle
      // e.g.
      //   #define call(x) x
      //   call(y());   // if we want to rename y()
      L = SM.getSpellingLoc(L);

      // this falls through to the rename routine below
    }
    else {
      // if the spelling location is from an actual file that we can
      // touch, then do the replacement, but show a warning
      SourceManager &SM = astContext->getSourceManager();
      auto SL = SM.getSpellingLoc(L);
      FullSourceLoc FSL(SL, SM);
      const FileEntry *FE = SM.getFileEntryForID(FSL.getFileID());
      if (FE) {
        llvm::errs() << "Warning: Rename attempted as a result of macro "
                     << "expansion may break things, at: " << loc(L) << "\n";
        L = SL;
        // this falls through to the rename routine below
      }
      else {
        // cannot handle this case
        llvm::errs() << "Error: Token is resulted from macro expansion"
          " and is therefore not renamed, at: " << loc(L) << "\n";
        return;
      }
    }
  }

  if (shouldIgnore(L)) {
    return;
  }

  auto LE = preprocessor->getLocForEndOfToken(L);
  if (LE.isValid()) {
    // getLocWithOffset returns the location *past* the token, hence -1
    auto E = LE.getLocWithOffset(-1);
    rewriter.ReplaceText(SourceRange(L, E), N);
  }
}

class SynthesizeRemovalAction : public ASTFrontendAction {
public:
    virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
      llvm::StringRef filename) {
      return new SynthesizeRemovalConsumer(CI);
    }
};

int main(int argc, const char **argv) {
  tooling::CommonOptionsParser parser(argc, argv);
  tooling::ClangTool Tool(parser.getCompilations(),
      parser.getSourcePathList());
  llvm::cl::extrahelp H(kMoreHelpText);
  return Tool.run(newFrontendActionFactory<SynthesizeRemovalAction>());
}
<commit_msg>Fix for latest llvm<commit_after>//
// synthaway.cpp
// synthaway
//
// Copyright (c) 2012 Inkling Systems, Inc.
//
// 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 <clang/AST/ASTConsumer.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/Attr.h>
#include <clang/AST/DeclObjc.h>
#include <clang/AST/ExprObjc.h>
#include <clang/AST/Stmt.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Lex/Lexer.h>
#include <clang/Lex/Preprocessor.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>
#include <llvm/Support/CommandLine.h>
#include <set>

#pragma clang diagnostic ignored "-Wc++11-extensions"

using namespace clang;
using namespace clang::tooling;

static const char *kMoreHelpText =
  "\tSee README.markdown for details.\n"
  "\n";

class SynthesizeRemovalConsumer : public ASTConsumer {
public:
  SynthesizeRemovalConsumer(CompilerInstance &CI);
  virtual void HandleTranslationUnit(ASTContext &) override;

protected:
  void removeSynthesizeDirectives(DeclContext *DC);
  void processDeclContext(DeclContext *DC);
  void processStmt(Stmt *S, DeclContext *DC);

  CompilerInstance *compilerInstance;
  Preprocessor *preprocessor;
  Rewriter rewriter;
  ASTContext *astContext;

  std::set<ObjCPropertyImplDecl *> removeSet;
  std::set<Expr *> renameSet;

protected:
  // utility methods
  std::string loc(SourceLocation L);
  std::string range(SourceRange R);
  bool shouldIgnore(SourceLocation L);
  void renameLocation(SourceLocation L, std::string& N);
};

SynthesizeRemovalConsumer::SynthesizeRemovalConsumer(CompilerInstance &CI)
  : compilerInstance(&CI)
  , preprocessor(&CI.getPreprocessor()) {
  rewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
}

void SynthesizeRemovalConsumer::HandleTranslationUnit(ASTContext &C)
{
  if (compilerInstance->getDiagnostics().hasErrorOccurred()) {
    return;
  }

  astContext = &C;
  auto TUD = C.getTranslationUnitDecl();
  removeSynthesizeDirectives(TUD);
  processDeclContext(TUD);

  if (removeSet.empty()) {
    // nothing is removed
    llvm::errs() << "nothing to remove.\n";
    return;
  }

  SourceManager &SM = rewriter.getSourceMgr();
  FileID FID = SM.getMainFileID();
  const FileEntry* F = SM.getFileEntryForID(FID);

  // backup the source
  std::string backupFilename = std::string(F->getName()) + ".bak";
  std::string errInfo;
  llvm::raw_fd_ostream backupStream(backupFilename.c_str(), errInfo,
    llvm::sys::fs::F_Binary);
  if (!errInfo.empty()) {
    llvm::errs() << "Cannot write backup file: " << backupFilename <<
      ", error info: " << errInfo << "\n";
    return;
  }
  backupStream << SM.getBufferData(FID);
  backupStream.flush();

  // write the output
  llvm::raw_fd_ostream outStream(F->getName(), errInfo,
    llvm::sys::fs::F_Binary);
  if (!errInfo.empty()) {
    llvm::errs() << "Cannot write output file: " << F->getName() <<
      ", error info: " << errInfo << "\n";
    return;
  }

  const RewriteBuffer *RB = rewriter.getRewriteBufferFor(FID);
  RB->write(outStream);
  outStream.flush();
}

void SynthesizeRemovalConsumer::removeSynthesizeDirectives(DeclContext *DC)
{
  for(auto I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {

    // encounters @implementatian
    if (auto D = dyn_cast<ObjCImplDecl>(*I)) {

      // iterate through all the @synthesize / @dynamic directives
      for (auto PI = D->propimpl_begin(), PE = D->propimpl_end(); PI != PE;
        ++PI) {
        auto P = *PI;

        auto SR = P->getSourceRange();

        // ignore if it's already an automatic @synthesize
        if (SR.getBegin().isInvalid()) {
          continue;
        }

        // ignore @dynamic
        if (P->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) {
          continue;
        }

        // if the ivar is not declared in the place where @synthesize is
        // (i.e. it is backed by some real ivar declared in @interface),
        // don't remove it
        auto PID = P->getPropertyIvarDecl();
        if (P->getPropertyIvarDeclLoc() != PID->getLocation()) {
          continue;
        }

        // get the context in which the @property resides
        auto PD = P->getPropertyDecl();
        auto PDC = PD->getDeclContext();
        auto ID = dyn_cast<ObjCInterfaceDecl>(PDC);

        if (!ID) {
          continue;
        }

        // see if it's an @interface definition; this is false for @protocol
        // and we can only remove the synthesize decl for properties
        // declared within an @interface and not in @protocol
        if (!ID->isThisDeclarationADefinition()) {
          continue;
        }

        // check if the interface has the attribute
        // __attribute__((objc_requires_property_definitions)); if yes, the
        // directive cannot be removed
        bool attrObjCRequiresPropertyDefs = false;
        for (auto AI = ID->attr_begin(), AE = ID->attr_end();
          AI != AE; ++AI) {
          if ((*AI)->getKind() == attr::ObjCRequiresPropertyDefs) {
            attrObjCRequiresPropertyDefs = true;
            break;
          }
        }

        if (attrObjCRequiresPropertyDefs) {
          continue;
        }

        // if there is both a manual getter *and* setter, it's equivalent to
        // a @dynamic, so we have to skip it
        auto GD = D->getInstanceMethod(PD->getGetterName());
        auto SD = D->getInstanceMethod(PD->getSetterName());
        if (GD && SD) {
          continue;
        }

        // another case for read-only properties
        if (GD && PD->isReadOnly()) {
          continue;
        }

        // scan past the ; token, get the end location
        SourceLocation EL = Lexer::findLocationAfterToken(SR.getEnd(),
          tok::semi, astContext->getSourceManager(),
          astContext->getLangOpts(), false);

        // probably run into a comma (compound directive)
        if (EL.isInvalid()) {
          continue;
        }

        // if it's a sub-directive after the comma, scan from the
        // beginning of the @synthesize token
        bool isCompoundDirective = false;
        const char *BCD = astContext->getSourceManager()
          .getCharacterData(SR.getBegin());
        const char *ECD = astContext->getSourceManager()
          .getCharacterData(EL);

        while (BCD != ECD) {
          if (*BCD == ',') {
            isCompoundDirective = true;
            break;
          }
          ++BCD;
        }

        if (isCompoundDirective) {
          continue;
        }

        // check if the synthesized ivar name is not the same
        // as the property's name plus underscore
        std::string PIDN = PID->getNameAsString();
        std::string PDN = PD->getNameAsString();

        // handle the case where it's not @synthesize x = _x;
        std::string underscored = std::string("_") + PDN;
        if (PIDN != PDN) {
          if (PIDN != underscored) {
            continue;
          }
        }

        // see if the property is actually an ivar name of
        // some parent class!
        auto IF = preprocessor->getIdentifierInfo(underscored);
        if (IF) {
          auto IVDL = ID->lookupInstanceVariable(IF);
          if (IVDL && IVDL->getContainingInterface() != ID) {
            continue;
          }
        }

        // if parent class also have a property of the same name,
        // but of a different type, we can't remove it
        bool isOverridingProperty = false;
        auto S = ID->getSuperClass();
        while (S) {
          auto SP = S->FindPropertyVisibleInPrimaryClass(
            PD->getIdentifier());

          if (SP && (SP != PD)) {
            isOverridingProperty = true;
            break;
          }

          S = S->getSuperClass();
        }

        if (isOverridingProperty) {
          continue;
        }

        // do the removal: record the removed directive
        removeSet.insert(P);

        // we want to remove the entire line if it becomes empty
        Rewriter::RewriteOptions RO;
        RO.RemoveLineIfEmpty = true;

        // and remove the @synthesize
        SourceRange RSR(SR.getBegin(), EL);
        rewriter.RemoveText(RSR, RO);
      } // PI
    } // D

    // descend into the next level (namespace, etc.)
    if (auto innerDC = dyn_cast<DeclContext>(*I)) {
      removeSynthesizeDirectives(innerDC);
    }
  } // DC
}

void SynthesizeRemovalConsumer::processDeclContext(DeclContext *DC)
{
  for(auto I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
    if (auto D = dyn_cast<ObjCMethodDecl>(*I)) {
      // handle methods
      if (auto B = D->getBody()) {
        processStmt(B, D);
      }
    }
    else if (auto D = dyn_cast<BlockDecl>(*I)) {
      // handle blocks in a method; find the parent context first
      DeclContext *P = D->getParent();
      while (P) {
        if (dyn_cast<ObjCMethodDecl>(P)) {
          break;
        }
        P = P->getParent();
      }

      // only when P is a ObjCMethodDecl can me proceed
      if (P) {
        if (auto B = D->getBody()) {
          processStmt(B, P);
        }
      }
    }

    // descend into the next level (for namespace, blocks, etc.)
    if (auto innerDC = dyn_cast<DeclContext>(*I)) {
      processDeclContext(innerDC);
    }
  }
}

void SynthesizeRemovalConsumer::processStmt(Stmt *S, DeclContext *DC)
{
  if (!S) {
    return;
  }

  if (auto OPE = dyn_cast<OpaqueValueExpr>(S)) {
    // descend into an opaque expr's source exrp
    if (auto E = OPE->getSourceExpr()) {
      processStmt(E, DC);
    }
  }
  else if (auto E = dyn_cast<ObjCIvarRefExpr>(S)) {
    // handle ivar ref expressions: see if we have renamed this before
    if (renameSet.find(E) == renameSet.end()) {
      // the statement is in the method context
      auto M = dyn_cast<ObjCMethodDecl>(DC);

      // get the ivar decl of the ref expr
      auto IVD = E->getDecl();

      // get the @implementatian
      auto IMPL = dyn_cast<ObjCImplDecl>(M->getParent());

      if (M && IVD && IMPL) {
        auto PD = IMPL->FindPropertyImplIvarDecl(IVD->getIdentifier());
        bool inRemoveSet = removeSet.find(PD) != removeSet.end();
        if (PD && inRemoveSet) {
          std::string name = IVD->getNameAsString();

          // if it dosen't have the '_' prefix, rename it
          if (name.length() > 0 && name[0] != '_') {
            std::string replName = std::string("_") + name;
            renameLocation(E->getLocation(), replName);

            // and add to the rename set
            renameSet.insert(E);
          }
        }
      }
    }
  }

  for (auto I = S->child_begin(), E = S->child_end(); I != E; ++I) {
    processStmt(*I, DC);
  }
}

std::string SynthesizeRemovalConsumer::loc(SourceLocation L) {
  std::string src;
  llvm::raw_string_ostream sst(src);
  L.print(sst, astContext->getSourceManager());
  return sst.str();
}

std::string SynthesizeRemovalConsumer::range(SourceRange R) {
  std::string src;
  llvm::raw_string_ostream sst(src);
  sst << "(";
  R.getBegin().print(sst, astContext->getSourceManager());
  sst << ", ";
  R.getEnd().print(sst, astContext->getSourceManager());
  sst << ")";
  return sst.str();
}

bool SynthesizeRemovalConsumer::shouldIgnore(SourceLocation L) {
  if (!L.isValid()) {
    return true;
  }

  SourceManager &SM = astContext->getSourceManager();
  FullSourceLoc FSL(L, SM);
  const FileEntry *FE = SM.getFileEntryForID(FSL.getFileID());
  if (!FE) {
    // attempt to get the spelling location
    auto SL = SM.getSpellingLoc(L);
    if (!SL.isValid()) {
      return true;
    }

    FullSourceLoc FSL2(SL, SM);
    FE = SM.getFileEntryForID(FSL2.getFileID());
    if (!FE) {
      return true;
    }
  }

  return false;
}

void SynthesizeRemovalConsumer::renameLocation(SourceLocation L,
  std::string& N) {
  if (L.isMacroID()) {
    // TODO: emit error using diagnostics
    SourceManager &SM = astContext->getSourceManager();
    if (SM.isMacroArgExpansion(L) || SM.isInSystemMacro(L)) {
      // see if it's the macro expansion we can handle
      // e.g.
      //   #define call(x) x
      //   call(y());   // if we want to rename y()
      L = SM.getSpellingLoc(L);

      // this falls through to the rename routine below
    }
    else {
      // if the spelling location is from an actual file that we can
      // touch, then do the replacement, but show a warning
      SourceManager &SM = astContext->getSourceManager();
      auto SL = SM.getSpellingLoc(L);
      FullSourceLoc FSL(SL, SM);
      const FileEntry *FE = SM.getFileEntryForID(FSL.getFileID());
      if (FE) {
        llvm::errs() << "Warning: Rename attempted as a result of macro "
                     << "expansion may break things, at: " << loc(L) << "\n";
        L = SL;
        // this falls through to the rename routine below
      }
      else {
        // cannot handle this case
        llvm::errs() << "Error: Token is resulted from macro expansion"
          " and is therefore not renamed, at: " << loc(L) << "\n";
        return;
      }
    }
  }

  if (shouldIgnore(L)) {
    return;
  }

  auto LE = preprocessor->getLocForEndOfToken(L);
  if (LE.isValid()) {
    // getLocWithOffset returns the location *past* the token, hence -1
    auto E = LE.getLocWithOffset(-1);
    rewriter.ReplaceText(SourceRange(L, E), N);
  }
}

class SynthesizeRemovalAction : public ASTFrontendAction {
public:
    virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
      llvm::StringRef filename) {
      return new SynthesizeRemovalConsumer(CI);
    }
};

int main(int argc, const char **argv) {
  static llvm::cl::OptionCategory ToolOptions("Tool for removing synthesization from objective-c files");

  tooling::CommonOptionsParser parser(argc, argv, ToolOptions);
  tooling::ClangTool Tool(parser.getCompilations(),
      parser.getSourcePathList());
  llvm::cl::extrahelp H(kMoreHelpText);
  return Tool.run(newFrontendActionFactory<SynthesizeRemovalAction>());
}
<|endoftext|>


<commit_before>  namespace spl
  {
    // =====================================================================
    template<typename E>
    template<unsigned dim>
    NDSignal<E>::NDSignal(const Domain<dim> dom)
    : _domain(dom)
    , _contiguous_data(nullptr, std::default_delete<traits_value_type(E)[]>())
    {
      for(unsigned i=0; i < traits_domain_dim(E); ++i)
        if(_domain[i] == 0)
          throw_logic("Signal data l-formed");
      _contiguous_data.reset(new traits_value_type(E)[dom.prod()],
                             std::default_delete<traits_value_type(E)[]>());
    }

    // =====================================================================
    template<typename E>
    template<unsigned dim, typename ... Args>
    NDSignal<E>::NDSignal(const Domain<dim> dom, Args ... args)
    : _domain(dom)
    , _contiguous_data(nullptr, std::default_delete<traits_value_type(E)[]>())
    {
      for(unsigned i=0; i < traits_domain_dim(E); ++i)
        if(_domain[i] == 0)
          throw_logic("Signal data l-formed");
      std::allocator<traits_value_type(E)> a;
      auto p = a.allocate(dom.prod());
      a.construct(p, args...); // Make this more feneric (ie : args[0] and recursive call...)
      _contiguous_data.reset(p, std::default_delete<traits_value_type(E)>());// TODO: understand why it does not require [] delete (Valgrind might be fooled)
    }

  }//!spl
<commit_msg>Fix new placement issue<commit_after>  namespace spl
  {
    // =====================================================================
    template<typename E>
    template<unsigned dim>
    NDSignal<E>::NDSignal(const Domain<dim> dom)
    : _domain(dom)
    , _contiguous_data(nullptr, std::default_delete<traits_value_type(E)[]>())
    {
      for(unsigned i=0; i < traits_domain_dim(E); ++i)
        if(_domain[i] == 0)
          throw_logic("Signal data l-formed");
      _contiguous_data.reset(new traits_value_type(E)[dom.prod()],
                             std::default_delete<traits_value_type(E)[]>());
    }

    // =====================================================================
    template<typename E>
    template<unsigned dim, typename ... Args>
    NDSignal<E>::NDSignal(const Domain<dim> dom, Args ... args)
    : _domain(dom)
    , _contiguous_data(nullptr, std::default_delete<traits_value_type(E)[]>())
    {
      for(unsigned i=0; i < traits_domain_dim(E); ++i)
        if(_domain[i] == 0)
          throw_logic("Signal data l-formed");

      //std::allocator<traits_value_type(E)> a;
      //auto p = a.allocate(dom.prod());
      //a.construct(p, args...); // Make this more feneric (ie : args[0] and recursive call...)
      auto *p = new char[dom.prod()*sizeof(traits_value_type(E))];
      _contiguous_data.reset((traits_value_type(E)*)p,
                             std::default_delete<traits_value_type(E)>());// TODO: understand why it does not require [] delete (Valgrind might be fooled)
      for(size_t e=0; e < dom.prod(); ++e)
      {
        new(p) traits_value_type(E)(args...);
        p+= sizeof(traits_value_type(E));
      }
    }

  }//!spl
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tp_3D_SceneGeometry.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-03 13:39:11 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include "tp_3D_SceneGeometry.hxx"
#include "tp_3D_SceneGeometry.hrc"
#include "ResId.hxx"
#include "NoWarningThisInCTOR.hxx"
#include "BaseGFXHelper.hxx"
#include "macros.hxx"
#include "DiagramHelper.hxx"
#include "ChartTypeHelper.hxx"
#include "ThreeDHelper.hxx"

#ifndef _BGFX_NUMERIC_FTOOLS_HXX
#include <basegfx/numeric/ftools.hxx>
#endif

#ifndef INCLUDED_RTL_MATH_HXX
#include <rtl/math.hxx>
#endif

#ifndef _SVX_UNOPRNMS_HXX
#include <svx/unoprnms.hxx>
#endif

#ifndef _COM_SUN_STAR_DRAWING_PROJECTIONMODE_HPP_
#include <com/sun/star/drawing/ProjectionMode.hpp>
#endif

//.............................................................................
namespace chart
{
//.............................................................................

using namespace ::com::sun::star;
//using namespace ::com::sun::star::chart2;

namespace
{

void lcl_shiftAngleToValidRange( double& rfAngleDegree )
{
    //valid range:  ]-180,180]
    while( rfAngleDegree<=-180.0 )
        rfAngleDegree+=360.0;
    while( rfAngleDegree>180.0 )
        rfAngleDegree-=360.0;
}

void lcl_SetMetricFieldLimits( MetricField& rField, sal_Int64 nLimit )
{
    rField.SetMin(-1*nLimit);
    rField.SetFirst(-1*nLimit);
    rField.SetMax(nLimit);
    rField.SetLast(nLimit);
}

double lcl_CameraDistanceToPerspective( double fCameraDistance )
{
    double fRet = fCameraDistance;
    double fMin, fMax;
    ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    //fMax <-> 0; fMin <->100
    //a/x + b = y
    double a = 100.0*fMax*fMin/(fMax-fMin);
    double b = -a/fMax;

    fRet = a/fCameraDistance + b;

    return fRet;
}
double lcl_PerspectiveToCameraDistance( double fPerspective )
{
    double fRet = fPerspective;
    double fMin, fMax;
    ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    //fMax <-> 0; fMin <->100
    //a/x + b = y
    double a = 100.0*fMax*fMin/(fMax-fMin);
    double b = -a/fMax;

    fRet = a/(fPerspective - b);

    return fRet;
}

}
ThreeD_SceneGeometry_TabPage::ThreeD_SceneGeometry_TabPage( Window* pWindow
                , const uno::Reference< beans::XPropertySet > & xSceneProperties
                , ControllerLockHelper & rControllerLockHelper )
                : TabPage       ( pWindow, SchResId( TP_3D_SCENEGEOMETRY ) )
                , m_xSceneProperties( xSceneProperties )
                , m_aCbxRightAngledAxes( this, SchResId( CBX_RIGHT_ANGLED_AXES ) )
                , m_aFtXRotation    ( this, SchResId( FT_X_ROTATION ) )
                , m_aMFXRotation    ( this, SchResId( MTR_FLD_X_ROTATION ) )
                , m_aFtYRotation    ( this, SchResId( FT_Y_ROTATION ) )
                , m_aMFYRotation    ( this, SchResId( MTR_FLD_Y_ROTATION ) )
                , m_aFtZRotation    ( this, SchResId( FT_Z_ROTATION ) )
                , m_aMFZRotation    ( this, SchResId( MTR_FLD_Z_ROTATION ) )
                , m_aCbxPerspective ( this, SchResId( CBX_PERSPECTIVE ) )
                , m_aMFPerspective  ( this, SchResId( MTR_FLD_PERSPECTIVE ) )
                , m_nXRotation(0)
                , m_nYRotation(0)
                , m_nZRotation(0)
                , m_bAngleChangePending( false )
                , m_bPerspectiveChangePending( false )
                , m_rControllerLockHelper( rControllerLockHelper )
{
    FreeResource();

    double fXAngle, fYAngle, fZAngle;
    ThreeDHelper::getRotationAngleFromDiagram( m_xSceneProperties, fXAngle, fYAngle, fZAngle );

    fXAngle = BaseGFXHelper::Rad2Deg( fXAngle );
    fYAngle = BaseGFXHelper::Rad2Deg( fYAngle );
    fZAngle = BaseGFXHelper::Rad2Deg( fZAngle );

    lcl_shiftAngleToValidRange( fXAngle );
    lcl_shiftAngleToValidRange( fYAngle );
    lcl_shiftAngleToValidRange( fZAngle );

    DBG_ASSERT( fZAngle>=-90 && fZAngle<=90, "z angle is out of valid range" );

    lcl_SetMetricFieldLimits( m_aMFZRotation, 90 );

    m_nXRotation = ::basegfx::fround(fXAngle*pow(10.0,m_aMFXRotation.GetDecimalDigits()));
    m_nYRotation = ::basegfx::fround(-1.0*fYAngle*pow(10.0,m_aMFYRotation.GetDecimalDigits()));
    m_nZRotation = ::basegfx::fround(-1.0*fZAngle*pow(10.0,m_aMFZRotation.GetDecimalDigits()));

    m_aMFXRotation.SetValue(m_nXRotation);
    m_aMFYRotation.SetValue(m_nYRotation);
    m_aMFZRotation.SetValue(m_nZRotation);

    const ULONG nTimeout = 4*EDIT_UPDATEDATA_TIMEOUT;
    Link aAngleChangedLink( LINK( this, ThreeD_SceneGeometry_TabPage, AngleChanged ));
    Link aAngleEditedLink( LINK( this, ThreeD_SceneGeometry_TabPage, AngleEdited ));

    m_aMFXRotation.EnableUpdateData( nTimeout );
    m_aMFXRotation.SetUpdateDataHdl( aAngleChangedLink );
    m_aMFXRotation.SetModifyHdl( aAngleEditedLink );

    m_aMFYRotation.EnableUpdateData( nTimeout );
    m_aMFYRotation.SetUpdateDataHdl( aAngleChangedLink );
    m_aMFYRotation.SetModifyHdl( aAngleEditedLink );

    m_aMFZRotation.EnableUpdateData( nTimeout );
    m_aMFZRotation.SetUpdateDataHdl( aAngleChangedLink );
    m_aMFZRotation.SetModifyHdl( aAngleEditedLink );

    drawing::ProjectionMode aProjectionMode = drawing::ProjectionMode_PERSPECTIVE;
    m_xSceneProperties->getPropertyValue( C2U("D3DScenePerspective")) >>= aProjectionMode;
    m_aCbxPerspective.Check( aProjectionMode == drawing::ProjectionMode_PERSPECTIVE );
    m_aCbxPerspective.SetToggleHdl( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveToggled ));

    m_aMFPerspective.SetValue( ::basegfx::fround( lcl_CameraDistanceToPerspective(
        ThreeDHelper::getCameraDistance( m_xSceneProperties ) ) ) );

    m_aMFPerspective.EnableUpdateData( nTimeout );
    m_aMFPerspective.SetUpdateDataHdl( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveChanged ) );
    m_aMFPerspective.SetModifyHdl( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveEdited ) );
    m_aMFPerspective.Enable( m_aCbxPerspective.IsChecked() );

    //RightAngledAxes
    sal_Bool bRightAngledAxes = false;

    uno::Reference< chart2::XDiagram > xDiagram( m_xSceneProperties, uno::UNO_QUERY );
    if( ChartTypeHelper::isSupportingRightAngledAxes(
            DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
    {
        m_xSceneProperties->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes;
        m_aCbxRightAngledAxes.SetToggleHdl( LINK( this, ThreeD_SceneGeometry_TabPage, RightAngledAxesToggled ));
        m_aCbxRightAngledAxes.Check( bRightAngledAxes );
    }
    else
    {
        m_aCbxRightAngledAxes.Enable(false);
    }
}

ThreeD_SceneGeometry_TabPage::~ThreeD_SceneGeometry_TabPage()
{
}

void ThreeD_SceneGeometry_TabPage::commitPendingChanges()
{
    ControllerLockHelperGuard aGuard( m_rControllerLockHelper );

    if( m_bAngleChangePending )
        applyAnglesToModel();
    if( m_bPerspectiveChangePending )
        applyPerspectiveToModel();
}

void ThreeD_SceneGeometry_TabPage::applyAnglesToModel()
{
    ControllerLockHelperGuard aGuard( m_rControllerLockHelper );

    double fXAngle = 0.0, fYAngle = 0.0, fZAngle = 0.0;

    if( !m_aMFZRotation.IsEmptyFieldValue() )
        m_nZRotation = m_aMFZRotation.GetValue();

    fXAngle = double(m_nXRotation)/double(pow(10.0,m_aMFXRotation.GetDecimalDigits()));
    fYAngle = double(-1.0*m_nYRotation)/double(pow(10.0,m_aMFYRotation.GetDecimalDigits()));
    fZAngle = double(-1.0*m_nZRotation)/double(pow(10.0,m_aMFZRotation.GetDecimalDigits()));

    fXAngle = BaseGFXHelper::Deg2Rad( fXAngle );
    fYAngle = BaseGFXHelper::Deg2Rad( fYAngle );
    fZAngle = BaseGFXHelper::Deg2Rad( fZAngle );

    ThreeDHelper::setRotationAngleToDiagram( m_xSceneProperties, fXAngle, fYAngle, fZAngle );

    m_bAngleChangePending = false;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, AngleEdited, void*, EMPTYARG )
{
    m_nXRotation = m_aMFXRotation.GetValue();
    m_nYRotation = m_aMFYRotation.GetValue();

    m_bAngleChangePending = true;
    return 0;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, AngleChanged, void*, EMPTYARG )
{
    applyAnglesToModel();
    return 0;
}

void ThreeD_SceneGeometry_TabPage::applyPerspectiveToModel()
{
    ControllerLockHelperGuard aGuard( m_rControllerLockHelper );

    drawing::ProjectionMode aMode = m_aCbxPerspective.IsChecked()
        ? drawing::ProjectionMode_PERSPECTIVE
        : drawing::ProjectionMode_PARALLEL;

    try
    {
        m_xSceneProperties->setPropertyValue( C2U("D3DScenePerspective"), uno::makeAny( aMode ));

        ThreeDHelper::setCameraDistance( m_xSceneProperties
            , lcl_PerspectiveToCameraDistance( m_aMFPerspective.GetValue() ) );
    }
    catch( const uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }

    m_bPerspectiveChangePending = false;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, PerspectiveEdited, void*, EMPTYARG )
{
    m_bPerspectiveChangePending = true;
    return 0;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, PerspectiveChanged, void*, EMPTYARG )
{
    applyPerspectiveToModel();
    return 0;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, PerspectiveToggled, void*, EMPTYARG )
{
    m_aMFPerspective.Enable( m_aCbxPerspective.IsChecked() );
    applyPerspectiveToModel();
    return 0;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, RightAngledAxesToggled, void*, EMPTYARG )
{
    ControllerLockHelperGuard aGuard( m_rControllerLockHelper );

    bool bEnableZ = !m_aCbxRightAngledAxes.IsChecked();
    m_aFtZRotation.Enable( bEnableZ );
    m_aMFZRotation.Enable( bEnableZ );
    m_aMFZRotation.EnableEmptyFieldValue( !bEnableZ );
    if( !bEnableZ )
    {
        m_nXRotation = m_aMFXRotation.GetValue();
        m_nYRotation = m_aMFYRotation.GetValue();
        m_nZRotation = m_aMFZRotation.GetValue();

        m_aMFXRotation.SetValue(ThreeDHelper::getValueClippedToRange(m_nXRotation, ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes() ));
        m_aMFYRotation.SetValue(ThreeDHelper::getValueClippedToRange(m_nYRotation, ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes() ));
        m_aMFZRotation.SetEmptyFieldValue();

        lcl_SetMetricFieldLimits( m_aMFXRotation, ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes() );
        lcl_SetMetricFieldLimits( m_aMFYRotation, ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes() );
    }
    else
    {
        lcl_SetMetricFieldLimits( m_aMFXRotation, 180 );
        lcl_SetMetricFieldLimits( m_aMFYRotation, 180 );

        m_aMFXRotation.SetValue(m_nXRotation);
        m_aMFYRotation.SetValue(m_nYRotation);
        m_aMFZRotation.SetValue(m_nZRotation);
    }

    ThreeDHelper::switchRightAngledAxes( m_xSceneProperties, m_aCbxRightAngledAxes.IsChecked(), true /*bRotateLights*/ );

    return 0;
}

//.............................................................................
} //namespace chart
//.............................................................................
<commit_msg>INTEGRATION: CWS chart07 (1.3.4); FILE MERGED 2007/07/11 15:48:28 bm 1.3.4.3: #i69281# warnings removed 2007/07/11 14:49:19 bm 1.3.4.2: #i69281# warnings removed 2007/07/10 11:57:28 bm 1.3.4.1: #i69281# warnings removed<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tp_3D_SceneGeometry.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-25 08:35:45 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include "tp_3D_SceneGeometry.hxx"
#include "tp_3D_SceneGeometry.hrc"
#include "ResId.hxx"
#include "NoWarningThisInCTOR.hxx"
#include "BaseGFXHelper.hxx"
#include "macros.hxx"
#include "DiagramHelper.hxx"
#include "ChartTypeHelper.hxx"
#include "ThreeDHelper.hxx"

#ifndef _BGFX_NUMERIC_FTOOLS_HXX
#include <basegfx/numeric/ftools.hxx>
#endif

#ifndef INCLUDED_RTL_MATH_HXX
#include <rtl/math.hxx>
#endif

#ifndef _SVX_UNOPRNMS_HXX
#include <svx/unoprnms.hxx>
#endif

#ifndef _COM_SUN_STAR_DRAWING_PROJECTIONMODE_HPP_
#include <com/sun/star/drawing/ProjectionMode.hpp>
#endif

//.............................................................................
namespace chart
{
//.............................................................................

using namespace ::com::sun::star;
//using namespace ::com::sun::star::chart2;

namespace
{

void lcl_shiftAngleToValidRange( double& rfAngleDegree )
{
    //valid range:  ]-180,180]
    while( rfAngleDegree<=-180.0 )
        rfAngleDegree+=360.0;
    while( rfAngleDegree>180.0 )
        rfAngleDegree-=360.0;
}

void lcl_SetMetricFieldLimits( MetricField& rField, sal_Int64 nLimit )
{
    rField.SetMin(-1*nLimit);
    rField.SetFirst(-1*nLimit);
    rField.SetMax(nLimit);
    rField.SetLast(nLimit);
}

double lcl_CameraDistanceToPerspective( double fCameraDistance )
{
    double fRet = fCameraDistance;
    double fMin, fMax;
    ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    //fMax <-> 0; fMin <->100
    //a/x + b = y
    double a = 100.0*fMax*fMin/(fMax-fMin);
    double b = -a/fMax;

    fRet = a/fCameraDistance + b;

    return fRet;
}
double lcl_PerspectiveToCameraDistance( double fPerspective )
{
    double fRet = fPerspective;
    double fMin, fMax;
    ThreeDHelper::getCameraDistanceRange( fMin, fMax );
    //fMax <-> 0; fMin <->100
    //a/x + b = y
    double a = 100.0*fMax*fMin/(fMax-fMin);
    double b = -a/fMax;

    fRet = a/(fPerspective - b);

    return fRet;
}

}
ThreeD_SceneGeometry_TabPage::ThreeD_SceneGeometry_TabPage( Window* pWindow
                , const uno::Reference< beans::XPropertySet > & xSceneProperties
                , ControllerLockHelper & rControllerLockHelper )
                : TabPage       ( pWindow, SchResId( TP_3D_SCENEGEOMETRY ) )
                , m_xSceneProperties( xSceneProperties )
                , m_aCbxRightAngledAxes( this, SchResId( CBX_RIGHT_ANGLED_AXES ) )
                , m_aFtXRotation    ( this, SchResId( FT_X_ROTATION ) )
                , m_aMFXRotation    ( this, SchResId( MTR_FLD_X_ROTATION ) )
                , m_aFtYRotation    ( this, SchResId( FT_Y_ROTATION ) )
                , m_aMFYRotation    ( this, SchResId( MTR_FLD_Y_ROTATION ) )
                , m_aFtZRotation    ( this, SchResId( FT_Z_ROTATION ) )
                , m_aMFZRotation    ( this, SchResId( MTR_FLD_Z_ROTATION ) )
                , m_aCbxPerspective ( this, SchResId( CBX_PERSPECTIVE ) )
                , m_aMFPerspective  ( this, SchResId( MTR_FLD_PERSPECTIVE ) )
                , m_nXRotation(0)
                , m_nYRotation(0)
                , m_nZRotation(0)
                , m_bAngleChangePending( false )
                , m_bPerspectiveChangePending( false )
                , m_rControllerLockHelper( rControllerLockHelper )
{
    FreeResource();

    double fXAngle, fYAngle, fZAngle;
    ThreeDHelper::getRotationAngleFromDiagram( m_xSceneProperties, fXAngle, fYAngle, fZAngle );

    fXAngle = BaseGFXHelper::Rad2Deg( fXAngle );
    fYAngle = BaseGFXHelper::Rad2Deg( fYAngle );
    fZAngle = BaseGFXHelper::Rad2Deg( fZAngle );

    lcl_shiftAngleToValidRange( fXAngle );
    lcl_shiftAngleToValidRange( fYAngle );
    lcl_shiftAngleToValidRange( fZAngle );

    DBG_ASSERT( fZAngle>=-90 && fZAngle<=90, "z angle is out of valid range" );

    lcl_SetMetricFieldLimits( m_aMFZRotation, 90 );

    m_nXRotation = ::basegfx::fround(fXAngle*pow(10.0,m_aMFXRotation.GetDecimalDigits()));
    m_nYRotation = ::basegfx::fround(-1.0*fYAngle*pow(10.0,m_aMFYRotation.GetDecimalDigits()));
    m_nZRotation = ::basegfx::fround(-1.0*fZAngle*pow(10.0,m_aMFZRotation.GetDecimalDigits()));

    m_aMFXRotation.SetValue(m_nXRotation);
    m_aMFYRotation.SetValue(m_nYRotation);
    m_aMFZRotation.SetValue(m_nZRotation);

    const ULONG nTimeout = 4*EDIT_UPDATEDATA_TIMEOUT;
    Link aAngleChangedLink( LINK( this, ThreeD_SceneGeometry_TabPage, AngleChanged ));
    Link aAngleEditedLink( LINK( this, ThreeD_SceneGeometry_TabPage, AngleEdited ));

    m_aMFXRotation.EnableUpdateData( nTimeout );
    m_aMFXRotation.SetUpdateDataHdl( aAngleChangedLink );
    m_aMFXRotation.SetModifyHdl( aAngleEditedLink );

    m_aMFYRotation.EnableUpdateData( nTimeout );
    m_aMFYRotation.SetUpdateDataHdl( aAngleChangedLink );
    m_aMFYRotation.SetModifyHdl( aAngleEditedLink );

    m_aMFZRotation.EnableUpdateData( nTimeout );
    m_aMFZRotation.SetUpdateDataHdl( aAngleChangedLink );
    m_aMFZRotation.SetModifyHdl( aAngleEditedLink );

    drawing::ProjectionMode aProjectionMode = drawing::ProjectionMode_PERSPECTIVE;
    m_xSceneProperties->getPropertyValue( C2U("D3DScenePerspective")) >>= aProjectionMode;
    m_aCbxPerspective.Check( aProjectionMode == drawing::ProjectionMode_PERSPECTIVE );
    m_aCbxPerspective.SetToggleHdl( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveToggled ));

    m_aMFPerspective.SetValue( ::basegfx::fround( lcl_CameraDistanceToPerspective(
        ThreeDHelper::getCameraDistance( m_xSceneProperties ) ) ) );

    m_aMFPerspective.EnableUpdateData( nTimeout );
    m_aMFPerspective.SetUpdateDataHdl( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveChanged ) );
    m_aMFPerspective.SetModifyHdl( LINK( this, ThreeD_SceneGeometry_TabPage, PerspectiveEdited ) );
    m_aMFPerspective.Enable( m_aCbxPerspective.IsChecked() );

    //RightAngledAxes
    sal_Bool bRightAngledAxes = false;

    uno::Reference< chart2::XDiagram > xDiagram( m_xSceneProperties, uno::UNO_QUERY );
    if( ChartTypeHelper::isSupportingRightAngledAxes(
            DiagramHelper::getChartTypeByIndex( xDiagram, 0 ) ) )
    {
        m_xSceneProperties->getPropertyValue( C2U("RightAngledAxes")) >>= bRightAngledAxes;
        m_aCbxRightAngledAxes.SetToggleHdl( LINK( this, ThreeD_SceneGeometry_TabPage, RightAngledAxesToggled ));
        m_aCbxRightAngledAxes.Check( bRightAngledAxes );
    }
    else
    {
        m_aCbxRightAngledAxes.Enable(false);
    }
}

ThreeD_SceneGeometry_TabPage::~ThreeD_SceneGeometry_TabPage()
{
}

void ThreeD_SceneGeometry_TabPage::commitPendingChanges()
{
    ControllerLockHelperGuard aGuard( m_rControllerLockHelper );

    if( m_bAngleChangePending )
        applyAnglesToModel();
    if( m_bPerspectiveChangePending )
        applyPerspectiveToModel();
}

void ThreeD_SceneGeometry_TabPage::applyAnglesToModel()
{
    ControllerLockHelperGuard aGuard( m_rControllerLockHelper );

    double fXAngle = 0.0, fYAngle = 0.0, fZAngle = 0.0;

    if( !m_aMFZRotation.IsEmptyFieldValue() )
        m_nZRotation = m_aMFZRotation.GetValue();

    fXAngle = double(m_nXRotation)/double(pow(10.0,m_aMFXRotation.GetDecimalDigits()));
    fYAngle = double(-1.0*m_nYRotation)/double(pow(10.0,m_aMFYRotation.GetDecimalDigits()));
    fZAngle = double(-1.0*m_nZRotation)/double(pow(10.0,m_aMFZRotation.GetDecimalDigits()));

    fXAngle = BaseGFXHelper::Deg2Rad( fXAngle );
    fYAngle = BaseGFXHelper::Deg2Rad( fYAngle );
    fZAngle = BaseGFXHelper::Deg2Rad( fZAngle );

    ThreeDHelper::setRotationAngleToDiagram( m_xSceneProperties, fXAngle, fYAngle, fZAngle );

    m_bAngleChangePending = false;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, AngleEdited, void*, EMPTYARG )
{
    m_nXRotation = m_aMFXRotation.GetValue();
    m_nYRotation = m_aMFYRotation.GetValue();

    m_bAngleChangePending = true;
    return 0;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, AngleChanged, void*, EMPTYARG )
{
    applyAnglesToModel();
    return 0;
}

void ThreeD_SceneGeometry_TabPage::applyPerspectiveToModel()
{
    ControllerLockHelperGuard aGuard( m_rControllerLockHelper );

    drawing::ProjectionMode aMode = m_aCbxPerspective.IsChecked()
        ? drawing::ProjectionMode_PERSPECTIVE
        : drawing::ProjectionMode_PARALLEL;

    try
    {
        m_xSceneProperties->setPropertyValue( C2U("D3DScenePerspective"), uno::makeAny( aMode ));

        ThreeDHelper::setCameraDistance( m_xSceneProperties
            , lcl_PerspectiveToCameraDistance( (double)m_aMFPerspective.GetValue() ) );
    }
    catch( const uno::Exception & ex )
    {
        ASSERT_EXCEPTION( ex );
    }

    m_bPerspectiveChangePending = false;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, PerspectiveEdited, void*, EMPTYARG )
{
    m_bPerspectiveChangePending = true;
    return 0;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, PerspectiveChanged, void*, EMPTYARG )
{
    applyPerspectiveToModel();
    return 0;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, PerspectiveToggled, void*, EMPTYARG )
{
    m_aMFPerspective.Enable( m_aCbxPerspective.IsChecked() );
    applyPerspectiveToModel();
    return 0;
}

IMPL_LINK( ThreeD_SceneGeometry_TabPage, RightAngledAxesToggled, void*, EMPTYARG )
{
    ControllerLockHelperGuard aGuard( m_rControllerLockHelper );

    bool bEnableZ = !m_aCbxRightAngledAxes.IsChecked();
    m_aFtZRotation.Enable( bEnableZ );
    m_aMFZRotation.Enable( bEnableZ );
    m_aMFZRotation.EnableEmptyFieldValue( !bEnableZ );
    if( !bEnableZ )
    {
        m_nXRotation = m_aMFXRotation.GetValue();
        m_nYRotation = m_aMFYRotation.GetValue();
        m_nZRotation = m_aMFZRotation.GetValue();

        m_aMFXRotation.SetValue(static_cast<sal_Int64>(ThreeDHelper::getValueClippedToRange(static_cast<double>(m_nXRotation), ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes())));
        m_aMFYRotation.SetValue(static_cast<sal_Int64>(ThreeDHelper::getValueClippedToRange(static_cast<double>(m_nYRotation), ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes())));
        m_aMFZRotation.SetEmptyFieldValue();

        lcl_SetMetricFieldLimits( m_aMFXRotation, static_cast<sal_Int64>(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()));
        lcl_SetMetricFieldLimits( m_aMFYRotation, static_cast<sal_Int64>(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()));
    }
    else
    {
        lcl_SetMetricFieldLimits( m_aMFXRotation, 180 );
        lcl_SetMetricFieldLimits( m_aMFYRotation, 180 );

        m_aMFXRotation.SetValue(m_nXRotation);
        m_aMFYRotation.SetValue(m_nYRotation);
        m_aMFZRotation.SetValue(m_nZRotation);
    }

    ThreeDHelper::switchRightAngledAxes( m_xSceneProperties, m_aCbxRightAngledAxes.IsChecked(), true /*bRotateLights*/ );

    return 0;
}

//.............................................................................
} //namespace chart
//.............................................................................
<|endoftext|>


<commit_before>// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "assert.h"

#include "chainparams.h"
#include "main.h"
#include "util.h"

#include <boost/assign/list_of.hpp>

using namespace boost::assign;

struct SeedSpec6 {
    uint8_t addr[16];
    uint16_t port;
};

#include "chainparamsseeds.h"

//
// Main network
//

// Convert the pnSeeds6 array into usable address objects.
static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data, unsigned int count)
{
    // It'll only connect to one or two seed nodes because once it connects,
    // it'll get a pile of addresses with newer timestamps.
    // Seed nodes are given a random 'last seen time' of between one and two
    // weeks ago.
    const int64_t nOneWeek = 7*24*60*60;
    for (unsigned int i = 0; i < count; i++)
    {
        struct in6_addr ip;
        memcpy(&ip, data[i].addr, sizeof(ip));
        CAddress addr(CService(ip, data[i].port));
        addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
        vSeedsOut.push_back(addr);
    }
}

class CMainParams : public CChainParams {
public:
    CMainParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0x70;
        pchMessageStart[1] = 0x35;
        pchMessageStart[2] = 0x22;
        pchMessageStart[3] = 0x05;
        vAlertPubKey = ParseHex("0486bce1bac0d543f104cbff2bd23680056a3b9ea05e1137d2ff90eeb5e08472eb500322593a2cb06fbf8297d7beb6cd30cb90f98153b5b7cce1493749e41e0284");
        nDefaultPort = 19914;
        nRPCPort = 19915;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20);

        // Build the genesis block. Note that the output of the genesis coinbase cannot
        // be spent as it did not originally exist in the database.
        //
        //CBlock(hash=000001faef25dec4fbcf906e6242621df2c183bf232f263d0ba5b101911e4563, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=12630d16a97f24b287c8c2594dda5fb98c9e6c70fc61d44191931ea2aa08dc90, nTime=1393221600, nBits=1e0fffff, nNonce=164482, vtx=1, vchBlockSig=)
        //  Coinbase(hash=12630d16a9, nTime=1393221600, ver=1, vin.size=1, vout.size=1, nLockTime=0)
        //    CTxIn(COutPoint(0000000000, 4294967295), coinbase 00012a24323020466562203230313420426974636f696e2041544d7320636f6d6520746f20555341)
        //    CTxOut(empty)
        //  vMerkleTree: 12630d16a9
        const char* pszTimestamp = "BitBay gonna make an Impact on the altcoin market never seen before";
        CTransaction txNew;
        txNew.nTime = 1414351032;
        txNew.vin.resize(1);
        txNew.vout.resize(1);
        txNew.vin[0].scriptSig = CScript() << 0 << CBigNum(42) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
        txNew.vout[0].SetEmpty();
        genesis.vtx.push_back(txNew);
        genesis.hashPrevBlock = 0;
        genesis.hashMerkleRoot = genesis.BuildMerkleTree();
        genesis.nVersion = 1;
        genesis.nTime    = 1414351032;
        genesis.nBits    = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce   = 1491418;
        //block.nNonce   = 1491418;
		//if(fTestNet)
        //{
        //    block.nNonce   = 21739;
        //}
        //if (false  && (block.GetHash() != hashGenesisBlock)) {

        // This will figure out a valid hash and Nonce if you're
        // creating a different genesis block:
        //    uint256 hashTarget = CBigNum().SetCompact(block.nBits).getuint256();
        //    while (block.GetHash() > hashTarget)
        //       {
        //           ++block.nNonce;
        //           if (block.nNonce == 0)
        //           {
        //               printf("NONCE WRAPPED, incrementing time");
        //               ++block.nTime;
        //           }
        //       }
        //}
        //block.print();
        printf("block.GetHash() == %s\n", genesis.GetHash().ToString().c_str());
        //printf("block.hashMerkleRoot == %s\n", block.hashMerkleRoot.ToString().c_str());
        //printf("block.nTime = %u \n", block.nTime);
        //printf("block.nNonce = %u \n", block.nNonce);

        //// debug print

        hashGenesisBlock = genesis.GetHash();
        assert(hashGenesisBlock == uint256("0x0000075685d3be1f253ce777174b1594354e79954d2a32a6f77fe9cba00e6467"));
        assert(genesis.hashMerkleRoot == uint256("0xd2b4345a1b1f0df76ab0cadfa1b44ca52270ff551c43e1b229d25873f0adc90d"));

        vSeeds.push_back(CDNSSeedData("bbaynode (nyc)", "104.236.208.150"));
        vSeeds.push_back(CDNSSeedData("bbaynode (amsterdam)", "188.166.39.223"));
        vSeeds.push_back(CDNSSeedData("bbaynode (singapore)", "128.199.118.67"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node1)", "104.255.33.162"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node2)", "194.135.84.161"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node3)", "23.227.190.163"));

        // reliable nodes from chainz
        vSeeds.push_back(CDNSSeedData("bbaynode (node4)", "104.172.24.79"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node5)", "106.187.50.153"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node6)", "158.69.27.82"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node7)", "24.37.11.106"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node8)", "40.112.149.192"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node9)", "45.56.109.7"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node10)", "69.254.222.98"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node11)", "85.25.146.74"));

	base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,25);
        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,85);
        base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1,153);
        base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
        base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();

        convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));

        nLastPOWBlock = 10000;
    }

    virtual const CBlock& GenesisBlock() const { return genesis; }
    virtual Network NetworkID() const { return CChainParams::MAIN; }

    virtual const vector<CAddress>& FixedSeeds() const {
        return vFixedSeeds;
    }
protected:
    CBlock genesis;
    vector<CAddress> vFixedSeeds;
};
static CMainParams mainParams;

//
// Testnet
//

class CTestNetParams : public CMainParams {
public:
    CTestNetParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0xcd;
        pchMessageStart[1] = 0xf2;
        pchMessageStart[2] = 0xc0;
        pchMessageStart[3] = 0xef;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 16);
        vAlertPubKey = ParseHex("0471dc165db490094d35cde15b1f5d755fa6ad6f2b5ed0f340e3f17f57389c3c2af113a8cbcc885bde73305a553b5640c83021128008ddf882e856336269080496");
        nDefaultPort = 21914;
        nRPCPort = 21915;
        strDataDir = "testnet";

        // Modify the testnet genesis block so the timestamp is valid for a later start.
        genesis.nBits  = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce = 216178;
        hashGenesisBlock = genesis.GetHash();
        //assert(hashGenesisBlock == uint256("0x000012424a3b8d8c1a4ae9ca4426d67a1678c26c4e8cc6e72cb368d687dc07dd"));

        vFixedSeeds.clear();
        vSeeds.clear();

        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
        base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1,239);
        base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
        base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();

        convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));

        nLastPOWBlock = 0x7fffffff;
    }
    virtual Network NetworkID() const { return CChainParams::TESTNET; }
};
static CTestNetParams testNetParams;

//
// Regression test
//
class CRegTestParams : public CTestNetParams {
public:
    CRegTestParams() {
        pchMessageStart[0] = 0xfa;
        pchMessageStart[1] = 0xbf;
        pchMessageStart[2] = 0xb5;
        pchMessageStart[3] = 0xda;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 1);
        genesis.nTime = 1411111111;
        genesis.nBits  = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce = 2;
        hashGenesisBlock = genesis.GetHash();
        nDefaultPort = 18444;
        strDataDir = "regtest";
        //assert(hashGenesisBlock == uint256("0x523dda6d336047722cbaf1c5dce622298af791bac21b33bf6e2d5048b2a13e3d"));

        vSeeds.clear();  // Regtest mode doesn't have any DNS seeds.
    }

    virtual bool RequireRPCPassword() const { return false; }
    virtual Network NetworkID() const { return CChainParams::REGTEST; }
};
static CRegTestParams regTestParams;

static CChainParams *pCurrentParams = &mainParams;

const CChainParams &Params() {
    return *pCurrentParams;
}

void SelectParams(CChainParams::Network network) {
    switch (network) {
        case CChainParams::MAIN:
            pCurrentParams = &mainParams;
            break;
        case CChainParams::TESTNET:
            pCurrentParams = &testNetParams;
            break;
        case CChainParams::REGTEST:
            pCurrentParams = &regTestParams;
            break;
        default:
            assert(false && "Unimplemented network");
            return;
    }
}

bool SelectParamsFromCommandLine() {
    bool fRegTest = GetBoolArg("-regtest", false);
    bool fTestNet = GetBoolArg("-testnet", false);

    if (fTestNet && fRegTest) {
        return false;
    }

    if (fRegTest) {
        SelectParams(CChainParams::REGTEST);
    } else if (fTestNet) {
        SelectParams(CChainParams::TESTNET);
    } else {
        SelectParams(CChainParams::MAIN);
    }
    return true;
}
<commit_msg>Update chainparams.cpp<commit_after>// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "assert.h"

#include "chainparams.h"
#include "main.h"
#include "util.h"

#include <boost/assign/list_of.hpp>

using namespace boost::assign;

struct SeedSpec6 {
    uint8_t addr[16];
    uint16_t port;
};

#include "chainparamsseeds.h"

//
// Main network
//

// Convert the pnSeeds6 array into usable address objects.
static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data, unsigned int count)
{
    // It'll only connect to one or two seed nodes because once it connects,
    // it'll get a pile of addresses with newer timestamps.
    // Seed nodes are given a random 'last seen time' of between one and two
    // weeks ago.
    const int64_t nOneWeek = 7*24*60*60;
    for (unsigned int i = 0; i < count; i++)
    {
        struct in6_addr ip;
        memcpy(&ip, data[i].addr, sizeof(ip));
        CAddress addr(CService(ip, data[i].port));
        addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
        vSeedsOut.push_back(addr);
    }
}

class CMainParams : public CChainParams {
public:
    CMainParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0x70;
        pchMessageStart[1] = 0x35;
        pchMessageStart[2] = 0x22;
        pchMessageStart[3] = 0x05;
        vAlertPubKey = ParseHex("0486bce1bac0d543f104cbff2bd23680056a3b9ea05e1137d2ff90eeb5e08472eb500322593a2cb06fbf8297d7beb6cd30cb90f98153b5b7cce1493749e41e0284");
        nDefaultPort = 19914;
        nRPCPort = 19915;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20);

        // Build the genesis block. Note that the output of the genesis coinbase cannot
        // be spent as it did not originally exist in the database.
        //
        //CBlock(hash=000001faef25dec4fbcf906e6242621df2c183bf232f263d0ba5b101911e4563, ver=1, hashPrevBlock=0000000000000000000000000000000000000000000000000000000000000000, hashMerkleRoot=12630d16a97f24b287c8c2594dda5fb98c9e6c70fc61d44191931ea2aa08dc90, nTime=1393221600, nBits=1e0fffff, nNonce=164482, vtx=1, vchBlockSig=)
        //  Coinbase(hash=12630d16a9, nTime=1393221600, ver=1, vin.size=1, vout.size=1, nLockTime=0)
        //    CTxIn(COutPoint(0000000000, 4294967295), coinbase 00012a24323020466562203230313420426974636f696e2041544d7320636f6d6520746f20555341)
        //    CTxOut(empty)
        //  vMerkleTree: 12630d16a9
        const char* pszTimestamp = "BitBay gonna make an Impact on the altcoin market never seen before";
        CTransaction txNew;
        txNew.nTime = 1414351032;
        txNew.vin.resize(1);
        txNew.vout.resize(1);
        txNew.vin[0].scriptSig = CScript() << 0 << CBigNum(42) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
        txNew.vout[0].SetEmpty();
        genesis.vtx.push_back(txNew);
        genesis.hashPrevBlock = 0;
        genesis.hashMerkleRoot = genesis.BuildMerkleTree();
        genesis.nVersion = 1;
        genesis.nTime    = 1414351032;
        genesis.nBits    = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce   = 1491418;
        //block.nNonce   = 1491418;
		//if(fTestNet)
        //{
        //    block.nNonce   = 21739;
        //}
        //if (false  && (block.GetHash() != hashGenesisBlock)) {

        // This will figure out a valid hash and Nonce if you're
        // creating a different genesis block:
        //    uint256 hashTarget = CBigNum().SetCompact(block.nBits).getuint256();
        //    while (block.GetHash() > hashTarget)
        //       {
        //           ++block.nNonce;
        //           if (block.nNonce == 0)
        //           {
        //               printf("NONCE WRAPPED, incrementing time");
        //               ++block.nTime;
        //           }
        //       }
        //}
        //block.print();
        printf("block.GetHash() == %s\n", genesis.GetHash().ToString().c_str());
        //printf("block.hashMerkleRoot == %s\n", block.hashMerkleRoot.ToString().c_str());
        //printf("block.nTime = %u \n", block.nTime);
        //printf("block.nNonce = %u \n", block.nNonce);

        //// debug print

        hashGenesisBlock = genesis.GetHash();
        assert(hashGenesisBlock == uint256("0x0000075685d3be1f253ce777174b1594354e79954d2a32a6f77fe9cba00e6467"));
        assert(genesis.hashMerkleRoot == uint256("0xd2b4345a1b1f0df76ab0cadfa1b44ca52270ff551c43e1b229d25873f0adc90d"));

        vSeeds.push_back(CDNSSeedData("bbaynode (nyc)", "104.236.208.150"));
        vSeeds.push_back(CDNSSeedData("bbaynode (amsterdam)", "188.166.39.223"));
        vSeeds.push_back(CDNSSeedData("bbaynode (singapore)", "128.199.118.67"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node1)", "104.255.33.162"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node2)", "194.135.84.161"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node3)", "23.227.190.163"));

        // reliable nodes from chainz
        vSeeds.push_back(CDNSSeedData("bbaynode (node4)", "104.172.24.79"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node5)", "106.187.50.153"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node6)", "158.69.27.82"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node7)", "24.37.11.106"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node8)", "40.112.149.192"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node9)", "45.56.109.7"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node10)", "69.254.222.98"));
        vSeeds.push_back(CDNSSeedData("bbaynode (node11)", "85.25.146.74"));

        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,25);
        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,85);
        base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1,153);
        base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container<std::vector<unsigned char> >();
        base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container<std::vector<unsigned char> >();

        convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));

        nLastPOWBlock = 10000;
    }

    virtual const CBlock& GenesisBlock() const { return genesis; }
    virtual Network NetworkID() const { return CChainParams::MAIN; }

    virtual const vector<CAddress>& FixedSeeds() const {
        return vFixedSeeds;
    }
protected:
    CBlock genesis;
    vector<CAddress> vFixedSeeds;
};
static CMainParams mainParams;

//
// Testnet
//

class CTestNetParams : public CMainParams {
public:
    CTestNetParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0xcd;
        pchMessageStart[1] = 0xf2;
        pchMessageStart[2] = 0xc0;
        pchMessageStart[3] = 0xef;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 16);
        vAlertPubKey = ParseHex("0471dc165db490094d35cde15b1f5d755fa6ad6f2b5ed0f340e3f17f57389c3c2af113a8cbcc885bde73305a553b5640c83021128008ddf882e856336269080496");
        nDefaultPort = 21914;
        nRPCPort = 21915;
        strDataDir = "testnet";

        // Modify the testnet genesis block so the timestamp is valid for a later start.
        genesis.nBits  = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce = 216178;
        hashGenesisBlock = genesis.GetHash();
        //assert(hashGenesisBlock == uint256("0x000012424a3b8d8c1a4ae9ca4426d67a1678c26c4e8cc6e72cb368d687dc07dd"));

        vFixedSeeds.clear();
        vSeeds.clear();

        base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
        base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
        base58Prefixes[SECRET_KEY] =     std::vector<unsigned char>(1,239);
        base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container<std::vector<unsigned char> >();
        base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container<std::vector<unsigned char> >();

        convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));

        nLastPOWBlock = 0x7fffffff;
    }
    virtual Network NetworkID() const { return CChainParams::TESTNET; }
};
static CTestNetParams testNetParams;

//
// Regression test
//
class CRegTestParams : public CTestNetParams {
public:
    CRegTestParams() {
        pchMessageStart[0] = 0xfa;
        pchMessageStart[1] = 0xbf;
        pchMessageStart[2] = 0xb5;
        pchMessageStart[3] = 0xda;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 1);
        genesis.nTime = 1411111111;
        genesis.nBits  = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce = 2;
        hashGenesisBlock = genesis.GetHash();
        nDefaultPort = 18444;
        strDataDir = "regtest";
        //assert(hashGenesisBlock == uint256("0x523dda6d336047722cbaf1c5dce622298af791bac21b33bf6e2d5048b2a13e3d"));

        vSeeds.clear();  // Regtest mode doesn't have any DNS seeds.
    }

    virtual bool RequireRPCPassword() const { return false; }
    virtual Network NetworkID() const { return CChainParams::REGTEST; }
};
static CRegTestParams regTestParams;

static CChainParams *pCurrentParams = &mainParams;

const CChainParams &Params() {
    return *pCurrentParams;
}

void SelectParams(CChainParams::Network network) {
    switch (network) {
        case CChainParams::MAIN:
            pCurrentParams = &mainParams;
            break;
        case CChainParams::TESTNET:
            pCurrentParams = &testNetParams;
            break;
        case CChainParams::REGTEST:
            pCurrentParams = &regTestParams;
            break;
        default:
            assert(false && "Unimplemented network");
            return;
    }
}

bool SelectParamsFromCommandLine() {
    bool fRegTest = GetBoolArg("-regtest", false);
    bool fTestNet = GetBoolArg("-testnet", false);

    if (fTestNet && fRegTest) {
        return false;
    }

    if (fRegTest) {
        SelectParams(CChainParams::REGTEST);
    } else if (fTestNet) {
        SelectParams(CChainParams::TESTNET);
    } else {
        SelectParams(CChainParams::MAIN);
    }
    return true;
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 Satoshi Nakamoteed

// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "assert.h"

#include "chainparams.h"
#include "main.h"
#include "util.h"

#include <boost/assign/list_of.hpp>

using namespace boost::assign;

unsigned int pnSeed[] =
{
0x7b0272a7, 0xada272a7
};

struct SeedSpec6 {
    uint8_t addr[16];
    uint16_t port;
};

#include "chainparamsseeds.h"

//
// Main network
//

// Convert the pnSeeds6 array into usable address objects.
static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data, unsigned int count)
{
    // It'll only connect to one or two seed nodes because once it connects,
    // it'll get a pile of addresses with newer timestamps.
    // Seed nodes are given a random 'last seen time' of between one and two
    // weeks ago.
    const int64_t nOneWeek = 7*24*60*60;
    for (unsigned int i = 0; i < count; i++)
    {
        struct in6_addr ip;
        memcpy(&ip, data[i].addr, sizeof(ip));
        CAddress addr(CService(ip, data[i].port));
        addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
        vSeedsOut.push_back(addr);
    }
}

class CMainParams : public CChainParams {
public:
    CMainParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0xa2;
        pchMessageStart[1] = 0x7a;
        pchMessageStart[2] = 0xc1;
        pchMessageStart[3] = 0x7c;
        vAlertPubKey = ParseHex("046d4a82462704df06381163858c5998e85277d995967632348ecaa24668d48b7910bae9c427f6ae929907fc5a33b5d731dfb0e53a057a8200bc11eab87d693ef7");
        nDefaultPort = 20302;
        nRPCPort = 20304;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20);

        const char* pszTimestamp = "2015 DraftCoin Start!";
        std::vector<CTxIn> vin;
        vin.resize(1);
        vin[0].scriptSig = CScript() << 0 << CBigNum(42) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
        std::vector<CTxOut> vout;
        vout.resize(1);
        vout[0].SetEmpty();
		CTransaction txNew(1, 1432374838, vin, vout, 0);
        genesis.vtx.push_back(txNew);
        genesis.hashPrevBlock = 0;
        genesis.hashMerkleRoot = genesis.BuildMerkleTree();
        genesis.nVersion = 1;
        genesis.nTime    = 1432374838;
        genesis.nBits    = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce   = 330954;

        hashGenesisBlock = genesis.GetHash();
/*
        while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){
            if (++genesis.nNonce==0) break;
            hashGenesisBlock = genesis.GetHash();
        }

        printf("%s\n MAIN ", hashGenesisBlock.ToString().c_str());
        printf("%s\n MAIN ", genesis.hashMerkleRoot.ToString().c_str());
        printf("%x\n MAIN ", bnProofOfWorkLimit.GetCompact());
        printf("%d\n MAIN ", genesis.nNonce);
*/
        assert(hashGenesisBlock == uint256("0x00000626d583465e39cc5eec2020f639792843efcfb4182d508e6734d4cfdab6"));
        assert(genesis.hashMerkleRoot == uint256("0x96b2046ee922b5724d19ade2ca7f44bc828e8b850f6e5416a98cf4fbea18ba87"));

		vSeeds.push_back(CDNSSeedData("dns.btcdraft.ca", "dns.btcdraft.ca"));
		vSeeds.push_back(CDNSSeedData("149.56.101.219", "149.56.101.219"));
		vSeeds.push_back(CDNSSeedData("158.69.199.130", "158.69.199.130"));
		vSeeds.push_back(CDNSSeedData("99.248.230.242", "99.248.230.242"));
	    	vSeeds.push_back(CDNSSeedData("68.206.29.192", "68.206.29.192"));
	    	vSeeds.push_back(CDNSSeedData("209.195.104.6", "209.195.104.6"));
	    	vSeeds.push_back(CDNSSeedData("204.188.161.57", "204.188.161.57"));
	    	vSeeds.push_back(CDNSSeedData("204.188.161.61", "204.188.161.61"));

        base58Prefixes[PUBKEY_ADDRESS] = list_of(30);
        base58Prefixes[SCRIPT_ADDRESS] = list_of(91);
        base58Prefixes[SECRET_KEY] =     list_of(117);
        base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x73)(0x77)(0xEE);
        base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x73)(0xDD)(0x55);

        convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));

        nLastPOWBlock = 15000;

		// Convert the pnSeeds array into usable address objects.
        for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
        {
            // It'll only connect to one or two seed nodes because once it connects,
            // it'll get a pile of addresses with newer timestamps.
            // Seed nodes are given a random 'last seen time' of between one and two
            // weeks ago.
            const int64_t nOneWeek = 7*24*60*60;
            struct in_addr ip;
            memcpy(&ip, &pnSeed[i], sizeof(ip));
            CAddress addr(CService(ip, GetDefaultPort()));
            addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
            vFixedSeeds.push_back(addr);
        }
    }

    virtual const CBlock& GenesisBlock() const { return genesis; }
    virtual Network NetworkID() const { return CChainParams::MAIN; }

    virtual const vector<CAddress>& FixedSeeds() const {
        return vFixedSeeds;
    }
protected:
    CBlock genesis;
    vector<CAddress> vFixedSeeds;
};
static CMainParams mainParams;

//
// Testnet
//

class CTestNetParams : public CMainParams {
public:
    CTestNetParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0xaa;
        pchMessageStart[1] = 0x33;
        pchMessageStart[2] = 0xff;
        pchMessageStart[3] = 0x77;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 16);
        vAlertPubKey = ParseHex("0433ec1132f34b5d4cafe6e9b3d848b710d75d8ec7a363d24554eac5256e70e5850b33a716492f2570f6f0cc5b2d3c01c2dfb25bf0a9327e634dee8a3b2d1039bb");
        nDefaultPort = 12345;
        nRPCPort = 12346;
        strDataDir = "testnet";

        // Modify the testnet genesis block so the timestamp is valid for a later start.
        genesis.nBits  = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce = 81778;
        hashGenesisBlock = genesis.GetHash();
/*
        while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){
            if (++genesis.nNonce==0) break;
            hashGenesisBlock = genesis.GetHash();
        }

        printf("%s\n TESTNET ", hashGenesisBlock.ToString().c_str());
        printf("%s\n TESTNET ", genesis.hashMerkleRoot.ToString().c_str());
        printf("%x\n TESTNET ", bnProofOfWorkLimit.GetCompact());
        printf("%d\n TESTNET ", genesis.nNonce);
*/
        assert(hashGenesisBlock == uint256("0x00007fe66ae67c7d800791c56234ef019ca1f85f9b059fcccc49447d33c22481"));

        vFixedSeeds.clear();
        vSeeds.clear();

        base58Prefixes[PUBKEY_ADDRESS] = list_of(110);
        base58Prefixes[SCRIPT_ADDRESS] = list_of(196);
        base58Prefixes[SECRET_KEY]     = list_of(239);
        base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x35)(0x17)(0xFF);
        base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x35)(0x43)(0x99);

        convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));

        nLastPOWBlock = 0x7fffffff;
    }
    virtual Network NetworkID() const { return CChainParams::TESTNET; }
};
static CTestNetParams testNetParams;

//
// Regression test
//
class CRegTestParams : public CTestNetParams {
public:
    CRegTestParams() {
        pchMessageStart[0] = 0xaf;
        pchMessageStart[1] = 0xbb;
        pchMessageStart[2] = 0x55;
        pchMessageStart[3] = 0xdd;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 1);
        genesis.nTime = 1412222222;
        genesis.nBits  = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce = 8;
        hashGenesisBlock = genesis.GetHash();
        nDefaultPort = 47992;
        strDataDir = "regtest";
/*
        while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){
            if (++genesis.nNonce==0) break;
            hashGenesisBlock = genesis.GetHash();
        }

        printf("%s\n REGTEST ", hashGenesisBlock.ToString().c_str());
        printf("%s\n REGTEST ", genesis.hashMerkleRoot.ToString().c_str());
        printf("%x\n REGTEST ", bnProofOfWorkLimit.GetCompact());
        printf("%d\n REGTEST ", genesis.nNonce);
*/
        assert(hashGenesisBlock == uint256("0x21a8f72f07cec34eb88c6088f382eeb868c9813adfb9edffbe40a5e076c14cb8"));

        vSeeds.clear();  // Regtest mode doesn't have any DNS seeds.
    }

    virtual bool RequireRPCPassword() const { return false; }
    virtual Network NetworkID() const { return CChainParams::REGTEST; }
};
static CRegTestParams regTestParams;

static CChainParams *pCurrentParams = &mainParams;

const CChainParams &Params() {
    return *pCurrentParams;
}

void SelectParams(CChainParams::Network network) {
    switch (network) {
        case CChainParams::MAIN:
            pCurrentParams = &mainParams;
            break;
        case CChainParams::TESTNET:
            pCurrentParams = &testNetParams;
            break;
        case CChainParams::REGTEST:
            pCurrentParams = &regTestParams;
            break;
        default:
            assert(false && "Unimplemented network");
            return;
    }
}

bool SelectParamsFromCommandLine() {
    bool fRegTest = GetBoolArg("-regtest", false);
    bool fTestNet = GetBoolArg("-testnet", false);

    if (fTestNet && fRegTest) {
        return false;
    }

    if (fRegTest) {
        SelectParams(CChainParams::REGTEST);
    } else if (fTestNet) {
        SelectParams(CChainParams::TESTNET);
    } else {
        SelectParams(CChainParams::MAIN);
    }
    return true;
}
<commit_msg>Update to node list in chainparams.cpp<commit_after>// Copyright (c) 2010 Satoshi Nakamoteed

// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "assert.h"

#include "chainparams.h"
#include "main.h"
#include "util.h"

#include <boost/assign/list_of.hpp>

using namespace boost::assign;

unsigned int pnSeed[] =
{
0x7b0272a7, 0xada272a7
};

struct SeedSpec6 {
    uint8_t addr[16];
    uint16_t port;
};

#include "chainparamsseeds.h"

//
// Main network
//

// Convert the pnSeeds6 array into usable address objects.
static void convertSeed6(std::vector<CAddress> &vSeedsOut, const SeedSpec6 *data, unsigned int count)
{
    // It'll only connect to one or two seed nodes because once it connects,
    // it'll get a pile of addresses with newer timestamps.
    // Seed nodes are given a random 'last seen time' of between one and two
    // weeks ago.
    const int64_t nOneWeek = 7*24*60*60;
    for (unsigned int i = 0; i < count; i++)
    {
        struct in6_addr ip;
        memcpy(&ip, data[i].addr, sizeof(ip));
        CAddress addr(CService(ip, data[i].port));
        addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
        vSeedsOut.push_back(addr);
    }
}

class CMainParams : public CChainParams {
public:
    CMainParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0xa2;
        pchMessageStart[1] = 0x7a;
        pchMessageStart[2] = 0xc1;
        pchMessageStart[3] = 0x7c;
        vAlertPubKey = ParseHex("046d4a82462704df06381163858c5998e85277d995967632348ecaa24668d48b7910bae9c427f6ae929907fc5a33b5d731dfb0e53a057a8200bc11eab87d693ef7");
        nDefaultPort = 20302;
        nRPCPort = 20304;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 20);

        const char* pszTimestamp = "2015 DraftCoin Start!";
        std::vector<CTxIn> vin;
        vin.resize(1);
        vin[0].scriptSig = CScript() << 0 << CBigNum(42) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
        std::vector<CTxOut> vout;
        vout.resize(1);
        vout[0].SetEmpty();
		CTransaction txNew(1, 1432374838, vin, vout, 0);
        genesis.vtx.push_back(txNew);
        genesis.hashPrevBlock = 0;
        genesis.hashMerkleRoot = genesis.BuildMerkleTree();
        genesis.nVersion = 1;
        genesis.nTime    = 1432374838;
        genesis.nBits    = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce   = 330954;

        hashGenesisBlock = genesis.GetHash();
/*
        while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){
            if (++genesis.nNonce==0) break;
            hashGenesisBlock = genesis.GetHash();
        }

        printf("%s\n MAIN ", hashGenesisBlock.ToString().c_str());
        printf("%s\n MAIN ", genesis.hashMerkleRoot.ToString().c_str());
        printf("%x\n MAIN ", bnProofOfWorkLimit.GetCompact());
        printf("%d\n MAIN ", genesis.nNonce);
*/
        assert(hashGenesisBlock == uint256("0x00000626d583465e39cc5eec2020f639792843efcfb4182d508e6734d4cfdab6"));
        assert(genesis.hashMerkleRoot == uint256("0x96b2046ee922b5724d19ade2ca7f44bc828e8b850f6e5416a98cf4fbea18ba87"));

		vSeeds.push_back(CDNSSeedData("dns.btcdraft.ca", "dns.btcdraft.ca"));
		vSeeds.push_back(CDNSSeedData("149.56.101.219", "149.56.101.219"));
		vSeeds.push_back(CDNSSeedData("158.69.199.130", "158.69.199.130"));
		vSeeds.push_back(CDNSSeedData("99.248.230.242", "99.248.230.242"));
	    	vSeeds.push_back(CDNSSeedData("68.206.29.192", "68.206.29.192"));
	    	vSeeds.push_back(CDNSSeedData("209.195.104.6", "209.195.104.6"));
	    	vSeeds.push_back(CDNSSeedData("204.188.161.57", "204.188.161.57"));
	    	vSeeds.push_back(CDNSSeedData("204.188.161.61", "204.188.161.61"));
	    	vSeeds.push_back(CDNSSeedData("55.133.130.87", "55.133.130.87"));

        base58Prefixes[PUBKEY_ADDRESS] = list_of(30);
        base58Prefixes[SCRIPT_ADDRESS] = list_of(91);
        base58Prefixes[SECRET_KEY] =     list_of(117);
        base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x73)(0x77)(0xEE);
        base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x73)(0xDD)(0x55);

        convertSeed6(vFixedSeeds, pnSeed6_main, ARRAYLEN(pnSeed6_main));

        nLastPOWBlock = 15000;

		// Convert the pnSeeds array into usable address objects.
        for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
        {
            // It'll only connect to one or two seed nodes because once it connects,
            // it'll get a pile of addresses with newer timestamps.
            // Seed nodes are given a random 'last seen time' of between one and two
            // weeks ago.
            const int64_t nOneWeek = 7*24*60*60;
            struct in_addr ip;
            memcpy(&ip, &pnSeed[i], sizeof(ip));
            CAddress addr(CService(ip, GetDefaultPort()));
            addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
            vFixedSeeds.push_back(addr);
        }
    }

    virtual const CBlock& GenesisBlock() const { return genesis; }
    virtual Network NetworkID() const { return CChainParams::MAIN; }

    virtual const vector<CAddress>& FixedSeeds() const {
        return vFixedSeeds;
    }
protected:
    CBlock genesis;
    vector<CAddress> vFixedSeeds;
};
static CMainParams mainParams;

//
// Testnet
//

class CTestNetParams : public CMainParams {
public:
    CTestNetParams() {
        // The message start string is designed to be unlikely to occur in normal data.
        // The characters are rarely used upper ASCII, not valid as UTF-8, and produce
        // a large 4-byte int at any alignment.
        pchMessageStart[0] = 0xaa;
        pchMessageStart[1] = 0x33;
        pchMessageStart[2] = 0xff;
        pchMessageStart[3] = 0x77;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 16);
        vAlertPubKey = ParseHex("0433ec1132f34b5d4cafe6e9b3d848b710d75d8ec7a363d24554eac5256e70e5850b33a716492f2570f6f0cc5b2d3c01c2dfb25bf0a9327e634dee8a3b2d1039bb");
        nDefaultPort = 12345;
        nRPCPort = 12346;
        strDataDir = "testnet";

        // Modify the testnet genesis block so the timestamp is valid for a later start.
        genesis.nBits  = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce = 81778;
        hashGenesisBlock = genesis.GetHash();
/*
        while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){
            if (++genesis.nNonce==0) break;
            hashGenesisBlock = genesis.GetHash();
        }

        printf("%s\n TESTNET ", hashGenesisBlock.ToString().c_str());
        printf("%s\n TESTNET ", genesis.hashMerkleRoot.ToString().c_str());
        printf("%x\n TESTNET ", bnProofOfWorkLimit.GetCompact());
        printf("%d\n TESTNET ", genesis.nNonce);
*/
        assert(hashGenesisBlock == uint256("0x00007fe66ae67c7d800791c56234ef019ca1f85f9b059fcccc49447d33c22481"));

        vFixedSeeds.clear();
        vSeeds.clear();

        base58Prefixes[PUBKEY_ADDRESS] = list_of(110);
        base58Prefixes[SCRIPT_ADDRESS] = list_of(196);
        base58Prefixes[SECRET_KEY]     = list_of(239);
        base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x35)(0x17)(0xFF);
        base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x35)(0x43)(0x99);

        convertSeed6(vFixedSeeds, pnSeed6_test, ARRAYLEN(pnSeed6_test));

        nLastPOWBlock = 0x7fffffff;
    }
    virtual Network NetworkID() const { return CChainParams::TESTNET; }
};
static CTestNetParams testNetParams;

//
// Regression test
//
class CRegTestParams : public CTestNetParams {
public:
    CRegTestParams() {
        pchMessageStart[0] = 0xaf;
        pchMessageStart[1] = 0xbb;
        pchMessageStart[2] = 0x55;
        pchMessageStart[3] = 0xdd;
        bnProofOfWorkLimit = CBigNum(~uint256(0) >> 1);
        genesis.nTime = 1412222222;
        genesis.nBits  = bnProofOfWorkLimit.GetCompact();
        genesis.nNonce = 8;
        hashGenesisBlock = genesis.GetHash();
        nDefaultPort = 47992;
        strDataDir = "regtest";
/*
        while (hashGenesisBlock > bnProofOfWorkLimit.getuint256()){
            if (++genesis.nNonce==0) break;
            hashGenesisBlock = genesis.GetHash();
        }

        printf("%s\n REGTEST ", hashGenesisBlock.ToString().c_str());
        printf("%s\n REGTEST ", genesis.hashMerkleRoot.ToString().c_str());
        printf("%x\n REGTEST ", bnProofOfWorkLimit.GetCompact());
        printf("%d\n REGTEST ", genesis.nNonce);
*/
        assert(hashGenesisBlock == uint256("0x21a8f72f07cec34eb88c6088f382eeb868c9813adfb9edffbe40a5e076c14cb8"));

        vSeeds.clear();  // Regtest mode doesn't have any DNS seeds.
    }

    virtual bool RequireRPCPassword() const { return false; }
    virtual Network NetworkID() const { return CChainParams::REGTEST; }
};
static CRegTestParams regTestParams;

static CChainParams *pCurrentParams = &mainParams;

const CChainParams &Params() {
    return *pCurrentParams;
}

void SelectParams(CChainParams::Network network) {
    switch (network) {
        case CChainParams::MAIN:
            pCurrentParams = &mainParams;
            break;
        case CChainParams::TESTNET:
            pCurrentParams = &testNetParams;
            break;
        case CChainParams::REGTEST:
            pCurrentParams = &regTestParams;
            break;
        default:
            assert(false && "Unimplemented network");
            return;
    }
}

bool SelectParamsFromCommandLine() {
    bool fRegTest = GetBoolArg("-regtest", false);
    bool fTestNet = GetBoolArg("-testnet", false);

    if (fTestNet && fRegTest) {
        return false;
    }

    if (fRegTest) {
        SelectParams(CChainParams::REGTEST);
    } else if (fTestNet) {
        SelectParams(CChainParams::TESTNET);
    } else {
        SelectParams(CChainParams::MAIN);
    }
    return true;
}
<|endoftext|>