<commit_before>//  2006-2008 (c) Viva64.com Team
//  2008-2016 (c) OOO "Program Verification Systems"

#include "comments.h"
#include "encoding.h"

#include <cstdio>
#include <cstring>
#include <string>
#include <functional>
#include <algorithm>
#include <vector>
#include <cassert>
#include <fstream>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <experimental/filesystem>

using namespace std;
using namespace std::experimental;

static bool IsSourceFile(const filesystem::path &path)
{
  static const vector<string> sourceExtensions = {
      ".c"
    , ".cc"
    , ".cpp"
    , ".cp"
    , ".cxx"
    , ".c++"
    , ".cs"
  };
  string ext = path.extension().string();
  transform(ext.begin(), ext.end(), ext.begin(), [](char ch){return tolower(ch);});
  return find(sourceExtensions.begin(), sourceExtensions.end(), ext) != sourceExtensions.end();
}

class ProgramOptions
{
  ProgramOptions() = default;
  ProgramOptions(const ProgramOptions& root) = delete;
  ProgramOptions& operator=(const ProgramOptions&) = delete;
public:
  size_t m_commentType     = -1;
  vector<string> m_files;
  bool m_multiline         = false;
  bool m_readSymlinks      = false;

  static ProgramOptions& Instance()
  {
    static ProgramOptions programOptions;
    return programOptions;
  }
};

void WriteComment(const filesystem::path &path,
                  const string &comment,
                  const string &source,
                  bool isUnixLineEnding,
                  Encoding enc,
                  size_t bomLen)
{
  ofstream osrc(path, ios::binary);
  if (!osrc.is_open())
  {
    cerr << "Error: Couldn't open " << path << endl;
    return;
  }

  if (bomLen != 0)
  {
    osrc.write(source.c_str(), bomLen);
  }

  ConvertEncoding(osrc, comment, enc, !isUnixLineEnding);
  osrc.write(source.c_str() + bomLen, source.length() - bomLen);
}

static void AddCommentsToFile(const filesystem::path &path, const string &comment, const ProgramOptions &options)
{
  if (!IsSourceFile(path))
    return;

  cout << "+ " << path << endl;

  ifstream isrc(path, ios::binary);
  if (!isrc.is_open())
  {
    cerr << "Error: Couldn't open " << path << endl;
    return;
  }

  string str;
  isrc.seekg(0, ios::end);
  str.reserve(isrc.tellg());
  isrc.seekg(0, ios::beg);

  str.assign((istreambuf_iterator<char>(isrc)), istreambuf_iterator<char>());
  isrc.close();
  string source = str;

  Encoding enc;
  size_t bomLen;
  ConvertEncoding(str, enc, bomLen);

  bool isUnixLineEnding = true;
  size_t idx = str.find('\n');
  if (idx != string::npos && idx != 0 && str[idx - 1] == '\r')
    isUnixLineEnding = false;

  PvsStudioFreeComments::CommentsParser parser;
  auto itFreeComment = parser.readFreeComment(source.c_str());
  const char *beg = parser.freeCommentBegin();
  const char *end = parser.freeCommentEnd();

  if (itFreeComment != PvsStudioFreeComments::Comments.end())
  {
    bool needToChangeComment =    (!options.m_multiline && beg[0] == '/' && beg[1] == '*')
                               || (options.m_multiline  && beg[0] == '/' && beg[1] == '/')
                               || itFreeComment != PvsStudioFreeComments::Comments.begin() + (ProgramOptions::Instance().m_commentType - 1);
    if (needToChangeComment)
    {
      source.erase(source.begin() + distance(source.c_str(), beg), source.begin() + distance(source.c_str(), end));
      WriteComment(path, comment, source, isUnixLineEnding, enc, bomLen);
    }
  }
  else
  {
    WriteComment(path, comment, source, isUnixLineEnding, enc, bomLen);
  }
}

static void ProcessFile(filesystem::path path, const string &comment, const ProgramOptions &options)
{
  if (options.m_readSymlinks && filesystem::is_symlink(path))
  {
    std::error_code error;
    path = filesystem::canonical(filesystem::read_symlink(path), path.parent_path(), error);
    if (error != std::error_code())
    {
      return;
    }
  }

  if (filesystem::is_regular_file(path))
  {
    AddCommentsToFile(path, comment, options);
  }
}

static void AddComments(const string &path, const string &comment, const ProgramOptions &options)
{
  auto fsPath = filesystem::canonical(path);
  if (!filesystem::exists(fsPath))
  {
    cerr << "File not exists: " << path << endl;
    return;
  }
  if (filesystem::is_directory(fsPath))
  {
    filesystem::directory_options symlink_flag = options.m_readSymlinks
                                                 ? filesystem::directory_options::follow_directory_symlink
                                                 : filesystem::directory_options::none;
    for (auto &&p : filesystem::recursive_directory_iterator(fsPath, symlink_flag))
    {
      ProcessFile(p.path(), comment, options);
    }
  }
  else
  {
    ProcessFile(fsPath, comment, options);
  }
}

static string Format(const string &comment, bool multiline)
{
  ostringstream ostream;
  istringstream stream(comment);
  string line;

  if (multiline)
  {
    ostream << "/*" << endl;

    while (getline(stream, line))
    {
      ostream << "* " << line << endl;
    }

    ostream << "*/" << endl;
  }
  else
  {
    while (getline(stream, line))
    {
      ostream << "// " << line << endl;
    }
  }

  return ostream.str();
}

static const char Help[] = R"HELP(How to use PVS-Studio for FREE?

  You can use PVS-Studio code analyzer for free, if you add special comments
  to your source code. Available options are provided below.

Usage:

  how-to-use-pvs-studio-free -c <1|2|3> [-m] [-s] [-h] <strings> ...

Options:

  -c <1|2|3>,  /c <1|2|3>,  --comment <1|2|3>
    (required)  Type of comment prepended to the source file.

  -m, /m, --multiline
    Use multi-line comments instead of single-line.

  -s, /s, --symlinks
    Follow the symbolic links and add comment to the files to which symbolic links point (files and directories).

  -h, /?, --help
    Display usage information and exit.

  <string>  (accepted multiple times)
    (required)  Files or directories.

Description:

  The utility will add comments to the files located in the specified folders
  and subfolders. The comments are added to the beginning of the files with the
  extensions .c, .cc, .cpp, .cp, .cxx, .c++, .cs. You don't have to change
  header files. If you use files with other extensions, you can customize this
  utility for your needs.

  Options of comments that will be added to the code (-c NUMBER):

    1. Personal academic project;
    2. Open source non-commercial project;
    3. Independent project of an individual developer.

  If you are using PVS-Studio as a Visual Studio plugin, then enter the
  following license key:

    Name: PVS-Studio Free
    Key:  FREE-FREE-FREE-FREE

  If you are using PVS-Studio for Linux, you do not need to do anything else
  besides adding comments to the source code. Just check your code.

  In case none of the options suits you, we suggest considering a purchase of a
  commercial license for PVS-Studio. We are ready to discuss this and other
  questions via e-mail: support@viva64.com.

  You can find more details about the free version of PVS-Studio
  here: https://www.viva64.com/en/b/0457/
)HELP";

void help()
{
  cout << Help;
}

struct Option
{
  vector<string> names;
  bool hasArg;
  function<void(string&&)> found;
};

struct ProgramOptionsError {};

typedef vector<Option> ParsedOptions;

static void ParseProgramOptions(int argc, const char *argv[], const ParsedOptions &options, function<void(string&&)> found)
{
  auto findOpt = [&options](const string& arg) {
    return find_if(begin(options), end(options), [arg](const Option &o) {
      return find(o.names.begin(), o.names.end(), arg) != o.names.end();
    });
  };

  for (int i = 1; i < argc; ++i)
  {
    string arg = argv[i];
    auto it = findOpt(arg);
    if (it == end(options))
    {
      found(move(arg));
    }
    else if (it->hasArg)
    {
      ++i;
      if (i == argc)
      {
        cout << "No argument specified for " << arg << endl;
        throw ProgramOptionsError();
      }

      string val = argv[i];
      auto itNext = findOpt(val);
      if (itNext != end(options))
      {
        cout << "No argument specified for " << arg << endl;
        throw ProgramOptionsError();
      }
      it->found(move(val));
    }
    else
    {
      it->found(string());
    }
  }
}

int main(int argc, const char *argv[])
{
  auto &progOptions = ProgramOptions::Instance();
  ParsedOptions options = {
    { { "-c", "/c", "--comment" },   true,   [&](string &&arg) { progOptions.m_commentType  = stoull(arg); } },
    { { "-m", "/m", "--multiline" }, false,  [&](string &&)    { progOptions.m_multiline    = true; } },
    { { "-s", "/s", "--symlinks" },  false,  [&](string &&)    { progOptions.m_readSymlinks = true; } },
    { { "-h", "/?", "--help" },      false,  [&](string &&)    { throw ProgramOptionsError(); } },
  };

  try
  {
    ParseProgramOptions(argc, argv, options, [&files = progOptions.m_files](string &&arg){files.emplace_back(move(arg));});

    unsigned long long n = progOptions.m_commentType;
    if (n == 0 || n > PvsStudioFreeComments::Comments.size())
    {
      throw invalid_argument("");
    }

    string comment = Format(PvsStudioFreeComments::Comments[n - 1].m_text, progOptions.m_multiline);
    for (const string &file : progOptions.m_files)
    {
      AddComments(file, comment, progOptions);
    }
  }
  catch (ProgramOptionsError &)
  {
    help();
    return 1;
  }
  catch (invalid_argument &)
  {
    cout << "Invalid comment type specified" << endl;
    help();
    return 1;
  }

  return 0;
}
<commit_msg>support java<commit_after>//  2006-2008 (c) Viva64.com Team
//  2008-2016 (c) OOO "Program Verification Systems"

