// File: /workspace/github_cpp_makefile_star2_O2/sanaa-khan[P]mini-linux-shell/gbsh.cpp
// Function: executeProgram(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>)
void executeProgram(vector<string> tokens) {

	bool outputRedirection = false, inputRedirection = false;

	for (int i = 0; i < tokens.size(); i++) { // detecting if output/input redirection required

		if (tokens[i].size() == 1) {

			if (tokens[i][0] == '>')
				outputRedirection = true;

			else if (tokens[i][0] == '<')
				inputRedirection = true;
		}
	}

	string cmd = tokens[0];
	int noOfArguments = 0;
	string outputFile, inputFile;
	char** arg;

	if (!inputRedirection and outputRedirection) { 
		for (int i = 1; i < tokens.size(); i++) {
			if (tokens[i].size() == 1 and tokens[i][0] == '>') {
				if (i == tokens.size() - 1) {
					cout << "\033[1;31m" << "Error: ";
					cout << "\033[0;38m" << "Output file not provided.\n";
					return;
				}

				else {
					outputFile = tokens[i + 1];
					break;
				}
			}

			else {
				noOfArguments++;
			}
		}

		arg = new char*[noOfArguments + 2];
		arg[0] = new char[20];

		strcpy(arg[0], cmd.c_str());
		arg[noOfArguments + 1] = nullptr;

		for (int i = 1; i <= noOfArguments; i++) {
			arg[i] = new char[20];
			strcpy(arg[i], tokens[i].c_str());
		}

		int file_desc = open(outputFile.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0777);
		output = dup(1);

		close(1);
		dup(file_desc);
		close(file_desc);

		oRedirect = true;
	}

	else if (inputRedirection and outputRedirection) {
		int i;
		for (i = 1; i < tokens.size(); i++) {
			if (tokens[i].size() == 1 and tokens[i][0] == '<') {
				if (i == tokens.size() - 1) {
					cout << "\033[1;31m" << "Error: ";
					cout << "\033[0;38m" << "Input file not provided.\n";
					return;
				}

				else {
					i++;
					inputFile = tokens[i];
					i++;
					break;
				}
			}

			else {
				noOfArguments++;
			}
		}

		for (i = 1; i < tokens.size(); i++) {
			if (tokens[i].size() == 1 and tokens[i][0] == '>') {
				if (i == tokens.size() - 1) {
					cout << "\033[1;31m" << "Error: ";
					cout << "\033[0;38m" << "Output file not provided.\n";
					return;
				}

				else {
					outputFile = tokens[i + 1];
					break;
				}
			}
		}

		arg = new char*[noOfArguments + 2];
		arg[0] = new char[20];

		strcpy(arg[0], cmd.c_str());
		arg[noOfArguments + 1] = nullptr;

		for (int j = 1; j <= noOfArguments; j++) {
			arg[j] = new char[20];
			strcpy(arg[j], tokens[j].c_str());
		}

		int file_desc = open(outputFile.c_str(), O_WRONLY | O_CREAT |  O_TRUNC, 0777);
		output = dup(1);

		close(1);
		dup(file_desc);
		close(file_desc);
		
		oRedirect = true;

		int file_desc2 = open(inputFile.c_str(), O_WRONLY | 0777);
		input = dup(0);

		close(0);
		dup(file_desc2);
		close(file_desc2);

		iRedirect = true;
	}

	else if (!inputRedirection and !outputRedirection) {
		noOfArguments = tokens.size() - 1;
		char* arg[noOfArguments + 2];

		for (int i = 0; i <= noOfArguments; i++)
			arg[i] = new char[20];
			
		strcpy(arg[0], cmd.c_str());

		int i;
		for (i = 1; i <= noOfArguments; i++) {
			strcpy(arg[i], tokens[i].c_str());
		}

		arg[i] = NULL;
	}

	if (cmd == "top") {
		char path[50];
		getcwd(path, 50);

		chdir("/usr/bin");
		execl("top", "top", NULL);
		chdir(path);
	}

	else if (cmd == "man") {
		char path[50];
		getcwd(path, 50);

		chdir("/usr/bin");

		if (tokens.size() > 1)
			execl("man", "man", tokens[1].c_str(), NULL);
		else
			execl("man", "man", NULL);

		chdir(path);
	}

	else if (cmd == "ps") {
		char path[50];
		getcwd(path, 50);

		chdir("/usr/bin");

		if (tokens.size() > 1)
			execl("ps", "ps", tokens[1].c_str(), NULL);
		else
			execl("ps", "ps", NULL);

		chdir(path);
	}

	else {
		if (execvp(arg[0], arg) < 0) {
			cout << "\033[1;31m" << "Error: ";
			cout << "\033[0;38m" << "'" << arg[0] << "' not found.\n";
			
			for (int i = 0; i < noOfArguments + 2; i++)
				delete []arg[i];

			exit(0);
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq (%rdi), %rsi
movq %rdi, -0x30(%rbp)
movq 0x8(%rdi), %rax
subq %rsi, %rax
sarq $0x5, %rax
leaq 0x8(%rsi), %rcx
xorl %r14d, %r14d
xorl %r15d, %r15d
subq $0x1, %rax
jb 0x3698
cmpq $0x1, (%rcx)
jne 0x3692
movq -0x8(%rcx), %rdx
movb (%rdx), %dl
cmpb $0x3e, %dl
jne 0x3689
movb $0x1, %r15b
jmp 0x3692
cmpb $0x3c, %dl
sete %dl
orb %dl, %r14b
addq $0x20, %rcx
jmp 0x366d
leaq -0x50(%rbp), %rdi
callq 0x2220
leaq -0x68(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
leaq -0x88(%rbp), %rcx
movq %rcx, -0x10(%rcx)
andq $0x0, -0x8(%rcx)
xorl %ebx, %ebx
movb %bl, (%rax)
movb %bl, (%rcx)
testb $0x1, %r14b
je 0x371e
testb $0x1, %r15b
je 0x3aa7
movq -0x30(%rbp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
subq %rax, %rcx
sarq $0x5, %rcx
leaq 0x40(%rax), %rsi
pushq $0x10
popq %r14
xorl %ebx, %ebx
leaq 0x1(%rbx), %rdx
cmpq %rdx, %rcx
jbe 0x3828
cmpq $0x1, -0x18(%rsi)
jne 0x3711
movq -0x20(%rsi), %rdi
cmpb $0x3c, (%rdi)
je 0x37fa
addq $0x20, %rsi
addq $0x8, %r14
movq %rdx, %rbx
jmp 0x36f0
movq -0x30(%rbp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rax
subq %rsi, %rax
sarq $0x5, %rax
testb $0x1, %r15b
je 0x3772
pushq $0x10
popq %r14
pushq $0x8
popq %r12
addq $0x40, %rsi
xorl %ebx, %ebx
leaq 0x1(%rbx), %rcx
cmpq %rcx, %rax
jbe 0x3900
cmpq $0x1, -0x18(%rsi)
jne 0x3765
movq -0x20(%rsi), %rdx
cmpb $0x3e, (%rdx)
je 0x3850
addq $0x20, %rsi
addq $0x8, %r14
movq %rcx, %rbx
jmp 0x3744
movq %rsp, -0x58(%rbp)
leal -0x1(%rax), %ebx
incl %eax
movq %rsp, %r12
leaq 0xf(,%rax,8), %rax
andq $-0x10, %rax
subq %rax, %r12
movq %r12, %rsp
movslq %ebx, %r13
xorl %r15d, %r15d
pushq $0x14
popq %r14
cmpq %r13, %r15
jg 0x37b0
movq %r14, %rdi
callq 0x2030
movq %rax, (%r12,%r15,8)
incq %r15
jmp 0x379a
movq (%r12), %rdi
movq -0x50(%rbp), %rsi
callq 0x2160
xorl %r14d, %r14d
testl %ebx, %ebx
movl $0x0, %r13d
cmovgl %ebx, %r13d
shlq $0x3, %r13
cmpq %r14, %r13
je 0x37f1
movq 0x8(%r12,%r14), %rdi
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq 0x20(%rax,%r14,4), %rsi
callq 0x2160
addq $0x8, %r14
jmp 0x37d0
movq -0x58(%rbp), %rsp
jmp 0x3aa7
movq %rbx, %rax
subq %rcx, %rax
cmpq $-0x2, %rax
je 0x3c9d
leaq -0x98(%rbp), %rdi
callq 0x20d0
movq -0x30(%rbp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
subq %rax, %rcx
sarq $0x5, %rcx
leaq 0x28(%rax), %rsi
pushq $0x1
popq %rdx
cmpq %rdx, %rcx
jbe 0x39bf
cmpq $0x1, (%rsi)
jne 0x3847
movq -0x8(%rsi), %rdi
cmpb $0x3e, (%rdi)
je 0x38a6
incq %rdx
addq $0x20, %rsi
jmp 0x382f
addq $-0x2, %rax
cmpq %rbx, %rax
jne 0x38f7
movq 0x3764(%rip), %rdi      # 0x6fc8
leaq 0x1816(%rip), %rsi      # 0x5081
callq 0x2170
leaq 0x1812(%rip), %rsi      # 0x5089
movq %rax, %rdi
callq 0x2170
movq 0x3742(%rip), %rdi      # 0x6fc8
leaq 0x1804(%rip), %rsi      # 0x5091
callq 0x2170
leaq 0x1800(%rip), %rsi      # 0x5099
movq %rax, %rdi
callq 0x2170
jmp 0x3c70
movq %rdx, %rsi
subq %rcx, %rsi
cmpq $-0x1, %rsi
jne 0x39a8
movq 0x370b(%rip), %rdi      # 0x6fc8
leaq 0x17bd(%rip), %rsi      # 0x5081
callq 0x2170
leaq 0x17b9(%rip), %rsi      # 0x5089
movq %rax, %rdi
callq 0x2170
movq 0x36e9(%rip), %rdi      # 0x6fc8
leaq 0x17ab(%rip), %rsi      # 0x5091
callq 0x2170
leaq 0x17a7(%rip), %rsi      # 0x5099
jmp 0x3cd9
leaq -0x78(%rbp), %rdi
callq 0x20d0
movq %r14, %rdi
callq 0x2030
movq %rax, %r14
pushq $0x14
popq %rdi
callq 0x2030
movq %rax, (%r14)
movq -0x50(%rbp), %rsi
movq %rax, %rdi
callq 0x2160
andq $0x0, 0x8(%r14,%rbx,8)
pushq $0x14
popq %r15
movq %rbx, %r13
subq $0x1, %r13
jb 0x395a
movq %r15, %rdi
callq 0x2030
movq %rax, (%r14,%r12)
movq -0x30(%rbp), %rcx
movq (%rcx), %rcx
movq (%rcx,%r12,4), %rsi
movq %rax, %rdi
callq 0x2160
addq $0x8, %r12
jmp 0x392f
movq -0x78(%rbp), %rdi
movl $0x241, %esi            # imm = 0x241
movl $0x1ff, %edx            # imm = 0x1FF
xorl %eax, %eax
callq 0x20e0
movl %eax, %r15d
pushq $0x1
popq %r12
movl %r12d, %edi
callq 0x2280
movl %eax, 0x3824(%rip)      # 0x71a8
movl %r12d, %edi
callq 0x2300
movl %r15d, %edi
callq 0x2280
movl %r15d, %edi
callq 0x2300
movb $0x1, 0x380d(%rip)      # 0x71b0
jmp 0x3aa7
movl %edx, %ecx
shlq $0x5, %rcx
leaq (%rax,%rcx), %rsi
addq $0x20, %rsi
leaq -0x78(%rbp), %rdi
callq 0x20d0
movq %r14, %rdi
callq 0x2030
movq %rax, %r14
pushq $0x14
popq %rdi
callq 0x2030
movq %rax, (%r14)
movq -0x50(%rbp), %rsi
movq %rax, %rdi
callq 0x2160
andq $0x0, 0x8(%r14,%rbx,8)
pushq $0x8
popq %r12
pushq $0x14
popq %r15
movq %rbx, %r13
subq $0x1, %r13
jb 0x3a1d
movq %r15, %rdi
callq 0x2030
movq %rax, (%r14,%r12)
movq -0x30(%rbp), %rcx
movq (%rcx), %rcx
movq (%rcx,%r12,4), %rsi
movq %rax, %rdi
callq 0x2160
addq $0x8, %r12
jmp 0x39f2
movq -0x78(%rbp), %rdi
movl $0x241, %esi            # imm = 0x241
movl $0x1ff, %edx            # imm = 0x1FF
xorl %eax, %eax
callq 0x20e0
movl %eax, %r15d
pushq $0x1
popq %r12
movl %r12d, %edi
callq 0x2280
movl %eax, 0x3761(%rip)      # 0x71a8
movl %r12d, %edi
callq 0x2300
movl %r15d, %edi
callq 0x2280
movl %r15d, %edi
callq 0x2300
movb $0x1, 0x374a(%rip)      # 0x71b0
movq -0x98(%rbp), %rdi
movl $0x1ff, %esi            # imm = 0x1FF
xorl %eax, %eax
callq 0x20e0
movl %eax, %r15d
xorl %edi, %edi
callq 0x2280
movl %eax, 0x3723(%rip)      # 0x71ac
xorl %edi, %edi
callq 0x2300
movl %r15d, %edi
callq 0x2280
movl %r15d, %edi
callq 0x2300
movb $0x1, 0x370a(%rip)      # 0x71b1
leaq 0x16f3(%rip), %rsi      # 0x51a1
leaq -0x50(%rbp), %rdi
callq 0x3d23
testb %al, %al
je 0x3af4
leaq -0xd0(%rbp), %rbx
pushq $0x32
popq %rsi
movq %rbx, %rdi
callq 0x20b0
leaq 0x16d1(%rip), %rdi      # 0x51a5
callq 0x2240
leaq 0x16c1(%rip), %rdi      # 0x51a1
movq %rdi, %rsi
xorl %edx, %edx
xorl %eax, %eax
callq 0x21e0
movq %rbx, %rdi
jmp 0x3c6b
leaq 0x16b3(%rip), %rsi      # 0x51ae
leaq -0x50(%rbp), %rdi
callq 0x3d23
testb %al, %al
je 0x3b44
leaq -0xd0(%rbp), %rdi
pushq $0x32
popq %rsi
callq 0x20b0
leaq 0x1687(%rip), %rdi      # 0x51a5
callq 0x2240
movq -0x30(%rbp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
subq %rax, %rcx
cmpq $0x21, %rcx
jb 0x3ba7
movq 0x20(%rax), %rdx
leaq 0x166c(%rip), %rdi      # 0x51ae
jmp 0x3b96
leaq 0x1667(%rip), %rsi      # 0x51b2
leaq -0x50(%rbp), %rdi
callq 0x3d23
testb %al, %al
je 0x3bb3
leaq -0xd0(%rbp), %rdi
pushq $0x32
popq %rsi
callq 0x20b0
leaq 0x1637(%rip), %rdi      # 0x51a5
callq 0x2240
movq -0x30(%rbp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
subq %rax, %rcx
cmpq $0x21, %rcx
jb 0x3c51
movq 0x20(%rax), %rdx
leaq 0x161c(%rip), %rdi      # 0x51b2
movq %rdi, %rsi
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x21e0
jmp 0x3c64
leaq 0x1600(%rip), %rdi      # 0x51ae
jmp 0x3c58
movq (%r14), %rdi
movq %r14, %rsi
callq 0x20f0
testl %eax, %eax
jns 0x3c70
movq 0x33fb(%rip), %rdi      # 0x6fc8
leaq 0x14ad(%rip), %rsi      # 0x5081
callq 0x2170
leaq 0x14a9(%rip), %rsi      # 0x5089
movq %rax, %rdi
callq 0x2170
movq 0x33d9(%rip), %rdi      # 0x6fc8
leaq 0x149b(%rip), %rsi      # 0x5091
callq 0x2170
leaq 0x1549(%rip), %rsi      # 0x514b
movq %rax, %rdi
callq 0x2170
movq (%r14), %rsi
movq %rax, %rdi
callq 0x2170
leaq 0x1599(%rip), %rsi      # 0x51b5
movq %rax, %rdi
callq 0x2170
cmpl $-0x1, %ebx
pushq $-0x2
popq %r15
cmovgel %ebx, %r15d
addl $0x2, %r15d
xorl %ebx, %ebx
cmpq %rbx, %r15
je 0x3ce3
movq (%r14,%rbx,8), %rdi
testq %rdi, %rdi
je 0x3c4c
callq 0x21f0
incq %rbx
jmp 0x3c35
leaq 0x155a(%rip), %rdi      # 0x51b2
movq %rdi, %rsi
xorl %edx, %edx
xorl %eax, %eax
callq 0x21e0
leaq -0xd0(%rbp), %rdi
callq 0x2240
leaq -0x98(%rbp), %rdi
callq 0x20a0
leaq -0x78(%rbp), %rdi
callq 0x20a0
leaq -0x50(%rbp), %rdi
callq 0x20a0
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x3324(%rip), %rdi      # 0x6fc8
leaq 0x13d6(%rip), %rsi      # 0x5081
callq 0x2170
leaq 0x13d2(%rip), %rsi      # 0x5089
movq %rax, %rdi
callq 0x2170
movq 0x3302(%rip), %rdi      # 0x6fc8
leaq 0x13c4(%rip), %rsi      # 0x5091
callq 0x2170
leaq 0x14ae(%rip), %rsi      # 0x5187
movq %rax, %rdi
callq 0x2170
jmp 0x3c70
xorl %edi, %edi
callq 0x21c0
jmp 0x3cfa
jmp 0x3cfa
jmp 0x3cfa
jmp 0x3cfa
jmp 0x3cfa
jmp 0x3cfa
jmp 0x3cfa
jmp 0x3cfa
movq %rax, %rbx
leaq -0x98(%rbp), %rdi
callq 0x20a0
leaq -0x78(%rbp), %rdi
callq 0x20a0
leaq -0x50(%rbp), %rdi
callq 0x20a0
movq %rbx, %rdi
callq 0x22e0