<commit_before>#include <iostream>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stack>
#include <sys/wait.h>
#include <vector>
#include <stack>
#include <queue>
#include <stdlib.h>

using namespace std;

#include "Rshell.h"
#include "Command.h"

Command::Command()
{

}

Command::Command(queue<char *> q)
{
	while (!q.empty())
	{
		v.push_back(q.front());
		q.pop();
	}
	v.push_back('\0');
}

Command::Command(stack<char *> s)
{
	while (!s.empty())
	{
		v.push_back(s.top());
		s.pop();
	}
	v.push_back('\0');
	/*
	   cout << "Making: ";
	   for (unsigned i = 0; v[i] != '\0'; ++i)
	   {
	   cout << v[i];
	   }
	   cout << endl;
	   */
}

Command::Command(char * temp)
{
	args[0] = temp;
}

Command::~Command()
{

}

bool Command::evaluate()
{
	//pid_t parent = getpid();
	string exit = "exit";
	int status;
	if (!v.empty())
	{
		if (v.at(0) == exit)
		{
			//_exit(1);
			std::exit(1);
		}
	}
	pid_t child_pid = fork();

	if (child_pid < 0)
	{
		cout << "Fork failed in: " << endl << "bool Command::evaluate()" << endl;
	}
	else if (child_pid == 0)
	{
		char ** vloc = &v[0];
		if (execvp(v.at(0), vloc) == -1)
		{
			cout << "-rshell: " << v.at(0) << ": command not found" << endl;
			//the or issue with first thing is taken care of if the line below
			//is taken out
			_exit(-1);
			//cout << "returning false in execvp if" << endl;
			//return false;
		}
		//_exit(1);
		//cout << "returning true" << endl;
		//return true;
	}
	else if (child_pid > 0)
	{
		waitpid(child_pid, &status, 0);
		/*
		while (!WIFEXITED(status) && !WIFSIGNALED(status))
		{
			return status;
		}
		*/
	}
	return true;
}

<commit_msg>sdfsdf || should work now<commit_after>#include <iostream>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stack>
#include <sys/wait.h>
#include <vector>
#include <stack>
#include <queue>
#include <stdlib.h>

using namespace std;

#include "Rshell.h"
#include "Command.h"

Command::Command()
{

}

Command::Command(queue<char *> q)
{
	while (!q.empty())
	{
		v.push_back(q.front());
		q.pop();
	}
	v.push_back('\0');
}

Command::Command(stack<char *> s)
{
	while (!s.empty())
	{
		v.push_back(s.top());
		s.pop();
	}
	v.push_back('\0');
}

Command::Command(char * temp)
{
	args[0] = temp;
}

Command::~Command()
{

}

bool Command::evaluate()
{
	string exit = "exit";
	int status;
	if (!v.empty())
	{
		if (v.at(0) == exit)
		{
			_exit(1);
		}
	}
	pid_t child_pid = fork();

	if (child_pid < 0)
	{
		cout << "Fork failed in: " << endl << "bool Command::evaluate()" << endl;
	}
	else if (child_pid == 0)
	{
		char ** vloc = &v[0];
		if (execvp(v.at(0), vloc) == -1)
		{
			cout << "-rshell: " << v.at(0) << ": command not found" << endl;
			_exit(1);
		}
	}
	else if (child_pid > 0)
	{
		if (waitpid(child_pid, &status, 0) == -1)
		{
			//cout << "wait error" << endl;
		}
		if (WEXITSTATUS(status) != 0)
		{
			return false;
		}
	}
	return true;
}

<|endoftext|>


<commit_before>// Filename: ppremake.cxx
// Created by:  drose (25Sep00)
//
////////////////////////////////////////////////////////////////////

#include "ppremake.h"
#include "ppMain.h"
#include "ppScope.h"
#include "check_include.h"
#include "tokenize.h"
#include "sedProcess.h"

#ifdef HAVE_UNISTD_H
  #include <unistd.h>
#endif

#if HAVE_GETOPT
  #ifdef HAVE_GETOPT_H
    #include <getopt.h>
  #endif  // HAVE_GETOPT_H
#else
  #include "gnu_getopt.h"
#endif  // HAVE_GETOPT

#include <set>
#include <vector>
#include <algorithm>
#include <sys/stat.h>
#include <assert.h>

bool unix_platform = false;
bool windows_platform = false;
bool dry_run = false;
bool verbose_dry_run = false;
int verbose = 0;
int debug_expansions = 0;

bool errors_occurred = false;

DebugExpand debug_expand;

class DebugExpandReport {
public:
  DebugExpandReport(DebugExpand::const_iterator source,
                    ExpandResultCount::const_iterator result) :
    _source(source),
    _result(result)
  { }

  const string &get_source() const {
    return (*_source).first;
  }
  const string &get_result() const {
    return (*_result).first;
  }
  int get_count() const {
    return (*_result).second;
  }

  bool operator < (const DebugExpandReport &other) const {
    return get_count() > other.get_count();
  }

  DebugExpand::const_iterator _source;
  ExpandResultCount::const_iterator _result;
};

static void
usage() {
  cerr <<
    "\n"
    "ppremake [opts] subdir-name [subdir-name..]\n"
    "ppremake\n"
    "ppremake -s 'sed-command' <input >output\n"
    "\n"
    "This is Panda pre-make: a script preprocessor that scans the source\n"
    "directory hierarchy containing the current directory, looking for\n"
    "directories that contain a file called " SOURCE_FILENAME ".  At the top of the\n"
    "directory tree must be a file called " PACKAGE_FILENAME ", which should define\n"
    "key variable definitions for processing, as well as pointing out the\n"
    "locations of further config files.\n\n"

    "The package file is read and interpreted, followed by each source file\n"
    "in turn; after each source file is read, the template file (specified in\n"
    "the config file) is read.  The template file contains the actual statements\n"
    "to be output and will typically be set up to generate Makefiles or whatever\n"
    "is equivalent and appropriate to the particular build environment in use.\n\n"

    "The parameters are the names of the subdirectories (their local names, not\n"
    "the relative or full paths to them) that are to be processed.  All\n"
    "subdirectories (that contain a file named " SOURCE_FILENAME ") will be\n"
    "scanned, but only the named subdirectories will have output files\n"
    "generated.  If no parameter is given, then all directories will be\n"
    "processed.\n\n"

    "ppremake -s is a special form of the command that runs as a very limited\n"
    "sed.  It has nothing to do with building makefiles, but is provided mainly\n"
    "so platforms that don't have sed built in can still portably run simple sed\n"
    "scripts.\n\n"

    "Options:\n\n"

    "  -h           Display this page.\n"
    "  -V           Report the version of ppremake, and exit.\n"
    "  -I           Report the compiled-in default for INSTALL_DIR, and exit.\n"
    "  -v           Turn on verbose output (may help in debugging .pp files).\n"
    "  -vv          Be very verbose (if you're getting desperate).\n"
    "  -x count     Print a histogram of the count most-frequently expanded strings\n"
    "               and their results.  Useful to optimize .pp scripts so that\n"
    "               variables are not needlessly repeatedly expanded.\n\n"

    "  -P           Report the current platform name, and exit.\n\n"

    "  -D pp.dep    Examine the given dependency file, and re-run ppremake\n"
    "               only if the dependency file is stale.\n\n"

    "  -d           Instead of generating makefiles, report the set of\n"
    "               subdirectories that the named subdirectory depends on.\n"
    "               Directories are named by their local name, not by the\n"
    "               path to them; e.g. util instead of src/util.\n"
    "  -r           Reverse dependency.  As above, but report instead the set\n"
    "               of directories that depend on the named subdirectory.\n"
    "               Options -d and -r may be combined, and you may also\n"
    "               name multiple subdirectories to scan at once.\n\n"
    "  -n           Dry run: generate no output, but instead report the\n"
    "               files that would change.\n"
    "  -N           Verbose dry run: show the output of diff for the files\n"
    "               that would change (not supported in Win32-only version).\n\n"
    "  -p platform  Build as if for the indicated platform name.  The default\n"
    "               for this build is \"" << PLATFORM << "\".\n"
    "  -c config.pp Read the indicated user-level config.pp file after reading\n"
    "               the system config.pp file.  If this is omitted, the value\n"
    "               given in the environment variable PPREMAKE_CONFIG is used\n"
    "               instead.\n\n";
}

static void
report_version() {
  cerr << "This is " << PACKAGE << " version " << VERSION
       << " built on " << __DATE__ << " at " << __TIME__
       << ".\n";
}

static void
report_install_dir() {
  cerr << "Default value for INSTALL_DIR is " << INSTALL_DIR << ".\n";
}

static void
report_platform() {
  cerr << "ppremake built for default platform " << PLATFORM << ".\n";
}

////////////////////////////////////////////////////////////////////
//     Function: check_one_file
//  Description: Checks a single file listed in the dependency cache
//               to see if it matches the cache.  Returns true if it
//               does, false if it does not.
////////////////////////////////////////////////////////////////////
static bool
check_one_file(const string &dir_prefix, const vector<string> &words) {
  assert(words.size() >= 2);

  string pathname = dir_prefix + words[0];
  time_t mtime = strtol(words[1].c_str(), (char **)NULL, 10);

  struct stat st;
  if (stat(pathname.c_str(), &st) < 0) {
    // The file doesn't even exist!
    return false;
  }

  if (st.st_mtime == mtime) {
    // The modification time matches; don't bother to read the file.
    return true;
  }

  // The modification time doesn't match, so we'll need to read the
  // file and look for #include directives.  First, get the complete
  // set of files we're expecting to find.

  set<string> expected_files;
  for (int i = 2; i < (int)words.size(); i++) {
    const string &word = words[i];
    size_t slash = word.rfind('/');
    if (slash == string::npos) {
      // Every file is expected to include a slash.
      return false;
    }
    expected_files.insert(word.substr(slash + 1));
  }

  // Now open the source file and read it for #include directives.
  set<string> found_files;
  ifstream in(pathname.c_str());
  if (!in) {
    // Can't read the file for some reason.
    return false;
  }
  if (verbose) {
    cerr << "Reading (one) \"" << pathname.c_str() << "\"\n";
  }

  string line;
  getline(in, line);
  while (!in.fail() && !in.eof()) {
    string filename = check_include(line);
    if (!filename.empty() && filename.find('/') == string::npos) {
      found_files.insert(filename);
    }
    getline(in, line);
  }

  // Now check that the two sets are equivalent.
  return (expected_files == found_files);
}

