<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#include "condor_common.h"
#include "condor_classad.h"
#include "condor_debug.h"
#include "../condor_daemon_core.V6/condor_daemon_core.h"
#include "condor_attributes.h"
#include "condor_syscall_mode.h"
#include "exit.h"
#include "vanilla_proc.h"
#include "starter.h"
#include "syscall_numbers.h"
#include "directory.h"

extern CStarter *Starter;

VanillaProc::VanillaProc( ClassAd *jobAd ) : OsProc()
{
	family = NULL;
	filetrans = NULL;
    JobAd = jobAd;
	snapshot_tid = -1;
	shadowupdate_tid = -1;
	shadowsock = NULL;
	TransferAtVacate = false;
}

VanillaProc::~VanillaProc()
{
	if (family) {
		delete family;
	}

	if (filetrans) {
		delete filetrans;
	}

	if ( snapshot_tid != -1 ) {
		daemonCore->Cancel_Timer(snapshot_tid);
		snapshot_tid = -1;
	}

	if ( shadowupdate_tid != -1 ) {
		daemonCore->Cancel_Timer(shadowupdate_tid);
		shadowupdate_tid = -1;
	}

	if ( shadowsock ) {
		delete shadowsock;
	}

}

int
VanillaProc::TransferCompleted(FileTransfer *ftrans)
{
	char tmp[_POSIX_ARG_MAX];

	// Make certain the file transfer succeeded.  It is
	// completely wrong to ASSERT here if it failed since
	// we are a _multi_ starter -- it is just a quick hack
	// to get WinNT out the door.
	if ( ftrans ) {
		ASSERT( (ftrans->GetInfo()).success );
	}

	// vanilla jobs, unlike standard jobs, are allowed to run
	// shell scripts (or as is the case on NT, batch files).  so
	// edit the ad so we start up a shell, pass the executable as
	// an argument to the shell, if we are asked to run a .bat file.
#ifdef WIN32
	char argstmp[_POSIX_ARG_MAX];
	char systemshell[_POSIX_PATH_MAX];

	int joblen = strlen(jobtmp);
	if ( joblen > 5 &&
			( (stricmp(".bat",&(jobtmp[joblen-4])) == 0) ||
			  (stricmp(".cmd",&(jobtmp[joblen-4])) == 0) ) ) {
		// executable name ends in .bat or .cmd

		// first change executable to be cmd.exe
		::GetSystemDirectory(systemshell,MAX_PATH);
		sprintf(tmp,"%s=\"%s\\cmd.exe\"",ATTR_JOB_CMD,systemshell);
		JobAd->InsertOrUpdate(tmp);

		// now change arguments to include name of program cmd.exe
		// should run
		if (JobAd->LookupString(ATTR_JOB_ARGUMENTS,argstmp) != 1) {
			argstmp[0] = '\0';
		}
		// also pass /Q and /C arguments to cmd.exe, to tell it we do not
		// want an interactive shell -- just run the command and exit
		sprintf ( tmp, "%s=\"/Q /C condor_exec.bat %s\"",
				  ATTR_JOB_ARGUMENTS, argstmp );
		JobAd->InsertOrUpdate(tmp);

		// finally we must rename file condor_exec to condor_exec.bat
		rename(CONDOR_EXEC,"condor_exec.bat");

		dprintf(D_FULLDEBUG,
			"Executable is .bat, so running %s\\cmd.exe %s\n",
			systemshell,tmp);

	}	// end of if executable name ends in .bat
#endif

	// call OsProc to start it up; if success, create the ProcFamily
	if (OsProc::StartJob()) {

		// success!  create a ProcFamily
		family = new ProcFamily(JobPid,PRIV_USER);
		ASSERT(family);

#ifdef WIN32
		// we only support running jobs as user nobody for the first pass
		char nobody_login[60];
		sprintf(nobody_login,"condor-run-dir_%d",daemonCore->getpid());
		// set ProcFamily to find decendants via a common login name
		family->setFamilyLogin(nobody_login);
#endif

		// take a snapshot of the family every 15 seconds
		snapshot_tid = daemonCore->Register_Timer(2, 15,
			(TimerHandlercpp)&ProcFamily::takesnapshot,
			"ProcFamily::takesnapshot", family);

		// update the shadow every 20 minutes.  years of study say
		// this is the optimal value. :^).
		shadowupdate_tid = daemonCore->Register_Timer(8,(20*60)+6,
			(TimerHandlercpp)&VanillaProc::UpdateShadow,
			"VanillaProc::UpdateShadow", this);

		return TRUE;
	} else {
		// failure
		// return FALSE;

		// DREADFUL HACK:  for now, if we fail to start the job,
		// do an EXCEPT.  Of course this is wrong for a multi-starter,
		// this is just a quick hack to get the first pass at WinNT
		// Condor out the door.
		EXCEPT("Failed to start job");

	}

	return FALSE;
}

int
VanillaProc::StartJob()
{
	int ret_value;
	char tmp[_POSIX_ARG_MAX];

	dprintf(D_FULLDEBUG,"in VanillaProc::StartJob()\n");

	// for now, stash the executable in jobtmp, and switch the ad to
	// say the executable is condor_exec
	jobtmp[0] = '\0';
	JobAd->LookupString(ATTR_JOB_CMD,jobtmp);
	sprintf(tmp,"%s=\"%s\"",ATTR_JOB_CMD,CONDOR_EXEC);
	JobAd->InsertOrUpdate(tmp);

	// setup value for TransferAtVacate
	tmp[0] = '\0';
	JobAd->LookupString(ATTR_TRANSFER_FILES,tmp);
		// if set to "ALWAYS", then set TransferAtVacate to true
	if ( tmp[0]=='a' || tmp[0]=='A' ) {
		TransferAtVacate = true;
	}

	// taken from OsProc::StartJob for now, here we create the user and
	// set the acls on the starter directory _before_ we start placing
	// files in there.
	{
		// we only support running jobs as user nobody for the first pass
		char nobody_login[60];
		sprintf(nobody_login,"condor-run-dir_%d",daemonCore->getpid());
		init_user_nobody_loginname(nobody_login);
		init_user_ids("nobody");
		{
			perm dirperm;
			dirperm.init(nobody_login);
			int ret_val = dirperm.set_acls(Starter->GetWorkingDir());
			if ( ret_val < 0 ) {
				EXCEPT("UNABLE TO SET PREMISSIONS ON STARTER DIRECTORY");
			}
		}
	}

	// if requested in the jobad, transfer files over
	char TransSock[40];
	if (JobAd->LookupString(ATTR_TRANSFER_SOCKET, TransSock) == 1) {
		char buf[ATTRLIST_MAX_EXPRESSION];

		// reset iwd of job to the starter directory
		sprintf(buf,"%s=\"%s\"",ATTR_JOB_IWD,Starter->GetWorkingDir());
		JobAd->InsertOrUpdate(buf);

		filetrans = new FileTransfer();
		ASSERT( filetrans->Init(JobAd) );
		filetrans->RegisterCallback(
			(FileTransferHandler)&VanillaProc::TransferCompleted,this);
		ret_value = filetrans->DownloadFiles(false); // do not block
	} else {
		// no file transfer desired, thus the file transfer is "done"
		ret_value = TransferCompleted(NULL);
	}

	return ret_value;
}

int
VanillaProc::UpdateShadow()
{
	unsigned long max_image;
	long sys_time, user_time;
	unsigned int execsz = 0;
	ClassAd ad;
	char buf[200];

	if ( ShadowAddr[0] == '\0' ) {
		// we do not have an address for the shadow
		return FALSE;
	}

	if ( !family ) {
		// we do not have a job family beneath us
		return FALSE;
	}

	if ( !shadowsock ) {
		shadowsock = new SafeSock();
		ASSERT(shadowsock);
		shadowsock->connect(ShadowAddr);
	}

	family->get_cpu_usage(sys_time,user_time);
	family->get_max_imagesize(max_image);

	// create an ad
	sprintf(buf,"%s=%lu",ATTR_JOB_REMOTE_SYS_CPU,sys_time);
	ad.InsertOrUpdate(buf);
	sprintf(buf,"%s=%lu",ATTR_JOB_REMOTE_USER_CPU,user_time);
	ad.InsertOrUpdate(buf);
	sprintf(buf,"%s=%lu",ATTR_IMAGE_SIZE,max_image);
	ad.InsertOrUpdate(buf);

	// if there is a filetrans object, then let's send the current
	// size of the starter execute directory back to the shadow.  this
	// way the ATTR_DISK_USAGE will be updated, and we won't end
	// up on a machine without enough local disk space.
	if ( filetrans ) {
		Directory starter_dir(Starter->GetWorkingDir(),PRIV_USER);
		execsz = starter_dir.GetDirectorySize();
		sprintf(buf,"%s=%u",ATTR_DISK_USAGE, (execsz+1023)/1024 );
		ad.InsertOrUpdate(buf);
	}

	// send it to the shadow
	dprintf(D_FULLDEBUG,
		"Sending shadow update, user_time=%lu, image=%lu, execsz=%u\n",
		user_time,max_image,execsz);
	shadowsock->snd_int(SHADOW_UPDATEINFO,FALSE);
	ad.put(*shadowsock);
	shadowsock->end_of_message();

	return TRUE;
}

int
VanillaProc::JobExit(int pid, int status)
{
	dprintf(D_FULLDEBUG,"in VanillaProc::JobExit()\n");

	// ok, the parent exited.  make certain all decendants are dead.
	family->hardkill();

	// update the shadow one last time, then cancel timers & close sockets
	UpdateShadow();
	daemonCore->Cancel_Timer(snapshot_tid);
	daemonCore->Cancel_Timer(shadowupdate_tid);
	delete shadowsock;
	snapshot_tid = -1;
	shadowupdate_tid = -1;
	shadowsock = NULL;

	// transfer output files back if requested job really finished.
	// may as well do this in the foreground,
	// since we do not want to be interrupted by anything short of a hardkill.
	if ( filetrans &&
		((Requested_Exit != TRUE) || TransferAtVacate) ) {
		// The user job may have created files only readable by the user,
		// so set_user_priv here.
		bool final_transfer = (Requested_Exit != TRUE);	// true if job exited on its own
		priv_state saved_priv = set_user_priv();
		ASSERT( filetrans->UploadFiles(true, final_transfer) );	// this will block
		set_priv(saved_priv);
	}

	if ( OsProc::JobExit(pid,status) ) {
		return 1;
	}

	return 0;
}

