<commit_before>// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <cstdio>       // for fileno(), stdin

#ifdef WIN32
#include <windows.h>    // for SetStdinEcho()
#include <io.h>         // for isatty()
#else
#include <termios.h>    // for SetStdinEcho()
#include <unistd.h>     // for SetStdinEcho(), isatty()
#include <sys/poll.h>   // for StdinReady()
#endif

#include <compat/stdin.h>

// https://stackoverflow.com/questions/1413445/reading-a-password-from-stdcin
void SetStdinEcho(bool enable)
{
#ifdef WIN32
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    DWORD mode;
    GetConsoleMode(hStdin, &mode);
    if (!enable) {
        mode &= ~ENABLE_ECHO_INPUT;
    } else {
        mode |= ENABLE_ECHO_INPUT;
    }
    SetConsoleMode(hStdin, mode);
#else
    struct termios tty;
    tcgetattr(STDIN_FILENO, &tty);
    if (!enable) {
        tty.c_lflag &= ~ECHO;
    } else {
        tty.c_lflag |= ECHO;
    }
    (void)tcsetattr(STDIN_FILENO, TCSANOW, &tty);
#endif
}

bool StdinTerminal()
{
#ifdef WIN32
    return _isatty(_fileno(stdin));
#else
    return isatty(fileno(stdin));
#endif
}

bool StdinReady()
{
    if (!StdinTerminal()) {
        return true;
    }
#ifdef WIN32
    return false;
#else
    struct pollfd fds;
    fds.fd = 0; /* this is STDIN */
    fds.events = POLLIN;
    return poll(&fds, 1, 0) == 1;
#endif
}

NoechoInst::NoechoInst() { SetStdinEcho(false); }
NoechoInst::~NoechoInst() { SetStdinEcho(true); }
<commit_msg>build: Fix #include sys/poll.h to just poll.h (without sys/)<commit_after>// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <cstdio>       // for fileno(), stdin

#ifdef WIN32
#include <windows.h>    // for SetStdinEcho()
#include <io.h>         // for isatty()
#else
#include <termios.h>    // for SetStdinEcho()
#include <unistd.h>     // for SetStdinEcho(), isatty()
#include <poll.h>       // for StdinReady()
#endif

#include <compat/stdin.h>

// https://stackoverflow.com/questions/1413445/reading-a-password-from-stdcin
void SetStdinEcho(bool enable)
{
#ifdef WIN32
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    DWORD mode;
    GetConsoleMode(hStdin, &mode);
    if (!enable) {
        mode &= ~ENABLE_ECHO_INPUT;
    } else {
        mode |= ENABLE_ECHO_INPUT;
    }
    SetConsoleMode(hStdin, mode);
#else
    struct termios tty;
    tcgetattr(STDIN_FILENO, &tty);
    if (!enable) {
        tty.c_lflag &= ~ECHO;
    } else {
        tty.c_lflag |= ECHO;
    }
    (void)tcsetattr(STDIN_FILENO, TCSANOW, &tty);
#endif
}

bool StdinTerminal()
{
#ifdef WIN32
    return _isatty(_fileno(stdin));
#else
    return isatty(fileno(stdin));
#endif
}

bool StdinReady()
{
    if (!StdinTerminal()) {
        return true;
    }
#ifdef WIN32
    return false;
#else
    struct pollfd fds;
    fds.fd = 0; /* this is STDIN */
    fds.events = POLLIN;
    return poll(&fds, 1, 0) == 1;
#endif
}

NoechoInst::NoechoInst() { SetStdinEcho(false); }
NoechoInst::~NoechoInst() { SetStdinEcho(true); }
<|endoftext|>


<commit_before><commit_msg>gui: removing unneeded if<commit_after><|endoftext|>


<commit_before>/*
** Copyright 1993 by Miron Livny, Mike Litzkow, and Emmanuel Ackaouy.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted,
** provided that the above copyright notice appear in all copies and that
** both that copyright notice and this permission notice appear in
** supporting documentation, and that the names of the University of
** Wisconsin and the copyright holders not be used in advertising or
** publicity pertaining to distribution of the software without specific,
** written prior permission.  The University of Wisconsin and the
** copyright holders make no representations about the suitability of this
** software for any purpose.  It is provided "as is" without express
** or implied warranty.
**
** THE UNIVERSITY OF WISCONSIN AND THE COPYRIGHT HOLDERS DISCLAIM ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE UNIVERSITY OF
** WISCONSIN OR THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT
** OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
** OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
** OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
** OR PERFORMANCE OF THIS SOFTWARE.
**
** Author:  Emmanuel Ackaouy
**
*/

#define _POSIX_SOURCE

#include "condor_common.h"
#include "condor_constants.h"
#include "condor_io.h"
#include "sock.h"
#include "condor_network.h"
#include "internet.h"
#include "condor_debug.h"
#include <stdio.h>

Sock::Sock() : Stream() {
	_sock = INVALID_SOCKET;
	_state = sock_virgin;
	_timeout = 0;
	memset(&_who, 0, sizeof( struct sockaddr_in ) );
}

#if defined(WIN32)
class SockInitializer
{
public:
	SockInitializer() {
		WORD wVersionRequested = MAKEWORD( 2, 0 );
		WSADATA wsaData;
		int err;

		err = WSAStartup( wVersionRequested, &wsaData );
		if ( err < 0 ) {
			fprintf( stderr, "Can't find usable WinSock DLL!\n" );
			exit(1);
		}

		if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 0 ) {
			fprintf( stderr, "Warning: using WinSock version %d.%d, requested 1.1\n",
				LOBYTE( wsaData.wVersion ), HIBYTE( wsaData.wVersion ) );
		}
	}

	~SockInitializer() {
		if (WSACleanup() < 0)
			fprintf(stderr, "WSACleanup() failed, errno = %d\n",
					WSAGetLastError());
		}
};

static SockInitializer _SockInitializer;
#endif

/*
**	Methods shared by all Socks
*/

int Sock::getportbyserv(
	char	*s
	)
{
	servent		*sp;
	char		*my_prot;

	if (!s) return -1;

	switch(type()){
		case safe_sock:
			my_prot = "udp";
			break;
		case reli_sock:
			my_prot = "tcp";
			break;
		default:
			assert(0);
	}

	if (!(sp = getservbyname(s, my_prot))) return -1;

	return ntohs(sp->s_port);
}

#if defined(WIN32) && defined(_WINSOCK2API_)
int Sock::assign(
	LPWSAPROTOCOL_INFO pProtoInfo
	)
{
	if (!valid()) return FALSE;
	if (_state != sock_virgin) return FALSE;

	// verify the win32 socket type we are about to inherit matches
	// our CEDAR socket type
	switch(type()){
		case safe_sock:
			assert( pProtoInfo->iSocketType == SOCK_DGRAM );
			break;
		case reli_sock:
			assert( pProtoInfo->iSocketType == SOCK_STREAM );
			break;
		default:
			assert(0);
	}

	_sock = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
					  FROM_PROTOCOL_INFO, pProtoInfo, 0, 0);

	if ( _sock == INVALID_SOCKET )
		return FALSE;

	_state = sock_assigned;
	return TRUE;
}
#endif

#ifdef WIN32
int Sock::set_inheritable( int flag )
{
	// on unix, all sockets are always inheritable by a child process.
	// but on Win32, each individual socket has a flag that says if it can
	// or cannot be inherited by a child.  this method effectively sets
	// that flag (by duplicating the socket).
	// pass flag as "TRUE" to make this socket inheritable, "FALSE" to make
	// it private to this process.
	// Returns TRUE on sucess, FALSE on failure.

	SOCKET DuplicateSock;

	if ( (flag != TRUE) && (flag != FALSE) )
		return FALSE;	// flag must be either TRUE or FALSE...

	if (!DuplicateHandle(GetCurrentProcess(),
        (HANDLE)_sock,
        GetCurrentProcess(),
        (HANDLE*)&DuplicateSock,
        0,
        flag, // inheritable flag
        DUPLICATE_SAME_ACCESS)) {
			// failed to duplicate
			dprintf(D_ALWAYS,"ERROR: DuplicateHandle() failed in Sock:set_inheritable(%d), error=%d\n"
				,flag,GetLastError());
			closesocket(DuplicateSock);
			return FALSE;
	}
	// if made it here, successful duplication; replace original
	closesocket(_sock);
	_sock = DuplicateSock;

	return TRUE;
}
#endif	// of WIN32

int Sock::assign(
	SOCKET		sockd
	)
{
	int		my_type;

	if (!valid()) return FALSE;
	if (_state != sock_virgin) return FALSE;

	if (sockd != INVALID_SOCKET){
		_sock = sockd;		/* Could we check for correct protocol ? */
		_state = sock_assigned;
		return TRUE;
	}

	switch(type()){
		case safe_sock:
			my_type = SOCK_DGRAM;
			break;
		case reli_sock:
			my_type = SOCK_STREAM;
			break;
		default:
			assert(0);
	}

	if ((_sock = socket(AF_INET, my_type, 0)) < 0) return FALSE;

	// on WinNT, sockets are created as inheritable by default.  we
	// want to create the socket as non-inheritable by default.  so
	// we duplicate the socket as non-inheritable and then close
	// the default inheritable socket.  Note on Win95, it is the opposite:
	// i.e. on Win95 sockets are created non-inheritable by default.
	// note: on UNIX, set_inheritable just always return TRUE.
	if ( !set_inheritable(FALSE) ) return FALSE;

	_state = sock_assigned;

	// If we called timeout() previously on this object, then called close() on the
	// socket, we are now left with _timeout set to some positive value __BUT__ the
	// socket itself has never been set to non-blocking mode with some ioctl or whatever.
	// SO, we check here for this situation and rectify by calling timeout() again. -Todd 10/97.
	if ( _timeout > 0 )
		timeout( _timeout );

	return TRUE;
}

int Sock::bind(
	int		port
	)
{
	sockaddr_in		sin;
	int					on = 0;
	struct linger		linger = {0, 0};

	if (!valid()) return FALSE;

		/* if stream not assigned to a sock, do it now	*/
	if (_state == sock_virgin) assign();

	if (_state != sock_assigned) return FALSE;

	memset(&sin, 0, sizeof(sockaddr_in));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl(INADDR_ANY);
	sin.sin_port = htons((u_short)port);

	if (::bind(_sock, (sockaddr *)&sin, sizeof(sockaddr_in)) < 0) {
#ifdef WIN32
		int error = WSAGetLastError();
		dprintf( D_ALWAYS, "bind failed: WSAError = %d\n", error );
#else
		dprintf( D_ALWAYS, "bind failed: errno = %d\n", errno );
#endif
		return FALSE;
	}

	_state = sock_bound;

	// Set options on this socket, SO_REUSEADDR and SO_LINGER, so that
	// if we are binding to a well known port, and we crash, we can be
	// restarted and still bind ok back to this same port. -Todd T, 11/97
	if( (!setsockopt(SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on))) ||
		((type() == Stream::reli_sock) &&	// SO_LINGER only defined on TCP
		(!setsockopt(SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger)))) ) {
		dprintf(D_ALWAYS,"ERROR: setsockopt() SO_REUSEADDR, SO_LINGER failed\n");
		return FALSE;
	}

	return TRUE;
}

int Sock::setsockopt(SOCKET level, int optname, const char* optval, int optlen)
{
	if(::setsockopt(_sock, level, optname, optval, optlen) < 0)
	{
		return FALSE;
	}
	return TRUE;
}

int Sock::do_connect(
	char	*host,
	int		port
	)
{
	sockaddr_in		sin;
	hostent			*hostp;
	unsigned long	inaddr;

	if (!valid()) return FALSE;
	if (!host || port < 0) return FALSE;

		/* we bind here so that a sock may be	*/
		/* assigned to the stream if needed		*/
	if (_state == sock_virgin || _state == sock_assigned) bind();

	if (_state != sock_bound) return FALSE;

	memset(&sin, 0, sizeof(sockaddr_in));
	sin.sin_family = AF_INET;
	sin.sin_port = htons((u_short)port);

	/* might be in <x.x.x.x:x> notation				*/
	if (host[0] == '<') {
		string_to_sin(host, &sin);
	}
	/* try to get a decimal notation 	 			*/
	else if ((inaddr = inet_addr(host)) != (unsigned int)-1){
		memcpy((char *)&sin.sin_addr, &inaddr, sizeof(inaddr));
	}
	/* if dotted notation fails, try host database	*/
	else{
		if ((hostp = gethostbyname(host)) == (hostent *)0) return FALSE;
		memcpy(&sin.sin_addr, hostp->h_addr, hostp->h_length);
	}

	time_t timeout_time = time(NULL) + CONNECT_TIMEOUT;
	bool connect_failed;

	do {
		connect_failed = false;

		if (::connect(_sock, (sockaddr *)&sin, sizeof(sockaddr_in)) == 0) {
			_state = sock_connect;
			return TRUE;
		}

#if defined(WIN32)
		if (WSAGetLastError() != WSAEALREADY) {
			dprintf( D_ALWAYS, "Can't connect to %s:%d, errno = %d\n",
				host, port, WSAGetLastError() );
			connect_failed = true;
		}
#else
		if (errno != EINPROGRESS) {
			dprintf( D_ALWAYS, "Can't connect to %s:%d, errno = %d\n",
				host, port, errno );
			connect_failed = true;
		}
#endif

		if (_timeout > 0 && !connect_failed) {
			struct timeval	timer;
			fd_set			writefds;
			int				nfds=0, nfound;
			timer.tv_sec = _timeout;
			timer.tv_usec = 0;
#if !defined(WIN32) // nfds is ignored on WIN32
			nfds = _sock + 1;
#endif
			FD_ZERO( &writefds );
			FD_SET( _sock, &writefds );

			nfound = ::select( nfds, 0, &writefds, 0, &timer );

			switch(nfound) {
			case 1:
				if (test_connection()) {
					_state = sock_connect;
					return TRUE;
				}
				break;
			default:
				dprintf( D_ALWAYS, "select returns %d, connect failed\n",
					nfound );
				break;
			}
		}

	} while (time(NULL) < timeout_time);

	dprintf( D_ALWAYS, "Connect failed for %d seconds; returning FALSE\n",
			 CONNECT_TIMEOUT );
	return FALSE;
}

