<commit_before>//===--- driver.cpp - Swift Compiler Driver -------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This is the entry point to the swift compiler driver.
//
//===----------------------------------------------------------------------===//

#include "swift/AST/DiagnosticEngine.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Basic/Program.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Driver/Compilation.h"
#include "swift/Driver/Driver.h"
#include "swift/Driver/FrontendUtil.h"
#include "swift/Driver/Job.h"
#include "swift/Driver/ToolChain.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/FrontendTool/FrontendTool.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"

#include <memory>
#include <stdlib.h>

using namespace swift;
using namespace swift::driver;

std::string getExecutablePath(const char *FirstArg) {
  void *P = (void *)(intptr_t)getExecutablePath;
  return llvm::sys::fs::getMainExecutable(FirstArg, P);
}

/// Run 'swift-autolink-extract'.
extern int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
                                 void *MainAddr);

extern int modulewrap_main(ArrayRef<const char *> Args, const char *Argv0,
                           void *MainAddr);

/// Run 'swift-format'
extern int swift_format_main(ArrayRef<const char *> Args, const char *Argv0,
                             void *MainAddr);

/// Determine if the given invocation should run as a subcommand.
///
/// \param ExecName The name of the argv[0] we were invoked as.
/// \param SubcommandName On success, the full name of the subcommand to invoke.
/// \param Args On return, the adjusted program arguments to use.
/// \returns True if running as a subcommand.
static bool shouldRunAsSubcommand(StringRef ExecName,
                                  SmallString<256> &SubcommandName,
                                  SmallVectorImpl<const char *> &Args) {
  assert(!Args.empty());

  // If we are not run as 'swift', don't do anything special. This doesn't work
  // with symlinks with alternate names, but we can't detect 'swift' vs 'swiftc'
  // if we try and resolve using the actual executable path.
  if (ExecName != "swift")
    return false;

  // If there are no program arguments, always invoke as normal.
  if (Args.size() == 1)
    return false;

  // Otherwise, we have a program argument. If it looks like an option or a
  // path, then invoke in interactive mode with the arguments as given.
  StringRef FirstArg(Args[1]);
  if (FirstArg.startswith("-") || FirstArg.find('.') != StringRef::npos ||
      FirstArg.find('/') != StringRef::npos)
    return false;

  // Otherwise, we should have some sort of subcommand. Get the subcommand name
  // and remove it from the program arguments.
  StringRef Subcommand = Args[1];
  Args.erase(&Args[1]);

  // If the subcommand is the "built-in" 'repl', then use the
  // normal driver.
  if (Subcommand == "repl")
    return false;

  // Form the subcommand name.
  SubcommandName.assign("swift-");
  SubcommandName.append(Subcommand);

  return true;
}

extern int apinotes_main(ArrayRef<const char *> Args);

int main(int argc_, const char **argv_) {
  PROGRAM_START(argc_, argv_);

  SmallVector<const char *, 256> argv;
  llvm::SpecificBumpPtrAllocator<char> ArgAllocator;
  std::error_code EC = llvm::sys::Process::GetArgumentVector(
      argv, llvm::ArrayRef<const char *>(argv_, argc_), ArgAllocator);
  if (EC) {
    llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n';
    return 1;
  }

  // Expand any response files in the command line argument vector
  llvm::BumpPtrAllocator Allocator;
  llvm::StringSaver Saver(Allocator);
  llvm::cl::ExpandResponseFiles(
      Saver,
      llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows() ?
      llvm::cl::TokenizeWindowsCommandLine :
      llvm::cl::TokenizeGNUCommandLine,
      argv);

  // Check if this invocation should execute a subcommand.
  StringRef ExecName = llvm::sys::path::stem(argv[0]);
  SmallString<256> SubcommandName;
  if (shouldRunAsSubcommand(ExecName, SubcommandName, argv)) {
    // We are running as a subcommand, try to find the subcommand adjacent to
    // the executable we are running as.
    SmallString<256> SubcommandPath(
      llvm::sys::path::parent_path(getExecutablePath(argv[0])));
    llvm::sys::path::append(SubcommandPath, SubcommandName);

    // If we didn't find the tool there, let the OS search for it.
    if (!llvm::sys::fs::exists(SubcommandPath)) {
      // Search for the program and use the path if found. If there was an
      // error, ignore it and just let the exec fail.
      auto result = llvm::sys::findProgramByName(SubcommandName);
      if (!result.getError())
        SubcommandPath = *result;
    }

    // Rewrite the program argument.
    argv[0] = SubcommandPath.c_str();

    // Execute the subcommand.
    argv.push_back(nullptr);
    ExecuteInPlace(SubcommandPath.c_str(), argv.data());

    // If we reach here then an error occurred (typically a missing path).
    std::string ErrorString = llvm::sys::StrError();
    llvm::errs() << "error: unable to invoke subcommand: " << argv[0]
                 << " (" << ErrorString << ")\n";
    return 2;
  }

  // Handle integrated tools.
  if (argv.size() > 1) {
    StringRef FirstArg(argv[1]);
    if (FirstArg == "-frontend") {
      return performFrontend(llvm::makeArrayRef(argv.data()+2,
                                                argv.data()+argv.size()),
                             argv[0], (void *)(intptr_t)getExecutablePath);
    }
    if (FirstArg == "-modulewrap") {
      return modulewrap_main(llvm::makeArrayRef(argv.data()+2,
                                                argv.data()+argv.size()),
                             argv[0], (void *)(intptr_t)getExecutablePath);
    }
    if (FirstArg == "-apinotes") {
      return apinotes_main(llvm::makeArrayRef(argv.data()+1,
                                              argv.data()+argv.size()));
    }
  }

  std::string Path = getExecutablePath(argv[0]);

  PrintingDiagnosticConsumer PDC;

  SourceManager SM;
  DiagnosticEngine Diags(SM);
  Diags.addConsumer(PDC);

  Driver TheDriver(Path, ExecName, argv, Diags);
  switch (TheDriver.getDriverKind()) {
  case Driver::DriverKind::AutolinkExtract:
    return autolink_extract_main(
      TheDriver.getArgsWithoutProgramNameAndDriverMode(argv),
      argv[0], (void *)(intptr_t)getExecutablePath);
  case Driver::DriverKind::SwiftFormat:
    return swift_format_main(
      TheDriver.getArgsWithoutProgramNameAndDriverMode(argv),
      argv[0], (void *)(intptr_t)getExecutablePath);
  default:
    break;
  }

  std::unique_ptr<llvm::opt::InputArgList> ArgList =
    TheDriver.parseArgStrings(ArrayRef<const char*>(argv).slice(1));
  if (Diags.hadAnyError())
    return 1;

  std::unique_ptr<ToolChain> TC = TheDriver.buildToolChain(*ArgList);
  if (Diags.hadAnyError())
    return 1;

  std::unique_ptr<Compilation> C =
      TheDriver.buildCompilation(*TC, std::move(ArgList));
  if (Diags.hadAnyError())
    return 1;

  if (C) {
    return C->performJobs();
  }

  return 0;
}
<commit_msg>Elaborate on the purpose of response files.<commit_after>//===--- driver.cpp - Swift Compiler Driver -------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This is the entry point to the swift compiler driver.
//
//===----------------------------------------------------------------------===//

#include "swift/AST/DiagnosticEngine.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Basic/Program.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Driver/Compilation.h"
#include "swift/Driver/Driver.h"
#include "swift/Driver/FrontendUtil.h"
#include "swift/Driver/Job.h"
#include "swift/Driver/ToolChain.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/FrontendTool/FrontendTool.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"

#include <memory>
#include <stdlib.h>

using namespace swift;
using namespace swift::driver;

std::string getExecutablePath(const char *FirstArg) {
  void *P = (void *)(intptr_t)getExecutablePath;
  return llvm::sys::fs::getMainExecutable(FirstArg, P);
}

/// Run 'swift-autolink-extract'.
extern int autolink_extract_main(ArrayRef<const char *> Args, const char *Argv0,
                                 void *MainAddr);

extern int modulewrap_main(ArrayRef<const char *> Args, const char *Argv0,
                           void *MainAddr);

/// Run 'swift-format'
extern int swift_format_main(ArrayRef<const char *> Args, const char *Argv0,
                             void *MainAddr);

/// Determine if the given invocation should run as a subcommand.
///
/// \param ExecName The name of the argv[0] we were invoked as.
/// \param SubcommandName On success, the full name of the subcommand to invoke.
/// \param Args On return, the adjusted program arguments to use.
/// \returns True if running as a subcommand.
static bool shouldRunAsSubcommand(StringRef ExecName,
                                  SmallString<256> &SubcommandName,
                                  SmallVectorImpl<const char *> &Args) {
  assert(!Args.empty());

  // If we are not run as 'swift', don't do anything special. This doesn't work
  // with symlinks with alternate names, but we can't detect 'swift' vs 'swiftc'
  // if we try and resolve using the actual executable path.
  if (ExecName != "swift")
    return false;

  // If there are no program arguments, always invoke as normal.
  if (Args.size() == 1)
    return false;

  // Otherwise, we have a program argument. If it looks like an option or a
  // path, then invoke in interactive mode with the arguments as given.
  StringRef FirstArg(Args[1]);
  if (FirstArg.startswith("-") || FirstArg.find('.') != StringRef::npos ||
      FirstArg.find('/') != StringRef::npos)
    return false;

  // Otherwise, we should have some sort of subcommand. Get the subcommand name
  // and remove it from the program arguments.
  StringRef Subcommand = Args[1];
  Args.erase(&Args[1]);

  // If the subcommand is the "built-in" 'repl', then use the
  // normal driver.
  if (Subcommand == "repl")
    return false;

  // Form the subcommand name.
  SubcommandName.assign("swift-");
  SubcommandName.append(Subcommand);

  return true;
}

extern int apinotes_main(ArrayRef<const char *> Args);