void
VanillaProc::Suspend()
{
	dprintf(D_FULLDEBUG,"in VanillaProc::Suspend()\n");

	// suspend any filetransfer activity
	if ( filetrans ) {
		filetrans->Suspend();
	}

	// suspend the user job
	if ( family ) {
		family->suspend();
	}

	// set our flag
	job_suspended = TRUE;
}

void
VanillaProc::Continue()
{
	dprintf(D_FULLDEBUG,"in VanillaProc::Continue()\n");

	// resume any filetransfer activity
	if ( filetrans ) {
		filetrans->Continue();
	}

	// resume user job
	if ( family ) {
		family->resume();
	}

	// set our flag
	job_suspended = FALSE;
}

bool
VanillaProc::ShutdownGraceful()
{
	dprintf(D_FULLDEBUG,"in VanillaProc::ShutdownGraceful()\n");

	if ( !family ) {
		// there is no process family yet, probably because we are still
		// transferring files.  just return true to say we're all done,
		// and that way the starter class will simply delete us and the
		// FileTransfer destructor will clean up.
		return true;
	}

	// take a snapshot before we softkill the parent job process.
	// this helps ensure that if the parent exits without killing
	// the kids, our JobExit() handler will get em all.
	family->takesnapshot();

	// now softkill the parent job process.  this is exactly what
	// OsProc::ShutdownGraceful does, so call it.
	return OsProc::ShutdownGraceful();
}

bool
VanillaProc::ShutdownFast()
{
	dprintf(D_FULLDEBUG,"in VanillaProc::ShutdownFast()\n");

	if ( !family ) {
		// there is no process family yet, probably because we are still
		// transferring files.  just return true to say we're all done,
		// and that way the starter class will simply delete us and the
		// FileTransfer destructor will clean up.
		return true;
	}

	// We purposely do not do a SIGCONT here, since there is no sense
	// in potentially swapping the job back into memory if our next
	// step is to hard kill it.

	// Despite what the user wants, do not transfer back any files
	// on a ShutdownFast.
	TransferAtVacate = false;

	Requested_Exit = TRUE;
	family->hardkill();
	return false;	// shutdown is pending, so return false
}

<commit_msg>Added #ifdef WIN32 around code that was only for (you guessed it) WIN32.<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#include "condor_common.h"
#include "condor_classad.h"
#include "condor_debug.h"
#include "../condor_daemon_core.V6/condor_daemon_core.h"
#include "condor_attributes.h"
#include "condor_syscall_mode.h"
#include "exit.h"
#include "vanilla_proc.h"
#include "starter.h"
#include "syscall_numbers.h"
#include "directory.h"

extern CStarter *Starter;

VanillaProc::VanillaProc( ClassAd *jobAd ) : OsProc()
{
	family = NULL;
	filetrans = NULL;
    JobAd = jobAd;
	snapshot_tid = -1;
	shadowupdate_tid = -1;
	shadowsock = NULL;
	TransferAtVacate = false;
}

VanillaProc::~VanillaProc()
{
	if (family) {
		delete family;
	}

	if (filetrans) {
		delete filetrans;
	}

	if ( snapshot_tid != -1 ) {
		daemonCore->Cancel_Timer(snapshot_tid);
		snapshot_tid = -1;
	}

	if ( shadowupdate_tid != -1 ) {
		daemonCore->Cancel_Timer(shadowupdate_tid);
		shadowupdate_tid = -1;
	}

	if ( shadowsock ) {
		delete shadowsock;
	}

}

int
VanillaProc::TransferCompleted(FileTransfer *ftrans)
{
	char tmp[_POSIX_ARG_MAX];

	// Make certain the file transfer succeeded.  It is
	// completely wrong to ASSERT here if it failed since
	// we are a _multi_ starter -- it is just a quick hack
	// to get WinNT out the door.
	if ( ftrans ) {
		ASSERT( (ftrans->GetInfo()).success );
	}

	// vanilla jobs, unlike standard jobs, are allowed to run
	// shell scripts (or as is the case on NT, batch files).  so
	// edit the ad so we start up a shell, pass the executable as
	// an argument to the shell, if we are asked to run a .bat file.
#ifdef WIN32
	char argstmp[_POSIX_ARG_MAX];
	char systemshell[_POSIX_PATH_MAX];

	int joblen = strlen(jobtmp);
	if ( joblen > 5 &&
			( (stricmp(".bat",&(jobtmp[joblen-4])) == 0) ||
			  (stricmp(".cmd",&(jobtmp[joblen-4])) == 0) ) ) {
		// executable name ends in .bat or .cmd

		// first change executable to be cmd.exe
		::GetSystemDirectory(systemshell,MAX_PATH);
		sprintf(tmp,"%s=\"%s\\cmd.exe\"",ATTR_JOB_CMD,systemshell);
		JobAd->InsertOrUpdate(tmp);

		// now change arguments to include name of program cmd.exe
		// should run
		if (JobAd->LookupString(ATTR_JOB_ARGUMENTS,argstmp) != 1) {
			argstmp[0] = '\0';
		}
		// also pass /Q and /C arguments to cmd.exe, to tell it we do not
		// want an interactive shell -- just run the command and exit
		sprintf ( tmp, "%s=\"/Q /C condor_exec.bat %s\"",
				  ATTR_JOB_ARGUMENTS, argstmp );
		JobAd->InsertOrUpdate(tmp);

		// finally we must rename file condor_exec to condor_exec.bat
		rename(CONDOR_EXEC,"condor_exec.bat");

		dprintf(D_FULLDEBUG,
			"Executable is .bat, so running %s\\cmd.exe %s\n",
			systemshell,tmp);

	}	// end of if executable name ends in .bat
#endif

	// call OsProc to start it up; if success, create the ProcFamily
	if (OsProc::StartJob()) {

		// success!  create a ProcFamily
		family = new ProcFamily(JobPid,PRIV_USER);
		ASSERT(family);

#ifdef WIN32
		// we only support running jobs as user nobody for the first pass
		char nobody_login[60];
		sprintf(nobody_login,"condor-run-dir_%d",daemonCore->getpid());
		// set ProcFamily to find decendants via a common login name
		family->setFamilyLogin(nobody_login);
#endif

		// take a snapshot of the family every 15 seconds
		snapshot_tid = daemonCore->Register_Timer(2, 15,
			(TimerHandlercpp)&ProcFamily::takesnapshot,
			"ProcFamily::takesnapshot", family);

		// update the shadow every 20 minutes.  years of study say
		// this is the optimal value. :^).
		shadowupdate_tid = daemonCore->Register_Timer(8,(20*60)+6,
			(TimerHandlercpp)&VanillaProc::UpdateShadow,
			"VanillaProc::UpdateShadow", this);

		return TRUE;
	} else {
		// failure
		// return FALSE;

		// DREADFUL HACK:  for now, if we fail to start the job,
		// do an EXCEPT.  Of course this is wrong for a multi-starter,
		// this is just a quick hack to get the first pass at WinNT
		// Condor out the door.
		EXCEPT("Failed to start job");

	}

	return FALSE;
}

int
VanillaProc::StartJob()
{
	int ret_value;
	char tmp[_POSIX_ARG_MAX];

	dprintf(D_FULLDEBUG,"in VanillaProc::StartJob()\n");

	// for now, stash the executable in jobtmp, and switch the ad to
	// say the executable is condor_exec
	jobtmp[0] = '\0';
	JobAd->LookupString(ATTR_JOB_CMD,jobtmp);
	sprintf(tmp,"%s=\"%s\"",ATTR_JOB_CMD,CONDOR_EXEC);
	JobAd->InsertOrUpdate(tmp);

	// setup value for TransferAtVacate
	tmp[0] = '\0';
	JobAd->LookupString(ATTR_TRANSFER_FILES,tmp);
		// if set to "ALWAYS", then set TransferAtVacate to true
	if ( tmp[0]=='a' || tmp[0]=='A' ) {
		TransferAtVacate = true;
	}

#ifdef WIN32
	// taken from OsProc::StartJob for now, here we create the user and
	// set the acls on the starter directory _before_ we start placing
	// files in there.
	{
		// we only support running jobs as user nobody for the first pass
		char nobody_login[60];
		sprintf(nobody_login,"condor-run-dir_%d",daemonCore->getpid());
		init_user_nobody_loginname(nobody_login);
		init_user_ids("nobody");
		{
			perm dirperm;
			dirperm.init(nobody_login);
			int ret_val = dirperm.set_acls(Starter->GetWorkingDir());
			if ( ret_val < 0 ) {
				EXCEPT("UNABLE TO SET PREMISSIONS ON STARTER DIRECTORY");
			}
		}
	}
#endif

	// if requested in the jobad, transfer files over
	char TransSock[40];
	if (JobAd->LookupString(ATTR_TRANSFER_SOCKET, TransSock) == 1) {
		char buf[ATTRLIST_MAX_EXPRESSION];

		// reset iwd of job to the starter directory
		sprintf(buf,"%s=\"%s\"",ATTR_JOB_IWD,Starter->GetWorkingDir());
		JobAd->InsertOrUpdate(buf);

		filetrans = new FileTransfer();
		ASSERT( filetrans->Init(JobAd) );
		filetrans->RegisterCallback(
			(FileTransferHandler)&VanillaProc::TransferCompleted,this);
		ret_value = filetrans->DownloadFiles(false); // do not block
	} else {
		// no file transfer desired, thus the file transfer is "done"
		ret_value = TransferCompleted(NULL);
	}

	return ret_value;
}

