<commit_before>#include <iostream>
#include <unistd.h>
#include <string>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <vector>
#include <stdlib.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>

using namespace std;

void parsePath(char * line, vector<string> &pathing) {

    if (line == NULL)
        return;

    char * pch;
    pch = strtok(line, ":");
    while (pch!=NULL) {
        string tmp = pch;
        pathing.push_back(tmp);
        pch = strtok(NULL, ":");
    }
}

void parse(char * line, vector<string> & input) {

    if (line == NULL)
        return;

    char * pch;
    int find_quote = 0;
	pch = strtok (line, " \n");
	while (pch!= NULL) {

        if (pch == NULL)
                break;

        find_quote = 0;
        if ((pch + strlen(pch) + 1) == NULL)
                cerr << "hello\n";
        if (((pch +strlen(pch) +1) != NULL) && (*(pch + strlen(pch) + 1) == '"'))
            find_quote = 1;

	    // Ignore after comments
	    if (*pch == '#')
		break;

	    // Check for && and ||
	    // Break input up
	    char * a = strstr(pch, "&&");
	    char * b = strstr(pch, "||");
	    char * c = strstr(pch, ";");
        char * d = strstr(pch, "<");
        char * e = strstr(pch, ">");
        char * f = strstr(pch, "|");

	    // If there are connectors, break up the string
	    // into parts and add them individually to the vector
	    if (a!=NULL || b!=NULL || c!=NULL || d!=NULL || e!=NULL || f!=NULL
                    || (isdigit(*pch) && pch[1] == '>')) {
		while (strlen(pch) != 0 ) {
            if (isdigit(pch[0]) && pch[1] == '>') {
                string tmp;
                int stringlen = 0;
                tmp += *pch;
                tmp += pch[1];
                if (pch[1] == '>' && pch[2] == '>') {
                    tmp += pch[2];
                    stringlen = 3;
                    tmp[3] = '\0';
                    }
                else {
                    stringlen = 2;
                    tmp[2] = '\0';
                }
                input.push_back(tmp);
                memmove(pch, pch +stringlen, strlen(pch) - stringlen);
                pch[strlen(pch) - stringlen] = '\0';

            }

            // Checks for && and ||
            if ((pch[0] == '&' && pch[1] == '&') ||
			(pch[0] == '|' && pch[1] == '|')) {

			    string tmp;
			    tmp += *pch;
			    tmp += *(pch+1);
			    tmp[2] = '\0';

			    input.push_back(tmp);
			    memmove(pch, pch+2, strlen(pch) - 2);
			    pch[strlen(pch)-2] = '\0';
		    }
		    // Check for semicolons
		    else if (*pch == ';') {
			    input.push_back(";");
			    memmove(pch, pch+1, strlen(pch) -1);
			    pch[strlen(pch)-1] = '\0';
		    }
            // Check for input/output redirectors
            else if (*pch == '<' || *pch =='>' || *pch == '|') {
                if (*pch == '>' && *(pch+1) == '>') {
                    input.push_back(">>");
                    memmove(pch, pch+2, strlen(pch)-2);
                    pch[strlen(pch)-2] = '\0';
                }
                else if (*pch == '<' && *(pch+1) == '<' && *(pch+2)=='<') {
                    input.push_back("<<<");
                    memmove(pch, pch+3, strlen(pch)-3);
                    pch[strlen(pch)-3] = '\0';
                }
                else {
                    string tmp;
                    tmp += *pch;
                    tmp[1] = '\0';
                    input.push_back(tmp);
                    memmove(pch, pch+1, strlen(pch)-1);
                    pch[strlen(pch)-1] = '\0';
                }
            }

            else {
			string word;
			int numletters = 0;
			char z = *pch;
			int i = 1;
            while ( z!= '\0' && z!= ';' && z!= '|' && z!= '&' && z!= '<' && z!= '>'
                            && !(isdigit(z) && pch[i] == '>')) {
			    word += z;
			    numletters++;
			    z = pch[i];
                i++;
			}
            if (numletters!=0)
			    input.push_back(word);
			memmove(pch, pch+numletters, strlen(pch) -numletters);
			pch[strlen(pch)-numletters] = '\0';
		    }

		    a = strstr(pch, "&&");
		    b = strstr(pch, "||");
		    c = strstr(pch, ";");
            d = strstr(pch, "<");
            e = strstr(pch, ">");
            f = strstr(pch, "|");
		}
	    }

	    // If no connectors, just add to vector
	    if (*pch != '\0' && *pch != '\n' && *pch != '#') {
            input.push_back(pch);

        }

        if (find_quote == 1)
            pch = strtok(NULL, "\"");
        else
	        pch = strtok (NULL, " \n");
	}
}

void execute(const vector<string> & input, const vector<string> & pathing,
        int start, int end) {

    //Call execvp, based on which elements in the string vector to use
    char * argv[20];

	    int i = 0;
	    int status;

	    for (i = 0; i <= (end - start); i++) {
		argv[i] = new char[20];
	    }

	    for (i = 0; i < (end-start); i++) {
		strcpy(argv[i], input[i+start].c_str());
            }

	    argv[i] = NULL;
            string cmd = argv[0];

            for (unsigned int j = 0; j < pathing.size(); j++) {
                string tmp = pathing[j] + "/" + cmd;
                strcpy(argv[0], tmp.c_str());
                status = execv(argv[0], argv);

            }
	    if (status == -1)
		perror("execv");
		exit(1);
}

void printusrhost() {

    // Get username
    char * usrname;
    struct passwd *pass = getpwuid(getuid());
    usrname = pass->pw_name;
    if (pass == NULL) {
	perror ("getpwuid");
    exit(1);
    }

    // Get hostname
    char hostname[20];

    if (gethostname(hostname, sizeof hostname) ==-1) {
	perror("gethostname");
	exit(1);
    }
    cout << usrname << "@" << hostname <<"$ ";

}

void int_handler(int x) {
        cout << endl;
}

int main() {

    if ((signal(SIGINT, int_handler)) == SIG_ERR)
        perror("signal");

    vector<string> input;
    vector<string> pathing;
    int status=0;
    char *pPath;

    pPath = getenv("PATH");
	if (pPath == NULL)
	    perror("PATH");
    parsePath(pPath, pathing);

    int savestdin;
    if ((savestdin = dup(0)) == -1)
        perror("dup");

    int savestdout;
    if ((savestdout = dup(1)) == -1)
        perror("dup");

    // Main loop
    while (1) {
        //Restore stdin and stdout
        if ((dup2(savestdin,0)) == -1)
            perror("dup2");

        if ((dup2(savestdout,0)) == -1)
            perror("dup2");

    printusrhost();

	status = 0;

	if (input.size() != 0)
	    input.clear();

	string string1;
	getline(cin, string1);

	parse((char *)string1.c_str(), input);

    //debugging
    //cerr << "AFTER PARSING: \n";
    //for (int i = 0; i < input.size(); i++)
            //cerr << input[i] << endl;

	if (input.size() == 0)
	    continue;

    for (unsigned int i = 0; i < input.size(); i++)
	    if (strcmp(input[i].c_str(), "exit") == 0) exit(0);

	int pid=fork();
    if (pid == -1)
        perror ("fork");
	int pid2;
	if (pid == 0) {
	    int start = 0;
	    int end = input.size();
	    unsigned i;

loop:
	    bool rancd = false;
        end = input.size();

        for (i = start; i < input.size(); ) {

            //chdir command
            if (strcmp(input[i].c_str(), "cd") == 0) {
                rancd = true;
                string directory =  input[i+1];
                int ret;
                ret = chdir(directory.c_str());
                if (ret == -1)
                    perror ("chdir");

                if ((input[i+2] == ";" || input[i+2] == "&&") && (i+3 < input.size())) {
                    start = i+3;
                    goto loop;
                }
                else
                    break;
            }

            //input output redirection
            if (input[i] == ">" || input[i] == ">>" || input[i]=="<"
                            || input[i] == "<<<" || input[i] == "|"
                            || (isdigit(input[i][0]) && input[i][1] == '>')) {

                if ((isdigit(input[i][0]) && input[i][1] == '>') || input[i][0] == '>') {

                    int flags = 0;
                    int file_no = 1;
                    flags |= O_CREAT | O_WRONLY;

                    if ((input[i][0] == '>' && input[i][1] == '>') ||
                                input[i][2] == '>')
                            flags |= O_APPEND;
                        else
                            flags |= O_TRUNC;

                    int fdo = open(input[i+1].c_str(), flags, S_IRUSR | S_IWUSR);
                    if (fdo==-1) {
                        perror("open");
                        exit(1);
                    }

                    if (isdigit(input[i][0]))
                        file_no = input[i][0] - '0';

                    status = close(file_no);
                    if (status == -1)
                        perror("close");

                    if ((dup(fdo)) == -1)
                        perror("dup");

                    if ((close(fdo)) == -1)
                        perror("close");

                    input.erase(input.begin() + i);
                    input.erase(input.begin() + i);

                    if (input[i][0] == '>' || input[i][0] == '<' || input[i][0] == '|'
                                            || (isdigit(input[i][0]) && input[i][1] == '>'))
                        continue;

                    else {
                        end = i;
                        break;
                    }

                }

                else if (input[i] == "<") {

                        int fdi = open(input[i+1].c_str(), O_RDONLY, 0);
                        if (fdi==-1) {
                            perror("open");
                            exit(1);
                        }

                        status = close(STDIN_FILENO);
                        if (status == -1)
                            perror("close");

                        if ((dup(fdi)) == -1)
                            perror("dup");

                        if ((close(fdi)) == -1)
                            perror("close");

                        input.erase(input.begin() + i);
                        input.erase(input.begin() + i);

                        if (input[i][0] == '>' || input[i][0] == '<' || input[i][0] == '|'
                                            || (isdigit(input[i][0]) && input[i][1] == '>'))
                            continue;

                        else {
                            end = i;
                            break;
                        }
                }

                else if (input[i] == "<<<") {

                    int pfd[2];

                    if ((pipe(pfd)) == -1)
                        perror("pipe");

                        char buf[128];
                        memset(buf, 0, 128);
                        strcpy(buf, input[i+1].c_str());

                        buf[strlen(buf)] = '\n';
                        buf[strlen(buf)+1] = '\0';

                        if ((write(pfd[1], buf, strlen(buf)) == -1))
                            perror("write");

                        if ((dup2(pfd[0], 0)) == -1)
                            perror("dup2");

                        if (close (pfd[1]) == -1)
                            perror("close");

                        input.erase(input.begin() + i);
                        input.erase(input.begin() + i);

                        if (input[i][0] == '>' || input[i][0] == '<' || input[i][0] == '|'
                                            || (isdigit(input[i][0]) && input[i][1] == '>'))
                            continue;

                        else {
                            end = i;
                            break;
                        }

                }
                else if (input[i] == "|") {
                    int pfd[2];

                    if ((pipe(pfd)) == -1)
                        perror("pipe");

                    int pid3 = fork();
                    if (pid3 == -1) {
                        perror("fork");
                        exit(1);
                    }
                    if (pid3==0) {

                        if ((dup2(pfd[1], 1)) == -1)
                            perror("dup2");

                        if ((close(pfd[0])) == -1)
                            perror("close");

                        end = i;
                        break;

                    }
                    else {
                        if((close(STDIN_FILENO)) == -1)
                            perror("close");

                        if ((dup2(pfd[0], 0)) == -1)
                            perror("dup2");

                        if ((close(pfd[1])) == -1)
                            perror("close");

                        if (-1 == wait(0))
                            perror("wait");

                        start = i+1;
                        goto loop;

                    }

                }
            }

            else if (input[i] == ";" || input[i] == "&&" || input[i] == "||") {

                string connector = input[i];

		        pid2 = fork();
		        if (pid2 == -1) {
			        perror("fork");
			        exit(1);
		        }
		        if (pid2!=0) {
			        if (-1 == wait(&status))
			            perror("wait");

			        if (connector == "&&" && status != 0)
			            exit(1);

			        if (connector == "||" && status == 0)
			            exit(0);

			        start = i + 1;
			        goto loop;

		        }
		        else {
			        end = i;
			        break;
		        }
		    }
	    i++;
        }

        if (rancd == false)
	        execute(input, pathing, start, end);

	}
	else {
	    status = wait(NULL);
	    if (status == -1)
		perror("wait");
	}
    }

    exit(0);
}
<commit_msg>updated chdir functionality<commit_after>#include <iostream>
#include <unistd.h>
#include <string>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <vector>
#include <stdlib.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>