int main(int argc_, const char **argv_) {
  PROGRAM_START(argc_, argv_);

  SmallVector<const char *, 256> argv;
  llvm::SpecificBumpPtrAllocator<char> ArgAllocator;
  std::error_code EC = llvm::sys::Process::GetArgumentVector(
      argv, llvm::ArrayRef<const char *>(argv_, argc_), ArgAllocator);
  if (EC) {
    llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n';
    return 1;
  }

  // Expand any response files in the command line argument vector - arguments
  // may be passed through response files in the event of command line length
  // restrictions.
  llvm::BumpPtrAllocator Allocator;
  llvm::StringSaver Saver(Allocator);
  llvm::cl::ExpandResponseFiles(
      Saver,
      llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows() ?
      llvm::cl::TokenizeWindowsCommandLine :
      llvm::cl::TokenizeGNUCommandLine,
      argv);

  // Check if this invocation should execute a subcommand.
  StringRef ExecName = llvm::sys::path::stem(argv[0]);
  SmallString<256> SubcommandName;
  if (shouldRunAsSubcommand(ExecName, SubcommandName, argv)) {
    // We are running as a subcommand, try to find the subcommand adjacent to
    // the executable we are running as.
    SmallString<256> SubcommandPath(
      llvm::sys::path::parent_path(getExecutablePath(argv[0])));
    llvm::sys::path::append(SubcommandPath, SubcommandName);

    // If we didn't find the tool there, let the OS search for it.
    if (!llvm::sys::fs::exists(SubcommandPath)) {
      // Search for the program and use the path if found. If there was an
      // error, ignore it and just let the exec fail.
      auto result = llvm::sys::findProgramByName(SubcommandName);
      if (!result.getError())
        SubcommandPath = *result;
    }

    // Rewrite the program argument.
    argv[0] = SubcommandPath.c_str();

    // Execute the subcommand.
    argv.push_back(nullptr);
    ExecuteInPlace(SubcommandPath.c_str(), argv.data());

    // If we reach here then an error occurred (typically a missing path).
    std::string ErrorString = llvm::sys::StrError();
    llvm::errs() << "error: unable to invoke subcommand: " << argv[0]
                 << " (" << ErrorString << ")\n";
    return 2;
  }

  // Handle integrated tools.
  if (argv.size() > 1) {
    StringRef FirstArg(argv[1]);
    if (FirstArg == "-frontend") {
      return performFrontend(llvm::makeArrayRef(argv.data()+2,
                                                argv.data()+argv.size()),
                             argv[0], (void *)(intptr_t)getExecutablePath);
    }
    if (FirstArg == "-modulewrap") {
      return modulewrap_main(llvm::makeArrayRef(argv.data()+2,
                                                argv.data()+argv.size()),
                             argv[0], (void *)(intptr_t)getExecutablePath);
    }
    if (FirstArg == "-apinotes") {
      return apinotes_main(llvm::makeArrayRef(argv.data()+1,
                                              argv.data()+argv.size()));
    }
  }

  std::string Path = getExecutablePath(argv[0]);

  PrintingDiagnosticConsumer PDC;

  SourceManager SM;
  DiagnosticEngine Diags(SM);
  Diags.addConsumer(PDC);

  Driver TheDriver(Path, ExecName, argv, Diags);
  switch (TheDriver.getDriverKind()) {
  case Driver::DriverKind::AutolinkExtract:
    return autolink_extract_main(
      TheDriver.getArgsWithoutProgramNameAndDriverMode(argv),
      argv[0], (void *)(intptr_t)getExecutablePath);
  case Driver::DriverKind::SwiftFormat:
    return swift_format_main(
      TheDriver.getArgsWithoutProgramNameAndDriverMode(argv),
      argv[0], (void *)(intptr_t)getExecutablePath);
  default:
    break;
  }

  std::unique_ptr<llvm::opt::InputArgList> ArgList =
    TheDriver.parseArgStrings(ArrayRef<const char*>(argv).slice(1));
  if (Diags.hadAnyError())
    return 1;

  std::unique_ptr<ToolChain> TC = TheDriver.buildToolChain(*ArgList);
  if (Diags.hadAnyError())
    return 1;

  std::unique_ptr<Compilation> C =
      TheDriver.buildCompilation(*TC, std::move(ArgList));
  if (Diags.hadAnyError())
    return 1;

  if (C) {
    return C->performJobs();
  }

  return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
 *
 * Project:  integrating laszip into liblas - http://liblas.org -
 * Purpose:
 * Author:   Martin Isenburg
 *           isenburg at cs.unc.edu
 *
 ******************************************************************************
 * Copyright (c) 2010, Martin Isenburg
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Licence as published
 * by the Free Software Foundation.
 *
 * See the COPYING file for more information.
 *
 ****************************************************************************/

/*
===============================================================================

  FILE:  laszippertest.cpp

  CONTENTS:

    This tool reads and writes point data in the LAS 1.X format compressed
    or uncompressed to test the laszipper and lasunzipper interfaces.

  PROGRAMMERS:

    martin isenburg@cs.unc.edu

  COPYRIGHT:

    copyright (C) 2010 martin isenburg@cs.unc.edu

    This software 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.

  CHANGE HISTORY:

    13 December 2010 -- created to test the remodularized laszip compressor

===============================================================================
*/

#include "laszipper.hpp"
#include "lasunzipper.hpp"

#ifdef LZ_WIN32_VC6
#include <fstream.h>
#else
#include <istream>
#include <fstream>
using namespace std;
#endif

#include <time.h>
#include <stdio.h>

static double taketime()
{
  return (double)(clock())/CLOCKS_PER_SEC;
}

int main(int argc, char *argv[])
{
  unsigned char c;
  unsigned int i, j;
  unsigned int num_points = 100000;
  unsigned int num_errors, num_bytes;
  double start_time, end_time;
  FILE* ofile1 = 0;
  FILE* ofile2 = 0;
  FILE* ofile3 = 0;
  FILE* ifile1 = 0;
  FILE* ifile2 = 0;
  FILE* ifile3 = 0;
  filebuf ofb1;
  filebuf ofb2;
  filebuf ofb3;
  filebuf ifb1;
  filebuf ifb2;
  filebuf ifb3;
#ifdef LZ_WIN32_VC6
  ostream* ostream1 = 0;
  ostream* ostream2 = 0;
  ostream* ostream3 = 0;
  istream* istream1 = 0;
  istream* istream2 = 0;
  istream* istream3 = 0;
#else
  ofstream* ostream1 = 0;
  ofstream* ostream2 = 0;
  ofstream* ostream3 = 0;
  ifstream* istream1 = 0;
  ifstream* istream2 = 0;
  ifstream* istream3 = 0;
#endif

  bool use_iostream = false;

  // describe the point structure

  unsigned int num_items = 5;
  LASitem items[5];

  items[0].type = LASitem::POINT10;
  items[0].size = 20;
  items[0].version = 0;

  items[1].type = LASitem::GPSTIME11;
  items[1].size = 8;
  items[1].version = 0;

  items[2].type = LASitem::RGB12;
  items[2].size = 6;
  items[2].version = 0;

  items[3].type = LASitem::WAVEPACKET13;
  items[3].size = 29;
  items[3].version = 0;

  items[4].type = LASitem::BYTE;
  items[4].size = 7;
  items[4].version = 0;

  // compute the point size
  unsigned int point_size = 0;
  for (i = 0; i < num_items; i++) point_size += items[i].size;

  // create the point data
  unsigned int point_offset = 0;
  unsigned char** point = new unsigned char*[num_items];
  unsigned char* point_data = new unsigned char[point_size];
  for (i = 0; i < num_items; i++)
  {
    point[i] = &(point_data[point_offset]);
    point_offset += items[i].size;
  }

  LASzipper* laszipper1 = new LASzipper(); // without compression
  LASzipper* laszipper2 = new LASzipper(); // with arithmetic compression
  LASzipper* laszipper3 = new LASzipper(); // with range compression

  if (use_iostream)
  {
#ifdef LZ_WIN32_VC6
    ofb1.open("test1.lax", ios::out);
    ofb1.setmode(filebuf::binary);
    ostream1 = new ostream(&ofb1);
#else
    ostream1 = new ofstream();
    ostream1->open("test1.lax", std::ios::out | std::ios::binary );
#endif
    if (laszipper1->open(*ostream1, num_items, items, LASZIP_COMPRESSION_NONE) != 0)
    {
      fprintf(stderr, "ERROR: could not open laszipper1\n");
      return 0;
    }

#ifdef LZ_WIN32_VC6
    ofb2.open("test2.lax", ios::out);
    ofb2.setmode(filebuf::binary);
    ostream2 = new ostream(&ofb2);
#else
    ostream2 = new ofstream();
    ostream2->open("test2.lax", std::ios::out | std::ios::binary );
#endif
    if (laszipper2->open(*ostream2, num_items, items, LASZIP_COMPRESSION_ARITHMETIC) != 0)
    {
      fprintf(stderr, "ERROR: could not open laszipper2\n");
      return 0;
    }

#ifdef LZ_WIN32_VC6
    ofb3.open("test3.lax", ios::out);
    ofb3.setmode(filebuf::binary);
    ostream3 = new ostream(&ofb3);
#else
    ostream3 = new ofstream();
    ostream3->open("test3.lax", std::ios::out | std::ios::binary );
#endif
    if (laszipper3->open(*ostream3, num_items, items, LASZIP_COMPRESSION_RANGE) != 0)
    {
      fprintf(stderr, "ERROR: could not open laszipper3\n");
      return 0;
    }
  }
  else
  {
    ofile1 = fopen("test1.lax", "wb");
    if (!laszipper1->open(ofile1, num_items, items, LASZIP_COMPRESSION_NONE))
    {
      fprintf(stderr, "ERROR: could not open laszipper1\n");
      return 0;
    }

    ofile2 = fopen("test2.lax", "wb");
    if (!laszipper2->open(ofile2, num_items, items, LASZIP_COMPRESSION_ARITHMETIC))
    {
      fprintf(stderr, "ERROR: could not open laszipper2\n");
      return 0;
    }

    ofile3 = fopen("test3.lax", "wb");
    if (!laszipper3->open(ofile3, num_items, items, LASZIP_COMPRESSION_RANGE))
    {
      fprintf(stderr, "ERROR: could not open laszipper3\n");
      return 0;
    }
  }

  // write / compress num_points with "random" data

  start_time = taketime();
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    for (j = 0; j < point_size; j++)
    {
      point_data[j] = c;
      c++;
    }
    laszipper1->write(point);
  }
  num_bytes = laszipper1->close();
  end_time = taketime();
  fprintf(stderr, "laszipper1 wrote %d bytes in %g seconds\n", num_bytes, end_time-start_time);

  start_time = taketime();
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    for (j = 0; j < point_size; j++)
    {
      point_data[j] = c;
      c++;
    }
    laszipper2->write(point);
  }
  num_bytes = laszipper2->close();
  end_time = taketime();
  fprintf(stderr, "laszipper2 wrote %d bytes in %g seconds\n", num_bytes, end_time-start_time);

  start_time = taketime();
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    for (j = 0; j < point_size; j++)
    {
      point_data[j] = c;
      c++;
    }
    laszipper3->write(point);
  }
  num_bytes = laszipper3->close();
  end_time = taketime();
  fprintf(stderr, "laszipper3 wrote %d bytes in %g seconds\n", num_bytes, end_time-start_time);

  delete laszipper1;
  delete laszipper2;
  delete laszipper3;

  if (use_iostream)
  {
    delete ostream1;
    delete ostream2;
    delete ostream3;
#ifdef LZ_WIN32_VC6
    ofb1.close();
    ofb2.close();
    ofb3.close();
#endif
  }
  else
  {
    fclose(ofile1);
    fclose(ofile2);
    fclose(ofile3);
  }

  LASunzipper* lasunzipper1 = new LASunzipper(); // without compression
  LASunzipper* lasunzipper2 = new LASunzipper(); // with arithmetic compression
  LASunzipper* lasunzipper3 = new LASunzipper(); // with range compression

  if (use_iostream)
  {
#ifdef LZ_WIN32_VC6
    ifb1.open("test1.lax", ios::in);
    ifb1.setmode(filebuf::binary);
    istream1 = new istream(&ifb1);
#else
    istream1 = new ifstream();
    istream1->open("test1.lax", std::ios::in | std::ios::binary );
#endif
    if (lasunzipper1->open(*istream1, num_items, items, LASZIP_COMPRESSION_NONE) != 0)
    {
      fprintf(stderr, "ERROR: could not open lasunzipper1\n");
      return 0;
    }
#ifdef LZ_WIN32_VC6
    ifb2.open("test2.lax", ios::in);
    ifb2.setmode(filebuf::binary);
    istream2 = new istream(&ifb2);
#else
    istream2 = new ifstream();
    istream2->open("test2.lax", std::ios::in | std::ios::binary );
#endif
    if (lasunzipper2->open(istream2, num_items, items, LASZIP_COMPRESSION_ARITHMETIC) != 0)
    {
      fprintf(stderr, "ERROR: could not open lasunzipper2\n");
      return 0;
    }
#ifdef LZ_WIN32_VC6
    ifb3.open("test3.lax", ios::in);
    ifb3.setmode(filebuf::binary);
    istream3 = new istream(&ifb3);
#else
    istream3 = new ifstream();
    istream3->open("test3.lax", std::ios::in | std::ios::binary );
#endif
    if (lasunzipper3->open(istream3, num_items, items, LASZIP_COMPRESSION_RANGE) != 0)
    {
      fprintf(stderr, "ERROR: could not open lasunzipper3\n");
      return 0;
    }
  }
  else
  {
    ifile1 = fopen("test1.lax", "rb");
    if (!lasunzipper1->open(ifile1, num_items, items, LASZIP_COMPRESSION_NONE))
    {
      fprintf(stderr, "ERROR: could not open lasunzipper1\n");
      return 0;
    }
    ifile2 = fopen("test2.lax", "rb");
    if (!lasunzipper2->open(ifile2, num_items, items, LASZIP_COMPRESSION_ARITHMETIC))
    {
      fprintf(stderr, "ERROR: could not open lasunzipper2\n");
      return 0;
    }
    ifile3 = fopen("test3.lax", "rb");
    if (!lasunzipper3->open(ifile3, num_items, items, LASZIP_COMPRESSION_RANGE))
    {
      fprintf(stderr, "ERROR: could not open lasunzipper3\n");
      return 0;
    }
  }

  // read num_points with "random" data

  start_time = taketime();
  num_errors = 0;
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    lasunzipper1->read(point);
    for (j = 0; j < point_size; j++)
    {
      if (point_data[j] != c)
      {
        fprintf(stderr, "%d %d %d != %d\n", i, j, point_data[j], c);
        num_errors++;
        if (num_errors > 20) return -1;
      }
      c++;
    }
  }
  num_bytes = lasunzipper1->close();
  end_time = taketime();
  if (num_errors)
  {
    fprintf(stderr, "ERROR: with lasunzipper1 %d\n", num_errors);
  }
  else
  {
   fprintf(stderr, "SUCCESS: lasunzipper1 read %d bytes in %g seconds\n", num_bytes, end_time-start_time);
  }

  // decompress num_points with "random" data

  start_time = taketime();
  num_errors = 0;
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    lasunzipper2->read(point);
    for (j = 0; j < point_size; j++)
    {
      if (point_data[j] != c)
      {
        fprintf(stderr, "%d %d %d != %d\n", i, j, point_data[j], c);
        num_errors++;
        if (num_errors > 20) return -1;
      }
      c++;
    }
  }
  num_bytes = lasunzipper2->close();
  end_time = taketime();
  if (num_errors)
  {
    fprintf(stderr, "ERROR: with lasunzipper2 %d\n", num_errors);
  }
  else
  {
   fprintf(stderr, "SUCCESS: lasunzipper2 read %d bytes in %g seconds\n", num_bytes, end_time-start_time);
  }

  // decompress num_points with "random" data

  start_time = taketime();
  num_errors = 0;
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    lasunzipper3->read(point);
    for (j = 0; j < point_size; j++)
    {
      if (point_data[j] != c)
      {
        fprintf(stderr, "%d %d %d != %d\n", i, j, point_data[j], c);
        num_errors++;
        if (num_errors > 20) return -1;
      }
      c++;
    }
  }
  num_bytes = lasunzipper3->close();
  end_time = taketime();
  if (num_errors)
  {
    fprintf(stderr, "ERROR: with lasunzipper3 %d\n", num_errors);
  }
  else
  {
   fprintf(stderr, "SUCCESS: lasunzipper3 read %d bytes in %g seconds\n", num_bytes, end_time-start_time);
  }

  delete lasunzipper1;
  delete lasunzipper2;
  delete lasunzipper3;

  if (use_iostream)
  {
    delete istream1;
    delete istream2;
    delete istream3;
#ifdef LZ_WIN32_VC6
    ifb1.close();
    ifb2.close();
    ifb3.close();
#endif
  }
  else
  {
    fclose(ifile1);
    fclose(ifile2);
    fclose(ifile3);
  }

  return 0;
}
<commit_msg>added test for new WAVEPACKET13 compressor<commit_after>/******************************************************************************
 *
 * Project:  integrating laszip into liblas - http://liblas.org -
 * Purpose:
 * Author:   Martin Isenburg
 *           isenburg at cs.unc.edu
 *
 ******************************************************************************
 * Copyright (c) 2010, Martin Isenburg
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Licence as published
 * by the Free Software Foundation.
 *
 * See the COPYING file for more information.
 *
 ****************************************************************************/

