<commit_before>/* -*- mode: c++; indent-tabs-mode: nil; tab-width: 2 -*-
 *
 *  $Id: collection.h,v 1.1 2007/08/27 07:07:59 $
 *
 *  Copyright 2006-2007 FLWOR Foundation.
 *  Author: David Graf
 *
 */

#include "store/api/item.h"
#include "store/api/iterator.h"
#include "errors/error_manager.h"
#include "system/globalenv.h"
#include "runtime/accessors/AccessorsImpl.h"
#include "util/Assert.h"
#include "store/api/item_factory.h"

namespace zorba {

// 2.4 fn:data
//---------------------
FnDataIteratorState::FnDataIteratorState() {}

FnDataIteratorState::~FnDataIteratorState() {}

void FnDataIteratorState::init(PlanState& planState)
{
  PlanIteratorState::init( planState );
  theTypedValue = NULL;
}

void FnDataIteratorState::reset(PlanState& planState)
{
  PlanIteratorState::reset( planState );
  theTypedValue = NULL;
}

FnDataIterator::FnDataIterator (
    const QueryLoc& loc,
    PlanIter_t& childIter)
  :
  UnaryBaseIterator<FnDataIterator, FnDataIteratorState> ( loc, childIter )
{
}

store::Item_t
FnDataIterator::nextImpl(PlanState& planState) const
{
  store::Item_t item;
  PlanIter_t iter;

  FnDataIteratorState* state;
  DEFAULT_STACK_INIT(FnDataIteratorState, state, planState);

  while (true) {
    item = consumeNext( theChild, planState );
    if (item == NULL)
      break;
    state->theTypedValue = item->getTypedValue();
    state->theTypedValue->open();

    while (true) {
      item = state->theTypedValue->next();
      if (item == NULL)
        break;
      ZORBA_ASSERT(!item->isNode());
      STACK_PUSH( item, state );
    }
  }
  state->theTypedValue = 0; // TODO remove???
  STACK_END (state);
}

// 14.9 fn:root
//---------------------
store::Item_t FnRootIterator::nextImpl(PlanState& planState) const
{
  store::Item_t contextNode;
  store::Item_t parentNode;

  PlanIteratorState* state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  contextNode = consumeNext(theChildren[0].getp(), planState);

  if (contextNode == NULL)
    return NULL;

  if (!contextNode->isNode())
  {
    ZORBA_ERROR_LOC_DESC( ZorbaError::XPTY0004, loc, "The argument of the fn:root function is not a node");
  }

  parentNode = contextNode->getParent();

  while (parentNode != NULL)
  {
    contextNode = parentNode;
    parentNode = parentNode->getParent();
  }

  STACK_PUSH(contextNode, state);
  STACK_END (state);
}

// 14.9 fn:node-name
//---------------------
store::Item_t FnNodeNameIterator::nextImpl(PlanState& planState) const
{
  store::Item_t inNode;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  inNode = consumeNext(theChildren[0].getp(), planState);

  if (inNode != NULL) {
    if (!inNode->isNode()) {
      ZORBA_ERROR_LOC_DESC( ZorbaError::XPTY0004, loc,  "The argument of the fn:node-name function is not a node");
    }

    STACK_PUSH(inNode->getNodeName(), state);
  }
  STACK_END (state);
}

// 2.2 fn:nilled
//---------------------
store::Item_t FnNilledIterator::nextImpl(PlanState& planState) const
{
  store::Item_t inNode;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  inNode = consumeNext(theChildren[0].getp(), planState);

  if (inNode != NULL && inNode->getNodeKind() == store::StoreConsts::elementNode)
      STACK_PUSH(GENV_ITEMFACTORY->createBoolean(inNode->getNilled()), state);

  STACK_END (state);
}

// 2.5 fn:base-uri
//---------------------
store::Item_t FnBaseUriIterator::nextImpl(PlanState& planState) const
{
  store::Item_t inNode;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  inNode = consumeNext(theChildren[0].getp(), planState);

  if (inNode != NULL)
  {
    if (inNode->isNode()) {
      STACK_PUSH(GENV_ITEMFACTORY->createAnyURI(inNode->getBaseURI().getStore()), state);
    }
    else {
      ZORBA_ERROR_LOC_DESC( ZorbaError::XPTY0004, loc,
                            "The argument of the fn:base-uri function is not a node");
    }
  }

  STACK_END (state);
}

// 2.6 fn:document-uri
//---------------------
store::Item_t FnDocumentUriIterator::nextImpl(PlanState& planState) const
{
  store::Item_t inNode;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  inNode = consumeNext(theChildren[0].getp(), planState);

  if (inNode != NULL)
  {
    if (!inNode->isNode())
      ZORBA_ERROR_LOC_DESC(
          ZorbaError::XPTY0004, loc, "The argument of the fn:document-uri function is not a node");

    if(inNode->getNodeKind() == store::StoreConsts::documentNode)
      STACK_PUSH(GENV_ITEMFACTORY->createAnyURI(inNode->getDocumentURI().getStore()), state);
  }

  STACK_END (state);
}
// 2.3 fn:string
//---------------------
store::Item_t FnStringIterator::nextImpl(PlanState& planState) const
{
  store::Item_t inVal;
  xqpStringStore_t empty;

  FnStringIteratorState *state;
  DEFAULT_STACK_INIT(FnStringIteratorState, state, planState);

  while((inVal = consumeNext(theChildren[0].getp(), planState)) != NULL) {
    state->hasOutput = true;
    STACK_PUSH(GENV_ITEMFACTORY->createString(inVal->getStringValue()), state);
  }

  if (!state->hasOutput && theEmptyStringOnNULL) {
    state->hasOutput = true;
    empty = new xqpStringStore("");
    STACK_PUSH(GENV_ITEMFACTORY->createString(empty), state);
  }

  STACK_END (state);
}

} /* namespace zorba */
/* vim:set ts=2 sw=2: */
<commit_msg>updated fn:base-uri() and fn:document-uri() iterators.<commit_after>/* -*- mode: c++; indent-tabs-mode: nil; tab-width: 2 -*-
 *
 *  $Id: collection.h,v 1.1 2007/08/27 07:07:59 $
 *
 *  Copyright 2006-2007 FLWOR Foundation.
 *  Author: David Graf
 *
 */

#include "store/api/item.h"
#include "store/api/iterator.h"
#include "errors/error_manager.h"
#include "system/globalenv.h"
#include "runtime/accessors/AccessorsImpl.h"
#include "util/Assert.h"
#include "store/api/item_factory.h"
#include "context/namespace_context.h"

namespace zorba {

// 2.4 fn:data
//---------------------
FnDataIteratorState::FnDataIteratorState() {}

FnDataIteratorState::~FnDataIteratorState() {}

void FnDataIteratorState::init(PlanState& planState)
{
  PlanIteratorState::init( planState );
  theTypedValue = NULL;
}

void FnDataIteratorState::reset(PlanState& planState)
{
  PlanIteratorState::reset( planState );
  theTypedValue = NULL;
}

FnDataIterator::FnDataIterator (
    const QueryLoc& loc,
    PlanIter_t& childIter)
  :
  UnaryBaseIterator<FnDataIterator, FnDataIteratorState> ( loc, childIter )
{
}

store::Item_t
FnDataIterator::nextImpl(PlanState& planState) const
{
  store::Item_t item;
  PlanIter_t iter;

  FnDataIteratorState* state;
  DEFAULT_STACK_INIT(FnDataIteratorState, state, planState);

  while (true) {
    item = consumeNext( theChild, planState );
    if (item == NULL)
      break;
    state->theTypedValue = item->getTypedValue();
    state->theTypedValue->open();

    while (true) {
      item = state->theTypedValue->next();
      if (item == NULL)
        break;
      ZORBA_ASSERT(!item->isNode());
      STACK_PUSH( item, state );
    }
  }
  state->theTypedValue = 0; // TODO remove???
  STACK_END (state);
}

// 14.9 fn:root
//---------------------
store::Item_t FnRootIterator::nextImpl(PlanState& planState) const
{
  store::Item_t contextNode;
  store::Item_t parentNode;

  PlanIteratorState* state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  contextNode = consumeNext(theChildren[0].getp(), planState);

  if (contextNode == NULL)
    return NULL;

  if (!contextNode->isNode())
  {
    ZORBA_ERROR_LOC_DESC( ZorbaError::XPTY0004, loc, "The argument of the fn:root function is not a node");
  }

  parentNode = contextNode->getParent();

  while (parentNode != NULL)
  {
    contextNode = parentNode;
    parentNode = parentNode->getParent();
  }

  STACK_PUSH(contextNode, state);
  STACK_END (state);
}

// 14.9 fn:node-name
//---------------------
store::Item_t FnNodeNameIterator::nextImpl(PlanState& planState) const
{
  store::Item_t inNode;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  inNode = consumeNext(theChildren[0].getp(), planState);

  if (inNode != NULL) {
    if (!inNode->isNode()) {
      ZORBA_ERROR_LOC_DESC( ZorbaError::XPTY0004, loc,  "The argument of the fn:node-name function is not a node");
    }

    STACK_PUSH(inNode->getNodeName(), state);
  }
  STACK_END (state);
}

// 2.2 fn:nilled
//---------------------
store::Item_t FnNilledIterator::nextImpl(PlanState& planState) const
{
  store::Item_t inNode;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  inNode = consumeNext(theChildren[0].getp(), planState);

  if (inNode != NULL && inNode->getNodeKind() == store::StoreConsts::elementNode)
      STACK_PUSH(GENV_ITEMFACTORY->createBoolean(inNode->getNilled()), state);

  STACK_END (state);
}

// 2.5 fn:base-uri
//---------------------
store::Item_t FnBaseUriIterator::nextImpl(PlanState& planState) const
{
  store::Item_t inNode, attr, attrName;
  Iterator_t    theAttributes;
  bool          found = false;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  inNode = consumeNext(theChildren[0].getp(), planState);

  if (inNode != NULL)
  {
    if(inNode->getNodeKind() == store::StoreConsts::documentNode ||
        inNode->getNodeKind() == store::StoreConsts::piNode)
    {
      if (!inNode->getBaseURI().getStore()->byteEqual("",0))
        STACK_PUSH(GENV_ITEMFACTORY->createAnyURI(inNode->getBaseURI().getStore()), state);
    }
    else if(inNode->getNodeKind() == store::StoreConsts::elementNode)
    {
      if (!inNode->getBaseURI().getStore()->byteEqual("",0))
        STACK_PUSH(GENV_ITEMFACTORY->createAnyURI(inNode->getBaseURI().getStore()), state);
      else
      {
        for ((theAttributes = inNode->getAttributes())->open ();
              ! found && NULL != (attr = theAttributes->next()); )
        {
          attrName = attr->getNodeName();
          found = xqp_string (attrName->getLocalName ()) == "base"
              && xqp_string (attrName->getNamespace ()) == XML_NS;
        }
        if(found)
          STACK_PUSH(GENV_ITEMFACTORY->createAnyURI(attr->getStringValue()), state);
      }
    }
  }

  STACK_END (state);
}

// 2.6 fn:document-uri
//---------------------
store::Item_t FnDocumentUriIterator::nextImpl(PlanState& planState) const
{
  store::Item_t inNode;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  inNode = consumeNext(theChildren[0].getp(), planState);

  if (inNode != NULL)
  {
    if (!inNode->isNode())
      ZORBA_ERROR_LOC_DESC(
          ZorbaError::XPTY0004, loc, "The argument of the fn:document-uri function is not a node");

    if(inNode->getNodeKind() == store::StoreConsts::documentNode)
      if(!inNode->getDocumentURI().byteEqual("",0))
        STACK_PUSH(GENV_ITEMFACTORY->createAnyURI(inNode->getDocumentURI().getStore()), state);
  }

  STACK_END (state);
}
// 2.3 fn:string
//---------------------
store::Item_t FnStringIterator::nextImpl(PlanState& planState) const
{
  store::Item_t inVal;
  xqpStringStore_t empty;

  FnStringIteratorState *state;
  DEFAULT_STACK_INIT(FnStringIteratorState, state, planState);

  while((inVal = consumeNext(theChildren[0].getp(), planState)) != NULL) {
    state->hasOutput = true;
    STACK_PUSH(GENV_ITEMFACTORY->createString(inVal->getStringValue()), state);
  }

  if (!state->hasOutput && theEmptyStringOnNULL) {
    state->hasOutput = true;
    empty = new xqpStringStore("");
    STACK_PUSH(GENV_ITEMFACTORY->createString(empty), state);
  }

  STACK_END (state);
}

} /* namespace zorba */
/* vim:set ts=2 sw=2: */
<|endoftext|>


