<commit_before>/*
 * RegexManager unit test set
 *
 * Copyright (c) eQualit.ie 2013 under GNU AGPL v3.0 or later
 *
 *  Vmon: Sept 2013, Initial version
 */

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

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <zmq.hpp>

#include <re2/re2.h> //google re2

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

#include <gtest/gtest.h> //google test

#include <ts/ts.h>
#include <unistd.h>

#include "util.h"
#include "banjax.h"
#include "unittest_common.h"
#include "regex_manager.h"

#include "swabber_interface.h"
#include "ip_database.h"

using namespace std;

/**
   Mainly fill an string stream buffer with a predefined configuration
   and to check if the regex manager has picked them correctly and
   match them correctly.
 */
class RegexManagerTest : public testing::Test {
 protected:

  libconfig::Config cfg;
  string TEMP_DIR;
  string TEST_CONF_FILE;

  fstream  mock_config;
  BanjaxFilter* test_regex_manager;

  IPDatabase test_ip_database;
  SwabberInterface test_swabber_interface;

  RegexManagerTest()
    :  test_swabber_interface(&test_ip_database)
  {}

  virtual void SetUp() {

    test_regex_manager = NULL;
    TEMP_DIR = "/tmp";

    TEST_CONF_FILE = TEMP_DIR + "/banjax.conf";
  }

  //if there is no way to feed an sstream to
  //to config reader then we might need to close the file
  //tear down. More importantly we need to make the file in case of non
  //existence anyways
  virtual void TearDown() {
   delete test_regex_manager;
  }

  void open_config()
  {
    libconfig::Config cfg;
    try  {
      cfg.readFile(TEST_CONF_FILE.c_str());
    }
    catch(const libconfig::FileIOException &fioex)  {
      ASSERT_TRUE(false);
    }
    catch(const libconfig::ParseException &pex)   {
      ASSERT_TRUE(false);
    }

    const libconfig::Setting& config_root = cfg.getRoot();
    test_regex_manager = new RegexManager(TEMP_DIR, config_root, &test_ip_database, &test_swabber_interface);

  }

};

/**
   make up a fake GET request and check that the manager is banning
 */
TEST_F(RegexManagerTest, match)
{

  open_config();

  //first we make a mock up request
  TransactionParts mock_transaction;
  mock_transaction[TransactionMuncher::METHOD] = "GET";
  mock_transaction[TransactionMuncher::IP] = "123.456.789.123";
  mock_transaction[TransactionMuncher::URL] = "http://simple_to_ban_me/";
  mock_transaction[TransactionMuncher::HOST] = "neverhood.com";
  mock_transaction[TransactionMuncher::UA] = "neverhood browsing and co";

  FilterResponse cur_filter_result = test_regex_manager->execute(mock_transaction);

  EXPECT_EQ(cur_filter_result.response_type, FilterResponse::I_RESPOND);

}

<commit_msg>name resolve<commit_after>/*
 * RegexManager unit test set
 *
 * Copyright (c) eQualit.ie 2013 under GNU AGPL v3.0 or later
 *
 *  Vmon: Sept 2013, Initial version
 */

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

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <zmq.hpp>

#include <re2/re2.h> //google re2

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

#include <gtest/gtest.h> //google test

#include <ts/ts.h>
#include <unistd.h>

#include "util.h"
#include "banjax.h"
#include "unittest_common.h"
#include "regex_manager.h"

#include "swabber_interface.h"
#include "ip_database.h"

using namespace std;

/**
   Mainly fill an string stream buffer with a predefined configuration
   and to check if the regex manager has picked them correctly and
   match them correctly.
 */
class RegexTester : public testing::Test {
 protected:

  libconfig::Config cfg;
  string TEMP_DIR;
  string TEST_CONF_FILE;

  fstream  mock_config;
  BanjaxFilter* test_regex_manager;

  IPDatabase test_ip_database;
  SwabberInterface test_swabber_interface;

  RegexTester()
    :  test_swabber_interface(&test_ip_database)
  {}

  virtual void SetUp() {

    test_regex_manager = NULL;
    TEMP_DIR = "/tmp";

    TEST_CONF_FILE = TEMP_DIR + "/banjax.conf";
  }

  //if there is no way to feed an sstream to
  //to config reader then we might need to close the file
  //tear down. More importantly we need to make the file in case of non
  //existence anyways
  virtual void TearDown() {
   delete test_regex_manager;
  }

  void open_config()
  {
    libconfig::Config cfg;
    try  {
      cfg.readFile(TEST_CONF_FILE.c_str());
    }
    catch(const libconfig::FileIOException &fioex)  {
      ASSERT_TRUE(false);
    }
    catch(const libconfig::ParseException &pex)   {
      ASSERT_TRUE(false);
    }

    const libconfig::Setting& config_root = cfg.getRoot();
    test_regex_manager = new RegexManager(TEMP_DIR, config_root, &test_ip_database, &test_swabber_interface);

  }

};

/**
   make up a fake GET request and check that the manager is banning
 */
TEST_F(RegexManagerTest, match)
{

  open_config();

  //first we make a mock up request
  TransactionParts mock_transaction;
  mock_transaction[TransactionMuncher::METHOD] = "GET";
  mock_transaction[TransactionMuncher::IP] = "123.456.789.123";
  mock_transaction[TransactionMuncher::URL] = "http://simple_to_ban_me/";
  mock_transaction[TransactionMuncher::HOST] = "neverhood.com";
  mock_transaction[TransactionMuncher::UA] = "neverhood browsing and co";

  FilterResponse cur_filter_result = test_regex_manager->execute(mock_transaction);

  EXPECT_EQ(cur_filter_result.response_type, FilterResponse::I_RESPOND);

}

<|endoftext|>


<commit_before>//===- TpiStream.cpp - PDB Type Info (TPI) Stream 2 Access ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"

#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/PDB/Raw/Hash.h"
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"

#include "llvm/Support/Endian.h"

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::support;
using namespace llvm::pdb;

namespace {
const uint32_t MinHashBuckets = 0x1000;
const uint32_t MaxHashBuckets = 0x40000;
}

static uint32_t HashBufferV8(uint8_t *buffer, uint32_t NumBuckets) {
  // Not yet implemented, this is probably some variation of CRC32 but we need
  // to be sure of the precise implementation otherwise we won't be able to work
  // with persisted hash values.
  return 0;
}

// This corresponds to `HDR` in PDB/dbi/tpi.h.
struct TpiStream::HeaderInfo {
  struct EmbeddedBuf {
    little32_t Off;
    ulittle32_t Length;
  };

  ulittle32_t Version;
  ulittle32_t HeaderSize;
  ulittle32_t TypeIndexBegin;
  ulittle32_t TypeIndexEnd;
  ulittle32_t TypeRecordBytes;

  // The following members correspond to `TpiHash` in PDB/dbi/tpi.h.
  ulittle16_t HashStreamIndex;
  ulittle16_t HashAuxStreamIndex;
  ulittle32_t HashKeySize;
  ulittle32_t NumHashBuckets;

  EmbeddedBuf HashValueBuffer;
  EmbeddedBuf IndexOffsetBuffer;
  EmbeddedBuf HashAdjBuffer;
};

TpiStream::TpiStream(const PDBFile &File,
                     std::unique_ptr<MappedBlockStream> Stream)
    : Pdb(File), Stream(std::move(Stream)), HashFunction(nullptr) {}

TpiStream::~TpiStream() {}

// Computes a hash for a given TPI record.
template <typename T> static uint32_t getTpiHash(T &Rec) {
  auto Opts = static_cast<uint16_t>(Rec.getOptions());

  // We don't know how to calculate a hash value for this yet.
  // Currently we just skip it.
  if (Opts & static_cast<uint16_t>(codeview::ClassOptions::ForwardReference))
    return 0;

  if (!(Opts & static_cast<uint16_t>(codeview::ClassOptions::Scoped)))
    return hashStringV1(Rec.getName());

  if (Opts & static_cast<uint16_t>(codeview::ClassOptions::HasUniqueName))
    return hashStringV1(Rec.getUniqueName());

  // This case is not implemented yet.
  return 0;
}

namespace {
class TpiHashVerifier : public CVTypeVisitor<TpiHashVerifier> {
public:
  TpiHashVerifier(FixedStreamArray<support::ulittle32_t> &HashValues,
                  uint32_t NumHashBuckets)
      : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {}

  void visitUdtSourceLine(TypeLeafKind, UdtSourceLineRecord &Rec) {
    verifySourceLine(Rec);
  }

  void visitUdtModSourceLine(TypeLeafKind, UdtModSourceLineRecord &Rec) {
    verifySourceLine(Rec);
  }

  void visitClass(TypeLeafKind, ClassRecord &Rec) { verify(Rec); }
  void visitEnum(TypeLeafKind, EnumRecord &Rec) { verify(Rec); }
  void visitInterface(TypeLeafKind, ClassRecord &Rec) { verify(Rec); }
  void visitStruct(TypeLeafKind, ClassRecord &Rec) { verify(Rec); }
  void visitUnion(TypeLeafKind, UnionRecord &Rec) { verify(Rec); }

  void visitTypeEnd(TypeLeafKind Leaf, ArrayRef<uint8_t> RecordData) {
    ++Index;
  }

private:
  template <typename T> void verify(T &Rec) {
    uint32_t Hash = getTpiHash(Rec);
    if (Hash && Hash % NumHashBuckets != HashValues[Index])
      parseError();
  }

  template <typename T> void verifySourceLine(T &Rec) {
    char Buf[4];
    support::endian::write32le(Buf, Rec.getUDT().getIndex());
    uint32_t Hash = hashStringV1(StringRef(Buf, 4));
    if (Hash % NumHashBuckets != HashValues[Index])
      parseError();
  }

  FixedStreamArray<support::ulittle32_t> HashValues;
  uint32_t NumHashBuckets;
  uint32_t Index = 0;
};
}

// Verifies that a given type record matches with a given hash value.
// Currently we only verify SRC_LINE records.
Error TpiStream::verifyHashValues() {
  TpiHashVerifier Verifier(HashValues, Header->NumHashBuckets);
  Verifier.visitTypeStream(TypeRecords);
  if (Verifier.hadError())
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Corrupt TPI hash table.");
  return Error::success();
}

