<commit_before>/*************************************************************************
 *
 *  $RCSfile: mkfilt.cxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 17:03:01 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>

#include <tools/string.hxx>
#include <tools/list.hxx>

class TextFilter
{
protected:
    FILE            *pIn, *pOut;
    virtual void    Filter();
public:
                    TextFilter( ByteString aInFile = "stdin",
                        ByteString aOutFile = "stdout" );
    virtual         ~TextFilter();

    virtual void    Execute();
};

TextFilter::TextFilter( ByteString aInFile, ByteString aOutFile )
{
    if ( aInFile == "stdin" )
        pIn = stdin;
    else
        if (( pIn = fopen( aInFile.GetBuffer(), "r" )) == NULL )
            printf( "Can't read %s\n", aInFile.GetBuffer() );

    if ( aOutFile == "stdout" )
        pOut = stdout;
    else
        if (( pOut = fopen( aOutFile.GetBuffer(), "w" )) == NULL )
            printf( "Can't write %s\n", aOutFile.GetBuffer() );
}

TextFilter::~TextFilter()
{
    fclose( pOut );
    fclose( pIn );
}

void TextFilter::Execute()
{
    Filter();
}

void TextFilter::Filter()
{
    char c;
    while ( (c = fgetc( pIn )) != EOF )
        fputc( c, pOut );
}

#define LINE_LEN 2048

class ByteStringList;

class MkLine
{
public:
    ByteString          aLine;
    ByteStringList*     pPrivateTnrLst;
    BOOL            bOut;
    BOOL            bHier;

                    MkLine();
};

MkLine::MkLine()
{
    bOut = FALSE;
    bHier = FALSE;
    pPrivateTnrLst = NULL;
}

DECLARE_LIST( ByteStringList, MkLine * );

class MkFilter : public TextFilter
{
    static ByteString   aTnr;
    ByteStringList      *pLst;
    ByteStringList      *pTnrLst;
protected:
    virtual void    Filter();
public:
                    MkFilter( ByteString aInFile = "stdin", ByteString aOutFile = "stdout");
                    ~MkFilter();
};

MkFilter::MkFilter( ByteString aInFile, ByteString aOutFile ) :
    TextFilter( aInFile, aOutFile )
{
    pLst = new ByteStringList;
    pTnrLst = new ByteStringList;
}

MkFilter::~MkFilter()
{
    delete pTnrLst;
    delete pLst;
}

ByteString MkFilter::aTnr="$(TNR)";

void MkFilter::Filter()
{
    char aLineBuf[LINE_LEN];
    int nState = 0;
    BOOL bNew = TRUE;

    while(( fgets(aLineBuf, LINE_LEN, pIn)) != NULL )
    {
        ByteString aLine( aLineBuf );
        //fprintf(stderr, "aLine :%s\n", aLine.GetBuffer());
        if ( aLine.Search("mkfilter1" ) != STRING_NOTFOUND )
        {
            // Zeilen unterdruecken
            fprintf( stderr, "mkfilter1\n" );
            nState = 0;
        }
        else if ( aLine.Search("unroll begin" ) != STRING_NOTFOUND )
        {
            // Zeilen raus schreiben mit ersetzen von $(TNR) nach int n
            fprintf( stderr, "\nunroll begin\n" );
            nState = 1;
        }
        ;

        if ( nState == 0  )
        {
            fprintf( stderr, "." );
            MkLine *pMkLine = new MkLine();
            ByteString *pStr = new ByteString( aLineBuf );
            pMkLine->aLine = *pStr;
            pMkLine->bOut = FALSE;

            pLst->Insert( pMkLine, LIST_APPEND );
        }
        else if ( nState == 1 )
        {
            BOOL bInTnrList = TRUE;
            fprintf( stderr, ":" );
            MkLine *pMkLine = new MkLine();
            if ( aLine.Search("unroll end") != STRING_NOTFOUND )
            {
                fprintf( stderr, ";\nunroll end\n" );
                MkLine *p_MkLine = new MkLine();
                p_MkLine->bHier = TRUE;
                ByteString *pByteString = new ByteString("# do not delete this line === mkfilter3i\n");
                p_MkLine->aLine = *pByteString;
                p_MkLine->bOut = FALSE;
                p_MkLine->pPrivateTnrLst = pTnrLst;
                pTnrLst = new ByteStringList();
                pLst->Insert( p_MkLine, LIST_APPEND );
                nState = 0;
                bInTnrList = FALSE;
            }
            ByteString *pStr = new ByteString( aLineBuf );
            pMkLine->aLine = *pStr;
            pMkLine->bOut = FALSE;

            if ( bInTnrList )
                pTnrLst->Insert( pMkLine, LIST_APPEND );
        }
        else
            /* Zeilen ignorieren */;
    }   // End Of File
    fprintf( stderr, "\n" );

    // das File wieder ausgegeben
    ULONG nLines = pLst->Count();
    for ( ULONG j=0; j<nLines; j++ )
    {
        MkLine *pLine = pLst->GetObject( j );
        if ( pLine->bHier )
        {
            // die List n - Mal abarbeiten
            for ( USHORT n=1; n<11; n++)
            {
                ULONG nCount = pLine->pPrivateTnrLst->Count();
                for ( ULONG i=0; i<nCount; i++ )
                {
                    MkLine *pMkLine = pLine->pPrivateTnrLst->GetObject(i);
                    ByteString aLine = pMkLine->aLine;
                    if ( pMkLine->bOut );
                    {
                        while( aLine.SearchAndReplace( aTnr, ByteString::CreateFromInt32( n )) != (USHORT)-1 );
                        fputs( aLine.GetBuffer(), pOut );
                        fprintf( stderr, "o" );
                    }
                }
            }
            if ( pLine->pPrivateTnrLst != NULL )
                delete pLine->pPrivateTnrLst;
            pLine->pPrivateTnrLst = NULL;
        }
        if ( pLine->bOut )
                fputs(pLine->aLine.GetBuffer(), pOut );
    }
    fprintf( stderr, "\n" );
}