int
VanillaProc::UpdateShadow()
{
	unsigned long max_image;
	long sys_time, user_time;
	unsigned int execsz = 0;
	ClassAd ad;
	char buf[200];

	if ( ShadowAddr[0] == '\0' ) {
		// we do not have an address for the shadow
		return FALSE;
	}

	if ( !family ) {
		// we do not have a job family beneath us
		return FALSE;
	}

	if ( !shadowsock ) {
		shadowsock = new SafeSock();
		ASSERT(shadowsock);
		shadowsock->connect(ShadowAddr);
	}

	family->get_cpu_usage(sys_time,user_time);
	family->get_max_imagesize(max_image);

	// create an ad
	sprintf(buf,"%s=%lu",ATTR_JOB_REMOTE_SYS_CPU,sys_time);
	ad.InsertOrUpdate(buf);
	sprintf(buf,"%s=%lu",ATTR_JOB_REMOTE_USER_CPU,user_time);
	ad.InsertOrUpdate(buf);
	sprintf(buf,"%s=%lu",ATTR_IMAGE_SIZE,max_image);
	ad.InsertOrUpdate(buf);

	// if there is a filetrans object, then let's send the current
	// size of the starter execute directory back to the shadow.  this
	// way the ATTR_DISK_USAGE will be updated, and we won't end
	// up on a machine without enough local disk space.
	if ( filetrans ) {
		Directory starter_dir(Starter->GetWorkingDir(),PRIV_USER);
		execsz = starter_dir.GetDirectorySize();
		sprintf(buf,"%s=%u",ATTR_DISK_USAGE, (execsz+1023)/1024 );
		ad.InsertOrUpdate(buf);
	}

	// send it to the shadow
	dprintf(D_FULLDEBUG,
		"Sending shadow update, user_time=%lu, image=%lu, execsz=%u\n",
		user_time,max_image,execsz);
	shadowsock->snd_int(SHADOW_UPDATEINFO,FALSE);
	ad.put(*shadowsock);
	shadowsock->end_of_message();

	return TRUE;
}

int
VanillaProc::JobExit(int pid, int status)
{
	dprintf(D_FULLDEBUG,"in VanillaProc::JobExit()\n");

	// ok, the parent exited.  make certain all decendants are dead.
	family->hardkill();

	// update the shadow one last time, then cancel timers & close sockets
	UpdateShadow();
	daemonCore->Cancel_Timer(snapshot_tid);
	daemonCore->Cancel_Timer(shadowupdate_tid);
	delete shadowsock;
	snapshot_tid = -1;
	shadowupdate_tid = -1;
	shadowsock = NULL;

	// transfer output files back if requested job really finished.
	// may as well do this in the foreground,
	// since we do not want to be interrupted by anything short of a hardkill.
	if ( filetrans &&
		((Requested_Exit != TRUE) || TransferAtVacate) ) {
		// The user job may have created files only readable by the user,
		// so set_user_priv here.
		// true if job exited on its own
		bool final_transfer = (Requested_Exit != TRUE);
		priv_state saved_priv = set_user_priv();
		// this will block
		ASSERT( filetrans->UploadFiles(true, final_transfer) );

		set_priv(saved_priv);
	}

	if ( OsProc::JobExit(pid,status) ) {
		return 1;
	}

	return 0;
}

void
VanillaProc::Suspend()
{
	dprintf(D_FULLDEBUG,"in VanillaProc::Suspend()\n");

	// suspend any filetransfer activity
	if ( filetrans ) {
		filetrans->Suspend();
	}

	// suspend the user job
	if ( family ) {
		family->suspend();
	}

	// set our flag
	job_suspended = TRUE;
}

void
VanillaProc::Continue()
{
	dprintf(D_FULLDEBUG,"in VanillaProc::Continue()\n");

	// resume any filetransfer activity
	if ( filetrans ) {
		filetrans->Continue();
	}

	// resume user job
	if ( family ) {
		family->resume();
	}

	// set our flag
	job_suspended = FALSE;
}

bool
VanillaProc::ShutdownGraceful()
{
	dprintf(D_FULLDEBUG,"in VanillaProc::ShutdownGraceful()\n");

	if ( !family ) {
		// there is no process family yet, probably because we are still
		// transferring files.  just return true to say we're all done,
		// and that way the starter class will simply delete us and the
		// FileTransfer destructor will clean up.
		return true;
	}

	// take a snapshot before we softkill the parent job process.
	// this helps ensure that if the parent exits without killing
	// the kids, our JobExit() handler will get em all.
	family->takesnapshot();

	// now softkill the parent job process.  this is exactly what
	// OsProc::ShutdownGraceful does, so call it.
	return OsProc::ShutdownGraceful();
}

bool
VanillaProc::ShutdownFast()
{
	dprintf(D_FULLDEBUG,"in VanillaProc::ShutdownFast()\n");

	if ( !family ) {
		// there is no process family yet, probably because we are still
		// transferring files.  just return true to say we're all done,
		// and that way the starter class will simply delete us and the
		// FileTransfer destructor will clean up.
		return true;
	}

	// We purposely do not do a SIGCONT here, since there is no sense
	// in potentially swapping the job back into memory if our next
	// step is to hard kill it.

	// Despite what the user wants, do not transfer back any files
	// on a ShutdownFast.
	TransferAtVacate = false;

	Requested_Exit = TRUE;
	family->hardkill();
	return false;	// shutdown is pending, so return false
}

<|endoftext|>


<commit_before>#ifndef MODIFIERNAME_HPP
#define MODIFIERNAME_HPP

#include "KeyCode.hpp"
#include "strlcpy_utf8.hpp"

namespace org_pqrs_Karabiner {
  class ModifierName {
  public:
    class Item {
    public:
      Item(void) {
        name_[0] = '\0';
      }

      Item(ModifierFlag modifierFlag, const char* name) : modifierFlag_(modifierFlag) {
        pqrs::strlcpy_utf8::strlcpy(name_, name, sizeof(name_));
      }

      Item(ModifierFlag modifierFlag, const uint32_t* name, size_t size) : modifierFlag_(modifierFlag) {
        char* tmp = new char[size + 1];
        {
          for (size_t i = 0; i < size; ++i) {
            tmp[i] = name[i];
          }
          tmp[size] = '\0';

          pqrs::strlcpy_utf8::strlcpy(name_, tmp, sizeof(name_));
        }
        delete[] tmp;
      }

      ModifierFlag getModifierFlag(void) const { return modifierFlag_; }
      const char* getName(void) const { return name_; }

    private:
      enum {
        MAXLEN = 32,
      };

      ModifierFlag modifierFlag_;
      char name_[MAXLEN];
    };
    DECLARE_VECTOR(Item);

    static void initialize(void) {
      clearVirtualModifiers();
    }

    static void clearVirtualModifiers(void);
    static void registerVirtualModifier(ModifierFlag modifierFlag, const uint32_t* name, size_t size);
    static const char* getName(ModifierFlag modifierFlag);

  private:
    static Vector_Item items_;
  };
}

#endif
<commit_msg>check args<commit_after>#ifndef MODIFIERNAME_HPP
#define MODIFIERNAME_HPP

#include "IOLogWrapper.hpp"
#include "KeyCode.hpp"
#include "strlcpy_utf8.hpp"

namespace org_pqrs_Karabiner {
  class ModifierName {
  public:
    class Item {
    public:
      Item(void) {
        name_[0] = '\0';
      }

      Item(ModifierFlag modifierFlag, const char* name) : modifierFlag_(modifierFlag) {
        if (name) {
          pqrs::strlcpy_utf8::strlcpy(name_, name, sizeof(name_));
        }
      }

      Item(ModifierFlag modifierFlag, const uint32_t* name, size_t size) : modifierFlag_(modifierFlag) {
        if (name) {
          char* tmp = new char[size + 1];
          if (! tmp) {
            IOLOG_ERROR("ModifierName: Failed to allocate: %p, %ld", name, size);
          } else {
            for (size_t i = 0; i < size; ++i) {
              tmp[i] = name[i];
            }
            tmp[size] = '\0';

            pqrs::strlcpy_utf8::strlcpy(name_, tmp, sizeof(name_));

            delete[] tmp;
          }
        }
      }

      ModifierFlag getModifierFlag(void) const { return modifierFlag_; }
      const char* getName(void) const { return name_; }

    private:
      enum {
        MAXLEN = 32,
      };

      ModifierFlag modifierFlag_;
      char name_[MAXLEN];
    };
    DECLARE_VECTOR(Item);

    static void initialize(void) {
      clearVirtualModifiers();
    }

    static void clearVirtualModifiers(void);
    static void registerVirtualModifier(ModifierFlag modifierFlag, const uint32_t* name, size_t size);
    static const char* getName(ModifierFlag modifierFlag);

  private:
    static Vector_Item items_;
  };
}

#endif
<|endoftext|>


<commit_before>/*
* Funambol is a mobile platform developed by Funambol, Inc.
* Copyright (C) 2008 Funambol, Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*
* You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
* 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by Funambol" logo. If the display of the logo is not reasonably
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by Funambol".
*/

/** @cond DEV */

#include "base/util/StringMap.h"

BEGIN_NAMESPACE

const static StringBuffer nullVal(NULL);

// Find the element in the StringMap with the given key.
int StringMap::findElement(const char *key) {

    KeyValuePair *e;
    int i=0;

    for (e=(KeyValuePair*)c.front(); e; e=(KeyValuePair*)c.next()) {
        if ( e->getKey() == key ) {
            return i;                   // item found
        }
        i++;
    }
    return -1;

}

// Add a new element to the StringMap, or modify an existent one
bool StringMap::put(const char *key, const char *val) {
    int index = findElement(key);
    if(index != -1) {
        ((KeyValuePair*)c[index])->setValue(val);
        return false;
    }
    else {
        c.add(KeyValuePair(key, val));
        return true;
    }
}

// Remove an element from the StringMap, if exists
bool StringMap::remove(const char *key) {
    int index = findElement(key);
    if(index != -1) {
        if(c.removeElementAt(index) != -1){
            return true;        // Success
        }
    }
    return false;               // Not found or failure
}

// Retrieve an element from the StringMap, if exists.
const StringBuffer& StringMap::get(const char *key) {
    int index = findElement(key);
    if(index != -1) {
        return ((KeyValuePair*)c[index])->getValue();
    }
    else {
        return nullVal;
    }
}

END_NAMESPACE

/** @endcond */
<commit_msg>Fixed build error on gcc.<commit_after>/*
* Funambol is a mobile platform developed by Funambol, Inc.
* Copyright (C) 2008 Funambol, Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*
* You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
* 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by Funambol" logo. If the display of the logo is not reasonably
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by Funambol".
*/

/** @cond DEV */

#include "base/util/StringMap.h"

BEGIN_NAMESPACE

const static StringBuffer nullVal(NULL);