Error TpiStream::reload() {
  codeview::StreamReader Reader(*Stream);

  if (Reader.bytesRemaining() < sizeof(HeaderInfo))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream does not contain a header.");

  if (Reader.readObject(Header))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream does not contain a header.");

  if (Header->Version != PdbTpiV80)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Unsupported TPI Version.");

  if (Header->HeaderSize != sizeof(HeaderInfo))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Corrupt TPI Header size.");

  if (Header->HashKeySize != sizeof(ulittle32_t))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream expected 4 byte hash key size.");

  if (Header->NumHashBuckets < MinHashBuckets ||
      Header->NumHashBuckets > MaxHashBuckets)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream Invalid number of hash buckets.");

  HashFunction = HashBufferV8;

  // The actual type records themselves come from this stream
  if (auto EC = Reader.readArray(TypeRecords, Header->TypeRecordBytes))
    return EC;

  // Hash indices, hash values, etc come from the hash stream.
  if (Header->HashStreamIndex >= Pdb.getNumStreams())
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Invalid TPI hash stream index.");

  auto HS =
      MappedBlockStream::createIndexedStream(Header->HashStreamIndex, Pdb);
  if (!HS)
    return HS.takeError();
  codeview::StreamReader HSR(**HS);

  uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
  if (NumHashValues != NumTypeRecords())
    return make_error<RawError>(
        raw_error_code::corrupt_file,
        "TPI hash count does not match with the number of type records.");
  HSR.setOffset(Header->HashValueBuffer.Off);
  if (auto EC = HSR.readArray(HashValues, NumHashValues))
    return EC;

  HSR.setOffset(Header->IndexOffsetBuffer.Off);
  uint32_t NumTypeIndexOffsets =
      Header->IndexOffsetBuffer.Length / sizeof(TypeIndexOffset);
  if (auto EC = HSR.readArray(TypeIndexOffsets, NumTypeIndexOffsets))
    return EC;

  HSR.setOffset(Header->HashAdjBuffer.Off);
  uint32_t NumHashAdjustments =
      Header->HashAdjBuffer.Length / sizeof(TypeIndexOffset);
  if (auto EC = HSR.readArray(HashAdjustments, NumHashAdjustments))
    return EC;

  HashStream = std::move(*HS);

  // TPI hash table is a parallel array for the type records.
  // Verify that the hash values match with type records.
  if (auto EC = verifyHashValues())
    return EC;

  return Error::success();
}

PdbRaw_TpiVer TpiStream::getTpiVersion() const {
  uint32_t Value = Header->Version;
  return static_cast<PdbRaw_TpiVer>(Value);
}

uint32_t TpiStream::TypeIndexBegin() const { return Header->TypeIndexBegin; }

uint32_t TpiStream::TypeIndexEnd() const { return Header->TypeIndexEnd; }

uint32_t TpiStream::NumTypeRecords() const {
  return TypeIndexEnd() - TypeIndexBegin();
}

uint16_t TpiStream::getTypeHashStreamIndex() const {
  return Header->HashStreamIndex;
}

uint16_t TpiStream::getTypeHashStreamAuxIndex() const {
  return Header->HashAuxStreamIndex;
}

uint32_t TpiStream::NumHashBuckets() const { return Header->NumHashBuckets; }
uint32_t TpiStream::getHashKeySize() const { return Header->HashKeySize; }

codeview::FixedStreamArray<support::ulittle32_t>
TpiStream::getHashValues() const {
  return HashValues;
}

codeview::FixedStreamArray<TypeIndexOffset>
TpiStream::getTypeIndexOffsets() const {
  return TypeIndexOffsets;
}

codeview::FixedStreamArray<TypeIndexOffset>
TpiStream::getHashAdjustments() const {
  return HashAdjustments;
}

iterator_range<codeview::CVTypeArray::Iterator>
TpiStream::types(bool *HadError) const {
  return llvm::make_range(TypeRecords.begin(HadError), TypeRecords.end());
}
<commit_msg>Remove redundant namespace specifiers.<commit_after>//===- TpiStream.cpp - PDB Type Info (TPI) Stream 2 Access ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"

#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/PDB/Raw/Hash.h"
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"

#include "llvm/Support/Endian.h"

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::support;
using namespace llvm::pdb;

namespace {
const uint32_t MinHashBuckets = 0x1000;
const uint32_t MaxHashBuckets = 0x40000;
}

static uint32_t HashBufferV8(uint8_t *buffer, uint32_t NumBuckets) {
  // Not yet implemented, this is probably some variation of CRC32 but we need
  // to be sure of the precise implementation otherwise we won't be able to work
  // with persisted hash values.
  return 0;
}

// This corresponds to `HDR` in PDB/dbi/tpi.h.
struct TpiStream::HeaderInfo {
  struct EmbeddedBuf {
    little32_t Off;
    ulittle32_t Length;
  };

  ulittle32_t Version;
  ulittle32_t HeaderSize;
  ulittle32_t TypeIndexBegin;
  ulittle32_t TypeIndexEnd;
  ulittle32_t TypeRecordBytes;

  // The following members correspond to `TpiHash` in PDB/dbi/tpi.h.
  ulittle16_t HashStreamIndex;
  ulittle16_t HashAuxStreamIndex;
  ulittle32_t HashKeySize;
  ulittle32_t NumHashBuckets;

  EmbeddedBuf HashValueBuffer;
  EmbeddedBuf IndexOffsetBuffer;
  EmbeddedBuf HashAdjBuffer;
};

TpiStream::TpiStream(const PDBFile &File,
                     std::unique_ptr<MappedBlockStream> Stream)
    : Pdb(File), Stream(std::move(Stream)), HashFunction(nullptr) {}

TpiStream::~TpiStream() {}

// Computes a hash for a given TPI record.
template <typename T> static uint32_t getTpiHash(T &Rec) {
  auto Opts = static_cast<uint16_t>(Rec.getOptions());

  // We don't know how to calculate a hash value for this yet.
  // Currently we just skip it.
  if (Opts & static_cast<uint16_t>(ClassOptions::ForwardReference))
    return 0;

  if (!(Opts & static_cast<uint16_t>(ClassOptions::Scoped)))
    return hashStringV1(Rec.getName());

  if (Opts & static_cast<uint16_t>(ClassOptions::HasUniqueName))
    return hashStringV1(Rec.getUniqueName());

  // This case is not implemented yet.
  return 0;
}

namespace {
class TpiHashVerifier : public CVTypeVisitor<TpiHashVerifier> {
public:
  TpiHashVerifier(FixedStreamArray<support::ulittle32_t> &HashValues,
                  uint32_t NumHashBuckets)
      : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {}

  void visitUdtSourceLine(TypeLeafKind, UdtSourceLineRecord &Rec) {
    verifySourceLine(Rec);
  }

  void visitUdtModSourceLine(TypeLeafKind, UdtModSourceLineRecord &Rec) {
    verifySourceLine(Rec);
  }

  void visitClass(TypeLeafKind, ClassRecord &Rec) { verify(Rec); }
  void visitEnum(TypeLeafKind, EnumRecord &Rec) { verify(Rec); }
  void visitInterface(TypeLeafKind, ClassRecord &Rec) { verify(Rec); }
  void visitStruct(TypeLeafKind, ClassRecord &Rec) { verify(Rec); }
  void visitUnion(TypeLeafKind, UnionRecord &Rec) { verify(Rec); }

  void visitTypeEnd(TypeLeafKind Leaf, ArrayRef<uint8_t> RecordData) {
    ++Index;
  }

private:
  template <typename T> void verify(T &Rec) {
    uint32_t Hash = getTpiHash(Rec);
    if (Hash && Hash % NumHashBuckets != HashValues[Index])
      parseError();
  }

  template <typename T> void verifySourceLine(T &Rec) {
    char Buf[4];
    support::endian::write32le(Buf, Rec.getUDT().getIndex());
    uint32_t Hash = hashStringV1(StringRef(Buf, 4));
    if (Hash % NumHashBuckets != HashValues[Index])
      parseError();
  }

  FixedStreamArray<support::ulittle32_t> HashValues;
  uint32_t NumHashBuckets;
  uint32_t Index = 0;
};
}

// Verifies that a given type record matches with a given hash value.
// Currently we only verify SRC_LINE records.
Error TpiStream::verifyHashValues() {
  TpiHashVerifier Verifier(HashValues, Header->NumHashBuckets);
  Verifier.visitTypeStream(TypeRecords);
  if (Verifier.hadError())
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Corrupt TPI hash table.");
  return Error::success();
}

Error TpiStream::reload() {
  StreamReader Reader(*Stream);

  if (Reader.bytesRemaining() < sizeof(HeaderInfo))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream does not contain a header.");

  if (Reader.readObject(Header))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream does not contain a header.");

  if (Header->Version != PdbTpiV80)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Unsupported TPI Version.");

  if (Header->HeaderSize != sizeof(HeaderInfo))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Corrupt TPI Header size.");

  if (Header->HashKeySize != sizeof(ulittle32_t))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream expected 4 byte hash key size.");

  if (Header->NumHashBuckets < MinHashBuckets ||
      Header->NumHashBuckets > MaxHashBuckets)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream Invalid number of hash buckets.");

  HashFunction = HashBufferV8;

  // The actual type records themselves come from this stream
  if (auto EC = Reader.readArray(TypeRecords, Header->TypeRecordBytes))
    return EC;

  // Hash indices, hash values, etc come from the hash stream.
  if (Header->HashStreamIndex >= Pdb.getNumStreams())
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Invalid TPI hash stream index.");

  auto HS =
      MappedBlockStream::createIndexedStream(Header->HashStreamIndex, Pdb);
  if (!HS)
    return HS.takeError();
  StreamReader HSR(**HS);

  uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
  if (NumHashValues != NumTypeRecords())
    return make_error<RawError>(
        raw_error_code::corrupt_file,
        "TPI hash count does not match with the number of type records.");
  HSR.setOffset(Header->HashValueBuffer.Off);
  if (auto EC = HSR.readArray(HashValues, NumHashValues))
    return EC;

  HSR.setOffset(Header->IndexOffsetBuffer.Off);
  uint32_t NumTypeIndexOffsets =
      Header->IndexOffsetBuffer.Length / sizeof(TypeIndexOffset);
  if (auto EC = HSR.readArray(TypeIndexOffsets, NumTypeIndexOffsets))
    return EC;

  HSR.setOffset(Header->HashAdjBuffer.Off);
  uint32_t NumHashAdjustments =
      Header->HashAdjBuffer.Length / sizeof(TypeIndexOffset);
  if (auto EC = HSR.readArray(HashAdjustments, NumHashAdjustments))
    return EC;

  HashStream = std::move(*HS);

  // TPI hash table is a parallel array for the type records.
  // Verify that the hash values match with type records.
  if (auto EC = verifyHashValues())
    return EC;

  return Error::success();
}

PdbRaw_TpiVer TpiStream::getTpiVersion() const {
  uint32_t Value = Header->Version;
  return static_cast<PdbRaw_TpiVer>(Value);
}

