<commit_before>//----------------------------------------------------------------------------
// Copyright (c) 2015, Codalogic Ltd (http://www.codalogic.com)
// All rights reserved.
//
// The license for this file is based on the BSD-3-Clause license
// (http://www.opensource.org/licenses/BSD-3-Clause).
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// - Neither the name Codalogic Ltd nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//----------------------------------------------------------------------------

#if defined(_MSC_VER)
// Require error when nonstandard extension used :
//      'token' : conversion from 'type' to 'type'
//      e.g. disallow foo( /*const*/ foo & ) for copy constructor
#pragma warning(error: 4239)
#endif

#include <string>
#include <iostream>

#include "annotate-lite.h"

// Modified functions from http://www.hyc.io/boost/expected-proposal.pdf
//----------------------------------------------------------------------------

template< typename Texception >
double safe_divide( double i, double j )
{
    if( j == 0.0 ) throw Texception();
    return i / j;
}

template< typename Texception >
double f1( double i, double j, double k )
{
    return i + safe_divide<Texception>(j,k);
}
// Some classes by which to record errors
//----------------------------------------------------------------------------

struct or_j_is_zero {};
struct or_k_is_zero {};
struct or_k1_is_zero {};
struct or_k2_is_zero {};

// Examples and tests
//----------------------------------------------------------------------------

