<commit_before>
#define _ALL_SOURCE

#include <stdio.h>
#include <filehdr.h>
#include <aouthdr.h>
#include <model.h>
#include <magic.h>
#include <nlist.h>
#include "condor_debug.h"
#include "_condor_fix_resource.h"
#include "types.h"
#include "proto.h"

#include <fcntl.h>
#include <unistd.h>
#include <string.h>

extern "C" {
	int nlist( char *FileName, struct nlist *N1 );
}

int magic_check( char *a_out )
{
	int exec_fd = -1;
	struct header exec_header;
	struct som_exec_auxhdr hpux_header;
	int nbytes;

	if ( (exec_fd=open(a_out,O_RDONLY)) < 0) {
		dprintf(D_ALWAYS,"error opening executeable file %s\n",a_out);
		return(-1);
	}

	nbytes = read(exec_fd, (char *)&exec_header, sizeof( exec_header) );
	if ( nbytes != sizeof( exec_header) ) {
		dprintf(D_ALWAYS,"read executeable main header error \n");
		close(exec_fd);
		return(-1);
	}

	close(exec_fd);

	if ( exec_header.a_magic != SHARE_MAGIC ) {
		dprintf(D_ALWAYS,"EXECUTEABLE %s HAS BAD MAGIC NUMBER\n",a_out);
		return -1;
	}
/****
#define MYSYS    0x20B // this is for g++ installation bug : dhruba
	if ( exec_header.system_id != MYSYS ) {
		dprintf(D_ALWAYS,"EXECUTEABLE %s NOT COMPILED FOR THIS ARCHITECTURE: system_id = %d\n",a_out,exec_header.system_id);
		return -1;
	}
***********/

	return 0;
}

/*
Check to see that the checkpoint file is linked with the Condor
library by looking for the symbol "_START".
*/
int symbol_main_check( char *name )
{
	int status;
	struct nlist nl[2];

	nl[0].n_name = "_START";
	nl[1].n_name = "";

	status = nlist( name, nl);

	/* Return TRUE even if nlist reports an error because the executeable
	 * may have simply been stripped by the user */
	if ( status < 0 ) {
		dprintf(D_ALWAYS,"Error: nlist returns %d, errno=%d\n",status,errno);
		return 0;
	}

	if ( nl[0].n_type == 0 ) {
		dprintf(D_ALWAYS,"No symbol _START found in executeable %s\n",name);
		return -1;

	}

	return 0;
}

int
calc_hdr_blocks()
{
	return (sizeof(struct header) + sizeof(struct som_exec_auxhdr) + 1023) / 1024;
}

int
calc_text_blocks( char *a_out )
{
	int exec_fd = -1;
	struct header exec_header;
	struct som_exec_auxhdr hpux_header;
	int nbytes;

	if ( (exec_fd=open(a_out,O_RDONLY)) < 0) {
		printf("error opening file\n");
		return(-1);
	}

	nbytes = read(exec_fd, (char *)&exec_header, sizeof( exec_header) );
	if ( nbytes != sizeof( exec_header) ) {
		dprintf(D_ALWAYS,"reading executeable %s main header error \n",a_out);
		close(exec_fd);
		return(-1);
	}

	nbytes = read(exec_fd, (char *)&hpux_header, sizeof( hpux_header) );
	if ( nbytes != sizeof( hpux_header) ) {
		dprintf(D_ALWAYS,"read executeable %s hpux header error \n",a_out);
		close(exec_fd);
		return(-1);
	}

	close(exec_fd);

	if ( hpux_header.som_auxhdr.type != HPUX_AUX_ID ) {
		dprintf(D_ALWAYS,"in executeable %s, hpux header does not immediately follow executeable header!\n",a_out);
		return(-1);
	}

	return hpux_header.exec_tsize / 1024;
}

<commit_msg>initial HPUX10 support<commit_after>
#define _ALL_SOURCE

#include <stdio.h>
#include <filehdr.h>
#include <aouthdr.h>
#include <model.h>
#include <magic.h>
#include <nlist.h>
#include "condor_debug.h"
#include "_condor_fix_resource.h"
#include "types.h"
#include "proto.h"

#include <fcntl.h>
#include <unistd.h>
#include <string.h>

extern "C" {
#ifdef HPUX10
	int nlist( const char *FileName, struct nlist *N1 );
#else
	int nlist( char *FileName, struct nlist *N1 );
#endif
}

int magic_check( char *a_out )
{
	int exec_fd = -1;
	struct header exec_header;
	struct som_exec_auxhdr hpux_header;
	int nbytes;

	if ( (exec_fd=open(a_out,O_RDONLY)) < 0) {
		dprintf(D_ALWAYS,"error opening executeable file %s\n",a_out);
		return(-1);
	}

	nbytes = read(exec_fd, (char *)&exec_header, sizeof( exec_header) );
	if ( nbytes != sizeof( exec_header) ) {
		dprintf(D_ALWAYS,"read executeable main header error \n");
		close(exec_fd);
		return(-1);
	}

	close(exec_fd);

	if ( exec_header.a_magic != SHARE_MAGIC ) {
		dprintf(D_ALWAYS,"EXECUTEABLE %s HAS BAD MAGIC NUMBER\n",a_out);
		return -1;
	}
/****
#define MYSYS    0x20B // this is for g++ installation bug : dhruba
	if ( exec_header.system_id != MYSYS ) {
		dprintf(D_ALWAYS,"EXECUTEABLE %s NOT COMPILED FOR THIS ARCHITECTURE: system_id = %d\n",a_out,exec_header.system_id);
		return -1;
	}
***********/

	return 0;
}

/*
Check to see that the checkpoint file is linked with the Condor
library by looking for the symbol "_START".
*/
int symbol_main_check( char *name )
{
	int status;
	struct nlist nl[2];

	nl[0].n_name = "_START";
	nl[1].n_name = "";

	status = nlist( name, nl);

	/* Return TRUE even if nlist reports an error because the executeable
	 * may have simply been stripped by the user */
	if ( status < 0 ) {
		dprintf(D_ALWAYS,"Error: nlist returns %d, errno=%d\n",status,errno);
		return 0;
	}

	if ( nl[0].n_type == 0 ) {
		dprintf(D_ALWAYS,"No symbol _START found in executeable %s\n",name);
		return -1;

	}

	return 0;
}

int
calc_hdr_blocks()
{
	return (sizeof(struct header) + sizeof(struct som_exec_auxhdr) + 1023) / 1024;
}

int
calc_text_blocks( char *a_out )
{
	int exec_fd = -1;
	struct header exec_header;
	struct som_exec_auxhdr hpux_header;
	int nbytes;

	if ( (exec_fd=open(a_out,O_RDONLY)) < 0) {
		printf("error opening file\n");
		return(-1);
	}

	nbytes = read(exec_fd, (char *)&exec_header, sizeof( exec_header) );
	if ( nbytes != sizeof( exec_header) ) {
		dprintf(D_ALWAYS,"reading executeable %s main header error \n",a_out);
		close(exec_fd);
		return(-1);
	}

	nbytes = read(exec_fd, (char *)&hpux_header, sizeof( hpux_header) );
	if ( nbytes != sizeof( hpux_header) ) {
		dprintf(D_ALWAYS,"read executeable %s hpux header error \n",a_out);
		close(exec_fd);
		return(-1);
	}

	close(exec_fd);

	if ( hpux_header.som_auxhdr.type != HPUX_AUX_ID ) {
		dprintf(D_ALWAYS,"in executeable %s, hpux header does not immediately follow executeable header!\n",a_out);
		return(-1);
	}

	return hpux_header.exec_tsize / 1024;
}

<|endoftext|>


<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.
 *
 ***************************************************************/

#include "condor_common.h"
#include "condor_config.h"
#include "match_prefix.h"
#include "param_info.h" // access to default params
#include "param_info_tables.h"
#include "condor_version.h"
#include <stdlib.h>

const char * check_configif = NULL;

void PREFAST_NORETURN
my_exit( int status )
{
	fflush( stdout );
	fflush( stderr );

	if ( ! status ) {
		clear_config();
	}

	exit( status );
}

// consume the next command line argument, otherwise return an error
// note that this function MAY change the value of i
//
static const char * use_next_arg(const char * arg, const char * argv[], int & i)
{
	if (argv[i+1]) {
		return argv[++i];
	}

	fprintf(stderr, "-%s requires an argument\n", arg);
	//usage();
	my_exit(1);
	return NULL;
}

int do_iftest(int /*out*/ &cTests);

bool dash_verbose = false;

int main(int argc, const char ** argv)
{
	bool do_test = true;

	int ix = 1;
	while (ix < argc) {
		if (is_dash_arg_prefix(argv[ix], "check-if", -1)) {
			check_configif = use_next_arg("check-if", argv, ix);
			do_test = false;
		} else if (is_dash_arg_prefix(argv[ix], "verbose", 1)) {
			dash_verbose = true;
		} else if (is_dash_arg_prefix(argv[ix], "memory-snapshot")) {
		#ifdef LINUX
			const char * filename = "tool";
			if (argv[ix+1]) filename = use_next_arg("memory-shapshot", argv, ix);
			char copy_smaps[300];
			pid_t pid = getpid();
			sprintf(copy_smaps, "cat /proc/%d/smaps > %s", pid, filename);
			int r = system(copy_smaps);
			fprintf(stdout, "%s returned %d\n", copy_smaps, r);
		#endif
		} else {
			fprintf(stderr, "unknown argument: %s\n", argv[ix]);
			my_exit(1);
		}
		++ix;
	}

	// handle check-if to valididate config's if/else parsing and help users to write
	// valid if conditions.
	if (check_configif) {
		std::string err_reason;
		bool bb = false;
		bool valid = config_test_if_expression(check_configif, bb, err_reason);
		fprintf(stdout, "# %s: \"%s\" %s\n",
			valid ? "ok" : "not supported",
			check_configif,
			valid ? (bb ? "\ntrue" : "\nfalse") : err_reason.c_str());
	}

	if (do_test) {
		printf("running standard config if tests\n");
		int cTests = 0;
		int cFail = do_iftest(cTests);
		printf("%d failures in %d tests\n", cFail, cTests);
		return cFail;
	}

	return 0;
}

static const char * const aBoolTrue[] = {
	"true", "True", "TRUE", "yes", "Yes", "YES", "t", "T", "1",
	"1.0", "0.1", ".1", "1.", "1e1", "1e10", "2.0e10",
	" true ", " 1 ",
};

static const char * const aBoolFalse[] = {
	"false", "False", "FALSE", "no", "No", "NO", "f", "F ",
	"0", "0.0", ".0", "0.", "0e1", "0.0e10", " false ", " 0 ",
};

#define CONDOR_SERIES_VERSION "8.2"
static const char * const aVerTrue[] = {
	"version > 6.0", "!version >" CONDOR_SERIES_VERSION, "version > 8.1.1",
	"version > 8.1.4", "version > 7.24.29",
	"version >= " CONDOR_VERSION, "version == " CONDOR_SERIES_VERSION, "version != 8.0",
	"version == " CONDOR_VERSION, "version <= " CONDOR_SERIES_VERSION ".9",
	"version <= " CONDOR_SERIES_VERSION, "version < " CONDOR_SERIES_VERSION ".9", "version < " CONDOR_SERIES_VERSION ".16",
	"version < 8.2.99", "version < " CONDOR_SERIES_VERSION, "version < 9.0",
	"version < 10.0", " VERSION < 10.0 ", " Version < 10.0"
};

