<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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.
 *
 ***************************************************************/

/************************************************************************
**
**	Set up the various dprintf variables based on the configuration file.
**
************************************************************************/
#define _FILE_OFFSET_BITS 64
#include "condor_common.h"
#include "condor_debug.h"
#include "condor_string.h"
#include "condor_sys_types.h"

#if HAVE_BACKTRACE
#include "sig_install.h"
#endif

int		Termlog = 0;

extern int		DebugFlags;
extern FILE		*DebugFPs[D_NUMLEVELS+1];
extern off_t		MaxLog[D_NUMLEVELS+1];
extern int 			MaxLogNum[D_NUMLEVELS+1];
extern char		*DebugFile[D_NUMLEVELS+1];
extern char		*DebugLock;
extern const char		*_condor_DebugFlagNames[];
extern int		_condor_dprintf_works;
extern time_t	DebugLastMod;
extern int		DebugUseTimestamps;
extern int      DebugContinueOnOpenFailure;
extern int		log_keep_open;

extern void		_condor_set_debug_flags( const char *strflags );
extern void		_condor_dprintf_saved_lines( void );

#if HAVE_EXT_GCB
void	_condor_gcb_dprintf_va( int flags, char* fmt, va_list args );
extern "C" void Generic_set_log_va(void(*app_log_va)(int level, char *fmt, va_list args));
#endif

#if HAVE_BACKTRACE
static void
sig_backtrace_handler(int signum)
{
	dprintf_dump_stack();

		// terminate for the same reason.
	struct sigaction sa;
	sa.sa_handler = SIG_DFL;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sigaction(signum, &sa, NULL);
	sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);

	raise(signum);
}

static void
install_backtrace_handler(void)
{
	sigset_t fullset;
	sigfillset( &fullset );
	install_sig_handler_with_mask(SIGSEGV, &fullset, sig_backtrace_handler);
	install_sig_handler_with_mask(SIGABRT, &fullset, sig_backtrace_handler);
	install_sig_handler_with_mask(SIGILL, &fullset, sig_backtrace_handler);
	install_sig_handler_with_mask(SIGFPE, &fullset, sig_backtrace_handler);
	install_sig_handler_with_mask(SIGBUS, &fullset, sig_backtrace_handler);
}
#endif

int
dprintf_config_ContinueOnFailure ( int fContinue )
{
    int fOld = DebugContinueOnOpenFailure;
	DebugContinueOnOpenFailure = fContinue;
	return fOld;
}

void
dprintf_config( const char *subsys )
{
	char pname[ BUFSIZ ];
	char *pval;
	static int first_time = 1;
	int want_truncate;
	int debug_level;
	FILE *debug_file_fp;
	int log_open_default = TRUE;

	/*
	**  We want to initialize this here so if we reconfig and the
	**	debug flags have changed, we actually use the new
	**  flags.  -Derek Wright 12/8/97
	*/
	DebugFlags = D_ALWAYS;

	/*
	** First, add the debug flags that are shared by everyone.
	*/
	pval = param("ALL_DEBUG");
	if( pval ) {
		_condor_set_debug_flags( pval );
		free( pval );
	}

	/*
	**  Then, pick up the subsys_DEBUG parameters.   Note: if we don't have
	**  anything set, we just leave it as D_ALWAYS.
	*/
	(void)sprintf(pname, "%s_DEBUG", subsys);
	pval = param(pname);
	if( pval ) {
		_condor_set_debug_flags( pval );
		free( pval );
	}

#ifdef WIN32
		/* Two reasons why we need to lock the log in Windows
		 * (when a lock is configured)
		 * 1) File rotation requires exclusive access in Windows.
		 * 2) O_APPEND doesn't guarantee atomic writes in Windows
		 */
	DebugShouldLockToAppend = 1;
#else
	DebugShouldLockToAppend = param_boolean_int("LOCK_DEBUG_LOG_TO_APPEND",0);
#endif

	/*
	**	If this is not going to the terminal, pick up the name
	**	of the log file, maximum log size, and the name of the
	**	lock file (if it is specified).
	*/
	if( !( Termlog) ) {
		for (debug_level = 0; debug_level <= D_NUMLEVELS; debug_level++) {
			want_truncate = 0;
			if (debug_level == 0) {
				/*
				** the level 0 file gets all debug messages; thus, the
				** offset into DebugFlagNames is off by one, since the
				** first level-specific file goes into the other arrays at
				** index 1
				*/
				(void)sprintf(pname, "%s_LOG", subsys);
			} else {
				(void)sprintf(pname, "%s_%s_LOG", subsys,
							  _condor_DebugFlagNames[debug_level-1]+2);
			}

			// Hold a temporary copy of the old file pointer until
			// *after* the param -- param can dprintf() in some cases
			{
				char	*tmp = DebugFile[debug_level];

				// NEGOTIATOR_MATCH_LOG is necessary by default, but debug_level
				// is not 0
				if(debug_level == 0)
				{
					char	*tmp2 = param(pname);

					// No default value found, so use $(LOG)/$(SUBSYSTEM)Log
					if(!tmp2) {
						// This char* will never be freed, but as long as
						// defaults are defined in condor_c++_util/param_info.in
						// we will never get here.
						char *str;
						char *log = param("LOG");
						char *lsubsys = param("SUBSYSTEM");
						if(!log || !lsubsys) {
							EXCEPT("Unable to find LOG or SUBSYSTEM.\n");
						}

						str = (char*)malloc(strlen(log) + strlen(lsubsys) + 5);
						sprintf(str, "%s%c%sLog", log, DIR_DELIM_CHAR, lsubsys);

						DebugFile[debug_level] = str;

						free(log);
						free(lsubsys);
					}
					else {
						DebugFile[debug_level] = tmp2;
					}
				}
				else {
					// This is looking up configuration options that I can't
					// find documentation for, so intead of coding in an
					// incorrect default value, I'm gonna use
					// param_without_default.
					// tristan 5/29/09
					DebugFile[debug_level] = param_without_default(pname);
				}
				if ( tmp ) {
					free( tmp );
				}
			}

			if( debug_level == 0 && DebugFile[0] == NULL ) {
				EXCEPT("No '%s' parameter specified.", pname);
			} else if ( DebugFile[debug_level] != NULL ) {

				if (debug_level == 0 && first_time) {
					struct stat stat_buf;
					if ( stat( DebugFile[debug_level], &stat_buf ) >= 0 ) {
						DebugLastMod = stat_buf.st_mtime > stat_buf.st_ctime ? stat_buf.st_mtime : stat_buf.st_ctime;
					} else {
						DebugLastMod = -errno;
					}
				}

				if (debug_level == 0) {
					(void)sprintf(pname, "TRUNC_%s_LOG_ON_OPEN", subsys);
				} else {
					(void)sprintf(pname, "TRUNC_%s_%s_LOG_ON_OPEN", subsys,
								  _condor_DebugFlagNames[debug_level-1]+2);
				}
				pval = param(pname);
				if( pval ) {
					if( *pval == 't' || *pval == 'T' ) {
						want_truncate = 1;
					}
					free(pval);
				}

				if (debug_level == 0) {
					(void)sprintf(pname, "%s_LOCK", subsys);
					if (DebugLock) {
						free(DebugLock);
					}
					DebugLock = param(pname);
				}

				if( first_time && want_truncate ) {
					debug_file_fp = debug_lock(debug_level, "w", 0);
				} else {
					debug_file_fp = debug_lock(debug_level, "a", 0);
				}

				if( debug_file_fp == NULL && debug_level == 0 ) {
                   #ifdef WIN32
					/*
					** If we could not open the log file, we might want to keep running anyway.
					** If we do, then set the log filename to NUL so we don't keep trying
					** (and failing) to open the file.
					*/
					if (DebugContinueOnOpenFailure) {

						// change the debug file to point to the NUL device.
						static const char strDevNull[] = "NUL";//"\\\\.\\Device\\Null";
						char * psz = (char*)malloc(sizeof(strDevNull));
						strcpy(psz, strDevNull);
						if (DebugFile[debug_level])
							free(DebugFile[debug_level]);
						DebugFile[debug_level] = psz;

					} else
                   #endif
					{
					    EXCEPT("Cannot open log file '%s'",
						       DebugFile[debug_level]);
					}
				}

				if (debug_file_fp) (void)debug_unlock( debug_level );
				debug_file_fp = NULL;

				if (debug_level == 0) {
					(void)sprintf(pname, "MAX_%s_LOG", subsys);
				} else {
					(void)sprintf(pname, "MAX_%s_%s_LOG", subsys,
								  _condor_DebugFlagNames[debug_level-1]+2);
				}
				MaxLog[debug_level] = param_integer(pname, 1024*1024);

				if (debug_level == 0) {
					(void)sprintf(pname, "MAX_NUM_%s_LOG", subsys);
				} else {
					(void)sprintf(pname, "MAX_NUM_%s_%s_LOG", subsys,
								  _condor_DebugFlagNames[debug_level-1]+2);
				}
				MaxLogNum[debug_level] = param_integer(pname, 1);
			}
		}
	} else {

#if !defined(WIN32)
		setlinebuf( stderr );
#endif

		(void)fflush( stderr );	/* Don't know why we need this, but if not here
							   the first couple dprintf don't come out right */
	}

#ifndef WIN32
	if((strcmp(subsys, "SHADOW") == 0) || (strcmp(subsys, "GRIDMANAGER") == 0))
	{
		log_open_default = FALSE;
	}
#endif

	if(!DebugLock) {
		sprintf(pname, "%s_LOG_KEEP_OPEN", subsys);
		log_keep_open = param_boolean_int(pname, log_open_default);
	}

	first_time = 0;
	_condor_dprintf_works = 1;
#if HAVE_EXT_GCB
		/*
		  this method currently only lives in libGCB.a, so don't even
		  try to param() or call this function unless we're on a
		  platform where we're using the GCB external
		*/
    if ( param_boolean_int("NET_REMAP_ENABLE", 0) ) {
        Generic_set_log_va(_condor_gcb_dprintf_va);
    }
#endif

		/*
		  If LOGS_USE_TIMESTAMP is enabled, we will print out Unix timestamps
		  instead of the standard date format in all the log messages
		*/
	DebugUseTimestamps = param_boolean_int( "LOGS_USE_TIMESTAMP", FALSE );

#if HAVE_BACKTRACE
	install_backtrace_handler();
#endif

	_condor_dprintf_saved_lines();
}

#if HAVE_EXT_GCB
void
_condor_gcb_dprintf_va( int flags, char* fmt, va_list args )
{
	char* new_fmt;
	int len;

	len = strlen(fmt);
	new_fmt = (char*) malloc( (len + 6) * sizeof(char) );
	if( ! new_fmt ) {
		EXCEPT( "_condor_gcb_dprintf_va() out of memory!" );
	}
	snprintf( new_fmt, len + 6, "GCB: %s", fmt );
	_condor_dprintf_va( flags, new_fmt, args );
	free( new_fmt );
}
#endif /* HAVE_EXT_GCB */
<commit_msg>Handled by eje, pending review of #2471<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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.
 *
 ***************************************************************/

/************************************************************************
**
**	Set up the various dprintf variables based on the configuration file.
**
************************************************************************/
#define _FILE_OFFSET_BITS 64
#include "condor_common.h"
#include "condor_debug.h"
#include "condor_string.h"
#include "condor_sys_types.h"

#if HAVE_BACKTRACE
#include "sig_install.h"
#endif

int		Termlog = 0;

extern int		DebugFlags;
extern FILE		*DebugFPs[D_NUMLEVELS+1];
extern off_t		MaxLog[D_NUMLEVELS+1];
extern int 			MaxLogNum[D_NUMLEVELS+1];
extern char		*DebugFile[D_NUMLEVELS+1];
extern char		*DebugLock;
extern const char		*_condor_DebugFlagNames[];
extern int		_condor_dprintf_works;
extern time_t	DebugLastMod;
extern int		DebugUseTimestamps;
extern int      DebugContinueOnOpenFailure;
extern int		log_keep_open;