using namespace std;

void parsePath(char * line, vector<string> &pathing) {

    if (line == NULL)
        return;

    char * pch;
    pch = strtok(line, ":");
    while (pch!=NULL) {
        string tmp = pch;
        pathing.push_back(tmp);
        pch = strtok(NULL, ":");
    }
}

void parse(char * line, vector<string> & input) {

    if (line == NULL)
        return;

    char * pch;
    int find_quote = 0;
	pch = strtok (line, " \n");
	while (pch!= NULL) {

        if (pch == NULL)
                break;

        find_quote = 0;
        if ((pch + strlen(pch) + 1) == NULL)
                cerr << "hello\n";
        if (((pch +strlen(pch) +1) != NULL) && (*(pch + strlen(pch) + 1) == '"'))
            find_quote = 1;

	    // Ignore after comments
	    if (*pch == '#')
		break;

	    // Check for && and ||
	    // Break input up
	    char * a = strstr(pch, "&&");
	    char * b = strstr(pch, "||");
	    char * c = strstr(pch, ";");
        char * d = strstr(pch, "<");
        char * e = strstr(pch, ">");
        char * f = strstr(pch, "|");

	    // If there are connectors, break up the string
	    // into parts and add them individually to the vector
	    if (a!=NULL || b!=NULL || c!=NULL || d!=NULL || e!=NULL || f!=NULL
                    || (isdigit(*pch) && pch[1] == '>')) {
		while (strlen(pch) != 0 ) {
            if (isdigit(pch[0]) && pch[1] == '>') {
                string tmp;
                int stringlen = 0;
                tmp += *pch;
                tmp += pch[1];
                if (pch[1] == '>' && pch[2] == '>') {
                    tmp += pch[2];
                    stringlen = 3;
                    tmp[3] = '\0';
                    }
                else {
                    stringlen = 2;
                    tmp[2] = '\0';
                }
                input.push_back(tmp);
                memmove(pch, pch +stringlen, strlen(pch) - stringlen);
                pch[strlen(pch) - stringlen] = '\0';

            }

            // Checks for && and ||
            if ((pch[0] == '&' && pch[1] == '&') ||
			(pch[0] == '|' && pch[1] == '|')) {

			    string tmp;
			    tmp += *pch;
			    tmp += *(pch+1);
			    tmp[2] = '\0';

			    input.push_back(tmp);
			    memmove(pch, pch+2, strlen(pch) - 2);
			    pch[strlen(pch)-2] = '\0';
		    }
		    // Check for semicolons
		    else if (*pch == ';') {
			    input.push_back(";");
			    memmove(pch, pch+1, strlen(pch) -1);
			    pch[strlen(pch)-1] = '\0';
		    }
            // Check for input/output redirectors
            else if (*pch == '<' || *pch =='>' || *pch == '|') {
                if (*pch == '>' && *(pch+1) == '>') {
                    input.push_back(">>");
                    memmove(pch, pch+2, strlen(pch)-2);
                    pch[strlen(pch)-2] = '\0';
                }
                else if (*pch == '<' && *(pch+1) == '<' && *(pch+2)=='<') {
                    input.push_back("<<<");
                    memmove(pch, pch+3, strlen(pch)-3);
                    pch[strlen(pch)-3] = '\0';
                }
                else {
                    string tmp;
                    tmp += *pch;
                    tmp[1] = '\0';
                    input.push_back(tmp);
                    memmove(pch, pch+1, strlen(pch)-1);
                    pch[strlen(pch)-1] = '\0';
                }
            }

            else {
			string word;
			int numletters = 0;
			char z = *pch;
			int i = 1;
            while ( z!= '\0' && z!= ';' && z!= '|' && z!= '&' && z!= '<' && z!= '>'
                            && !(isdigit(z) && pch[i] == '>')) {
			    word += z;
			    numletters++;
			    z = pch[i];
                i++;
			}
            if (numletters!=0)
			    input.push_back(word);
			memmove(pch, pch+numletters, strlen(pch) -numletters);
			pch[strlen(pch)-numletters] = '\0';
		    }

		    a = strstr(pch, "&&");
		    b = strstr(pch, "||");
		    c = strstr(pch, ";");
            d = strstr(pch, "<");
            e = strstr(pch, ">");
            f = strstr(pch, "|");
		}
	    }

	    // If no connectors, just add to vector
	    if (*pch != '\0' && *pch != '\n' && *pch != '#') {
            input.push_back(pch);

        }

        if (find_quote == 1)
            pch = strtok(NULL, "\"");
        else
	        pch = strtok (NULL, " \n");
	}
}

void execute(const vector<string> & input, const vector<string> & pathing,
        int start, int end) {

    //Call execvp, based on which elements in the string vector to use
    char * argv[20];

	    int i = 0;
	    int status;

	    for (i = 0; i <= (end - start); i++) {
		argv[i] = new char[20];
	    }

	    for (i = 0; i < (end-start); i++) {
		strcpy(argv[i], input[i+start].c_str());
            }

	    argv[i] = NULL;
            string cmd = argv[0];

            for (unsigned int j = 0; j < pathing.size(); j++) {
                string tmp = pathing[j] + "/" + cmd;
                strcpy(argv[0], tmp.c_str());
                status = execv(argv[0], argv);

            }
	    if (status == -1)
		perror("execv");
		exit(1);
}

void printusrhost() {

    // Get username
    char * usrname;
    struct passwd *pass = getpwuid(getuid());
    usrname = pass->pw_name;
    if (pass == NULL) {
	perror ("getpwuid");
    exit(1);
    }

    // Get hostname
    char hostname[20];

    if (gethostname(hostname, sizeof hostname) ==-1) {
	perror("gethostname");
	exit(1);
    }
    cout << usrname << "@" << hostname <<"$ ";

}

void int_handler(int x) {
        cout << endl;
}

int main() {

    if ((signal(SIGINT, int_handler)) == SIG_ERR)
        perror("signal");

    vector<string> input;
    vector<string> pathing;
    int status=0;
    char *pPath;

    pPath = getenv("PATH");
	if (pPath == NULL)
	    perror("PATH");
    parsePath(pPath, pathing);

    int savestdin;
    if ((savestdin = dup(0)) == -1)
        perror("dup");

    int savestdout;
    if ((savestdout = dup(1)) == -1)
        perror("dup");

    // Main loop
    while (1) {
        //Restore stdin and stdout
        if ((dup2(savestdin,0)) == -1)
            perror("dup2");

        if ((dup2(savestdout,0)) == -1)
            perror("dup2");

    printusrhost();

	status = 0;

	if (input.size() != 0)
	    input.clear();

	string string1;
	getline(cin, string1);

	parse((char *)string1.c_str(), input);

    //debugging
    //cerr << "AFTER PARSING: \n";
    //for (int i = 0; i < input.size(); i++)
            //cerr << input[i] << endl;

	if (input.size() == 0)
	    continue;

    for (unsigned int i = 0; i < input.size(); i++)
	    if (strcmp(input[i].c_str(), "exit") == 0) exit(0);

	int pid=fork();
    if (pid == -1)
        perror ("fork");
	int pid2;
	if (pid == 0) {
	    int start = 0;
	    int end = input.size();
	    unsigned i;

loop:
        end = input.size();

        for (i = start; i < input.size(); ) {

            if (input[i] == "cd") {
                string directory =  input[i+1];
                int ret;
                ret = chdir(directory.c_str());
                if (ret == -1)
                    perror ("chdir");

                if ((i+2) >= input.size())
                    exit(0);
                else if (input[i+2] == ";" || input[i+2] == "&&") {
                    start = i+3;
                    goto loop;
                }

            }

            //input output redirection
            if (input[i] == ">" || input[i] == ">>" || input[i]=="<"
                            || input[i] == "<<<" || input[i] == "|"
                            || (isdigit(input[i][0]) && input[i][1] == '>')) {

                if ((isdigit(input[i][0]) && input[i][1] == '>') || input[i][0] == '>') {

                    int flags = 0;
                    int file_no = 1;
                    flags |= O_CREAT | O_WRONLY;

                    if ((input[i][0] == '>' && input[i][1] == '>') ||
                                input[i][2] == '>')
                            flags |= O_APPEND;
                        else
                            flags |= O_TRUNC;

                    int fdo = open(input[i+1].c_str(), flags, S_IRUSR | S_IWUSR);
                    if (fdo==-1) {
                        perror("open");
                        exit(1);
                    }

                    if (isdigit(input[i][0]))
                        file_no = input[i][0] - '0';

                    status = close(file_no);
                    if (status == -1)
                        perror("close");

                    if ((dup(fdo)) == -1)
                        perror("dup");

                    if ((close(fdo)) == -1)
                        perror("close");

                    input.erase(input.begin() + i);
                    input.erase(input.begin() + i);

                    if (input[i][0] == '>' || input[i][0] == '<' || input[i][0] == '|'
                                            || (isdigit(input[i][0]) && input[i][1] == '>'))
                        continue;

                    else {
                        end = i;
                        break;
                    }

                }

                else if (input[i] == "<") {

                        int fdi = open(input[i+1].c_str(), O_RDONLY, 0);
                        if (fdi==-1) {
                            perror("open");
                            exit(1);
                        }

                        status = close(STDIN_FILENO);
                        if (status == -1)
                            perror("close");

                        if ((dup(fdi)) == -1)
                            perror("dup");

                        if ((close(fdi)) == -1)
                            perror("close");

                        input.erase(input.begin() + i);
                        input.erase(input.begin() + i);

                        if (input[i][0] == '>' || input[i][0] == '<' || input[i][0] == '|'
                                            || (isdigit(input[i][0]) && input[i][1] == '>'))
                            continue;

                        else {
                            end = i;
                            break;
                        }
                }

                else if (input[i] == "<<<") {

                    int pfd[2];

                    if ((pipe(pfd)) == -1)
                        perror("pipe");

                        char buf[128];
                        memset(buf, 0, 128);
                        strcpy(buf, input[i+1].c_str());

                        buf[strlen(buf)] = '\n';
                        buf[strlen(buf)+1] = '\0';

                        if ((write(pfd[1], buf, strlen(buf)) == -1))
                            perror("write");

                        if ((dup2(pfd[0], 0)) == -1)
                            perror("dup2");

                        if (close (pfd[1]) == -1)
                            perror("close");

                        input.erase(input.begin() + i);
                        input.erase(input.begin() + i);

                        if (input[i][0] == '>' || input[i][0] == '<' || input[i][0] == '|'
                                            || (isdigit(input[i][0]) && input[i][1] == '>'))
                            continue;

                        else {
                            end = i;
                            break;
                        }

                }
                else if (input[i] == "|") {
                    int pfd[2];

                    if ((pipe(pfd)) == -1)
                        perror("pipe");

                    int pid3 = fork();
                    if (pid3 == -1) {
                        perror("fork");
                        exit(1);
                    }
                    if (pid3==0) {

                        if ((dup2(pfd[1], 1)) == -1)
                            perror("dup2");

                        if ((close(pfd[0])) == -1)
                            perror("close");

                        end = i;
                        break;

                    }
                    else {
                        if((close(STDIN_FILENO)) == -1)
                            perror("close");

                        if ((dup2(pfd[0], 0)) == -1)
                            perror("dup2");

                        if ((close(pfd[1])) == -1)
                            perror("close");

                        if (-1 == wait(0))
                            perror("wait");

                        start = i+1;
                        goto loop;

                    }

                }
            }

            else if (input[i] == ";" || input[i] == "&&" || input[i] == "||") {

                string connector = input[i];

		        pid2 = fork();
		        if (pid2 == -1) {
			        perror("fork");
			        exit(1);
		        }
		        if (pid2!=0) {
			        if (-1 == wait(&status))
			            perror("wait");

			        if (connector == "&&" && status != 0)
			            exit(1);

			        if (connector == "||" && status == 0)
			            exit(0);

			        start = i + 1;
			        goto loop;

		        }
		        else {
			        end = i;
			        break;
		        }
		    }
	    i++;
        }

	    execute(input, pathing, start, end);

	}
	else {
	    status = wait(NULL);
	    if (status == -1)
		perror("wait");

            //chdir command
        for (int i = 0; i < input.size(); i++) {
            if (strcmp(input[i].c_str(), "cd") == 0) {
                string directory =  input[i+1];
                int ret;
                ret = chdir(directory.c_str());
                if (ret == -1)
                    perror ("chdir");

            }
        }
    }
    }

    exit(0);
}
<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the CutePaste project
 * Copyright (c) 2013 Laszlo Papp <lpapp@kde.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <QSslError>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTcpSocket>