uint32_t TpiStream::TypeIndexBegin() const { return Header->TypeIndexBegin; }

uint32_t TpiStream::TypeIndexEnd() const { return Header->TypeIndexEnd; }

uint32_t TpiStream::NumTypeRecords() const {
  return TypeIndexEnd() - TypeIndexBegin();
}

uint16_t TpiStream::getTypeHashStreamIndex() const {
  return Header->HashStreamIndex;
}

uint16_t TpiStream::getTypeHashStreamAuxIndex() const {
  return Header->HashAuxStreamIndex;
}

uint32_t TpiStream::NumHashBuckets() const { return Header->NumHashBuckets; }
uint32_t TpiStream::getHashKeySize() const { return Header->HashKeySize; }

FixedStreamArray<support::ulittle32_t>
TpiStream::getHashValues() const {
  return HashValues;
}

FixedStreamArray<TypeIndexOffset>
TpiStream::getTypeIndexOffsets() const {
  return TypeIndexOffsets;
}

FixedStreamArray<TypeIndexOffset>
TpiStream::getHashAdjustments() const {
  return HashAdjustments;
}

iterator_range<CVTypeArray::Iterator>
TpiStream::types(bool *HadError) const {
  return llvm::make_range(TypeRecords.begin(HadError), TypeRecords.end());
}
<|endoftext|>


<commit_before>//===-- CompilerInvocation.cpp - CompilerInvocation methods ---------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Frontend/Frontend.h"

#include "swift/Driver/Options.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/Path.h"

using namespace swift;

swift::CompilerInvocation::CompilerInvocation() {
  TargetTriple = llvm::sys::getDefaultTargetTriple();
}

void CompilerInvocation::setMainExecutablePath(StringRef Path) {
  llvm::SmallString<128> LibPath(Path);
  llvm::sys::path::remove_filename(LibPath); // Remove /swift
  llvm::sys::path::remove_filename(LibPath); // Remove /bin
  llvm::sys::path::append(LibPath, "lib", "swift");
  setRuntimeIncludePath(LibPath.str());
}

bool CompilerInvocation::parseArgs(ArrayRef<const char *> Args,
                                   DiagnosticEngine &Diags) {
  using namespace driver;
  using namespace driver::options;

  if (Args.empty())
    return false;

  // Parse command line options using FrontendOptions.td
  std::unique_ptr<llvm::opt::InputArgList> ParsedArgs;
  std::unique_ptr<llvm::opt::OptTable> Table = createDriverOptTable();
  unsigned MissingIndex;
  unsigned MissingCount;
  ParsedArgs.reset(
      Table->ParseArgs(Args.begin(), Args.end(), MissingIndex, MissingCount,
                       driver::options::FrontendOption));
  if (MissingCount) {
    Diags.diagnose(SourceLoc(), diag::error_missing_arg_value,
                   ParsedArgs->getArgString(MissingIndex), MissingCount);
    return true;
  }

  bool HasUnknownArgument = false;

  for (auto InputArg : *ParsedArgs) {
    switch (InputArg->getOption().getID()) {
    case OPT_target:
      setTargetTriple(InputArg->getValue());
      break;

    case OPT_I:
      ImportSearchPaths.push_back(InputArg->getValue());
      break;

    case OPT_F:
      FrameworkSearchPaths.push_back(InputArg->getValue());
      break;

    case OPT_module_name:
      setModuleName(InputArg->getValue());
      break;

    case OPT_sdk:
      setSDKPath(InputArg->getValue());
      break;

    case OPT_module_cache_path:
      setClangModuleCachePath(InputArg->getValue());
      break;

    case OPT_parse_as_library:
      setInputKind(SourceFileKind::Library);
      break;

    case OPT_parse_stdlib:
      setParseStdlib();
      break;

    case OPT_Xcc:
      ExtraClangArgs.push_back(InputArg->getValue());
      break;

    case OPT_debug_constraints:
      LangOpts.DebugConstraintSolver = true;
      break;

    case OPT_l:
      addLinkLibrary(InputArg->getValue(), LibraryKind::Library);
      break;

    case OPT_framework:
      addLinkLibrary(InputArg->getValue(), LibraryKind::Framework);
      break;

    case OPT_serialize_diagnostics:
      setSerializedDiagnosticsPath(InputArg->getValue());
      break;

    case OPT_module_source_list:
      setModuleSourceListPath(InputArg->getValue());
      break;

    case OPT_o:
      setOutputFilename(InputArg->getValue());
      break;

    case OPT_INPUT:
      addInputFilename(InputArg->getValue());
      break;

    default:
      HasUnknownArgument = true;
      Diags.diagnose(SourceLoc(), diag::error_unknown_arg,
                     InputArg->getAsString(*ParsedArgs));
      break;
    }
  }

  return HasUnknownArgument;
}
<commit_msg>[frontend] Switch from a default case to OPT_UNKNOWN for catching unknown arguments.<commit_after>//===-- CompilerInvocation.cpp - CompilerInvocation methods ---------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Frontend/Frontend.h"

#include "swift/Driver/Options.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/Path.h"

using namespace swift;

swift::CompilerInvocation::CompilerInvocation() {
  TargetTriple = llvm::sys::getDefaultTargetTriple();
}

void CompilerInvocation::setMainExecutablePath(StringRef Path) {
  llvm::SmallString<128> LibPath(Path);
  llvm::sys::path::remove_filename(LibPath); // Remove /swift
  llvm::sys::path::remove_filename(LibPath); // Remove /bin
  llvm::sys::path::append(LibPath, "lib", "swift");
  setRuntimeIncludePath(LibPath.str());
}

bool CompilerInvocation::parseArgs(ArrayRef<const char *> Args,
                                   DiagnosticEngine &Diags) {
  using namespace driver;
  using namespace driver::options;

  if (Args.empty())
    return false;

  // Parse command line options using FrontendOptions.td
  std::unique_ptr<llvm::opt::InputArgList> ParsedArgs;
  std::unique_ptr<llvm::opt::OptTable> Table = createDriverOptTable();
  unsigned MissingIndex;
  unsigned MissingCount;
  ParsedArgs.reset(
      Table->ParseArgs(Args.begin(), Args.end(), MissingIndex, MissingCount,
                       driver::options::FrontendOption));
  if (MissingCount) {
    Diags.diagnose(SourceLoc(), diag::error_missing_arg_value,
                   ParsedArgs->getArgString(MissingIndex), MissingCount);
    return true;
  }

  bool HasUnknownArgument = false;

  for (auto InputArg : *ParsedArgs) {
    switch (InputArg->getOption().getID()) {
    case OPT_target:
      setTargetTriple(InputArg->getValue());
      break;

    case OPT_I:
      ImportSearchPaths.push_back(InputArg->getValue());
      break;

    case OPT_F:
      FrameworkSearchPaths.push_back(InputArg->getValue());
      break;

    case OPT_module_name:
      setModuleName(InputArg->getValue());
      break;

    case OPT_sdk:
      setSDKPath(InputArg->getValue());
      break;

    case OPT_module_cache_path:
      setClangModuleCachePath(InputArg->getValue());
      break;

    case OPT_parse_as_library:
      setInputKind(SourceFileKind::Library);
      break;

    case OPT_parse_stdlib:
      setParseStdlib();
      break;

    case OPT_Xcc:
      ExtraClangArgs.push_back(InputArg->getValue());
      break;

    case OPT_debug_constraints:
      LangOpts.DebugConstraintSolver = true;
      break;

    case OPT_l:
      addLinkLibrary(InputArg->getValue(), LibraryKind::Library);
      break;

    case OPT_framework:
      addLinkLibrary(InputArg->getValue(), LibraryKind::Framework);
      break;

    case OPT_serialize_diagnostics:
      setSerializedDiagnosticsPath(InputArg->getValue());
      break;

    case OPT_module_source_list:
      setModuleSourceListPath(InputArg->getValue());
      break;

    case OPT_o:
      setOutputFilename(InputArg->getValue());
      break;

    case OPT_INPUT:
      addInputFilename(InputArg->getValue());
      break;

    case OPT_UNKNOWN:
      HasUnknownArgument = true;
      Diags.diagnose(SourceLoc(), diag::error_unknown_arg,
                     InputArg->getAsString(*ParsedArgs));
      break;
    }
  }

  return HasUnknownArgument;
}
<|endoftext|>


<commit_before>#include "swift/IDE/ModuleInterfacePrinting.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTPrinter.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Module.h"
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/ClangImporter/ClangModule.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/Module.h"
#include "clang/Lex/MacroInfo.h"
#include <utility>

using namespace swift;

void swift::ide::printModuleInterface(Module *M, ASTPrinter &Printer,
                                      const PrintOptions &Options) {
  StringRef FullModuleName[] = { M->Name.str() };
  printSubmoduleInterface(M, FullModuleName, Printer, Options);
}