extern void		_condor_set_debug_flags( const char *strflags );
extern void		_condor_dprintf_saved_lines( void );

#if HAVE_EXT_GCB
void	_condor_gcb_dprintf_va( int flags, char* fmt, va_list args );
extern "C" void Generic_set_log_va(void(*app_log_va)(int level, char *fmt, va_list args));
#endif

#if HAVE_BACKTRACE
static void
sig_backtrace_handler(int signum)
{
	dprintf_dump_stack();

		// terminate for the same reason.
	struct sigaction sa;
	sa.sa_handler = SIG_DFL;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sigaction(signum, &sa, NULL);
	sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);

	raise(signum);
}

static void
install_backtrace_handler(void)
{
	sigset_t fullset;
	sigfillset( &fullset );
	install_sig_handler_with_mask(SIGSEGV, &fullset, sig_backtrace_handler);
	install_sig_handler_with_mask(SIGABRT, &fullset, sig_backtrace_handler);
	install_sig_handler_with_mask(SIGILL, &fullset, sig_backtrace_handler);
	install_sig_handler_with_mask(SIGFPE, &fullset, sig_backtrace_handler);
	install_sig_handler_with_mask(SIGBUS, &fullset, sig_backtrace_handler);
}
#endif

int
dprintf_config_ContinueOnFailure ( int fContinue )
{
    int fOld = DebugContinueOnOpenFailure;
	DebugContinueOnOpenFailure = fContinue;
	return fOld;
}

void
dprintf_config( const char *subsys )
{
	char pname[ BUFSIZ ];
	char *pval;
	static int first_time = 1;
	int want_truncate;
	int debug_level;
	FILE *debug_file_fp;
	int log_open_default = TRUE;

	/*
	**  We want to initialize this here so if we reconfig and the
	**	debug flags have changed, we actually use the new
	**  flags.  -Derek Wright 12/8/97
	*/
	DebugFlags = D_ALWAYS;

	/*
	** First, add the debug flags that are shared by everyone.
	*/
	pval = param("ALL_DEBUG");
	if( pval ) {
		_condor_set_debug_flags( pval );
		free( pval );
	}

	/*
	**  Then, pick up the subsys_DEBUG parameters.   Note: if we don't have
	**  anything set, we just leave it as D_ALWAYS.
	*/
	(void)sprintf(pname, "%s_DEBUG", subsys);
	pval = param(pname);
	if( pval ) {
		_condor_set_debug_flags( pval );
		free( pval );
	}

#ifdef WIN32
		/* Two reasons why we need to lock the log in Windows
		 * (when a lock is configured)
		 * 1) File rotation requires exclusive access in Windows.
		 * 2) O_APPEND doesn't guarantee atomic writes in Windows
		 */
	DebugShouldLockToAppend = 1;
#else
	DebugShouldLockToAppend = param_boolean_int("LOCK_DEBUG_LOG_TO_APPEND",0);
#endif

	/*
	**	If this is not going to the terminal, pick up the name
	**	of the log file, maximum log size, and the name of the
	**	lock file (if it is specified).
	*/
	if( !( Termlog) ) {
		for (debug_level = 0; debug_level <= D_NUMLEVELS; debug_level++) {
			want_truncate = 0;
			if (debug_level == 0) {
				/*
				** the level 0 file gets all debug messages; thus, the
				** offset into DebugFlagNames is off by one, since the
				** first level-specific file goes into the other arrays at
				** index 1
				*/
				(void)sprintf(pname, "%s_LOG", subsys);
			} else {
				(void)sprintf(pname, "%s_%s_LOG", subsys,
							  _condor_DebugFlagNames[debug_level-1]+2);
			}

			// Hold a temporary copy of the old file pointer until
			// *after* the param -- param can dprintf() in some cases
			{
				char	*tmp = DebugFile[debug_level];

				// NEGOTIATOR_MATCH_LOG is necessary by default, but debug_level
				// is not 0
				if(debug_level == 0)
				{
					char	*tmp2 = param(pname);

					// No default value found, so use $(LOG)/$(SUBSYSTEM)Log
					if(!tmp2) {
						// This char* will never be freed, but as long as
						// defaults are defined in condor_c++_util/param_info.in
						// we will never get here.
						char *str;
						char *log = param("LOG");
						char *lsubsys = param("SUBSYSTEM");
						if(!log || !lsubsys) {
							EXCEPT("Unable to find LOG or SUBSYSTEM.\n");
						}

						str = (char*)malloc(strlen(log) + strlen(lsubsys) + 5);
						sprintf(str, "%s%c%sLog", log, DIR_DELIM_CHAR, lsubsys);

						DebugFile[debug_level] = str;

						free(log);
						free(lsubsys);
					}
					else {
						DebugFile[debug_level] = tmp2;
					}
				}
				else {
					// This is looking up configuration options that I can't
					// find documentation for, so intead of coding in an
					// incorrect default value, I'm gonna use
					// param_without_default.
					// tristan 5/29/09
					DebugFile[debug_level] = param_without_default(pname);
				}
				if ( tmp ) {
					free( tmp );
				}
			}

			if( debug_level == 0 && DebugFile[0] == NULL ) {
				EXCEPT("No '%s' parameter specified.", pname);
			} else if ( DebugFile[debug_level] != NULL ) {

				if (debug_level == 0 && first_time) {
					struct stat stat_buf;
					if ( stat( DebugFile[debug_level], &stat_buf ) >= 0 ) {
						DebugLastMod = stat_buf.st_mtime > stat_buf.st_ctime ? stat_buf.st_mtime : stat_buf.st_ctime;
					} else {
						DebugLastMod = -errno;
					}
				}

				if (debug_level == 0) {
					(void)sprintf(pname, "TRUNC_%s_LOG_ON_OPEN", subsys);
				} else {
					(void)sprintf(pname, "TRUNC_%s_%s_LOG_ON_OPEN", subsys,
								  _condor_DebugFlagNames[debug_level-1]+2);
				}
				pval = param(pname);
				if( pval ) {
					if( *pval == 't' || *pval == 'T' ) {
						want_truncate = 1;
					}
					free(pval);
				}

				if (debug_level == 0) {
					(void)sprintf(pname, "%s_LOCK", subsys);
					if (DebugLock) {
						free(DebugLock);
					}
					DebugLock = param(pname);
				}

				if( first_time && want_truncate ) {
					debug_file_fp = debug_lock(debug_level, "w", 0);
				} else {
					debug_file_fp = debug_lock(debug_level, "a", 0);
				}

				if( debug_file_fp == NULL && debug_level == 0 ) {
                   #ifdef WIN32
					/*
					** If we could not open the log file, we might want to keep running anyway.
					** If we do, then set the log filename to NUL so we don't keep trying
					** (and failing) to open the file.
					*/
					if (DebugContinueOnOpenFailure) {

						// change the debug file to point to the NUL device.
						static const char strDevNull[] = "NUL";//"\\\\.\\Device\\Null";
						char * psz = (char*)malloc(sizeof(strDevNull));
						strcpy(psz, strDevNull);
						if (DebugFile[debug_level])
							free(DebugFile[debug_level]);
						DebugFile[debug_level] = psz;

					} else
                   #endif
					{
					    EXCEPT("Cannot open log file '%s'",
						       DebugFile[debug_level]);
					}
				}

				if (debug_file_fp) (void)debug_unlock( debug_level );
				debug_file_fp = NULL;

				if (debug_level == 0) {
					(void)sprintf(pname, "MAX_%s_LOG", subsys);
				} else {
					(void)sprintf(pname, "MAX_%s_%s_LOG", subsys,
								  _condor_DebugFlagNames[debug_level-1]+2);
				}
				pval = param(pname);
				if( pval != NULL ) {
					MaxLog[debug_level] = atoi( pval );
					free(pval);
				} else {
					MaxLog[debug_level] = 1024*1024;
				}

				if (debug_level == 0) {
					(void)sprintf(pname, "MAX_NUM_%s_LOG", subsys);
				} else {
					(void)sprintf(pname, "MAX_NUM_%s_%s_LOG", subsys,
								  _condor_DebugFlagNames[debug_level-1]+2);
				}
				MaxLogNum[debug_level] = param_integer(pname, 1);
			}
		}
	} else {

#if !defined(WIN32)
		setlinebuf( stderr );
#endif

		(void)fflush( stderr );	/* Don't know why we need this, but if not here
							   the first couple dprintf don't come out right */
	}

#ifndef WIN32
	if((strcmp(subsys, "SHADOW") == 0) || (strcmp(subsys, "GRIDMANAGER") == 0))
	{
		log_open_default = FALSE;
	}
#endif

	if(!DebugLock) {
		sprintf(pname, "%s_LOG_KEEP_OPEN", subsys);
		log_keep_open = param_boolean_int(pname, log_open_default);
	}

	first_time = 0;
	_condor_dprintf_works = 1;
#if HAVE_EXT_GCB
		/*
		  this method currently only lives in libGCB.a, so don't even
		  try to param() or call this function unless we're on a
		  platform where we're using the GCB external
		*/
    if ( param_boolean_int("NET_REMAP_ENABLE", 0) ) {
        Generic_set_log_va(_condor_gcb_dprintf_va);
    }
#endif

		/*
		  If LOGS_USE_TIMESTAMP is enabled, we will print out Unix timestamps
		  instead of the standard date format in all the log messages
		*/
	DebugUseTimestamps = param_boolean_int( "LOGS_USE_TIMESTAMP", FALSE );

#if HAVE_BACKTRACE
	install_backtrace_handler();
#endif

	_condor_dprintf_saved_lines();
}

#if HAVE_EXT_GCB
void
_condor_gcb_dprintf_va( int flags, char* fmt, va_list args )
{
	char* new_fmt;
	int len;

	len = strlen(fmt);
	new_fmt = (char*) malloc( (len + 6) * sizeof(char) );
	if( ! new_fmt ) {
		EXCEPT( "_condor_gcb_dprintf_va() out of memory!" );
	}
	snprintf( new_fmt, len + 6, "GCB: %s", fmt );
	_condor_dprintf_va( flags, new_fmt, args );
	free( new_fmt );
}
#endif /* HAVE_EXT_GCB */
<|endoftext|>


<commit_before>/*********************************************************************
** Author: Zach Colbert
** Date: 22 November 2017
** Description: The T3Reader class interacts with the Board class to
"play" a game of tic-tac-toe based on a set of instructions read from
a text file. It features a simple constructor and a member function to
feed the input file to.
*********************************************************************/

#include "T3Reader.hpp"
#include <fstream>
#include <string>
#include <iostream>

using std::string;
using std::cout;
using std::endl;

// The constructor takes a char argument to indicate which "player"
// will go first in the game
T3Reader::T3Reader(char firstTurn)
{
    nextTurn = firstTurn;
}

/*********************************************************************
** Description: readGameFile takes a string argument for the name of
the input file. It reads the text file line by line, passing
instructions to the makeMove function of the Board class.
It checks the state of the game after each move, returning false if
the instructions continue beyond the end of the game. It also returns
false when it encounters an illegal move.
After each move, it toggles the game piece that is placed in the
succeeding turn.
*********************************************************************/
bool T3Reader::readGameFile(string fileName)
{
    // Initialize variables to store the coords and results for each move
    int xCoord, yCoord;
    int breakReturn = 0;
    bool moveResult;

    // Open the input file
    std::ifstream inFile(fileName);

    // Loop until the end of the file
    while (inFile >> xCoord >> yCoord)
    {
        // If the game is finished, return false
        if (gameBoard.gameState() != 3)
        {
            // Make sure to close the file!
            inFile.close();
            breakReturn = 1;
            break;
        }

        // Otherwise, record the result of each move
        moveResult = gameBoard.makeMove(xCoord, yCoord, nextTurn);

        // Return false if the move failed
        if (moveResult == false)
        {
            // Make sure to close the file!
            inFile.close();
            breakReturn = 1;
            break;
        }

        // Toggle the next player
        if (nextTurn == 'x')
        {
            nextTurn = 'o';
        }
        else
        {
            nextTurn = 'x';
        }
    }

    // Return false for the things that break the while loop
    if (breakReturn == 1)
    {
        return false;
    }
    else
    {
        // If you got this far, it worked! Close the file and return true.
        inFile.close();
        return true;
    }
}
<commit_msg>Fixed a flip error<commit_after>/*********************************************************************
** Author: Zach Colbert
** Date: 22 November 2017
** Description: The T3Reader class interacts with the Board class to
"play" a game of tic-tac-toe based on a set of instructions read from
a text file. It features a simple constructor and a member function to
feed the input file to.
*********************************************************************/

