<commit_before>// Copyright (c) 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "xwalk/runtime/browser/xwalk_browser_main_parts_tizen.h"

#include "base/file_util.h"
#include "base/files/file_path.h"
#include "content/public/common/content_switches.h"
#include "xwalk/application/browser/application.h"
#include "xwalk/application/browser/application_service.h"
#include "xwalk/application/browser/application_system.h"
#include "xwalk/extensions/common/xwalk_extension.h"
#include "xwalk/runtime/browser/xwalk_runner.h"
#include "xwalk/runtime/common/xwalk_runtime_features.h"
#include "xwalk/sysapps/raw_socket/raw_socket_extension.h"
#include "ui/gl/gl_switches.h"
#include "ui/gfx/switches.h"

#include "content/browser/device_orientation/device_inertial_sensor_service.h"
#include "xwalk/application/browser/installer/tizen/package_installer.h"
#include "xwalk/runtime/extension/screen_orientation_extension.h"
#include "xwalk/sysapps/device_capabilities/device_capabilities_extension.h"
#include "xwalk/tizen/mobile/sensor/tizen_data_fetcher_shared_memory.h"

namespace xwalk {

using application::Application;

XWalkBrowserMainPartsTizen::XWalkBrowserMainPartsTizen(
    const content::MainFunctionParams& parameters)
    : XWalkBrowserMainParts(parameters) {
}

void XWalkBrowserMainPartsTizen::PreMainMessageLoopStart() {
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  command_line->AppendSwitch(switches::kIgnoreGpuBlacklist);

  const char* gl_name;
  if (base::PathExists(base::FilePath("/usr/lib/xwalk/libosmesa.so")))
    gl_name = gfx::kGLImplementationOSMesaName;
  else if (base::PathExists(base::FilePath("/usr/lib/libGL.so")))
    gl_name = gfx::kGLImplementationDesktopName;
  else
    gl_name = gfx::kGLImplementationEGLName;
  command_line->AppendSwitchASCII(switches::kUseGL, gl_name);

  // Workaround to provide viewport meta tag proper behavior on Tizen.
  // FIXME: Must be removed when Chromium r235967 is in place.
  command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor, "2.0");

  XWalkBrowserMainParts::PreMainMessageLoopStart();
}

void XWalkBrowserMainPartsTizen::PreMainMessageLoopRun() {
  if (content::DeviceInertialSensorService* sensor_service =
          content::DeviceInertialSensorService::GetInstance()) {
    // As the data fetcher of sensors is implemented outside of Chromium, we
    // need to make it available to Chromium by "abusing" the test framework.
    // TODO(zliang7): Find a decent way to inject our sensor fetcher for Tizen.
    sensor_service->SetDataFetcherForTests(new TizenDataFetcherSharedMemory());
  }

  XWalkBrowserMainParts::PreMainMessageLoopRun();
}

// static.
OrientationMask XWalkBrowserMainPartsTizen::GetAllowedUAOrientations() {
  char* env = getenv("TIZEN_ALLOWED_ORIENTATIONS");
  int value = env ? atoi(env) : 0;
  if (value > 0 && value < (1 << 4))
    return static_cast<OrientationMask>(value);

  // Tizen mobile supports all orientations by default.
  return ANY;
}

void XWalkBrowserMainPartsTizen::CreateInternalExtensionsForUIThread(
    content::RenderProcessHost* host,
    extensions::XWalkExtensionVector* extensions) {
  XWalkBrowserMainParts::CreateInternalExtensionsForUIThread(
      host, extensions);
  // FIXME(Mikhail): move this code to a dedicated XWalkComponent.
  application::ApplicationSystem* app_system = xwalk_runner_->app_system();
  application::ApplicationService* app_service
      = app_system->application_service();
  Application* application =
      app_service->GetApplicationByRenderHostID(host->GetID());
  if (!application)
    return;
  extensions->push_back(new ScreenOrientationExtension(
        application, GetAllowedUAOrientations()));
}

}  // namespace xwalk
<commit_msg>Fix Tizen build after PR#1489<commit_after>// Copyright (c) 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "xwalk/runtime/browser/xwalk_browser_main_parts_tizen.h"

#include "base/file_util.h"
#include "base/files/file_path.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "xwalk/application/browser/application.h"
#include "xwalk/application/browser/application_service.h"
#include "xwalk/application/browser/application_system.h"
#include "xwalk/extensions/common/xwalk_extension.h"
#include "xwalk/runtime/browser/xwalk_runner.h"
#include "xwalk/runtime/common/xwalk_runtime_features.h"
#include "xwalk/sysapps/raw_socket/raw_socket_extension.h"
#include "ui/gl/gl_switches.h"
#include "ui/gfx/switches.h"

#include "content/browser/device_orientation/device_inertial_sensor_service.h"
#include "xwalk/application/browser/installer/tizen/package_installer.h"
#include "xwalk/runtime/extension/screen_orientation_extension.h"
#include "xwalk/sysapps/device_capabilities/device_capabilities_extension.h"
#include "xwalk/tizen/mobile/sensor/tizen_data_fetcher_shared_memory.h"

namespace xwalk {

using application::Application;

XWalkBrowserMainPartsTizen::XWalkBrowserMainPartsTizen(
    const content::MainFunctionParams& parameters)
    : XWalkBrowserMainParts(parameters) {
}

void XWalkBrowserMainPartsTizen::PreMainMessageLoopStart() {
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  command_line->AppendSwitch(switches::kIgnoreGpuBlacklist);

  const char* gl_name;
  if (base::PathExists(base::FilePath("/usr/lib/xwalk/libosmesa.so")))
    gl_name = gfx::kGLImplementationOSMesaName;
  else if (base::PathExists(base::FilePath("/usr/lib/libGL.so")))
    gl_name = gfx::kGLImplementationDesktopName;
  else
    gl_name = gfx::kGLImplementationEGLName;
  command_line->AppendSwitchASCII(switches::kUseGL, gl_name);

  // Workaround to provide viewport meta tag proper behavior on Tizen.
  // FIXME: Must be removed when Chromium r235967 is in place.
  command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor, "2.0");

  XWalkBrowserMainParts::PreMainMessageLoopStart();
}

void XWalkBrowserMainPartsTizen::PreMainMessageLoopRun() {
  if (content::DeviceInertialSensorService* sensor_service =
          content::DeviceInertialSensorService::GetInstance()) {
    // As the data fetcher of sensors is implemented outside of Chromium, we
    // need to make it available to Chromium by "abusing" the test framework.
    // TODO(zliang7): Find a decent way to inject our sensor fetcher for Tizen.
    sensor_service->SetDataFetcherForTests(new TizenDataFetcherSharedMemory());
  }

  XWalkBrowserMainParts::PreMainMessageLoopRun();
}

// static.
OrientationMask XWalkBrowserMainPartsTizen::GetAllowedUAOrientations() {
  char* env = getenv("TIZEN_ALLOWED_ORIENTATIONS");
  int value = env ? atoi(env) : 0;
  if (value > 0 && value < (1 << 4))
    return static_cast<OrientationMask>(value);

  // Tizen mobile supports all orientations by default.
  return ANY;
}

void XWalkBrowserMainPartsTizen::CreateInternalExtensionsForUIThread(
    content::RenderProcessHost* host,
    extensions::XWalkExtensionVector* extensions) {
  XWalkBrowserMainParts::CreateInternalExtensionsForUIThread(
      host, extensions);
  // FIXME(Mikhail): move this code to a dedicated XWalkComponent.
  application::ApplicationSystem* app_system = xwalk_runner_->app_system();
  application::ApplicationService* app_service
      = app_system->application_service();
  Application* application =
      app_service->GetApplicationByRenderHostID(host->GetID());
  if (!application)
    return;
  extensions->push_back(new ScreenOrientationExtension(
        application, GetAllowedUAOrientations()));
}

}  // namespace xwalk
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>
#include <queue>
#include <sys/stat.h>

//getlogin() and gethostname().
#include <unistd.h>

//perror.
#include <stdio.h>

//fork,wait and execvp.
#include <sys/types.h>
#include <sys/wait.h>

//boost!
#include "boost/algorithm/string.hpp"
#include "boost/tokenizer.hpp"
#include "boost/foreach.hpp"

//that one class.
#include "Command.h"

using namespace std;
using namespace boost;

//execute command.
void execute(const vector<string> & s);

//replaces char in string.
void replace_char(string &s, char o, char r);

//takes a string and returns vector of parsed string.
vector<string> parseInput(string s);

//display vector.
template<typename unit>
void display_vector(vector<unit> v);

//helper function that finds amount of character.
int find_char_amount(const string s,char c);

//removes comment from input.
void remove_comment(string &s);

//removes char in string.
void remove_char(string &s, char c);

//checks if string passed in contains a flag
bool isFlag(string f);

//creates command types from vector of strings.
vector<Command> create_commands(const vector<string> &v);

int main()
{
    //grab the login.
    char* login = getlogin();

    //start a flag.
    bool login_check = true;

    if((!login) != 0)
    {
        //check flag.
        login_check = false;

        //output error.
        perror("Error: could not retrieve login name");
    }

    //hold c-string for host name.
    char host[150];

    //start another flag.
    bool host_check = true;

    //gets hostname while checking if it actually grabbed it.
    if(gethostname(host,sizeof(host)) != 0)
    {
        //check flag.
        host_check = false;

        //output error.
        perror("Error: could not rerieve host name.");
    }

    //warn user of upcoming trouble.
    if(login_check == false || host_check == false)
        cout << "Unable to display login and/or host information." << endl;

    //string to hold user input.
    string input;

    while(true)
    {
        //output login@hostname.
        if(login_check && host_check)
            cout << login << '@' << host << ' ';

        //bash money.
        cout << "$ ";

        //placeholder to tell its the program.
        cout << " (program) ";

        //geting input as a string.
        getline(cin,input);

        //remove extra white space.
        trim(input);

        //remove comments.
        remove_comment(input);

        //trim again just in case.
        trim(input);

        //testing parse.
        cout << "Testing parse" << endl;
        display_vector(parseInput(input));

        //execute command.
        execute(parseInput(input));

    }

    cout << "End of program" << endl;

    return 0;
}

void execute(const vector<string> &s)
{
    //check to see if user wants to quit and its the only command.
    if(s.size() == 1)
        for(unsigned int i = 0; i < s.size(); ++i)
            if(s.at(i) == "exit")
                exit(0);

    //c-string to hold command.
    char* args[2048];

    //place, remove comments and convert commands.
    for(unsigned int i = 0; i < s.size(); ++i)
    {
        string temp = s.at(i);
        remove_char(temp,'\"');
        args[i] = (char*)temp.c_str();
    }
    args[s.size()] = NULL;

    //creates fork process.
    pid_t pid = fork();

    if(pid == -1)
    {
        //fork didn't work.
        perror("fork");
    }
    if(pid ==0)
    {
        if(execvp(args[0], args) == -1)
        {
            //execute didn't work.
            perror("execvp");

            //break out of shadow realm.
            exit(1);
        }

    }
    if(pid > 0)
    {
        //wait for child to die.
        if(wait(0) == -1)
        {
            //didnt wait.
            perror("wait");
        }
    }

    return;
}