void swift::ide::printSubmoduleInterface(Module *M,
                                         ArrayRef<StringRef> FullModuleName,
                                         ASTPrinter &Printer,
                                         const PrintOptions &Options) {
  auto AdjustedOptions = Options;

  // Don't print empty curly braces while printing the module interface.
  AdjustedOptions.FunctionDefinitions = false;

  AdjustedOptions.PrintGetSetOnRWProperties = false;

  // Print var declarations separately, one variable per decl.
  AdjustedOptions.ExplodePatternBindingDecls = true;
  AdjustedOptions.VarInitializers = false;

  SmallVector<Decl *, 1> Decls;
  M->getDisplayDecls(Decls);

  auto &SwiftContext = M->Ctx;
  auto &Importer =
      static_cast<ClangImporter &>(*SwiftContext.getClangModuleLoader());

  SmallVector<ImportDecl *, 1> ImportDecls;
  SmallVector<Decl *, 1> SwiftDecls;
  llvm::DenseMap<const clang::Module *,
                 SmallVector<std::pair<Decl *, clang::SourceLocation>, 1> >
  ClangDecls;

  // Drop top-level module name.
  FullModuleName = FullModuleName.slice(1);

  bool WholeModule = FullModuleName.empty();
  if (!WholeModule) {
    // Find the top-level Clang module.
    ClangModuleUnit *CMU = nullptr;
    for (auto *FU : M->getFiles()) {
      if ((CMU = dyn_cast<ClangModuleUnit>(FU)))
        break;
    }
    const clang::Module *TopLevel = CMU->getClangModule();
    for (StringRef Name : FullModuleName) {
      TopLevel = TopLevel->findSubmodule(Name);
      if (!TopLevel)
        return;
    }

    // Find all submodules to print.
    SmallVector<const clang::Module *, 8> Worklist;
    Worklist.push_back(TopLevel);
    while (!Worklist.empty()) {
      const clang::Module *CM = Worklist.pop_back_val();
      if (!TopLevel->isModuleVisible(CM))
        return;
      ClangDecls.insert({ CM, {} });
      Worklist.append(CM->submodule_begin(), CM->submodule_end());
    }
  }

  // Separate the declarations that we are going to print into different
  // buckets.
  for (Decl *D : Decls) {
    if (auto ID = dyn_cast<ImportDecl>(D)) {
      ImportDecls.push_back(ID);
      continue;
    }
    if (auto CN = D->getClangNode()) {
      clang::SourceLocation Loc;
      if (auto *CD = CN.getAsDecl()) {
        Loc = CD->getLocation();
      } else {
        Loc = CN.getAsMacro()->getDefinitionLoc();
      }
      auto *OwningModule = Importer.getClangOwningModule(CN);
      if (WholeModule) {
        ClangDecls[OwningModule].push_back({ D, Loc });
      } else {
        auto I = ClangDecls.find(OwningModule);
        if (I != ClangDecls.end())
          I->second.push_back({ D, Loc });
      }
      continue;
    }
    SwiftDecls.push_back(D);
  }

  auto &ClangSourceManager = Importer.getClangASTContext().getSourceManager();

  // Sort imported declarations in source order *within a submodule*.
  for (auto &P : ClangDecls) {
    std::sort(P.second.begin(), P.second.end(),
              [&](std::pair<Decl *, clang::SourceLocation> LHS,
                  std::pair<Decl *, clang::SourceLocation> RHS)
                  -> bool {
      return ClangSourceManager.isBeforeInTranslationUnit(LHS.second,
                                                          RHS.second);
    });
  }

  // Sort Swift declarations so that we print them in a consistent order.
  std::sort(ImportDecls.begin(), ImportDecls.end(),
            [](ImportDecl *LHS, ImportDecl *RHS) -> bool {
    auto LHSPath = LHS->getFullAccessPath();
    auto RHSPath = RHS->getFullAccessPath();
    for (unsigned i = 0, e = std::min(LHSPath.size(), RHSPath.size()); i != e;
         i++) {
      if (int Ret = LHSPath[i].first.str().compare(RHSPath[i].first.str()))
        return Ret < 0;
    }
    return false;
  });

  std::sort(SwiftDecls.begin(), SwiftDecls.end(),
            [](Decl *LHS, Decl *RHS) -> bool {
    auto *LHSValue = dyn_cast<ValueDecl>(LHS);
    auto *RHSValue = dyn_cast<ValueDecl>(RHS);
    if (LHSValue && RHSValue) {
      StringRef LHSName = LHSValue->getName().str();
      StringRef RHSName = RHSValue->getName().str();
      if (int Ret = LHSName.compare(RHSName))
        return Ret < 0;
      // FIXME: this is not sufficient to establish a total order for overloaded
      // decls.
      return LHS->getKind() < RHS->getKind();
    }

    return LHS->getKind() < RHS->getKind();
  });

  auto PrintDecl = [&](Decl *D) {
    if (isa<ExtensionDecl>(D))
      return;

    D->print(Printer, AdjustedOptions);
    Printer << "\n";
    if (auto NTD = dyn_cast<NominalTypeDecl>(D)) {
      for (auto Ext : NTD->getExtensions()) {
        Ext->print(Printer, AdjustedOptions);
        Printer << "\n";
      }
    }
  };

  for (auto *D : ImportDecls)
    PrintDecl(D);

  {
    using ModuleAndName = std::pair<const clang::Module *, std::string>;
    SmallVector<ModuleAndName, 8> ClangModules;
    for (auto P : ClangDecls) {
      ClangModules.push_back({ P.first, P.first->getFullModuleName() });
    }

    // Sort modules by name.
    std::sort(ClangModules.begin(), ClangModules.end(),
              [](const ModuleAndName &LHS, const ModuleAndName &RHS)
                  -> bool {
      return LHS.second < RHS.second;
    });

    for (auto CM : ClangModules) {
      for (auto DeclAndLoc : ClangDecls[CM.first])
        PrintDecl(DeclAndLoc.first);
    }
  }

  for (auto *D : SwiftDecls)
    PrintDecl(D);
}

<commit_msg>Simplify code<commit_after>#include "swift/IDE/ModuleInterfacePrinting.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTPrinter.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Module.h"
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/ClangImporter/ClangModule.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/Module.h"
#include "clang/Lex/MacroInfo.h"
#include <utility>

using namespace swift;

void swift::ide::printModuleInterface(Module *M, ASTPrinter &Printer,
                                      const PrintOptions &Options) {
  printSubmoduleInterface(M, M->Name.str(), Printer, Options);
}

void swift::ide::printSubmoduleInterface(Module *M,
                                         ArrayRef<StringRef> FullModuleName,
                                         ASTPrinter &Printer,
                                         const PrintOptions &Options) {
  auto AdjustedOptions = Options;

  // Don't print empty curly braces while printing the module interface.
  AdjustedOptions.FunctionDefinitions = false;

  AdjustedOptions.PrintGetSetOnRWProperties = false;

  // Print var declarations separately, one variable per decl.
  AdjustedOptions.ExplodePatternBindingDecls = true;
  AdjustedOptions.VarInitializers = false;

  SmallVector<Decl *, 1> Decls;
  M->getDisplayDecls(Decls);

  auto &SwiftContext = M->Ctx;
  auto &Importer =
      static_cast<ClangImporter &>(*SwiftContext.getClangModuleLoader());

  SmallVector<ImportDecl *, 1> ImportDecls;
  SmallVector<Decl *, 1> SwiftDecls;
  llvm::DenseMap<const clang::Module *,
                 SmallVector<std::pair<Decl *, clang::SourceLocation>, 1> >
  ClangDecls;

  // Drop top-level module name.
  FullModuleName = FullModuleName.slice(1);

  bool WholeModule = FullModuleName.empty();
  if (!WholeModule) {
    // Find the top-level Clang module.
    ClangModuleUnit *CMU = nullptr;
    for (auto *FU : M->getFiles()) {
      if ((CMU = dyn_cast<ClangModuleUnit>(FU)))
        break;
    }
    const clang::Module *TopLevel = CMU->getClangModule();
    for (StringRef Name : FullModuleName) {
      TopLevel = TopLevel->findSubmodule(Name);
      if (!TopLevel)
        return;
    }

    // Find all submodules to print.
    SmallVector<const clang::Module *, 8> Worklist;
    Worklist.push_back(TopLevel);
    while (!Worklist.empty()) {
      const clang::Module *CM = Worklist.pop_back_val();
      if (!TopLevel->isModuleVisible(CM))
        return;
      ClangDecls.insert({ CM, {} });
      Worklist.append(CM->submodule_begin(), CM->submodule_end());
    }
  }

  // Separate the declarations that we are going to print into different
  // buckets.
  for (Decl *D : Decls) {
    if (auto ID = dyn_cast<ImportDecl>(D)) {
      ImportDecls.push_back(ID);
      continue;
    }
    if (auto CN = D->getClangNode()) {
      clang::SourceLocation Loc;
      if (auto *CD = CN.getAsDecl()) {
        Loc = CD->getLocation();
      } else {
        Loc = CN.getAsMacro()->getDefinitionLoc();
      }
      auto *OwningModule = Importer.getClangOwningModule(CN);
      if (WholeModule) {
        ClangDecls[OwningModule].push_back({ D, Loc });
      } else {
        auto I = ClangDecls.find(OwningModule);
        if (I != ClangDecls.end())
          I->second.push_back({ D, Loc });
      }
      continue;
    }
    SwiftDecls.push_back(D);
  }

  auto &ClangSourceManager = Importer.getClangASTContext().getSourceManager();

  // Sort imported declarations in source order *within a submodule*.
  for (auto &P : ClangDecls) {
    std::sort(P.second.begin(), P.second.end(),
              [&](std::pair<Decl *, clang::SourceLocation> LHS,
                  std::pair<Decl *, clang::SourceLocation> RHS)
                  -> bool {
      return ClangSourceManager.isBeforeInTranslationUnit(LHS.second,
                                                          RHS.second);
    });
  }

  // Sort Swift declarations so that we print them in a consistent order.
  std::sort(ImportDecls.begin(), ImportDecls.end(),
            [](ImportDecl *LHS, ImportDecl *RHS) -> bool {
    auto LHSPath = LHS->getFullAccessPath();
    auto RHSPath = RHS->getFullAccessPath();
    for (unsigned i = 0, e = std::min(LHSPath.size(), RHSPath.size()); i != e;
         i++) {
      if (int Ret = LHSPath[i].first.str().compare(RHSPath[i].first.str()))
        return Ret < 0;
    }
    return false;
  });

  std::sort(SwiftDecls.begin(), SwiftDecls.end(),
            [](Decl *LHS, Decl *RHS) -> bool {
    auto *LHSValue = dyn_cast<ValueDecl>(LHS);
    auto *RHSValue = dyn_cast<ValueDecl>(RHS);
    if (LHSValue && RHSValue) {
      StringRef LHSName = LHSValue->getName().str();
      StringRef RHSName = RHSValue->getName().str();
      if (int Ret = LHSName.compare(RHSName))
        return Ret < 0;
      // FIXME: this is not sufficient to establish a total order for overloaded
      // decls.
      return LHS->getKind() < RHS->getKind();
    }

    return LHS->getKind() < RHS->getKind();
  });

  auto PrintDecl = [&](Decl *D) {
    if (isa<ExtensionDecl>(D))
      return;

    D->print(Printer, AdjustedOptions);
    Printer << "\n";
    if (auto NTD = dyn_cast<NominalTypeDecl>(D)) {
      for (auto Ext : NTD->getExtensions()) {
        Ext->print(Printer, AdjustedOptions);
        Printer << "\n";
      }
    }
  };

  for (auto *D : ImportDecls)
    PrintDecl(D);

  {
    using ModuleAndName = std::pair<const clang::Module *, std::string>;
    SmallVector<ModuleAndName, 8> ClangModules;
    for (auto P : ClangDecls) {
      ClangModules.push_back({ P.first, P.first->getFullModuleName() });
    }

    // Sort modules by name.
    std::sort(ClangModules.begin(), ClangModules.end(),
              [](const ModuleAndName &LHS, const ModuleAndName &RHS)
                  -> bool {
      return LHS.second < RHS.second;
    });

    for (auto CM : ClangModules) {
      for (auto DeclAndLoc : ClangDecls[CM.first])
        PrintDecl(DeclAndLoc.first);
    }
  }

  for (auto *D : SwiftDecls)
    PrintDecl(D);
}

<|endoftext|>