#include "comments.h"
#include "encoding.h"

#include <cstdio>
#include <cstring>
#include <string>
#include <functional>
#include <algorithm>
#include <vector>
#include <cassert>
#include <fstream>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <experimental/filesystem>

using namespace std;
using namespace std::experimental;

static bool IsSourceFile(const filesystem::path &path)
{
  static const vector<string> sourceExtensions = {
      ".c"
    , ".cc"
    , ".cpp"
    , ".cp"
    , ".cxx"
    , ".c++"
    , ".cs"
    , ".java"
  };
  string ext = path.extension().string();
  transform(ext.begin(), ext.end(), ext.begin(), [](char ch){return tolower(ch);});
  return find(sourceExtensions.begin(), sourceExtensions.end(), ext) != sourceExtensions.end();
}

class ProgramOptions
{
  ProgramOptions() = default;
  ProgramOptions(const ProgramOptions& root) = delete;
  ProgramOptions& operator=(const ProgramOptions&) = delete;
public:
  size_t m_commentType     = -1;
  vector<string> m_files;
  bool m_multiline         = false;
  bool m_readSymlinks      = false;

  static ProgramOptions& Instance()
  {
    static ProgramOptions programOptions;
    return programOptions;
  }
};

void WriteComment(const filesystem::path &path,
                  const string &comment,
                  const string &source,
                  bool isUnixLineEnding,
                  Encoding enc,
                  size_t bomLen)
{
  ofstream osrc(path, ios::binary);
  if (!osrc.is_open())
  {
    cerr << "Error: Couldn't open " << path << endl;
    return;
  }

  if (bomLen != 0)
  {
    osrc.write(source.c_str(), bomLen);
  }

  ConvertEncoding(osrc, comment, enc, !isUnixLineEnding);
  osrc.write(source.c_str() + bomLen, source.length() - bomLen);
}

static void AddCommentsToFile(const filesystem::path &path, const string &comment, const ProgramOptions &options)
{
  if (!IsSourceFile(path))
    return;

  cout << "+ " << path << endl;

  ifstream isrc(path, ios::binary);
  if (!isrc.is_open())
  {
    cerr << "Error: Couldn't open " << path << endl;
    return;
  }

  string str;
  isrc.seekg(0, ios::end);
  str.reserve(isrc.tellg());
  isrc.seekg(0, ios::beg);

  str.assign((istreambuf_iterator<char>(isrc)), istreambuf_iterator<char>());
  isrc.close();
  string source = str;

  Encoding enc;
  size_t bomLen;
  ConvertEncoding(str, enc, bomLen);

  bool isUnixLineEnding = true;
  size_t idx = str.find('\n');
  if (idx != string::npos && idx != 0 && str[idx - 1] == '\r')
    isUnixLineEnding = false;

  PvsStudioFreeComments::CommentsParser parser;
  auto itFreeComment = parser.readFreeComment(source.c_str());
  const char *beg = parser.freeCommentBegin();
  const char *end = parser.freeCommentEnd();

  if (itFreeComment != PvsStudioFreeComments::Comments.end())
  {
    bool needToChangeComment =    (!options.m_multiline && beg[0] == '/' && beg[1] == '*')
                               || (options.m_multiline  && beg[0] == '/' && beg[1] == '/')
                               || itFreeComment != PvsStudioFreeComments::Comments.begin() + (ProgramOptions::Instance().m_commentType - 1);
    if (needToChangeComment)
    {
      source.erase(source.begin() + distance(source.c_str(), beg), source.begin() + distance(source.c_str(), end));
      WriteComment(path, comment, source, isUnixLineEnding, enc, bomLen);
    }
  }
  else
  {
    WriteComment(path, comment, source, isUnixLineEnding, enc, bomLen);
  }
}

static void ProcessFile(filesystem::path path, const string &comment, const ProgramOptions &options)
{
  if (options.m_readSymlinks && filesystem::is_symlink(path))
  {
    std::error_code error;
    path = filesystem::canonical(filesystem::read_symlink(path), path.parent_path(), error);
    if (error != std::error_code())
    {
      return;
    }
  }

  if (filesystem::is_regular_file(path))
  {
    AddCommentsToFile(path, comment, options);
  }
}

static void AddComments(const string &path, const string &comment, const ProgramOptions &options)
{
  auto fsPath = filesystem::canonical(path);
  if (!filesystem::exists(fsPath))
  {
    cerr << "File not exists: " << path << endl;
    return;
  }
  if (filesystem::is_directory(fsPath))
  {
    filesystem::directory_options symlink_flag = options.m_readSymlinks
                                                 ? filesystem::directory_options::follow_directory_symlink
                                                 : filesystem::directory_options::none;
    for (auto &&p : filesystem::recursive_directory_iterator(fsPath, symlink_flag))
    {
      ProcessFile(p.path(), comment, options);
    }
  }
  else
  {
    ProcessFile(fsPath, comment, options);
  }
}

static string Format(const string &comment, bool multiline)
{
  ostringstream ostream;
  istringstream stream(comment);
  string line;

  if (multiline)
  {
    ostream << "/*" << endl;

    while (getline(stream, line))
    {
      ostream << "* " << line << endl;
    }

    ostream << "*/" << endl;
  }
  else
  {
    while (getline(stream, line))
    {
      ostream << "// " << line << endl;
    }
  }

  return ostream.str();
}

static const char Help[] = R"HELP(How to use PVS-Studio for FREE?

  You can use PVS-Studio code analyzer for free, if you add special comments
  to your source code. Available options are provided below.

Usage:

  how-to-use-pvs-studio-free -c <1|2|3> [-m] [-s] [-h] <strings> ...

Options:

  -c <1|2|3>,  /c <1|2|3>,  --comment <1|2|3>
    (required)  Type of comment prepended to the source file.

  -m, /m, --multiline
    Use multi-line comments instead of single-line.

  -s, /s, --symlinks
    Follow the symbolic links and add comment to the files to which symbolic links point (files and directories).

  -h, /?, --help
    Display usage information and exit.

  <string>  (accepted multiple times)
    (required)  Files or directories.

Description:

  The utility will add comments to the files located in the specified folders
  and subfolders. The comments are added to the beginning of the files with the
  extensions .c, .cc, .cpp, .cp, .cxx, .c++, .cs. You don't have to change
  header files. If you use files with other extensions, you can customize this
  utility for your needs.

  Options of comments that will be added to the code (-c NUMBER):

    1. Personal academic project;
    2. Open source non-commercial project;
    3. Independent project of an individual developer.

  If you are using PVS-Studio as a Visual Studio plugin, then enter the
  following license key:

    Name: PVS-Studio Free
    Key:  FREE-FREE-FREE-FREE

  If you are using PVS-Studio for Linux, you do not need to do anything else
  besides adding comments to the source code. Just check your code.

  In case none of the options suits you, we suggest considering a purchase of a
  commercial license for PVS-Studio. We are ready to discuss this and other
  questions via e-mail: support@viva64.com.

  You can find more details about the free version of PVS-Studio
  here: https://www.viva64.com/en/b/0457/
)HELP";

void help()
{
  cout << Help;
}

struct Option
{
  vector<string> names;
  bool hasArg;
  function<void(string&&)> found;
};

struct ProgramOptionsError {};

typedef vector<Option> ParsedOptions;

static void ParseProgramOptions(int argc, const char *argv[], const ParsedOptions &options, function<void(string&&)> found)
{
  auto findOpt = [&options](const string& arg) {
    return find_if(begin(options), end(options), [arg](const Option &o) {
      return find(o.names.begin(), o.names.end(), arg) != o.names.end();
    });
  };

  for (int i = 1; i < argc; ++i)
  {
    string arg = argv[i];
    auto it = findOpt(arg);
    if (it == end(options))
    {
      found(move(arg));
    }
    else if (it->hasArg)
    {
      ++i;
      if (i == argc)
      {
        cout << "No argument specified for " << arg << endl;
        throw ProgramOptionsError();
      }

      string val = argv[i];
      auto itNext = findOpt(val);
      if (itNext != end(options))
      {
        cout << "No argument specified for " << arg << endl;
        throw ProgramOptionsError();
      }
      it->found(move(val));
    }
    else
    {
      it->found(string());
    }
  }
}