void test_safe_divide_ok()
{
    try
    {
        double i=1.0, j=1.0;
        double r = safe_divide<or_j_is_zero>( i, j );
        Good( "test_safe_divide_ok exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Bad( "test_safe_divide_ok exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_safe_divide_bad()
{
    try
    {
        double i=1.0, j=0.0;
        double r = safe_divide<or_j_is_zero>( i, j );
        Bad( "test_safe_divide_bad exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Good( "test_safe_divide_bad exception thrown" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_multiple_safe_divide_ok()
{
    try
    {
        double i=1.0, j=1.0, k=1.0;
        double r = safe_divide<or_j_is_zero>(
                    safe_divide<or_k_is_zero>( i, j ) + 1.0, k );
        Good( "test_multiple_safe_divide_ok exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Bad( "test_multiple_safe_divide_ok or_j_is_zero exception should not throw" );
    }
    catch( or_k_is_zero & )
    {
        Bad( "test_multiple_safe_divide_ok or_k_is_zero exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_multiple_safe_divide_bad()
{
    try
    {
        double i=1.0, j=0.0, k=1.0;
        double r = safe_divide<or_k_is_zero>(
                    safe_divide<or_j_is_zero>( i, j ) + 1.0, k );
        Bad( "test_multiple_safe_divide_bad exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Good( "test_multiple_safe_divide_bad or_j_is_zero exception thrown" );
    }
    catch( or_k_is_zero & )
    {
        Bad( "test_multiple_safe_divide_bad or_k_is_zero exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }

    try
    {
        double i=1.0, j=1.0, k=0.0;
        double r = safe_divide<or_k_is_zero>(
                    safe_divide<or_j_is_zero>( i, j ) + 1.0, k );
        Bad( "test_multiple_safe_divide_bad exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Bad( "test_multiple_safe_divide_bad or_j_is_zero exception should not throw" );
    }
    catch( or_k_is_zero & )
    {
        Good( "test_multiple_safe_divide_bad or_k_is_zero exception thrown" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_f1_ok()
{
    try
    {
        double i=1.0, j=1.0, k=1.0;
        double r = f1<or_k_is_zero>( i, j, k );
        Good( "test_f1_ok exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Bad( "test_f1_ok exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_f1_bad()
{
    try
    {
        double i=1.0, j=1.0, k=0.0;
        double r = f1<or_k_is_zero>( i, j, k );
        Bad( "test_f1_bad exception did not throw" );
    }
    catch( or_k_is_zero & )
    {
        Good( "test_f1_bad exception thrown" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_multiple_f1_ok()
{
    try
    {
        double i=1.0, j=1.0, k1=1.0, k2=1.0;
        double r = f1<or_k1_is_zero>( i, j, k1 ) +
                    f1<or_k2_is_zero>( i, j, k2 );
        Good( "test_multiple_f1_ok exception did not throw" );
    }
    catch( or_k1_is_zero & )
    {
        Bad( "test_multiple_f1_ok exception should not throw" );
    }
    catch( or_k2_is_zero & )
    {
        Bad( "test_multiple_f1_ok exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_multiple_f1_bad()
{
    try
    {
        double i=1.0, j=1.0, k1=0.0, k2=1.0;
        double r = f1<or_k1_is_zero>( i, j, k1 ) +
                    f1<or_k2_is_zero>( i, j, k2 );
        Bad( "test_multiple_f1_ok exception did not throw" );
    }
    catch( or_k1_is_zero & )
    {
        Good( "test_multiple_f1_ok or_k1_is_zero exception thrown" );
    }
    catch( or_k2_is_zero & )
    {
        Bad( "test_multiple_f1_ok or_k2_is_zero exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }

    try
    {
        double i=1.0, j=1.0, k1=1.0, k2=0.0;
        double r = f1<or_k1_is_zero>( i, j, k1 ) +
                    f1<or_k2_is_zero>( i, j, k2 );
        Bad( "test_multiple_f1_ok exception did not throw" );
    }
    catch( or_k1_is_zero & )
    {
        Bad( "test_multiple_f1_ok or_k1_is_zero exception should not throw" );
    }
    catch( or_k2_is_zero & )
    {
        Good( "test_multiple_f1_ok or_k2_is_zero exception thrown" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

int main( int argc, char * argv[] )
{
    test_safe_divide_ok();
    test_safe_divide_bad();

    test_multiple_safe_divide_ok();
    test_multiple_safe_divide_bad();

    test_f1_ok();
    test_f1_bad();

    test_multiple_f1_ok();
    test_multiple_f1_bad();

    report();

    return 0;
}
<commit_msg>Beautification<commit_after>//----------------------------------------------------------------------------
// Copyright (c) 2015, Codalogic Ltd (http://www.codalogic.com)
// All rights reserved.
//
// The license for this file is based on the BSD-3-Clause license
// (http://www.opensource.org/licenses/BSD-3-Clause).
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// - Neither the name Codalogic Ltd nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//----------------------------------------------------------------------------

#if defined(_MSC_VER)
// Require error when nonstandard extension used :
//      'token' : conversion from 'type' to 'type'
//      e.g. disallow foo( /*const*/ foo & ) for copy constructor
#pragma warning(error: 4239)
#endif

#include <string>
#include <iostream>

#include "annotate-lite.h"

// Modified functions from http://www.hyc.io/boost/expected-proposal.pdf
//----------------------------------------------------------------------------

template< typename Texception >
double safe_divide( double i, double j )
{
    if( j == 0.0 ) throw Texception();
    return i / j;
}

template< typename Texception >
double f1( double i, double j, double k )
{
    return i + safe_divide<Texception>(j,k);
}

// Some classes by which to record errors
//----------------------------------------------------------------------------

struct or_j_is_zero {};
struct or_k_is_zero {};
struct or_k1_is_zero {};
struct or_k2_is_zero {};

// Examples and tests
//----------------------------------------------------------------------------

void test_safe_divide_ok()
{
    try
    {
        double i=1.0, j=1.0;
        double r = safe_divide<or_j_is_zero>( i, j );
        Good( "test_safe_divide_ok exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Bad( "test_safe_divide_ok exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_safe_divide_bad()
{
    try
    {
        double i=1.0, j=0.0;
        double r = safe_divide<or_j_is_zero>( i, j );
        Bad( "test_safe_divide_bad exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Good( "test_safe_divide_bad exception thrown" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_multiple_safe_divide_ok()
{
    try
    {
        double i=1.0, j=1.0, k=1.0;
        double r = safe_divide<or_j_is_zero>(
                    safe_divide<or_k_is_zero>( i, j ) + 1.0, k );
        Good( "test_multiple_safe_divide_ok exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Bad( "test_multiple_safe_divide_ok or_j_is_zero exception should not throw" );
    }
    catch( or_k_is_zero & )
    {
        Bad( "test_multiple_safe_divide_ok or_k_is_zero exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_multiple_safe_divide_bad()
{
    try
    {
        double i=1.0, j=0.0, k=1.0;
        double r = safe_divide<or_k_is_zero>(
                    safe_divide<or_j_is_zero>( i, j ) + 1.0, k );
        Bad( "test_multiple_safe_divide_bad exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Good( "test_multiple_safe_divide_bad or_j_is_zero exception thrown" );
    }
    catch( or_k_is_zero & )
    {
        Bad( "test_multiple_safe_divide_bad or_k_is_zero exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }

    try
    {
        double i=1.0, j=1.0, k=0.0;
        double r = safe_divide<or_k_is_zero>(
                    safe_divide<or_j_is_zero>( i, j ) + 1.0, k );
        Bad( "test_multiple_safe_divide_bad exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Bad( "test_multiple_safe_divide_bad or_j_is_zero exception should not throw" );
    }
    catch( or_k_is_zero & )
    {
        Good( "test_multiple_safe_divide_bad or_k_is_zero exception thrown" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_f1_ok()
{
    try
    {
        double i=1.0, j=1.0, k=1.0;
        double r = f1<or_k_is_zero>( i, j, k );
        Good( "test_f1_ok exception did not throw" );
    }
    catch( or_j_is_zero & )
    {
        Bad( "test_f1_ok exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_f1_bad()
{
    try
    {
        double i=1.0, j=1.0, k=0.0;
        double r = f1<or_k_is_zero>( i, j, k );
        Bad( "test_f1_bad exception did not throw" );
    }
    catch( or_k_is_zero & )
    {
        Good( "test_f1_bad exception thrown" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_multiple_f1_ok()
{
    try
    {
        double i=1.0, j=1.0, k1=1.0, k2=1.0;
        double r = f1<or_k1_is_zero>( i, j, k1 ) +
                    f1<or_k2_is_zero>( i, j, k2 );
        Good( "test_multiple_f1_ok exception did not throw" );
    }
    catch( or_k1_is_zero & )
    {
        Bad( "test_multiple_f1_ok exception should not throw" );
    }
    catch( or_k2_is_zero & )
    {
        Bad( "test_multiple_f1_ok exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

void test_multiple_f1_bad()
{
    try
    {
        double i=1.0, j=1.0, k1=0.0, k2=1.0;
        double r = f1<or_k1_is_zero>( i, j, k1 ) +
                    f1<or_k2_is_zero>( i, j, k2 );
        Bad( "test_multiple_f1_ok exception did not throw" );
    }
    catch( or_k1_is_zero & )
    {
        Good( "test_multiple_f1_ok or_k1_is_zero exception thrown" );
    }
    catch( or_k2_is_zero & )
    {
        Bad( "test_multiple_f1_ok or_k2_is_zero exception should not throw" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }

    try
    {
        double i=1.0, j=1.0, k1=1.0, k2=0.0;
        double r = f1<or_k1_is_zero>( i, j, k1 ) +
                    f1<or_k2_is_zero>( i, j, k2 );
        Bad( "test_multiple_f1_ok exception did not throw" );
    }
    catch( or_k1_is_zero & )
    {
        Bad( "test_multiple_f1_ok or_k1_is_zero exception should not throw" );
    }
    catch( or_k2_is_zero & )
    {
        Good( "test_multiple_f1_ok or_k2_is_zero exception thrown" );
    }
    catch( ... )
    {
        Bad( "Unexpected shit happened. Our program is broken!" );
    }
}

int main( int argc, char * argv[] )
{
    test_safe_divide_ok();
    test_safe_divide_bad();

    test_multiple_safe_divide_ok();
    test_multiple_safe_divide_bad();

    test_f1_ok();
    test_f1_bad();

    test_multiple_f1_ok();
    test_multiple_f1_bad();

    report();

    return 0;
}
<|endoftext|>


<commit_before>#include "func.h"

#include <glob.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

#include <algorithm>
#include <iterator>
#include <unordered_map>

#include "eval.h"
#include "log.h"
#include "strutil.h"

namespace {

void PatsubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> pat = args[0]->Eval(ev);
  shared_ptr<string> repl = args[1]->Eval(ev);
  shared_ptr<string> str = args[2]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(*str)) {
    ww.MaybeAddWhitespace();
    AppendSubstPattern(tok, *pat, *repl, s);
  }
}

void StripFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> str = args[0]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(*str)) {
    ww.Write(tok);
  }
}

void SubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> pat = args[0]->Eval(ev);
  shared_ptr<string> repl = args[1]->Eval(ev);
  shared_ptr<string> str = args[2]->Eval(ev);
  size_t index = 0;
  while (index < str->size()) {
    size_t found = str->find(*pat, index);
    if (found == string::npos)
      break;
    AppendString(StringPiece(*str).substr(index, found - index), s);
    AppendString(*repl, s);
    index = found + pat->size();
  }
  AppendString(StringPiece(*str).substr(index), s);
}

void FindstringFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> find = args[0]->Eval(ev);
  shared_ptr<string> in = args[1]->Eval(ev);
  if (in->find(*find) != string::npos)
    AppendString(*find, s);
}

void FilterFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> pat_buf = args[0]->Eval(ev);
  shared_ptr<string> text = args[1]->Eval(ev);
  vector<StringPiece> pats;
  WordScanner(*pat_buf).Split(&pats);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(*text)) {
    for (StringPiece pat : pats) {
      if (MatchPattern(tok, pat)) {
        ww.Write(tok);
        break;
      }
    }
  }
}

void FilterOutFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> pat_buf = args[0]->Eval(ev);
  shared_ptr<string> text = args[1]->Eval(ev);
  vector<StringPiece> pats;
  WordScanner(*pat_buf).Split(&pats);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(*text)) {
    bool matched = false;
    for (StringPiece pat : pats) {
      if (MatchPattern(tok, pat)) {
        matched = true;
        break;
      }
    }
    if (!matched)
      ww.Write(tok);
  }
}

void SortFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> list = args[0]->Eval(ev);
  vector<StringPiece> toks;
  WordScanner(*list).Split(&toks);
  sort(toks.begin(), toks.end());
  WordWriter ww(s);
  StringPiece prev;
  for (StringPiece tok : toks) {
    if (prev != tok) {
      ww.Write(tok);
      prev = tok;
    }
  }
}

static int GetNumericValueForFunc(const string& buf) {
  StringPiece s = TrimLeftSpace(buf);
  char* end;
  long n = strtol(s.data(), &end, 10);
  if (n < 0 || n == LONG_MAX || s.data() + s.size() != end) {
    return -1;
  }
  return n;
}

void WordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> n_str = args[0]->Eval(ev);
  int n = GetNumericValueForFunc(*n_str);
  if (n < 0) {
    ev->Error(StringPrintf(
        "*** non-numeric first argument to `word' function: '%s'.",
        n_str->c_str()));
  }
  if (n == 0) {
    ev->Error("*** first argument to `word' function must be greater than 0.");
  }

  shared_ptr<string> text = args[1]->Eval(ev);
  for (StringPiece tok : WordScanner(*text)) {
    n--;
    if (n == 0) {
      AppendString(tok, s);
      break;
    }
  }
}

void WordlistFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> s_str = args[0]->Eval(ev);
  int si = GetNumericValueForFunc(*s_str);
  if (si < 0) {
    ev->Error(StringPrintf(
        "*** non-numeric first argument to `wordlist' function: '%s'.",
        s_str->c_str()));
  }
  if (si == 0) {
    ev->Error(StringPrintf(
        "*** invalid first argument to `wordlist' function: %s`",
        s_str->c_str()));
  }

  shared_ptr<string> e_str = args[1]->Eval(ev);
  int ei = GetNumericValueForFunc(*e_str);
  if (ei < 0) {
    ev->Error(StringPrintf(
        "*** non-numeric second argument to `wordlist' function: '%s'.",
        e_str->c_str()));
  }

  shared_ptr<string> text = args[2]->Eval(ev);
  int i = 0;
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(*text)) {
    i++;
    if (si <= i && i <= ei) {
      ww.Write(tok);
    }
  }
}

void WordsFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> text = args[0]->Eval(ev);
  WordScanner ws(*text);
  int n = 0;
  for (auto iter = ws.begin(); iter != ws.end(); ++iter)
    n++;
  char buf[32];
  sprintf(buf, "%d", n);
  *s += buf;
}

void FirstwordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> text = args[0]->Eval(ev);
  for (StringPiece tok : WordScanner(*text)) {
    AppendString(tok, s);
    return;
  }
}

void LastwordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> text = args[0]->Eval(ev);
  StringPiece last;
  for (StringPiece tok : WordScanner(*text)) {
    last = tok;
  }
  AppendString(last, s);
}

void JoinFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> list1 = args[0]->Eval(ev);
  shared_ptr<string> list2 = args[1]->Eval(ev);
  WordScanner ws1(*list1);
  WordScanner ws2(*list2);
  WordWriter ww(s);
  for (WordScanner::Iterator iter1 = ws1.begin(), iter2 = ws2.begin();
       iter1 != ws1.end() && iter2 != ws2.end();
       ++iter1, ++iter2) {
    ww.Write(*iter1);
    // Use |AppendString| not to append extra ' '.
    AppendString(*iter2, s);
  }
}

void WildcardFunc(const vector<Value*>&, Evaluator*, string*) {
  shared_ptr<string> pat = args[0]->Eval(ev);
  for (StringPiece tok : WordScanner(*pat)) {
    char orig = tok[tok.size()];
    tok[tok.size()] = '\0';
    glob(tok.data());
    tok[tok.size()] = orig;
  }
}

void DirFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(dir)");
}

void NotdirFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(notdir)");
}

void SuffixFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(suffix)");
}

void BasenameFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(basename)");
}

void AddsuffixFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(addsuffix)");
}

void AddprefixFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(addprefix)");
}

void RealpathFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(realpath)");
}

void AbspathFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(abspath)");
}

void IfFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(if)");
}

void AndFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(and)");
}

void OrFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(or)");
}

void ValueFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(value)");
}

void EvalFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(eval)");
}

void ShellFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(shell)");
}

void CallFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(call)");
}

void ForeachFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(foreach)");
}

void OriginFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(origin)");
}

void FlavorFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(flavor)");
}

void InfoFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  shared_ptr<string> a = args[0]->Eval(ev);
  printf("%s\n", a->c_str());
  fflush(stdout);
}

void WarningFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  shared_ptr<string> a = args[0]->Eval(ev);
  printf("%s:%d: %s\n", LOCF(ev->loc()), a->c_str());
  fflush(stdout);
}

void ErrorFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  shared_ptr<string> a = args[0]->Eval(ev);
  ev->Error(StringPrintf("*** %s.", a->c_str()));
}

FuncInfo g_func_infos[] = {
  { "patsubst", &PatsubstFunc, 3 },
  { "strip", &StripFunc, 1 },
  { "subst", &SubstFunc, 3 },
  { "findstring", &FindstringFunc, 2 },
  { "filter", &FilterFunc, 2 },
  { "filter-out", &FilterOutFunc, 2 },
  { "sort", &SortFunc, 1 },
  { "word", &WordFunc, 2 },
  { "wordlist", &WordlistFunc, 3 },
  { "words", &WordsFunc, 1 },
  { "firstword", &FirstwordFunc, 1 },
  { "lastword", &LastwordFunc, 1 },

  { "join", &JoinFunc, 2 },
  { "wildcard", &WildcardFunc, 1 },
  { "dir", &DirFunc, 1 },
  { "notdir", &NotdirFunc, 1 },
  { "suffix", &SuffixFunc, 1 },
  { "basename", &BasenameFunc, 1 },
  { "addsuffix", &AddsuffixFunc, 2 },
  { "addprefix", &AddprefixFunc, 2 },
  { "realpath", &RealpathFunc, 1 },
  { "abspath", &AbspathFunc, 1 },

  { "if", &IfFunc, 1 },
  { "and", &AndFunc, 1 },
  { "or", &OrFunc, 1 },
  { "value", &ValueFunc, 1 },
  { "eval", &EvalFunc, 1 },
  { "shell", &ShellFunc, 1 },
  { "call", &CallFunc, 1 },
  { "foreach", &ForeachFunc, 1 },
  { "origin", &OriginFunc, 1 },
  { "flavor", &FlavorFunc, 1 },
  { "info", &InfoFunc, 1 },
  { "warning", &WarningFunc, 1 },
  { "error", &ErrorFunc, 1 },
};

unordered_map<StringPiece, FuncInfo*>* g_func_info_map;

}  // namespace

void InitFuncTable() {
  g_func_info_map = new unordered_map<StringPiece, FuncInfo*>;
  for (size_t i = 0; i < sizeof(g_func_infos) / sizeof(g_func_infos[0]); i++) {
    FuncInfo* fi = &g_func_infos[i];
    bool ok = g_func_info_map->insert(make_pair(Intern(fi->name), fi)).second;
    CHECK(ok);
  }
}

void QuitFuncTable() {
  delete g_func_info_map;
}

FuncInfo* GetFuncInfo(StringPiece name) {
  auto found = g_func_info_map->find(name);
  if (found == g_func_info_map->end())
    return NULL;
  return found->second;
}
<commit_msg>[C++] Implement wildcard and shell<commit_after>#include "func.h"

#include <glob.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

#include <algorithm>
#include <iterator>
#include <unordered_map>

#include "eval.h"
#include "log.h"
#include "strutil.h"

namespace {

void PatsubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> pat = args[0]->Eval(ev);
  shared_ptr<string> repl = args[1]->Eval(ev);
  shared_ptr<string> str = args[2]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(*str)) {
    ww.MaybeAddWhitespace();
    AppendSubstPattern(tok, *pat, *repl, s);
  }
}

void StripFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> str = args[0]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(*str)) {
    ww.Write(tok);
  }
}

void SubstFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> pat = args[0]->Eval(ev);
  shared_ptr<string> repl = args[1]->Eval(ev);
  shared_ptr<string> str = args[2]->Eval(ev);
  size_t index = 0;
  while (index < str->size()) {
    size_t found = str->find(*pat, index);
    if (found == string::npos)
      break;
    AppendString(StringPiece(*str).substr(index, found - index), s);
    AppendString(*repl, s);
    index = found + pat->size();
  }
  AppendString(StringPiece(*str).substr(index), s);
}

void FindstringFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> find = args[0]->Eval(ev);
  shared_ptr<string> in = args[1]->Eval(ev);
  if (in->find(*find) != string::npos)
    AppendString(*find, s);
}

void FilterFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> pat_buf = args[0]->Eval(ev);
  shared_ptr<string> text = args[1]->Eval(ev);
  vector<StringPiece> pats;
  WordScanner(*pat_buf).Split(&pats);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(*text)) {
    for (StringPiece pat : pats) {
      if (MatchPattern(tok, pat)) {
        ww.Write(tok);
        break;
      }
    }
  }
}

void FilterOutFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> pat_buf = args[0]->Eval(ev);
  shared_ptr<string> text = args[1]->Eval(ev);
  vector<StringPiece> pats;
  WordScanner(*pat_buf).Split(&pats);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(*text)) {
    bool matched = false;
    for (StringPiece pat : pats) {
      if (MatchPattern(tok, pat)) {
        matched = true;
        break;
      }
    }
    if (!matched)
      ww.Write(tok);
  }
}

void SortFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> list = args[0]->Eval(ev);
  vector<StringPiece> toks;
  WordScanner(*list).Split(&toks);
  sort(toks.begin(), toks.end());
  WordWriter ww(s);
  StringPiece prev;
  for (StringPiece tok : toks) {
    if (prev != tok) {
      ww.Write(tok);
      prev = tok;
    }
  }
}

static int GetNumericValueForFunc(const string& buf) {
  StringPiece s = TrimLeftSpace(buf);
  char* end;
  long n = strtol(s.data(), &end, 10);
  if (n < 0 || n == LONG_MAX || s.data() + s.size() != end) {
    return -1;
  }
  return n;
}

void WordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> n_str = args[0]->Eval(ev);
  int n = GetNumericValueForFunc(*n_str);
  if (n < 0) {
    ev->Error(StringPrintf(
        "*** non-numeric first argument to `word' function: '%s'.",
        n_str->c_str()));
  }
  if (n == 0) {
    ev->Error("*** first argument to `word' function must be greater than 0.");
  }

  shared_ptr<string> text = args[1]->Eval(ev);
  for (StringPiece tok : WordScanner(*text)) {
    n--;
    if (n == 0) {
      AppendString(tok, s);
      break;
    }
  }
}

void WordlistFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> s_str = args[0]->Eval(ev);
  int si = GetNumericValueForFunc(*s_str);
  if (si < 0) {
    ev->Error(StringPrintf(
        "*** non-numeric first argument to `wordlist' function: '%s'.",
        s_str->c_str()));
  }
  if (si == 0) {
    ev->Error(StringPrintf(
        "*** invalid first argument to `wordlist' function: %s`",
        s_str->c_str()));
  }

  shared_ptr<string> e_str = args[1]->Eval(ev);
  int ei = GetNumericValueForFunc(*e_str);
  if (ei < 0) {
    ev->Error(StringPrintf(
        "*** non-numeric second argument to `wordlist' function: '%s'.",
        e_str->c_str()));
  }

  shared_ptr<string> text = args[2]->Eval(ev);
  int i = 0;
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(*text)) {
    i++;
    if (si <= i && i <= ei) {
      ww.Write(tok);
    }
  }
}

void WordsFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> text = args[0]->Eval(ev);
  WordScanner ws(*text);
  int n = 0;
  for (auto iter = ws.begin(); iter != ws.end(); ++iter)
    n++;
  char buf[32];
  sprintf(buf, "%d", n);
  *s += buf;
}

void FirstwordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> text = args[0]->Eval(ev);
  for (StringPiece tok : WordScanner(*text)) {
    AppendString(tok, s);
    return;
  }
}

void LastwordFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> text = args[0]->Eval(ev);
  StringPiece last;
  for (StringPiece tok : WordScanner(*text)) {
    last = tok;
  }
  AppendString(last, s);
}

void JoinFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> list1 = args[0]->Eval(ev);
  shared_ptr<string> list2 = args[1]->Eval(ev);
  WordScanner ws1(*list1);
  WordScanner ws2(*list2);
  WordWriter ww(s);
  for (WordScanner::Iterator iter1 = ws1.begin(), iter2 = ws2.begin();
       iter1 != ws1.end() && iter2 != ws2.end();
       ++iter1, ++iter2) {
    ww.Write(*iter1);
    // Use |AppendString| not to append extra ' '.
    AppendString(*iter2, s);
  }
}

void WildcardFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> pat = args[0]->Eval(ev);
  WordWriter ww(s);
  for (StringPiece tok : WordScanner(*pat)) {
    char orig = tok[tok.size()];
    const_cast<char*>(tok.data())[tok.size()] = '\0';

    // TODO: Make this faster by not always using glob.
    glob_t gl;
    glob(tok.data(), GLOB_NOSORT, NULL, &gl);
    for (size_t i = 0; i < gl.gl_pathc; i++) {
      ww.Write(gl.gl_pathv[i]);
    }
    globfree(&gl);

    const_cast<char*>(tok.data())[tok.size()] = orig;
  }
}

void DirFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(dir)");
}

void NotdirFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(notdir)");
}

void SuffixFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(suffix)");
}

void BasenameFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(basename)");
}

void AddsuffixFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(addsuffix)");
}

void AddprefixFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(addprefix)");
}

void RealpathFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(realpath)");
}

void AbspathFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(abspath)");
}

void IfFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(if)");
}

void AndFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(and)");
}

void OrFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(or)");
}

void ValueFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(value)");
}

void EvalFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(eval)");
}

void ShellFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
  shared_ptr<string> cmd = args[0]->Eval(ev);
  LOG("ShellFunc: %s", cmd->c_str());
  string out;
  // TODO: Handle $(SHELL).
  FILE* fp = popen(cmd->c_str(), "r");
  while (true) {
    char buf[4096];
    size_t r = fread(buf, 1, 4096, fp);
    out.append(buf, buf+r);
    if (r == 0) {
      fclose(fp);
      break;
    }
  }

  while (out[out.size()-1] == '\n')
    out.pop_back();
  for (size_t i = 0; i < out.size(); i++) {
    if (out[i] == '\n')
      out[i] = ' ';
  }
  *s += out;
}

void CallFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(call)");
}

void ForeachFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(foreach)");
}

void OriginFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(origin)");
}

void FlavorFunc(const vector<Value*>&, Evaluator*, string*) {
  printf("TODO(flavor)");
}

void InfoFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  shared_ptr<string> a = args[0]->Eval(ev);
  printf("%s\n", a->c_str());
  fflush(stdout);
}

void WarningFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  shared_ptr<string> a = args[0]->Eval(ev);
  printf("%s:%d: %s\n", LOCF(ev->loc()), a->c_str());
  fflush(stdout);
}

void ErrorFunc(const vector<Value*>& args, Evaluator* ev, string*) {
  shared_ptr<string> a = args[0]->Eval(ev);
  ev->Error(StringPrintf("*** %s.", a->c_str()));
}

FuncInfo g_func_infos[] = {
  { "patsubst", &PatsubstFunc, 3 },
  { "strip", &StripFunc, 1 },
  { "subst", &SubstFunc, 3 },
  { "findstring", &FindstringFunc, 2 },
  { "filter", &FilterFunc, 2 },
  { "filter-out", &FilterOutFunc, 2 },
  { "sort", &SortFunc, 1 },
  { "word", &WordFunc, 2 },
  { "wordlist", &WordlistFunc, 3 },
  { "words", &WordsFunc, 1 },
  { "firstword", &FirstwordFunc, 1 },
  { "lastword", &LastwordFunc, 1 },

  { "join", &JoinFunc, 2 },
  { "wildcard", &WildcardFunc, 1 },
  { "dir", &DirFunc, 1 },
  { "notdir", &NotdirFunc, 1 },
  { "suffix", &SuffixFunc, 1 },
  { "basename", &BasenameFunc, 1 },
  { "addsuffix", &AddsuffixFunc, 2 },
  { "addprefix", &AddprefixFunc, 2 },
  { "realpath", &RealpathFunc, 1 },
  { "abspath", &AbspathFunc, 1 },

  { "if", &IfFunc, 1 },
  { "and", &AndFunc, 1 },
  { "or", &OrFunc, 1 },
  { "value", &ValueFunc, 1 },
  { "eval", &EvalFunc, 1 },
  { "shell", &ShellFunc, 1 },
  { "call", &CallFunc, 1 },
  { "foreach", &ForeachFunc, 1 },
  { "origin", &OriginFunc, 1 },
  { "flavor", &FlavorFunc, 1 },
  { "info", &InfoFunc, 1 },
  { "warning", &WarningFunc, 1 },
  { "error", &ErrorFunc, 1 },
};