<commit_before>#include <iostream>
#include <cmath>
#include <stack>
using namesspace std;

int evaluateOp(char theOperator,int numberStack, char operatorStack)
{
	int leftValue = numberStack.pop();
	int rightValue = numberStack.pop();
	int result;
	switch(theOperator)
	{
		case '+'://adds the two number and returns the value
			result = leftValue + rightValue;
			return result;
			break;
		case '-'://subtracts the two number and returns the value
			result = leftValue - rightValue;
			return result;
			break;
		case '/'://divides the two number and returns the value
			result = leftValue / rightValue;
			return result;
			break;
		case '*'://multiplies the two number and returns the value
			result = leftValue * rightValue;
			return result;
			break;
		case'^'://exponent
			result = pow(leftValue, rightValue);
			return result;
			break;
		case'%'://mod operator
			result = leftValue % rightValue;
			return result;
			break;
		case'!'://logical not
			result = 0; //false
			return result;
			break;
		case'A'://increments the left value by one ++
			leftValue++;
			return leftValue;
			break;
		case'B'://decrements the left value by one --
			leftValue--;
			return leftValue;
			break;
		case'C'://checks to see if two values are equal ==
			if (leftValue == rightValue)//if they're equal return 1 for true
			{
				result = 1;//true
				return result;
			}
			else//else return 0 for false
			{
				result = 0;//false
				return result;
			}
			break;
		case'D'://checks to see if left value is not equal to right value !=
			if (leftValue != rightValue)//returns true(1) if they are not equal
			{
				result = 1;//true
				return result;
			}
			else//if they are equal returns false(0)
			{
				result = 0;//false
				return result;
			}
			break;
		case'E'://logical and operator &&
			break;
		case'F'://logical or operator ||
			result = 1;//true
			return result;
			break;
		case'G'://greater than or equal
			if (leftValue >= rightValue)
			{
				result = 1;//true
				return result;
			}
			else
			{
				result = 0;//false
				return result;
			}
			break;
		case'H'://less than or equal
			if (leftValue <= rightValue)

			{
				result = 1;//true
				return result;
			}
			else
			{
				result = 0;//false
				return result;
			}
			break;
		case'I'://negative
			result = leftValue * -1;
			return result;
			break;

	}
}

int main()
{

	/* code */
	return 0;
}

//changes each token
istringstream tokens();
char nextChar;
stack<int> numberStack;
stack<char> operatorStack;

while (tokens >> nextChar){
	if (isdigit(nextChar)){
		tokens.push()			//add to integer stack
		int number;
		tokens >> number; //converts the characters to ints
		numberStack.push(number);
	}
	else if (isOperator(nextChar)){
		int weight = precedenceOfOperator(nextChar);
		int stackWeight = precedenceOfOperator(operatorStack.top())
		if(weight >= stackWeight)
		{
			operatorStack.push(nextChar);
		}
		else
		{

		}
	}
	else{
		throw caseErrors(" ");
	}
}<commit_msg>added errors<commit_after>#include <iostream>
#include <cmath>
#include <stack>
using namesspace std;

int evaluateOp(char theOperator,int numberStack, char operatorStack)
{
	int leftValue = numberStack.pop();
	int rightValue = numberStack.pop();
	int result;
	switch(theOperator)
	{
<<<<<<< Updated upstream
		case '+'://adds the two number and returns the value
			result = leftValue + rightValue;
			return result;
			break;
		case '-'://subtracts the two number and returns the value
			result = leftValue - rightValue;
			return result;
			break;
		case '/'://divides the two number and returns the value
			result = leftValue / rightValue;
			return result;
			break;
		case '*'://multiplies the two number and returns the value
			result = leftValue * rightValue;
			return result;
			break;
		case'^'://exponent
			result = pow(leftValue, rightValue);
			return result;
			break;
		case'%'://mod operator
			result = leftValue % rightValue;
			return result;
			break;
		case'!'://logical not
			result = 0; //false
			return result;
			break;
		case'A'://increments the left value by one ++
			leftValue++;
			return leftValue;
			break;
		case'B'://decrements the left value by one --
			leftValue--;
			return leftValue;
			break;
		case'C'://checks to see if two values are equal ==
			if (leftValue == rightValue)//if they're equal return 1 for true
			{
				result = 1;//true
				return result;
			}
			else//else return 0 for false
			{
				result = 0;//false
				return result;
			}
			break;
		case'D'://checks to see if left value is not equal to right value !=
			if (leftValue != rightValue)//returns true(1) if they are not equal
			{
				result = 1;//true
				return result;
			}
			else//if they are equal returns false(0)
			{
				result = 0;//false
				return result;
			}
			break;
		case'E'://logical and operator &&
			break;
		case'F'://logical or operator ||
			result = 1;//true
			return result;
			break;
		case'G'://greater than or equal
			if (leftValue >= rightValue)
			{
				result = 1;//true
				return result;
			}
			else
			{
				result = 0;//false
				return result;
			}
			break;
		case'H'://less than or equal
			if (leftValue <= rightValue)

			{
				result = 1;//true
				return result;
			}
			else
			{
				result = 0;//false
				return result;
			}
			break;
		case'I'://negative
			result = leftValue * -1;
			return result;
			break;

=======
		case '+':
		result = leftValue + rightValue;
		return result;
		break;
		case '-':
		result = leftValue - rightValue;
		return result;
		break;
>>>>>>> Stashed changes

	}
}

int main()
{

	/* code */
	return 0;
}

//changes each token
istringstream tokens();
char nextChar;
stack<int> numberStack;
stack<char> operatorStack;

while (tokens >> nextChar){
	if (isdigit(nextChar)){
		tokens.push()			//add to integer stack
		int number;
		tokens >> number; //converts the characters to ints
		numberStack.push(number);
	}
	else if (isOperator(nextChar)){
		int weight = precedenceOfOperator(nextChar);
		int stackWeight = precedenceOfOperator(operatorStack.top())
		if(weight >= stackWeight)
		{
			operatorStack.push(nextChar);
		}
		else
		{

		}
	} //errors

	}
}

// Errors
/*try
{
	if (/*missing parenthese)
	{
		throw 0;
	}
	else if (/* starts with < )
	{
		throw 1;
	}
	else if (/* two binary operation)
	{
		throw 2;
	}
	else if (/* two operands in a row)
	{
		throw 3;
	}
	else if (/* unary operand can't be followed)
	{
		throw 4;
	}
	else (/*division by 0)
	{
		throw 5;
	}

}

catch(int x)
{
	cout << "Expression can't start with a closing parenthesis @ char: 0" << endl;
}
catch(int x)
{
	cout << "Expression can't start with a binary operator @ char: 0" << endl;
}
catch(int x)
{
	cout << "Two binary operators in a row @ row char 3" << endl;
}
catch(int x)
{
	cout << "Two operands in a row @ char 5" << endl;
}
catch(int x)
{
	cout << "A unary operand can't be followed by a binary operator @ char 6" << endl;
}
catch(int x)
{
	cout << "division by zero @ char 2" << endl;
}
}*/<|endoftext|>


<commit_before>#include "mbed.h"
#include "lorawan.h"

int main(void)
{
    init();
    while (true) {
        os_runloop_once();
    }
    return 0;
}
<commit_msg>add working example main() function<commit_after>#include "mbed.h"
#include "Simple-LoRaWAN.h"

using namespace SimpleLoRaWAN;

#include "stdio.h"