// Find the element in the StringMap with the given key.
int StringMap::findElement(const char *key) {

    KeyValuePair *e;
    int i=0;

    for (e=(KeyValuePair*)c.front(); e; e=(KeyValuePair*)c.next()) {
        if ( e->getKey() == key ) {
            return i;                   // item found
        }
        i++;
    }
    return -1;

}

// Add a new element to the StringMap, or modify an existent one
bool StringMap::put(const char *key, const char *val) {
    int index = findElement(key);
    if(index != -1) {
        ((KeyValuePair*)c[index])->setValue(val);
        return false;
    }
    else {
        KeyValuePair kv(key, val);
        c.add(kv);
        return true;
    }
}

// Remove an element from the StringMap, if exists
bool StringMap::remove(const char *key) {
    int index = findElement(key);
    if(index != -1) {
        if(c.removeElementAt(index) != -1){
            return true;        // Success
        }
    }
    return false;               // Not found or failure
}

// Retrieve an element from the StringMap, if exists.
const StringBuffer& StringMap::get(const char *key) {
    int index = findElement(key);
    if(index != -1) {
        return ((KeyValuePair*)c[index])->getValue();
    }
    else {
        return nullVal;
    }
}

END_NAMESPACE

/** @endcond */
<|endoftext|>


<commit_before>/*
 * RStudioAPI.cpp
 *
 * Copyright (C) 2009-16 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/Macros.hpp>
#include <core/Algorithm.hpp>
#include <core/Debug.hpp>
#include <core/Error.hpp>
#include <core/Exec.hpp>

#include <r/RSexp.hpp>
#include <r/RRoutines.hpp>
#include <r/RExec.hpp>
#include <r/RJson.hpp>
#include <r/session/RSessionUtils.hpp>

#include <session/SessionModuleContext.hpp>
#include <session/projects/SessionProjects.hpp>

using namespace rstudio::core;

namespace rstudio {
namespace session {
namespace modules {
namespace rstudioapi {

namespace {
module_context::WaitForMethodFunction s_waitForShowDialog;
module_context::WaitForMethodFunction s_waitForOpenFileDialog;
} // end anonymous namespace

ClientEvent showDialogEvent(const std::string& title,
                            const std::string& message,
                            int dialogIcon,
                            bool prompt,
                            const std::string& promptDefault,
                            const std::string& ok,
                            const std::string& cancel,
                            const std::string& url)
{
   json::Object data;
   data["title"] = title;
   data["message"] = message;
   data["dialogIcon"] = dialogIcon;
   data["prompt"] = prompt;
   data["default"] = promptDefault;
   data["ok"] = ok;
   data["cancel"] = cancel;
   data["url"] = url;
   return ClientEvent(client_events::kRStudioAPIShowDialog, data);
}

SEXP rs_showDialog(SEXP titleSEXP,
                   SEXP messageSEXP,
                   SEXP dialogIconSEXP,
                   SEXP promptSEXP,
                   SEXP promptDefaultSEXP,
                   SEXP okSEXP,
                   SEXP cancelSEXP,
                   SEXP urlSEXP)
{
   try
   {
      std::string title = r::sexp::asString(titleSEXP);
      std::string message = r::sexp::asString(messageSEXP);
      int dialogIcon = r::sexp::asInteger(dialogIconSEXP);
      bool prompt = r::sexp::asLogical(promptSEXP);
      std::string promptDefault = r::sexp::asString(promptDefaultSEXP);
      std::string ok = r::sexp::asString(okSEXP);
      std::string cancel = r::sexp::asString(cancelSEXP);
      std::string url = r::sexp::asString(urlSEXP);

      ClientEvent event = showDialogEvent(
         title,
         message,
         dialogIcon,
         prompt,
         promptDefault,
         ok,
         cancel,
         url);

      // wait for rstudioapi_show_dialog_completed
      json::JsonRpcRequest request;
      if (!s_waitForShowDialog(&request, event))
      {
         return R_NilValue;
      }

      if (dialogIcon == 4 && !request.params[1].is_null()) {
         bool result;
         Error error = json::readParam(request.params, 1, &result);
         if (error)
         {
            LOG_ERROR(error);
            return R_NilValue;
         }

         r::sexp::Protect rProtect;
         return r::sexp::create(result, &rProtect);
      }
      else if (!request.params[0].is_null())
      {
         std::string promptValue;
         Error error = json::readParam(request.params, 0, &promptValue);
         if (error)
         {
            LOG_ERROR(error);
            return R_NilValue;
         }

         r::sexp::Protect rProtect;
         return r::sexp::create(promptValue, &rProtect);
      }
   }
   CATCH_UNEXPECTED_EXCEPTION

   return R_NilValue;
}

SEXP rs_openFileDialog(SEXP typeSEXP,
                       SEXP captionSEXP,
                       SEXP labelSEXP,
                       SEXP pathSEXP,
                       SEXP filterSEXP,
                       SEXP existingSEXP)
{
   // extract components
   int type = r::sexp::asInteger(typeSEXP);
   std::string caption = r::sexp::asString(captionSEXP);
   std::string label = r::sexp::asString(labelSEXP);
   std::string path = r::sexp::asString(pathSEXP);
   std::string filter = r::sexp::asString(filterSEXP);
   bool existing = r::sexp::asLogical(existingSEXP);

   // default to all files when filter is empty
   if (filter.empty())
      filter = "All Files (*)";

   // when path is empty, use project path if available, user home path
   // otherwise
   FilePath filePath;
   if (path.empty())
   {
      if (projects::projectContext().hasProject())
         filePath = projects::projectContext().directory();
      else
         filePath = module_context::userHomePath();
   }
   else
   {
      filePath = module_context::resolveAliasedPath(path);
   }

   json::Object data;
   data["type"] = type;
   data["caption"] = caption;
   data["label"] = label;
   data["file"] = module_context::createFileSystemItem(filePath);
   data["filter"] = filter;
   data["existing"] = existing;
   ClientEvent event(client_events::kOpenFileDialog, data);

   json::JsonRpcRequest request;
   if (!s_waitForOpenFileDialog(&request, event))
      return R_NilValue;

   std::string selection;
   Error error = json::readParams(request.params, &selection);
   if (error)
       LOG_ERROR(error);

   if (selection.empty())
      return R_NilValue;

   r::sexp::Protect protect;
   return r::sexp::create(selection, &protect);
}

Error initialize()
{
   using boost::bind;
   using namespace module_context;

   // register waitForMethod handler
   s_waitForShowDialog     = registerWaitForMethod("rstudioapi_show_dialog_completed");
   s_waitForOpenFileDialog = registerWaitForMethod("open_file_dialog_completed");

   RS_REGISTER_CALL_METHOD(rs_showDialog, 8);
   RS_REGISTER_CALL_METHOD(rs_openFileDialog, 6);

   return Success();
}

} // namespace connections
} // namespace modules
} // namespace session
} // namespace rstudio

<commit_msg>safeAsString for NULLs<commit_after>/*
 * RStudioAPI.cpp
 *
 * Copyright (C) 2009-16 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/Macros.hpp>
#include <core/Algorithm.hpp>
#include <core/Debug.hpp>
#include <core/Error.hpp>
#include <core/Exec.hpp>

#include <r/RSexp.hpp>
#include <r/RRoutines.hpp>
#include <r/RExec.hpp>
#include <r/RJson.hpp>
#include <r/session/RSessionUtils.hpp>

#include <session/SessionModuleContext.hpp>
#include <session/projects/SessionProjects.hpp>

using namespace rstudio::core;

namespace rstudio {
namespace session {
namespace modules {
namespace rstudioapi {

namespace {
module_context::WaitForMethodFunction s_waitForShowDialog;
module_context::WaitForMethodFunction s_waitForOpenFileDialog;
} // end anonymous namespace

ClientEvent showDialogEvent(const std::string& title,
                            const std::string& message,
                            int dialogIcon,
                            bool prompt,
                            const std::string& promptDefault,
                            const std::string& ok,
                            const std::string& cancel,
                            const std::string& url)
{
   json::Object data;
   data["title"] = title;
   data["message"] = message;
   data["dialogIcon"] = dialogIcon;
   data["prompt"] = prompt;
   data["default"] = promptDefault;
   data["ok"] = ok;
   data["cancel"] = cancel;
   data["url"] = url;
   return ClientEvent(client_events::kRStudioAPIShowDialog, data);
}

SEXP rs_showDialog(SEXP titleSEXP,
                   SEXP messageSEXP,
                   SEXP dialogIconSEXP,
                   SEXP promptSEXP,
                   SEXP promptDefaultSEXP,
                   SEXP okSEXP,
                   SEXP cancelSEXP,
                   SEXP urlSEXP)
{
   try
   {
      std::string title = r::sexp::asString(titleSEXP);
      std::string message = r::sexp::asString(messageSEXP);
      int dialogIcon = r::sexp::asInteger(dialogIconSEXP);
      bool prompt = r::sexp::asLogical(promptSEXP);
      std::string promptDefault = r::sexp::asString(promptDefaultSEXP);
      std::string ok = r::sexp::asString(okSEXP);
      std::string cancel = r::sexp::asString(cancelSEXP);
      std::string url = r::sexp::asString(urlSEXP);

      ClientEvent event = showDialogEvent(
         title,
         message,
         dialogIcon,
         prompt,
         promptDefault,
         ok,
         cancel,
         url);

      // wait for rstudioapi_show_dialog_completed
      json::JsonRpcRequest request;
      if (!s_waitForShowDialog(&request, event))
      {
         return R_NilValue;
      }

      if (dialogIcon == 4 && !request.params[1].is_null()) {
         bool result;
         Error error = json::readParam(request.params, 1, &result);
         if (error)
         {
            LOG_ERROR(error);
            return R_NilValue;
         }

         r::sexp::Protect rProtect;
         return r::sexp::create(result, &rProtect);
      }
      else if (!request.params[0].is_null())
      {
         std::string promptValue;
         Error error = json::readParam(request.params, 0, &promptValue);
         if (error)
         {
            LOG_ERROR(error);
            return R_NilValue;
         }

         r::sexp::Protect rProtect;
         return r::sexp::create(promptValue, &rProtect);
      }
   }
   CATCH_UNEXPECTED_EXCEPTION

   return R_NilValue;
}

SEXP rs_openFileDialog(SEXP typeSEXP,
                       SEXP captionSEXP,
                       SEXP labelSEXP,
                       SEXP pathSEXP,
                       SEXP filterSEXP,
                       SEXP existingSEXP)
{
   // extract components
   int type = r::sexp::asInteger(typeSEXP);
   std::string caption = r::sexp::asString(captionSEXP);
   std::string label = r::sexp::asString(labelSEXP);
   std::string path = r::sexp::safeAsString(pathSEXP);
   std::string filter = r::sexp::safeAsString(filterSEXP);
   bool existing = r::sexp::asLogical(existingSEXP);

   // default to all files when filter is empty
   if (filter.empty())
      filter = "All Files (*)";

   // when path is empty, use project path if available, user home path
   // otherwise
   FilePath filePath;
   if (path.empty())
   {
      if (projects::projectContext().hasProject())
         filePath = projects::projectContext().directory();
      else
         filePath = module_context::userHomePath();
   }
   else
   {
      filePath = module_context::resolveAliasedPath(path);
   }

   json::Object data;
   data["type"] = type;
   data["caption"] = caption;
   data["label"] = label;
   data["file"] = module_context::createFileSystemItem(filePath);
   data["filter"] = filter;
   data["existing"] = existing;
   ClientEvent event(client_events::kOpenFileDialog, data);

   json::JsonRpcRequest request;
   if (!s_waitForOpenFileDialog(&request, event))
      return R_NilValue;

   std::string selection;
   Error error = json::readParams(request.params, &selection);
   if (error)
       LOG_ERROR(error);

   if (selection.empty())
      return R_NilValue;

   r::sexp::Protect protect;
   return r::sexp::create(selection, &protect);
}

Error initialize()
{
   using boost::bind;
   using namespace module_context;

   // register waitForMethod handler
   s_waitForShowDialog     = registerWaitForMethod("rstudioapi_show_dialog_completed");
   s_waitForOpenFileDialog = registerWaitForMethod("open_file_dialog_completed");

   RS_REGISTER_CALL_METHOD(rs_showDialog, 8);
   RS_REGISTER_CALL_METHOD(rs_openFileDialog, 6);

   return Success();
}

} // namespace connections
} // namespace modules
} // namespace session
} // namespace rstudio

<|endoftext|>


<commit_before>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "fnord/test/unittest.h"
#include "fnord/protobuf/MessageEncoder.h"
#include "fnord/protobuf/MessagePrinter.h"
#include "tsdb/RecordSet.h"
#include "cstable/CSTableReader.h"
#include "cstable/CSTableBuilder.h"
#include "cstable/RecordMaterializer.h"
#include "cstable/StringColumnReader.h"

using namespace fnord;
using namespace fnord::cstable;
using namespace fnord::msg;

UNIT_TEST(RecordMaterializerTest);

TEST_CASE(RecordMaterializerTest, TestSimpleReMaterialization, [] () {
  String testfile = "/tmp/__fnord_testcstablematerialization.cst";

  msg::MessageSchemaField level1(
      1,
      "level1",
      msg::FieldType::OBJECT,
      0,
      true,
      false);

  msg::MessageSchemaField level1_str(
      2,
      "str",
      msg::FieldType::STRING,
      1024,
      true,
      false);

  level1.schema = new MessageSchema(
      "Level1",
      Vector<msg::MessageSchemaField> { level1_str });

  msg::MessageSchema schema(
      "TestSchema",
      Vector<msg::MessageSchemaField> { level1 });

  msg::MessageObject sobj;
  auto& l1_a = sobj.addChild(1);
  l1_a.addChild(2, "fnord1");
  l1_a.addChild(2, "fnord2");

  auto& l1_b = sobj.addChild(1);
  l1_b.addChild(2, "fnord3");
  l1_b.addChild(2, "fnord4");

  cstable::CSTableBuilder builder(&schema);
  builder.addRecord(sobj);
  builder.write(testfile);

  cstable::CSTableReader reader(testfile);
  cstable::RecordMaterializer materializer(&schema, &reader);

  msg::MessageObject robj;
  materializer.nextRecord(&robj);

  EXPECT_EQ(robj.asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject()[0].asString(), "fnord1");
  EXPECT_EQ(robj.asObject()[0].asObject()[1].asString(), "fnord2");
  EXPECT_EQ(robj.asObject()[1].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[1].asObject()[0].asString(), "fnord3");
  EXPECT_EQ(robj.asObject()[1].asObject()[1].asString(), "fnord4");
});

TEST_CASE(RecordMaterializerTest, TestSimpleReMaterializationWithNull, [] () {
  String testfile = "/tmp/__fnord_testcstablematerialization.cst";

  msg::MessageSchemaField level1(
      1,
      "level1",
      msg::FieldType::OBJECT,
      0,
      true,
      false);

  msg::MessageSchemaField level1_str(
      2,
      "str",
      msg::FieldType::STRING,
      1024,
      true,
      false);

  level1.schema = new MessageSchema(
      "Level1",
      Vector<msg::MessageSchemaField> { level1_str });

  msg::MessageSchema schema(
      "TestSchema",
      Vector<msg::MessageSchemaField> { level1 });

  msg::MessageObject sobj;
  auto& l1_a = sobj.addChild(1);
  l1_a.addChild(2, "fnord1");
  l1_a.addChild(2, "fnord2");

  auto& l1_b = sobj.addChild(1);

  auto& l1_c = sobj.addChild(1);
  l1_c.addChild(2, "fnord3");
  l1_c.addChild(2, "fnord4");

  cstable::CSTableBuilder builder(&schema);
  builder.addRecord(sobj);
  builder.write(testfile);

  cstable::CSTableReader reader(testfile);
  cstable::RecordMaterializer materializer(&schema, &reader);

  msg::MessageObject robj;
  materializer.nextRecord(&robj);

  EXPECT_EQ(robj.asObject().size(), 3);
  EXPECT_EQ(robj.asObject()[0].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject()[0].asString(), "fnord1");
  EXPECT_EQ(robj.asObject()[0].asObject()[1].asString(), "fnord2");
  EXPECT_EQ(robj.asObject()[1].asObject().size(), 0);
  EXPECT_EQ(robj.asObject()[2].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[2].asObject()[0].asString(), "fnord3");
  EXPECT_EQ(robj.asObject()[2].asObject()[1].asString(), "fnord4");
});

TEST_CASE(RecordMaterializerTest, TestReMatWithNonRepeatedParent, [] () {
  String testfile = "/tmp/__fnord_testcstablematerialization.cst";

  msg::MessageSchemaField level1(
      1,
      "level1",
      msg::FieldType::OBJECT,
      0,
      true,
      false);

  msg::MessageSchemaField level2(
      2,
      "level2",
      msg::FieldType::OBJECT,
      0,
      true,
      false);

  msg::MessageSchemaField level2_str(
      3,
      "str",
      msg::FieldType::STRING,
      1024,
      true,
      false);

  level2.schema = new MessageSchema(
      "Level2",
      Vector<msg::MessageSchemaField> { level2_str });

  level1.schema = new MessageSchema(
      "Level1",
      Vector<msg::MessageSchemaField> { level2 });

  msg::MessageSchema schema(
      "TestSchema",
      Vector<msg::MessageSchemaField> { level1 });

  msg::MessageObject sobj;
  auto& l1_a = sobj.addChild(1);
  auto& l2_aa = l1_a.addChild(2);
  l2_aa.addChild(3, "fnord1");
  l2_aa.addChild(3, "fnord2");
  auto& l2_ab = l1_a.addChild(2);
  l2_ab.addChild(3, "fnord3");
  l2_ab.addChild(3, "fnord4");
  auto& l1_b = sobj.addChild(1);
  auto& l1_c = sobj.addChild(1);
  auto& l2_ca = l1_c.addChild(2);
  auto& l2_cb = l1_c.addChild(2);
  l2_cb.addChild(3, "fnord5");
  l2_cb.addChild(3, "fnord6");

  cstable::CSTableBuilder builder(&schema);
  builder.addRecord(sobj);
  builder.write(testfile);

  cstable::CSTableReader reader(testfile);
  cstable::RecordMaterializer materializer(&schema, &reader);

  msg::MessageObject robj;
  materializer.nextRecord(&robj);

  EXPECT_EQ(robj.asObject().size(), 3);
  EXPECT_EQ(robj.asObject()[0].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject()[0].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject()[0].asObject()[0].asString(), "fnord1");
  EXPECT_EQ(robj.asObject()[0].asObject()[0].asObject()[1].asString(), "fnord2");
  EXPECT_EQ(robj.asObject()[0].asObject()[1].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject()[1].asObject()[0].asString(), "fnord3");
  EXPECT_EQ(robj.asObject()[0].asObject()[1].asObject()[1].asString(), "fnord4");
  EXPECT_EQ(robj.asObject()[1].asObject().size(), 0);
  EXPECT_EQ(robj.asObject()[2].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[2].asObject()[0].asObject().size(), 0);
  EXPECT_EQ(robj.asObject()[2].asObject()[1].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[2].asObject()[1].asObject()[0].asString(), "fnord5");
  EXPECT_EQ(robj.asObject()[2].asObject()[1].asObject()[1].asString(), "fnord6");
});
<commit_msg>remove dead include<commit_after>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "fnord/test/unittest.h"
#include "fnord/protobuf/MessageEncoder.h"
#include "fnord/protobuf/MessagePrinter.h"
#include "cstable/CSTableReader.h"
#include "cstable/CSTableBuilder.h"
#include "cstable/RecordMaterializer.h"
#include "cstable/StringColumnReader.h"

using namespace fnord;
using namespace fnord::cstable;
using namespace fnord::msg;

UNIT_TEST(RecordMaterializerTest);

TEST_CASE(RecordMaterializerTest, TestSimpleReMaterialization, [] () {
  String testfile = "/tmp/__fnord_testcstablematerialization.cst";

  msg::MessageSchemaField level1(
      1,
      "level1",
      msg::FieldType::OBJECT,
      0,
      true,
      false);

  msg::MessageSchemaField level1_str(
      2,
      "str",
      msg::FieldType::STRING,
      1024,
      true,
      false);

  level1.schema = new MessageSchema(
      "Level1",
      Vector<msg::MessageSchemaField> { level1_str });

  msg::MessageSchema schema(
      "TestSchema",
      Vector<msg::MessageSchemaField> { level1 });

  msg::MessageObject sobj;
  auto& l1_a = sobj.addChild(1);
  l1_a.addChild(2, "fnord1");
  l1_a.addChild(2, "fnord2");

  auto& l1_b = sobj.addChild(1);
  l1_b.addChild(2, "fnord3");
  l1_b.addChild(2, "fnord4");

  cstable::CSTableBuilder builder(&schema);
  builder.addRecord(sobj);
  builder.write(testfile);

  cstable::CSTableReader reader(testfile);
  cstable::RecordMaterializer materializer(&schema, &reader);

  msg::MessageObject robj;
  materializer.nextRecord(&robj);

  EXPECT_EQ(robj.asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject()[0].asString(), "fnord1");
  EXPECT_EQ(robj.asObject()[0].asObject()[1].asString(), "fnord2");
  EXPECT_EQ(robj.asObject()[1].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[1].asObject()[0].asString(), "fnord3");
  EXPECT_EQ(robj.asObject()[1].asObject()[1].asString(), "fnord4");
});

TEST_CASE(RecordMaterializerTest, TestSimpleReMaterializationWithNull, [] () {
  String testfile = "/tmp/__fnord_testcstablematerialization.cst";

  msg::MessageSchemaField level1(
      1,
      "level1",
      msg::FieldType::OBJECT,
      0,
      true,
      false);

  msg::MessageSchemaField level1_str(
      2,
      "str",
      msg::FieldType::STRING,
      1024,
      true,
      false);

  level1.schema = new MessageSchema(
      "Level1",
      Vector<msg::MessageSchemaField> { level1_str });

  msg::MessageSchema schema(
      "TestSchema",
      Vector<msg::MessageSchemaField> { level1 });

  msg::MessageObject sobj;
  auto& l1_a = sobj.addChild(1);
  l1_a.addChild(2, "fnord1");
  l1_a.addChild(2, "fnord2");

  auto& l1_b = sobj.addChild(1);

  auto& l1_c = sobj.addChild(1);
  l1_c.addChild(2, "fnord3");
  l1_c.addChild(2, "fnord4");

  cstable::CSTableBuilder builder(&schema);
  builder.addRecord(sobj);
  builder.write(testfile);

  cstable::CSTableReader reader(testfile);
  cstable::RecordMaterializer materializer(&schema, &reader);

  msg::MessageObject robj;
  materializer.nextRecord(&robj);

  EXPECT_EQ(robj.asObject().size(), 3);
  EXPECT_EQ(robj.asObject()[0].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject()[0].asString(), "fnord1");
  EXPECT_EQ(robj.asObject()[0].asObject()[1].asString(), "fnord2");
  EXPECT_EQ(robj.asObject()[1].asObject().size(), 0);
  EXPECT_EQ(robj.asObject()[2].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[2].asObject()[0].asString(), "fnord3");
  EXPECT_EQ(robj.asObject()[2].asObject()[1].asString(), "fnord4");
});

TEST_CASE(RecordMaterializerTest, TestReMatWithNonRepeatedParent, [] () {
  String testfile = "/tmp/__fnord_testcstablematerialization.cst";

  msg::MessageSchemaField level1(
      1,
      "level1",
      msg::FieldType::OBJECT,
      0,
      true,
      false);

  msg::MessageSchemaField level2(
      2,
      "level2",
      msg::FieldType::OBJECT,
      0,
      true,
      false);

  msg::MessageSchemaField level2_str(
      3,
      "str",
      msg::FieldType::STRING,
      1024,
      true,
      false);

  level2.schema = new MessageSchema(
      "Level2",
      Vector<msg::MessageSchemaField> { level2_str });

  level1.schema = new MessageSchema(
      "Level1",
      Vector<msg::MessageSchemaField> { level2 });

  msg::MessageSchema schema(
      "TestSchema",
      Vector<msg::MessageSchemaField> { level1 });

  msg::MessageObject sobj;
  auto& l1_a = sobj.addChild(1);
  auto& l2_aa = l1_a.addChild(2);
  l2_aa.addChild(3, "fnord1");
  l2_aa.addChild(3, "fnord2");
  auto& l2_ab = l1_a.addChild(2);
  l2_ab.addChild(3, "fnord3");
  l2_ab.addChild(3, "fnord4");
  auto& l1_b = sobj.addChild(1);
  auto& l1_c = sobj.addChild(1);
  auto& l2_ca = l1_c.addChild(2);
  auto& l2_cb = l1_c.addChild(2);
  l2_cb.addChild(3, "fnord5");
  l2_cb.addChild(3, "fnord6");

  cstable::CSTableBuilder builder(&schema);
  builder.addRecord(sobj);
  builder.write(testfile);

  cstable::CSTableReader reader(testfile);
  cstable::RecordMaterializer materializer(&schema, &reader);

  msg::MessageObject robj;
  materializer.nextRecord(&robj);

  EXPECT_EQ(robj.asObject().size(), 3);
  EXPECT_EQ(robj.asObject()[0].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject()[0].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject()[0].asObject()[0].asString(), "fnord1");
  EXPECT_EQ(robj.asObject()[0].asObject()[0].asObject()[1].asString(), "fnord2");
  EXPECT_EQ(robj.asObject()[0].asObject()[1].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[0].asObject()[1].asObject()[0].asString(), "fnord3");
  EXPECT_EQ(robj.asObject()[0].asObject()[1].asObject()[1].asString(), "fnord4");
  EXPECT_EQ(robj.asObject()[1].asObject().size(), 0);
  EXPECT_EQ(robj.asObject()[2].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[2].asObject()[0].asObject().size(), 0);
  EXPECT_EQ(robj.asObject()[2].asObject()[1].asObject().size(), 2);
  EXPECT_EQ(robj.asObject()[2].asObject()[1].asObject()[0].asString(), "fnord5");
  EXPECT_EQ(robj.asObject()[2].asObject()[1].asObject()[1].asString(), "fnord6");
});
<|endoftext|>


<commit_before>#include <stan/math/mix/mat.hpp>
#include <stan/math/prim/scal.hpp>
#include <stan/math/prim/mat.hpp>
#include <stan/math/prim/scal/prob/von_mises_lpdf.hpp>
#include <iostream>
/*
#include <gtest/gtest.h>
#include <test/unit/util.hpp>
#include <limits>
#include <string>
*/