/*
===============================================================================

  FILE:  laszippertest.cpp

  CONTENTS:

    This tool reads and writes point data in the LAS 1.X format compressed
    or uncompressed to test the laszipper and lasunzipper interfaces.

  PROGRAMMERS:

    martin isenburg@cs.unc.edu

  COPYRIGHT:

    copyright (C) 2010 martin isenburg@cs.unc.edu

    This software 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.

  CHANGE HISTORY:

    13 December 2010 -- created to test the remodularized laszip compressor

===============================================================================
*/

#include "laszipper.hpp"
#include "lasunzipper.hpp"

#ifdef LZ_WIN32_VC6
#include <fstream.h>
#else
#include <istream>
#include <fstream>
using namespace std;
#endif

#include <time.h>
#include <stdio.h>

static double taketime()
{
  return (double)(clock())/CLOCKS_PER_SEC;
}

int main(int argc, char *argv[])
{
  unsigned char c;
  unsigned int i, j;
  unsigned int num_points = 100000;
  unsigned int num_errors, num_bytes;
  double start_time, end_time;
  FILE* ofile1 = 0;
  FILE* ofile2 = 0;
  FILE* ofile3 = 0;
  FILE* ifile1 = 0;
  FILE* ifile2 = 0;
  FILE* ifile3 = 0;
  filebuf ofb1;
  filebuf ofb2;
  filebuf ofb3;
  filebuf ifb1;
  filebuf ifb2;
  filebuf ifb3;
#ifdef LZ_WIN32_VC6
  ostream* ostream1 = 0;
  ostream* ostream2 = 0;
  ostream* ostream3 = 0;
  istream* istream1 = 0;
  istream* istream2 = 0;
  istream* istream3 = 0;
#else
  ofstream* ostream1 = 0;
  ofstream* ostream2 = 0;
  ofstream* ostream3 = 0;
  ifstream* istream1 = 0;
  ifstream* istream2 = 0;
  ifstream* istream3 = 0;
#endif

  bool use_iostream = false;

  // describe the point structure

  unsigned int num_items = 5;
  LASitem items[5];

  items[0].type = LASitem::POINT10;
  items[0].size = 20;
  items[0].version = 0;

  items[1].type = LASitem::GPSTIME11;
  items[1].size = 8;
  items[1].version = 0;

  items[2].type = LASitem::RGB12;
  items[2].size = 6;
  items[2].version = 0;

  items[3].type = LASitem::WAVEPACKET13;
  items[3].size = 29;
  items[3].version = 0;

  items[4].type = LASitem::BYTE;
  items[4].size = 7;
  items[4].version = 0;

  // compute the point size
  unsigned int point_size = 0;
  for (i = 0; i < num_items; i++) point_size += items[i].size;

  // create the point data
  unsigned int point_offset = 0;
  unsigned char** point = new unsigned char*[num_items];
  unsigned char* point_data = new unsigned char[point_size];
  for (i = 0; i < num_items; i++)
  {
    point[i] = &(point_data[point_offset]);
    point_offset += items[i].size;
  }

  LASzipper* laszipper1 = new LASzipper(); // without compression
  LASzipper* laszipper2 = new LASzipper(); // with arithmetic compression
  LASzipper* laszipper3 = new LASzipper(); // with range compression

  if (use_iostream)
  {
#ifdef LZ_WIN32_VC6
    ofb1.open("test1.lax", ios::out);
    ofb1.setmode(filebuf::binary);
    ostream1 = new ostream(&ofb1);
#else
    ostream1 = new ofstream();
    ostream1->open("test1.lax", std::ios::out | std::ios::binary );
#endif
    if (laszipper1->open(*ostream1, num_items, items, LASZIP_COMPRESSION_NONE) != 0)
    {
      fprintf(stderr, "ERROR: could not open laszipper1\n");
      return 0;
    }

#ifdef LZ_WIN32_VC6
    ofb2.open("test2.lax", ios::out);
    ofb2.setmode(filebuf::binary);
    ostream2 = new ostream(&ofb2);
#else
    ostream2 = new ofstream();
    ostream2->open("test2.lax", std::ios::out | std::ios::binary );
#endif
    if (laszipper2->open(*ostream2, num_items, items, LASZIP_COMPRESSION_ARITHMETIC) != 0)
    {
      fprintf(stderr, "ERROR: could not open laszipper2\n");
      return 0;
    }

#ifdef LZ_WIN32_VC6
    ofb3.open("test3.lax", ios::out);
    ofb3.setmode(filebuf::binary);
    ostream3 = new ostream(&ofb3);
#else
    ostream3 = new ofstream();
    ostream3->open("test3.lax", std::ios::out | std::ios::binary );
#endif
    if (laszipper3->open(*ostream3, num_items, items, LASZIP_COMPRESSION_RANGE) != 0)
    {
      fprintf(stderr, "ERROR: could not open laszipper3\n");
      return 0;
    }
  }
  else
  {
    ofile1 = fopen("test1.lax", "wb");
    if (!laszipper1->open(ofile1, num_items, items, LASZIP_COMPRESSION_NONE))
    {
      fprintf(stderr, "ERROR: could not open laszipper1\n");
      return 0;
    }

    ofile2 = fopen("test2.lax", "wb");
    if (!laszipper2->open(ofile2, num_items, items, LASZIP_COMPRESSION_ARITHMETIC))
    {
      fprintf(stderr, "ERROR: could not open laszipper2\n");
      return 0;
    }

    ofile3 = fopen("test3.lax", "wb");
    if (!laszipper3->open(ofile3, num_items, items, LASZIP_COMPRESSION_RANGE))
    {
      fprintf(stderr, "ERROR: could not open laszipper3\n");
      return 0;
    }
  }

  // write / compress num_points with "random" data

  start_time = taketime();
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    for (j = 0; j < point_size; j++)
    {
      point_data[j] = c;
      c++;
    }
    laszipper1->write(point);
  }
  num_bytes = laszipper1->close();
  end_time = taketime();
  fprintf(stderr, "laszipper1 wrote %d bytes in %g seconds\n", num_bytes, end_time-start_time);

  start_time = taketime();
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    for (j = 0; j < point_size; j++)
    {
      point_data[j] = c;
      c++;
    }
    laszipper2->write(point);
  }
  num_bytes = laszipper2->close();
  end_time = taketime();
  fprintf(stderr, "laszipper2 wrote %d bytes in %g seconds\n", num_bytes, end_time-start_time);

  start_time = taketime();
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    for (j = 0; j < point_size; j++)
    {
      point_data[j] = c;
      c++;
    }
    laszipper3->write(point);
  }
  num_bytes = laszipper3->close();
  end_time = taketime();
  fprintf(stderr, "laszipper3 wrote %d bytes in %g seconds\n", num_bytes, end_time-start_time);

  delete laszipper1;
  delete laszipper2;
  delete laszipper3;

  if (use_iostream)
  {
    delete ostream1;
    delete ostream2;
    delete ostream3;
#ifdef LZ_WIN32_VC6
    ofb1.close();
    ofb2.close();
    ofb3.close();
#endif
  }
  else
  {
    fclose(ofile1);
    fclose(ofile2);
    fclose(ofile3);
  }

  LASunzipper* lasunzipper1 = new LASunzipper(); // without compression
  LASunzipper* lasunzipper2 = new LASunzipper(); // with arithmetic compression
  LASunzipper* lasunzipper3 = new LASunzipper(); // with range compression

  if (use_iostream)
  {
#ifdef LZ_WIN32_VC6
    ifb1.open("test1.lax", ios::in);
    ifb1.setmode(filebuf::binary);
    istream1 = new istream(&ifb1);
#else
    istream1 = new ifstream();
    istream1->open("test1.lax", std::ios::in | std::ios::binary );
#endif
    if (lasunzipper1->open(*istream1, num_items, items, LASZIP_COMPRESSION_NONE) != 0)
    {
      fprintf(stderr, "ERROR: could not open lasunzipper1\n");
      return 0;
    }
#ifdef LZ_WIN32_VC6
    ifb2.open("test2.lax", ios::in);
    ifb2.setmode(filebuf::binary);
    istream2 = new istream(&ifb2);
#else
    istream2 = new ifstream();
    istream2->open("test2.lax", std::ios::in | std::ios::binary );
#endif
    if (lasunzipper2->open(*istream2, num_items, items, LASZIP_COMPRESSION_ARITHMETIC) != 0)
    {
      fprintf(stderr, "ERROR: could not open lasunzipper2\n");
      return 0;
    }
#ifdef LZ_WIN32_VC6
    ifb3.open("test3.lax", ios::in);
    ifb3.setmode(filebuf::binary);
    istream3 = new istream(&ifb3);
#else
    istream3 = new ifstream();
    istream3->open("test3.lax", std::ios::in | std::ios::binary );
#endif
    if (lasunzipper3->open(*istream3, num_items, items, LASZIP_COMPRESSION_RANGE) != 0)
    {
      fprintf(stderr, "ERROR: could not open lasunzipper3\n");
      return 0;
    }
  }
  else
  {
    ifile1 = fopen("test1.lax", "rb");
    if (!lasunzipper1->open(ifile1, num_items, items, LASZIP_COMPRESSION_NONE))
    {
      fprintf(stderr, "ERROR: could not open lasunzipper1\n");
      return 0;
    }
    ifile2 = fopen("test2.lax", "rb");
    if (!lasunzipper2->open(ifile2, num_items, items, LASZIP_COMPRESSION_ARITHMETIC))
    {
      fprintf(stderr, "ERROR: could not open lasunzipper2\n");
      return 0;
    }
    ifile3 = fopen("test3.lax", "rb");
    if (!lasunzipper3->open(ifile3, num_items, items, LASZIP_COMPRESSION_RANGE))
    {
      fprintf(stderr, "ERROR: could not open lasunzipper3\n");
      return 0;
    }
  }

  // read num_points with "random" data

  start_time = taketime();
  num_errors = 0;
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    lasunzipper1->read(point);
    for (j = 0; j < point_size; j++)
    {
      if (point_data[j] != c)
      {
        fprintf(stderr, "%d %d %d != %d\n", i, j, point_data[j], c);
        num_errors++;
        if (num_errors > 20) return -1;
      }
      c++;
    }
  }
  num_bytes = lasunzipper1->close();
  end_time = taketime();
  if (num_errors)
  {
    fprintf(stderr, "ERROR: with lasunzipper1 %d\n", num_errors);
  }
  else
  {
   fprintf(stderr, "SUCCESS: lasunzipper1 read %d bytes in %g seconds\n", num_bytes, end_time-start_time);
  }

  // decompress num_points with "random" data

  start_time = taketime();
  num_errors = 0;
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    lasunzipper2->read(point);
    for (j = 0; j < point_size; j++)
    {
      if (point_data[j] != c)
      {
        fprintf(stderr, "%d %d %d != %d\n", i, j, point_data[j], c);
        num_errors++;
        if (num_errors > 20) return -1;
      }
      c++;
    }
  }
  num_bytes = lasunzipper2->close();
  end_time = taketime();
  if (num_errors)
  {
    fprintf(stderr, "ERROR: with lasunzipper2 %d\n", num_errors);
  }
  else
  {
   fprintf(stderr, "SUCCESS: lasunzipper2 read %d bytes in %g seconds\n", num_bytes, end_time-start_time);
  }

  // decompress num_points with "random" data

  start_time = taketime();
  num_errors = 0;
  c = 0;
  for (i = 0; i < num_points; i++)
  {
    lasunzipper3->read(point);
    for (j = 0; j < point_size; j++)
    {
      if (point_data[j] != c)
      {
        fprintf(stderr, "%d %d %d != %d\n", i, j, point_data[j], c);
        num_errors++;
        if (num_errors > 20) return -1;
      }
      c++;
    }
  }
  num_bytes = lasunzipper3->close();
  end_time = taketime();
  if (num_errors)
  {
    fprintf(stderr, "ERROR: with lasunzipper3 %d\n", num_errors);
  }
  else
  {
   fprintf(stderr, "SUCCESS: lasunzipper3 read %d bytes in %g seconds\n", num_bytes, end_time-start_time);
  }

  delete lasunzipper1;
  delete lasunzipper2;
  delete lasunzipper3;

  if (use_iostream)
  {
    delete istream1;
    delete istream2;
    delete istream3;
#ifdef LZ_WIN32_VC6
    ifb1.close();
    ifb2.close();
    ifb3.close();
#endif
  }
  else
  {
    fclose(ifile1);
    fclose(ifile2);
    fclose(ifile3);
  }

  return 0;
}
<|endoftext|>