vector<string> parseInput(string s)
{

    //replace spaces.
    replace_char(s,' ','*');

    //make temp vector to hold parsed strings.
    vector<string> temp;

    //create boost magic function.
    char_separator<char> sep(" ;||&&(){}", ";||&&()[]",keep_empty_tokens);

    //create boost magic holder thingy.
    tokenizer< char_separator<char> > cm(s,sep);

    //for each loop to grab each peice and push it into a vector.
    for(tokenizer< char_separator<char> >::iterator it = cm.begin(); it != cm.end(); ++it)
        if(*it != "")
        {
            //fix string.
            string temp_string = *it;
            replace_char(temp_string,'*',' ');
            temp.push_back(temp_string);
        }

    //return that vector.
    return temp;
}

void replace_char(string &s, char o, char r)
{
    //different use for the function.
    if(o == '\"')
    {
        //nothing to replace.
        if(s.find(o) == string::npos)
            return;

        //replace.
        for(unsigned int i = 0; i < s.size(); ++i)
            if(s.at(i) == o)
                s.at(i) = r;

        return;

    }

    //no quotes.
    if(s.find("\"") == string::npos)
        return;
    else if(s.find(o) == string::npos)
        return;

    //vector to hold quote positions.
    vector<int> pos;

    //place positions of char into vector.
    for(unsigned int i = 0; i < s.size(); ++i)
        if(s.at(i) == '\"')
            pos.push_back(i);

    //count position.
    unsigned int count = 0;

    //replace.
    while(count < pos.size())
    {
        for(int i = pos.at(count); i < pos.at(count+1); ++i)
            if(s.at(i) == o)
                s.at(i) = r;

        count++;
        count++;
    }

    return;
}

template<typename unit>
void display_vector(vector<unit> v)
{
    for(unsigned int i = 0; i < v.size(); ++i)
        cout << i+1 << ": " << v.at(i) << endl;
    return;
}

void remove_comment(string &s)
{
    //just add a " to the end to avoid errors.
    if(find_char_amount(s,'\"') % 2 != 0)
        s += '\"';

    //delete everything!
    if(s.find("#") == 0)
    {
        s = "";
        return;
    }

    //return if no comments.
    if(s.find("#") == string::npos)
    {
        return;
    }

    //if no comments then deletes everything from hash forward.
    if(s.find("\"") == string::npos && s.find("#") != string::npos)
    {
        s = s.substr(0,s.find("#"));
        return;
    }

    //if comment before quote then delete.
    if(s.find("\"") > s.find("#"))
    {
        s = s.substr(0,s.find("#"));
        return;
    }

    //advanced situations.
    //get a vector to hold positions of quotes and hash.
    vector<int> quotePos;
    vector<int> hashPos;

    //grab pos.
    for(unsigned int i = 0; i < s.size(); ++i)
    {
        if(s.at(i) == '\"')
            quotePos.push_back(i);
        else if(s.at(i) == '#')
            hashPos.push_back(i);
    }

    //no comments or hash for some reason.
    if(hashPos.size() == 0 || quotePos.size() == 0)
        return;

    //just in case.
    if(quotePos.size() % 2 != 0)
        quotePos.push_back(0);

    //overall check;
    vector<bool> check;

    //start it up.
    for(unsigned int i = 0; i < hashPos.size(); ++i)
        check.push_back(true);

    //check if hash is in quotes.
    for(unsigned int i = 0; i < hashPos.size(); ++i )
        for(unsigned int j = 0; j < quotePos.size(); j+=2 )
        {
            if(hashPos.at(i) > quotePos.at(j) && hashPos.at(i) < quotePos.at(j+1))
            {
                check.at(i) = true;
                break;
            }
            else
                check.at(i) = false;
        }

    //check bool vector to delete string.
    for(unsigned int i = 0; i < check.size(); ++i)
        if(!check.at(i))
        {
            s = s.substr(0,hashPos.at(i));
            return;
        }

    //if comment at end then kill it.
    if(hashPos.at(hashPos.size()-1) > quotePos.at(quotePos.size()-1))
        s = s.substr(0,hashPos.at(hashPos.size()-1));

    return;
}

int find_char_amount(const string s, char c)
{
    if(s.find(c) == string::npos)
        return 0;

    int count = 0;
    for(unsigned int i = 0; i < s.size(); ++i)
        if(s.at(i) == c)
            count++;
    return count;

}

void remove_char(string &s, char c)
{
    //if not there then just return.
    if(s.find(c) == string::npos)
        return;

    //start empty.
    string temp = "";

    //add everything thats not what we dont want.
    for(unsigned int i = 0; i < s.size(); ++i)
        if(s.at(i) != c)
            temp += s.at(i);

    //transfer to s.
    s = temp;

    return;
}

int is_connector(string s)
{
    if(s == ";")
		return 1;
	if(s == "&&")
		return 2;
	if(s == "||")
		return 3;

	return -1;
}

bool isFlag(string f)
{	//default list of possible flags
	string flags = "-e -d -f";
	//see if string is one of the flags
	if (flags.find(f) != string::npos)
		return true;
	return false;
}

/*
bool test(vector<string> &commands, vector<char*> &command_v)
{
	//defaults to "-e"
	string flag = "-e";

	struct stat s_thing;

	//put everything into a queue for ease of use
	queue<string> coms;
	for (unsigned int i = 0; i < commands.size(); i++)
	{
		coms.push_back(commands.at(i));
	}

	//was a bracket used for the test command?
	bool bracketUsed = false;

	//set if a bracket was used
	if(coms.front() == "[";
		bracketUsed = true;

	//remove the first part of the command regardless of whether it's "test" or "["
	coms.pop();

	if (isTestFlag(coms.front()))
	{
		flag = coms.front();
		//now we have the flag for the test
		coms.pop()
	}

	//if there's another flag attempt then it's broken
	if (coms.front().at(0) == "-")
	{
		cout << "ERROR: incorrect flags" << endl;

		//keep deleting from queue till the next command
		while (!is_connector(coms.front()))
		{
			coms.pop();
		}
		return true;
	}

	// if the first part of the path is a "/" remove it (that way it can't mess up)
	if(coms.front().at(0) == "/")
		commands.front().substr(1, commands.front().size() - 1);

	//make a new c_string to hold the file path
	char *filePath = new char[coms.front.size()];

	//copy it on over from the command vector
	strcpy(filePath, coms.front().c_str());
	command_v.push_back(filePath);

	//moving along
	coms.pop();

	//Did we use a bracket instead of "test"? If so get rid of the last bracket
	if(bracketUsed)
	{
		coms.pop();
	}

	//valuse for using the stat thingy
	int current_stat;

	//get the status of the command
	current_stat = stat(command_v.front(), &s_thing);

	//Did it fail?
	if(current_stat < 0)
	{
		//Yup it did
		perror("ERROR: Coudn't get the stat");
		return true;
	}
	//No it didn't so lets try out with "-e"
	if (flag == "-e")
	{
		return false;
	}

	//Try it out with "-f"
	if(flag == "-f")
	{
		if(S_ISREG(s_thing.st_mode))
		{
			return false
		} else
		{
			return true
		}
	}

	//Try it out with "-d"
	if (flag == "-d")
	{
		if (S_ISDIR(s_thing.st_mode))
		{
			return false;
		} else
		{
			return true
		}
	}
	//Obviously something went wrong if you got here
	return true
}*/

vector<Command> create_commands(const vector<string> &v)
{
    vector<Command> commandVector;
    Command temp;

    return commandVector;
}

<commit_msg>fixed part of the test function<commit_after>#include <iostream>
#include <cstdlib>
#include <vector>
#include <string>
#include <queue>
#include <sys/stat.h>

//getlogin() and gethostname().
#include <unistd.h>

//perror.
#include <stdio.h>

//fork,wait and execvp.
#include <sys/types.h>
#include <sys/wait.h>

//boost!
#include "boost/algorithm/string.hpp"
#include "boost/tokenizer.hpp"
#include "boost/foreach.hpp"

//that one class.
#include "Command.h"

using namespace std;
using namespace boost;

//execute command.
void execute(const vector<string> & s);

//replaces char in string.
void replace_char(string &s, char o, char r);

//takes a string and returns vector of parsed string.
vector<string> parseInput(string s);

//display vector.
template<typename unit>
void display_vector(vector<unit> v);

//helper function that finds amount of character.
int find_char_amount(const string s,char c);

//removes comment from input.
void remove_comment(string &s);

//removes char in string.
void remove_char(string &s, char c);

//checks if string passed in contains a flag
bool isFlag(string f);

//creates command types from vector of strings.
vector<Command> create_commands(const vector<string> &v);

int main()
{
    //grab the login.
    char* login = getlogin();

    //start a flag.
    bool login_check = true;

    if((!login) != 0)
    {
        //check flag.
        login_check = false;

        //output error.
        perror("Error: could not retrieve login name");
    }

    //hold c-string for host name.
    char host[150];

    //start another flag.
    bool host_check = true;

    //gets hostname while checking if it actually grabbed it.
    if(gethostname(host,sizeof(host)) != 0)
    {
        //check flag.
        host_check = false;

        //output error.
        perror("Error: could not rerieve host name.");
    }

    //warn user of upcoming trouble.
    if(login_check == false || host_check == false)
        cout << "Unable to display login and/or host information." << endl;

    //string to hold user input.
    string input;

    while(true)
    {
        //output login@hostname.
        if(login_check && host_check)
            cout << login << '@' << host << ' ';

        //bash money.
        cout << "$ ";

        //placeholder to tell its the program.
        cout << " (program) ";

        //geting input as a string.
        getline(cin,input);

        //remove extra white space.
        trim(input);

        //remove comments.
        remove_comment(input);

        //trim again just in case.
        trim(input);

        //testing parse.
        cout << "Testing parse" << endl;
        display_vector(parseInput(input));

        //execute command.
        execute(parseInput(input));

    }

    cout << "End of program" << endl;

    return 0;
}

void execute(const vector<string> &s)
{
    //check to see if user wants to quit and its the only command.
    if(s.size() == 1)
        for(unsigned int i = 0; i < s.size(); ++i)
            if(s.at(i) == "exit")
                exit(0);

    //c-string to hold command.
    char* args[2048];

    //place, remove comments and convert commands.
    for(unsigned int i = 0; i < s.size(); ++i)
    {
        string temp = s.at(i);
        remove_char(temp,'\"');
        args[i] = (char*)temp.c_str();
    }
    args[s.size()] = NULL;

    //creates fork process.
    pid_t pid = fork();

    if(pid == -1)
    {
        //fork didn't work.
        perror("fork");
    }
    if(pid ==0)
    {
        if(execvp(args[0], args) == -1)
        {
            //execute didn't work.
            perror("execvp");

            //break out of shadow realm.
            exit(1);
        }

    }
    if(pid > 0)
    {
        //wait for child to die.
        if(wait(0) == -1)
        {
            //didnt wait.
            perror("wait");
        }
    }

    return;
}

vector<string> parseInput(string s)
{

    //replace spaces.
    replace_char(s,' ','*');

    //make temp vector to hold parsed strings.
    vector<string> temp;

    //create boost magic function.
    char_separator<char> sep(" ;||&&(){}", ";||&&()[]",keep_empty_tokens);

    //create boost magic holder thingy.
    tokenizer< char_separator<char> > cm(s,sep);

    //for each loop to grab each peice and push it into a vector.
    for(tokenizer< char_separator<char> >::iterator it = cm.begin(); it != cm.end(); ++it)
        if(*it != "")
        {
            //fix string.
            string temp_string = *it;
            replace_char(temp_string,'*',' ');
            temp.push_back(temp_string);
        }

    //return that vector.
    return temp;
}