<commit_before>//
// coverage tests for error_reporting
//
// g++-mp-7 -O2 -Wall -std=c++11 -I/opt/local/include error_reporting_test.cpp -o error_reporting.test -L/opt/local/lib -loptim -framework Accelerate
// g++-mp-7 -O2 -Wall -std=c++11 -I./../../include error_reporting.cpp -o error_reporting.test -L./../.. -loptim -framework Accelerate
//

#include "optim.hpp"

double optim_simple_fn_1(const arma::vec& vals_inp, arma::vec* grad_out, void* opt_data)
{
    return 1.0;
}

arma::vec optim_simple_fn_2(const arma::vec& vals_inp, void* opt_data)
{
    int n = vals_inp.n_elem;
    return arma::zeros(n,1);
}

int main()
{

    arma::vec out_vals = arma::ones(2,1);
    arma::vec x_p = arma::ones(2,1);

    bool success = false;
    double value_out = 1.0;

    double err_1 = 0.5;
    double err_2 = 1.5;
    double err_tol = 1.0;

    int iter_1 = 1;
    int iter_2 = 3;
    int iter_max = 2;

    optim::opt_settings settings;

    //
    // error_reporting_1

    int conv_failure_switch = 0;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,&value_out,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,&value_out,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 1;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,&value_out,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,&value_out,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 2;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,&value_out,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,&value_out,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 3; // error
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,&value_out,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);

    //
    // error_reporting_2

    conv_failure_switch = 0;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,&value_out,conv_failure_switch,settings);

    conv_failure_switch = 2;
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,&value_out,conv_failure_switch,settings);

    conv_failure_switch = 3; // error
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,&value_out,conv_failure_switch,settings);

    //
    // error_reporting_3

    conv_failure_switch = 0;
    arma::vec val_vec_out;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,&val_vec_out,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,&val_vec_out,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 1;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,&val_vec_out,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,&val_vec_out,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 2;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,&val_vec_out,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,&val_vec_out,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 3; // error
    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,&val_vec_out,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);

    // done

    return 0;
}
<commit_msg>update test<commit_after>//
// coverage tests for error_reporting
//
// g++-mp-7 -O2 -Wall -std=c++11 -I/opt/local/include error_reporting_test.cpp -o error_reporting.test -L/opt/local/lib -loptim -framework Accelerate
// g++-mp-7 -O2 -Wall -std=c++11 -I./../../include error_reporting.cpp -o error_reporting.test -L./../.. -loptim -framework Accelerate
//

#include "optim.hpp"

double optim_simple_fn_1(const arma::vec& vals_inp, arma::vec* grad_out, void* opt_data)
{
    return 1.0;
}

arma::vec optim_simple_fn_2(const arma::vec& vals_inp, void* opt_data)
{
    int n = vals_inp.n_elem;
    return arma::zeros(n,1);
}

int main()
{

    arma::vec out_vals = arma::ones(2,1);
    arma::vec x_p = arma::ones(2,1);

    bool success = false;

    double err_1 = 0.5;
    double err_2 = 1.5;
    double err_tol = 1.0;

    int iter_1 = 1;
    int iter_2 = 3;
    int iter_max = 2;

    optim::opt_settings settings;

    //
    // error_reporting_1

    int conv_failure_switch = 0;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 1;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 2;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 3; // error
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);

    //
    // error_reporting_2

    conv_failure_switch = 0;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,conv_failure_switch,settings);

    conv_failure_switch = 2;
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,conv_failure_switch,settings);

    conv_failure_switch = 3; // error
    optim::error_reporting(out_vals,x_p,optim_simple_fn_1,success,conv_failure_switch,settings);

    //
    // error_reporting_3

    conv_failure_switch = 0;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 1;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 2;

    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);
    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,err_2,err_tol,iter_2,iter_max,conv_failure_switch,settings);

    conv_failure_switch = 3; // error
    optim::error_reporting(out_vals,x_p,optim_simple_fn_2,success,err_1,err_tol,iter_1,iter_max,conv_failure_switch,settings);

    // done

    return 0;
}
<|endoftext|>


<commit_before>//=-- InstrProfWriter.cpp - Instrumented profiling writer -------------------=//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing profiling data for clang's
// instrumentation based PGO and coverage.
//
//===----------------------------------------------------------------------===//

#include "llvm/ProfileData/InstrProfWriter.h"
#include "llvm/Support/Endian.h"

using namespace llvm;

error_code InstrProfWriter::addFunctionCounts(StringRef FunctionName,
                                              uint64_t FunctionHash,
                                              ArrayRef<uint64_t> Counters) {
  auto Where = FunctionData.find(FunctionName);
  if (Where == FunctionData.end()) {
    // If this is the first time we've seen this function, just add it.
    FunctionData[FunctionName] = {FunctionHash, Counters};
    return instrprof_error::success;;
  }

  auto &Data = Where->getValue();
  // We can only add to existing functions if they match, so we check the hash
  // and number of counters.
  if (Data.Hash != FunctionHash)
    return instrprof_error::hash_mismatch;
  if (Data.Counts.size() != Counters.size())
    return instrprof_error::count_mismatch;
  // These match, add up the counters.
  for (size_t I = 0, E = Counters.size(); I < E; ++I) {
    if (Data.Counts[I] + Counters[I] < Data.Counts[I])
      return instrprof_error::counter_overflow;
    Data.Counts[I] += Counters[I];
  }
  return instrprof_error::success;
}

void InstrProfWriter::write(raw_ostream &OS) {
  // Write out the counts for each function.
  for (const auto &I : FunctionData) {
    StringRef Name = I.getKey();
    uint64_t Hash = I.getValue().Hash;
    const std::vector<uint64_t> &Counts = I.getValue().Counts;

    OS << Name << "\n" << Hash << "\n" << Counts.size() << "\n";
    for (uint64_t Count : Counts)
      OS << Count << "\n";
    OS << "\n";
  }
}
<commit_msg>ProfileData: Avoid brace initialization, windows doesn't like it<commit_after>//=-- InstrProfWriter.cpp - Instrumented profiling writer -------------------=//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing profiling data for clang's
// instrumentation based PGO and coverage.
//
//===----------------------------------------------------------------------===//

#include "llvm/ProfileData/InstrProfWriter.h"
#include "llvm/Support/Endian.h"

using namespace llvm;

error_code InstrProfWriter::addFunctionCounts(StringRef FunctionName,
                                              uint64_t FunctionHash,
                                              ArrayRef<uint64_t> Counters) {
  auto Where = FunctionData.find(FunctionName);
  if (Where == FunctionData.end()) {
    // If this is the first time we've seen this function, just add it.
    auto &Data = FunctionData[FunctionName];
    Data.Hash = FunctionHash;
    Data.Counts = Counters;
    return instrprof_error::success;;
  }

  auto &Data = Where->getValue();
  // We can only add to existing functions if they match, so we check the hash
  // and number of counters.
  if (Data.Hash != FunctionHash)
    return instrprof_error::hash_mismatch;
  if (Data.Counts.size() != Counters.size())
    return instrprof_error::count_mismatch;
  // These match, add up the counters.
  for (size_t I = 0, E = Counters.size(); I < E; ++I) {
    if (Data.Counts[I] + Counters[I] < Data.Counts[I])
      return instrprof_error::counter_overflow;
    Data.Counts[I] += Counters[I];
  }
  return instrprof_error::success;
}

void InstrProfWriter::write(raw_ostream &OS) {
  // Write out the counts for each function.
  for (const auto &I : FunctionData) {
    StringRef Name = I.getKey();
    uint64_t Hash = I.getValue().Hash;
    const std::vector<uint64_t> &Counts = I.getValue().Counts;

    OS << Name << "\n" << Hash << "\n" << Counts.size() << "\n";
    for (uint64_t Count : Counts)
      OS << Count << "\n";
    OS << "\n";
  }
}
<|endoftext|>


<commit_before><commit_msg>Remove unnecessary incl file.<commit_after><|endoftext|>


<commit_before>//===-- ARMTargetAsmInfo.cpp - ARM asm properties ---------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by James M. Laskey and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations of the ARMTargetAsmInfo properties.
//
//===----------------------------------------------------------------------===//

#include "ARMTargetAsmInfo.h"
#include "ARMTargetMachine.h"
using namespace llvm;

ARMTargetAsmInfo::ARMTargetAsmInfo(const ARMTargetMachine &TM) {
  const ARMSubtarget *Subtarget = &TM.getSubtarget<ARMSubtarget>();
  if (Subtarget->isTargetDarwin()) {
    GlobalPrefix = "_";
    ZeroDirective = "\t.space\t";
    PrivateGlobalPrefix = "L";
    BSSSection = 0;                       // no BSS section.
    ZeroFillDirective = "\t.zerofill\t";  // Uses .zerofill
    SetDirective = "\t.set";
    WeakRefDirective = "\t.weak_reference\t";
    JumpTableDataSection = ".const";
    CStringSection = "\t.cstring";
    LCOMMDirective = "\t.lcomm\t";
    COMMDirectiveTakesAlignment = false;
    HasDotTypeDotSizeDirective = false;
    StaticCtorsSection = ".mod_init_func";
    StaticDtorsSection = ".mod_term_func";
    InlineAsmStart = "@ InlineAsm Start";
    InlineAsmEnd = "@ InlineAsm End";

    // In non-PIC modes, emit a special label before jump tables so that the
    // linker can perform more accurate dead code stripping.
    if (TM.getRelocationModel() != Reloc::PIC_) {
      // Emit a local label that is preserved until the linker runs.
      JumpTableSpecialLabelPrefix = "l";
    }

    NeedsSet = true;
    DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
    DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
    DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
    DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
    DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
    DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
    DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
    DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
    DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
    DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug";
    DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug";
  } else {
    Data16bitsDirective = "\t.half\t";
    Data32bitsDirective = "\t.word\t";
    ZeroDirective = "\t.skip\t";
    WeakRefDirective = "\t.weak\t";
    StaticCtorsSection = "\t.section .ctors,\"aw\",%progbits";
    StaticDtorsSection = "\t.section .dtors,\"aw\",%progbits";
  }
  AlignmentIsInBytes = false;
  Data64bitsDirective = 0;
  CommentString = "@";
  DataSection = "\t.data";
  ConstantPoolSection = "\t.text\n";
}
<commit_msg>Darwin HiddenDirective is .private_extern.<commit_after>//===-- ARMTargetAsmInfo.cpp - ARM asm properties ---------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by James M. Laskey and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations of the ARMTargetAsmInfo properties.
//
//===----------------------------------------------------------------------===//

#include "ARMTargetAsmInfo.h"
#include "ARMTargetMachine.h"
using namespace llvm;