<commit_before>#include <shogun/features/Labels.h>
#include <shogun/io/StreamingAsciiFile.h>
#include <shogun/io/SGIO.h>
#include <shogun/features/StreamingDenseFeatures.h>
#include <shogun/features/DenseFeatures.h>
#include <shogun/multiclass/MulticlassOneVsOneStrategy.h>
#include <shogun/machine/LinearMulticlassMachine.h>
#include <shogun/classifier/svm/LibLinear.h>
#include <shogun/base/init.h>

#define  EPSILON  1e-5

using namespace shogun;

int main(int argc, char** argv)
{
	int32_t num_vectors = 0;
	int32_t num_feats   = 2;

	init_shogun_with_defaults();

	// Prepare to read a file for the training data
	char fname_feats[]  = "../data/fm_train_real.dat";
	char fname_labels[] = "../data/label_train_multiclass.dat";
	CStreamingAsciiFile* ffeats_train  = new CStreamingAsciiFile(fname_feats);
	CStreamingAsciiFile* flabels_train = new CStreamingAsciiFile(fname_labels);
	SG_REF(ffeats_train);
	SG_REF(flabels_train);

	CStreamingDenseFeatures< float64_t >* stream_features =
		new CStreamingDenseFeatures< float64_t >(ffeats_train, false, 1024);

	CStreamingDenseFeatures< float64_t >* stream_labels =
		new CStreamingDenseFeatures< float64_t >(flabels_train, true, 1024);

	SG_REF(stream_features);
	SG_REF(stream_labels);

	// Create a matrix with enough space to read all the feature vectors
	SGMatrix< float64_t > mat = SGMatrix< float64_t >(num_feats, 1000);

	// Read the values from the file and store them in mat
	SGVector< float64_t > vec;
	stream_features->start_parser();
	while ( stream_features->get_next_example() )
	{
		vec = stream_features->get_vector();

		for ( int32_t i = 0 ; i < num_feats ; ++i )
			mat[num_vectors*num_feats + i] = vec[i];

		num_vectors++;
		stream_features->release_example();
	}
	stream_features->end_parser();

	// Create features with the useful values from mat
	CDenseFeatures< float64_t >* features = new CDenseFeatures< float64_t >(mat.matrix, num_feats, num_vectors);

	CLabels* labels = new CLabels(num_vectors);
	SG_REF(features);
	SG_REF(labels);

	// Read the labels from the file
	int32_t idx = 0;
	stream_labels->start_parser();
	while ( stream_labels->get_next_example() )
	{
		labels->set_int_label( idx++, (int32_t)stream_labels->get_label() );
		stream_labels->release_example();
	}
	stream_labels->end_parser();

	// Create liblinear svm classifier with L2-regularized L2-loss
	CLibLinear* svm = new CLibLinear(L2R_L2LOSS_SVC);
	SG_REF(svm);

	// Add some configuration to the svm
	svm->set_epsilon(EPSILON);
	svm->set_bias_enabled(true);

	// Create a multiclass svm classifier that consists of several of the previous one
	CLinearMulticlassMachine* mc_svm = new CLinearMulticlassMachine(
			new CMulticlassOneVsOneStrategy(), (CDotFeatures*) features, svm, labels);
	SG_REF(mc_svm);

	// Train the multiclass machine using the data passed in the constructor
	mc_svm->train();

	// Classify the training examples and show the results
	CLabels* output = mc_svm->apply();

	SGVector< int32_t > out_labels = output->get_int_labels();
	CMath::display_vector(out_labels.vector, out_labels.vlen);

	// Free resources
	SG_UNREF(mc_svm);
	SG_UNREF(svm);
	SG_UNREF(output);
	SG_UNREF(features);
	SG_UNREF(labels);
	SG_UNREF(ffeats_train);
	SG_UNREF(flabels_train);
	SG_UNREF(stream_features);
	SG_UNREF(stream_labels);
	exit_shogun();

	return 0;
}
<commit_msg>fix double free in example<commit_after>#include <shogun/features/Labels.h>
#include <shogun/io/StreamingAsciiFile.h>
#include <shogun/io/SGIO.h>
#include <shogun/features/StreamingDenseFeatures.h>
#include <shogun/features/DenseFeatures.h>
#include <shogun/multiclass/MulticlassOneVsOneStrategy.h>
#include <shogun/machine/LinearMulticlassMachine.h>
#include <shogun/classifier/svm/LibLinear.h>
#include <shogun/base/init.h>