int main() {
  double y = -0.8;
  double mu = 0.4;
  double kappa = 0;

  stan::math::von_mises_lpdf(y, mu, kappa);

  /*
    const double t = 1.0;
    Eigen::MatrixXd A(0, 0);
    Eigen::MatrixXd B(0, 0);

    Eigen::Matrix<var, -1, -1> C(0, 2);
    auto D = stan::math::scale_matrix_exp_multiply(t, A, C);
    std::cout << "rows: " << D.rows() << ", cols: " << D.cols() << std::endl;
    double nan = std::numeric_limits<double>::quiet_NaN();
    Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> y(1, 1);
    y << nan;

    stan::math::check_pos_definite("ciao", "y", y);
  */
}
<commit_msg>Remove spurious file<commit_after><|endoftext|>


<commit_before><commit_msg>[(UTC +8:00) 2017-12-30 23:22] Add our own object_pool, not tested.<commit_after><|endoftext|>


<commit_before>/* -*- Mode: C++; indent-tabs-mode: nil -*- */
#include "processor.h"

#include <cassert>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>

#include <schwa/msgpack.h>
#include <schwa/pool.h>
#include <schwa/port.h>
#include <schwa/unicode.h>

namespace io = schwa::io;
namespace mp = schwa::msgpack;

namespace schwa {
namespace mp_less {

const std::string Processor::SEP(std::string("\t") + port::DARK_GREY + "# ");
const std::string Processor::REPR_NIL("<nil>");
const std::string Processor::REPR_UNKNOWN("<UNKNOWN VALUE>");

Processor::Processor(void) : _indent(0), _out(nullptr) { }

Processor::~Processor(void) { }

std::ostream &
Processor::_write_indent(void) {
  for (unsigned int i = 0; i != _indent; ++i)
    *_out << "  ";
  return *_out;
}

void
Processor::_write_value(const mp::Value &value, const bool add_description) {
  if (is_bool(value.type)) {
    *_out << std::boolalpha << value.via._bool;
    if (add_description)
      *_out << SEP << "bool" << port::OFF;
  }
  else if (is_double(value.type)) {
    *_out << value.via._double;
    if (add_description)
      *_out << SEP << "double" << port::OFF;
  }
  else if (is_float(value.type)) {
    *_out << value.via._float;
    if (add_description)
      *_out << SEP << "float" << port::OFF;
  }
  else if (is_nil(value.type)) {
    *_out << REPR_NIL;
    if (add_description)
      *_out << SEP << "nil" << port::OFF;
  }
  else if (is_sint(value.type)) {
    *_out << "0x" << std::hex << value.via._int64 << std::dec;
    if (add_description)
      *_out << SEP << "int (" << value.via._int64 << ")" << port::OFF;
  }
  else if (is_uint(value.type)) {
    *_out << "0x" << std::hex << value.via._uint64 << std::dec;
    if (add_description)
      *_out << SEP << "uint (" << value.via._uint64 << ")" << port::OFF;
  }
  else if (is_str(value.type)) {
    const mp::Str &obj = *value.via._str;
    const UnicodeString s = UnicodeString::from_utf8(obj.data(), obj.nbytes());
    *_out << "\"" << s << "\"";
    if (add_description)
      *_out << SEP << "str (" << std::dec << obj.nbytes() << "B, " << s.size() << " code point(s))" << port::OFF;
  }
  else if (is_bin(value.type)) {
    const mp::Bin &obj = *value.via._bin;
    *_out << "\"";
    for (uint32_t i = 0; i != obj.nbytes(); ++i) {
      const char c = obj.data()[i];
      if (std::isprint(c))
        *_out << c;
      else
        *_out << "\\x" << std::hex << static_cast<unsigned int>(c) << std::dec;
    }
    *_out << "\"";
    if (add_description)
      *_out << SEP << "bin (" << std::dec << obj.nbytes() << "B)" << port::OFF;
  }
  else if (is_array(value.type)) {
    const mp::Array &obj = *value.via._array;
    _write_indent() << port::BOLD << "[" << port::OFF;
    if (obj.size() == 0)
      *_out << port::BOLD << "]" << port::OFF;
    if (add_description)
      *_out << SEP << "array (" << std::dec << obj.size() << ")" << port::OFF;
    if (obj.size() != 0) {
      *_out << "\n";
      ++_indent;
      for (uint32_t i = 0; i != obj.size(); ++i) {
        _write_indent();
        _write_value(obj[i]);
        *_out << ",\n";
      }
      --_indent;
      _write_indent() << port::BOLD << "]" << port::OFF;
    }
  }
  else if (is_map(value.type)) {
    const mp::Map &obj = *value.via._map;
    _write_indent() << port::BOLD << "{" << port::OFF;
    if (obj.size() == 0)
      *_out << port::BOLD << "}" << port::OFF;
    if (add_description)
      *_out << SEP << "map (" << std::dec << obj.size() << ")" << port::OFF;
    if (obj.size() != 0) {
      *_out << "\n";
      ++_indent;
      for (uint32_t i = 0; i != obj.size(); ++i) {
        const mp::Map::Pair &pair = obj[i];
        _write_indent();
        _write_value(pair.key, false);
        *_out << port::BOLD << ": " << port::OFF;
        _write_value(pair.value);
        *_out << ",\n";
      }
      --_indent;
      _write_indent() << port::BOLD << "}" << port::OFF;
    }
  }
  else if (is_ext(value.type)) {
    const mp::Ext &obj = *value.via._ext;
    *_out << "\"";
    for (uint32_t i = 0; i != obj.nbytes(); ++i) {
      const char c = obj.data()[i];
      if (std::isprint(c))
        *_out << std::dec << c;
      else
        *_out << "\\x" << std::hex << static_cast<unsigned int>(c);
    }
    *_out << "\"";
    if (add_description)
      *_out << SEP << "ext (" << std::dec << obj.nbytes() << "B)" << port::OFF;
  }
  else
    *_out << port::RED << REPR_UNKNOWN << port::OFF;
}

void
Processor::process(std::istream &in, std::ostream &out) {
  // Reset our state.
  _indent = 0;
  _out = &out;

  Pool pool(4096);
  while (in) {
    // Read in the next MessagePack object.
    const auto at_byte = in.tellg();
    mp::Value *value = nullptr;
    try {
      value = mp::read_dynamic(in, pool);
      assert(value != nullptr);
    }
    catch (mp::ReadError &e) {
      *_out << port::RED << "ReadError at byte " << std::dec << in.tellg() << ": " << e.what() << port::OFF << std::endl;
      break;
    }

    // Pretty-print the object.
    *_out << port::DARK_GREY << "# at byte " << at_byte << port::OFF << "\n";
    _write_value(*value);
    *_out << "\n";
  }
}

}  // namespace mp_less
}  // namespace schwa
<commit_msg>Corrected EOF detection in `mp-less`.<commit_after>/* -*- Mode: C++; indent-tabs-mode: nil -*- */
#include "processor.h"