void replace_char(string &s, char o, char r)
{
    //different use for the function.
    if(o == '\"')
    {
        //nothing to replace.
        if(s.find(o) == string::npos)
            return;

        //replace.
        for(unsigned int i = 0; i < s.size(); ++i)
            if(s.at(i) == o)
                s.at(i) = r;

        return;

    }

    //no quotes.
    if(s.find("\"") == string::npos)
        return;
    else if(s.find(o) == string::npos)
        return;

    //vector to hold quote positions.
    vector<int> pos;

    //place positions of char into vector.
    for(unsigned int i = 0; i < s.size(); ++i)
        if(s.at(i) == '\"')
            pos.push_back(i);

    //count position.
    unsigned int count = 0;

    //replace.
    while(count < pos.size())
    {
        for(int i = pos.at(count); i < pos.at(count+1); ++i)
            if(s.at(i) == o)
                s.at(i) = r;

        count++;
        count++;
    }

    return;
}

template<typename unit>
void display_vector(vector<unit> v)
{
    for(unsigned int i = 0; i < v.size(); ++i)
        cout << i+1 << ": " << v.at(i) << endl;
    return;
}

void remove_comment(string &s)
{
    //just add a " to the end to avoid errors.
    if(find_char_amount(s,'\"') % 2 != 0)
        s += '\"';

    //delete everything!
    if(s.find("#") == 0)
    {
        s = "";
        return;
    }

    //return if no comments.
    if(s.find("#") == string::npos)
    {
        return;
    }

    //if no comments then deletes everything from hash forward.
    if(s.find("\"") == string::npos && s.find("#") != string::npos)
    {
        s = s.substr(0,s.find("#"));
        return;
    }

    //if comment before quote then delete.
    if(s.find("\"") > s.find("#"))
    {
        s = s.substr(0,s.find("#"));
        return;
    }

    //advanced situations.
    //get a vector to hold positions of quotes and hash.
    vector<int> quotePos;
    vector<int> hashPos;

    //grab pos.
    for(unsigned int i = 0; i < s.size(); ++i)
    {
        if(s.at(i) == '\"')
            quotePos.push_back(i);
        else if(s.at(i) == '#')
            hashPos.push_back(i);
    }

    //no comments or hash for some reason.
    if(hashPos.size() == 0 || quotePos.size() == 0)
        return;

    //just in case.
    if(quotePos.size() % 2 != 0)
        quotePos.push_back(0);

    //overall check;
    vector<bool> check;

    //start it up.
    for(unsigned int i = 0; i < hashPos.size(); ++i)
        check.push_back(true);

    //check if hash is in quotes.
    for(unsigned int i = 0; i < hashPos.size(); ++i )
        for(unsigned int j = 0; j < quotePos.size(); j+=2 )
        {
            if(hashPos.at(i) > quotePos.at(j) && hashPos.at(i) < quotePos.at(j+1))
            {
                check.at(i) = true;
                break;
            }
            else
                check.at(i) = false;
        }

    //check bool vector to delete string.
    for(unsigned int i = 0; i < check.size(); ++i)
        if(!check.at(i))
        {
            s = s.substr(0,hashPos.at(i));
            return;
        }

    //if comment at end then kill it.
    if(hashPos.at(hashPos.size()-1) > quotePos.at(quotePos.size()-1))
        s = s.substr(0,hashPos.at(hashPos.size()-1));

    return;
}

int find_char_amount(const string s, char c)
{
    if(s.find(c) == string::npos)
        return 0;

    int count = 0;
    for(unsigned int i = 0; i < s.size(); ++i)
        if(s.at(i) == c)
            count++;
    return count;

}

void remove_char(string &s, char c)
{
    //if not there then just return.
    if(s.find(c) == string::npos)
        return;

    //start empty.
    string temp = "";

    //add everything thats not what we dont want.
    for(unsigned int i = 0; i < s.size(); ++i)
        if(s.at(i) != c)
            temp += s.at(i);

    //transfer to s.
    s = temp;

    return;
}

int is_connector(string s)
{
    if(s == ";")
		return 1;
	if(s == "&&")
		return 2;
	if(s == "||")
		return 3;

	return -1;
}

bool isFlag(string f)
{	//default list of possible flags
	string flags = "-e -d -f";
	//see if string is one of the flags
	if (flags.find(f) != string::npos)
		return true;
	return false;
}

/*
bool test(vector<string> &commands, vector<strings> &command_list)
{
	//defaults to "-e"
	string flag = "-e";

	struct stat s_thing;

	//put everything into a queue for ease of use
	queue<string> coms;
	for (unsigned int i = 0; i < commands.size(); i++)
	{
		coms.push_back(commands.at(i));
	}

	//was a bracket used for the test command?
	bool bracketUsed = false;

	//set if a bracket was used
	if(coms.front() == "[";
		bracketUsed = true;

	//remove the first part of the command regardless of whether it's "test" or "["
	coms.pop();

	if (isTestFlag(coms.front()))
	{
		flag = coms.front();
		//now we have the flag for the test
		coms.pop()
	}

	//if there's another flag attempt then it's broken
	if (coms.front().at(0) == "-")
	{
		cout << "ERROR: incorrect flags" << endl;

		//keep deleting from queue till the next command
		while (!is_connector(coms.front()))
		{
			coms.pop();
		}
		return true;
	}

	// if the first part of the path is a "/" remove it (that way it can't mess up)
	if(coms.front().at(0) == "/")
		coms.front().substr(1, coms.front().size() - 1);

	//make a new c_string to hold the file path
	char *filePath = new char[coms.front.size()];

	//copy it on over from the command vector
	strcpy(filePath, coms.front().c_str());
	command_list.push_back(filePath);

	//moving along
	coms.pop();

	//Did we use a bracket instead of "test"? If so get rid of the last bracket
	if(bracketUsed)
	{
		coms.pop();
	}

	//valuse for using the stat thingy
	int current_stat;

	//get the status of the command
	current_stat = stat(command_list.front(), &s_thing);

	//Did it fail?
	if(current_stat < 0)
	{
		//Yup it did
		perror("ERROR: Coudn't get the stat");
		return true;
	}
	//No it didn't so lets try out with "-e"
	if (flag == "-e")
	{
		return false;
	}

	//Try it out with "-f"
	if(flag == "-f")
	{
		if(S_ISREG(s_thing.st_mode))
		{
			return false
		} else
		{
			return true
		}
	}

	//Try it out with "-d"
	if (flag == "-d")
	{
		if (S_ISDIR(s_thing.st_mode))
		{
			return false;
		} else
		{
			return true
		}
	}
	//Obviously something went wrong if you got here
	return true
}*/

vector<Command> create_commands(const vector<string> &v)
{
    vector<Command> commandVector;
    Command temp;

    return commandVector;
}

<|endoftext|>


<commit_before>//
//  main.cpp
//  Spin Wave Fit
//
//  Created by Hahn, Steven E. on 1/7/13.
//  Copyright (c) 2013 Oak Ridge National Laboratory. All rights reserved.
//
#define _USE_MATH_DEFINES
#include <cmath>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include "SpinWave.h"
#include "Initializer.h"
#include "Cell/Neighbors.h"
#include "PointsAlongLine.h"
#include "Positions.h"

using namespace boost;
using namespace std;

int main(int argc, char * argv[])
{

    //Init four_sl;
    Init four_sl("/Users/svh/Documents/spin_wave_genie/examples/MnV2O4_cubic.xml");
    SW_Builder builder = four_sl.get_builder();

    //cout << check << endl;

    /*Cell cell = four_sl.get_cell();

    string sl_r = "Mn0";
    string sl_s = "Mn1";
    double min = 0.0;
    double max = 7.0;

    Neighbors neighborList;
    neighborList.findNeighbors(cell,sl_r,sl_s,min,max);
    size_t z_rs = neighborList.getNumberNeighbors();

    cout << "z_rs= " << z_rs << endl;
    for(Neighbors::Iterator nbr=neighborList.begin();nbr!=neighborList.end();++nbr)
    {
        cout << (*nbr)[0] << " " << (*nbr)[1] << " " << (*nbr)[2] << endl;
    }*/

    SpinWave test = builder.Create_Element();

    double SA = 2.3;
    double SB = 0.9;
    double theta = M_PI - 35.0*M_PI/180.0;
    double DB = -6.62711;
    double JBB = -9.80542;
    double DBz = 0.073016;

    for(int dbi = 0; dbi != 1; dbi++)
    {
    double JBBP = 6.56457*(1.0+(double)dbi/50.0);
    double JAB = SB*((6.0*JBB+6.0*JBBP+DB-3.0*DBz)*cos(theta)*sin(theta) -sqrt(2.0)*DB*(2.0*pow(cos(theta),2)-1.0))/(-9.0*SA*sin(theta));
    cout << "JBBP= " << JBBP << " " << " JAB= " << JAB << endl;
    test.updateValue("Jbbp",JBBP);
    test.updateValue("Jab",JAB);

    std::cout << "hello world" << std::endl;

    PointsAlongLine Line;
    Line.setFirstPoint(1.0,1.0,0.0);
    Line.setFinalPoint(3.0,3.0,0.0);
    Line.setNumberPoints(11);
    Positions KPoints = Line.getPoints();

    for(Positions::Iterator it = KPoints.begin(); it != KPoints.end(); it++)
    {
        double x = it->get<0>();
        double y = it->get<1>();
        double z = it->get<2>();

        //cout << "Pos." << endl;
        cout << x << " " << y << " " << z << " ";// << endl;
        test.createMatrix(x,y,z);
        test.Calc();
        vector<point> pts = test.getPoints();
        //cout << "Freq.  Int." << endl;
        for(vector<point>::iterator it2 = pts.begin();it2!=pts.end();it2++)
        {
            cout << (*it2).frequency << "  " << (*it2).intensity*10.0 << " " ;//<< endl;
        }
        cout << endl;
    }
    }
    return 0;
}
<commit_msg>cleaned up dispersion code<commit_after>//
//  main.cpp
//  Spin Wave Fit
//
//  Created by Hahn, Steven E. on 1/7/13.
//  Copyright (c) 2013 Oak Ridge National Laboratory. All rights reserved.
//
#define _USE_MATH_DEFINES
#include <cmath>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include "SpinWave.h"
#include "Initializer.h"
#include "Cell/Neighbors.h"
#include "PointsAlongLine.h"
#include "Positions.h"

using namespace boost;
using namespace std;