int main( int argc, char **argv )
{
    int nRet = 0;

    TextFilter *pFlt = new MkFilter();
    pFlt->Execute();
    delete pFlt;

    return nRet;
}
<commit_msg>Corrected include paths for string.hxx and list.hxx<commit_after>/*************************************************************************
 *
 *  $RCSfile: mkfilt.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: oisin $ $Date: 2000-11-03 13:39:54 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>

#include <../../inc/string.hxx>
#include <../../inc/list.hxx>

class TextFilter
{
protected:
    FILE            *pIn, *pOut;
    virtual void    Filter();
public:
                    TextFilter( ByteString aInFile = "stdin",
                        ByteString aOutFile = "stdout" );
    virtual         ~TextFilter();

    virtual void    Execute();
};

TextFilter::TextFilter( ByteString aInFile, ByteString aOutFile )
{
    if ( aInFile == "stdin" )
        pIn = stdin;
    else
        if (( pIn = fopen( aInFile.GetBuffer(), "r" )) == NULL )
            printf( "Can't read %s\n", aInFile.GetBuffer() );

    if ( aOutFile == "stdout" )
        pOut = stdout;
    else
        if (( pOut = fopen( aOutFile.GetBuffer(), "w" )) == NULL )
            printf( "Can't write %s\n", aOutFile.GetBuffer() );
}

TextFilter::~TextFilter()
{
    fclose( pOut );
    fclose( pIn );
}

void TextFilter::Execute()
{
    Filter();
}

void TextFilter::Filter()
{
    char c;
    while ( (c = fgetc( pIn )) != EOF )
        fputc( c, pOut );
}

#define LINE_LEN 2048

class ByteStringList;

class MkLine
{
public:
    ByteString          aLine;
    ByteStringList*     pPrivateTnrLst;
    BOOL            bOut;
    BOOL            bHier;

                    MkLine();
};

MkLine::MkLine()
{
    bOut = FALSE;
    bHier = FALSE;
    pPrivateTnrLst = NULL;
}

DECLARE_LIST( ByteStringList, MkLine * );

class MkFilter : public TextFilter
{
    static ByteString   aTnr;
    ByteStringList      *pLst;
    ByteStringList      *pTnrLst;
protected:
    virtual void    Filter();
public:
                    MkFilter( ByteString aInFile = "stdin", ByteString aOutFile = "stdout");
                    ~MkFilter();
};

MkFilter::MkFilter( ByteString aInFile, ByteString aOutFile ) :
    TextFilter( aInFile, aOutFile )
{
    pLst = new ByteStringList;
    pTnrLst = new ByteStringList;
}

MkFilter::~MkFilter()
{
    delete pTnrLst;
    delete pLst;
}

ByteString MkFilter::aTnr="$(TNR)";

void MkFilter::Filter()
{
    char aLineBuf[LINE_LEN];
    int nState = 0;
    BOOL bNew = TRUE;

    while(( fgets(aLineBuf, LINE_LEN, pIn)) != NULL )
    {
        ByteString aLine( aLineBuf );
        //fprintf(stderr, "aLine :%s\n", aLine.GetBuffer());
        if ( aLine.Search("mkfilter1" ) != STRING_NOTFOUND )
        {
            // Zeilen unterdruecken
            fprintf( stderr, "mkfilter1\n" );
            nState = 0;
        }
        else if ( aLine.Search("unroll begin" ) != STRING_NOTFOUND )
        {
            // Zeilen raus schreiben mit ersetzen von $(TNR) nach int n
            fprintf( stderr, "\nunroll begin\n" );
            nState = 1;
        }
        ;

        if ( nState == 0  )
        {
            fprintf( stderr, "." );
            MkLine *pMkLine = new MkLine();
            ByteString *pStr = new ByteString( aLineBuf );
            pMkLine->aLine = *pStr;
            pMkLine->bOut = FALSE;

            pLst->Insert( pMkLine, LIST_APPEND );
        }
        else if ( nState == 1 )
        {
            BOOL bInTnrList = TRUE;
            fprintf( stderr, ":" );
            MkLine *pMkLine = new MkLine();
            if ( aLine.Search("unroll end") != STRING_NOTFOUND )
            {
                fprintf( stderr, ";\nunroll end\n" );
                MkLine *p_MkLine = new MkLine();
                p_MkLine->bHier = TRUE;
                ByteString *pByteString = new ByteString("# do not delete this line === mkfilter3i\n");
                p_MkLine->aLine = *pByteString;
                p_MkLine->bOut = FALSE;
                p_MkLine->pPrivateTnrLst = pTnrLst;
                pTnrLst = new ByteStringList();
                pLst->Insert( p_MkLine, LIST_APPEND );
                nState = 0;
                bInTnrList = FALSE;
            }
            ByteString *pStr = new ByteString( aLineBuf );
            pMkLine->aLine = *pStr;
            pMkLine->bOut = FALSE;

            if ( bInTnrList )
                pTnrLst->Insert( pMkLine, LIST_APPEND );
        }
        else
            /* Zeilen ignorieren */;
    }   // End Of File
    fprintf( stderr, "\n" );

    // das File wieder ausgegeben
    ULONG nLines = pLst->Count();
    for ( ULONG j=0; j<nLines; j++ )
    {
        MkLine *pLine = pLst->GetObject( j );
        if ( pLine->bHier )
        {
            // die List n - Mal abarbeiten
            for ( USHORT n=1; n<11; n++)
            {
                ULONG nCount = pLine->pPrivateTnrLst->Count();
                for ( ULONG i=0; i<nCount; i++ )
                {
                    MkLine *pMkLine = pLine->pPrivateTnrLst->GetObject(i);
                    ByteString aLine = pMkLine->aLine;
                    if ( pMkLine->bOut );
                    {
                        while( aLine.SearchAndReplace( aTnr, ByteString::CreateFromInt32( n )) != (USHORT)-1 );
                        fputs( aLine.GetBuffer(), pOut );
                        fprintf( stderr, "o" );
                    }
                }
            }
            if ( pLine->pPrivateTnrLst != NULL )
                delete pLine->pPrivateTnrLst;
            pLine->pPrivateTnrLst = NULL;
        }
        if ( pLine->bOut )
                fputs(pLine->aLine.GetBuffer(), pOut );
    }
    fprintf( stderr, "\n" );
}

int main( int argc, char **argv )
{
    int nRet = 0;

    TextFilter *pFlt = new MkFilter();
    pFlt->Execute();
    delete pFlt;

    return nRet;
}
<|endoftext|>


<commit_before>//===- OptimizerDriver.cpp - Allow BugPoint to run passes safely ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines an interface that allows bugpoint to run various passes
// without the threat of a buggy pass corrupting bugpoint (of course, bugpoint
// may have its own bugs, but that's another story...).  It achieves this by
// forking a copy of itself and having the child process do the optimizations.
// If this client dies, we can always fork a new one.  :)
//
//===----------------------------------------------------------------------===//

// Note: as a short term hack, the old Unix-specific code and platform-
// independent code co-exist via conditional compilation until it is verified
// that the new code works correctly on Unix.

#include "BugDriver.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/System/Path.h"
#include "llvm/System/Program.h"
#include "llvm/Config/alloca.h"

#define DONT_GET_PLUGIN_LOADER_OPTION
#include "llvm/Support/PluginLoader.h"

#include <fstream>
using namespace llvm;

namespace {
  // ChildOutput - This option captures the name of the child output file that
  // is set up by the parent bugpoint process
  cl::opt<std::string> ChildOutput("child-output", cl::ReallyHidden);
}

/// writeProgramToFile - This writes the current "Program" to the named bytecode
/// file.  If an error occurs, true is returned.
///
bool BugDriver::writeProgramToFile(const std::string &Filename,
                                   Module *M) const {
  std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
                               std::ios::binary;
  std::ofstream Out(Filename.c_str(), io_mode);
  if (!Out.good()) return true;
  WriteBytecodeToFile(M ? M : Program, Out, /*compression=*/true);
  return false;
}

/// EmitProgressBytecode - This function is used to output the current Program
/// to a file named "bugpoint-ID.bc".
///
void BugDriver::EmitProgressBytecode(const std::string &ID, bool NoFlyer) {
  // Output the input to the current pass to a bytecode file, emit a message
  // telling the user how to reproduce it: opt -foo blah.bc
  //
  std::string Filename = "bugpoint-" + ID + ".bc";
  if (writeProgramToFile(Filename)) {
    std::cerr <<  "Error opening file '" << Filename << "' for writing!\n";
    return;
  }

  std::cout << "Emitted bytecode to '" << Filename << "'\n";
  if (NoFlyer || PassesToRun.empty()) return;
  std::cout << "\n*** You can reproduce the problem with: ";

  unsigned PassType = PassesToRun[0]->getPassType();
  for (unsigned i = 1, e = PassesToRun.size(); i != e; ++i)
    PassType &= PassesToRun[i]->getPassType();

  if (PassType & PassInfo::Analysis)
    std::cout << "analyze";
  else if (PassType & PassInfo::Optimization)
    std::cout << "opt";
  else
    std::cout << "bugpoint";
  std::cout << " " << Filename << " ";
  std::cout << getPassesString(PassesToRun) << "\n";
}

int BugDriver::runPassesAsChild(const std::vector<const PassInfo*> &Passes) {

  std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
                               std::ios::binary;
  std::ofstream OutFile(ChildOutput.c_str(), io_mode);
  if (!OutFile.good()) {
    std::cerr << "Error opening bytecode file: " << ChildOutput << "\n";
    return 1;
  }

  PassManager PM;
  // Make sure that the appropriate target data is always used...
  PM.add(new TargetData("bugpoint", Program));

  for (unsigned i = 0, e = Passes.size(); i != e; ++i) {
    if (Passes[i]->getNormalCtor())
      PM.add(Passes[i]->getNormalCtor()());
    else
      std::cerr << "Cannot create pass yet: " << Passes[i]->getPassName()
                << "\n";
  }
  // Check that the module is well formed on completion of optimization
  PM.add(createVerifierPass());

  // Write bytecode out to disk as the last step...
  PM.add(new WriteBytecodePass(&OutFile));

  // Run all queued passes.
  PM.run(*Program);

  return 0;
}