#include <QJsonDocument>
#include <QJsonObject>
#include <QFile>
#include <QScopedPointer>
#include <QTextStream>
#include <QList>
#include <QCoreApplication>

int main(int argc, char **argv)
{
    QCoreApplication application(argc, argv);
    application.setOrganizationName("CutePaste");
    application.setApplicationName("CutePaste Desktop Console Frontend");

    QTextStream standardOutputStream(stdout);

    QFile dataFile;
    dataFile.open(stdin, QIODevice::ReadOnly);

    QNetworkRequest networkRequest;
    networkRequest.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, true);
    networkRequest.setUrl(QUrl("http://sandbox.paste.kde.org/api/json/create"));

    QNetworkAccessManager networkAccessManager;
    QScopedPointer<QNetworkReply> networkReplyScopedPointer(networkAccessManager.post(networkRequest, &dataFile));
    QObject::connect(networkReplyScopedPointer.data(), &QNetworkReply::finished, [&]() {
        QJsonDocument jsonDocument = QJsonDocument::fromJson(networkReplyScopedPointer->readAll());

        if (!jsonDocument.isObject())
            return;

        QJsonObject jsonObject = jsonDocument.object();
        QJsonValue identifierValue = jsonObject.value(QStringLiteral("id"));

        if (identifierValue.isString()) {
            standardOutputStream << identifierValue.toString();
            endl(standardOutputStream);
        }
    });

    QObject::connect(networkReplyScopedPointer.data(), static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), [&](QNetworkReply::NetworkError networkReplyError) {
        if (networkReplyError != QNetworkReply::NoError) {
            QTextStream standardOutputStream2(stdout);
            standardOutputStream2 << networkReplyScopedPointer->errorString();
            // endl(standardOutputStream);
        }
    });

    QObject::connect(networkReplyScopedPointer.data(), &QNetworkReply::sslErrors, [&](QList<QSslError> networkReplySslErrors) {
        if (!networkReplySslErrors.isEmpty()) {
            foreach (const QSslError &networkReplySslError, networkReplySslErrors) {
                standardOutputStream << networkReplySslError.errorString();
                // endl(standardOutputStream);
            }
        }
    });

    bool returnValue = application.exec();

    dataFile.close();
    if (dataFile.error() != QFileDevice::NoError) {
        standardOutputStream << dataFile.errorString();
        // endl(standardOutputStream);
    }

    return returnValue;
}
<commit_msg>Make the cast explicit to the desired signal not to confuse the compiler<commit_after>/******************************************************************************
 * This file is part of the CutePaste project
 * Copyright (c) 2013 Laszlo Papp <lpapp@kde.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <QSslError>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTcpSocket>

#include <QJsonDocument>
#include <QJsonObject>
#include <QFile>
#include <QScopedPointer>
#include <QTextStream>
#include <QList>
#include <QCoreApplication>

int main(int argc, char **argv)
{
    QCoreApplication application(argc, argv);
    application.setOrganizationName("CutePaste");
    application.setApplicationName("CutePaste Desktop Console Frontend");

    QTextStream standardOutputStream(stdout);

    QFile dataFile;
    dataFile.open(stdin, QIODevice::ReadOnly);

    QNetworkRequest networkRequest;
    networkRequest.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, true);
    networkRequest.setUrl(QUrl("http://sandbox.paste.kde.org/api/json/create"));

    QNetworkAccessManager networkAccessManager;
    QScopedPointer<QNetworkReply> networkReplyScopedPointer(networkAccessManager.post(networkRequest, &dataFile));
    QObject::connect(networkReplyScopedPointer.data(), &QNetworkReply::finished, [&]() {
        QJsonDocument jsonDocument = QJsonDocument::fromJson(networkReplyScopedPointer->readAll());

        if (!jsonDocument.isObject())
            return;

        QJsonObject jsonObject = jsonDocument.object();
        QJsonValue identifierValue = jsonObject.value(QStringLiteral("id"));

        if (identifierValue.isString()) {
            standardOutputStream << identifierValue.toString();
            endl(standardOutputStream);
        }
    });

    QObject::connect(networkReplyScopedPointer.data(), static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error), [&](QNetworkReply::NetworkError networkReplyError) {
        if (networkReplyError != QNetworkReply::NoError) {
            QTextStream standardOutputStream2(stdout);
            standardOutputStream2 << networkReplyScopedPointer->errorString();
            endl(standardOutputStream);
        }
    });

    QObject::connect(networkReplyScopedPointer.data(), &QNetworkReply::sslErrors, [&](QList<QSslError> networkReplySslErrors) {
        if (!networkReplySslErrors.isEmpty()) {
            foreach (const QSslError &networkReplySslError, networkReplySslErrors) {
                standardOutputStream << networkReplySslError.errorString();
                endl(standardOutputStream);
            }
        }
    });

    bool returnValue = application.exec();

    dataFile.close();
    if (dataFile.error() != QFileDevice::NoError) {
        standardOutputStream << dataFile.errorString();
        endl(standardOutputStream);
    }

    return returnValue;
}
<|endoftext|>


<commit_before>#include <boost/tokenizer.hpp>
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <cstdlib>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <sstream>
#include <vector>

using namespace std;
using namespace boost;

void execvp(char **ye, int k) {
	ye[k] = NULL;
        int pid = fork();
        if(pid == -1) {
       		perror("fork");
                exit(1);
        }
        if(pid == 0) {
        	int r = execvp(ye[0], ye);
                if(r == -1) {
                       perror("execvp");
                       exit(1);
                }
        }
      	else {
        	if(-1 == waitpid(pid, &pid, 0)) {
                          perror("waitpid");
                }
        }

}

void pipe() {}

void rshell(string &x) {
	char *argv[9];
	int i = 0;
	string going;
	string saad;
	vector<string> arg_s;
	typedef tokenizer< char_separator<char> > tokenizer;
	char_separator<char> sep (" ", "#-;||&&", drop_empty_tokens);
	tokenizer tokens(x, sep);
	for(tokenizer::iterator tok_iter=tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {
		 if(saad == "-") {
			going += *tok_iter;
			going += " ";
		 	saad.append(*tok_iter);
			arg_s.push_back(saad);
			argv[i] = new char[12];
			strcpy(argv[i], const_cast<char*>(saad.c_str()));
			if(*tok_iter == "exit")
				exit(0);
                        ++i;
                        continue;

		  }

                  if(*tok_iter == "-") {
                        saad = *tok_iter;
			going += *tok_iter;
			going += " ";
                        continue;
                  }

	          if(*tok_iter == "#") {
			break;
		  }

		  if(*tok_iter == ";") {
                        ++tok_iter;
                        rshell(going);
                        going.erase(0, going.find(*tok_iter, i));
                        arg_s.clear();
                        i = 0;
                        argv[i] = new char[12];
	          }

		  if(*tok_iter == "&") {
			++tok_iter;
			if(*tok_iter == "&") {
				++tok_iter;
				rshell(going);
				going.erase(0, going.find(*tok_iter, i));
				arg_s.clear();
				i = 0;
				argv[i] = new char[12];
			}
		  }

		  if(*tok_iter == "|") {
			++tok_iter;
			if(*tok_iter == "|") {
				++tok_iter;
				rshell(going);
				going.erase(0, going.find(*tok_iter, i));
				arg_s.clear();
				i = 0;
				argv[i] = new char[12];
			}

		  }

		  going += *tok_iter;
		  going += " ";

		  arg_s.push_back(*tok_iter);
		  argv[i] = new char[12];
	 	  strcpy(argv[i], const_cast<char*>(arg_s[i].c_str()));

		  if(*tok_iter == "exit")
			exit(0);

		  ++i;

	}
	execvp(argv, i);

	return;
}

int main()
{
	string args;
	while(1 != 2)
	{
		cout << "$ ";
		getline(cin, args);
		rshell(args);
	}

	return 0;
}
<commit_msg>rshell.cpp updated<commit_after>#include <boost/tokenizer.hpp>
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <cstdlib>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <sstream>
#include <vector>
#include <sys/stat.h>
#include <fcntl.h>

using namespace std;

using namespace boost;

void execvp(char **ye, int k) {
	ye[k] = NULL;
        int pid = fork();
        if(pid == -1) {
       		perror("fork");
                exit(1);
        }
        if(pid == 0) {
        	int r = execvp(ye[0], ye);
                if(r == -1) {
                       perror("execvp");
                       exit(1);
                }
        }
      	else {
        	if(-1 == waitpid(pid, &pid, 0)) {
                          perror("waitpid");
                }
        }

}

void rshell(string &x) {
	char *argv[9];
	int i = 0;
	string going;
	string saad;
	vector<string> arg_s;
	typedef tokenizer< char_separator<char> > tokenizer;
	char_separator<char> sep (" ", "<>>>\"#-;||&&", drop_empty_tokens);
	tokenizer tokens(x, sep);
	for(tokenizer::iterator tok_iter=tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {

		if(saad == "-") {
			if(*tok_iter == "-") {
				saad += *tok_iter;
				going += *tok_iter;
				continue;
			}
			going += *tok_iter;
			going += " ";
		 	saad.append(*tok_iter);
			arg_s.push_back(saad);
			argv[i] = new char[12];
			strcpy(argv[i], const_cast<char*>(saad.c_str()));
			if(*tok_iter == "exit")
				exit(0);
                        ++i;
                        continue;

		  }

                  if(*tok_iter == "-") {
                        saad = *tok_iter;
			going += *tok_iter;
                        continue;
                  }

	          if(*tok_iter == "#") {
			break;
		  }

		  if(*tok_iter == ";") {
                        ++tok_iter;
                        rshell(going);
                        going.erase(0, going.find(*tok_iter, i));
                        arg_s.clear();
                        i = 0;
                        argv[i] = new char[12];
	          }

		  if(*tok_iter == "&") {
			++tok_iter;
			if(*tok_iter == "&") {
				++tok_iter;
				rshell(going);
				going.erase(0, going.find(*tok_iter, i));
				arg_s.clear();
				i = 0;
				argv[i] = new char[12];
			}
		  }

		  if(*tok_iter == "<") {
			++tok_iter;

			if(*tok_iter == "<") {
			//	going += *tok_iter;
				++tok_iter;
			//	going += *tok_iter;
				if(*tok_iter == "<") {
					//EXTRA CREDIT 1 HERE!!!!!!!!!!
				//	char *buf = new char[sizeof(BUFSIZ)];
				//	int fd5 = open("ok.string", O_CREAT | O_WRONLY, S_IWUSR);
				//	if(fd5 == -1) {
				//		perror("open");
				//		exit(1);
				//	}

				//	int bag = write(fd5, buf, BUFSIZ);
				//	if(bag == -1) {
				//		perror("write");
				//		exit(1);
				//	}
					++tok_iter;
					going += *tok_iter;
					string leggo;
				if(*tok_iter == "\"") {
				//	if(dup2(fd5, 0) == -1)
				//		perror("dup2");

				//	int savestdin = dup(0);
				//	if(savestdin == -1)
				//		perror("dup");
				//	if(*tok_iter == "\"") {
						++tok_iter;
						while(*tok_iter != "\"") {
						//	int bag = write(fd5, buf, BUFSIZ);
						//	if(bag == -1) {
						//		perror("write");
						//		exit(1);
						//	}

							cout << *tok_iter << endl;
							leggo += *tok_iter;
							leggo += " ";
							++tok_iter;
						}
						leggo += *tok_iter;
						going += " ";
						going += leggo;
						cout << leggo << endl;
						//int bag = write(fd2, buf, BUFSIZ);
						//if(bag == -1) {
						//	perror("write");
						//	exit(1);
						//}
					}
				//	int claw = read(fd2, buf, BUFSIZ);
				//	if(claw == -1)
				//		perror("read");

			//		int mk = close(fd5);
			//		if(mk == -1)
			//			perror("close");
			//		delete [] buf;
			//		if(dup2(savestdin, 0) == -1)
			//			perror("dup2");
				}
			}
			string cake = *tok_iter;
			int savestdin;
			if(-1 == (savestdin = dup(0))) {
				perror("dup");
				exit(1);
			}
			int fd = open(cake.c_str(), O_RDWR);
			if(fd == -1) {
				perror("open");
				exit(1);
			}
			int drag = dup2(fd, 0);
			if(drag == -1) {
				perror("dup2");
				exit(1);
			}
			//if(-1 == dup2(savestdin, 0))
			//{
			//	perror("dup2");
			//	exit(1);
			//}
			continue;
		  }

		  if(*tok_iter == "0") {
			if(*tok_iter == ">") {
				++tok_iter;
				if(*tok_iter == ">") {
					++tok_iter;
					string swerve = *tok_iter;
					int fd2 = open(swerve.c_str(), O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
					if(fd2 == -1) {
						perror("open");
						exit(1);
					}
					int grag = dup2(fd2, 0);
					if(grag == -1) {
						perror("dup2");
						exit(1);
					}
					continue;
				}
				else {
					string hold = *tok_iter;
					int fd = open(hold.c_str(), O_RDWR|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR);
					if(fd == -1) {
						perror("open");
						exit(1);
					}
					int drag = dup2(fd, 0);
					if(drag == -1) {
						perror("dup2");
						exit(1);
					}
					continue;
				}
		  	}

		  }

		  if(*tok_iter == "1") {
			if(*tok_iter == ">") {
				++tok_iter;
				if(*tok_iter == ">") {
					++tok_iter;
					string swerve = *tok_iter;
					int fd2 = open(swerve.c_str(), O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
					if(fd2 == -1) {
						perror("open");
						exit(1);
					}
					int grag = dup2(fd2, 1);
					if(grag == -1) {
						perror("dup2");
						exit(1);
					}
					continue;
				}
				else {
					string hold = *tok_iter;
					int fd = open(hold.c_str(), O_RDWR|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR);
					if(fd == -1) {
						perror("open");
						exit(1);
					}
					int drag = dup2(fd, 1);
					if(drag == -1) {
						perror("dup2");
						exit(1);
					}
					continue;
				}
		  	}
		  }

		  if(*tok_iter == "2") {
			if(*tok_iter == ">") {
				++tok_iter;
				if(*tok_iter == ">") {
					++tok_iter;
					string swerve = *tok_iter;
					int fd2 = open(swerve.c_str(), O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
					if(fd2 == -1) {
						perror("open");
						exit(1);
					}
					int grag = dup2(fd2, 2);
					if(grag == -1) {
						perror("dup2");
						exit(1);
					}
					continue;
				}
				else {
					string hold = *tok_iter;
					int fd = open(hold.c_str(), O_RDWR|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR);
					if(fd == -1) {
						perror("open");
						exit(1);
					}
					int drag = dup2(fd, 2);
					if(drag == -1) {
						perror("dup2");
						exit(1);
					}
					continue;
				}
		  	}
		  }

		  if(*tok_iter == ">") {
			++tok_iter;
			if(*tok_iter == ">") {
				++tok_iter;
				string swerve = *tok_iter;
				int fd2 = open(swerve.c_str(), O_RDWR|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
				if(fd2 == -1) {
					perror("open");
					exit(1);
				}
				int grag = dup2(fd2, 1);
				if(grag == -1) {
					perror("dup2");
					exit(1);
				}
				continue;
			}
			else {
				string hold = *tok_iter;
				int fd = open(hold.c_str(), O_RDWR|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR);
				if(fd == -1) {
					perror("open");
					exit(1);
				}
				int drag = dup2(fd, 1);
				if(drag == -1) {
					perror("dup2");
					exit(1);
				}
				continue;
			}
		  }

		  if(*tok_iter == "|") {
			++tok_iter;
			tokenizer::iterator coward;
			if(*tok_iter != "|") {
			//piping
				int pipefd[2];
				pid_t cpid;
				//char buf;
				if(pipe(pipefd) == -1) {
					perror("pipe");
					exit(1);
				}
				cpid = fork();
				if(cpid == -1) {
					perror("fork");
					exit(1);
				}
				else if(cpid == 0) {
					if(-1 == dup2(pipefd[1],1))
					{
						perror("dup2");
						exit(1);
					}
					if(-1 == close(pipefd[0]))
					{
						perror("close");
						exit(1);
					}
					argv[i] = NULL;
					if(-1 == execvp(argv[0], argv))
					{
						perror("execvp");
					}
					exit(1);
				}
				else if(cpid > 0)
				{
					int savestdin;
					if(-1 == (savestdin = dup(0)))
					{
						perror("dup");
						exit(1);
					}
					if(-1 == dup2(pipefd[0], 0)) {
						perror("dup2");
						exit(1);
					}
					if(-1 == close(pipefd[1])) {
						perror("close");
						exit(1);
					}
					if(-1 == waitpid(cpid, &cpid, 0)) {
						perror("waitpid");
						exit(1);
					}

					int pipefd2[2];
					pid_t cpid2;
					string temp;
					if(pipe(pipefd2) == -1) {
						perror("pipe");
						exit(1);
					}
					cpid2 = fork();
					if(cpid2 == -1) {
						perror("fork");
						exit(1);
					}
					else if(cpid2 == 0) {
						if(-1 == dup2(pipefd2[1], 1))
						{
							perror("dup2");
							exit(1);
						}
						if(-1 == close(pipefd2[0]))
						{
							perror("close");
							exit(1);
						}
						while(tok_iter != tokens.end()) {
							//temp += *tok_iter;
							cerr << temp << endl;
							if((*tok_iter).size() == 1) {
								temp += *tok_iter; //A
								++tok_iter;
								temp += *tok_iter; //A-
								++tok_iter;
								temp += *tok_iter; //A-Z
								temp += " ";
								++tok_iter;
							}
							else
							{
								temp += *tok_iter;
								temp += " ";
								++tok_iter;
							}
						}
							cout << temp << endl;
							char *toby[9];
							int l = 0;
							string goin;
						//	string saad;
							vector<string> ar;
						//	typedef tokenizer< char_separator<char> > tokenizer;
							char_separator<char> sep (" ", "<>>>\"#-;||&&", drop_empty_tokens);
							tokenizer tokens(temp, sep);
							for(tokenizer::iterator tok_iter2=tokens.begin(); tok_iter2 != tokens.end(); ++tok_iter2) {
								 ar.push_back(*tok_iter2);
								 toby[l] = new char[12];
	 	 						 strcpy(toby[l], const_cast<char*>(ar[l].c_str()));
		  						 ++l;
							}
							toby[l] = NULL;
							if(-1 == execvp(toby[0], toby)) {
								perror("execvp");
							}

							exit(1);
					}
					else if(cpid > 0) {
						int savestdin;
						if(-1 == (savestdin = dup(0)))
						{
							perror("dup");
							exit(1);
						}
						if(-1 == dup2(pipefd2[0], 0)) {
							perror("dup2");
							exit(1);
						}
						if(-1 == close(pipefd2[1])) {
							perror("close");
							exit(1);
						}
						if(-1 == waitpid(cpid2, &cpid2, 0)) {
							perror("waitpid");
							exit(1);
						}
					//if(-1 == dup2(savestdout, 1))
					//	perror("dup2");
					}
							//if(-1 == dup2(savestdin, 0))
					//	perror("dup2");

				//tok_iter = coward;
					continue;
				}
			}//end piping
			else if(*tok_iter == "|") {
				++tok_iter;
				rshell(going);
				going.erase(0, going.find(*tok_iter, i));
				arg_s.clear();
				i = 0;
				argv[i] = new char[12];
			}

		  }

		  tokenizer::iterator daw = tok_iter;
		  string lop = *tok_iter;
		  string llop;
		  if((*tok_iter).size() == 1) {
			++tok_iter;
			if(*tok_iter == "-") {
				llop += lop;
				llop += *tok_iter;
		//		cerr << mok << endl;
				++tok_iter;
		//		llop += *tok_iter;
		//		cerr << mok << endl;
		//		++tok_iter;
				llop += *tok_iter;
				llop += " ";
		//		cerr << mok << endl;
				++tok_iter;

				going += llop;
				going += " ";

			//	cerr << llop << "ADASDOAKSDOKAS" << endl;
				arg_s.push_back(llop);
				argv[i] = new char[12];
				strcpy(argv[i], const_cast<char*>(arg_s[i].c_str()));
				++i;
				continue;
			}
			tok_iter = daw;
		  }

		  going += *tok_iter;
		  going += " ";
//		  cout << going << endl;

		  arg_s.push_back(*tok_iter);
		  argv[i] = new char[12];
	 	  strcpy(argv[i], const_cast<char*>(arg_s[i].c_str()));

		  if(*tok_iter == "exit")
			exit(0);

		  ++i;

	}

	execvp(argv, i);

	return;
}

int main()
{
	int oldstdin = dup(0);

	if(oldstdin == -1)
		perror("dup");

	int oldstdout = dup(1);

	if(oldstdout == -1)
		perror("dup");

	int oldstderr = dup(2);

	if(oldstderr == -1)
		perror("dup");

	string args;
	while(1 != 2)
	{
		cout << "$ ";
		getline(cin, args);
		rshell(args);

		int ok = dup2(oldstdin, 0);
		if(ok == -1) {
			perror("dup2");
			exit(1);
		}
		int ok2 = dup2(oldstdout, 1);
		if(ok2 == -1) {
			perror("dup2");
			exit(1);
		}
		int ok3 = dup2(oldstderr, 2);
		if(ok3 == -1) {
			perror("dup2");
			exit(1);
		}
	}

	return 0;
}
<|endoftext|>


<commit_before>//===- IndexingContext.cpp - Indexing context data ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "IndexingContext.h"
#include "clang/Index/IndexDataConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/SourceManager.h"

using namespace clang;
using namespace index;

bool IndexingContext::shouldIndexFunctionLocalSymbols() const {
  return IndexOpts.IndexFunctionLocals;
}

bool IndexingContext::handleDecl(const Decl *D,
                                 SymbolRoleSet Roles,
                                 ArrayRef<SymbolRelation> Relations) {
  return handleDeclOccurrence(D, D->getLocation(), /*IsRef=*/false,
                              cast<Decl>(D->getDeclContext()), Roles, Relations,
                              nullptr, nullptr, D->getDeclContext());
}

