<commit_before>#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <iterator>
#include <iostream>
#include <sstream>
#include <string>

#include "shell.hpp"
#include "commands.hpp"

Shell::Shell()
{ }

bool Shell::command::is_background()
{
	return *argv[argc - 1].rbegin() == '&';
}

int Shell::start()
{
	while(1)
	{
		// Display the user prompt
		std::cout << prompt();

		// Read the use input into the command string
		std::string input_command;
		std::getline(std::cin, input_command);

		// Ignore empty inputs
		if (input_command.empty()) continue;

		// Execute the command
		execute(input_command);
	}

	return 0;
}

std::string Shell::prompt()
{
	// Get the hostname of the machine
	char hostname[1024];
	gethostname(hostname, sizeof hostname);

	std::ostringstream prompt;

	prompt << hostname << "(" << getenv("USER") << ")$ ";

	return prompt.str();
}

Shell::command Shell::parse_command(std::string input_command)
{
	// Tokenize the input command into a vector of strings
	std::istringstream iss(input_command);
	std::vector<std::string> argv;

	copy(std::istream_iterator<std::string>(iss),
	     std::istream_iterator<std::string>(),
	     std::back_inserter<std::vector<std::string> >(argv));

	// We also want the arguments as a vector of C style strings
	std::vector<const char *> argv_c;

	for (int i = 0; i < argv.size(); ++i)
	{
		argv_c.push_back(argv[i].c_str());
	}

	// Setup the command struct
	command command;

	command.command = input_command;
	command.name    = argv[0];
	command.argc    = argv.size();
	command.argv    = argv;
	command.argv_c  = argv_c;

	return command;
}

int Shell::execute(std::string input_command)
{
	return execute(parse_command(input_command));
}

int Shell::execute(Shell::command command)
{
	// Check if the command is a built in function of the shell
	int(*internal_call)() = commands::internal_commands()[command.name];

	if (internal_call != 0)
	{
		return internal_call();
	}








}

/**
 * Begin execution
 */
int main(int argc, char* argv[])
{
	Shell shell;<commit_msg>Execute the command using execvp and wait for it<commit_after>#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <iterator>
#include <iostream>
#include <sstream>
#include <string>
#include <sys/wait.h>

#include "shell.hpp"
#include "commands.hpp"

Shell::Shell()
{ }

bool Shell::command::is_background()
{
	return *argv[argc - 1].rbegin() == '&';
}

int Shell::start()
{
	while(1)
	{
		// Display the user prompt
		std::cout << prompt();

		// Read the use input into the command string
		std::string input_command;
		std::getline(std::cin, input_command);

		// Ignore empty inputs
		if (input_command.empty()) continue;

		// Execute the command
		execute(input_command);
	}

	return 0;
}

std::string Shell::prompt()
{
	// Get the hostname of the machine
	char hostname[1024];
	gethostname(hostname, sizeof hostname);

	std::ostringstream prompt;

	prompt << hostname << "(" << getenv("USER") << ")$ ";

	return prompt.str();
}

Shell::command Shell::parse_command(std::string input_command)
{
	// Tokenize the input command into a vector of strings
	std::istringstream iss(input_command);
	std::vector<std::string> argv;

	copy(std::istream_iterator<std::string>(iss),
	     std::istream_iterator<std::string>(),
	     std::back_inserter<std::vector<std::string> >(argv));

	// We also want the arguments as a vector of C style strings
	std::vector<const char *> argv_c;

	for (int i = 0; i < argv.size(); ++i)
	{
		argv_c.push_back(argv[i].c_str());
	}

	// Setup the command struct
	command command;

	command.command = input_command;
	command.name    = argv[0];
	command.argc    = argv.size();
	command.argv    = argv;
	command.argv_c  = argv_c;

	return command;
}

int Shell::execute(std::string input_command)
{
	return execute(parse_command(input_command));
}

int Shell::execute(Shell::command command)
{
	// Check if the command is a built in function of the shell
	int(*internal_call)() = commands::internal_commands()[command.name];

	if (internal_call != 0)
	{
		return internal_call();
	}

	if (fork() == 0)
	{
		// execvp always expects the last argument to be a null terminator
		command.argv_c.push_back(0);

		// Because the argv_c vector stores the C-strings in order we can
		// simply de-refrence the first element of the argv_c vector
		execvp(command.argv_c[0], (char * const *) &command.argv_c[0]);
	}
	else
	{
		wait(0);
	}
}

/**
 * Begin execution
 */
int main(int argc, char* argv[])
{
	Shell shell;
{'fraction_non_alphanumeric': 0.1523428825227626, 'fraction_numerical': 0.00555185431934266, 'mean_word_length': 4.3747016706443915, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5669458', 'n_tokens_mistral': 1610, 'n_tokens_neox': 1525, 'n_words': 398}