////////////////////////////////////////////////////////////////////
//     Function: check_dependencies
//  Description: Read in the indicated dependency cache file,
//               verifying that it is still current.  If it is stale,
//               return false; otherwise, return true.
////////////////////////////////////////////////////////////////////
static bool
check_dependencies(const string &dep_filename) {
  // Extract the directory prefix from the dependency filename.  This
  // is everything up until (and including) the last slash.
  string dir_prefix;
  size_t slash = dep_filename.rfind('/');
  if (slash != string::npos) {
    dir_prefix = dep_filename.substr(0, slash + 1);
  }

  ifstream in(dep_filename.c_str());
  if (!in) {
    // The dependency filename doesn't even exist: it's definitely
    // stale.
    return false;
  }
  if (verbose) {
    cerr << "Reading (chk) \"" << dep_filename.c_str() << "\"\n";
  }

  string line;
  getline(in, line);
  while (!in.fail() && !in.eof()) {
    vector<string> words;
    tokenize_whitespace(line, words);
    if (words.size() < 2) {
      // Invalid file; return false.
      return false;
    }
    if (!check_one_file(dir_prefix, words)) {
      // This file is stale; return false.
      return false;
    }
    getline(in, line);
  }

  // All files are ok; return true.
  return true;
}

int
main(int argc, char *argv[]) {
  string progname = argv[0];
  extern char *optarg;
  extern int optind;
  const char *optstr = "hVIvx:PD:drnNp:c:s:";

  bool any_d = false;
  bool dependencies_stale = false;
  bool report_depends = false;
  bool report_reverse_depends = false;

  string platform;
  char *platform_env = getenv("PPREMAKE_PLATFORM");
  if(platform_env==NULL)
     platform=PLATFORM;
    else platform=platform_env;

  string ppremake_config;
  bool got_ppremake_config = false;
  string sed_command;
  bool got_sed_command = false;
  int flag = getopt(argc, argv, optstr);

  while (flag != EOF) {
    switch (flag) {
    case 'h':
      usage();
      exit(0);

    case 'V':
      report_version();
      exit(0);
      break;

    case 'I':
      report_install_dir();
      exit(0);
      break;

    case 'v':
      ++verbose;
      break;

    case 'x':
      debug_expansions = atoi(optarg);
      break;

    case 'P':
      report_platform();
      exit(0);
      break;

    case 'D':
      if (!check_dependencies(optarg)) {
        dependencies_stale = true;
      }
      any_d = true;
      break;

    case 'd':
      report_depends = true;
      break;

    case 'r':
      report_reverse_depends = true;
      break;

    case 'n':
      dry_run = true;
      break;

    case 'N':
      dry_run = true;
      verbose_dry_run = true;
      break;

    case 'p':
      platform = optarg;
      break;

    case 'c':
      ppremake_config = optarg;
      got_ppremake_config = true;
      break;

    case 's':
      sed_command = optarg;
      got_sed_command = true;
      break;

    default:
      exit(1);
    }
    flag = getopt(argc, argv, optstr);
  }

  argc -= (optind-1);
  argv += (optind-1);

  if (got_sed_command) {
    SedProcess sp;
    if (!sp.add_script_line(sed_command)) {
      exit(1);
    }
    sp.run(cin, cout);
    exit(0);
  }

#ifdef WIN32_VC
  if (verbose_dry_run) {
    cerr << "Option -N treated like -n when ppremake is built without Cygwin.\n";
  }
#endif

  // If the user supplied one or more -d parameters, then we should
  // not continue unless some of the dependencies were stale.
  if (any_d) {
    if (!dependencies_stale) {
      exit(0);
    }
    cout << progname << "\n";
  }

  PPScope global_scope((PPNamedScopes *)NULL);
  global_scope.define_variable("PPREMAKE", PACKAGE);
  global_scope.define_variable("PPREMAKE_VERSION", VERSION);
  global_scope.define_variable("PLATFORM", platform);
  global_scope.define_variable("PACKAGE_FILENAME", PACKAGE_FILENAME);
  global_scope.define_variable("SOURCE_FILENAME", SOURCE_FILENAME);
  global_scope.define_variable("INSTALL_DIR", INSTALL_DIR);

  if (got_ppremake_config) {
    // If this came in on the command line, define a variable as such.
    // Otherwise, the system scripts can pull this value in from the
    // similarly-named environment variable.
    global_scope.define_variable("PPREMAKE_CONFIG", ppremake_config);
  }

  // Also, it's convenient to have a way to represent the literal tab
  // character, without actually putting a literal tab character in
  // the source file.  Similarly with some other special characters.
  global_scope.define_variable("TAB", "\t");
  global_scope.define_variable("SPACE", " ");
  global_scope.define_variable("DOLLAR", "$");
  global_scope.define_variable("HASH", "#");

  PPMain ppmain(&global_scope);
  if (!ppmain.read_source(".")) {
    exit(1);
  }

  if (report_depends || report_reverse_depends) {
    // With -d or -n, just report inter-directory dependency
    // relationships.
    if (argc < 2) {
      cerr << "No named directories.\n";
      exit(1);
    }

    for (int i = 1; i < argc; i++) {
      cerr << "\n";
      if (report_depends) {
        ppmain.report_depends(argv[i]);
      }
      cerr << "\n";
      if (report_reverse_depends) {
        ppmain.report_reverse_depends(argv[i]);
      }
    }

  } else {
    // Without -d or -n, do normal processing.

    if (argc < 2) {
      if (!ppmain.process_all()) {
        exit(1);
      }
    } else {
      for (int i = 1; i < argc; i++) {
        if (!ppmain.process(argv[i])) {
          cerr << "Unable to process " << argv[i] << ".\n";
          exit(1);
        }
      }
    }
  }

  if (debug_expansions > 0) {
    // Now report the worst expansion offenders.  These are the
    // strings that were most often expanded to the same thing.
    cerr << "\nExpansion report:\n";
    vector<DebugExpandReport> report;

    DebugExpand::const_iterator dei;
    for (dei = debug_expand.begin(); dei != debug_expand.end(); ++dei) {
      const ExpandResultCount &result_count = (*dei).second;
      ExpandResultCount::const_iterator rci;
      for (rci = result_count.begin(); rci != result_count.end(); ++rci) {
        report.push_back(DebugExpandReport(dei, rci));
      }
    }

    sort(report.begin(), report.end());

    int num_reports = min((int)report.size(), debug_expansions);
    for (int i = 0; i < num_reports; i++) {
      cerr << "\"" << report[i].get_source() << "\" -> \""
           << report[i].get_result()
           << "\" (" << report[i].get_count() << ")\n";
    }
    cerr << "\n";
  }

  if (errors_occurred) {
    cerr << "Errors occurred during processing.\n";
    return (1);

  } else {
    cerr << "No errors.\n";
    return (0);
  }
}
<commit_msg>add errors_occurred flag<commit_after>// Filename: ppremake.cxx
// Created by:  drose (25Sep00)
//
////////////////////////////////////////////////////////////////////

#include "ppremake.h"
#include "ppMain.h"
#include "ppScope.h"
#include "check_include.h"
#include "tokenize.h"
#include "sedProcess.h"

#ifdef HAVE_UNISTD_H
  #include <unistd.h>
#endif

#if HAVE_GETOPT
  #ifdef HAVE_GETOPT_H
    #include <getopt.h>
  #endif  // HAVE_GETOPT_H
#else
  #include "gnu_getopt.h"
#endif  // HAVE_GETOPT

#include <set>
#include <vector>
#include <algorithm>
#include <sys/stat.h>
#include <assert.h>

bool unix_platform = false;
bool windows_platform = false;
bool dry_run = false;
bool verbose_dry_run = false;
int verbose = 0;
int debug_expansions = 0;

bool errors_occurred = false;

DebugExpand debug_expand;

class DebugExpandReport {
public:
  DebugExpandReport(DebugExpand::const_iterator source,
                    ExpandResultCount::const_iterator result) :
    _source(source),
    _result(result)
  { }

  const string &get_source() const {
    return (*_source).first;
  }
  const string &get_result() const {
    return (*_result).first;
  }
  int get_count() const {
    return (*_result).second;
  }

  bool operator < (const DebugExpandReport &other) const {
    return get_count() > other.get_count();
  }

  DebugExpand::const_iterator _source;
  ExpandResultCount::const_iterator _result;
};

