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

#include <assert.h>
#include <stdio.h>
#include <unistd.h>

#include <iostream>

#include "SetupPayload.cpp"
#include "SetupCodeUtils.cpp"
#include "QRCodeSetupPayloadGenerator.cpp"

using namespace chip;
using namespace std;

#define EXPECT_EQ(x, y) ((x) != (y)) ? cerr << __FILE__ << ":" << __LINE__ << ":error EXPECT_EQ(" << x << ", " << y << ")\n", 1 : 0

int testPayloadByteArrayRep()
{
    SetupPayload payload;

    payload.version               = 5;
    payload.vendorID              = 12;
    payload.productID             = 1;
    payload.requiresCustomFlow    = 0;
    payload.rendezvousInformation = 1;
    payload.discriminator         = 128;
    payload.setUpPINCode          = 2048;

    QRCodeSetupPayloadGenerator generator(payload);
    string result   = generator.payloadBinaryRepresentation();
    string expected = "000000000000000000100000000000010000000000000000100000000000000000010000000000000011001010";

    return EXPECT_EQ(result, expected);
}

int testPayloadBase45Rep()
{
    SetupPayload payload;

    payload.version               = 5;
    payload.vendorID              = 12;
    payload.productID             = 1;
    payload.requiresCustomFlow    = 0;
    payload.rendezvousInformation = 1;
    payload.discriminator         = 128;
    payload.setUpPINCode          = 2048;

    QRCodeSetupPayloadGenerator generator(payload);
    string result   = generator.payloadBase45Representation();
    string expected = "B20800G00G8G000";

    return EXPECT_EQ(result, expected);
}