/// runPasses - Run the specified passes on Program, outputting a bytecode file
/// and writing the filename into OutputFile if successful.  If the
/// optimizations fail for some reason (optimizer crashes), return true,
/// otherwise return false.  If DeleteOutput is set to true, the bytecode is
/// deleted on success, and the filename string is undefined.  This prints to
/// cout a single line message indicating whether compilation was successful or
/// failed.
///
bool BugDriver::runPasses(const std::vector<const PassInfo*> &Passes,
                          std::string &OutputFilename, bool DeleteOutput,
                          bool Quiet) const{
  // setup the output file name
  std::cout << std::flush;
  sys::Path uniqueFilename("bugpoint-output.bc");
  uniqueFilename.makeUnique();
  OutputFilename = uniqueFilename.toString();

  // set up the input file name
  sys::Path inputFilename("bugpoint-input.bc");
  inputFilename.makeUnique();
  std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
                               std::ios::binary;
  std::ofstream InFile(inputFilename.c_str(), io_mode);
  if (!InFile.good()) {
    std::cerr << "Error opening bytecode file: " << inputFilename << "\n";
    return(1);
  }
  WriteBytecodeToFile(Program,InFile,false);
  InFile.close();

  // setup the child process' arguments
  const char** args = (const char**)
    alloca(sizeof(const char*) *
	   (Passes.size()+10+2*PluginLoader::getNumPlugins()));
  int n = 0;
  args[n++] = ToolName.c_str();
  args[n++] = "-as-child";
  args[n++] = "-child-output";
  args[n++] = OutputFilename.c_str();
  std::vector<std::string> pass_args;
  for (unsigned i = 0, e = PluginLoader::getNumPlugins(); i != e; ++i) {
    pass_args.push_back( std::string("-load"));
    pass_args.push_back( PluginLoader::getPlugin(i));
  }
  for (std::vector<const PassInfo*>::const_iterator I = Passes.begin(),
       E = Passes.end(); I != E; ++I )
    pass_args.push_back( std::string("-") + (*I)->getPassArgument() );
  for (std::vector<std::string>::const_iterator I = pass_args.begin(),
       E = pass_args.end(); I != E; ++I )
    args[n++] = I->c_str();
  args[n++] = inputFilename.c_str();
  args[n++] = 0;

  sys::Path prog(sys::Program::FindProgramByName(ToolName));
  int result = sys::Program::ExecuteAndWait(prog,args);

  // If we are supposed to delete the bytecode file or if the passes crashed,
  // remove it now.  This may fail if the file was never created, but that's ok.
  if (DeleteOutput || result != 0)
    sys::Path(OutputFilename).eraseFromDisk();

  // Remove the temporary input file as well
  inputFilename.eraseFromDisk();

  if (!Quiet) {
    if (result == 0)
      std::cout << "Success!\n";
    else if (result > 0)
      std::cout << "Exited with error code '" << result << "'\n";
    else if (result < 0)
      std::cout << "Crashed with signal #" << abs(result) << "\n";
    if (result & 0x01000000)
      std::cout << "Dumped core\n";
  }

  // Was the child successful?
  return result != 0;
}

/// runPassesOn - Carefully run the specified set of pass on the specified
/// module, returning the transformed module on success, or a null pointer on
/// failure.
Module *BugDriver::runPassesOn(Module *M,
                               const std::vector<const PassInfo*> &Passes,
                               bool AutoDebugCrashes) {
  Module *OldProgram = swapProgramIn(M);
  std::string BytecodeResult;
  if (runPasses(Passes, BytecodeResult, false/*delete*/, true/*quiet*/)) {
    if (AutoDebugCrashes) {
      std::cerr << " Error running this sequence of passes"
                << " on the input program!\n";
      delete OldProgram;
      EmitProgressBytecode("pass-error",  false);
      exit(debugOptimizerCrash());
    }
    swapProgramIn(OldProgram);
    return 0;
  }

  // Restore the current program.
  swapProgramIn(OldProgram);

  Module *Ret = ParseInputFile(BytecodeResult);
  if (Ret == 0) {
    std::cerr << getToolName() << ": Error reading bytecode file '"
              << BytecodeResult << "'!\n";
    exit(1);
  }
  sys::Path(BytecodeResult).eraseFromDisk();  // No longer need the file on disk
  return Ret;
}
<commit_msg>Fix a bug found by inspection.<commit_after>//===- OptimizerDriver.cpp - Allow BugPoint to run passes safely ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines an interface that allows bugpoint to run various passes
// without the threat of a buggy pass corrupting bugpoint (of course, bugpoint
// may have its own bugs, but that's another story...).  It achieves this by
// forking a copy of itself and having the child process do the optimizations.
// If this client dies, we can always fork a new one.  :)
//
//===----------------------------------------------------------------------===//

// Note: as a short term hack, the old Unix-specific code and platform-
// independent code co-exist via conditional compilation until it is verified
// that the new code works correctly on Unix.

#include "BugDriver.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/System/Path.h"
#include "llvm/System/Program.h"
#include "llvm/Config/alloca.h"

#define DONT_GET_PLUGIN_LOADER_OPTION
#include "llvm/Support/PluginLoader.h"

#include <fstream>
using namespace llvm;

namespace {
  // ChildOutput - This option captures the name of the child output file that
  // is set up by the parent bugpoint process
  cl::opt<std::string> ChildOutput("child-output", cl::ReallyHidden);
}

/// writeProgramToFile - This writes the current "Program" to the named bytecode
/// file.  If an error occurs, true is returned.
///
bool BugDriver::writeProgramToFile(const std::string &Filename,
                                   Module *M) const {
  std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
                               std::ios::binary;
  std::ofstream Out(Filename.c_str(), io_mode);
  if (!Out.good()) return true;
  try {
    WriteBytecodeToFile(M ? M : Program, Out, /*compression=*/true);
  } catch (...) {
    return true;
  }
  return false;
}

/// EmitProgressBytecode - This function is used to output the current Program
/// to a file named "bugpoint-ID.bc".
///
void BugDriver::EmitProgressBytecode(const std::string &ID, bool NoFlyer) {
  // Output the input to the current pass to a bytecode file, emit a message
  // telling the user how to reproduce it: opt -foo blah.bc
  //
  std::string Filename = "bugpoint-" + ID + ".bc";
  if (writeProgramToFile(Filename)) {
    std::cerr <<  "Error opening file '" << Filename << "' for writing!\n";
    return;
  }

  std::cout << "Emitted bytecode to '" << Filename << "'\n";
  if (NoFlyer || PassesToRun.empty()) return;
  std::cout << "\n*** You can reproduce the problem with: ";

  unsigned PassType = PassesToRun[0]->getPassType();
  for (unsigned i = 1, e = PassesToRun.size(); i != e; ++i)
    PassType &= PassesToRun[i]->getPassType();

  if (PassType & PassInfo::Analysis)
    std::cout << "analyze";
  else if (PassType & PassInfo::Optimization)
    std::cout << "opt";
  else
    std::cout << "bugpoint";
  std::cout << " " << Filename << " ";
  std::cout << getPassesString(PassesToRun) << "\n";
}

int BugDriver::runPassesAsChild(const std::vector<const PassInfo*> &Passes) {

  std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
                               std::ios::binary;
  std::ofstream OutFile(ChildOutput.c_str(), io_mode);
  if (!OutFile.good()) {
    std::cerr << "Error opening bytecode file: " << ChildOutput << "\n";
    return 1;
  }

  PassManager PM;
  // Make sure that the appropriate target data is always used...
  PM.add(new TargetData("bugpoint", Program));

  for (unsigned i = 0, e = Passes.size(); i != e; ++i) {
    if (Passes[i]->getNormalCtor())
      PM.add(Passes[i]->getNormalCtor()());
    else
      std::cerr << "Cannot create pass yet: " << Passes[i]->getPassName()
                << "\n";
  }
  // Check that the module is well formed on completion of optimization
  PM.add(createVerifierPass());

  // Write bytecode out to disk as the last step...
  PM.add(new WriteBytecodePass(&OutFile));

  // Run all queued passes.
  PM.run(*Program);

  return 0;
}

/// runPasses - Run the specified passes on Program, outputting a bytecode file
/// and writing the filename into OutputFile if successful.  If the
/// optimizations fail for some reason (optimizer crashes), return true,
/// otherwise return false.  If DeleteOutput is set to true, the bytecode is
/// deleted on success, and the filename string is undefined.  This prints to
/// cout a single line message indicating whether compilation was successful or
/// failed.
///
bool BugDriver::runPasses(const std::vector<const PassInfo*> &Passes,
                          std::string &OutputFilename, bool DeleteOutput,
                          bool Quiet) const{
  // setup the output file name
  std::cout << std::flush;
  sys::Path uniqueFilename("bugpoint-output.bc");
  uniqueFilename.makeUnique();
  OutputFilename = uniqueFilename.toString();

  // set up the input file name
  sys::Path inputFilename("bugpoint-input.bc");
  inputFilename.makeUnique();
  std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
                               std::ios::binary;
  std::ofstream InFile(inputFilename.c_str(), io_mode);
  if (!InFile.good()) {
    std::cerr << "Error opening bytecode file: " << inputFilename << "\n";
    return(1);
  }
  WriteBytecodeToFile(Program,InFile,false);
  InFile.close();

  // setup the child process' arguments
  const char** args = (const char**)
    alloca(sizeof(const char*) *
	   (Passes.size()+10+2*PluginLoader::getNumPlugins()));
  int n = 0;
  args[n++] = ToolName.c_str();
  args[n++] = "-as-child";
  args[n++] = "-child-output";
  args[n++] = OutputFilename.c_str();
  std::vector<std::string> pass_args;
  for (unsigned i = 0, e = PluginLoader::getNumPlugins(); i != e; ++i) {
    pass_args.push_back( std::string("-load"));
    pass_args.push_back( PluginLoader::getPlugin(i));
  }
  for (std::vector<const PassInfo*>::const_iterator I = Passes.begin(),
       E = Passes.end(); I != E; ++I )
    pass_args.push_back( std::string("-") + (*I)->getPassArgument() );
  for (std::vector<std::string>::const_iterator I = pass_args.begin(),
       E = pass_args.end(); I != E; ++I )
    args[n++] = I->c_str();
  args[n++] = inputFilename.c_str();
  args[n++] = 0;

  sys::Path prog(sys::Program::FindProgramByName(ToolName));
  int result = sys::Program::ExecuteAndWait(prog,args);

  // If we are supposed to delete the bytecode file or if the passes crashed,
  // remove it now.  This may fail if the file was never created, but that's ok.
  if (DeleteOutput || result != 0)
    sys::Path(OutputFilename).eraseFromDisk();

  // Remove the temporary input file as well
  inputFilename.eraseFromDisk();

  if (!Quiet) {
    if (result == 0)
      std::cout << "Success!\n";
    else if (result > 0)
      std::cout << "Exited with error code '" << result << "'\n";
    else if (result < 0)
      std::cout << "Crashed with signal #" << abs(result) << "\n";
    if (result & 0x01000000)
      std::cout << "Dumped core\n";
  }

  // Was the child successful?
  return result != 0;
}