static void
usage() {
  cerr <<
    "\n"
    "ppremake [opts] subdir-name [subdir-name..]\n"
    "ppremake\n"
    "ppremake -s 'sed-command' <input >output\n"
    "\n"
    "This is Panda pre-make: a script preprocessor that scans the source\n"
    "directory hierarchy containing the current directory, looking for\n"
    "directories that contain a file called " SOURCE_FILENAME ".  At the top of the\n"
    "directory tree must be a file called " PACKAGE_FILENAME ", which should define\n"
    "key variable definitions for processing, as well as pointing out the\n"
    "locations of further config files.\n\n"

    "The package file is read and interpreted, followed by each source file\n"
    "in turn; after each source file is read, the template file (specified in\n"
    "the config file) is read.  The template file contains the actual statements\n"
    "to be output and will typically be set up to generate Makefiles or whatever\n"
    "is equivalent and appropriate to the particular build environment in use.\n\n"

    "The parameters are the names of the subdirectories (their local names, not\n"
    "the relative or full paths to them) that are to be processed.  All\n"
    "subdirectories (that contain a file named " SOURCE_FILENAME ") will be\n"
    "scanned, but only the named subdirectories will have output files\n"
    "generated.  If no parameter is given, then all directories will be\n"
    "processed.\n\n"

    "ppremake -s is a special form of the command that runs as a very limited\n"
    "sed.  It has nothing to do with building makefiles, but is provided mainly\n"
    "so platforms that don't have sed built in can still portably run simple sed\n"
    "scripts.\n\n"

    "Options:\n\n"

    "  -h           Display this page.\n"
    "  -V           Report the version of ppremake, and exit.\n"
    "  -I           Report the compiled-in default for INSTALL_DIR, and exit.\n"
    "  -v           Turn on verbose output (may help in debugging .pp files).\n"
    "  -vv          Be very verbose (if you're getting desperate).\n"
    "  -x count     Print a histogram of the count most-frequently expanded strings\n"
    "               and their results.  Useful to optimize .pp scripts so that\n"
    "               variables are not needlessly repeatedly expanded.\n\n"

    "  -P           Report the current platform name, and exit.\n\n"

    "  -D pp.dep    Examine the given dependency file, and re-run ppremake\n"
    "               only if the dependency file is stale.\n\n"

    "  -d           Instead of generating makefiles, report the set of\n"
    "               subdirectories that the named subdirectory depends on.\n"
    "               Directories are named by their local name, not by the\n"
    "               path to them; e.g. util instead of src/util.\n"
    "  -r           Reverse dependency.  As above, but report instead the set\n"
    "               of directories that depend on the named subdirectory.\n"
    "               Options -d and -r may be combined, and you may also\n"
    "               name multiple subdirectories to scan at once.\n\n"
    "  -n           Dry run: generate no output, but instead report the\n"
    "               files that would change.\n"
    "  -N           Verbose dry run: show the output of diff for the files\n"
    "               that would change (not supported in Win32-only version).\n\n"
    "  -p platform  Build as if for the indicated platform name.  The default\n"
    "               for this build is \"" << PLATFORM << "\".\n"
    "  -c config.pp Read the indicated user-level config.pp file after reading\n"
    "               the system config.pp file.  If this is omitted, the value\n"
    "               given in the environment variable PPREMAKE_CONFIG is used\n"
    "               instead.\n\n";
}

static void
report_version() {
  cerr << "This is " << PACKAGE << " version " << VERSION
       << " built on " << __DATE__ << " at " << __TIME__
       << ".\n";
}

static void
report_install_dir() {
  cerr << "Default value for INSTALL_DIR is " << INSTALL_DIR << ".\n";
}

static void
report_platform() {
  cerr << "ppremake built for default platform " << PLATFORM << ".\n";
}

////////////////////////////////////////////////////////////////////
//     Function: check_one_file
//  Description: Checks a single file listed in the dependency cache
//               to see if it matches the cache.  Returns true if it
//               does, false if it does not.
////////////////////////////////////////////////////////////////////
static bool
check_one_file(const string &dir_prefix, const vector<string> &words) {
  assert(words.size() >= 2);

  string pathname = dir_prefix + words[0];
  time_t mtime = strtol(words[1].c_str(), (char **)NULL, 10);

  struct stat st;
  if (stat(pathname.c_str(), &st) < 0) {
    // The file doesn't even exist!
    return false;
  }

  if (st.st_mtime == mtime) {
    // The modification time matches; don't bother to read the file.
    return true;
  }

  // The modification time doesn't match, so we'll need to read the
  // file and look for #include directives.  First, get the complete
  // set of files we're expecting to find.

  set<string> expected_files;
  for (int i = 2; i < (int)words.size(); i++) {
    const string &word = words[i];
    size_t slash = word.rfind('/');
    if (slash == string::npos) {
      // Every file is expected to include a slash.
      return false;
    }
    expected_files.insert(word.substr(slash + 1));
  }

  // Now open the source file and read it for #include directives.
  set<string> found_files;
  ifstream in(pathname.c_str());
  if (!in) {
    // Can't read the file for some reason.
    return false;
  }
  if (verbose) {
    cerr << "Reading (one) \"" << pathname.c_str() << "\"\n";
  }

  string line;
  getline(in, line);
  while (!in.fail() && !in.eof()) {
    string filename = check_include(line);
    if (!filename.empty() && filename.find('/') == string::npos) {
      found_files.insert(filename);
    }
    getline(in, line);
  }

  // Now check that the two sets are equivalent.
  return (expected_files == found_files);
}

////////////////////////////////////////////////////////////////////
//     Function: check_dependencies
//  Description: Read in the indicated dependency cache file,
//               verifying that it is still current.  If it is stale,
//               return false; otherwise, return true.
////////////////////////////////////////////////////////////////////
static bool
check_dependencies(const string &dep_filename) {
  // Extract the directory prefix from the dependency filename.  This
  // is everything up until (and including) the last slash.
  string dir_prefix;
  size_t slash = dep_filename.rfind('/');
  if (slash != string::npos) {
    dir_prefix = dep_filename.substr(0, slash + 1);
  }

  ifstream in(dep_filename.c_str());
  if (!in) {
    // The dependency filename doesn't even exist: it's definitely
    // stale.
    return false;
  }
  if (verbose) {
    cerr << "Reading (chk) \"" << dep_filename.c_str() << "\"\n";
  }

  string line;
  getline(in, line);
  while (!in.fail() && !in.eof()) {
    vector<string> words;
    tokenize_whitespace(line, words);
    if (words.size() < 2) {
      // Invalid file; return false.
      return false;
    }
    if (!check_one_file(dir_prefix, words)) {
      // This file is stale; return false.
      return false;
    }
    getline(in, line);
  }

  // All files are ok; return true.
  return true;
}

int
main(int argc, char *argv[]) {
  string progname = argv[0];
  extern char *optarg;
  extern int optind;
  const char *optstr = "hVIvx:PD:drnNp:c:s:";

  bool any_d = false;
  bool dependencies_stale = false;
  bool report_depends = false;
  bool report_reverse_depends = false;

  string platform;
  char *platform_env = getenv("PPREMAKE_PLATFORM");
  if(platform_env==NULL)
     platform=PLATFORM;
    else platform=platform_env;

  string ppremake_config;
  bool got_ppremake_config = false;
  string sed_command;
  bool got_sed_command = false;
  int flag = getopt(argc, argv, optstr);

  while (flag != EOF) {
    switch (flag) {
    case 'h':
      usage();
      exit(0);

    case 'V':
      report_version();
      exit(0);
      break;

    case 'I':
      report_install_dir();
      exit(0);
      break;

    case 'v':
      ++verbose;
      break;

    case 'x':
      debug_expansions = atoi(optarg);
      break;

    case 'P':
      report_platform();
      exit(0);
      break;

    case 'D':
      if (!check_dependencies(optarg)) {
        dependencies_stale = true;
      }
      any_d = true;
      break;

    case 'd':
      report_depends = true;
      break;

    case 'r':
      report_reverse_depends = true;
      break;

    case 'n':
      dry_run = true;
      break;

    case 'N':
      dry_run = true;
      verbose_dry_run = true;
      break;

    case 'p':
      platform = optarg;
      break;

    case 'c':
      ppremake_config = optarg;
      got_ppremake_config = true;
      break;

    case 's':
      sed_command = optarg;
      got_sed_command = true;
      break;

    default:
      exit(1);
    }
    flag = getopt(argc, argv, optstr);
  }

  argc -= (optind-1);
  argv += (optind-1);

  if (got_sed_command) {
    SedProcess sp;
    if (!sp.add_script_line(sed_command)) {
      exit(1);
    }
    sp.run(cin, cout);
    exit(0);
  }

#ifdef WIN32_VC
  if (verbose_dry_run) {
    cerr << "Option -N treated like -n when ppremake is built without Cygwin.\n";
  }
#endif

  // If the user supplied one or more -d parameters, then we should
  // not continue unless some of the dependencies were stale.
  if (any_d) {
    if (!dependencies_stale) {
      exit(0);
    }
    cout << progname << "\n";
  }

  PPScope global_scope((PPNamedScopes *)NULL);
  global_scope.define_variable("PPREMAKE", PACKAGE);
  global_scope.define_variable("PPREMAKE_VERSION", VERSION);
  global_scope.define_variable("PLATFORM", platform);
  global_scope.define_variable("PACKAGE_FILENAME", PACKAGE_FILENAME);
  global_scope.define_variable("SOURCE_FILENAME", SOURCE_FILENAME);
  global_scope.define_variable("INSTALL_DIR", INSTALL_DIR);

  if (got_ppremake_config) {
    // If this came in on the command line, define a variable as such.
    // Otherwise, the system scripts can pull this value in from the
    // similarly-named environment variable.
    global_scope.define_variable("PPREMAKE_CONFIG", ppremake_config);
  }

  // Also, it's convenient to have a way to represent the literal tab
  // character, without actually putting a literal tab character in
  // the source file.  Similarly with some other special characters.
  global_scope.define_variable("TAB", "\t");
  global_scope.define_variable("SPACE", " ");
  global_scope.define_variable("DOLLAR", "$");
  global_scope.define_variable("HASH", "#");

  PPMain ppmain(&global_scope);
  if (!ppmain.read_source(".")) {
    exit(1);
  }

  if (report_depends || report_reverse_depends) {
    // With -d or -n, just report inter-directory dependency
    // relationships.
    if (argc < 2) {
      cerr << "No named directories.\n";
      exit(1);
    }

    for (int i = 1; i < argc; i++) {
      cerr << "\n";
      if (report_depends) {
        ppmain.report_depends(argv[i]);
      }
      cerr << "\n";
      if (report_reverse_depends) {
        ppmain.report_reverse_depends(argv[i]);
      }
    }

  } else {
    // Without -d or -n, do normal processing.

    if (argc < 2) {
      if (!ppmain.process_all()) {
        exit(1);
      }
    } else {
      for (int i = 1; i < argc; i++) {
        if (!ppmain.process(argv[i])) {
          cerr << "Unable to process " << argv[i] << ".\n";
          exit(1);
        }
      }
    }
  }

  if (debug_expansions > 0) {
    // Now report the worst expansion offenders.  These are the
    // strings that were most often expanded to the same thing.
    cerr << "\nExpansion report:\n";
    vector<DebugExpandReport> report;

    DebugExpand::const_iterator dei;
    for (dei = debug_expand.begin(); dei != debug_expand.end(); ++dei) {
      const ExpandResultCount &result_count = (*dei).second;
      ExpandResultCount::const_iterator rci;
      for (rci = result_count.begin(); rci != result_count.end(); ++rci) {
        report.push_back(DebugExpandReport(dei, rci));
      }
    }

    sort(report.begin(), report.end());

    int num_reports = min((int)report.size(), debug_expansions);
    for (int i = 0; i < num_reports; i++) {
      cerr << "\"" << report[i].get_source() << "\" -> \""
           << report[i].get_result()
           << "\" (" << report[i].get_count() << ")\n";
    }
    cerr << "\n";
  }

  if (errors_occurred) {
    cerr << "Errors occurred during ppremake.\n";
    return (1);

  } else {
    cerr << "No errors.\n";
    return (0);
  }
}
<|endoftext|>