int main(int argc, char * argv[])
{

    //Init four_sl;
    Init four_sl("/Users/svh/Documents/spin_wave_genie/examples/MnV2O4_cubic.xml");

    //cout << check << endl;

    Cell cell = four_sl.get_cell();

    string sl_r = "Mn0";
    string sl_s = "Mn1";
    double min = 0.0;
    double max = 7.0;

    Neighbors neighborList;
    neighborList.findNeighbors(cell,sl_r,sl_s,min,max);
    size_t z_rs = neighborList.getNumberNeighbors();

    cout << "z_rs= " << z_rs << endl;
    for(Neighbors::Iterator nbr=neighborList.begin();nbr!=neighborList.end();++nbr)
    {
        cout << (*nbr)[0] << " " << (*nbr)[1] << " " << (*nbr)[2] << endl;
    }

    SW_Builder builder = four_sl.get_builder();
    SpinWave test = builder.Create_Element();

    PointsAlongLine Line;
    Line.setFirstPoint(1.0,1.0,0.0);
    Line.setFinalPoint(3.0,3.0,0.0);
    Line.setNumberPoints(11);
    Positions KPoints = Line.getPoints();

    for(Positions::Iterator it = KPoints.begin(); it != KPoints.end(); it++)
    {
        double x = it->get<0>();
        double y = it->get<1>();
        double z = it->get<2>();

        //cout << "Pos." << endl;
        cout << x << " " << y << " " << z << " ";// << endl;
        test.createMatrix(x,y,z);
        test.Calc();
        vector<point> pts = test.getPoints();
        //cout << "Freq.  Int." << endl;
        for(vector<point>::iterator it2 = pts.begin();it2!=pts.end();it2++)
        {
            cout << (*it2).frequency << "  " << (*it2).intensity*10.0 << " " ;//<< endl;
        }
        cout << endl;
    }
    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2019-present ScyllaDB
 */

/*
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

#include "leveled_compaction_strategy.hh"
#include "leveled_manifest.hh"
#include <algorithm>

#include <boost/range/algorithm/remove_if.hpp>

namespace sstables {

compaction_descriptor leveled_compaction_strategy::get_sstables_for_compaction(table_state& table_s, strategy_control& control, std::vector<sstables::shared_sstable> candidates) {
    // NOTE: leveled_manifest creation may be slightly expensive, so later on,
    // we may want to store it in the strategy itself. However, the sstable
    // lists managed by the manifest may become outdated. For example, one
    // sstable in it may be marked for deletion after compacted.
    // Currently, we create a new manifest whenever it's time for compaction.
    leveled_manifest manifest = leveled_manifest::create(table_s, candidates, _max_sstable_size_in_mb, _stcs_options);
    if (!_last_compacted_keys) {
        generate_last_compacted_keys(manifest);
    }
    auto candidate = manifest.get_compaction_candidates(*_last_compacted_keys, _compaction_counter);

    if (!candidate.sstables.empty()) {
        leveled_manifest::logger.debug("leveled: Compacting {} out of {} sstables", candidate.sstables.size(), table_s.get_sstable_set().all()->size());
        return candidate;
    }

    // if there is no sstable to compact in standard way, try compacting based on droppable tombstone ratio
    // unlike stcs, lcs can look for sstable with highest droppable tombstone ratio, so as not to choose
    // a sstable which droppable data shadow data in older sstable, by starting from highest levels which
    // theoretically contain oldest non-overlapping data.
    auto compaction_time = gc_clock::now();
    for (auto level = int(manifest.get_level_count()); level >= 0; level--) {
        auto& sstables = manifest.get_level(level);
        // filter out sstables which droppable tombstone ratio isn't greater than the defined threshold.
        auto e = boost::range::remove_if(sstables, [this, compaction_time] (const sstables::shared_sstable& sst) -> bool {
            return !worth_dropping_tombstones(sst, compaction_time);
        });
        sstables.erase(e, sstables.end());
        if (sstables.empty()) {
            continue;
        }
        auto& sst = *std::max_element(sstables.begin(), sstables.end(), [&] (auto& i, auto& j) {
            auto gc_before1 = i->get_gc_before_for_drop_estimation(compaction_time);
            auto gc_before2 = j->get_gc_before_for_drop_estimation(compaction_time);
            return i->estimate_droppable_tombstone_ratio(gc_before1) < j->estimate_droppable_tombstone_ratio(gc_before2);
        });
        return sstables::compaction_descriptor({ sst }, service::get_local_compaction_priority(), sst->get_sstable_level());
    }
    return {};
}

compaction_descriptor leveled_compaction_strategy::get_major_compaction_job(table_state& table_s, std::vector<sstables::shared_sstable> candidates) {
    if (candidates.empty()) {
        return compaction_descriptor();
    }

    auto& sst = *std::max_element(candidates.begin(), candidates.end(), [&] (sstables::shared_sstable& sst1, sstables::shared_sstable& sst2) {
        return sst1->get_sstable_level() < sst2->get_sstable_level();
    });
    return compaction_descriptor(std::move(candidates), service::get_local_compaction_priority(),
                                 sst->get_sstable_level(), _max_sstable_size_in_mb*1024*1024);
}

void leveled_compaction_strategy::notify_completion(const std::vector<shared_sstable>& removed, const std::vector<shared_sstable>& added) {
    if (removed.empty() || added.empty()) {
        return;
    }
    auto min_level = std::numeric_limits<uint32_t>::max();
    for (auto& sstable : removed) {
        min_level = std::min(min_level, sstable->get_sstable_level());
    }

    const sstables::sstable *last = nullptr;
    int target_level = 0;
    for (auto& candidate : added) {
        if (!last || last->compare_by_first_key(*candidate) < 0) {
            last = &*candidate;
        }
        target_level = std::max(target_level, int(candidate->get_sstable_level()));
    }
    _last_compacted_keys.value().at(min_level) = last->get_last_decorated_key();

    for (int i = leveled_manifest::MAX_LEVELS - 1; i > 0; i--) {
        _compaction_counter[i]++;
    }
    _compaction_counter[target_level] = 0;

    if (leveled_manifest::logger.level() == logging::log_level::debug) {
        for (auto j = 0U; j < _compaction_counter.size(); j++) {
            leveled_manifest::logger.debug("CompactionCounter: {}: {}", j, _compaction_counter[j]);
        }
    }
}

void leveled_compaction_strategy::generate_last_compacted_keys(leveled_manifest& manifest) {
    std::vector<std::optional<dht::decorated_key>> last_compacted_keys(leveled_manifest::MAX_LEVELS);
    for (auto i = 0; i < leveled_manifest::MAX_LEVELS - 1; i++) {
        if (manifest.get_level(i + 1).empty()) {
            continue;
        }

        const sstables::sstable* sstable_with_last_compacted_key = nullptr;
        std::optional<db_clock::time_point> max_creation_time;
        for (auto& sst : manifest.get_level(i + 1)) {
            auto wtime = sst->data_file_write_time();
            if (!max_creation_time || wtime >= *max_creation_time) {
                sstable_with_last_compacted_key = &*sst;
                max_creation_time = wtime;
            }
        }
        last_compacted_keys[i] = sstable_with_last_compacted_key->get_last_decorated_key();
    }
    _last_compacted_keys = std::move(last_compacted_keys);
}

int64_t leveled_compaction_strategy::estimated_pending_compactions(table_state& table_s) const {
    std::vector<sstables::shared_sstable> sstables;
    auto all_sstables = table_s.get_sstable_set().all();
    sstables.reserve(all_sstables->size());
    for (auto& entry : *all_sstables) {
        sstables.push_back(entry);
    }
    return leveled_manifest::get_estimated_tasks(leveled_manifest::get_levels(sstables), _max_sstable_size_in_mb * 1024 * 1024);
}

compaction_descriptor
leveled_compaction_strategy::get_reshaping_job(std::vector<shared_sstable> input, schema_ptr schema, const ::io_priority_class& iop, reshape_mode mode) {
    std::array<std::vector<shared_sstable>, leveled_manifest::MAX_LEVELS> level_info;

    auto is_disjoint = [this, schema] (const std::vector<shared_sstable>& sstables, unsigned tolerance) -> std::tuple<bool, unsigned> {
        auto overlapping_sstables = sstable_set_overlapping_count(schema, sstables);
        return { overlapping_sstables <= tolerance, overlapping_sstables };
    };

    auto max_sstable_size_in_bytes = _max_sstable_size_in_mb * 1024 * 1024;

    for (auto& sst : input) {
        auto sst_level = sst->get_sstable_level();
        if (sst_level > leveled_manifest::MAX_LEVELS - 1) {
            leveled_manifest::logger.warn("Found SSTable with level {}, higher than the maximum {}. This is unexpected, but will fix", sst_level, leveled_manifest::MAX_LEVELS - 1);

            // This is really unexpected, so we'll just compact it all to fix it
            compaction_descriptor desc(std::move(input), iop, leveled_manifest::MAX_LEVELS - 1, max_sstable_size_in_bytes);
            desc.options = compaction_type_options::make_reshape();
            return desc;
        }
        level_info[sst_level].push_back(sst);
    }

    // Can't use std::ranges::views::drop due to https://bugs.llvm.org/show_bug.cgi?id=47509
    for (auto i = level_info.begin(); i != level_info.end(); ++i) {
        auto& level = *i;
        std::sort(level.begin(), level.end(), [&schema] (const shared_sstable& a, const shared_sstable& b) {
            return dht::ring_position(a->get_first_decorated_key()).less_compare(*schema, dht::ring_position(b->get_first_decorated_key()));
        });
    }

    unsigned max_filled_level = 0;

    size_t offstrategy_threshold = (mode == reshape_mode::strict) ? std::max(schema->min_compaction_threshold(), 4) : std::max(schema->max_compaction_threshold(), 32);
    size_t max_sstables = std::max(schema->max_compaction_threshold(), int(offstrategy_threshold));
    auto tolerance = [mode] (unsigned level) -> unsigned {
        if (mode == reshape_mode::strict) {
            return 0;
        }
        constexpr unsigned fan_out = leveled_manifest::leveled_fan_out;
        return std::max(double(fan_out), std::ceil(std::pow(fan_out, level) * 0.1));
    };

    // If there's only disjoint L0 sstables like on bootstrap, let's compact them all into a level L which has capacity to store the output.
    // The best possible level can be calculated with the formula: log (base fan_out) of (L0_total_bytes / max_sstable_size)
    auto [l0_disjoint, _] = is_disjoint(level_info[0], 0);
    if (mode == reshape_mode::strict && level_info[0].size() >= offstrategy_threshold && level_info[0].size() == input.size() && l0_disjoint) {
        auto log_fanout = [fanout = leveled_manifest::leveled_fan_out] (double x) {
            double inv_log_fanout = 1.0f / std::log(fanout);
            return log(x) * inv_log_fanout;
        };

        auto total_bytes = std::max(leveled_manifest::get_total_bytes(level_info[0]), uint64_t(max_sstable_size_in_bytes));
        unsigned ideal_level = std::ceil(log_fanout(total_bytes / max_sstable_size_in_bytes));

        leveled_manifest::logger.info("Reshaping {} disjoint sstables in level 0 into level {}", level_info[0].size(), ideal_level);
        compaction_descriptor desc(std::move(input), iop, ideal_level, max_sstable_size_in_bytes);
        desc.options = compaction_type_options::make_reshape();
        return desc;
    }

    if (level_info[0].size() > offstrategy_threshold) {
        size_tiered_compaction_strategy stcs(_stcs_options);
        return stcs.get_reshaping_job(std::move(level_info[0]), schema, iop, mode);
    }

    for (unsigned level = leveled_manifest::MAX_LEVELS - 1; level > 0; --level) {
        if (level_info[level].empty()) {
            continue;
        }
        max_filled_level = std::max(max_filled_level, level);

        auto [disjoint, overlapping_sstables] = is_disjoint(level_info[level], tolerance(level));
        if (!disjoint) {
            leveled_manifest::logger.warn("Turns out that level {} is not disjoint, found {} overlapping SSTables, so compacting everything on behalf of {}.{}", level, overlapping_sstables, schema->ks_name(), schema->cf_name());
            // Unfortunately no good limit to limit input size to max_sstables for LCS major
            compaction_descriptor desc(std::move(input), iop, max_filled_level, max_sstable_size_in_bytes);
            desc.options = compaction_type_options::make_reshape();
            return desc;
        }
    }

   return compaction_descriptor();
}

std::vector<compaction_descriptor>
leveled_compaction_strategy::get_cleanup_compaction_jobs(table_state& table_s, std::vector<shared_sstable> candidates) const {
    std::vector<compaction_descriptor> ret;

    auto levels = leveled_manifest::get_levels(candidates);

    ret = size_tiered_compaction_strategy(_stcs_options).get_cleanup_compaction_jobs(table_s, std::move(levels[0]));
    for (size_t level = 1; level < levels.size(); level++) {
        if (levels[level].empty()) {
            continue;
        }
        ret.push_back(compaction_descriptor(std::move(levels[level]), service::get_local_compaction_priority(), level, _max_sstable_size_in_mb * 1024 * 1024));
    }
    return ret;
}

}
<commit_msg>compaction: LCS: Fix off-by-one in formula used to calculate ideal level<commit_after>/*
 * Copyright (C) 2019-present ScyllaDB
 */

/*
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

#include "leveled_compaction_strategy.hh"
#include "leveled_manifest.hh"
#include <algorithm>

#include <boost/range/algorithm/remove_if.hpp>

namespace sstables {

compaction_descriptor leveled_compaction_strategy::get_sstables_for_compaction(table_state& table_s, strategy_control& control, std::vector<sstables::shared_sstable> candidates) {
    // NOTE: leveled_manifest creation may be slightly expensive, so later on,
    // we may want to store it in the strategy itself. However, the sstable
    // lists managed by the manifest may become outdated. For example, one
    // sstable in it may be marked for deletion after compacted.
    // Currently, we create a new manifest whenever it's time for compaction.
    leveled_manifest manifest = leveled_manifest::create(table_s, candidates, _max_sstable_size_in_mb, _stcs_options);
    if (!_last_compacted_keys) {
        generate_last_compacted_keys(manifest);
    }
    auto candidate = manifest.get_compaction_candidates(*_last_compacted_keys, _compaction_counter);

    if (!candidate.sstables.empty()) {
        leveled_manifest::logger.debug("leveled: Compacting {} out of {} sstables", candidate.sstables.size(), table_s.get_sstable_set().all()->size());
        return candidate;
    }

    // if there is no sstable to compact in standard way, try compacting based on droppable tombstone ratio
    // unlike stcs, lcs can look for sstable with highest droppable tombstone ratio, so as not to choose
    // a sstable which droppable data shadow data in older sstable, by starting from highest levels which
    // theoretically contain oldest non-overlapping data.
    auto compaction_time = gc_clock::now();
    for (auto level = int(manifest.get_level_count()); level >= 0; level--) {
        auto& sstables = manifest.get_level(level);
        // filter out sstables which droppable tombstone ratio isn't greater than the defined threshold.
        auto e = boost::range::remove_if(sstables, [this, compaction_time] (const sstables::shared_sstable& sst) -> bool {
            return !worth_dropping_tombstones(sst, compaction_time);
        });
        sstables.erase(e, sstables.end());
        if (sstables.empty()) {
            continue;
        }
        auto& sst = *std::max_element(sstables.begin(), sstables.end(), [&] (auto& i, auto& j) {
            auto gc_before1 = i->get_gc_before_for_drop_estimation(compaction_time);
            auto gc_before2 = j->get_gc_before_for_drop_estimation(compaction_time);
            return i->estimate_droppable_tombstone_ratio(gc_before1) < j->estimate_droppable_tombstone_ratio(gc_before2);
        });
        return sstables::compaction_descriptor({ sst }, service::get_local_compaction_priority(), sst->get_sstable_level());
    }
    return {};
}

compaction_descriptor leveled_compaction_strategy::get_major_compaction_job(table_state& table_s, std::vector<sstables::shared_sstable> candidates) {
    if (candidates.empty()) {
        return compaction_descriptor();
    }

    auto& sst = *std::max_element(candidates.begin(), candidates.end(), [&] (sstables::shared_sstable& sst1, sstables::shared_sstable& sst2) {
        return sst1->get_sstable_level() < sst2->get_sstable_level();
    });
    return compaction_descriptor(std::move(candidates), service::get_local_compaction_priority(),
                                 sst->get_sstable_level(), _max_sstable_size_in_mb*1024*1024);
}

void leveled_compaction_strategy::notify_completion(const std::vector<shared_sstable>& removed, const std::vector<shared_sstable>& added) {
    if (removed.empty() || added.empty()) {
        return;
    }
    auto min_level = std::numeric_limits<uint32_t>::max();
    for (auto& sstable : removed) {
        min_level = std::min(min_level, sstable->get_sstable_level());
    }

    const sstables::sstable *last = nullptr;
    int target_level = 0;
    for (auto& candidate : added) {
        if (!last || last->compare_by_first_key(*candidate) < 0) {
            last = &*candidate;
        }
        target_level = std::max(target_level, int(candidate->get_sstable_level()));
    }
    _last_compacted_keys.value().at(min_level) = last->get_last_decorated_key();

    for (int i = leveled_manifest::MAX_LEVELS - 1; i > 0; i--) {
        _compaction_counter[i]++;
    }
    _compaction_counter[target_level] = 0;

    if (leveled_manifest::logger.level() == logging::log_level::debug) {
        for (auto j = 0U; j < _compaction_counter.size(); j++) {
            leveled_manifest::logger.debug("CompactionCounter: {}: {}", j, _compaction_counter[j]);
        }
    }
}

void leveled_compaction_strategy::generate_last_compacted_keys(leveled_manifest& manifest) {
    std::vector<std::optional<dht::decorated_key>> last_compacted_keys(leveled_manifest::MAX_LEVELS);
    for (auto i = 0; i < leveled_manifest::MAX_LEVELS - 1; i++) {
        if (manifest.get_level(i + 1).empty()) {
            continue;
        }

        const sstables::sstable* sstable_with_last_compacted_key = nullptr;
        std::optional<db_clock::time_point> max_creation_time;
        for (auto& sst : manifest.get_level(i + 1)) {
            auto wtime = sst->data_file_write_time();
            if (!max_creation_time || wtime >= *max_creation_time) {
                sstable_with_last_compacted_key = &*sst;
                max_creation_time = wtime;
            }
        }
        last_compacted_keys[i] = sstable_with_last_compacted_key->get_last_decorated_key();
    }
    _last_compacted_keys = std::move(last_compacted_keys);
}

int64_t leveled_compaction_strategy::estimated_pending_compactions(table_state& table_s) const {
    std::vector<sstables::shared_sstable> sstables;
    auto all_sstables = table_s.get_sstable_set().all();
    sstables.reserve(all_sstables->size());
    for (auto& entry : *all_sstables) {
        sstables.push_back(entry);
    }
    return leveled_manifest::get_estimated_tasks(leveled_manifest::get_levels(sstables), _max_sstable_size_in_mb * 1024 * 1024);
}

compaction_descriptor
leveled_compaction_strategy::get_reshaping_job(std::vector<shared_sstable> input, schema_ptr schema, const ::io_priority_class& iop, reshape_mode mode) {
    std::array<std::vector<shared_sstable>, leveled_manifest::MAX_LEVELS> level_info;

    auto is_disjoint = [this, schema] (const std::vector<shared_sstable>& sstables, unsigned tolerance) -> std::tuple<bool, unsigned> {
        auto overlapping_sstables = sstable_set_overlapping_count(schema, sstables);
        return { overlapping_sstables <= tolerance, overlapping_sstables };
    };

    auto max_sstable_size_in_bytes = _max_sstable_size_in_mb * 1024 * 1024;

    for (auto& sst : input) {
        auto sst_level = sst->get_sstable_level();
        if (sst_level > leveled_manifest::MAX_LEVELS - 1) {
            leveled_manifest::logger.warn("Found SSTable with level {}, higher than the maximum {}. This is unexpected, but will fix", sst_level, leveled_manifest::MAX_LEVELS - 1);

            // This is really unexpected, so we'll just compact it all to fix it
            compaction_descriptor desc(std::move(input), iop, leveled_manifest::MAX_LEVELS - 1, max_sstable_size_in_bytes);
            desc.options = compaction_type_options::make_reshape();
            return desc;
        }
        level_info[sst_level].push_back(sst);
    }

    // Can't use std::ranges::views::drop due to https://bugs.llvm.org/show_bug.cgi?id=47509
    for (auto i = level_info.begin(); i != level_info.end(); ++i) {
        auto& level = *i;
        std::sort(level.begin(), level.end(), [&schema] (const shared_sstable& a, const shared_sstable& b) {
            return dht::ring_position(a->get_first_decorated_key()).less_compare(*schema, dht::ring_position(b->get_first_decorated_key()));
        });
    }

    unsigned max_filled_level = 0;

    size_t offstrategy_threshold = (mode == reshape_mode::strict) ? std::max(schema->min_compaction_threshold(), 4) : std::max(schema->max_compaction_threshold(), 32);
    size_t max_sstables = std::max(schema->max_compaction_threshold(), int(offstrategy_threshold));
    auto tolerance = [mode] (unsigned level) -> unsigned {
        if (mode == reshape_mode::strict) {
            return 0;
        }
        constexpr unsigned fan_out = leveled_manifest::leveled_fan_out;
        return std::max(double(fan_out), std::ceil(std::pow(fan_out, level) * 0.1));
    };

    // If there's only disjoint L0 sstables like on bootstrap, let's compact them all into a level L which has capacity to store the output.
    // The best possible level can be calculated with the formula: log (base fan_out) of (L0_total_bytes / max_sstable_size)
    auto [l0_disjoint, _] = is_disjoint(level_info[0], 0);
    if (mode == reshape_mode::strict && level_info[0].size() >= offstrategy_threshold && level_info[0].size() == input.size() && l0_disjoint) {
        auto log_fanout = [fanout = leveled_manifest::leveled_fan_out] (double x) {
            double inv_log_fanout = 1.0f / std::log(fanout);
            return log(x) * inv_log_fanout;
        };

        auto total_bytes = std::max(leveled_manifest::get_total_bytes(level_info[0]), uint64_t(max_sstable_size_in_bytes));
        unsigned ideal_level = std::ceil(log_fanout((total_bytes + max_sstable_size_in_bytes - 1) / max_sstable_size_in_bytes));

        leveled_manifest::logger.info("Reshaping {} disjoint sstables in level 0 into level {}", level_info[0].size(), ideal_level);
        compaction_descriptor desc(std::move(input), iop, ideal_level, max_sstable_size_in_bytes);
        desc.options = compaction_type_options::make_reshape();
        return desc;
    }

    if (level_info[0].size() > offstrategy_threshold) {
        size_tiered_compaction_strategy stcs(_stcs_options);
        return stcs.get_reshaping_job(std::move(level_info[0]), schema, iop, mode);
    }

    for (unsigned level = leveled_manifest::MAX_LEVELS - 1; level > 0; --level) {
        if (level_info[level].empty()) {
            continue;
        }
        max_filled_level = std::max(max_filled_level, level);

        auto [disjoint, overlapping_sstables] = is_disjoint(level_info[level], tolerance(level));
        if (!disjoint) {
            leveled_manifest::logger.warn("Turns out that level {} is not disjoint, found {} overlapping SSTables, so compacting everything on behalf of {}.{}", level, overlapping_sstables, schema->ks_name(), schema->cf_name());
            // Unfortunately no good limit to limit input size to max_sstables for LCS major
            compaction_descriptor desc(std::move(input), iop, max_filled_level, max_sstable_size_in_bytes);
            desc.options = compaction_type_options::make_reshape();
            return desc;
        }
    }

   return compaction_descriptor();
}

std::vector<compaction_descriptor>
leveled_compaction_strategy::get_cleanup_compaction_jobs(table_state& table_s, std::vector<shared_sstable> candidates) const {
    std::vector<compaction_descriptor> ret;

    auto levels = leveled_manifest::get_levels(candidates);

    ret = size_tiered_compaction_strategy(_stcs_options).get_cleanup_compaction_jobs(table_s, std::move(levels[0]));
    for (size_t level = 1; level < levels.size(); level++) {
        if (levels[level].empty()) {
            continue;
        }
        ret.push_back(compaction_descriptor(std::move(levels[level]), service::get_local_compaction_priority(), level, _max_sstable_size_in_mb * 1024 * 1024));
    }
    return ret;
}

}
<|endoftext|>


<commit_before>
// Copyright **********************************************************
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 2003
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright ******************************************************

//--------------------------------------------------------------------
// Includes
//--------------------------------------------------------------------
#include <string.h>
#include <stdio.h>
#include <ctype.h>

#include <ecmdClientCapi.H>
#include <ecmdDataBuffer.H>
#include <ecmdReturnCodes.H>
#include <ecmdUtils.H>
#include <ecmdClientPerlapi.H>
#include <ecmdSharedUtils.H>

static int myErrorCode = ECMD_SUCCESS;

int ecmdPerlInterfaceErrorCheck (int errorCode) {

  if (errorCode == -1) {
    errorCode = myErrorCode;
    myErrorCode = ECMD_SUCCESS;

    if (errorCode != ECMD_SUCCESS) {
      ::ecmdOutputError( (::ecmdGetErrorMsg(errorCode) + "\n").c_str());
    }

    return errorCode;
  }
  else if (errorCode != ECMD_SUCCESS) {
    myErrorCode = errorCode;
  }

  return ECMD_SUCCESS;
}

ecmdClientPerlapi::ecmdClientPerlapi () {
  perlFormat = "b";

}

ecmdClientPerlapi::~ecmdClientPerlapi () {

  this->cleanup();
}

void ecmdClientPerlapi::cleanup()  {
  ecmdUnloadDll();
}

int ecmdClientPerlapi::initDll (const char * i_dllName, const char * i_options) {

  int rc = ECMD_SUCCESS;
  std::string dllName = "";
  if (i_dllName != NULL) {
    dllName = i_dllName;
  }

  rc = ecmdLoadDll(dllName);
  ecmdPerlInterfaceErrorCheck(rc);

  return rc;

}

int ecmdClientPerlapi::getScom (const char* i_target, int i_address, char** o_data) {

  ecmdChipTarget myTarget;
  std::string dataStr;

  int rc = setupTarget(i_target, myTarget);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) {
    *o_data = NULL;
    return rc;
  }

  ecmdDataBuffer buffer;
  rc = ::getScom(myTarget, i_address, buffer);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) {
    o_data = NULL;
    return rc;
  }

  dataStr = buffer.genBinStr();

  char* tmp;
  tmp = new char[dataStr.length()+1];
  strcpy(tmp,dataStr.c_str());
  *o_data = tmp;

  return rc;
}

int ecmdClientPerlapi::putScom (const char * i_target, int i_address, const char * i_data) {

  ecmdChipTarget myTarget;

  int rc = setupTarget(i_target, myTarget);
  if (rc) return rc;

  ecmdDataBuffer buffer;

  buffer.setBitLength(strlen(i_data));
  rc = buffer.insertFromBin(i_data);

  rc = ::putScom(myTarget, i_address, buffer);

  ecmdPerlInterfaceErrorCheck(rc);
  return rc;
}

int ecmdClientPerlapi::getRing (const char * i_target, const char * i_ringName, char **o_data) {

  int rc = 0;
  ecmdDataBuffer buffer;
  ecmdChipTarget myTarget;
  std::string dataStr;

  rc = setupTarget(i_target, myTarget);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) return rc;

  rc = ::getRing(myTarget, i_ringName, buffer);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) return rc;

  dataStr = buffer.genBinStr();

  char* tmp;
  tmp = new char[dataStr.length()+1];
  strcpy(tmp,dataStr.c_str());
  *o_data = tmp;

  return rc;
}

int ecmdClientPerlapi::putRing (const char * i_target, const char * i_ringName, const char * i_data) {

  ecmdChipTarget myTarget;

  int rc = setupTarget(i_target, myTarget);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) return rc;

  ecmdDataBuffer buffer;

  buffer.setBitLength(strlen(i_data));
  rc = buffer.insertFromBin(i_data);

  rc = ::putRing(myTarget, i_ringName, buffer);

  ecmdPerlInterfaceErrorCheck(rc);
  return rc;
}

/***
void ecmdClientPerlapi::add(char *retval) {
  printf("Inside function: %c %c %c\n",retval[0],retval[1],retval[2]);

  retval[0] = 'L'; retval[1] = 'p';

 strcpy(retval,"Looky here - I made it");
}

void ecmdClientPerlapi::add2(char **retval) {
  printf("Inside function: %s\n",*retval);

  *retval = (char*)malloc(sizeof (char[100]));
  strcpy(*retval,"Looky here - I made it");
}
***/

int ecmdClientPerlapi::setupTarget (const char * i_targetStr, ecmdChipTarget & o_target) {

  int rc = ECMD_SUCCESS;
  std::string printed;
  if (i_targetStr == NULL) {
    ecmdOutputError("ecmdClientPerlapi::setupTarget - It appears the target string is null\n");
    return ECMD_INVALID_ARGS;
  }
  std::vector<std::string> tokens;

  ecmdParseTokens(i_targetStr, " ,.", tokens);

  /* Set our initial states */
  o_target.cage = o_target.node = o_target.slot = o_target.pos = o_target.core = o_target.thread = 0;
  o_target.cageState = o_target.nodeState = o_target.slotState = o_target.posState = o_target.coreState = o_target.threadState = ECMD_TARGET_FIELD_VALID;
  o_target.chipTypeState = ECMD_TARGET_FIELD_UNUSED;

  for (std::vector<std::string>::iterator tokit = tokens.begin(); tokit != tokens.end(); tokit ++) {
    if ((*tokit)[0] == '-') {
      switch((*tokit)[1]) {
        case 'k': case 'K':
          o_target.cage = atoi(tokit->substr(2,20).c_str());
          break;
        case 'n': case 'N':
          o_target.node = atoi(tokit->substr(2,20).c_str());
          break;
        case 's': case 'S':
          o_target.slot = atoi(tokit->substr(2,20).c_str());
          break;
        case 'p': case 'P':
          o_target.pos = atoi(tokit->substr(2,20).c_str());
          break;
        case 'c': case 'C':
          o_target.core = atoi(tokit->substr(2,20).c_str());
          break;
        case 't': case 'T':
          o_target.thread = atoi(tokit->substr(2,20).c_str());
          break;
        default:
          ecmdOutputError((((printed = "ecmdClientPerlapi::setupTarget - It appears the target string contained an invalid target parm : ") + i_targetStr) + "\n").c_str());
          return ECMD_INVALID_ARGS;

      }
    } else {
      /* If the first char is a digit then they must have specified a p1..3 or p1,4 and we tokenized it above, this is not good */
      if (isdigit((*tokit)[0])) {
        ecmdOutputError((((printed = "ecmdClientPerlapi::setupTarget - It appears the target string contained a range or multiple positions : ") + i_targetStr) + "\n").c_str());
        return ECMD_INVALID_ARGS;
      } else if (o_target.chipTypeState == ECMD_TARGET_FIELD_VALID) {
        ecmdOutputError((((printed = "ecmdClientPerlapi::setupTarget - It appears the target string contained multiple chip names : ") + i_targetStr) + "\n").c_str());
        return ECMD_INVALID_ARGS;
      }
      o_target.chipTypeState = ECMD_TARGET_FIELD_VALID;
      o_target.chipType = *tokit;
    }
  }

  return rc;
}

int ecmdClientPerlapi::ecmdCommandArgs(char** i_argv[]){

  return 0;
}

/***
int ecmdClientPerlapi::ecmdCommandArgs(int* i_argc, char** i_argv[]) {

  return 0;
}

***/
int ecmdClientPerlapi::sendCmd(const char* i_target, int i_instruction, int i_modifier, char** o_status) {

  return 0;
}

int ecmdClientPerlapi::getCfamRegister (const char* i_target, int i_address, char** o_data){

  return 0;
}

int ecmdClientPerlapi::putCfamRegister (const char* i_target, int i_address, const char* i_data){

  return 0;
}

int ecmdClientPerlapi::getSpy (const char* i_target, const char * i_spyName, char** o_data){

  return 0;
}

int ecmdClientPerlapi::getSpyEnum (const char* i_target, const char * i_spyName, char** o_enumValue){

  return 0;
}

int ecmdClientPerlapi::getSpyEccGrouping (const char* i_target, const char * i_spyEccGroupName, char** o_groupData, char** o_eccData, char** o_eccErrorMask){

  return 0;
}

int ecmdClientPerlapi::putSpy (const char* i_target, const char * i_spyName, const char* i_data){

  return 0;
}

int ecmdClientPerlapi::putSpyEnum (const char* i_target, const char * i_spyName, const char* i_enumValue){

  return 0;
}

void ecmdClientPerlapi::ecmdEnableRingCache(){

  return ;
}

int  ecmdClientPerlapi::ecmdDisableRingCache(){

  return 0;
}

int  ecmdClientPerlapi::ecmdFlushRingCache(){

  return 0;
}

int ecmdClientPerlapi::getArray (const char* i_target, const char * i_arrayName, const char* i_address, char** o_data){

  return 0;
}

int ecmdClientPerlapi::putArray (const char* i_target, const char * i_arrayName, const char* i_address, const char* i_data){

  return 0;
}

int ecmdClientPerlapi::simaet(const char* i_function){

  return 0;
}

int ecmdClientPerlapi::simcheckpoint(const char* i_checkpoint){

  return 0;
}

int ecmdClientPerlapi::simclock(int i_cycles){

  return 0;
}

int ecmdClientPerlapi::simecho(const char* i_message){

  return 0;
}

int ecmdClientPerlapi::simexit(){

  return 0;
}

int ecmdClientPerlapi::simEXPECTFAC(const char* i_facname, int i_bitlength, const char* i_expect, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simexpecttcfac(const char* i_tcfacname, int i_bitlength, const char* i_expect, int i_row){

  return 0;
}

int ecmdClientPerlapi::simgetcurrentcycle(char** o_cyclecount){

  return 0;
}

int ecmdClientPerlapi::simGETFAC(const char* i_facname, int i_bitlength, char** o_data, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simGETFACX(const char* i_facname, int i_bitlength, char** o_data, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simgettcfac(const char* i_tcfacname, char** o_data, int i_row, int i_startbit, int i_bitlength){

  return 0;
}

int ecmdClientPerlapi::siminit(const char* i_checkpoint){

  return 0;
}

int ecmdClientPerlapi::simPUTFAC(const char* i_facname, int i_bitlength, const char* i_data, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simPUTFACX(const char* i_facname, int i_bitlength, const char* i_data, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simputtcfac(const char* i_tcfacname, int i_bitlength, const char* i_data, int i_row, int i_numrows){

  return 0;
}

int ecmdClientPerlapi::simrestart(const char* i_checkpoint){

  return 0;
}

int ecmdClientPerlapi::simSTKFAC(const char* i_facname, int i_bitlength, const char* i_data, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simstktcfac(const char* i_tcfacname, int i_bitlength, const char* i_data, int i_row, int i_numrows){

  return 0;
}

int ecmdClientPerlapi::simSUBCMD(const char* i_command){

  return 0;
}

int ecmdClientPerlapi::simtckinterval(int i_tckinterval){

  return 0;
}

int ecmdClientPerlapi::simUNSTICK(const char* i_facname, int i_bitlength, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simunsticktcfac(const char* i_tcfacname, int i_bitlength, const char* i_data, int i_row, int i_numrows){

  return 0;
}

char* ecmdClientPerlapi::ecmdGetErrorMsg(int i_errorCode){

  return NULL;
}

void ecmdClientPerlapi::ecmdOutputError(const char* i_message){
  ::ecmdOutputError(i_message);
  return ;
}

void ecmdClientPerlapi::ecmdOutputWarning(const char* i_message){
  ::ecmdOutputWarning(i_message);
  return ;
}

void ecmdClientPerlapi::ecmdOutput(const char* i_message){
  ::ecmdOutput(i_message);
  return ;
}

<commit_msg>added getspy putspy.<commit_after>
// Copyright **********************************************************
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 2003
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright ******************************************************

//--------------------------------------------------------------------
// Includes
//--------------------------------------------------------------------
#include <string.h>
#include <stdio.h>
#include <ctype.h>

#include <ecmdClientCapi.H>
#include <ecmdDataBuffer.H>
#include <ecmdReturnCodes.H>
#include <ecmdUtils.H>
#include <ecmdClientPerlapi.H>
#include <ecmdSharedUtils.H>

static int myErrorCode = ECMD_SUCCESS;

int ecmdPerlInterfaceErrorCheck (int errorCode) {

  if (errorCode == -1) {
    errorCode = myErrorCode;
    myErrorCode = ECMD_SUCCESS;

    if (errorCode != ECMD_SUCCESS) {
      ::ecmdOutputError( (::ecmdGetErrorMsg(errorCode) + "\n").c_str());
    }

    return errorCode;
  }
  else if (errorCode != ECMD_SUCCESS) {
    myErrorCode = errorCode;
  }

  return ECMD_SUCCESS;
}

ecmdClientPerlapi::ecmdClientPerlapi () {

}

ecmdClientPerlapi::~ecmdClientPerlapi () {

  this->cleanup();
}

void ecmdClientPerlapi::cleanup()  {
  ecmdUnloadDll();
}

int ecmdClientPerlapi::initDll (const char * i_dllName, const char * i_options) {

  int rc = ECMD_SUCCESS;
  std::string dllName = "";
  if (i_dllName != NULL) {
    dllName = i_dllName;
  }

  rc = ecmdLoadDll(dllName);
  ecmdPerlInterfaceErrorCheck(rc);

  return rc;

}

int ecmdClientPerlapi::setupTarget (const char * i_targetStr, ecmdChipTarget & o_target) {

  int rc = ECMD_SUCCESS;
  std::string printed;
  if (i_targetStr == NULL) {
    ecmdOutputError("ecmdClientPerlapi::setupTarget - It appears the target string is null\n");
    return ECMD_INVALID_ARGS;
  }
  std::vector<std::string> tokens;

  ecmdParseTokens(i_targetStr, " ,.", tokens);

  /* Set our initial states */
  o_target.cage = o_target.node = o_target.slot = o_target.pos = o_target.core = o_target.thread = 0;
  o_target.cageState = o_target.nodeState = o_target.slotState = o_target.posState = o_target.coreState = o_target.threadState = ECMD_TARGET_FIELD_VALID;
  o_target.chipTypeState = ECMD_TARGET_FIELD_UNUSED;

  for (std::vector<std::string>::iterator tokit = tokens.begin(); tokit != tokens.end(); tokit ++) {
    if ((*tokit)[0] == '-') {
      switch((*tokit)[1]) {
        case 'k': case 'K':
          o_target.cage = atoi(tokit->substr(2,20).c_str());
          break;
        case 'n': case 'N':
          o_target.node = atoi(tokit->substr(2,20).c_str());
          break;
        case 's': case 'S':
          o_target.slot = atoi(tokit->substr(2,20).c_str());
          break;
        case 'p': case 'P':
          o_target.pos = atoi(tokit->substr(2,20).c_str());
          break;
        case 'c': case 'C':
          o_target.core = atoi(tokit->substr(2,20).c_str());
          break;
        case 't': case 'T':
          o_target.thread = atoi(tokit->substr(2,20).c_str());
          break;
        default:
          ecmdOutputError((((printed = "ecmdClientPerlapi::setupTarget - It appears the target string contained an invalid target parm : ") + i_targetStr) + "\n").c_str());
          return ECMD_INVALID_ARGS;

      }
    } else {
      /* If the first char is a digit then they must have specified a p1..3 or p1,4 and we tokenized it above, this is not good */
      if (isdigit((*tokit)[0])) {
        ecmdOutputError((((printed = "ecmdClientPerlapi::setupTarget - It appears the target string contained a range or multiple positions : ") + i_targetStr) + "\n").c_str());
        return ECMD_INVALID_ARGS;
      } else if (o_target.chipTypeState == ECMD_TARGET_FIELD_VALID) {
        ecmdOutputError((((printed = "ecmdClientPerlapi::setupTarget - It appears the target string contained multiple chip names : ") + i_targetStr) + "\n").c_str());
        return ECMD_INVALID_ARGS;
      }
      o_target.chipTypeState = ECMD_TARGET_FIELD_VALID;
      o_target.chipType = *tokit;
    }
  }

  return rc;
}

int ecmdClientPerlapi::getScom (const char* i_target, int i_address, char** o_data) {

  ecmdChipTarget myTarget;
  std::string dataStr;

  int rc = setupTarget(i_target, myTarget);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) {
    *o_data = NULL;
    return rc;
  }

  ecmdDataBuffer buffer;
  rc = ::getScom(myTarget, i_address, buffer);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) {
    o_data = NULL;
    return rc;
  }

  dataStr = buffer.genBinStr();

  char* tmp;
  tmp = new char[dataStr.length()+1];
  strcpy(tmp,dataStr.c_str());
  *o_data = tmp;

  return rc;
}

int ecmdClientPerlapi::putScom (const char * i_target, int i_address, const char * i_data) {

  ecmdChipTarget myTarget;

  int rc = setupTarget(i_target, myTarget);
  if (rc) return rc;

  ecmdDataBuffer buffer;

  buffer.setBitLength(strlen(i_data));
  rc = buffer.insertFromBin(i_data);

  rc = ::putScom(myTarget, i_address, buffer);

  ecmdPerlInterfaceErrorCheck(rc);
  return rc;
}

int ecmdClientPerlapi::getRing (const char * i_target, const char * i_ringName, char **o_data) {

  int rc = 0;
  ecmdDataBuffer buffer;
  ecmdChipTarget myTarget;

  rc = setupTarget(i_target, myTarget);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) return rc;

  rc = ::getRing(myTarget, i_ringName, buffer);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) return rc;

  char* tmp;
  tmp = new char[buffer.getBitLength()+1];
  strcpy(tmp,buffer.genBinStr().c_str());
  *o_data = tmp;

  return rc;
}

int ecmdClientPerlapi::putRing (const char * i_target, const char * i_ringName, const char * i_data) {

  ecmdChipTarget myTarget;

  int rc = setupTarget(i_target, myTarget);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) return rc;

  ecmdDataBuffer buffer;

  buffer.setBitLength(strlen(i_data));
  rc = buffer.insertFromBin(i_data);

  rc = ::putRing(myTarget, i_ringName, buffer);

  ecmdPerlInterfaceErrorCheck(rc);
  return rc;
}

int ecmdClientPerlapi::getSpy (const char* i_target, const char * i_spyName, char** o_data){
  int rc = 0;
  ecmdDataBuffer buffer;
  ecmdChipTarget myTarget;

  rc = setupTarget(i_target, myTarget);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) return rc;

  rc = ::getSpy(myTarget, i_spyName, buffer);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) return rc;

  char* tmp;
  tmp = new char[buffer.getBitLength()+1];
  strcpy(tmp,buffer.genBinStr().c_str());
  *o_data = tmp;

  return rc;
}

int ecmdClientPerlapi::putSpy (const char* i_target, const char * i_spyName, const char* i_data){

  ecmdChipTarget myTarget;

  int rc = setupTarget(i_target, myTarget);
  ecmdPerlInterfaceErrorCheck(rc);
  if (rc) return rc;

  ecmdDataBuffer buffer;

  buffer.setBitLength(strlen(i_data));
  rc = buffer.insertFromBin(i_data);

  rc = ::putSpy(myTarget, i_spyName, buffer);

  ecmdPerlInterfaceErrorCheck(rc);
  return rc;
}

/***
void ecmdClientPerlapi::add(char *retval) {
  printf("Inside function: %c %c %c\n",retval[0],retval[1],retval[2]);

  retval[0] = 'L'; retval[1] = 'p';

 strcpy(retval,"Looky here - I made it");
}

void ecmdClientPerlapi::add2(char **retval) {
  printf("Inside function: %s\n",*retval);

  *retval = (char*)malloc(sizeof (char[100]));
  strcpy(*retval,"Looky here - I made it");
}
***/

int ecmdClientPerlapi::ecmdCommandArgs(char** i_argv[]){

  return 0;
}

/***
int ecmdClientPerlapi::ecmdCommandArgs(int* i_argc, char** i_argv[]) {

  return 0;
}

***/
int ecmdClientPerlapi::sendCmd(const char* i_target, int i_instruction, int i_modifier, char** o_status) {

  return 0;
}

int ecmdClientPerlapi::getCfamRegister (const char* i_target, int i_address, char** o_data){

  return 0;
}

int ecmdClientPerlapi::putCfamRegister (const char* i_target, int i_address, const char* i_data){

  return 0;
}

int ecmdClientPerlapi::getSpyEnum (const char* i_target, const char * i_spyName, char** o_enumValue){

  return 0;
}

int ecmdClientPerlapi::getSpyEccGrouping (const char* i_target, const char * i_spyEccGroupName, char** o_groupData, char** o_eccData, char** o_eccErrorMask){

  return 0;
}

int ecmdClientPerlapi::putSpyEnum (const char* i_target, const char * i_spyName, const char* i_enumValue){

  return 0;
}

void ecmdClientPerlapi::ecmdEnableRingCache(){

  return ;
}

int  ecmdClientPerlapi::ecmdDisableRingCache(){

  return 0;
}

int  ecmdClientPerlapi::ecmdFlushRingCache(){

  return 0;
}

int ecmdClientPerlapi::getArray (const char* i_target, const char * i_arrayName, const char* i_address, char** o_data){

  return 0;
}

int ecmdClientPerlapi::putArray (const char* i_target, const char * i_arrayName, const char* i_address, const char* i_data){

  return 0;
}

int ecmdClientPerlapi::simaet(const char* i_function){

  return 0;
}

int ecmdClientPerlapi::simcheckpoint(const char* i_checkpoint){

  return 0;
}

int ecmdClientPerlapi::simclock(int i_cycles){

  return 0;
}

int ecmdClientPerlapi::simecho(const char* i_message){

  return 0;
}

int ecmdClientPerlapi::simexit(){

  return 0;
}

int ecmdClientPerlapi::simEXPECTFAC(const char* i_facname, int i_bitlength, const char* i_expect, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simexpecttcfac(const char* i_tcfacname, int i_bitlength, const char* i_expect, int i_row){

  return 0;
}

int ecmdClientPerlapi::simgetcurrentcycle(char** o_cyclecount){

  return 0;
}

int ecmdClientPerlapi::simGETFAC(const char* i_facname, int i_bitlength, char** o_data, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simGETFACX(const char* i_facname, int i_bitlength, char** o_data, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simgettcfac(const char* i_tcfacname, char** o_data, int i_row, int i_startbit, int i_bitlength){

  return 0;
}

int ecmdClientPerlapi::siminit(const char* i_checkpoint){

  return 0;
}

int ecmdClientPerlapi::simPUTFAC(const char* i_facname, int i_bitlength, const char* i_data, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simPUTFACX(const char* i_facname, int i_bitlength, const char* i_data, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simputtcfac(const char* i_tcfacname, int i_bitlength, const char* i_data, int i_row, int i_numrows){

  return 0;
}

int ecmdClientPerlapi::simrestart(const char* i_checkpoint){

  return 0;
}

int ecmdClientPerlapi::simSTKFAC(const char* i_facname, int i_bitlength, const char* i_data, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simstktcfac(const char* i_tcfacname, int i_bitlength, const char* i_data, int i_row, int i_numrows){

  return 0;
}

int ecmdClientPerlapi::simSUBCMD(const char* i_command){

  return 0;
}

int ecmdClientPerlapi::simtckinterval(int i_tckinterval){

  return 0;
}

int ecmdClientPerlapi::simUNSTICK(const char* i_facname, int i_bitlength, int i_row, int i_offset){

  return 0;
}

int ecmdClientPerlapi::simunsticktcfac(const char* i_tcfacname, int i_bitlength, const char* i_data, int i_row, int i_numrows){

  return 0;
}

char* ecmdClientPerlapi::ecmdGetErrorMsg(int i_errorCode){

  return NULL;
}

void ecmdClientPerlapi::ecmdOutputError(const char* i_message){
  ::ecmdOutputError(i_message);
  return ;
}

void ecmdClientPerlapi::ecmdOutputWarning(const char* i_message){
  ::ecmdOutputWarning(i_message);
  return ;
}

void ecmdClientPerlapi::ecmdOutput(const char* i_message){
  ::ecmdOutput(i_message);
  return ;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

#include "Tokenizer.h"
#include "Parser.h"
#include "IOException.h"

using namespace std;

/**
 * /main Interpreter
 *
 */

void usage () {
  cout << "  cat infile.txt | Interpreter > output.txt" << endl;
}

/*
	pre: msg wijst naar een array can len chars
	post: de tekst in msg wordt naar het bestand en het schem geschreven
*/
void out(const char* msg, int len){
  cout.write(msg, len);
}

void processInput(istream* in){
  Tokenizer* tokenizer = new Tokenizer(in);
  Parser* parser = new Parser(tokenizer);

  string str;

  try{
    bool b = parser->parseStylesheet();

  } catch(ParseException* e) {
    ostringstream stream1(ostringstream::out);
    stream1 << "Line " << tokenizer->getLineNumber() << ", Collumn " <<
      tokenizer->getPosition() << " Parse Error: " << e->what() << endl;
    cout << stream1.str();
  }

  delete tokenizer;
  delete parser;
}

int main(int argc, char * argv[]){
  string helpstr("-h");
  if (argc > 1 && helpstr.compare(argv[1]) == 0) {
    usage();
    return 0;
  }

  try {
    if(argc <= 1){
      cout << "For help run 'Interpreter -h'" << endl;
      processInput(&cin);
    } else {
      for (int i=1; i < argc; i++){
        ifstream* file = new ifstream(argv[i]);

        if (file->fail() || file->bad())
          throw new IOException("Error opening file");

        processInput(file);
        file->close();
        delete file;
      }
    }
  } catch (IOException* e) {
    ostringstream stream1(ostringstream::out);
    string str;
    stream1 << " Error: " << e->what() << endl;
    str = stream1.str();
    out(str.c_str(), str.size());
  }

  return 0;
}

<commit_msg>Updated main to receive a stylesheet from the parser instead of a boolean.<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

#include "Tokenizer.h"
#include "Parser.h"
#include "Stylesheet.h"
#include "IOException.h"

using namespace std;

/**
 * /main Interpreter
 *
 */

void usage () {
  cout << "  cat infile.txt | Interpreter > output.txt" << endl;
}

/*
	pre: msg wijst naar een array can len chars
	post: de tekst in msg wordt naar het bestand en het schem geschreven
*/
void out(const char* msg, int len){
  cout.write(msg, len);
}

void processInput(istream* in){
  Tokenizer* tokenizer = new Tokenizer(in);
  Parser* parser = new Parser(tokenizer);

  string str;

  try{
    Stylesheet* s = parser->parseStylesheet();

  } catch(ParseException* e) {
    ostringstream stream1(ostringstream::out);
    stream1 << "Line " << tokenizer->getLineNumber() << ", Collumn " <<
      tokenizer->getPosition() << " Parse Error: " << e->what() << endl;
    cout << stream1.str();
  }

  delete tokenizer;
  delete parser;
}

int main(int argc, char * argv[]){
  string helpstr("-h");
  if (argc > 1 && helpstr.compare(argv[1]) == 0) {
    usage();
    return 0;
  }

  try {
    if(argc <= 1){
      cout << "For help run 'Interpreter -h'" << endl;
      processInput(&cin);
    } else {
      for (int i=1; i < argc; i++){
        ifstream* file = new ifstream(argv[i]);

        if (file->fail() || file->bad())
          throw new IOException("Error opening file");

        processInput(file);
        file->close();
        delete file;
      }
    }
  } catch (IOException* e) {
    ostringstream stream1(ostringstream::out);
    string str;
    stream1 << " Error: " << e->what() << endl;
    str = stream1.str();
    out(str.c_str(), str.size());
  }

  return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 Tmplt <tmplt@dragons.rocks>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <cstdint>    // explicitly-sized integral types
#include <cstdlib>    // EXIT_SUCCESS, EXIT_FAILURE
#include <exception>  // std::exception

#include <spdlog/spdlog.h>

#include "item.hpp"
#include "components/command_line.hpp"
#include "components/logger.hpp"
#include "config.hpp"

int main(int argc, char *argv[])
{
    using valid_opts = std::initializer_list<string>;

    /* Future work: make main, excl, exact, misc and groups constexpr. */
    const auto main = command_line::option_group("Main", "necessarily inclusive arguments; at least one required")
        ("-a", "--author",    "Specify authors", "AUTHOR")
        ("-t", "--title",     "Specify title", "TITLE")
        ("-s", "--serie",     "Specify serie", "SERIE")
        ("-p", "--publisher", "Specify publisher", "PUBLISHER");

    const auto excl = command_line::option_group("Exclusive", "cannot be combined with any other arguments")
        ("-d", "--ident",     "Specify an item identification (such as DOI, URL, etc.)", "IDENT");

    const auto exact = command_line::option_group("Exact", "matched fuzzily; all are optional")
        ("-y", "--year",      "Specify year of release", "YEAR")
        ("-L", "--language",  "Specify text language", "LANG")
        ("-e", "--edition",   "Specify item edition", "EDITION")
        ("-E", "--extension", "Specify item extension", "EXT",
            valid_opts{"epub", "pdf", "djvu"})
        ("-i", "--isbn",      "Specify item ISBN", "ISBN");

    const auto misc = command_line::option_group("Misc", "miscellaneous arguments")
        ("-h", "--help",      "Display this text and exit ")
        ("-v", "--version",   "Print version information")
        ("-l", "--log",       "Set logging level to info");

    const command_line::groups groups = {main, excl, exact, misc};
    uint8_t exit_code = EXIT_SUCCESS;

    const auto logger = logger::create("main");
    logger->set_pattern("%l: %v");
    logger->set_level(spdlog::level::err);

    try {
        /* Parse command line arguments. */
        std::string progname = argv[0];
        std::vector<std::string> args(argv + 1, argv + argc);

        auto cli = cliparser::make(std::move(progname), std::move(groups));
        cli->process_arguments(args);

        if (cli->has("log"))
            logger->set_level(spdlog::level::info);

        logger->info("the mighty eldwyrm has been summoned!");

        if (cli->has("help")) {
            cli->usage();
            return EXIT_SUCCESS;
        } else if (cli->has("version")) {
            print_build_info();
            return EXIT_SUCCESS;
        } else if (args.empty()) {
            cli->usage();
            return EXIT_FAILURE;
        }

        cli->validate_arguments();

    } catch (const command_line::argument_error &err) {
        logger->error(err.what() + std::string("; see --help"));
        exit_code = EXIT_FAILURE;
    } catch (const std::exception &err) {
        logger->error(err.what());
        exit_code = EXIT_FAILURE;
    }

    logger->info("dropping all loggers and returning exitval = {}", exit_code);
    spdlog::drop_all();
    return exit_code;
}
<commit_msg>remove lie from the exact option_group<commit_after>/*
 * Copyright (C) 2017 Tmplt <tmplt@dragons.rocks>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <cstdint>    // explicitly-sized integral types
#include <cstdlib>    // EXIT_SUCCESS, EXIT_FAILURE
#include <exception>  // std::exception

#include <spdlog/spdlog.h>

#include "item.hpp"
#include "components/command_line.hpp"
#include "components/logger.hpp"
#include "config.hpp"

int main(int argc, char *argv[])
{
    using valid_opts = std::initializer_list<string>;

    /* Future work: make main, excl, exact, misc and groups constexpr. */
    const auto main = command_line::option_group("Main", "necessarily inclusive arguments; at least one required")
        ("-a", "--author",    "Specify authors", "AUTHOR")
        ("-t", "--title",     "Specify title", "TITLE")
        ("-s", "--serie",     "Specify serie", "SERIE")
        ("-p", "--publisher", "Specify publisher", "PUBLISHER");

    const auto excl = command_line::option_group("Exclusive", "cannot be combined with any other arguments")
        ("-d", "--ident",     "Specify an item identification (such as DOI, URL, etc.)", "IDENT");

    const auto exact = command_line::option_group("Exact", "all are optional")
        ("-y", "--year",      "Specify year of release", "YEAR")
        ("-L", "--language",  "Specify text language", "LANG")
        ("-e", "--edition",   "Specify item edition", "EDITION")
        ("-E", "--extension", "Specify item extension", "EXT",
            valid_opts{"epub", "pdf", "djvu"})
        ("-i", "--isbn",      "Specify item ISBN", "ISBN");

    const auto misc = command_line::option_group("Misc", "miscellaneous arguments")
        ("-h", "--help",      "Display this text and exit ")
        ("-v", "--version",   "Print version information")
        ("-l", "--log",       "Set logging level to info");

    const command_line::groups groups = {main, excl, exact, misc};
    uint8_t exit_code = EXIT_SUCCESS;

    const auto logger = logger::create("main");
    logger->set_pattern("%l: %v");
    logger->set_level(spdlog::level::err);

    try {
        /* Parse command line arguments. */
        std::string progname = argv[0];
        std::vector<std::string> args(argv + 1, argv + argc);

        auto cli = cliparser::make(std::move(progname), std::move(groups));
        cli->process_arguments(args);

        if (cli->has("log"))
            logger->set_level(spdlog::level::info);

        logger->info("the mighty eldwyrm has been summoned!");

        if (cli->has("help")) {
            cli->usage();
            return EXIT_SUCCESS;
        } else if (cli->has("version")) {
            print_build_info();
            return EXIT_SUCCESS;
        } else if (args.empty()) {
            cli->usage();
            return EXIT_FAILURE;
        }

        cli->validate_arguments();

    } catch (const command_line::argument_error &err) {
        logger->error(err.what() + std::string("; see --help"));
        exit_code = EXIT_FAILURE;
    } catch (const std::exception &err) {
        logger->error(err.what());
        exit_code = EXIT_FAILURE;
    }

    logger->info("dropping all loggers and returning exitval = {}", exit_code);
    spdlog::drop_all();
    return exit_code;
}
<|endoftext|>