#define  EPSILON  1e-5

using namespace shogun;

int main(int argc, char** argv)
{
	int32_t num_vectors = 0;
	int32_t num_feats   = 2;

	init_shogun_with_defaults();

	// Prepare to read a file for the training data
	char fname_feats[]  = "../data/fm_train_real.dat";
	char fname_labels[] = "../data/label_train_multiclass.dat";
	CStreamingAsciiFile* ffeats_train  = new CStreamingAsciiFile(fname_feats);
	CStreamingAsciiFile* flabels_train = new CStreamingAsciiFile(fname_labels);
	SG_REF(ffeats_train);
	SG_REF(flabels_train);

	CStreamingDenseFeatures< float64_t >* stream_features =
		new CStreamingDenseFeatures< float64_t >(ffeats_train, false, 1024);

	CStreamingDenseFeatures< float64_t >* stream_labels =
		new CStreamingDenseFeatures< float64_t >(flabels_train, true, 1024);

	SG_REF(stream_features);
	SG_REF(stream_labels);

	// Create a matrix with enough space to read all the feature vectors
	SGMatrix< float64_t > mat = SGMatrix< float64_t >(num_feats, 1000);

	// Read the values from the file and store them in mat
	SGVector< float64_t > vec;
	stream_features->start_parser();
	while ( stream_features->get_next_example() )
	{
		vec = stream_features->get_vector();

		for ( int32_t i = 0 ; i < num_feats ; ++i )
			mat.matrix[num_vectors*num_feats + i] = vec[i];

		num_vectors++;
		stream_features->release_example();
	}
	stream_features->end_parser();

	// Create features with the useful values from mat
	CDenseFeatures< float64_t >* features = new CDenseFeatures<float64_t>(mat);

	CLabels* labels = new CLabels(num_vectors);
	SG_REF(features);
	SG_REF(labels);

	// Read the labels from the file
	int32_t idx = 0;
	stream_labels->start_parser();
	while ( stream_labels->get_next_example() )
	{
		labels->set_int_label( idx++, (int32_t)stream_labels->get_label() );
		stream_labels->release_example();
	}
	stream_labels->end_parser();

	// Create liblinear svm classifier with L2-regularized L2-loss
	CLibLinear* svm = new CLibLinear(L2R_L2LOSS_SVC);
	SG_REF(svm);

	// Add some configuration to the svm
	svm->set_epsilon(EPSILON);
	svm->set_bias_enabled(true);

	// Create a multiclass svm classifier that consists of several of the previous one
	CLinearMulticlassMachine* mc_svm = new CLinearMulticlassMachine(
			new CMulticlassOneVsOneStrategy(), (CDotFeatures*) features, svm, labels);
	SG_REF(mc_svm);

	// Train the multiclass machine using the data passed in the constructor
	mc_svm->train();

	// Classify the training examples and show the results
	CLabels* output = mc_svm->apply();

	SGVector< int32_t > out_labels = output->get_int_labels();
	CMath::display_vector(out_labels.vector, out_labels.vlen);

	// Free resources
	SG_UNREF(mc_svm);
	SG_UNREF(svm);
	SG_UNREF(output);
	SG_UNREF(features);
	SG_UNREF(labels);
	SG_UNREF(ffeats_train);
	SG_UNREF(flabels_train);
	SG_UNREF(stream_features);
	SG_UNREF(stream_labels);
	exit_shogun();

	return 0;
}
<|endoftext|>


<commit_before>/**\file
 * \ingroup example-programmes
 * \brief FaaS: Fortune as a Service
 *
 * Call it like this:
 * \code
 * $ ./fortuned http:localhost:8080
 * \endcode
 *
 * With localhost and 8080 being a host name and port of your choosing. Then,
 * while the programme is running.
 *
 * \copyright
 * Copyright (c) 2015, ef.gy Project Members
 * \copyright
 * 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:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * 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.
 *
 * \see Project Documentation: https://ef.gy/documentation/libefgy
 * \see Project Source Code: https://github.com/ef-gy/libefgy
 */

#define ASIO_DISABLE_THREADS
#include <ef.gy/httpd.h>

#include <cstdlib>
#include <dirent.h>
#include <iostream>
#include <fstream>

using namespace efgy;
using namespace std;

map<string, string> fortuneData;

std::string replace(std::string subject, const std::string &search,
                    const std::string &replace) {
  size_t pos = 0;
  while ((pos = subject.find(search, pos)) != std::string::npos) {
    subject.replace(pos, search.length(), replace);
    pos += replace.length();
  }
  return subject;
}

class cookie {
public:
  enum encoding { ePlain, eROT13 } encoding;
  string file;
  size_t offset;
  size_t length;

  cookie(enum encoding pE, const string &pFile, size_t pOffset, size_t pLength)
      : encoding(pE), file(pFile), offset(pOffset), length(pLength) {}

  operator string(void) const {
    string r(fortuneData[file].data() + offset, length);

    if (encoding == eROT13) {
      for (size_t i = 0; i < r.size(); i++) {
        char c = r[i];

        switch (c) {
        case 'a':
        case 'b':
        case 'c':
        case 'd':
        case 'e':
        case 'f':
        case 'g':
        case 'h':
        case 'i':
        case 'j':
        case 'k':
        case 'l':
        case 'm':
        case 'A':
        case 'B':
        case 'C':
        case 'D':
        case 'E':
        case 'F':
        case 'G':
        case 'H':
        case 'I':
        case 'J':
        case 'K':
        case 'L':
        case 'M':
          r[i] = c + 13;
          break;
        case 'n':
        case 'o':
        case 'p':
        case 'q':
        case 'r':
        case 's':
        case 't':
        case 'u':
        case 'v':
        case 'w':
        case 'x':
        case 'y':
        case 'z':
        case 'N':
        case 'O':
        case 'P':
        case 'Q':
        case 'R':
        case 'S':
        case 'T':
        case 'U':
        case 'V':
        case 'W':
        case 'X':
        case 'Y':
        case 'Z':
          r[i] = c - 13;
          break;
        default:
          break;
        }
      }
    }

    return r;
  }
};

vector<cookie> cookies;

static bool
prepareFortunes(const string &pInoffensive = "/usr/share/games/fortunes/",
                const string &pOffensive = "/usr/share/games/fortunes/off/") {
  static const regex dataFile(".*/[a-zA-Z-]+");
  smatch matches;

  for (unsigned int q = 0; q < 2; q++) {
    string dir = (q == 0) ? pInoffensive : pOffensive;
    bool doROT13 = (q == 1);

    DIR *d = opendir(dir.c_str());
    if (!d) {
      continue;
    }
    struct dirent *en;
    while ((en = readdir(d)) != 0) {
      string e = dir + en->d_name;

      if (regex_match(e, matches, dataFile)) {
        std::ifstream t(e);
        std::stringstream buffer;
        buffer << t.rdbuf();

        fortuneData[e] = buffer.str();

        const string &p = fortuneData[e];
        const char *data = p.c_str();
        size_t start = 0;
        enum { stN, stNL, stNLP } state = stN;

        for (size_t c = 0; c < p.size(); c++) {
          switch (data[c]) {
          case '\n':
            switch (state) {
            case stN:
              state = stNL;
              break;
            case stNLP:
              cookies.push_back(
                  cookie((doROT13 ? cookie::eROT13 : cookie::ePlain), e, start,
                         c - start - 1));
              start = c + 1;
            default:
              state = stN;
              break;
            }
            break;

          case '%':
            switch (state) {
            case stNL:
              state = stNLP;
              break;
            default:
              state = stN;
              break;
            }
            break;

          case '\r':
            break;

          default:
            state = stN;
            break;
          }
        }
      }
    }
    closedir(d);
  }

  return true;
}