bool Sock::test_connection()
{
	// test the connection -- on OSF1, select returns 1 even if
	// the connect fails!

	struct sockaddr_in test_addr;
	memset((char *) &test_addr, 0, sizeof(test_addr));
	test_addr.sin_family = AF_INET;
	int nbytes = sizeof(test_addr);
	if (getpeername(_sock, (struct sockaddr *) &test_addr, &nbytes) < 0) {
		dprintf( D_ALWAYS,
				 "getpeername failed so connect must have failed\n" );
		return false;
	}
	return true;
}

#if !defined(WIN32)
#define closesocket close
#endif

int Sock::close()
{
	if (_state == sock_virgin) return FALSE;

	if (::closesocket(_sock) < 0) return FALSE;

	_state = sock_virgin;
	return TRUE;
}

#if !defined(WIN32)
#define ioctlsocket ioctl
#endif

int Sock::timeout(int sec)
{
	int t = _timeout;

	_timeout = sec;

	if (_timeout == 0) {
		unsigned long mode = 0;	// reset blocking mode
		if (ioctlsocket(_sock, FIONBIO, &mode) < 0)
			return FALSE;
	} else {
		unsigned long mode = 1;	// nonblocking mode
		if (ioctlsocket(_sock, FIONBIO, &mode) < 0)
			return FALSE;
	}

	return t;
}

char * Sock::do_serialize(char *buf)
{
	char *ptmp;
	int i;

	if ( buf == NULL ) {
		// here we want to save our state into a buffer
		char * outbuf = new char[100];
		sprintf(outbuf,"%u*%d*%d",_sock,_state,_timeout);
		return( outbuf );
	}

	// here we want to restore our state from the incoming buffer
	sscanf(buf,"%u*%d*%d",&_sock,&_state,&_timeout);

	// set our return value to a pointer beyond the 3 state values...
	ptmp = buf;
	for (i=0;i<3;i++) {
		if ( ptmp ) {
			ptmp = strchr(ptmp,'*');
			ptmp++;
		}
	}

	return ptmp;
}

<commit_msg>only dprintf error once on connect failure<commit_after>/*
** Copyright 1993 by Miron Livny, Mike Litzkow, and Emmanuel Ackaouy.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted,
** provided that the above copyright notice appear in all copies and that
** both that copyright notice and this permission notice appear in
** supporting documentation, and that the names of the University of
** Wisconsin and the copyright holders not be used in advertising or
** publicity pertaining to distribution of the software without specific,
** written prior permission.  The University of Wisconsin and the
** copyright holders make no representations about the suitability of this
** software for any purpose.  It is provided "as is" without express
** or implied warranty.
**
** THE UNIVERSITY OF WISCONSIN AND THE COPYRIGHT HOLDERS DISCLAIM ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE UNIVERSITY OF
** WISCONSIN OR THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT
** OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
** OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
** OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
** OR PERFORMANCE OF THIS SOFTWARE.
**
** Author:  Emmanuel Ackaouy
**
*/

#define _POSIX_SOURCE

#include "condor_common.h"
#include "condor_constants.h"
#include "condor_io.h"
#include "sock.h"
#include "condor_network.h"
#include "internet.h"
#include "condor_debug.h"
#include <stdio.h>

Sock::Sock() : Stream() {
	_sock = INVALID_SOCKET;
	_state = sock_virgin;
	_timeout = 0;
	memset(&_who, 0, sizeof( struct sockaddr_in ) );
}

#if defined(WIN32)
class SockInitializer
{
public:
	SockInitializer() {
		WORD wVersionRequested = MAKEWORD( 2, 0 );
		WSADATA wsaData;
		int err;

		err = WSAStartup( wVersionRequested, &wsaData );
		if ( err < 0 ) {
			fprintf( stderr, "Can't find usable WinSock DLL!\n" );
			exit(1);
		}

		if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 0 ) {
			fprintf( stderr, "Warning: using WinSock version %d.%d, requested 1.1\n",
				LOBYTE( wsaData.wVersion ), HIBYTE( wsaData.wVersion ) );
		}
	}

	~SockInitializer() {
		if (WSACleanup() < 0)
			fprintf(stderr, "WSACleanup() failed, errno = %d\n",
					WSAGetLastError());
		}
};

static SockInitializer _SockInitializer;
#endif

/*
**	Methods shared by all Socks
*/

int Sock::getportbyserv(
	char	*s
	)
{
	servent		*sp;
	char		*my_prot;

	if (!s) return -1;

	switch(type()){
		case safe_sock:
			my_prot = "udp";
			break;
		case reli_sock:
			my_prot = "tcp";
			break;
		default:
			assert(0);
	}

	if (!(sp = getservbyname(s, my_prot))) return -1;

	return ntohs(sp->s_port);
}

#if defined(WIN32) && defined(_WINSOCK2API_)
int Sock::assign(
	LPWSAPROTOCOL_INFO pProtoInfo
	)
{
	if (!valid()) return FALSE;
	if (_state != sock_virgin) return FALSE;

	// verify the win32 socket type we are about to inherit matches
	// our CEDAR socket type
	switch(type()){
		case safe_sock:
			assert( pProtoInfo->iSocketType == SOCK_DGRAM );
			break;
		case reli_sock:
			assert( pProtoInfo->iSocketType == SOCK_STREAM );
			break;
		default:
			assert(0);
	}

	_sock = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
					  FROM_PROTOCOL_INFO, pProtoInfo, 0, 0);

	if ( _sock == INVALID_SOCKET )
		return FALSE;

	_state = sock_assigned;
	return TRUE;
}
#endif

#ifdef WIN32
int Sock::set_inheritable( int flag )
{
	// on unix, all sockets are always inheritable by a child process.
	// but on Win32, each individual socket has a flag that says if it can
	// or cannot be inherited by a child.  this method effectively sets
	// that flag (by duplicating the socket).
	// pass flag as "TRUE" to make this socket inheritable, "FALSE" to make
	// it private to this process.
	// Returns TRUE on sucess, FALSE on failure.

	SOCKET DuplicateSock;

	if ( (flag != TRUE) && (flag != FALSE) )
		return FALSE;	// flag must be either TRUE or FALSE...

	if (!DuplicateHandle(GetCurrentProcess(),
        (HANDLE)_sock,
        GetCurrentProcess(),
        (HANDLE*)&DuplicateSock,
        0,
        flag, // inheritable flag
        DUPLICATE_SAME_ACCESS)) {
			// failed to duplicate
			dprintf(D_ALWAYS,"ERROR: DuplicateHandle() failed in Sock:set_inheritable(%d), error=%d\n"
				,flag,GetLastError());
			closesocket(DuplicateSock);
			return FALSE;
	}
	// if made it here, successful duplication; replace original
	closesocket(_sock);
	_sock = DuplicateSock;

	return TRUE;
}
#endif	// of WIN32

int Sock::assign(
	SOCKET		sockd
	)
{
	int		my_type;

	if (!valid()) return FALSE;
	if (_state != sock_virgin) return FALSE;

	if (sockd != INVALID_SOCKET){
		_sock = sockd;		/* Could we check for correct protocol ? */
		_state = sock_assigned;
		return TRUE;
	}

	switch(type()){
		case safe_sock:
			my_type = SOCK_DGRAM;
			break;
		case reli_sock:
			my_type = SOCK_STREAM;
			break;
		default:
			assert(0);
	}

	if ((_sock = socket(AF_INET, my_type, 0)) < 0) return FALSE;

	// on WinNT, sockets are created as inheritable by default.  we
	// want to create the socket as non-inheritable by default.  so
	// we duplicate the socket as non-inheritable and then close
	// the default inheritable socket.  Note on Win95, it is the opposite:
	// i.e. on Win95 sockets are created non-inheritable by default.
	// note: on UNIX, set_inheritable just always return TRUE.
	if ( !set_inheritable(FALSE) ) return FALSE;

	_state = sock_assigned;

	// If we called timeout() previously on this object, then called close() on the
	// socket, we are now left with _timeout set to some positive value __BUT__ the
	// socket itself has never been set to non-blocking mode with some ioctl or whatever.
	// SO, we check here for this situation and rectify by calling timeout() again. -Todd 10/97.
	if ( _timeout > 0 )
		timeout( _timeout );

	return TRUE;
}

int Sock::bind(
	int		port
	)
{
	sockaddr_in		sin;
	int					on = 0;
	struct linger		linger = {0, 0};

	if (!valid()) return FALSE;

		/* if stream not assigned to a sock, do it now	*/
	if (_state == sock_virgin) assign();

	if (_state != sock_assigned) return FALSE;

	memset(&sin, 0, sizeof(sockaddr_in));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl(INADDR_ANY);
	sin.sin_port = htons((u_short)port);

	if (::bind(_sock, (sockaddr *)&sin, sizeof(sockaddr_in)) < 0) {
#ifdef WIN32
		int error = WSAGetLastError();
		dprintf( D_ALWAYS, "bind failed: WSAError = %d\n", error );
#else
		dprintf( D_ALWAYS, "bind failed: errno = %d\n", errno );
#endif
		return FALSE;
	}

	_state = sock_bound;

	// Set options on this socket, SO_REUSEADDR and SO_LINGER, so that
	// if we are binding to a well known port, and we crash, we can be
	// restarted and still bind ok back to this same port. -Todd T, 11/97
	if( (!setsockopt(SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on))) ||
		((type() == Stream::reli_sock) &&	// SO_LINGER only defined on TCP
		(!setsockopt(SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger)))) ) {
		dprintf(D_ALWAYS,"ERROR: setsockopt() SO_REUSEADDR, SO_LINGER failed\n");
		return FALSE;
	}

	return TRUE;
}

int Sock::setsockopt(SOCKET level, int optname, const char* optval, int optlen)
{
	if(::setsockopt(_sock, level, optname, optval, optlen) < 0)
	{
		return FALSE;
	}
	return TRUE;
}

int Sock::do_connect(
	char	*host,
	int		port
	)
{
	sockaddr_in		sin;
	hostent			*hostp;
	unsigned long	inaddr;

	if (!valid()) return FALSE;
	if (!host || port < 0) return FALSE;

		/* we bind here so that a sock may be	*/
		/* assigned to the stream if needed		*/
	if (_state == sock_virgin || _state == sock_assigned) bind();

	if (_state != sock_bound) return FALSE;

	memset(&sin, 0, sizeof(sockaddr_in));
	sin.sin_family = AF_INET;
	sin.sin_port = htons((u_short)port);

	/* might be in <x.x.x.x:x> notation				*/
	if (host[0] == '<') {
		string_to_sin(host, &sin);
	}
	/* try to get a decimal notation 	 			*/
	else if ((inaddr = inet_addr(host)) != (unsigned int)-1){
		memcpy((char *)&sin.sin_addr, &inaddr, sizeof(inaddr));
	}
	/* if dotted notation fails, try host database	*/
	else{
		if ((hostp = gethostbyname(host)) == (hostent *)0) return FALSE;
		memcpy(&sin.sin_addr, hostp->h_addr, hostp->h_length);
	}

	time_t timeout_time = time(NULL) + CONNECT_TIMEOUT;
	bool connect_failed, failed_once = false;

	do {
		connect_failed = false;

		if (::connect(_sock, (sockaddr *)&sin, sizeof(sockaddr_in)) == 0) {
			_state = sock_connect;
			return TRUE;
		}

#if defined(WIN32)
		if (WSAGetLastError() != WSAEALREADY) {
			if (!failed_once) {
				dprintf( D_ALWAYS, "Can't connect to %s:%d, errno = %d\n",
						 host, port, WSAGetLastError() );
				dprintf( D_ALWAYS, "Will keep trying for %d seconds...\n",
						 CONNECT_TIMEOUT );
				failed_once = true;
			}
			connect_failed = true;
		}
#else
		if (errno != EINPROGRESS) {
			if (!failed_once) {
				dprintf( D_ALWAYS, "Can't connect to %s:%d, errno = %d\n",
						 host, port, errno );
				dprintf( D_ALWAYS, "Will keep trying for %d seconds...\n",
						 CONNECT_TIMEOUT );
				failed_once = true;
			}
			connect_failed = true;
		}
#endif

		if (_timeout > 0 && !connect_failed) {
			struct timeval	timer;
			fd_set			writefds;
			int				nfds=0, nfound;
			timer.tv_sec = _timeout;
			timer.tv_usec = 0;
#if !defined(WIN32) // nfds is ignored on WIN32
			nfds = _sock + 1;
#endif
			FD_ZERO( &writefds );
			FD_SET( _sock, &writefds );

			nfound = ::select( nfds, 0, &writefds, 0, &timer );

			switch(nfound) {
			case 1:
				if (test_connection()) {
					_state = sock_connect;
					return TRUE;
				}
				break;
			default:
				if (!failed_once) {
					dprintf( D_ALWAYS, "select returns %d, connect failed\n",
							 nfound );
					dprintf( D_ALWAYS, "Will keep trying for %d seconds...\n",
							 CONNECT_TIMEOUT );
					failed_once = true;
				}
				break;
			}
		}

	} while (time(NULL) < timeout_time);

	dprintf( D_ALWAYS, "Connect failed for %d seconds; returning FALSE\n",
			 CONNECT_TIMEOUT );
	return FALSE;
}