ARMTargetAsmInfo::ARMTargetAsmInfo(const ARMTargetMachine &TM) {
  const ARMSubtarget *Subtarget = &TM.getSubtarget<ARMSubtarget>();
  if (Subtarget->isTargetDarwin()) {
    GlobalPrefix = "_";
    ZeroDirective = "\t.space\t";
    PrivateGlobalPrefix = "L";
    BSSSection = 0;                       // no BSS section.
    ZeroFillDirective = "\t.zerofill\t";  // Uses .zerofill
    SetDirective = "\t.set";
    WeakRefDirective = "\t.weak_reference\t";
    HiddenDirective = "\t.private_extern\t";
    JumpTableDataSection = ".const";
    CStringSection = "\t.cstring";
    LCOMMDirective = "\t.lcomm\t";
    COMMDirectiveTakesAlignment = false;
    HasDotTypeDotSizeDirective = false;
    StaticCtorsSection = ".mod_init_func";
    StaticDtorsSection = ".mod_term_func";
    InlineAsmStart = "@ InlineAsm Start";
    InlineAsmEnd = "@ InlineAsm End";

    // In non-PIC modes, emit a special label before jump tables so that the
    // linker can perform more accurate dead code stripping.
    if (TM.getRelocationModel() != Reloc::PIC_) {
      // Emit a local label that is preserved until the linker runs.
      JumpTableSpecialLabelPrefix = "l";
    }

    NeedsSet = true;
    DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
    DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
    DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
    DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
    DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
    DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
    DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
    DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
    DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
    DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug";
    DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug";
  } else {
    Data16bitsDirective = "\t.half\t";
    Data32bitsDirective = "\t.word\t";
    ZeroDirective = "\t.skip\t";
    WeakRefDirective = "\t.weak\t";
    StaticCtorsSection = "\t.section .ctors,\"aw\",%progbits";
    StaticDtorsSection = "\t.section .dtors,\"aw\",%progbits";
  }
  AlignmentIsInBytes = false;
  Data64bitsDirective = 0;
  CommentString = "@";
  DataSection = "\t.data";
  ConstantPoolSection = "\t.text\n";
}
<|endoftext|>


<commit_before>//===- AlphaSubtarget.cpp - Alpha Subtarget Information ---------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Andrew Lenharth and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Alpha specific subclass of TargetSubtarget.
//
//===----------------------------------------------------------------------===//

#include "AlphaSubtarget.h"
#include "Alpha.h"
#include "llvm/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/SubtargetFeature.h"
#include "AlphaGenSubtarget.inc"
using namespace llvm;

enum {
  FeatureKVSize = sizeof(FeatureKV) / sizeof(SubtargetFeatureKV),
  SubTypeKVSize = sizeof(SubTypeKV) / sizeof(SubtargetFeatureKV)
};

AlphaSubtarget::AlphaSubtarget(const Module &M, const std::string &FS)
  : HasF2I(false), HasCT(false) {
  std::string CPU = "generic";
  uint32_t Bits =
    SubtargetFeatures::Parse(FS, CPU,
                             SubTypeKV, SubTypeKVSize,
                             FeatureKV, FeatureKVSize);
  HasF2I = (Bits & FeatureFIX) != 0;
  HasCT  = (Bits & FeatureCIX) != 0;
}
<commit_msg>Simplify this due to changes in the tblgen side<commit_after>//===- AlphaSubtarget.cpp - Alpha Subtarget Information ---------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Andrew Lenharth and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Alpha specific subclass of TargetSubtarget.
//
//===----------------------------------------------------------------------===//

#include "AlphaSubtarget.h"
#include "Alpha.h"
#include "AlphaGenSubtarget.inc"
using namespace llvm;

AlphaSubtarget::AlphaSubtarget(const Module &M, const std::string &FS)
  : HasF2I(false), HasCT(false) {
  std::string CPU = "generic";
  uint32_t Bits =
    SubtargetFeatures::Parse(FS, CPU,
                             SubTypeKV, SubTypeKVSize,
                             FeatureKV, FeatureKVSize);
  HasF2I = (Bits & FeatureFIX) != 0;
  HasCT  = (Bits & FeatureCIX) != 0;
}
<|endoftext|>


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

#ifndef _MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SBXCLASS_HXX //autogen
#include <sbx.hxx>
#endif

// AB-Uno-Test
//#define unotest
#ifdef unotest
#ifndef _USR_UNO_HXX
#include <usr/uno.hxx>
#endif
#include <sbuno.hxx>
#include <sbunoobj.hxx>
#endif

#include "sbintern.hxx"

#ifndef _BASIC_TTRESHLP_HXX
#include "ttstrhlp.hxx"
#endif
#include "mybasic.hxx"
#include "basic.hrc"
#include "appbased.hxx"

#include "status.hxx"
#include "basic.hrc"

#include "object.hxx"

#include "processw.hxx"

TYPEINIT1(MyBasic,StarBASIC)

class MyFactory : public SbxFactory
{
public:
    virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
};

static SampleObjectFac aFac1;
static MyFactory aFac2;
static ProcessFactory aProcessFac;
static short nInst = 0;

SbxBase* MyFactory::Create( UINT16 nSbxId, UINT32 nCr )
{
    if( nCr == SBXCR_TEST && nSbxId == SBXID_MYBASIC )
        return new MyBasic;
    else
        return NULL;
}

MyBasic::MyBasic() : StarBASIC()
{
    nError = 0;
    if( !nInst++ )
    {
        AddFactory( &aFac1 );
        AddFactory( &aFac2 );
        AddFactory( &aProcessFac );
    }
    SbxVariable* p = new SbxCollection( CUniString("MyColl") );
    p->SetName( CUniString("Objects") );
    Insert( p );

    // AB-Uno-Test
#ifdef unotest
    // Uno-Service-Manager holenReflection Service bolen
    createAndSetDefaultServiceManager();        // spaeter schon erledigt

    // Uno-Test-Objekt holen
    UsrAny aObjAny = getIntrospectionTestObject();

    // Objekt verpacken in ein SbUnoObject packen
    String aName( "UnoObject" );
    SbxObjectRef xSbUnoObj = GetSbUnoObject( aName, aObjAny );
    //SbxObjectRef xSbUnoObj = new SbUnoObject( aName, aObjAny );
    Insert( (SbxObject*)xSbUnoObj );
#endif

    pTestObject = NULL;
}

Link MyBasic::GenLogHdl()
{
    return LINK( GetpApp()->GetAppWindow(), BasicFrame, Log );
}

Link MyBasic::GenWinInfoHdl()
{
    return LINK( GetpApp()->GetAppWindow(), BasicFrame, WinInfo );
}

Link MyBasic::GenModuleWinExistsHdl()
{
    return LINK( GetpApp()->GetAppWindow(), BasicFrame, ModuleWinExists );
}

Link MyBasic::GenWriteStringHdl()
{
    return LINK( GetpApp()->GetAppWindow(), BasicFrame, WriteString );
}

void MyBasic::StartListening( SfxBroadcaster &rBroadcaster )
{
    ((BasicFrame*)GetpApp()->GetAppWindow())->StartListening( rBroadcaster );
}

void MyBasic::SetCompileModule( SbModule *pMod )
{
    GetSbData()->pCompMod = pMod;
}

SbModule *MyBasic::GetCompileModule()
{
    return GetSbData()->pCompMod;
}

String MyBasic::GenRealString( const String &aResString )
{
    return ((BasicFrame*)GetpApp()->GetAppWindow())->GenRealString( aResString );
}

void MyBasic::LoadIniFile()
{
}

SbTextType MyBasic::GetSymbolType( const String &rSymbol, BOOL bWasTTControl )
{
    return SB_SYMBOL;   // Alles was hier landet ist vom Typ SB_SYMBOL und bleibt es auch
}

MyBasic::~MyBasic()
{
    aErrors.Clear();
    if( !--nInst )
    {
        RemoveFactory( &aFac1 );
        RemoveFactory( &aFac2 );
        RemoveFactory( &aProcessFac );
    }
}

void MyBasic::Reset()
{
    aErrors.Clear();
    nError = 0;
}

BOOL MyBasic::Compile( SbModule* p )
{
    Reset();
    return StarBASIC::Compile( p );
}

BOOL MyBasic::ErrorHdl()
{
    AppBasEd* pWin = aBasicApp.pFrame->FindModuleWin( GetActiveModule()->GetName() );
    if( !pWin )
    {       // erstmal Fenster aufmachen
        pWin = aBasicApp.pFrame->CreateModuleWin( GetActiveModule() );
    }
    else
        pWin->ToTop();
    if( IsCompilerError() )
    {
        aErrors.Insert(
          new BasicError
            ( pWin,
              0, StarBASIC::GetErrorText(), GetLine(), GetCol1(), GetCol2() ),
              LIST_APPEND );
        nError++;
        return BOOL( nError < 20 ); // Abbruch nach 20 Fehlern
    }
    else
    {
        ReportRuntimeError( pWin );
        return FALSE;
    }
}

void MyBasic::ReportRuntimeError( AppBasEd *pEditWin )
{
    String nErrorText;
    nErrorText = GetSpechialErrorText();

    if ( pEditWin )     // just in case the focus is not right
        pEditWin->ToTop();

    BasicError( pEditWin,
        GetVBErrorCode( GetErrorCode() ), nErrorText, GetLine(),
        GetCol1(), GetCol2() ).Show();
}

void MyBasic::DebugFindNoErrors( BOOL bDebugFindNoErrors )
{
}

const String MyBasic::GetSpechialErrorText()
{
    return GetErrorText();
}

USHORT MyBasic::BreakHdl()
{
    SbModule* pMod = GetActiveModule();
    if( pMod )
    {
        AppBasEd* pWin = aBasicApp.pFrame->FindModuleWin( pMod->GetName() );
        if( !pWin )
        {       // erstmal Fenster aufmachen
            pWin = aBasicApp.pFrame->CreateModuleWin( pMod );
        }
        else
            pWin->ToTop();
        pWin->Highlight( GetLine(), GetCol1(), GetCol2() );
    }

    if( IsBreak() ) // Wenn Breakpoint (oder "Run to Cursor")
    {
//      if ( GetActiveModule()->IsBP(GetLine()) )
//          GetActiveModule()->ClearBP(GetLine());
        return aBasicApp.pFrame->BreakHandler();
    }
    else
    {
        return aBasicApp.pFrame->BreakHandler();
    }
}

/***************************************************************************
|*
|*                          class BasicError
|*
***************************************************************************/