template <class transport>
static bool fortune(typename net::http::server<transport>::session &session,
                    std::smatch &) {
  const int id = rand() % cookies.size();
  const cookie &c = cookies[id];
  char nbuf[20];
  snprintf(nbuf, 20, "%i", id);
  string sc = string(c);

  /* note: this escaping is not exactly efficient, but it's fairly simple
     and the strings are fairly short, so it shouldn't be much of an issue. */
  for (char i = 0; i < 0x20; i++) {
    if ((i == '\n') || (i == '\t')) {
      continue;
    }
    const char org[2] = {i, 0};
    const char rep[3] = {'^', (char)(('A' - 1) + i), 0};
    replace(sc, org, rep);
  }

  sc = "<![CDATA[" + sc + "]]>";

  session.reply(200, "Content-Type: text/xml; charset=utf-8\r\n",
                string("<?xml version='1.0' encoding='utf-8'?>"
                       "<fortune xmlns='http://ef.gy/2012/fortune' quoteID='") +
                    nbuf + "' sourceFile='" + c.file + "'>" + sc +
                    "</fortune>");

  return true;
}

namespace tcp {
using asio::ip::tcp;
static httpd::servlet<tcp> fortune("^/fortune$", ::fortune<tcp>);
static httpd::servlet<tcp> quit("^/quit$", httpd::quit<tcp>);
}

namespace unix {
using asio::local::stream_protocol;
static httpd::servlet<stream_protocol> fortune("^/fortune$",
                                               ::fortune<stream_protocol>);
static httpd::servlet<stream_protocol> quit("^/quit$",
                                            httpd::quit<stream_protocol>);
}

static cli::option
    count("count", [](std::smatch &m) -> bool {
                     std::cout << cookies.size() << " cookie(s) loaded\n";

                     return true;
                   },
          "prints the number of fortune cookies in the database.");

static cli::option print("print(:([0-9]+))?",
                         [](std::smatch &m) -> bool {
                           if (m[1] != "") {
                             std::stringstream s(m[2]);
                             std::size_t n;
                             s >> n;
                             if (n < cookies.size()) {
                               std::cout << std::string(cookies[n]);
                             } else {
                               return false;
                             }
                           } else {
                             std::cout << std::string(
                                 cookies[(rand() % cookies.size())]);
                           }

                           return true;
                         },
                         "print a fortune to stdout"
                         " - a numerical parameter selects a specific cookie.");

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

  srand(time(0));

  return io::main(argc, argv);
}
<commit_msg>this daemon will need more cleaning<commit_after>/**\file
 * \ingroup example-programmes
 * \brief FaaS: Fortune as a Service
 *
 * Call it like this:
 * \code
 * $ ./fortuned http:localhost:8080
 * \endcode
 *
 * With localhost and 8080 being a host name and port of your choosing. Then,
 * while the programme is running.
 *
 * \copyright
 * Copyright (c) 2015, ef.gy Project Members
 * \copyright
 * 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:
 * \copyright
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * \copyright
 * 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.
 *
 * \see Project Documentation: https://ef.gy/documentation/libefgy
 * \see Project Source Code: https://github.com/ef-gy/libefgy
 */

#define ASIO_DISABLE_THREADS
#include <ef.gy/httpd.h>

#include <cstdlib>
#include <dirent.h>
#include <iostream>
#include <fstream>

using namespace efgy;
using namespace std;

map<string, string> fortuneData;

class cookie {
public:
  enum encoding { ePlain, eROT13 } encoding;
  string file;
  size_t offset;
  size_t length;

  cookie(enum encoding pE, const string &pFile, size_t pOffset, size_t pLength)
      : encoding(pE), file(pFile), offset(pOffset), length(pLength) {}

  operator string(void) const {
    string r(fortuneData[file].data() + offset, length);

    if (encoding == eROT13) {
      for (size_t i = 0; i < r.size(); i++) {
        char c = r[i];

        switch (c) {
        case 'a':
        case 'b':
        case 'c':
        case 'd':
        case 'e':
        case 'f':
        case 'g':
        case 'h':
        case 'i':
        case 'j':
        case 'k':
        case 'l':
        case 'm':
        case 'A':
        case 'B':
        case 'C':
        case 'D':
        case 'E':
        case 'F':
        case 'G':
        case 'H':
        case 'I':
        case 'J':
        case 'K':
        case 'L':
        case 'M':
          r[i] = c + 13;
          break;
        case 'n':
        case 'o':
        case 'p':
        case 'q':
        case 'r':
        case 's':
        case 't':
        case 'u':
        case 'v':
        case 'w':
        case 'x':
        case 'y':
        case 'z':
        case 'N':
        case 'O':
        case 'P':
        case 'Q':
        case 'R':
        case 'S':
        case 'T':
        case 'U':
        case 'V':
        case 'W':
        case 'X':
        case 'Y':
        case 'Z':
          r[i] = c - 13;
          break;
        default:
          break;
        }
      }
    }

    return r;
  }
};

vector<cookie> cookies;

static bool prepareFortunes(const string &dir, const bool doROT13 = false) {
  static const regex dataFile(".*/[a-zA-Z-]+");
  smatch matches;

  DIR *d = opendir(dir.c_str());
  if (!d) {
    return false;
  }
  struct dirent *en;
  while ((en = readdir(d)) != 0) {
    string e = dir + en->d_name;

    if (regex_match(e, matches, dataFile)) {
      std::ifstream t(e);
      std::stringstream buffer;
      buffer << t.rdbuf();

      fortuneData[e] = buffer.str();

      const string &p = fortuneData[e];
      const char *data = p.c_str();
      size_t start = 0;
      enum { stN, stNL, stNLP } state = stN;

      for (size_t c = 0; c < p.size(); c++) {
        switch (data[c]) {
        case '\n':
          switch (state) {
          case stN:
            state = stNL;
            break;
          case stNLP:
            cookies.push_back(
                cookie((doROT13 ? cookie::eROT13 : cookie::ePlain), e, start,
                       c - start - 1));
            start = c + 1;
          default:
            state = stN;
            break;
          }
          break;

        case '%':
          switch (state) {
          case stNL:
            state = stNLP;
            break;
          default:
            state = stN;
            break;
          }
          break;

        case '\r':
          break;

        default:
          state = stN;
          break;
        }
      }
    }
  }
  closedir(d);

  return true;
}

template <class transport>
static bool fortune(typename net::http::server<transport>::session &session,
                    std::smatch &) {
  const int id = rand() % cookies.size();
  const cookie &c = cookies[id];
  char nbuf[20];
  snprintf(nbuf, 20, "%i", id);
  string sc = string(c);

  /* note: this escaping is not exactly efficient, but it's fairly simple
     and the strings are fairly short, so it shouldn't be much of an issue. */
  for (char i = 0; i < 0x20; i++) {
    if ((i == '\n') || (i == '\t')) {
      continue;
    }
    const char org[2] = {i, 0};
    const char rep[3] = {'^', (char)(('A' - 1) + i), 0};
    for (size_t pos = sc.find(org, pos); pos != std::string::npos;
         pos = sc.find(org, pos)) {
      sc.replace(pos, 2, rep);
      pos += 3;
    }
  }

  sc = "<![CDATA[" + sc + "]]>";

  session.reply(200, "Content-Type: text/xml; charset=utf-8\r\n",
                string("<?xml version='1.0' encoding='utf-8'?>"
                       "<fortune xmlns='http://ef.gy/2012/fortune' quoteID='") +
                    nbuf + "' sourceFile='" + c.file + "'>" + sc +
                    "</fortune>");

  return true;
}

namespace tcp {
using asio::ip::tcp;
static httpd::servlet<tcp> fortune("^/fortune$", ::fortune<tcp>);
static httpd::servlet<tcp> quit("^/quit$", httpd::quit<tcp>);
}

namespace unix {
using asio::local::stream_protocol;
static httpd::servlet<stream_protocol> fortune("^/fortune$",
                                               ::fortune<stream_protocol>);
static httpd::servlet<stream_protocol> quit("^/quit$",
                                            httpd::quit<stream_protocol>);
}

static cli::option
    count("count", [](std::smatch &m) -> bool {
                     std::cout << cookies.size() << " cookie(s) loaded\n";

                     return true;
                   },
          "prints the number of fortune cookies in the database.");

static cli::option print("print(:([0-9]+))?",
                         [](std::smatch &m) -> bool {
                           if (m[1] != "") {
                             std::stringstream s(m[2]);
                             std::size_t n;
                             s >> n;
                             if (n < cookies.size()) {
                               std::cout << std::string(cookies[n]);
                             } else {
                               return false;
                             }
                           } else {
                             std::cout << std::string(
                                 cookies[(rand() % cookies.size())]);
                           }

                           return true;
                         },
                         "print a fortune to stdout - a numerical parameter "
                         "selects a specific cookie.");

int main(int argc, char *argv[]) {
  prepareFortunes("/usr/share/games/fortunes/");
  prepareFortunes("/usr/share/games/fortunes/off/", true);

  srand(time(0));

  return io::main(argc, argv);
}
<|endoftext|>


<commit_before>#include "command.hh"
#include "shared.hh"
#include "store-api.hh"
#include "sync.hh"
#include "thread-pool.hh"

#include <atomic>

using namespace nix;

struct CmdCopy : StorePathsCommand
{
    std::string srcUri, dstUri;

    CheckSigsFlag checkSigs = CheckSigs;