bool Sock::test_connection()
{
	// test the connection -- on OSF1, select returns 1 even if
	// the connect fails!

	struct sockaddr_in test_addr;
	memset((char *) &test_addr, 0, sizeof(test_addr));
	test_addr.sin_family = AF_INET;
	int nbytes = sizeof(test_addr);
	if (getpeername(_sock, (struct sockaddr *) &test_addr, &nbytes) < 0) {
		dprintf( D_ALWAYS,
				 "getpeername failed so connect must have failed\n" );
		return false;
	}
	return true;
}

#if !defined(WIN32)
#define closesocket close
#endif

int Sock::close()
{
	if (_state == sock_virgin) return FALSE;

	if (::closesocket(_sock) < 0) return FALSE;

	_state = sock_virgin;
	return TRUE;
}

#if !defined(WIN32)
#define ioctlsocket ioctl
#endif

int Sock::timeout(int sec)
{
	int t = _timeout;

	_timeout = sec;

	if (_timeout == 0) {
		unsigned long mode = 0;	// reset blocking mode
		if (ioctlsocket(_sock, FIONBIO, &mode) < 0)
			return FALSE;
	} else {
		unsigned long mode = 1;	// nonblocking mode
		if (ioctlsocket(_sock, FIONBIO, &mode) < 0)
			return FALSE;
	}

	return t;
}

char * Sock::do_serialize(char *buf)
{
	char *ptmp;
	int i;

	if ( buf == NULL ) {
		// here we want to save our state into a buffer
		char * outbuf = new char[100];
		sprintf(outbuf,"%u*%d*%d",_sock,_state,_timeout);
		return( outbuf );
	}

	// here we want to restore our state from the incoming buffer
	sscanf(buf,"%u*%d*%d",&_sock,&_state,&_timeout);

	// set our return value to a pointer beyond the 3 state values...
	ptmp = buf;
	for (i=0;i<3;i++) {
		if ( ptmp ) {
			ptmp = strchr(ptmp,'*');
			ptmp++;
		}
	}

	return ptmp;
}

<|endoftext|>


<commit_before>#include <libgen.h>
#include <stdlib.h>
#include <unistd.h>

#include <algorithm>
#include <iostream>

#include "configurator.hpp"
#include "foreach.hpp"
#include "params.hpp"
#include "string_utils.hpp"

using namespace nexus::internal;

const char* Configurator::DEFAULT_CONFIG_DIR = "conf";
const char* Configurator::CONFIG_FILE_NAME = "mesos.conf";
const char* Configurator::ENV_VAR_PREFIX = "MESOS_";

// Define a function for accessing the list of environment variables
// in a platform-independent way.
// On Mac OS X, the environ symbol isn't visible to shared libraries,
// so we must use the _NSGetEnviron() function (see man environ on OS X).
// On other platforms, it's fine to access environ from shared libraries.
#ifdef __APPLE__
#include "crt_externs.h"
namespace {
char** getEnviron() { return *_NSGetEnviron(); }
}
#else
extern char** environ;
namespace {
char** getEnviron() { return environ; }
}
#endif /* __APPLE__ */

void Configurator::validate()
{
  foreachpair (const string& key, const Option& opt, options) {
    if (params.contains(key) && opt.validator &&
        !opt.validator->isValid(params[key])) {
      string msg = "Invalid value for '" + key + "' option: " + params[key];
      throw ConfigurationException(msg.c_str());
    }
  }
}

Params& Configurator::load(int argc, char** argv, bool inferMesosHomeFromArg0)
{
  loadEnv();
  loadCommandLine(argc, argv, inferMesosHomeFromArg0);
  loadConfigFileIfGiven();
  validate();
  return params;
}

Params& Configurator::load()
{
  loadEnv();
  loadConfigFileIfGiven();
  validate();
  return params;
}

Params& Configurator::load(const map<string, string>& _params)
{
  loadEnv();
  params.loadMap(_params);
  loadConfigFileIfGiven();
  validate();
  return params;
}

void Configurator::loadConfigFileIfGiven(bool overwrite) {
  string confDir = "";
  if (params.contains("conf"))
    confDir = params["conf"];
  else if (params.contains("home")) // find conf dir relative to MESOS_HOME
    confDir = params["home"] + "/" + DEFAULT_CONFIG_DIR;
  if (confDir != "")
    loadConfigFile(confDir + "/" + CONFIG_FILE_NAME, overwrite);
}

void Configurator::loadEnv(bool overwrite)
{
  char** environ = getEnviron();
  int i = 0;
  while (environ[i] != NULL) {
    string line = environ[i];
    if (line.find(ENV_VAR_PREFIX) == 0) {
      string key, val;
      size_t eq = line.find_first_of("=");
      if (eq == string::npos)
        continue; // ignore malformed lines (they shouldn't occur in environ!)
      key = line.substr(strlen(ENV_VAR_PREFIX), eq - strlen(ENV_VAR_PREFIX));
      std::transform(key.begin(), key.end(), key.begin(), ::tolower);
      val = line.substr(eq + 1);
      if (overwrite || !params.contains(key)) {
        params[key] = val;
      }
    }
    i++;
  }
}

void Configurator::loadCommandLine(int argc,
                                   char** argv,
                                   bool inferMesosHomeFromArg0,
                                   bool overwrite)
{
  // Set home based on argument 0 if asked to do so
  if (inferMesosHomeFromArg0) {
    char buf[4096];
    if (realpath(dirname(argv[0]), buf) == 0) {
      throw ConfigurationException(
          "Could not get directory containing argv[0] -- realpath failed");
    }
    params["home"] = buf;
  }

  // Convert args 1 and above to STL strings
  vector<string> args;
  for (int i=1; i < argc; i++) {
    args.push_back(string(argv[i]));
  }

  for (int i = 0; i < args.size(); i++) {
    string key, val;
    bool set = false;
    if (args[i].find("--", 0) == 0) {
      // handle "--" case

      size_t eq = args[i].find_first_of("=");
      if (eq == string::npos &&
          args[i].find("--no-", 0) == 0) { // handle --no-blah
        key = args[i].substr(5);
        val = "0";
        set = true;
      } else if (eq == string::npos) {     // handle --blah
        key = args[i].substr(2);
        val = "1";
        set = true;
      } else {                             // handle --blah=25
        key = args[i].substr(2, eq-2);
        val = args[i].substr(eq+1);
        set = true;
      }

    } else if (args[i].find_first_of("-", 0) == 0 &&
               args[i].size() > 1) {
      // handle "-" case

      if (args[i].find("-no-",0) == 0 && args[i].size() > 4) { // handle -no-b
        key = getLongName(args[i][4]);
        val = "0";
      } else if (args[i].size() > 1) {  // shared code for -b and -b 25
        key = getLongName(args[i][1]);
        val = "1";
      }
      if (key == "")
        continue;  // couldn't extract long name from short name

      if (options[key].validator->isBool())
        set = true;
      else if (i+1 < args.size()) {  // handle -b 25
        val = args[i+1];
        set = true;
        i++;  // we've consumed next parameter as a "value"-parameter
      }

    }
    if (set && (overwrite || !params.contains(key))) {
      std::transform(key.begin(), key.end(), key.begin(), ::tolower);
      params[key] = val;
    }
  }
}

void Configurator::loadConfigFile(const string& fname, bool overwrite)
{
  ifstream cfg(fname.c_str(), std::ios::in);
  if (!cfg.is_open()) {
    string message = "Couldn't read Mesos config file: " + fname;
    throw ConfigurationException(message.c_str());
  }

  string line, originalLine;

  while (!cfg.eof()) {
    getline(cfg, line);
    originalLine = line;
    // Strip any comment at end of line
    size_t hash = line.find_first_of("#"); // strip comments
    if (hash != string::npos) {
      line = line.substr(0, hash);
    }
    // Check for empty line
    line = StringUtils::trim(line);
    if (line == "") {
      continue;
    }
    // Split line by = and trim to get key and value
    vector<string> tokens;
    StringUtils::split(line, "=", &tokens);
    if (tokens.size() != 2) {
      string message = "Malformed line in config file: '" +
                       StringUtils::trim(originalLine) + "'";
      throw ConfigurationException(message.c_str());
    }
    string key = StringUtils::trim(tokens[0]);
    string value = StringUtils::trim(tokens[1]);
    if (overwrite || !params.contains(key)) {
      params[key] = value;
    }
  }
  cfg.close();
}

string Configurator::getUsage() const
{
  const int PAD = 5;
  string usage;

  map<string,string> col1; // key -> col 1 string
  int maxLen = 0;

  // construct string for the first column and get size of column
  foreachpair (const string& key, const Option& opt, options) {
    string val = "--" + key;
    if (!opt.validator->isBool())
      val += " VAL";

    if (opt.hasShortName) {
      if (opt.validator->isBool())
        val += string(" (or -") + opt.shortName + " or -no-" +
          opt.shortName + ")";
      else
        val += string(" (or -") + opt.shortName + " VAL)";
    } else if (opt.validator->isBool())
      val += " (--no-" + key + ")";

    col1[key] = val;
    maxLen = val.size() > maxLen ? val.size() : maxLen;
  }

  foreachpair (const string& key, const Option& opt, options) {
    string helpStr = opt.helpString;
    string line = col1[key];

    if (opt.defaultValue != "") {  // add default value
      // Place a space between help string and (default: VAL) if the
      // help string does not end with a newline itself
      size_t lastNewLine = helpStr.find_last_of("\n\r");
      if (helpStr.size() > 0 && lastNewLine != helpStr.size() - 1) {
        helpStr += " ";
      }
      string defval = opt.defaultValue;

      helpStr += "(default: " + defval + ")";
    }

    string pad(PAD + maxLen - line.size(), ' ');
    line += pad;
    size_t pos1 = 0, pos2 = 0;
    pos2 = helpStr.find_first_of("\n\r", pos1);
    line += helpStr.substr(pos1, pos2 - pos1) + "\n";
    usage += line;

    while(pos2 != string::npos) {  // handle multi line help strings
      line = "";
      pos1 = pos2 + 1;
      string pad2(PAD + maxLen, ' ');
      line += pad2;
      pos2 = helpStr.find_first_of("\n\r", pos1);
      line += helpStr.substr(pos1, pos2 - pos1) + "\n";
      usage += line;
    }

  }
  return usage;
}

vector<string> Configurator::getOptions() const
{
  vector<string> ret;
  foreachpair (const string& key, _, options) {
    ret.push_back(key);
  }
  return ret;
}

Params& Configurator::getParams()
{
  return params;
}

string Configurator::getLongName(char shortName) const
{
  foreachpair (const string& key, const Option& opt, options) {
    if (opt.hasShortName && opt.shortName == shortName)
      return key;
  }
  return "";
}

void Configurator::clearMesosEnvironmentVars()
{
  char** environ = getEnviron();
  int i = 0;
  vector<string> toRemove;
  while (environ[i] != NULL) {
    string line = environ[i];
    if (line.find(ENV_VAR_PREFIX) == 0) {
      string key;
      size_t eq = line.find_first_of("=");
      if (eq == string::npos)
        continue; // ignore malformed lines (they shouldn't occur in environ!)
      key = line.substr(strlen(ENV_VAR_PREFIX), eq - strlen(ENV_VAR_PREFIX));
      toRemove.push_back(key);
    }
    i++;
  }
  foreach (string& str, toRemove) {
    unsetenv(str.c_str());
  }
}
<commit_msg>bools are printed as false/true in usage() and a typo was fixed<commit_after>#include <libgen.h>
#include <stdlib.h>
#include <unistd.h>

#include <algorithm>
#include <iostream>

#include "configurator.hpp"
#include "foreach.hpp"
#include "params.hpp"
#include "string_utils.hpp"

using namespace nexus::internal;

const char* Configurator::DEFAULT_CONFIG_DIR = "conf";
const char* Configurator::CONFIG_FILE_NAME = "mesos.conf";
const char* Configurator::ENV_VAR_PREFIX = "MESOS_";