/// runPassesOn - Carefully run the specified set of pass on the specified
/// module, returning the transformed module on success, or a null pointer on
/// failure.
Module *BugDriver::runPassesOn(Module *M,
                               const std::vector<const PassInfo*> &Passes,
                               bool AutoDebugCrashes) {
  Module *OldProgram = swapProgramIn(M);
  std::string BytecodeResult;
  if (runPasses(Passes, BytecodeResult, false/*delete*/, true/*quiet*/)) {
    if (AutoDebugCrashes) {
      std::cerr << " Error running this sequence of passes"
                << " on the input program!\n";
      delete OldProgram;
      EmitProgressBytecode("pass-error",  false);
      exit(debugOptimizerCrash());
    }
    swapProgramIn(OldProgram);
    return 0;
  }

  // Restore the current program.
  swapProgramIn(OldProgram);

  Module *Ret = ParseInputFile(BytecodeResult);
  if (Ret == 0) {
    std::cerr << getToolName() << ": Error reading bytecode file '"
              << BytecodeResult << "'!\n";
    exit(1);
  }
  sys::Path(BytecodeResult).eraseFromDisk();  // No longer need the file on disk
  return Ret;
}
<|endoftext|>


<commit_before>//===-- MIUtilStreamStdin.cpp -----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// In-house headers:
#include "MICmnStreamStdin.h"
#include "MICmnStreamStdout.h"
#include "MICmnResources.h"
#include "MICmnLog.h"
#include "MIUtilSingletonHelper.h"
#include <string.h> // For std::strerror()

//++ ------------------------------------------------------------------------------------
// Details: CMICmnStreamStdin constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmnStreamStdin::CMICmnStreamStdin(void)
    : m_strPromptCurrent("(gdb)")
    , m_bShowPrompt(true)
    , m_bRedrawPrompt(true)
    , m_pCmdBuffer(nullptr)
{
}

//++ ------------------------------------------------------------------------------------
// Details: CMICmnStreamStdin destructor.
// Type:    Overridable.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmnStreamStdin::~CMICmnStreamStdin(void)
{
    Shutdown();
}

//++ ------------------------------------------------------------------------------------
// Details: Initialize resources for *this Stdin stream.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::Initialize(void)
{
    m_clientUsageRefCnt++;

    if (m_bInitialized)
        return MIstatus::success;

    bool bOk = MIstatus::success;
    CMIUtilString errMsg;

    // Note initialisation order is important here as some resources depend on previous
    MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
    MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);

    if (bOk)
    {
        m_pCmdBuffer = new MIchar[m_constBufferSize];
    }
    else
    {
        CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_STREAMSTDIN), errMsg.c_str()));
        SetErrorDescription(strInitError);

        return MIstatus::failure;
    }
    m_bInitialized = bOk;

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// Details: Release resources for *this Stdin stream.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::Shutdown(void)
{
    if (--m_clientUsageRefCnt > 0)
        return MIstatus::success;

    if (!m_bInitialized)
        return MIstatus::success;

    m_bInitialized = false;

    ClrErrorDescription();

    if (m_pCmdBuffer != nullptr)
    {
        delete[] m_pCmdBuffer;
        m_pCmdBuffer = nullptr;
    }

    bool bOk = MIstatus::success;
    CMIUtilString errMsg;

    MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
    MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);

    if (!bOk)
    {
        SetErrorDescriptionn(MIRSRC(IDE_MI_SHTDWN_ERR_STREAMSTDIN), errMsg.c_str());
    }

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// Details: Validate and set the text that forms the prompt on the command line.
// Type:    Method.
// Args:    vNewPrompt  - (R) Text description.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::SetPrompt(const CMIUtilString &vNewPrompt)
{
    if (vNewPrompt.empty())
    {
        const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_STDIN_ERR_INVALID_PROMPT), vNewPrompt.c_str()));
        CMICmnStreamStdout::Instance().Write(msg);
        return MIstatus::failure;
    }

    m_strPromptCurrent = vNewPrompt;

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// Details: Retrieve the command line prompt text currently being used.
// Type:    Method.
// Args:    None.
// Return:  const CMIUtilString & - Functional failed.
// Throws:  None.
//--
const CMIUtilString &
CMICmnStreamStdin::GetPrompt(void) const
{
    return m_strPromptCurrent;
}

//++ ------------------------------------------------------------------------------------
// Details: Set whether to display optional command line prompt. The prompt is output to
//          stdout. Disable it when this may interfere with the client reading stdout as
//          input and it tries to interpret the prompt text to.
// Type:    Method.
// Args:    vbYes   - (R) True = Yes prompt is shown/output to the user (stdout), false = no prompt.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
void
CMICmnStreamStdin::SetEnablePrompt(const bool vbYes)
{
    m_bShowPrompt = vbYes;
}

//++ ------------------------------------------------------------------------------------
// Details: Get whether to display optional command line prompt. The prompt is output to
//          stdout. Disable it when this may interfere with the client reading stdout as
//          input and it tries to interpret the prompt text to.
// Type:    Method.
// Args:    None.
// Return:  bool - True = Yes prompt is shown/output to the user (stdout), false = no prompt.
// Throws:  None.
//--
bool
CMICmnStreamStdin::GetEnablePrompt(void) const
{
    return m_bShowPrompt;
}

//++ ------------------------------------------------------------------------------------
// Details: Wait on new line of data from stdin stream (completed by '\n' or '\r').
// Type:    Method.
// Args:    vwErrMsg    - (W) Empty string ok or error description.
// Return:  MIchar * - text buffer pointer or NULL on failure.
// Throws:  None.
//--
const MIchar *
CMICmnStreamStdin::ReadLine(CMIUtilString &vwErrMsg)
{
    vwErrMsg.clear();

    // Read user input
    const MIchar *pText = ::fgets(&m_pCmdBuffer[0], m_constBufferSize, stdin);
    if (pText == nullptr)
    {
        if (::ferror(stdin) != 0)
            vwErrMsg = ::strerror(errno);
        return nullptr;
    }

    // Strip off new line characters
    for (MIchar *pI = m_pCmdBuffer; *pI != '\0'; pI++)
    {
        if ((*pI == '\n') || (*pI == '\r'))
        {
            *pI = '\0';
            break;
        }
    }

    return pText;
}
<commit_msg>Fix infinite loop when ^D was pressed (MI)<commit_after>//===-- MIUtilStreamStdin.cpp -----------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// In-house headers:
#include "MICmnStreamStdin.h"
#include "MICmnStreamStdout.h"
#include "MICmnResources.h"
#include "MICmnLog.h"
#include "MIDriver.h"
#include "MIUtilSingletonHelper.h"
#include <string.h> // For std::strerror()

//++ ------------------------------------------------------------------------------------
// Details: CMICmnStreamStdin constructor.
// Type:    Method.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmnStreamStdin::CMICmnStreamStdin(void)
    : m_strPromptCurrent("(gdb)")
    , m_bShowPrompt(true)
    , m_bRedrawPrompt(true)
    , m_pCmdBuffer(nullptr)
{
}

//++ ------------------------------------------------------------------------------------
// Details: CMICmnStreamStdin destructor.
// Type:    Overridable.
// Args:    None.
// Return:  None.
// Throws:  None.
//--
CMICmnStreamStdin::~CMICmnStreamStdin(void)
{
    Shutdown();
}