#include "T3Reader.hpp"
#include <fstream>
#include <string>
#include <iostream>

using std::string;
using std::cout;
using std::endl;

// The constructor takes a char argument to indicate which "player"
// will go first in the game
T3Reader::T3Reader(char firstTurn)
{
    nextTurn = firstTurn;
}

/*********************************************************************
** Description: readGameFile takes a string argument for the name of
the input file. It reads the text file line by line, passing
instructions to the makeMove function of the Board class.
It checks the state of the game after each move, returning false if
the instructions continue beyond the end of the game. It also returns
false when it encounters an illegal move.
After each move, it toggles the game piece that is placed in the
succeeding turn.
*********************************************************************/
bool T3Reader::readGameFile(string fileName)
{
    // Initialize variables to store the coords and results for each move
    int xCoord, yCoord;
    int breakReturn = 0;
    bool moveResult;

    // Open the input file
    std::ifstream inFile;
    inFile.open(fileName);

    // Loop until the end of the file
    while (inFile >> xCoord >> yCoord)
    {
        // If the game is finished, return false
        if (gameBoard.gameState() != 3)
        {
            // Make sure to close the file!
            inFile.close();
            breakReturn = 1;
            break;
        }

        // Otherwise, record the result of each move
        moveResult = gameBoard.makeMove(xCoord, yCoord, nextTurn);

        // Return false if the move failed
        if (moveResult == false)
        {
            // Make sure to close the file!
            inFile.close();
            breakReturn = 1;
            break;
        }

        // Toggle the next player
        if (nextTurn == 'x')
        {
            nextTurn = 'o';
        }
        else
        {
            nextTurn = 'x';
        }
    }

    // Return false for the things that break the while loop
    if (breakReturn == 1)
    {
        return false;
    }
    else
    {
        // If you got this far, it worked! Close the file and return true.
        inFile.close();
        return true;
    }
}
<|endoftext|>


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

#ifndef _DBACORE_RESULTCOLUMN_HXX_
#define _DBACORE_RESULTCOLUMN_HXX_

#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATA_HDL_
#include <com/sun/star/sdbc/XResultSetMetaData.hdl>
#endif
#ifndef _DBA_COREAPI_COLUMN_HXX_
#include <column.hxx>
#endif
namespace dbaccess
{
    //************************************************************
    //  OResultColumn
    //************************************************************
    class OResultColumn : public OColumn,
                          public ::comphelper::OPropertyArrayUsageHelper < OResultColumn >
    {
    protected:
        ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XResultSetMetaData > m_xMetaData;
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >   m_xDBMetaData;
        sal_Int32                   m_nPos;
        ::com::sun::star::uno::Any  m_aIsRowVersion;

        virtual ~OResultColumn();
    public:
        OResultColumn(
            const ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XResultSetMetaData >& _xMetaData,
            sal_Int32 _nPos,
            const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxDBMeta );

    // com::sun::star::lang::XTypeProvider
        virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);

    // com::sun::star::lang::XServiceInfo
        virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);

    // cppu::OComponentHelper
        virtual void SAL_CALL disposing(void);

    // comphelper::OPropertyArrayUsageHelper
        virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;

    // cppu::OPropertySetHelper
        virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
        virtual void SAL_CALL getFastPropertyValue(
                                    ::com::sun::star::uno::Any& rValue,
                                    sal_Int32 nHandle
                                         ) const;

    private:
        void    impl_determineIsRowVersion_nothrow();
    };
}
#endif // _DBACORE_RESULTCOLUMN_HXX_

<commit_msg>INTEGRATION: CWS warnings01 (1.6.28); FILE MERGED 2006/03/24 15:35:49 fs 1.6.28.1: #i57457# warning-free code (unxlngi6/.pro + unxsoli4.pro)<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: resultcolumn.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 02:40:45 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _DBACORE_RESULTCOLUMN_HXX_
#define _DBACORE_RESULTCOLUMN_HXX_

#ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATA_HDL_
#include <com/sun/star/sdbc/XResultSetMetaData.hdl>
#endif
#ifndef _DBA_COREAPI_COLUMN_HXX_
#include <column.hxx>
#endif
namespace dbaccess
{
    //************************************************************
    //  OResultColumn
    //************************************************************
    class OResultColumn : public OColumn,
                          public ::comphelper::OPropertyArrayUsageHelper < OResultColumn >
    {
    protected:
        ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XResultSetMetaData > m_xMetaData;
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >   m_xDBMetaData;
        sal_Int32                   m_nPos;
        ::com::sun::star::uno::Any  m_aIsRowVersion;

        virtual ~OResultColumn();
    public:
        OResultColumn(
            const ::com::sun::star::uno::Reference < ::com::sun::star::sdbc::XResultSetMetaData >& _xMetaData,
            sal_Int32 _nPos,
            const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _rxDBMeta );

    // com::sun::star::lang::XTypeProvider
        virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);

    // com::sun::star::lang::XServiceInfo
        virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);

    // cppu::OComponentHelper
        virtual void SAL_CALL disposing(void);

    // comphelper::OPropertyArrayUsageHelper
        virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;

    // cppu::OPropertySetHelper
        virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
        virtual void SAL_CALL getFastPropertyValue(
                                    ::com::sun::star::uno::Any& rValue,
                                    sal_Int32 nHandle
                                         ) const;

    private:
        void    impl_determineIsRowVersion_nothrow();

    protected:
        using ::cppu::OPropertySetHelper::getFastPropertyValue;
    };
}
#endif // _DBACORE_RESULTCOLUMN_HXX_

<|endoftext|>


<commit_before>// @(#)root/meta:$Id$
// Author: Rene Brun   09/02/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/** \class TMethod
 Each ROOT class (see TClass) has a linked list of methods.
 This class describes one single method (member function).
 The method info is obtained via the CINT api. See class TCling.

 The method information is used a.o. by the THml class and by the
 TTree class.
*/

#include "strtok.h"
#include "strlcpy.h"
#include "snprintf.h"
#include "TClass.h"
#include "TList.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TMethodCall.h"
#include "TInterpreter.h"
#include "Strlen.h"
#include "TDataMember.h"

ClassImp(TMethod);

////////////////////////////////////////////////////////////////////////////////
/// Default TMethod ctor. TMethods are constructed in TClass.
/// Comment strings are pre-parsed to find out whether the method is
/// a context-menu item.