int main(int argc, const char *argv[])
{
  auto &progOptions = ProgramOptions::Instance();
  ParsedOptions options = {
    { { "-c", "/c", "--comment" },   true,   [&](string &&arg) { progOptions.m_commentType  = stoull(arg); } },
    { { "-m", "/m", "--multiline" }, false,  [&](string &&)    { progOptions.m_multiline    = true; } },
    { { "-s", "/s", "--symlinks" },  false,  [&](string &&)    { progOptions.m_readSymlinks = true; } },
    { { "-h", "/?", "--help" },      false,  [&](string &&)    { throw ProgramOptionsError(); } },
  };

  try
  {
    ParseProgramOptions(argc, argv, options, [&files = progOptions.m_files](string &&arg){files.emplace_back(move(arg));});

    unsigned long long n = progOptions.m_commentType;
    if (n == 0 || n > PvsStudioFreeComments::Comments.size())
    {
      throw invalid_argument("");
    }

    string comment = Format(PvsStudioFreeComments::Comments[n - 1].m_text, progOptions.m_multiline);
    for (const string &file : progOptions.m_files)
    {
      AddComments(file, comment, progOptions);
    }
  }
  catch (ProgramOptionsError &)
  {
    help();
    return 1;
  }
  catch (invalid_argument &)
  {
    cout << "Invalid comment type specified" << endl;
    help();
    return 1;
  }

  return 0;
}
<|endoftext|>


<commit_before>2ac80917-ad5c-11e7-8223-ac87a332f658<commit_msg>updated some files<commit_after>2b21b89e-ad5c-11e7-b143-ac87a332f658<|endoftext|>


<commit_before>068b2b97-2748-11e6-935f-e0f84713e7b8<commit_msg>more bug fix<commit_after>06a0aa8f-2748-11e6-9b7e-e0f84713e7b8<|endoftext|>


<commit_before>6fe03aa3-2749-11e6-a743-e0f84713e7b8<commit_msg>Does anyone even read these anymore???<commit_after>6ff15294-2749-11e6-871c-e0f84713e7b8<|endoftext|>


<commit_before>b1bcb051-4b02-11e5-8f6a-28cfe9171a43<commit_msg>Now it no longer crashes if X<commit_after>b1c85db0-4b02-11e5-a0b5-28cfe9171a43<|endoftext|>


<commit_before>a90b7fcf-4b02-11e5-a3b3-28cfe9171a43<commit_msg>Added that feature we discussed on... Was it monday?<commit_after>a91744f8-4b02-11e5-82fe-28cfe9171a43<|endoftext|>


<commit_before>// $RCSfile: $
// $Revision: $ $Date: $
// Auth: Samson Bonfante (bonfante@steptools.com)
//
// Copyright (c) 1991-2015 by STEP Tools Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <rose.h>
#include <stp_schema.h>

void main(int argc,char **argv)
{
    stplib_init();

	RoseDesign * d = ROSE.findDesign("io1-md-214.stp.stp");

	RoseCursor cur;
	RoseObject * obj;

	cur.traverse(d);
	cur.domain(ROSE_DOMAIN(stp_product_definition));

	while ((obj = cur.next()) != 0){
		stp_product_definition * pd = ROSE_CAST(stp_product_definition, obj);

		printf("Product Definiton ID #%d \n", pd->id());
	}

    return;
}<commit_msg>Testing GUID code.<commit_after>// $RCSfile: $
// $Revision: $ $Date: $
// Auth: Samson Bonfante (bonfante@steptools.com)
//
// Copyright (c) 1991-2015 by STEP Tools Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <rose.h>
#include <stp_schema.h>
#include "GUID.h"
void main(int argc,char **argv)
{
    stplib_init();

	RoseDesign * d = ROSE.findDesign("io1-md-214.stp.stp");

	RoseCursor cur;
	RoseObject * obj;

	cur.traverse(d);
	cur.domain(ROSE_DOMAIN(stp_product_definition));

	while ((obj = cur.next()) != 0){
		stp_product_definition * pd = ROSE_CAST(stp_product_definition, obj);
		unsigned char GUID[16];
		get_guid(GUID);
		printf("Product Definiton ID #%d \t GUID: %s\n", pd->id(),GUID);
	}

    return;
}<|endoftext|>


<commit_before>//Copyright 2015 Adam Smith
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

// Contact :
// Email             : solairelibrary@mail.com
// GitHub repository : https://github.com/SolaireLibrary/SolaireCPP

#include "Solaire/Json/Format.hpp"

namespace Solaire {

    static bool skipWhitespace(IStream& aStream) {
        if(aStream.end()) return true;
        char c;
        aStream >> c;
        while(std::isspace(c)) {
            if(aStream.end()) return true;
            aStream >> c;
        }
        aStream.setOffset(aStream.getOffset() - 1);
        return true;
    }

    static bool writeValue(const GenericValue& aValue, OStream& aStream) throw();

    static bool writeNull(OStream& aStream) throw() {
        aStream << "null";
        return true;
    }

    static bool writeChar(const char aValue, OStream& aStream) throw() {
        aStream << '"' << aValue << '"';
        return true;
    }

    static bool writeBool(const bool aValue, OStream& aStream) throw() {
        if(aValue) {
            aStream << "true";
        }else {
            aStream << "false";
        }
        return true;
    }

    static bool writeUnsigned(const uint64_t aValue, OStream& aStream) throw() {
        CString tmp;
        tmp += aValue;
        aStream << tmp;
        return true;
    }

    static bool writeSigned(const int64_t aValue, OStream& aStream) throw() {
        CString tmp;
        tmp += aValue;
        aStream << tmp;
        return true;
    }

    static bool writeDouble(const double aValue, OStream& aStream) throw() {
        CString tmp;
        tmp += aValue;
        aStream << tmp;
    }

    static bool writeString(const StringConstant<char>& aValue, OStream& aStream) throw() {
        aStream << '"';
        aStream << aValue;
        aStream << '"';
        return true;
    }

    static bool writeArray(const GenericArray& aValue, OStream& aStream) throw() {
        aStream << '[';
        const auto end = aValue.end();
        for(auto i = aValue.begin(); i != end; ++i) {
            if(! writeValue(*i, aStream)) return false;
            if(end - i > 1) aStream << ',';
        }
        aStream << ']';
        return true;
    }

    static bool writeObject(const GenericObject& aValue, OStream& aStream) throw() {
        aStream << '{';
        const SharedAllocation<StaticContainer<GenericObject::Entry>> entries = aValue.getEntries();
        const auto end = entries->end();
        for(auto i = entries->begin(); i != end; ++i) {
            if(! writeString(i->first, aStream)) return false;
            aStream << ':';
            if(! writeValue(i->second, aStream)) return false;
            if(end - i > 1) aStream << ',';
        }
        aStream << '}';
        return false;
    }

    static bool writeValue(const GenericValue& aValue, OStream& aStream) throw() {
        switch(aValue.getType()) {
        case GenericValue::NULL_T:
            return writeNull(aStream);
        case GenericValue::CHAR_T:
            return writeChar(aValue.getChar(), aStream);
        case GenericValue::BOOL_T:
            return writeBool(aValue.getBool(), aStream);
        case GenericValue::UNSIGNED_T:
            return writeUnsigned(aValue.getUnsigned(), aStream);
        case GenericValue::SIGNED_T:
            return writeSigned(aValue.getSigned(), aStream);
        case GenericValue::DOUBLE_T:
            return writeDouble(aValue.getDouble(), aStream);
        case GenericValue::STRING_T:
            return writeString(aValue.getString(), aStream);
        case GenericValue::ARRAY_T:
            return writeArray(aValue.getArray(), aStream);
        case GenericValue::OBJECT_T:
            return writeObject(aValue.getObject(), aStream);
        default:
            return false;
        }
    }

    static GenericValue::ValueType getType(IStream& aStream) {
        const int32_t offset = aStream.getOffset();
        GenericValue::ValueType type = GenericValue::NULL_T;

        skipWhitespace(aStream);
        if(! aStream.end()) {
            char c;
            aStream >> c;

            switch(c){
            case 'n':
                type = GenericValue::NULL_T;
                break;
            case 't':
            case 'f':
                type = GenericValue::BOOL_T;
                break;
            case '-':
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                type = GenericValue::DOUBLE_T;
                break;
            case '"':
                type = GenericValue::STRING_T;
                break;
            case '[':
                type = GenericValue::ARRAY_T;
                break;
            case '{':
                type = GenericValue::OBJECT_T;
                break;
            default:
                break;
            }
        }

        aStream.setOffset(offset);
        return type;
    }

    static GenericValue readValue(IStream& aStream);

    static GenericValue readNull(IStream& aStream) throw() {
        if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Null : Could not locate value");
        char buffer[4];
        aStream.read(buffer, 4);
        if(std::memcmp(buffer, "null", 4) != 0) throw std::runtime_error("Json::Null : Value must be either 'null'");
        return GenericValue();
    }

    static GenericValue readBool(IStream& aStream) {
        if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Bool : Could not locate value");
        char buffer[5];
        aStream.read(buffer, 4);
        switch(buffer[0]){
        case 't':
            if(std::memcmp(buffer, "true", 4) != 0) throw std::runtime_error("Json::Bool : Value must be either 'true' or 'false'");
            return GenericValue(true);
        case 'f':
            aStream >> buffer[4];
            if(std::memcmp(buffer, "false", 5) != 0) throw std::runtime_error("Json::Bool : Value must be either 'true' or 'false'");
            return GenericValue(false);
        default:
           throw std::runtime_error("Json::Bool : Failed to read value");
        }
    }

    static GenericValue readDouble(IStream& aStream) throw() {
        if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Number : Could not locate value");
        CString buffer;
        char c;
        aStream >> c;
        while((c >= '0' && c <= '9') || c == '-' || c == '.' || c == 'e' || c == 'E') {
            buffer += c;
            aStream >> c;
        }
        aStream.setOffset(aStream.getOffset() - 1);

        return static_cast<int32_t>(buffer); //! \todo readDouble
    }