#include <cassert>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>

#include <schwa/msgpack.h>
#include <schwa/pool.h>
#include <schwa/port.h>
#include <schwa/unicode.h>

namespace io = schwa::io;
namespace mp = schwa::msgpack;

namespace schwa {
namespace mp_less {

const std::string Processor::SEP(std::string("\t") + port::DARK_GREY + "# ");
const std::string Processor::REPR_NIL("<nil>");
const std::string Processor::REPR_UNKNOWN("<UNKNOWN VALUE>");

Processor::Processor(void) : _indent(0), _out(nullptr) { }

Processor::~Processor(void) { }

std::ostream &
Processor::_write_indent(void) {
  for (unsigned int i = 0; i != _indent; ++i)
    *_out << "  ";
  return *_out;
}

void
Processor::_write_value(const mp::Value &value, const bool add_description) {
  if (is_bool(value.type)) {
    *_out << std::boolalpha << value.via._bool;
    if (add_description)
      *_out << SEP << "bool" << port::OFF;
  }
  else if (is_double(value.type)) {
    *_out << value.via._double;
    if (add_description)
      *_out << SEP << "double" << port::OFF;
  }
  else if (is_float(value.type)) {
    *_out << value.via._float;
    if (add_description)
      *_out << SEP << "float" << port::OFF;
  }
  else if (is_nil(value.type)) {
    *_out << REPR_NIL;
    if (add_description)
      *_out << SEP << "nil" << port::OFF;
  }
  else if (is_sint(value.type)) {
    *_out << "0x" << std::hex << value.via._int64 << std::dec;
    if (add_description)
      *_out << SEP << "int (" << value.via._int64 << ")" << port::OFF;
  }
  else if (is_uint(value.type)) {
    *_out << "0x" << std::hex << value.via._uint64 << std::dec;
    if (add_description)
      *_out << SEP << "uint (" << value.via._uint64 << ")" << port::OFF;
  }
  else if (is_str(value.type)) {
    const mp::Str &obj = *value.via._str;
    const UnicodeString s = UnicodeString::from_utf8(obj.data(), obj.nbytes());
    *_out << "\"" << s << "\"";
    if (add_description)
      *_out << SEP << "str (" << std::dec << obj.nbytes() << "B, " << s.size() << " code point(s))" << port::OFF;
  }
  else if (is_bin(value.type)) {
    const mp::Bin &obj = *value.via._bin;
    *_out << "\"";
    for (uint32_t i = 0; i != obj.nbytes(); ++i) {
      const char c = obj.data()[i];
      if (std::isprint(c))
        *_out << c;
      else
        *_out << "\\x" << std::hex << static_cast<unsigned int>(c) << std::dec;
    }
    *_out << "\"";
    if (add_description)
      *_out << SEP << "bin (" << std::dec << obj.nbytes() << "B)" << port::OFF;
  }
  else if (is_array(value.type)) {
    const mp::Array &obj = *value.via._array;
    _write_indent() << port::BOLD << "[" << port::OFF;
    if (obj.size() == 0)
      *_out << port::BOLD << "]" << port::OFF;
    if (add_description)
      *_out << SEP << "array (" << std::dec << obj.size() << ")" << port::OFF;
    if (obj.size() != 0) {
      *_out << "\n";
      ++_indent;
      for (uint32_t i = 0; i != obj.size(); ++i) {
        _write_indent();
        _write_value(obj[i]);
        *_out << ",\n";
      }
      --_indent;
      _write_indent() << port::BOLD << "]" << port::OFF;
    }
  }
  else if (is_map(value.type)) {
    const mp::Map &obj = *value.via._map;
    _write_indent() << port::BOLD << "{" << port::OFF;
    if (obj.size() == 0)
      *_out << port::BOLD << "}" << port::OFF;
    if (add_description)
      *_out << SEP << "map (" << std::dec << obj.size() << ")" << port::OFF;
    if (obj.size() != 0) {
      *_out << "\n";
      ++_indent;
      for (uint32_t i = 0; i != obj.size(); ++i) {
        const mp::Map::Pair &pair = obj[i];
        _write_indent();
        _write_value(pair.key, false);
        *_out << port::BOLD << ": " << port::OFF;
        _write_value(pair.value);
        *_out << ",\n";
      }
      --_indent;
      _write_indent() << port::BOLD << "}" << port::OFF;
    }
  }
  else if (is_ext(value.type)) {
    const mp::Ext &obj = *value.via._ext;
    *_out << "\"";
    for (uint32_t i = 0; i != obj.nbytes(); ++i) {
      const char c = obj.data()[i];
      if (std::isprint(c))
        *_out << std::dec << c;
      else
        *_out << "\\x" << std::hex << static_cast<unsigned int>(c);
    }
    *_out << "\"";
    if (add_description)
      *_out << SEP << "ext (" << std::dec << obj.nbytes() << "B)" << port::OFF;
  }
  else
    *_out << port::RED << REPR_UNKNOWN << port::OFF;
}

void
Processor::process(std::istream &in, std::ostream &out) {
  // Reset our state.
  _indent = 0;
  _out = &out;

  Pool pool(4096);
  while (in) {
    // Read in the next MessagePack object.
    const auto at_byte = in.tellg();
    mp::Value *value = nullptr;
    try {
      value = mp::read_dynamic(in, pool);
    }
    catch (mp::ReadError &e) {
      *_out << port::RED << "ReadError at byte " << std::dec << in.tellg() << ": " << e.what() << port::OFF << std::endl;
      break;
    }

    // Check for EOF.
    if (value == nullptr) {
      assert(in.eof());
      break;
    }

    // Pretty-print the object.
    *_out << port::DARK_GREY << "# at byte " << at_byte << port::OFF << "\n";
    _write_value(*value);
    *_out << "\n";
  }
}

}  // namespace mp_less
}  // namespace schwa
<|endoftext|>


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