// Define a function for accessing the list of environment variables
// in a platform-independent way.
// On Mac OS X, the environ symbol isn't visible to shared libraries,
// so we must use the _NSGetEnviron() function (see man environ on OS X).
// On other platforms, it's fine to access environ from shared libraries.
#ifdef __APPLE__
#include "crt_externs.h"
namespace {
char** getEnviron() { return *_NSGetEnviron(); }
}
#else
extern char** environ;
namespace {
char** getEnviron() { return environ; }
}
#endif /* __APPLE__ */

void Configurator::validate()
{
  foreachpair (const string& key, const Option& opt, options) {
    if (params.contains(key) && opt.validator &&
        !opt.validator->isValid(params[key])) {
      string msg = "Invalid value for '" + key + "' option: " + params[key];
      throw ConfigurationException(msg.c_str());
    }
  }
}

Params& Configurator::load(int argc, char** argv, bool inferMesosHomeFromArg0)
{
  loadEnv();
  loadCommandLine(argc, argv, inferMesosHomeFromArg0);
  loadConfigFileIfGiven();
  validate();
  return params;
}

Params& Configurator::load()
{
  loadEnv();
  loadConfigFileIfGiven();
  validate();
  return params;
}

Params& Configurator::load(const map<string, string>& _params)
{
  loadEnv();
  params.loadMap(_params);
  loadConfigFileIfGiven();
  validate();
  return params;
}

void Configurator::loadConfigFileIfGiven(bool overwrite) {
  string confDir = "";
  if (params.contains("conf"))
    confDir = params["conf"];
  else if (params.contains("home")) // find conf dir relative to MESOS_HOME
    confDir = params["home"] + "/" + DEFAULT_CONFIG_DIR;
  if (confDir != "")
    loadConfigFile(confDir + "/" + CONFIG_FILE_NAME, overwrite);
}

void Configurator::loadEnv(bool overwrite)
{
  char** environ = getEnviron();
  int i = 0;
  while (environ[i] != NULL) {
    string line = environ[i];
    if (line.find(ENV_VAR_PREFIX) == 0) {
      string key, val;
      size_t eq = line.find_first_of("=");
      if (eq == string::npos)
        continue; // ignore malformed lines (they shouldn't occur in environ!)
      key = line.substr(strlen(ENV_VAR_PREFIX), eq - strlen(ENV_VAR_PREFIX));
      std::transform(key.begin(), key.end(), key.begin(), ::tolower);
      val = line.substr(eq + 1);
      if (overwrite || !params.contains(key)) {
        params[key] = val;
      }
    }
    i++;
  }
}

void Configurator::loadCommandLine(int argc,
                                   char** argv,
                                   bool inferMesosHomeFromArg0,
                                   bool overwrite)
{
  // Set home based on argument 0 if asked to do so
  if (inferMesosHomeFromArg0) {
    char buf[4096];
    if (realpath(dirname(argv[0]), buf) == 0) {
      throw ConfigurationException(
          "Could not get directory containing argv[0] -- realpath failed");
    }
    params["home"] = buf;
  }

  // Convert args 1 and above to STL strings
  vector<string> args;
  for (int i=1; i < argc; i++) {
    args.push_back(string(argv[i]));
  }

  for (int i = 0; i < args.size(); i++) {
    string key, val;
    bool set = false;
    if (args[i].find("--", 0) == 0) {
      // handle "--" case

      size_t eq = args[i].find_first_of("=");
      if (eq == string::npos &&
          args[i].find("--no-", 0) == 0) { // handle --no-blah
        key = args[i].substr(5);
        val = "0";
        set = true;
      } else if (eq == string::npos) {     // handle --blah
        key = args[i].substr(2);
        val = "1";
        set = true;
      } else {                             // handle --blah=25
        key = args[i].substr(2, eq-2);
        val = args[i].substr(eq+1);
        set = true;
      }

    } else if (args[i].find_first_of("-", 0) == 0 &&
               args[i].size() > 1) {
      // handle "-" case

      if (args[i].find("-no-",0) == 0 && args[i].size() > 4) { // handle -no-b
        key = getLongName(args[i][4]);
        val = "0";
      } else if (args[i].size() > 1) {  // shared code for -b and -b 25
        key = getLongName(args[i][1]);
        val = "1";
      }
      if (key == "")
        continue;  // couldn't extract long name from short name

      if (options[key].validator->isBool())
        set = true;
      else if (i+1 < args.size()) {  // handle -b 25
        val = args[i+1];
        set = true;
        i++;  // we've consumed next parameter as a "value"-parameter
      }

    }
    if (set && (overwrite || !params.contains(key))) {
      std::transform(key.begin(), key.end(), key.begin(), ::tolower);
      params[key] = val;
    }
  }
}

void Configurator::loadConfigFile(const string& fname, bool overwrite)
{
  ifstream cfg(fname.c_str(), std::ios::in);
  if (!cfg.is_open()) {
    string message = "Couldn't read Mesos config file: " + fname;
    throw ConfigurationException(message.c_str());
  }

  string line, originalLine;

  while (!cfg.eof()) {
    getline(cfg, line);
    originalLine = line;
    // Strip any comment at end of line
    size_t hash = line.find_first_of("#"); // strip comments
    if (hash != string::npos) {
      line = line.substr(0, hash);
    }
    // Check for empty line
    line = StringUtils::trim(line);
    if (line == "") {
      continue;
    }
    // Split line by = and trim to get key and value
    vector<string> tokens;
    StringUtils::split(line, "=", &tokens);
    if (tokens.size() != 2) {
      string message = "Malformed line in config file: '" +
                       StringUtils::trim(originalLine) + "'";
      throw ConfigurationException(message.c_str());
    }
    string key = StringUtils::trim(tokens[0]);
    string value = StringUtils::trim(tokens[1]);
    if (overwrite || !params.contains(key)) {
      params[key] = value;
    }
  }
  cfg.close();
}

string Configurator::getUsage() const
{
  const int PAD = 5;
  string usage;

  map<string,string> col1; // key -> col 1 string
  int maxLen = 0;

  // construct string for the first column and get size of column
  foreachpair (const string& key, const Option& opt, options) {
    string val = "--" + key;
    if (!opt.validator->isBool())
      val += "=VAL";

    if (opt.hasShortName) {
      if (opt.validator->isBool())
        val += string(" (or -") + opt.shortName + " or -no-" +
          opt.shortName + ")";
      else
        val += string(" (or -") + opt.shortName + " VAL)";
    } else if (opt.validator->isBool())
      val += " (--no-" + key + ")";

    col1[key] = val;
    maxLen = val.size() > maxLen ? val.size() : maxLen;
  }

  foreachpair (const string& key, const Option& opt, options) {
    string helpStr = opt.helpString;
    string line = col1[key];

    if (opt.defaultValue != "") {  // add default value
      // Place a space between help string and (default: VAL) if the
      // help string does not end with a newline itself
      size_t lastNewLine = helpStr.find_last_of("\n\r");
      if (helpStr.size() > 0 && lastNewLine != helpStr.size() - 1) {
        helpStr += " ";
      }
      string defval = opt.defaultValue;
      if (opt.validator->isBool())
        defval = opt.defaultValue == "0" ? "false" : "true";

      helpStr += "(default: " + defval + ")";
    }

    string pad(PAD + maxLen - line.size(), ' ');
    line += pad;
    size_t pos1 = 0, pos2 = 0;
    pos2 = helpStr.find_first_of("\n\r", pos1);
    line += helpStr.substr(pos1, pos2 - pos1) + "\n";
    usage += line;

    while(pos2 != string::npos) {  // handle multi line help strings
      line = "";
      pos1 = pos2 + 1;
      string pad2(PAD + maxLen, ' ');
      line += pad2;
      pos2 = helpStr.find_first_of("\n\r", pos1);
      line += helpStr.substr(pos1, pos2 - pos1) + "\n";
      usage += line;
    }

  }
  return usage;
}

vector<string> Configurator::getOptions() const
{
  vector<string> ret;
  foreachpair (const string& key, _, options) {
    ret.push_back(key);
  }
  return ret;
}

Params& Configurator::getParams()
{
  return params;
}

string Configurator::getLongName(char shortName) const
{
  foreachpair (const string& key, const Option& opt, options) {
    if (opt.hasShortName && opt.shortName == shortName)
      return key;
  }
  return "";
}

void Configurator::clearMesosEnvironmentVars()
{
  char** environ = getEnviron();
  int i = 0;
  vector<string> toRemove;
  while (environ[i] != NULL) {
    string line = environ[i];
    if (line.find(ENV_VAR_PREFIX) == 0) {
      string key;
      size_t eq = line.find_first_of("=");
      if (eq == string::npos)
        continue; // ignore malformed lines (they shouldn't occur in environ!)
      key = line.substr(strlen(ENV_VAR_PREFIX), eq - strlen(ENV_VAR_PREFIX));
      toRemove.push_back(key);
    }
    i++;
  }
  foreach (string& str, toRemove) {
    unsetenv(str.c_str());
  }
}
<|endoftext|>


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

#include "testpp.h"
#include "default_output.h"

testpp_c::testpp_c()
: m_result( NULL )
{}

void testpp_c::set_result( testpp_result_c &result )
{
	m_result = &result;
}

void testpp_c::fail( const char *filename, int line, const std::string &msg )
{
	m_result->fail( filename, line, msg );
}

testpp_runner_i::testpp_runner_i( const std::string &test_name
	       , const char *file_name, int line_number )
: m_id( test_name, file_name, line_number )
{
	/*
	static int i( 0 );
	std::cerr << "runners().push_back( " << i++ << " )"
		<< " = " << runners().size() << std::endl;
	*/
	runners().push_back( this );
}

testpp_runner_i::testpp_runner_i( const std::string &test_name
	       , testpp_suite_c &suite, const char *file_name
	       , int line_number )
: m_id( suite, test_name, file_name, line_number )
{
	/*
	static int i( 0 );
	std::cerr << "runners().push_back( " << i++ << " )"
		<< " = " << runners().size() << std::endl;
	*/
	runners().push_back( this );
}

testpp_runner_i::~testpp_runner_i()
{
	std::list< testpp_runner_i * >::iterator it;
	it = std::find( runners().begin(), runners().end(), this );
	if ( it == runners().end() ) {
		runners().erase( it );
	}
}

void testpp_runner_i::run_test( testpp_result_c &result )
{
	std::auto_ptr< testpp_c > test( create_test() );
	test->set_result( result );
	try {
		test->setup();
		test->test();
		test->teardown();
	} catch (...) {
		std::cerr << "catch...";
	}
}

void testpp_runner_i::run_all( testpp_output_i &out )
{
	// std::cerr << "run_all( " << runners().size() << " )\n";
	std::list< testpp_runner_i * >::iterator it;
	int i( 0 );
	int passed( 0 );
	int failed( 0 );
	for ( it=runners().begin(); it!=runners().end(); ++it ) {
		out.begin( (*it)->id() );

		testpp_result_c result;
		(*it)->run_test( result );
		if ( result.failure() ) {
			++failed;
			// out << "\t" << result.message() << std::endl;
		} else {
			++passed;
		}

		out.complete( (*it)->id(), result );
	}

	out.summarize( passed, failed );
	/*
	out << failures << " failures in " << runners().size()
		<< " tests\n";
		*/
}

void testpp_runner_i::run_some( testpp_output_i &out, const std::string &suite )
{
	std::list< testpp_runner_i * >::iterator it;
	int i( 0 );
	int passed( 0 );
	int failed( 0 );
	for ( it=runners().begin(); it!=runners().end(); ++it ) {
		if ( ! (*it)->in_suite( suite ) ) {
			continue;
		}

		out.begin( (*it)->id() );

		testpp_result_c result;
		// std::cerr << "run( " << i++ << " )" << std::endl;
		(*it)->run_test( result );
		if ( result.failure() ) {
			++failed;
			// out << "\t" << result.message() << std::endl;
		} else {
			++passed;
		}

		out.complete( (*it)->id(), result );
	}

	out.summarize( passed, failed );
	/*
	out << failures << " failures in " << run_count
		<< " tests\n";
		*/
}

std::list< testpp_runner_i * > & testpp_runner_i::runners()
{
	static std::list< testpp_runner_i * > static_runners;
	return static_runners;
}

int main( int argc, char **argv )
{
	human_testpp_output_c human;
	testpp_output_i &output( human );
	output.set_stream( std::cout );

	if ( argc == 1 ) {
		testpp_runner_i::run_all( output );
	} else if ( argc == 2 ) {
		testpp_runner_i::run_some( output, argv[1] );
	}
	return 0;
}

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

#include "testpp.h"
#include "default_output.h"
#include "testpp_project.h"

testpp_c::testpp_c()
: m_result( NULL )
{}

void testpp_c::set_result( testpp_result_c &result )
{
	m_result = &result;
}

void testpp_c::fail( const char *filename, int line, const std::string &msg )
{
	m_result->fail( filename, line, msg );
}

testpp_runner_i::testpp_runner_i( const std::string &test_name
	       , const char *file_name, int line_number )
: m_id( test_name, file_name, line_number )
{
	/*
	static int i( 0 );
	std::cerr << "runners().push_back( " << i++ << " )"
		<< " = " << runners().size() << std::endl;
	*/
	runners().push_back( this );
}