<commit_before>/** \file    add_authority_beacon_information.cc
 *  \brief   Adds BEACON information to authority files
 *  \author  Dr. Johannes Ruscheinski
 *
 *  Copyright (C) 2018,2019 Library of the University of Tübingen
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero 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/>.
 */
#include <iostream>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <cctype>
#include <cstdlib>
#include "Compiler.h"
#include "FileUtil.h"
#include "MARC.h"
#include "StringUtil.h"
#include "Url.h"
#include "util.h"

namespace {

std::string NameFromURL(const std::string &url_string) {
    const Url url(url_string);
    std::string name(url.getAuthority());
    if (StringUtil::StartsWith(name, "www.", /* ignore_case = */true))
        name = name.substr(__builtin_strlen("www."));
    const auto last_dot_pos(name.rfind('.'));
    if (last_dot_pos != std::string::npos)
        name.resize(last_dot_pos);
    StringUtil::Map(&name, '.', ' ');

    // Convert the first letter of each "word" to uppercase:
    bool first_char_of_word(true);
    for (auto &ch : name) {
        if (first_char_of_word)
            ch = std::toupper(ch);
        first_char_of_word = ch == ' ' or ch == '-';
    }

    return name;
}

void CollectBeaconLinks(const std::string &beacon_filename,
                        std::unordered_map<std::string, std::set<std::pair<std::string, std::string>>> * const gnd_numbers_to_beacon_links_map)
{
    const auto input(FileUtil::OpenInputFileOrDie(beacon_filename));
    std::string url_prefix, institution_name;
    while (not input->eof()) {
        std::string line;
        input->getline(&line);
        StringUtil::TrimWhite(&line);
        if (unlikely(line.empty()))
            continue;
        if (unlikely(line[0] == '#')) {
            if (StringUtil::StartsWith(line, "#TARGET:")) {
                line = StringUtil::TrimWhite(line.substr(__builtin_strlen("#TARGET:")));
                if (not StringUtil::EndsWith(line, "{ID}"))
                    LOG_ERROR("Bad TARGET line in \"" + beacon_filename + "\"!");
                url_prefix = line.substr(0, line.length() - __builtin_strlen("{ID}"));
                institution_name = NameFromURL(url_prefix);
            }
        } else { // Probably a GND number.
            auto gnd_number_and_beacon_links(gnd_numbers_to_beacon_links_map->find(line));
            if (gnd_number_and_beacon_links == gnd_numbers_to_beacon_links_map->end())
                (*gnd_numbers_to_beacon_links_map)[line] =
                    std::set<std::pair<std::string, std::string>>({ std::make_pair(institution_name, url_prefix + line) });
            else
                gnd_number_and_beacon_links->second.emplace(std::make_pair(institution_name, url_prefix + line));
        }
    }
}

void ProcessAuthorityRecords(
    MARC::Reader * const authority_reader, MARC::Writer * const authority_writer,
    const std::unordered_map<std::string, std::set<std::pair<std::string, std::string>>> &gnd_numbers_to_beacon_links_map)
{
    unsigned gnd_tagged_count(0);
    while (auto record = authority_reader->read()) {
        std::string gnd_number;
        if (MARC::GetGNDCode(record, &gnd_number)) {
            const auto gnd_number_and_beacon_links(gnd_numbers_to_beacon_links_map.find(gnd_number));
            if (gnd_number_and_beacon_links != gnd_numbers_to_beacon_links_map.cend()) {
                ++gnd_tagged_count;
                for (const auto &beacon_link : gnd_number_and_beacon_links->second)
                    record.insertField("BEA", { { 'a', beacon_link.first }, { 'u', beacon_link.second } });
            }
        }

        authority_writer->write(record);
    }

    LOG_INFO("tagged " + std::to_string(gnd_tagged_count) + " author records with beacon links.");
}

} // unnamed namespace

int Main(int argc, char **argv) {
    if (argc < 4)
        ::Usage("authority_records augmented_authority_records [beacon_list1 beacon_list2 .. beacon_listN]");

    const std::string authority_records_filename(argv[1]);
    const std::string augmented_authority_records_filename(argv[2]);

    if (unlikely(authority_records_filename == augmented_authority_records_filename))
        LOG_ERROR("Authority data input file name equals authority output file name!");

    auto authority_reader(MARC::Reader::Factory(authority_records_filename));
    auto authority_writer(MARC::Writer::Factory(augmented_authority_records_filename));

    try {
        std::unordered_map<std::string, std::set<std::pair<std::string, std::string>>> gnd_numbers_to_beacon_links_map;
        for (int arg_no(3); arg_no < argc; ++arg_no)
            CollectBeaconLinks(argv[arg_no], &gnd_numbers_to_beacon_links_map);

        ProcessAuthorityRecords(authority_reader.get(), authority_writer.get(), gnd_numbers_to_beacon_links_map);
    } catch (const std::exception &x) {
        LOG_ERROR("caught exception: " + std::string(x.what()));
    }

    return EXIT_SUCCESS;
}
<commit_msg>add_authority_beacon_information: removed try/catch from Main<commit_after>/** \file    add_authority_beacon_information.cc
 *  \brief   Adds BEACON information to authority files
 *  \author  Dr. Johannes Ruscheinski
 *
 *  Copyright (C) 2018,2019 Library of the University of Tübingen
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero 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/>.
 */
#include <iostream>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <cctype>
#include <cstdlib>
#include "Compiler.h"
#include "FileUtil.h"
#include "MARC.h"
#include "StringUtil.h"
#include "Url.h"
#include "util.h"

namespace {

std::string NameFromURL(const std::string &url_string) {
    const Url url(url_string);
    std::string name(url.getAuthority());
    if (StringUtil::StartsWith(name, "www.", /* ignore_case = */true))
        name = name.substr(__builtin_strlen("www."));
    const auto last_dot_pos(name.rfind('.'));
    if (last_dot_pos != std::string::npos)
        name.resize(last_dot_pos);
    StringUtil::Map(&name, '.', ' ');

    // Convert the first letter of each "word" to uppercase:
    bool first_char_of_word(true);
    for (auto &ch : name) {
        if (first_char_of_word)
            ch = std::toupper(ch);
        first_char_of_word = ch == ' ' or ch == '-';
    }

    return name;
}

void CollectBeaconLinks(const std::string &beacon_filename,
                        std::unordered_map<std::string, std::set<std::pair<std::string, std::string>>> * const gnd_numbers_to_beacon_links_map)
{
    const auto input(FileUtil::OpenInputFileOrDie(beacon_filename));
    std::string url_prefix, institution_name;
    while (not input->eof()) {
        std::string line;
        input->getline(&line);
        StringUtil::TrimWhite(&line);
        if (unlikely(line.empty()))
            continue;
        if (unlikely(line[0] == '#')) {
            if (StringUtil::StartsWith(line, "#TARGET:")) {
                line = StringUtil::TrimWhite(line.substr(__builtin_strlen("#TARGET:")));
                if (not StringUtil::EndsWith(line, "{ID}"))
                    LOG_ERROR("Bad TARGET line in \"" + beacon_filename + "\"!");
                url_prefix = line.substr(0, line.length() - __builtin_strlen("{ID}"));
                institution_name = NameFromURL(url_prefix);
            }
        } else { // Probably a GND number.
            auto gnd_number_and_beacon_links(gnd_numbers_to_beacon_links_map->find(line));
            if (gnd_number_and_beacon_links == gnd_numbers_to_beacon_links_map->end())
                (*gnd_numbers_to_beacon_links_map)[line] =
                    std::set<std::pair<std::string, std::string>>({ std::make_pair(institution_name, url_prefix + line) });
            else
                gnd_number_and_beacon_links->second.emplace(std::make_pair(institution_name, url_prefix + line));
        }
    }
}

void ProcessAuthorityRecords(
    MARC::Reader * const authority_reader, MARC::Writer * const authority_writer,
    const std::unordered_map<std::string, std::set<std::pair<std::string, std::string>>> &gnd_numbers_to_beacon_links_map)
{
    unsigned gnd_tagged_count(0);
    while (auto record = authority_reader->read()) {
        std::string gnd_number;
        if (MARC::GetGNDCode(record, &gnd_number)) {
            const auto gnd_number_and_beacon_links(gnd_numbers_to_beacon_links_map.find(gnd_number));
            if (gnd_number_and_beacon_links != gnd_numbers_to_beacon_links_map.cend()) {
                ++gnd_tagged_count;
                for (const auto &beacon_link : gnd_number_and_beacon_links->second)
                    record.insertField("BEA", { { 'a', beacon_link.first }, { 'u', beacon_link.second } });
            }
        }

        authority_writer->write(record);
    }

    LOG_INFO("tagged " + std::to_string(gnd_tagged_count) + " author records with beacon links.");
}

} // unnamed namespace