//++ ------------------------------------------------------------------------------------
// Details: Initialize resources for *this Stdin stream.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::Initialize(void)
{
    m_clientUsageRefCnt++;

    if (m_bInitialized)
        return MIstatus::success;

    bool bOk = MIstatus::success;
    CMIUtilString errMsg;

    // Note initialisation order is important here as some resources depend on previous
    MI::ModuleInit<CMICmnLog>(IDS_MI_INIT_ERR_LOG, bOk, errMsg);
    MI::ModuleInit<CMICmnResources>(IDS_MI_INIT_ERR_RESOURCES, bOk, errMsg);

    if (bOk)
    {
        m_pCmdBuffer = new MIchar[m_constBufferSize];
    }
    else
    {
        CMIUtilString strInitError(CMIUtilString::Format(MIRSRC(IDS_MI_INIT_ERR_STREAMSTDIN), errMsg.c_str()));
        SetErrorDescription(strInitError);

        return MIstatus::failure;
    }
    m_bInitialized = bOk;

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// Details: Release resources for *this Stdin stream.
// Type:    Method.
// Args:    None.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::Shutdown(void)
{
    if (--m_clientUsageRefCnt > 0)
        return MIstatus::success;

    if (!m_bInitialized)
        return MIstatus::success;

    m_bInitialized = false;

    ClrErrorDescription();

    if (m_pCmdBuffer != nullptr)
    {
        delete[] m_pCmdBuffer;
        m_pCmdBuffer = nullptr;
    }

    bool bOk = MIstatus::success;
    CMIUtilString errMsg;

    MI::ModuleShutdown<CMICmnResources>(IDE_MI_SHTDWN_ERR_RESOURCES, bOk, errMsg);
    MI::ModuleShutdown<CMICmnLog>(IDS_MI_SHTDWN_ERR_LOG, bOk, errMsg);

    if (!bOk)
    {
        SetErrorDescriptionn(MIRSRC(IDE_MI_SHTDWN_ERR_STREAMSTDIN), errMsg.c_str());
    }

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// Details: Validate and set the text that forms the prompt on the command line.
// Type:    Method.
// Args:    vNewPrompt  - (R) Text description.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
bool
CMICmnStreamStdin::SetPrompt(const CMIUtilString &vNewPrompt)
{
    if (vNewPrompt.empty())
    {
        const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_STDIN_ERR_INVALID_PROMPT), vNewPrompt.c_str()));
        CMICmnStreamStdout::Instance().Write(msg);
        return MIstatus::failure;
    }

    m_strPromptCurrent = vNewPrompt;

    return MIstatus::success;
}

//++ ------------------------------------------------------------------------------------
// Details: Retrieve the command line prompt text currently being used.
// Type:    Method.
// Args:    None.
// Return:  const CMIUtilString & - Functional failed.
// Throws:  None.
//--
const CMIUtilString &
CMICmnStreamStdin::GetPrompt(void) const
{
    return m_strPromptCurrent;
}

//++ ------------------------------------------------------------------------------------
// Details: Set whether to display optional command line prompt. The prompt is output to
//          stdout. Disable it when this may interfere with the client reading stdout as
//          input and it tries to interpret the prompt text to.
// Type:    Method.
// Args:    vbYes   - (R) True = Yes prompt is shown/output to the user (stdout), false = no prompt.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
void
CMICmnStreamStdin::SetEnablePrompt(const bool vbYes)
{
    m_bShowPrompt = vbYes;
}

//++ ------------------------------------------------------------------------------------
// Details: Get whether to display optional command line prompt. The prompt is output to
//          stdout. Disable it when this may interfere with the client reading stdout as
//          input and it tries to interpret the prompt text to.
// Type:    Method.
// Args:    None.
// Return:  bool - True = Yes prompt is shown/output to the user (stdout), false = no prompt.
// Throws:  None.
//--
bool
CMICmnStreamStdin::GetEnablePrompt(void) const
{
    return m_bShowPrompt;
}

//++ ------------------------------------------------------------------------------------
// Details: Wait on new line of data from stdin stream (completed by '\n' or '\r').
// Type:    Method.
// Args:    vwErrMsg    - (W) Empty string ok or error description.
// Return:  MIchar * - text buffer pointer or NULL on failure.
// Throws:  None.
//--
const MIchar *
CMICmnStreamStdin::ReadLine(CMIUtilString &vwErrMsg)
{
    vwErrMsg.clear();

    // Read user input
    const MIchar *pText = ::fgets(&m_pCmdBuffer[0], m_constBufferSize, stdin);
    if (pText == nullptr)
    {
        if (::feof(stdin))
        {
            const bool bForceExit = true;
            CMIDriver::Instance().SetExitApplicationFlag(bForceExit);
        }
        else if (::ferror(stdin) != 0)
            vwErrMsg = ::strerror(errno);
        return nullptr;
    }

    // Strip off new line characters
    for (MIchar *pI = m_pCmdBuffer; *pI != '\0'; pI++)
    {
        if ((*pI == '\n') || (*pI == '\r'))
        {
            *pI = '\0';
            break;
        }
    }

    return pText;
}
<|endoftext|>


<commit_before>#ifndef GENERIC_FORWARDER_HPP
# define GENERIC_FORWARDER_HPP
# pragma once

#include <cassert>

// ::std::size_t
#include <cstddef>

#include <type_traits>

#include <utility>

namespace generic
{

namespace detail
{

namespace forwarder
{

template <typename ...A>
struct argument_types
{
};

template <typename A>
struct argument_types
{
  using argument_type = A;
};

template <typename A, typename B>
struct argument_types
{
  using first_argument_type = A;
  using second_argument_type = B;
};

}

}

template<typename F, ::std::size_t N = 4 * sizeof(void*)>
class forwarder;

template<typename R, typename ...A, ::std::size_t N>
class forwarder<R (A...), N> : public detail::forwarder::argument_types
{
  R (*stub_)(void const*, A&&...){};

  typename ::std::aligned_storage<N>::type store_;

  template<typename T, typename ...U, ::std::size_t M>
  friend bool operator==(forwarder<T (U...), M> const&,
    ::std::nullptr_t) noexcept;
  template<typename T, typename ...U, ::std::size_t M>
  friend bool operator==(::std::nullptr_t,
    forwarder<T (U...), M> const&) noexcept;

  template<typename T, typename ...U, ::std::size_t M>
  friend bool operator!=(forwarder<T (U...), M> const&,
    ::std::nullptr_t) noexcept;
  template<typename T, typename ...U, ::std::size_t M>
  friend bool operator!=(::std::nullptr_t,
    forwarder<T (U...), M> const&) noexcept;

public:
  using result_type	= R;

public:
  forwarder() = default;

  forwarder(forwarder const&) = default;

  template<typename T, typename ...U,
    typename = typename ::std::enable_if<
      !::std::is_same<forwarder, typename ::std::decay<T>::type>{}
    >::type
  >
  forwarder(T&& t, U&& ...u) noexcept
  {
    assign(::std::forward<T>(t), ::std::forward(u)...);
  }

  forwarder& operator=(forwarder const&) = default;

  forwarder& operator=(forwarder&&) = default;

  template<typename T, typename ...U,
    typename = typename ::std::enable_if<
      !::std::is_same<forwarder, typename ::std::decay<T>::type>{}
    >::type
  >
  forwarder(T&& t, U&& ...u) noexcept
  {
    assign(::std::forward<T>(t), ::std::forward(u)...);

    return *this;
  }

  explicit operator bool() const noexcept { return stub_; }

  R operator()(A... args) const
    noexcept(noexcept(stub_(&store_, ::std::forward(args)...)))
  {
    //assert(stub_);
    return stub_(&store_, ::std::forward(args)...);
  }

  template <typename T>
  void assign(T&& f) noexcept
  {
    using functor_type = typename ::std::decay<T>::type;

    static_assert(sizeof(functor_type) <= sizeof(store_),
      "functor too large");
    static_assert(::std::is_trivially_copyable<T>{},
      "functor not trivially copyable");

    ::new (static_cast<void*>(&store_)) functor_type(::std::forward<T>(f));

    stub_ = [](void const* const ptr, A&&... args) noexcept(noexcept(
        (*static_cast<functor_type const*>(ptr))(::std::forward(args)...))
      ) -> R
      {
        return (*static_cast<functor_type const*>(ptr))(
          ::std::forward(args)...
        );
      };
  }

  template <class C>
  void assign(C* const object_ptr,
    R (C::* const method_ptr)(A...)) noexcept
  {
    assign([object_ptr, method_ptr](A&&... args) noexcept(
      (object_ptr->*method_ptr)(::std::declval()...)) {
        return (object_ptr->*method_ptr)(::std::forward(args)...);
      }
    );
  }

  template <class C>
  void assign(C* const object_ptr,
    R (C::* const method_ptr)(A...) const) noexcept
  {
    assign([object_ptr, method_ptr](A&&... args) noexcept(
      (object_ptr->*method_ptr)(::std::declval()...)) {
        return (object_ptr->*method_ptr)(::std::forward(args)...);
      }
    );
  }

  template <class C>
  void assign(C& object,
    R (C::* const method_ptr)(A...)) noexcept
  {
    assign([&object, method_ptr](A&&... args) noexcept(
      (object.*method_ptr)(::std::declval()...)) {
        return (object.*method_ptr)(::std::forward(args)...);
      }
    );
  }