unordered_map<StringPiece, FuncInfo*>* g_func_info_map;

}  // namespace

void InitFuncTable() {
  g_func_info_map = new unordered_map<StringPiece, FuncInfo*>;
  for (size_t i = 0; i < sizeof(g_func_infos) / sizeof(g_func_infos[0]); i++) {
    FuncInfo* fi = &g_func_infos[i];
    bool ok = g_func_info_map->insert(make_pair(Intern(fi->name), fi)).second;
    CHECK(ok);
  }
}

void QuitFuncTable() {
  delete g_func_info_map;
}

FuncInfo* GetFuncInfo(StringPiece name) {
  auto found = g_func_info_map->find(name);
  if (found == g_func_info_map->end())
    return NULL;
  return found->second;
}
<|endoftext|>


<commit_before>#include "game.h"

#define LOOKAHEAD 4
#define SACRIFICE_OPTIONS 5
#define OPPONENT_MOVES 5

using namespace std;

// globals
int sacrificeCombinations = factorial(SACRIFICE_OPTIONS) / (factorial(SACRIFICE_OPTIONS - 2) * factorial(2));
stringstream token;
char botId;
char state[16][18];
int roundNum, timebank, myLiveCells, theirLiveCells;

// this just for logging time TODO: remove
auto t = chrono::steady_clock::now();

void game()
{
  string line, command;

  while (getline(cin, line))
  {
    token.clear();
    token.str(line);
    token >> command;

    if (command == "action")
      processAction();
    if (command == "update")
      processUpdate();
    if (command == "settings")
      processSettings();
  }
}

void processAction()
{
  string type, time;
  token >> type;
  token >> time;

  if (type == "move") {
    t = chrono::steady_clock::now(); // TODO: remove
    timebank = stoi(time);
    makeMove();
    chrono::duration<double> diff = chrono::steady_clock::now() - t; // TODO: remove
    cerr << diff.count() * 1000 << "ms used\n"; // TODO: remove
  } else
    cerr << "action type: " << type << " not expected\n";
}

void processUpdate()
{
  string target, field, value;
  token >> target;
  token >> field;
  token >> value;

  if (target == "game") {
    if (field == "round") {
      roundNum = stoi(value);
    }
    if (field == "field") {
      parseState(value);
    }
  } else if (target == "player0" or target == "player1") {
    if (field == "living_cells") {
      if (target[6] == botId)
        myLiveCells = stoi(value);
      else
        theirLiveCells = stoi(value);
    } else if (field != "move")
      cerr << "update playerX field: " << field << " not expected\n";
  } else
    cerr << "update target: " << target << " not expected\n";
}

void processSettings()
{
  string field, value;
  token >> field;
  token >> value;

  if (field == "player_names") {
    if (value != "player0,player1")
      cerr << "settings player_names value: " << value << " not expected\n";
  } else if (field == "your_bot") {
    if (value != "player0" and value != "player1")
      cerr << "settings your_bot value: " << value << " not expected\n";
  } else if (field == "timebank") {
    if (value == "10000")
      timebank = stoi(value);
    else
      cerr << "settings timebank value: " << value << " not expected\n";
  } else if (field == "time_per_move") {
    if (value != "100")
      cerr << "settings time_per_move value: " << value << " not expected\n";
  } else if (field == "field_width") {
    if (value != "18")
      cerr << "settings field_width value: " << value << " not expected\n";
  } else if (field == "field_height") {
    if (value != "16")
      cerr << "settings field_height value: " << value << " not expected\n";
  } else if (field == "max_rounds") {
    if (value != "100")
      cerr << "settings max_rounds value: " << value << " not expected\n";
  } else if (field == "your_botid") {
    if (value == "0" or value == "1")
      botId = value[0];
    else
      cerr << "settings your_botid value: " << value << " not expected\n";
  } else
    cerr << "settings field: " << field << " not expected\n";
}

void parseState(const string &value)
{
  int row = 0;
  int col = 0;
  for (const char& c : value) {
    if (c != ',') {
      state[row][col] = c;
      if (col == 17) {
        col = 0;
        row++;
      } else {
        col++;
      }
    }
  }
}

void makeMove()
{
  int numMoves = 1 + (myLiveCells + theirLiveCells) + (sacrificeCombinations * (288 - myLiveCells - theirLiveCells));

  // TODO: handle less then n of my cells alive for birthing calcs
  node nodes[numMoves];

  addKillNodes(nodes);

  node bestKillNodes[SACRIFICE_OPTIONS];
  findBestKillNodes(nodes, bestKillNodes);

  addPassNode(nodes);

  addBirthNodes(nodes, bestKillNodes);

  // TODO: for the best n nodes, calculate opponent moves and recalculate heuristic, then pick the best of those
  // sort then slice, then 2nd round heuristic, then sort then first
  sort(nodes, nodes + numMoves, nodeCompare);

  // node bestNode = findBestNode(nodes, numMoves);
  node bestNode = nodes[0];

  sendMove(bestNode);
}

void addKillNodes(node nodes[])
{
  int i = 0;
  for (int c = 0; c < 18; c++) {
    for (int r = 0; r < 16; r++) {
      if (state[r][c] != '.') {
        node n;
        n.value = state[r][c];
        n.type = 'k';
        n.target = r * 18 + c;
        copyState(n.state);
        n.state[r][c] = '.';
        calculateNextState(n);
        calculateHeuristic(n);
        nodes[i++] = n;
      }
    }
  }
}

void findBestKillNodes(node nodes[], node bestKillNodes[])
{
  sort(nodes, nodes + myLiveCells + theirLiveCells, nodeCompare);

  int killNodeCount = 0;
  for (int i = 0; i < myLiveCells + theirLiveCells; i++) {
    node n = nodes[i];

    if (n.value == botId) {
      bestKillNodes[killNodeCount] = n;
      killNodeCount++;

      if (killNodeCount == SACRIFICE_OPTIONS) {
        break;
      }
    }
  }
}

void addPassNode(node nodes[])
{
  node n;
  n.type = 'p';
  copyState(n.state);
  calculateNextState(n);
  calculateHeuristic(n);
  nodes[myLiveCells + theirLiveCells] = n;
}

void addBirthNodes(node nodes[], const node bestKillNodes[])
{
  int i = myLiveCells + theirLiveCells + 1;
  for (int x = 0; x < SACRIFICE_OPTIONS - 1; x++) {
    for (int y = x + 1; y < SACRIFICE_OPTIONS; y++) {
      for (int c = 0; c < 18; c++) {
        for (int r = 0; r < 16; r++) {
          if (state[r][c] == '.') {
            node n;
            n.type = 'b';
            n.target = r * 18 + c;
            n.sacrifice1 = bestKillNodes[x].target;
            n.sacrifice2 = bestKillNodes[y].target;
            copyState(n.state);
            n.state[r][c] = botId;
            n.state[n.sacrifice1 / 18][n.sacrifice1 % 18] = '.';
            n.state[n.sacrifice2 / 18][n.sacrifice2 % 18] = '.';
            calculateNextState(n);
            calculateHeuristic(n);
            nodes[i++] = n;
          }
        }
      }
    }
  }
}

node findBestNode(const node nodes[], int nodeCount)
{
  int topHeuristic = -288;
  int topHeuristicIdx = 0;
  for (int i = 0; i < nodeCount; i++) {
    if (nodes[i].heuristicValue > topHeuristic) {
      topHeuristic = nodes[topHeuristicIdx].heuristicValue;
      topHeuristicIdx = i;
    }
  }

  return nodes[topHeuristicIdx];
}

void sendMove(const node &n)
{
  if (n.type == 'p') {
    cout << "pass\n";
  } else if (n.type == 'k') {
    cout << "kill " << coords(n.target) << "\n";
  } else if (n.type == 'b') {
    cout << "birth " << coords(n.target) << " " << coords(n.sacrifice1) << " " << coords(n.sacrifice2) << "\n";
  }
}

void calculateNextState(node &n, int lookahead)
{
  for (int l = 0; l < lookahead; l++) {
    int neighbours0[16][18];
    int neighbours1[16][18];

    for (int c = 0; c < 18; c++) {
      for (int r = 0; r < 16; r++) {
        neighbours0[r][c] = 0;
        neighbours1[r][c] = 0;
      }
    }

    for (int c = 0; c < 18; c++) {
      for (int r = 0; r < 16; r++) {
        if (n.state[r][c] == '0') {
          if (c > 0) {
            neighbours0[r][c - 1]++;
            if (r > 0) neighbours0[r - 1][c - 1]++;
            if (r < 15) neighbours0[r + 1][c - 1]++;
          }
          if (c < 17) {
            neighbours0[r][c + 1]++;
            if (r > 0) neighbours0[r - 1][c + 1]++;
            if (r < 15) neighbours0[r + 1][c + 1]++;
          }
          if (r > 0) neighbours0[r - 1][c]++;
          if (r < 15) neighbours0[r + 1][c]++;
        }
        if (n.state[r][c] == '1') {
          if (c > 0) {
            neighbours1[r][c - 1]++;
            if (r > 0) neighbours1[r - 1][c - 1]++;
            if (r < 15) neighbours1[r + 1][c - 1]++;
          }
          if (c < 17) {
            neighbours1[r][c + 1]++;
            if (r > 0) neighbours1[r - 1][c + 1]++;
            if (r < 15) neighbours1[r + 1][c + 1]++;
          }
          if (r > 0) neighbours1[r - 1][c]++;
          if (r < 15) neighbours1[r + 1][c]++;
        }
      }
    }

    int neighbours;
    for (int c = 0; c < 18; c++) {
      for (int r = 0; r < 16; r++) {
        neighbours = neighbours0[r][c] + neighbours1[r][c];
        if (n.state[r][c] == '.' and neighbours == 3) {
          n.state[r][c] = (neighbours0[r][c] > neighbours1[r][c]) ?  '0' : '1';
        } else if (n.state[r][c] != '.' and (neighbours < 2 or neighbours > 3)) {
          n.state[r][c] = '.';
        }
      }
    }
  }
}