int Main(int argc, char **argv) {
    if (argc < 4)
        ::Usage("authority_records augmented_authority_records [beacon_list1 beacon_list2 .. beacon_listN]");

    const std::string authority_records_filename(argv[1]);
    const std::string augmented_authority_records_filename(argv[2]);

    if (unlikely(authority_records_filename == augmented_authority_records_filename))
        LOG_ERROR("Authority data input file name equals authority output file name!");

    auto authority_reader(MARC::Reader::Factory(authority_records_filename));
    auto authority_writer(MARC::Writer::Factory(augmented_authority_records_filename));

    std::unordered_map<std::string, std::set<std::pair<std::string, std::string>>> gnd_numbers_to_beacon_links_map;
    for (int arg_no(3); arg_no < argc; ++arg_no)
        CollectBeaconLinks(argv[arg_no], &gnd_numbers_to_beacon_links_map);

    ProcessAuthorityRecords(authority_reader.get(), authority_writer.get(), gnd_numbers_to_beacon_links_map);

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include "copasi.h"

#include "AssignmentHandler.h"
#include "CXMLParser.h"
#include "utilities/CCopasiMessage.h"

#include "model/CModel.h"

/**
 * Replace Assignment with the name type of the handler and implement the
 * three methods below.
 */
AssignmentHandler::AssignmentHandler(CXMLParser & parser, CXMLParserData & data):
  CXMLHandler(parser, data, CXMLHandler::Assignment)
{
  init();
}

// virtual
AssignmentHandler::~AssignmentHandler()
{}

// virtual
CXMLHandler * AssignmentHandler::processStart(const XML_Char * pszName,
    const XML_Char ** papszAttrs)
{
  CXMLHandler * pHandlerToCall = NULL;
  const char * Key;
  const CModelEntity* pME = NULL;

  switch (mCurrentElement.first)
    {
      case Assignment:
        mpData->pEventAssignment = NULL;
        Key = mpParser->getAttributeValue("targetKey", papszAttrs);
        pME = dynamic_cast<const CModelEntity *>(mpData->mKeyMap.get(Key));

        if (pME != NULL &&
            mpData->pEvent->getAssignments().getIndex(pME->getKey()) == C_INVALID_INDEX)
          {
            mpData->pEventAssignment = new CEventAssignment(pME->getKey());
            mpData->pEvent->getAssignments().add(mpData->pEventAssignment, true);
          }

        break;

      case Expression:
        pHandlerToCall = getHandler(mCurrentElement.second);
        break;

      default:
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCXML + 2,
                       mpParser->getCurrentLineNumber(), mpParser->getCurrentColumnNumber(), pszName);
        break;
    }

  return pHandlerToCall;
}

// virtual
bool AssignmentHandler::processEnd(const XML_Char * pszName)
{
  bool finished = false;

  switch (mCurrentElement.first)
    {
      case Assignment:
        finished = true;
        break;

      case Expression:

      {
        size_t Size = CCopasiMessage::size();

        if (mpData->pEventAssignment != NULL)
          mpData->pEventAssignment->setExpression(mpData->CharacterData);

        // Remove error messages created by setExpression as this may fail
        // due to incomplete model specification at this time.
        while (CCopasiMessage::size() > Size)
          {
            CCopasiMessage::getLastMessage();
          }
      }

      break;

      default:
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCXML + 2,
                       mpParser->getCurrentLineNumber(), mpParser->getCurrentColumnNumber(), pszName);
        break;
    }

  return finished;
}

// virtual
CXMLHandler::sProcessLogic * AssignmentHandler::getProcessLogic() const
{
  static sProcessLogic Elements[] =
  {
    {"BEFORE", BEFORE, BEFORE, {Assignment, HANDLER_COUNT}},
    {"Assignment", Assignment, Assignment, {Expression, AFTER, HANDLER_COUNT}},
    {"Expression", Expression, CharacterData, {AFTER, HANDLER_COUNT}},
    {"AFTER", AFTER, AFTER, {HANDLER_COUNT}}
  };

  return Elements;
}
<commit_msg>- issue 2623: can't assign NULL to std::string<commit_after>// Copyright (C) 2017 - 2018 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and University of
// of Connecticut School of Medicine.
// All rights reserved.

// Copyright (C) 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include "copasi.h"

#include "AssignmentHandler.h"
#include "CXMLParser.h"
#include "utilities/CCopasiMessage.h"

#include "model/CModel.h"

/**
 * Replace Assignment with the name type of the handler and implement the
 * three methods below.
 */
AssignmentHandler::AssignmentHandler(CXMLParser & parser, CXMLParserData & data):
  CXMLHandler(parser, data, CXMLHandler::Assignment)
{
  init();
}

// virtual
AssignmentHandler::~AssignmentHandler()
{}

// virtual
CXMLHandler * AssignmentHandler::processStart(const XML_Char * pszName,
    const XML_Char ** papszAttrs)
{
  CXMLHandler * pHandlerToCall = NULL;
  const char * Key;
  const char * TargetCStr;
  std::string Target;

  const CModelEntity* pME = NULL;

  switch (mCurrentElement.first)
    {
      case Assignment:
        mpData->pEventAssignment = NULL;
        TargetCStr = mpParser->getAttributeValue("target", papszAttrs, false);

        if (TargetCStr != NULL)
          Target = TargetCStr;

        if (Target.empty())
          {
            mpData->pEventAssignment = new CEventAssignment(pME->getKey());
            mpData->pEvent->getAssignments().add(mpData->pEventAssignment, true);
          }

        break;

      case Expression:
        pHandlerToCall = getHandler(mCurrentElement.second);
        break;

      default:
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCXML + 2,
                       mpParser->getCurrentLineNumber(), mpParser->getCurrentColumnNumber(), pszName);
        break;
    }

  return pHandlerToCall;
}

// virtual
bool AssignmentHandler::processEnd(const XML_Char * pszName)
{
  bool finished = false;

  switch (mCurrentElement.first)
    {
      case Assignment:
        finished = true;
        break;

      case Expression:

      {
        size_t Size = CCopasiMessage::size();

        if (mpData->pEventAssignment != NULL)
          mpData->pEventAssignment->setExpression(mpData->CharacterData);

        // Remove error messages created by setExpression as this may fail
        // due to incomplete model specification at this time.
        while (CCopasiMessage::size() > Size)
          {
            CCopasiMessage::getLastMessage();
          }
      }

      break;

      default:
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCXML + 2,
                       mpParser->getCurrentLineNumber(), mpParser->getCurrentColumnNumber(), pszName);
        break;
    }

  return finished;
}

// virtual
CXMLHandler::sProcessLogic * AssignmentHandler::getProcessLogic() const
{
  static sProcessLogic Elements[] =
  {
    {"BEFORE", BEFORE, BEFORE, {Assignment, HANDLER_COUNT}},
    {"Assignment", Assignment, Assignment, {Expression, AFTER, HANDLER_COUNT}},
    {"Expression", Expression, CharacterData, {AFTER, HANDLER_COUNT}},
    {"AFTER", AFTER, AFTER, {HANDLER_COUNT}}
  };

  return Elements;
}
<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2013 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */
#include "runtimes/libjoynr-runtime/LibJoynrRuntime.h"

#include <QtConcurrent/QtConcurrent>

#include "joynr/Dispatcher.h"
#include "joynr/InProcessDispatcher.h"
#include "joynr/system/CommonApiDbusAddress.h"
#include "joynr/PublicationManager.h"
#include "joynr/SubscriptionManager.h"
#include "joynr/InProcessPublicationSender.h"
#include "joynr/JoynrMessageSender.h"
#include "joynr/MessageRouter.h"
#include "libjoynr/in-process/InProcessLibJoynrMessagingSkeleton.h"
#include "joynr/InProcessMessagingAddress.h"
#include "joynr/MessagingStubFactory.h"
#include "libjoynr/in-process/InProcessMessagingStubFactory.h"
#include "joynr/system/DiscoveryProxy.h"

#include "joynr/Util.h"