  template <class C>
  void assign(C const& object,
    R (C::* const method_ptr)(A...) const) noexcept
  {
    assign([&object, method_ptr](A&&... args) noexcept(
      (object.*method_ptr)(::std::declval()...)) {
        return (object.*method_ptr)(::std::forward(args)...);
      }
    );
  }

  void reset() noexcept { stub_ = nullptr; }

  void swap(forwarder& other) noexcept { ::std::swap(*this, other); }

  template <typename T>
  T* target() noexcept
  {
    return reinterpret_cast<T*>(&store_);
  }

  template <typename T>
  T const* target() const noexcept
  {
    return reinterpret_cast<T const*>(&store_);
  }
};

template<typename R, typename ...A, ::std::size_t N>
bool operator==(forwarder<R (A...), N> const& f,
  ::std::nullptr_t const) noexcept
{
  return f.stub_ == nullptr;
}

template<typename R, typename ...A, ::std::size_t N>
bool operator==(::std::nullptr_t const,
  forwarder<R (A...), N> const& f) noexcept
{
  return f.stub_ == nullptr;
}

template<typename R, typename ...A, ::std::size_t N>
bool operator!=(forwarder<R (A...), N> const& f,
  ::std::nullptr_t const) noexcept
{
  return !operator==(f, nullptr);
}

template<typename R, typename ...A, ::std::size_t N>
bool operator!=(::std::nullptr_t const,
  forwarder<R (A...), N> const& f) noexcept
{
  return !operator==(f, nullptr);
}

}

#endif // GENERIC_FORWARDER_HPP
<commit_msg>some fixes<commit_after>#ifndef GENERIC_FORWARDER_HPP
# define GENERIC_FORWARDER_HPP
# pragma once

#include <cassert>

// ::std::size_t
#include <cstddef>

#include <type_traits>

#include <utility>

namespace generic
{

namespace detail
{

namespace forwarder
{

template <typename ...A>
struct argument_types
{
};

template <typename A>
struct argument_types
{
  using argument_type = A;
};

template <typename A, typename B>
struct argument_types
{
  using first_argument_type = A;
  using second_argument_type = B;
};

}

}

template<typename F, ::std::size_t N = 4 * sizeof(void*)>
class forwarder;

template<typename R, typename ...A, ::std::size_t N>
class forwarder<R (A...), N> : public detail::forwarder::argument_types
{
  R (*stub_)(void const*, A&&...){};

  typename ::std::aligned_storage<N>::type store_;

  template<typename T, typename ...U, ::std::size_t M>
  friend bool operator==(forwarder<T (U...), M> const&,
    ::std::nullptr_t) noexcept;
  template<typename T, typename ...U, ::std::size_t M>
  friend bool operator==(::std::nullptr_t,
    forwarder<T (U...), M> const&) noexcept;

  template<typename T, typename ...U, ::std::size_t M>
  friend bool operator!=(forwarder<T (U...), M> const&,
    ::std::nullptr_t) noexcept;
  template<typename T, typename ...U, ::std::size_t M>
  friend bool operator!=(::std::nullptr_t,
    forwarder<T (U...), M> const&) noexcept;

public:
  using result_type	= R;

public:
  forwarder() = default;

  forwarder(forwarder const&) = default;

  template<typename T, typename ...U,
    typename = typename ::std::enable_if<
      !::std::is_same<forwarder, typename ::std::decay<T>::type>{}
    >::type
  >
  forwarder(T&& t, U&& ...u) noexcept
  {
    assign(::std::forward<T>(t), ::std::forward(u)...);
  }

  forwarder& operator=(forwarder const&) = default;

  forwarder& operator=(forwarder&&) = default;

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<forwarder, typename ::std::decay<T>::type>{}
    >::type
  >
  forwarder& operator=(T&& f) noexcept
  {
    assign(::std::forward<T>(f));

    return *this;
  }

  explicit operator bool() const noexcept { return stub_; }

  R operator()(A... args) const
    noexcept(noexcept(stub_(&store_, ::std::forward(args)...)))
  {
    //assert(stub_);
    return stub_(&store_, ::std::forward(args)...);
  }

  template <typename T>
  void assign(T&& f) noexcept
  {
    using functor_type = typename ::std::decay<T>::type;

    static_assert(sizeof(functor_type) <= sizeof(store_),
      "functor too large");
    static_assert(::std::is_trivially_copyable<T>{},
      "functor not trivially copyable");

    ::new (static_cast<void*>(&store_)) functor_type(::std::forward<T>(f));

    stub_ = [](void const* const ptr, A&&... args) noexcept(noexcept(
        (*static_cast<functor_type const*>(ptr))(::std::forward(args)...))
      ) -> R
      {
        return (*static_cast<functor_type const*>(ptr))(
          ::std::forward(args)...
        );
      };
  }

  template <class C>
  void assign(C* const object_ptr,
    R (C::* const method_ptr)(A...)) noexcept
  {
    assign([object_ptr, method_ptr](A&&... args) noexcept(
      (object_ptr->*method_ptr)(::std::declval()...)) {
        return (object_ptr->*method_ptr)(::std::forward(args)...);
      }
    );
  }

  template <class C>
  void assign(C* const object_ptr,
    R (C::* const method_ptr)(A...) const) noexcept
  {
    assign([object_ptr, method_ptr](A&&... args) noexcept(
      (object_ptr->*method_ptr)(::std::declval()...)) {
        return (object_ptr->*method_ptr)(::std::forward(args)...);
      }
    );
  }

  template <class C>
  void assign(C& object,
    R (C::* const method_ptr)(A...)) noexcept
  {
    assign([&object, method_ptr](A&&... args) noexcept(
      (object.*method_ptr)(::std::declval()...)) {
        return (object.*method_ptr)(::std::forward(args)...);
      }
    );
  }

  template <class C>
  void assign(C const& object,
    R (C::* const method_ptr)(A...) const) noexcept
  {
    assign([&object, method_ptr](A&&... args) noexcept(
      (object.*method_ptr)(::std::declval()...)) {
        return (object.*method_ptr)(::std::forward(args)...);
      }
    );
  }

  void reset() noexcept { stub_ = nullptr; }

  void swap(forwarder& other) noexcept { ::std::swap(*this, other); }

  template <typename T>
  T* target() noexcept
  {
    return reinterpret_cast<T*>(&store_);
  }

  template <typename T>
  T const* target() const noexcept
  {
    return reinterpret_cast<T const*>(&store_);
  }
};

template<typename R, typename ...A, ::std::size_t N>
bool operator==(forwarder<R (A...), N> const& f,
  ::std::nullptr_t const) noexcept
{
  return f.stub_ == nullptr;
}

template<typename R, typename ...A, ::std::size_t N>
bool operator==(::std::nullptr_t const,
  forwarder<R (A...), N> const& f) noexcept
{
  return f.stub_ == nullptr;
}

template<typename R, typename ...A, ::std::size_t N>
bool operator!=(forwarder<R (A...), N> const& f,
  ::std::nullptr_t const) noexcept
{
  return !operator==(f, nullptr);
}

template<typename R, typename ...A, ::std::size_t N>
bool operator!=(::std::nullptr_t const,
  forwarder<R (A...), N> const& f) noexcept
{
  return !operator==(f, nullptr);
}

}

#endif // GENERIC_FORWARDER_HPP
<|endoftext|>


<commit_before>#ifndef GENERIC_FORWARDER_HPP
# define GENERIC_FORWARDER_HPP
# pragma once

#include <cassert>

#include <cstddef>

#include <cstdint>

#include <type_traits>

#include <utility>

namespace generic
{

template<typename F, ::std::size_t N = 4 * sizeof(void*)>
class forwarder;

template<typename R, typename ...A, ::std::size_t N>
class forwarder<R (A...), N>
{
  template <typename U>
  static R invoker_stub(void const* const ptr, A&&... args) noexcept(noexcept(
    (*static_cast<U const*>(ptr))(::std::forward<A>(args)...)))
  {
    return (*static_cast<U const*>(ptr))(::std::forward<A>(args)...);
  }

  R (*stub_)(void const*, A&&...){};

  typename ::std::aligned_storage<N>::type store_;

public:
  forwarder() = default;

  forwarder(forwarder const&) = default;

  template<typename T>
  forwarder(T&& f)
  {
    operator=(::std::forward<T>(f));
  }

  forwarder& operator=(forwarder const&) = default;

  forwarder& operator=(forwarder&&) = default;

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<forwarder, typename ::std::decay<T>::type>{}
    >::type
  >
  forwarder& operator=(T&& f)
  {
    using functor_type = typename ::std::decay<T>::type;

    static_assert(sizeof(functor_type) <= sizeof(store_),
      "functor too large");
    static_assert(::std::is_trivially_copyable<T>{},
      "functor not trivially copyable");

    new (static_cast<void*>(&store_)) functor_type(::std::forward<T>(f));

    stub_ = invoker_stub<functor_type>;

    return *this;
  }