static const char * const aVerFalse[] = {
	"version < 6.0", "version < " CONDOR_SERIES_VERSION, "version < " CONDOR_VERSION,
	"version < 8.1.4", " version < 8.1.4", "version < 8.1.4 ",
	"  version  <  8.1.4  ", "version < 7.24.29", " ! version <= " CONDOR_VERSION,
	"version == 8.0", "version == 8.0.6", "version <= 8.0.5",
	"!version >= " CONDOR_SERIES_VERSION, "version > " CONDOR_VERSION, "version > " CONDOR_SERIES_VERSION ".16",
	"version > " CONDOR_SERIES_VERSION ".99", "version > " CONDOR_SERIES_VERSION, "version > 9.0",
	"version > 10.0",
};

static const char * const aDefTrue[] = {
	"defined true", "defined false", "defined 1",
	"defined 0", "defined t", "defined f",
	"defined release_dir", "defined log",
	"defined LOG", "defined $(not_a_real_param:true)",
	"defined use ROLE", "defined use ROLE:", "defined use ROLE:Personal",
	"defined use feature", "defined use Feature:VMware",
};

static const char * const aDefFalse[] = {
	"defined", " defined ", "defined a",
	"defined not_a_real_param",
	"defined master.not_a_real_param",
	"defined $(not_a_real_param)",
	"defined use NOT", "defined use NOT:a_real_meta",
	"defined use",
};

static const char * const aBoolError[] = {
	"truthy", "falsify", "true dat",
	"0 0", "1 0", "1b1",
};

static const char * const aVerError[] = {
	"version", "version ", "version 99", "version <= aaa",
	"version =!= 8.1", "version <> 8.1", "Version < ",
	"version > 1.1", "version <= 1.1", " Ver < 9.9",
};

static const char * const aDefError[] = {
	"defined a b", "defined 11 99", "defined < 1.1",
	"defined use foo bar", // internal whitespace (or no :)
	"defined use ROLE: Personal", // internal whitespace
};

static const char * const aUnsupError[] = {
	"1 == 0", "false == false", "foo < bar", "$(foo) < $(bar)",
	"\"foo\" == \"bar\"", "$(foo) == $(bar)", "$(foo) != $(bar)",
};

#ifndef COUNTOF
  #define COUNTOF(aa)  (int)(sizeof(aa)/sizeof((aa)[0]))
#endif
#define TEST_TABLE(aa)  aa, (int)COUNTOF(aa)

typedef const char * PCSTR;
static const struct _test_set {
	const char * label;
	bool valid;
	bool result;
	PCSTR const * aTbl;
	int cTbl;
} aTestSets[] = {
	{ "bool",    true, true,  TEST_TABLE(aBoolTrue) },
	{ "bool",    true, false,  TEST_TABLE(aBoolFalse) },
	{ "version", true, true,  TEST_TABLE(aVerTrue) },
	{ "version", true, false,  TEST_TABLE(aVerFalse) },
	{ "defined", true, true,  TEST_TABLE(aDefTrue) },
	{ "defined", true, false,  TEST_TABLE(aDefFalse) },
	{ "bool",    false, false,  TEST_TABLE(aBoolError) },
	{ "version", false, false,  TEST_TABLE(aVerError) },
	{ "version", false, false,  TEST_TABLE(aDefError) },
	{ "complex", false, false, TEST_TABLE(aUnsupError) },
};

int do_iftest(int &cTests)
{
	int fail_count = 0;
	cTests = 0;

	std::string err_reason;
	bool bb = false;

	for (int ixSet = 0; ixSet < (int)COUNTOF(aTestSets); ++ixSet) {
		const struct _test_set & tset = aTestSets[ixSet];

		if (dash_verbose) {
			fprintf(stdout, "--- %s - expecting %s %s\n",
				tset.label, tset.valid ? "ok" : "unsup", tset.valid ? (tset.result ? "true" : "false") : "");
		}

		for (int ix = 0; ix < tset.cTbl; ++ix) {
			++cTests;
			err_reason = "bogus";
			const char * cond = aTestSets[ixSet].aTbl[ix];
			bool valid = config_test_if_expression(cond, bb, err_reason);
			if ((valid != tset.valid) || (valid && (bb != tset.result))) {
				++fail_count;
				fprintf(stdout, "Test Failure: '%s' is (%s,%s) should be (%s,%s)\n",
					   cond,
					   valid ? "ok" : "unsup", bb ? "true" : "false",
					   tset.valid ? "ok" : "unsup", tset.result ? "true" : "false"
					   );
			} else if (dash_verbose) {
				fprintf(stdout, "# %s: \"%s\" %s\n",
					valid ? "ok" : "not supported",
					cond, valid ? (bb ? "\ntrue" : "\nfalse") : err_reason.c_str());
			}
		}
	}

	return fail_count;
}
<commit_msg>more fixes for config tests that expect version to be 8.1 ===VersionHistory:None===<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.
 *
 ***************************************************************/

#include "condor_common.h"
#include "condor_config.h"
#include "match_prefix.h"
#include "param_info.h" // access to default params
#include "param_info_tables.h"
#include "condor_version.h"
#include <stdlib.h>

const char * check_configif = NULL;

void PREFAST_NORETURN
my_exit( int status )
{
	fflush( stdout );
	fflush( stderr );

	if ( ! status ) {
		clear_config();
	}

	exit( status );
}

// consume the next command line argument, otherwise return an error
// note that this function MAY change the value of i
//
static const char * use_next_arg(const char * arg, const char * argv[], int & i)
{
	if (argv[i+1]) {
		return argv[++i];
	}

	fprintf(stderr, "-%s requires an argument\n", arg);
	//usage();
	my_exit(1);
	return NULL;
}

int do_iftest(int /*out*/ &cTests);

bool dash_verbose = false;

int main(int argc, const char ** argv)
{
	bool do_test = true;

	int ix = 1;
	while (ix < argc) {
		if (is_dash_arg_prefix(argv[ix], "check-if", -1)) {
			check_configif = use_next_arg("check-if", argv, ix);
			do_test = false;
		} else if (is_dash_arg_prefix(argv[ix], "verbose", 1)) {
			dash_verbose = true;
		} else if (is_dash_arg_prefix(argv[ix], "memory-snapshot")) {
		#ifdef LINUX
			const char * filename = "tool";
			if (argv[ix+1]) filename = use_next_arg("memory-shapshot", argv, ix);
			char copy_smaps[300];
			pid_t pid = getpid();
			sprintf(copy_smaps, "cat /proc/%d/smaps > %s", pid, filename);
			int r = system(copy_smaps);
			fprintf(stdout, "%s returned %d\n", copy_smaps, r);
		#endif
		} else {
			fprintf(stderr, "unknown argument: %s\n", argv[ix]);
			my_exit(1);
		}
		++ix;
	}

	// handle check-if to valididate config's if/else parsing and help users to write
	// valid if conditions.
	if (check_configif) {
		std::string err_reason;
		bool bb = false;
		bool valid = config_test_if_expression(check_configif, bb, err_reason);
		fprintf(stdout, "# %s: \"%s\" %s\n",
			valid ? "ok" : "not supported",
			check_configif,
			valid ? (bb ? "\ntrue" : "\nfalse") : err_reason.c_str());
	}

	if (do_test) {
		printf("running standard config if tests\n");
		int cTests = 0;
		int cFail = do_iftest(cTests);
		printf("%d failures in %d tests\n", cFail, cTests);
		return cFail;
	}

	return 0;
}

static const char * const aBoolTrue[] = {
	"true", "True", "TRUE", "yes", "Yes", "YES", "t", "T", "1",
	"1.0", "0.1", ".1", "1.", "1e1", "1e10", "2.0e10",
	" true ", " 1 ",
};

static const char * const aBoolFalse[] = {
	"false", "False", "FALSE", "no", "No", "NO", "f", "F ",
	"0", "0.0", ".0", "0.", "0e1", "0.0e10", " false ", " 0 ",
};

#define CONDOR_SERIES_VERSION "8.2"
#define CONDOR_NEXT_VERSION "8.3"
static const char * const aVerTrue[] = {
	"version > 6.0", "!version >" CONDOR_SERIES_VERSION, "version > 8.1.1",
	"version > 8.1.4", "version > 7.24.29",
	"version >= " CONDOR_VERSION, "version == " CONDOR_SERIES_VERSION, "version != 8.0",
	"version == " CONDOR_VERSION, "version <= " CONDOR_SERIES_VERSION ".9",
	"version <= " CONDOR_SERIES_VERSION, "version < " CONDOR_SERIES_VERSION ".9", "version < " CONDOR_SERIES_VERSION ".16",
	"version < " CONDOR_SERIES_VERSION ".99", "version < " CONDOR_NEXT_VERSION, "version < 9.0",
	"version < 10.0", " VERSION < 10.0 ", " Version < 10.0"
};

static const char * const aVerFalse[] = {
	"version < 6.0", "version < " CONDOR_SERIES_VERSION, "version < " CONDOR_VERSION,
	"version < 8.1.4", " version < 8.1.4", "version < 8.1.4 ",
	"  version  <  8.1.4  ", "version < 7.24.29", " ! version <= " CONDOR_VERSION,
	"version == 8.0", "version == 8.0.6", "version <= 8.0.5",
	"!version >= " CONDOR_SERIES_VERSION, "version > " CONDOR_VERSION, "version > " CONDOR_SERIES_VERSION ".16",
	"version > " CONDOR_SERIES_VERSION ".99", "version > " CONDOR_SERIES_VERSION, "version > 9.0",
	"version > 10.0",
};

static const char * const aDefTrue[] = {
	"defined true", "defined false", "defined 1",
	"defined 0", "defined t", "defined f",
	"defined release_dir", "defined log",
	"defined LOG", "defined $(not_a_real_param:true)",
	"defined use ROLE", "defined use ROLE:", "defined use ROLE:Personal",
	"defined use feature", "defined use Feature:VMware",
};

static const char * const aDefFalse[] = {
	"defined", " defined ", "defined a",
	"defined not_a_real_param",
	"defined master.not_a_real_param",
	"defined $(not_a_real_param)",
	"defined use NOT", "defined use NOT:a_real_meta",
	"defined use",
};

static const char * const aBoolError[] = {
	"truthy", "falsify", "true dat",
	"0 0", "1 0", "1b1",
};

static const char * const aVerError[] = {
	"version", "version ", "version 99", "version <= aaa",
	"version =!= 8.1", "version <> 8.1", "Version < ",
	"version > 1.1", "version <= 1.1", " Ver < 9.9",
};

static const char * const aDefError[] = {
	"defined a b", "defined 11 99", "defined < 1.1",
	"defined use foo bar", // internal whitespace (or no :)
	"defined use ROLE: Personal", // internal whitespace
};