    CmdCopy()
    {
        mkFlag(0, "from", "store-uri", "URI of the source Nix store", &srcUri);
        mkFlag(0, "to", "store-uri", "URI of the destination Nix store", &dstUri);

        mkFlag()
            .longName("no-check-sigs")
            .description("do not require that paths are signed by trusted keys")
            .set(&checkSigs, NoCheckSigs);
    }

    std::string name() override
    {
        return "copy";
    }

    std::string description() override
    {
        return "copy paths between Nix stores";
    }

    Examples examples() override
    {
        return {
            Example{
                "To copy Firefox from the local store to a binary cache in file:///tmp/cache:",
                "nix copy --to file:///tmp/cache -r $(type -p firefox)"
            },
            Example{
                "To copy the entire current NixOS system closure to another machine via SSH:",
                "nix copy --to ssh://server -r /run/current-system"
            },
            Example{
                "To copy a closure from another machine via SSH:",
                "nix copy --from ssh://server -r /nix/store/a6cnl93nk1wxnq84brbbwr6hxw9gp2w9-blender-2.79-rc2"
            },
        };
    }

    ref<Store> createStore() override
    {
        return srcUri.empty() ? StoreCommand::createStore() : openStore(srcUri);
    }

    void run(ref<Store> srcStore, Paths storePaths) override
    {
        if (srcUri.empty() && dstUri.empty())
            throw UsageError("you must pass '--from' and/or '--to'");

        ref<Store> dstStore = dstUri.empty() ? openStore() : openStore(dstUri);

        copyPaths(srcStore, dstStore, PathSet(storePaths.begin(), storePaths.end()),
            NoRepair, checkSigs);
    }
};

static RegisterCommand r1(make_ref<CmdCopy>());
<commit_msg>nix copy: Add --substitute flag<commit_after>#include "command.hh"
#include "shared.hh"
#include "store-api.hh"
#include "sync.hh"
#include "thread-pool.hh"

#include <atomic>

using namespace nix;

struct CmdCopy : StorePathsCommand
{
    std::string srcUri, dstUri;

    CheckSigsFlag checkSigs = CheckSigs;

    SubstituteFlag substitute = NoSubstitute;

    CmdCopy()
    {
        mkFlag(0, "from", "store-uri", "URI of the source Nix store", &srcUri);
        mkFlag(0, "to", "store-uri", "URI of the destination Nix store", &dstUri);

        mkFlag()
            .longName("no-check-sigs")
            .description("do not require that paths are signed by trusted keys")
            .set(&checkSigs, NoCheckSigs);

        mkFlag()
            .longName("substitute")
            .shortName('s')
            .description("whether to try substitutes on the destination store (only supported by SSH)")
            .set(&substitute, Substitute);
    }

    std::string name() override
    {
        return "copy";
    }

    std::string description() override
    {
        return "copy paths between Nix stores";
    }

    Examples examples() override
    {
        return {
            Example{
                "To copy Firefox from the local store to a binary cache in file:///tmp/cache:",
                "nix copy --to file:///tmp/cache -r $(type -p firefox)"
            },
            Example{
                "To copy the entire current NixOS system closure to another machine via SSH:",
                "nix copy --to ssh://server -r /run/current-system"
            },
            Example{
                "To copy a closure from another machine via SSH:",
                "nix copy --from ssh://server -r /nix/store/a6cnl93nk1wxnq84brbbwr6hxw9gp2w9-blender-2.79-rc2"
            },
        };
    }

    ref<Store> createStore() override
    {
        return srcUri.empty() ? StoreCommand::createStore() : openStore(srcUri);
    }

    void run(ref<Store> srcStore, Paths storePaths) override
    {
        if (srcUri.empty() && dstUri.empty())
            throw UsageError("you must pass '--from' and/or '--to'");

        ref<Store> dstStore = dstUri.empty() ? openStore() : openStore(dstUri);

        copyPaths(srcStore, dstStore, PathSet(storePaths.begin(), storePaths.end()),
            NoRepair, checkSigs, substitute);
    }
};

static RegisterCommand r1(make_ref<CmdCopy>());
<|endoftext|>


<commit_before>#include "notebook.h"
#include "logging.h"
#include "sourcefile.h"
#include "singletons.h"
#include <fstream>
#include <regex>
#include "cmake.h"

#if GTK_VERSION_GE(3, 18)
#include "gtksourceview-3.0/gtksourceview/gtksourcemap.h"
#endif

#include <iostream> //TODO: remove
using namespace std; //TODO: remove

namespace sigc {
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
  template <typename Functor>
  struct functor_trait<Functor, false> {
    typedef decltype (::sigc::mem_fun(std::declval<Functor&>(),
                                      &Functor::operator())) _intermediate;
    typedef typename _intermediate::result_type result_type;
    typedef Functor functor_type;
  };
#else
  SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
#endif
}

Notebook::Notebook(Directories &directories) : Gtk::Notebook(), directories(directories) {
  Gsv::init();
}

int Notebook::size() {
  return get_n_pages();
}

Source::View* Notebook::get_view(int page) {
  return source_views.at(get_index(page));
}

size_t Notebook::get_index(int page) {
  for(size_t c=0;c<hboxes.size();c++) {
    if(page_num(*hboxes.at(c))==page)
      return c;
  }
  return -1;
}

Source::View* Notebook::get_current_view() {
  return get_view(get_current_page());
}

void Notebook::open(const boost::filesystem::path &file_path) {
  DEBUG("start");
  for(int c=0;c<size();c++) {
    if(file_path==get_view(c)->file_path) {
      set_current_page(c);
      get_current_view()->grab_focus();
      return;
    }
  }

  std::ifstream can_read(file_path.string());
  if(!can_read) {
    Singleton::terminal()->print("Error: could not open "+file_path.string()+"\n");
    return;
  }
  can_read.close();

  auto language=Source::guess_language(file_path);
  if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) {
    boost::filesystem::path project_path;
    if(directories.cmake && directories.cmake->project_path!="" && file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') {
      project_path=directories.cmake->project_path;
      if(boost::filesystem::exists(project_path.string()+"/CMakeLists.txt") && !boost::filesystem::exists(project_path.string()+"/compile_commands.json"))
        CMake::create_compile_commands(project_path);
    }
    else {
      project_path=file_path.parent_path();
      CMake cmake(project_path);
      if(cmake.project_path!="") {
        project_path=cmake.project_path;
        Singleton::terminal()->print("Project path for "+file_path.string()+" set to "+project_path.string()+"\n");
      }
      else
        Singleton::terminal()->print("Error: could not find project path for "+file_path.string()+"\n");
    }
    source_views.emplace_back(new Source::ClangView(file_path, project_path, language));
  }
  else
    source_views.emplace_back(new Source::GenericView(file_path, language));

  source_views.back()->on_update_status=[this](Source::View* view, const std::string &status) {
    if(get_current_page()!=-1 && get_current_view()==view)
      Singleton::status()->set_text(status+" ");
  };
  source_views.back()->on_update_info=[this](Source::View* view, const std::string &info) {
    if(get_current_page()!=-1 && get_current_view()==view)
      Singleton::info()->set_text(" "+info);
  };

  scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
  hboxes.emplace_back(new Gtk::HBox());
  scrolled_windows.back()->add(*source_views.back());
  hboxes.back()->pack_start(*scrolled_windows.back());

#if GTK_VERSION_GE(3, 18)
  source_maps.emplace_back(Glib::wrap(gtk_source_map_new()));
  hboxes.back()->pack_end(*source_maps.back(), Gtk::PACK_SHRINK);
  gtk_source_map_set_view(GTK_SOURCE_MAP(source_maps.back()->gobj()), source_views.back()->gobj());
#endif
  configure(source_views.size()-1);

  std::string title=file_path.filename().string();
  append_page(*hboxes.back(), title);

  set_tab_reorderable(*hboxes.back(), true);
  show_all_children();
  set_current_page(size()-1);
  set_focus_child(*source_views.back());
  get_current_view()->get_buffer()->set_modified(false);
  get_current_view()->grab_focus();
  //Add star on tab label when the page is not saved:
  auto source_view=get_current_view();
  get_current_view()->get_buffer()->signal_modified_changed().connect([this, source_view]() {
    std::string title=source_view->file_path.filename().string();
    if(source_view->get_buffer()->get_modified())
      title+="*";
    int page=-1;
    for(int c=0;c<size();c++) {
      if(get_view(c)==source_view) {
        page=c;
        break;
      }
    }
    if(page!=-1)
      set_tab_label_text(*(get_nth_page(page)), title);
  });

  DEBUG("end");
}

void Notebook::configure(int view_nr) {
#if GTK_VERSION_GE(3, 18)
  auto source_font_description=Pango::FontDescription(Singleton::Config::source()->font);
  auto source_map_font_desc=Pango::FontDescription(static_cast<std::string>(source_font_description.get_family())+" "+Singleton::Config::source()->map_font_size);
  source_maps.at(view_nr)->override_font(source_map_font_desc);
  if(Singleton::Config::source()->show_map)
    source_maps.at(view_nr)->show();
  else
    source_maps.at(view_nr)->hide();
#endif
}

bool Notebook::save(int page, bool reparse_needed) {
  DEBUG("start");
  if(page>=size()) {
    DEBUG("end false");
    return false;
  }
  auto view=get_view(page);
  if (view->file_path != "" && view->get_buffer()->get_modified()) {
    if(juci::filesystem::write(view->file_path, view->get_buffer())) {
      if(reparse_needed) {
        if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
          for(auto a_view: source_views) {
            if(auto a_clang_view=dynamic_cast<Source::ClangView*>(a_view)) {
              if(clang_view!=a_clang_view)
                a_clang_view->reparse_needed=true;
            }
          }
        }
      }

      view->get_buffer()->set_modified(false);
      Singleton::terminal()->print("File saved to: " +view->file_path.string()+"\n");

      //If CMakeLists.txt have been modified:
      //TODO: recreate cmake even without directories open?
      if(view->file_path.filename()=="CMakeLists.txt") {
        if(directories.cmake && directories.cmake->project_path!="" && view->file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/' && CMake::create_compile_commands(directories.cmake->project_path)) {
          for(auto source_view: source_views) {
            if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
              if(directories.cmake->project_path.string()==source_clang_view->project_path) {
                if(source_clang_view->restart_parse())
                  Singleton::terminal()->async_print("Reparsing "+source_clang_view->file_path.string()+"\n");
                else
                  Singleton::terminal()->async_print("Error: failed to reparse "+source_clang_view->file_path.string()+". Please reopen the file manually.\n");
              }
            }
          }
        }
      }
      DEBUG("end true");
      return true;
    }
    Singleton::terminal()->print("Error: could not save file " +view->file_path.string()+"\n");
  }
  DEBUG("end false");
  return false;
}