void calculateHeuristic(node &n)
{
  int cellCount0 = 0;
  int cellCount1 = 0;

  // TODO: consider the number of opponent cells alive to increase aggression when they are low
  for (int c = 0; c < 18; c++) {
    for (int r = 0; r < 16; r++) {
      if (n.state[r][c] == '0') {
        cellCount0++;
      } else if (n.state[r][c] == '1') {
        cellCount1++;
      }
    }
  }

  if (botId == '0') {
    if (cellCount0 == 0) {
      n.heuristicValue = -288;
    } else if (cellCount1 == 0) {
      n.heuristicValue = 288;
    } else {
      n.heuristicValue = cellCount0 - cellCount1;
    }
  } else if (botId == '1') {
    if (cellCount1 == 0) {
      n.heuristicValue = -288;
    } else if (cellCount0 == 0) {
      n.heuristicValue = 288;
    } else {
      n.heuristicValue = cellCount1 - cellCount0;
    }
  }
}

// utility functions
int factorial(int x, int result) {
  return (x == 1) ? result : factorial(x - 1, x * result);
}

string coords(int cellIdx)
{
  stringstream ss;
  ss << (cellIdx % 18) << "," << cellIdx / 18;
  return ss.str();
}

void copyState(const char source[][18], char target[][18])
{
  for (int r = 0; r < 16; r++) {
    for (int c = 0; c < 18; c++) {
      target[r][c] = source[r][c];
    }
  }
}

bool nodeCompare(node lhs, node rhs)
{
  // sort descending
  return lhs.heuristicValue > rhs.heuristicValue;
}

// debug functions
void setBotId(const char id)
{
  botId = id;
}
<commit_msg>add birthNodes takes state and idx as args<commit_after>#include "game.h"

#define LOOKAHEAD 4
#define SACRIFICE_OPTIONS 5
#define OPPONENT_MOVES 5

using namespace std;

// globals
int sacrificeCombinations = factorial(SACRIFICE_OPTIONS) / (factorial(SACRIFICE_OPTIONS - 2) * factorial(2));
stringstream token;
char botId;
char state[16][18];
int roundNum, timebank, myLiveCells, theirLiveCells;

// this just for logging time TODO: remove
auto t = chrono::steady_clock::now();

void game()
{
  string line, command;

  while (getline(cin, line))
  {
    token.clear();
    token.str(line);
    token >> command;

    if (command == "action")
      processAction();
    if (command == "update")
      processUpdate();
    if (command == "settings")
      processSettings();
  }
}

void processAction()
{
  string type, time;
  token >> type;
  token >> time;

  if (type == "move") {
    t = chrono::steady_clock::now(); // TODO: remove
    timebank = stoi(time);
    makeMove();
    chrono::duration<double> diff = chrono::steady_clock::now() - t; // TODO: remove
    cerr << diff.count() * 1000 << "ms used\n"; // TODO: remove
  } else
    cerr << "action type: " << type << " not expected\n";
}

void processUpdate()
{
  string target, field, value;
  token >> target;
  token >> field;
  token >> value;

  if (target == "game") {
    if (field == "round") {
      roundNum = stoi(value);
    }
    if (field == "field") {
      parseState(value);
    }
  } else if (target == "player0" or target == "player1") {
    if (field == "living_cells") {
      if (target[6] == botId)
        myLiveCells = stoi(value);
      else
        theirLiveCells = stoi(value);
    } else if (field != "move")
      cerr << "update playerX field: " << field << " not expected\n";
  } else
    cerr << "update target: " << target << " not expected\n";
}

void processSettings()
{
  string field, value;
  token >> field;
  token >> value;

  if (field == "player_names") {
    if (value != "player0,player1")
      cerr << "settings player_names value: " << value << " not expected\n";
  } else if (field == "your_bot") {
    if (value != "player0" and value != "player1")
      cerr << "settings your_bot value: " << value << " not expected\n";
  } else if (field == "timebank") {
    if (value == "10000")
      timebank = stoi(value);
    else
      cerr << "settings timebank value: " << value << " not expected\n";
  } else if (field == "time_per_move") {
    if (value != "100")
      cerr << "settings time_per_move value: " << value << " not expected\n";
  } else if (field == "field_width") {
    if (value != "18")
      cerr << "settings field_width value: " << value << " not expected\n";
  } else if (field == "field_height") {
    if (value != "16")
      cerr << "settings field_height value: " << value << " not expected\n";
  } else if (field == "max_rounds") {
    if (value != "100")
      cerr << "settings max_rounds value: " << value << " not expected\n";
  } else if (field == "your_botid") {
    if (value == "0" or value == "1")
      botId = value[0];
    else
      cerr << "settings your_botid value: " << value << " not expected\n";
  } else
    cerr << "settings field: " << field << " not expected\n";
}

void parseState(const string &value)
{
  int row = 0;
  int col = 0;
  for (const char& c : value) {
    if (c != ',') {
      state[row][col] = c;
      if (col == 17) {
        col = 0;
        row++;
      } else {
        col++;
      }
    }
  }
}

void makeMove()
{
  int numMoves = 1 + (myLiveCells + theirLiveCells) + (sacrificeCombinations * (288 - myLiveCells - theirLiveCells));

  // TODO: handle less then n of my cells alive for birthing calcs
  node nodes[numMoves];

  addKillNodes(nodes);

  node bestKillNodes[SACRIFICE_OPTIONS];
  findBestKillNodes(nodes, bestKillNodes);

  addPassNode(nodes);

  addBirthNodes(nodes, bestKillNodes);

  // TODO: for the best n nodes, calculate opponent moves and recalculate heuristic, then pick the best of those
  // sort then slice, then 2nd round heuristic, then sort then first
  sort(nodes, nodes + numMoves, nodeCompare);

  // node bestNode = findBestNode(nodes, numMoves);
  node bestNode = nodes[0];

  sendMove(bestNode);
}

void addKillNodes(node nodes[])
{
  int i = 0;
  for (int c = 0; c < 18; c++) {
    for (int r = 0; r < 16; r++) {
      if (state[r][c] != '.') {
        node n;
        n.value = state[r][c];
        n.type = 'k';
        n.target = r * 18 + c;
        copyState(n.state);
        n.state[r][c] = '.';
        calculateNextState(n);
        calculateHeuristic(n);
        nodes[i++] = n;
      }
    }
  }
}

void findBestKillNodes(node nodes[], node bestKillNodes[])
{
  sort(nodes, nodes + myLiveCells + theirLiveCells, nodeCompare);

  int killNodeCount = 0;
  for (int i = 0; i < myLiveCells + theirLiveCells; i++) {
    node n = nodes[i];

    if (n.value == botId) {
      bestKillNodes[killNodeCount] = n;
      killNodeCount++;

      if (killNodeCount == SACRIFICE_OPTIONS) {
        break;
      }
    }
  }
}

void addPassNode(node nodes[])
{
  node n;
  n.type = 'p';
  copyState(n.state);
  calculateNextState(n);
  calculateHeuristic(n);
  nodes[myLiveCells + theirLiveCells] = n;
}

void addBirthNodes(node nodes[], char state[][18], const node bestKillNodes[], int idx)
{
  for (int x = 0; x < SACRIFICE_OPTIONS - 1; x++) {
    for (int y = x + 1; y < SACRIFICE_OPTIONS; y++) {
      for (int c = 0; c < 18; c++) {
        for (int r = 0; r < 16; r++) {
          if (state[r][c] == '.') {
            node n;
            n.type = 'b';
            n.target = r * 18 + c;
            n.sacrifice1 = bestKillNodes[x].target;
            n.sacrifice2 = bestKillNodes[y].target;
            copyState(n.state);
            n.state[r][c] = botId;
            n.state[n.sacrifice1 / 18][n.sacrifice1 % 18] = '.';
            n.state[n.sacrifice2 / 18][n.sacrifice2 % 18] = '.';
            calculateNextState(n);
            calculateHeuristic(n);
            nodes[idx++] = n;
          }
        }
      }
    }
  }
}

node findBestNode(const node nodes[], int nodeCount)
{
  int topHeuristic = -288;
  int topHeuristicIdx = 0;
  for (int i = 0; i < nodeCount; i++) {
    if (nodes[i].heuristicValue > topHeuristic) {
      topHeuristic = nodes[topHeuristicIdx].heuristicValue;
      topHeuristicIdx = i;
    }
  }

  return nodes[topHeuristicIdx];
}

void sendMove(const node &n)
{
  if (n.type == 'p') {
    cout << "pass\n";
  } else if (n.type == 'k') {
    cout << "kill " << coords(n.target) << "\n";
  } else if (n.type == 'b') {
    cout << "birth " << coords(n.target) << " " << coords(n.sacrifice1) << " " << coords(n.sacrifice2) << "\n";
  }
}

void calculateNextState(node &n, int lookahead)
{
  for (int l = 0; l < lookahead; l++) {
    int neighbours0[16][18];
    int neighbours1[16][18];

    for (int c = 0; c < 18; c++) {
      for (int r = 0; r < 16; r++) {
        neighbours0[r][c] = 0;
        neighbours1[r][c] = 0;
      }
    }

    for (int c = 0; c < 18; c++) {
      for (int r = 0; r < 16; r++) {
        if (n.state[r][c] == '0') {
          if (c > 0) {
            neighbours0[r][c - 1]++;
            if (r > 0) neighbours0[r - 1][c - 1]++;
            if (r < 15) neighbours0[r + 1][c - 1]++;
          }
          if (c < 17) {
            neighbours0[r][c + 1]++;
            if (r > 0) neighbours0[r - 1][c + 1]++;
            if (r < 15) neighbours0[r + 1][c + 1]++;
          }
          if (r > 0) neighbours0[r - 1][c]++;
          if (r < 15) neighbours0[r + 1][c]++;
        }
        if (n.state[r][c] == '1') {
          if (c > 0) {
            neighbours1[r][c - 1]++;
            if (r > 0) neighbours1[r - 1][c - 1]++;
            if (r < 15) neighbours1[r + 1][c - 1]++;
          }
          if (c < 17) {
            neighbours1[r][c + 1]++;
            if (r > 0) neighbours1[r - 1][c + 1]++;
            if (r < 15) neighbours1[r + 1][c + 1]++;
          }
          if (r > 0) neighbours1[r - 1][c]++;
          if (r < 15) neighbours1[r + 1][c]++;
        }
      }
    }

    int neighbours;
    for (int c = 0; c < 18; c++) {
      for (int r = 0; r < 16; r++) {
        neighbours = neighbours0[r][c] + neighbours1[r][c];
        if (n.state[r][c] == '.' and neighbours == 3) {
          n.state[r][c] = (neighbours0[r][c] > neighbours1[r][c]) ?  '0' : '1';
        } else if (n.state[r][c] != '.' and (neighbours < 2 or neighbours > 3)) {
          n.state[r][c] = '.';
        }
      }
    }
  }
}