#include "arch/alpha/miscregfile.hh"
#include "base/misc.hh"

namespace AlphaISA
{

    void
    MiscRegFile::serialize(std::ostream &os)
    {
        SERIALIZE_SCALAR(fpcr);
        SERIALIZE_SCALAR(uniq);
        SERIALIZE_SCALAR(lock_flag);
        SERIALIZE_SCALAR(lock_addr);
#if FULL_SYSTEM
        SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
#endif
    }

    void
    MiscRegFile::unserialize(Checkpoint *cp, const std::string &section)
    {
        UNSERIALIZE_SCALAR(fpcr);
        UNSERIALIZE_SCALAR(uniq);
        UNSERIALIZE_SCALAR(lock_flag);
        UNSERIALIZE_SCALAR(lock_addr);
#if FULL_SYSTEM
        UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
#endif
    }

    MiscReg
    MiscRegFile::readReg(int misc_reg)
    {
        switch(misc_reg) {
          case MISCREG_FPCR:
            return fpcr;
          case MISCREG_UNIQ:
            return uniq;
          case MISCREG_LOCKFLAG:
            return lock_flag;
          case MISCREG_LOCKADDR:
            return lock_addr;
          case MISCREG_INTR:
            return intr_flag;
#if FULL_SYSTEM
          default:
            assert(misc_reg < NumInternalProcRegs);
            return ipr[misc_reg];
#else
          default:
            panic("Attempt to read an invalid misc register!");
            return 0;
#endif
        }
    }

    MiscReg
    MiscRegFile::readRegWithEffect(int misc_reg, ThreadContext *tc)
    {
#if FULL_SYSTEM
        return readIpr(misc_reg, tc);
#else
        panic("No faulting misc regs in SE mode!");
        return 0;
#endif
    }