TMethod::TMethod(MethodInfo_t *info, TClass *cl) : TFunction(info)
{
   fClass        = cl;
   fGetterMethod = 0;
   fSetterMethod = 0;
   fMenuItem     = kMenuNoMenu;

   if (fInfo) {
      SetMenuItem(gCling->MethodInfo_Title(fInfo));
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Copy ctor.

TMethod::TMethod(const TMethod& orig) : TFunction(orig)
{
   fClass        = orig.fClass;
   fMenuItem     = orig.fMenuItem;
   fGetter       = orig.fGetter;
   fGetterMethod = 0;
   fSetterMethod = 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Assignment operator.

TMethod& TMethod::operator=(const TMethod& rhs)
{
   if (this != &rhs) {
      TFunction::operator=(rhs);
      fClass        = rhs.fClass;
      fMenuItem     = rhs.fMenuItem;
      fGetter       = rhs.fGetter;
      if (fGetterMethod)
         delete fGetterMethod;
      fGetterMethod = 0;
      if (fSetterMethod)
         delete fSetterMethod;
      fSetterMethod = 0;
   }
   return *this;
}

////////////////////////////////////////////////////////////////////////////////
/// Cleanup.

TMethod::~TMethod()
{
   delete fGetterMethod;
   delete fSetterMethod;
}

////////////////////////////////////////////////////////////////////////////////
/// Clone method.

TObject *TMethod::Clone(const char *newname) const
{
   TNamed *newobj = new TMethod(*this);
   if (newname && strlen(newname)) newobj->SetName(newname);
   return newobj;
}

////////////////////////////////////////////////////////////////////////////////
/// Returns a comment string from the class declaration.

const char *TMethod::GetCommentString()
{
   return fInfo ? gCling->MethodInfo_Title(fInfo) : "";
}

////////////////////////////////////////////////////////////////////////////////
/// Using the CINT method arg information create a complete signature string.

void TMethod::CreateSignature()
{
   TFunction::CreateSignature();

   if (Property() & kIsConstMethod) fSignature += " const";
}

////////////////////////////////////////////////////////////////////////////////
/// Tries to guess DataMember from comment string
/// and Method's name <==(only if 1 Argument!).
/// If more then one argument=> returns pointer to the last argument.
/// It also sets MethodArgs' pointers to point to specified data members.
///
/// The form of comment string defining arguments is:
/// void XXX(Int_t x1, Float_t y2) //*ARGS={x1=>fX1,y2=>fY2}
/// where fX1, fY2 are data fields in the same class.
/// ("pointers" to data members)

TDataMember *TMethod::FindDataMember()
{
   Char_t *argstring = (char*)strstr(GetCommentString(),"*ARGS={");

   // the following statement has been commented (Rene). Not needed
   // it was making troubles in BuildRealData for classes with protected
   // default constructors.
   // if (!(GetClass()->GetListOfRealData())) GetClass()->BuildRealData();

   if (argstring) {

      // if we found any argument-specifying hints  - parse it

      if (!fMethodArgs) return 0;

      Int_t nchs = strlen(argstring);    // workspace...
      char *argstr = new char[nchs+1];   // workspace...
      char *ptr1 = 0;
      char *tok  = 0;
      char *ptr2 = 0;
      Int_t i;

      strlcpy(argstr,argstring,nchs+1);       //let's move it to "workspace"  copy
      char *rest;
      ptr2 = R__STRTOK_R(argstr, "{}", &rest); // extract the data!
      if (ptr2 == 0) {
         Fatal("FindDataMember","Internal error found '*ARGS=\"' but not \"{}\" in %s",GetCommentString());
         delete [] argstr;
         return 0;
      }
      ptr2 = R__STRTOK_R((char *)0, "{}", &rest);

      //extract argument tokens//
      char *tokens[20];
      Int_t cnt       = 0;
      Int_t token_cnt = 0;
      do {
         ptr1 = R__STRTOK_R((char *)(cnt++ ? 0 : ptr2), ",;", &rest); // extract tokens
                                                                   // separated by , or ;
         if (ptr1) {
            Int_t nch = strlen(ptr1);
            tok = new char[nch+1];
            strlcpy(tok,ptr1,nch+1);
            tokens[token_cnt] = tok;            //store this token.
            token_cnt++;
         }
      } while (ptr1);

      //now let's  parse all argument tokens...
      TClass     *cl = 0;
      TMethodArg *a  = 0;
      TMethodArg *ar = 0;
      TDataMember *member = 0;

      for (i=0; i<token_cnt;i++) {
         cnt = 0;
         ptr1 = R__STRTOK_R(tokens[i], "=>", &rest);         // LeftHandedSide=methodarg
         ptr2 = R__STRTOK_R((char *)0, "=>", &rest);         // RightHandedSide-points to datamember

         //find the MethodArg
         a      = 0;
         ar     = 0;
         member = 0;
         TIter nextarg(fMethodArgs);     // iterate through all arguments.
         while ((ar = (TMethodArg*)nextarg())) {
            if (!strcmp(ptr1,ar->GetName())) {
               a = ar;
               break;
            }
         }

         //now find the data member
         cl = GetClass()->GetBaseDataMember(ptr2);
         if (cl) {
            member = cl->GetDataMember(ptr2);
            if (a) a->fDataMember = member; //SET THE APROPRIATE FIELD !!!
                                     //We can do it - friend decl. in MethodArg
         }
         delete [] tokens[i];
      }
      delete [] argstr;
      return member; // nothing else to do! We return a pointer to the last
                     // found data member

   // if not found in comment string - try to guess it from name!
   } else {
      if (fMethodArgs)
         if (fMethodArgs->GetSize() != 1) return 0;

      TMethodArg *a = 0;
      if (fMethodArgs) a = (TMethodArg*)(fMethodArgs->First());

      char dataname[67]    = "";
      char basename[64]    = "";
      const char *funcname = GetName();
      if ( strncmp(funcname,"Get",3) == 0 || strncmp(funcname,"Set",3) == 0 )
         snprintf(basename,64,"%s",funcname+3);
      else if ( strncmp(funcname,"Is",2) == 0 )
         snprintf(basename,64,"%s",funcname+2);
      else if (strncmp(funcname, "Has", 3) == 0)
         snprintf(basename,64,"%s", funcname+3);
      else
         return 0;

      snprintf(dataname,67,"f%s",basename);

      TClass *cl = GetClass()->GetBaseDataMember(dataname);
      if (cl) {
         TDataMember *member   = cl->GetDataMember(dataname);
         if (a) a->fDataMember = member;
         return member;
      } else {
         snprintf(dataname,67,"fIs%s",basename);  //in case of IsEditable()
                                                        //and fIsEditable
         cl = GetClass()->GetBaseDataMember(dataname);
         if (cl) {
            TDataMember *member = cl->GetDataMember(dataname);
            if (a) a->fDataMember = member;
            return member;
         }
      }
   }

   //if nothing found - return null -pointer:
   return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Return call environment for the getter method in case this is a
/// *TOGGLE method (for the context menu).

TMethodCall *TMethod::GetterMethod()
{
   if (!fGetterMethod && fMenuItem == kMenuToggle && fGetter != "" && fClass) {
      fGetterMethod = new TMethodCall(fClass, Getter(), "");
   }
   return fGetterMethod;
}

////////////////////////////////////////////////////////////////////////////////
/// Return true if this function object is pointing to a currently
/// loaded function.  If a function is unloaded after the TMethod
/// is created, the TMethod will be set to be invalid.

Bool_t TMethod::IsValid()
{
   // Register the transaction when checking the validity of the object.
   if (!fInfo && UpdateInterpreterStateMarker()) {
      DeclId_t newId = gInterpreter->GetFunction(fClass->GetClassInfo(), fName);
      if (newId) {
         MethodInfo_t *info = gInterpreter->MethodInfo_Factory(newId);
         Update(info);
      }
      return newId != 0;
   }
   return fInfo != 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Return call environment for this method in case this is a
/// *TOGGLE method which takes a single boolean or integer argument.

TMethodCall *TMethod::SetterMethod()
{
   if (!fSetterMethod && fMenuItem == kMenuToggle && fClass) {
      fSetterMethod = new TMethodCall(fClass, GetName(), "1");
   }
   return fSetterMethod;
}

////////////////////////////////////////////////////////////////////////////////
/// Returns methodarg list and additionally updates fDataMember in TMethod by
/// calling FindDataMember();

TList *TMethod::GetListOfMethodArgs()
{
   if (!fMethodArgs){
      TFunction::GetListOfMethodArgs();
      FindDataMember();
   }
   return fMethodArgs;
}

////////////////////////////////////////////////////////////////////////////////
/// Set the menu item as prescribed in the doctstring.

void TMethod::SetMenuItem(const char *docstring)
{
   if (docstring && strstr(docstring, "*TOGGLE")) {
      fMenuItem = kMenuToggle;
      const char *s;
      if ((s = strstr(docstring, "*GETTER="))) {
         fGetter = s+8;
         fGetter = fGetter.Strip(TString::kBoth);
      }
   } else
      if (docstring && strstr(docstring, "*MENU"))
         fMenuItem = kMenuDialog;
      else
         if (docstring && strstr(docstring, "*SUBMENU"))
            fMenuItem = kMenuSubMenu;
         else
            fMenuItem = kMenuNoMenu;
}

////////////////////////////////////////////////////////////////////////////////
/// Update the TMethod to reflect the new info.
///
/// This can be used to implement unloading (info == 0) and then reloading
/// (info being the 'new' decl address).

Bool_t TMethod::Update(MethodInfo_t *info)
{
   if (TFunction::Update(info)) {
      delete fGetterMethod; fGetterMethod = 0;
      delete fSetterMethod; fSetterMethod = 0;
      if (fInfo) {
         SetMenuItem(gCling->MethodInfo_Title(fInfo));
      }
      return kTRUE;
   } else {
      return kFALSE;
   }
}
<commit_msg>Remove unused variable from TMethod.cxx<commit_after>// @(#)root/meta:$Id$
// Author: Rene Brun   09/02/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/** \class TMethod
 Each ROOT class (see TClass) has a linked list of methods.
 This class describes one single method (member function).
 The method info is obtained via the CINT api. See class TCling.

 The method information is used a.o. by the THml class and by the
 TTree class.
*/

#include "strtok.h"
#include "strlcpy.h"
#include "snprintf.h"
#include "TClass.h"
#include "TList.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TMethodCall.h"
#include "TInterpreter.h"
#include "Strlen.h"
#include "TDataMember.h"

ClassImp(TMethod);

////////////////////////////////////////////////////////////////////////////////
/// Default TMethod ctor. TMethods are constructed in TClass.
/// Comment strings are pre-parsed to find out whether the method is
/// a context-menu item.

TMethod::TMethod(MethodInfo_t *info, TClass *cl) : TFunction(info)
{
   fClass        = cl;
   fGetterMethod = 0;
   fSetterMethod = 0;
   fMenuItem     = kMenuNoMenu;

   if (fInfo) {
      SetMenuItem(gCling->MethodInfo_Title(fInfo));
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Copy ctor.

TMethod::TMethod(const TMethod& orig) : TFunction(orig)
{
   fClass        = orig.fClass;
   fMenuItem     = orig.fMenuItem;
   fGetter       = orig.fGetter;
   fGetterMethod = 0;
   fSetterMethod = 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Assignment operator.

TMethod& TMethod::operator=(const TMethod& rhs)
{
   if (this != &rhs) {
      TFunction::operator=(rhs);
      fClass        = rhs.fClass;
      fMenuItem     = rhs.fMenuItem;
      fGetter       = rhs.fGetter;
      if (fGetterMethod)
         delete fGetterMethod;
      fGetterMethod = 0;
      if (fSetterMethod)
         delete fSetterMethod;
      fSetterMethod = 0;
   }
   return *this;
}

////////////////////////////////////////////////////////////////////////////////
/// Cleanup.

TMethod::~TMethod()
{
   delete fGetterMethod;
   delete fSetterMethod;
}

////////////////////////////////////////////////////////////////////////////////
/// Clone method.

TObject *TMethod::Clone(const char *newname) const
{
   TNamed *newobj = new TMethod(*this);
   if (newname && strlen(newname)) newobj->SetName(newname);
   return newobj;
}

////////////////////////////////////////////////////////////////////////////////
/// Returns a comment string from the class declaration.

const char *TMethod::GetCommentString()
{
   return fInfo ? gCling->MethodInfo_Title(fInfo) : "";
}

////////////////////////////////////////////////////////////////////////////////
/// Using the CINT method arg information create a complete signature string.

void TMethod::CreateSignature()
{
   TFunction::CreateSignature();

   if (Property() & kIsConstMethod) fSignature += " const";
}

////////////////////////////////////////////////////////////////////////////////
/// Tries to guess DataMember from comment string
/// and Method's name <==(only if 1 Argument!).
/// If more then one argument=> returns pointer to the last argument.
/// It also sets MethodArgs' pointers to point to specified data members.
///
/// The form of comment string defining arguments is:
/// void XXX(Int_t x1, Float_t y2) //*ARGS={x1=>fX1,y2=>fY2}
/// where fX1, fY2 are data fields in the same class.
/// ("pointers" to data members)

TDataMember *TMethod::FindDataMember()
{
   Char_t *argstring = (char*)strstr(GetCommentString(),"*ARGS={");

   // the following statement has been commented (Rene). Not needed
   // it was making troubles in BuildRealData for classes with protected
   // default constructors.
   // if (!(GetClass()->GetListOfRealData())) GetClass()->BuildRealData();

   if (argstring) {

      // if we found any argument-specifying hints  - parse it

      if (!fMethodArgs) return 0;

      Int_t nchs = strlen(argstring);    // workspace...
      char *argstr = new char[nchs+1];   // workspace...
      char *ptr1 = 0;
      char *tok  = 0;
      char *ptr2 = 0;
      Int_t i;

      strlcpy(argstr,argstring,nchs+1);       //let's move it to "workspace"  copy
      char *rest;
      ptr2 = R__STRTOK_R(argstr, "{}", &rest); // extract the data!
      if (ptr2 == 0) {
         Fatal("FindDataMember","Internal error found '*ARGS=\"' but not \"{}\" in %s",GetCommentString());
         delete [] argstr;
         return 0;
      }
      ptr2 = R__STRTOK_R((char *)0, "{}", &rest);

      //extract argument tokens//
      char *tokens[20];
      Int_t cnt       = 0;
      Int_t token_cnt = 0;
      do {
         ptr1 = R__STRTOK_R((char *)(cnt++ ? 0 : ptr2), ",;", &rest); // extract tokens
                                                                   // separated by , or ;
         if (ptr1) {
            Int_t nch = strlen(ptr1);
            tok = new char[nch+1];
            strlcpy(tok,ptr1,nch+1);
            tokens[token_cnt] = tok;            //store this token.
            token_cnt++;
         }
      } while (ptr1);

      //now let's  parse all argument tokens...
      TClass     *cl = nullptr;
      TMethodArg *a  = nullptr;
      TMethodArg *ar = nullptr;
      TDataMember *member = nullptr;

      for (i=0; i<token_cnt;i++) {
         ptr1 = R__STRTOK_R(tokens[i], "=>", &rest);         // LeftHandedSide=methodarg
         ptr2 = R__STRTOK_R((char *) nullptr, "=>", &rest);  // RightHandedSide-points to datamember

         //find the MethodArg
         a      = 0;
         ar     = 0;
         member = 0;
         TIter nextarg(fMethodArgs);     // iterate through all arguments.
         while ((ar = (TMethodArg*)nextarg())) {
            if (!strcmp(ptr1,ar->GetName())) {
               a = ar;
               break;
            }
         }

         //now find the data member
         cl = GetClass()->GetBaseDataMember(ptr2);
         if (cl) {
            member = cl->GetDataMember(ptr2);
            if (a) a->fDataMember = member; //SET THE APROPRIATE FIELD !!!
                                     //We can do it - friend decl. in MethodArg
         }
         delete [] tokens[i];
      }
      delete [] argstr;
      return member; // nothing else to do! We return a pointer to the last
                     // found data member

   // if not found in comment string - try to guess it from name!
   } else {
      if (fMethodArgs)
         if (fMethodArgs->GetSize() != 1) return 0;

      TMethodArg *a = 0;
      if (fMethodArgs) a = (TMethodArg*)(fMethodArgs->First());

      char dataname[67]    = "";
      char basename[64]    = "";
      const char *funcname = GetName();
      if ( strncmp(funcname,"Get",3) == 0 || strncmp(funcname,"Set",3) == 0 )
         snprintf(basename,64,"%s",funcname+3);
      else if ( strncmp(funcname,"Is",2) == 0 )
         snprintf(basename,64,"%s",funcname+2);
      else if (strncmp(funcname, "Has", 3) == 0)
         snprintf(basename,64,"%s", funcname+3);
      else
         return 0;

      snprintf(dataname,67,"f%s",basename);

      TClass *cl = GetClass()->GetBaseDataMember(dataname);
      if (cl) {
         TDataMember *member   = cl->GetDataMember(dataname);
         if (a) a->fDataMember = member;
         return member;
      } else {
         snprintf(dataname,67,"fIs%s",basename);  //in case of IsEditable()
                                                        //and fIsEditable
         cl = GetClass()->GetBaseDataMember(dataname);
         if (cl) {
            TDataMember *member = cl->GetDataMember(dataname);
            if (a) a->fDataMember = member;
            return member;
         }
      }
   }

   //if nothing found - return null -pointer:
   return 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Return call environment for the getter method in case this is a
/// *TOGGLE method (for the context menu).

TMethodCall *TMethod::GetterMethod()
{
   if (!fGetterMethod && fMenuItem == kMenuToggle && fGetter != "" && fClass) {
      fGetterMethod = new TMethodCall(fClass, Getter(), "");
   }
   return fGetterMethod;
}

////////////////////////////////////////////////////////////////////////////////
/// Return true if this function object is pointing to a currently
/// loaded function.  If a function is unloaded after the TMethod
/// is created, the TMethod will be set to be invalid.

Bool_t TMethod::IsValid()
{
   // Register the transaction when checking the validity of the object.
   if (!fInfo && UpdateInterpreterStateMarker()) {
      DeclId_t newId = gInterpreter->GetFunction(fClass->GetClassInfo(), fName);
      if (newId) {
         MethodInfo_t *info = gInterpreter->MethodInfo_Factory(newId);
         Update(info);
      }
      return newId != 0;
   }
   return fInfo != 0;
}

////////////////////////////////////////////////////////////////////////////////
/// Return call environment for this method in case this is a
/// *TOGGLE method which takes a single boolean or integer argument.

TMethodCall *TMethod::SetterMethod()
{
   if (!fSetterMethod && fMenuItem == kMenuToggle && fClass) {
      fSetterMethod = new TMethodCall(fClass, GetName(), "1");
   }
   return fSetterMethod;
}

////////////////////////////////////////////////////////////////////////////////
/// Returns methodarg list and additionally updates fDataMember in TMethod by
/// calling FindDataMember();

TList *TMethod::GetListOfMethodArgs()
{
   if (!fMethodArgs){
      TFunction::GetListOfMethodArgs();
      FindDataMember();
   }
   return fMethodArgs;
}

////////////////////////////////////////////////////////////////////////////////
/// Set the menu item as prescribed in the doctstring.

void TMethod::SetMenuItem(const char *docstring)
{
   if (docstring && strstr(docstring, "*TOGGLE")) {
      fMenuItem = kMenuToggle;
      const char *s;
      if ((s = strstr(docstring, "*GETTER="))) {
         fGetter = s+8;
         fGetter = fGetter.Strip(TString::kBoth);
      }
   } else
      if (docstring && strstr(docstring, "*MENU"))
         fMenuItem = kMenuDialog;
      else
         if (docstring && strstr(docstring, "*SUBMENU"))
            fMenuItem = kMenuSubMenu;
         else
            fMenuItem = kMenuNoMenu;
}

////////////////////////////////////////////////////////////////////////////////
/// Update the TMethod to reflect the new info.
///
/// This can be used to implement unloading (info == 0) and then reloading
/// (info being the 'new' decl address).

Bool_t TMethod::Update(MethodInfo_t *info)
{
   if (TFunction::Update(info)) {
      delete fGetterMethod; fGetterMethod = 0;
      delete fSetterMethod; fSetterMethod = 0;
      if (fInfo) {
         SetMenuItem(gCling->MethodInfo_Title(fInfo));
      }
      return kTRUE;
   } else {
      return kFALSE;
   }
}
<|endoftext|>


<commit_before>#include "Application.hpp"

#include "StringIDImpl.hpp"

#include <iomanip>
#include <iostream>
#include <fstream>
#include <sstream>

#include <regex>

#include "File.hpp"

#include <stdio.h>
#include <windows.h>
#include <algorithm>

static const char* g_help =
"-help                     Display this help and do nothing\n"
"-project                  Name of the project (default=\"StringIDProj\"\n"
"-gui                      Launch GUI application\n"
"-sources                  List folders to search (=\"C:/Folder1;../Folder2\")\n"
"-destination              Destination root folder where to copy results.\n"
"                          If empty, modifications will be in place\n"
"-excludedFolders          List folders to exclude (=\"C:/Folder1;../Folder2\")\n"
"-excludedSources          List sources to exclude (=\"path1;path2\")\n"
"-extensions               List extensions to parse (default=\".cpp;.h;.hh;.inl\")\n"
"-clean                    Will not use cache infos, will re-parse all files\n"
"-verbose                  Show detailed diagnostic information for debugging\n"
"-saveForUndo              Will keep a save of modified files in project's file\n"
"-undo                     Used in association with -project will undo last generation\n"
"-summary                  Display a detailed summary\n";

Application::Application()
	:
	_projectName("StringIDProj"),
	_guiEnabled(false),
	_destination(""),
	_clean(false),
	_verbose(false),
	_saveforundo(false),
	_undo(false),
	_displaySummary(false),
	_inPlace(false)
{
}

Application::~Application()
{
}

bool Application::init(int argc, char *argv[])
{
	for (int i = 1; i < argc; ++i)
	{
		std::string arg = argv[i];

		if (arg.empty())
			continue;

		if (arg[0] == '-')
		{
			if (arg == "-help")
			{
				std::cout << g_help << std::endl;
				continue;
			}
			if (arg == "-project")
			{
				int projectPathIndex = i + 1;
				if (projectPathIndex >= argc)
				{
					//ERROR
					std::cerr << "Project path missing\n";
					return false;
				}
				_projectName = argv[projectPathIndex];
				++i;
				continue;
			}
			if (arg == "-gui")
			{
				_guiEnabled = true;
				continue;
			}
			if (arg == "-sources")
			{
				int sourcesIndex = i + 1;
				if (sourcesIndex >= argc)
				{
					std::cerr << "Sources missing\n";
					return false;
					//ERROR
				}

				std::string source = argv[sourcesIndex];
				while (source.empty() == false && source[0] != '-')
				{
					_sources.push_back(CleanPath(MakePathAbsolute(source)) + "/");
					++sourcesIndex;
					source = "";
					if (sourcesIndex < argc)
					{
						source = argv[sourcesIndex];
					}
				}
				if (_sources.empty())
				{
					std::cerr << "Sources missing\n";
					return false;
					//ERROR
				}
				i = sourcesIndex - 1;
				continue;
			}
			if (arg == "-destination")
			{
				int destIndex = i + 1;
				if (destIndex >= argc)
				{
					std::cerr << "Destination missing\n";
					return false;
					//ERROR
				}
				arg = argv[destIndex];
				if (arg.empty() || arg[0] == '-')
				{
					std::cerr << "Destination missing\n";
					return false;
					//ERROR
				}
				_destination = CleanPath(MakePathAbsolute(arg));
				++i;
				continue;
			}
			if (arg == "-excludedFolders")
			{
				int excludedFoldersIndex = i + 1;
				if (excludedFoldersIndex >= argc)
				{
					std::cerr << "Excluded folders missing\n";
					return false;
					//ERROR
				}

				std::string source = argv[excludedFoldersIndex];
				while (source.empty() == false && source[0] != '-')
				{
					_excludedFolders.push_back(CleanPath(MakePathAbsolute(source)));
					++excludedFoldersIndex;
					source = "";
					if (excludedFoldersIndex < argc)
					{
						source = argv[excludedFoldersIndex];
					}
				}
				if (_excludedFolders.empty())
				{
					std::cerr << "Excluded folders missing\n";
					return false;
					//ERROR
				}
				i = excludedFoldersIndex - 1;
				continue;
			}
			if (arg == "-excludedSources")
			{
				int excludedSourcesIndex = i + 1;
				if (excludedSourcesIndex >= argc)
				{
					std::cerr << "Excluded sources missing\n";
					return false;
					//ERROR
				}

				std::string source = argv[excludedSourcesIndex];
				while (source.empty() == false && source[0] != '-')
				{
					_excludedSources.push_back(CleanPath(MakePathAbsolute(source)));
					++excludedSourcesIndex;
					source = "";
					if (excludedSourcesIndex < argc)
					{
						source = argv[excludedSourcesIndex];
					}
				}
				if (_excludedSources.empty())
				{
					std::cerr << "Excluded sources missing\n";
					return false;
					//ERROR
				}
				i = excludedSourcesIndex - 1;
				continue;
			}
			if (arg == "-extensions")
			{
				int extIndex = i + 1;
				if (extIndex >= argc)
				{
					std::cerr << "Extensions missing\n";
					return false;
					//ERROR
				}

				std::string source = argv[extIndex];
				while (source.empty() == false && source[0] != '-')
				{
					_extensions.push_back(source);
					++extIndex;
					source = "";
					if (extIndex < argc)
					{
						source = argv[extIndex];
					}
				}
				if (_extensions.empty())
				{
					std::cerr << "Extensions missing\n";
					return false;
					//ERROR
				}
				i = extIndex - 1;
				continue;
			}
			if (arg == "-clean")
			{
				_clean = true;
				continue;
			}
			if (arg == "-verbose")
			{
				_verbose = true;
				continue;
			}
			if (arg == "-saveForUndo")
			{
				_saveforundo = true;
				continue;
			}
			if (arg == "-undo")
			{
				_undo = true;
				continue;
			}
			if (arg == "-summary")
			{
				_displaySummary = true;
				continue;
			}
		}
	}

	if (_extensions.empty())
	{
		_extensions.push_back("h");
		_extensions.push_back("cpp");
		_extensions.push_back("hpp");
		_extensions.push_back("inl");
	}
	if (_sources.empty())
	{
		std::cerr << "Sources missing\n";
		return false;
		//ERROR
	}

	if (_destination.empty())
	{
		_inPlace = true;
	}

	_currentDirectory = GetCurrentDirectory();

	return true;
}

/*
Regexp :

StringID("String") :
[\\s+|\\t|\\n|\\r]StringID\s*[(]{1}\s*["]{1}.+["]{1}\s*[)]

\bStringID\s*[(]{1}\s*["]{1}.+["]{1}\s*[)]{1}
\\bStringID\\s*[(]{1}\\s*[\"]{1}.+[\"]{1}\\s*[)]{1}

StringID("String", 0x123) :
(\\s+|\\t|\\n|\\r)StringID\s*[(]{1}\s*["]{1}.+["]{1}\s*[,]{1}\s*(0x\d+|\d+)\s*[)]{1}

StringID(0x123) :
(\\s+|\\t|\\n|\\r)StringID\s*[(]{1}\s*(0x\d+|\d+)\s*[)]{1}

For test :
StringID("StringA")
StringID( "StringB" )
StringID ("StringC")
StringID  ("StringD")
StringID  (  "StringE")
StringID(  "  StringF "  )
  StringID   (     "StringG"    )
TotoStringID   (     "StringH"    )
  TotoStringID   (     "StringI"    )
*/

template< typename T >
std::string IntToHex(T i)
{
	std::stringstream stream;
	stream << "0x"
		<< std::setfill('0') << std::setw(sizeof(T) * 2)
		<< std::hex << i;
	return stream.str();
}

void Application::treatFile(const FileInfo &fileInfo)
{
	std::ifstream file(fileInfo.absPath.c_str());

	std::ofstream output(std::string(_destination + fileInfo.absPath + ".sid").c_str());

	std::string line;
	std::size_t counter = 0;

	/*
	1 : crap
	2 : str
	*/
	std::regex regStringOnly   ("(.*?)\\bStringID\\s*[(]{1}\\s*[\"]{1}(.+?)[\"]{1}\\s*[)]{1}");
	/*
	1 : Crap
	2 : str
	3 : 0x123
	*/
	std::regex regStringAndHash("(.*?)\\bStringID\\s*[(]{1}\\s*\"(.+?)\"\\s*,\\s*(0x[\\d|a-f]+|[\\d|a-f]+)\\s*[)]{1}");
	std::match_results<std::string::const_iterator> match;

	while (std::getline(file, line))
	{
		std::istringstream iss(line);

		line += "\n";

		if (line.find("StringID") != std::string::npos)
		{
			std::string lineCopy = line;
			line.clear();

			auto flags = std::regex_constants::match_default | std::regex_constants::format_first_only | std::regex_constants::format_no_copy;
			bool pass = false;

			// We search for already hashed strings like StringID("Literal", 0x123);
			// We check if the hash is up to date, if not we re-generate it
			// We also register the hash if not already in db cache to check for collisions
			while (std::regex_search(lineCopy, match, regStringAndHash, flags))
			{
				auto &str = match[2].str();
				auto &h = match[3].str();
				StringIDType id = strtoll(h.c_str(), nullptr, 16);
				StringID sid = StringID(str);

				if (sid.getId() != id)
				{
					std::string replacer = "$1StringID(\"$2\", ";
					replacer += IntToHex(sid.getId());
					replacer += ")";
					line += std::regex_replace(lineCopy, regStringAndHash, replacer, flags);
					pass = true;
				}
				else
				{
					line = lineCopy;
				}
				lineCopy = match.suffix().str();
			}
			if (pass)
			{
				line += lineCopy;
			}

			if (!line.empty())
				lineCopy = line;
			line.clear();
			pass = false;

			// We search for StringID("Literal");
			// And generate ID for it
			while (std::regex_search(lineCopy, match, regStringOnly, flags))
			{
				std::string replacer = "$1StringID(\"$2\", ";
				auto &str = match[2].str();
				replacer += IntToHex(StringID(str).getId());
				replacer += ")";
				line += std::regex_replace(lineCopy, regStringOnly, replacer, flags);
				lineCopy = match.suffix().str();
				pass = true;
			}
			if (pass)
			{
				line += lineCopy;
			}

			if (line.empty())
			{
				line = lineCopy;
			}
		}
		output << line;
	}

}

void Application::run()
{

	if (_guiEnabled)
	{
		//_initGui();
	}

	std::vector<FileInfo> infos;
	FileFilter filter;
	filter._extensions = _extensions;
	filter._excludedPath = _excludedSources;
	filter._excludedDir = _excludedFolders;
	filter._minimumWriteTime = 0;
	for (auto &source : _sources)
	{
		SearchFiles(/*"D:\Epic Games/"*/ source /*"../Tests/"*/, &filter, infos);

		// we set relative path
		for (auto &res : infos)
		{
			res.relPath = res.absPath;
			res.relPath.erase(0, source.size());
		}
	}
	for (auto &s : infos)
	{
		treatFile(s);
	}

}<commit_msg>Small fix<commit_after>#include "Application.hpp"

#include "StringIDImpl.hpp"

#include <iomanip>
#include <iostream>
#include <fstream>
#include <sstream>

#include <regex>

#include "File.hpp"

#include <stdio.h>
#include <windows.h>
#include <algorithm>

static const char* g_help =
"-help                     Display this help and do nothing\n"
"-project                  Name of the project (default=\"StringIDProj\"\n"
"-gui                      Launch GUI application\n"
"-sources                  List folders to search (=\"C:/Folder1;../Folder2\")\n"
"-destination              Destination root folder where to copy results.\n"
"                          If empty, modifications will be in place\n"
"-excludedFolders          List folders to exclude (=\"C:/Folder1;../Folder2\")\n"
"-excludedSources          List sources to exclude (=\"path1;path2\")\n"
"-extensions               List extensions to parse (default=\".cpp;.h;.hh;.inl\")\n"
"-clean                    Will not use cache infos, will re-parse all files\n"
"-verbose                  Show detailed diagnostic information for debugging\n"
"-saveForUndo              Will keep a save of modified files in project's file\n"
"-undo                     Used in association with -project will undo last generation\n"
"-summary                  Display a detailed summary\n";

Application::Application()
	:
	_projectName("StringIDProj"),
	_guiEnabled(false),
	_destination(""),
	_clean(false),
	_verbose(false),
	_saveforundo(false),
	_undo(false),
	_displaySummary(false),
	_inPlace(false)
{
}

Application::~Application()
{
}

bool Application::init(int argc, char *argv[])
{
	for (int i = 1; i < argc; ++i)
	{
		std::string arg = argv[i];

		if (arg.empty())
			continue;

		if (arg[0] == '-')
		{
			if (arg == "-help")
			{
				std::cout << g_help << std::endl;
				continue;
			}
			if (arg == "-project")
			{
				int projectPathIndex = i + 1;
				if (projectPathIndex >= argc)
				{
					//ERROR
					std::cerr << "Project path missing\n";
					return false;
				}
				_projectName = argv[projectPathIndex];
				++i;
				continue;
			}
			if (arg == "-gui")
			{
				_guiEnabled = true;
				continue;
			}
			if (arg == "-sources")
			{
				int sourcesIndex = i + 1;
				if (sourcesIndex >= argc)
				{
					std::cerr << "Sources missing\n";
					return false;
					//ERROR
				}

				std::string source = argv[sourcesIndex];
				while (source.empty() == false && source[0] != '-')
				{
					_sources.push_back(CleanPath(MakePathAbsolute(source)) + "/");
					++sourcesIndex;
					source = "";
					if (sourcesIndex < argc)
					{
						source = argv[sourcesIndex];
					}
				}
				if (_sources.empty())
				{
					std::cerr << "Sources missing\n";
					return false;
					//ERROR
				}
				i = sourcesIndex - 1;
				continue;
			}
			if (arg == "-destination")
			{
				int destIndex = i + 1;
				if (destIndex >= argc)
				{
					std::cerr << "Destination missing\n";
					return false;
					//ERROR
				}
				arg = argv[destIndex];
				if (arg.empty() || arg[0] == '-')
				{
					std::cerr << "Destination missing\n";
					return false;
					//ERROR
				}
				_destination = CleanPath(MakePathAbsolute(arg));
				++i;
				continue;
			}
			if (arg == "-excludedFolders")
			{
				int excludedFoldersIndex = i + 1;
				if (excludedFoldersIndex >= argc)
				{
					std::cerr << "Excluded folders missing\n";
					return false;
					//ERROR
				}

				std::string source = argv[excludedFoldersIndex];
				while (source.empty() == false && source[0] != '-')
				{
					_excludedFolders.push_back(CleanPath(MakePathAbsolute(source)));
					++excludedFoldersIndex;
					source = "";
					if (excludedFoldersIndex < argc)
					{
						source = argv[excludedFoldersIndex];
					}
				}
				if (_excludedFolders.empty())
				{
					std::cerr << "Excluded folders missing\n";
					return false;
					//ERROR
				}
				i = excludedFoldersIndex - 1;
				continue;
			}
			if (arg == "-excludedSources")
			{
				int excludedSourcesIndex = i + 1;
				if (excludedSourcesIndex >= argc)
				{
					std::cerr << "Excluded sources missing\n";
					return false;
					//ERROR
				}

				std::string source = argv[excludedSourcesIndex];
				while (source.empty() == false && source[0] != '-')
				{
					_excludedSources.push_back(CleanPath(MakePathAbsolute(source)));
					++excludedSourcesIndex;
					source = "";
					if (excludedSourcesIndex < argc)
					{
						source = argv[excludedSourcesIndex];
					}
				}
				if (_excludedSources.empty())
				{
					std::cerr << "Excluded sources missing\n";
					return false;
					//ERROR
				}
				i = excludedSourcesIndex - 1;
				continue;
			}
			if (arg == "-extensions")
			{
				int extIndex = i + 1;
				if (extIndex >= argc)
				{
					std::cerr << "Extensions missing\n";
					return false;
					//ERROR
				}

				std::string source = argv[extIndex];
				while (source.empty() == false && source[0] != '-')
				{
					_extensions.push_back(source);
					++extIndex;
					source = "";
					if (extIndex < argc)
					{
						source = argv[extIndex];
					}
				}
				if (_extensions.empty())
				{
					std::cerr << "Extensions missing\n";
					return false;
					//ERROR
				}
				i = extIndex - 1;
				continue;
			}
			if (arg == "-clean")
			{
				_clean = true;
				continue;
			}
			if (arg == "-verbose")
			{
				_verbose = true;
				continue;
			}
			if (arg == "-saveForUndo")
			{
				_saveforundo = true;
				continue;
			}
			if (arg == "-undo")
			{
				_undo = true;
				continue;
			}
			if (arg == "-summary")
			{
				_displaySummary = true;
				continue;
			}
		}
	}

	if (_extensions.empty())
	{
		_extensions.push_back("h");
		_extensions.push_back("cpp");
		_extensions.push_back("hpp");
		_extensions.push_back("inl");
	}
	if (_sources.empty())
	{
		std::cerr << "Sources missing\n";
		return false;
		//ERROR
	}

	if (_destination.empty())
	{
		_inPlace = true;
	}

	_currentDirectory = GetCurrentDirectory();

	return true;
}

/*
Regexp :

StringID("String") :
[\\s+|\\t|\\n|\\r]StringID\s*[(]{1}\s*["]{1}.+["]{1}\s*[)]

\bStringID\s*[(]{1}\s*["]{1}.+["]{1}\s*[)]{1}
\\bStringID\\s*[(]{1}\\s*[\"]{1}.+[\"]{1}\\s*[)]{1}

StringID("String", 0x123) :
(\\s+|\\t|\\n|\\r)StringID\s*[(]{1}\s*["]{1}.+["]{1}\s*[,]{1}\s*(0x\d+|\d+)\s*[)]{1}

StringID(0x123) :
(\\s+|\\t|\\n|\\r)StringID\s*[(]{1}\s*(0x\d+|\d+)\s*[)]{1}

For test :
StringID("StringA")
StringID( "StringB" )
StringID ("StringC")
StringID  ("StringD")
StringID  (  "StringE")
StringID(  "  StringF "  )
  StringID   (     "StringG"    )
TotoStringID   (     "StringH"    )
  TotoStringID   (     "StringI"    )
*/

template< typename T >
std::string IntToHex(T i)
{
	std::stringstream stream;
	stream << "0x"
		<< std::setfill('0') << std::setw(sizeof(T) * 2)
		<< std::hex << i;
	return stream.str();
}

void Application::treatFile(const FileInfo &fileInfo)
{
	std::ifstream file(fileInfo.absPath.c_str());

	std::ofstream output(std::string(_destination + fileInfo.absPath + ".sid").c_str());

	std::string line;
	std::size_t counter = 0;

	/*
	1 : crap StringID("
	2 : str
	*/
	std::regex regStringOnly   ("(.*?\\bStringID\\s*[(]{1}\\s*[\"]{1})(.+?)[\"]{1}\\s*[)]{1}");
	/*
	1 : Crap StringID
	2 : str
	3 : ,
	4 : 0x123
	*/
	std::regex regStringAndHash("(.*?\\bStringID\\s*[(]{1}\\s*\")(.+?)(\"\\s*,\\s*)(0x[\\d|a-f]+|[\\d|a-f]+)\\s*[)]{1}");
	std::match_results<std::string::const_iterator> match;

	while (std::getline(file, line))
	{
		std::istringstream iss(line);

		line += "\n";

		if (line.find("StringID") != std::string::npos)
		{
			std::string lineCopy = line;
			line.clear();

			auto flags = std::regex_constants::match_default | std::regex_constants::format_first_only | std::regex_constants::format_no_copy;
			bool pass = false;

			// We search for already hashed strings like StringID("Literal", 0x123);
			// We check if the hash is up to date, if not we re-generate it
			// We also register the hash if not already in db cache to check for collisions
			while (std::regex_search(lineCopy, match, regStringAndHash, flags))
			{
				auto &str = match[2].str();
				auto &h = match[4].str();
				StringIDType id = strtoll(h.c_str(), nullptr, 16);
				StringID sid = StringID(str);

				if (sid.getId() != id)
				{
					std::string replacer = "$1$2\", ";
					replacer += IntToHex(sid.getId());
					replacer += ")";
					line += std::regex_replace(lineCopy, regStringAndHash, replacer, flags);
					pass = true;
				}
				else
				{
					line = lineCopy;
				}
				lineCopy = match.suffix().str();
			}
			if (pass)
			{
				line += lineCopy;
			}

			if (!line.empty())
				lineCopy = line;
			line.clear();
			pass = false;

			// We search for StringID("Literal");
			// And generate ID for it
			while (std::regex_search(lineCopy, match, regStringOnly, flags))
			{
				std::string replacer = "$1$2\", ";
				auto &str = match[2].str();
				replacer += IntToHex(StringID(str).getId());
				replacer += ")";
				line += std::regex_replace(lineCopy, regStringOnly, replacer, flags);
				lineCopy = match.suffix().str();
				pass = true;
			}
			if (pass)
			{
				line += lineCopy;
			}

			if (line.empty())
			{
				line = lineCopy;
			}
		}
		output << line;
	}

}

void Application::run()
{

	if (_guiEnabled)
	{
		//_initGui();
	}

	std::vector<FileInfo> infos;
	FileFilter filter;
	filter._extensions = _extensions;
	filter._excludedPath = _excludedSources;
	filter._excludedDir = _excludedFolders;
	filter._minimumWriteTime = 0;
	for (auto &source : _sources)
	{
		SearchFiles(/*"D:\Epic Games/"*/ source /*"../Tests/"*/, &filter, infos);

		// we set relative path
		for (auto &res : infos)
		{
			res.relPath = res.absPath;
			res.relPath.erase(0, source.size());
		}
	}
	for (auto &s : infos)
	{
		treatFile(s);
	}

}<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/PointCloud.h>
#include <sensor_msgs/point_cloud_conversion.h>
#include <tf/transform_listener.h>
#include <octomap/octomap.h>
#include <octomap/OcTree.h>
#include <octomap_msgs/Octomap.h>
#include <octomap_msgs/conversions.h>
#include <geometry_msgs/PointStamped.h>

#include <string>
#include <math.h>
#include <vector>

#include "dmath/geometry.h"

class ArtificialPotentialField{
public:
    ArtificialPotentialField(ros::NodeHandle &node) :
        base_link_("base_link"),
        cmd_pub_(node.advertise<geometry_msgs::Twist>("cmd_vel", 10)),
        obs_sub_(node.subscribe("octomap_full", 10, &ArtificialPotentialField::obstacleCallback, this)),
        goal_sub_(node.subscribe("clicked_point", 10, &ArtificialPotentialField::goalCallback, this))

    {
        collision_map_.header.stamp = ros::Time(0);
    }

    void spin(){
        ros::Rate r(10);

        ros::Duration(1).sleep();
        geometry_msgs::Twist cmd;
        cmd.linear.z = 0.15;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        cmd.linear.z = 0;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        const double force = 0.025;

        while(ros::ok()){
            if(collision_map_.header.stamp != ros::Time(0)){
                std::vector<dmath::Vector3D> obstacles_lc;
                std::string map_frame = collision_map_.header.frame_id;
                octomap::OcTree *tree = dynamic_cast<octomap::OcTree*>(octomap_msgs::msgToMap(collision_map_));
                octomap::OcTree::leaf_iterator const end_it = tree->end_leafs();
                for(octomap::OcTree::leaf_iterator it = tree->begin_leafs(0); it != end_it; it++){
                    geometry_msgs::PointStamped p_in, p_out;
                    p_in.header.frame_id = map_frame;
                    p_in.point.x = it.getX();
                    p_in.point.y = it.getY();
                    p_in.point.z = it.getZ();

                    try{
                        tf_listener_.transformPoint(base_link_, p_in, p_out);
                        dmath::Vector3D obs(p_out.point.x, p_out.point.y, p_out.point.z);
                        if(magnitude(obs) < 2.0){
                            obstacles_lc.push_back(obs);
                        }
                    }catch(tf::TransformException &ex){
                        ROS_ERROR_STREAM("Exception trying to transform octomap: " << ex.what());
                    }
                }

                dmath::Vector3D Fs;
                for(int i=0; i < obstacles_lc.size(); i++){
                    Fs += get_potential_force(obstacles_lc[i], 0, 0.3, 1.0, 1.0);
                }

                geometry_msgs::PointStamped goal_msg_lc;
                dmath::Vector3D goal_lc;
                try{
                    tf_listener_.waitForTransform(goal_msg_gl_.header.frame_id, base_link_, ros::Time(0), ros::Duration(1));
                    goal_msg_gl_.header.stamp = ros::Time(0);
                    tf_listener_.transformPoint(base_link_, goal_msg_gl_, goal_msg_lc);
                    goal_lc = -dmath::Vector3D(goal_msg_lc.point.x, goal_msg_lc.point.y, goal_msg_lc.point.z);
                }catch(tf::TransformException &ex){
                    ROS_ERROR_STREAM("Exception trying to transform goal position: " << ex.what());
                    goal_lc = dmath::Vector3D();
                }

                Fs += get_potential_force(goal_lc, 100, 0, 1, 1);

                dmath::Vector3D vel = Fs * force;
                cmd.linear.x = vel.x;
                cmd.linear.y = vel.y;
                cmd.linear.z = vel.z;

                cmd_pub_.publish(cmd);
            }
            r.sleep();
            ros::spinOnce();
        }
    }

private:
    dmath::Vector3D get_potential_force(const dmath::Vector3D &dest_lc, double A = 1, double B = 1, double n = 1, double m = 1){
        dmath::Vector3D u = dest_lc;
        u = normalize(u);

        const double d = magnitude(dest_lc);
        ROS_INFO_STREAM("dist = " << d);
        double U = 0;
        if(fabs(d) > dmath::tol){
            U = -A/pow(d, n) + B/pow(d, m);
        }

        return U * u;
    }

    void obstacleCallback(const octomap_msgs::OctomapPtr &obs_msg){
        collision_map_ = *obs_msg;
    }

    void goalCallback(const geometry_msgs::PointStamped &goal_msg){
        goal_msg_gl_ = goal_msg;
    }

    octomap_msgs::Octomap collision_map_;
    ros::Publisher cmd_pub_;
    ros::Subscriber obs_sub_, goal_sub_;
    tf::TransformListener tf_listener_;
    std::string base_link_;
    geometry_msgs::PointStamped goal_msg_gl_;
};

int main(int argc, char *argv[]){
    ros::init(argc, argv, "apf_planner");

    ros::NodeHandle node;
    ArtificialPotentialField apf(node);
    apf.spin();

    return 0;
}

<commit_msg>Limit x-velocity<commit_after>#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/PointCloud.h>
#include <sensor_msgs/point_cloud_conversion.h>
#include <tf/transform_listener.h>
#include <octomap/octomap.h>
#include <octomap/OcTree.h>
#include <octomap_msgs/Octomap.h>
#include <octomap_msgs/conversions.h>
#include <geometry_msgs/PointStamped.h>

#include <string>
#include <math.h>
#include <vector>

#include "dmath/geometry.h"

class ArtificialPotentialField{
public:
    ArtificialPotentialField(ros::NodeHandle &node) :
        base_link_("base_link"),
        cmd_pub_(node.advertise<geometry_msgs::Twist>("cmd_vel", 10)),
        obs_sub_(node.subscribe("octomap_full", 10, &ArtificialPotentialField::obstacleCallback, this)),
        goal_sub_(node.subscribe("clicked_point", 10, &ArtificialPotentialField::goalCallback, this))

    {
        collision_map_.header.stamp = ros::Time(0);
    }

    void spin(){
        ros::Rate r(10);

        ros::Duration(1).sleep();
        geometry_msgs::Twist cmd;
        cmd.linear.z = 0.15;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        cmd.linear.z = 0;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        const double force = 0.025;

        while(ros::ok()){
            if(collision_map_.header.stamp != ros::Time(0)){
                std::vector<dmath::Vector3D> obstacles_lc;
                std::string map_frame = collision_map_.header.frame_id;
                octomap::OcTree *tree = dynamic_cast<octomap::OcTree*>(octomap_msgs::msgToMap(collision_map_));
                octomap::OcTree::leaf_iterator const end_it = tree->end_leafs();
                for(octomap::OcTree::leaf_iterator it = tree->begin_leafs(0); it != end_it; it++){
                    geometry_msgs::PointStamped p_in, p_out;
                    p_in.header.frame_id = map_frame;
                    p_in.point.x = it.getX();
                    p_in.point.y = it.getY();
                    p_in.point.z = it.getZ();

                    try{
                        tf_listener_.transformPoint(base_link_, p_in, p_out);
                        dmath::Vector3D obs(p_out.point.x, p_out.point.y, p_out.point.z);
                        if(magnitude(obs) < 2.0){
                            obstacles_lc.push_back(obs);
                        }
                    }catch(tf::TransformException &ex){
                        ROS_ERROR_STREAM("Exception trying to transform octomap: " << ex.what());
                    }
                }

                dmath::Vector3D Fs;
                for(int i=0; i < obstacles_lc.size(); i++){
                    Fs += get_potential_force(obstacles_lc[i], 0, 0.3, 1.0, 1.0);
                }

                geometry_msgs::PointStamped goal_msg_lc;
                dmath::Vector3D goal_lc;
                try{
                    tf_listener_.waitForTransform(goal_msg_gl_.header.frame_id, base_link_, ros::Time(0), ros::Duration(1));
                    goal_msg_gl_.header.stamp = ros::Time(0);
                    tf_listener_.transformPoint(base_link_, goal_msg_gl_, goal_msg_lc);
                    goal_lc = -dmath::Vector3D(goal_msg_lc.point.x, goal_msg_lc.point.y, goal_msg_lc.point.z);
                }catch(tf::TransformException &ex){
                    ROS_ERROR_STREAM("Exception trying to transform goal position: " << ex.what());
                    goal_lc = dmath::Vector3D();
                }

                Fs += get_potential_force(goal_lc, 100, 0, 1, 1);

                dmath::Vector3D vel = Fs * force;
                if(vel.x > 0.5) vel.x = 0.5;
                if(vel.x < -0.5) vel.x = -0.5;
                cmd.linear.x = vel.x;
                cmd.linear.y = vel.y;
                cmd.linear.z = vel.z;

                cmd_pub_.publish(cmd);
            }
            r.sleep();
            ros::spinOnce();
        }
    }

private:
    dmath::Vector3D get_potential_force(const dmath::Vector3D &dest_lc, double A = 1, double B = 1, double n = 1, double m = 1){
        dmath::Vector3D u = dest_lc;
        u = normalize(u);

        const double d = magnitude(dest_lc);
        ROS_INFO_STREAM("dist = " << d);
        double U = 0;
        if(fabs(d) > dmath::tol){
            U = -A/pow(d, n) + B/pow(d, m);
        }

        return U * u;
    }

    void obstacleCallback(const octomap_msgs::OctomapPtr &obs_msg){
        collision_map_ = *obs_msg;
    }

    void goalCallback(const geometry_msgs::PointStamped &goal_msg){
        goal_msg_gl_ = goal_msg;
    }

    octomap_msgs::Octomap collision_map_;
    ros::Publisher cmd_pub_;
    ros::Subscriber obs_sub_, goal_sub_;
    tf::TransformListener tf_listener_;
    std::string base_link_;
    geometry_msgs::PointStamped goal_msg_gl_;
};

int main(int argc, char *argv[]){
    ros::init(argc, argv, "apf_planner");

    ros::NodeHandle node;
    ArtificialPotentialField apf(node);
    apf.spin();

    return 0;
}

<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/PointCloud.h>
#include <sensor_msgs/point_cloud_conversion.h>
#include <tf/transform_listener.h>
#include <octomap/octomap.h>
#include <octomap/OcTree.h>
#include <octomap_msgs/Octomap.h>
#include <octomap_msgs/conversions.h>
#include <geometry_msgs/PointStamped.h>

#include <string>
#include <math.h>
#include <vector>

#include "dmath/geometry.h"

class ArtificialPotentialField{
public:
    ArtificialPotentialField(ros::NodeHandle &node) :
        base_link_("base_link"),
        cmd_pub_(node.advertise<geometry_msgs::Twist>("cmd_vel", 10)),
        obs_sub_(node.subscribe("octomap_full", 10, &ArtificialPotentialField::obstacleCallback, this)),
        goal_sub_(node.subscribe("clicked_point", 10, &ArtificialPotentialField::goalCallback, this))

    {
        collision_map_.header.stamp = ros::Time(0);
    }

    void spin(){
        ros::Rate r(10);

        ros::Duration(1).sleep();
        geometry_msgs::Twist cmd;
        cmd.linear.z = 0.15;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        cmd.linear.z = 0;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        const double force = 0.025;

        while(ros::ok()){
            if(collision_map_.header.stamp != ros::Time(0)){
                std::vector<dmath::Vector3D> obstacles_lc;
                std::string map_frame = collision_map_.header.frame_id;
                octomap::OcTree *tree = dynamic_cast<octomap::OcTree*>(octomap_msgs::msgToMap(collision_map_));
                octomap::OcTree::leaf_iterator const end_it = tree->end_leafs();
                for(octomap::OcTree::leaf_iterator it = tree->begin_leafs(0); it != end_it; it++){
                    geometry_msgs::PointStamped p_in, p_out;
                    p_in.header.frame_id = map_frame;
                    p_in.point.x = it.getX();
                    p_in.point.y = it.getY();
                    p_in.point.z = it.getZ();

                    try{
                        tf_listener_.transformPoint(base_link_, p_in, p_out);
                        dmath::Vector3D obs(p_out.point.x, p_out.point.y, p_out.point.z);
                        if(magnitude(obs) < 500){
                            obstacles_lc.push_back(obs);
                        }
                    }catch(tf::TransformException &ex){
                        ROS_ERROR_STREAM("Exception trying to transform octomap: " << ex.what());
                    }
                }

                dmath::Vector3D Fs;
                //for(int i=0; i < obstacles_lc.size(); i++){
                //    Fs += get_potential_force(obstacles_lc[i], 0, 1.0, 1.0, 1.5);
                //}

                dmath::Vector3D g = goal_lc_;
                Fs += get_potential_force(g, 200, 0, 1.5, 1);

                dmath::Vector3D vel = Fs * force;
                cmd.linear.x = vel.y;
                cmd.linear.y = vel.x;
                cmd.linear.z = vel.z;

                cmd_pub_.publish(cmd);
            }
            r.sleep();
            ros::spinOnce();
        }
    }

private:
    dmath::Vector3D get_potential_force(const dmath::Vector3D &dest_lc, double A = 1, double B = 1, double n = 1, double m = 1){
        dmath::Vector3D u = dest_lc;
        u = normalize(u);

        const double d = magnitude(dest_lc);
        double U = 0;
        if(fabs(d) > dmath::tol){
            U = -A/pow(d, n) + B/pow(d, m);
        }

        return U * u;
    }

    void obstacleCallback(const octomap_msgs::OctomapPtr &obs_msg){
        collision_map_ = *obs_msg;
    }

    void goalCallback(const geometry_msgs::PointStamped &goal_msg){
        geometry_msgs::PointStamped g_lc;
        try{
            tf_listener_.transformPoint(base_link_, goal_msg, g_lc);
            goal_lc_ = dmath::Vector3D(g_lc.point.x, g_lc.point.y, g_lc.point.z);
        }catch(tf::TransformException &ex){
            ROS_ERROR_STREAM("Exception trying to transform octomap: " << ex.what());
            goal_lc_ = dmath::Vector3D();
        }
    }

    octomap_msgs::Octomap collision_map_;
    ros::Publisher cmd_pub_;
    ros::Subscriber obs_sub_, goal_sub_;
    tf::TransformListener tf_listener_;
    std::string base_link_;
    dmath::Vector3D goal_lc_;
};

int main(int argc, char *argv[]){
    ros::init(argc, argv, "apf_planner");

    ros::NodeHandle node;
    ArtificialPotentialField apf(node);
    apf.spin();

    return 0;
}

<commit_msg>Add debug code<commit_after>#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/PointCloud.h>
#include <sensor_msgs/point_cloud_conversion.h>
#include <tf/transform_listener.h>
#include <octomap/octomap.h>
#include <octomap/OcTree.h>
#include <octomap_msgs/Octomap.h>
#include <octomap_msgs/conversions.h>
#include <geometry_msgs/PointStamped.h>

#include <string>
#include <math.h>
#include <vector>

#include "dmath/geometry.h"

class ArtificialPotentialField{
public:
    ArtificialPotentialField(ros::NodeHandle &node) :
        base_link_("base_link"),
        cmd_pub_(node.advertise<geometry_msgs::Twist>("cmd_vel", 10)),
        obs_sub_(node.subscribe("octomap_full", 10, &ArtificialPotentialField::obstacleCallback, this)),
        goal_sub_(node.subscribe("clicked_point", 10, &ArtificialPotentialField::goalCallback, this))

    {
        collision_map_.header.stamp = ros::Time(0);
    }

    void spin(){
        ros::Rate r(10);

        ros::Duration(1).sleep();
        geometry_msgs::Twist cmd;
        cmd.linear.z = 0.15;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        cmd.linear.z = 0;
        cmd_pub_.publish(cmd);
        ros::Duration(3).sleep();

        const double force = 0.025;

        while(ros::ok()){
            if(collision_map_.header.stamp != ros::Time(0)){
                std::vector<dmath::Vector3D> obstacles_lc;
                std::string map_frame = collision_map_.header.frame_id;
                octomap::OcTree *tree = dynamic_cast<octomap::OcTree*>(octomap_msgs::msgToMap(collision_map_));
                octomap::OcTree::leaf_iterator const end_it = tree->end_leafs();
                for(octomap::OcTree::leaf_iterator it = tree->begin_leafs(0); it != end_it; it++){
                    geometry_msgs::PointStamped p_in, p_out;
                    p_in.header.frame_id = map_frame;
                    p_in.point.x = it.getX();
                    p_in.point.y = it.getY();
                    p_in.point.z = it.getZ();

                    try{
                        tf_listener_.transformPoint(base_link_, p_in, p_out);
                        dmath::Vector3D obs(p_out.point.x, p_out.point.y, p_out.point.z);
                        if(magnitude(obs) < 500){
                            obstacles_lc.push_back(obs);
                        }
                    }catch(tf::TransformException &ex){
                        ROS_ERROR_STREAM("Exception trying to transform octomap: " << ex.what());
                    }
                }

                dmath::Vector3D Fs;
                //for(int i=0; i < obstacles_lc.size(); i++){
                //    Fs += get_potential_force(obstacles_lc[i], 0, 1.0, 1.0, 1.5);
                //}

                dmath::Vector3D g = goal_lc_;
                Fs += get_potential_force(g, 200, 0, 1.5, 1);

                dmath::Vector3D vel = Fs * force;
                cmd.linear.x = vel.x;
                //cmd.linear.y = vel.x;
                //cmd.linear.z = vel.z;

                cmd_pub_.publish(cmd);
            }
            r.sleep();
            ros::spinOnce();
        }
    }

private:
    dmath::Vector3D get_potential_force(const dmath::Vector3D &dest_lc, double A = 1, double B = 1, double n = 1, double m = 1){
        dmath::Vector3D u = dest_lc;
        u = normalize(u);

        const double d = magnitude(dest_lc);
        double U = 0;
        if(fabs(d) > dmath::tol){
            U = -A/pow(d, n) + B/pow(d, m);
        }

        return U * u;
    }

    void obstacleCallback(const octomap_msgs::OctomapPtr &obs_msg){
        collision_map_ = *obs_msg;
    }

    void goalCallback(const geometry_msgs::PointStamped &goal_msg){
        geometry_msgs::PointStamped g_lc;
        try{
            tf_listener_.transformPoint(base_link_, goal_msg, g_lc);
            goal_lc_ = dmath::Vector3D(g_lc.point.x, g_lc.point.y, g_lc.point.z);
        }catch(tf::TransformException &ex){
            ROS_ERROR_STREAM("Exception trying to transform octomap: " << ex.what());
            goal_lc_ = dmath::Vector3D();
        }
    }

    octomap_msgs::Octomap collision_map_;
    ros::Publisher cmd_pub_;
    ros::Subscriber obs_sub_, goal_sub_;
    tf::TransformListener tf_listener_;
    std::string base_link_;
    dmath::Vector3D goal_lc_;
};

int main(int argc, char *argv[]){
    ros::init(argc, argv, "apf_planner");

    ros::NodeHandle node;
    ArtificialPotentialField apf(node);
    apf.spin();

    return 0;
}

<|endoftext|>


<commit_before>//
//  recursion.cpp
//  DS
//
//  Created by Rahul Goel on 7/26/17.
//  Copyright © 2017 Rahul Goel. All rights reserved.
//

#include "recursion.hpp"

//As Its not suggestable to return local variable outside the function So use this array in case you need to return Array or list of elements
static int *arrayTmp;

int recursion_SumOfNumbersFromList(int *arr, int size){
    if (size <= 0){
        return arr[size];
    }else{
        return arr[size] + recursion_SumOfNumbersFromList(arr,size - 1);
    }
}

int recursion_SumOfNNaturalNumbers(int upto){
    if (upto <= 0){
        return 0;
    }else{
        return upto + recursion_SumOfNNaturalNumbers(upto - 1);
    }
}

int recursion_numberOfChars( char *str){

    if (*str == '\0'){
        return 0;
    }
    else{
        return  1 + recursion_numberOfChars(str + 1);
    }
}

void recursion_reverseOfString(char *str, int index){
    if (str[index] == '\0'){
        return ;
    }else{
        recursion_reverseOfString(str, ++index);
        printf("%c",str[index]);
    }
}

int recursion_power(int number, int power){
    if (power <= 0){
        return 1;
    }else{
        return number*recursion_power(number, power-1);
    }
}

int* recursion_getAllWordsFromSentence(char *str,char *ptr){

    //In case sentence ends
    if (*str == '\0'){
        return arrayTmp;
    }else{

        //In case of Sapce
        if (*str == ' '){

        }
        return recursion_getAllWordsFromSentence(str + 1,ptr);
    }

    return arrayTmp;
}
<commit_msg>changes for recursion added<commit_after>//
//  recursion.cpp
//  DS
//
//  Created by Rahul Goel on 7/26/17.
//  Copyright © 2017 Rahul Goel. All rights reserved.
//

#include "recursion.hpp"

//As Its not suggestable to return local variable outside the function So use this array in case you need to return Array or list of elements
static int *arrayTmp;

int recursion_SumOfNumbersFromList(int *arr, int size){
    if (size <= 0){
        return arr[size];
    }else{
        return arr[size] + recursion_SumOfNumbersFromList(arr,size - 1);
    }
}

int recursion_SumOfNNaturalNumbers(int upto){
    if (upto <= 0){
        return 0;
    }else{
        return upto + recursion_SumOfNNaturalNumbers(upto - 1);
    }
}

int recursion_numberOfChars( char *str){

    if (*str == '\0'){
        return 0;
    }
    else{
        return  1 + recursion_numberOfChars(str + 1);
    }
}

void recursion_reverseOfString(char *str, int index){
    if (str[index] == '\0'){
        return ;
    }else{
        recursion_reverseOfString(str, ++index);
        printf("%c",str[index]);
    }
}

int recursion_power(int number, int power){
    if (power <= 0){ //In Case pow(number,0) = 1
        return 1;
    }else{
        return number*recursion_power(number, power-1);
    }
}

int* recursion_getAllWordsFromSentence(char *str,char *ptr){

    //In case sentence ends
    if (*str == '\0'){
        return arrayTmp;
    }else{

        //In case of Space
        if (*str == ' '){

        }
        return recursion_getAllWordsFromSentence(str ,ptr+1);
    }

    return arrayTmp;
}

void reverseWordAndAddItToArray(char *str,int length){

}

<|endoftext|>