namespace joynr
{

LibJoynrRuntime::LibJoynrRuntime(QSettings* settings)
        : JoynrRuntime(*settings),
          connectorFactory(NULL),
          subscriptionManager(NULL),
          inProcessPublicationSender(NULL),
          inProcessConnectorFactory(NULL),
          joynrMessagingConnectorFactory(NULL),
          joynrMessagingSendStub(NULL),
          joynrMessageSender(NULL),
          joynrDispatcher(NULL),
          inProcessDispatcher(NULL),
          settings(settings),
          libjoynrSettings(new LibjoynrSettings(*settings)),
          dispatcherMessagingSkeleton(NULL),
          runtimeExecutor(NULL)
{
    libjoynrSettings->printSettings();
}

LibJoynrRuntime::~LibJoynrRuntime()
{
    delete proxyFactory;
    delete inProcessDispatcher;
    delete capabilitiesRegistrar;
    delete joynrMessageSender;
    delete joynrDispatcher;
    delete libjoynrSettings;
    libjoynrSettings = Q_NULLPTR;
    settings->clear();
    settings->deleteLater();
    if (runtimeExecutor != Q_NULLPTR) {
        runtimeExecutor->stop();
        runtimeExecutor->deleteLater();
        runtimeExecutor = Q_NULLPTR;
    }
}

void LibJoynrRuntime::init(IMiddlewareMessagingStubFactory* middlewareMessagingStubFactory,
                           QSharedPointer<joynr::system::Address> libjoynrMessagingAddress,
                           QSharedPointer<joynr::system::Address> ccMessagingAddress)
{
    // create messaging stub factory
    MessagingStubFactory* messagingStubFactory = new MessagingStubFactory();
    messagingStubFactory->registerStubFactory(middlewareMessagingStubFactory);
    messagingStubFactory->registerStubFactory(new InProcessMessagingStubFactory());

    // create message router
    messageRouter = QSharedPointer<MessageRouter>(
            new MessageRouter(messagingStubFactory, libjoynrMessagingAddress));

    startLibJoynrMessagingSkeleton(*messageRouter);

    joynrMessageSender = new JoynrMessageSender(messageRouter);
    joynrDispatcher = new Dispatcher(joynrMessageSender);
    joynrMessageSender->registerDispatcher(joynrDispatcher);

    // create the inprocess skeleton for the dispatcher
    dispatcherMessagingSkeleton = QSharedPointer<InProcessMessagingSkeleton>(
            new InProcessLibJoynrMessagingSkeleton(joynrDispatcher));
    dispatcherAddress = QSharedPointer<joynr::system::Address>(
            new InProcessMessagingAddress(dispatcherMessagingSkeleton));

    publicationManager = new PublicationManager();
    subscriptionManager = new SubscriptionManager();
    inProcessDispatcher = new InProcessDispatcher();

    inProcessPublicationSender = new InProcessPublicationSender(subscriptionManager);
    inProcessConnectorFactory = new InProcessConnectorFactory(
            subscriptionManager,
            publicationManager,
            inProcessPublicationSender,
            dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher));
    joynrMessagingConnectorFactory =
            new JoynrMessagingConnectorFactory(joynrMessageSender, subscriptionManager);

    connectorFactory =
            new ConnectorFactory(inProcessConnectorFactory, joynrMessagingConnectorFactory);

    proxyFactory = new ProxyFactory(libjoynrMessagingAddress, connectorFactory, NULL);

    // Set up the persistence file for storing provider participant ids
    QString persistenceFilename = libjoynrSettings->getParticipantIdsPersistenceFilename();
    participantIdStorage =
            QSharedPointer<ParticipantIdStorage>(new ParticipantIdStorage(persistenceFilename));

    // initialize the dispatchers
    QList<IDispatcher*> dispatcherList;
    dispatcherList.append(inProcessDispatcher);
    dispatcherList.append(joynrDispatcher);

    joynrDispatcher->registerPublicationManager(publicationManager);
    joynrDispatcher->registerSubscriptionManager(subscriptionManager);

    discoveryProxy = new LocalDiscoveryAggregator(
            *dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher), systemServicesSettings);
    QString systemServicesDomain = systemServicesSettings.getDomain();
    QString routingProviderParticipantId =
            systemServicesSettings.getCcRoutingProviderParticipantId();

    DiscoveryQos routingProviderDiscoveryQos;
    routingProviderDiscoveryQos.setCacheMaxAge(1000);
    routingProviderDiscoveryQos.setArbitrationStrategy(
            DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
    routingProviderDiscoveryQos.addCustomParameter(
            "fixedParticipantId", routingProviderParticipantId);
    routingProviderDiscoveryQos.setDiscoveryTimeout(50);

    auto routingProxyBuilder = getProxyBuilder<joynr::system::RoutingProxy>(systemServicesDomain);
    auto routingProxy = routingProxyBuilder->setRuntimeQos(MessagingQos(5000))
                                ->setCached(false)
                                ->setDiscoveryQos(routingProviderDiscoveryQos)
                                ->build();
    messageRouter->setParentRouter(routingProxy, ccMessagingAddress, routingProviderParticipantId);
    delete routingProxyBuilder;

    // setup discovery
    QString discoveryProviderParticipantId =
            systemServicesSettings.getCcDiscoveryProviderParticipantId();
    DiscoveryQos discoveryProviderDiscoveryQos;
    discoveryProviderDiscoveryQos.setCacheMaxAge(1000);
    discoveryProviderDiscoveryQos.setArbitrationStrategy(
            DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
    discoveryProviderDiscoveryQos.addCustomParameter(
            "fixedParticipantId", discoveryProviderParticipantId);
    discoveryProviderDiscoveryQos.setDiscoveryTimeout(1000);

    ProxyBuilder<joynr::system::DiscoveryProxy>* discoveryProxyBuilder =
            getProxyBuilder<joynr::system::DiscoveryProxy>(systemServicesDomain);
    discoveryProxy->setDiscoveryProxy(discoveryProxyBuilder->setRuntimeQos(MessagingQos(5000))
                                              ->setCached(false)
                                              ->setDiscoveryQos(discoveryProviderDiscoveryQos)
                                              ->build());
    capabilitiesRegistrar = new CapabilitiesRegistrar(dispatcherList,
                                                      *discoveryProxy,
                                                      libjoynrMessagingAddress,
                                                      participantIdStorage,
                                                      dispatcherAddress,
                                                      messageRouter);
}

void LibJoynrRuntime::unregisterCapability(QString participantId)
{
    assert(capabilitiesRegistrar);
    capabilitiesRegistrar->remove(participantId);
}

void LibJoynrRuntime::setRuntimeExecutor(JoynrRuntimeExecutor* runtimeExecutor)
{
    this->runtimeExecutor = runtimeExecutor;
}

LibJoynrRuntime* LibJoynrRuntime::create(JoynrRuntimeExecutor* runtimeExecutor)
{
    LibJoynrRuntime* runtime = runtimeExecutor->getRuntime();
    runtime->setRuntimeExecutor(runtimeExecutor);
    return runtime;
}

} // namespace joynr
<commit_msg>[Cpp] Set ttl for communication with Routing/DiscoveryProxy to 10000ms<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2013 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */
#include "runtimes/libjoynr-runtime/LibJoynrRuntime.h"

#include <QtConcurrent/QtConcurrent>

#include "joynr/Dispatcher.h"
#include "joynr/InProcessDispatcher.h"
#include "joynr/system/CommonApiDbusAddress.h"
#include "joynr/PublicationManager.h"
#include "joynr/SubscriptionManager.h"
#include "joynr/InProcessPublicationSender.h"
#include "joynr/JoynrMessageSender.h"
#include "joynr/MessageRouter.h"
#include "libjoynr/in-process/InProcessLibJoynrMessagingSkeleton.h"
#include "joynr/InProcessMessagingAddress.h"
#include "joynr/MessagingStubFactory.h"
#include "libjoynr/in-process/InProcessMessagingStubFactory.h"
#include "joynr/system/DiscoveryProxy.h"

#include "joynr/Util.h"

namespace joynr
{

LibJoynrRuntime::LibJoynrRuntime(QSettings* settings)
        : JoynrRuntime(*settings),
          connectorFactory(NULL),
          subscriptionManager(NULL),
          inProcessPublicationSender(NULL),
          inProcessConnectorFactory(NULL),
          joynrMessagingConnectorFactory(NULL),
          joynrMessagingSendStub(NULL),
          joynrMessageSender(NULL),
          joynrDispatcher(NULL),
          inProcessDispatcher(NULL),
          settings(settings),
          libjoynrSettings(new LibjoynrSettings(*settings)),
          dispatcherMessagingSkeleton(NULL),
          runtimeExecutor(NULL)
{
    libjoynrSettings->printSettings();
}

LibJoynrRuntime::~LibJoynrRuntime()
{
    delete proxyFactory;
    delete inProcessDispatcher;
    delete capabilitiesRegistrar;
    delete joynrMessageSender;
    delete joynrDispatcher;
    delete libjoynrSettings;
    libjoynrSettings = Q_NULLPTR;
    settings->clear();
    settings->deleteLater();
    if (runtimeExecutor != Q_NULLPTR) {
        runtimeExecutor->stop();
        runtimeExecutor->deleteLater();
        runtimeExecutor = Q_NULLPTR;
    }
}

void LibJoynrRuntime::init(IMiddlewareMessagingStubFactory* middlewareMessagingStubFactory,
                           QSharedPointer<joynr::system::Address> libjoynrMessagingAddress,
                           QSharedPointer<joynr::system::Address> ccMessagingAddress)
{
    // create messaging stub factory
    MessagingStubFactory* messagingStubFactory = new MessagingStubFactory();
    messagingStubFactory->registerStubFactory(middlewareMessagingStubFactory);
    messagingStubFactory->registerStubFactory(new InProcessMessagingStubFactory());

    // create message router
    messageRouter = QSharedPointer<MessageRouter>(
            new MessageRouter(messagingStubFactory, libjoynrMessagingAddress));

    startLibJoynrMessagingSkeleton(*messageRouter);

    joynrMessageSender = new JoynrMessageSender(messageRouter);
    joynrDispatcher = new Dispatcher(joynrMessageSender);
    joynrMessageSender->registerDispatcher(joynrDispatcher);

    // create the inprocess skeleton for the dispatcher
    dispatcherMessagingSkeleton = QSharedPointer<InProcessMessagingSkeleton>(
            new InProcessLibJoynrMessagingSkeleton(joynrDispatcher));
    dispatcherAddress = QSharedPointer<joynr::system::Address>(
            new InProcessMessagingAddress(dispatcherMessagingSkeleton));

    publicationManager = new PublicationManager();
    subscriptionManager = new SubscriptionManager();
    inProcessDispatcher = new InProcessDispatcher();

    inProcessPublicationSender = new InProcessPublicationSender(subscriptionManager);
    inProcessConnectorFactory = new InProcessConnectorFactory(
            subscriptionManager,
            publicationManager,
            inProcessPublicationSender,
            dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher));
    joynrMessagingConnectorFactory =
            new JoynrMessagingConnectorFactory(joynrMessageSender, subscriptionManager);