uint8_t appEui[8]  = { 0x3A, 0x04, 0x00, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 }; // MSBF
uint8_t devEui[8]  = { 0x77, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; // MSBF

uint32_t devAddr    = 0xECB5C5E5;
uint8_t nwksKey[16] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; // LSBF

uint8_t appKey[16]  = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; // LSBF

Node* node;

int main(void)
{
    node = new ABP::Node(devAddr, nwksKey, appKey);
    //node = new OTAA::Node(appEui, devEui, appKey);
    wait(1.0);
    printf("send message\r\n");
    node->send("Hello from Simple-LoRaWAN", 25);

    while(true){
        node->process();
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 Samplecount S.L.
//
// 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.

#ifndef METHCLA_MEMORY_MANAGER_HPP_INCLUDED
#define METHCLA_MEMORY_MANAGER_HPP_INCLUDED

#include "Methcla/Exception.hpp"
#include "Methcla/Memory.hpp"

#include <boost/assert.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <cstddef>
#include <tlsf.h>

namespace Methcla { namespace Memory {

class RTMemoryManager
{
public:
    //* Construct a realtime memory allocator with a capacity of `size` kB.
    RTMemoryManager(size_t size);
    ~RTMemoryManager();

    //* Allocate memory of `size` bytes.
    //
    // @throw std::invalid_argument
    // @throw std::bad_alloc
    void* alloc(size_t size);

    //* Allocate aligned memory of `size` bytes.
    //
    // @throw std::invalid_argument
    // @throw std::bad_alloc
    void* allocAligned(Alignment align, size_t size);

    //* Free memory allocated by this allocator.
    void free(void* ptr) noexcept;

    //* Allocate memory for `n` elements of type `T`.
    //
    // @throw std::invalid_argument
    // @throw std::bad_alloc
    template <typename T> T* allocOf(size_t n=1)
    {
        return static_cast<T*>(alloc(n * sizeof(T)));
    }

    //* Allocate aligned memory for `n` elements of type `T`.
    //
    // @throw std::invalid_argument
    // @throw std::bad_alloc
    template <typename T> T* allocAlignedOf(Alignment align, size_t n=1)
    {
        return static_cast<T*>(allocAligned(align, n * sizeof(T)));
    }

private:
    void*       m_memory;
    tlsf_pool   m_pool;
};

template <class T, class Allocator> class AllocatedBase
{
    struct Chunk
    {
        typedef boost::aligned_storage<1,boost::alignment_of<T>::value> Padding;

        Allocator*  alloc;
        Padding     padding;
        char        data[];
    };

protected:
    static void* alloc(Allocator& allocator, size_t size)
    {
        Chunk* chunk = static_cast<Chunk*>(allocator.alloc(sizeof(Chunk) + size));
        chunk->alloc = &allocator;
        BOOST_ASSERT( Alignment::isAligned(
            boost::alignment_of<T>::value,
            reinterpret_cast<std::uintptr_t>(chunk->data)) );
        return chunk->data;
    }

    static void destroy(void* ptr)
    {
        Chunk* chunk = static_cast<Chunk*>(ptr) - 1;
        BOOST_ASSERT( chunk->data == ptr );
        chunk->alloc->free(chunk);
    }

private:
    void* operator new(size_t);
};

template <class T, class Allocator> class Allocated
    : public AllocatedBase<T, Allocator>
{
    typedef AllocatedBase<T, Allocator> super;

public:
    void* operator new(size_t size, Allocator& alloc)
    {
        return super::alloc(alloc, size);
    }
    void operator delete(void* ptr, Allocator&)
    {
        super::destroy(ptr);
    }
    void* operator new(size_t size, Allocator& alloc, size_t additional)
    {
        return super::alloc(alloc, size+additional);
    }
    void operator delete(void* ptr, Allocator&, size_t)
    {
        super::destroy(ptr);
    }
    void operator delete(void* ptr)
    {
        super::destroy(ptr);
    }
};
} }

#endif // METHCLA_MEMORY_MANAGER_HPP_INCLUDED
<commit_msg>Zero sized arrays are not standard C++<commit_after>// Copyright 2012-2013 Samplecount S.L.
//
// 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.

#ifndef METHCLA_MEMORY_MANAGER_HPP_INCLUDED
#define METHCLA_MEMORY_MANAGER_HPP_INCLUDED

#include "Methcla/Exception.hpp"
#include "Methcla/Memory.hpp"

#include <boost/assert.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <cstddef>
#include <tlsf.h>

namespace Methcla { namespace Memory {

class RTMemoryManager
{
public:
    //* Construct a realtime memory allocator with a capacity of `size` kB.
    RTMemoryManager(size_t size);
    ~RTMemoryManager();

    //* Allocate memory of `size` bytes.
    //
    // @throw std::invalid_argument
    // @throw std::bad_alloc
    void* alloc(size_t size);

    //* Allocate aligned memory of `size` bytes.
    //
    // @throw std::invalid_argument
    // @throw std::bad_alloc
    void* allocAligned(Alignment align, size_t size);

    //* Free memory allocated by this allocator.
    void free(void* ptr) noexcept;

    //* Allocate memory for `n` elements of type `T`.
    //
    // @throw std::invalid_argument
    // @throw std::bad_alloc
    template <typename T> T* allocOf(size_t n=1)
    {
        return static_cast<T*>(alloc(n * sizeof(T)));
    }

    //* Allocate aligned memory for `n` elements of type `T`.
    //
    // @throw std::invalid_argument
    // @throw std::bad_alloc
    template <typename T> T* allocAlignedOf(Alignment align, size_t n=1)
    {
        return static_cast<T*>(allocAligned(align, n * sizeof(T)));
    }

private:
    void*       m_memory;
    tlsf_pool   m_pool;
};

template <class T, class Allocator> class AllocatedBase
{
    struct Chunk
    {
        typedef boost::aligned_storage<1,boost::alignment_of<T>::value> Padding;

        Allocator*  alloc;
        Padding     padding;
    };

protected:
    static void* alloc(Allocator& allocator, size_t size)
    {
        Chunk* chunk = static_cast<Chunk*>(allocator.alloc(sizeof(Chunk) + size));
        chunk->alloc = &allocator;
        void* ptr = chunk + 1;
        BOOST_ASSERT( Alignment::isAligned(
            boost::alignment_of<T>::value,
            reinterpret_cast<std::uintptr_t>(ptr)) );
        return ptr;
    }

    static void destroy(void* ptr)
    {
        Chunk* chunk = static_cast<Chunk*>(ptr) - 1;
        chunk->alloc->free(chunk);
    }

private:
    void* operator new(size_t);
};

template <class T, class Allocator> class Allocated
    : public AllocatedBase<T, Allocator>
{
    typedef AllocatedBase<T, Allocator> super;

public:
    void* operator new(size_t size, Allocator& alloc)
    {
        return super::alloc(alloc, size);
    }
    void operator delete(void* ptr, Allocator&)
    {
        super::destroy(ptr);
    }
    void* operator new(size_t size, Allocator& alloc, size_t additional)
    {
        return super::alloc(alloc, size+additional);
    }
    void operator delete(void* ptr, Allocator&, size_t)
    {
        super::destroy(ptr);
    }
    void operator delete(void* ptr)
    {
        super::destroy(ptr);
    }
};
} }

#endif // METHCLA_MEMORY_MANAGER_HPP_INCLUDED
<|endoftext|>


<commit_before>#include "native.h"

#include <dlfcn.h>
#include <exception>
#include <map>
#include <type_traits>

typedef void* shlib;

namespace {
    std::map<std::string, shlib> open_modules;

    shlib fetch_module(std::string module) {
        if (open_modules.count(module))
            return open_modules[module];

        shlib so = dlopen(("./lib" + module + ".so").data(), RTLD_NOW);
        if (so) open_modules[module] = so;
        return so;
    }
}

template <typename T>
T* get_native(std::string module, std::string symbol) {
    // Fetch module, and open if not already open
    shlib so = fetch_module(module);
    if (!so) throw std::runtime_error("module " + module + " not found");

    void* sym = dlsym(so, symbol.data());
    if (!sym) throw std::runtime_error("symbol " + module + "::" + symbol + " not found");
    if (std::is_function<T>::value)
        return reinterpret_cast<T*>(sym);
    return static_cast<T*>(sym);
}

template <typename RetType, typename... ArgType>
RetType call_native(std::string module, std::string function, ArgType... argv) {
    typedef RetType FuncType(ArgType...);
    FuncType* func = get_native<FuncType>(module, function);
    return func(argv...);
}
<commit_msg>Add comment with fun fact about extern "C" functions<commit_after>#include "native.h"

#include <dlfcn.h>
#include <exception>
#include <map>
#include <type_traits>

typedef void* shlib;

namespace {
    std::map<std::string, shlib> open_modules;

    shlib fetch_module(std::string module) {
        if (open_modules.count(module))
            return open_modules[module];

        shlib so = dlopen(("./lib" + module + ".so").data(), RTLD_NOW);
        if (so) open_modules[module] = so;
        return so;
    }
}

template <typename T>
T* get_native(std::string module, std::string symbol) {
    // Fetch module, and open if not already open
    shlib so = fetch_module(module);
    if (!so) throw std::runtime_error("module " + module + " not found");

    void* sym = dlsym(so, symbol.data());
    if (!sym) throw std::runtime_error("symbol " + module + "::" + symbol + " not found");
    if (std::is_function<T>::value)
        return reinterpret_cast<T*>(sym);
    return static_cast<T*>(sym);
}

template <typename RetType, typename... ArgType>
RetType call_native(std::string module, std::string function, ArgType... argv) {
    // Fun fact: if you're calling a C function, the standard technically says that FuncType should be defined with C language linkage (aka extern "C").
    // But you can't do extern "C" inside templates or functions, even if it's just a typedef, so fixing this is impossible in the general case.
    // This isn't a problem on "normal" architectures, so we can safely ignore this.
    // If we end up calling only one or two function signatures, and want to be really standards compliant, we can extern "C" typedef what we need at namespace scope.
    // For now, though, screw it.
    typedef RetType FuncType(ArgType...);

    FuncType* func = get_native<FuncType>(module, function);
    return func(argv...);
}
<|endoftext|>


<commit_before>/*
    This file is part of Kontact.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qcursor.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qtooltip.h>

#include <kdialog.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kparts/part.h>
#include <kpopupmenu.h>
#include <kstandarddirs.h>
#include <kurllabel.h>
#include <libkcal/resourcecalendar.h>
#include <libkcal/resourcelocal.h>
#include <libkcal/todo.h>
#include <libkcal/incidenceformatter.h>
#include <libkdepim/kpimprefs.h>

#include "korganizeriface_stub.h"

#include "core.h"
#include "plugin.h"
#include "todoplugin.h"

#include "korganizer/stdcalendar.h"
#include "korganizer/koglobals.h"
#include "korganizer/incidencechanger.h"

#include "todosummarywidget.h"

TodoSummaryWidget::TodoSummaryWidget( TodoPlugin *plugin,
                                      QWidget *parent, const char *name )
  : Kontact::Summary( parent, name ), mPlugin( plugin )
{
  QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 );

  QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_todo",
                   KIcon::Desktop, KIcon::SizeMedium );
  QWidget *header = createHeader( this, icon, i18n( "To-do List" ) );
  mainLayout->addWidget( header );

  mLayout = new QGridLayout( mainLayout, 7, 4, 3 );
  mLayout->setRowStretch( 6, 1 );

  mCalendar = KOrg::StdCalendar::self();
  mCalendar->load();

  connect( mCalendar, SIGNAL( calendarChanged() ), SLOT( updateView() ) );
  connect( mPlugin->core(), SIGNAL( dayChanged( const QDate& ) ),
           SLOT( updateView() ) );

  updateView();
}

TodoSummaryWidget::~TodoSummaryWidget()
{
}

void TodoSummaryWidget::updateView()
{
  mLabels.setAutoDelete( true );
  mLabels.clear();
  mLabels.setAutoDelete( false );

  KConfig config( "kcmkorgsummaryrc" );
  config.setGroup( "Todo" );
  bool showAllTodos = config.readBoolEntry( "ShowAllTodos", false );

  KIconLoader loader( "kdepim" );

  QLabel *label = 0;
  int counter = 0;

  QDate currentDate = QDate::currentDate();
  KCal::Todo::List todos = mCalendar->todos();
  if ( todos.count() > 0 ) {
    QPixmap pm = loader.loadIcon( "todo", KIcon::Small );
    KCal::Todo::List::ConstIterator it;
    for ( it = todos.begin(); it != todos.end(); ++it ) {
      KCal::Todo *todo = *it;

      bool accepted = false;
      QString stateText;

      // show all incomplete todos
      if ( showAllTodos && !todo->isCompleted())
        accepted = true;

      // show uncomplete todos from the last days
      if ( todo->hasDueDate() && !todo->isCompleted() &&
           todo->dtDue().date() < currentDate ) {
        accepted = true;
        stateText = i18n( "overdue" );
      }

      // show todos which started somewhere in the past and has to be finished in future
      if ( todo->hasStartDate() && todo->hasDueDate() &&
           todo->dtStart().date() < currentDate &&
           currentDate < todo->dtDue().date() ) {
        accepted = true;
        stateText = i18n( "in progress" );
      }

      // all todos which start today
      if ( todo->hasStartDate() && todo->dtStart().date() == currentDate ) {
        accepted = true;
        stateText = i18n( "starts today" );
      }

      // all todos which end today
      if ( todo->hasDueDate() && todo->dtDue().date() == currentDate ) {
        accepted = true;
        stateText = i18n( "ends today" );
      }

      if ( !accepted )
        continue;

      label = new QLabel( this );
      label->setPixmap( pm );
      label->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
      mLayout->addWidget( label, counter, 0 );
      mLabels.append( label );

      label = new QLabel( QString::number( todo->percentComplete() ) + "%", this );
      label->setAlignment( AlignHCenter | AlignVCenter );
      label->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
      mLayout->addWidget( label, counter, 1 );
      mLabels.append( label );

      QString sSummary = todo->summary();
      if ( todo->relatedTo() ) { // show parent only, not entire ancestry
        sSummary = todo->relatedTo()->summary() + ":" + todo->summary();
      }
      KURLLabel *urlLabel = new KURLLabel( this );
      urlLabel->setText( sSummary );
      urlLabel->setURL( todo->uid() );
      urlLabel->installEventFilter( this );
      urlLabel->setTextFormat( Qt::RichText );
      mLayout->addWidget( urlLabel, counter, 2 );
      mLabels.append( urlLabel );

      connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
               this, SLOT( viewTodo( const QString& ) ) );
      connect( urlLabel, SIGNAL( rightClickedURL( const QString& ) ),
               this, SLOT( popupMenu( const QString& ) ) );

      QString tipText( KCal::IncidenceFormatter::toolTipString( todo, true ) );
      if ( !tipText.isEmpty() ) {
        QToolTip::add( urlLabel, tipText );
      }

      label = new QLabel( stateText, this );
      label->setAlignment( AlignLeft | AlignVCenter );
      label->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
      mLayout->addWidget( label, counter, 3 );
      mLabels.append( label );

      counter++;
    }
  }

  if ( counter == 0 ) {
    QLabel *noTodos = new QLabel( i18n( "No to-dos pending" ), this );
    noTodos->setAlignment( AlignHCenter | AlignVCenter );
    mLayout->addWidget( noTodos, 0, 1 );
    mLabels.append( noTodos );
  }

  for ( label = mLabels.first(); label; label = mLabels.next() )
    label->show();
}

void TodoSummaryWidget::viewTodo( const QString &uid )
{
  mPlugin->core()->selectPlugin( "kontact_todoplugin" );//ensure loaded
  KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
  iface.editIncidence( uid );
}

void TodoSummaryWidget::removeTodo( const QString &uid )
{
  mPlugin->core()->selectPlugin( "kontact_todoplugin" );//ensure loaded
  KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
  iface.deleteIncidence( uid, false );
}

void TodoSummaryWidget::completeTodo( const QString &uid )
{
  KCal::Todo *todo = mCalendar->todo( uid );
  IncidenceChanger *changer = new IncidenceChanger( mCalendar, this );
  if ( !todo->isReadOnly() && changer->beginChange( todo ) ) {
    KCal::Todo *oldTodo = todo->clone();
    todo->setCompleted( QDateTime::currentDateTime() );
    changer->changeIncidence( oldTodo, todo, KOGlobals::COMPLETION_MODIFIED );
    changer->endChange( todo );
    delete oldTodo;
    updateView();
  }
}

void TodoSummaryWidget::popupMenu( const QString &uid )
{
  KPopupMenu popup( this );
  QToolTip::remove( this );
  popup.insertItem( i18n( "&Edit To-do..." ), 0 );
  popup.insertItem( KGlobal::iconLoader()->loadIcon( "editdelete", KIcon::Small),
                    i18n( "&Delete To-do" ), 1 );
  KCal::Todo *todo = mCalendar->todo( uid );
  if ( !todo->isCompleted() ) {
    popup.insertItem( KGlobal::iconLoader()->loadIcon( "checkedbox", KIcon::Small),
                      i18n( "&Mark To-do Completed" ), 2 );
  }

  switch ( popup.exec( QCursor::pos() ) ) {
    case 0:
      viewTodo( uid );
      break;
    case 1:
      removeTodo( uid );
      break;
    case 2:
      completeTodo( uid );
      break;
  }
}

bool TodoSummaryWidget::eventFilter( QObject *obj, QEvent* e )
{
  if ( obj->inherits( "KURLLabel" ) ) {
    KURLLabel* label = static_cast<KURLLabel*>( obj );
    if ( e->type() == QEvent::Enter )
      emit message( i18n( "Edit To-do: \"%1\"" ).arg( label->text() ) );
    if ( e->type() == QEvent::Leave )
      emit message( QString::null );
  }

  return Kontact::Summary::eventFilter( obj, e );
}

QStringList TodoSummaryWidget::configModules() const
{
  return QStringList( "kcmtodosummary.desktop" );
}

#include "todosummarywidget.moc"
<commit_msg>Change the summary view title to "To-Do" from "To-do List" for consistency with the side bar. kolab/issue896<commit_after>/*
    This file is part of Kontact.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qcursor.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qtooltip.h>

#include <kdialog.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kparts/part.h>
#include <kpopupmenu.h>
#include <kstandarddirs.h>
#include <kurllabel.h>
#include <libkcal/resourcecalendar.h>
#include <libkcal/resourcelocal.h>
#include <libkcal/todo.h>
#include <libkcal/incidenceformatter.h>
#include <libkdepim/kpimprefs.h>

#include "korganizeriface_stub.h"

#include "core.h"
#include "plugin.h"
#include "todoplugin.h"

#include "korganizer/stdcalendar.h"
#include "korganizer/koglobals.h"
#include "korganizer/incidencechanger.h"

#include "todosummarywidget.h"

TodoSummaryWidget::TodoSummaryWidget( TodoPlugin *plugin,
                                      QWidget *parent, const char *name )
  : Kontact::Summary( parent, name ), mPlugin( plugin )
{
  QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 );

  QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_todo",
                   KIcon::Desktop, KIcon::SizeMedium );
  QWidget *header = createHeader( this, icon, i18n( "To-do" ) );
  mainLayout->addWidget( header );

  mLayout = new QGridLayout( mainLayout, 7, 4, 3 );
  mLayout->setRowStretch( 6, 1 );

  mCalendar = KOrg::StdCalendar::self();
  mCalendar->load();

  connect( mCalendar, SIGNAL( calendarChanged() ), SLOT( updateView() ) );
  connect( mPlugin->core(), SIGNAL( dayChanged( const QDate& ) ),
           SLOT( updateView() ) );

  updateView();
}

TodoSummaryWidget::~TodoSummaryWidget()
{
}

void TodoSummaryWidget::updateView()
{
  mLabels.setAutoDelete( true );
  mLabels.clear();
  mLabels.setAutoDelete( false );

  KConfig config( "kcmkorgsummaryrc" );
  config.setGroup( "Todo" );
  bool showAllTodos = config.readBoolEntry( "ShowAllTodos", false );

  KIconLoader loader( "kdepim" );

  QLabel *label = 0;
  int counter = 0;

  QDate currentDate = QDate::currentDate();
  KCal::Todo::List todos = mCalendar->todos();
  if ( todos.count() > 0 ) {
    QPixmap pm = loader.loadIcon( "todo", KIcon::Small );
    KCal::Todo::List::ConstIterator it;
    for ( it = todos.begin(); it != todos.end(); ++it ) {
      KCal::Todo *todo = *it;

      bool accepted = false;
      QString stateText;

      // show all incomplete todos
      if ( showAllTodos && !todo->isCompleted())
        accepted = true;

      // show uncomplete todos from the last days
      if ( todo->hasDueDate() && !todo->isCompleted() &&
           todo->dtDue().date() < currentDate ) {
        accepted = true;
        stateText = i18n( "overdue" );
      }

      // show todos which started somewhere in the past and has to be finished in future
      if ( todo->hasStartDate() && todo->hasDueDate() &&
           todo->dtStart().date() < currentDate &&
           currentDate < todo->dtDue().date() ) {
        accepted = true;
        stateText = i18n( "in progress" );
      }

      // all todos which start today
      if ( todo->hasStartDate() && todo->dtStart().date() == currentDate ) {
        accepted = true;
        stateText = i18n( "starts today" );
      }

      // all todos which end today
      if ( todo->hasDueDate() && todo->dtDue().date() == currentDate ) {
        accepted = true;
        stateText = i18n( "ends today" );
      }

      if ( !accepted )
        continue;

      label = new QLabel( this );
      label->setPixmap( pm );
      label->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
      mLayout->addWidget( label, counter, 0 );
      mLabels.append( label );

      label = new QLabel( QString::number( todo->percentComplete() ) + "%", this );
      label->setAlignment( AlignHCenter | AlignVCenter );
      label->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
      mLayout->addWidget( label, counter, 1 );
      mLabels.append( label );

      QString sSummary = todo->summary();
      if ( todo->relatedTo() ) { // show parent only, not entire ancestry
        sSummary = todo->relatedTo()->summary() + ":" + todo->summary();
      }
      KURLLabel *urlLabel = new KURLLabel( this );
      urlLabel->setText( sSummary );
      urlLabel->setURL( todo->uid() );
      urlLabel->installEventFilter( this );
      urlLabel->setTextFormat( Qt::RichText );
      mLayout->addWidget( urlLabel, counter, 2 );
      mLabels.append( urlLabel );

      connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
               this, SLOT( viewTodo( const QString& ) ) );
      connect( urlLabel, SIGNAL( rightClickedURL( const QString& ) ),
               this, SLOT( popupMenu( const QString& ) ) );

      QString tipText( KCal::IncidenceFormatter::toolTipString( todo, true ) );
      if ( !tipText.isEmpty() ) {
        QToolTip::add( urlLabel, tipText );
      }

      label = new QLabel( stateText, this );
      label->setAlignment( AlignLeft | AlignVCenter );
      label->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
      mLayout->addWidget( label, counter, 3 );
      mLabels.append( label );

      counter++;
    }
  }

  if ( counter == 0 ) {
    QLabel *noTodos = new QLabel( i18n( "No to-dos pending" ), this );
    noTodos->setAlignment( AlignHCenter | AlignVCenter );
    mLayout->addWidget( noTodos, 0, 1 );
    mLabels.append( noTodos );
  }

  for ( label = mLabels.first(); label; label = mLabels.next() )
    label->show();
}

void TodoSummaryWidget::viewTodo( const QString &uid )
{
  mPlugin->core()->selectPlugin( "kontact_todoplugin" );//ensure loaded
  KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
  iface.editIncidence( uid );
}

void TodoSummaryWidget::removeTodo( const QString &uid )
{
  mPlugin->core()->selectPlugin( "kontact_todoplugin" );//ensure loaded
  KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
  iface.deleteIncidence( uid, false );
}

void TodoSummaryWidget::completeTodo( const QString &uid )
{
  KCal::Todo *todo = mCalendar->todo( uid );
  IncidenceChanger *changer = new IncidenceChanger( mCalendar, this );
  if ( !todo->isReadOnly() && changer->beginChange( todo ) ) {
    KCal::Todo *oldTodo = todo->clone();
    todo->setCompleted( QDateTime::currentDateTime() );
    changer->changeIncidence( oldTodo, todo, KOGlobals::COMPLETION_MODIFIED );
    changer->endChange( todo );
    delete oldTodo;
    updateView();
  }
}

void TodoSummaryWidget::popupMenu( const QString &uid )
{
  KPopupMenu popup( this );
  QToolTip::remove( this );
  popup.insertItem( i18n( "&Edit To-do..." ), 0 );
  popup.insertItem( KGlobal::iconLoader()->loadIcon( "editdelete", KIcon::Small),
                    i18n( "&Delete To-do" ), 1 );
  KCal::Todo *todo = mCalendar->todo( uid );
  if ( !todo->isCompleted() ) {
    popup.insertItem( KGlobal::iconLoader()->loadIcon( "checkedbox", KIcon::Small),
                      i18n( "&Mark To-do Completed" ), 2 );
  }

  switch ( popup.exec( QCursor::pos() ) ) {
    case 0:
      viewTodo( uid );
      break;
    case 1:
      removeTodo( uid );
      break;
    case 2:
      completeTodo( uid );
      break;
  }
}

bool TodoSummaryWidget::eventFilter( QObject *obj, QEvent* e )
{
  if ( obj->inherits( "KURLLabel" ) ) {
    KURLLabel* label = static_cast<KURLLabel*>( obj );
    if ( e->type() == QEvent::Enter )
      emit message( i18n( "Edit To-do: \"%1\"" ).arg( label->text() ) );
    if ( e->type() == QEvent::Leave )
      emit message( QString::null );
  }

  return Kontact::Summary::eventFilter( obj, e );
}

QStringList TodoSummaryWidget::configModules() const
{
  return QStringList( "kcmtodosummary.desktop" );
}

#include "todosummarywidget.moc"
<|endoftext|>


<commit_before>#include "lookalikemain.h"
#include <MApplication>
#include <MApplicationWindow>
#include <MComponentCache>
#include <MExport>

M_EXPORT int main(int argc, char *argv[])
{
    MApplication *application = MComponentCache::mApplication(argc, argv, "lookalike");
    MApplicationWindow *window = MComponentCache::mApplicationWindow();
    window->setStyleName(QLatin1String("CommonApplicationWindowInverted"));
    window->setWindowTitle("Look alike");
    LookAlikeMain *main = new LookAlikeMain();
    window->show();

    int result = application->exec();

    delete main;
    delete window;
    delete application;

    return result;
}
<commit_msg>Set fullscreen mode<commit_after>#include "lookalikemain.h"
#include <MApplication>
#include <MApplicationWindow>
#include <MComponentCache>
#include <MExport>

M_EXPORT int main(int argc, char *argv[])
{
    MApplication *application = MComponentCache::mApplication(argc, argv, "lookalike");
    MApplicationWindow *window = MComponentCache::mApplicationWindow();
    window->setStyleName(QLatin1String("CommonApplicationWindowInverted"));
    window->setWindowTitle("Look alike");
    LookAlikeMain *main = new LookAlikeMain();
    window->show();

    // Hide the status bar
    Qt::WindowStates state = window->windowState();
    window->setWindowState(state | Qt::WindowFullScreen);
    // Disable rounded corners
    window->setRoundedCornersEnabled(false);

    int result = application->exec();

    delete main;
    delete window;
    delete application;

    return result;
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <ncurses.h>

#include "../global/Global.h"

#include "../game.h"
#include "Actor.h"
#include "Enemy.h"

// Where am I drawn; who is my enemy?
Enemy::Enemy(Window &w, Actor &a) : Actor(&w) {
    setChar('X');
    init_pair(1, COLOR_RED, -1);
    disp_colo = COLOR_PAIR(1);

    target = &a;
    computeAggro();

    setPosRand();
};

void Enemy::computeAggro() {
    switch(g->getDifficulty()) {
        case CHEAT:
            aggro = 0;
            break;
        case EASY:
            aggro = 20;
            break;
        case MEDIUM:
            aggro = 30;
            break;
        case HARD:
            aggro = 50;
            break;
        case NIGHTMARE:
            aggro = 100;
            break;
    }
}

void Enemy::move() {
    // Check if target is within aggro range
    if (getDistance(target->getPos()) <= aggro) {
        seek();
    } else {
        mill();
    }
}

void Enemy::mill() {
    int targetDirection = getDirection(*target);
}

// TODO refactor to use getDirection
vec2ui Enemy::seek() {

    // Target above, below, left, or right of me
    if (isSouth(*target)) {
        this->moveSouth();
    } else if (isNorth(*target)) {
        this->moveNorth();
    } else if (isEast(*target)) {
        this->moveEast();
    } else if (isWest(*target)) {
        this->moveWest();
    }

    // Target diagonal to me
    else if(isNorthEast(*target)) {
        this->moveNorthEast();
    } else if(isSouthEast(*target)) {
        this->moveSouthEast();
    } else if(isSouthWest(*target)) {
        this->moveSouthWest();
    } else {
        this->moveNorthWest();
    }

    return this->getPos();
}
<commit_msg>Pseudo-randomly determine if skipping turn<commit_after>#include <stdlib.h>
#include <ncurses.h>

#include "../global/Global.h"

#include "../game.h"
#include "Actor.h"
#include "Enemy.h"

// Where am I drawn; who is my enemy?
Enemy::Enemy(Window &w, Actor &a) : Actor(&w) {
    setChar('X');
    init_pair(1, COLOR_RED, -1);
    disp_colo = COLOR_PAIR(1);

    target = &a;
    computeAggro();

    setPosRand();
};

void Enemy::computeAggro() {
    switch(g->getDifficulty()) {
        case CHEAT:
            aggro = 0;
            break;
        case EASY:
            aggro = 20;
            break;
        case MEDIUM:
            aggro = 30;
            break;
        case HARD:
            aggro = 50;
            break;
        case NIGHTMARE:
            aggro = 100;
            break;
    }
}

void Enemy::move() {
    int modifier = (100 - getDistance(target->getPos()) * 4.2);
    int pool     = (100 - g->getDifficulty());
    int roll     = (rand() % pool);
    bool chance  = (roll < modifier);

    // Check if target is lucky
    if (chance) {
        // Check if target is within aggro range
        if (getDistance(target->getPos()) <= aggro) {
            seek();
        } else {
            mill();
        }
    }
}

void Enemy::mill() {
    int targetDirection = getDirection(*target);
}

// TODO refactor to use getDirection
vec2ui Enemy::seek() {

    // Target above, below, left, or right of me
    if (isSouth(*target)) {
        this->moveSouth();
    } else if (isNorth(*target)) {
        this->moveNorth();
    } else if (isEast(*target)) {
        this->moveEast();
    } else if (isWest(*target)) {
        this->moveWest();
    }

    // Target diagonal to me
    else if(isNorthEast(*target)) {
        this->moveNorthEast();
    } else if(isSouthEast(*target)) {
        this->moveSouthEast();
    } else if(isSouthWest(*target)) {
        this->moveSouthWest();
    } else {
        this->moveNorthWest();
    }

    return this->getPos();
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "s60devicespreferencepane.h"
#include "ui_s60devicespreferencepane.h"

#include <qt4projectmanager/qt4projectmanagerconstants.h>

#include <QtDebug>

using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;

S60DevicesWidget::S60DevicesWidget(QWidget *parent, S60Devices *devices) :
    QWidget(parent),
    m_ui(new Ui::S60DevicesPreferencePane),
    m_devices(devices)
{
    m_ui->setupUi(this);
    connect(m_ui->refreshButton, SIGNAL(clicked()), this, SLOT(updateDevices()));
    updateDevicesList();
}

S60DevicesWidget::~S60DevicesWidget()
{
    delete m_ui;
}

void S60DevicesWidget::updateDevices()
{
    m_devices->read();
    Q_ASSERT(m_devices->detectQtForDevices());
    updateDevicesList();
}

void S60DevicesWidget::updateDevicesList()
{
    QList<S60Devices::Device> devices = m_devices->devices();
    m_ui->list->clear();
    foreach (const S60Devices::Device &device, devices) {
        QStringList columns;
        columns << device.epocRoot << (device.qt.isEmpty()?tr("No Qt installed"):device.qt);
        QTreeWidgetItem *item = new QTreeWidgetItem(columns);
        const QString tooltip = device.toHtml();
        item->setToolTip(0, tooltip);
        item->setToolTip(1, tooltip);
        m_ui->list->addTopLevelItem(item);
    }
    const QString errorString = m_devices->errorString();
    if (errorString.isEmpty()) {
        clearErrorLabel();
    } else {
        setErrorLabel(errorString);
    }
}

void S60DevicesWidget::setErrorLabel(const QString& t)
{
    m_ui->errorLabel->setText(t);
    m_ui->errorLabel->setVisible(true);
}

void S60DevicesWidget::clearErrorLabel()
{
    m_ui->errorLabel->setVisible(false);
}

S60DevicesPreferencePane::S60DevicesPreferencePane(S60Devices *devices, QObject *parent)
        : Core::IOptionsPage(parent),
        m_widget(0),
        m_devices(devices)
{
    m_devices->read();
}

S60DevicesPreferencePane::~S60DevicesPreferencePane()
{
}

QString S60DevicesPreferencePane::id() const
{
    return QLatin1String("Z.S60 SDKs");
}

QString S60DevicesPreferencePane::displayName() const
{
    return tr("S60 SDKs");
}

QString S60DevicesPreferencePane::category() const
{
    return QLatin1String(Constants::QT_SETTINGS_CATEGORY);
}

QString S60DevicesPreferencePane::displayCategory() const
{
    return QCoreApplication::translate("Qt4ProjectManager", Constants::QT_SETTINGS_CATEGORY);
}

QWidget *S60DevicesPreferencePane::createPage(QWidget *parent)
{
    if (m_widget)
        delete m_widget;
    m_widget = new S60DevicesWidget(parent, m_devices);
    return m_widget;
}

void S60DevicesPreferencePane::apply()
{
}

void S60DevicesPreferencePane::finish()
{
}

<commit_msg>Use native  dir separators in S60 device preference pane.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "s60devicespreferencepane.h"
#include "ui_s60devicespreferencepane.h"

#include <qt4projectmanager/qt4projectmanagerconstants.h>

#include <QtCore/QDir>
#include <QtDebug>

using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;

S60DevicesWidget::S60DevicesWidget(QWidget *parent, S60Devices *devices) :
    QWidget(parent),
    m_ui(new Ui::S60DevicesPreferencePane),
    m_devices(devices)
{
    m_ui->setupUi(this);
    connect(m_ui->refreshButton, SIGNAL(clicked()), this, SLOT(updateDevices()));
    updateDevicesList();
}

S60DevicesWidget::~S60DevicesWidget()
{
    delete m_ui;
}

void S60DevicesWidget::updateDevices()
{
    m_devices->read();
    Q_ASSERT(m_devices->detectQtForDevices());
    updateDevicesList();
}

void S60DevicesWidget::updateDevicesList()
{
    QList<S60Devices::Device> devices = m_devices->devices();
    m_ui->list->clear();
    foreach (const S60Devices::Device &device, devices) {
        QStringList columns;
        columns << QDir::toNativeSeparators(device.epocRoot)
                << (device.qt.isEmpty()?tr("No Qt installed"):QDir::toNativeSeparators(device.qt));
        QTreeWidgetItem *item = new QTreeWidgetItem(columns);
        const QString tooltip = device.toHtml();
        item->setToolTip(0, tooltip);
        item->setToolTip(1, tooltip);
        m_ui->list->addTopLevelItem(item);
    }
    const QString errorString = m_devices->errorString();
    if (errorString.isEmpty()) {
        clearErrorLabel();
    } else {
        setErrorLabel(errorString);
    }
}

void S60DevicesWidget::setErrorLabel(const QString& t)
{
    m_ui->errorLabel->setText(t);
    m_ui->errorLabel->setVisible(true);
}

void S60DevicesWidget::clearErrorLabel()
{
    m_ui->errorLabel->setVisible(false);
}

S60DevicesPreferencePane::S60DevicesPreferencePane(S60Devices *devices, QObject *parent)
        : Core::IOptionsPage(parent),
        m_widget(0),
        m_devices(devices)
{
    m_devices->read();
}

S60DevicesPreferencePane::~S60DevicesPreferencePane()
{
}

QString S60DevicesPreferencePane::id() const
{
    return QLatin1String("Z.S60 SDKs");
}

QString S60DevicesPreferencePane::displayName() const
{
    return tr("S60 SDKs");
}

QString S60DevicesPreferencePane::category() const
{
    return QLatin1String(Constants::QT_SETTINGS_CATEGORY);
}

QString S60DevicesPreferencePane::displayCategory() const
{
    return QCoreApplication::translate("Qt4ProjectManager", Constants::QT_SETTINGS_CATEGORY);
}

QWidget *S60DevicesPreferencePane::createPage(QWidget *parent)
{
    if (m_widget)
        delete m_widget;
    m_widget = new S60DevicesWidget(parent, m_devices);
    return m_widget;
}

void S60DevicesPreferencePane::apply()
{
}

void S60DevicesPreferencePane::finish()
{
}

<|endoftext|>


<commit_before>#include <cstdlib>
#include <sys/wait.h>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include "main.h"
using namespace std;

pid_t wpid = 0;
static void sigHandle(int sig, siginfo_t *Info, void *Pointer);
int main() {
	string userinput;
	string login = getlogin();
	if(login == "")
		perror("getlogin");
	char hostname[128];
	if(gethostname(hostname, sizeof hostname))
		perror("gethostname");
	bool ext  = false;
	string exit_status = "exit";
	struct sigaction Curr;
	struct sigaction Prev;
	sigset_t x;
	Curr.sa_mask = x;
	Curr.sa_sigaction = sigHandle;
	Curr.sa_flags = 0;
	Prev.sa_flags = 0;
	string directory_a = "";
	if(sigaction(SIGINT, &Curr, &Prev) == -1)
		perror("SIGINT sigaction");
	if(sigaction(SIGTSTP, &Curr, &Prev) == -1)
		perror("SIGTSTP sigaction");
	if(sigaction(SIGCHLD, &Curr, &Prev) == -1)
		perror("SIGCHLD sigaction");
	while(!ext) {
		char *pPath, *hHome;
		if((pPath = getenv("PWD")) == NULL)
			perror("first.1 getenv");
		if((hHome = getenv("HOME")) == NULL)
			perror("first.2 getenv");
		string PPath(pPath), HHome(hHome);
		if(PPath.find(HHome) != string::npos) {
			PPath.erase(PPath.begin(), PPath.begin() + HHome.size());
			PPath.insert(PPath.begin(), '~');
		}
		cout << login << "@" << hostname << PPath << " $ ";
		char *command_a;
		char *command;
		cin.clear();
		getline(cin, userinput);
		if(userinput.find("#") != string::npos)
			userinput.erase(userinput.find("#"), userinput.size());
		command = new char[userinput.size()];
		vector<int> c_pat;
		vector<int> c_pos;
		bool first = false;
		bool multiple = false;
		if(userinput.size() != 0)
			connectors(userinput, c_pat, c_pos, first, multiple);
		int x = 0;
		unsigned int b = 0;
		int y = 0;
		char *arg[50000];
		int status;
		redir condition;
		if(userinput.size() != 0) {
			while(userinput.substr(x, 1) != "") {
				if(multiple) {
					cout << "Error: Incorrect connector config" << endl;
					break;
				}
				if(first) {
					cout << "Error: file does not exist" << endl;
					break;
				}
				redir_check(condition, userinput.substr(x, c_pos.at(y) -x).c_str());
				strcpy(command, userinput.substr(x, c_pos.at(y) - x).c_str());
				command_a = strtok(command, "&;| \t");
				while(command_a != NULL) {
					arg[b] = command_a;
					command_a = strtok(NULL, "&;| \t");
					b++;
				}
				if(userinput.substr(x, c_pos.at(y) - x).find("exit") != string::npos && b==1) {
					ext = true;
					break;
				}
				if(condition.redir_x) {
					redir_action(condition);
					nullify(condition);
				}
				else if(strcmp(arg[0], "cd") == 0) {
					if(b == 1) {
						char *home, *old;
						if((home = getenv("HOME")) == NULL)
							perror("getenv_1.1");
						if((old = getenv("PWD")) == NULL)
							perror("getenv_1.2");
						if(chdir(home) == -1)
							perror("chdir_1");
						if(setenv("PWD", home, 1) == -1)
							perror("setenv_1.1");
						if(setenv("OLDPWD", old, 1) == -1)
							perror("setenv_1.2");
					}
					else if(strcmp(arg[1], "-") == 0) {
						char *old, *newDir;
						if((old = getenv("PWD")) == NULL)
							perror("getenv_2.1");
						if((newDir = getenv("OLDPWD")) == NULL)
							perror("getenv_2.2");
						if(chdir(newDir) == -1)
							perror("chdr_2");
						if(setenv("PWD", newDir, 1) == -1)
							perror("setenv_2.1");
						if(setenv("OLDPWD", old, 1) == -1)
							perror("setenv_2.2");
					}
					else if(strrchr(arg[1], '~') != NULL) {
						if(strlen(arg[1]) == 1) {
							char *old, *home;
							if((old = getenv("PWD")) == NULL)
								perror("~ getenv1");
							if((home = getenv("HOME")) == NULL)
								perror("~ getenv2");
							if((chdir(home)) == -1)
								perror("~ chdir");
							if(setenv("OLDPWD", old, 1) == -1)
								perror("~ setenv_1");
							if(setenv("PWD", home, 1) == -1)
								perror("~ setenv_1");
						}
						else {
							char *old, *home;
							if((old = getenv("PWD")) == NULL)
								perror("~-- getenv1");
							if((home = getenv("HOME")) == NULL)
								perror("~-- getenv2");
							string ndir(home), argu(arg[1]);
							argu.erase(argu.begin());
							ndir = ndir + argu;
							if((chdir(ndir.c_str())) == -1) {
								perror("~-- chdir");
								if(chdir(old) == -1)
									perror("chdir 1");
								if(setenv("OLDPWD", old, 1) == -1)
									perror("~-- setenv1");
								if(setenv("PWD", old, 1) == -1)
									perror("~-- setenvr2");

							}
							else {
								if(setenv("OLDPWD", old, 1) == -1)
									perror("~-- setenv1");
								if(setenv("PWD", ndir.c_str(), 1) == -1)
									perror("~-- setenvr2");
							}
						}
					}
					else {
						char *old;
						if((old = getenv("PWD")) == NULL)
							perror("getenv_3.1");
						if(setenv("OLDPWD", old, 1) == -1)
							perror("setenv_3.1");
						if(chdir(arg[1]) == -1) {
							perror("chdir_3");
							if(chdir(old) == -1)
								perror("chdir 2");
							if(setenv("PWD", old, 1) == -1)
								perror("setenv 4");
						}
						else {string newEnv(old);
							string newDir(arg[1]);
							if(strcmp(arg[1],"..") != 0) {
								string g(arg[1]);
								directory_a = g;
								newEnv = newEnv + "/" + newDir;
							}
							else if(strcmp(arg[1], "..") == 0) {
								char *temp;
								if((temp = getenv("PWD")) == NULL)
									perror(".. getenv");
								string g(temp);
								while(g.at(g.size() - 1) != '/')
									g.erase(g.size() - 1);
								g.erase(g.size() - 1);
								newEnv = g;
							}
							if(setenv("PWD", newEnv.c_str(), 1) == -1)
								perror("setenv_3.2");
						}
					}

				}
				else {
					int i = fork();
					if(i == -1)
						perror("fork");
					if(i == 0) {
						if(execvp(arg[0], arg) == -1) {
							perror("execvp");
							exit(-1);
						}
						exit(0);
					}
					do {
						wpid = wait(&status);
					} while (wpid == -1 && errno == EINTR);
					if(wpid == -1) {
						perror("wait error");
						exit(-1);
					}
				}
				x = c_pos.at(y);
				unsigned int help = c_pat.at(y);
				for(unsigned int i = 0; i < b; i++)
					arg[i] = NULL;
				if((help == 1 && status == 0) || (help == 0 && status != 0) || help == 2)
					y++;
				else if(help == 1 && status != 0 && (userinput.find("||", x) != string::npos || userinput.find(";", x) != string::npos)) {
					x = c_pos.at(y + 1);
					y+=2;
				}
				else if(help == 0 && status == 0 && (userinput.find("&&", x) != string::npos || userinput.find(";", x) != string::npos)) {
					x = c_pos.at(y + 1);
					y+=2;
				}
				else
					break;
				b = 0;
			}
		}
		delete []command;
	}
	return 0;
}
static void sigHandle(int sig, siginfo_t *Info, void *Pointer) {
	if(sig == SIGINT) {
		cout << Info->si_pid - Info->si_pid << Pointer;
		cout << "C" << endl;
		kill(wpid, SIGKILL);
		return;
	}
	else if (sig == SIGTSTP) {
		raise(SIGSTOP);
		cout << endl;
	}
	else {
	//	cout << "not a valid signal" << endl;
		return;
	}
}
<commit_msg>most likely almost there<commit_after>#include <cstdlib>
#include <sys/wait.h>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include "main.h"
using namespace std;

pid_t wpid = 0;
pid_t fpid = 0;
static void sigHandle(int sig, siginfo_t *Info, void *Pointer);
int main() {
	string userinput;
	string login = getlogin();
	if(login == "")
		perror("getlogin");
	char hostname[128];
	if(gethostname(hostname, sizeof hostname))
		perror("gethostname");
	bool ext  = false;
	string exit_status = "exit";
	struct sigaction Curr;
	struct sigaction Prev;
	sigset_t x;
	Curr.sa_mask = x;
	Curr.sa_sigaction = sigHandle;
	Curr.sa_flags = 0;
	Prev.sa_flags = 0;
	string directory_a = "";
	if(sigaction(SIGINT, &Curr, &Prev) == -1)
		perror("SIGINT sigaction");
	if(sigaction(SIGTSTP, &Curr, &Prev) == -1)
		perror("SIGTSTP sigaction");
	if(sigaction(SIGCHLD, &Curr, &Prev) == -1)
		perror("SIGCHLD sigaction");
	while(!ext) {
		char *pPath, *hHome;
		if((pPath = getenv("PWD")) == NULL)
			perror("first.1 getenv");
		if((hHome = getenv("HOME")) == NULL)
			perror("first.2 getenv");
		string PPath(pPath), HHome(hHome);
		if(PPath.find(HHome) != string::npos) {
			PPath.erase(PPath.begin(), PPath.begin() + HHome.size());
			PPath.insert(PPath.begin(), '~');
		}
		cout << login << "@" << hostname << PPath << " $ ";
		char *command_a;
		char *command;
		cin.clear();
		getline(cin, userinput);
		if(userinput.find("#") != string::npos)
			userinput.erase(userinput.find("#"), userinput.size());
		command = new char[userinput.size()];
		vector<int> c_pat;
		vector<int> c_pos;
		bool first = false;
		bool multiple = false;
		if(userinput.size() != 0)
			connectors(userinput, c_pat, c_pos, first, multiple);
		int x = 0;
		unsigned int b = 0;
		int y = 0;
		char *arg[50000];
		int status;
		redir condition;
		if(userinput.size() != 0) {
			while(userinput.substr(x, 1) != "") {
				if(multiple) {
					cout << "Error: Incorrect connector config" << endl;
					break;
				}
				if(first) {
					cout << "Error: file does not exist" << endl;
					break;
				}
				redir_check(condition, userinput.substr(x, c_pos.at(y) -x).c_str());
				strcpy(command, userinput.substr(x, c_pos.at(y) - x).c_str());
				command_a = strtok(command, "&;| \t");
				while(command_a != NULL) {
					arg[b] = command_a;
					command_a = strtok(NULL, "&;| \t");
					b++;
				}
				if(userinput.substr(x, c_pos.at(y) - x).find("exit") != string::npos && b==1) {
					ext = true;
					break;
				}
				if(condition.redir_x) {
					redir_action(condition);
					nullify(condition);
				}
				else if(strcmp(arg[0], "cd") == 0) {
					if(b == 1) {
						char *home, *old;
						if((home = getenv("HOME")) == NULL)
							perror("getenv_1.1");
						if((old = getenv("PWD")) == NULL)
							perror("getenv_1.2");
						if(chdir(home) == -1)
							perror("chdir_1");
						if(setenv("PWD", home, 1) == -1)
							perror("setenv_1.1");
						if(setenv("OLDPWD", old, 1) == -1)
							perror("setenv_1.2");
					}
					else if(strcmp(arg[1], "-") == 0) {
						char *old, *newDir;
						if((old = getenv("PWD")) == NULL)
							perror("getenv_2.1");
						if((newDir = getenv("OLDPWD")) == NULL)
							perror("getenv_2.2");
						if(chdir(newDir) == -1)
							perror("chdr_2");
						if(setenv("PWD", newDir, 1) == -1)
							perror("setenv_2.1");
						if(setenv("OLDPWD", old, 1) == -1)
							perror("setenv_2.2");
					}
					else if(strrchr(arg[1], '~') != NULL) {
						if(strlen(arg[1]) == 1) {
							char *old, *home;
							if((old = getenv("PWD")) == NULL)
								perror("~ getenv1");
							if((home = getenv("HOME")) == NULL)
								perror("~ getenv2");
							if((chdir(home)) == -1)
								perror("~ chdir");
							if(setenv("OLDPWD", old, 1) == -1)
								perror("~ setenv_1");
							if(setenv("PWD", home, 1) == -1)
								perror("~ setenv_1");
						}
						else {
							char *old, *home;
							if((old = getenv("PWD")) == NULL)
								perror("~-- getenv1");
							if((home = getenv("HOME")) == NULL)
								perror("~-- getenv2");
							string ndir(home), argu(arg[1]);
							argu.erase(argu.begin());
							ndir = ndir + argu;
							if((chdir(ndir.c_str())) == -1) {
								perror("~-- chdir");
								if(chdir(old) == -1)
									perror("chdir 1");
								if(setenv("OLDPWD", old, 1) == -1)
									perror("~-- setenv1");
								if(setenv("PWD", old, 1) == -1)
									perror("~-- setenvr2");

							}
							else {
								if(setenv("OLDPWD", old, 1) == -1)
									perror("~-- setenv1");
								if(setenv("PWD", ndir.c_str(), 1) == -1)
									perror("~-- setenvr2");
							}
						}
					}
					else {
						char *old;
						if((old = getenv("PWD")) == NULL)
							perror("getenv_3.1");
						if(setenv("OLDPWD", old, 1) == -1)
							perror("setenv_3.1");
						if(chdir(arg[1]) == -1) {
							perror("chdir_3");
							if(chdir(old) == -1)
								perror("chdir 2");
							if(setenv("PWD", old, 1) == -1)
								perror("setenv 4");
						}
						else {string newEnv(old);
							string newDir(arg[1]);
							if(strcmp(arg[1],"..") != 0) {
								string g(arg[1]);
								directory_a = g;
								newEnv = newEnv + "/" + newDir;
							}
							else if(strcmp(arg[1], "..") == 0) {
								char *temp;
								if((temp = getenv("PWD")) == NULL)
									perror(".. getenv");
								string g(temp);
								while(g.at(g.size() - 1) != '/')
									g.erase(g.size() - 1);
								g.erase(g.size() - 1);
								newEnv = g;
							}
							if(setenv("PWD", newEnv.c_str(), 1) == -1)
								perror("setenv_3.2");
						}
					}

				}
				else {
					fpid = fork();
					if(fpid == -1)
						perror("fork");
					if(fpid == 0) {
						if(execvp(arg[0], arg) == -1) {
							perror("execvp");
							exit(-1);
						}
						exit(0);
					}
					do {
						wpid = wait(&status);
					} while (wpid == -1 && errno == EINTR);
					if(wpid == -1) {
						perror("wait error");
						exit(-1);
					}
				}
				x = c_pos.at(y);
				unsigned int help = c_pat.at(y);
				for(unsigned int i = 0; i < b; i++)
					arg[i] = NULL;
				if((help == 1 && status == 0) || (help == 0 && status != 0) || help == 2)
					y++;
				else if(help == 1 && status != 0 && (userinput.find("||", x) != string::npos || userinput.find(";", x) != string::npos)) {
					x = c_pos.at(y + 1);
					y+=2;
				}
				else if(help == 0 && status == 0 && (userinput.find("&&", x) != string::npos || userinput.find(";", x) != string::npos)) {
					x = c_pos.at(y + 1);
					y+=2;
				}
				else
					break;
				b = 0;
			}
		}
		delete []command;
	}
	return 0;
}
static void sigHandle(int sig, siginfo_t *Info, void *Pointer) {
	if(sig == SIGINT) {
		cout << Info->si_pid - Info->si_pid << Pointer;
		cout << "C" << endl;
		return;
	}
	else if (sig == SIGTSTP) {
		if(fpid != 0) {
			kill(fpid, SIGSTOP);
			cout << endl;
		}
		return;
	}
	else {
	//	cout << "not a valid signal" << endl;
		return;
	}
}
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2012 Heiko Strathmann
 */

#include <shogun/statistics/LinearTimeMMD.h>
#include <shogun/features/Features.h>
#include <shogun/mathematics/Statistics.h>

using namespace shogun;

CLinearTimeMMD::CLinearTimeMMD() :
		CKernelTwoSampleTestStatistic()
{
	init();
}

CLinearTimeMMD::CLinearTimeMMD(CKernel* kernel, CFeatures* p_and_q,
		index_t q_start) :
		CKernelTwoSampleTestStatistic(kernel, p_and_q, q_start)
{
	init();

	if (q_start!=p_and_q->get_num_vectors()/2)
	{
		SG_ERROR("CLinearTimeMMD: Only features with equal number of vectors "
				"are currently possible\n");
	}
}

CLinearTimeMMD::~CLinearTimeMMD()
{

}

void CLinearTimeMMD::init()
{

}

float64_t CLinearTimeMMD::compute_statistic()
{
	/* TODO features with a different number of vectors should be allowed */

	/* m is number of samples from each distribution, m_2 is half of it
	 * using names from JLMR paper (see class documentation) */
	index_t m=m_q_start;
	index_t m_2=m/2;

	/* compute traces of kernel matrices for linear MMD */
	m_kernel->init(m_p_and_q, m_p_and_q);

	float64_t pp=0;
	float64_t qq=0;
	float64_t pq=0;
	float64_t qp=0;

	/* compute traces */
	for (index_t i=0; i<m_2; ++i)
	{
		pp+=m_kernel->kernel(i, m_2+i);
		qq+=m_kernel->kernel(m+i, m+m_2+i);
		pq+=m_kernel->kernel(i, m+m_2+i);
		qp+=m_kernel->kernel(m_2+i, m+i);
	}

	/* mean of sum all traces is linear time mmd */
	return 1.0/m_2*(pp+qq-pq-qp);
}

float64_t CLinearTimeMMD::compute_p_value(float64_t statistic)
{
	float64_t result=0;

	switch (m_p_value_method)
	{
	case MMD1_GAUSSIAN:
		if (m_p_and_q->get_num_vectors()<10000)
		{
			SG_WARNING("CLinearTimeMMD::compute_p_value: The number of samples"
					" should be very large (at least 10000)  in order to get a"
					" good Gaussian approximation using MMD1_GAUSSIAN.\n");
		}

		{
			/* compute variance and use to estimate Gaussian distribution */
			float64_t std_dev=CMath::sqrt(compute_variance_estimate());
			result=CStatistics::normal_cdf(statistic, std_dev);
		}
		break;
	default:
		result=CKernelTwoSampleTestStatistic::compute_p_value(statistic);
		break;
	}

	return result;
}

float64_t CLinearTimeMMD::compute_variance_estimate()
{
	/* this corresponds to computing the statistic itself, however, the
	 * difference is that all terms (of the traces) have to be stored */
	index_t m=m_q_start;
	index_t m_2=m/2;

	m_kernel->init(m_p_and_q, m_p_and_q);

	/* allocate memory for traces */
	SGVector<float64_t> traces(m_2);

	/* sum up diagonals of all kernel matrices */
	for (index_t i=0; i<m_2; ++i)
	{
		/* init for code beauty :) */
		traces[i]=0;

		/* p and p */
		traces[i]+=m_kernel->kernel(i, m_2+i);

		/* q and q */
		traces[i]+=m_kernel->kernel(m+i, m+m_2+i);

		/* p and q */
		traces[i]-=m_kernel->kernel(i, m+m_2+i);

		/* q and p */
		traces[i]-=m_kernel->kernel(m_2+i, m+i);
	}

	/* return linear time variance estimate */
	return CStatistics::variance(traces)/m_2;
}

<commit_msg>small fix<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2012 Heiko Strathmann
 */

#include <shogun/statistics/LinearTimeMMD.h>
#include <shogun/features/Features.h>
#include <shogun/mathematics/Statistics.h>

using namespace shogun;

CLinearTimeMMD::CLinearTimeMMD() :
		CKernelTwoSampleTestStatistic()
{
	init();
}

CLinearTimeMMD::CLinearTimeMMD(CKernel* kernel, CFeatures* p_and_q,
		index_t q_start) :
		CKernelTwoSampleTestStatistic(kernel, p_and_q, q_start)
{
	init();

	if (q_start!=p_and_q->get_num_vectors()/2)
	{
		SG_ERROR("CLinearTimeMMD: Only features with equal number of vectors "
				"are currently possible\n");
	}
}

CLinearTimeMMD::~CLinearTimeMMD()
{

}

void CLinearTimeMMD::init()
{

}

float64_t CLinearTimeMMD::compute_statistic()
{
	/* TODO features with a different number of vectors should be allowed */

	/* m is number of samples from each distribution, m_2 is half of it
	 * using names from JLMR paper (see class documentation) */
	index_t m=m_q_start;
	index_t m_2=m/2;

	/* compute traces of kernel matrices for linear MMD */
	m_kernel->init(m_p_and_q, m_p_and_q);

	float64_t pp=0;
	float64_t qq=0;
	float64_t pq=0;
	float64_t qp=0;

	/* compute traces */
	for (index_t i=0; i<m_2; ++i)
	{
		pp+=m_kernel->kernel(i, m_2+i);
		qq+=m_kernel->kernel(m+i, m+m_2+i);
		pq+=m_kernel->kernel(i, m+m_2+i);
		qp+=m_kernel->kernel(m_2+i, m+i);
	}

	/* mean of sum all traces is linear time mmd */
	return 1.0/m_2*(pp+qq-pq-qp);
}

float64_t CLinearTimeMMD::compute_p_value(float64_t statistic)
{
	float64_t result=0;

	switch (m_p_value_method)
	{
	case MMD1_GAUSSIAN:
		if (m_p_and_q->get_num_vectors()<10000)
		{
			SG_WARNING("CLinearTimeMMD::compute_p_value: The number of samples"
					" should be very large (at least 10000)  in order to get a"
					" good Gaussian approximation using MMD1_GAUSSIAN.\n");
		}

		{
			/* compute variance and use to estimate Gaussian distribution */
			float64_t std_dev=CMath::sqrt(compute_variance_estimate());
			result=1.0-CStatistics::normal_cdf(statistic, std_dev);
		}
		break;
	default:
		result=CKernelTwoSampleTestStatistic::compute_p_value(statistic);
		break;
	}

	return result;
}

float64_t CLinearTimeMMD::compute_variance_estimate()
{
	/* this corresponds to computing the statistic itself, however, the
	 * difference is that all terms (of the traces) have to be stored */
	index_t m=m_q_start;
	index_t m_2=m/2;

	m_kernel->init(m_p_and_q, m_p_and_q);

	/* allocate memory for traces */
	SGVector<float64_t> traces(m_2);

	/* sum up diagonals of all kernel matrices */
	for (index_t i=0; i<m_2; ++i)
	{
		/* init for code beauty :) */
		traces[i]=0;

		/* p and p */
		traces[i]+=m_kernel->kernel(i, m_2+i);

		/* q and q */
		traces[i]+=m_kernel->kernel(m+i, m+m_2+i);

		/* p and q */
		traces[i]-=m_kernel->kernel(i, m+m_2+i);

		/* q and p */
		traces[i]-=m_kernel->kernel(m_2+i, m+i);
	}

	/* return linear time variance estimate */
	return CStatistics::variance(traces)/m_2;
}

<|endoftext|>


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

#include "chord.h"
#include "dhash.h"
#include "parseopt.h"
#include <sys/types.h>

//#define PROFILING

// When a process starts up profiling is not happening.  But by
// sending a SIGUSR1, profiling is turned on.  (Another SIGUSR1 turns
// it off.)  This always specific, user-controlled periods of time to
// be profiled.  Program must be compiled with -pg for this to work.

#ifdef PROFILING
extern "C" {
  void moncontrol(int);
}
#endif

EXITFN (cleanup);

// XXX temporary hack -- reset to something reasonable soon.
//     [used to be 60000]
//     --josh
#define STORE_SIZE 2000000 //size of block store per vnode (in blocks)

ptr<chord> chordnode;
static str p2psocket;
bool do_cache;
int cache_size;
vec<dhash *> dh;
int myport;

void stats ();
void stop ();
void halt ();

void
client_accept (int fd)
{
  if (fd < 0)
    fatal ("EOF\n");

  ref<axprt_stream> x = axprt_stream::alloc (fd);

  // XXX these dhashgateway objects are leaked
  //

   vNew dhashgateway (x, chordnode, do_cache);
}

static void
client_accept_socket (int lfd)
{
  sockaddr_un sun;
  bzero (&sun, sizeof (sun));
  socklen_t sunlen = sizeof (sun);
  int fd = accept (lfd, reinterpret_cast<sockaddr *> (&sun), &sunlen);
  if (fd >= 0)
    client_accept (fd);
}

static void
client_listening_cb (int fd, int status)
{
  if (status)
    close (fd);
  else if (listen (fd, 5) < 0) {
    fatal ("Error from listen: %m\n");
    close (fd);
  } else {
    fdcb (fd, selread, wrap (client_accept_socket, fd));
  }
}

static void
cleanup ()
{
   unlink (p2psocket);
}

static void
startclntd()
{

  unlink (p2psocket);
  int clntfd = unixsocket (p2psocket);
  if (clntfd < 0)
    fatal << "Error creating client socket (UNIX)" << strerror (errno) << "\n";
  client_listening_cb (clntfd, 0);

  int port = (myport == 0) ? 0 : myport + 1;
  int tcp_clntfd = inetsocket (SOCK_STREAM, port);
  if (tcp_clntfd < 0)
    fatal << "Error creating client socket (TCP) " << strerror(errno) << "\n";
  client_listening_cb (tcp_clntfd, 0);

}

static void
newvnode_cb (int nreplica, str db_name, int ss_mode, int n, vnode *my,
	     chordstat stat)
{
  if (stat != CHORD_OK) {
    warnx << "newvnode_cb: status " << stat << "\n";
    fatal ("unable to join\n");
  }
  str db_name_prime = strbuf () << db_name << "-" << n;
  if ((int)dh.size () >= chord::max_vnodes)
    fatal << "Too many virtual nodes (" << chord::max_vnodes << ")\n";
  dh.push_back( New dhash (db_name_prime, my, nreplica,
			    STORE_SIZE,
			    cache_size,
			    ss_mode));
  if (n > 0) chordnode->newvnode (wrap (newvnode_cb, nreplica, db_name,
					ss_mode, n-1));
}

void
halt ()
{
  warnx << "Exiting on command.\n";
  exit (0);
}

#ifdef PROFILING
void
toggle_profiling ()
{
  static int pfstate = 1;
  if (pfstate)
    warn << "Turning profiling off\n";
  else
    warn << "Turning profiling on\n";

  pfstate = !pfstate;
  moncontrol (pfstate ? 1 : 0);
}
#endif

void
stats ()
{
#ifdef PROFILING
  toggle_profiling ();
#else
  chordnode->stats ();
  for (unsigned int i = 0 ; i < dh.size (); i++)
    dh[i]->print_stats ();
  chordnode->print ();
#endif
}

void
stop ()
{
#if 1
  chordnode->stop ();
  for (unsigned int i = 0 ; i < dh.size (); i++)
    dh[i]->stop ();
#else
  setenv ("LOG_FILE", "log", 1);
#endif
}

static void
usage ()
{
  warnx << "Usage: " << progname
	<< " -d <dbfile> -j hostname:port -p port "
    "[-l <locally bound IP>] "
    "[-S <sock>] [-v <nvnode>] [-c <cache?>] "
    "-B <cache size> "
    "[-s <server select mode>]\n";
  exit (1);
}

int
main (int argc, char **argv)
{

#ifdef PROFILING
  toggle_profiling ();
#endif

  int vnode = 1;
  setprogname (argv[0]);
  sfsconst_init ();
  random_init ();

  int ch;

  do_cache = false;
  int ss_mode = 0;

  myport = 0;
  cache_size = 2000;
  // ensure enough room for fingers and successors.
  int max_loccache = (int) (1.2 * (NSUCC + NBIT));
  str wellknownhost;
  int wellknownport = 0;
  int nreplica = 0;
  str db_name = "/var/tmp/db";
  p2psocket = "/tmp/chord-sock";
  str myname = my_addr ();

  while ((ch = getopt (argc, argv, "B:cd:j:l:M:n:p:S:s:v:")) != -1)
    switch (ch) {
    case 'B':
      cache_size = atoi (optarg);
      break;
    case 'c':
      do_cache = true;
      break;
    case 'd':
      db_name = optarg;
      break;
    case 'j':
      {
	char *bs_port = strchr(optarg, ':');
	if (!bs_port) usage ();
	*bs_port = 0;
	bs_port++;
	if (inet_addr (optarg) == INADDR_NONE) {
	  //yep, this blocks
	  struct hostent *h = gethostbyname (optarg);
	  if (!h) {
	    warn << "Invalid address or hostname: " << optarg << "\n";
	    usage ();
	  }
	  struct in_addr *ptr = (struct in_addr *)h->h_addr;
	  wellknownhost = inet_ntoa (*ptr);
	} else
	  wellknownhost = optarg;

	wellknownport = atoi (bs_port);

	break;
      }
    case 'l':
      if (inet_addr (optarg) == INADDR_NONE)
	fatal << "must specify bind address in dotted decimal form\n";
      myname = optarg;
      break;
    case 'M':
      max_loccache = atoi (optarg);
      break;
    case 'n':
      nreplica = atoi (optarg);
      break;
    case 'p':
      myport = atoi (optarg);
      break;
    case 'S':
      p2psocket = optarg;
      break;
    case 's':
      ss_mode = atoi(optarg);
      break;
    case 'v':
      vnode = atoi (optarg);
      break;
    default:
      usage ();
      break;
    }

  if (wellknownport == 0) usage ();

  if (vnode > chord::max_vnodes) {
    warn << "Requested vnodes (" << vnode << ") more than maximum allowed ("
	 << chord::max_vnodes << ")\n";
    usage ();
  }

#ifdef PNODE
  warn << "Chord nodes will emulate physical nodes.\n";
#else /* PNODE */
  max_loccache = max_loccache * (vnode + 1);
#endif /* PNODE */

  chordnode = New refcounted<chord> (wellknownhost, wellknownport,
				     myname,
				     myport,
				     max_loccache,
				     ss_mode);
  chordnode->newvnode (wrap (newvnode_cb, nreplica, db_name, ss_mode,
			     vnode-1));

  sigcb(SIGUSR1, wrap (&stats));
  sigcb(SIGUSR2, wrap (&stop));
  sigcb(SIGHUP, wrap (&halt));

  if (p2psocket)
    startclntd();
  amain ();
}

<commit_msg>don't need to call sfsconst_init, so we can use lsd on machines w/o sfs installed<commit_after>/*
 *
 * Copyright (C) 2000 Frans Kaashoek (kaashoek@lcs.mit.edu)
 *                    Frank Dabek (fdabek@mit.edu)
 *
 *  Permission is hereby granted, free of charge, to any person obtaining
 *  a copy of this software and associated documentation files (the
 *  "Software"), to deal in the Software without restriction, including
 *  without limitation the rights to use, copy, modify, merge, publish,
 *  distribute, sublicense, and/or sell copies of the Software, and to
 *  permit persons to whom the Software is furnished to do so, subject to
 *  the following conditions:
 *
 *  The above copyright notice and this permission notice shall be
 *  included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "chord.h"
#include "dhash.h"
#include "parseopt.h"
#include <sys/types.h>

//#define PROFILING

// When a process starts up profiling is not happening.  But by
// sending a SIGUSR1, profiling is turned on.  (Another SIGUSR1 turns
// it off.)  This always specific, user-controlled periods of time to
// be profiled.  Program must be compiled with -pg for this to work.

#ifdef PROFILING
extern "C" {
  void moncontrol(int);
}
#endif

EXITFN (cleanup);

// XXX temporary hack -- reset to something reasonable soon.
//     [used to be 60000]
//     --josh
#define STORE_SIZE 2000000 //size of block store per vnode (in blocks)

ptr<chord> chordnode;
static str p2psocket;
bool do_cache;
int cache_size;
vec<dhash *> dh;
int myport;

void stats ();
void stop ();
void halt ();

void
client_accept (int fd)
{
  if (fd < 0)
    fatal ("EOF\n");

  ref<axprt_stream> x = axprt_stream::alloc (fd);

  // XXX these dhashgateway objects are leaked
  //

   vNew dhashgateway (x, chordnode, do_cache);
}

static void
client_accept_socket (int lfd)
{
  sockaddr_un sun;
  bzero (&sun, sizeof (sun));
  socklen_t sunlen = sizeof (sun);
  int fd = accept (lfd, reinterpret_cast<sockaddr *> (&sun), &sunlen);
  if (fd >= 0)
    client_accept (fd);
}

static void
client_listening_cb (int fd, int status)
{
  if (status)
    close (fd);
  else if (listen (fd, 5) < 0) {
    fatal ("Error from listen: %m\n");
    close (fd);
  } else {
    fdcb (fd, selread, wrap (client_accept_socket, fd));
  }
}

static void
cleanup ()
{
   unlink (p2psocket);
}

static void
startclntd()
{

  unlink (p2psocket);
  int clntfd = unixsocket (p2psocket);
  if (clntfd < 0)
    fatal << "Error creating client socket (UNIX)" << strerror (errno) << "\n";
  client_listening_cb (clntfd, 0);

  int port = (myport == 0) ? 0 : myport + 1;
  int tcp_clntfd = inetsocket (SOCK_STREAM, port);
  if (tcp_clntfd < 0)
    fatal << "Error creating client socket (TCP) " << strerror(errno) << "\n";
  client_listening_cb (tcp_clntfd, 0);

}

static void
newvnode_cb (int nreplica, str db_name, int ss_mode, int n, vnode *my,
	     chordstat stat)
{
  if (stat != CHORD_OK) {
    warnx << "newvnode_cb: status " << stat << "\n";
    fatal ("unable to join\n");
  }
  str db_name_prime = strbuf () << db_name << "-" << n;
  if ((int)dh.size () >= chord::max_vnodes)
    fatal << "Too many virtual nodes (" << chord::max_vnodes << ")\n";
  dh.push_back( New dhash (db_name_prime, my, nreplica,
			    STORE_SIZE,
			    cache_size,
			    ss_mode));
  if (n > 0) chordnode->newvnode (wrap (newvnode_cb, nreplica, db_name,
					ss_mode, n-1));
}

void
halt ()
{
  warnx << "Exiting on command.\n";
  exit (0);
}

#ifdef PROFILING
void
toggle_profiling ()
{
  static int pfstate = 1;
  if (pfstate)
    warn << "Turning profiling off\n";
  else
    warn << "Turning profiling on\n";

  pfstate = !pfstate;
  moncontrol (pfstate ? 1 : 0);
}
#endif

void
stats ()
{
#ifdef PROFILING
  toggle_profiling ();
#else
  chordnode->stats ();
  for (unsigned int i = 0 ; i < dh.size (); i++)
    dh[i]->print_stats ();
  chordnode->print ();
#endif
}

void
stop ()
{
#if 1
  chordnode->stop ();
  for (unsigned int i = 0 ; i < dh.size (); i++)
    dh[i]->stop ();
#else
  setenv ("LOG_FILE", "log", 1);
#endif
}

static void
usage ()
{
  warnx << "Usage: " << progname
	<< " -d <dbfile> -j hostname:port -p port "
    "[-l <locally bound IP>] "
    "[-S <sock>] [-v <nvnode>] [-c <cache?>] "
    "-B <cache size> "
    "[-s <server select mode>]\n";
  exit (1);
}

int
main (int argc, char **argv)
{

#ifdef PROFILING
  toggle_profiling ();
#endif

  int vnode = 1;
  setprogname (argv[0]);
  // sfsconst_init ();
  random_init ();

  int ch;

  do_cache = false;
  int ss_mode = 0;

  myport = 0;
  cache_size = 2000;
  // ensure enough room for fingers and successors.
  int max_loccache = (int) (1.2 * (NSUCC + NBIT));
  str wellknownhost;
  int wellknownport = 0;
  int nreplica = 0;
  str db_name = "/var/tmp/db";
  p2psocket = "/tmp/chord-sock";
  str myname = my_addr ();

  while ((ch = getopt (argc, argv, "B:cd:j:l:M:n:p:S:s:v:")) != -1)
    switch (ch) {
    case 'B':
      cache_size = atoi (optarg);
      break;
    case 'c':
      do_cache = true;
      break;
    case 'd':
      db_name = optarg;
      break;
    case 'j':
      {
	char *bs_port = strchr(optarg, ':');
	if (!bs_port) usage ();
	*bs_port = 0;
	bs_port++;
	if (inet_addr (optarg) == INADDR_NONE) {
	  //yep, this blocks
	  struct hostent *h = gethostbyname (optarg);
	  if (!h) {
	    warn << "Invalid address or hostname: " << optarg << "\n";
	    usage ();
	  }
	  struct in_addr *ptr = (struct in_addr *)h->h_addr;
	  wellknownhost = inet_ntoa (*ptr);
	} else
	  wellknownhost = optarg;

	wellknownport = atoi (bs_port);

	break;
      }
    case 'l':
      if (inet_addr (optarg) == INADDR_NONE)
	fatal << "must specify bind address in dotted decimal form\n";
      myname = optarg;
      break;
    case 'M':
      max_loccache = atoi (optarg);
      break;
    case 'n':
      nreplica = atoi (optarg);
      break;
    case 'p':
      myport = atoi (optarg);
      break;
    case 'S':
      p2psocket = optarg;
      break;
    case 's':
      ss_mode = atoi(optarg);
      break;
    case 'v':
      vnode = atoi (optarg);
      break;
    default:
      usage ();
      break;
    }

  if (wellknownport == 0) usage ();

  if (vnode > chord::max_vnodes) {
    warn << "Requested vnodes (" << vnode << ") more than maximum allowed ("
	 << chord::max_vnodes << ")\n";
    usage ();
  }

#ifdef PNODE
  warn << "Chord nodes will emulate physical nodes.\n";
#else /* PNODE */
  max_loccache = max_loccache * (vnode + 1);
#endif /* PNODE */

  chordnode = New refcounted<chord> (wellknownhost, wellknownport,
				     myname,
				     myport,
				     max_loccache,
				     ss_mode);
  chordnode->newvnode (wrap (newvnode_cb, nreplica, db_name, ss_mode,
			     vnode-1));

  sigcb(SIGUSR1, wrap (&stats));
  sigcb(SIGUSR2, wrap (&stop));
  sigcb(SIGHUP, wrap (&halt));

  if (p2psocket)
    startclntd();
  amain ();
}

<|endoftext|>