BasicError::BasicError
    ( AppBasEd* w, USHORT nE, const String& r, USHORT nL, USHORT nC1, USHORT nC2 )
    : aText( ResId( IDS_ERROR1 ) )
{
    pWin  = w;
    nLine = nL;
    nCol1 = nC1;
    nCol2 = nC2;
    if( nE )
    {
        aText += String::CreateFromInt32( nE );
        aText.AppendAscii(": ");
        aText += r;
    }
    else
        aText = r;
}

// Dies ist ein Beispiel, wie die Fehler-Information geschickt
// aufgebaut werden kann, um ein Statement zu highlighten.

void BasicError::Show()
{
    if( pWin && aBasicApp.pFrame->IsWinValid( pWin ) ) {
        pWin->Highlight( nLine, nCol1, nCol2 );
        aBasicApp.pFrame->pStatus->Message( aText );
    } else MessBox( aBasicApp.pFrame, WB_OK, aBasicApp.pFrame->GetText(),
                    aText ).Execute();
}

<commit_msg>INTEGRATION: CWS warnings01 (1.9.28); FILE MERGED 2005/12/23 10:13:46 gh 1.9.28.2: rename method to resolv ambiguity 2005/11/18 09:57:04 gh 1.9.28.1: linux warnings (some more)<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: mybasic.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 17:36:52 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SBXCLASS_HXX //autogen
#include <sbx.hxx>
#endif

// AB-Uno-Test
//#define unotest
#ifdef unotest
#ifndef _USR_UNO_HXX
#include <usr/uno.hxx>
#endif
#include <sbuno.hxx>
#include <sbunoobj.hxx>
#endif

#include "sbintern.hxx"

#ifndef _BASIC_TTRESHLP_HXX
#include "ttstrhlp.hxx"
#endif
#include "mybasic.hxx"
#include "basic.hrc"
#include "appbased.hxx"

#include "status.hxx"
#include "basic.hrc"

#include "object.hxx"

#include "processw.hxx"

TYPEINIT1(MyBasic,StarBASIC)

class MyFactory : public SbxFactory
{
public:
    virtual SbxBase* Create( UINT16 nSbxId, UINT32 = SBXCR_SBX );
};

static SampleObjectFac aFac1;
static MyFactory aFac2;
static ProcessFactory aProcessFac;
static short nInst = 0;

SbxBase* MyFactory::Create( UINT16 nSbxId, UINT32 nCr )
{
    if( nCr == SBXCR_TEST && nSbxId == SBXID_MYBASIC )
        return new MyBasic;
    else
        return NULL;
}

MyBasic::MyBasic() : StarBASIC()
{
    nError = 0;
    if( !nInst++ )
    {
        AddFactory( &aFac1 );
        AddFactory( &aFac2 );
        AddFactory( &aProcessFac );
    }
    SbxVariable* p = new SbxCollection( CUniString("MyColl") );
    p->SetName( CUniString("Objects") );
    Insert( p );

    // AB-Uno-Test
#ifdef unotest
    // Uno-Service-Manager holenReflection Service bolen
    createAndSetDefaultServiceManager();        // spaeter schon erledigt

    // Uno-Test-Objekt holen
    UsrAny aObjAny = getIntrospectionTestObject();

    // Objekt verpacken in ein SbUnoObject packen
    String aName( "UnoObject" );
    SbxObjectRef xSbUnoObj = GetSbUnoObject( aName, aObjAny );
    //SbxObjectRef xSbUnoObj = new SbUnoObject( aName, aObjAny );
    Insert( (SbxObject*)xSbUnoObj );
#endif

    pTestObject = NULL;
}

Link MyBasic::GenLogHdl()
{
    return LINK( GetpApp()->GetAppWindow(), BasicFrame, Log );
}

Link MyBasic::GenWinInfoHdl()
{
    return LINK( GetpApp()->GetAppWindow(), BasicFrame, WinInfo );
}

Link MyBasic::GenModuleWinExistsHdl()
{
    return LINK( GetpApp()->GetAppWindow(), BasicFrame, ModuleWinExists );
}

Link MyBasic::GenWriteStringHdl()
{
    return LINK( GetpApp()->GetAppWindow(), BasicFrame, WriteString );
}

void MyBasic::StartListeningTT( SfxBroadcaster &rBroadcaster )
{
    ((BasicFrame*)GetpApp()->GetAppWindow())->StartListening( rBroadcaster );
}

void MyBasic::SetCompileModule( SbModule *pMod )
{
    GetSbData()->pCompMod = pMod;
}

SbModule *MyBasic::GetCompileModule()
{
    return GetSbData()->pCompMod;
}

String MyBasic::GenRealString( const String &aResString )
{
    return ((BasicFrame*)GetpApp()->GetAppWindow())->GenRealString( aResString );
}

void MyBasic::LoadIniFile()
{
}

SbTextType MyBasic::GetSymbolType( const String &rSymbol, BOOL bWasTTControl )
{
    (void) rSymbol; /* avoid warning about unused parameter */
    (void) bWasTTControl; /* avoid warning about unused parameter */
    return SB_SYMBOL;   // Alles was hier landet ist vom Typ SB_SYMBOL und bleibt es auch
}

MyBasic::~MyBasic()
{
    aErrors.Clear();
    if( !--nInst )
    {
        RemoveFactory( &aFac1 );
        RemoveFactory( &aFac2 );
        RemoveFactory( &aProcessFac );
    }
}

void MyBasic::Reset()
{
    aErrors.Clear();
    nError = 0;
}

BOOL MyBasic::Compile( SbModule* p )
{
    Reset();
    return StarBASIC::Compile( p );
}

BOOL MyBasic::ErrorHdl()
{
    AppBasEd* pWin = aBasicApp.pFrame->FindModuleWin( GetActiveModule()->GetName() );
    if( !pWin )
    {       // erstmal Fenster aufmachen
        pWin = aBasicApp.pFrame->CreateModuleWin( GetActiveModule() );
    }
    else
        pWin->ToTop();
    if( IsCompilerError() )
    {
        aErrors.Insert(
          new BasicError
            ( pWin,
              0, StarBASIC::GetErrorText(), GetLine(), GetCol1(), GetCol2() ),
              LIST_APPEND );
        nError++;
        return BOOL( nError < 20 ); // Abbruch nach 20 Fehlern
    }
    else
    {
        ReportRuntimeError( pWin );
        return FALSE;
    }
}

void MyBasic::ReportRuntimeError( AppBasEd *pEditWin )
{
    String nErrorText;
    nErrorText = GetSpechialErrorText();

    if ( pEditWin )     // just in case the focus is not right
        pEditWin->ToTop();

    BasicError( pEditWin,
        GetVBErrorCode( GetErrorCode() ), nErrorText, GetLine(),
        GetCol1(), GetCol2() ).Show();
}

void MyBasic::DebugFindNoErrors( BOOL bDebugFindNoErrors )
{
    (void) bDebugFindNoErrors; /* avoid warning about unused parameter */
}

const String MyBasic::GetSpechialErrorText()
{
    return GetErrorText();
}

USHORT MyBasic::BreakHdl()
{
    SbModule* pMod = GetActiveModule();
    if( pMod )
    {
        AppBasEd* pWin = aBasicApp.pFrame->FindModuleWin( pMod->GetName() );
        if( !pWin )
        {       // erstmal Fenster aufmachen
            pWin = aBasicApp.pFrame->CreateModuleWin( pMod );
        }
        else
            pWin->ToTop();
        pWin->Highlight( GetLine(), GetCol1(), GetCol2() );
    }

    if( IsBreak() ) // Wenn Breakpoint (oder "Run to Cursor")
    {
//      if ( GetActiveModule()->IsBP(GetLine()) )
//          GetActiveModule()->ClearBP(GetLine());
        return aBasicApp.pFrame->BreakHandler();
    }
    else
    {
        return aBasicApp.pFrame->BreakHandler();
    }
}

/***************************************************************************
|*
|*                          class BasicError
|*
***************************************************************************/

BasicError::BasicError
    ( AppBasEd* w, USHORT nE, const String& r, USHORT nL, USHORT nC1, USHORT nC2 )
    : aText( ResId( IDS_ERROR1 ) )
{
    pWin  = w;
    nLine = nL;
    nCol1 = nC1;
    nCol2 = nC2;
    if( nE )
    {
        aText += String::CreateFromInt32( nE );
        aText.AppendAscii(": ");
        aText += r;
    }
    else
        aText = r;
}

// Dies ist ein Beispiel, wie die Fehler-Information geschickt
// aufgebaut werden kann, um ein Statement zu highlighten.