  explicit operator bool() const noexcept { return stub_; }

  R operator()(A... args) const
    noexcept(noexcept(stub_(&store_, ::std::forward<A>(args)...)))
  {
    //assert(stub_);
    return stub_(&store_, ::std::forward<A>(args)...);
  }

  template <typename T>
  void assign(T&& f)
  {
    operator=(::std::forward<T>(f));
  }

  void reset() noexcept { stub_ = nullptr; }
};

}

#endif // GENERIC_FORWARDER_HPP
<commit_msg>some fixes<commit_after>#ifndef GENERIC_FORWARDER_HPP
# define GENERIC_FORWARDER_HPP
# pragma once

#include <cassert>

#include <cstddef>

#include <cstdint>

#include <type_traits>

#include <utility>

namespace generic
{

template<typename F, ::std::size_t N = 4 * sizeof(void*)>
class forwarder;

template<typename R, typename ...A, ::std::size_t N>
class forwarder<R (A...), N>
{
  template <typename U>
  static R invoker_stub(void const* const ptr, A&&... args) noexcept(noexcept(
    (*static_cast<U const*>(ptr))(::std::forward<A>(args)...)))
  {
    return (*static_cast<U const*>(ptr))(::std::forward<A>(args)...);
  }

  R (*stub_)(void const*, A&&...){};

  typename ::std::aligned_storage<N>::type store_;

public:
  forwarder() = default;

  forwarder(forwarder const&) = default;

  template<typename T>
  forwarder(T&& f) noexcept
  {
    operator=(::std::forward<T>(f));
  }

  forwarder& operator=(forwarder const&) = default;

  forwarder& operator=(forwarder&&) = default;

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<forwarder, typename ::std::decay<T>::type>{}
    >::type
  >
  forwarder& operator=(T&& f) noexcept
  {
    using functor_type = typename ::std::decay<T>::type;

    static_assert(sizeof(functor_type) <= sizeof(store_),
      "functor too large");
    static_assert(::std::is_trivially_copyable<T>{},
      "functor not trivially copyable");

    new (static_cast<void*>(&store_)) functor_type(::std::forward<T>(f));

    stub_ = invoker_stub<functor_type>;

    return *this;
  }

  explicit operator bool() const noexcept { return stub_; }

  R operator()(A... args) const
    noexcept(noexcept(stub_(&store_, ::std::forward<A>(args)...)))
  {
    //assert(stub_);
    return stub_(&store_, ::std::forward<A>(args)...);
  }

  template <typename T>
  void assign(T&& f) noexcept
  {
    operator=(::std::forward<T>(f));
  }

  void reset() noexcept { stub_ = nullptr; }
};

}

#endif // GENERIC_FORWARDER_HPP
<|endoftext|>


<commit_before>#include "Search.h"
#include "board.hpp"
#include <iostream>

void outbitboard(u64 n);

string Search::RootAlphaBeta(Board gameBoard, int playerColor, int remainingDepth)
{
    vector<Board> possibleMoves = gameBoard.getBoards(playerColor);
    Board curBestMove = possibleMoves[0];
    int maxScore = -1000000;
    int score;
    for (unsigned int i = 0; i < possibleMoves.size(); i++) {
        score = -AlphaBeta(possibleMoves[i], -1000000, 1000000, remainingDepth - 1, playerColor*-1);
        if (score > maxScore){
            maxScore = score;
            curBestMove = possibleMoves[i];
        }
    }
    //outbitboard(curBestMove.getPieces());
    return gameBoard.getmove(curBestMove);
}

int Search::AlphaBeta(Board board, int alpha, int beta, int remainingDepth, int playerColor)
{
    if (remainingDepth == 0){
        return board.evalutateBoard()*playerColor;
    }
    vector<Board> possibleMoves = board.getBoards(playerColor);
    int score;
    if (possibleMoves.size() == 0){
        int colorCode = 6;
        if (playerColor == -1){
            colorCode = 7;
        }
        if (board.inCheck(colorCode) == true){
            //checkmate
            return 1000000*playerColor;
        } else {
            //stale mate
            return 0;
        }
    }
    for (unsigned int i = 0; i < possibleMoves.size(); i++){
        score = -AlphaBeta(board, -beta, -alpha, remainingDepth - 1, playerColor*-1);
        if (score >= beta){
            return beta; // fail-hard beta cut off
        }
        if (score > alpha){
            alpha = score;
        }
    }
    return alpha;
}

<commit_msg>Fixed search<commit_after>#include "Search.h"
#include "board.hpp"
#include <iostream>

void outbitboard(u64 n);

string Search::RootAlphaBeta(Board gameBoard, int playerColor, int remainingDepth)
{
    vector<Board> possibleMoves = gameBoard.getBoards(playerColor);
    Board curBestMove = possibleMoves[0];
    int maxScore = -1000000;
    int score;
    for (unsigned int i = 0; i < possibleMoves.size(); i++){
        score = -AlphaBeta(possibleMoves[i], -1000000, 1000000, remainingDepth, playerColor*-1);
        if (score > maxScore){
            maxScore = score;
            curBestMove = possibleMoves[i];
        }
    }
    return gameBoard.getmove(curBestMove);
}

int Search::AlphaBeta(Board gameBoard, int alpha, int beta, int remainingDepth, int playerColor)
{
    if (remainingDepth == 0){
        return gameBoard.evalutateBoard()*playerColor;
    }
    int score;
    vector<Board> possibleMoves = gameBoard.getBoards(playerColor);
    if (possibleMoves.size() == 0){
        int colorCode = 6;
        if (playerColor == -1){
            colorCode = 7;
        }
        if (gameBoard.inCheck(colorCode) == true){
            //checkmate
            return 1000000*playerColor;
        } else {
            //stale mate
            return 0;
        }
    }
    for (unsigned int i = 0; i < possibleMoves.size(); i++){
        score = -AlphaBeta(possibleMoves[i], -beta, -alpha, remainingDepth - 1, playerColor*-1);
        if (score >= beta){
            return beta;
        }
        if (score > alpha){
            alpha = score;
        }
    }
    return alpha;
}

<|endoftext|>


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

#include "rpcclient.h"

#include "rpcprotocol.h"
#include "util.h"
#include "ui_interface.h"

#include <set>
#include <stdint.h>

using namespace std;
using namespace json_spirit;

class CRPCConvertParam
{
public:
    std::string methodName;            //! method whose params want conversion
    int paramIdx;                      //! 0-based idx of param to convert
};

static const CRPCConvertParam vRPCConvertParams[] =
{
    { "stop", 0 },
    { "setmocktime", 0 },
    { "getaddednodeinfo", 0 },
    { "setgenerate", 0 },
    { "setgenerate", 1 },
    { "getnetworkhashps", 0 },
    { "getnetworkhashps", 1 },
    { "sendtoaddress", 1 },
    { "settxfee", 0 },
    { "getreceivedbyaddress", 1 },
    { "getreceivedbyaccount", 1 },
    { "listreceivedbyaddress", 0 },
    { "listreceivedbyaddress", 1 },
    { "listreceivedbyaddress", 2 },
    { "listreceivedbyaccount", 0 },
    { "listreceivedbyaccount", 1 },
    { "listreceivedbyaccount", 2 },
    { "getbalance", 1 },
    { "getbalance", 2 },
    { "getblockhash", 0 },
    { "move", 2 },
    { "move", 3 },
    { "sendfrom", 2 },
    { "sendfrom", 3 },
    { "listtransactions", 1 },
    { "listtransactions", 2 },
    { "listtransactions", 3 },
    { "listaccounts", 0 },
    { "listaccounts", 1 },
    { "walletpassphrase", 1 },
    { "getblocktemplate", 0 },
    { "listsinceblock", 1 },
    { "listsinceblock", 2 },
    { "sendmany", 1 },
    { "sendmany", 2 },
    { "addmultisigaddress", 0 },
    { "addmultisigaddress", 1 },
    { "createmultisig", 0 },
    { "createmultisig", 1 },
    { "listunspent", 0 },
    { "listunspent", 1 },
    { "listunspent", 2 },
    { "getblock", 1 },
    { "gettransaction", 1 },
    { "getrawtransaction", 1 },
    { "createrawtransaction", 0 },
    { "createrawtransaction", 1 },
    { "signrawtransaction", 1 },
    { "signrawtransaction", 2 },
    { "sendrawtransaction", 1 },
    { "gettxout", 1 },
    { "gettxout", 2 },
    { "lockunspent", 0 },
    { "lockunspent", 1 },
    { "importprivkey", 2 },
    { "importaddress", 2 },
    { "verifychain", 0 },
    { "verifychain", 1 },
    { "keypoolrefill", 0 },
    { "getrawmempool", 0 },
    { "estimatefee", 0 },
    { "estimatepriority", 0 },
    { "prioritisetransaction", 1 },
    { "prioritisetransaction", 2 },

    /* Omni Core related conversions */
    { "getcrowdsale_MP", 0 },
    { "getcrowdsale_MP", 1 },
    { "getgrants_MP", 0 },
    { "send_MP", 2 },
    { "getbalance_MP", 1 },
    { "sendtoowners_MP", 1 },
    { "getproperty_MP", 0 },
    { "listtransactions_MP", 1 },
    { "listtransactions_MP", 2 },
    { "listtransactions_MP", 3 },
    { "listtransactions_MP", 4 },
    { "getallbalancesforid_MP", 0 },
    { "listblocktransactions_MP", 0 },
#if 0 // disabled for pre meta DEx release
    { "trade_MP", 2 },
    { "trade_MP", 4 },
    { "trade_MP", 5 },
    { "getorderbook_MP", 0 },
    { "getorderbook_MP", 1 },
    { "gettradessince_MP", 0 },
    { "gettradessince_MP", 1 },
    { "gettradessince_MP", 2 },
    { "gettradehistory_MP", 1 },
    { "gettradehistory_MP", 2 },
#endif
};