    static GenericValue readString(IStream& aStream) {
        bool escaped = false;
        char c;
        aStream >> c;
        if(c != '"') throw std::runtime_error("Json::String : String must be opened by '\"'");
        GenericValue value;
        String<char>& string = value.setString();

        while(! aStream.end()){
            aStream >> c;
            switch(c) {
            case '\\':
                if(escaped){
                    string.pushBack('\\');
                    escaped = false;
                }else{
                    escaped = true;
                }
                break;
            case '"':
                if(escaped){
                    string.pushBack('"');
                    escaped = false;
                }else{
                    return value;
                }
                break;
            default:
                string.pushBack(c);
                escaped = false;
                break;
            }
        }

        throw std::runtime_error("Json::String : String must be closed by '\"'");
    }

    static GenericValue readArray(IStream& aStream) {
        char c;
        aStream >> c;
        if(c != '[') throw std::runtime_error("Json::Array : Array must be opened '['");

        GenericValue value;
        GenericArray& array_ = value.setArray();

        // Check for close
        if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Array : Failed to locate first element");
        if(aStream.peek<char>() == ']') return value;

        while(! aStream.end()) {
            // Read value
            array_.pushBack(readValue(aStream));

            // Read seperator
            if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Array : Failed to locate next element");
            aStream >> c;
            switch(c){
            case ']':
                return value;
            case ',':
                break;
            default:
                #ifdef SOLAIRE_JSON_WHITESPACE_SEPERATORS
                    aStream.setOffset(aStream.getOffset() -1);
                    break;
                #else
                    throw std::runtime_error("Json::Array : Array elements must be separated by ','");
                #endif
            }
        }
        throw std::runtime_error("Json::Array : Array must be closed by ']'");
    }

    static GenericValue readObject(IStream& aStream) {
        char c;
        aStream >> c;
        if(c != '{') throw std::runtime_error("Json::Object : Object must be opened by '{'");

        GenericValue value;
        GenericObject& object = value.setObject();

        // Check for close
        if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Object : Failed to read first member");
        if(aStream.peek<char>() == '}') return value;

        while(! aStream.end()) {
            // Read name
            const GenericValue name = readString(aStream);
            if(! name.isString()) throw std::runtime_error("Json::Object : Member name must be a string");

            // Read divider
            if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Object : Failed to determine position of member name divider");
            aStream >> c;
            if(c != ':') throw std::runtime_error("Json::Object : Member name and value must be separated by ':'");

            // Read value
            object.emplace(name.getString(), readValue(aStream));

            // Read seperator
            if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Object : Failed to determine position of member separator");
            aStream >> c;
            switch(c){
            case '}':
                return value;
            case ',':
                break;
            default:
                #ifdef SOLAIRE_JSON_WHITESPACE_SEPERATORS
                    aStream.setOffset(aStream.getOffset() -1);
                    break;
                #else
                    throw std::runtime_error("Json::Object : Members must be separated by ','");
                #endif
            }
        }
        throw std::runtime_error("Json::Object : Object must be closed by '}'");
    }

    static GenericValue readValue(IStream& aStream) {
        switch(getType(aStream)) {
        case GenericValue::NULL_T:
            return readNull(aStream);
        case GenericValue::BOOL_T:
            return readBool(aStream);
        case GenericValue::DOUBLE_T:
            return readDouble(aStream);
        case GenericValue::STRING_T:
            return readString(aStream);
        case GenericValue::ARRAY_T:
            return readArray(aStream);
        case GenericValue::OBJECT_T:
            return readObject(aStream);
        default:
        throw std::runtime_error("Invalid json type");
        }
    }

    // JsonFormat

    SOLAIRE_EXPORT_CALL JsonFormat::~JsonFormat() {

    }

    GenericValue SOLAIRE_EXPORT_CALL JsonFormat::readValue(IStream& aStream) const throw() {
        try{
            return Solaire::readValue(aStream);
        }catch(std::exception& e) {
            std::cerr << e.what() << std::endl;
            return GenericValue();
        }
    }

    bool SOLAIRE_EXPORT_CALL JsonFormat::writeValue(const GenericValue& aValue, OStream& aStream) const throw() {

        try{
            return Solaire::writeValue(aValue, aStream);
        }catch(std::exception& e) {
            std::cerr << e.what() << std::endl;
            return false;
        }
    }

}
<commit_msg>Fixed double parsing implementation<commit_after>//Copyright 2015 Adam Smith
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

// Contact :
// Email             : solairelibrary@mail.com
// GitHub repository : https://github.com/SolaireLibrary/SolaireCPP

#include "Solaire/Json/Format.hpp"

namespace Solaire {

    static bool skipWhitespace(IStream& aStream) {
        if(aStream.end()) return true;
        char c;
        aStream >> c;
        while(std::isspace(c)) {
            if(aStream.end()) return true;
            aStream >> c;
        }
        aStream.setOffset(aStream.getOffset() - 1);
        return true;
    }

    static bool writeValue(const GenericValue& aValue, OStream& aStream) throw();

    static bool writeNull(OStream& aStream) throw() {
        aStream << "null";
        return true;
    }

    static bool writeChar(const char aValue, OStream& aStream) throw() {
        aStream << '"' << aValue << '"';
        return true;
    }

    static bool writeBool(const bool aValue, OStream& aStream) throw() {
        if(aValue) {
            aStream << "true";
        }else {
            aStream << "false";
        }
        return true;
    }

    static bool writeUnsigned(const uint64_t aValue, OStream& aStream) throw() {
        CString tmp;
        tmp += aValue;
        aStream << tmp;
        return true;
    }

    static bool writeSigned(const int64_t aValue, OStream& aStream) throw() {
        CString tmp;
        tmp += aValue;
        aStream << tmp;
        return true;
    }

    static bool writeDouble(const double aValue, OStream& aStream) throw() {
        CString tmp;
        tmp += aValue;
        aStream << tmp;
        return true;
    }

    static bool writeString(const StringConstant<char>& aValue, OStream& aStream) throw() {
        aStream << '"';
        aStream << aValue;
        aStream << '"';
        return true;
    }

    static bool writeArray(const GenericArray& aValue, OStream& aStream) throw() {
        aStream << '[';
        const auto end = aValue.end();
        for(auto i = aValue.begin(); i != end; ++i) {
            if(! writeValue(*i, aStream)) return false;
            if(end - i > 1) aStream << ',';
        }
        aStream << ']';
        return true;
    }

    static bool writeObject(const GenericObject& aValue, OStream& aStream) throw() {
        aStream << '{';
        const SharedAllocation<StaticContainer<GenericObject::Entry>> entries = aValue.getEntries();
        const auto end = entries->end();
        for(auto i = entries->begin(); i != end; ++i) {
            if(! writeString(i->first, aStream)) return false;
            aStream << ':';
            if(! writeValue(i->second, aStream)) return false;
            if(end - i > 1) aStream << ',';
        }
        aStream << '}';
        return false;
    }

    static bool writeValue(const GenericValue& aValue, OStream& aStream) throw() {
        switch(aValue.getType()) {
        case GenericValue::NULL_T:
            return writeNull(aStream);
        case GenericValue::CHAR_T:
            return writeChar(aValue.getChar(), aStream);
        case GenericValue::BOOL_T:
            return writeBool(aValue.getBool(), aStream);
        case GenericValue::UNSIGNED_T:
            return writeUnsigned(aValue.getUnsigned(), aStream);
        case GenericValue::SIGNED_T:
            return writeSigned(aValue.getSigned(), aStream);
        case GenericValue::DOUBLE_T:
            return writeDouble(aValue.getDouble(), aStream);
        case GenericValue::STRING_T:
            return writeString(aValue.getString(), aStream);
        case GenericValue::ARRAY_T:
            return writeArray(aValue.getArray(), aStream);
        case GenericValue::OBJECT_T:
            return writeObject(aValue.getObject(), aStream);
        default:
            return false;
        }
    }

    static GenericValue::ValueType getType(IStream& aStream) {
        const int32_t offset = aStream.getOffset();
        GenericValue::ValueType type = GenericValue::NULL_T;

        skipWhitespace(aStream);
        if(! aStream.end()) {
            char c;
            aStream >> c;

            switch(c){
            case 'n':
                type = GenericValue::NULL_T;
                break;
            case 't':
            case 'f':
                type = GenericValue::BOOL_T;
                break;
            case '-':
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                type = GenericValue::DOUBLE_T;
                break;
            case '"':
                type = GenericValue::STRING_T;
                break;
            case '[':
                type = GenericValue::ARRAY_T;
                break;
            case '{':
                type = GenericValue::OBJECT_T;
                break;
            default:
                break;
            }
        }

        aStream.setOffset(offset);
        return type;
    }

    static GenericValue readValue(IStream& aStream);

    static GenericValue readNull(IStream& aStream) throw() {
        if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Null : Could not locate value");
        char buffer[4];
        aStream.read(buffer, 4);
        if(std::memcmp(buffer, "null", 4) != 0) throw std::runtime_error("Json::Null : Value must be either 'null'");
        return GenericValue();
    }