bool IndexingContext::handleDecl(const Decl *D, SourceLocation Loc,
                                 SymbolRoleSet Roles,
                                 ArrayRef<SymbolRelation> Relations,
                                 const DeclContext *DC) {
  if (!DC)
    DC = D->getDeclContext();
  return handleDeclOccurrence(D, Loc, /*IsRef=*/false, cast<Decl>(DC),
                              Roles, Relations,
                              nullptr, nullptr, DC);
}

bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
                                      const NamedDecl *Parent,
                                      const DeclContext *DC,
                                      SymbolRoleSet Roles,
                                      ArrayRef<SymbolRelation> Relations,
                                      const Expr *RefE,
                                      const Decl *RefD) {
  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D))
    return true;

  if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D))
    return true;

  return handleDeclOccurrence(D, Loc, /*IsRef=*/true, Parent, Roles, Relations,
                              RefE, RefD, DC);
}

bool IndexingContext::importedModule(const ImportDecl *ImportD) {
  SourceLocation Loc;
  auto IdLocs = ImportD->getIdentifierLocs();
  if (!IdLocs.empty())
    Loc = IdLocs.front();
  else
    Loc = ImportD->getLocation();
  SourceManager &SM = Ctx->getSourceManager();
  Loc = SM.getFileLoc(Loc);
  if (Loc.isInvalid())
    return true;

  FileID FID;
  unsigned Offset;
  std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
  if (FID.isInvalid())
    return true;

  bool Invalid = false;
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
  if (Invalid || !SEntry.isFile())
    return true;

  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
    switch (IndexOpts.SystemSymbolFilter) {
    case IndexingOptions::SystemSymbolFilterKind::None:
    case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
      return true;
    case IndexingOptions::SystemSymbolFilterKind::All:
      break;
    }
  }

  SymbolRoleSet Roles = (unsigned)SymbolRole::Reference;
  if (ImportD->isImplicit())
    Roles |= (unsigned)SymbolRole::Implicit;

  return DataConsumer.handleModuleOccurence(ImportD, Roles, FID, Offset);
}

bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
  assert(D);

  if (isa<TemplateTemplateParmDecl>(D))
    return true;

  if (isa<ObjCTypeParamDecl>(D))
    return true;

  if (!D->getParentFunctionOrMethod())
    return false;

  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
    switch (ND->getFormalLinkage()) {
    case NoLinkage:
    case VisibleNoLinkage:
    case InternalLinkage:
      return true;
    case UniqueExternalLinkage:
      llvm_unreachable("Not a sema linkage");
    case ExternalLinkage:
      return false;
    }
  }

  return true;
}

bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
  TemplateSpecializationKind TKind = TSK_Undeclared;
  if (const ClassTemplateSpecializationDecl *
      SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
    TKind = SD->getSpecializationKind();
  }
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
    TKind = FD->getTemplateSpecializationKind();
  }
  switch (TKind) {
    case TSK_Undeclared:
    case TSK_ExplicitSpecialization:
      return false;
    case TSK_ImplicitInstantiation:
    case TSK_ExplicitInstantiationDeclaration:
    case TSK_ExplicitInstantiationDefinition:
      return true;
  }
  llvm_unreachable("invalid TemplateSpecializationKind");
}

bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) {
  if (isa<ObjCInterfaceDecl>(D))
    return false;
  if (isa<ObjCCategoryDecl>(D))
    return false;
  if (isa<ObjCIvarDecl>(D))
    return false;
  if (isa<ObjCMethodDecl>(D))
    return false;
  if (isa<ImportDecl>(D))
    return false;
  return true;
}

static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
  if (const ClassTemplateSpecializationDecl *
      SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
    return SD->getTemplateInstantiationPattern();
  }
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
    return FD->getTemplateInstantiationPattern();
  }
  return nullptr;
}

static bool isDeclADefinition(const Decl *D, ASTContext &Ctx) {
  if (auto VD = dyn_cast<VarDecl>(D))
    return VD->isThisDeclarationADefinition(Ctx);

  if (auto FD = dyn_cast<FunctionDecl>(D))
    return FD->isThisDeclarationADefinition();

  if (auto TD = dyn_cast<TagDecl>(D))
    return TD->isThisDeclarationADefinition();

  if (auto MD = dyn_cast<ObjCMethodDecl>(D))
    return MD->isThisDeclarationADefinition();

  if (isa<TypedefNameDecl>(D) ||
      isa<EnumConstantDecl>(D) ||
      isa<FieldDecl>(D) ||
      isa<MSPropertyDecl>(D) ||
      isa<ObjCImplDecl>(D) ||
      isa<ObjCPropertyImplDecl>(D))
    return true;

  return false;
}

static const Decl *adjustParent(const Decl *Parent) {
  if (!Parent)
    return nullptr;
  for (;; Parent = cast<Decl>(Parent->getDeclContext())) {
    if (isa<TranslationUnitDecl>(Parent))
      return nullptr;
    if (isa<LinkageSpecDecl>(Parent) || isa<BlockDecl>(Parent))
      continue;
    if (auto NS = dyn_cast<NamespaceDecl>(Parent)) {
      if (NS->isAnonymousNamespace())
        continue;
    } else if (auto RD = dyn_cast<RecordDecl>(Parent)) {
      if (RD->isAnonymousStructOrUnion())
        continue;
    } else if (auto FD = dyn_cast<FieldDecl>(Parent)) {
      if (FD->getDeclName().isEmpty())
        continue;
    }
    return Parent;
  }
}

static const Decl *getCanonicalDecl(const Decl *D) {
  D = D->getCanonicalDecl();
  if (auto TD = dyn_cast<TemplateDecl>(D)) {
    D = TD->getTemplatedDecl();
    assert(D->isCanonicalDecl());
  }

  return D;
}

bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
                                           bool IsRef, const Decl *Parent,
                                           SymbolRoleSet Roles,
                                           ArrayRef<SymbolRelation> Relations,
                                           const Expr *OrigE,
                                           const Decl *OrigD,
                                           const DeclContext *ContainerDC) {
  if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
    return true;
  if (!isa<NamedDecl>(D) ||
      (cast<NamedDecl>(D)->getDeclName().isEmpty() &&
       !isa<TagDecl>(D) && !isa<ObjCCategoryDecl>(D)))
    return true;

  SourceManager &SM = Ctx->getSourceManager();
  Loc = SM.getFileLoc(Loc);
  if (Loc.isInvalid())
    return true;

  FileID FID;
  unsigned Offset;
  std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
  if (FID.isInvalid())
    return true;

  bool Invalid = false;
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
  if (Invalid || !SEntry.isFile())
    return true;

  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
    switch (IndexOpts.SystemSymbolFilter) {
    case IndexingOptions::SystemSymbolFilterKind::None:
      return true;
    case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
      if (IsRef)
        return true;
      break;
    case IndexingOptions::SystemSymbolFilterKind::All:
      break;
    }
  }

  if (isTemplateImplicitInstantiation(D)) {
    if (!IsRef)
      return true;
    D = adjustTemplateImplicitInstantiation(D);
    if (!D)
      return true;
    assert(!isTemplateImplicitInstantiation(D));
  }

  if (!OrigD)
    OrigD = D;

  if (IsRef)
    Roles |= (unsigned)SymbolRole::Reference;
  else if (isDeclADefinition(D, *Ctx))
    Roles |= (unsigned)SymbolRole::Definition;
  else
    Roles |= (unsigned)SymbolRole::Declaration;

  D = getCanonicalDecl(D);
  if (D->isImplicit() && !isa<ObjCMethodDecl>(D)) {
    // operator new declarations will link to the implicit one as canonical.
    return true;
  }
  Parent = adjustParent(Parent);
  if (Parent)
    Parent = getCanonicalDecl(Parent);
  assert(!Parent || !Parent->isImplicit() ||
         isa<FunctionDecl>(Parent) ||
         isa<ObjCInterfaceDecl>(Parent) || isa<ObjCMethodDecl>(Parent) &&
         "unexpected implicit parent!");

  SmallVector<SymbolRelation, 6> FinalRelations;
  FinalRelations.reserve(Relations.size()+1);

  auto addRelation = [&](SymbolRelation Rel) {
    auto It = std::find_if(FinalRelations.begin(), FinalRelations.end(),
                [&](SymbolRelation Elem)->bool {
                  return Elem.RelatedSymbol == Rel.RelatedSymbol;
                });
    if (It != FinalRelations.end()) {
      It->Roles |= Rel.Roles;
    } else {
      FinalRelations.push_back(Rel);
    }
    Roles |= Rel.Roles;
  };

  if (!IsRef && Parent && !cast<DeclContext>(Parent)->isFunctionOrMethod()) {
    addRelation(SymbolRelation{(unsigned)SymbolRole::RelationChildOf, Parent});
  }
  for (auto &Rel : Relations) {
    addRelation(SymbolRelation(Rel.Roles,
                               Rel.RelatedSymbol->getCanonicalDecl()));
  }

  IndexDataConsumer::ASTNodeInfo Node{ OrigE, OrigD, Parent, ContainerDC };
  return DataConsumer.handleDeclOccurence(D, Roles, FinalRelations, FID, Offset,
                                          Node);
}
<commit_msg>Pacify gcc's parenthesis warning, which doesn't realize that parens don't matter here.<commit_after>//===- IndexingContext.cpp - Indexing context data ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "IndexingContext.h"
#include "clang/Index/IndexDataConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/SourceManager.h"

