void sortList(struct node *head){ struct node *sort[3]; sort[0] = head; sort[1] = (node*) nshNext(head); //sort[2] = (node*) nshMalloc(sizeof(struct node)); sort[2] = (node*) malloc (sizeof(struct node)); while (TRUE){ if (strcmp(sort[0]->name,sort[1]->name) > 0) { strcpy(sort[2]->name, sort[0]->name); strcpy(sort[2]->value, sort[0]->value); strcpy(sort[0]->name, sort[1]->name); strcpy(sort[0]->value, sort[1]->value); strcpy(sort[1]->name, sort[2]->name); strcpy(sort[1]->value, sort[2]->value); // start again at the beginning of the list sort[0] = head; sort[1] = (node*) nshNext(head); } else{ if (sort[1]->next != NULL){ sort[0] = sort[1]; sort[1] = (node*) nshNext(sort[1]); } else{ break; } } } }
//Delete Function void nshDelete(EnvP *list, char* name){ EnvP temp, prev; temp = *list; while(temp!=NULL) { if(strcmp(temp->name,name) == 0) { if(temp==*list) { *list=temp->next; nshFree(temp); } else { prev->next=temp->next; nshFree(temp); } break; } else { prev=temp; nshNext(&temp); } } }
void printVarList(struct node *head){ // create a node to track the place struct node *place; place = head; if (place != NULL) { printf("%s=%s\n",place->name,place->value); while(place->next != NULL){ place = (node*) nshNext(place); printf("%s=%s\n",place->name, place->value); } } }
//Update function nshUpdate(EnvP *list, char* name, char* value){ EnvP temp; temp = *list; while(temp!=NULL) { if(strcmp(temp->name,name) == 0) { strcpy(temp->value,value); break; } else { nshNext(&temp); } } }
// print all the nodes in list with their values void printVarList(struct node *head){ // create a node to track the place struct node *place; place = head; int x = 0; int flag = 0; if (place != NULL) { while(x < strlen(place->value)) { //check if value is complex alias if(place->value[x] == '{') { flag = 0; break; } else if(place->value[x] ==' ') { //if so, print brackets. flag = 1; break; } x++; } if(flag == 1) { printf("%s {%s}\n", place->name, place->value); } else printf("%s %s\n",place->name,place->value); while(place->next != NULL){ flag = 0; //reset flag. place = (node*) nshNext(place); while(x < strlen(place->value)) { //check if value is complex string if(place->value[x] == '{') { flag = 0; break; } else if(place->value[x] == ' ') { //if so, print brackets around it. flag = 1; break; } x++; } if(flag == 1) { printf("%s {%s}\n", place->name, place->value); } else printf("%s %s\n",place->name, place->value); } } }
bool matchAlias(struct node *head, char *command, char *varName){ // create a node to track the place struct node *place; place = head; if (place != NULL) { if (strcmp(place->name,command) == 0 && strcmp(place->value,varName)==0) { return TRUE; } else { while(place != NULL){ if (strcmp(place->name,command) == 0 && strcmp(place->value,varName)==0) { return TRUE; } else { place = (node*) nshNext(place); } } } } return FALSE; }
//Insert function void nshInsert(EnvP *list, char *name, char *value){ EnvP temp = (EnvP) nshMalloc(sizeof(struct env)); if (temp == NULL) { return; } EnvP left,right; right = *list; int found = 0; int i; left = NULL; strcpy(temp->name,name); strcpy(temp->value,value); //Checks to see if list is empty if (right == NULL) { *list=temp; (*list)->next = NULL; return; } //If list is not empty, insert new item alphabetically while(right != NULL && found == 0) { for (i = 0; i < sizeof(right->name);i++) { //If letter matches,keep checking current var if (right->name[i] == name[i]) { found = 1; continue; } //if new var is after current var, keep searching else if (right->name[i] < name[i]) { left=right; nshNext(&right); break; } //if new var is before current var else if (right->name[i] > name[i]) { found = 1; break; } } } //Store new value //Checks if new value will be first in list if (left == NULL) { temp->next = *list; *list = temp; } else { left->next = temp; temp->next = right; } }
int main() { // boolean values bool needToExecuteProgram, extendVariable, extendAtBack, extendAtFront, didComplete, checkAlias; // counters int wordCount, loopCount, tempCount, arrayPosition_x, arrayPosition_y; // strings char commandInput[100],tempWord[20],userCommand[10][30], temp[50], temp2[50], temp3[50]; // commands & variables char *command, *arg1, *arg2, *arg3, *extending; // declare list heads struct node *varHP; struct node *aliasHP; // init to null varHP = NULL; aliasHP = NULL; char mem[1000]; initialize_globals(mem, 1000); memset(mem, 0, 1000); //all values need to be initialized to 0. // get command input needToExecuteProgram = TRUE; while (needToExecuteProgram) { // print shell prompt wordCount = 0; prompt; fgets(commandInput, 100, stdin); // For @var to display if(commandInput[0] == '@') { int temporary = strlen(commandInput) -2; //to ignore "@" and "\n" in input char temporary2[temporary]; int x = 1,y = 0;; //skip the @ while(y < temporary) { if(commandInput[x] == '\n') //break at the newline, we don't want that included break; temporary2[y] = commandInput[x]; x++; //temporary[2] will hold the variable name. y++; } temporary2[y] = '\0'; nshFind(varHP, temporary2); continue; } //end of @var display // break up input string from user into an array of strings to interpret tempCount = arrayPosition_x = arrayPosition_y = 0; // loop through each character of the string entered from the command line for (loopCount=0; loopCount<strlen(commandInput)-1; loopCount++) { // if a space is found if (commandInput[loopCount] == space) { // end the temp word tempWord[tempCount] = EOS; // place it in the command array arrayPosition_y = 0; wordCount++; while (TRUE) { if (tempWord[arrayPosition_y] == EOS) { userCommand[arrayPosition_x][arrayPosition_y] = EOS; break; } userCommand[arrayPosition_x][arrayPosition_y] = tempWord[arrayPosition_y]; arrayPosition_y++; } // move to get the next word arrayPosition_x++; tempCount = 0; } // while there are no spaces else { // put the characters in a temporary word until one is found tempWord[tempCount] = commandInput[loopCount]; tempCount++; // if there is no space, but its the end of the user's input if (loopCount == strlen(commandInput)-2) { tempWord[tempCount] = EOS; arrayPosition_y = 0; wordCount++; while (TRUE) { if (tempWord[arrayPosition_y] == EOS) { userCommand[arrayPosition_x][arrayPosition_y] = EOS; break; } userCommand[arrayPosition_x][arrayPosition_y] = tempWord[arrayPosition_y]; arrayPosition_y++; } } } } // Implement whatever command was given or print the errors // if there was input if (wordCount > 0) { // get the command command = &userCommand[0][0]; // if the command is "set" if (strcmp(command,"set") == 0 || (matchAlias(aliasHP, "set", command))==TRUE ) { // check for the correct amount of arguments if (wordCount-1 <= 2) { // display all variables if (wordCount == 1) { printVarList(nshHead(varHP)); } // display a variable's specific value else if (wordCount == 2) { arg1 = &userCommand[1][0]; nshFind(nshHead(varHP),arg1); } // set OR reset a variable else { arg1 = &userCommand[1][0]; arg2 = &userCommand[2][0]; strcpy(temp3,userCommand[2]); extendVariable = extendAtFront = extendAtBack = FALSE; // if wanting to extend a variable with the new value on the back if (temp3[0] == '@') { extendAtBack = TRUE; extendVariable = FALSE; // look for the '!' ending variable character for(loopCount=0; loopCount < strlen(temp3); loopCount++) { if (temp3[loopCount] == '!') { extendVariable = TRUE; temp[loopCount-1] = EOS; // get the rest of the string to use to extend variable with loopCount++; int i = 0; for (loopCount; loopCount < strlen(temp3); loopCount++) { temp2[i] = temp3[loopCount]; i++; if (loopCount == (strlen(temp3) -1)) { temp2[i] = EOS; arg2 = temp; arg3 = temp2; break; } } } else if (extendVariable == TRUE) break; else { if (loopCount != 0) temp[loopCount-1] = temp3[loopCount]; } } } // test to see if user wants to extend the variable on the front of it with the new value if (extendAtBack == FALSE) { extendAtFront = FALSE; for(loopCount=0; loopCount < strlen(temp3); loopCount++) { if (temp3[loopCount] == '@' && temp3[loopCount-1] == '!') { int tempSpot, j; j = 0; tempSpot = loopCount + 1; for (tempSpot; tempSpot < strlen(temp3); tempSpot++) { temp[j] = temp3[tempSpot]; j++; } temp[j] = EOS; for (tempSpot = 0; tempSpot < (loopCount-1); tempSpot++) { temp2[tempSpot] = temp3[tempSpot]; } temp2[tempSpot] = EOS; extendAtFront = TRUE; extendVariable = TRUE; arg2 = temp; arg3 = temp2; break; } } } // Set or reset a variable if (extendVariable == FALSE) { // if the head is null if (varHP == NULL){ //varHP = (node*)nshMalloc(sizeof(node)); varHP = (node*) malloc (sizeof(node)); strcpy(varHP->name,&userCommand[1][0]); strcpy(varHP->value, arg2); varHP->next = NULL; } // if need to find its place in the list else { nshInsert(nshHead(varHP), arg1,arg2, VARIABLE); } } else if (extendAtFront == TRUE) { // extendVarValue (node *head, char *set_resetValue, char *getVarValue, char *extendWith, int extendingPosition) didComplete = extendVarValue(nshHead(varHP), arg1, arg2, arg3, varValueInBack); if (didComplete == FALSE) printf("Couldn't extend variable, it doesn't exist\n"); } else { // extendVarValue (node *head, char *set_resetValue, char *getVarValue, char *extendWith, int extendingPosition) didComplete = extendVarValue(nshHead(varHP), arg1, arg2, arg3, varValueInFront); if (didComplete == FALSE) printf("Couldn't extend variable, it doesn't exist\n"); } // reset bool values extendVariable = extendAtFront = extendAtBack = FALSE; } } else { printf("Error - To many arguments for the \"set\" command\n"); continue; } } // if the command is "tes" else if (strcmp(command,"tes") == 0 || (matchAlias(aliasHP, "tes", command))==TRUE ) { // if there are not to many OR to few arguments for this command if (wordCount-1 == 1) { arg1 = &userCommand[1][0]; int status; status = nshRemove(varHP,arg1); if (status == onlyOneNode){ varHP = NULL; } else if (status == popHead){ varHP = (node*) nshNext(varHP); } } else { printf("Error - To many or to few arguments for the \"tes\" command\n"); } } // if the command is "alias" else if (strcmp(command,"alias") == 0 || (matchAlias(aliasHP, "alias", command))==TRUE ) { // if wordCount is 1 - display all aliases (External & Internal) if (wordCount == 1) { printVarList(nshHead(aliasHP)); } // wordCount = 2 - display a specific command alias else if (wordCount == 2) { arg1 = &userCommand[1][0]; nshFind(nshHead(aliasHP),arg1); } // wordCout =3 - set/reset a command alias else { // if the new alias is an internal command arg1 = &userCommand[1][0]; arg2 = &userCommand[2][0]; // if the head is null if (aliasHP == NULL){ //aliasHP = (node*)nshMalloc(sizeof(node)); aliasHP = (node*) malloc(sizeof(node)); strcpy(aliasHP->name,&userCommand[1][0]); strcpy(aliasHP->value, arg2); aliasHP->next = NULL; } // if need to find its place in the list else { nshInsert(nshHead(aliasHP), arg1,arg2, ALIAS); } } } // if the command is "saila" else if (strcmp(command,"saila") == 0 || (matchAlias(aliasHP, "saila", command))==TRUE ) { if (wordCount == 2) { arg1 = &userCommand[1][0]; int status; status = nshRemove(nshHead(aliasHP),arg1); if (status == onlyOneNode){ aliasHP = NULL; } else if (status == popHead){ aliasHP = (node*) nshNext(aliasHP); } } else { printf("To many arguments for 'saila' command\n"); } } // if the command is "exit" else if (strcmp(command,"exit") == 0 || (matchAlias(aliasHP, "exit", command))==TRUE ) { needToExecuteProgram = FALSE; continue; } // if the command is not supported or found else { printf("-bash: %s: external command not supported\n",command); } } } return END_PROGRAM; }