testpp_runner_i::testpp_runner_i( const std::string &test_name
	       , testpp_suite_c &suite, const char *file_name
	       , int line_number )
: m_id( suite, test_name, file_name, line_number )
{
	/*
	static int i( 0 );
	std::cerr << "runners().push_back( " << i++ << " )"
		<< " = " << runners().size() << std::endl;
	*/
	runners().push_back( this );
}

testpp_runner_i::~testpp_runner_i()
{
	std::list< testpp_runner_i * >::iterator it;
	it = std::find( runners().begin(), runners().end(), this );
	if ( it == runners().end() ) {
		runners().erase( it );
	}
}

void testpp_runner_i::run_test( testpp_result_c &result )
{
	std::auto_ptr< testpp_c > test( create_test() );
	test->set_result( result );
	try {
		test->setup();
		test->test();
		test->teardown();
	} catch (...) {
		std::cerr << "catch...";
	}
}

void testpp_runner_i::run_all( testpp_output_i &out )
{
	// std::cerr << "run_all( " << runners().size() << " )\n";
	std::list< testpp_runner_i * >::iterator it;
	int i( 0 );
	int passed( 0 );
	int failed( 0 );
	for ( it=runners().begin(); it!=runners().end(); ++it ) {
		out.begin( (*it)->id() );

		testpp_result_c result;
		(*it)->run_test( result );
		if ( result.failure() ) {
			++failed;
			// out << "\t" << result.message() << std::endl;
		} else {
			++passed;
		}

		out.complete( (*it)->id(), result );
	}

	out.summarize( passed, failed );
	/*
	out << failures << " failures in " << runners().size()
		<< " tests\n";
		*/
}

void testpp_runner_i::run_some( testpp_output_i &out, const std::string &suite )
{
	std::list< testpp_runner_i * >::iterator it;
	int i( 0 );
	int passed( 0 );
	int failed( 0 );
	for ( it=runners().begin(); it!=runners().end(); ++it ) {
		if ( ! (*it)->in_suite( suite ) ) {
			continue;
		}

		out.begin( (*it)->id() );

		testpp_result_c result;
		// std::cerr << "run( " << i++ << " )" << std::endl;
		(*it)->run_test( result );
		if ( result.failure() ) {
			++failed;
			// out << "\t" << result.message() << std::endl;
		} else {
			++passed;
		}

		out.complete( (*it)->id(), result );
	}

	out.summarize( passed, failed );
	/*
	out << failures << " failures in " << run_count
		<< " tests\n";
		*/
}

std::list< testpp_runner_i * > & testpp_runner_i::runners()
{
	static std::list< testpp_runner_i * > static_runners;
	return static_runners;
}

int main( int argc, char **argv )
{
	human_testpp_output_c human;
	testpp_output_i &output( human );
	output.set_stream( std::cout );

	testpp_project_loader_i &project_loader(
			testpp_project_loader_i::project_loader() );
	std::auto_ptr< testpp_project_c > project(
			project_loader.create_project() );

	std::string suite_name;
	std::string whole_format;
	std::string format;

	if ( argc == 1 ) {
		// do nothing here
	} else if ( argc == 2 ) {
		whole_format = argv[1];
		std::string output( "--output=" );
		if ( whole_format.find( output ) == 0 ) {
			format = whole_format.substr( output.length() );
			std::cerr << "output = " << format << std::endl;
		} else {
			suite_name = argv[1];
		}
	} else if ( argc == 3 ) {
		whole_format = argv[1];
		std::string output( "--output=" );
		if ( whole_format.find( output ) == 0 ) {
			format = whole_format.substr( output.length() );
			std::cerr << "output = " << format << std::endl;
		}
		suite_name = argv[2];
	}

	if ( suite_name.empty() ) {
		testpp_runner_i::run_all( output );
	} else {
		testpp_runner_i::run_some( output, suite_name );
	}

	return 0;
}

<|endoftext|>


<commit_before>
#include <iostream>
#include <limits>

int countCommonElements(int u[], int v[], int nu, int nv, int top);
int countCommonElements(int u[], int v[], int nu, int nv);

int main() {

	int u[100] = {0}; // u = {0, 0, 0, 0, 0, .....}
	int v[200] = {0}; // v = {0, 0, 0, 0, 0, .....}

	int c;

	c = countCommonElements(u, v, sizeof(u) / sizeof(int), sizeof(v) / sizeof(int));  // Should return 1
	std::cout << "1? " << c << std::endl;

	u[0] = 1; // u = {1, 0, 0, 0, 0, .....}
	v[0] = 1; // v = {1, 0, 0, 0, 0, .....}
	c = countCommonElements(u, v, sizeof(u) / sizeof(int), sizeof(v) / sizeof(int));  // Should return 2
	std::cout << "2? " << c << std::endl;

	u[0] = 0; u[1] = 1; u[2] = 2; u[3] = 3; // u = {0, 1, 2, 3}
	v[0] = 0; v[1] = 1; v[2] = 2; v[3] = 3; // v = {0, 1, 2, 3}
	c = countCommonElements(u, v, 4, 4); // Should return 4
	std::cout << "4? " << c << std::endl;

	u[0] = 0; u[1] = 1; u[2] = 2; u[3] = 3; u[4] = 3; u[5] = 3; // u = {0, 1, 2, 3, 3, 3}
	v[0] = 0; v[1] = 1; v[2] = 2; v[3] = 3; v[4] = 3; v[5] = 3; // v = {0, 1, 2, 3, 3, 3}
	c = countCommonElements(u, v, 6, 6); // Should return 4
	std::cout << "4? " << c << std::endl;

	u[0] = 0; u[1] = 100; u[2] = 300; u[3] = 350; u[4] = 450; u[5] = 600; // u = {0, 100, 300, 350, 450, 600}
	v[0] = 0; v[1] = 100; v[2] = 200; v[3] = 300; v[4] = 400; v[5] = 500; // v = {0, 100, 200, 300, 400, 500}
	c = countCommonElements(u, v, 6, 6); // Should return 3
	std::cout << "3? " << c << std::endl;

	u[0] = -1000; u[1] = -100; u[2] = 0; u[3] = 100; u[4] = 200; u[5] = 4000; // u = {-1000, -100, 0, 100, 200, 4000}
	v[0] = 0; v[1] = 100; v[2] = 200; v[3] = 300; v[4] = 400; v[5] = 500; // v = {0, 100, 200, 300, 400, 500}
	c = countCommonElements(u, v, 6, 6); // Should return 3
	std::cout << "3? " << c << std::endl;

	u[0] = -1000; u[1] = -100; u[2] = 0; u[3] = 100; u[4] = 200; u[5] = 4000; // u = {-1000, -100, 0, 100, 200, 4000}
	v[0] = 0; v[1] = 100; v[2] = 200; v[3] = 300; v[4] = 400; v[5] = 500; // v = {0, 100, 200, 300, 400, 500}
	c = countCommonElements(u, v, 6, 6); // Should return 3
	std::cout << "3? " << c << std::endl;

	for (int i = 0; i < sizeof(u) / sizeof(int); i++) // u = {0, 1, 2, 3, 4, 5, 6, ...}
		u[i] = i;
	for (int i = 0; i < sizeof(v) / sizeof(int); i++) // v = {0, 1, 2, 3, 4, 5, 6, ...}
		v[i] = i;
	c = countCommonElements(u, v, sizeof(u) / sizeof(int), sizeof(v) / sizeof(int));  // Should return: min(sizeof(u) / sizeof(int), sizeof(v) / sizeof(int))
	std::cout << ((sizeof(u) / sizeof(int) > sizeof(v) / sizeof(int)) ? sizeof(v) / sizeof(int) : sizeof(u) / sizeof(int)) << "? " << c << std::endl;

	for (int i = 0; i < sizeof(u) / sizeof(int); i++) // u = {0, 1, 2, 3, 4, 5, 6, ...}
		u[i] = i;
	for (int i = 0; i < sizeof(v) / sizeof(int); i++) // v = {0, 2, 4, 6, 8, 10, 12, ...}
		v[i] = 2 * i;
	c = countCommonElements(u, v, sizeof(u) / sizeof(int), sizeof(v) / sizeof(int)); // Should return?: min[(sizeof(u) / sizeof(int)) / 2 + ((sizeof(u) / sizeof(int)) % 2 == 1 ? 1 : 0) , sizeof(v) / sizeof(int)]
	std::cout << ((((sizeof(u) / sizeof(int)) / 2 + ((sizeof(u) / sizeof(int)) % 2 == 0 ? 0 : 1)) < sizeof(v) / sizeof(int)) ? ((sizeof(u) / sizeof(int)) / 2 + ((sizeof(u) / sizeof(int)) % 2 == 0 ? 0 : 1)) : sizeof(v) / sizeof(int)) << "? " << c << std::endl;

	for (int i = 0; i < sizeof(u) / sizeof(int); i++) // u = {0, 1, 2, 3, 4, 5, 6, ...}
		u[i] = i;
	for (int i = 0; i < sizeof(v) / sizeof(int); i++) // v = {0, 2, 4, 6, 8, 10, 12, ...}
		v[i] = 3 * i;
	c = countCommonElements(u, v, sizeof(u) / sizeof(int), sizeof(v) / sizeof(int)); // Should return?: min[(sizeof(u) / sizeof(int)) / 3 + ((sizeof(u) / sizeof(int)) % 3 == 0 ? 0 : 1) , sizeof(v) / sizeof(int)]
	std::cout << ((((sizeof(u) / sizeof(int)) / 3 + ((sizeof(u) / sizeof(int)) % 3 == 0 ? 0 : 1)) < sizeof(v) / sizeof(int)) ? ((sizeof(u) / sizeof(int)) / 3 + ((sizeof(u) / sizeof(int)) % 3 == 0 ? 0 : 1)) : sizeof(v) / sizeof(int)) << "? " << c << std::endl;

	return 0;
}

/*
P: {
	nu = lenght(u) ^
	nu = lenght(v) ^
	nu >= 0 ^
	nv >= 0 ^
	ForAll wu : 0 <= wu < nu - 1 : u[wu] <= u[wu + 1] ^ // u is sorted in ascending order
	ForAll wv : 0 <= wv < nv - 1 : v[wv] <= u[wv + 1] ^ // v is sorted in ascending order
	u[nu - 1] < INT_MAX ^ // Values have to be less than INT_MAX
	v[vu - 1] < INT_MAX   // Values have to be less than INT_MAX
}

*/
int countCommonElements(int u[], int v[], int nu, int nv) {
	return countCommonElements(u, v, nu, nv, std::numeric_limits<int>::max());
}
/*
Q: { // Returned value "r"
	r =
	(# wv : 0 <= wv < nv :
		( Exists wu : 0 <= wu < nu : nu[wu] = nv[wv] )
	)
}
*/

int countCommonElements(int u[], int v[], int nu, int nv, int top) {
	if (nu == 0 || nv == 0) { // When the size of any array is 0, there is no element to compare. Return 0.
		return 0;
	}
	else {
		if		(v[nv - 1] == top)			return countCommonElements(u, v, nu		, nv - 1, top		);		// If the last elemet of the array v is the same as the last element compared, ignore it. Check again with one element less.
		else if	(u[nu - 1] == top)			return countCommonElements(u, v, nu - 1	, nv	, top		);		// The same, but with u
		else if	(v[nv - 1] == u[nu - 1])	return countCommonElements(u, v, nu - 1	, nv - 1, v[nv - 1]	) + 1;	// If the last element of both arrays is the same, check again with one element less in each array, ignoring that last element. The last argument (top) becomes that element. Add one to the result of that "smaller problem" ('tail' recursion broken here).
		else if (v[nv - 1] <  u[nu - 1])	return countCommonElements(u, v, nu - 1	, nv	, top		);		// If the last element in u is greater than the last element in v, check again ignoring the last element in u
		else if	(v[nv - 1] >  u[nu - 1])	return countCommonElements(u, v, nu		, nv - 1, top		);		// The same, but with v
		// It should never come out of the if-else. All cases are taken into account.
	}
}

/*
In ALL recursive call, at least one of "nv" or "nu" is decreased ==> The size of the problem decreases.
The base case happens when the size of the problem is small enought (at least one array has size 0).
The recursive case takes into account all cases from the last 3 else-if cases, one always happens).

The result of the problem is the result of a smaller problem (at least one of the arrays is smaller), plus one if the result for the current problem is the one checked.

(It is not tail recursion, as in one of the resursive calls, 1 is added after the recursive call)

*/

<commit_msg>Fixed error in Lab 3 code<commit_after>
#include <iostream>
#include <limits>

int countCommonElements(int u[], int v[], int nu, int nv, int top);
int countCommonElements(int u[], int v[], int nu, int nv);