using namespace clang;
using namespace index;

bool IndexingContext::shouldIndexFunctionLocalSymbols() const {
  return IndexOpts.IndexFunctionLocals;
}

bool IndexingContext::handleDecl(const Decl *D,
                                 SymbolRoleSet Roles,
                                 ArrayRef<SymbolRelation> Relations) {
  return handleDeclOccurrence(D, D->getLocation(), /*IsRef=*/false,
                              cast<Decl>(D->getDeclContext()), Roles, Relations,
                              nullptr, nullptr, D->getDeclContext());
}

bool IndexingContext::handleDecl(const Decl *D, SourceLocation Loc,
                                 SymbolRoleSet Roles,
                                 ArrayRef<SymbolRelation> Relations,
                                 const DeclContext *DC) {
  if (!DC)
    DC = D->getDeclContext();
  return handleDeclOccurrence(D, Loc, /*IsRef=*/false, cast<Decl>(DC),
                              Roles, Relations,
                              nullptr, nullptr, DC);
}

bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
                                      const NamedDecl *Parent,
                                      const DeclContext *DC,
                                      SymbolRoleSet Roles,
                                      ArrayRef<SymbolRelation> Relations,
                                      const Expr *RefE,
                                      const Decl *RefD) {
  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D))
    return true;

  if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D))
    return true;

  return handleDeclOccurrence(D, Loc, /*IsRef=*/true, Parent, Roles, Relations,
                              RefE, RefD, DC);
}

bool IndexingContext::importedModule(const ImportDecl *ImportD) {
  SourceLocation Loc;
  auto IdLocs = ImportD->getIdentifierLocs();
  if (!IdLocs.empty())
    Loc = IdLocs.front();
  else
    Loc = ImportD->getLocation();
  SourceManager &SM = Ctx->getSourceManager();
  Loc = SM.getFileLoc(Loc);
  if (Loc.isInvalid())
    return true;

  FileID FID;
  unsigned Offset;
  std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
  if (FID.isInvalid())
    return true;

  bool Invalid = false;
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
  if (Invalid || !SEntry.isFile())
    return true;

  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
    switch (IndexOpts.SystemSymbolFilter) {
    case IndexingOptions::SystemSymbolFilterKind::None:
    case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
      return true;
    case IndexingOptions::SystemSymbolFilterKind::All:
      break;
    }
  }

  SymbolRoleSet Roles = (unsigned)SymbolRole::Reference;
  if (ImportD->isImplicit())
    Roles |= (unsigned)SymbolRole::Implicit;

  return DataConsumer.handleModuleOccurence(ImportD, Roles, FID, Offset);
}

bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
  assert(D);

  if (isa<TemplateTemplateParmDecl>(D))
    return true;

  if (isa<ObjCTypeParamDecl>(D))
    return true;

  if (!D->getParentFunctionOrMethod())
    return false;

  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
    switch (ND->getFormalLinkage()) {
    case NoLinkage:
    case VisibleNoLinkage:
    case InternalLinkage:
      return true;
    case UniqueExternalLinkage:
      llvm_unreachable("Not a sema linkage");
    case ExternalLinkage:
      return false;
    }
  }

  return true;
}

bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
  TemplateSpecializationKind TKind = TSK_Undeclared;
  if (const ClassTemplateSpecializationDecl *
      SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
    TKind = SD->getSpecializationKind();
  }
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
    TKind = FD->getTemplateSpecializationKind();
  }
  switch (TKind) {
    case TSK_Undeclared:
    case TSK_ExplicitSpecialization:
      return false;
    case TSK_ImplicitInstantiation:
    case TSK_ExplicitInstantiationDeclaration:
    case TSK_ExplicitInstantiationDefinition:
      return true;
  }
  llvm_unreachable("invalid TemplateSpecializationKind");
}

bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) {
  if (isa<ObjCInterfaceDecl>(D))
    return false;
  if (isa<ObjCCategoryDecl>(D))
    return false;
  if (isa<ObjCIvarDecl>(D))
    return false;
  if (isa<ObjCMethodDecl>(D))
    return false;
  if (isa<ImportDecl>(D))
    return false;
  return true;
}

static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
  if (const ClassTemplateSpecializationDecl *
      SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
    return SD->getTemplateInstantiationPattern();
  }
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
    return FD->getTemplateInstantiationPattern();
  }
  return nullptr;
}

static bool isDeclADefinition(const Decl *D, ASTContext &Ctx) {
  if (auto VD = dyn_cast<VarDecl>(D))
    return VD->isThisDeclarationADefinition(Ctx);

  if (auto FD = dyn_cast<FunctionDecl>(D))
    return FD->isThisDeclarationADefinition();

  if (auto TD = dyn_cast<TagDecl>(D))
    return TD->isThisDeclarationADefinition();

  if (auto MD = dyn_cast<ObjCMethodDecl>(D))
    return MD->isThisDeclarationADefinition();

  if (isa<TypedefNameDecl>(D) ||
      isa<EnumConstantDecl>(D) ||
      isa<FieldDecl>(D) ||
      isa<MSPropertyDecl>(D) ||
      isa<ObjCImplDecl>(D) ||
      isa<ObjCPropertyImplDecl>(D))
    return true;

  return false;
}

static const Decl *adjustParent(const Decl *Parent) {
  if (!Parent)
    return nullptr;
  for (;; Parent = cast<Decl>(Parent->getDeclContext())) {
    if (isa<TranslationUnitDecl>(Parent))
      return nullptr;
    if (isa<LinkageSpecDecl>(Parent) || isa<BlockDecl>(Parent))
      continue;
    if (auto NS = dyn_cast<NamespaceDecl>(Parent)) {
      if (NS->isAnonymousNamespace())
        continue;
    } else if (auto RD = dyn_cast<RecordDecl>(Parent)) {
      if (RD->isAnonymousStructOrUnion())
        continue;
    } else if (auto FD = dyn_cast<FieldDecl>(Parent)) {
      if (FD->getDeclName().isEmpty())
        continue;
    }
    return Parent;
  }
}

static const Decl *getCanonicalDecl(const Decl *D) {
  D = D->getCanonicalDecl();
  if (auto TD = dyn_cast<TemplateDecl>(D)) {
    D = TD->getTemplatedDecl();
    assert(D->isCanonicalDecl());
  }

  return D;
}

bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
                                           bool IsRef, const Decl *Parent,
                                           SymbolRoleSet Roles,
                                           ArrayRef<SymbolRelation> Relations,
                                           const Expr *OrigE,
                                           const Decl *OrigD,
                                           const DeclContext *ContainerDC) {
  if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
    return true;
  if (!isa<NamedDecl>(D) ||
      (cast<NamedDecl>(D)->getDeclName().isEmpty() &&
       !isa<TagDecl>(D) && !isa<ObjCCategoryDecl>(D)))
    return true;

  SourceManager &SM = Ctx->getSourceManager();
  Loc = SM.getFileLoc(Loc);
  if (Loc.isInvalid())
    return true;

  FileID FID;
  unsigned Offset;
  std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
  if (FID.isInvalid())
    return true;

  bool Invalid = false;
  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
  if (Invalid || !SEntry.isFile())
    return true;

  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
    switch (IndexOpts.SystemSymbolFilter) {
    case IndexingOptions::SystemSymbolFilterKind::None:
      return true;
    case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
      if (IsRef)
        return true;
      break;
    case IndexingOptions::SystemSymbolFilterKind::All:
      break;
    }
  }

  if (isTemplateImplicitInstantiation(D)) {
    if (!IsRef)
      return true;
    D = adjustTemplateImplicitInstantiation(D);
    if (!D)
      return true;
    assert(!isTemplateImplicitInstantiation(D));
  }

  if (!OrigD)
    OrigD = D;

  if (IsRef)
    Roles |= (unsigned)SymbolRole::Reference;
  else if (isDeclADefinition(D, *Ctx))
    Roles |= (unsigned)SymbolRole::Definition;
  else
    Roles |= (unsigned)SymbolRole::Declaration;

  D = getCanonicalDecl(D);
  if (D->isImplicit() && !isa<ObjCMethodDecl>(D)) {
    // operator new declarations will link to the implicit one as canonical.
    return true;
  }
  Parent = adjustParent(Parent);
  if (Parent)
    Parent = getCanonicalDecl(Parent);
  assert((!Parent || !Parent->isImplicit() || isa<FunctionDecl>(Parent) ||
          isa<ObjCInterfaceDecl>(Parent) || isa<ObjCMethodDecl>(Parent)) &&
         "unexpected implicit parent!");

  SmallVector<SymbolRelation, 6> FinalRelations;
  FinalRelations.reserve(Relations.size()+1);

  auto addRelation = [&](SymbolRelation Rel) {
    auto It = std::find_if(FinalRelations.begin(), FinalRelations.end(),
                [&](SymbolRelation Elem)->bool {
                  return Elem.RelatedSymbol == Rel.RelatedSymbol;
                });
    if (It != FinalRelations.end()) {
      It->Roles |= Rel.Roles;
    } else {
      FinalRelations.push_back(Rel);
    }
    Roles |= Rel.Roles;
  };

  if (!IsRef && Parent && !cast<DeclContext>(Parent)->isFunctionOrMethod()) {
    addRelation(SymbolRelation{(unsigned)SymbolRole::RelationChildOf, Parent});
  }
  for (auto &Rel : Relations) {
    addRelation(SymbolRelation(Rel.Roles,
                               Rel.RelatedSymbol->getCanonicalDecl()));
  }

  IndexDataConsumer::ASTNodeInfo Node{ OrigE, OrigD, Parent, ContainerDC };
  return DataConsumer.handleDeclOccurence(D, Roles, FinalRelations, FID, Offset,
                                          Node);
}
<|endoftext|>


<commit_before>#include <bits/stdc++.h>
using namespace std;

int main()
{
    cin.tie(NULL);
    ios_base::sync_with_stdio(0);

    int houses, a, b, c, x, y, z, row1, row2, row3;

    cin >> houses;
    cin >> row1 >> row2 >> row3;

    while(--houses)
    {
        cin >> a >> b >> c;

        x = a + min(row2, row3);
        y = b + min(row1, row3);
        z = c + min(row1, row2);

        row1 = x;
        row2 = y;
        row3 = z;
}

    cout << min(row1, min(row2, row3)) << "\n";
    return 0;
}<commit_msg>spoj/02-srednie/ROZ.cc<commit_after>int main() { }<|endoftext|>