    void
    MiscRegFile::setReg(int misc_reg, const MiscReg &val)
    {
        switch(misc_reg) {
          case MISCREG_FPCR:
            fpcr = val;
            return;
          case MISCREG_UNIQ:
            uniq = val;
            return;
          case MISCREG_LOCKFLAG:
            lock_flag = val;
            return;
          case MISCREG_LOCKADDR:
            lock_addr = val;
            return;
          case MISCREG_INTR:
            intr_flag = val;
            return;
#if FULL_SYSTEM
          default:
            assert(misc_reg < NumInternalProcRegs);
            ipr[misc_reg] = val;
            return;
#else
          default:
            panic("Attempt to write to an invalid misc register!");
#endif
        }
    }

    void
    MiscRegFile::setRegWithEffect(int misc_reg, const MiscReg &val,
            ThreadContext *tc)
    {
#if FULL_SYSTEM
        switch(misc_reg) {
          case MISCREG_FPCR:
            fpcr = val;
            return;
          case MISCREG_UNIQ:
            uniq = val;
            return;
          case MISCREG_LOCKFLAG:
            lock_flag = val;
            return;
          case MISCREG_LOCKADDR:
            lock_addr = val;
            return;
          case MISCREG_INTR:
            intr_flag = val;
            return;
          default:
            return setIpr(misc_reg, val, tc);
        }
#else
        //panic("No registers with side effects in SE mode!");
        return;
#endif
    }

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

#include "arch/alpha/miscregfile.hh"
#include "base/misc.hh"

namespace AlphaISA
{

    void
    MiscRegFile::serialize(std::ostream &os)
    {
        SERIALIZE_SCALAR(fpcr);
        SERIALIZE_SCALAR(uniq);
        SERIALIZE_SCALAR(lock_flag);
        SERIALIZE_SCALAR(lock_addr);
#if FULL_SYSTEM
        SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
#endif
    }

    void
    MiscRegFile::unserialize(Checkpoint *cp, const std::string &section)
    {
        UNSERIALIZE_SCALAR(fpcr);
        UNSERIALIZE_SCALAR(uniq);
        UNSERIALIZE_SCALAR(lock_flag);
        UNSERIALIZE_SCALAR(lock_addr);
#if FULL_SYSTEM
        UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
#endif
    }

    MiscReg
    MiscRegFile::readReg(int misc_reg)
    {
        switch(misc_reg) {
          case MISCREG_FPCR:
            return fpcr;
          case MISCREG_UNIQ:
            return uniq;
          case MISCREG_LOCKFLAG:
            return lock_flag;
          case MISCREG_LOCKADDR:
            return lock_addr;
          case MISCREG_INTR:
            return intr_flag;
#if FULL_SYSTEM
          default:
            assert(misc_reg < NumInternalProcRegs);
            return ipr[misc_reg];
#else
          default:
            panic("Attempt to read an invalid misc register!");
            return 0;
#endif
        }
    }

    MiscReg
    MiscRegFile::readRegWithEffect(int misc_reg, ThreadContext *tc)
    {
#if FULL_SYSTEM
        return readIpr(misc_reg, tc);
#else
        panic("No faulting misc regs in SE mode!");
        return 0;
#endif
    }

    void
    MiscRegFile::setReg(int misc_reg, const MiscReg &val)
    {
        switch(misc_reg) {
          case MISCREG_FPCR:
            fpcr = val;
            return;
          case MISCREG_UNIQ:
            uniq = val;
            return;
          case MISCREG_LOCKFLAG:
            lock_flag = val;
            return;
          case MISCREG_LOCKADDR:
            lock_addr = val;
            return;
          case MISCREG_INTR:
            intr_flag = val;
            return;
#if FULL_SYSTEM
          default:
            assert(misc_reg < NumInternalProcRegs);
            ipr[misc_reg] = val;
            return;
#else
          default:
            panic("Attempt to write to an invalid misc register!");
#endif
        }
    }

    void
    MiscRegFile::setRegWithEffect(int misc_reg, const MiscReg &val,
            ThreadContext *tc)
    {
        switch(misc_reg) {
          case MISCREG_FPCR:
            fpcr = val;
            return;
          case MISCREG_UNIQ:
            uniq = val;
            return;
          case MISCREG_LOCKFLAG:
            lock_flag = val;
            return;
          case MISCREG_LOCKADDR:
            lock_addr = val;
            return;
          case MISCREG_INTR:
            intr_flag = val;
            return;
          default:
#if FULL_SYSTEM
            setIpr(misc_reg, val, tc);
#else
            panic("No registers with side effects in SE mode!");
#endif
            return;
        }
    }

}
<|endoftext|>


<commit_before><commit_msg>[nostalgia/studio] Cleanup main<commit_after><|endoftext|>


<commit_before><commit_msg>network_driver: Cleanup<commit_after><|endoftext|>


<commit_before><commit_msg>Bugfix: should not depend on keyNum to decide whether UintFullIndex is used or not within Build()<commit_after><|endoftext|>


<commit_before>#include "Game.h"

namespace hm
{
	Game::Game() : capFrameRate(true), framerate(30), frameTimer(), maxFrameTime(0), cappedFrameTime(0)
	{
		// Set up our members.
		window = new Window("No Title", 640, 480);
		manager = new StateManager(window);
	}

	Game::Game(std::string title) : capFrameRate(true), framerate(30), frameTimer(), maxFrameTime(0), cappedFrameTime(0)
	{
		window = new Window(title, 640, 480);
		manager = new StateManager(window);
	}

	Game::Game(std::string title, int width, int height, int bpp) : capFrameRate(true), framerate(30), frameTimer(), maxFrameTime(0), cappedFrameTime(0)
	{
		window = new Window(title, width, height, bpp);
		manager = new StateManager(window);
	}

	Game::~Game()
	{
		delete manager;
		manager = NULL;
		delete window;
		window = NULL;
	}

	void Game::setCapFrameRate(bool b)
	{
		capFrameRate = b;
		return;
	}

	bool Game::frameRateIsCapped()
	{
		return capFrameRate;
	}

	void Game::setFrameRate(int i)
	{
		framerate = i;
		return;
	}

	float Game::getMaxFrameTime()
	{
		return maxFrameTime;
	}

	float Game::getCappedFrameTime()
	{
		return cappedFrameTime;
	}

	float Game::getMaxFrameRate()
	{
		// Frame Rate = 1000ms / Time Spent per Frame
		return 1000 / maxFrameTime;
	}

	float Game::getCappedFrameRate()
	{
		// Frame Rate = 1000ms / Time Spent per Frame
		return 1000 / cappedFrameTime;
	}

	float Game::getFrameRate()
	{
		if(frameRateIsCapped())
			return 1000 / cappedFrameTime;
		else
			return 1000 / maxFrameTime;
	}

    void Game::loop()
    {
        while(running)
        {
			frameTimer.start();
            processInput();
            update();
            display();

			// Record the faster time.
			frameTimer.pause();
			maxFrameTime = (float)(maxFrameTime * .995 + frameTimer.getTime() * .005);
			frameTimer.unpause();

			// Record the capped time.
			if(capFrameRate && frameTimer.getTime() < 1000 / framerate)
			{
				SDL_Delay((Uint32)(1000 / framerate - frameTimer.getTime()));
				cappedFrameTime = (float)((cappedFrameTime * .95 + frameTimer.getTime() * .05));
			}
        }

        // Clean up afterwards.
        cleanup();
    }
}
<commit_msg>Changed sample size for capped frame rate average.<commit_after>#include "Game.h"

namespace hm
{
	Game::Game() : capFrameRate(true), framerate(30), frameTimer(), maxFrameTime(0), cappedFrameTime(0)
	{
		// Set up our members.
		window = new Window("No Title", 640, 480);
		manager = new StateManager(window);
	}

	Game::Game(std::string title) : capFrameRate(true), framerate(30), frameTimer(), maxFrameTime(0), cappedFrameTime(0)
	{
		window = new Window(title, 640, 480);
		manager = new StateManager(window);
	}

	Game::Game(std::string title, int width, int height, int bpp) : capFrameRate(true), framerate(30), frameTimer(), maxFrameTime(0), cappedFrameTime(0)
	{
		window = new Window(title, width, height, bpp);
		manager = new StateManager(window);
	}

	Game::~Game()
	{
		delete manager;
		manager = NULL;
		delete window;
		window = NULL;
	}

	void Game::setCapFrameRate(bool b)
	{
		capFrameRate = b;
		return;
	}

	bool Game::frameRateIsCapped()
	{
		return capFrameRate;
	}

	void Game::setFrameRate(int i)
	{
		framerate = i;
		return;
	}

	float Game::getMaxFrameTime()
	{
		return maxFrameTime;
	}

	float Game::getCappedFrameTime()
	{
		return cappedFrameTime;
	}

	float Game::getMaxFrameRate()
	{
		// Frame Rate = 1000ms / Time Spent per Frame
		return 1000 / maxFrameTime;
	}

	float Game::getCappedFrameRate()
	{
		// Frame Rate = 1000ms / Time Spent per Frame
		return 1000 / cappedFrameTime;
	}

	float Game::getFrameRate()
	{
		if(frameRateIsCapped())
			return 1000 / cappedFrameTime;
		else
			return 1000 / maxFrameTime;
	}

    void Game::loop()
    {
        while(running)
        {
			frameTimer.start();
            processInput();
            update();
            display();

			// Record the faster time.
			frameTimer.pause();
			maxFrameTime = (float)(maxFrameTime * .995 + frameTimer.getTime() * .005);
			frameTimer.unpause();

			// Record the capped time.
			if(capFrameRate && frameTimer.getTime() < 1000 / framerate)
			{
				SDL_Delay((Uint32)(1000 / framerate - frameTimer.getTime()));
				cappedFrameTime = (float)((cappedFrameTime * .995 + frameTimer.getTime() * .005));
			}
        }

        // Clean up afterwards.
        cleanup();
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove whitespace from path valued configuration file settings.<commit_after><|endoftext|>


<commit_before><commit_msg>Documentation: clarify that DOMWriter::writeToString always returns string in UTF-16<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS c09v003 (1.33.14); FILE MERGED 2006/03/01 10:30:35 os 1.33.14.1: #132598# repositioning of component buttons fixed<commit_after><|endoftext|>