void calculateHeuristic(node &n)
{
  int cellCount0 = 0;
  int cellCount1 = 0;

  // TODO: consider the number of opponent cells alive to increase aggression when they are low
  for (int c = 0; c < 18; c++) {
    for (int r = 0; r < 16; r++) {
      if (n.state[r][c] == '0') {
        cellCount0++;
      } else if (n.state[r][c] == '1') {
        cellCount1++;
      }
    }
  }

  if (botId == '0') {
    if (cellCount0 == 0) {
      n.heuristicValue = -288;
    } else if (cellCount1 == 0) {
      n.heuristicValue = 288;
    } else {
      n.heuristicValue = cellCount0 - cellCount1;
    }
  } else if (botId == '1') {
    if (cellCount1 == 0) {
      n.heuristicValue = -288;
    } else if (cellCount0 == 0) {
      n.heuristicValue = 288;
    } else {
      n.heuristicValue = cellCount1 - cellCount0;
    }
  }
}

// utility functions
int factorial(int x, int result) {
  return (x == 1) ? result : factorial(x - 1, x * result);
}

string coords(int cellIdx)
{
  stringstream ss;
  ss << (cellIdx % 18) << "," << cellIdx / 18;
  return ss.str();
}

void copyState(const char source[][18], char target[][18])
{
  for (int r = 0; r < 16; r++) {
    for (int c = 0; c < 18; c++) {
      target[r][c] = source[r][c];
    }
  }
}

bool nodeCompare(node lhs, node rhs)
{
  // sort descending
  return lhs.heuristicValue > rhs.heuristicValue;
}