    static GenericValue readBool(IStream& aStream) {
        if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Bool : Could not locate value");
        char buffer[5];
        aStream.read(buffer, 4);
        switch(buffer[0]){
        case 't':
            if(std::memcmp(buffer, "true", 4) != 0) throw std::runtime_error("Json::Bool : Value must be either 'true' or 'false'");
            return GenericValue(true);
        case 'f':
            aStream >> buffer[4];
            if(std::memcmp(buffer, "false", 5) != 0) throw std::runtime_error("Json::Bool : Value must be either 'true' or 'false'");
            return GenericValue(false);
        default:
           throw std::runtime_error("Json::Bool : Failed to read value");
        }
    }

    static GenericValue readDouble(IStream& aStream) throw() {
        if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Number : Could not locate value");
        CString buffer;
        char c;
        aStream >> c;
        while((c >= '0' && c <= '9') || c == '-' || c == '.' || c == 'e' || c == 'E') {
            buffer += c;
            aStream >> c;
        }
        aStream.setOffset(aStream.getOffset() - 1);

        return static_cast<double>(buffer);
    }

    static GenericValue readString(IStream& aStream) {
        bool escaped = false;
        char c;
        aStream >> c;
        if(c != '"') throw std::runtime_error("Json::String : String must be opened by '\"'");
        GenericValue value;
        String<char>& string = value.setString();

        while(! aStream.end()){
            aStream >> c;
            switch(c) {
            case '\\':
                if(escaped){
                    string.pushBack('\\');
                    escaped = false;
                }else{
                    escaped = true;
                }
                break;
            case '"':
                if(escaped){
                    string.pushBack('"');
                    escaped = false;
                }else{
                    return value;
                }
                break;
            default:
                string.pushBack(c);
                escaped = false;
                break;
            }
        }

        throw std::runtime_error("Json::String : String must be closed by '\"'");
    }

    static GenericValue readArray(IStream& aStream) {
        char c;
        aStream >> c;
        if(c != '[') throw std::runtime_error("Json::Array : Array must be opened '['");

        GenericValue value;
        GenericArray& array_ = value.setArray();

        // Check for close
        if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Array : Failed to locate first element");
        if(aStream.peek<char>() == ']') return value;

        while(! aStream.end()) {
            // Read value
            array_.pushBack(readValue(aStream));

            // Read seperator
            if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Array : Failed to locate next element");
            aStream >> c;
            switch(c){
            case ']':
                return value;
            case ',':
                break;
            default:
                #ifdef SOLAIRE_JSON_WHITESPACE_SEPERATORS
                    aStream.setOffset(aStream.getOffset() -1);
                    break;
                #else
                    throw std::runtime_error("Json::Array : Array elements must be separated by ','");
                #endif
            }
        }
        throw std::runtime_error("Json::Array : Array must be closed by ']'");
    }

    static GenericValue readObject(IStream& aStream) {
        char c;
        aStream >> c;
        if(c != '{') throw std::runtime_error("Json::Object : Object must be opened by '{'");

        GenericValue value;
        GenericObject& object = value.setObject();

        // Check for close
        if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Object : Failed to read first member");
        if(aStream.peek<char>() == '}') return value;

        while(! aStream.end()) {
            // Read name
            const GenericValue name = readString(aStream);
            if(! name.isString()) throw std::runtime_error("Json::Object : Member name must be a string");

            // Read divider
            if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Object : Failed to determine position of member name divider");
            aStream >> c;
            if(c != ':') throw std::runtime_error("Json::Object : Member name and value must be separated by ':'");

            // Read value
            object.emplace(name.getString(), readValue(aStream));

            // Read seperator
            if(! skipWhitespace(aStream)) throw std::runtime_error("Json::Object : Failed to determine position of member separator");
            aStream >> c;
            switch(c){
            case '}':
                return value;
            case ',':
                break;
            default:
                #ifdef SOLAIRE_JSON_WHITESPACE_SEPERATORS
                    aStream.setOffset(aStream.getOffset() -1);
                    break;
                #else
                    throw std::runtime_error("Json::Object : Members must be separated by ','");
                #endif
            }
        }
        throw std::runtime_error("Json::Object : Object must be closed by '}'");
    }

    static GenericValue readValue(IStream& aStream) {
        switch(getType(aStream)) {
        case GenericValue::NULL_T:
            return readNull(aStream);
        case GenericValue::BOOL_T:
            return readBool(aStream);
        case GenericValue::DOUBLE_T:
            return readDouble(aStream);
        case GenericValue::STRING_T:
            return readString(aStream);
        case GenericValue::ARRAY_T:
            return readArray(aStream);
        case GenericValue::OBJECT_T:
            return readObject(aStream);
        default:
        throw std::runtime_error("Invalid json type");
        }
    }

    // JsonFormat

    SOLAIRE_EXPORT_CALL JsonFormat::~JsonFormat() {

    }

    GenericValue SOLAIRE_EXPORT_CALL JsonFormat::readValue(IStream& aStream) const throw() {
        try{
            return Solaire::readValue(aStream);
        }catch(std::exception& e) {
            std::cerr << e.what() << std::endl;
            return GenericValue();
        }
    }

    bool SOLAIRE_EXPORT_CALL JsonFormat::writeValue(const GenericValue& aValue, OStream& aStream) const throw() {

        try{
            return Solaire::writeValue(aValue, aStream);
        }catch(std::exception& e) {
            std::cerr << e.what() << std::endl;
            return false;
        }
    }

}
<|endoftext|>


<commit_before>#include <cuda_runtime.h>
#include <cublas_v2.h>
#include <cassert>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <iostream>

using namespace std;

#define M_MAX 256
#define K_MAX 32768
#define N_MAX 16344

/*
 *         K                  N
 *    ____________       ____________
 *   |            |     |            |
 *   |            |     |            |
 *   |   M_{1}    |     |    M_{2}   |
 * M |            | * K |            |
 *   |            |     |            |
 *   |____________|     |____________|
 *
 */

int main() {
    cublasHandle_t cublasHandle;
    void* devPtr[3], * hostPtr[3];
    float alpha, beta;
    clock_t startTime;
    alpha = beta = 1.0;

    assert(cublasCreate(&cublasHandle) == CUBLAS_STATUS_SUCCESS);
    assert(cudaMalloc(&devPtr[0], M_MAX * K_MAX * sizeof(float)) == cudaSuccess);
    assert(cudaMalloc(&devPtr[1], K_MAX * N_MAX * sizeof(float)) == cudaSuccess);
    assert(cudaMalloc(&devPtr[2], M_MAX * N_MAX * sizeof(float)) == cudaSuccess);
    assert(hostPtr[0] = malloc(M_MAX * K_MAX * sizeof(float)));
    assert(hostPtr[1] = malloc(K_MAX * N_MAX * sizeof(float)));
    assert(hostPtr[2] = malloc(M_MAX * N_MAX * sizeof(float)));

    for (int m = 64; m <= M_MAX; m <<= 1) {
        for (int k = 64; k <= K_MAX; k <<= 1) {
            printf("M: %d, K: %d\n", m, k);
            for (int n = 128; n <= N_MAX; n <<= 1) {
                int repeat = (M_MAX / m) * (N_MAX / n) * (K_MAX / k);
                startTime = clock();
                while (repeat--) {
                    assert(cublasSetMatrix(k, m, sizeof(float), hostPtr[0], k, devPtr[0], k) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasSetMatrix(n, k, sizeof(float), hostPtr[1], n, devPtr[1], n) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasSetMatrix(n, m, sizeof(float), hostPtr[2], n, devPtr[2], n) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasSgemm(cublasHandle, CUBLAS_OP_N, CUBLAS_OP_N, n, m, k, &alpha, (const float*) devPtr[1], n, (const float*) devPtr[0], k, &beta, (float*) devPtr[2], n) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasGetMatrix(k, m, sizeof(float), devPtr[0], k, hostPtr[0], k) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasGetMatrix(n, k, sizeof(float), devPtr[1], n, hostPtr[1], n) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasGetMatrix(n, m, sizeof(float), devPtr[2], n, hostPtr[2], n) == CUBLAS_STATUS_SUCCESS);
                }
                printf("N: %d, time: %lf\n", n, (double) (clock() - startTime) / CLOCKS_PER_SEC);
            }
        }
    }

    free(hostPtr[2]);
    free(hostPtr[1]);
    free(hostPtr[0]);
    assert(cudaFree(devPtr[2]) == cudaSuccess);
    assert(cudaFree(devPtr[1]) == cudaSuccess);
    assert(cudaFree(devPtr[0]) == cudaSuccess);
    cublasDestroy(cublasHandle);
    return 0;
}

<commit_msg>[master] Second running version. Of constant output size<commit_after>#include <cuda_runtime.h>
#include <cublas_v2.h>
#include <cassert>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <iostream>

using namespace std;

#define M_MAX 256
#define K_MAX 32768
#define MAT_MAX (1 << 21)

/*
 *         K                  N
 *    ____________       ____________
 *   |            |     |            |
 *   |            |     |            |
 *   |   M_{1}    |     |    M_{2}   |
 * M |            | * K |            |
 *   |            |     |            |
 *   |____________|     |____________|
 *
 */