int main() {

	int u[100] = {0}; // u = {0, 0, 0, 0, 0, .....}
	int v[200] = {0}; // v = {0, 0, 0, 0, 0, .....}

	int c;

	c = countCommonElements(u, v, sizeof(u) / sizeof(int), sizeof(v) / sizeof(int));  // Should return 1
	std::cout << "1? " << c << std::endl;

	u[0] = 1; // u = {1, 0, 0, 0, 0, .....}
	v[0] = 1; // v = {1, 0, 0, 0, 0, .....}
	c = countCommonElements(u, v, sizeof(u) / sizeof(int), sizeof(v) / sizeof(int));  // Should return 2
	std::cout << "2? " << c << std::endl;

	u[0] = 0; u[1] = 1; u[2] = 2; u[3] = 3; // u = {0, 1, 2, 3}
	v[0] = 0; v[1] = 1; v[2] = 2; v[3] = 3; // v = {0, 1, 2, 3}
	c = countCommonElements(u, v, 4, 4); // Should return 4
	std::cout << "4? " << c << std::endl;

	u[0] = 0; u[1] = 1; u[2] = 2; u[3] = 3; u[4] = 3; u[5] = 3; // u = {0, 1, 2, 3, 3, 3}
	v[0] = 0; v[1] = 1; v[2] = 2; v[3] = 3; v[4] = 3; v[5] = 3; // v = {0, 1, 2, 3, 3, 3}
	c = countCommonElements(u, v, 6, 6); // Should return 4
	std::cout << "4? " << c << std::endl;

	u[0] = 0; u[1] = 100; u[2] = 300; u[3] = 350; u[4] = 450; u[5] = 600; // u = {0, 100, 300, 350, 450, 600}
	v[0] = 0; v[1] = 100; v[2] = 200; v[3] = 300; v[4] = 400; v[5] = 500; // v = {0, 100, 200, 300, 400, 500}
	c = countCommonElements(u, v, 6, 6); // Should return 3
	std::cout << "3? " << c << std::endl;

	u[0] = -1000; u[1] = -100; u[2] = 0; u[3] = 100; u[4] = 200; u[5] = 4000; // u = {-1000, -100, 0, 100, 200, 4000}
	v[0] = 0; v[1] = 100; v[2] = 200; v[3] = 300; v[4] = 400; v[5] = 500; // v = {0, 100, 200, 300, 400, 500}
	c = countCommonElements(u, v, 6, 6); // Should return 3
	std::cout << "3? " << c << std::endl;

	u[0] = -1000; u[1] = -100; u[2] = 0; u[3] = 100; u[4] = 200; u[5] = 4000; // u = {-1000, -100, 0, 100, 200, 4000}
	v[0] = 0; v[1] = 100; v[2] = 200; v[3] = 300; v[4] = 400; v[5] = 500; // v = {0, 100, 200, 300, 400, 500}
	c = countCommonElements(u, v, 6, 6); // Should return 3
	std::cout << "3? " << c << std::endl;

	for (int i = 0; i < sizeof(u) / sizeof(int); i++) // u = {0, 1, 2, 3, 4, 5, 6, ...}
		u[i] = i;
	for (int i = 0; i < sizeof(v) / sizeof(int); i++) // v = {0, 1, 2, 3, 4, 5, 6, ...}
		v[i] = i;
	c = countCommonElements(u, v, sizeof(u) / sizeof(int), sizeof(v) / sizeof(int));  // Should return: min(sizeof(u) / sizeof(int), sizeof(v) / sizeof(int))
	std::cout << ((sizeof(u) / sizeof(int) > sizeof(v) / sizeof(int)) ? sizeof(v) / sizeof(int) : sizeof(u) / sizeof(int)) << "? " << c << std::endl;

	for (int i = 0; i < sizeof(u) / sizeof(int); i++) // u = {0, 1, 2, 3, 4, 5, 6, ...}
		u[i] = i;
	for (int i = 0; i < sizeof(v) / sizeof(int); i++) // v = {0, 2, 4, 6, 8, 10, 12, ...}
		v[i] = 2 * i;
	c = countCommonElements(u, v, sizeof(u) / sizeof(int), sizeof(v) / sizeof(int)); // Should return?: min[(sizeof(u) / sizeof(int)) / 2 + ((sizeof(u) / sizeof(int)) % 2 == 1 ? 1 : 0) , sizeof(v) / sizeof(int)]
	std::cout << ((((sizeof(u) / sizeof(int)) / 2 + ((sizeof(u) / sizeof(int)) % 2 == 0 ? 0 : 1)) < sizeof(v) / sizeof(int)) ? ((sizeof(u) / sizeof(int)) / 2 + ((sizeof(u) / sizeof(int)) % 2 == 0 ? 0 : 1)) : sizeof(v) / sizeof(int)) << "? " << c << std::endl;

	for (int i = 0; i < sizeof(u) / sizeof(int); i++) // u = {0, 1, 2, 3, 4, 5, 6, ...}
		u[i] = i;
	for (int i = 0; i < sizeof(v) / sizeof(int); i++) // v = {0, 2, 4, 6, 8, 10, 12, ...}
		v[i] = 3 * i;
	c = countCommonElements(u, v, sizeof(u) / sizeof(int), sizeof(v) / sizeof(int)); // Should return?: min[(sizeof(u) / sizeof(int)) / 3 + ((sizeof(u) / sizeof(int)) % 3 == 0 ? 0 : 1) , sizeof(v) / sizeof(int)]
	std::cout << ((((sizeof(u) / sizeof(int)) / 3 + ((sizeof(u) / sizeof(int)) % 3 == 0 ? 0 : 1)) < sizeof(v) / sizeof(int)) ? ((sizeof(u) / sizeof(int)) / 3 + ((sizeof(u) / sizeof(int)) % 3 == 0 ? 0 : 1)) : sizeof(v) / sizeof(int)) << "? " << c << std::endl;

	return 0;
}

/*
P: {
	nu = lenght(u) ^
	nu = lenght(v) ^
	nu >= 0 ^
	nv >= 0 ^
	ForAll wu : 0 <= wu < nu - 1 : u[wu] <= u[wu + 1] ^ // u is sorted in ascending order
	ForAll wv : 0 <= wv < nv - 1 : v[wv] <= u[wv + 1] ^ // v is sorted in ascending order
	u[nu - 1] < INT_MAX ^ // Values have to be less than INT_MAX
	v[vu - 1] < INT_MAX   // Values have to be less than INT_MAX
}

*/
int countCommonElements(int u[], int v[], int nu, int nv) {
	return countCommonElements(u, v, nu, nv, std::numeric_limits<int>::max());
}
/*
Q: { // Returned value "r"
	r =
	(# wv : 0 <= wv < nv :
		( Exists wu : 0 <= wu < nu : nu[wu] = nv[wv] )
	)
}
*/

int countCommonElements(int u[], int v[], int nu, int nv, int top) {
	if (nu == 0 || nv == 0) { // When the size of any array is 0, there is no element to compare. Return 0.
		return 0;
	}
	else {
		if		(v[nv - 1] == top)			return countCommonElements(u, v, nu		, nv - 1, top		);		// If the last elemet of the array v is the same as the last element compared, ignore it. Check again with one element less.
		else if	(u[nu - 1] == top)			return countCommonElements(u, v, nu - 1	, nv	, top		);		// The same, but with u
		else if	(v[nv - 1] == u[nu - 1])	return countCommonElements(u, v, nu - 1	, nv - 1, v[nv - 1]	) + 1;	// If the last element of both arrays is the same, check again with one element less in each array, ignoring that last element. The last argument (top) becomes that element. Add one to the result of that "smaller problem" ('tail' recursion broken here).
		else if (v[nv - 1] <  u[nu - 1])	return countCommonElements(u, v, nu - 1	, nv	, top		);		// If the last element in u is greater than the last element in v, check again ignoring the last element in u
		else if	(v[nv - 1] >  u[nu - 1])	return countCommonElements(u, v, nu		, nv - 1, top		);		// The same, but with v
		// It should never come out of the if-else. All cases are taken into account.
	}
}

/*
In ALL recursive calls, at least one of "nv" or "nu" is decreased ==> The size of the problem decreases.
The base case happens when the size of the problem is small enought (at least one array has size 0).
The recursive case takes into account all cases from the last 3 else-if cases, one always happens).

The result of the problem is the result of a smaller problem (at least one of the arrays is smaller), plus one if the result for the current problem is the one checked.

(It is not tail recursion, as in one of the resursive calls, 1 is added after the recursive call)

*/

<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#define DBLEVEL  20

#include "include/types.h"

#include "MDS.h"
#include "ClientMap.h"

#include "osdc/Filer.h"

#include "config.h"

#define dout(x)  if (x <= g_conf.debug_mds) *_dout << dbeginl << g_clock.now() << " mds" << mds->get_nodeid() << ".clientmap "

void ClientMap::init_inode()
{
  memset(&inode, 0, sizeof(inode));
  inode.ino = MDS_INO_CLIENTMAP_OFFSET + mds->get_nodeid();
  inode.layout = g_OSD_FileLayout;
}

// ----------------
// LOAD

class C_CM_Load : public Context {
  ClientMap *clientmap;
public:
  bufferlist bl;
  C_CM_Load(ClientMap *cm) : clientmap(cm) {}
  void finish(int r) {
	clientmap->_load_finish(bl);
  }
};

void ClientMap::load(Context *onload)
{
  dout(10) << "load" << dendl;

  init_inode();

  if (onload)
	waiting_for_load.push_back(onload);

  C_CM_Load *c = new C_CM_Load(this);
  mds->filer->read(inode,
                   0, inode.layout.stripe_unit,
                   &c->bl,
                   c);

}

void ClientMap::_load_finish(bufferlist &bl)
{
  int off = 0;
  decode(bl, off);
  dout(10) << "_load_finish v " << version
		   << ", " << client_inst.size() << " clients, "
		   << bl.length() << " bytes"
		   << dendl;
  projected = committing = committed = version;
  finish_contexts(waiting_for_load);
}

// ----------------
// SAVE

class C_CM_Save : public Context {
  ClientMap *clientmap;
  version_t version;
public:
  C_CM_Save(ClientMap *cm, version_t v) : clientmap(cm), version(v) {}
  void finish(int r) {
	clientmap->_save_finish(version);
  }
};

void ClientMap::save(Context *onsave, version_t needv)
{
  dout(10) << "save needv " << needv << ", v " << version << dendl;
  commit_waiters[version].push_back(onsave);

  if (needv && committing >= needv) return;

  bufferlist bl;

  init_inode();
  encode(bl);
  committing = version;
  mds->filer->write(inode,
                    0, bl.length(), bl,
                    0,
					0, new C_CM_Save(this, version));
}

void ClientMap::_save_finish(version_t v)
{
  dout(10) << "_save_finish v" << v << dendl;
  committed = v;

  finish_contexts(commit_waiters[v]);
  commit_waiters.erase(v);
}
<commit_msg>fixed bug in clientmap save callback<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#define DBLEVEL  20

#include "include/types.h"

#include "MDS.h"
#include "ClientMap.h"

#include "osdc/Filer.h"

#include "config.h"

#define dout(x)  if (x <= g_conf.debug_mds) *_dout << dbeginl << g_clock.now() << " mds" << mds->get_nodeid() << ".clientmap "

void ClientMap::init_inode()
{
  memset(&inode, 0, sizeof(inode));
  inode.ino = MDS_INO_CLIENTMAP_OFFSET + mds->get_nodeid();
  inode.layout = g_OSD_FileLayout;
}

// ----------------
// LOAD

class C_CM_Load : public Context {
  ClientMap *clientmap;
public:
  bufferlist bl;
  C_CM_Load(ClientMap *cm) : clientmap(cm) {}
  void finish(int r) {
	clientmap->_load_finish(bl);
  }
};

void ClientMap::load(Context *onload)
{
  dout(10) << "load" << dendl;

  init_inode();

  if (onload)
	waiting_for_load.push_back(onload);

  C_CM_Load *c = new C_CM_Load(this);
  mds->filer->read(inode,
                   0, inode.layout.stripe_unit,
                   &c->bl,
                   c);

}

void ClientMap::_load_finish(bufferlist &bl)
{
  int off = 0;
  decode(bl, off);
  dout(10) << "_load_finish v " << version
		   << ", " << client_inst.size() << " clients, "
		   << bl.length() << " bytes"
		   << dendl;
  projected = committing = committed = version;
  finish_contexts(waiting_for_load);
}

// ----------------
// SAVE

class C_CM_Save : public Context {
  ClientMap *clientmap;
  version_t version;
public:
  C_CM_Save(ClientMap *cm, version_t v) : clientmap(cm), version(v) {}
  void finish(int r) {
	clientmap->_save_finish(version);
  }
};

void ClientMap::save(Context *onsave, version_t needv)
{
  dout(10) << "save needv " << needv << ", v " << version << dendl;

  if (needv && committing >= needv) {
    assert(committing > committed);
    commit_waiters[committing].push_back(onsave);
    return;
  }

  commit_waiters[version].push_back(onsave);

  bufferlist bl;

  init_inode();
  encode(bl);
  committing = version;
  mds->filer->write(inode,
                    0, bl.length(), bl,
                    0,
		    0, new C_CM_Save(this, version));
}

void ClientMap::_save_finish(version_t v)
{
  dout(10) << "_save_finish v" << v << dendl;
  committed = v;

  finish_contexts(commit_waiters[v]);
  commit_waiters.erase(v);
}
<|endoftext|>


<commit_before>// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <atomic>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>

#include "base/logging.h"
#include "mojo/edk/system/ports/node.h"
#include "mojo/edk/system/ports/node_delegate.h"
#include "testing/gtest/include/gtest/gtest.h"