bool Notebook::save_current() {
  if(get_current_page()==-1)
    return false;
  return save(get_current_page(), true);
}

bool Notebook::close_current_page() {
  DEBUG("start");
  if (get_current_page()!=-1) {
    if(get_current_view()->get_buffer()->get_modified()){
      if(!save_modified_dialog()) {
        DEBUG("end false");
        return false;
      }
    }
    int page = get_current_page();
    int index=get_index(page);
    remove_page(page);
#if GTK_VERSION_GE(3, 18)
    source_maps.erase(source_maps.begin()+index);
#endif
    auto source_view=source_views.at(index);
    if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view))
      source_clang_view->async_delete();
    else
      delete source_view;
    source_views.erase(source_views.begin()+index);
    scrolled_windows.erase(scrolled_windows.begin()+index);
    hboxes.erase(hboxes.begin()+index);
  }
  DEBUG("end true");
  return true;
}

bool Notebook::save_modified_dialog() {
  Gtk::MessageDialog dialog((Gtk::Window&)(*get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
  dialog.set_default_response(Gtk::RESPONSE_YES);
  dialog.set_secondary_text("Do you want to save: " + get_current_view()->file_path.string()+" ?");
  int result = dialog.run();
  if(result==Gtk::RESPONSE_YES) {
    save_current();
    return true;
  }
  else if(result==Gtk::RESPONSE_NO) {
    return true;
  }
  else {
    return false;
  }
}

<commit_msg>Source map show/hide configuration is now working.<commit_after>#include "notebook.h"
#include "logging.h"
#include "sourcefile.h"
#include "singletons.h"
#include <fstream>
#include <regex>
#include "cmake.h"

#if GTK_VERSION_GE(3, 18)
#include "gtksourceview-3.0/gtksourceview/gtksourcemap.h"
#endif

#include <iostream> //TODO: remove
using namespace std; //TODO: remove

namespace sigc {
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
  template <typename Functor>
  struct functor_trait<Functor, false> {
    typedef decltype (::sigc::mem_fun(std::declval<Functor&>(),
                                      &Functor::operator())) _intermediate;
    typedef typename _intermediate::result_type result_type;
    typedef Functor functor_type;
  };
#else
  SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
#endif
}

Notebook::Notebook(Directories &directories) : Gtk::Notebook(), directories(directories) {
  Gsv::init();
}

int Notebook::size() {
  return get_n_pages();
}

Source::View* Notebook::get_view(int page) {
  return source_views.at(get_index(page));
}

size_t Notebook::get_index(int page) {
  for(size_t c=0;c<hboxes.size();c++) {
    if(page_num(*hboxes.at(c))==page)
      return c;
  }
  return -1;
}

Source::View* Notebook::get_current_view() {
  return get_view(get_current_page());
}

void Notebook::open(const boost::filesystem::path &file_path) {
  DEBUG("start");
  for(int c=0;c<size();c++) {
    if(file_path==get_view(c)->file_path) {
      set_current_page(c);
      get_current_view()->grab_focus();
      return;
    }
  }

  std::ifstream can_read(file_path.string());
  if(!can_read) {
    Singleton::terminal()->print("Error: could not open "+file_path.string()+"\n");
    return;
  }
  can_read.close();

  auto language=Source::guess_language(file_path);
  if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) {
    boost::filesystem::path project_path;
    if(directories.cmake && directories.cmake->project_path!="" && file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') {
      project_path=directories.cmake->project_path;
      if(boost::filesystem::exists(project_path.string()+"/CMakeLists.txt") && !boost::filesystem::exists(project_path.string()+"/compile_commands.json"))
        CMake::create_compile_commands(project_path);
    }
    else {
      project_path=file_path.parent_path();
      CMake cmake(project_path);
      if(cmake.project_path!="") {
        project_path=cmake.project_path;
        Singleton::terminal()->print("Project path for "+file_path.string()+" set to "+project_path.string()+"\n");
      }
      else
        Singleton::terminal()->print("Error: could not find project path for "+file_path.string()+"\n");
    }
    source_views.emplace_back(new Source::ClangView(file_path, project_path, language));
  }
  else
    source_views.emplace_back(new Source::GenericView(file_path, language));

  source_views.back()->on_update_status=[this](Source::View* view, const std::string &status) {
    if(get_current_page()!=-1 && get_current_view()==view)
      Singleton::status()->set_text(status+" ");
  };
  source_views.back()->on_update_info=[this](Source::View* view, const std::string &info) {
    if(get_current_page()!=-1 && get_current_view()==view)
      Singleton::info()->set_text(" "+info);
  };

  scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
  hboxes.emplace_back(new Gtk::HBox());
  scrolled_windows.back()->add(*source_views.back());
  hboxes.back()->pack_start(*scrolled_windows.back());

#if GTK_VERSION_GE(3, 18)
  source_maps.emplace_back(Glib::wrap(gtk_source_map_new()));
  gtk_source_map_set_view(GTK_SOURCE_MAP(source_maps.back()->gobj()), source_views.back()->gobj());
#endif
  configure(source_views.size()-1);

  std::string title=file_path.filename().string();
  append_page(*hboxes.back(), title);

  set_tab_reorderable(*hboxes.back(), true);
  show_all_children();
  set_current_page(size()-1);
  set_focus_child(*source_views.back());
  get_current_view()->get_buffer()->set_modified(false);
  get_current_view()->grab_focus();
  //Add star on tab label when the page is not saved:
  auto source_view=get_current_view();
  get_current_view()->get_buffer()->signal_modified_changed().connect([this, source_view]() {
    std::string title=source_view->file_path.filename().string();
    if(source_view->get_buffer()->get_modified())
      title+="*";
    int page=-1;
    for(int c=0;c<size();c++) {
      if(get_view(c)==source_view) {
        page=c;
        break;
      }
    }
    if(page!=-1)
      set_tab_label_text(*(get_nth_page(page)), title);
  });

  DEBUG("end");
}

void Notebook::configure(int view_nr) {
#if GTK_VERSION_GE(3, 18)
  auto source_font_description=Pango::FontDescription(Singleton::Config::source()->font);
  auto source_map_font_desc=Pango::FontDescription(static_cast<std::string>(source_font_description.get_family())+" "+Singleton::Config::source()->map_font_size);
  source_maps.at(view_nr)->override_font(source_map_font_desc);
  if(Singleton::Config::source()->show_map) {
    if(hboxes.at(view_nr)->get_children().size()==1)
      hboxes.at(view_nr)->pack_end(*source_maps.at(view_nr), Gtk::PACK_SHRINK);
  }
  else if(hboxes.at(view_nr)->get_children().size()==2)
    hboxes.at(view_nr)->remove(*source_maps.at(view_nr));
#endif
}

bool Notebook::save(int page, bool reparse_needed) {
  DEBUG("start");
  if(page>=size()) {
    DEBUG("end false");
    return false;
  }
  auto view=get_view(page);
  if (view->file_path != "" && view->get_buffer()->get_modified()) {
    if(juci::filesystem::write(view->file_path, view->get_buffer())) {
      if(reparse_needed) {
        if(auto clang_view=dynamic_cast<Source::ClangView*>(view)) {
          for(auto a_view: source_views) {
            if(auto a_clang_view=dynamic_cast<Source::ClangView*>(a_view)) {
              if(clang_view!=a_clang_view)
                a_clang_view->reparse_needed=true;
            }
          }
        }
      }

      view->get_buffer()->set_modified(false);
      Singleton::terminal()->print("File saved to: " +view->file_path.string()+"\n");

      //If CMakeLists.txt have been modified:
      //TODO: recreate cmake even without directories open?
      if(view->file_path.filename()=="CMakeLists.txt") {
        if(directories.cmake && directories.cmake->project_path!="" && view->file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/' && CMake::create_compile_commands(directories.cmake->project_path)) {
          for(auto source_view: source_views) {
            if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view)) {
              if(directories.cmake->project_path.string()==source_clang_view->project_path) {
                if(source_clang_view->restart_parse())
                  Singleton::terminal()->async_print("Reparsing "+source_clang_view->file_path.string()+"\n");
                else
                  Singleton::terminal()->async_print("Error: failed to reparse "+source_clang_view->file_path.string()+". Please reopen the file manually.\n");
              }
            }
          }
        }
      }
      DEBUG("end true");
      return true;
    }
    Singleton::terminal()->print("Error: could not save file " +view->file_path.string()+"\n");
  }
  DEBUG("end false");
  return false;
}

bool Notebook::save_current() {
  if(get_current_page()==-1)
    return false;
  return save(get_current_page(), true);
}

bool Notebook::close_current_page() {
  DEBUG("start");
  if (get_current_page()!=-1) {
    if(get_current_view()->get_buffer()->get_modified()){
      if(!save_modified_dialog()) {
        DEBUG("end false");
        return false;
      }
    }
    int page = get_current_page();
    int index=get_index(page);
    remove_page(page);
#if GTK_VERSION_GE(3, 18)
    source_maps.erase(source_maps.begin()+index);
#endif
    auto source_view=source_views.at(index);
    if(auto source_clang_view=dynamic_cast<Source::ClangView*>(source_view))
      source_clang_view->async_delete();
    else
      delete source_view;
    source_views.erase(source_views.begin()+index);
    scrolled_windows.erase(scrolled_windows.begin()+index);
    hboxes.erase(hboxes.begin()+index);
  }
  DEBUG("end true");
  return true;
}

bool Notebook::save_modified_dialog() {
  Gtk::MessageDialog dialog((Gtk::Window&)(*get_toplevel()), "Save file!", false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO);
  dialog.set_default_response(Gtk::RESPONSE_YES);
  dialog.set_secondary_text("Do you want to save: " + get_current_view()->file_path.string()+" ?");
  int result = dialog.run();
  if(result==Gtk::RESPONSE_YES) {
    save_current();
    return true;
  }
  else if(result==Gtk::RESPONSE_NO) {
    return true;
  }
  else {
    return false;
  }
}

<|endoftext|>