void BasicError::Show()
{
    if( pWin && aBasicApp.pFrame->IsWinValid( pWin ) ) {
        pWin->Highlight( nLine, nCol1, nCol2 );
        aBasicApp.pFrame->pStatus->Message( aText );
    } else MessBox( aBasicApp.pFrame, WB_OK, aBasicApp.pFrame->GetText(),
                    aText ).Execute();
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

#ifdef WNT
#include    <tools/prewin.h>
#include "winbase.h"
#include    <tools/postwin.h>
#endif
#include <tools/errcode.hxx>
#include <basic/sbxcore.hxx>
#include <tools/string.hxx>
#include <osl/file.hxx>
#include <osl/process.h>

#include <basic/ttstrhlp.hxx>
#include <basic/process.hxx>

Process::Process()
: m_nArgumentCount( 0 )
, m_pArgumentList( NULL )
, m_nEnvCount( 0 )
, m_pEnvList( NULL )
, m_aProcessName()
, m_pProcess( NULL )
, bWasGPF( FALSE )
, bHasBeenStarted( FALSE )
{
}

#define FREE_USTRING_LIST( count, list ) \
    if ( count && list ) \
    { \
        for ( unsigned int i = 0; i < count; ++i ) \
        { \
            rtl_uString_release( list[i] ); \
            list[i] = NULL; \
        } \
        delete[] list; \
    } \
    count = 0; \
    list = NULL;

Process::~Process()
{
    FREE_USTRING_LIST( m_nArgumentCount, m_pArgumentList );
    FREE_USTRING_LIST( m_nEnvCount, m_pEnvList );
    if ( m_pProcess )
        osl_freeProcessHandle( m_pProcess );
}

BOOL Process::ImplIsRunning()
{
    if ( m_pProcess && bHasBeenStarted )
    {
        oslProcessInfo aProcessInfo;
        osl_getProcessInfo(m_pProcess, osl_Process_EXITCODE, &aProcessInfo );
        if ( !(aProcessInfo.Fields & osl_Process_EXITCODE) )
            return TRUE;
        else
            return FALSE;
    }
    else
        return FALSE;
}

long Process::ImplGetExitCode()
{
    if ( m_pProcess )
    {
        oslProcessInfo aProcessInfo;
        osl_getProcessInfo(m_pProcess, osl_Process_EXITCODE, &aProcessInfo );
        if ( !(aProcessInfo.Fields & osl_Process_EXITCODE) )
            SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
        return aProcessInfo.Code;
    }
    else
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
        return 0;
}

////////////////////////////////////////////////////////////////////////////

void Process::SetImage( const String &aAppPath, const String &aAppParams, const Environment *pEnv )
{ // Set image file of executable
    if ( m_pProcess && ImplIsRunning() )
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
    else
    {
        FREE_USTRING_LIST( m_nArgumentCount, m_pArgumentList );
        FREE_USTRING_LIST( m_nEnvCount, m_pEnvList );
        osl_freeProcessHandle( m_pProcess );
        m_pProcess = NULL;

        xub_StrLen i, nCount = aAppParams.GetQuotedTokenCount( CUniString("\"\"" ), ' ' );
        ::rtl::OUString *pParamList = new ::rtl::OUString[nCount];

        xub_StrLen nParamCount = 0;
        for ( i = 0 ; i < nCount ; i++ )
        {
            ::rtl::OUString aTemp = ::rtl::OUString(aAppParams.GetQuotedToken( i, CUniString("\"\"''" ), ' ' ));
            if ( aTemp.getLength() )
            {
                pParamList[nParamCount] = aTemp;
                nParamCount++;
            }
        }
        m_nArgumentCount = nParamCount;
        m_pArgumentList = new rtl_uString*[m_nArgumentCount];
        for ( i = 0 ; i < m_nArgumentCount ; i++ )
        {
            m_pArgumentList[i] = NULL;
            rtl_uString_assign( &(m_pArgumentList[i]), pParamList[i].pData );
        }
        delete [] pParamList;

        if ( pEnv )
        {
            m_pEnvList = new rtl_uString*[pEnv->size()];

            m_nEnvCount = 0;
            Environment::const_iterator aIter = pEnv->begin();
            while ( aIter != pEnv->end() )
            {
                ::rtl::OUString aTemp = ::rtl::OUString( (*aIter).first );
                aTemp += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "=" ));
                aTemp += ::rtl::OUString( (*aIter).second );
                m_pEnvList[m_nEnvCount] = NULL;
                rtl_uString_assign( &(m_pEnvList[m_nEnvCount]), aTemp.pData );
                ++m_nEnvCount;
                ++aIter;
            }
        }

        ::rtl::OUString aNormalizedAppPath;
        osl::FileBase::getFileURLFromSystemPath( ::rtl::OUString(aAppPath), aNormalizedAppPath );
        m_aProcessName = aNormalizedAppPath;;
        bHasBeenStarted = FALSE;

    }
}

BOOL Process::Start()
{ // Start program
    BOOL bSuccess=FALSE;
    if ( m_aProcessName.getLength() && !ImplIsRunning() )
    {
        bWasGPF = FALSE;
#ifdef WNT
        sal_uInt32 nErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX);
        try
        {
#endif
            bSuccess = osl_executeProcess(
                    m_aProcessName.pData,
                    m_pArgumentList,
                    m_nArgumentCount,
                    osl_Process_SEARCHPATH
                    /*| osl_Process_DETACHED*/
                    /*| osl_Process_WAIT*/,
                    NULL,
                    NULL,
                    m_pEnvList,
                    m_nEnvCount,
                    &m_pProcess ) == osl_Process_E_None;

#ifdef WNT
        }
        catch( ... )
        {
            bWasGPF = TRUE;
            // TODO: Output debug message !!
        }
        nErrorMode = SetErrorMode(nErrorMode);
#endif
        bHasBeenStarted = bSuccess;
    }
    else
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
    return bSuccess;
}

ULONG Process::GetExitCode()
{ // ExitCode of program after execution
    return ImplGetExitCode();
}

BOOL Process::IsRunning()
{
    return ImplIsRunning();
}

BOOL Process::WasGPF()
{ // Did the process fail?
#ifdef WNT
    return ImplGetExitCode() == 3221225477;
#else
    return bWasGPF;
#endif
}

BOOL Process::Terminate()
{
    if ( ImplIsRunning() )
        return osl_terminateProcess(m_pProcess) == osl_Process_E_None;
    return TRUE;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>osl_getProcessInfo requires Size to be set first<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

#ifdef WNT
#include    <tools/prewin.h>
#include "winbase.h"
#include    <tools/postwin.h>
#endif
#include <tools/errcode.hxx>
#include <basic/sbxcore.hxx>
#include <tools/string.hxx>
#include <osl/file.hxx>
#include <osl/process.h>

#include <basic/ttstrhlp.hxx>
#include <basic/process.hxx>

Process::Process()
: m_nArgumentCount( 0 )
, m_pArgumentList( NULL )
, m_nEnvCount( 0 )
, m_pEnvList( NULL )
, m_aProcessName()
, m_pProcess( NULL )
, bWasGPF( FALSE )
, bHasBeenStarted( FALSE )
{
}

#define FREE_USTRING_LIST( count, list ) \
    if ( count && list ) \
    { \
        for ( unsigned int i = 0; i < count; ++i ) \
        { \
            rtl_uString_release( list[i] ); \
            list[i] = NULL; \
        } \
        delete[] list; \
    } \
    count = 0; \
    list = NULL;

Process::~Process()
{
    FREE_USTRING_LIST( m_nArgumentCount, m_pArgumentList );
    FREE_USTRING_LIST( m_nEnvCount, m_pEnvList );
    if ( m_pProcess )
        osl_freeProcessHandle( m_pProcess );
}

BOOL Process::ImplIsRunning()
{
    if ( m_pProcess && bHasBeenStarted )
    {
        oslProcessInfo aProcessInfo;
        aProcessInfo.Size = sizeof(oslProcessInfo);
        osl_getProcessInfo(m_pProcess, osl_Process_EXITCODE, &aProcessInfo );
        if ( !(aProcessInfo.Fields & osl_Process_EXITCODE) )
            return TRUE;
        else
            return FALSE;
    }
    else
        return FALSE;
}

long Process::ImplGetExitCode()
{
    if ( m_pProcess )
    {
        oslProcessInfo aProcessInfo;
        osl_getProcessInfo(m_pProcess, osl_Process_EXITCODE, &aProcessInfo );
        if ( !(aProcessInfo.Fields & osl_Process_EXITCODE) )
            SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
        return aProcessInfo.Code;
    }
    else
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
        return 0;
}

////////////////////////////////////////////////////////////////////////////

void Process::SetImage( const String &aAppPath, const String &aAppParams, const Environment *pEnv )
{ // Set image file of executable
    if ( m_pProcess && ImplIsRunning() )
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
    else
    {
        FREE_USTRING_LIST( m_nArgumentCount, m_pArgumentList );
        FREE_USTRING_LIST( m_nEnvCount, m_pEnvList );
        osl_freeProcessHandle( m_pProcess );
        m_pProcess = NULL;

        xub_StrLen i, nCount = aAppParams.GetQuotedTokenCount( CUniString("\"\"" ), ' ' );
        ::rtl::OUString *pParamList = new ::rtl::OUString[nCount];

        xub_StrLen nParamCount = 0;
        for ( i = 0 ; i < nCount ; i++ )
        {
            ::rtl::OUString aTemp = ::rtl::OUString(aAppParams.GetQuotedToken( i, CUniString("\"\"''" ), ' ' ));
            if ( aTemp.getLength() )
            {
                pParamList[nParamCount] = aTemp;
                nParamCount++;
            }
        }
        m_nArgumentCount = nParamCount;
        m_pArgumentList = new rtl_uString*[m_nArgumentCount];
        for ( i = 0 ; i < m_nArgumentCount ; i++ )
        {
            m_pArgumentList[i] = NULL;
            rtl_uString_assign( &(m_pArgumentList[i]), pParamList[i].pData );
        }
        delete [] pParamList;

        if ( pEnv )
        {
            m_pEnvList = new rtl_uString*[pEnv->size()];

            m_nEnvCount = 0;
            Environment::const_iterator aIter = pEnv->begin();
            while ( aIter != pEnv->end() )
            {
                ::rtl::OUString aTemp = ::rtl::OUString( (*aIter).first );
                aTemp += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "=" ));
                aTemp += ::rtl::OUString( (*aIter).second );
                m_pEnvList[m_nEnvCount] = NULL;
                rtl_uString_assign( &(m_pEnvList[m_nEnvCount]), aTemp.pData );
                ++m_nEnvCount;
                ++aIter;
            }
        }

        ::rtl::OUString aNormalizedAppPath;
        osl::FileBase::getFileURLFromSystemPath( ::rtl::OUString(aAppPath), aNormalizedAppPath );
        m_aProcessName = aNormalizedAppPath;;
        bHasBeenStarted = FALSE;

    }
}

BOOL Process::Start()
{ // Start program
    BOOL bSuccess=FALSE;
    if ( m_aProcessName.getLength() && !ImplIsRunning() )
    {
        bWasGPF = FALSE;
#ifdef WNT
        sal_uInt32 nErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX);
        try
        {
#endif
            bSuccess = osl_executeProcess(
                    m_aProcessName.pData,
                    m_pArgumentList,
                    m_nArgumentCount,
                    osl_Process_SEARCHPATH
                    /*| osl_Process_DETACHED*/
                    /*| osl_Process_WAIT*/,
                    NULL,
                    NULL,
                    m_pEnvList,
                    m_nEnvCount,
                    &m_pProcess ) == osl_Process_E_None;

#ifdef WNT
        }
        catch( ... )
        {
            bWasGPF = TRUE;
            // TODO: Output debug message !!
        }
        nErrorMode = SetErrorMode(nErrorMode);
#endif
        bHasBeenStarted = bSuccess;
    }
    else
        SbxBase::SetError( SbxERR_NO_ACTIVE_OBJECT );
    return bSuccess;
}

ULONG Process::GetExitCode()
{ // ExitCode of program after execution
    return ImplGetExitCode();
}

BOOL Process::IsRunning()
{
    return ImplIsRunning();
}

BOOL Process::WasGPF()
{ // Did the process fail?
#ifdef WNT
    return ImplGetExitCode() == 3221225477;
#else
    return bWasGPF;
#endif
}

BOOL Process::Terminate()
{
    if ( ImplIsRunning() )
        return osl_terminateProcess(m_pProcess) == osl_Process_E_None;
    return TRUE;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


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

<commit_msg>INTEGRATION: CWS ab17fixes (1.1.1.1.326); FILE MERGED<commit_after>/*************************************************************************
 *
 *  $RCSfile: ttbasic.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2005-09-29 12:37:27 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
class TTBasic
{
public:
    static MyBasic* CreateMyBasic();
};

<|endoftext|>