int testBase45()
{
    int surprises = 0;

    uint8_t input[] = { 10, 10, 10 };

    surprises += EXPECT_EQ(base45Encode(input, 0), "");

    surprises += EXPECT_EQ(base45Encode(input, 1), "A0");

    surprises += EXPECT_EQ(base45Encode(input, 2), "5C1");

    surprises += EXPECT_EQ(base45Encode(input, 3), "5C1A0");

    surprises += EXPECT_EQ(base45Encode((uint8_t *) "Hello World!", sizeof("Hello World!") - 1), "8 C VDN44I3E.VD/94");

    vector<uint8_t> decoded = base45Decode("8 C VDN44I3E.VD/94");
    string hello_world;
    for (unsigned _ = 0; _ < decoded.size(); _++)
    {
        hello_world += (char) decoded[_];
    }
    surprises += EXPECT_EQ(hello_world, "Hello World!");

    // short input
    surprises += EXPECT_EQ(base45Decode("A0").size(), 1);

    // empty == empty
    surprises += EXPECT_EQ(base45Decode("").size(), 0);
    // too short
    surprises += EXPECT_EQ(base45Decode("A").size(), 0);
    // outside valid chars
    surprises += EXPECT_EQ(base45Decode("0\x1").size(), 0);
    surprises += EXPECT_EQ(base45Decode("\x10").size(), 0);
    surprises += EXPECT_EQ(base45Decode("[0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("0[").size(), 0);

    // BOGUS chars
    surprises += EXPECT_EQ(base45Decode("!0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("\"0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("#0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("&0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("'0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("(0").size(), 0);
    surprises += EXPECT_EQ(base45Decode(")0").size(), 0);
    surprises += EXPECT_EQ(base45Decode(",0").size(), 0);
    surprises += EXPECT_EQ(base45Decode(";0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("<0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("=0").size(), 0);
    surprises += EXPECT_EQ(base45Decode(">0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("@0").size(), 0);

    return surprises;
}

int testBitsetLen()
{
    return EXPECT_EQ(kTotalPayloadDataSizeInBits % 8, 0);
}

int testSetupPayloadVerify()
{
    int surprises = 0;
    SetupPayload payload;

    payload.version               = 5;
    payload.vendorID              = 12;
    payload.productID             = 1;
    payload.requiresCustomFlow    = 0;
    payload.rendezvousInformation = 1;
    payload.discriminator         = 128;
    payload.setUpPINCode          = 2048;
    surprises += EXPECT_EQ(payload.isValid(), true);

    // test invalid version
    SetupPayload test_payload = payload;
    test_payload.version      = 2 << kVersionFieldLengthInBits;
    surprises += EXPECT_EQ(test_payload.isValid(), false);

    // test invalid rendezvousInformation
    test_payload                       = payload;
    test_payload.rendezvousInformation = 3;
    surprises += EXPECT_EQ(test_payload.isValid(), false);

    // test invalid discriminator
    test_payload               = payload;
    test_payload.discriminator = 2 << kPayloadDiscriminatorFieldLengthInBits;
    surprises += EXPECT_EQ(test_payload.isValid(), false);

    // test invalid stetup PIN
    test_payload              = payload;
    test_payload.setUpPINCode = 2 << kSetupPINCodeFieldLengthInBits;
    surprises += EXPECT_EQ(test_payload.isValid(), false);

    return surprises;
}

int main(int argc, char ** argv)
{
    return testBitsetLen() + testPayloadByteArrayRep() + testPayloadBase45Rep() + testBase45() + testSetupPayloadVerify();
}
<commit_msg>review input<commit_after>/*
 *
 *    <COPYRIGHT>
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include <assert.h>
#include <stdio.h>
#include <unistd.h>

#include <iostream>

#include "SetupPayload.cpp"
#include "SetupCodeUtils.cpp"
#include "QRCodeSetupPayloadGenerator.cpp"

using namespace chip;
using namespace std;

#define EXPECT_EQ(x, y) ((x) != (y)) ? cerr << __FILE__ << ":" << __LINE__ << ":error EXPECT_EQ(" << x << ", " << y << ")\n", 1 : 0

int testPayloadByteArrayRep()
{
    SetupPayload payload;

    payload.version               = 5;
    payload.vendorID              = 12;
    payload.productID             = 1;
    payload.requiresCustomFlow    = 0;
    payload.rendezvousInformation = 1;
    payload.discriminator         = 128;
    payload.setUpPINCode          = 2048;

    QRCodeSetupPayloadGenerator generator(payload);
    string result   = generator.payloadBinaryRepresentation();
    string expected = "000000000000000000100000000000010000000000000000100000000000000000010000000000000011001010";

    return EXPECT_EQ(result, expected);
}

int testPayloadBase45Rep()
{
    SetupPayload payload;

    payload.version               = 5;
    payload.vendorID              = 12;
    payload.productID             = 1;
    payload.requiresCustomFlow    = 0;
    payload.rendezvousInformation = 1;
    payload.discriminator         = 128;
    payload.setUpPINCode          = 2048;

    QRCodeSetupPayloadGenerator generator(payload);
    string result   = generator.payloadBase45Representation();
    string expected = "B20800G00G8G000";

    return EXPECT_EQ(result, expected);
}

int testBase45()
{
    int surprises = 0;

    uint8_t input[] = { 10, 10, 10 };

    surprises += EXPECT_EQ(base45Encode(input, 0), "");

    surprises += EXPECT_EQ(base45Encode(input, 1), "A0");

    surprises += EXPECT_EQ(base45Encode(input, 2), "5C1");

    surprises += EXPECT_EQ(base45Encode(input, 3), "5C1A0");

    surprises += EXPECT_EQ(base45Encode((uint8_t *) "Hello World!", sizeof("Hello World!") - 1), "8 C VDN44I3E.VD/94");

    vector<uint8_t> decoded = base45Decode("8 C VDN44I3E.VD/94");
    string hello_world;
    for (size_t _ = 0; _ < decoded.size(); _++)
    {
        hello_world += (char) decoded[_];
    }
    surprises += EXPECT_EQ(hello_world, "Hello World!");

    // short input
    surprises += EXPECT_EQ(base45Decode("A0").size(), 1);

    // empty == empty
    surprises += EXPECT_EQ(base45Decode("").size(), 0);
    // too short
    surprises += EXPECT_EQ(base45Decode("A").size(), 0);
    // outside valid chars
    surprises += EXPECT_EQ(base45Decode("0\x1").size(), 0);
    surprises += EXPECT_EQ(base45Decode("\x10").size(), 0);
    surprises += EXPECT_EQ(base45Decode("[0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("0[").size(), 0);

    // BOGUS chars
    surprises += EXPECT_EQ(base45Decode("!0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("\"0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("#0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("&0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("'0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("(0").size(), 0);
    surprises += EXPECT_EQ(base45Decode(")0").size(), 0);
    surprises += EXPECT_EQ(base45Decode(",0").size(), 0);
    surprises += EXPECT_EQ(base45Decode(";0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("<0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("=0").size(), 0);
    surprises += EXPECT_EQ(base45Decode(">0").size(), 0);
    surprises += EXPECT_EQ(base45Decode("@0").size(), 0);

    return surprises;
}

int testBitsetLen()
{
    return EXPECT_EQ(kTotalPayloadDataSizeInBits % 8, 0);
}

int testSetupPayloadVerify()
{
    int surprises = 0;
    SetupPayload payload;

    payload.version               = 5;
    payload.vendorID              = 12;
    payload.productID             = 1;
    payload.requiresCustomFlow    = 0;
    payload.rendezvousInformation = 1;
    payload.discriminator         = 128;
    payload.setUpPINCode          = 2048;
    surprises += EXPECT_EQ(payload.isValid(), true);

    // test invalid version
    SetupPayload test_payload = payload;
    test_payload.version      = 2 << kVersionFieldLengthInBits;
    surprises += EXPECT_EQ(test_payload.isValid(), false);

    // test invalid rendezvousInformation
    test_payload                       = payload;
    test_payload.rendezvousInformation = 3;
    surprises += EXPECT_EQ(test_payload.isValid(), false);

    // test invalid discriminator
    test_payload               = payload;
    test_payload.discriminator = 2 << kPayloadDiscriminatorFieldLengthInBits;
    surprises += EXPECT_EQ(test_payload.isValid(), false);

    // test invalid stetup PIN
    test_payload              = payload;
    test_payload.setUpPINCode = 2 << kSetupPINCodeFieldLengthInBits;
    surprises += EXPECT_EQ(test_payload.isValid(), false);

    return surprises;
}

int main(int argc, char ** argv)
{
    return testBitsetLen() + testPayloadByteArrayRep() + testPayloadBase45Rep() + testBase45() + testSetupPayloadVerify();
}
<|endoftext|>


<commit_before>/*
 * Copyright © 2014 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "brw_fs.h"
#include "brw_fs_live_variables.h"
#include "brw_cfg.h"

/** @file brw_fs_dead_code_eliminate.cpp
 *
 * Dataflow-aware dead code elimination.
 *
 * Walks the instruction list from the bottom, removing instructions that
 * have results that both aren't used in later blocks and haven't been read
 * yet in the tail end of this block.
 */

bool
fs_visitor::dead_code_eliminate()
{
   bool progress = false;

   calculate_live_intervals();

   int num_vars = live_intervals->num_vars;
   BITSET_WORD *live = rzalloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
   BITSET_WORD *flag_live = rzalloc_array(NULL, BITSET_WORD, 1);

   foreach_block_reverse_safe(block, cfg) {
      memcpy(live, live_intervals->block_data[block->num].liveout,
             sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
      memcpy(flag_live, live_intervals->block_data[block->num].flag_liveout,
             sizeof(BITSET_WORD));

      foreach_inst_in_block_reverse_safe(fs_inst, inst, block) {
         if (inst->dst.file == VGRF && !inst->has_side_effects()) {
            const unsigned var = live_intervals->var_from_reg(inst->dst);
            bool result_live = false;

            for (unsigned i = 0; i < regs_written(inst); i++)
               result_live |= BITSET_TEST(live, var + i);

            if (!result_live) {
               progress = true;

               if (inst->writes_accumulator || inst->flags_written()) {
                  inst->dst = fs_reg(retype(brw_null_reg(), inst->dst.type));
               } else {
                  inst->opcode = BRW_OPCODE_NOP;
               }
            }
         }

         if (inst->dst.is_null() && inst->flags_written()) {
            if (!(flag_live[0] & inst->flags_written())) {
               inst->opcode = BRW_OPCODE_NOP;
               progress = true;
            }
         }

         if (inst->dst.is_null() &&
             !inst->is_control_flow() &&
             !inst->has_side_effects() &&
             !inst->flags_written() &&
             !inst->writes_accumulator) {
            inst->opcode = BRW_OPCODE_NOP;
            progress = true;
         }

         if (inst->dst.file == VGRF) {
            if (!inst->is_partial_write()) {
               int var = live_intervals->var_from_reg(inst->dst);
               for (unsigned i = 0; i < regs_written(inst); i++) {
                  BITSET_CLEAR(live, var + i);
               }
            }
         }

         if (!inst->predicate && inst->exec_size >= 8)
            flag_live[0] &= ~inst->flags_written();

         if (inst->opcode == BRW_OPCODE_NOP) {
            inst->remove(block);
            continue;
         }

         for (int i = 0; i < inst->sources; i++) {
            if (inst->src[i].file == VGRF) {
               int var = live_intervals->var_from_reg(inst->src[i]);

               for (unsigned j = 0; j < regs_read(inst, i); j++) {
                  BITSET_SET(live, var + j);
               }
            }
         }

         flag_live[0] |= inst->flags_read(devinfo);
      }
   }

   ralloc_free(live);
   ralloc_free(flag_live);

   if (progress)
      invalidate_live_intervals();

   return progress;
}
<commit_msg>i965: Combine some dead code elimination NOP'ing code.<commit_after>/*
 * Copyright © 2014 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "brw_fs.h"
#include "brw_fs_live_variables.h"
#include "brw_cfg.h"

/** @file brw_fs_dead_code_eliminate.cpp
 *
 * Dataflow-aware dead code elimination.
 *
 * Walks the instruction list from the bottom, removing instructions that
 * have results that both aren't used in later blocks and haven't been read
 * yet in the tail end of this block.
 */

bool
fs_visitor::dead_code_eliminate()
{
   bool progress = false;

   calculate_live_intervals();

   int num_vars = live_intervals->num_vars;
   BITSET_WORD *live = rzalloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
   BITSET_WORD *flag_live = rzalloc_array(NULL, BITSET_WORD, 1);

   foreach_block_reverse_safe(block, cfg) {
      memcpy(live, live_intervals->block_data[block->num].liveout,
             sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
      memcpy(flag_live, live_intervals->block_data[block->num].flag_liveout,
             sizeof(BITSET_WORD));

      foreach_inst_in_block_reverse_safe(fs_inst, inst, block) {
         if (inst->dst.file == VGRF && !inst->has_side_effects()) {
            const unsigned var = live_intervals->var_from_reg(inst->dst);
            bool result_live = false;

            for (unsigned i = 0; i < regs_written(inst); i++)
               result_live |= BITSET_TEST(live, var + i);

            if (!result_live) {
               progress = true;

               if (inst->writes_accumulator || inst->flags_written()) {
                  inst->dst = fs_reg(retype(brw_null_reg(), inst->dst.type));
               } else {
                  inst->opcode = BRW_OPCODE_NOP;
               }
            }
         }

         if (inst->dst.is_null() &&
             !inst->is_control_flow() &&
             !inst->has_side_effects() &&
             !(flag_live[0] & inst->flags_written()) &&
             !inst->writes_accumulator) {
            inst->opcode = BRW_OPCODE_NOP;
            progress = true;
         }

         if (inst->dst.file == VGRF) {
            if (!inst->is_partial_write()) {
               int var = live_intervals->var_from_reg(inst->dst);
               for (unsigned i = 0; i < regs_written(inst); i++) {
                  BITSET_CLEAR(live, var + i);
               }
            }
         }

         if (!inst->predicate && inst->exec_size >= 8)
            flag_live[0] &= ~inst->flags_written();

         if (inst->opcode == BRW_OPCODE_NOP) {
            inst->remove(block);
            continue;
         }

         for (int i = 0; i < inst->sources; i++) {
            if (inst->src[i].file == VGRF) {
               int var = live_intervals->var_from_reg(inst->src[i]);

               for (unsigned j = 0; j < regs_read(inst, i); j++) {
                  BITSET_SET(live, var + j);
               }
            }
         }

         flag_live[0] |= inst->flags_read(devinfo);
      }
   }

   ralloc_free(live);
   ralloc_free(flag_live);

   if (progress)
      invalidate_live_intervals();

   return progress;
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2009, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author 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 <ctime>
#include <string>
#include <cstdio>
#include <boost/limits.hpp>
#include <boost/version.hpp>
#include "libtorrent/config.hpp"
#include "libtorrent/time.hpp"

#ifndef _WIN32
#include <unistd.h>
#endif

namespace libtorrent
{
	namespace aux
	{
		// used to cache the current time
		// every 100 ms. This is cheaper
		// than a system call and can be
		// used where more accurate time
		// is not necessary
		ptime g_current_time;
	}

	ptime const& TORRENT_EXPORT time_now() { return aux::g_current_time; }

	char const* time_now_string()
	{
//		time_t t = std::time(0);
//		tm* timeinfo = std::localtime(&t);
//		static char str[200];
//		std::strftime(str, 200, "%b %d %X", timeinfo);
//		return str;

		static const ptime start = time_now_hires();
		static char ret[200];
		int t = total_milliseconds(time_now_hires() - start);
		int h = t / 1000 / 60 / 60;
		t -= h * 60 * 60 * 1000;
		int m = t / 1000 / 60;
		t -= m * 60 * 1000;
		int s = t / 1000;
		t -= s * 1000;
		int ms = t;
		snprintf(ret, sizeof(ret), "%02d:%02d:%02d.%03d", h, m, s, ms);
		return ret;
	}

	std::string log_time()
	{
		static const ptime start = time_now_hires();
		char ret[200];
		snprintf(ret, sizeof(ret), "%d", total_microseconds(time_now_hires() - start));
		return ret;
	}
}

#if defined TORRENT_USE_BOOST_DATE_TIME

#include <boost/date_time/microsec_time_clock.hpp>

namespace libtorrent
{
	ptime time_now_hires()
	{ return boost::date_time::microsec_clock<ptime>::universal_time(); }
	ptime min_time()
	{ return boost::posix_time::ptime(boost::posix_time::min_date_time); }
	ptime max_time()
	{ return boost::posix_time::ptime(boost::posix_time::max_date_time); }
	time_duration seconds(int s) { return boost::posix_time::seconds(s); }
	time_duration milliseconds(int s) { return boost::posix_time::milliseconds(s); }
	time_duration microsec(int s) { return boost::posix_time::microsec(s); }
	time_duration minutes(int s) { return boost::posix_time::minutes(s); }
	time_duration hours(int s) { return boost::posix_time::hours(s); }

	int total_seconds(time_duration td)
	{ return td.total_seconds(); }
	int total_milliseconds(time_duration td)
	{ return td.total_milliseconds(); }
	boost::int64_t total_microseconds(time_duration td)
	{ return td.total_microseconds(); }
}

#else // TORRENT_USE_BOOST_DATE_TIME

namespace libtorrent
{
	ptime min_time() { return ptime(0); }
	ptime max_time() { return ptime((std::numeric_limits<boost::uint64_t>::max)()); }
}

#if defined TORRENT_USE_ABSOLUTE_TIME

#include <mach/mach_time.h>
#include <boost/cstdint.hpp>
#include "libtorrent/assert.hpp"

// high precision timer for darwin intel and ppc

namespace libtorrent
{
	ptime time_now_hires()
	{
		static mach_timebase_info_data_t timebase_info = {0,0};
		if (timebase_info.denom == 0)
			mach_timebase_info(&timebase_info);
		boost::uint64_t at = mach_absolute_time();
		// make sure we don't overflow
		TORRENT_ASSERT((at >= 0 && at >= at / 1000 * timebase_info.numer / timebase_info.denom)
			|| (at < 0 && at < at / 1000 * timebase_info.numer / timebase_info.denom));
		return ptime(at / 1000 * timebase_info.numer / timebase_info.denom);
	}
}
#elif defined TORRENT_USE_QUERY_PERFORMANCE_TIMER

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include "libtorrent/assert.hpp"

namespace libtorrent
{
	namespace aux
	{
		boost::int64_t performance_counter_to_microseconds(boost::int64_t pc)
		{
			static LARGE_INTEGER performace_counter_frequency = {0,0};
			if (performace_counter_frequency.QuadPart == 0)
				QueryPerformanceFrequency(&performace_counter_frequency);

#ifdef TORRENT_DEBUG
			// make sure we don't overflow
			boost::int64_t ret = (pc * 1000 / performace_counter_frequency.QuadPart) * 1000;
			TORRENT_ASSERT((pc >= 0 && pc >= ret) || (pc < 0 && pc < ret));
#endif
			return (pc * 1000 / performace_counter_frequency.QuadPart) * 1000;
		}

		boost::int64_t microseconds_to_performance_counter(boost::int64_t ms)
		{
			static LARGE_INTEGER performace_counter_frequency = {0,0};
			if (performace_counter_frequency.QuadPart == 0)
				QueryPerformanceFrequency(&performace_counter_frequency);
#ifdef TORRENT_DEBUG
			// make sure we don't overflow
			boost::int64_t ret = (ms / 1000) * performace_counter_frequency.QuadPart / 1000;
			TORRENT_ASSERT((ms >= 0 && ms <= ret)
				|| (ms < 0 && ms > ret));
#endif
			return (ms / 1000) * performace_counter_frequency.QuadPart / 1000;
		}
	}

	ptime time_now_hires()
	{
		LARGE_INTEGER now;
		QueryPerformanceCounter(&now);
		return ptime(now.QuadPart);
	}
}

#elif defined TORRENT_USE_CLOCK_GETTIME

#include <time.h>
#include "libtorrent/assert.hpp"

namespace libtorrent
{
	ptime time_now_hires()
	{
		timespec ts;
		clock_gettime(CLOCK_MONOTONIC, &ts);
		return ptime(boost::uint64_t(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000);
	}
}

#elif defined TORRENT_USE_SYSTEM_TIME

#include <kernel/OS.h>

namespace libtorrent
{
	ptime time_now_hires()
	{ return ptime(system_time()); }
}

#endif // TORRENT_USE_SYSTEM_TIME

#endif // TORRENT_USE_BOOST_DATE_TIME

<commit_msg>fix log_time string formatting issue<commit_after>/*

Copyright (c) 2009, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author 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 <ctime>
#include <string>
#include <cstdio>
#include <boost/limits.hpp>
#include <boost/version.hpp>
#include "libtorrent/config.hpp"
#include "libtorrent/time.hpp"

#ifndef _WIN32
#include <unistd.h>
#endif

namespace libtorrent
{
	namespace aux
	{
		// used to cache the current time
		// every 100 ms. This is cheaper
		// than a system call and can be
		// used where more accurate time
		// is not necessary
		ptime g_current_time;
	}

	ptime const& TORRENT_EXPORT time_now() { return aux::g_current_time; }

	char const* time_now_string()
	{
//		time_t t = std::time(0);
//		tm* timeinfo = std::localtime(&t);
//		static char str[200];
//		std::strftime(str, 200, "%b %d %X", timeinfo);
//		return str;

		static const ptime start = time_now_hires();
		static char ret[200];
		int t = total_milliseconds(time_now_hires() - start);
		int h = t / 1000 / 60 / 60;
		t -= h * 60 * 60 * 1000;
		int m = t / 1000 / 60;
		t -= m * 60 * 1000;
		int s = t / 1000;
		t -= s * 1000;
		int ms = t;
		snprintf(ret, sizeof(ret), "%02d:%02d:%02d.%03d", h, m, s, ms);
		return ret;
	}

	std::string log_time()
	{
		static const ptime start = time_now_hires();
		char ret[200];
		snprintf(ret, sizeof(ret), "%"PRId64, total_microseconds(time_now_hires() - start));
		return ret;
	}
}

#if defined TORRENT_USE_BOOST_DATE_TIME

#include <boost/date_time/microsec_time_clock.hpp>

namespace libtorrent
{
	ptime time_now_hires()
	{ return boost::date_time::microsec_clock<ptime>::universal_time(); }
	ptime min_time()
	{ return boost::posix_time::ptime(boost::posix_time::min_date_time); }
	ptime max_time()
	{ return boost::posix_time::ptime(boost::posix_time::max_date_time); }
	time_duration seconds(int s) { return boost::posix_time::seconds(s); }
	time_duration milliseconds(int s) { return boost::posix_time::milliseconds(s); }
	time_duration microsec(int s) { return boost::posix_time::microsec(s); }
	time_duration minutes(int s) { return boost::posix_time::minutes(s); }
	time_duration hours(int s) { return boost::posix_time::hours(s); }

	int total_seconds(time_duration td)
	{ return td.total_seconds(); }
	int total_milliseconds(time_duration td)
	{ return td.total_milliseconds(); }
	boost::int64_t total_microseconds(time_duration td)
	{ return td.total_microseconds(); }
}

#else // TORRENT_USE_BOOST_DATE_TIME

namespace libtorrent
{
	ptime min_time() { return ptime(0); }
	ptime max_time() { return ptime((std::numeric_limits<boost::uint64_t>::max)()); }
}

#if defined TORRENT_USE_ABSOLUTE_TIME

#include <mach/mach_time.h>
#include <boost/cstdint.hpp>
#include "libtorrent/assert.hpp"

// high precision timer for darwin intel and ppc

namespace libtorrent
{
	ptime time_now_hires()
	{
		static mach_timebase_info_data_t timebase_info = {0,0};
		if (timebase_info.denom == 0)
			mach_timebase_info(&timebase_info);
		boost::uint64_t at = mach_absolute_time();
		// make sure we don't overflow
		TORRENT_ASSERT((at >= 0 && at >= at / 1000 * timebase_info.numer / timebase_info.denom)
			|| (at < 0 && at < at / 1000 * timebase_info.numer / timebase_info.denom));
		return ptime(at / 1000 * timebase_info.numer / timebase_info.denom);
	}
}
#elif defined TORRENT_USE_QUERY_PERFORMANCE_TIMER

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include "libtorrent/assert.hpp"

namespace libtorrent
{
	namespace aux
	{
		boost::int64_t performance_counter_to_microseconds(boost::int64_t pc)
		{
			static LARGE_INTEGER performace_counter_frequency = {0,0};
			if (performace_counter_frequency.QuadPart == 0)
				QueryPerformanceFrequency(&performace_counter_frequency);

#ifdef TORRENT_DEBUG
			// make sure we don't overflow
			boost::int64_t ret = (pc * 1000 / performace_counter_frequency.QuadPart) * 1000;
			TORRENT_ASSERT((pc >= 0 && pc >= ret) || (pc < 0 && pc < ret));
#endif
			return (pc * 1000 / performace_counter_frequency.QuadPart) * 1000;
		}

		boost::int64_t microseconds_to_performance_counter(boost::int64_t ms)
		{
			static LARGE_INTEGER performace_counter_frequency = {0,0};
			if (performace_counter_frequency.QuadPart == 0)
				QueryPerformanceFrequency(&performace_counter_frequency);
#ifdef TORRENT_DEBUG
			// make sure we don't overflow
			boost::int64_t ret = (ms / 1000) * performace_counter_frequency.QuadPart / 1000;
			TORRENT_ASSERT((ms >= 0 && ms <= ret)
				|| (ms < 0 && ms > ret));
#endif
			return (ms / 1000) * performace_counter_frequency.QuadPart / 1000;
		}
	}

	ptime time_now_hires()
	{
		LARGE_INTEGER now;
		QueryPerformanceCounter(&now);
		return ptime(now.QuadPart);
	}
}

#elif defined TORRENT_USE_CLOCK_GETTIME

#include <time.h>
#include "libtorrent/assert.hpp"

namespace libtorrent
{
	ptime time_now_hires()
	{
		timespec ts;
		clock_gettime(CLOCK_MONOTONIC, &ts);
		return ptime(boost::uint64_t(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000);
	}
}

#elif defined TORRENT_USE_SYSTEM_TIME

#include <kernel/OS.h>

namespace libtorrent
{
	ptime time_now_hires()
	{ return ptime(system_time()); }
}

#endif // TORRENT_USE_SYSTEM_TIME

#endif // TORRENT_USE_BOOST_DATE_TIME

<|endoftext|>


<commit_before>/* Copyright (C) 2005-2009, Thorvald Natvig <thorvald@natvig.com>
   Copyright (C) 2008-2009, Mikkel Krautz <mikkel@krautz.dk>

   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers 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 FOUNDATION 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 "GlobalShortcut_macx.h"

#define MOD_OFFSET   0x10000
#define MOUSE_OFFSET 0x20000

/*
 * We use DeferInit in here to pop up a dialog box if their system isn't
 * properly set up to receieve global keyboard/mouse events.
 */

GlobalShortcutMacInit::GlobalShortcutMacInit() : QObject(NULL) {
}

void GlobalShortcutMacInit::initialize() {
	if (!accessibilityApiEnabled())
		accessibilityDialog();
}

bool GlobalShortcutMacInit::accessibilityApiEnabled() const {
	return QFile::exists("/private/var/db/.AccessibilityAPIEnabled");
}

void GlobalShortcutMacInit::openPrefsPane(const QString &) const {
	system("open /Applications/System\\ Preferences.app/ /System/Library/PreferencePanes/UniversalAccessPref.prefPane/");
}

void GlobalShortcutMacInit::accessibilityDialog() const {
	QMessageBox mb("Mumble",
	               tr("Mumble has detected that it is unable to receive Global Shortcut events when it is in the background.

"
	                  "This is because the Universal Access feature called 'Enable access for assistive devices' is currently disabled.

"
	                  "Please enable this setting and continue when done."),
	               QMessageBox::Question, QMessageBox::Ok | QMessageBox::Default, QMessageBox::NoButton, QMessageBox::NoButton);

	QLabel *label = mb.findChild<QLabel *>(QLatin1String("qt_msgbox_label"));
	label->setOpenExternalLinks(false);
	connect(label, SIGNAL(linkActivated(const QString &)), this, SLOT(openPrefsPane(const QString &)));

	mb.exec();
}

static GlobalShortcutMacInit gsminit;

/* --- */

GlobalShortcutEngine *GlobalShortcutEngine::platformInit() {
	return new GlobalShortcutMac();
}

CGEventRef EventTapCallback(CGEventTapProxy proxy, CGEventType type,
                            CGEventRef event, void *udata) {
	GlobalShortcutMac *gs = reinterpret_cast<GlobalShortcutMac *>(udata);
	unsigned int keycode;
	bool suppress = false;
	bool down = false;
	int64_t repeat = 0;

	switch (type) {
		case kCGEventLeftMouseDown:
		case kCGEventRightMouseDown:
		case kCGEventOtherMouseDown:
			down = true;
		case kCGEventLeftMouseUp:
		case kCGEventRightMouseUp:
		case kCGEventOtherMouseUp:
			keycode = static_cast<unsigned int>(CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber));
			suppress = gs->handleButton(MOUSE_OFFSET+keycode, down);
			/* Suppressing "the" mouse button is probably not a good idea :-) */
			if (keycode == 0)
				suppress = false;
			break;

		case kCGEventKeyDown:
			down = true;
		case kCGEventKeyUp:
			repeat = CGEventGetIntegerValueField(event, kCGKeyboardEventAutorepeat);
			if (! repeat) {
				keycode = static_cast<unsigned int>(CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode));
				suppress = gs->handleButton(keycode, down);
			}
			break;

		case kCGEventFlagsChanged:
			suppress = gs->handleModButton(CGEventGetFlags(event));
			break;
	}

	return suppress ? NULL : event;
}

GlobalShortcutMac::GlobalShortcutMac() : modmask(0) {

	static const CGEventType evmask = CGEventMaskBit(kCGEventLeftMouseDown) |
	                                  CGEventMaskBit(kCGEventLeftMouseUp) |
	                                  CGEventMaskBit(kCGEventRightMouseDown) |
	                                  CGEventMaskBit(kCGEventRightMouseUp) |
	                                  CGEventMaskBit(kCGEventOtherMouseDown) |
	                                  CGEventMaskBit(kCGEventOtherMouseUp) |
	                                  CGEventMaskBit(kCGEventKeyDown) |
	                                  CGEventMaskBit(kCGEventKeyUp) |
	                                  CGEventMaskBit(kCGEventFlagsChanged);

	port = CGEventTapCreate(kCGSessionEventTap,
	                        kCGHeadInsertEventTap,
	                        0, evmask, EventTapCallback,
	                        this);

	if (! port) {
		qWarning("GlobalShortcutMac: Unable to create EventTap. Global Shortcuts will not be available.");
		return;
	}

	kbdLayout = NULL;
	if (TISCopyCurrentKeyboardInputSource && TISGetInputSourceProperty) {
		TISInputSourceRef inputSource = TISCopyCurrentKeyboardInputSource();
		if (inputSource) {
			CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(inputSource, kTISPropertyUnicodeKeyLayoutData));
			if (data)
				kbdLayout = reinterpret_cast<UCKeyboardLayout *>(const_cast<UInt8 *>(CFDataGetBytePtr(data)));
		}
	} else {
		SInt16 currentKeyScript = GetScriptManagerVariable(smKeyScript);
		SInt16 lastKeyLayoutID = GetScriptVariable(currentKeyScript, smScriptKeys);
		Handle handle = GetResource('uchr', lastKeyLayoutID);
		if (handle)
			kbdLayout = reinterpret_cast<UCKeyboardLayout *>(*handle);
	}
	if (! kbdLayout)
		qWarning("GlobalShortcutMac: No keyboard layout mapping available. Unable to perform key translation.");

	start(QThread::TimeCriticalPriority);
}

GlobalShortcutMac::~GlobalShortcutMac() {
	CFRunLoopStop(loop);
	loop = NULL;
	wait();
}

void GlobalShortcutMac::run() {
	loop = CFRunLoopGetCurrent();
	CFRunLoopSourceRef src = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, port, 0);
	CFRunLoopAddSource(loop, src, kCFRunLoopCommonModes);
	CFRunLoopRun();
}

void GlobalShortcutMac::needRemap() {
	remap();
}

bool GlobalShortcutMac::handleModButton(const CGEventFlags newmask) {
	bool down;
	bool suppress = false;

#define MOD_CHANGED(mask, btn) do { \
	    if ((newmask & mask) != (modmask & mask)) { \
	        down = newmask & mask; \
	        suppress = handleButton(MOD_OFFSET+btn, down); \
	        modmask = newmask; \
	        return suppress; \
	    }} while (0)

	MOD_CHANGED(kCGEventFlagMaskAlphaShift, 0);
	MOD_CHANGED(kCGEventFlagMaskShift, 1);
	MOD_CHANGED(kCGEventFlagMaskControl, 2);
	MOD_CHANGED(kCGEventFlagMaskAlternate, 3);
	MOD_CHANGED(kCGEventFlagMaskCommand, 4);
	MOD_CHANGED(kCGEventFlagMaskHelp, 5);
	MOD_CHANGED(kCGEventFlagMaskSecondaryFn, 6);
	MOD_CHANGED(kCGEventFlagMaskNumericPad, 7);
}

QString GlobalShortcutMac::translateMouseButton(const unsigned int keycode) const {
	return QString("Mouse Button %1").arg(keycode-MOUSE_OFFSET+1);
}

QString GlobalShortcutMac::translateModifierKey(const unsigned int keycode) const {
	unsigned int key = keycode - MOD_OFFSET;
	switch (key) {
		case 0:
			return QString("Caps Lock");
		case 1:
			return QString("Shift");
		case 2:
			return QString("Control");
		case 3:
			return QString("Alt/Option");
		case 4:
			return QString("Command");
		case 5:
			return QString("Help");
		case 6:
			return QString("Fn");
		case 7:
			return QString("Num Lock");
	}
	return QString("Modifier %1").arg(key);
}

QString GlobalShortcutMac::translateKeyName(const unsigned int keycode) const {
	UInt32 junk = 0;
	UniCharCount len = 64;
	UniChar unicodeString[len];

	if (! kbdLayout)
		return QString();

	OSStatus err = UCKeyTranslate(kbdLayout, static_cast<UInt16>(keycode),
	                              kUCKeyActionDisplay, 0, LMGetKbdType(),
	                              kUCKeyTranslateNoDeadKeysBit, &junk,
	                              len, &len, unicodeString);
	if (err != noErr)
		return QString();

	if (len == 1) {
		switch (unicodeString[0]) {
			case '\t':
				return QString("Tab");
			case '\r':
				return QString("Enter");
			case '\b':
				return QString("Backspace");
			case '\e':
				return QString("Escape");
			case ' ':
				return QString("Space");
			case 28:
				return QString("Left");
			case 29:
				return QString("Right");
			case 30:
				return QString("Up");
			case 31:
				return QString("Down");
		}

		if (unicodeString[0] < ' ') {
			qWarning("GlobalShortcutMac: Unknown translation for keycode %u: %u", keycode, unicodeString[0]);
			return QString();
		}
	}

	return QString(reinterpret_cast<const QChar *>(unicodeString), len).toUpper();
}

QString GlobalShortcutMac::buttonName(const QVariant &v) {
	bool ok;
	unsigned int key = v.toUInt(&ok);
	if (!ok)
		return QString();

	if (key >= MOUSE_OFFSET)
		return translateMouseButton(key);
	else if (key >= MOD_OFFSET)
		return translateModifierKey(key);
	else {
		QString str = translateKeyName(key);
		if (!str.isEmpty())
			return str;
	}

	return QString("Keycode %1").arg(key);
}

bool GlobalShortcutMac::canSuppress() {
	return true;
}
<commit_msg>Make GlobalShortuctMac build with 10.4 SDK once again.<commit_after>/* Copyright (C) 2005-2009, Thorvald Natvig <thorvald@natvig.com>
   Copyright (C) 2008-2009, Mikkel Krautz <mikkel@krautz.dk>

   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
     and/or other materials provided with the distribution.
   - Neither the name of the Mumble Developers 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 FOUNDATION 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 "GlobalShortcut_macx.h"

#define MOD_OFFSET   0x10000
#define MOUSE_OFFSET 0x20000

/*
 * We use DeferInit in here to pop up a dialog box if their system isn't
 * properly set up to receieve global keyboard/mouse events.
 */

GlobalShortcutMacInit::GlobalShortcutMacInit() : QObject(NULL) {
}

void GlobalShortcutMacInit::initialize() {
	if (!accessibilityApiEnabled())
		accessibilityDialog();
}

bool GlobalShortcutMacInit::accessibilityApiEnabled() const {
	return QFile::exists("/private/var/db/.AccessibilityAPIEnabled");
}

void GlobalShortcutMacInit::openPrefsPane(const QString &) const {
	system("open /Applications/System\\ Preferences.app/ /System/Library/PreferencePanes/UniversalAccessPref.prefPane/");
}

void GlobalShortcutMacInit::accessibilityDialog() const {
	QMessageBox mb("Mumble",
	               tr("Mumble has detected that it is unable to receive Global Shortcut events when it is in the background.

"
	                  "This is because the Universal Access feature called 'Enable access for assistive devices' is currently disabled.

"
	                  "Please enable this setting and continue when done."),
	               QMessageBox::Question, QMessageBox::Ok | QMessageBox::Default, QMessageBox::NoButton, QMessageBox::NoButton);

	QLabel *label = mb.findChild<QLabel *>(QLatin1String("qt_msgbox_label"));
	label->setOpenExternalLinks(false);
	connect(label, SIGNAL(linkActivated(const QString &)), this, SLOT(openPrefsPane(const QString &)));

	mb.exec();
}

static GlobalShortcutMacInit gsminit;

/* --- */

GlobalShortcutEngine *GlobalShortcutEngine::platformInit() {
	return new GlobalShortcutMac();
}

CGEventRef EventTapCallback(CGEventTapProxy proxy, CGEventType type,
                            CGEventRef event, void *udata) {
	GlobalShortcutMac *gs = reinterpret_cast<GlobalShortcutMac *>(udata);
	unsigned int keycode;
	bool suppress = false;
	bool down = false;
	int64_t repeat = 0;

	switch (type) {
		case kCGEventLeftMouseDown:
		case kCGEventRightMouseDown:
		case kCGEventOtherMouseDown:
			down = true;
		case kCGEventLeftMouseUp:
		case kCGEventRightMouseUp:
		case kCGEventOtherMouseUp:
			keycode = static_cast<unsigned int>(CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber));
			suppress = gs->handleButton(MOUSE_OFFSET+keycode, down);
			/* Suppressing "the" mouse button is probably not a good idea :-) */
			if (keycode == 0)
				suppress = false;
			break;

		case kCGEventKeyDown:
			down = true;
		case kCGEventKeyUp:
			repeat = CGEventGetIntegerValueField(event, kCGKeyboardEventAutorepeat);
			if (! repeat) {
				keycode = static_cast<unsigned int>(CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode));
				suppress = gs->handleButton(keycode, down);
			}
			break;

		case kCGEventFlagsChanged:
			suppress = gs->handleModButton(CGEventGetFlags(event));
			break;
	}

	return suppress ? NULL : event;
}

GlobalShortcutMac::GlobalShortcutMac() : modmask(0) {

	static const CGEventType evmask = CGEventMaskBit(kCGEventLeftMouseDown) |
	                                  CGEventMaskBit(kCGEventLeftMouseUp) |
	                                  CGEventMaskBit(kCGEventRightMouseDown) |
	                                  CGEventMaskBit(kCGEventRightMouseUp) |
	                                  CGEventMaskBit(kCGEventOtherMouseDown) |
	                                  CGEventMaskBit(kCGEventOtherMouseUp) |
	                                  CGEventMaskBit(kCGEventKeyDown) |
	                                  CGEventMaskBit(kCGEventKeyUp) |
	                                  CGEventMaskBit(kCGEventFlagsChanged);

	port = CGEventTapCreate(kCGSessionEventTap,
	                        kCGHeadInsertEventTap,
	                        0, evmask, EventTapCallback,
	                        this);

	if (! port) {
		qWarning("GlobalShortcutMac: Unable to create EventTap. Global Shortcuts will not be available.");
		return;
	}

	kbdLayout = NULL;

#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
	if (TISCopyCurrentKeyboardInputSource && TISGetInputSourceProperty) {
		TISInputSourceRef inputSource = TISCopyCurrentKeyboardInputSource();
		if (inputSource) {
			CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(inputSource, kTISPropertyUnicodeKeyLayoutData));
			if (data)
				kbdLayout = reinterpret_cast<UCKeyboardLayout *>(const_cast<UInt8 *>(CFDataGetBytePtr(data)));
		}
	} else
#endif
	{
		SInt16 currentKeyScript = GetScriptManagerVariable(smKeyScript);
		SInt16 lastKeyLayoutID = GetScriptVariable(currentKeyScript, smScriptKeys);
		Handle handle = GetResource('uchr', lastKeyLayoutID);
		if (handle)
			kbdLayout = reinterpret_cast<UCKeyboardLayout *>(*handle);
	}
	if (! kbdLayout)
		qWarning("GlobalShortcutMac: No keyboard layout mapping available. Unable to perform key translation.");

	start(QThread::TimeCriticalPriority);
}

GlobalShortcutMac::~GlobalShortcutMac() {
	CFRunLoopStop(loop);
	loop = NULL;
	wait();
}

void GlobalShortcutMac::run() {
	loop = CFRunLoopGetCurrent();
	CFRunLoopSourceRef src = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, port, 0);
	CFRunLoopAddSource(loop, src, kCFRunLoopCommonModes);
	CFRunLoopRun();
}

void GlobalShortcutMac::needRemap() {
	remap();
}

bool GlobalShortcutMac::handleModButton(const CGEventFlags newmask) {
	bool down;
	bool suppress = false;

#define MOD_CHANGED(mask, btn) do { \
	    if ((newmask & mask) != (modmask & mask)) { \
	        down = newmask & mask; \
	        suppress = handleButton(MOD_OFFSET+btn, down); \
	        modmask = newmask; \
	        return suppress; \
	    }} while (0)

	MOD_CHANGED(kCGEventFlagMaskAlphaShift, 0);
	MOD_CHANGED(kCGEventFlagMaskShift, 1);
	MOD_CHANGED(kCGEventFlagMaskControl, 2);
	MOD_CHANGED(kCGEventFlagMaskAlternate, 3);
	MOD_CHANGED(kCGEventFlagMaskCommand, 4);
	MOD_CHANGED(kCGEventFlagMaskHelp, 5);
	MOD_CHANGED(kCGEventFlagMaskSecondaryFn, 6);
	MOD_CHANGED(kCGEventFlagMaskNumericPad, 7);
}

QString GlobalShortcutMac::translateMouseButton(const unsigned int keycode) const {
	return QString("Mouse Button %1").arg(keycode-MOUSE_OFFSET+1);
}

QString GlobalShortcutMac::translateModifierKey(const unsigned int keycode) const {
	unsigned int key = keycode - MOD_OFFSET;
	switch (key) {
		case 0:
			return QString("Caps Lock");
		case 1:
			return QString("Shift");
		case 2:
			return QString("Control");
		case 3:
			return QString("Alt/Option");
		case 4:
			return QString("Command");
		case 5:
			return QString("Help");
		case 6:
			return QString("Fn");
		case 7:
			return QString("Num Lock");
	}
	return QString("Modifier %1").arg(key);
}

QString GlobalShortcutMac::translateKeyName(const unsigned int keycode) const {
	UInt32 junk = 0;
	UniCharCount len = 64;
	UniChar unicodeString[len];

	if (! kbdLayout)
		return QString();

	OSStatus err = UCKeyTranslate(kbdLayout, static_cast<UInt16>(keycode),
	                              kUCKeyActionDisplay, 0, LMGetKbdType(),
	                              kUCKeyTranslateNoDeadKeysBit, &junk,
	                              len, &len, unicodeString);
	if (err != noErr)
		return QString();

	if (len == 1) {
		switch (unicodeString[0]) {
			case '\t':
				return QString("Tab");
			case '\r':
				return QString("Enter");
			case '\b':
				return QString("Backspace");
			case '\e':
				return QString("Escape");
			case ' ':
				return QString("Space");
			case 28:
				return QString("Left");
			case 29:
				return QString("Right");
			case 30:
				return QString("Up");
			case 31:
				return QString("Down");
		}

		if (unicodeString[0] < ' ') {
			qWarning("GlobalShortcutMac: Unknown translation for keycode %u: %u", keycode, unicodeString[0]);
			return QString();
		}
	}

	return QString(reinterpret_cast<const QChar *>(unicodeString), len).toUpper();
}

QString GlobalShortcutMac::buttonName(const QVariant &v) {
	bool ok;
	unsigned int key = v.toUInt(&ok);
	if (!ok)
		return QString();

	if (key >= MOUSE_OFFSET)
		return translateMouseButton(key);
	else if (key >= MOD_OFFSET)
		return translateModifierKey(key);
	else {
		QString str = translateKeyName(key);
		if (!str.isEmpty())
			return str;
	}

	return QString("Keycode %1").arg(key);
}

bool GlobalShortcutMac::canSuppress() {
	return true;
}
<|endoftext|>


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

#include <fstream>

#include "ngraph/function.hpp"
#include "ngraph/graph_util.hpp"
#include "ngraph/node.hpp"
#include "ngraph/pass/pass.hpp"
#include "ngraph/pass/visualize_tree.hpp"
#include "ngraph/util.hpp"

using namespace ngraph;
using namespace std;

bool pass::VisualizeTree::run_on_module(vector<shared_ptr<ngraph::Function>>& functions)
{
    for (shared_ptr<Function> f : functions)
    {
        // map<size_t, list<node_ptr>> dependent_nodes;
        traverse_nodes(f, [&](shared_ptr<Node> node) {
            for (auto arg : node->get_input_ops())
            {
                m_ss << add_attributes(arg);
                m_ss << add_attributes(node);
                m_ss << "    " << arg->get_name() << " -> " << node->get_name();
                m_ss << ";\n";
            }
        });
    }

    render();

    return false;
}

pass::VisualizeTree::VisualizeTree(const string& file_name)
    : m_name{file_name}
{
}

std::string pass::VisualizeTree::add_attributes(shared_ptr<Node> node)
{
    string rc;
    if (!contains(m_nodes_with_attributes, node))
    {
        m_nodes_with_attributes.insert(node);
        rc = get_attributes(node);
    }
    return rc;
}

std::string pass::VisualizeTree::get_attributes(shared_ptr<Node> node)
{
    stringstream ss;
    if (node->is_parameter() || node->is_output())
    {
        ss << "    " << node->get_name() << " [shape=box ";
        if (node->is_parameter())
        {
            ss << "color=blue ";
        }
        if (node->is_output())
        {
            ss << "style=filled fillcolor=pink ";
        }
    }
    else
    {
        ss << "    " << node->get_name() << " [shape=ellipse color=black";
    }

    ss << " label=\"" << node->get_name();

    if (std::getenv("NGRAPH_VISUALIZE_TREE_OUTPUT_SHAPES") != nullptr)
    {
        ss << " " << vector_to_string(node->get_shape());
    }

    ss << " \"]\n";

    return ss.str();
}

void pass::VisualizeTree::render() const
{
#ifdef GRAPHVIZ_FOUND
    auto tmp_file = m_name + ".tmp";
    ofstream out(tmp_file);
    if (out)
    {
        out << "digraph ngraph\n{\n";
        out << m_ss.str();
        out << "}\n";
        out.close();

        stringstream ss;

        const char* format = std::getenv("NGRAPH_VISUALIZE_TREE_OUTPUT_FORMAT");
        if (!format)
        {
            format = "png";
        }

        ss << "dot -T" << format << " " << tmp_file << " -o " << m_name;
        auto cmd = ss.str();
        auto stream = popen(cmd.c_str(), "r");
        pclose(stream);

        remove(tmp_file.c_str());
    }
#endif
}
<commit_msg>add edge labels (#678)<commit_after>/*******************************************************************************
* Copyright 2017-2018 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

#include <fstream>

#include "ngraph/function.hpp"
#include "ngraph/graph_util.hpp"
#include "ngraph/node.hpp"
#include "ngraph/ops/get_output_element.hpp"
#include "ngraph/pass/pass.hpp"
#include "ngraph/pass/visualize_tree.hpp"
#include "ngraph/util.hpp"

using namespace ngraph;
using namespace std;

bool pass::VisualizeTree::run_on_module(vector<shared_ptr<ngraph::Function>>& functions)
{
    for (shared_ptr<Function> f : functions)
    {
        // map<size_t, list<node_ptr>> dependent_nodes;
        traverse_nodes(f, [&](shared_ptr<Node> node) {
            size_t i = 0;
            for (auto arg : node->get_input_ops())
            {
                m_ss << add_attributes(arg);
                m_ss << add_attributes(node);
                m_ss << "    " << arg->get_name() << " -> " << node->get_name();

                if (std::getenv("NGRAPH_VISUALIZE_EDGE_LABELS") != nullptr)
                {
                    size_t output = 0;
                    if (auto goe = std::dynamic_pointer_cast<op::GetOutputElement>(node))
                    {
                        output = goe->get_n();
                    }
                    stringstream label_edge;
                    label_edge << "[label=\" " << output << " -> " << i << " \"]";
                    m_ss << label_edge.str();
                }

                m_ss << ";\n";
                i++;
            }
        });
    }

    render();

    return false;
}

pass::VisualizeTree::VisualizeTree(const string& file_name)
    : m_name{file_name}
{
}

std::string pass::VisualizeTree::add_attributes(shared_ptr<Node> node)
{
    string rc;
    if (!contains(m_nodes_with_attributes, node))
    {
        m_nodes_with_attributes.insert(node);
        rc = get_attributes(node);
    }
    return rc;
}

std::string pass::VisualizeTree::get_attributes(shared_ptr<Node> node)
{
    stringstream ss;
    if (node->is_parameter() || node->is_output())
    {
        ss << "    " << node->get_name() << " [shape=box ";
        if (node->is_parameter())
        {
            ss << "color=blue ";
        }
        if (node->is_output())
        {
            ss << "style=filled fillcolor=pink ";
        }
    }
    else
    {
        ss << "    " << node->get_name() << " [shape=ellipse color=black";
    }

    ss << " label=\"" << node->get_name();

    if (std::getenv("NGRAPH_VISUALIZE_TREE_OUTPUT_SHAPES") != nullptr)
    {
        ss << " " << vector_to_string(node->get_shape());
    }

    ss << " \"]\n";

    return ss.str();
}

void pass::VisualizeTree::render() const
{
#ifdef GRAPHVIZ_FOUND
    auto tmp_file = m_name + ".tmp";
    ofstream out(tmp_file);
    if (out)
    {
        out << "digraph ngraph\n{\n";
        out << m_ss.str();
        out << "}\n";
        out.close();

        stringstream ss;

        const char* format = std::getenv("NGRAPH_VISUALIZE_TREE_OUTPUT_FORMAT");
        if (!format)
        {
            format = "png";
        }

        ss << "dot -T" << format << " " << tmp_file << " -o " << m_name;
        auto cmd = ss.str();
        auto stream = popen(cmd.c_str(), "r");
        pclose(stream);

        remove(tmp_file.c_str());
    }
#endif
}
<|endoftext|>


<commit_before>#include "usdt.h"
#include "log.h"

#include <signal.h>

#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <unordered_set>

#include <bcc/bcc_elf.h>
#include <bcc/bcc_usdt.h>

static std::unordered_set<std::string> path_cache;
static std::unordered_set<int> pid_cache;

// Maps all traced paths and all their providers to vector of tracepoints
// on each provider
static std::unordered_map<std::string,
                          std::unordered_map<std::string, usdt_probe_list>>
    usdt_provider_cache;

static void usdt_probe_each(struct bcc_usdt *usdt_probe)
{
  usdt_provider_cache[usdt_probe->bin_path][usdt_probe->provider].emplace_back(
      usdt_probe_entry{
          .path = usdt_probe->bin_path,
          .provider = usdt_probe->provider,
          .name = usdt_probe->name,
#ifdef LIBBCC_ATTACH_UPROBE_SEVEN_ARGS_SIGNATURE
          .semaphore_offset = usdt_probe->semaphore_offset,
#else
          .semaphore_offset = 0,
#endif
          .num_locations = usdt_probe->num_locations,
      });
}

std::optional<usdt_probe_entry> USDTHelper::find(int pid,
                                                 const std::string &target,
                                                 const std::string &provider,
                                                 const std::string &name)
{
  usdt_probe_list probes;
  if (pid > 0)
  {
    read_probes_for_pid(pid);
    std::string path = bpftrace::get_pid_exe(pid);
    if (usdt_provider_cache.find(path) == usdt_provider_cache.end())
      path = bpftrace::path_for_pid_mountns(pid, path);
    probes = usdt_provider_cache[path][provider];
  }
  else
  {
    read_probes_for_path(target);
    probes = usdt_provider_cache[target][provider];
  }

  auto it = std::find_if(probes.begin(),
                         probes.end(),
                         [&name](const usdt_probe_entry &e) {
                           return e.name == name;
                         });
  if (it != probes.end())
  {
    return *it;
  }
  else
  {
    return std::nullopt;
  }
}

usdt_probe_list USDTHelper::probes_for_pid(int pid)
{
  read_probes_for_pid(pid);

  std::string path = bpftrace::get_pid_exe(pid);
  if (usdt_provider_cache.find(path) == usdt_provider_cache.end())
    path = bpftrace::path_for_pid_mountns(pid, path);

  usdt_probe_list probes;
  for (auto const &usdt_probes : usdt_provider_cache[path])
  {
    probes.insert(probes.end(),
                  usdt_probes.second.begin(),
                  usdt_probes.second.end());
  }
  return probes;
}

usdt_probe_list USDTHelper::probes_for_path(const std::string &path)
{
  read_probes_for_path(path);

  usdt_probe_list probes;
  for (auto const &usdt_probes : usdt_provider_cache[path])
  {
    probes.insert(probes.end(),
                  usdt_probes.second.begin(),
                  usdt_probes.second.end());
  }
  return probes;
}

void USDTHelper::read_probes_for_pid(int pid)
{
  if (pid_cache.count(pid))
    return;

  if (pid > 0)
  {
    void *ctx = bcc_usdt_new_frompid(pid, nullptr);
    if (ctx == nullptr)
    {
      LOG(ERROR) << "failed to initialize usdt context for pid: " << pid;

      if (kill(pid, 0) == -1 && errno == ESRCH)
        LOG(ERROR) << "hint: process not running";

      return;
    }
    bcc_usdt_foreach(ctx, usdt_probe_each);
    bcc_usdt_close(ctx);

    pid_cache.emplace(pid);
  }
  else
  {
    LOG(ERROR) << "a pid must be specified to list USDT probes by PID";
  }
}

void USDTHelper::read_probes_for_path(const std::string &path)
{
  if (path_cache.count(path))
    return;

  void *ctx = bcc_usdt_new_frompath(path.c_str());
  if (ctx == nullptr)
  {
    LOG(ERROR) << "failed to initialize usdt context for path " << path;
    return;
  }
  bcc_usdt_foreach(ctx, usdt_probe_each);
  bcc_usdt_close(ctx);

  path_cache.emplace(path);
}
<commit_msg>Locate usdt paths for pids dynamically<commit_after>#include "usdt.h"
#include "log.h"

#include <signal.h>

#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <unordered_set>

#include <bcc/bcc_elf.h>
#include <bcc/bcc_usdt.h>

static std::unordered_set<std::string> path_cache;
static std::unordered_set<int> pid_cache;

// Maps all traced paths and all their providers to vector of tracepoints
// on each provider
static std::unordered_map<std::string,
                          std::unordered_map<std::string, usdt_probe_list>>
    usdt_provider_cache;

// Maps a pid to a set of paths for its probes
static std::unordered_map<int, std::unordered_set<std::string>>
    usdt_pid_to_paths_cache;

// Used as a temporary buffer, during read_probes_for_pid to maintain
// current tracepoint paths for the current pid
static std::unordered_set<std::string> current_pid_paths;

static void usdt_probe_each(struct bcc_usdt *usdt_probe)
{
  usdt_provider_cache[usdt_probe->bin_path][usdt_probe->provider].emplace_back(
      usdt_probe_entry{
          .path = usdt_probe->bin_path,
          .provider = usdt_probe->provider,
          .name = usdt_probe->name,
#ifdef LIBBCC_ATTACH_UPROBE_SEVEN_ARGS_SIGNATURE
          .semaphore_offset = usdt_probe->semaphore_offset,
#else
          .semaphore_offset = 0,
#endif
          .num_locations = usdt_probe->num_locations,
      });
  current_pid_paths.emplace(usdt_probe->bin_path);
}

/**
 * Move the current pid paths onto the pid_to_paths_cache, and clear
 * current_pid_paths.
 */
static void cache_current_pid_paths(int pid)
{
  usdt_pid_to_paths_cache[pid].merge(current_pid_paths);
  current_pid_paths.clear();
}

std::optional<usdt_probe_entry> USDTHelper::find(int pid,
                                                 const std::string &target,
                                                 const std::string &provider,
                                                 const std::string &name)
{
  usdt_probe_list probes;
  if (pid > 0)
  {
    read_probes_for_pid(pid);
    for (auto const &path : usdt_pid_to_paths_cache[pid])
    {
      probes.insert(probes.end(),
                    usdt_provider_cache[path][provider].begin(),
                    usdt_provider_cache[path][provider].end());
    }
  }
  else
  {
    read_probes_for_path(target);
    probes = usdt_provider_cache[target][provider];
  }

  auto it = std::find_if(probes.begin(),
                         probes.end(),
                         [&name](const usdt_probe_entry &e) {
                           return e.name == name;
                         });
  if (it != probes.end())
  {
    return *it;
  }
  else
  {
    return std::nullopt;
  }
}

usdt_probe_list USDTHelper::probes_for_pid(int pid)
{
  read_probes_for_pid(pid);

  usdt_probe_list probes;
  for (auto const &path : usdt_pid_to_paths_cache[pid])
  {
    for (auto const &usdt_probes : usdt_provider_cache[path])
    {
      probes.insert(probes.end(),
                    usdt_probes.second.begin(),
                    usdt_probes.second.end());
    }
  }
  return probes;
}

usdt_probe_list USDTHelper::probes_for_path(const std::string &path)
{
  read_probes_for_path(path);

  usdt_probe_list probes;
  for (auto const &usdt_probes : usdt_provider_cache[path])
  {
    probes.insert(probes.end(),
                  usdt_probes.second.begin(),
                  usdt_probes.second.end());
  }
  return probes;
}

void USDTHelper::read_probes_for_pid(int pid)
{
  if (pid_cache.count(pid))
    return;

  if (pid > 0)
  {
    void *ctx = bcc_usdt_new_frompid(pid, nullptr);
    if (ctx == nullptr)
    {
      LOG(ERROR) << "failed to initialize usdt context for pid: " << pid;

      if (kill(pid, 0) == -1 && errno == ESRCH)
        LOG(ERROR) << "hint: process not running";

      return;
    }
    bcc_usdt_foreach(ctx, usdt_probe_each);
    bcc_usdt_close(ctx);
    cache_current_pid_paths(pid);

    pid_cache.emplace(pid);
  }
  else
  {
    LOG(ERROR) << "a pid must be specified to list USDT probes by PID";
  }
}

void USDTHelper::read_probes_for_path(const std::string &path)
{
  if (path_cache.count(path))
    return;

  void *ctx = bcc_usdt_new_frompath(path.c_str());
  if (ctx == nullptr)
  {
    LOG(ERROR) << "failed to initialize usdt context for path " << path;
    return;
  }
  bcc_usdt_foreach(ctx, usdt_probe_each);
  bcc_usdt_close(ctx);

  path_cache.emplace(path);
}
<|endoftext|>


<commit_before>#include "util.h"

#include <iomanip>
#include <ostream>

// TODO: Currently throwing compiler exceptions by pointer in order
// to maintain alignment requirements of BID_UINT128 type on some
// platforms. See https://stackoverflow.com/questions/30885997/clang-runtime-fault-when-throwing-aligned-type-compiler-bug
// for full explanation.

void abort_error(const char *file, int line, int number, const Token &token, const std::string &message)
{
    throw new SourceError(file, line, number, token, message);
}

void abort_error_a(const char *file, int line, int number, const Token &token_before, const Token &token, const std::string &message)
{
    if (token_before.line == token.line) {
        throw new SourceError(file, line, number, token, message);
    }
    Token tok = token_before;
    tok.column = static_cast<int>(1 + tok.source.length());
    if (tok.source[tok.source.length()-1] != ' ') {
        tok.column++;
    }
    throw new SourceError(file, line, number, tok, message);
}

void abort_error(const char *file, int line, int number, const Token &token, const Token &token2, const std::string &message)
{
    throw new SourceError(file, line, number, token, token2, message);
}

void abort_internal_error(const char *file, int line, const std::string &message)
{
    throw new InternalError(file, line, message);
}

void InternalError::write(std::ostream &out)
{
    out << "Compiler Internal Error: " << message << " (" << file << ":" << line << ")\n";
}

void SourceError::write(std::ostream &out)
{
    out << token.source << "\n";
    out << std::setw(token.column) << "^" << "\n";
    out << "Error N" << number << ": " << token.line << ":" << token.column << " " << token.tostring() << " " << message << " (" << file << ":" << line << ")\n";
    if (token2.type != NONE) {
        out << token2.source << "\n";
        out << std::setw(token2.column) << "^" << "\n";
        out << "Error N" << number << ": " << token2.line << ":" << token2.column << " " << token2.tostring() << "\n";
    }
}
<commit_msg>Improve error message formatting (fixes #31)<commit_after>#include "util.h"

#include <iomanip>
#include <ostream>

// TODO: Currently throwing compiler exceptions by pointer in order
// to maintain alignment requirements of BID_UINT128 type on some
// platforms. See https://stackoverflow.com/questions/30885997/clang-runtime-fault-when-throwing-aligned-type-compiler-bug
// for full explanation.

void abort_error(const char *file, int line, int number, const Token &token, const std::string &message)
{
    throw new SourceError(file, line, number, token, message);
}

void abort_error_a(const char *file, int line, int number, const Token &token_before, const Token &token, const std::string &message)
{
    if (token_before.line == token.line) {
        throw new SourceError(file, line, number, token, message);
    }
    Token tok = token_before;
    tok.column = static_cast<int>(1 + tok.source.length());
    if (tok.source[tok.source.length()-1] != ' ') {
        tok.column++;
    }
    throw new SourceError(file, line, number, tok, message);
}

void abort_error(const char *file, int line, int number, const Token &token, const Token &token2, const std::string &message)
{
    throw new SourceError(file, line, number, token, token2, message);
}

void abort_internal_error(const char *file, int line, const std::string &message)
{
    throw new InternalError(file, line, message);
}

void InternalError::write(std::ostream &out)
{
    out << "Compiler Internal Error: " << message << " (" << file << ":" << line << ")\n";
}

void SourceError::write(std::ostream &out)
{
    out << "Error in file: " << file << "\n";
    out << "\n";
    out << token.line << "| " << token.source << "\n";
    out << std::setw(std::to_string(token.line).length()+2+token.column) << "^" << "\n";
    out << "Error N" << number << ": " << token.line << ":" << token.column << " " << message << " (" << file << ":" << line << ")\n";
    if (token2.type != NONE) {
        out << "\n";
        out << "Related line information:\n";
        out << "\n";
        out << token2.line << "| " << token2.source << "\n";
        out << std::setw(std::to_string(token2.line).length()+2+token2.column) << "^" << "\n";
        out << "Error N" << number << ": " << token2.line << ":" << token2.column << "\n";
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011  Timo Savola
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */

#include <iostream>

#include <boost/format.hpp>

#include <concrete/objects/dict.hpp>
#include <concrete/objects/internal.hpp>
#include <concrete/objects/object.hpp>
#include <concrete/objects/tuple.hpp>

using namespace concrete;

namespace example {

static Object Test(const TupleObject &args, const DictObject &kwargs)
{
	std::cout << boost::format("concrete.test: args=%d kwargs=%d")
		% args.size() % kwargs.size() << std::endl;

	return args.get_item(0);
}

} // namespace

CONCRETE_INTERNAL_FUNCTION(ConcreteModule_Test, example::Test)
<commit_msg>lib: use anonymous namespace in module implementation<commit_after>/*
 * Copyright (c) 2011  Timo Savola
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */

#include <iostream>

#include <boost/format.hpp>

#include <concrete/objects/dict.hpp>
#include <concrete/objects/internal.hpp>
#include <concrete/objects/object.hpp>
#include <concrete/objects/tuple.hpp>

using namespace concrete;

namespace {

static Object Test(const TupleObject &args, const DictObject &kwargs)
{
	std::cout << boost::format("concrete.test: args=%d kwargs=%d")
		% args.size() % kwargs.size() << std::endl;

	return args.get_item(0);
}

} // namespace

CONCRETE_INTERNAL_FUNCTION(ConcreteModule_Test, Test)
<|endoftext|>


<commit_before>/*
 * v8cgi main file. Loosely based on V8's "shell" sample app.
 */

#include <v8.h>
#include "js_system.h"
#include "js_io.h"
#include "js_mysql.h"

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <sstream>

#define _STRING(x) #x
#define STRING(x) _STRING(x)

v8::Handle<v8::Array> onexit;

void die(int code) {
    int max = onexit->Length();
    v8::Handle<v8::Function> fun;
    for (int i=0;i<max;i++) {
	fun = v8::Handle<v8::Function>::Cast(onexit->Get(v8::Integer::New(i)));
	fun->Call(v8::Context::GetCurrent()->Global(), 0, NULL);
    }
    exit(code);
}

v8::Handle<v8::String> read_file(const char* name) {
  FILE* file = fopen(name, "rb");
  if (file == NULL) return v8::Handle<v8::String>();

  fseek(file, 0, SEEK_END);
  int size = ftell(file);
  rewind(file);

  char* chars = new char[size + 1];
  chars[size] = '\0';
  for (int i = 0; i < size;) {
    int read = fread(&chars[i], 1, size - i, file);
    i += read;
  }
  fclose(file);

  /* remove shebang line */
  std::string str = chars;
  if ( str.find('#',0) == 0 && str.find('!',1) == 1 ) {
    int pfix = str.find('\n',0);
    str.erase(0,pfix);
  };

  v8::Handle<v8::String> result = v8::String::New(str.c_str(), str.size());
  delete[] chars;
  return result;
}

void report_exception(v8::TryCatch* try_catch) {
  v8::HandleScope handle_scope;
  v8::String::Utf8Value exception(try_catch->Exception());
  v8::Handle<v8::Message> message = try_catch->Message();

  char * msg;
  std::string msgstring = "";

  if (message.IsEmpty()) {
    asprintf(&msg, "%s\n", *exception);
    msgstring += msg;
  } else {
    // Print (filename):(line number): (message).
    v8::String::Utf8Value filename(message->GetScriptResourceName());
    int linenum = message->GetLineNumber();
    asprintf(&msg, "%s:%i: %s\n", *filename, linenum, *exception);
    msgstring += msg;
    // Print line of source code.
    v8::String::Utf8Value sourceline(message->GetSourceLine());
    asprintf(&msg, "%s\n", *sourceline);
    msgstring += msg;

    // Print wavy underline (GetUnderline is deprecated).
    int start = message->GetStartColumn();
    for (int i = 0; i < start; i++) {
      msgstring += " ";
    }
    int end = message->GetEndColumn();
    for (int i = start; i < end; i++) {
      msgstring += "^";
    }
    msgstring += "\n";
  }

  int cgi = 0;
  v8::Local<v8::Function> fun;
  v8::Local<v8::Value> context = v8::Context::GetCurrent()->Global()->Get(v8::String::New("response"));
  if (context->IsObject()) {
    v8::Local<v8::Value> print = context->ToObject()->Get(v8::String::New("error"));
    if (print->IsObject()) {
	fun = v8::Local<v8::Function>::Cast(print);
	cgi = 1;
    }
  }
  if (!cgi) {
    context = v8::Context::GetCurrent()->Global()->Get(v8::String::New("System"));
    fun = v8::Local<v8::Function>::Cast(context->ToObject()->Get(v8::String::New("stdout")));
  }

  v8::Handle<v8::Value> data[1];
  data[0] = v8::String::New(msgstring.c_str());
  fun->Call(context->ToObject(), 1, data);
}

int execute_file(char * str) {
    v8::HandleScope handle_scope;
    v8::TryCatch try_catch;
    v8::Handle<v8::String> name = v8::String::New(str);
    v8::Handle<v8::String> source = read_file(str);

    if (source.IsEmpty()) {
	printf("Error reading '%s'\n", str);
        return 1;
    }

    v8::Handle<v8::Script> script = v8::Script::Compile(source, name);
    if (script.IsEmpty()) {
	report_exception(&try_catch);
	return 1;
    } else {
	v8::Handle<v8::Value> result = script->Run();
	if (result.IsEmpty()) {
	    report_exception(&try_catch);
	    return 1;
	}
    }
    return 0;
}

void init() {
    int result = execute_file(STRING(CONFIG_PATH));
    if (result) {
	printf("Cannot load configuration, quitting...\n");
	die(1);
    }
}

v8::Handle<v8::Value> _include(const v8::Arguments& args) {
  for (int i = 0; i < args.Length(); i++) {
    v8::HandleScope handle_scope;
    v8::String::Utf8Value file(args[i]);
    execute_file(*file); /* in include, we don't care about returned values */
  }
  return v8::Undefined();
}

v8::Handle<v8::Value> _exit(const v8::Arguments& args) {
  die(args[0]->Int32Value());
  return v8::Undefined();
}

v8::Handle<v8::Value> _onexit(const v8::Arguments& args) {
  onexit->Set(v8::Integer::New(onexit->Length()), args[0]);
  return v8::Undefined();
}

int main(int argc, char ** argv, char ** envp) {
  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
  v8::HandleScope handle_scope;

  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
  v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
  v8::Context::Scope context_scope(context);

  onexit = v8::Array::New();
  context->Global()->Set(v8::String::New("include"), v8::FunctionTemplate::New(_include)->GetFunction());
  context->Global()->Set(v8::String::New("exit"), v8::FunctionTemplate::New(_exit)->GetFunction());
  context->Global()->Set(v8::String::New("onexit"), v8::FunctionTemplate::New(_onexit)->GetFunction());
  context->Global()->Set(v8::String::New("global"), context->Global());
  context->Global()->Set(v8::String::New("Config"), v8::Object::New());

  setup_system(envp, context->Global());
  setup_io(context->Global());

  #ifdef HAVE_MYSQL
    setup_mysql(context->Global());
  #endif

  init();

  if (argc == 1) {
    printf("Nothing to do.\n");
  } else {
    int result = execute_file(argv[1]);
    if (result) { die(result); }
  }
  die(0);
}
<commit_msg>windows<commit_after>/*
 * v8cgi main file. Loosely based on V8's "shell" sample app.
 */

#include <v8.h>
#include "js_system.h"
#include "js_io.h"
#include "js_mysql.h"

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <sstream>

#define _STRING(x) #x
#define STRING(x) _STRING(x)

v8::Handle<v8::Array> __onexit;

void die(int code) {
    int max = __onexit->Length();
    v8::Handle<v8::Function> fun;
    for (int i=0;i<max;i++) {
	fun = v8::Handle<v8::Function>::Cast(__onexit->Get(v8::Integer::New(i)));
	fun->Call(v8::Context::GetCurrent()->Global(), 0, NULL);
    }
    exit(code);
}

v8::Handle<v8::String> read_file(const char* name) {
  FILE* file = fopen(name, "rb");
  if (file == NULL) return v8::Handle<v8::String>();

  fseek(file, 0, SEEK_END);
  size_t size = ftell(file);
  rewind(file);

  char* chars = new char[size + 1];
  chars[size] = '\0';
  for (unsigned int i = 0; i < size;) {
    int read = fread(&chars[i], 1, size - i, file);
    i += read;
  }
  fclose(file);

  /* remove shebang line */
  std::string str = chars;
  if ( str.find('#',0) == 0 && str.find('!',1) == 1 ) {
    int pfix = str.find('\n',0);
    str.erase(0,pfix);
  };

  v8::Handle<v8::String> result = v8::String::New(str.c_str(), str.size());
  delete[] chars;
  return result;
}

void report_exception(v8::TryCatch* try_catch) {
  v8::HandleScope handle_scope;
  v8::String::Utf8Value exception(try_catch->Exception());
  v8::Handle<v8::Message> message = try_catch->Message();
  std::string msgstring = "";
  std::stringstream ss;
  std::string tmp;

  if (message.IsEmpty()) {
    msgstring += *exception;
    msgstring += "\n";
  } else {
    v8::String::Utf8Value filename(message->GetScriptResourceName());
    int linenum = message->GetLineNumber();
    msgstring += *filename;
    msgstring += ":";

    ss << linenum;
    ss >> tmp;

    msgstring += tmp;
    msgstring += ": ";
    msgstring += *exception;
    msgstring += "\n";
    v8::String::Utf8Value sourceline(message->GetSourceLine());
    msgstring += *sourceline;
    msgstring += "\n";

    // Print wavy underline (GetUnderline is deprecated).
    int start = message->GetStartColumn();
    for (int i = 0; i < start; i++) {
      msgstring += " ";
    }
    int end = message->GetEndColumn();
    for (int i = start; i < end; i++) {
      msgstring += "^";
    }
    msgstring += "\n";
  }

  int cgi = 0;
  v8::Local<v8::Function> fun;
  v8::Local<v8::Value> context = v8::Context::GetCurrent()->Global()->Get(v8::String::New("response"));
  if (context->IsObject()) {
    v8::Local<v8::Value> print = context->ToObject()->Get(v8::String::New("error"));
    if (print->IsObject()) {
	fun = v8::Local<v8::Function>::Cast(print);
	cgi = 1;
    }
  }
  if (!cgi) {
    context = v8::Context::GetCurrent()->Global()->Get(v8::String::New("System"));
    fun = v8::Local<v8::Function>::Cast(context->ToObject()->Get(v8::String::New("stdout")));
  }

  v8::Handle<v8::Value> data[1];
  data[0] = v8::String::New(msgstring.c_str());
  fun->Call(context->ToObject(), 1, data);
}

int execute_file(char * str) {
    v8::HandleScope handle_scope;
    v8::TryCatch try_catch;
    v8::Handle<v8::String> name = v8::String::New(str);
    v8::Handle<v8::String> source = read_file(str);

    if (source.IsEmpty()) {
	printf("Error reading '%s'\n", str);
        return 1;
    }

    v8::Handle<v8::Script> script = v8::Script::Compile(source, name);
    if (script.IsEmpty()) {
	report_exception(&try_catch);
	return 1;
    } else {
	v8::Handle<v8::Value> result = script->Run();
	if (result.IsEmpty()) {
	    report_exception(&try_catch);
	    return 1;
	}
    }
    return 0;
}

void init() {
    int result = execute_file(STRING(CONFIG_PATH));
    if (result) {
	printf("Cannot load configuration, quitting...\n");
	die(1);
    }
}

v8::Handle<v8::Value> _include(const v8::Arguments& args) {
  for (int i = 0; i < args.Length(); i++) {
    v8::HandleScope handle_scope;
    v8::String::Utf8Value file(args[i]);
    execute_file(*file); /* in include, we don't care about returned values */
  }
  return v8::Undefined();
}

v8::Handle<v8::Value> _exit(const v8::Arguments& args) {
  die(args[0]->Int32Value());
  return v8::Undefined();
}

v8::Handle<v8::Value> _onexit(const v8::Arguments& args) {
  __onexit->Set(v8::Integer::New(__onexit->Length()), args[0]);
  return v8::Undefined();
}

int main(int argc, char ** argv, char ** envp) {
  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
  v8::HandleScope handle_scope;

  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
  v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
  v8::Context::Scope context_scope(context);

  __onexit = v8::Array::New();
  context->Global()->Set(v8::String::New("include"), v8::FunctionTemplate::New(_include)->GetFunction());
  context->Global()->Set(v8::String::New("exit"), v8::FunctionTemplate::New(_exit)->GetFunction());
  context->Global()->Set(v8::String::New("onexit"), v8::FunctionTemplate::New(_onexit)->GetFunction());
  context->Global()->Set(v8::String::New("global"), context->Global());
  context->Global()->Set(v8::String::New("Config"), v8::Object::New());

  setup_system(envp, context->Global());
  setup_io(context->Global());

  #ifdef HAVE_MYSQL
    setup_mysql(context->Global());
  #endif

  init();

  if (argc == 1) {
    printf("Nothing to do.\n");
  } else {
    int result = execute_file(argv[1]);
    if (result) { die(result); }
  }
  die(0);
}
<|endoftext|>