static const char * const aUnsupError[] = {
	"1 == 0", "false == false", "foo < bar", "$(foo) < $(bar)",
	"\"foo\" == \"bar\"", "$(foo) == $(bar)", "$(foo) != $(bar)",
};

#ifndef COUNTOF
  #define COUNTOF(aa)  (int)(sizeof(aa)/sizeof((aa)[0]))
#endif
#define TEST_TABLE(aa)  aa, (int)COUNTOF(aa)

typedef const char * PCSTR;
static const struct _test_set {
	const char * label;
	bool valid;
	bool result;
	PCSTR const * aTbl;
	int cTbl;
} aTestSets[] = {
	{ "bool",    true, true,  TEST_TABLE(aBoolTrue) },
	{ "bool",    true, false,  TEST_TABLE(aBoolFalse) },
	{ "version", true, true,  TEST_TABLE(aVerTrue) },
	{ "version", true, false,  TEST_TABLE(aVerFalse) },
	{ "defined", true, true,  TEST_TABLE(aDefTrue) },
	{ "defined", true, false,  TEST_TABLE(aDefFalse) },
	{ "bool",    false, false,  TEST_TABLE(aBoolError) },
	{ "version", false, false,  TEST_TABLE(aVerError) },
	{ "version", false, false,  TEST_TABLE(aDefError) },
	{ "complex", false, false, TEST_TABLE(aUnsupError) },
};