    connectorFactory =
            new ConnectorFactory(inProcessConnectorFactory, joynrMessagingConnectorFactory);

    proxyFactory = new ProxyFactory(libjoynrMessagingAddress, connectorFactory, NULL);

    // Set up the persistence file for storing provider participant ids
    QString persistenceFilename = libjoynrSettings->getParticipantIdsPersistenceFilename();
    participantIdStorage =
            QSharedPointer<ParticipantIdStorage>(new ParticipantIdStorage(persistenceFilename));

    // initialize the dispatchers
    QList<IDispatcher*> dispatcherList;
    dispatcherList.append(inProcessDispatcher);
    dispatcherList.append(joynrDispatcher);

    joynrDispatcher->registerPublicationManager(publicationManager);
    joynrDispatcher->registerSubscriptionManager(subscriptionManager);

    discoveryProxy = new LocalDiscoveryAggregator(
            *dynamic_cast<IRequestCallerDirectory*>(inProcessDispatcher), systemServicesSettings);
    QString systemServicesDomain = systemServicesSettings.getDomain();
    QString routingProviderParticipantId =
            systemServicesSettings.getCcRoutingProviderParticipantId();

    DiscoveryQos routingProviderDiscoveryQos;
    routingProviderDiscoveryQos.setCacheMaxAge(1000);
    routingProviderDiscoveryQos.setArbitrationStrategy(
            DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
    routingProviderDiscoveryQos.addCustomParameter(
            "fixedParticipantId", routingProviderParticipantId);
    routingProviderDiscoveryQos.setDiscoveryTimeout(50);

    auto routingProxyBuilder = getProxyBuilder<joynr::system::RoutingProxy>(systemServicesDomain);
    auto routingProxy = routingProxyBuilder->setRuntimeQos(MessagingQos(10000))
                                ->setCached(false)
                                ->setDiscoveryQos(routingProviderDiscoveryQos)
                                ->build();
    messageRouter->setParentRouter(routingProxy, ccMessagingAddress, routingProviderParticipantId);
    delete routingProxyBuilder;

    // setup discovery
    QString discoveryProviderParticipantId =
            systemServicesSettings.getCcDiscoveryProviderParticipantId();
    DiscoveryQos discoveryProviderDiscoveryQos;
    discoveryProviderDiscoveryQos.setCacheMaxAge(1000);
    discoveryProviderDiscoveryQos.setArbitrationStrategy(
            DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
    discoveryProviderDiscoveryQos.addCustomParameter(
            "fixedParticipantId", discoveryProviderParticipantId);
    discoveryProviderDiscoveryQos.setDiscoveryTimeout(1000);

    ProxyBuilder<joynr::system::DiscoveryProxy>* discoveryProxyBuilder =
            getProxyBuilder<joynr::system::DiscoveryProxy>(systemServicesDomain);
    discoveryProxy->setDiscoveryProxy(discoveryProxyBuilder->setRuntimeQos(MessagingQos(10000))
                                              ->setCached(false)
                                              ->setDiscoveryQos(discoveryProviderDiscoveryQos)
                                              ->build());
    capabilitiesRegistrar = new CapabilitiesRegistrar(dispatcherList,
                                                      *discoveryProxy,
                                                      libjoynrMessagingAddress,
                                                      participantIdStorage,
                                                      dispatcherAddress,
                                                      messageRouter);
}

void LibJoynrRuntime::unregisterCapability(QString participantId)
{
    assert(capabilitiesRegistrar);
    capabilitiesRegistrar->remove(participantId);
}

void LibJoynrRuntime::setRuntimeExecutor(JoynrRuntimeExecutor* runtimeExecutor)
{
    this->runtimeExecutor = runtimeExecutor;
}

LibJoynrRuntime* LibJoynrRuntime::create(JoynrRuntimeExecutor* runtimeExecutor)
{
    LibJoynrRuntime* runtime = runtimeExecutor->getRuntime();
    runtime->setRuntimeExecutor(runtimeExecutor);
    return runtime;
}

} // namespace joynr
<|endoftext|>


<commit_before>// Copyright (C) 2017 - 2018 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and University of
// of Connecticut School of Medicine.
// All rights reserved.

// Copyright (C) 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include "copasi.h"

#include "AssignmentHandler.h"
#include "CXMLParser.h"
#include "utilities/CCopasiMessage.h"

#include "model/CModel.h"

/**
 * Replace Assignment with the name type of the handler and implement the
 * three methods below.
 */
AssignmentHandler::AssignmentHandler(CXMLParser & parser, CXMLParserData & data):
  CXMLHandler(parser, data, CXMLHandler::Assignment)
{
  init();
}

// virtual
AssignmentHandler::~AssignmentHandler()
{}

// virtual
CXMLHandler * AssignmentHandler::processStart(const XML_Char * pszName,
    const XML_Char ** papszAttrs)
{
  CXMLHandler * pHandlerToCall = NULL;
  const char * Key;
  const char * TargetCStr;
  std::string Target;

  const CModelEntity* pME = NULL;

  switch (mCurrentElement.first)
    {
      case Assignment:
        mpData->pEventAssignment = NULL;
        TargetCStr = mpParser->getAttributeValue("target", papszAttrs, false);

        if (TargetCStr != NULL)
          Target = TargetCStr;

        if (Target.empty())
          {
            Key = mpParser->getAttributeValue("targetKey", papszAttrs);
            pME = dynamic_cast<const CModelEntity *>(mpData->mKeyMap.get(Key));

            mpData->pEventAssignment = new CEventAssignment(pME->getKey());
            mpData->pEvent->getAssignments().add(mpData->pEventAssignment, true);
          }

        break;

      case Expression:
        pHandlerToCall = getHandler(mCurrentElement.second);
        break;

      default:
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCXML + 2,
                       mpParser->getCurrentLineNumber(), mpParser->getCurrentColumnNumber(), pszName);
        break;
    }

  return pHandlerToCall;
}

// virtual
bool AssignmentHandler::processEnd(const XML_Char * pszName)
{
  bool finished = false;

  switch (mCurrentElement.first)
    {
      case Assignment:
        finished = true;
        break;

      case Expression:

      {
        size_t Size = CCopasiMessage::size();

        if (mpData->pEventAssignment != NULL)
          mpData->pEventAssignment->setExpression(mpData->CharacterData);

        // Remove error messages created by setExpression as this may fail
        // due to incomplete model specification at this time.
        while (CCopasiMessage::size() > Size)
          {
            CCopasiMessage::getLastMessage();
          }
      }

      break;

      default:
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCXML + 2,
                       mpParser->getCurrentLineNumber(), mpParser->getCurrentColumnNumber(), pszName);
        break;
    }

  return finished;
}

// virtual
CXMLHandler::sProcessLogic * AssignmentHandler::getProcessLogic() const
{
  static sProcessLogic Elements[] =
  {
    {"BEFORE", BEFORE, BEFORE, {Assignment, HANDLER_COUNT}},
    {"Assignment", Assignment, Assignment, {Expression, AFTER, HANDLER_COUNT}},
    {"Expression", Expression, CharacterData, {AFTER, HANDLER_COUNT}},
    {"AFTER", AFTER, AFTER, {HANDLER_COUNT}}
  };

  return Elements;
}
<commit_msg>Bug 2635. Release is now able to read event assignments from all files.<commit_after>// Copyright (C) 2017 - 2018 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and University of
// of Connecticut School of Medicine.
// All rights reserved.

// Copyright (C) 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include "copasi.h"

#include "AssignmentHandler.h"
#include "CXMLParser.h"
#include "utilities/CCopasiMessage.h"

#include "model/CModel.h"

/**
 * Replace Assignment with the name type of the handler and implement the
 * three methods below.
 */
AssignmentHandler::AssignmentHandler(CXMLParser & parser, CXMLParserData & data):
  CXMLHandler(parser, data, CXMLHandler::Assignment)
{
  init();
}

// virtual
AssignmentHandler::~AssignmentHandler()
{}

// virtual
CXMLHandler * AssignmentHandler::processStart(const XML_Char * pszName,
    const XML_Char ** papszAttrs)
{
  CXMLHandler * pHandlerToCall = NULL;
  const char * Key;
  const char * TargetCStr;
  std::string Target;

  const CModelEntity* pME = NULL;

  switch (mCurrentElement.first)
    {
      case Assignment:
        mpData->pEventAssignment = NULL;
        TargetCStr = mpParser->getAttributeValue("target", papszAttrs, false);

        if (TargetCStr != NULL)
          Target = TargetCStr;

        if (Target.empty())
          {
            Key = mpParser->getAttributeValue("targetKey", papszAttrs);
            pME = dynamic_cast<const CModelEntity *>(mpData->mKeyMap.get(Key));
          }
        else
          {
            pME = dynamic_cast<const CModelEntity *>(mpData->pModel->getObjectFromCN(Target));
          }

        if (pME != NULL)
          {
            mpData->pEventAssignment = new CEventAssignment(pME->getKey());
            mpData->pEvent->getAssignments().add(mpData->pEventAssignment, true);
          }

        break;

      case Expression:
        pHandlerToCall = getHandler(mCurrentElement.second);
        break;

      default:
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCXML + 2,
                       mpParser->getCurrentLineNumber(), mpParser->getCurrentColumnNumber(), pszName);
        break;
    }

  return pHandlerToCall;
}

// virtual
bool AssignmentHandler::processEnd(const XML_Char * pszName)
{
  bool finished = false;

  switch (mCurrentElement.first)
    {
      case Assignment:
        finished = true;
        break;

      case Expression:

      {
        size_t Size = CCopasiMessage::size();

        if (mpData->pEventAssignment != NULL)
          mpData->pEventAssignment->setExpression(mpData->CharacterData);

        // Remove error messages created by setExpression as this may fail
        // due to incomplete model specification at this time.
        while (CCopasiMessage::size() > Size)
          {
            CCopasiMessage::getLastMessage();
          }
      }

      break;

      default:
        CCopasiMessage(CCopasiMessage::EXCEPTION, MCXML + 2,
                       mpParser->getCurrentLineNumber(), mpParser->getCurrentColumnNumber(), pszName);
        break;
    }

  return finished;
}