class CRPCConvertTable
{
private:
    std::set<std::pair<std::string, int> > members;

public:
    CRPCConvertTable();

    bool convert(const std::string& method, int idx) {
        return (members.count(std::make_pair(method, idx)) > 0);
    }
};

CRPCConvertTable::CRPCConvertTable()
{
    const unsigned int n_elem =
        (sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0]));

    for (unsigned int i = 0; i < n_elem; i++) {
        members.insert(std::make_pair(vRPCConvertParams[i].methodName,
                                      vRPCConvertParams[i].paramIdx));
    }
}

static CRPCConvertTable rpcCvtTable;

/** Convert strings to command-specific RPC representation */
Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
{
    Array params;

    for (unsigned int idx = 0; idx < strParams.size(); idx++) {
        const std::string& strVal = strParams[idx];

        // insert string value directly
        if (!rpcCvtTable.convert(strMethod, idx)) {
            params.push_back(strVal);
        }

        // parse string as JSON, insert bool/number/object/etc. value
        else {
            Value jVal;
            if (!read_string(strVal, jVal))
                throw runtime_error(string("Error parsing JSON:")+strVal);
            params.push_back(jVal);
        }
    }

    return params;
}

<commit_msg>[CONSOLIDATE] rpcclient.cpp/h changes<commit_after>// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "rpcclient.h"

#include "rpcprotocol.h"
#include "util.h"
#include "ui_interface.h"

#include <set>
#include <stdint.h>

using namespace std;
using namespace json_spirit;

class CRPCConvertParam
{
public:
    std::string methodName;            //! method whose params want conversion
    int paramIdx;                      //! 0-based idx of param to convert
};

static const CRPCConvertParam vRPCConvertParams[] =
{
    { "stop", 0 },
    { "setmocktime", 0 },
    { "getaddednodeinfo", 0 },
    { "setgenerate", 0 },
    { "setgenerate", 1 },
    { "getnetworkhashps", 0 },
    { "getnetworkhashps", 1 },
    { "sendtoaddress", 1 },
    { "settxfee", 0 },
    { "getreceivedbyaddress", 1 },
    { "getreceivedbyaccount", 1 },
    { "listreceivedbyaddress", 0 },
    { "listreceivedbyaddress", 1 },
    { "listreceivedbyaddress", 2 },
    { "listreceivedbyaccount", 0 },
    { "listreceivedbyaccount", 1 },
    { "listreceivedbyaccount", 2 },
    { "getbalance", 1 },
    { "getbalance", 2 },
    { "getblockhash", 0 },
    { "move", 2 },
    { "move", 3 },
    { "sendfrom", 2 },
    { "sendfrom", 3 },
    { "listtransactions", 1 },
    { "listtransactions", 2 },
    { "listtransactions", 3 },
    { "listaccounts", 0 },
    { "listaccounts", 1 },
    { "walletpassphrase", 1 },
    { "getblocktemplate", 0 },
    { "listsinceblock", 1 },
    { "listsinceblock", 2 },
    { "sendmany", 1 },
    { "sendmany", 2 },
    { "addmultisigaddress", 0 },
    { "addmultisigaddress", 1 },
    { "createmultisig", 0 },
    { "createmultisig", 1 },
    { "listunspent", 0 },
    { "listunspent", 1 },
    { "listunspent", 2 },
    { "getblock", 1 },
    { "gettransaction", 1 },
    { "getrawtransaction", 1 },
    { "createrawtransaction", 0 },
    { "createrawtransaction", 1 },
    { "signrawtransaction", 1 },
    { "signrawtransaction", 2 },
    { "sendrawtransaction", 1 },
    { "gettxout", 1 },
    { "gettxout", 2 },
    { "lockunspent", 0 },
    { "lockunspent", 1 },
    { "importprivkey", 2 },
    { "importaddress", 2 },
    { "verifychain", 0 },
    { "verifychain", 1 },
    { "keypoolrefill", 0 },
    { "getrawmempool", 0 },
    { "estimatefee", 0 },
    { "estimatepriority", 0 },
    { "prioritisetransaction", 1 },
    { "prioritisetransaction", 2 },

    /* Omni Core related conversions */
    { "getcrowdsale_MP", 0 },
    { "getcrowdsale_MP", 1 },
    { "getgrants_MP", 0 },
    { "send_MP", 2 },
    { "getbalance_MP", 1 },
    { "sendtoowners_MP", 1 },
    { "getproperty_MP", 0 },
    { "listtransactions_MP", 1 },
    { "listtransactions_MP", 2 },
    { "listtransactions_MP", 3 },
    { "listtransactions_MP", 4 },
    { "getallbalancesforid_MP", 0 },
    { "listblocktransactions_MP", 0 },
    { "setautocommit_OMNI", 0 },
#if 0 // disabled for pre meta DEx release
    { "trade_MP", 2 },
    { "trade_MP", 4 },
    { "trade_MP", 5 },
    { "getorderbook_MP", 0 },
    { "getorderbook_MP", 1 },
    { "gettradessince_MP", 0 },
    { "gettradessince_MP", 1 },
    { "gettradessince_MP", 2 },
    { "gettradehistory_MP", 1 },
    { "gettradehistory_MP", 2 },
#endif
    // omni_rpctx
    { "send_OMNI", 2 },
    { "sendsto_OMNI", 1 },
    { "sendtrade_OMNI", 1 },
    { "sendtrade_OMNI", 3 },
    { "sendtrade_OMNI", 5 },
    { "sendissuancefixed_OMNI", 1 },
    { "sendissuancefixed_OMNI", 2 },
    { "sendissuancefixed_OMNI", 3 },
    { "sendissuancemanaged_OMNI", 1 },
    { "sendissuancemanaged_OMNI", 2 },
    { "sendissuancemanaged_OMNI", 3 },
    { "sendissuancecrowdsale_OMNI", 1 },
    { "sendissuancecrowdsale_OMNI", 2 },
    { "sendissuancecrowdsale_OMNI", 3 },
    { "sendissuancecrowdsale_OMNI", 9 },
    { "sendissuancecrowdsale_OMNI", 11 },
    { "sendissuancecrowdsale_OMNI", 12 },
    { "sendissuancecrowdsale_OMNI", 13 },
    { "senddexsell_OMNI", 1 },
    { "senddexsell_OMNI", 4 },
    { "senddexsell_OMNI", 6 },
    { "senddexaccept_OMNI", 2 },
    { "sendclosecrowdsale_OMNI", 1 },
    { "sendgrant_OMNI", 2 },
    { "sendrevoke_OMNI", 1 },
    { "sendchangeissuer_OMNI", 2 },
};

class CRPCConvertTable
{
private:
    std::set<std::pair<std::string, int> > members;

public:
    CRPCConvertTable();

    bool convert(const std::string& method, int idx) {
        return (members.count(std::make_pair(method, idx)) > 0);
    }
};

CRPCConvertTable::CRPCConvertTable()
{
    const unsigned int n_elem =
        (sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0]));

    for (unsigned int i = 0; i < n_elem; i++) {
        members.insert(std::make_pair(vRPCConvertParams[i].methodName,
                                      vRPCConvertParams[i].paramIdx));
    }
}

static CRPCConvertTable rpcCvtTable;

/** Convert strings to command-specific RPC representation */
Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
{
    Array params;

    for (unsigned int idx = 0; idx < strParams.size(); idx++) {
        const std::string& strVal = strParams[idx];

        // insert string value directly
        if (!rpcCvtTable.convert(strMethod, idx)) {
            params.push_back(strVal);
        }

        // parse string as JSON, insert bool/number/object/etc. value
        else {
            Value jVal;
            if (!read_string(strVal, jVal))
                throw runtime_error(string("Error parsing JSON:")+strVal);
            params.push_back(jVal);
        }
    }

    return params;
}

<|endoftext|>