int main() {
    cublasHandle_t cublasHandle;
    void* devPtr[3], * hostPtr[3];
    float alpha, beta;
    clock_t startTime;
    alpha = beta = 1.0;

    assert(cublasCreate(&cublasHandle) == CUBLAS_STATUS_SUCCESS);
    assert(cudaMalloc(&devPtr[0], M_MAX * K_MAX * sizeof(float)) == cudaSuccess);
    assert(hostPtr[0] = malloc(M_MAX * K_MAX * sizeof(float)));

    for (int m = 64; m <= M_MAX; m <<= 1) {
        for (int k = 64; k <= K_MAX; k <<= 1) {
            printf("M: %d, K: %d\n", m, k);
            int nMax;
            if (m < k) {
                nMax = MAT_MAX / k;
            } else {
                nMax = MAT_MAX / m;
            }
            assert(cudaMalloc(&devPtr[1], K_MAX * nMax * sizeof(float)) == cudaSuccess);
            assert(cudaMalloc(&devPtr[2], M_MAX * nMax * sizeof(float)) == cudaSuccess);
            assert(hostPtr[1] = malloc(K_MAX * nMax * sizeof(float)));
            assert(hostPtr[2] = malloc(M_MAX * nMax * sizeof(float)));
            for (int n = 128; n <= nMax; n <<= 1) {
                int repeat = (M_MAX / m) * (MAT_MAX / 64 / n) * (K_MAX / k);
                startTime = clock();
                while (repeat--) {
                    assert(cublasSetMatrix(k, m, sizeof(float), hostPtr[0], k, devPtr[0], k) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasSetMatrix(n, k, sizeof(float), hostPtr[1], n, devPtr[1], n) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasSetMatrix(n, m, sizeof(float), hostPtr[2], n, devPtr[2], n) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasSgemm(cublasHandle, CUBLAS_OP_N, CUBLAS_OP_N, n, m, k, &alpha, (const float*) devPtr[1], n, (const float*) devPtr[0], k, &beta, (float*) devPtr[2], n) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasGetMatrix(k, m, sizeof(float), devPtr[0], k, hostPtr[0], k) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasGetMatrix(n, k, sizeof(float), devPtr[1], n, hostPtr[1], n) == CUBLAS_STATUS_SUCCESS);
                    assert(cublasGetMatrix(n, m, sizeof(float), devPtr[2], n, hostPtr[2], n) == CUBLAS_STATUS_SUCCESS);
                }
                printf("N: %d, time: %lf\n", n, (double) (clock() - startTime) / CLOCKS_PER_SEC);
            }
            free(hostPtr[2]);
            free(hostPtr[1]);
            assert(cudaFree(devPtr[2]) == cudaSuccess);
            assert(cudaFree(devPtr[1]) == cudaSuccess);
        }
    }

    free(hostPtr[0]);
    assert(cudaFree(devPtr[0]) == cudaSuccess);
    cublasDestroy(cublasHandle);
    return 0;
}

<|endoftext|>


<commit_before>c262d6cf-2747-11e6-9a2b-e0f84713e7b8<commit_msg>Added that feature we discussed on... Was it monday?<commit_after>c26dec00-2747-11e6-85d3-e0f84713e7b8<|endoftext|>


<commit_before>/* main.cpp
 *
*/

#include "main.h"

//constructor - initialize drive
robot_class::robot_class() :
	drive (		left_front_motor.jag,
				left_rear_motor.jag,
				right_front_motor.jag,
				right_rear_motor.jag
	)
{
	GetWatchdog().SetEnabled(false); //we don't want Watchdog
	//now set the necessary inversions
	drive.SetInvertedMotor(left_front_motor.type,  left_front_motor.reverse);
	drive.SetInvertedMotor(left_rear_motor.type,   left_rear_motor.reverse);
	drive.SetInvertedMotor(right_front_motor.type, right_front_motor.reverse);
	drive.SetInvertedMotor(right_rear_motor.type,  right_rear_motor.reverse);
}

void robot_class::RobotInit() {
	//do nothing
}

void robot_class::DisabledInit() {
	//do nothing
}

void robot_class::AutonomousInit() {
	//do nothing
}

void robot_class::TeleopInit() {
	//do nothing
}

void robot_class::DisabledPeriodic() {
	//do nothing
}

void robot_class::AutonomousPeriodic() {
	//do nothing
}

void robot_class::TeleopPeriodic() {
	//do nothing
}

void robot_class::DisabledContinuous() {
	//do nothing
}

void robot_class::AutonomousContinuous() {
	//do nothing
}

void robot_class::TeleopContinuous() {
	//actually do something!! :D
	drive.TankDrive(left_joystick, right_joystick);
	Wait(0.005);
}

//the following macro tells the library that we want to generate code
//for our class robot_class
START_ROBOT_CLASS(robot_class);
<commit_msg>explicitly includes ports.h<commit_after>/* main.cpp
 *
*/

#include "main.h"
#include "ports.h"

//constructor - initialize drive
robot_class::robot_class() :
	drive (		left_front_motor.jag,
				left_rear_motor.jag,
				right_front_motor.jag,
				right_rear_motor.jag
	)
{
	GetWatchdog().SetEnabled(false); //we don't want Watchdog
	//now set the necessary inversions
	drive.SetInvertedMotor(left_front_motor.type,  left_front_motor.reverse);
	drive.SetInvertedMotor(left_rear_motor.type,   left_rear_motor.reverse);
	drive.SetInvertedMotor(right_front_motor.type, right_front_motor.reverse);
	drive.SetInvertedMotor(right_rear_motor.type,  right_rear_motor.reverse);
}

void robot_class::RobotInit() {
	//do nothing
}

void robot_class::DisabledInit() {
	//do nothing
}

void robot_class::AutonomousInit() {
	//do nothing
}

void robot_class::TeleopInit() {
	//do nothing
}

void robot_class::DisabledPeriodic() {
	//do nothing
}

void robot_class::AutonomousPeriodic() {
	//do nothing
}

void robot_class::TeleopPeriodic() {
	//do nothing
}

void robot_class::DisabledContinuous() {
	//do nothing
}

void robot_class::AutonomousContinuous() {
	//do nothing
}

void robot_class::TeleopContinuous() {
	//actually do something!! :D
	drive.TankDrive(left_joystick, right_joystick);
	Wait(0.005);
}

//the following macro tells the library that we want to generate code
//for our class robot_class
START_ROBOT_CLASS(robot_class);
<|endoftext|>


<commit_before>dea911e1-2747-11e6-a278-e0f84713e7b8<commit_msg>lets try again<commit_after>deb7c55c-2747-11e6-a98e-e0f84713e7b8<|endoftext|>


<commit_before>#include <stdio.h>   // Standard Input/Output Header
#include <stdlib.h>  // C Standard General Utilities Library
#include <omp.h>     // Open Multi-Processing Library

#include "testio.h"  // Test Input/Output Header

int main (int argc, char const *argv[]){
  Testio myTestio;
  printf("Nombre de processeurs : %d \n",omp_get_num_procs());
  printf("Nombre de thread actifs : %d \n",omp_get_num_threads());
  int n;
  #pragma omp parallel for schedule(dynamic,2)
  for(n=0;n<18;n++){
    printf("Element %d traité par le thread %d \n",n,omp_get_thread_num());
  }
  return EXIT_SUCCESS;
}
<commit_msg>Changes to be committed: 	modified:   main.cpp<commit_after>#include <stdio.h>   // Standard Input/Output Header
#include <stdlib.h>  // C Standard General Utilities Library
#include <omp.h>     // Open Multi-Processing Library

#include "testio.h"  // Test Input/Output Header

/** Mets tes tests dedans Tristan :) */
int Test_Tristan()
{
}

/** Mets tes tests dedans Etienne :) */
int Test_Etienne()
{
  Testio myTestio;
  printf("Nombre de processeurs : %d \n",omp_get_num_procs());
  printf("Nombre de thread actifs : %d \n",omp_get_num_threads());
  int n;
  #pragma omp parallel for schedule(dynamic,2)
  for(n=0;n<18;n++){
    printf("Element %d traité par le thread %d \n",n,omp_get_thread_num());
  }
}