// Each thread has a thread-local mapping from thread_id to port to used to
// communication to the thread.
//
//   TLS: map(thread_id) -> port
//
// This can be used to send a message from any thread to any thread.
//
// Upon receiving a message, a thread will wake up and perform a random
// activity. Activities include:
//
//   1. Forward the message to a random thread.
//   2. Forward the received ports to a random assortment of threads.
//   3  Send a message with a random number of ports to the received ports,
//      send the peer ports to other random threads, and then close the
//      received ports.
//   4. Close the received ports. Send a new message to a random port.
//
// The test concludes after N messages have been received.

namespace ports {

static const size_t kNumThreads = 100;
static const size_t kNumNodes = 10;

static const uint32_t kMaxMessages = 1000000;
static std::atomic<uint32_t> message_counter(1);
static bool ShouldExit() {
  return message_counter.load() > kMaxMessages;
}
static void MessageWasRead() {
  uint32_t value = message_counter.fetch_add(1);
  if (value % (kMaxMessages / 1000) == 0) {
    printf(".");
    fflush(stdout);
  }
  if (value % (kMaxMessages / 10) == 0)
    printf("\n");
}

struct NodeData {
  std::unique_ptr<Node> node;
  std::unique_ptr<NodeDelegate> delegate;
  std::mutex lock;
  std::queue<Event> events;
  std::condition_variable cvar;
};

struct ThreadData {
  NodeName node_name;
  PortName ports[kNumThreads];  // Ports to all of the other threads.
  PortName self_port;           // The peer of the port to ourselves.
};
static thread_local ThreadData* this_thread_data;

static void PutEvent(NodeData* node_data, Event event) {
  {
    std::lock_guard<std::mutex> guard(node_data->lock);
    node_data->events.emplace(std::move(event));
  }
  node_data->cvar.notify_one();
}

static bool GetEvent(NodeData* node_data, Event* event) {
  while (!ShouldExit()) {
    std::unique_lock<std::mutex> guard(node_data->lock);
    if (node_data->events.empty()) {
      node_data->cvar.wait(guard);
    } else {
      *event = std::move(node_data->events.front());
      node_data->events.pop();
      return true;
    }
  }
  return false;
}

static std::atomic<uint64_t> next_unique_uint64;
static uint64_t GenerateUniqueUint64() {
  return next_unique_uint64.fetch_add(1, std::memory_order_relaxed);
}

static ThreadData* kThreadData[kNumThreads];
static NodeData* kNodeData[kNumNodes];

static int RandomDestination() {
  return rand() % kNumThreads;
}

static ScopedMessage NewMessageWithNumPorts(size_t num_ports) {
  const char kMessageText[] = "hello";
  ScopedMessage message(AllocMessage(sizeof(kMessageText), num_ports));
  strcpy(static_cast<char*>(message->bytes), kMessageText);
  return message;
}

static ScopedMessage NewMessageWithPort(PortName port) {
  ScopedMessage message(NewMessageWithNumPorts(1));
  message->ports[0].name = port;
  return message;
}

static ScopedMessage NewMessageWithRandomNumPorts(
    Node* node, std::vector<PortName>* other_ports) {
  size_t num_ports = rand() % 10;

  ScopedMessage message(NewMessageWithNumPorts(num_ports));

  other_ports->clear();
  for (size_t i = 0; i < num_ports; ++i) {
    PortName a, b;
    node->CreatePortPair(&a, &b);
    message->ports[i].name = a;
    other_ports->push_back(b);
  }

  return message;
}

static void DoRandomActivity(Node* node, ScopedMessage message) {
  switch (rand() % 3) {
    case 0: {
      // Forward the message to a random thread.
      node->SendMessage(this_thread_data->ports[RandomDestination()],
                        std::move(message));
      break;
    }
    case 1:
      // Forward the received ports to a random assortment of threads.
      for (size_t i = 0; i < message->num_ports; ++i) {
        ScopedMessage new_message = NewMessageWithPort(message->ports[i].name);
        node->SendMessage(this_thread_data->ports[RandomDestination()],
                          std::move(new_message));
      }
      break;
    case 2:
      // Send a message with a random number of ports to the received ports,
      // send the peer ports to other random threads, and then close the
      // received ports.
      for (size_t i = 0; i < message->num_ports; ++i) {
        std::vector<PortName> other_ports;
        ScopedMessage new_message(
            NewMessageWithRandomNumPorts(node, &other_ports));
        for (size_t i = 0; i < other_ports.size(); ++i) {
          node->SendMessage(this_thread_data->ports[RandomDestination()],
                            NewMessageWithPort(other_ports[i]));
        }
        node->SendMessage(message->ports[i].name, std::move(new_message));
        node->ClosePort(message->ports[i].name);
      }
      break;
    case 3:
      // Close the received ports. Send a new message to a random port.
      for (size_t i = 0; i < message->num_ports; ++i)
        node->ClosePort(message->ports[i].name);
      node->SendMessage(this_thread_data->ports[RandomDestination()],
                        NewMessageWithNumPorts(0));
      break;
  }
}

class TestNodeDelegate : public NodeDelegate {
 public:
  explicit TestNodeDelegate(const NodeName& node_name)
      : node_name_(node_name) {
  }

  void GenerateRandomPortName(PortName* port_name) override {
    port_name->value_major = GenerateUniqueUint64();
    port_name->value_minor = 0;
  }

  void SendEvent(const NodeName& node_name, Event event) override {
    PutEvent(kNodeData[node_name.value_major], std::move(event));
  }

  void MessagesAvailable(const PortName& port,
                         std::shared_ptr<UserData> user_data) override {
    Node* node = kNodeData[node_name_.value_major]->node.get();
    for (;;) {
      ScopedMessage message;
      node->GetMessage(port, &message);
      if (message) {
        DoRandomActivity(node, std::move(message));
        MessageWasRead();
      } else {
        break;
      }
    }
  }

 private:
  NodeName node_name_;
};

static void ThreadFunc(size_t thread_index) {
  this_thread_data = kThreadData[thread_index];

  NodeData* node_data = kNodeData[this_thread_data->node_name.value_major];

  for (;;) {
    Event event(Event::kAcceptMessage);  // dummy event
    if (GetEvent(node_data, &event)) {
      node_data->node->AcceptEvent(std::move(event));
    } else {
      break;
    }
  }
}

static void KickOffTest() {
  ThreadData* thread_data = kThreadData[0];
  NodeData* node_data = kNodeData[thread_data->node_name.value_major];

  std::vector<PortName> other_ports;
  ScopedMessage message(
      NewMessageWithRandomNumPorts(node_data->node.get(), &other_ports));
  for (size_t i = 0; i < other_ports.size(); ++i) {
    node_data->node->SendMessage(
        thread_data->ports[RandomDestination()],
        NewMessageWithPort(other_ports[i]));
  }
  node_data->node->SendMessage(
      thread_data->ports[RandomDestination()], std::move(message));
}

TEST(ThreadedStressTest, RandomDance) {
  for (size_t i = 0; i < kNumNodes; ++i) {
    NodeName node_name(i, 0);
    kNodeData[i] = new NodeData();
    kNodeData[i]->delegate.reset(new TestNodeDelegate(node_name));
    kNodeData[i]->node.reset(new Node(node_name, kNodeData[i]->delegate.get()));
  }

  for (size_t i = 0; i < kNumThreads; ++i) {
    kThreadData[i] = new ThreadData();
    kThreadData[i]->node_name = NodeName(i % kNumNodes, 0);
  }

  // Create web of ports between threads.
  for (size_t i = 0; i < kNumThreads; ++i) {
    for (size_t j = i; j < kNumThreads; ++j) {
      NodeName node_name_i = kThreadData[i]->node_name;
      NodeName node_name_j = kThreadData[j]->node_name;

      Node* node_i = kNodeData[node_name_i.value_major]->node.get();
      Node* node_j = kNodeData[node_name_j.value_major]->node.get();

      PortName port_i, port_j;
      node_i->CreatePort(&port_i);
      node_j->CreatePort(&port_j);
      node_i->InitializePort(port_i, node_name_j, port_j);
      node_j->InitializePort(port_j, node_name_i, port_i);

      if (i == j) {
        kThreadData[i]->ports[j] = port_i;
        kThreadData[i]->self_port = port_j;
      } else {
        kThreadData[i]->ports[j] = port_i;
        kThreadData[j]->ports[i] = port_j;
      }
    }
  }

  std::thread threads[kNumThreads];

  for (size_t i = 0; i < kNumThreads; ++i)
    threads[i] = std::thread(ThreadFunc, i);

  KickOffTest();

  for (size_t i = 0; i < kNumThreads; ++i)
    threads[i].join();

  for (size_t i = 0; i < kNumThreads; ++i)
    delete kThreadData[i];

  for (size_t i = 0; i < kNumNodes; ++i)
    delete kNodeData[i];
}

}  // namespace ports

<commit_msg>remove stale stress test<commit_after><|endoftext|>


<commit_before>#include "player_sys.sqf"

class playerSettings {

	idd = playersys_DIALOG;
	movingEnable = true;
	enableSimulation = true;
	onLoad = "[] execVM 'client\systems\playerMenu\item_list.sqf'";

	class controlsBackground {

		class MainBG : w_RscPicture {
			idc = -1;
			text = "client\ui\ui_background_controlers_ca.paa";
			moving = true;
			x = 0.0; y = 0.1;
			w = 1.0; h = 0.65;
		};

		class MainTitle : w_RscText {
			idc = -1;
			text = "Player Inventory Menu";
			sizeEx = 0.04;
			shadow = 2;
			x = 0.260; y = 0.112;
			w = 0.3; h = 0.05;
		};

		class moneyIcon : w_RscPicture {
	  		idc = -1;
        	text = "client\icons\money.paa";
        	x = 0.02; y = 0.32;
			w = 0.04; h = 0.04;
		};

		class waterIcon : w_RscPicture {
	  		idc = -1;
        	text = "client\icons\water.paa";
        	x = 0.015; y = 0.19;
			w = 0.05; h = 0.05;
		};

		class foodIcon : w_RscPicture {
      		idc = -1;
        	text = "client\icons\food.paa";
        	x = 0.02; y = 0.26;
			w = 0.04; h = 0.04;
		};

		class moneyText : w_RscText {
			idc = money_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.313;
			w = 0.3; h = 0.05;
		};

		class foodText : w_RscText {
			idc = food_text;
			sizeEx = 0.03;
			text = "";
			x = 0.06; y = 0.254;
			w = 0.3; h = 0.05;
		};

		class waterText : w_RscText {
			idc = water_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.193;
			w = 0.3; h = 0.05;
		};

		class distanceText : w_RscText {
			idc = view_range_text;
			text = "View range:";
			sizeEx = 0.025;
			x = 0.03; y = 0.40;
			w = 0.3; h = 0.02;
		};
	};

	class controls {

		class itemList : w_Rsclist {
			idc = item_list;
			x = 0.49; y = 0.200;
			w = 0.235; h = 0.325;
		};

		class DropButton : w_RscButton {
			text = "Drop";
			onButtonClick = "[1] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.610; y = 0.54;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class UseButton : w_RscButton {
			text = "Use";
			onButtonClick = "[0] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.48; y = 0.54;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class moneyInput: w_RscCombo {
			idc = money_value;
			x = 0.625; y = 0.605;
			w = .1; h = .030;
		};

		class DropcButton : w_RscButton {
			text = "Drop Money";
			onButtonClick = "[] execVM 'client\systems\playerMenu\dropMoney.sqf'";
			x = 0.48; y = 0.60;
			w = 0.135; h = 0.033 * safezoneH;
		};

		class CloseButton : w_RscButton {
			text = "Close";
			onButtonClick = "closeDialog 0;";
			x = 0.02; y = 0.68;
			w = 0.125; h = 0.033 * safezoneH;
			color[] = {0.95,0.1,0.1,1};
		};

		class GroupsButton : w_RscButton {
			idc = groupButton;
			text = "Group Management";
			onButtonClick = "[] execVM 'client\systems\groups\loadGroupManagement.sqf'";
			x = 0.150; y = 0.68;
			w = 0.225; h = 0.033 * safezoneH;
		};

		class btnDistanceNear : w_RscButton {
			text = "Near";
			onButtonClick = "setViewDistance 1100;";
			x = 0.02; y = 0.45;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceMedium : w_RscButton {
			text = "Medium";
			onButtonClick = "setViewDistance 2200;";
			x = 0.02; y = 0.50;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceFar : w_RscButton {
			text = "Far";
			onButtonClick = "setViewDistance 3300;";
			x = 0.02; y = 0.55;
			w = 0.125; h = 0.033 * safezoneH;
		};
		class btnDistanceInsane : w_RscButton {
			text = "Insane";
			onButtonClick = "setViewDistance 5000;";
			x = 0.02; y = 0.60;
			w = 0.125; h = 0.033 * safezoneH;
		};

	};

};<commit_msg>Fixed player menu icons scale<commit_after>#include "player_sys.sqf"

class playerSettings {

	idd = playersys_DIALOG;
	movingEnable = true;
	enableSimulation = true;
	onLoad = "[] execVM 'client\systems\playerMenu\item_list.sqf'";

	class controlsBackground {

