/* * main * class: None */ int main(int argc, char **argv) { Manager m; // The todo list manager. string homedir = getenv("HOME"); string filename = homedir+"/todo.txt"; // default file bool invalidArgs = argc < 2; bool parsing = true; // Whether it's still parsing argument int command = -1; // The switch code for command int subCom = -1; // The switch code for sub commands. int comInd = -1; // The index of the command in argv int ac = -1; // number of arguments for a command int task = -1; // The task number being amended. int x = -1, y = -1; // Hold argument values. ifstream fin; // The input filestream ofstream fout; // The output filestream. // scan the command line arguments for(int i = 1; i < argc && !invalidArgs && parsing; ++i) { string s = argv[i]; // determine what type of argument it is if(s[0] == '-') { // option // check if it has the necessary arguments given // set the associated flags if(s.compare("-f") == 0 || s.compare("--file") == 0) { // check if there is another argument, which should be the file // name. if(1 < (argc-i)) { filename = argv[i+1]; i++; } else { invalidArgs = true; } } else { // There are no other options I recognize at the moment. invalidArgs = true; } } else { // it's a command parsing = false; comInd = i; ac = (argc - comInd - 1); if(s.compare("add") == 0) { command = ADD; } else if(s.compare("amend") == 0) { command = AMEND; } else if(s.compare("demote") == 0) { command = DEMOTE; } else if(s.compare("help") == 0) { command = HELP; } else if(s.compare("list") == 0) { command = LIST; } else if(s.compare("promote") == 0) { command = PROMOTE; } else if(s.compare("remove") == 0) { command = REMOVE; } else if(s.compare("swap") == 0) { command = SWAP; } else if(s.compare("top") == 0) { command = TOP; } else { invalidArgs = true; } } } if(invalidArgs) { displayHelp(cout); exit(1); } fin.open(filename.c_str()); m.read(fin); fin.close(); // read in the file. // do the command switch(command) { case ADD: if(0 < ac) { Task t; t.setTitle(argv[comInd+1]); for(int i = comInd+2; i < argc; ++i) { t.addItem(argv[i]); } m.addTask(t); fout.open(filename.c_str()); m.write(fout); fout.close(); } else { cout << "Invalid number of arguments." << endl; exit(1); } break; case AMEND: if(ac < 3) { cout << "Not enough arguments given." << endl; exit(1); } if(!isNumeric(argv[comInd+1])) { cout << "Non-numeric value given for the task number." << endl; exit(1); } task = atoi(argv[comInd+1]); // determine what changes is actually going to be made. // add item, remove item, change item, change title. if(strcmp(argv[comInd+2],"add") == 0 ) { for(int i = comInd+3; i < argc; ++i) { m.addItem(task,argv[i]); } } else if(strcmp(argv[comInd+2],"mod")==0) { if(!isNumeric(argv[comInd+3])) { cout << "Non-numeric value given for item index." << endl; exit(1); } if(ac < 4) { cout << "Not enough arguments given." << endl; exit(1); } y = atoi(argv[comInd+3]); if(!m.setItem(task,y,argv[comInd+4])) { cout << "An error occured." << endl; exit(1); } } else if(strcmp(argv[comInd+2],"promote")==0) { // Attempt to promote a subitem if(ac < 4) { cout << "Not enough arguments given to promote item.\n"; } // check that the two arguments given are numeric if(!isNumeric(argv[comInd+3]) || !isNumeric(argv[comInd+4])) { cout << "Non-numeric arguments given for promotion.\n"; } x = atoi(argv[comInd+3]); y = atoi(argv[comInd+4]); m.promoteItem(task,x,y); } else if(strcmp(argv[comInd+2],"demote")==0) { // Attempt to demote a subitem if(ac < 4) { cout << "Not enough arguments given to demote item.\n"; } // check that the two arguments given are numeric if(!isNumeric(argv[comInd+3]) || !isNumeric(argv[comInd+4])) { cout << "Non-numeric arguments given for demotion.\n"; } x = atoi(argv[comInd+3]); y = atoi(argv[comInd+4]); m.demoteItem(task,x,y); } else if(strcmp(argv[comInd+2],"remove")==0) { if(!isNumeric(argv[comInd+3])) { cout << "Non-numeric value given for the item." << endl; exit(1); } m.removeItem(task,atoi(argv[comInd+3])); } else if(strcmp(argv[comInd+2],"rename")==0) { // Attempt to set the title if(!m.setTitle(task,argv[comInd+3])) { cout << "An error has occured." << endl; exit(1); } } fout.open(filename.c_str()); m.write(fout); fout.close(); break; case DEMOTE: if(ac != 2) { cout << "Invalid number of arguments." << endl; exit(1); } if(!isNumeric(argv[comInd+1]) && !isNumeric(argv[comInd+2])) { cout << "Non-numeric argument given." << endl; exit(1); } x = atoi(argv[comInd+1]); y = atoi(argv[comInd+2]); m.demote(x,y); fout.open(filename.c_str()); m.write(fout); fout.close(); break; case HELP: // Display a simple help message // Eventually this should parse argument passed to display // information about as specific command. displayHelp(cout); break; case LIST: // there are several options for this. // If there is no arguments past the command, it will list // everything. If there is one it will only list that one. If there // are two it will list an inclusive range. switch(ac) { case 0: cout << m; break; case 1: if(isNumeric(argv[comInd+1])) { x = atoi(argv[comInd+1]); if(0 <= x && x < m.getNumberOfTasks()) { cout << "(" << x << ")" << m.getTask(x) << endl; } else { cout << "Error. Task does not exist." << endl; exit(1); } } else { cout << "Non numeric argument given for list." << endl; exit(1); } break; case 2: if(isNumeric(argv[comInd+1]) && isNumeric(argv[comInd+2])){ x = atoi(argv[comInd+1]); y = atoi(argv[comInd+2]); if(0 <= x && x < y) { for(int i = x; i <= y && i < m.getNumberOfTasks(); ++i){ cout << "(" << i << ")" << m.getTask(i) << endl; } } } else { cout << "Non numeric argument given for list." << endl; exit(1); } break; default: displayHelp(cout); exit(1); break; } break; case PROMOTE: if(ac < 1) { // display the help cout << "Wrong number of arguments given." << endl; exit(1); } if(!isNumeric(argv[comInd+1]) && !isNumeric(argv[comInd+2])) { cout << "Non-numeric argument given." << endl; exit(1); } x = atoi(argv[comInd+1]); // The item being promoted if( ac == 1) { y = 1; // promote the item by only one } else { y = atoi(argv[comInd+2]); } m.promote(x,y); fout.open(filename.c_str()); m.write(fout); fout.close(); break; case REMOVE: // Remove the nth task. if(ac < 1) { cout << "Not enough arguments given." << endl; exit(1); } if(!isNumeric(argv[comInd+1])) { cout << "Non-numeric argument given." << endl; exit(1); } x = atoi(argv[comInd+1]); m.removeTask(x); fout.open(filename.c_str()); m.write(fout); fout.close(); break; case SWAP: // Swap the priorty/position of two tasks. if(ac != 2) { cout << "Wrong number of arguments given." << endl; exit(1); } if(!isNumeric(argv[comInd+1]) && !isNumeric(argv[comInd+2])) { cout << "Non-numeric argument given." << endl; exit(1); } x = atoi(argv[comInd+1]); y = atoi(argv[comInd+2]); m.swapTasks(x,y); fout.open(filename.c_str()); m.write(fout); fout.close(); break; case TOP: // Display the top (n) tasks. if(ac == 0) { // display the top task cout << "(0) " << m.getTask(0) << endl; } else { // display the top n tasks if(!isNumeric(argv[comInd+1])) { cout << "Non-numeric argument given." << endl; exit(1); } x = atoi(argv[comInd+1]); for(int i = 0; i < x; ++i) { cout << "(" << i << ") " << m.getTask(i) << endl; } } break; default: displayHelp(cout); exit(1); break; } return 0; }