<commit_before>/*  This file is part of the KDE project.

Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 or 3 of the License.

This library 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <QUrl>
#include <QTimer>
#include <QWidget>

#include <coemain.h>	// For CCoeEnv
#include <coecntrl.h>

#include "videoplayer.h"
#include "utils.h"

using namespace Phonon;
using namespace Phonon::MMF;

//-----------------------------------------------------------------------------
// Constructor / destructor
//-----------------------------------------------------------------------------

MMF::VideoPlayer::VideoPlayer()
								:	m_wsSession(NULL)
								,	m_screenDevice(NULL)
								,	m_window(NULL)
								,   m_totalTime(0)
{
	construct();
}

MMF::VideoPlayer::VideoPlayer(const AbstractPlayer& player)
								:	AbstractMediaPlayer(player)
								,	m_wsSession(NULL)
								,	m_screenDevice(NULL)
								,	m_window(NULL)
                                ,   m_totalTime(0)
{
	construct();
}

void MMF::VideoPlayer::construct()
{
	TRACE_CONTEXT(VideoPlayer::VideoPlayer, EVideoApi);
	TRACE_ENTRY_0();

	if(!m_videoOutput)
	{
		m_dummyVideoOutput.reset(new VideoOutput(NULL));
	}

	videoOutput().setObserver(this);

	const TInt priority = 0;
	const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone;

	getNativeWindowSystemHandles();

	// TODO: is this the correct way to handle errors which occur when
	// creating a Symbian object in the constructor of a Qt object?
	TRAPD(err,
		m_player = CVideoPlayerUtility::NewL
			(
			*this,
			priority, preference,
			*m_wsSession, *m_screenDevice,
			*m_window,
			m_windowRect, m_clipRect
			)
		);

	if(KErrNone != err)
	{
		changeState(ErrorState);
	}

	TRACE_EXIT_0();
}

MMF::VideoPlayer::~VideoPlayer()
{
	TRACE_CONTEXT(VideoPlayer::~VideoPlayer, EVideoApi);
    TRACE_ENTRY_0();

	delete m_player;

	TRACE_EXIT_0();
}

//-----------------------------------------------------------------------------
// Public API
//-----------------------------------------------------------------------------

void MMF::VideoPlayer::doPlay()
{
	m_player->Play();
}

void MMF::VideoPlayer::doPause()
{
	TRACE_CONTEXT(VideoPlayer::doPause, EVideoApi);

	TRAPD(err, m_player->PauseL());
	if(KErrNone != err)
	{
		TRACE("PauseL error %d", err);
		setError(NormalError);
	}
}

void MMF::VideoPlayer::doStop()
{
	m_player->Stop();
}

void MMF::VideoPlayer::doSeek(qint64 ms)
{
    TRACE_CONTEXT(VideoPlayer::doSeek, EVideoApi);

    TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000)));

    if(KErrNone != err)
    {
        TRACE("SetPositionL error %d", err);
        setError(NormalError);
    }
}

int MMF::VideoPlayer::setDeviceVolume(int mmfVolume)
{
	TRAPD(err, m_player->SetVolumeL(mmfVolume));
	return err;
}

int MMF::VideoPlayer::openFile(RFile& file)
{
	TRAPD(err, m_player->OpenFileL(file));
	return err;
}

void MMF::VideoPlayer::close()
{
	m_player->Close();
}

bool MMF::VideoPlayer::hasVideo() const
{
	return true;
}

qint64 MMF::VideoPlayer::currentTime() const
{
	TRACE_CONTEXT(VideoPlayer::currentTime, EVideoApi);

	TTimeIntervalMicroSeconds us;
    TRAPD(err, us = m_player->PositionL())

    qint64 result = 0;

    if(KErrNone == err)
    {
        result = toMilliSeconds(us);
    }
    else
    {
		TRACE("PositionL error %d", err);

		// If we don't cast away constness here, we simply have to ignore
		// the error.
    	const_cast<VideoPlayer*>(this)->setError(NormalError);
    }

    return result;
}

qint64 MMF::VideoPlayer::totalTime() const
{
    return m_totalTime;
}

//-----------------------------------------------------------------------------
// MVideoPlayerUtilityObserver callbacks
//-----------------------------------------------------------------------------

void MMF::VideoPlayer::MvpuoOpenComplete(TInt aError)
{
	TRACE_CONTEXT(VideoPlayer::MvpuoOpenComplete, EVideoApi);
    TRACE_ENTRY("state %d error %d", state(), aError);

    __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));

	if(KErrNone == aError)
	{
		m_player->Prepare();
	}
	else
	{
		// TODO: set different error states according to value of aError?
		setError(NormalError);
	}

    TRACE_EXIT_0();
}

void MMF::VideoPlayer::MvpuoPrepareComplete(TInt aError)
{
	TRACE_CONTEXT(VideoPlayer::MvpuoPrepareComplete, EVideoApi);
	TRACE_ENTRY("state %d error %d", state(), aError);

    __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));

    TRAPD(err, doPrepareCompleteL(aError));

	if(KErrNone == err)
	{
		maxVolumeChanged(m_player->MaxVolume());

		videoOutput().setFrameSize(m_frameSize);

        emit totalTimeChanged(totalTime());
        changeState(StoppedState);
	}
    else
	{
	    // TODO: set different error states according to value of aError?
	    setError(NormalError);
	}

	TRACE_EXIT_0();
}

void MMF::VideoPlayer::doPrepareCompleteL(TInt aError)
{
    User::LeaveIfError(aError);

    // Get frame size
    TSize size;
    m_player->VideoFrameSizeL(size);
    m_frameSize = QSize(size.iWidth, size.iHeight);

    // Get duration
    m_totalTime = toMilliSeconds(m_player->DurationL());
}

void MMF::VideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError)
{
	TRACE_CONTEXT(VideoPlayer::MvpuoFrameReady, EVideoApi);
	TRACE_ENTRY("state %d error %d", state(), aError);

	// TODO
	Q_UNUSED(aFrame);
	Q_UNUSED(aError);	// suppress warnings in release builds

	TRACE_EXIT_0();
}

void MMF::VideoPlayer::MvpuoPlayComplete(TInt aError)
{
	TRACE_CONTEXT(VideoPlayer::MvpuoPlayComplete, EVideoApi)
	TRACE_ENTRY("state %d error %d", state(), aError);

	// TODO
	Q_UNUSED(aError);	// suppress warnings in release builds

	TRACE_EXIT_0();
}

void MMF::VideoPlayer::MvpuoEvent(const TMMFEvent &aEvent)
{
	TRACE_CONTEXT(VideoPlayer::MvpuoEvent, EVideoApi);
	TRACE_ENTRY("state %d", state());

	// TODO
	Q_UNUSED(aEvent);

	TRACE_EXIT_0();
}

//-----------------------------------------------------------------------------
// VideoOutputObserver
//-----------------------------------------------------------------------------

void MMF::VideoPlayer::videoOutputRegionChanged()
{
    TRACE_CONTEXT(VideoPlayer::videoOutputRegionChanged, EVideoInternal);
    TRACE_ENTRY_0();

#ifdef PHONON_MMF_DEBUG_VIDEO_OUTPUT
    videoOutput().dump();
#endif

    getNativeWindowSystemHandles();

    TRAPD(err,
        m_player->SetDisplayWindowL
            (
            *m_wsSession, *m_screenDevice,
            *m_window,
            m_windowRect, m_clipRect
            )
        );

    if(KErrNone != err)
    {
        TRACE("SetDisplayWindowL error %d", err);
        setError(NormalError);
    }

    TRACE_EXIT_0();
}

//-----------------------------------------------------------------------------
// Private functions
//-----------------------------------------------------------------------------

VideoOutput& MMF::VideoPlayer::videoOutput()
{
	TRACE_CONTEXT(VideoPlayer::videoOutput, EVideoInternal);
	TRACE("videoOutput 0x%08x dummy 0x%08x", m_videoOutput, m_dummyVideoOutput.data());

	return m_videoOutput ? *m_videoOutput : *m_dummyVideoOutput;
}

void MMF::VideoPlayer::videoOutputChanged()
{
	TRACE_CONTEXT(VideoPlayer::videoOutputChanged, EVideoInternal);
	TRACE_ENTRY_0();

	// Lazily construct a dummy output if needed here
	if(!m_videoOutput and m_dummyVideoOutput.isNull())
	{
		m_dummyVideoOutput.reset(new VideoOutput(NULL));
	}

	videoOutput().setObserver(this);

	videoOutput().setFrameSize(m_frameSize);

	videoOutputRegionChanged();

	TRACE_EXIT_0();
}

void MMF::VideoPlayer::getNativeWindowSystemHandles()
{
	TRACE_CONTEXT(VideoPlayer::getNativeWindowSystemHandles, EVideoInternal);

	VideoOutput& output = videoOutput();
	CCoeControl* const control = output.winId();

	TRACE("control 0x%08x", control);
	TRACE("control isVisible %d", control->IsVisible());
	TRACE("control isDimmed  %d", control->IsDimmed());
	TRACE("control hasBorder %d", control->HasBorder());
	TRACE("control position  %d %d",
		control->Position().iX, control->Position().iY);
	TRACE("control rect      %d %d - %d %d",
		control->Rect().iTl.iX, control->Rect().iTl.iY,
		control->Rect().iBr.iX, control->Rect().iBr.iY);

	CCoeEnv* const coeEnv = control->ControlEnv();

	m_wsSession = &(coeEnv->WsSession());

	TRACE("session handle    0x%08x", m_wsSession->Handle());

	m_screenDevice = coeEnv->ScreenDevice();

	TRACE("device srv handle 0x%08x", m_screenDevice->WsHandle());

	m_window = control->DrawableWindow();

	TRACE("window cli handle 0x%08x", m_window->ClientHandle());
	TRACE("window srv handle 0x%08x", m_window->WsHandle());
	TRACE("window group      %d", m_window->WindowGroupId());
	TRACE("window position   %d %d",
		m_window->Position().iX, m_window->Position().iY);
	TRACE("window abs_pos    %d %d",
	    m_window->AbsPosition().iX, m_window->AbsPosition().iY);
	TRACE("window size       %d %d",
        m_window->Size().iWidth, m_window->Size().iHeight);

#ifdef PHONON_MMF_HARD_CODE_VIDEO_RECT
	// HACK: why isn't control->Rect updated following a call to
	// updateGeometry on the parent widget?
	m_windowRect = TRect(0,100,320,250);
#else
	m_windowRect = control->Rect();
#endif

	m_clipRect = m_windowRect;
}
<commit_msg>Added more tracing to VideoPlayer<commit_after>/*  This file is part of the KDE project.

Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).

This library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 or 3 of the License.

This library 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <QUrl>
#include <QTimer>
#include <QWidget>

#include <coemain.h>	// For CCoeEnv
#include <coecntrl.h>

#include "videoplayer.h"
#include "utils.h"

using namespace Phonon;
using namespace Phonon::MMF;

//-----------------------------------------------------------------------------
// Constructor / destructor
//-----------------------------------------------------------------------------

MMF::VideoPlayer::VideoPlayer()
								:	m_wsSession(NULL)
								,	m_screenDevice(NULL)
								,	m_window(NULL)
								,   m_totalTime(0)
{
	construct();
}

MMF::VideoPlayer::VideoPlayer(const AbstractPlayer& player)
								:	AbstractMediaPlayer(player)
								,	m_wsSession(NULL)
								,	m_screenDevice(NULL)
								,	m_window(NULL)
                                ,   m_totalTime(0)
{
	construct();
}

void MMF::VideoPlayer::construct()
{
	TRACE_CONTEXT(VideoPlayer::VideoPlayer, EVideoApi);
	TRACE_ENTRY_0();

	if(!m_videoOutput)
	{
		m_dummyVideoOutput.reset(new VideoOutput(NULL));
	}

	videoOutput().setObserver(this);

	const TInt priority = 0;
	const TMdaPriorityPreference preference = EMdaPriorityPreferenceNone;

	getNativeWindowSystemHandles();

	// TODO: is this the correct way to handle errors which occur when
	// creating a Symbian object in the constructor of a Qt object?
	TRAPD(err,
		m_player = CVideoPlayerUtility::NewL
			(
			*this,
			priority, preference,
			*m_wsSession, *m_screenDevice,
			*m_window,
			m_windowRect, m_clipRect
			)
		);

	if(KErrNone != err)
	{
		changeState(ErrorState);
	}

	TRACE_EXIT_0();
}

MMF::VideoPlayer::~VideoPlayer()
{
	TRACE_CONTEXT(VideoPlayer::~VideoPlayer, EVideoApi);
    TRACE_ENTRY_0();

	delete m_player;

	TRACE_EXIT_0();
}

//-----------------------------------------------------------------------------
// Public API
//-----------------------------------------------------------------------------

void MMF::VideoPlayer::doPlay()
{
	m_player->Play();
}

void MMF::VideoPlayer::doPause()
{
	TRACE_CONTEXT(VideoPlayer::doPause, EVideoApi);

	TRAPD(err, m_player->PauseL());
	if(KErrNone != err)
	{
		TRACE("PauseL error %d", err);
		setError(NormalError);
	}
}

void MMF::VideoPlayer::doStop()
{
	m_player->Stop();
}

void MMF::VideoPlayer::doSeek(qint64 ms)
{
    TRACE_CONTEXT(VideoPlayer::doSeek, EVideoApi);

    TRAPD(err, m_player->SetPositionL(TTimeIntervalMicroSeconds(ms * 1000)));

    if(KErrNone != err)
    {
        TRACE("SetPositionL error %d", err);
        setError(NormalError);
    }
}

int MMF::VideoPlayer::setDeviceVolume(int mmfVolume)
{
	TRAPD(err, m_player->SetVolumeL(mmfVolume));
	return err;
}

int MMF::VideoPlayer::openFile(RFile& file)
{
	TRAPD(err, m_player->OpenFileL(file));
	return err;
}

void MMF::VideoPlayer::close()
{
	m_player->Close();
}

bool MMF::VideoPlayer::hasVideo() const
{
	return true;
}

qint64 MMF::VideoPlayer::currentTime() const
{
	TRACE_CONTEXT(VideoPlayer::currentTime, EVideoApi);

	TTimeIntervalMicroSeconds us;
    TRAPD(err, us = m_player->PositionL())

    qint64 result = 0;

    if(KErrNone == err)
    {
        result = toMilliSeconds(us);
    }
    else
    {
		TRACE("PositionL error %d", err);

		// If we don't cast away constness here, we simply have to ignore
		// the error.
    	const_cast<VideoPlayer*>(this)->setError(NormalError);
    }

    return result;
}

qint64 MMF::VideoPlayer::totalTime() const
{
    return m_totalTime;
}

//-----------------------------------------------------------------------------
// MVideoPlayerUtilityObserver callbacks
//-----------------------------------------------------------------------------

void MMF::VideoPlayer::MvpuoOpenComplete(TInt aError)
{
	TRACE_CONTEXT(VideoPlayer::MvpuoOpenComplete, EVideoApi);
    TRACE_ENTRY("state %d error %d", state(), aError);

    __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));

	if(KErrNone == aError)
	{
		m_player->Prepare();
	}
	else
	{
		// TODO: set different error states according to value of aError?
		setError(NormalError);
	}

    TRACE_EXIT_0();
}

void MMF::VideoPlayer::MvpuoPrepareComplete(TInt aError)
{
	TRACE_CONTEXT(VideoPlayer::MvpuoPrepareComplete, EVideoApi);
	TRACE_ENTRY("state %d error %d", state(), aError);

    __ASSERT_ALWAYS(LoadingState == state(), Utils::panic(InvalidStatePanic));

    TRAPD(err, doPrepareCompleteL(aError));

	if(KErrNone == err)
	{
		maxVolumeChanged(m_player->MaxVolume());

		videoOutput().setFrameSize(m_frameSize);

        emit totalTimeChanged(totalTime());
        changeState(StoppedState);
	}
    else
	{
	    // TODO: set different error states according to value of aError?
	    setError(NormalError);
	}

	TRACE_EXIT_0();
}

void MMF::VideoPlayer::doPrepareCompleteL(TInt aError)
{
    User::LeaveIfError(aError);

    // Get frame size
    TSize size;
    m_player->VideoFrameSizeL(size);
    m_frameSize = QSize(size.iWidth, size.iHeight);

    // Get duration
    m_totalTime = toMilliSeconds(m_player->DurationL());
}

void MMF::VideoPlayer::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError)
{
	TRACE_CONTEXT(VideoPlayer::MvpuoFrameReady, EVideoApi);
	TRACE_ENTRY("state %d error %d", state(), aError);

	// TODO
	Q_UNUSED(aFrame);
	Q_UNUSED(aError);	// suppress warnings in release builds

	TRACE_EXIT_0();
}

void MMF::VideoPlayer::MvpuoPlayComplete(TInt aError)
{
	TRACE_CONTEXT(VideoPlayer::MvpuoPlayComplete, EVideoApi)
	TRACE_ENTRY("state %d error %d", state(), aError);

	// TODO
	Q_UNUSED(aError);	// suppress warnings in release builds

	TRACE_EXIT_0();
}

void MMF::VideoPlayer::MvpuoEvent(const TMMFEvent &aEvent)
{
	TRACE_CONTEXT(VideoPlayer::MvpuoEvent, EVideoApi);
	TRACE_ENTRY("state %d", state());

	// TODO
	Q_UNUSED(aEvent);

	TRACE_EXIT_0();
}

//-----------------------------------------------------------------------------
// VideoOutputObserver
//-----------------------------------------------------------------------------

void MMF::VideoPlayer::videoOutputRegionChanged()
{
    TRACE_CONTEXT(VideoPlayer::videoOutputRegionChanged, EVideoInternal);
    TRACE_ENTRY_0();

#ifdef PHONON_MMF_DEBUG_VIDEO_OUTPUT
    videoOutput().dump();
#endif

    getNativeWindowSystemHandles();

    TRAPD(err,
        m_player->SetDisplayWindowL
            (
            *m_wsSession, *m_screenDevice,
            *m_window,
            m_windowRect, m_clipRect
            )
        );

    if(KErrNone != err)
    {
        TRACE("SetDisplayWindowL error %d", err);
        setError(NormalError);
    }

    TRACE_EXIT_0();
}

//-----------------------------------------------------------------------------
// Private functions
//-----------------------------------------------------------------------------

VideoOutput& MMF::VideoPlayer::videoOutput()
{
	TRACE_CONTEXT(VideoPlayer::videoOutput, EVideoInternal);
	TRACE("videoOutput 0x%08x dummy 0x%08x", m_videoOutput, m_dummyVideoOutput.data());

	return m_videoOutput ? *m_videoOutput : *m_dummyVideoOutput;
}

void MMF::VideoPlayer::videoOutputChanged()
{
	TRACE_CONTEXT(VideoPlayer::videoOutputChanged, EVideoInternal);
	TRACE_ENTRY_0();

	// Lazily construct a dummy output if needed here
	if(!m_videoOutput and m_dummyVideoOutput.isNull())
	{
		m_dummyVideoOutput.reset(new VideoOutput(NULL));
	}

	videoOutput().setObserver(this);

	videoOutput().setFrameSize(m_frameSize);

	videoOutputRegionChanged();

	TRACE_EXIT_0();
}

void MMF::VideoPlayer::getNativeWindowSystemHandles()
{
	TRACE_CONTEXT(VideoPlayer::getNativeWindowSystemHandles, EVideoInternal);

	VideoOutput& output = videoOutput();
	CCoeControl* const control = output.winId();

	TRACE("control               0x%08x", control);
	TRACE("control IsVisible     %d", control->IsVisible());
	TRACE("control IsDimmed      %d", control->IsDimmed());
	TRACE("control HasBorder     %d", control->HasBorder());
	TRACE("control Position      %d %d",
		control->Position().iX, control->Position().iY);
	TRACE("control Rect          %d %d - %d %d",
		control->Rect().iTl.iX, control->Rect().iTl.iY,
		control->Rect().iBr.iX, control->Rect().iBr.iY);
	TRACE("control OwnsWindow    %d", control->OwnsWindow());

	CCoeEnv* const coeEnv = control->ControlEnv();

	m_wsSession = &(coeEnv->WsSession());

	TRACE("session Handle        0x%08x", m_wsSession->Handle());

	m_screenDevice = coeEnv->ScreenDevice();

	TRACE("device WsHandle       0x%08x", m_screenDevice->WsHandle());

	m_window = control->DrawableWindow();

	TRACE("window ClientHandle   0x%08x", m_window->ClientHandle());
	TRACE("window WsHandle       0x%08x", m_window->WsHandle());
	TRACE("window WindowGroupId  %d", m_window->WindowGroupId());
	TRACE("window Position       %d %d",
		m_window->Position().iX, m_window->Position().iY);
	TRACE("window AbsPosition    %d %d",
	    m_window->AbsPosition().iX, m_window->AbsPosition().iY);
	TRACE("window Size           %d %d",
        m_window->Size().iWidth, m_window->Size().iHeight);

#ifdef PHONON_MMF_HARD_CODE_VIDEO_RECT
	// HACK: why isn't control->Rect updated following a call to
	// updateGeometry on the parent widget?
	m_windowRect = TRect(0,100,320,250);
#else
	m_windowRect = control->Rect();
#endif

	m_clipRect = m_windowRect;
}
<|endoftext|>


<commit_before>#include "filename/ast/filename-node-conditional.h"
#include "filename/ast/filename-visitor.h"

FilenameNodeConditional::FilenameNodeConditional(FilenameNodeCondition *condition, FilenameNode *ifTrue, FilenameNode *ifFalse)
	: condition(condition), ifTrue(ifTrue), ifFalse(ifFalse)
{}

FilenameNodeConditional::~FilenameNodeConditional()
{
	delete condition;
	delete ifTrue;
	delete ifFalse;
}

void FilenameNodeConditional::accept(FilenameVisitor &v) const
{
	v.visit(*this);
}
<commit_msg>Fix warning about deleting non full type<commit_after>#include "filename/ast/filename-node-conditional.h"
#include "filename/ast/filename-node-condition.h"
#include "filename/ast/filename-visitor.h"

FilenameNodeConditional::FilenameNodeConditional(FilenameNodeCondition *condition, FilenameNode *ifTrue, FilenameNode *ifFalse)
	: condition(condition), ifTrue(ifTrue), ifFalse(ifFalse)
{}

FilenameNodeConditional::~FilenameNodeConditional()
{
	delete condition;
	delete ifTrue;
	delete ifFalse;
}

void FilenameNodeConditional::accept(FilenameVisitor &v) const
{
	v.visit(*this);
}
<|endoftext|>


<commit_before><commit_msg>set AA_UseHighDpiPixmaps flag in attempt to fix pixelated icons<commit_after><|endoftext|>