int main (int argc, char const *argv[]){
  Test_Tristan();
  Test_Etienne();
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include "ray.hpp"

Ray transformRay(glm::mat4 const& mat, Ray const& ray)
{
	glm::vec4 a{ray.m_origin,1.0f};
	glm::vec4 b{ray.m_direction,0.0f};

	return {mat*a,mat*b};
}<commit_msg>Camera updated with matrix<commit_after>#include "ray.hpp"

Ray transformRay(glm::mat4 const& mat, Ray const& ray)
{
	glm::vec4 a{ray.m_origin,1.0f};
	glm::vec4 b{ray.m_direction,0.0f};

	return {glm::vec3(mat*a),glm::vec3(mat*b)};
}<|endoftext|>


<commit_before>/*
MIT License

Copyright (c) 2017 CPirc

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cassert>

#include "bitboard.h"
#include "uci.h"

/* reads from the file descriptor fd into the pre-allocated buffer pointed to by buff,
 * until either it hits EOF, '\n', or it reads buff_len - 1 characters.
 * Returns true if it read less than buff_len characters (or if the EOF character was read)
 * false otherwise. */
bool getline_auto(FILE *fd, char *buff, std::size_t buff_len)
{
    assert(buff && fd && buff_len);

    std::size_t idx = 0, idx_len = buff_len - 1;
    int curr;
    bool ret = true;

    while ( ((curr = std::fgetc(fd)) != EOF) && curr != '\n') {

        if (idx == idx_len) {
            break;
        }

        if (!std::isblank(curr)) {
            buff[idx++] = (char)curr;
        }
    }

    //flush stdin
    if (curr != EOF && curr != '\n') {
        ret = false;

        while ( ((curr = std::fgetc(fd)) != EOF) && curr != '\n');
    }

    buff[idx] = '\0';

    return ret;
}

/* The start of all things (after _start) */
int main(int argc, char *argv[])
{
    init_bitboards();

    char protocol[12];

    assert(!std::setvbuf(stdout, NULL, _IONBF, 0));
    assert(!std::setvbuf(stdin, NULL, _IONBF, 0));

    if (getline_auto(stdin, protocol, 12)) {

        if (!std::strncmp(protocol, "uci", 3)) {
            return uci_main(argc, argv);
        }

        std::puts("Unsupported protocol!");
    } else
        std::puts("Stack overflow!");

    /*Position pos;
    parse_fen_to_position("3q3k/1Q4R1/2pNB2p/2Pp3n/8/6P1/3r2r1/7K b - - 3 38", pos);
    parse_fen_to_position("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", pos);
    start_search(pos);*/

    return 1;
}

<commit_msg>Remove assert() for setvbuf.<commit_after>/*
MIT License

Copyright (c) 2017 CPirc

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#include <cstdio>
#include <cstring>
#include <cctype>
#include <cassert>

#include "bitboard.h"
#include "uci.h"

/* reads from the file descriptor fd into the pre-allocated buffer pointed to by buff,
 * until either it hits EOF, '\n', or it reads buff_len - 1 characters.
 * Returns true if it read less than buff_len characters (or if the EOF character was read)
 * false otherwise. */
bool getline_auto(FILE *fd, char *buff, std::size_t buff_len)
{
    assert(buff && fd && buff_len);

    std::size_t idx = 0, idx_len = buff_len - 1;
    int curr;
    bool ret = true;

    while ( ((curr = std::fgetc(fd)) != EOF) && curr != '\n') {

        if (idx == idx_len) {
            break;
        }

        if (!std::isblank(curr)) {
            buff[idx++] = (char)curr;
        }
    }

    //flush stdin
    if (curr != EOF && curr != '\n') {
        ret = false;

        while ( ((curr = std::fgetc(fd)) != EOF) && curr != '\n');
    }

    buff[idx] = '\0';

    return ret;
}

/* The start of all things (after _start) */
int main(int argc, char *argv[])
{
    init_bitboards();

    char protocol[12];

    std::setvbuf(stdout, NULL, _IONBF, 0);
    std::setvbuf(stdin, NULL, _IONBF, 0);

    if (getline_auto(stdin, protocol, 12)) {

        if (!std::strncmp(protocol, "uci", 3)) {
            return uci_main(argc, argv);
        }

        std::puts("Unsupported protocol!");
    } else
        std::puts("Stack overflow!");

    /*Position pos;
    parse_fen_to_position("3q3k/1Q4R1/2pNB2p/2Pp3n/8/6P1/3r2r1/7K b - - 3 38", pos);
    parse_fen_to_position("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", pos);
    start_search(pos);*/

    return 1;
}

<|endoftext|>


<commit_before>6ff15294-2749-11e6-871c-e0f84713e7b8<commit_msg>I finished programming, there is nothing left to program<commit_after>70017957-2749-11e6-9cc4-e0f84713e7b8<|endoftext|>


<commit_before>#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <dastring/dastring.h>

#include "optparse.h"

typedef std::string string_type;
typedef std::vector<string_type> strings_type;
typedef dastring::ngram_generator ngram_generator_type;
typedef dastring::writer_base<string_type, ngram_generator_type> writer_type;
typedef dastring::reader_base<string_type> reader_type;
typedef dastring::query::exact<string_type, ngram_generator_type> query_exact_type;
typedef dastring::query::cosine<string_type, ngram_generator_type> query_cosine_type;
typedef dastring::query::dice<string_type, ngram_generator_type> query_dice_type;
typedef dastring::query::jaccard<string_type, ngram_generator_type> query_jaccard_type;
typedef dastring::query::overlap<string_type, ngram_generator_type> query_overlap_type;

class option : public optparse
{
public:
    enum {
        MODE_INTERACTIVE,
        MODE_BUILD,
        MODE_HELP,
    };

    enum {
        QT_EXACT,
        QT_DICE,
        QT_COSINE,
        QT_JACCARD,
        QT_OVERLAP,
    };

    int mode;
    std::string name;

    int ngram_size;
    int query_type;
    double threshold;

public:
    option() :
        mode(MODE_INTERACTIVE),
        name(""),
        ngram_size(3),
        query_type(QT_EXACT),
        threshold(1.)
    {
    }

    BEGIN_OPTION_MAP_INLINE()
        ON_OPTION(SHORTOPT('b') || LONGOPT("build"))
            mode = MODE_BUILD;

        ON_OPTION_WITH_ARG(SHORTOPT('d') || LONGOPT("database"))
            name = arg;

        ON_OPTION_WITH_ARG(SHORTOPT('n') || LONGOPT("ngram"))
            ngram_size = std::atoi(arg);

        ON_OPTION(SHORTOPT('h') || LONGOPT("help"))
            mode = MODE_HELP;

    END_OPTION_MAP()
};

int usage(std::ostream& os, const char *argv0)
{
    os << "USAGE: " << argv0 << " [OPTIONS]" << std::endl;
    os << std::endl;
    return 0;
}

int build(option& opt)
{
    int n = 0;
    clock_t clk;
    std::istream& is = std::cin;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    // Show parameters for database construction.
    os << "Constructing the database" << std::endl;
    os << "Database name: " << opt.name << std::endl;
    os << "N-gram length: " << opt.ngram_size << std::endl;
    os.flush();

    // Open the database for construction.
    clk = std::clock();
    ngram_generator_type gen(opt.ngram_size);
    writer_type db(gen, opt.name);
    if (db.fail()) {
        es << "ERROR: " << db.error() << std::endl;
        return 1;
    }

    // Insert every string from STDIN into the database.
    for (;;) {
        std::string line;
        std::getline(is, line);
        if (is.eof()) {
            break;
        }

        if (!db.insert(line)) {
            es << "ERROR: " << db.error() << std::endl;
            return 1;
        }

        // Progress report.
        if (++n % 10000 == 0) {
            os << "Number of strings: " << n << std::endl;
            os.flush();
        }
    }
    os << "Number of strings: " << n << std::endl;
    os << std::endl;
    os.flush();

    // Finalize the database.
    os << "Flushing the database" << std::endl;
    if (!db.close()) {
        es << "ERROR: " << db.error() << std::endl;
        return 1;
    }
    os << std::endl;

    // Report the elaped time for construction.
    os << "Seconds required: "
        << (std::clock() - clk) / (double)CLOCKS_PER_SEC << std::endl;
    os << std::endl;
    os.flush();

    return 0;
}

int interactive(option& opt)
{
    reader_type db;
    std::istream& is = std::cin;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    db.open(opt.name);

    ngram_generator_type gen(opt.ngram_size);

    for (;;) {
        // Show a prompt.
        switch (opt.query_type) {
        case option::QT_EXACT:
            os << "[exact]$ ";
            break;
        case option::QT_DICE:
            os << "[dice>=" << opt.threshold << "]$ ";
            break;
        case option::QT_COSINE:
            os << "[cosine>=" << opt.threshold << "]$ ";
            break;
        case option::QT_JACCARD:
            os << "[jaccard>=" << opt.threshold << "]$ ";
            break;
        case option::QT_OVERLAP:
            os << "[overlap>=" << opt.threshold << "]$ ";
            break;
        }

        // Read a line.
        std::string line;
        std::getline(is, line);
        if (is.eof()) {
            break;
        }

        // Check if the line indicates a command.
        if (line.compare(0, 16, ":set query exact") == 0) {
            opt.query_type = option::QT_EXACT;

        } else if (line.compare(0, 16, ":set query dice ") == 0) {
            opt.query_type = option::QT_DICE;
            opt.threshold = std::atof(line.c_str() + 16);

        } else if (line.compare(0, 18, ":set query cosine ") == 0) {
            opt.query_type = option::QT_COSINE;
            opt.threshold = std::atof(line.c_str() + 18);

        } else if (line.compare(0, 19, ":set query jaccard ") == 0) {
            opt.query_type = option::QT_JACCARD;
            opt.threshold = std::atof(line.c_str() + 19);

        } else if (line.compare(0, 19, ":set query overlap ") == 0) {
            opt.query_type = option::QT_OVERLAP;
            opt.threshold = std::atof(line.c_str() + 19);

        } else if (line == ":help") {
            //usage_interactive(os);

        } else if (line == ":quit") {
            break;

        } else {
            // The line is a query.
            strings_type xstrs;
            clock_t clk = std::clock();

            // Issue a query.
            switch (opt.query_type) {
            case option::QT_EXACT:
                db.retrieve(
                    query_exact_type(gen, line),
                    std::back_inserter(xstrs)
                    );
                break;
            case option::QT_DICE:
                db.retrieve(
                    query_dice_type(gen, line, opt.threshold),
                    std::back_inserter(xstrs)
                    );
                break;
            case option::QT_COSINE:
                db.retrieve(
                    query_cosine_type(gen, line, opt.threshold),
                    std::back_inserter(xstrs)
                    );
                break;
            case option::QT_JACCARD:
                db.retrieve(
                    query_jaccard_type(gen, line, opt.threshold),
                    std::back_inserter(xstrs)
                    );
                break;
            case option::QT_OVERLAP:
                db.retrieve(
                    query_overlap_type(gen, line, opt.threshold),
                    std::back_inserter(xstrs)
                    );
                break;
            }

            // Output the retrieved strings.
            strings_type::const_iterator it;
            for (it = xstrs.begin();it != xstrs.end();++it) {
                os << '\t' << *it << std::endl;
            }
            os << xstrs.size() << " strings retrieved (" <<
                (std::clock() - clk) / (double)CLOCKS_PER_SEC <<
                " sec)" << std::endl;
        }
    }

    return 0;
}

int main(int argc, char *argv[])
{
    option opt;
    std::istream& is = std::cin;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    // Show the copyright information.
    os << DASTRING_NAME " ";
    os << DASTRING_MAJOR_VERSION << "." << DASTRING_MINOR_VERSION << " ";
    os << DASTRING_COPYRIGHT << std::endl;
    os << std::endl;

    // Parse the command-line options.
    try {
        int arg_used = opt.parse(argv, argc);
    } catch (const optparse::unrecognized_option& e) {
        es << "ERROR: unrecognized option: " << e.what() << std::endl;
        return 1;
    } catch (const optparse::invalid_value& e) {
        es << "ERROR: " << e.what() << std::endl;
        return 1;
    }

    // Branches for the processing mode.
    switch (opt.mode) {
    case option::MODE_HELP:
        return usage(os, argv[0]);
    case option::MODE_BUILD:
        return build(opt);
    case option::MODE_INTERACTIVE:
        return interactive(opt);
    default:
        return 1;
    }
}
<commit_msg>Revised the prompt symbol a bit.<commit_after>#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <dastring/dastring.h>

#include "optparse.h"

typedef std::string string_type;
typedef std::vector<string_type> strings_type;
typedef dastring::ngram_generator ngram_generator_type;
typedef dastring::writer_base<string_type, ngram_generator_type> writer_type;
typedef dastring::reader_base<string_type> reader_type;
typedef dastring::query::exact<string_type, ngram_generator_type> query_exact_type;
typedef dastring::query::cosine<string_type, ngram_generator_type> query_cosine_type;
typedef dastring::query::dice<string_type, ngram_generator_type> query_dice_type;
typedef dastring::query::jaccard<string_type, ngram_generator_type> query_jaccard_type;
typedef dastring::query::overlap<string_type, ngram_generator_type> query_overlap_type;

class option : public optparse
{
public:
    enum {
        MODE_INTERACTIVE,
        MODE_BUILD,
        MODE_HELP,
    };

    enum {
        QT_EXACT,
        QT_DICE,
        QT_COSINE,
        QT_JACCARD,
        QT_OVERLAP,
    };

    int mode;
    std::string name;

    int ngram_size;
    int query_type;
    double threshold;

public:
    option() :
        mode(MODE_INTERACTIVE),
        name(""),
        ngram_size(3),
        query_type(QT_EXACT),
        threshold(1.)
    {
    }

    BEGIN_OPTION_MAP_INLINE()
        ON_OPTION(SHORTOPT('b') || LONGOPT("build"))
            mode = MODE_BUILD;

        ON_OPTION_WITH_ARG(SHORTOPT('d') || LONGOPT("database"))
            name = arg;

        ON_OPTION_WITH_ARG(SHORTOPT('n') || LONGOPT("ngram"))
            ngram_size = std::atoi(arg);

        ON_OPTION(SHORTOPT('h') || LONGOPT("help"))
            mode = MODE_HELP;

    END_OPTION_MAP()
};

int usage(std::ostream& os, const char *argv0)
{
    os << "USAGE: " << argv0 << " [OPTIONS]" << std::endl;
    os << std::endl;
    return 0;
}

int build(option& opt)
{
    int n = 0;
    clock_t clk;
    std::istream& is = std::cin;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    // Show parameters for database construction.
    os << "Constructing the database" << std::endl;
    os << "Database name: " << opt.name << std::endl;
    os << "N-gram length: " << opt.ngram_size << std::endl;
    os.flush();

    // Open the database for construction.
    clk = std::clock();
    ngram_generator_type gen(opt.ngram_size);
    writer_type db(gen, opt.name);
    if (db.fail()) {
        es << "ERROR: " << db.error() << std::endl;
        return 1;
    }

    // Insert every string from STDIN into the database.
    for (;;) {
        std::string line;
        std::getline(is, line);
        if (is.eof()) {
            break;
        }

        if (!db.insert(line)) {
            es << "ERROR: " << db.error() << std::endl;
            return 1;
        }

        // Progress report.
        if (++n % 10000 == 0) {
            os << "Number of strings: " << n << std::endl;
            os.flush();
        }
    }
    os << "Number of strings: " << n << std::endl;
    os << std::endl;
    os.flush();

    // Finalize the database.
    os << "Flushing the database" << std::endl;
    if (!db.close()) {
        es << "ERROR: " << db.error() << std::endl;
        return 1;
    }
    os << std::endl;

    // Report the elaped time for construction.
    os << "Seconds required: "
        << (std::clock() - clk) / (double)CLOCKS_PER_SEC << std::endl;
    os << std::endl;
    os.flush();

    return 0;
}

int interactive(option& opt)
{
    reader_type db;
    std::istream& is = std::cin;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    db.open(opt.name);

    ngram_generator_type gen(opt.ngram_size);

    for (;;) {
        // Show a prompt.
        switch (opt.query_type) {
        case option::QT_EXACT:
            os << "[exact]> ";
            break;
        case option::QT_DICE:
            os << "[dice>=" << opt.threshold << "]> ";
            break;
        case option::QT_COSINE:
            os << "[cosine>=" << opt.threshold << "]> ";
            break;
        case option::QT_JACCARD:
            os << "[jaccard>=" << opt.threshold << "]> ";
            break;
        case option::QT_OVERLAP:
            os << "[overlap>=" << opt.threshold << "]> ";
            break;
        }

        // Read a line.
        std::string line;
        std::getline(is, line);
        if (is.eof()) {
            break;
        }

        // Check if the line indicates a command.
        if (line.compare(0, 16, ":set query exact") == 0) {
            opt.query_type = option::QT_EXACT;

        } else if (line.compare(0, 16, ":set query dice ") == 0) {
            opt.query_type = option::QT_DICE;
            opt.threshold = std::atof(line.c_str() + 16);

        } else if (line.compare(0, 18, ":set query cosine ") == 0) {
            opt.query_type = option::QT_COSINE;
            opt.threshold = std::atof(line.c_str() + 18);

        } else if (line.compare(0, 19, ":set query jaccard ") == 0) {
            opt.query_type = option::QT_JACCARD;
            opt.threshold = std::atof(line.c_str() + 19);

        } else if (line.compare(0, 19, ":set query overlap ") == 0) {
            opt.query_type = option::QT_OVERLAP;
            opt.threshold = std::atof(line.c_str() + 19);

        } else if (line == ":help") {
            //usage_interactive(os);

        } else if (line == ":quit") {
            break;

        } else {
            // The line is a query.
            strings_type xstrs;
            clock_t clk = std::clock();

            // Issue a query.
            switch (opt.query_type) {
            case option::QT_EXACT:
                db.retrieve(
                    query_exact_type(gen, line),
                    std::back_inserter(xstrs)
                    );
                break;
            case option::QT_DICE:
                db.retrieve(
                    query_dice_type(gen, line, opt.threshold),
                    std::back_inserter(xstrs)
                    );
                break;
            case option::QT_COSINE:
                db.retrieve(
                    query_cosine_type(gen, line, opt.threshold),
                    std::back_inserter(xstrs)
                    );
                break;
            case option::QT_JACCARD:
                db.retrieve(
                    query_jaccard_type(gen, line, opt.threshold),
                    std::back_inserter(xstrs)
                    );
                break;
            case option::QT_OVERLAP:
                db.retrieve(
                    query_overlap_type(gen, line, opt.threshold),
                    std::back_inserter(xstrs)
                    );
                break;
            }

            // Output the retrieved strings.
            strings_type::const_iterator it;
            for (it = xstrs.begin();it != xstrs.end();++it) {
                os << '\t' << *it << std::endl;
            }
            os << xstrs.size() << " strings retrieved (" <<
                (std::clock() - clk) / (double)CLOCKS_PER_SEC <<
                " sec)" << std::endl;
        }
    }

    return 0;
}

int main(int argc, char *argv[])
{
    option opt;
    std::istream& is = std::cin;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    // Show the copyright information.
    os << DASTRING_NAME " ";
    os << DASTRING_MAJOR_VERSION << "." << DASTRING_MINOR_VERSION << " ";
    os << DASTRING_COPYRIGHT << std::endl;
    os << std::endl;

    // Parse the command-line options.
    try {
        int arg_used = opt.parse(argv, argc);
    } catch (const optparse::unrecognized_option& e) {
        es << "ERROR: unrecognized option: " << e.what() << std::endl;
        return 1;
    } catch (const optparse::invalid_value& e) {
        es << "ERROR: " << e.what() << std::endl;
        return 1;
    }

    // Branches for the processing mode.
    switch (opt.mode) {
    case option::MODE_HELP:
        return usage(os, argv[0]);
    case option::MODE_BUILD:
        return build(opt);
    case option::MODE_INTERACTIVE:
        return interactive(opt);
    default:
        return 1;
    }
}
<|endoftext|>