		class MainBG : w_RscPicture {
			idc = -1;
			text = "client\ui\ui_background_controlers_ca.paa";
			moving = true;
			x = 0.0; y = 0.1;
			w = 1.0; h = 0.65;
		};

		class MainTitle : w_RscText {
			idc = -1;
			text = "Player Inventory Menu";
			sizeEx = 0.04;
			shadow = 2;
			x = 0.260; y = 0.112;
			w = 0.3; h = 0.05;
		};

		class moneyIcon : w_RscPicture {
	  		idc = -1;
        	text = "client\icons\money.paa";
        	x = 0.02; y = 0.32;
			w = 0.04 * (safezoneH/safezoneW); h = 0.04;
		};

		class waterIcon : w_RscPicture {
	  		idc = -1;
        	text = "client\icons\water.paa";
        	x = 0.015; y = 0.19;
			w = 0.05 * (safezoneH/safezoneW); h = 0.05;
		};

		class foodIcon : w_RscPicture {
      		idc = -1;
        	text = "client\icons\food.paa";
        	x = 0.02; y = 0.26;
			w = 0.04 * (safezoneH/safezoneW); h = 0.04;
		};

		class moneyText : w_RscText {
			idc = money_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.313;
			w = 0.3; h = 0.05;
		};

		class foodText : w_RscText {
			idc = food_text;
			sizeEx = 0.03;
			text = "";
			x = 0.06; y = 0.254;
			w = 0.3; h = 0.05;
		};

		class waterText : w_RscText {
			idc = water_text;
			text = "";
			sizeEx = 0.03;
			x = 0.06; y = 0.193;
			w = 0.3; h = 0.05;
		};

		class distanceText : w_RscText {
			idc = view_range_text;
			text = "View range:";
			sizeEx = 0.025;
			x = 0.03; y = 0.40;
			w = 0.3; h = 0.02;
		};
	};

	class controls {

		class itemList : w_Rsclist {
			idc = item_list;
			x = 0.49; y = 0.200;
			w = 0.235; h = 0.325;
		};

		class DropButton : w_RscButton {
			text = "Drop";
			onButtonClick = "[1] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.610; y = 0.54;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class UseButton : w_RscButton {
			text = "Use";
			onButtonClick = "[0] execVM 'client\systems\playerMenu\itemfnc.sqf'";
			x = 0.48; y = 0.54;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class moneyInput: w_RscCombo {
			idc = money_value;
			x = 0.625; y = 0.605;
			w = .1; h = .030;
		};

		class DropcButton : w_RscButton {
			text = "Drop Money";
			onButtonClick = "[] execVM 'client\systems\playerMenu\dropMoney.sqf'";
			x = 0.48; y = 0.60;
			w = 0.135; h = 0.033 * safezoneH;
		};

		class CloseButton : w_RscButton {
			text = "Close";
			onButtonClick = "closeDialog 0;";
			x = 0.02; y = 0.68;
			w = 0.125; h = 0.033 * safezoneH;
			color[] = {0.95,0.1,0.1,1};
		};

		class GroupsButton : w_RscButton {
			idc = groupButton;
			text = "Group Management";
			onButtonClick = "[] execVM 'client\systems\groups\loadGroupManagement.sqf'";
			x = 0.150; y = 0.68;
			w = 0.225; h = 0.033 * safezoneH;
		};

		class btnDistanceNear : w_RscButton {
			text = "Near";
			onButtonClick = "setViewDistance 1100;";
			x = 0.02; y = 0.45;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceMedium : w_RscButton {
			text = "Medium";
			onButtonClick = "setViewDistance 2200;";
			x = 0.02; y = 0.50;
			w = 0.125; h = 0.033 * safezoneH;
		};

		class btnDistanceFar : w_RscButton {
			text = "Far";
			onButtonClick = "setViewDistance 3300;";
			x = 0.02; y = 0.55;
			w = 0.125; h = 0.033 * safezoneH;
		};
		class btnDistanceInsane : w_RscButton {
			text = "Insane";
			onButtonClick = "setViewDistance 5000;";
			x = 0.02; y = 0.60;
			w = 0.125; h = 0.033 * safezoneH;
		};

	};

};<|endoftext|>


<commit_before>/*
 * Copyright (C) 2016 Muhammad Tayyab Akram
 *
 * 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.
 */

extern "C" {
#include <SBBase.h>
#include <SBParagraph.h>
}

#include <jni.h>

#include "JavaBridge.h"
#include "BidiParagraph.h"

using namespace Tehreer;

static void dispose(JNIEnv *env, jobject obj, jlong paragraphHandle)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBParagraphRelease(bidiParagraph);
}

static jint getCharStart(JNIEnv *env, jobject obj, jlong paragraphHandle)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBUInteger paragraphOffset = SBParagraphGetOffset(bidiParagraph);

    return static_cast<jint>(paragraphOffset);
}

static jint getCharEnd(JNIEnv *env, jobject obj, jlong paragraphHandle)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBUInteger paragraphOffset = SBParagraphGetOffset(bidiParagraph);
    SBUInteger paragraphLength = SBParagraphGetLength(bidiParagraph);

    return static_cast<jint>(paragraphOffset + paragraphLength);
}

static jbyte getBaseLevel(JNIEnv *env, jobject obj, jlong paragraphHandle)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBLevel baseLevel = SBParagraphGetBaseLevel(bidiParagraph);

    return static_cast<jbyte>(baseLevel);
}

static jbyte getLevel(JNIEnv *env, jobject obj, jlong paragraphHandle, jint levelIndex)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    const SBLevel *levelsPtr = SBParagraphGetLevelsPtr(bidiParagraph);

    return static_cast<jbyte>(levelsPtr[levelIndex]);
}

static jobject getRun(JNIEnv *env, jobject obj, jlong paragraphHandle, jint levelIndex)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBUInteger paragraphLength = SBParagraphGetLength(bidiParagraph);

    if (levelIndex < paragraphLength) {
        const SBLevel *levelsPtr = SBParagraphGetLevelsPtr(bidiParagraph);
        SBLevel currentLevel = levelsPtr[levelIndex];
        SBUInteger nextIndex = static_cast<SBUInteger>(levelIndex);

        while (++nextIndex < paragraphLength) {
            if (levelsPtr[nextIndex] != currentLevel) {
                break;
            }
        }

        SBUInteger paragraphOffset = SBParagraphGetOffset(bidiParagraph);
        jint charStart = static_cast<jint>(levelIndex + paragraphOffset);
        jint charEnd = static_cast<jint>(nextIndex + paragraphOffset);
        jbyte embeddingLevel = static_cast<jbyte>(currentLevel);

        return JavaBridge(env).BidiRun_construct(charStart, charEnd, embeddingLevel);
    }

    return nullptr;
}

static jlong createLine(JNIEnv *env, jobject obj, jlong paragraphHandle, jint charStart, jint charEnd)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBUInteger lineOffset = static_cast<SBUInteger>(charStart);
    SBUInteger lineLength = static_cast<SBUInteger>(charEnd - charStart);

    SBLineRef bidiLine = SBParagraphCreateLine(bidiParagraph, lineOffset, lineLength);
    return reinterpret_cast<jlong>(bidiLine);
}

static JNINativeMethod JNI_METHODS[] = {
    { "nativeDispose", "(J)V", (void *)dispose },
    { "nativeGetCharStart", "(J)I", (void *)getCharStart },
    { "nativeGetCharEnd", "(J)I", (void *)getCharEnd },
    { "nativeGetBaseLevel", "(J)B", (void *)getBaseLevel },
    { "nativeGetLevel", "(JI)B", (void *)getLevel },
    { "nativeGetRun", "(JI)Lcom/mta/tehreer/bidi/BidiRun;", (void *)getRun },
    { "nativeCreateLine", "(JII)J", (void *)createLine },
};

jint register_com_mta_tehreer_bidi_BidiParagraph(JNIEnv *env) {
    return JavaBridge::registerClass(env, "com/mta/tehreer/bidi/BidiParagraph", JNI_METHODS, sizeof(JNI_METHODS) / sizeof(JNI_METHODS[0]));
}
<commit_msg>[jni] Implemented bidi paragraph updates...<commit_after>/*
 * Copyright (C) 2017 Muhammad Tayyab Akram
 *
 * 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.
 */

extern "C" {
#include <SBBase.h>
#include <SBParagraph.h>
}

#include <jni.h>

#include "JavaBridge.h"
#include "BidiParagraph.h"

using namespace Tehreer;

static void dispose(JNIEnv *env, jobject obj, jlong paragraphHandle)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBParagraphRelease(bidiParagraph);
}

static jint getCharStart(JNIEnv *env, jobject obj, jlong paragraphHandle)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBUInteger paragraphOffset = SBParagraphGetOffset(bidiParagraph);

    return static_cast<jint>(paragraphOffset);
}

static jint getCharEnd(JNIEnv *env, jobject obj, jlong paragraphHandle)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBUInteger paragraphOffset = SBParagraphGetOffset(bidiParagraph);
    SBUInteger paragraphLength = SBParagraphGetLength(bidiParagraph);

    return static_cast<jint>(paragraphOffset + paragraphLength);
}

static jint getCharCount(JNIEnv *env, jobject obj, jlong paragraphHandle)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBUInteger paragraphLength = SBParagraphGetLength(bidiParagraph);

    return static_cast<jint>(paragraphLength);
}

static jbyte getBaseLevel(JNIEnv *env, jobject obj, jlong paragraphHandle)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBLevel baseLevel = SBParagraphGetBaseLevel(bidiParagraph);

    return static_cast<jbyte>(baseLevel);
}

static jlong getLevelsPtr(JNIEnv *env, jobject obj, jlong paragraphHandle)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    const SBLevel *levelsPtr = SBParagraphGetLevelsPtr(bidiParagraph);

    return reinterpret_cast<jlong>(levelsPtr);
}

static jobject getOnwardRun(JNIEnv *env, jobject obj, jlong paragraphHandle, jint charIndex)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBUInteger paragraphOffset = SBParagraphGetOffset(bidiParagraph);
    SBUInteger paragraphLength = SBParagraphGetLength(bidiParagraph);

    jint levelIndex = static_cast<jint>(charIndex - paragraphOffset);
    if (levelIndex < paragraphLength) {
        const SBLevel *levelsPtr = SBParagraphGetLevelsPtr(bidiParagraph);
        SBLevel currentLevel = levelsPtr[levelIndex];
        SBUInteger nextIndex = static_cast<SBUInteger>(levelIndex);

        while (++nextIndex < paragraphLength) {
            if (levelsPtr[nextIndex] != currentLevel) {
                break;
            }
        }

        jint charStart = static_cast<jint>(levelIndex + paragraphOffset);
        jint charEnd = static_cast<jint>(nextIndex + paragraphOffset);
        jbyte embeddingLevel = static_cast<jbyte>(currentLevel);

        return JavaBridge(env).BidiRun_construct(charStart, charEnd, embeddingLevel);
    }

    return nullptr;
}

static jlong createLine(JNIEnv *env, jobject obj, jlong paragraphHandle, jint charStart, jint charEnd)
{
    SBParagraphRef bidiParagraph = reinterpret_cast<SBParagraphRef>(paragraphHandle);
    SBUInteger lineOffset = static_cast<SBUInteger>(charStart);
    SBUInteger lineLength = static_cast<SBUInteger>(charEnd - charStart);

    SBLineRef bidiLine = SBParagraphCreateLine(bidiParagraph, lineOffset, lineLength);
    return reinterpret_cast<jlong>(bidiLine);
}

static JNINativeMethod JNI_METHODS[] = {
    { "nativeDispose", "(J)V", (void *)dispose },
    { "nativeGetCharStart", "(J)I", (void *)getCharStart },
    { "nativeGetCharEnd", "(J)I", (void *)getCharEnd },
    { "nativeGetCharCount", "(J)I", (void *)getCharCount },
    { "nativeGetBaseLevel", "(J)B", (void *)getBaseLevel },
    { "nativeGetLevelsPtr", "(J)J", (void *)getLevelsPtr },
    { "nativeGetOnwardRun", "(JI)Lcom/mta/tehreer/bidi/BidiRun;", (void *)getOnwardRun },
    { "nativeCreateLine", "(JII)J", (void *)createLine },
};

jint register_com_mta_tehreer_bidi_BidiParagraph(JNIEnv *env) {
    return JavaBridge::registerClass(env, "com/mta/tehreer/bidi/BidiParagraph", JNI_METHODS, sizeof(JNI_METHODS) / sizeof(JNI_METHODS[0]));
}
<|endoftext|>


<commit_before>#include <PMath/Vector2.hpp>

using namespace pmath;

int main()
{
	Vec2 vec;

	vec.x = 5;
	vec.y = 10;

	return 0;
}<commit_msg>Initial tests<commit_after>#include <PMath/Vector2.hpp>

#include <iostream>

using namespace pmath;

int main()
{
	Vec2 vec1, vec2;

	vec1.x = 5;
	vec1.y = 10;

	vec2.x = 10;
	vec2.y = 5;

	Vec2 vec3 = vec1 - vec2;

	// Stop the program
	std::cout << "Press any key to continue..." << std::endl;
	std::cin.get();

	return 0;
}<|endoftext|>