int do_iftest(int &cTests)
{
	int fail_count = 0;
	cTests = 0;

	std::string err_reason;
	bool bb = false;

	for (int ixSet = 0; ixSet < (int)COUNTOF(aTestSets); ++ixSet) {
		const struct _test_set & tset = aTestSets[ixSet];

		if (dash_verbose) {
			fprintf(stdout, "--- %s - expecting %s %s\n",
				tset.label, tset.valid ? "ok" : "unsup", tset.valid ? (tset.result ? "true" : "false") : "");
		}

		for (int ix = 0; ix < tset.cTbl; ++ix) {
			++cTests;
			err_reason = "bogus";
			const char * cond = aTestSets[ixSet].aTbl[ix];
			bool valid = config_test_if_expression(cond, bb, err_reason);
			if ((valid != tset.valid) || (valid && (bb != tset.result))) {
				++fail_count;
				fprintf(stdout, "Test Failure: '%s' is (%s,%s) should be (%s,%s)\n",
					   cond,
					   valid ? "ok" : "unsup", bb ? "true" : "false",
					   tset.valid ? "ok" : "unsup", tset.result ? "true" : "false"
					   );
			} else if (dash_verbose) {
				fprintf(stdout, "# %s: \"%s\" %s\n",
					valid ? "ok" : "not supported",
					cond, valid ? (bb ? "\ntrue" : "\nfalse") : err_reason.c_str());
			}
		}
	}

	return fail_count;
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "mcontentitemmodel.h"

void MContentItemModel::setItemPixmap(const QPixmap &itemImage)
{
    _itemPixmap() = itemImage;
    memberModified(ItemPixmap);
}

void MContentItemModel::setOptionalPixmap(const QPixmap& pixmap)
{
    _optionalPixmap() = pixmap;
    memberModified(OptionalPixmap);
}

const QPixmap &MContentItemModel::optionalPixmap() const
{
    return _optionalPixmap();
}

const QPixmap &MContentItemModel::itemPixmap() const
{
    return _itemPixmap();
}

void MContentItemModel::setItemImage(const QImage &itemImage)
{
    _itemImage() = itemImage;
    memberModified(ItemImage);
}

void MContentItemModel::setOptionalImage(const QImage& image)
{
    _optionalImage() = image;
    memberModified(OptionalImage);
}

const QImage &MContentItemModel::optionalImage() const
{
    return _optionalImage();
}

const QImage &MContentItemModel::itemImage() const
{
    return _itemImage();
}
<commit_msg>Fixes: MB#9971 - MContentItemModel doesn't provide get/set for ItemQImage<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "mcontentitemmodel.h"

void MContentItemModel::setItemQImage(QImage const& itemQImage)
{
    _itemQImage() = itemQImage;
    memberModified(ItemQImage);
}

const QImage &MContentItemModel::itemQImage() const
{
    return _itemQImage();
}

void MContentItemModel::setItemPixmap(const QPixmap &itemImage)
{
    _itemPixmap() = itemImage;
    memberModified(ItemPixmap);
}

void MContentItemModel::setOptionalPixmap(const QPixmap& pixmap)
{
    _optionalPixmap() = pixmap;
    memberModified(OptionalPixmap);
}

const QPixmap &MContentItemModel::optionalPixmap() const
{
    return _optionalPixmap();
}

const QPixmap &MContentItemModel::itemPixmap() const
{
    return _itemPixmap();
}

void MContentItemModel::setItemImage(const QImage &itemImage)
{
    _itemImage() = itemImage;
    memberModified(ItemImage);
}

void MContentItemModel::setOptionalImage(const QImage& image)
{
    _optionalImage() = image;
    memberModified(OptionalImage);
}

const QImage &MContentItemModel::optionalImage() const
{
    return _optionalImage();
}

const QImage &MContentItemModel::itemImage() const
{
    return _itemImage();
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "mdetailedlistitem.h"
#include "mdetailedlistitem_p.h"

#include <MImageWidget>
#include <MLabel>
#include <MStylableWidget>

#include <QGraphicsGridLayout>
#include <QGraphicsLinearLayout>

MDetailedListItemPrivate::MDetailedListItemPrivate(MDetailedListItem::ItemStyle style)
    : q_ptr(NULL),
    layoutGrid(NULL),
    image(NULL),
    sideTopImage(NULL),
    sideBottomImage(NULL),
    titleLabel(NULL),
    subtitleLabel(NULL),
    sideBottomLabel(NULL),
    isLayoutInitialized(false),
    listItemStyle(style),
    iconStyle(MDetailedListItem::Icon)
{

}

MDetailedListItemPrivate::~MDetailedListItemPrivate()
{
}

void MDetailedListItemPrivate::createLayout()
{
    Q_Q(MDetailedListItem);

    if (!layoutGrid) {
        layoutGrid = new QGraphicsGridLayout(q);
        layoutGrid->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        layoutGrid->setContentsMargins(0, 0, 0, 0);
        layoutGrid->setSpacing(0);
    }

    switch (listItemStyle) {
    case MDetailedListItem::IconTitleSubtitleAndTwoSideIcons: {
            q->titleLabelWidget()->setObjectName("CommonTitle");
            q->setIconStyle(MDetailedListItem::Icon);

            layout()->addItem(q->imageWidget(), 0, 0, 3, 1, Qt::AlignLeft | Qt::AlignVCenter);
            layout()->addItem(q->titleLabelWidget(), 0, 1, Qt::AlignLeft | Qt::AlignTop);
            layout()->addItem(q->subtitleLabelWidget(), 1, 1, Qt::AlignLeft | Qt::AlignBottom);
            layout()->addItem(new QGraphicsWidget(q), 2, 1, 1, 2);
            layout()->addItem(q->sideTopImageWidget(), 0, 2, Qt::AlignRight | Qt::AlignBottom);
            layout()->addItem(q->sideBottomImageWidget(), 1, 2, Qt::AlignRight | Qt::AlignTop);

            break;
        }
    case MDetailedListItem::IconTitleSubtitleAndSideIconWithLabel: {
            q->titleLabelWidget()->setObjectName("CommonTitle");
            q->setIconStyle(MDetailedListItem::Icon);

            layout()->addItem(q->imageWidget(), 0, 0, 3, 1, Qt::AlignLeft | Qt::AlignVCenter);

            layout()->addItem(q->titleLabelWidget(), 0, 1, 1, 3, Qt::AlignLeft | Qt::AlignTop);
            layout()->addItem(q->sideTopImageWidget(), 0, 4, Qt::AlignRight | Qt::AlignBottom);

            layout()->addItem(q->subtitleLabelWidget(), 1, 1, 1, 2);

            layout()->addItem(q->sideBottomLabelWidget(), 1, 3, 1, 2);

            layout()->addItem(new QGraphicsWidget(q), 2, 1);
            break;
        }
    case MDetailedListItem::ThumbnailTitleAndTwoSideIcons: {
            q->titleLabelWidget()->setObjectName("CommonSingleTitle");
            q->setIconStyle(MDetailedListItem::Thumbnail);

            layout()->addItem(q->imageWidget(), 0, 0, 2, 1, Qt::AlignLeft | Qt::AlignVCenter);

            layout()->addItem(q->titleLabelWidget(), 0, 1, 2, 1, Qt::AlignLeft | Qt::AlignVCenter);
            layout()->addItem(new QGraphicsWidget(q), 2, 1, Qt::AlignRight | Qt::AlignVCenter);

            QGraphicsWidget * panel = new QGraphicsWidget(q);
            QGraphicsLinearLayout * panelLayout = new QGraphicsLinearLayout(Qt::Vertical);
            panelLayout->setContentsMargins(0, 0, 0, 0);
            panelLayout->setSpacing(0);
            panel->setLayout(panelLayout);

            q->sideTopImageWidget()->setParentItem(panel);
            q->sideBottomImageWidget()->setParentItem(panel);

            panelLayout->addItem(q->sideTopImageWidget());
            panelLayout->addItem(q->sideBottomImageWidget());

            layout()->addItem(panel, 0, 2, 2, 1, Qt::AlignVCenter);

            break;
        }
    case MDetailedListItem::ThumbnailTitleSubtitleAndTwoSideIcons: {
            q->titleLabelWidget()->setObjectName("CommonTitle");
            q->setIconStyle(MDetailedListItem::Thumbnail);

            layout()->addItem(q->imageWidget(), 0, 0, 3, 1);

            layout()->addItem(q->titleLabelWidget(), 0, 1);
            layout()->addItem(q->subtitleLabelWidget(), 1, 1);

            QGraphicsWidget * panel = new QGraphicsWidget(q);
            QGraphicsLinearLayout * panelLayout = new QGraphicsLinearLayout(Qt::Vertical);
            panelLayout->setContentsMargins(0, 0, 0, 0);
            panelLayout->setSpacing(0);
            panel->setLayout(panelLayout);

            q->sideTopImageWidget()->setParentItem(panel);
            q->sideBottomImageWidget()->setParentItem(panel);

            panelLayout->addItem(q->sideTopImageWidget());
            panelLayout->addItem(q->sideBottomImageWidget());

            layout()->addItem(panel, 0, 2, 3, 1, Qt::AlignVCenter);
            layout()->addItem(new QGraphicsWidget(q), 2, 1);
            break;
        }
    default:
        break;
    }
}

void MDetailedListItemPrivate::clearLayout()
{
    if (layout()) {
        for (int i = 0; i < layout()->count(); i++) {
            QGraphicsLayoutItem *item = layoutGrid->itemAt(0);
            layoutGrid->removeAt(0);
            delete item;
        }
        image = NULL;
        titleLabel = NULL;
        subtitleLabel = NULL;
        sideTopImage = NULL;
        sideBottomImage = NULL;
        sideBottomLabel = NULL;
    }
}

QGraphicsGridLayout *MDetailedListItemPrivate::layout()
{
    return layoutGrid;
}

void MDetailedListItemPrivate::applyIconStyle()
{
    if (!image)
        return;

    if (iconStyle == MDetailedListItem::Thumbnail)
        image->setObjectName("CommonThumbnail");
    else if (iconStyle == MDetailedListItem::Icon)
        image->setObjectName("CommonMainIcon");
}

MDetailedListItem::MDetailedListItem(MDetailedListItem::ItemStyle style, QGraphicsItem *parent)
    : MListItem(parent), d_ptr(new MDetailedListItemPrivate(style))
{
    Q_D(MDetailedListItem);
    d->q_ptr = this;

    setObjectName("CommonPanel");
}

MDetailedListItem::~MDetailedListItem()
{
    delete d_ptr;
}

void MDetailedListItem::initLayout()
{
    Q_D(MDetailedListItem);

    if (d->isLayoutInitialized)
        return;

    setLayout(createLayout());
    d->isLayoutInitialized = true;
}

QGraphicsLayout *MDetailedListItem::createLayout()
{
    Q_D(MDetailedListItem);

    clearLayout();
    d->createLayout();

    return d->layout();
}

void MDetailedListItem::clearLayout()
{
    Q_D(MDetailedListItem);

    d->clearLayout();
}

void MDetailedListItem::setItemStyle(ItemStyle itemStyle)
{
    Q_D(MDetailedListItem);

    if (itemStyle == d->listItemStyle)
        return;

    d->listItemStyle = itemStyle;
    d->isLayoutInitialized = false;
    initLayout();
}

MDetailedListItem::ItemStyle MDetailedListItem::itemStyle() const
{
    Q_D(const MDetailedListItem);
    return d->listItemStyle;
}

void MDetailedListItem::setIconStyle(IconStyle style)
{
    Q_D(MDetailedListItem);

    if(style == d->iconStyle)
        return;

    d->iconStyle = style;
    d->applyIconStyle();
}

MDetailedListItem::IconStyle MDetailedListItem::iconStyle() const
{
    Q_D(const MDetailedListItem);

    return d->iconStyle;
}

void MDetailedListItem::setImageWidget(MImageWidget *image)
{
    Q_D(MDetailedListItem);

    if (d->image) {
        if (d->layout())
            for (int i = 0; i < d->layout()->count(); i++) {
                if (d->layout()->itemAt(i) == d->image) {
                    d->layout()->removeAt(i);
                    break;
                }
            }
        delete d->image;
        d->image = NULL;
    }

    if (image) {
        d->image = image;
        if (d->listItemStyle == MDetailedListItem::IconTitleSubtitleAndTwoSideIcons ||
            d->listItemStyle == MDetailedListItem::IconTitleSubtitleAndSideIconWithLabel) {
            setIconStyle(Icon);
            if (d->layout())
                d->layout()->addItem(imageWidget(), 0, 0, 3, 1, Qt::AlignLeft | Qt::AlignVCenter);
        } else if (d->listItemStyle == MDetailedListItem::ThumbnailTitleAndTwoSideIcons) {
            setIconStyle(Thumbnail);
            if (d->layout())
                d->layout()->addItem(imageWidget(), 0, 0, 2, 1, Qt::AlignLeft | Qt::AlignVCenter);
        } else if (d->listItemStyle == MDetailedListItem::ThumbnailTitleSubtitleAndTwoSideIcons) {
            setIconStyle(Thumbnail);
            if (d->layout())
                d->layout()->addItem(imageWidget(), 0, 0, 3, 1);
        }
        d->applyIconStyle();
    }
}

MImageWidget *MDetailedListItem::imageWidget()
{
    Q_D(MDetailedListItem);

    if (!d->image) {
        d->image = new MImageWidget(this);
        d->applyIconStyle();
    }
    return d->image;
}

MImageWidget *MDetailedListItem::sideTopImageWidget()
{
    Q_D(MDetailedListItem);

    if (!d->sideTopImage) {
        d->sideTopImage = new MImageWidget(this);
        d->sideTopImage->setObjectName("CommonSubIconTop");
    }
    return d->sideTopImage;
}

MImageWidget *MDetailedListItem::sideBottomImageWidget()
{
    Q_D(MDetailedListItem);

    if (!d->sideBottomImage) {
        d->sideBottomImage = new MImageWidget(this);
        d->sideBottomImage->setObjectName("CommonSubIconBottom");
    }
    return d->sideBottomImage;
}

MLabel *MDetailedListItem::titleLabelWidget()
{
    Q_D(MDetailedListItem);

    if (!d->titleLabel) {
        d->titleLabel = new MLabel(this);
        d->titleLabel->setTextElide(true);
        d->titleLabel->setObjectName("CommonTitle");
    }

    return d->titleLabel;
}

void MDetailedListItem::setTitle(const QString &title)
{
    titleLabelWidget()->setText(title);
}

QString MDetailedListItem::title()
{
    return titleLabelWidget()->text();
}

MLabel *MDetailedListItem::subtitleLabelWidget()
{
    Q_D(MDetailedListItem);

    if (!d->subtitleLabel) {
        d->subtitleLabel = new MLabel(this);
        d->subtitleLabel->setTextElide(true);
        d->subtitleLabel->setObjectName("CommonSubTitle");
    }

    return d->subtitleLabel;
}

void MDetailedListItem::setSubtitle(const QString &subtitle)
{
    subtitleLabelWidget()->setText(subtitle);
}

QString MDetailedListItem::subtitle()
{
    return subtitleLabelWidget()->text();
}

MLabel *MDetailedListItem::sideBottomLabelWidget()
{
    Q_D(MDetailedListItem);

    if (!d->sideBottomLabel) {
        d->sideBottomLabel = new MLabel(this);
        d->sideBottomLabel->setTextElide(true);
        d->sideBottomLabel->setAlignment(Qt::AlignRight);
        d->sideBottomLabel->setObjectName("CommonItemInfo");
        d->sideBottomLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
    }

    return d->sideBottomLabel;
}

void MDetailedListItem::setSideBottomTitle(const QString &text)
{
    sideBottomLabelWidget()->setText(text);
}

QString MDetailedListItem::sideBottomTitle()
{
    return sideBottomLabelWidget()->text();
}

void MDetailedListItem::resizeEvent(QGraphicsSceneResizeEvent *event)
{
    MListItem::resizeEvent(event);
    initLayout();
}

<commit_msg>Fixes: MDetailedListItemPrivate::clearLayout() does not remove all items from gridLayout.<commit_after>/***************************************************************************
**
** Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** 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
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "mdetailedlistitem.h"
#include "mdetailedlistitem_p.h"

#include <MImageWidget>
#include <MLabel>
#include <MStylableWidget>

#include <QGraphicsGridLayout>
#include <QGraphicsLinearLayout>

MDetailedListItemPrivate::MDetailedListItemPrivate(MDetailedListItem::ItemStyle style)
    : q_ptr(NULL),
    layoutGrid(NULL),
    image(NULL),
    sideTopImage(NULL),
    sideBottomImage(NULL),
    titleLabel(NULL),
    subtitleLabel(NULL),
    sideBottomLabel(NULL),
    isLayoutInitialized(false),
    listItemStyle(style),
    iconStyle(MDetailedListItem::Icon)
{

}

MDetailedListItemPrivate::~MDetailedListItemPrivate()
{
}

void MDetailedListItemPrivate::createLayout()
{
    Q_Q(MDetailedListItem);

    if (!layoutGrid) {
        layoutGrid = new QGraphicsGridLayout(q);
        layoutGrid->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
        layoutGrid->setContentsMargins(0, 0, 0, 0);
        layoutGrid->setSpacing(0);
    }

    switch (listItemStyle) {
    case MDetailedListItem::IconTitleSubtitleAndTwoSideIcons: {
            q->titleLabelWidget()->setObjectName("CommonTitle");
            q->setIconStyle(MDetailedListItem::Icon);

            layout()->addItem(q->imageWidget(), 0, 0, 3, 1, Qt::AlignLeft | Qt::AlignVCenter);
            layout()->addItem(q->titleLabelWidget(), 0, 1, Qt::AlignLeft | Qt::AlignTop);
            layout()->addItem(q->subtitleLabelWidget(), 1, 1, Qt::AlignLeft | Qt::AlignBottom);
            layout()->addItem(new QGraphicsWidget(q), 2, 1, 1, 2);
            layout()->addItem(q->sideTopImageWidget(), 0, 2, Qt::AlignRight | Qt::AlignBottom);
            layout()->addItem(q->sideBottomImageWidget(), 1, 2, Qt::AlignRight | Qt::AlignTop);

            break;
        }
    case MDetailedListItem::IconTitleSubtitleAndSideIconWithLabel: {
            q->titleLabelWidget()->setObjectName("CommonTitle");
            q->setIconStyle(MDetailedListItem::Icon);

            layout()->addItem(q->imageWidget(), 0, 0, 3, 1, Qt::AlignLeft | Qt::AlignVCenter);

            layout()->addItem(q->titleLabelWidget(), 0, 1, 1, 3, Qt::AlignLeft | Qt::AlignTop);
            layout()->addItem(q->sideTopImageWidget(), 0, 4, Qt::AlignRight | Qt::AlignBottom);

            layout()->addItem(q->subtitleLabelWidget(), 1, 1, 1, 2);

            layout()->addItem(q->sideBottomLabelWidget(), 1, 3, 1, 2);

            layout()->addItem(new QGraphicsWidget(q), 2, 1);
            break;
        }
    case MDetailedListItem::ThumbnailTitleAndTwoSideIcons: {
            q->titleLabelWidget()->setObjectName("CommonSingleTitle");
            q->setIconStyle(MDetailedListItem::Thumbnail);

            layout()->addItem(q->imageWidget(), 0, 0, 2, 1, Qt::AlignLeft | Qt::AlignVCenter);

            layout()->addItem(q->titleLabelWidget(), 0, 1, 2, 1, Qt::AlignLeft | Qt::AlignVCenter);
            layout()->addItem(new QGraphicsWidget(q), 2, 1, Qt::AlignRight | Qt::AlignVCenter);

            QGraphicsWidget * panel = new QGraphicsWidget(q);
            QGraphicsLinearLayout * panelLayout = new QGraphicsLinearLayout(Qt::Vertical);
            panelLayout->setContentsMargins(0, 0, 0, 0);
            panelLayout->setSpacing(0);
            panel->setLayout(panelLayout);

            q->sideTopImageWidget()->setParentItem(panel);
            q->sideBottomImageWidget()->setParentItem(panel);

            panelLayout->addItem(q->sideTopImageWidget());
            panelLayout->addItem(q->sideBottomImageWidget());

            layout()->addItem(panel, 0, 2, 2, 1, Qt::AlignVCenter);

            break;
        }
    case MDetailedListItem::ThumbnailTitleSubtitleAndTwoSideIcons: {
            q->titleLabelWidget()->setObjectName("CommonTitle");
            q->setIconStyle(MDetailedListItem::Thumbnail);

            layout()->addItem(q->imageWidget(), 0, 0, 3, 1);

            layout()->addItem(q->titleLabelWidget(), 0, 1);
            layout()->addItem(q->subtitleLabelWidget(), 1, 1);

            QGraphicsWidget * panel = new QGraphicsWidget(q);
            QGraphicsLinearLayout * panelLayout = new QGraphicsLinearLayout(Qt::Vertical);
            panelLayout->setContentsMargins(0, 0, 0, 0);
            panelLayout->setSpacing(0);
            panel->setLayout(panelLayout);

            q->sideTopImageWidget()->setParentItem(panel);
            q->sideBottomImageWidget()->setParentItem(panel);

            panelLayout->addItem(q->sideTopImageWidget());
            panelLayout->addItem(q->sideBottomImageWidget());

            layout()->addItem(panel, 0, 2, 3, 1, Qt::AlignVCenter);
            layout()->addItem(new QGraphicsWidget(q), 2, 1);
            break;
        }
    default:
        break;
    }
}

void MDetailedListItemPrivate::clearLayout()
{
    if (layout()) {
        while (layout()->count() > 0) {
            QGraphicsLayoutItem *item = layoutGrid->itemAt(0);
            layoutGrid->removeAt(0);
            delete item;
        }
        image = NULL;
        titleLabel = NULL;
        subtitleLabel = NULL;
        sideTopImage = NULL;
        sideBottomImage = NULL;
        sideBottomLabel = NULL;
    }
}

QGraphicsGridLayout *MDetailedListItemPrivate::layout()
{
    return layoutGrid;
}

void MDetailedListItemPrivate::applyIconStyle()
{
    if (!image)
        return;

    if (iconStyle == MDetailedListItem::Thumbnail)
        image->setObjectName("CommonThumbnail");
    else if (iconStyle == MDetailedListItem::Icon)
        image->setObjectName("CommonMainIcon");
}

MDetailedListItem::MDetailedListItem(MDetailedListItem::ItemStyle style, QGraphicsItem *parent)
    : MListItem(parent), d_ptr(new MDetailedListItemPrivate(style))
{
    Q_D(MDetailedListItem);
    d->q_ptr = this;

    setObjectName("CommonPanel");
}

MDetailedListItem::~MDetailedListItem()
{
    delete d_ptr;
}

void MDetailedListItem::initLayout()
{
    Q_D(MDetailedListItem);

    if (d->isLayoutInitialized)
        return;

    setLayout(createLayout());
    d->isLayoutInitialized = true;
}

QGraphicsLayout *MDetailedListItem::createLayout()
{
    Q_D(MDetailedListItem);

    clearLayout();
    d->createLayout();

    return d->layout();
}

void MDetailedListItem::clearLayout()
{
    Q_D(MDetailedListItem);

    d->clearLayout();
}

void MDetailedListItem::setItemStyle(ItemStyle itemStyle)
{
    Q_D(MDetailedListItem);

    if (itemStyle == d->listItemStyle)
        return;

    d->listItemStyle = itemStyle;
    d->isLayoutInitialized = false;
    initLayout();
}

MDetailedListItem::ItemStyle MDetailedListItem::itemStyle() const
{
    Q_D(const MDetailedListItem);
    return d->listItemStyle;
}

void MDetailedListItem::setIconStyle(IconStyle style)
{
    Q_D(MDetailedListItem);

    if(style == d->iconStyle)
        return;

    d->iconStyle = style;
    d->applyIconStyle();
}

MDetailedListItem::IconStyle MDetailedListItem::iconStyle() const
{
    Q_D(const MDetailedListItem);

    return d->iconStyle;
}

void MDetailedListItem::setImageWidget(MImageWidget *image)
{
    Q_D(MDetailedListItem);

    if (d->image) {
        if (d->layout())
            for (int i = 0; i < d->layout()->count(); i++) {
                if (d->layout()->itemAt(i) == d->image) {
                    d->layout()->removeAt(i);
                    break;
                }
            }
        delete d->image;
        d->image = NULL;
    }

    if (image) {
        d->image = image;
        if (d->listItemStyle == MDetailedListItem::IconTitleSubtitleAndTwoSideIcons ||
            d->listItemStyle == MDetailedListItem::IconTitleSubtitleAndSideIconWithLabel) {
            setIconStyle(Icon);
            if (d->layout())
                d->layout()->addItem(imageWidget(), 0, 0, 3, 1, Qt::AlignLeft | Qt::AlignVCenter);
        } else if (d->listItemStyle == MDetailedListItem::ThumbnailTitleAndTwoSideIcons) {
            setIconStyle(Thumbnail);
            if (d->layout())
                d->layout()->addItem(imageWidget(), 0, 0, 2, 1, Qt::AlignLeft | Qt::AlignVCenter);
        } else if (d->listItemStyle == MDetailedListItem::ThumbnailTitleSubtitleAndTwoSideIcons) {
            setIconStyle(Thumbnail);
            if (d->layout())
                d->layout()->addItem(imageWidget(), 0, 0, 3, 1);
        }
        d->applyIconStyle();
    }
}

MImageWidget *MDetailedListItem::imageWidget()
{
    Q_D(MDetailedListItem);

    if (!d->image) {
        d->image = new MImageWidget(this);
        d->applyIconStyle();
    }
    return d->image;
}

MImageWidget *MDetailedListItem::sideTopImageWidget()
{
    Q_D(MDetailedListItem);

    if (!d->sideTopImage) {
        d->sideTopImage = new MImageWidget(this);
        d->sideTopImage->setObjectName("CommonSubIconTop");
    }
    return d->sideTopImage;
}

MImageWidget *MDetailedListItem::sideBottomImageWidget()
{
    Q_D(MDetailedListItem);

    if (!d->sideBottomImage) {
        d->sideBottomImage = new MImageWidget(this);
        d->sideBottomImage->setObjectName("CommonSubIconBottom");
    }
    return d->sideBottomImage;
}

MLabel *MDetailedListItem::titleLabelWidget()
{
    Q_D(MDetailedListItem);

    if (!d->titleLabel) {
        d->titleLabel = new MLabel(this);
        d->titleLabel->setTextElide(true);
        d->titleLabel->setObjectName("CommonTitle");
    }

    return d->titleLabel;
}

void MDetailedListItem::setTitle(const QString &title)
{
    titleLabelWidget()->setText(title);
}

QString MDetailedListItem::title()
{
    return titleLabelWidget()->text();
}

MLabel *MDetailedListItem::subtitleLabelWidget()
{
    Q_D(MDetailedListItem);

    if (!d->subtitleLabel) {
        d->subtitleLabel = new MLabel(this);
        d->subtitleLabel->setTextElide(true);
        d->subtitleLabel->setObjectName("CommonSubTitle");
    }

    return d->subtitleLabel;
}

void MDetailedListItem::setSubtitle(const QString &subtitle)
{
    subtitleLabelWidget()->setText(subtitle);
}

QString MDetailedListItem::subtitle()
{
    return subtitleLabelWidget()->text();
}

MLabel *MDetailedListItem::sideBottomLabelWidget()
{
    Q_D(MDetailedListItem);

    if (!d->sideBottomLabel) {
        d->sideBottomLabel = new MLabel(this);
        d->sideBottomLabel->setTextElide(true);
        d->sideBottomLabel->setAlignment(Qt::AlignRight);
        d->sideBottomLabel->setObjectName("CommonItemInfo");
        d->sideBottomLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
    }

    return d->sideBottomLabel;
}

void MDetailedListItem::setSideBottomTitle(const QString &text)
{
    sideBottomLabelWidget()->setText(text);
}

QString MDetailedListItem::sideBottomTitle()
{
    return sideBottomLabelWidget()->text();
}

void MDetailedListItem::resizeEvent(QGraphicsSceneResizeEvent *event)
{
    MListItem::resizeEvent(event);
    initLayout();
}

<|endoftext|>


<commit_before>/*
 * REnvironmentPosix.cpp
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * 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/r_util/REnvironment.hpp>

#include <algorithm>

#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/replace.hpp>

#include <core/Error.hpp>
#include <core/FilePath.hpp>
#include <core/ConfigUtils.hpp>
#include <core/system/System.hpp>

namespace core {
namespace r_util {

namespace {

FilePath scanForRScript(const std::vector<std::string>& rScriptPaths)
{
   // iterate over paths
   for (std::vector<std::string>::const_iterator it = rScriptPaths.begin();
        it != rScriptPaths.end();
        ++it)
   {
      FilePath rScriptPath(*it);
      if (rScriptPath.exists())
      {
         // verify that the alias points to a real version of R
         Error error = core::system::realPath(*it, &rScriptPath);
         if (!error)
         {
            return rScriptPath;
         }
         else
         {
            LOG_ERROR(error);
            continue;
         }
      }
   }

   // didn't find it
   return FilePath();
}

// MacOS X Specific
#ifdef __APPLE__

#define kLibRFileName            "libR.dylib"
#define kLibraryPathEnvVariable  "DYLD_LIBRARY_PATH"

// no extra paths on the mac
std::string extraLibraryPaths(const FilePath& ldPathsScript,
                              const std::string& rHome)
{
   return std::string();
}

FilePath systemDefaultRScript()
{
   // define potential paths (use same order as in conventional osx PATH)
   std::vector<std::string> rScriptPaths;
   rScriptPaths.push_back("/opt/local/bin/R");
   rScriptPaths.push_back("/usr/bin/R");
   rScriptPaths.push_back("/usr/local/bin/R");
   return scanForRScript(rScriptPaths);
}

bool getRHomeAndLibPath(const FilePath& rScriptPath,
                        const config_utils::Variables& scriptVars,
                        std::string* pRHome,
                        std::string* pRLibPath,
                        std::string* pErrMsg)
{
   config_utils::Variables::const_iterator it = scriptVars.find("R_HOME_DIR");
   if (it != scriptVars.end())
   {
      // get R home
      *pRHome = it->second;

      // get R lib path (probe subdiretories if necessary)
      FilePath libPath = FilePath(*pRHome).complete("lib");

      // check for dylib in lib and lib/x86_64
      if (libPath.complete(kLibRFileName).exists())
      {
         *pRLibPath = libPath.absolutePath();
         return true;
      }
      else if (libPath.complete("x86_64/" kLibRFileName).exists())
      {
         *pRLibPath = libPath.complete("x86_64").absolutePath();
         return true;
      }
      else
      {
         *pErrMsg = "Unable to find " kLibRFileName " in expected locations"
                    "within R Home directory " + *pRHome;
         LOG_ERROR_MESSAGE(*pErrMsg);
         return false;
      }
   }
   else
   {
      *pErrMsg = "Unable to find R_HOME_DIR in " + rScriptPath.absolutePath();
      LOG_ERROR_MESSAGE(*pErrMsg);
      return false;
   }
}

// Linux specific
#else

#define kLibRFileName            "libR.so"
#define kLibraryPathEnvVariable  "LD_LIBRARY_PATH"

// extra paths from R (for rjava) on linux
std::string extraLibraryPaths(const FilePath& ldPathsScript,
                              const std::string& rHome)
{
   // verify that script exists
   if (!ldPathsScript.exists())
   {
      LOG_WARNING_MESSAGE("r-ldpaths script not found at " +
                          ldPathsScript.absolutePath());
      return std::string();
   }

   // run script to capture paths
   std::string libraryPaths;
   std::string command = ldPathsScript.absolutePath() + " " + rHome;
   Error error = system::captureCommand(command, &libraryPaths);
   if (error)
      LOG_ERROR(error);
   boost::algorithm::trim(libraryPaths);
   return libraryPaths;
}

FilePath systemDefaultRScript()
{
   // ask system which R to use
   std::string whichOutput;
   Error error = core::system::captureCommand("which R", &whichOutput);
   if (error)
   {
      LOG_ERROR(error);
      return FilePath();
   }
   boost::algorithm::trim(whichOutput);

   // check for nothing returned
   if (whichOutput.empty())
   {
      // try scanning known locations
      std::vector<std::string> rScriptPaths;
      rScriptPaths.push_back("/usr/local/bin/R");
      rScriptPaths.push_back("/usr/bin/R");
      FilePath rScriptPath = scanForRScript(rScriptPaths);
      if (rScriptPath.empty())
         return FilePath();
      else
         whichOutput = rScriptPath.absolutePath();
   }

   // verify that the alias points to a real version of R
   FilePath rBinaryPath;
   error = core::system::realPath(whichOutput, &rBinaryPath);
   if (error)
   {
      LOG_ERROR(error);
      return FilePath();
   }

   // check for real path doesn't exist
   if (!rBinaryPath.exists())
   {
      LOG_ERROR_MESSAGE("Real path of R script does not exist (" +
                        rBinaryPath.absolutePath() + ")");
      return FilePath();
   }

   // got a valid R binary
   return rBinaryPath;
}

bool getRHomeAndLibPath(const FilePath& rScriptPath,
                        const config_utils::Variables& scriptVars,
                        std::string* pRHome,
                        std::string* pRLibPath,
                        std::string* pErrMsg)
{
   // eliminate a potentially conflicting R_HOME before calling R RHOME"
   // (the normal semantics of invoking the R script are that it overwrites
   // R_HOME and prints a warning -- this warning is co-mingled with the
   // output of "R RHOME" and messes up our parsing)
   core::system::setenv("R_HOME", "");

   // run R script to detect R home
   std::string rHomeOutput;
   std::string command = rScriptPath.absolutePath() + " RHOME";
   Error error = core::system::captureCommand(command, &rHomeOutput);
   if (error)
   {
      LOG_ERROR(error);
      *pErrMsg = "Error running R (" + rScriptPath.absolutePath() + "): " +
                 error.summary();
      return false;
   }
   else
   {
      boost::algorithm::trim(rHomeOutput);
      *pRHome = rHomeOutput;
      *pRLibPath = FilePath(*pRHome).complete("lib").absolutePath();
      return true;
   }
}

#endif

bool validateREnvironment(const EnvironmentVars& vars,
                          const FilePath& rLibPath,
                          std::string* pErrMsg)
{
   // first extract paths
   FilePath rHomePath, rSharePath, rIncludePath, rDocPath, rLibRPath;
   for (EnvironmentVars::const_iterator it = vars.begin();
        it != vars.end();
        ++it)
   {
      if (it->first == "R_HOME")
         rHomePath = FilePath(it->second);
      else if (it->first == "R_SHARE_DIR")
         rSharePath = FilePath(it->second);
      else if (it->first == "R_INCLUDE_DIR")
         rIncludePath = FilePath(it->second);
      else if (it->first == "R_DOC_DIR")
         rDocPath = FilePath(it->second);
   }

   // resolve libR path
   rLibRPath = rLibPath.complete(kLibRFileName);

   // validate required paths (if these don't exist then rsession won't
   // be able start up)
   if (!rHomePath.exists())
   {
      *pErrMsg = "R Home path (" + rHomePath.absolutePath() + ") not found";
      return false;
   }
   else if (!rLibPath.exists())
   {
      *pErrMsg = "R lib path (" + rLibPath.absolutePath() + ") not found";
      return false;
   }
   else if (!rLibRPath.exists())
   {
      *pErrMsg = "R shared library (" + rLibRPath.absolutePath() + ") "
                 "not found. If this is a custom build of R, was it "
                 "built with the --enable-R-shlib option?";
      return false;
   }
   else if (!rDocPath.exists())
   {
      *pErrMsg = "R doc dir (" + rDocPath.absolutePath() + ") not found.";
      return false;
   }

   // log warnings for other missing paths (rsession can still start but
   // won't be able to find these env variables)

   if (!rSharePath.exists())
   {
      LOG_WARNING_MESSAGE("R share path (" + rSharePath.absolutePath() +
                          ") not found");
   }

   if (!rIncludePath.exists())
   {
      LOG_WARNING_MESSAGE("R include path (" + rIncludePath.absolutePath() +
                          ") not found");
   }

   return true;
}

// resolve an R path which has been parsed from the R bash script. If
// R is running out of the source directory (and was thus never installed)
// then the values for R_DOC_DIR, etc. will contain unexpanded references
// to the R_HOME_DIR, so we expand these if they are present.
std::string resolveRPath(const FilePath& rHomePath, const std::string& path)
{
   std::string resolvedPath = path;
   boost::algorithm::replace_all(resolvedPath,
                                 "${R_HOME_DIR}",
                                 rHomePath.absolutePath());
   return resolvedPath;
}

} // anonymous namespace

bool detectREnvironment(const FilePath& ldPathsScript,
                        EnvironmentVars* pVars,
                        std::string* pErrMsg)
{
   return detectREnvironment(FilePath(),
                             ldPathsScript,
                             std::string(),
                             pVars,
                             pErrMsg);
}

bool detectREnvironment(const FilePath& whichRScript,
                        const FilePath& ldPathsScript,
                        const std::string& ldLibraryPath,
                        EnvironmentVars* pVars,
                        std::string* pErrMsg)
{
   // if there is a which R script override then validate it (but only
   // log a warning then move on to the system default)
   FilePath rScriptPath;
   if (!whichRScript.empty())
   {
      // but warn (and ignore) if it doesn't exist
      if (!whichRScript.exists())
      {
         LOG_WARNING_MESSAGE("Override for which R (" +
                             whichRScript.absolutePath() +
                             ") does not exist (ignoring)");
      }

      // also warn and ignore if it is a directory
      else if (whichRScript.isDirectory())
      {
         LOG_WARNING_MESSAGE("Override for which R (" +
                             whichRScript.absolutePath() +
                             ") is a directory rather than a file (ignoring)");
      }

      // otherwise set it
      else
      {
         rScriptPath = whichRScript;
      }
   }

   // if don't have an override (or it was invalid) then use system default
   if (rScriptPath.empty())
      rScriptPath = systemDefaultRScript();

   // bail if not found
   if (!rScriptPath.exists())
   {
      LOG_ERROR(pathNotFoundError(rScriptPath.absolutePath(), ERROR_LOCATION));
      *pErrMsg = "R binary (" + rScriptPath.absolutePath() + ") not found";
      return false;
   }

   // scan R script for other locations and append them to our vars
   config_utils::Variables scriptVars;
   Error error = config_utils::extractVariables(rScriptPath, &scriptVars);
   if (error)
   {
      LOG_ERROR(error);
      *pErrMsg = "Error reading R script (" + rScriptPath.absolutePath() +
                 "), " + error.summary();
      return false;
   }

   // get r home path
   std::string rHome, rLib;
   if (!getRHomeAndLibPath(rScriptPath, scriptVars, &rHome, &rLib, pErrMsg))
      return false;

   // validate: error if we got no output
   if (rHome.empty())
   {
      *pErrMsg = "Unable to determine R home directory";
      LOG_ERROR(systemError(boost::system::errc::not_supported,
                            *pErrMsg,
                            ERROR_LOCATION));
      return false;
   }

   // validate: error if `R RHOME` yields file that doesn't exist
   FilePath rHomePath(rHome);
   if (!rHomePath.exists())
   {
      *pErrMsg = "R home path (" + rHome + ") not found";
      LOG_ERROR(pathNotFoundError(*pErrMsg, ERROR_LOCATION));
      return false;
   }

   // set R home path
   pVars->push_back(std::make_pair("R_HOME", rHomePath.absolutePath()));

   // set other environment values
   pVars->push_back(std::make_pair("R_SHARE_DIR",
                                   resolveRPath(rHomePath,
                                                scriptVars["R_SHARE_DIR"])));
   pVars->push_back(std::make_pair("R_INCLUDE_DIR",
                                   resolveRPath(rHomePath,
                                                scriptVars["R_INCLUDE_DIR"])));
   pVars->push_back(std::make_pair("R_DOC_DIR",
                                   resolveRPath(rHomePath,
                                                scriptVars["R_DOC_DIR"])));

   // determine library path (existing + r lib dir + r extra lib dirs)
   FilePath rLibPath(rLib);
   std::string libraryPath = core::system::getenv(kLibraryPathEnvVariable);
   if (!libraryPath.empty())
      libraryPath.append(":");
   libraryPath.append(ldLibraryPath);
   if (!libraryPath.empty())
      libraryPath.append(":");
   libraryPath.append(rLibPath.absolutePath());
   std::string extraPaths = extraLibraryPaths(ldPathsScript,
                                              rHomePath.absolutePath());
   if (!extraPaths.empty())
      libraryPath.append(":" + extraPaths);
   pVars->push_back(std::make_pair(kLibraryPathEnvVariable, libraryPath));

   return validateREnvironment(*pVars, rLibPath, pErrMsg);
}

void setREnvironmentVars(const EnvironmentVars& vars)
{
   for (EnvironmentVars::const_iterator it = vars.begin();
        it != vars.end();
        ++it)
   {
      core::system::setenv(it->first, it->second);
   }
}

} // namespace r_util
} // namespace core

<commit_msg>refactor REnvironmentPosix in preparation for detection changes<commit_after>/*
 * REnvironmentPosix.cpp
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * 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/r_util/REnvironment.hpp>

#include <algorithm>

#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/replace.hpp>

#include <core/Error.hpp>
#include <core/FilePath.hpp>
#include <core/ConfigUtils.hpp>
#include <core/system/System.hpp>

namespace core {
namespace r_util {

namespace {

FilePath scanForRScript(const std::vector<std::string>& rScriptPaths)
{
   // iterate over paths
   for (std::vector<std::string>::const_iterator it = rScriptPaths.begin();
        it != rScriptPaths.end();
        ++it)
   {
      FilePath rScriptPath(*it);
      if (rScriptPath.exists())
      {
         // verify that the alias points to a real version of R
         Error error = core::system::realPath(*it, &rScriptPath);
         if (!error)
         {
            return rScriptPath;
         }
         else
         {
            LOG_ERROR(error);
            continue;
         }
      }
   }

   // didn't find it
   return FilePath();
}

// MacOS X Specific
#ifdef __APPLE__

#define kLibRFileName            "libR.dylib"
#define kLibraryPathEnvVariable  "DYLD_LIBRARY_PATH"

// no extra paths on the mac
std::string extraLibraryPaths(const FilePath& ldPathsScript,
                              const std::string& rHome)
{
   return std::string();
}

FilePath systemDefaultRScript()
{
   // define potential paths (use same order as in conventional osx PATH)
   std::vector<std::string> rScriptPaths;
   rScriptPaths.push_back("/opt/local/bin/R");
   rScriptPaths.push_back("/usr/bin/R");
   rScriptPaths.push_back("/usr/local/bin/R");
   return scanForRScript(rScriptPaths);
}

bool getRHomeAndLibPath(const FilePath& rScriptPath,
                        const config_utils::Variables& scriptVars,
                        std::string* pRHome,
                        std::string* pRLibPath,
                        std::string* pErrMsg)
{
   config_utils::Variables::const_iterator it = scriptVars.find("R_HOME_DIR");
   if (it != scriptVars.end())
   {
      // get R home
      *pRHome = it->second;

      // get R lib path (probe subdiretories if necessary)
      FilePath libPath = FilePath(*pRHome).complete("lib");

      // check for dylib in lib and lib/x86_64
      if (libPath.complete(kLibRFileName).exists())
      {
         *pRLibPath = libPath.absolutePath();
         return true;
      }
      else if (libPath.complete("x86_64/" kLibRFileName).exists())
      {
         *pRLibPath = libPath.complete("x86_64").absolutePath();
         return true;
      }
      else
      {
         *pErrMsg = "Unable to find " kLibRFileName " in expected locations"
                    "within R Home directory " + *pRHome;
         LOG_ERROR_MESSAGE(*pErrMsg);
         return false;
      }
   }
   else
   {
      *pErrMsg = "Unable to find R_HOME_DIR in " + rScriptPath.absolutePath();
      LOG_ERROR_MESSAGE(*pErrMsg);
      return false;
   }
}

// Linux specific
#else

#define kLibRFileName            "libR.so"
#define kLibraryPathEnvVariable  "LD_LIBRARY_PATH"

// extra paths from R (for rjava) on linux
std::string extraLibraryPaths(const FilePath& ldPathsScript,
                              const std::string& rHome)
{
   // verify that script exists
   if (!ldPathsScript.exists())
   {
      LOG_WARNING_MESSAGE("r-ldpaths script not found at " +
                          ldPathsScript.absolutePath());
      return std::string();
   }

   // run script to capture paths
   std::string libraryPaths;
   std::string command = ldPathsScript.absolutePath() + " " + rHome;
   Error error = system::captureCommand(command, &libraryPaths);
   if (error)
      LOG_ERROR(error);
   boost::algorithm::trim(libraryPaths);
   return libraryPaths;
}

FilePath systemDefaultRScript()
{
   // ask system which R to use
   std::string whichOutput;
   Error error = core::system::captureCommand("which R", &whichOutput);
   if (error)
   {
      LOG_ERROR(error);
      return FilePath();
   }
   boost::algorithm::trim(whichOutput);

   // check for nothing returned
   if (whichOutput.empty())
   {
      // try scanning known locations
      std::vector<std::string> rScriptPaths;
      rScriptPaths.push_back("/usr/local/bin/R");
      rScriptPaths.push_back("/usr/bin/R");
      FilePath rScriptPath = scanForRScript(rScriptPaths);
      if (rScriptPath.empty())
         return FilePath();
      else
         whichOutput = rScriptPath.absolutePath();
   }

   // verify that the alias points to a real version of R
   FilePath rBinaryPath;
   error = core::system::realPath(whichOutput, &rBinaryPath);
   if (error)
   {
      LOG_ERROR(error);
      return FilePath();
   }

   // check for real path doesn't exist
   if (!rBinaryPath.exists())
   {
      LOG_ERROR_MESSAGE("Real path of R script does not exist (" +
                        rBinaryPath.absolutePath() + ")");
      return FilePath();
   }

   // got a valid R binary
   return rBinaryPath;
}

bool getRHomeAndLibPath(const FilePath& rScriptPath,
                        const config_utils::Variables& scriptVars,
                        std::string* pRHome,
                        std::string* pRLibPath,
                        std::string* pErrMsg)
{
   // eliminate a potentially conflicting R_HOME before calling R RHOME"
   // (the normal semantics of invoking the R script are that it overwrites
   // R_HOME and prints a warning -- this warning is co-mingled with the
   // output of "R RHOME" and messes up our parsing)
   core::system::setenv("R_HOME", "");

   // run R script to detect R home
   std::string rHomeOutput;
   std::string command = rScriptPath.absolutePath() + " RHOME";
   Error error = core::system::captureCommand(command, &rHomeOutput);
   if (error)
   {
      LOG_ERROR(error);
      *pErrMsg = "Error running R (" + rScriptPath.absolutePath() + "): " +
                 error.summary();
      return false;
   }
   else
   {
      boost::algorithm::trim(rHomeOutput);
      *pRHome = rHomeOutput;
      *pRLibPath = FilePath(*pRHome).complete("lib").absolutePath();
      return true;
   }
}

#endif

bool validateREnvironment(const EnvironmentVars& vars,
                          const FilePath& rLibPath,
                          std::string* pErrMsg)
{
   // first extract paths
   FilePath rHomePath, rSharePath, rIncludePath, rDocPath, rLibRPath;
   for (EnvironmentVars::const_iterator it = vars.begin();
        it != vars.end();
        ++it)
   {
      if (it->first == "R_HOME")
         rHomePath = FilePath(it->second);
      else if (it->first == "R_SHARE_DIR")
         rSharePath = FilePath(it->second);
      else if (it->first == "R_INCLUDE_DIR")
         rIncludePath = FilePath(it->second);
      else if (it->first == "R_DOC_DIR")
         rDocPath = FilePath(it->second);
   }

   // resolve libR path
   rLibRPath = rLibPath.complete(kLibRFileName);

   // validate required paths (if these don't exist then rsession won't
   // be able start up)
   if (!rHomePath.exists())
   {
      *pErrMsg = "R Home path (" + rHomePath.absolutePath() + ") not found";
      return false;
   }
   else if (!rLibPath.exists())
   {
      *pErrMsg = "R lib path (" + rLibPath.absolutePath() + ") not found";
      return false;
   }
   else if (!rLibRPath.exists())
   {
      *pErrMsg = "R shared library (" + rLibRPath.absolutePath() + ") "
                 "not found. If this is a custom build of R, was it "
                 "built with the --enable-R-shlib option?";
      return false;
   }
   else if (!rDocPath.exists())
   {
      *pErrMsg = "R doc dir (" + rDocPath.absolutePath() + ") not found.";
      return false;
   }

   // log warnings for other missing paths (rsession can still start but
   // won't be able to find these env variables)

   if (!rSharePath.exists())
   {
      LOG_WARNING_MESSAGE("R share path (" + rSharePath.absolutePath() +
                          ") not found");
   }

   if (!rIncludePath.exists())
   {
      LOG_WARNING_MESSAGE("R include path (" + rIncludePath.absolutePath() +
                          ") not found");
   }

   return true;
}

// resolve an R path which has been parsed from the R bash script. If
// R is running out of the source directory (and was thus never installed)
// then the values for R_DOC_DIR, etc. will contain unexpanded references
// to the R_HOME_DIR, so we expand these if they are present.
std::string resolveRPath(const FilePath& rHomePath, const std::string& path)
{
   std::string resolvedPath = path;
   boost::algorithm::replace_all(resolvedPath,
                                 "${R_HOME_DIR}",
                                 rHomePath.absolutePath());
   return resolvedPath;
}

bool detectRLocations(const FilePath& rScriptPath,
                      FilePath* pHomePath,
                      FilePath* pLibPath,
                      config_utils::Variables* pScriptVars,
                      std::string* pErrMsg)
{
   // scan R script for other locations and append them to our vars
   Error error = config_utils::extractVariables(rScriptPath, pScriptVars);
   if (error)
   {
      LOG_ERROR(error);
      *pErrMsg = "Error reading R script (" + rScriptPath.absolutePath() +
                 "), " + error.summary();
      return false;
   }

   // get r home path
   std::string rHome, rLib;
   if (!getRHomeAndLibPath(rScriptPath, *pScriptVars, &rHome, &rLib, pErrMsg))
      return false;

   // validate: error if we got no output
   if (rHome.empty())
   {
      *pErrMsg = "Unable to determine R home directory";
      LOG_ERROR(systemError(boost::system::errc::not_supported,
                            *pErrMsg,
                            ERROR_LOCATION));
      return false;
   }

   // validate: error if `R RHOME` yields file that doesn't exist
   *pHomePath = FilePath(rHome);
   if (!pHomePath->exists())
   {
      *pErrMsg = "R home path (" + rHome + ") not found";
      LOG_ERROR(pathNotFoundError(*pErrMsg, ERROR_LOCATION));
      return false;
   }

   // get lib path
   *pLibPath = FilePath(rLib);

   return true;
}

} // anonymous namespace

bool detectREnvironment(const FilePath& ldPathsScript,
                        EnvironmentVars* pVars,
                        std::string* pErrMsg)
{
   return detectREnvironment(FilePath(),
                             ldPathsScript,
                             std::string(),
                             pVars,
                             pErrMsg);
}

bool detectREnvironment(const FilePath& whichRScript,
                        const FilePath& ldPathsScript,
                        const std::string& ldLibraryPath,
                        EnvironmentVars* pVars,
                        std::string* pErrMsg)
{
   // if there is a which R script override then validate it (but only
   // log a warning then move on to the system default)
   FilePath rScriptPath;
   if (!whichRScript.empty())
   {
      // but warn (and ignore) if it doesn't exist
      if (!whichRScript.exists())
      {
         LOG_WARNING_MESSAGE("Override for which R (" +
                             whichRScript.absolutePath() +
                             ") does not exist (ignoring)");
      }

      // also warn and ignore if it is a directory
      else if (whichRScript.isDirectory())
      {
         LOG_WARNING_MESSAGE("Override for which R (" +
                             whichRScript.absolutePath() +
                             ") is a directory rather than a file (ignoring)");
      }

      // otherwise set it
      else
      {
         rScriptPath = whichRScript;
      }
   }

   // if don't have an override (or it was invalid) then use system default
   if (rScriptPath.empty())
      rScriptPath = systemDefaultRScript();

   // bail if not found
   if (!rScriptPath.exists())
   {
      LOG_ERROR(pathNotFoundError(rScriptPath.absolutePath(), ERROR_LOCATION));
      *pErrMsg = "R binary (" + rScriptPath.absolutePath() + ") not found";
      return false;
   }

   // detect R locations
   FilePath rHomePath, rLibPath;
   config_utils::Variables scriptVars;
   if (!detectRLocations(rScriptPath,
                         &rHomePath,
                         &rLibPath,
                         &scriptVars,
                         pErrMsg))
   {
      return false;
   }

   // set R home path
   pVars->push_back(std::make_pair("R_HOME", rHomePath.absolutePath()));

   // set other environment values
   pVars->push_back(std::make_pair("R_SHARE_DIR",
                                   resolveRPath(rHomePath,
                                                scriptVars["R_SHARE_DIR"])));
   pVars->push_back(std::make_pair("R_INCLUDE_DIR",
                                   resolveRPath(rHomePath,
                                                scriptVars["R_INCLUDE_DIR"])));
   pVars->push_back(std::make_pair("R_DOC_DIR",
                                   resolveRPath(rHomePath,
                                                scriptVars["R_DOC_DIR"])));

   // determine library path (existing + r lib dir + r extra lib dirs)
   std::string libraryPath = core::system::getenv(kLibraryPathEnvVariable);
   if (!libraryPath.empty())
      libraryPath.append(":");
   libraryPath.append(ldLibraryPath);
   if (!libraryPath.empty())
      libraryPath.append(":");
   libraryPath.append(rLibPath.absolutePath());
   std::string extraPaths = extraLibraryPaths(ldPathsScript,
                                              rHomePath.absolutePath());
   if (!extraPaths.empty())
      libraryPath.append(":" + extraPaths);
   pVars->push_back(std::make_pair(kLibraryPathEnvVariable, libraryPath));

   return validateREnvironment(*pVars, rLibPath, pErrMsg);
}

void setREnvironmentVars(const EnvironmentVars& vars)
{
   for (EnvironmentVars::const_iterator it = vars.begin();
        it != vars.end();
        ++it)
   {
      core::system::setenv(it->first, it->second);
   }
}

} // namespace r_util
} // namespace core

<|endoftext|>


<commit_before>#include <cache.h>

Cache::Cache() {
    QString medusaHome = QDir::homePath() + "/.medusa/";

    if (!QFile(medusaHome).exists()) {
        cerr << "\x1b[31m[Medusa Error] What?! Medusa Home folder not found or unreadable. Please Reinstall.\x1b[0m" << endl;
        exit(-1);
    }

    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(medusaHome + "medusa.cache");

    if (!QFile(medusaHome + "medusa.cache").exists()) {
        db.open();
        QSqlQuery query(db);
        query.exec("CREATE TABLE MedusaCache (InFile TEXT UNIQUE, Hash VARCHAR(64) UNIQUE, GenCode TEXT)");
    }
    else
        db.open();
}

Cache::~Cache() {
    db.close();
}

QString Cache::hashFile(QString path) {
    sha256_ctx ctx;
    FILE *inFile;
    char buffer[BUFFER_SIZE], output[2 * SHA256_DIGEST_SIZE + 1];
    unsigned char digest[SHA256_DIGEST_SIZE];
    int bytes;

    if (!(inFile = fopen(path.toStdString().c_str(), "rb"))) {
        cerr << "\x1b[31m[Medusa Error]: Couldn't read " + path.toStdString() + ". Please check if it exists and is readable.\x1b[0m" << endl;
        exit(-1);
    }

    sha256_init(&ctx);
    while ((bytes = fread(buffer, 1, BUFFER_SIZE, inFile)) != 0)
        sha256_update(&ctx, (const unsigned char *) buffer, bytes);
    sha256_final(&ctx, digest);

    fclose(inFile);
    output[2 * SHA256_DIGEST_SIZE] = 0;

    for (int i = 0; i < SHA256_DIGEST_SIZE ; i++)
        sprintf(output + 2 * i, "%02X", digest[i]);

    return QString(output);
}

bool Cache::tryInsert(QString path, QString hash) {
    QSqlQuery query(db);
    return query.exec("INSERT INTO MedusaCache VALUES ('" + path + "', '" + hash + "', '')");
}

bool Cache::changed(QString path, QString hash, QString &code) {
    QSqlQuery query(db);

    query.exec("SELECT Hash, GenCode FROM MedusaCache WHERE InFile='" + path + "'");
    query.next();

    if (query.value(0).toString() != hash)
        return query.exec("UPDATE MedusaCache SET Hash='" + hash + "' WHERE InFile='" + path + "'");

    code = query.value(1).toString();
    return false;
}

bool Cache::isCached(QString path, QString &code) {
    QString hash = hashFile(path);
    QSqlQuery query(db);

    if (!tryInsert(path, hash)) {
        query.exec("SELECT GenCode FROM MedusaCache WHERE Hash='" + hash + "'");
        query.next();

        if ((code = query.value(0).toString()) != "")
            return true;
        else
            return changed(path, hash, code) ? false : true;
    }
    else
        return false;
}
<commit_msg>Fixed Cache Checks<commit_after>#include <cache.h>

Cache::Cache() {
    QString medusaHome = QDir::homePath() + "/.medusa/";

    if (!QFile(medusaHome).exists()) {
        cerr << "\x1b[31m[Medusa Error] What?! Medusa Home folder not found or unreadable. Please Reinstall.\x1b[0m" << endl;
        exit(-1);
    }

    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(medusaHome + "medusa.cache");

    if (!QFile(medusaHome + "medusa.cache").exists()) {
        db.open();
        QSqlQuery query(db);
        query.exec("CREATE TABLE MedusaCache (InFile TEXT UNIQUE, Hash VARCHAR(64) UNIQUE, GenCode TEXT)");
    }
    else
        db.open();
}

Cache::~Cache() {
    db.close();
}

QString Cache::hashFile(QString path) {
    sha256_ctx ctx;
    FILE *inFile;
    char buffer[BUFFER_SIZE], output[2 * SHA256_DIGEST_SIZE + 1];
    unsigned char digest[SHA256_DIGEST_SIZE];
    int bytes;

    if (!(inFile = fopen(path.toStdString().c_str(), "rb"))) {
        cerr << "\x1b[31m[Medusa Error]: Couldn't read " + path.toStdString() + ". Please check if it exists and is readable.\x1b[0m" << endl;
        exit(-1);
    }

    sha256_init(&ctx);
    while ((bytes = fread(buffer, 1, BUFFER_SIZE, inFile)) != 0)
        sha256_update(&ctx, (const unsigned char *) buffer, bytes);
    sha256_final(&ctx, digest);

    fclose(inFile);
    output[2 * SHA256_DIGEST_SIZE] = 0;

    for (int i = 0; i < SHA256_DIGEST_SIZE ; i++)
        sprintf(output + 2 * i, "%02X", digest[i]);

    return QString(output);
}

bool Cache::tryInsert(QString path, QString hash) {
    QSqlQuery query(db);
    return query.exec("INSERT INTO MedusaCache VALUES ('" + path + "', '" + hash + "', '')");
}

bool Cache::changed(QString path, QString hash, QString &code) {
    QSqlQuery query(db);

    query.exec("SELECT Hash, GenCode FROM MedusaCache WHERE InFile='" + path + "'");
    query.next();

    if (query.value(0).toString() != hash)
        return query.exec("UPDATE MedusaCache SET Hash='" + hash + "' WHERE InFile='" + path + "'");

    code = query.value(1).toString();
    return false;
}

bool Cache::isCached(QString path, QString &code) {
    QString hash = hashFile(path);
    QSqlQuery query(db);

    if (!tryInsert(path, hash)) {
        query.exec("SELECT GenCode FROM MedusaCache WHERE Hash='" + hash + "'");
        query.next();

        if (query.isValid()) {
            code = query.value(0).toString();
            return true;
        }
        else
            return changed(path, hash, code) ? false : true;
    }
    else
        return false;
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016 zScale Technology GmbH <legal@zscale.io>
 * Authors:
 *   - Paul Asmuth <paul@zscale.io>
 *   - Laura Schlimmer <laura@zscale.io>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * 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 license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include "eventql/eventql.h"
#include <eventql/util/stdtypes.h>
#include <eventql/util/exception.h>
#include <eventql/util/wallclock.h>
#include <eventql/util/test/unittest.h>
#include <eventql/config/process_config.h>

using namespace eventql;
UNIT_TEST(ProcessConfigTest);

TEST_CASE(ProcessConfigTest, TestProcessConfigBuilder, [] () {
  ProcessConfigBuilder builder;
  builder.setProperty("evql", "host", "localhost");
  builder.setProperty("evql", "port", "8080");
  builder.setProperty("evql", "fuu", "bar");

  auto config = builder.getConfig();
  {
    auto p = config->getProperty("evql", "host");
    EXPECT_FALSE(p.isEmpty());
    EXPECT_EQ(p.get(), "localhost");
  }

  {
    auto p = config->getProperty("evql", "port");
    EXPECT_FALSE(p.isEmpty());
    EXPECT_EQ(p.get(), "8080");
  }

  {
    auto p = config->getProperty("evql", "fuu");
    EXPECT_FALSE(p.isEmpty());
    EXPECT_EQ(p.get(), "bar");
  }
});

<commit_msg>ProcessConfigBuilderLoadFileTest<commit_after>/**
 * Copyright (c) 2016 zScale Technology GmbH <legal@zscale.io>
 * Authors:
 *   - Paul Asmuth <paul@zscale.io>
 *   - Laura Schlimmer <laura@zscale.io>
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License ("the license") as
 * published by the Free Software Foundation, either version 3 of the License,
 * or any later version.
 *
 * In accordance with Section 7(e) of the license, the licensing of the Program
 * under the license does not imply a trademark license. Therefore any rights,
 * title and interest in our trademarks remain entirely with us.
 *
 * 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 license for more details.
 *
 * You can be released from the requirements of the license by purchasing a
 * commercial license. Buying such a license is mandatory as soon as you develop
 * commercial activities involving this program without disclosing the source
 * code of your own applications
 */
#include "eventql/eventql.h"
#include <eventql/util/stdtypes.h>
#include <eventql/util/exception.h>
#include <eventql/util/wallclock.h>
#include <eventql/util/test/unittest.h>
#include <eventql/config/process_config.h>

using namespace eventql;
UNIT_TEST(ProcessConfigTest);

TEST_CASE(ProcessConfigTest, TestProcessConfigBuilder, [] () {
  ProcessConfigBuilder builder;
  builder.setProperty("evql", "host", "localhost");
  builder.setProperty("evql", "port", "8080");
  builder.setProperty("evql", "fuu", "bar");

  auto config = builder.getConfig();
  {
    auto p = config->getProperty("evql", "host");
    EXPECT_FALSE(p.isEmpty());
    EXPECT_EQ(p.get(), "localhost");
  }

  {
    auto p = config->getProperty("evql", "port");
    EXPECT_FALSE(p.isEmpty());
    EXPECT_EQ(p.get(), "8080");
  }

  {
    auto p = config->getProperty("evql", "fuu");
    EXPECT_FALSE(p.isEmpty());
    EXPECT_EQ(p.get(), "bar");
  }
});

TEST_CASE(ProcessConfigTest, TestProcessConfigBuilderLoadFile, [] () {
  auto test_file_path = "eventql/config/testdata/.process_cfg";
  ProcessConfigBuilder builder;

  auto status = builder.loadFile(test_file_path);
  EXPECT_TRUE(status.isSuccess());

  builder.setProperty("test", "port", "9175");

  auto config = builder.getConfig();
  {
    auto p = config->getProperty("test", "host");
    EXPECT_FALSE(p.isEmpty());
    EXPECT_EQ(p.get(), "localhost");
  }
  {
    auto p = config->getProperty("test", "port");
    EXPECT_FALSE(p.isEmpty());
    EXPECT_EQ(p.get(), "9175");
  }
  {
    auto p = config->getProperty("test", "authors");
    EXPECT_FALSE(p.isEmpty());
    EXPECT_EQ(p.get(), "eventQL Authors");
  }
  {
    auto p = config->getProperty("test2", "mail");
    EXPECT_FALSE(p.isEmpty());
    EXPECT_EQ(p.get(), "authors@test.com");
  }
});
<|endoftext|>