// virtual
CXMLHandler::sProcessLogic * AssignmentHandler::getProcessLogic() const
{
  static sProcessLogic Elements[] =
  {
    {"BEFORE", BEFORE, BEFORE, {Assignment, HANDLER_COUNT}},
    {"Assignment", Assignment, Assignment, {Expression, AFTER, HANDLER_COUNT}},
    {"Expression", Expression, CharacterData, {AFTER, HANDLER_COUNT}},
    {"AFTER", AFTER, AFTER, {HANDLER_COUNT}}
  };

  return Elements;
}
<|endoftext|>


<commit_before>#include "schedulers/shortest_path_switch_scheduler.h"

DEFINE_bool(overtake, true, "Should car overtake others?");

// TODO refactor whole code here, its copypaste

using game::Position;

namespace schedulers {

ShortestPathSwitchScheduler::ShortestPathSwitchScheduler(
    const game::Race& race,
    game::RaceTracker& race_tracker,
    game::CarTracker& car_tracker)
  : race_(race), car_tracker_(car_tracker), race_tracker_(race_tracker),
    should_switch_now_(false), waiting_for_switch_(false),
    target_switch_(-1) {
  //ComputeShortestPaths();
}

// Prepares for overtake
void ShortestPathSwitchScheduler::Overtake(const string& color) {
  printf("Feature not implemented\n");
}

// Updates the state and calculates next state
// TODO switch time
void ShortestPathSwitchScheduler::Schedule(const game::CarState& state) {
  if (state.position().piece() == target_switch_) {
    waiting_for_switch_ = false;
    target_switch_ = -1;
  }
  if (waiting_for_switch_)
    return;

  // TODO its greedy :D
  const Position& position = state.position();

  // We evaluate next two switches to decide if we should change the lane.
  int from = race_.track().NextSwitch(position.piece());
  int to = race_.track().NextSwitch(from);

  // Distance between current position and the 'to' switch:
  // - if we stay on current lane
  // - if we decide to switch to left lane
  // - if we decide to switch to right lane
  Position end_position;
  end_position.set_piece(to);
  double current = DistanceBetween(position, end_position, position.end_lane());
  double left = DistanceBetween(position, end_position, position.end_lane() - 1);
  double right = DistanceBetween(position, end_position, position.end_lane() + 1);

  // TODO(tomek) Improve:
  // - we should "score" every lane, based on opponents on them
  // - even if someone has very good lap, he can crashed and respawned
  // - consider instead of distance, trying to estimate how much time
  //   it will take us to drive through given lanes

  // Overtaking
  if (FLAGS_overtake) {
    int left_score = race_tracker_.ScoreLane(from, to, position.end_lane() - 1);
    int right_score = race_tracker_.ScoreLane(from, to, position.end_lane() + 1);
    int current_score = race_tracker_.ScoreLane(from, to, position.end_lane());

    if (left_score < 0) left = kInf;
    if (right_score < 0) right = kInf;
    if (current_score < 0) current = kInf;
  }

  printf("%lf %lf %lf\n",left, current, right);

  if (left < current && left < right) {
    scheduled_switch_ = game::Switch::kSwitchLeft;
    target_switch_ = from;
    should_switch_now_ = true;
  } else if (right < current && right <= left) {
    scheduled_switch_ = game::Switch::kSwitchRight;
    target_switch_ = from;
    should_switch_now_ = true;
  } else {
    should_switch_now_ = false;
    target_switch_ = -1;
  }
}

double ShortestPathSwitchScheduler::DistanceBetween(const Position& position1, const Position& position2, int lane) {
  if (!race_.track().IsLaneCorrect(lane)) {
    return kInf;
  }
  Position end_position = position2;
  end_position.set_start_lane(lane);
  end_position.set_end_lane(lane);

  return car_tracker_.DistanceBetween(position1, end_position);
}

void ShortestPathSwitchScheduler::ComputeShortestPaths() {
  // TODO
}

void ShortestPathSwitchScheduler::Switched() {
  should_switch_now_ = false;
  waiting_for_switch_ = true;
}

// Returns scheduled switch
bool ShortestPathSwitchScheduler::ShouldSwitch() {
  if (should_switch_now_ &&
      !waiting_for_switch_) {
    auto s = car_tracker_.current_state();
    s = car_tracker_.Predict(s, game::Command(1));
    s = car_tracker_.Predict(s, game::Command(1));
    if (s.position().piece() != target_switch_)
      return false;

    if (car_tracker_.current_state().velocity() > 0 &&
        car_tracker_.IsSafe(car_tracker_.current_state(), game::Command(scheduled_switch_)))
      return true;
  }
  return false;
}

game::Switch ShortestPathSwitchScheduler::ExpectedSwitch() {
  if (should_switch_now_ && !waiting_for_switch_)
    return scheduled_switch_;
  return game::Switch::kStay;
}

game::Switch ShortestPathSwitchScheduler::SwitchDirection() {
  return scheduled_switch_;
}

}  // namespace schedulers
<commit_msg>Choose lane with fastest guy<commit_after>#include "schedulers/shortest_path_switch_scheduler.h"

DEFINE_bool(overtake, true, "Should car overtake others?");

// TODO refactor whole code here, its copypaste

using game::Position;

namespace schedulers {

ShortestPathSwitchScheduler::ShortestPathSwitchScheduler(
    const game::Race& race,
    game::RaceTracker& race_tracker,
    game::CarTracker& car_tracker)
  : race_(race), car_tracker_(car_tracker), race_tracker_(race_tracker),
    should_switch_now_(false), waiting_for_switch_(false),
    target_switch_(-1) {
  //ComputeShortestPaths();
}

// Prepares for overtake
void ShortestPathSwitchScheduler::Overtake(const string& color) {
  printf("Feature not implemented\n");
}

// Updates the state and calculates next state
// TODO switch time
void ShortestPathSwitchScheduler::Schedule(const game::CarState& state) {
  if (state.position().piece() == target_switch_) {
    waiting_for_switch_ = false;
    target_switch_ = -1;
  }
  if (waiting_for_switch_)
    return;

  // TODO its greedy :D
  const Position& position = state.position();

  // We evaluate next two switches to decide if we should change the lane.
  int from = race_.track().NextSwitch(position.piece());
  int to = race_.track().NextSwitch(from);

  // Distance between current position and the 'to' switch:
  // - if we stay on current lane
  // - if we decide to switch to left lane
  // - if we decide to switch to right lane
  Position end_position;
  end_position.set_piece(to);
  double current = DistanceBetween(position, end_position, position.end_lane());
  double left = DistanceBetween(position, end_position, position.end_lane() - 1);
  double right = DistanceBetween(position, end_position, position.end_lane() + 1);

  // TODO(tomek) Improve:
  // - we should "score" every lane, based on opponents on them
  // - even if someone has very good lap, he can crashed and respawned
  // - consider instead of distance, trying to estimate how much time
  //   it will take us to drive through given lanes

  // Overtaking
  if (FLAGS_overtake) {
    int left_score = race_tracker_.ScoreLane(from, to, position.end_lane() - 1);
    int right_score = race_tracker_.ScoreLane(from, to, position.end_lane() + 1);
    int current_score = race_tracker_.ScoreLane(from, to, position.end_lane());

    if (left_score < 0) left = kInf;
    if (right_score < 0) right = kInf;
    if (current_score < 0) current = kInf;

    // Score is <-10, 0), 0 is best
    // Nest part of algorithm chooses smallest so we need to reverse it temporarily
    if (left_score < 0 && current_score < 0 && right_score < 0) {
      left = -left_score;
      current = -current_score;
      right = -current_score;
    }
  }

  printf("%lf %lf %lf\n",left, current, right);

  if (left < current && left < right) {
    scheduled_switch_ = game::Switch::kSwitchLeft;
    target_switch_ = from;
    should_switch_now_ = true;
  } else if (right < current && right <= left) {
    scheduled_switch_ = game::Switch::kSwitchRight;
    target_switch_ = from;
    should_switch_now_ = true;
  } else {
    should_switch_now_ = false;
    target_switch_ = -1;
  }
}

double ShortestPathSwitchScheduler::DistanceBetween(const Position& position1, const Position& position2, int lane) {
  if (!race_.track().IsLaneCorrect(lane)) {
    return kInf;
  }
  Position end_position = position2;
  end_position.set_start_lane(lane);
  end_position.set_end_lane(lane);

  return car_tracker_.DistanceBetween(position1, end_position);
}

void ShortestPathSwitchScheduler::ComputeShortestPaths() {
  // TODO
}

void ShortestPathSwitchScheduler::Switched() {
  should_switch_now_ = false;
  waiting_for_switch_ = true;
}

// Returns scheduled switch
bool ShortestPathSwitchScheduler::ShouldSwitch() {
  if (should_switch_now_ &&
      !waiting_for_switch_) {
    auto s = car_tracker_.current_state();
    s = car_tracker_.Predict(s, game::Command(1));
    s = car_tracker_.Predict(s, game::Command(1));
    if (s.position().piece() != target_switch_)
      return false;

    if (car_tracker_.current_state().velocity() > 0 &&
        car_tracker_.IsSafe(car_tracker_.current_state(), game::Command(scheduled_switch_)))
      return true;
  }
  return false;
}

game::Switch ShortestPathSwitchScheduler::ExpectedSwitch() {
  if (should_switch_now_ && !waiting_for_switch_)
    return scheduled_switch_;
  return game::Switch::kStay;
}

game::Switch ShortestPathSwitchScheduler::SwitchDirection() {
  return scheduled_switch_;
}

}  // namespace schedulers
<|endoftext|>