// debug functions
void setBotId(const char id)
{
  botId = id;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011, Peter Thorson. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the WebSocket++ Project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "generic.hpp"

using wsperf::message_test;

// Construct a message_test from a wscmd command
/* Reads values from the wscmd object into member variables. The cmd object is
 * passed to the parent constructor for extracting values common to all test
 * cases.
 *
 * Any of the constructors may throw a `case_exception` if required parameters
 * are not found or default values don't make sense.
 *
 * Values that message_test checks for:
 *
 * size=[interger];
 * Example: size=4096;
 * Size of messages to send in bytes. Valid values 0 - max size_t
 *
 * count=[integer];
 * Example: count=1000;
 * Number of test messages to send. Valid values 0-2^64
 *
 * timeout=[integer];
 * Example: timeout=10000;
 * How long to wait (in ms) for a response before failing the test.
 *
 * binary=[bool];
 * Example: binary=true;
 * Whether or not to use binary websocket frames. (true=binary, false=utf8)
 *
 * sync=[bool];
 * Example: sync=true;
 * Syncronize messages. When sync is on wsperf will wait for a response before
 * sending the next message. When sync is off, messages will be sent as quickly
 * as possible.
 *
 * correctness=[string];
 * Example: correctness=exact;
 * Example: correctness=length;
 * How to evaluate the correctness of responses. Exact checks each response for
 * exact correctness. Length checks only that the response has the correct
 * length. Length mode is faster but won't catch invalid implimentations. Length
 * mode can be used to test situations where you deliberately return incorrect
 * bytes in order to compare performance (ex: performance with/without masking)
 */
message_test::message_test(wscmd::cmd& cmd)
 : case_handler(cmd),
   m_message_size(extract_number<uint64_t>(cmd,"size")),
   m_message_count(extract_number<uint64_t>(cmd,"count")),
   m_timeout(extract_number<uint64_t>(cmd,"timeout")),
   m_binary(extract_bool(cmd,"binary")),
   m_sync(extract_bool(cmd,"sync")),
   m_acks(0)
{
    if (cmd.args["correctness"] == "exact") {
        m_mode = EXACT;
    } else if (cmd.args["correctness"] == "length") {
        m_mode = LENGTH;
    } else {
        throw case_exception("Invalid correctness parameter.");
    }
}

void message_test::on_open(connection_ptr con) {
    m_msg = con->get_data_message();

    m_data.reserve(static_cast<size_t>(m_message_size));

    if (!m_binary) {
        fill_utf8(m_data,static_cast<size_t>(m_message_size),true);
        m_msg->reset(websocketpp::frame::opcode::TEXT);
    } else {
        fill_binary(m_data,static_cast<size_t>(m_message_size),true);
        m_msg->reset(websocketpp::frame::opcode::BINARY);
    }

    m_msg->set_payload(m_data);

    start(con,m_timeout);

    if (m_sync) {
        con->send(m_msg);
    } else {
        for (uint64_t i = 0; i < m_message_count; i++) {
            con->send(m_msg);
        }
    }
}

void message_test::on_message(connection_ptr con,websocketpp::message::data_ptr msg) {
    if ((m_mode == LENGTH && msg->get_payload().size() == m_data.size()) ||
        (m_mode == EXACT && msg->get_payload() == m_data))
    {
        m_acks++;
        m_bytes += m_message_size;
        mark();
    } else {
        mark();
        m_msg.reset();
        m_pass = FAIL;

        //std::cout << "sent: " << zsutil::to_hex(m_data) << std::endl;
        //std::cout << "recieved: " << zsutil::to_hex(msg->get_payload()) << std::endl;

        this->end(con);
    }

    if (m_acks == m_message_count) {
        m_pass = PASS;
        m_msg.reset();
        this->end(con);
    } else if (m_sync && m_pass == RUNNING) {
        con->send(m_msg);
    }
}
<commit_msg>removes some debug code<commit_after>/*
 * Copyright (c) 2011, Peter Thorson. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the WebSocket++ Project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "generic.hpp"

using wsperf::message_test;

// Construct a message_test from a wscmd command
/* Reads values from the wscmd object into member variables. The cmd object is
 * passed to the parent constructor for extracting values common to all test
 * cases.
 *
 * Any of the constructors may throw a `case_exception` if required parameters
 * are not found or default values don't make sense.
 *
 * Values that message_test checks for:
 *
 * size=[interger];
 * Example: size=4096;
 * Size of messages to send in bytes. Valid values 0 - max size_t
 *
 * count=[integer];
 * Example: count=1000;
 * Number of test messages to send. Valid values 0-2^64
 *
 * timeout=[integer];
 * Example: timeout=10000;
 * How long to wait (in ms) for a response before failing the test.
 *
 * binary=[bool];
 * Example: binary=true;
 * Whether or not to use binary websocket frames. (true=binary, false=utf8)
 *
 * sync=[bool];
 * Example: sync=true;
 * Syncronize messages. When sync is on wsperf will wait for a response before
 * sending the next message. When sync is off, messages will be sent as quickly
 * as possible.
 *
 * correctness=[string];
 * Example: correctness=exact;
 * Example: correctness=length;
 * How to evaluate the correctness of responses. Exact checks each response for
 * exact correctness. Length checks only that the response has the correct
 * length. Length mode is faster but won't catch invalid implimentations. Length
 * mode can be used to test situations where you deliberately return incorrect
 * bytes in order to compare performance (ex: performance with/without masking)
 */
message_test::message_test(wscmd::cmd& cmd)
 : case_handler(cmd),
   m_message_size(extract_number<uint64_t>(cmd,"size")),
   m_message_count(extract_number<uint64_t>(cmd,"count")),
   m_timeout(extract_number<uint64_t>(cmd,"timeout")),
   m_binary(extract_bool(cmd,"binary")),
   m_sync(extract_bool(cmd,"sync")),
   m_acks(0)
{
    if (cmd.args["correctness"] == "exact") {
        m_mode = EXACT;
    } else if (cmd.args["correctness"] == "length") {
        m_mode = LENGTH;
    } else {
        throw case_exception("Invalid correctness parameter.");
    }
}

void message_test::on_open(connection_ptr con) {
    m_msg = con->get_data_message();

    m_data.reserve(static_cast<size_t>(m_message_size));

    if (!m_binary) {
        fill_utf8(m_data,static_cast<size_t>(m_message_size),true);
        m_msg->reset(websocketpp::frame::opcode::TEXT);
    } else {
        fill_binary(m_data,static_cast<size_t>(m_message_size),true);
        m_msg->reset(websocketpp::frame::opcode::BINARY);
    }

    m_msg->set_payload(m_data);

    start(con,m_timeout);

    if (m_sync) {
        con->send(m_msg);
    } else {
        for (uint64_t i = 0; i < m_message_count; i++) {
            con->send(m_msg);
        }
    }
}

void message_test::on_message(connection_ptr con,websocketpp::message::data_ptr msg) {
    if ((m_mode == LENGTH && msg->get_payload().size() == m_data.size()) ||
        (m_mode == EXACT && msg->get_payload() == m_data))
    {
        m_acks++;
        m_bytes += m_message_size;
        mark();
    } else {
        mark();
        m_msg.reset();
        m_pass = FAIL;

        this->end(con);
    }

    if (m_acks == m_message_count) {
        m_pass = PASS;
        m_msg.reset();
        this->end(con);
    } else if (m_sync && m_pass == RUNNING) {
        con->send(m_msg);
    }
}
<|endoftext|>


<commit_before>#ifdef ENABLE_HIP

#include "hoomd/ExecutionConfiguration.h"

#include <stdio.h>
#include <string>
#include <vector>

#include "GPUEvalFactory.h"

// pybind11 vector bindings
#include <pybind11/pybind11.h>
#include <pybind11/stl_bind.h>

#include <hip/hip_runtime.h>

#if __HIP_PLATFORM_NVCC__
#include <cuda.h>
#include <nvrtc.h>

#include "jitify_safe_headers.hpp"

void GPUEvalFactory::compileGPU(
    const std::string& code,
    const std::string& kernel_name,
    const std::string& include_path,
    const std::string& include_path_source,
    const std::string& cuda_devrt_library_path,
    const unsigned int compute_arch)
    {
    m_exec_conf->msg->notice(3) << "Compiling nvrtc code" << std::endl;

    std::vector<std::string> compile_options = {
        "--gpu-architecture=compute_"+std::to_string(compute_arch),
        "--include-path="+include_path,
        "--include-path="+include_path_source,
        "--device-as-default-execution-space",
        "--std=c++11",
#ifdef ENABLE_HPMC_MIXED_PRECISION
        "-DENABLE_HPMC_MIXED_PRECISION",
#endif
        "-DHOOMD_LLVMJIT_BUILD",
        "-D__HIPCC__",
        "-D__HIP_PLATFORM_NVCC__",
        "-lineinfo"
        };

    char *compileParams[compile_options.size()];
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        compileParams[i] = reinterpret_cast<char *>(
            malloc(sizeof(char) * (compile_options[i].length() + 1)));
        snprintf(compileParams[i], compile_options[i].length() + 1, "%s",
                 compile_options[i].c_str());
        }

    // compile

    // add fake math headers + printf
    std::string printf_include = std::string("#define FILE int\n") +
        std::string("int fflush ( FILE * stream );\n") +
        std::string("int fprintf ( FILE * stream, const char * format, ... );\n");

    std::string code_with_headers = std::string(jitify::detail::jitsafe_header_math) +
        printf_include + code;

    m_exec_conf->msg->notice(4) << code_with_headers << std::endl;

    nvrtcResult status = nvrtcCreateProgram(&m_program, code_with_headers.c_str(), "evaluator.cu", 0, NULL, NULL);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcCreateProgram error: "+std::string(nvrtcGetErrorString(status)));

    m_exec_conf->msg->notice(3) << "nvrtc options (notice level 4 shows code):" << std::endl;
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        m_exec_conf->msg->notice(3) << " " << compileParams[i] << std::endl;
        }

    status = nvrtcAddNameExpression(m_program, kernel_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string alpha_iso_name = "&alpha_iso";
    status = nvrtcAddNameExpression(m_program, alpha_iso_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string alpha_union_name = "&alpha_union";
    status = nvrtcAddNameExpression(m_program, alpha_union_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string rcut_name = "&jit::d_rcut_union";
    status = nvrtcAddNameExpression(m_program, rcut_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string union_params_name = "&jit::d_union_params";
    status = nvrtcAddNameExpression(m_program, union_params_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    nvrtcResult compile_result = nvrtcCompileProgram(m_program, compile_options.size(), compileParams);
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        free(compileParams[i]);
        }

    // Obtain compilation log from the program.
    size_t logSize;
    status = nvrtcGetProgramLogSize(m_program, &logSize);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetProgramLogSize error: "+std::string(nvrtcGetErrorString(status)));

    char *log = new char[logSize];
    status = nvrtcGetProgramLog(m_program, log);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetProgramLog error: "+std::string(nvrtcGetErrorString(status)));
    m_exec_conf->msg->notice(3) << "nvrtc output" << std::endl << log << '\n';
    delete[] log;

    if (compile_result != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcCompileProgram error (set device.notice_level=3 to see full log): "+std::string(nvrtcGetErrorString(compile_result)));

    // fetch PTX
    size_t ptx_size;
    status = nvrtcGetPTXSize(m_program, &ptx_size);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetPTXSize error: "+std::string(nvrtcGetErrorString(status)));

    char ptx[ptx_size];
    status = nvrtcGetPTX(m_program, ptx);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetPTX error: "+std::string(nvrtcGetErrorString(status)));

    // look up mangled names
    char *kernel_name_mangled;
    status = nvrtcGetLoweredName(m_program, kernel_name.c_str(), const_cast<const char **>(&kernel_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *alpha_iso_name_mangled;
    status = nvrtcGetLoweredName(m_program, alpha_iso_name.c_str(), const_cast<const char **>(&alpha_iso_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *alpha_union_name_mangled;
    status = nvrtcGetLoweredName(m_program, alpha_union_name.c_str(), const_cast<const char **>(&alpha_union_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *rcut_name_mangled;
    status = nvrtcGetLoweredName(m_program, rcut_name.c_str(), const_cast<const char **>(&rcut_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *union_params_name_mangled;
    status = nvrtcGetLoweredName(m_program, union_params_name.c_str(), const_cast<const char **>(&union_params_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    // link PTX into cubin
    CUresult custatus;
    char *error;
    custatus = cuLinkCreate(0, 0, 0, &m_link_state);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkCreate: "+std::string(error));
        }

    custatus = cuLinkAddFile(m_link_state, CU_JIT_INPUT_LIBRARY, cuda_devrt_library_path.c_str(), 0, 0, 0);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkAddFile: "+std::string(error));
        }

    custatus = cuLinkAddData(m_link_state, CU_JIT_INPUT_PTX, (void *) ptx, ptx_size, "evaluator.ptx", 0, 0, 0);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkAddData: "+std::string(error));
        }

    size_t cubinSize;
    void *cubin;

    custatus = cuLinkComplete(m_link_state, &cubin, &cubinSize);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkComplete: "+std::string(error));
        }

    // load cubin into active contexts, and return function pointers
    auto gpu_map = m_exec_conf->getGPUIds();
    m_module.resize(m_exec_conf->getNumActiveGPUs());
    for (int idev = m_exec_conf->getNumActiveGPUs()-1; idev >= 0; --idev)
        {
        cudaSetDevice(gpu_map[idev]);

        // get module
        custatus = cuModuleLoadData(&m_module[idev], cubin);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleLoadData: "+std::string(error));
            }

        // get variable pointers
        CUfunction kernel_ptr;
        custatus = cuModuleGetFunction(&kernel_ptr, m_module[idev], kernel_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetFunction: "+std::string(error));
            }
        m_kernel_ptr[idev] = kernel_ptr;

        // get variable pointers
        CUdeviceptr alpha_iso_ptr;
        custatus = cuModuleGetGlobal(&alpha_iso_ptr, 0, m_module[idev], alpha_iso_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }

        m_alpha_iso_device_ptr[idev] = alpha_iso_ptr;

        CUdeviceptr alpha_union_ptr;
        custatus = cuModuleGetGlobal(&alpha_union_ptr, 0, m_module[idev], alpha_union_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_alpha_union_device_ptr[idev] = alpha_union_ptr;

        CUdeviceptr rcut_ptr;
        custatus = cuModuleGetGlobal(&rcut_ptr, 0, m_module[idev], rcut_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_rcut_union_device_ptr[idev] = rcut_ptr;

        CUdeviceptr union_params_ptr;
        custatus = cuModuleGetGlobal(&union_params_ptr, 0, m_module[idev], union_params_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_union_params_device_ptr[idev] = union_params_ptr;
        }
    }
#endif
#endif
<commit_msg>pass flag to switch to shared memory<commit_after>#ifdef ENABLE_HIP

#include "hoomd/ExecutionConfiguration.h"

#include <stdio.h>
#include <string>
#include <vector>

#include "GPUEvalFactory.h"

// pybind11 vector bindings
#include <pybind11/pybind11.h>
#include <pybind11/stl_bind.h>

#include <hip/hip_runtime.h>

#if __HIP_PLATFORM_NVCC__
#include <cuda.h>
#include <nvrtc.h>

#include "jitify_safe_headers.hpp"

void GPUEvalFactory::compileGPU(
    const std::string& code,
    const std::string& kernel_name,
    const std::string& include_path,
    const std::string& include_path_source,
    const std::string& cuda_devrt_library_path,
    const unsigned int compute_arch)
    {
    m_exec_conf->msg->notice(3) << "Compiling nvrtc code" << std::endl;

    std::vector<std::string> compile_options = {
        "--gpu-architecture=compute_"+std::to_string(compute_arch),
        "--include-path="+include_path,
        "--include-path="+include_path_source,
        "--device-as-default-execution-space",
        "--std=c++11",
#ifdef ENABLE_HPMC_MIXED_PRECISION
        "-DENABLE_HPMC_MIXED_PRECISION",
#endif
        "-DHOOMD_LLVMJIT_BUILD",
        "-D__HIPCC__",
        "-D__HIP_DEVICE_COMPILE__",
        "-D__HIP_PLATFORM_NVCC__",
        "-lineinfo"
        };

    char *compileParams[compile_options.size()];
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        compileParams[i] = reinterpret_cast<char *>(
            malloc(sizeof(char) * (compile_options[i].length() + 1)));
        snprintf(compileParams[i], compile_options[i].length() + 1, "%s",
                 compile_options[i].c_str());
        }

    // compile

    // add fake math headers + printf
    std::string printf_include = std::string("#define FILE int\n") +
        std::string("int fflush ( FILE * stream );\n") +
        std::string("int fprintf ( FILE * stream, const char * format, ... );\n");

    std::string code_with_headers = std::string(jitify::detail::jitsafe_header_math) +
        printf_include + code;

    m_exec_conf->msg->notice(4) << code_with_headers << std::endl;

    nvrtcResult status = nvrtcCreateProgram(&m_program, code_with_headers.c_str(), "evaluator.cu", 0, NULL, NULL);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcCreateProgram error: "+std::string(nvrtcGetErrorString(status)));

    m_exec_conf->msg->notice(3) << "nvrtc options (notice level 4 shows code):" << std::endl;
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        m_exec_conf->msg->notice(3) << " " << compileParams[i] << std::endl;
        }

    status = nvrtcAddNameExpression(m_program, kernel_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string alpha_iso_name = "&alpha_iso";
    status = nvrtcAddNameExpression(m_program, alpha_iso_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string alpha_union_name = "&alpha_union";
    status = nvrtcAddNameExpression(m_program, alpha_union_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string rcut_name = "&jit::d_rcut_union";
    status = nvrtcAddNameExpression(m_program, rcut_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    std::string union_params_name = "&jit::d_union_params";
    status = nvrtcAddNameExpression(m_program, union_params_name.c_str());
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcAddNameExpression error: "+std::string(nvrtcGetErrorString(status)));

    nvrtcResult compile_result = nvrtcCompileProgram(m_program, compile_options.size(), compileParams);
    for (unsigned int i = 0; i < compile_options.size(); ++i)
        {
        free(compileParams[i]);
        }

    // Obtain compilation log from the program.
    size_t logSize;
    status = nvrtcGetProgramLogSize(m_program, &logSize);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetProgramLogSize error: "+std::string(nvrtcGetErrorString(status)));

    char *log = new char[logSize];
    status = nvrtcGetProgramLog(m_program, log);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetProgramLog error: "+std::string(nvrtcGetErrorString(status)));
    m_exec_conf->msg->notice(3) << "nvrtc output" << std::endl << log << '\n';
    delete[] log;

    if (compile_result != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcCompileProgram error (set device.notice_level=3 to see full log): "+std::string(nvrtcGetErrorString(compile_result)));

    // fetch PTX
    size_t ptx_size;
    status = nvrtcGetPTXSize(m_program, &ptx_size);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetPTXSize error: "+std::string(nvrtcGetErrorString(status)));

    char ptx[ptx_size];
    status = nvrtcGetPTX(m_program, ptx);
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetPTX error: "+std::string(nvrtcGetErrorString(status)));

    // look up mangled names
    char *kernel_name_mangled;
    status = nvrtcGetLoweredName(m_program, kernel_name.c_str(), const_cast<const char **>(&kernel_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *alpha_iso_name_mangled;
    status = nvrtcGetLoweredName(m_program, alpha_iso_name.c_str(), const_cast<const char **>(&alpha_iso_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *alpha_union_name_mangled;
    status = nvrtcGetLoweredName(m_program, alpha_union_name.c_str(), const_cast<const char **>(&alpha_union_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *rcut_name_mangled;
    status = nvrtcGetLoweredName(m_program, rcut_name.c_str(), const_cast<const char **>(&rcut_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    char *union_params_name_mangled;
    status = nvrtcGetLoweredName(m_program, union_params_name.c_str(), const_cast<const char **>(&union_params_name_mangled));
    if (status != NVRTC_SUCCESS)
        throw std::runtime_error("nvrtcGetLoweredName: "+std::string(nvrtcGetErrorString(status)));

    // link PTX into cubin
    CUresult custatus;
    char *error;
    custatus = cuLinkCreate(0, 0, 0, &m_link_state);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkCreate: "+std::string(error));
        }

    custatus = cuLinkAddFile(m_link_state, CU_JIT_INPUT_LIBRARY, cuda_devrt_library_path.c_str(), 0, 0, 0);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkAddFile: "+std::string(error));
        }

    custatus = cuLinkAddData(m_link_state, CU_JIT_INPUT_PTX, (void *) ptx, ptx_size, "evaluator.ptx", 0, 0, 0);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkAddData: "+std::string(error));
        }

    size_t cubinSize;
    void *cubin;

    custatus = cuLinkComplete(m_link_state, &cubin, &cubinSize);
    if (custatus != CUDA_SUCCESS)
        {
        cuGetErrorString(custatus, const_cast<const char **>(&error));
        throw std::runtime_error("cuLinkComplete: "+std::string(error));
        }

    // load cubin into active contexts, and return function pointers
    auto gpu_map = m_exec_conf->getGPUIds();
    m_module.resize(m_exec_conf->getNumActiveGPUs());
    for (int idev = m_exec_conf->getNumActiveGPUs()-1; idev >= 0; --idev)
        {
        cudaSetDevice(gpu_map[idev]);

        // get module
        custatus = cuModuleLoadData(&m_module[idev], cubin);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleLoadData: "+std::string(error));
            }

        // get variable pointers
        CUfunction kernel_ptr;
        custatus = cuModuleGetFunction(&kernel_ptr, m_module[idev], kernel_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetFunction: "+std::string(error));
            }
        m_kernel_ptr[idev] = kernel_ptr;

        // get variable pointers
        CUdeviceptr alpha_iso_ptr;
        custatus = cuModuleGetGlobal(&alpha_iso_ptr, 0, m_module[idev], alpha_iso_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }

        m_alpha_iso_device_ptr[idev] = alpha_iso_ptr;

        CUdeviceptr alpha_union_ptr;
        custatus = cuModuleGetGlobal(&alpha_union_ptr, 0, m_module[idev], alpha_union_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_alpha_union_device_ptr[idev] = alpha_union_ptr;

        CUdeviceptr rcut_ptr;
        custatus = cuModuleGetGlobal(&rcut_ptr, 0, m_module[idev], rcut_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_rcut_union_device_ptr[idev] = rcut_ptr;

        CUdeviceptr union_params_ptr;
        custatus = cuModuleGetGlobal(&union_params_ptr, 0, m_module[idev], union_params_name_mangled);
        if (custatus != CUDA_SUCCESS)
            {
            cuGetErrorString(custatus, const_cast<const char **>(&error));
            throw std::runtime_error("cuModuleGetGlobal: "+std::string(error));
            }
        m_union_params_device_ptr[idev] = union_params_ptr;
        }
    }
#endif
#endif
<|endoftext|>


<commit_before><commit_msg>fix previous commit:<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ascfldlg.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 08:59:17 $
 *
 *  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
 *
 ************************************************************************/
#ifndef _ASCFLDLG_HXX
#define _ASCFLDLG_HXX

#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _SV_LSTBOX_HXX
#include <vcl/lstbox.hxx>
#endif
#ifndef _BASEDLGS_HXX
#include <sfx2/basedlgs.hxx>
#endif
#ifndef _SVX_TXENCBOX_HXX
#include <svx/txencbox.hxx>
#endif
#ifndef _SVX_LANGBOX_HXX
#include <svx/langbox.hxx>
#endif

class SwAsciiOptions;
class SvStream;
class SwDocShell;

class SwAsciiFilterDlg : public SfxModalDialog
{
    FixedLine           aFL;
    FixedText           aCharSetFT;
    SvxTextEncodingBox  aCharSetLB;
    FixedText           aFontFT;
    ListBox             aFontLB;
    FixedText           aLanguageFT;
    SvxLanguageBox      aLanguageLB;
    FixedText           aCRLF_FT;
    RadioButton         aCRLF_RB, aCR_RB, aLF_RB;
    OKButton            aOkPB;
    CancelButton        aCancelPB;
    HelpButton          aHelpPB;
    String              sSystemCharSet;
    BOOL                bSaveLineStatus;

    DECL_LINK( CharSetSelHdl, SvxTextEncodingBox* );
    DECL_LINK( LineEndHdl, RadioButton* );
    void SetCRLF( LineEnd eEnd );
    LineEnd GetCRLF() const;

public:
    // CTOR:    for import - pStream is the inputstream
    //          for export - pStream must be 0
    SwAsciiFilterDlg( Window* pParent, SwDocShell& rDocSh,
                        SvStream* pStream );
    virtual ~SwAsciiFilterDlg();

    void FillOptions( SwAsciiOptions& rOptions );
};

#endif

<commit_msg>INTEGRATION: CWS writercorehandoff (1.4.1310); FILE MERGED 2005/09/13 17:12:21 tra 1.4.1310.2: RESYNC: (1.4-1.5); FILE MERGED 2005/06/06 09:29:42 tra 1.4.1310.1: Unnecessary includes removed #i50348#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: ascfldlg.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-08-14 17:38:18 $
 *
 *  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
 *
 ************************************************************************/
#ifndef _ASCFLDLG_HXX
#define _ASCFLDLG_HXX
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif

#ifndef _SV_LSTBOX_HXX
#include <vcl/lstbox.hxx>
#endif

#ifndef _BASEDLGS_HXX
#include <sfx2/basedlgs.hxx>
#endif

#ifndef _SVX_TXENCBOX_HXX
#include <svx/txencbox.hxx>
#endif

#ifndef _SVX_LANGBOX_HXX
#include <svx/langbox.hxx>
#endif

class SwAsciiOptions;
class SvStream;
class SwDocShell;

class SwAsciiFilterDlg : public SfxModalDialog
{
    FixedLine           aFL;
    FixedText           aCharSetFT;
    SvxTextEncodingBox  aCharSetLB;
    FixedText           aFontFT;
    ListBox             aFontLB;
    FixedText           aLanguageFT;
    SvxLanguageBox      aLanguageLB;
    FixedText           aCRLF_FT;
    RadioButton         aCRLF_RB, aCR_RB, aLF_RB;
    OKButton            aOkPB;
    CancelButton        aCancelPB;
    HelpButton          aHelpPB;
    String              sSystemCharSet;
    BOOL                bSaveLineStatus;

    DECL_LINK( CharSetSelHdl, SvxTextEncodingBox* );
    DECL_LINK( LineEndHdl, RadioButton* );
    void SetCRLF( LineEnd eEnd );
    LineEnd GetCRLF() const;

public:
    // CTOR:    for import - pStream is the inputstream
    //          for export - pStream must be 0
    SwAsciiFilterDlg( Window* pParent, SwDocShell& rDocSh,
                        SvStream* pStream );
    virtual ~SwAsciiFilterDlg();

    void FillOptions( SwAsciiOptions& rOptions );
};

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: navicont.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 09:52:04 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _NAVICONT_HXX
#define _NAVICONT_HXX

#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif

class SwDocShell;
class TransferDataContainer;
class TransferableDataHelper;

/*  [Beschreibung]
    Navigator-Bookmark zur eindeutigen Identifizierung im Sw
*/

class NaviContentBookmark
{
    String          aUrl;       // URL inkl. Sprungmarke
    String          aDescr;     // Description
    long            nDocSh;     // Adresse der DocShell
    USHORT          nDefDrag;   // Description enthaelt defaultDragType

public:
    NaviContentBookmark();
    NaviContentBookmark( const String &rUrl, const String& rDesc,
                            USHORT nDragType, const SwDocShell* );

    const String&   GetURL() const              { return aUrl; }
    const String&   GetDescription() const      { return aDescr; }
    USHORT          GetDefaultDragType() const  { return nDefDrag; }
    long            GetDocShell() const         { return nDocSh; }
    void            Copy( TransferDataContainer& rData ) const;
    BOOL            Paste( TransferableDataHelper& rData );
};

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.4.1202); FILE MERGED 2008/04/01 15:59:16 thb 1.4.1202.2: #i85898# Stripping all external header guards 2008/03/31 16:58:36 rt 1.4.1202.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: navicont.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _NAVICONT_HXX
#define _NAVICONT_HXX

#include <tools/string.hxx>

class SwDocShell;
class TransferDataContainer;
class TransferableDataHelper;

/*  [Beschreibung]
    Navigator-Bookmark zur eindeutigen Identifizierung im Sw
*/

class NaviContentBookmark
{
    String          aUrl;       // URL inkl. Sprungmarke
    String          aDescr;     // Description
    long            nDocSh;     // Adresse der DocShell
    USHORT          nDefDrag;   // Description enthaelt defaultDragType

public:
    NaviContentBookmark();
    NaviContentBookmark( const String &rUrl, const String& rDesc,
                            USHORT nDragType, const SwDocShell* );

    const String&   GetURL() const              { return aUrl; }
    const String&   GetDescription() const      { return aDescr; }
    USHORT          GetDefaultDragType() const  { return nDefDrag; }
    long            GetDocShell() const         { return nDocSh; }
    void            Copy( TransferDataContainer& rData ) const;
    BOOL            Paste( TransferableDataHelper& rData );
};

#endif
<|endoftext|>